Categories: R10旧型PC

日立 MB-S1 S1-CP/M80にCPMDrvWinのI/Oを移植 その1

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が応答してくれた記録・・・

kabekin