Last Updated on 2021年5月2日 by kabekin
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が応答してくれた記録・・・