牧村さんとばくてんさんがいろいろ調べてた結果を(横取りする形で)確認してみました。$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); }
確認したお二方に感謝。