Jonathan カードの解析(4)プログラムの実行
Jonathan カードの動作がおおよそ分かりましたので、簡単な 68000 のプログラムを実行してみます。
DOS 3.3 で Apple II を起動。
$1F00 に、Jonathan カードスロット番号 x $10 + $80 を書き込む。たとえば、スロット 5 なら、$D0。
$1F03 に、0 を書き込むと、起動時の RAM チェックをスキップ。0 以外なら、RAM チェックが実行される。
$1F10 に、起動ディスクのスロット番号 x $10 を書き込む。たとえば、スロット 6 なら $60。
$1F40-5E に、起動ファイル名を書き込む。空白は $A0 にする。
Jonathan カードスロットの I/O アドレス ($C0n0) に $FF を書き込むと、Apple II の /RDY がアクティブになり、6502 が停止する。68000 側で、$FFC0n0 に 0 を書き込むと、/RDY が解除され、6502 が動く。
全体を制御するプログラムを Applesoft で作ります。
10 JOHN = 5
20 DISK = 6
30 BOOT$ = "JONATHANTEST "
40 FOR I = 0 TO 255
50 POKE 7936 + I, 0
60 NEXT I
70 POKE 7936, JOHN * 16 + 128
80 POKE 7939,1
90 POKE 7952, DISK * 16:
100 FOR I = 0 TO 29
110 POKE 8000 + I, ASC(MID$(BOOT$, I + 1))
120 NEXT I
130 PRINT CHR$(4)"BLOAD BIOS6502,A$300"
140 CALL 768
150 INPUT "CONTINUE ?";A$
160 IF A$ = "Y" THEN 140
170 END
DOS 3.3 の RWTS を実行するために Apple II 側の常駐プログラムが必要です。
以下の 6502 プログラムを S-C Macro Assembler で書きました。
Jonathan カードスロットの I/O アドレスを $07-08 にセット。
I/O アドレスに $FF を書き込み、68000 からの戻りを待つ。
復帰したら、$04 の値を調べ、$01 なら、RWTS の読み出し処理を実行。
IOB アドレスを取得し、$00-01 に設定。
$02 からトラック番号を取得し、IOB のオフセット 4 に設定。
$03 からセクタ番号を取得し、IOB のオフセット 5 に設定。
セクタバッファアドレス $2500 を、IOB のオフセット 8 に設定。
$04 から、RWTS コマンドを取得し、IOB のオフセット $C に設定。
ボリューム番号 0 を、IOB のオフセット 3 に設定。
$05 からドライブ番号を取得し、IOB のオフセット 2 に設定。
$06 から ドライブスロット番号を取得し、IOB のオフセット 1 に設定。
RWTS ルーチンを呼び出し。
エラーコードを $04 に設定。
1000 * JONATHAN INTERFACE TEST
1010 * JAN.12,2025 NANJA.INFO
1020 *
1030 .OR $300
1040 .TF BIOS6502
1050 *
0300- AD 00 1F 1060 START LDA $1F00 ;Jonathan Card Slot
0303- 85 07 1070 STA $07 ; 07-08 $C0n0
0305- A9 C0 1080 LDA #$C0 ; n = slot * $10 + $80
0307- 85 08 1090 STA $08
0309- A9 FF 1100 CONT LDA #$FF ;$FF = Go Jonathan
030B- A0 00 1110 LDY #$00
030D- 91 07 1120 STA ($07),Y ;Go Jonathan
030F- A5 04 1130 LDA $04 ;Check command
0311- C9 FF 1140 CMP #$FF ;None
0313- F0 F4 1150 BEQ CONT
0315- C9 01 1160 CMP #$01 ;Sector read
0317- F0 01 1170 BEQ DISKIO
0319- 60 1180 RTS
1190 *
031A- 20 E3 03 1200 DISKIO JSR $03E3 ;SETUP IOB
031D- 84 00 1210 STY $00 ;Save IOB address
031F- 85 01 1220 STA $01
0321- A5 02 1230 LDA $02 ;Get Track number
0323- A0 04 1240 LDY #$04
0325- 91 00 1250 STA ($00),Y ;Set track
0327- A5 03 1260 LDA $03 ;Get Sector number
0329- A0 05 1270 LDY #$05
032B- 91 00 1280 STA ($00),Y ;Set Sector
032D- A0 08 1290 LDY #$08
032F- A9 00 1300 LDA #$00 ;Sector buffer address lo
0331- 91 00 1310 STA ($00),Y
0333- C8 1320 INY
0334- A9 25 1330 LDA #$25 ;Sector buffer address hi
0336- 91 00 1340 STA ($00),Y
0338- A5 04 1350 LDA $04 ;Get RWTS command
033A- A0 0C 1360 LDY #$0C
033C- 91 00 1370 STA ($00),Y ;Set RWTS command
033E- A9 00 1380 LDA #$00
0340- A0 03 1390 LDY #$03
0342- 91 00 1400 STA ($00),Y ;Clear Volume number
0344- A5 05 1410 LDA $05 ;Get Drive number
0346- A0 02 1420 LDY #$02
0348- 91 00 1430 STA ($00),Y ;Set Drive number
034A- A5 06 1440 LDA $06 ;Get Slot number
034C- A0 01 1450 LDY #$01
034E- 91 00 1460 STA ($00),Y ;Set Slot number
0350- 20 E3 03 1470 JSR $03E3 ;Set IOB address
0353- 20 D9 03 1480 JSR $03D9 ;RWTS
0356- A9 00 1490 LDA #$00
0358- B0 05 1500 BCS DISKER ;If error goto DISKER
035A- 85 04 1510 STA $04 ;Save error code
035C- 4C 09 03 1520 JMP CONT
1530 *
035F- A0 0D 1540 DISKER LDY #$0D
0361- B1 00 1550 LDA ($00),Y
0363- 85 04 1560 STA $04 ;Save error code
0365- 4C 09 03 1570 JMP CONT
1580 END .EN
SYMBOL TABLE
0309- CONT
035F- DISKER
031A- DISKIO
0368- END
0300- START
0000 ERRORS IN ASSEMBLY
68000 のプログラムを S-C Macro cross assembler を使って作成します。
$000000 にスタックポインタ初期値、$000004 にプログラムカウンタ初期値を設定しますが、小細工が必要です。
DOS 3.3 のバイナリファイルは、先頭にロードアドレス 2 バイトとファイルサイズ 2 バイトの計 4 バイトのヘッダがつきます。RWTS でのセクタ呼び出しでは、このヘッダも読み込んでしまいますので、スタックポインタ初期値としてヘッダの 4 バイトが使われます。
.OR を 4 として、START が $000004 から始まるようにします。
.TA を 0 として、ロードアドレスが 0 になるようにします。ファイルサイズはプログラムの長さですが、今回の場合 $3E となります。
バイナリファイルの先頭は、$00、$00、$3E、$00 となるので、スタックポインタ初期値は $003E00 になります。
プログラム本体は、以下の処理を行います。
$FF1F00 から、Jonathan I/O アドレスを取得し、A0 に設定する。
A1 に Apple II TEXT VRAM のアドレス $FF0400 を設定する。
D0 に、表示する文字コードを設定する。
D1 に VRAM サイズ $3FF を設定する。
VRAM に D0 書き込む。
1 画面書き込んだら、$FF0004 に $FF または $01 以外の値を書き込む。
Jonathan I/O アドレスに 0 を書き込み、Apple II の処理を再開する。
$FE0000 のビット 1 を監視し、Apple II 側の処理が終わるのを待つ。
D0 をインクリメントし、繰り返す。
1000 * JONATHAN TEST
1010 * JAN.12,2025 NANJA.INFO
1020 *
1030 .OR $4
1040 .TA $0
1050 .TF JONATHANTEST
1060 *
1070 * .DA STACK
00000004- 0000 0008 1080 START .DA INIT
00000008- 203C 00FF
0000000C- C000 1090 INIT MOVE.L #$FFC000,D0
0000000E- 1039 00FF
00000012- 1F00 1100 MOVE.B $FF1F00,D0
00000014- 2040 1110 MOVE.L D0,A0
00000016- 103C 00A1 1120 MOVE.B #$A1,D0
0000001A- 43F9 00FF
0000001E- 0400 1130 CONT LEA $FF0400,A1
00000020- 323C 03FF 1140 MOVE #$3FF,D1
00000024- 12C0 1150 NEXT MOVE.B D0,(A1)+
00000026- 51C9 FFFC 1160 DBF D1,NEXT
0000002A- 13FC 00FE
0000002E- 00FF 0004 1170 MOVE.B #$FE,$FF0004
00000032- 4210 1180 CLR.B (A0)
00000034- 0839 0001
00000038- 00FE 0000 1190 WAIT BTST #1,$FE0000
0000003C- 67F6 1200 BEQ WAIT
0000003E- 5240 1210 ADDQ #1,D0
00000040- 60D8 1220 BRA CONT
1230 END .EN
SYMBOL TABLE
0000001A- CONT
00000042- END
00000008- INIT
00000024- NEXT
00000004- START
00000034- WAIT
0000 ERRORS IN ASSEMBLY
動かしてみます。
RAM チェックの後、プログラムが読み込まれ、無事動作しました。
表示が乱れるのは、MAIN/AUX のバンク切り替えを省略しているためです。
カーソル位置がズレるのは Laser 128 の仕様です。
Applesoft のようなユーザインターフェースで使えるアセンブラ、S-C macro assembler は、Sander-Cederlof family の web ページで公開されています。6502 アセンブラの他、68000、6809、Z-80 のクロスアセンブラがあります。
小さなプログラムを作るのにはとても便利です。