S1-CP/M80のディスクドライブにold68funさんのCPMDrvWinの8251版ドライバを移植しています。
Windows側のソフト内部の動作は不明ですが、BIOS09側はold68funさんのOneDriveにコードがアップされているので、仮想ドライブとのやり取りはそのまま使わせて頂きます。
コードを見た感じではドライブ名、トラック、BDOSセクタ÷2を渡して256バイトのデータをやり取りする仕組みのようです。
こんな感じでしょうか、
セクタ÷2で受け取った256バイトデータのブロッキングとデブロッキングはBIOS09側でやっているので単にFDDとの256バイトのやり取りを仮想ドライブの256バイトのやり取りに置換えるだけで実装できそうな感じです^^
と、いうわけでFM用に書かれている8251用のドライバを6850用に書き換えました。
; old68funさんのCPMDrvWin用ドライバ移植中 .if 1 ;*================================================ ;*read windows virtual drive (old68fun) RDWDRV = . ;*read 256bytes RDS0: LDX #fdc_param CLR CSUM LDA #'R LBSR ACIA_TX ;read cmd BSR ADDCS LDA IO_DRV,X LBSR ACIA_TX ;drv BSR ADDCS LDA IO_TRK,X LBSR ACIA_TX ;trk BSR ADDCS LDA IO_SCT,X LBSR ACIA_TX ;sct BSR ADDCS LDA CSUM LBSR ACIA_TX ;csum ;*wait receive ACKorNAKorESC ;* if NAK then re-send 'R',Drv,Trk,Sct,csum ;* if ESC then error return / if ACK then next RDS1: LBSR ACIA_RX CMPA #NAK BEQ RDS0 CMPA #ESC BNE RDS2 LDA #0xFF ;*error RTS ;*error end ;* RDS2: CMPA #ACK BNE RDS1 ;* send ACK LBSR ACIA_TX ;ACK ;*receive data(256bytes),csum ;* data is saved to Buffer(X) ;* if csum error then send NAK ;* if csum ok then send ACK and to next process RDS3: LDX #fdc_param LDX IO_ADR,X ;BIOS BUF ; LDX #cpmio_buf ;BIOS BUF CLRB ;counter(256) CLR CSUM RDSLOP: LBSR ACIA_RX ;data STA ,X+ BSR ADDCS DECB BNE RDSLOP LDA CSUM LBSR ACIA_TX ;csum LBSR ACIA_RX ;csum CMPA CSUM BEQ RDS4 LDA #NAK LBSR ACIA_TX ;NAK BRA RDS3 ;* RDS4: LDA #ACK LBSR ACIA_TX ;ACK ;*wait receive ACK RDS5: LBSR ACIA_RX CMPA #ACK BNE RDS5 RTS ;* ;*-------------------- ;*add check sum ADDCS: ADDA CSUM STA CSUM RTS ;*--------------------
書き換えましたと言っても、ACIA送受信用サブルーチンの変更なので仮想ドライブの送受信部は変数のオフセット以外はそのままだったりします^^;;
(Writeの処理もそのまま流用させて頂いております)
ACIAの送受信部もold68funさんのソフトにしたがってRTS,CTSを追加しました。
.if 1 ;*--- ACIA 1バイト受信 --- ;IN=RS232C Out:AccA(受信文字) ACIA_RX = . PSHS B LDB #CLR_RTS ;RTS=H LDA #SET_RTS ;RTS=L STA ACIACMD NOP ACIA_RX1: LDA ACIASTS ASRA BCC ACIA_RX1 LDA ACIADAT ;get data STB ACIACMD PULS B,PC ;*--- ACIA 1バイト送信 --- ;IN=AccA(受信文字) Out:RS232C ACIA_TX = . PSHS B LDB #CLR_RTS ;RTS=H PSHS A LDA #SET_RTS ;RTS=L STA ACIACMD NOP ACIA_TX1: LDA ACIASTS ASRA ASRA BCC ACIA_TX1 PULS A STA ACIADAT ;send data STB ACIACMD PULS B,PC .endif .if 0 ACIA_TX: pshs A,B ;ACIA 1バイト送信 lda #SERTSA ;RTS=L sta ACIA ACIA_TX1: ldb ACIA ;フラグリード asrb asrb bcc ACIA_TX1 ;フラグチェック sta ACIA+1 ;データ送信 puls A,B,PC ACIA_RX: lda #SERTSA ;RTS=L sta ACIA lda ACIA ;ACIA 1バイト受信(受信待ち) asra ;フラグチェック bcc ACIA_RX lda ACIA+1 ;データ受信 rts .endif
仮想ドライブ用I/Oを追加しドライブ2、3なら仮想ドライブに変更されるようにリードサブルーチンを切り替えます。
cpmio_RdSec: ;対象セクタを読み込む lda DRV sta IO_DRV,X ;Driveを設定 lda TRK sta IO_TRK,X ;Trackを設定 lda SCT lsra ;CP/Mセクタ番号→S1セクタ番号変換 inca sta IO_SCT,X ;Sectorを設定 ldb IO_DRV,X cmpb #2 bhs VTRD jsr _fdc_read ;FDDでReadを実行 bra VTRDE VTRD: lbsr RDWDRV ;仮想ドライブでReadを実行 VTRDE: lda IO_BufF,X anda #0xfe sta IO_BufF,X ;バッファ変更フラグ(b0)を0:OFFにする
上記のI/Oを追加してDIR C: をしてみると、
シリアルポートから、
応答がありました。
ASCIIの’R’とドライブ=2 , トラック=2, セクタ=1, チェックサム=57を送出してきます。
TeraTermのマクロで応答を返してみると、
想定とはちょっと違いますが、返信もあります^^
想定では256バイトのデータを送るとBIOS09側からチェックサムを送ってくるので、Windows側からもチェックサムを送ると ACK 又は NAKを返してくれるのではないかと思っています。
256バイト送信後も$D等のデリミタを送信しないと反応してくれないのでデリミタも必要かもしれません^^;;
しかし、
256バイトのデータを仮に$01+$02+$03.+$00…+$00+$03+$02+$01と送るとBIOS09側からチェックサムを計算し$0Cを返してくれているので基本的には動作しているようです。
正しいかどうか不明ですが、TeraTermeのマクロはこんな感じで書きました。
; Teratermマクロ CPMWinDrvとのやりとり確認 ;ACK 0x06 ;NAK 0x15 ;ESC 0x1B setdebug 2 ;バイナリモードに切替 ;setdebug 0 ;通常に戻す ;R wait '52' ;→'R'待ち ;→DrvNo, TrkNo, SctNo, CheckSumがBINで4バイト送られてくる mpause 1000 ;1000ms send $06 ;←ACK送信 wait '06' ;→ACK待ち mpause 1000 ;1000msec ;256バイトデータ送信 send $01$02$03$00$00$00$00$00$00$00$00$00$00$00$00$00 send $00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00 send $00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00 send $00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00 send $00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00 send $00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00 send $00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00 send $00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00 send $00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00 send $00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00 send $00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00 send $00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00 send $00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00 send $00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00 send $00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00 send $00$00$00$00$00$00$00$00$00$00$00$00$00$03$02$01 send $0D ;→CheckSumが1バイト ;mpause 1000 ;1000msec ;send $0C ;CheckSum送信 ;wait '06' ;'ACK待ち CheckSum後' ;mpause 1000 ;1000msec ;send $06 ;ACK送信
TeraTermで動作確認してもよく分からいので、次回からは実機で動作確認してみます。
そんな、S1-CP/M80のBIOS09が応答してくれた記録・・・