163 の workram register

牧村さんとばくてんさんがいろいろ調べてた結果を(横取りする形で)確認してみました。$f800 の IO ポートに仕込まれていました。$f800 は内蔵RAMのポインタ設定を兼ねているため、音源を使用するとポインタがずれてライトプロテクトが再度設定されてしまうようです。このため、いままでの自作プログラムなどでは音源と外部RAMの併用ができなかった要因でしょう。

$f800 _w
 7   internal work RAM pointer auto increment 0:off 1:on
 6:0 internal work RAM pointer address
 7:4 4:external work RAM write protect control else:disable
 3   control CPU $7f00-$7fff 0:write and read 1:read only
 2   control CPU $7000-$77ff 0:write and read 1:read only
 1   control CPU $6800-$6fff 0:write and read 1:read only
 0   control CPU $6000-$67ff 0:write and read 1:read only

いくつか市販ソフトのセーブルーチンをMESSのデバッガで追ってみたところこんな感じ。

DDS2
CAE7: lda  #$40
CAE9: sta  $F800
CAEC: lda  #$00
CAEE: sta  $B9
CAF0: sta  $BB
CAF2: tax  
CAF3: tay  
CAF4: lda  ($BB),y
CAF6: sta  ($B9),y
CAF8: iny  

KoK
CEDD: lda  #$40
CEDF: sta  $F800
CEE2: lda  $041B
CEE5: clc  
CEE6: adc  #$70
CEE8: sta  $ED
CEEA: lda  #$00
CEEC: sta  $EC
CEEE: ldy  #$09
CEF0: lda  $0347
CEF3: sta  ($EC),y

Dokuganryu Masamune (内蔵RAM)
B3EC: lda  #$81
B3EE: sta  $F800
B3F1: ldx  #$00
B3F3: lda  $0100,x
B3F6: sta  $6000
B3F9: sta  $4800
B3FC: inx  
B3FD: cpx  #$7E
B3FF: bcc  $B3F3
B401: lda  #$7F
B403: sta  $F800
B406: rts  

総当たりプログラムを書く前にちゃんとしたデバッガを使えばすぐにわかることでした。また、音源を使用していないじゅうべえくえすとは watch point の仕掛け方も容易だったので、最初からこれで調べればすぐでした。

anago 用のスクリプトを作成し、未改造の KoK のカセットにデータを書き込むことに成功しました。

function cpu_ram_access(d, pagesize, banksize)
{
	cpu_write(d, 0xf800, 0x40);
	cpu_ramrw(d, 0x6000, banksize);
	cpu_write(d, 0xf800, 0x4f);
}

確認したお二方に感謝。