○アドレッシングモード
A アキュムレータ。計算などに使うレジスタ。 X, Y インデクスレジスタ。主にメモリアクセスなどに使います。 S スタックポインタ。スタックのアドレスを保持しておくレジスタ
レジスタは8bitで、スタックエリアは$0100-$01FFの間に取られ、下位8bitが保持されてます。P プロセッサステータスレジスタ。計算結果のフラグを保持してるレジスタ。
・ステータスレジスタ詳細
Bit7:ネガティブフラグ。アキュムレータの最上位ビットがセットされます。
Bit6:オーバーフローフラグ。演算結果が127を超えるか-128より小さくなったときにセットされます。
Bit4:ブレイクフラグ。BRKによって割り込み処理が起きたときにセットされます。IRQ割り込みかBRK割り込みかの識別に使います。
Bit3:デシマルモードフラグ。このフラグをセットするとBCD(2進化10進数)モードになります。が、ファミコンのCPUではBCDモードはサポートされてません。
Bit2:インタラプトフラグ。このフラグをセットすると割り込み不許可になります。
Bit1:ゼロフラグ。演算結果が0になるとセットされます。
Bit0:キャリーフラグ。キャリーが発生したときセットされます。また引き算命令ではボローが起きたときは0、起きなかったときは1になります。他にシフトはローテート命令でも使用されます。
○割り込み?は16進数の一桁を表します。??=1バイトです。
名称 書式 説明 イミディエート #?? 値を直接指定 絶対アドレス ???? アドレスを直接指定 絶対アドレスX ????, X アドレスにXレジスタの値を足したアドレスを指定 絶対アドレスY ????, Y アドレスにYレジスタの値を足したアドレスを指定 ゼロページアドレス ?? ゼロページ内のアドレスを8bitで指定します。命令長が短くなります。 ゼロページアドレスX ??, X ゼロページアドレスにXレジスタの値を足したアドレスを指定 ゼロページアドレスY ??, Y ゼロページアドレスにXレジスタの値を足したアドレスを指定 間接アドレス (????) $????番地に入っているデータを指定。(2バイト)
$????番地のデータが下位8bitになり、$????+1番地のデータが上位8bitになります。間接アドレスX (??, X) ??とXレジスタの値を足した値をアドレスとして指定(2バイト) 間接アドレスY (??), Y $00??番地に入ってる値(2バイト)とYレジスタの値を足した値をアドレスとして指定
ゼロページとは8bitでアクセスできるページで、ファミコンの場合は$0000-$00FFになります。
各割り込みが起きたときには特定のメモリにかかれたアドレスにジャンプします。
NMI VBlankの時に発生します。NTSCでは1/60秒毎、PALでは1/50秒毎に発生します。 RESET 起動時とリセット時に発生します。 IRQ/BRK ハードウェア割り込み(IRQ)とソフトウェア割り込み(BRK)によって発生します。
NMI $FFFA RESET $FFFC IRQ/BRK $FFFE
○スタック命令
LDA Mem → A LDX Mem → X LDY Mem → Y STA A → Mem STX X → Mem STY Y → Mem TXA X → A TYA Y → A TAX A → X TAY A → Y TXS X → S TSX S → X
○演算命令
PHA Aをスタックへプッシュ PHP Pをスタックへプッシュ PLA Aをスタックからプル PLP Pをスタックからプル
○比較命令
ADC A + Mem + C → A SBC A - Mem - ~C → A AND A AND Mem → A ORA A OR Mem → A EOR A XOR Mem → A INC A + 1 → A INX X + 1 → X INY Y + 1 → Y DEC A - 1 → A DEX X - 1 → X DEY Y - 1 → Y
演算結果によるフラグをセットするだけで、結果は保存しない。○シフト/ローテート
CMP A - Mem CPX X - Mem CPY Y - Mem BIT A AND Mem
○ステータスビットセット/クリア
ASL 左シフト。Bit0 = 0、C = Bit7、Bit[n] = Bit[n-1] LSR 論理右シフト。Bit7 = 0、C = Bit0、Bit[n] = Bit[n+1] ROL 左ローテート。Bit0 = C、C = Bit7、Bit[n] = Bit[n-1] ROR 右ローテート。Bit7 = C、C = Bit0、Bit[n] = Bit[n+1]
○ジャンプ/条件分岐/サブルーチンコール/復帰
CLC 0 → C CLD 0 → D CLI 0 → I CLV 0 → V SEC 1 → C SED 1 → D SEI 1 → I
○その他
JMP 指定アドレスへジャンプ BCC C = 0のとき指定アドレスへジャンプ BCS C = 1のとき指定アドレスへジャンプ BEQ Z = 1のとき指定アドレスへジャンプ BNE Z = 0のとき指定アドレスへジャンプ BMI N = 1のとき指定アドレスへジャンプ BPL B = 0のとき指定アドレスへジャンプ BVS V = 1のとき指定アドレスへジャンプ BVC V = 0のとき指定アドレスへジャンプ JSR 指定アドレスのサブルーチンへ RTS サブルーチンから復帰 RTI 割り込み処理から復帰
BRK ソフトウェア割り込み NOP 何もしない
特に$4020-$7FFFはカードリッジに入ってるメモリマップコントラーラ(マッパー)使われ方が違います。
アドレス サイズ 内容 $0000 $0800 RAM $0800 $0800 RAM($0000-$07FFのミラー) $1000 $0800 RAM($0000-$07FFのミラー) $1800 $0800 RAM($0000-$07FFのミラー) $2000 $0008 I/Oレジスタ $2008 $1FF8 I/Oレジスタ($2000-2007のミラー×$03FF) $4000 $0020 I/Oレジスタ $4020 $1FE0 拡張ROM用 $6000 $2000 バックアップRAM用 $8000 $4000 プログラムROM $C000 $4000 プログラムROM
プログラムROMは32KByteのリニアアドレスですが、16KByte単位でバンク切り替えを行うことができます。
切り替え方は搭載されてるマッパーによって違います。
主なマッパーの仕様はこれを見てください。
アドレス サイズ 内容 $0000 $1000 パターンテーブル0 $1000 $1000 パターンテーブル1 $2000 $03C0 ネームテーブル $23C0 $0040 属性テーブル $2400 $03C0 ネームテーブル $27C0 $0040 属性テーブル $2800 $03C0 ネームテーブル $2BC0 $0040 属性テーブル $2C00 $03C0 ネームテーブル $2FC0 $0040 属性テーブル $3000 $0F00 $2000-$2EFFのミラー $3F00 $0010 BG用パレット $3F10 $0010 スプライト用パレット $3F20 $00E0 パレットミラー $4000 $C000 $0000-$3FFFのミラー
(例)文字”A”
アドレス(オフセット) データ(16進) データ(2進) 表示データ $0000 下位1bitのデータ $10 00010000 $0001 $00 00000000 $0002 $44 01000100 $0003 $00 00000000 $0004 $FE 11111110 00010000
00202000
03000300
20000020
11111110
20000020
30000030
00000000$0005 $00 00000000 $0006 $82 10000010 $0007 $00 00000000 $0008 上位1bitのデータ $00 00000000 $0009 $28 00101000 $000A $44 01000100 $000B $82 10000010 $000C $00 00000000 $000D $82 10000010 $000E $82 10000010 $000F $00 00000000
しかし実際は2つ分のメモリしかなく、残りの2つはミラーになります。
ネームテーブル2 ネームテーブル3 ネームテーブル0 ネームテーブル1
横スクロールゲームでは垂直ミラー、縦スクロールゲームでは水平ミラーを使うといいです。
名前 ネームテーブル0 ネームテーブル1 ネームテーブル2 ネームテーブル3 水平ミラー $2000 $2000 $2400 $2400 垂直ミラー $2000 $2400 $2000 $2400 4スクリーン $2000 $2400 $2800 $2C00
4x4タイルのデータを下のように名前をつけます。
グループ0
タイル0 タイル1 タイル2 タイル3 グループ1
タイル4 タイル5 タイル6 タイル7 グループ2
タイル8 タイル9 タイルA タイルB グループ3
タイルC タイルD タイルE タイルF
この4x4タイルの属性データは下のようになります。
bit0-1 グループ0のパレットの上位2bit bit2-3 グループ1のパレットの上位2bit bit4-5 グループ2のパレットの上位2bit bit6-7 グループ3のパレットの上位2bit
すなわち2x2タイルでは同じ4色パレットを使うことになります。
表示エリアはI/Oレジスタ$2000で基準となるネームテーブルを指定し、
ネームテーブル2 ネームテーブル3 ネームテーブル0 ネームテーブル1
スプライトの優先順位は0が1番手前で、63が1番奥です。座標はスプライトの左上の座標を指定します。
1バイト目 Y座標 2バイト目 タイルインデクス番号 3バイト目 bit7:垂直反転(1で反転)
bit6:水平反転(1で反転)
bit5:BGとの優先順位(0:手前、1:奥)
bit0-1:パレットの上位2bit
(他のビットは0に)4バイト目 X座標
タイルインデクス番号はサイズが8x8の場合、I/Oレジスタ$2000でパターンテーブルを選びます。
サイズが8x16の場合、偶数がパターンテーブル0、奇数がパターンテーブル1になります。
00だとパターンテーブルの0と1、01だとパターンテーブル1の0と1、02だとパターンテーブル0の2と3・・・となります。
1 A 2 B 3 SELECT 4 START 5 UP 6 DOWN 7 LEFT 8 RIGHT 9-16 無効(マルチタップ用) 17-24 パッド接続判定
波形の設定は$4000(矩形波1用)と$4004(矩形波2用)で行います。○三角波の鳴らし方
$4000/$4004の内容は下のようになってます。
bit7-6: DutyサイクルDutyサイクルの設定(positive/negative)は
bit5: 長さカウンタ無効/エンベロープDecayループ
bit4: エンベロープDecay無効
bit3-0: ボリューム/Decayレート
00: 2/14(12.5%)になります。
01: 4/12(25%)
10: 8/ 8(50%)
11:12/ 4(75%)
bit4が1のときDecay(音の減衰)が無効になり、bit3-0のデータがそのままボリュームになります。
bit4が0のときDecayが有効となりbit3-0はDecay速度を表します。bit3-0の値がNのとき、(N+1)/240秒でボリュームが1下がります。
bit5は再生時間の設定フラグで、1のときは自分で出力を止めるまで鳴りつづけます。
0のときはDecay使用時は減衰によってボリュームが0になるか設定した時間($4003,$4007)でストップします。Decay未使用時は設定時間後ストップします。
周波数の設定は$4002,$4006と$4003,$4007のbit2-0の11bitで指定します。
$4002,$4006が下位8bit、$4003,$4007のbit2-0が上位3bitになります。
基本となる周波数はCPUクロック(1.79MHz)で、設定した11bitの数をNとすると、
再生周波数は 1.79MHz / ((N+1)*16)になります。
ただし矩形波の場合Nを8以下に設定できません。
よって再生できる周波数は54.6Hzから12.4KHzになります。
再生時間は$4003,$4007のbit7-3で指定します。
設定値と再生時間の関係は下のようになります。
bit3 = 1 bit7-4 再生フレーム 0000 $7F 0001 $01 0010 $02 0011 $03 0100 $04 0101 $05 0110 $06 0111 $07 1000 $08 1001 $09 1010 $0A 1011 $0B 1100 $0C 1101 $0D 1110 $0E 1111 $0F
bit3 = 0 bit7-4 再生フレーム 0000 $05 0001 $0A 0010 $14 0011 $28 0100 $50 0101 $1E 0110 $07 0111 $0E 1000 $06 1001 $0C 1010 $18 1011 $30 1100 $60 1101 $24 1110 $08 1111 $10
スイープの設定は$4001,$4005で行います。
bit7はスイープの有効/無効フラグで、1のときスイープが有効になります。
bit3はスイープ方向の設定で、0のとき波長を長く(音を低く)、1のとき波長を短く(音を高く)します。
bit6-4は変化の速さを指定します。bit6-4で指定した値をNとすると(N+1)/120秒単位でスイープを行います。
bit2-0は変化の大きさを指定します。bit2-0で指定した値をN、$4002/$4003,$4006/$4007で指定した波長をLとすると、変化量は(L >> N)になります。
三角波の波形は0,1,2....D,E,F,F,E,D...2,1,0,0,1,2...のような形になります。○ノイズの鳴らし方
周波数は$400Aを下位8bit、$400Bのbit2-0を上位3bitとする11bitで表し、1.79MHz / ((N+1)*32)が周波数になります。
音の長さは$400Bのbit7-3で表し、内容は矩形波の設定と同じです。
また三角波の場合は音の長さをリニアカウンタで設定することができます。
設定は$4008で行い、bit7が1にセットするとリニアカウンタを使用します。
音の長さはbit6-0で指定し、指定した値をNとすると、N/240秒再生します。
ノイズは乱数ジェネレータが生成したビットを再生します。○DMCの鳴らし方
エンベロープの設定や再生時間の設定は矩形波と同じです。
乱数のタイプは32kbitモードと93bitモードがあり、$400Eのbit7で指定します。bit7が0のとき32kbitモードになります。
周波数は$400Eのbit3-0で指定します。この値は11bitの数字に変換され、周波数は1.79MHz / 11bit値になります。
bit3-0 11bit値 音程(オクターブ) 0 002 A(15) 1 004 A(14) 2 008 A(13) 3 010 A(12) 4 020 A(11) 5 030 D(11) 6 040 A(10) 7 050 F(10) 8 065 C(10) 9 07F A( 9) A 0BE D( 9) B 0FE A( 8) C 17D D( 8) D 1FC A( 7) E 3F9 A( 6) F 7F2 A( 5)
アドレス Read/Write 内容 $2000 W PPUコントロールレジスタ1
bit7: VBlank時にNMIを実行(0:実行しない,1:実行する)
bit6: PPUマスター/スレーブセレクト(常に1にする)
bit5: スプライトサイズ(0:8x8,1:8x16)
bit4: BGパターンテーブルアドレス(0:$0000,1:$1000)
bit3: スプライトパターンテーブルアドレス(0:$0000,1:$1000)
bit2: PPUアドレスインクリメント(0:+1,1:+32)
bit1-0: 表示するネームテーブルアドレス番号
$2001 W PPUコントロールレジスタ2
bit7-5: bit0=1のとき背景色/bit0=1のとき色強調
000:なしbit4: スプライト表示(0:非表示,1:表示)
001:緑
010:青
100:赤
それ以外の数字は不可
bit3: BG表示(0:非表示,1:表示)
bit2: スプライトクリップ(0:画面の左8ドットを表示しない,1:クリップなし)
bit1: BGクリップ(0:画面の左8ドットを表示しない,1:クリップなし)
bit0: ディスプレイタイプ(0:カラー,1:モノクロ)
$2002 R PPUステータスレジスタ
bit7: VBlank発生(1:VBlank中、ただしRead後0クリアされる)
bit6: スプライト#0ヒット(0:ヒットなし,1:ヒット)
bit5: スキャンラインスプライト数(0:8個以下,1:9個以上)
bit4: VRAM書きこみフラグ(0:書き込み成功,1:書き込み失敗)
$2003 W スプライトRAMアドレスレジスタ
$2004を使ってスプライトRAMに書きこむアドレスを指定する。$2004 W スプライトI/Oレジスタ
$2003で指定したスプライトRAMにデータを書きこむ$2005 W VRAMアドレスレジスタ1
BGのスクロール値をセットする。
このレジスタは2度書きレジスタでXのスクロール値、Yのスクロール値の順でセットする。
$2002をReadするとセットの順番はリセットされ、X値をセットする番になっている。
$2006 W VRAMアドレスレジスタ2
$2007を使ってVRAMに書きこむアドレスを指定する。
このレジスタは2度書きレジスタで上位8bit、下位8bitの順でセットする。
$2002をReadするとセットの順番はリセットされ、上位8bitをセットする番になっている。
$2007 R/W $2006で指定したアドレスのVRAMデータを読み書きする。
読み書き後$2000のbit2の値により、VRAMアドレスが1または32足される。$4000 R/W 矩形波チャンネル1制御レジスタ1
bit7-6: Dutyサイクル(positive/negative)
00: 2/14bit5: エンベロープDecayループ/長さカウンタ無効(1:ループ/無効)
01: 4/12
10: 8/ 8
11:12/ 4
bit4: エンベロープDecay無効(1:無効,0:有効)
bit3-0: ボリューム/Decayレート
$4001 R/W 矩形波チャンネル1制御レジスタ2
bit7: スイープ有効(0:無効,1:有効)
bit6-4: スイープレート
bit3: スイープ方向(1:decrease,0:increase)
bit2-0: スイープ右シフト値
$4002 R/W 矩形波チャンネル1周波数レジスタ1
チャンネル1で使う周波数の下位8bitをセットする。$4003 R/W 矩形波チャンネル1周波数レジスタ2
bit7-3: 音の長さ
bit2-0: 周波数の上位3bit
$4004 R/W 矩形波チャンネル2制御レジスタ1
bit7-6: Dutyサイクル(positive/negative)
00: 2/14bit5: エンベロープDecayループ/長さカウンタ無効(1:ループ/無効)
01: 4/12
10: 8/ 8
11:12/ 4
bit4: エンベロープDecay無効(1:無効,0:有効)
bit3-0: ボリューム/Decayレート
$4005 R/W 矩形波チャンネル2制御レジスタ2
bit7: スイープ有効(0:無効,1:有効)
bit6-4: スイープレート
bit3: スイープ方向(1:decrease,0:increase)
bit2-0: スイープ右シフト値
$4006 R/W 矩形波チャンネル2周波数レジスタ1
チャンネル1で使う周波数の下位8bitをセットする。$4007 R/W 矩形波チャンネル2周波数レジスタ2
bit7-3: 音の長さ
bit2-0: 周波数の上位3bit
$4008 R/W 三角波制御レジスタ1
bit7: リニアカウンタスタート
bit6-0: リニアカウンタ
$4009 未使用 $400A R/W 三角波周波数レジスタ1
チャンネル1で使う周波数の下位8bitをセットする。$400B R/W 三角波周波数レジスタ2
bit7-3: 音の長さ
bit2-0: 周波数の上位3bit
$400C R/W ノイズ制御レジスタ1
bit7-6: 未使用
bit5: エンベロープDecayループ/長さカウンタ無効(1:ループ/無効)
bit4: エンベロープDecay無効(1:無効,0:有効)
bit3-0: ボリューム/Decayレート
$400D 未使用 $400E R/W ノイズ周波数レジスタ1
bit7: 乱数タイプ選択(0:32Kmode,1:93bitmode)
bit6-4: 未使用
bit3-0: 波長選択
$400F R/W ノイズ周波数レジスタ2
bit7-3: 音の長さ
bit2-0: 未使用
$4010 R/W DMC制御レジスタ1 $4011 R/W DMC制御レジスタ2 $4012 R/W DMCアドレスレジスタ $4013 R/W DMCデータ長レジスタ $4014 W スプライトDMAレジスタ
メモリからスプライトRAMへDMA転送を行う
このレジスタに書きこんだ値をNをすると、
N×$100のアドレスから256バイトをスプライトRAMへ転送する。$4015 R/W サウンドレジスタ
bit7: DMC(Delta Modulation Channel)のIRQステータス(Readのみ)
bit4: DMC(0:無効,1:有効)
bit3: ノイズチャンネル(0:無効,1:有効)
bit2: 三角波チャンネル(0:無効,1:有効)
bit1: 矩形波チャンネル2(0:無効,1:有効)
bit0: 矩形波チャンネル1(0:無効,1:有効)
$4016 R/W パッドI/O1
bit4: ガンコントリガー(0:ON,1:OFF)
bit3: ガンコンスプライト検出(0:検出なし,1:検出)
bit0: パッドデータ(0:OFF,1:ON)
$4017 R/W パッドI/O2
bit4: ガンコントリガー(0:ON,1:OFF)
bit3: ガンコンスプライト検出(0:検出なし,1:検出)
bit0: パッドデータ(0:OFF,1:ON)