自作したZ80カード用に制作しているCP/Mがとりあえず動作しました
動作しなかった原因は
前回は動作していないと報告しました。その原因はいくつかありましたが主なものは以下の2つでした。
(1)DMAADRSの読み方が間違っていた
FDDの読み書き時に用いるバッファのアドレスをZ80で設定して6809で読む際に、例のビッグエンディアンとリトルエンディアンの違いに引っかかってしまった。
(2)CP/Mでもセクタ番号が1から始まっているものと思い込んでいた。
CP/Mでははセクタ番号は1ではなく0から始まるのですが、参考にした本(「CP/M80の世界」 工学社)でも1から始まるように書かれていたので信じ込んでしまった。
(2)は決定的でした。(1)に気づいて修正してDirectoryが表示されるようになったのですが、ファイル内容をTYPEしてみると半分ゴミが混じるのです。
プログラムを何回見直しても間違いが見つからず困っていましたが、そういえば中日電工の菱田さんのブログではセクタ番号を0からにしていたなと思い出して、それに合わせてプログラムを書き直したところようやく動作しました。
動作の様子
動作画面を示します。
|
CP/M起動画面 |
6809用のBIOS09を別ファイルにしてあるので、CP/M本体(Z80側のBIOS80を含む)、BIOS09の順に読み込んで、BIOS09を起動すると6809側の初期化をした後Z80に動作を移してCP/Mが起動します。
FM-CP/M用のフロッピーディスクがありましたので、それを読み込ませています。
|
コマンドも動作しています |
STATコマンドやTYPEコマンドが正常に動作しています。
メモリマップ
RAMディスクが無くなったので、TPAが$0100から$47FFまでと広くなりました。
サイズとしては25K CP/Mということでしょうか。
しかし、F-BASICと共存する形ですのでちょっと窮屈です。
|
左:以前のもの 右:今回のもの |
以前報告した自作のRS232Cカードも装着しており、RS232CのI/Oルーチンも実装しているので、WindowsからHEXファイルを読み込めますし、それなりに使える状態になっているかなと思います。
これから
変更すべき重要な点は2つあります。
(1)ブロッキング、デブロッキングをまともにしていない。
書き込み時にはまずCP/Mでの2セクタ(256バイト)を読み込んで、それに書き込むべき1セクタ(128バイト)を重ね書きしてからそれをフロッピーに書き込んでいます。
また読み込み時も、連続したセクタの読み込みでバッファにデータがあっても毎回フロッピーを読み込んでいます。
とりあえず動作させるためでしたが、流石に何とかしないと恥ずかしい。
(2)メモリマップで分かりますようにF-BASICのROMが邪魔をしていますので、オールRAMの状態で動作するように手直しをしなければもったいない。
また、今どきフロッピーディスクでもないので、ドライブC:やD:にWindows上の仮想ドライブを設定してFlex09やOS-9のように仮想ドライブをメインにしたいという希望もあります。
これが実現できると、ファイルの保存がWindows上でできるので、使い勝手がそれなりに良いCP/Mになるのではないでしょうか。
自作のCP/Mであれば機能の拡張も可能でしょうし、お仕着せのメーカー製よりもいじりがいがありそうです。BIOS09を拡張すればあれこれできそうで楽しみです。
しかし、不思議なのですがCP/MはなぜFAT情報(に相当するもの)をディスクに持たない設計にしたのでしょう。以前、Flex09, OS-9, F-BASIC用の仮想ドライブソフト(FlexDrvWin.exe, OS9DrvWin.exe, FBasDrvWin.exe)を製作した時と同じようにCpmDrvWin.exeを作ろうとしたことがあったのですが、ディスクの入れ替え時の切り替えの面倒さでメゲてしまったことがありました。
最後に
まず中日電工の菱田さんに感謝いたします。
80系の経験がほとんどない私が曲がりなりにも作ることができたのも
菱田さんのブログのおかげです。またND80Z3.5のマニュアル中のZ80や8080の命令表もとても分かりやすくて助かりました。
今はCP/Mのソースも公開されており、個人使用なら自由に使えるようですし、Z80カードも費用がそれ程かからず製作できますので、FM-7やFM-77をお持ちの方が遊んでみるのには向いているのではないでしょうか。
フロッピーディスクがなくても、RAMディスク版をオールRAMで動作させれば良いのですから、必要なのはZ80カードのみです。(RS232Cカードも必要かも)
280回も続くブログですが、117回まで読めばRAMディスク版が作れます。私は第87回ででき上がったファイル cpm22l.txt を元にしました。
参考にはならないと思いますが、私が製作したBIOS09を載せておきます。まだ途中の段階のものですが、FM-7のBIOSを使えばこの程度で動作するのだという見本ということで。
Z80の方は、基本的にパラメータを書き込んでコマンド番号を設定しているだけです。
*
* MY BIOS09 for CP/M-80
*
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ENTRY EQU $6233
FBASE EQU $5406 ;BDOS ENTRY POINT
DPBASE EQU $6239 ;DISK PARAMETER HEADER BASE
TDRIVE EQU $04
TBUFF EQU $80 ;i/o buffer and command line storage.
TRKADRS EQU $4B90
SCTADRS EQU $4B92
DMAADRS EQU $4B94
DRVNO EQU $4B96
CMDNO EQU $4B98
PTO09 EQU $4B99
PTOZ80 EQU $4B9B
KCSAVE EQU $4B9D
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
*---------- 6809 routine ----------
ORG $6800
*
BIOS EQU $FBFA
ACK EQU $06 ;
NAK EQU $15 ;
ESC EQU $1B ;
*USART 8251A
SDATA EQU $FD06 ;DATA
SCMD EQU SDATA+1 ;CMD
SSTS EQU SDATA+1 ;STATUS
MRSTU EQU $40 ;master reset
MODEU EQU $4E ;1stopbit,non pari,8bit,16x
CLRTSU EQU $15 ;RTS=H,ER,RxE,TxEN
SERTSUR EQU $34 ;RTS=L,ER,RxE for receive
SERTSUS EQU $31 ;RTS=L,ER,TxEN for trans
TxEMPTY EQU $04
START EQU *
*initialize
* reset 8251A
CLRA
STA SCMD
STA SCMD
STA SCMD
LDA #MRSTU ;reset
STA SCMD
LDA #MODEU ;1stop,nonpari,8bit,16x
STA SCMD
* set command to 8251A
LDA #CLRTSU ;RTS=H,ER,RxE,DTR,TxEN
STA SCMD
*set Z80 cold start
*write to $0000
LDX #0
LDA #$C3
STA ,X+
LDD #ENTRY
EXG A,B
STD ,X++
*go to Z80
TOZ80 EQU *
LDX #$FD05
LDA #1
STA ,X
NOP
*from Z80
*****************************
CMDIN LDA CMDNO
CMPA #2
BEQ CONST
CMPA #3
BEQ CONIN
CMPA #4
LBEQ CONOUT
CMPA #5
LBEQ LIST
CMPA #6
LBEQ PUNCH
CMPA #7
LBEQ READER
CMPA #8
LBEQ HOME
CMPA #9
LBEQ SELDSK
CMPA #10
LBEQ SETTRK
CMPA #11
LBEQ SETSEC
CMPA #12
LBEQ SETDMA
CMPA #13
LBEQ READ
CMPA #14
LBEQ WRITE
CMPA #15
LBEQ LISTST
CMPA #16
LBEQ SECTRAN
BRA TOZ80
*****************************
*
CONST EQU * ;2
LDX #RCBKIN
JSR [BIOS]
CLRB ;00
LDA RCBDBA+1 ;1:keyin, 0:none
BEQ CS1 ;not keyin
LDA RCBDBA ;keycode
DECB ;ff
CS1 STA KCSAVE ;0 or keycode
STB PTOZ80 ;0 or ff
LBRA TOZ80
*
CONIN EQU * ;3
LDA KCSAVE 0:none, !0:keycode
BNE CI2
LDX #RCBKIN
CI1 JSR [BIOS]
LDA RCBDBA+1 ;keyin?
BEQ CI1
LDA RCBDBA
CI2 STA PTOZ80
LBRA TOZ80
*
CONOUT EQU * ;4
LDA PTO09
LDX #RCBOUT
STA RCBDBA
LDD #$0001
STD RCBLNH
JSR [BIOS]
LBRA TOZ80
*
LIST EQU * ;5
LDA PTO09
LBSR SNDCH
LBRA TOZ80
*
PUNCH EQU * ;6
LDA PTO09
LBSR SNDCH ;rs232c
LBRA TOZ80
*
READER EQU * ;7
LBSR RCVCH ;rs232c
STA PTOZ80
LBRA TOZ80
*
HOME EQU * ;8
LDX #RCBRST
LDA PTO09
STA 7,X
JSR [BIOS]
LBRA TOZ80
*
SELDSK EQU * ;9
LBRA TOZ80
*
SETTRK EQU * ;10
LDX #RCBRWD
LDA TRKADRS
CMPA #39
BLS STT1
CLRA
STT1 STA 4,X
LBRA TOZ80
*
SETSEC EQU * ;11
LDX #RCBRWD
BSR SETSCT ;A:sct,B:side
STD 5,X
LBRA TOZ80
*
SETDMA EQU * ;12
LBRA TOZ80
*
READ EQU * ;13
BSR READSUB
*set read data
LDX #RCBBUF
TST BUFHL ;0:even, 1:odd
BEQ RE1
LDB #128
ABX ;rcbbuf+128
RE1 PSHS D
LDD DMAADRS
EXG A,B
TFR D,Y
PULS D
LDB #128
RLOP LDA ,X+
STA ,Y+
DECB
BNE RLOP
CLRA
STA PTOZ80
LBRA TOZ80
*
READSUB EQU *
LDX #RCBRWD
LDA #10 ;read cmd
STA ,X
LDD #RCBBUF
STD 2,X
LDA TRKADRS ;trk
STA 4,X
BSR SETSCT ;A:sct,B:side
RS2 STD 5,X ;sct,side
LDA DRVNO ;drv
STA 7,X
JSR [BIOS]
RTS
*
*return A:sct,B:side,BUFHL:0or1
SETSCT EQU *
CLRB
CLR BUFHL
LDA SCTADRS ;sct
BITA #$01
BEQ SE1
DECA
INC BUFHL ;0:even, 1:odd
SE1 LSRA
INCA
CMPA #16
BLS SE2
SUBA #16
INCB
SE2 RTS
*
WRITE EQU * ;14
*read
BSR READSUB
*set write data
LDX #RCBBUF
TST BUFHL ;0:even, 1:odd
BEQ WR0
LDB #128
ABX
WR0 PSHS D
LDD DMAADRS
EXG A,B
TFR D,Y
PULS D
LDB #128
WLOP LDA ,Y+
STA ,X+
DECB
BNE WLOP
*write
LDX #RCBRWD
LDA #9 ;write cmd
STA ,X
LDD #RCBBUF
STD 2,X
LDA TRKADRS ;trk
STA 4,X
BSR SETSCT ;A:sct,B:side
WR2 STD 5,X ;sct,side
LDA DRVNO
STA 7,X
JSR [BIOS]
CLRA
STA PTOZ80
LBRA TOZ80
BUFHL FCB 0
*
LISTST EQU * ;15
CLRA not ready
STA PTOZ80
LBRA TOZ80
*
SECTRAN EQU * ;16
LBRA TOZ80
*
*
RCBKIN FCB 21
FCB 0
FDB RCBDBA
FDB 00
RCBOUT FCB 20
FCB 0
FDB RCBDBA
RCBLNH FDB 0001
*
RCBDBA RMB 2
*
RCBRST FCB 8
FCB 0
FDB 00
FDB 00
FCB 0
FCB 0 DRVNO
RCBRWD FCB 9 9:dwrite, 10:dread
FCB 0
FDB RCBBUF
RCBTRK FCB 0 trk
RCBSCT FCB 0 sct
RCBSID FCB 0 side
RCBUNT FCB 0 DRVNO
*
*
*--------------------------------------
* receive from serial port
* (use USART 8251A)
* A <- port
*
RCVCH EQU *
LDA #SERTSUR ;RTS=L
STA SCMD
NOP
RCV1 LDA SSTS
ASRA
ASRA
BCC RCV1
LDA SDATA ;get data
PSHS A
LDA #CLRTSU ;RTS=H
STA SCMD
PULS A,PC
*
*--------------------------------------
* send to serial port
* (use USART 8251A)
* port <- A
*
SNDCH EQU *
PSHS A
LDA #SERTSUS ;RTS=L
STA SCMD
NOP
SND1 LDA SSTS
ASRA
BCC SND1
PULS A
STA SDATA ;send data
PSHS A
SND2 LDA SSTS
BITA #TxEMPTY
BEQ SND2
LDA #CLRTSU ;RTS=H
STA SCMD
PULS A,PC
*
RCBBUF RMB 256
END START
蛇足
製作したZ80カードですが、多少余りがありますので40Pコネクタとのセットで頒布しようと思い、ちょっと安い業者を見つけてコネクタを発注したのですが発送予定が何と7月末と言われました!
しかし待つしかありませんね。