ドラクエ風RPGファミコンプログラム講座
【 算術演算と論理演算】
* ファミコン(6502)の算術演算は、加算と減算のみで、
キャリー付きの加算命令と減算命令が1つずつあるだけです。
〖 論理積命令( AND ) 〗
*論理積命令 AND は、Aレジスタとオペランドの各BITを比較して、双方が1の時
のみ そのBITを 1 にする。
『例』
lda #$44
and #$0f
*上記のコードは Aレジスタは #%01000100 オペランドが #$00001111
なので。
Aレジスタ #$01000100
オペランド #$00001111
演算結果 #$00000100
*上の演算結果で、#$04 になるのが理解できるとおもう。このことから AND
命令は、特定のBITを取り出すのに使われる。
〖 論理和命令( ORA ) 〗
*論理積命令 ORA は、Aレジスタとオペランドの各BITを比較して、片方が1の時
そのBITを 1 にする。
『例』
lda #$44
and #$0f
ora #$80
*上記のコードは Aレジスタは 論理積の続きで #%00000100 オペランドが #$1000000 なので。
Aレジスタ #$00000100
オペランド #$10000000
演算結果 #$10000100
*上の演算結果で、#$84 になるのが理解できるとおもう。このことから ORA
命令は、特定のBITをはめ込むのに使われる。
ドラクエ風RPGファミコンプログラム講座
【 算術演算と論理演算】
* ファミコン(6502)の算術演算は、加算と減算のみで、
キャリー付きの加算命令と減算命令が1つずつあるだけです。
〖 加算命令( ADC ) 〗
*加算命令 ADC は、Aレジスタとオペランドを加算し更にキャリーフラグを
加えます。
『例』
lda #$44
clc
adc #$56
*CLC は、キャリーフラグをリセットする命令です。
〖 減算命令(SBC ) 〗
*減算命令 SBC は、Aレジスタとオペランド減算し更にキャリーフラグを
引きます。
『例』
lda #$44
sec
sbc #$56
*SEC は、キャリーフラグをセットする命令です。
〖 インクリメント・デクリメント 〗
☆INC(インクリメント)は、メモリーの値を+1する命令。
☆DEC(デクリメント)は、メモリーの値を-1する命令。
☆INX・INXYは、レジスタX・Y を +1する命令です。
☆DEX・DEYは、レジスタX・Y を -1 する命令です。
⁂インクリメント・デクリメント命令は、キャリーフラグ・オーバーフローフラグを
変化させない。
ドラクエ風RPGファミコンプログラム講座
【 16bitの変数】
* ファミコン(6502)は、扱えるDATAが8ビット(1byte)長なので16ビットを
超えるDATAは、8ビットずつ数回にわけて処理する必要があります。
『 メインカウンターの設置』
*ゲームプログラムには欠かせないメインカウンター(CT)を設置します。
ZEROPAGEに 変数 CTを宣言します。 CT = $10
TEST用プログラムの無限ループの中に inc CT を追加します。
これを 2byte を連動させるには、繰り上がりが発生したときに上位BYTEに加算
します。
loop000:
inc CT
jmp loop000
* inc は、オペランドを +1する命令。
inc CT
bne loop000
inc CT+1
jmp loop000
*上記は、キャリー判定ではなく CT が0になったかを見ています。
bne は、ゼロ出ない時 loop000 にjmpします。
ドラクエ風RPGファミコンプログラム講座
【 16bitの変数】
* ファミコン(6502)は、扱えるDATAが8ビット(1byte)長なので16ビットを
超えるDATAは、8ビットずつ数回にわけて処理する必要があります。
『 メインカウンターの設置』
*ゲームプログラムには欠かせないメインカウンター(CT)を設置します。
TEST用プログラムの無限ループの中に
[例]
CT = $10
*上記は、CT という名の変数を ゼロページ $10 で使うことを宣言しています、
ファミコン(6502)では、レジスタが8bit なのでCTは8bitの変数に
なりますが、16bit 以上の変数を扱う場合は CT,CT+1,CT+2 の様にアクセス
します、この場合 CT が最下位 CT+2 が最上位になり $1034df という値だとすると
CT = $df, CT+1 = $34, CT+2 = $10 に格納することになります。
ファミコンの変数は、宣言のみで代入はできません、 ROM領域から格納します。
lda #100, sta <$10 のように代入します、ゼロページ以外の宣言方法は .org $0300
.dw 0, db $00 の様に変数領域を確保します、DWは、2バイト DBは、
1バイトです。
ドラクエ風RPGファミコンプログラム講座
【 アセンブラでの変数】
* アセンブラに於いて変数の扱いは、基本的にRAMの領域なら自由に使えますが、
プログラムの領域と分けて使うのが望ましいでしょう。
ファミコンでは、プログラムの領域はROMになっているので競合の心配は、
ありません。 ファミコンでは、変数用にゼロページが用意されていて、
高速且つ利便性にも優れています, RAM領域は $0000~$07ff まででスタック領域
以外は自由につかえます。
『 変数の宣言』
*ゼロページに変数を宣言するには、下記の様に書きます。
変数名 = $**
[例]
CT = $10
*上記は、CT という名の変数を ゼロページ $10 で使うことを宣言しています、
ファミコン(6502)では、レジスタが8bit なのでCTは8bitの変数に
なりますが、16bit 以上の変数を扱う場合は CT,CT+1,CT+2 の様にアクセス
します、この場合 CT が最下位 CT+2 が最上位になり $1034df という値だとすると
CT = $df, CT+1 = $34, CT+2 = $10 に格納することになります。
ファミコンの変数は、宣言のみで代入はできません、 ROM領域から格納します。
lda #100, sta <$10 のように代入します、ゼロページ以外の宣言方法は .org $0300
.dw 0, db $00 の様に変数領域を確保します、DWは、2バイト DBは、
1バイトです。
ドラクエ風RPGファミコンプログラム講座
【libraryの作成 】
*今回からは、前回のプログラムを使って、ライブラリーを作成していきます。
ファイル名は、library.asm とします。
【TEST用プログラム再掲載】
;------------------------------------------------------
.inesprg 1
.ineschr 1
.inesmir 1
.inesmap 0
;-------------------------------------------------------
.bank 1
.org $FFFA
.dw 0
.dw Start
.dw 0
;--------------------------------------------------------------
.bank 0
.org $8000;
Start:
sei ;割り込み禁止
cld ;フラグクリア
ldx #$ff ;スタックポインターの初期化
txs
lda #%00001000 ; ここではVBlank割り込み禁止
sta $2000
lda #%00011000
sta $2001
VB0:
lda $2002
bpl VB0
jsr palette
jsr zero_init
*********
*********
main_loop:
jmp main_loop
.include "library.asm"
palette:
lda #$3f
sta $2006
lda #$00
sta $2006
ldx #0
pal_loop:
lda pall,x
sta $2007
inx
cpx #32
bne pal_loop
rts
zero_init:
lda #0
tax
lp00:
sta <$00,x
inx
bne lp00
rts
;-------------------------------------------------------------pall:
.db $0f,$30,$11,$21
.db $0f,$29,$1a,$27
.db $0f,$10,$00,$29
.db $0f,$29,$37,$11
.db $0f,$35,$30,$12
.db $0f,$26,$24,$25
.db $0f,$26,$27,$28
.db $0f,$11,$12,$13
*赤色の部分を切り取って、別ファイルにしファイル名を付けて保存します。
そこへ .include "library.asm” を追加します。
.include は、この場所にアセンブラファイルを挿入しますという疑似命令です。
バイナリーファイルをインクルードするには、.incbin を使います。
ドラクエ風RPGファミコンプログラム講座
【 TEST用プログラムの作成 】
〖 〗
*下記のコードはエミュレータで動く最小プログラムでFCEUXでは、動きましたが
VirtualNES では、ゼロページの初期化とパターンDATAの設置までしないと
動かないようです。ネストピアは、さらにシビアなようです。
*****印の所にテストプログラムを書いていきます。
;------------------------------------------------------
.inesprg 1
.ineschr 1
.inesmir 1
.inesmap 0
;-------------------------------------------------------
.bank 1
.org $FFFA
.dw 0
.dw Start
.dw 0
;--------------------------------------------------------------
.bank 0
.org $8000;
Start:
sei ;割り込み禁止
cld ;フラグクリア
ldx #$ff ;スタックポインターの初期化
txs
lda #%00001000 ; ここではVBlank割り込み禁止
sta $2000
lda #%00011000
sta $2001
VB0:
lda $2002
bpl VB0
jsr palette
jsr zero_init
*********
*********
main_loop:
jmp main_loop
palette:
lda #$3f
sta $2006
lda #$00
sta $2006
ldx #0
pal_loop:
lda pall,x
sta $2007
inx
cpx #32
bne pal_loop
rts
zero_init:
lda #0
tax
lp00:
sta <$00,x
inx
bne lp00
rts
;-------------------------------------------------------------pall:
.db $0f,$30,$11,$21
.db $0f,$29,$1a,$27
.db $0f,$10,$00,$29
.db $0f,$29,$37,$11
.db $0f,$35,$30,$12
.db $0f,$26,$24,$25
.db $0f,$26,$27,$28
.db $0f,$11,$12,$13
*コントロールレジスタの設定は、BGパターンが $0000 スプライトパターンが
$1000, BG・スプライトの表示ON