2020年5月2日土曜日

CP/M用の仮想ドライブの構築ソフト(その2)

仮想ドライブ構築ソフトCpmDrvWin.exeをCP/Mに接続してみました。


前回報告したCpmDrvWin.exeをCP/Mに接続してみました。
書き直したのは、CP/MのBIOSの6809側のルーチンのみで、DrvNoが0(A:),1(B:)の時は従来のFDDアクセスルーチンのままで、2(C:),3(D:)の場合にはRS232Cを通してCpmDrvWinと通信して仮想ドライブ中のファイルを読み書きします。

具体的には、ファイルを読む場合にはCpmDrvWinに対して’R',DrvNo,TrkNo,SctNo(+チェックサム)という文字列を、書き込む場合には’W',DrvNo,TrkNo,SctNo(+チェックサム)という文字列を送って、その結果を受け取るだけです。



ディレクトリを表示

ドライブA:はフロッピーディスクで、ドライブC:とD:が仮想ドライブです。
まだテスト中ですので、BaudRateを4800baudと遅くしてありますが、完成時には38400baudになります。


ドライブC:のディレクトリ表示時

右のテキストボックスは受信したコマンド列を表示しています。
Trk2,Sct1から始まって、各2回ずつ読んでいるのが分かりますが、これはブロッキング・デブロッキングをちゃんと行っていないためです。(何とかしなければ...)


ドライブD:のディレクトリ表示時

ディレクトリの範囲はTrk2のSct1~16なのですが、ドライブD:の場合のように、ファイル数が少なくても、その範囲のセクタを全て読んで、空を表示しています。(これはBDOSの仕様なのか、それとも自作BIOSの責任なのか...)

前回のブログで書きましたように、左のリストボックス中にWindows上のファイルをドラッグ&ドロップしてファイルを追加すれば、CP/Mからそのファイルにアクセスすることができます。

また、CP/MとWindows上のCpmDrvWinとの間の通信部分は、Flex9用、F-Basic用などと共通で、8251A使用のRS232Cカードや以前発表した拡張I/Oボード上の6850(ACIA)使用の場合の通信ルーチンが使用できますが、FM-7でも6850(ACIA)の方はあっさりと38400baudで動いています。

未だ完成ではありませんが、とりあえずこの程度でできるのだというサンプルとして、BIOSに追加した仮想ドライブアクセスルーチンを記しておきます。

*================================================
*read windows virtual drive
RDWDRV EQU *
*read 256bytes
 BSR READSUB2
 LBRA RE0

*read 256bytes
READSUB2 EQU *
RDS0 CLR CSUM
 LDA #'R
 LBSR SNDCH read cmd
 BSR ADDCS
 LDA DRVNO
 LBSR SNDCH drv
 BSR ADDCS
 LDA TRKADR
 LBSR SNDCH trk
 BSR ADDCS
 LDA SCTADR
 BSR SETSCT2
 LBSR SNDCH sct
 BSR ADDCS
 LDA CSUM
 LBSR SNDCH 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 RCVCH
 CMPA #NAK
 BEQ RDS0
 CMPA #ESC
 BNE RDS2
 LDA #$FF *error
 RTS *error end
*
RDS2 CMPA #ACK
 BNE RDS1
* send ACK
 LBSR SNDCH 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 #RCBBUF
 CLRB counter(256)
 CLR CSUM
RDSLOP LBSR RCVCH data
 STA ,X+
 BSR ADDCS
 DECB
 BNE RDSLOP
 LBSR RCVCH csum
 CMPA CSUM
 BEQ RDS4
 LDA #NAK
 LBSR SNDCH NAK
 BRA RDS3
*
RDS4 LDA #ACK
 LBSR SNDCH ACK
*wait receive ACK
RDS5 LBSR RCVCH
 CMPA #ACK
 BNE RDS5
 RTS
*
*return A:sct,BUFHL:0or1
SETSCT2 EQU *
 CLR BUFHL
 LDA SCTADR ;sct
 BITA #$01
 BEQ SE21
 DECA
 INC BUFHL ;0:even, 1:odd
SE21 LSRA
 INCA
 RTS
*
*--------------------
*add check sum
ADDCS EQU *
 ADDA CSUM
 STA CSUM
 RTS
*--------------------
*write windows virtual drive
WRWDRV EQU *
*read 256bytes
 LBSR READSUB2
*set write data
 BSR WRDTSET
*write
WRW2 CLR CSUM
 LDA #'W
 BSR SNDCH write cmd
 BSR ADDCS
 LDA DRVNO
 BSR SNDCH drv
 BSR ADDCS
 LDA TRKADR
 BSR SNDCH trk
 BSR ADDCS
 LDA SCTADR
 BSR SETSCT2
 BSR SNDCH sct
 BSR ADDCS
 LDA CSUM
 BSR SNDCH csum
*wait receive ACKorNAK
*  if NAK then re-send 'W',Drv,Trk,Sct,csum
*  if ESC then error return
*  if ACK then next
WRW3 BSR RCVCH
 CMPA #NAK
 BEQ WRW2
 CMPA #ESC
 BNE WRW4
 LDA #$FF  *error
 BRA WRW7 *error end
*
WRW4 CMPA #ACK
 BNE WRW3
*send data(256bytes),csum
*data is in Buffer(X)
WRW5 LDX #RCBBUF
 CLRB counter(256)
 CLR CSUM
WRWLOP2 LDA ,X+
 BSR SNDCH data
 BSR ADDCS
 DECB
 BNE WRWLOP2
 LDA CSUM
 BSR SNDCH csum
*wait receive ACKorNAK
*  if NAK then re-send data(256bytes),csum
*  if ACK then next
WRW6 BSR RCVCH
 CMPA #NAK
 BEQ WRW5
 CMPA #ACK
 BNE WRW6
 CLRA *no error
WRW7 STA PTOZ80
 LBRA TOZ80
*
*======================================

ということで、あちこちに不備があってまだまだ修正の必要がありますが、CP/M用の仮想ドライブのプロトタイプがとりあえずできたという報告でした。

2020年4月29日水曜日

CP/M用の仮想ドライブの構築ソフト

CP/M-80用の仮想ドライブ構築ソフトCpmDrvWin.exeを作りました。



FM-7用の自作Z-80カードのためのCP/Mを制作中ですが、何回も起動を繰り返すので、フロッピーディスクから起動したり、読み書きするのは結構面倒です。
とりあえず起動するのはフロッピーからでも仕方がないとして、せめて読み書きはもっと便利にしたいし、ファイルをWindowsとの間で自由にやり取りしたいと考えて、自作CP/MのBIOSの仕上げを中断して、仮想ドライブ構築ソフトCpmDrvWin.exeの制作に取り掛かりました。

今までにFlex9用、OS-9用、F-Basic用を作ってきましたが、CP/M用については、以前作ろうと試みたものの、CP/Mのファイルシステムが理解できず挫折していました。
今回は中日電工の菱田さんのブログで勉強しましたので大丈夫だとは思いましたが、それでも意外に時間がかかりました。

CP/Mのファイルシステムというかディレクトリの構成法は他のDOSと比較すると、原始的というかどうしてこうなっているのかと思えるもので、中でも特に、同じファイル名のディレクトリエクステントが複数存在する(それも、ディレクトリ全体を読まないと幾つあるかも分からない...)のには参りました。

とりあえず第1版として出来上がったものが動作している様子を示します。


CpmDrvWin.exeの動作画面


下のXM7上で動作しているFM-CP/Mと同じ情報が(並び順は異なりますが)表示されているのが分かると思います。
XM7ではスクロールアップしてしまったものはもう見ることはできませんが、CpmDrvWin.exeでは自由にスクロールアップダウンしてみることができます。


XM7上のFM-7 CP/Mの動作画面

機能としては、
・ファイルの追加(リストボックス中へのドラッグ&ドロップによる)
・ファイルの名称変更、削除、Windowsへの読み出し(ファイルを選択してからの右ボタンメニューによる)
・全ファイルのWindowsへの読み出し(編集メニュー中のコマンドによる)
があります。

現在は、表示されているドライブがWindows上の仮想ドライブとして見えるように、CP/M側のBIOSを手直し中です。
しばらく使用して不具合などを修正したら、CP/MのBIOSと共に公開する予定です。


2020年4月18日土曜日

FM-7用の自作CP/Mがとりあえず動作しました

自作した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月末と言われました!
しかし待つしかありませんね。


2020年4月15日水曜日

FM-7用のCP/M制作の試み(まだ未完成ですが...)

Z80カードを製作したので、CP/M-80を自作して走らせてみようと考えました


今更8ビットのCP/Mでもないとは思いますが、大昔にFM-7のCP/MでTurboPascalを使用していたこともあり、Z80カードを製作したのを機会に、もう一度昔の環境を復活させてみたくなりました。

と言っても80系の経験はほとんどないので自力ではとても無理ですが、幸い手元には中日電工さんのND80Z3.5とCP/M互換DOSがありますので、当時中日電工の菱田さんがCP/M互換DOSを開発する一部始終を連載された2012年のブログを元にすれば作れるだろうと思いました。
(それに、実際の処理はFM-7のBIOSに丸投げすれば良いだろうという、甘い考えもありました。)

実際に取り掛かってみて、まず引っかかったのは機械語での6809とZ80の間の切り替えでした。何しろ、$FD05に1や0を書いて切り替わった後に、どこへ飛んでいくかも分かっていないという無知な状態からのスタートです。
前回報告したATmega2560カードで四苦八苦しながら得た経験もあり、手探り状態ながら少しずつ進んできました。

ND80Z3.5用のRAMディスク版は移植できた

現在は、菱田さんのブログにあるND80Z3.5の32KBのRAM上で動作するRAMディスク版のCP/MがFM-7のDISK BASIC上でとりあえず動いたという状態です。
下にメモリマップを示します。

メモリマップ

TPAがわずか700hという超ミニサイズのCP/Mです。
使用したCP/Mのソースは公開されているcpm2-asm.zip中のcpm22.z80です。菱田さんのブログの通りにソースのバグを修正し、CONSOLE I/OとRS232CルーチンだけをFM-7用に書き直し、RAMディスク関係はND80Z3.5版をそのまま使わせてもらいました。



動作画面

CP/M本体をロードしておいて、6809用のBIOSをロードして実行するとCP/Mが起動します。この状態ではRAMディスクの中身は空ですが、菱田さんのブログでの手法を真似て6809のBIOSの起動中にTPAにプログラムを書き込んでおき、起動後にSAVEコマンドで保存しています。DIR,SAVE,ERAコマンドが正常に動作しています。

フロッピーディスク版はまだ動かない

次の段階として、フロッピーディスクのアクセスルーチンを書き、ディスク関係のパラメータを書き換えてRAMディスクからフロッピーに切り替えてみましたが、今のところ正常に動作していません。
FM-CP/Mのディスクを入れてDIR A:やDIR B:とすると、ドライブのアクセスランプは点灯してディレクトリを表示しようとするのですがファイル名が表示されません。
原因はまだ掴めていません。セクタブロッキング・デブロッキングあたりではないかと予想していますがどうでしょうか。

という現状報告でした。

2020年4月10日金曜日

ArduinoMega2560カードの紹介その後(完結編)

ArduinoMega2560カードが正常に動作するようになりました


前回、FM-7の40Pスロットで動作するArduinoMega2560カードを紹介しましたが、その際、動作後に6809に戻すためにはFM-7のメインRAMのリフレッシュ信号が必要であること。それをMega2560のソフトで実現したいが、なかなかうまく行かず、F-BASICに戻ってはくるがエラーメッセージが出てしまうという報告をしました。

そのブログを読んで下さったtomi9さんから、すぐに具体的なアドバイスをいただきました。

オートリフレッシュを用いる

それは、FM-7のDRAMであるMB8265はオートリフレッシュ(RFSH Refresh)でリフレッシュできるということ(など)でした。私のDRAMに関する知識は数十年前のもので、RASオンリリフレッシュでリフレッシュするものだと思い込んでおりましたので、まさに目からうろこでした。
早速そのようにプログラムを修正し、リフレッシュ信号などのパルス幅もできる限りデータシートの値に近づけてみました。

その結果、かなり動作が安定し、相変わらずエラーメッセージが出るものの、いつも同じエラーメッセージが表示されるようになりました。

Z80W信号がHighになることを確認する

さらにtomi9さんからの追加のアドバイスによって、Mega2560から6809へ復帰するために$FD05に0を書き込んだ後に、Z80W信号が実際にHighに変わるのを確認するためのwhile文を追加したことで、ほぼ確実に6809に戻ってくるようになりましたが、まだ、BREAKキーを押して戻す必要がありました。

ついに

その後、「思い付きハードで七転八倒」さんによる動作確認の結果やお二人からのプログラムの修正案をいただきながらプログラムの細かい見直しをした結果、ついに、常に正常に復帰させることができるようになりました。


連続実行の結果


ご覧のように、何回連続実行してもちゃんとF-BASICに復帰して、20行が実行されてLISTが表示されています。

FM-7の個体差か

しかし、私の2台のFM-7ではどちらも正常に動作しましたが、tomi9さんや「思い付きハードで七転八倒」さんのFM-7でも同様に正常に動作するというわけではないようです。
同じFM-7でも微妙な個体差があるようで、リフレッシュや6809への切り替え時のタイミングの調整で対応する必要があるということでしょうか。


資料

「思い付きハードで七転八倒」さんより提供された回路図を示します。


回路図


FM-7とMega2560の動作のシーケンスを下に示します。

動作のシーケンス

まとめ

FM-7の40Pスロットに他のボードを装着して動作させる場合には、6809がHALTしているので、ボード側でDRAMのリフレッシュを行なわなければならないが、それをソフトで行う試みについて報告しました。

この試みから得られた知見

(1)6809から別のCPUに制御を移した場合は、そのCPUでDRAMのリフレッシュを行う必要があるが、そのリフレッシュ方法としてはオートリフレッシュ(RFSH Refresh)が使用できる。
(2)6809から別のCPUに制御を移すには$FD05に1を書き込むだけで良いが、6809に戻すには$FD05に0を書くだけでなく、QB, EBの制御も必要。
(訂正:ご指摘を受けて間違っていることに気づきましたので、訂正します。戻るときも$FD05に0を書くだけで良いです。)
(3)同じFM-7という機種でも、このような場合には「個体差」が結果に影響することがある。
(追記:この手法そのものがFM-7には不適切なために「個体差」が影響したと言うべきでした。)

最後に、オリジナルのボードを考案されたFS-Micro Corporationさん、そのボードを目的に合うように改造され、動作確認やアドバイスを下さった「思い付きハードで七転八倒」さん、そして重要なアドバイスをいただいたtomi9さんの諸氏に感謝いたします。

なお、Mega2560ボードの回路図とスケッチはOneDriveで公開しております。


2020年3月28日土曜日

FM-7の40Pスロットで動作するArduinoMega2560カードの紹介

FM-7の40Pスロットで動作するArduinoMega2560カードを紹介します


オリジナルのカード

このカードを着想されオリジナルを製作されたのは「FS-Micro」さんで、FM-7のROMの内容を読み出すために考案されたものです。
FS-Microさんはこのカードを用いて、FM-7本体をいじることなくメインROM,サブROMの内容を読み出しておられます。

FS-Microさん考案のカード


改造したカード

そのカードを見て「思い付きハードで七転八倒」さんがFM-7のRAMへの書き込みができるのではないかと着想し、その機能の実現のために必要な改造を施しました。

思い付きハードで七転八倒さん改造のカード

改造の要点は、アドレス線、制御線にバッファを入れ、リード/ライトに合わせて制御することです。


RAMにデータを書き込めました

その結果、FM-7のF-BASICからアドレス$FD05に1を書きこんで、Mega2560に切り替え、Mega2560に書き込んだ「思い付きハードで七転八倒」さんが作成されたプログラムによってメインRAMに必要なデータを書き込むことができましたが、書き込み後にMega2560側で$FD05に0を書き込んでもF-BASICに戻ってきませんでした。
ただし、FM-7をホットスタートすることで、F-BASICに戻って書き込んだデータを利用することができますので当初の目的は達成されました。
「思い付きハードで七転八倒」さんは、このカードを用いて、自作のFT-245RL利用の高速転送カードでFM-7とパソコン間の通信をするための、FM-7側のプログラムを送り込むために利用しておられます。


そのカードをいただきましたので

ちょうどその頃、私もZ80カードを製作しており、6809とZ80 カードとの切り替えに興味を持っているときでしたが、そのカードを頂きましたので、Mega2560のソフトをそのまま利用させていただいて、何とか$FD05に0を書き込んでF-BASICに戻ってくるようにできないものかと考えました。

Z80カードの製作経験から、FM-7のメインDRAMのリフレッシュが関係しているだろうと感じていましたし、6809系の経験が豊富な「カベキン」さんからもDRAMのリフレッシュが必要というアドバイスをいただいていましたので、Mega2560のソフトにリフレッシュルーチンを追加することで何とか実現できないかと試みました。
なお、以下は「思い付きハードで七転八倒」さんの構想による回路とMega2560のプログラムを元にして、度重なるアドバイスをいただきながら私が何とかリフレッシュルーチンをでっち上げることができたという、2人の共同作業による結果です。

リフレッシュ信号(もどき)の作成

まずは、FM-7本体のリフレッシュのタイミングをロジアナで観測してみました。


ロジアナでのタイミング観測


FM-7のF-BASIC動作中リフレッシュ信号を確認しました。
時間軸は0.2us/divです。


F-BASIC動作中のリフレッシュ信号

それを真似てリフレッシュ信号(もどき)を作成してみました。
時間軸は10us/divです。

Mega2560のリフレッシュ信号

ソフトで作成している信号ですので、形は似ていても速度がかなり異なりますが、これ以上は速くできませんでした。
2ms毎にデータをRAMに書き込むのを中断して、上記のリフレッシュ信号(もどき)をリフレッシュアドレス$00から$FFまで256回繰り返しています。

その結果は

その結果、RAMにデータを書き込んだ後、一応、F-BASICに戻ってくるようになりましたが、エラーメッセージが出ることがあります。
しかも不思議なことにそのエラーメッセージが毎回同じではありません。

エラーメッセージ

上のエラーメッセージは5回繰り返して実行したものですが、エラーが3回出ていますし、そのエラーメッセージが意味不明です。

とりあえずここまで

エラーメッセージが出たりするものの、一応、F-BASICに戻ってくるようになったので、これで良しとしようと思います。
ソフトでDRAMのリフレッシュ信号を生成しているつもりですが、時間的には本来のリフレッシュ信号とはかなり異なっていますので、リフレッシュ動作というよりもただRAMを読んでいるだけかもしれません。(そうであってもRAMの値が保持されれば良いわけですが...)
そもそもソフトでリフレッシュしようという方法が間違っている可能性もありますし、
こんな方法があるよというアドバイスなどをいただけたらありがたいです。

なお、Mega2560の回路図とスケッチは「思い付きハードで七転八倒」さんのブログで公開されます。

2020年3月13日金曜日

FM-7用Z80カードの第2作などを製作

FM-7用のZ80カード(第2作)がようやく製作できました


ようやく基板が届いたのでZ80カードを製作することができました。
第2作はI/O誌1985年9月号に掲載された記事「Z80カードの製作」(著者は北斗星さん)の回路です。
第1作のインターフェース誌のFM-8用の回路の流用では動作が不安定だったり、対応していないFM-7があったりしたのですが、その原因を究明できていないのに(恐らくDRAMのリフレッシュ周りだろうとは思っているのですが、)別の回路に移るというのは、安易な姿勢だとは思いますが、Z80の知識がないので仕方がないと自分を納得させています。

この回路はFM-7/New7/77用として設計されており、第1作にはなかった6809とZ80を切り替えるためにアドレス$FD05をアクセスする際の対応やリフレッシュ回路もあり、動作が期待できましたが、実際にあっけなく動作しました。
(ということで第3作として予定していた「F-BASIC解析マニュアル」中の回路はKiCadで書き上げて準備してありましたが、製作の必要はなさそうです。)

回路ですが、ほぼI/O誌の回路図のとおりで、私が変更したのはLS244をLS541に置き換えたのと、Z80がアクセスされたときに点灯するLEDを追加した部分だけですので、回路図を載せるのは控えておきます。

製作したZ80カードです。10㎝x8㎝に収まっています。

Z80カード表面


Z80カード裏面

動作している様子です。(余計なものが写っていますが...)
左の基板は同時に製作した修正版FDCカードです。
Step信号2倍化回路を通して2DDのFDD(TEAC FD-235HG)を使用しています。


動作全景


両カードのアップ


FM-CP/Mも正常に動作しています。

FM-CP/Mの起動画面


FDCカードも手直しをしました。


前作のミスを修正したFDCカードです。


FDCカード


今度はちゃんと裏面からFDDへのケーブルのコネクタを出しています。
しかし、今回もミスがあり、パターンカットは不要でしたが、GNDへのジャンパの追加が2本必要でした...(ちゃんと見直しをしたつもりでしたが、ダメですね。)
でも簡単な修正ですので、基板はこれで完成とします。

FDCカード裏面



ということで、手持ちの純正CP/M基板は温存して、以前から所有していながらほとんど使用していなかったCP/Mを安心して使えるようになりましたので、多少Z80への興味が出てきたこともあり、CP/MのBIOSを自分で書いてみようなどと(無謀ですね!)考えています。

どうやらZ80側では必要なパラメータを6809に渡して、実際の処理は6809にさせれば良いようですので、これならできるかななどと甘いことを考えています。
参考資料としては、中日電工さんのZ80ワンボードマイコン(ND80Z3.5 上の動作全景写真の左上に映っています!)と互換CP/Mシステムを所有しておりますので、2012年の互換CP/M開発当時のブログを読みながら、ND80Z3.5上にCP/Mシステムを構築するという試みをなぞっているところです。
BIOSが作れれば、CP/M本体のソースは公開されていますので(上記ブログによれば何ヶ所かバグがあるようですが)、自分用のCP/Mができあがることになります。
いつになるかは全く分かりませんが、できましたらブログで紹介させていただきます。

2020年2月28日金曜日

2DDドライブと2Dドライブの混在の工夫

Step Doubler回路を用いて2DDドライブと2Dドライブを混在させる


中国の業者に発注したFDCカードとZ-80カードの基板が十日もあれば届くと思っていたのに、一か月を過ぎても届かないので、予定していたことが全く進みません。。。
ということで、今回はほんのちょっとした工夫の報告です。

10月26日のブログ(12月31日に追記あり)で、FM-7でPC用の2DDドライブを使用するという報告をしましたが、それは自作のFDCカードの中でMB8877AからのSTEP出力を2倍化するというものでした。
従って、適用できるのは2DDドライブのみということになるわけですが、実際の運用としては、5インチとのメディア変換などで2Dドライブも接続したい場合があります。

そこで、FDCカード中でStep信号を2倍化するのではなく、2DDドライブの直前のフラットケーブルの途中に挿入することにしました。さらに、ドライブのコネクタ部で行っていたドライブセレクト信号の切り替えとReady信号生成も同じ基板に載せました。

この形ですと、市販の2DドライブのFDDシステムをお持ちの方でも、別途2DDドライブを用意して、この回路を通してドライブに接続することで、2DDドライブを使用できることになります。

作成した基板です

Ready信号生成回路を後付けしたので見苦しいですが、基板中央の8ピンICがStepDoubler回路のATtiny85で、その出力を7438を通してFDDに送っています。外付けの8ピンICがReady信号用のPIC12F675です。ドライブ0と1の切り替えジャンパとStepDoubler回路のバイパス用のジャンパがあります。


基板


回路図を示します。

手持ちの7438を用いていますが、3.5インチの2DDドライブは負荷としてはそう大きくはないので、7406でも大丈夫だと思います。

回路図

Ready信号の生成部ですが、以前のブログで紹介した2つの回路のうちのPIC12F675を用いてIndex信号とMotorOn信号からReady信号を生成する回路を用いております。
最初はダイオードによる簡便な回路で製作しましたが、残念ながら正常に動作しませんでした。ドライブがセレクトされたときには常にReady信号が出るのがまずいのでしょうか。PICを用いた回路では、正常に動作しています。


動作風景です。

画像で分かりますようにフラットケーブルの途中に基板を入れ、基板を通さずに2Dドライブを、基板を通して2DDドライブを接続しています。
FM-7に刺さっているカードが自作のFDCカードで、これに載っているStepDoubler回路はスキップしています。


動作風景

ディスプレイは小さいので左の棚の上に置いています。

画面表示


私は、通常は2DDドライブ2台で運用しているのですが、2Dドライブが必要な場合はこの回路を用いてFM77AV1から外した2Dドライブ(YD-625)と2DDドライブ(FD-235HG)とで運用しています。メディア変換が必要な場合にはYD-625の代わりに5インチドライブを使用しています。

改良すべき点として、ATtiny85とPIC12F675を一つのICに置き換えることがあるとは思いますが、当面はこのままで使用するつもりです。

2020年2月1日土曜日

FM-7用のZ80カードを製作してみましたが...


いじって遊べるFM-7用のZ80カードが欲しい


手元に今でも動作するFM-7用のZ80カードとCP/M-80システムがあるのですが、そのカードの6809とZ80の切り替えの仕組みに興味がありました。
でも純正のZ80カードも古いですし、あれこれいじっていて故障させてしまうのは怖いので、いじり倒して遊べるZ80カードが欲しいと思っていました。

まず最初にFM-8用の倍速化した回路で製作してみました


インターフェース誌1983年7月号の村上啓司さんによる「FM-8を高速化する」という記事中に倍速化したFM-8用Z80カードの回路図が載っており、そのコネクタ信号がFM-7と同じようでしたので、もしかしたらFM-7でも動くのではないかと考えました。


FM-8用の倍速化回路を利用したZ80カード


手持ちの富士通製の純正Z80カードは19個ものICを使用していますが、この回路は11個と少ないのでサイズも小さくできて作りやすいので、ものは試しと製作してみることにしました。


左:富士通製 右:製作したカード

製作したカードの回路図を示します。
村上さんのFM-8の高速化の回路と倍速化Z80カードの回路のうちのZ80カードの部分のみにFM-7用の32Pコネクタをつけただけです。


FM-8用倍速化Z80カードの回路を利用しました


プリント基板を作り、試作してみました。
最初は、例によって全く動作しなかったのですが、自作したテストプログラムが悪いのかそれとも回路がダメなのかが分からずお手上げ状態でした。
そんな時に、WebでI/O誌の1985年9月号に掲載されたFM-7用Z80カードの製作記事を見つけ、その中のテストプログラムを利用することができ、ハードの調査に専念することができました。
あれこれと思いつく箇所を変更してみたりしていたのですが、結局、使用した手持ちの古いセラミックコンデンサ(1000pF)がショートしていたため74LS00の出力段を破損していることを見つけて、ICとCを交換して無事にテストプログラムが動作するようになりました。

動作中の様子を示します。
(画像中のディスプレイはWindows用で、FM-7用のディスプレイは左側に配置してあるので写っていません。)

動作中の様子(右基板がZ80カード、左はFDCカード)



次に、動くことは期待していなかったのですが、試しに富士通のFM-7用のCP/M-80を走らせてみました。

CP/M-80の起動画面


最初は画像のようなオープニングメッセージが表示されたところでハングアップするか、あるいは入力を受け付けたところでハングアップしてしまいました。
画面表示ができることや、入力を受け付けるときもあること、そして、2台のFM-7で微妙に動作が異なることから、メモリアクセスのタイミングに問題があるのだろうと考えて、とりあえず1000pFにCを並列に加えて容量を変えてみました。値を増やすと徐々に正常な動作に近づくのですが、それでも時々エラーでハングアップしてしまいます。
結局は、これも1000pFのコンデンサの不良(容量抜け?)が原因で、コンデンサを交換することで無事に動作しました。(1000pF~2000pFの範囲で正常動作しました。)

CP/M-80が動作している画面を示します。




このZ80カードは正常に動作すると思ったのですが...


ところが、何とこのZ80カードはもう一台のFM-7では正常に動作しないのです。
CP/M-80では起動画面でハングアップしますし、上記のテストプログラム(6809とZ80間のチェンジを8回繰り返す)では途中でエラーで終了してしまい、リストを取ってみるとプログラムが書き変わっています。
どうもNew7ではない同じFM-7でもメモリアクセス周りに微妙な違いがあるようです。

ということで、村上さんのFM-8用の倍速化Z80カードの回路は、そのままでは全てのFM-7で動作するというわけではないということになりそうです。

ならば、I/O誌に掲載されたFM-7用のZ80カードでということになるわけですが、実は、もう既にKiCadで回路図を起こして、修正したFM-FDC基板と共にFusionPCBに発注してあります。(春節とコロナウイルスのために未だ製造にも入っていませんが...)
ということで、I/O誌の回路によるZ80カードが完成し、正常に動作したら報告したいと思います。

2020年1月23日木曜日

FM-7用のFDCカードのプリント基板化完了

FM-7用のFDCカードをプリント基板化しました。


2019年8月26日のブログ「FM77用の拡張I/Oボード、ROM/RAMディスクボードのプリント基板化が完了」の末尾で紹介しました、手配線のFM-7用FDCカードですが、プリント基板化し、ようやく動作確認ができました。

いつものようにいくつかのドジをしてしまい、しなくても良い回り道をしましたが、現在は無事に動作しております。

まず回路図を示します。
2019年10月26日のブログ「FM-7でPC用のフロッピードライブを使う」で示した回路には一個所間違いがありましたので訂正してあります。(Q,E,RW信号からWE信号を作るところです。)
また、Step信号の2倍化回路を追加してあります。


回路図(StepDoubler回路付き)


製作した基板を以下に示します。
およそ12cmx8cmのサイズに計21個のICを何とか収めることができました。
中央の40ピンICがFDCのMB8877A、その右上の8ピンICがデータセパレータの9216B、基板右上隅の8ピンICがStepDoubler用のATtiny85で、その右のスイッチはそのStepDoubler回路のバイパススイッチです。
(ミスのある基板ですので、試作ということで34ピンコネクタの代わりにボックスコネクタを使用したり、FDD用の電源として0.1uのパスコン用の穴にピンを立てて取り出したり、修正をICの足を切断して表面で配線したりしていますので見苦しいですが...)


FM-7用FDCカード


回路のミスのみでなく、FDD用の34ピンコネクタを裏側ではなく表側に配置してしまったり、FDD用の電源コネクタを忘れたりしています。(こんな基板を10枚も作ってしまいました...)
全くダメな基板というわけでもなく、多少の修正で動作するのでまあ良しとします。

もう一度、これらを修正し、FDD用の電源コネクタを追加した基板を作成中です。
このカードのみで普通の2Dのドライブ(あるいはDOS用の2HD/2DDドライブ)を4台まで接続できます。(もちろん、各ドライブにはReady信号を生成する回路が必要ですが。)

一度はもうFM-7ではFDDを使うのはやめようと決めましたし、FDを使わない工夫をされている方々がおられますので(「思い付きハードでソフトに七転八倒」さん、「ysflight.com」さん、「日本橋電気街徘徊日誌」さんなど)、その方々のお知恵を拝借すれば、あえてクラシックなFDDを使う必要もないのですが、大昔、手配線で苦労して製作したFDCカードですので、プリント基板化し、資料として残すことができて満足です。


2020年1月21日火曜日

FM77AV用PS/2キーボード変換器の不具合を修正

FM77AV用のPS/2変換器のビープ音が鳴るという不具合を修正しました


2019年7月19日に公開しましたPS/2キーボード変換器ですが、身近の方々や、ご希望の方に基板やプログラム書き込み済みのATtiny85を配布したりして使っていただいておりました。
最近ある方から、キーを押すたびにビープ音が出て困るというお話をいただきました。
私自身も4年以上使用していましたが、常にボリュームをゼロにしていましたので全く気づいていませんでした。何故か常用しているFM77AV40SXではビープ音は出ませんが、最近入手したFM77AV1では出ました。

キーを押すたびにビープ音が出る原因ですが、RS232Cカードの件でお世話になりましたysflight.comさんのブログによりますと、キーを離したときにリリースコードを発行していないからだということでした。
リリースコードをどのように構成すればよいのか分からず、ysflgith.comさんのプログラムを読んでみたりしていたのですが、40ビットコードを30ビットに変換して処理されていることもあってか処理内容が理解できず、思い余って直接ysflight.comさんに助けを求めましたところ、快く教えていただけました。とても丁寧に解説していただいたのでようやく理解することができました。ありがとうございました。

ysflight.comさんによれば40ビットのコード中の、第4ビットからの8ビットのみを変換すれば良いとのことでした。
ということで処理が必要なのは先頭からの2バイトのみということになりますので、コードを確認したところ、第1バイトは常に0xb4で、第2バイトは0xcc,0xcb,0xb4,0xb3の4通りしかありませんでしたので、それらに必要な処理をした結果は以下のようになりました。
  0xb4, 0xcc -> 0xb3, 0x4c
  0xb4, 0xcb -> 0xb3, 0x4b
  0xb4, 0xb4 -> 0xb3, 0x34
  0xb4, 0xb3 -> 0xb3, 0x33
キーを押下したときのコードの第1,2バイトを上のように置き換えたものをリリースコードとして押下コードの直後に発行することで、無事にビープ音を消すことができました。
その部分のプログラムを以下に示します。



// convert from codeno to serial code
// change keycode to serial code for FM77AV
void outserialdata(unsigned char kcode)
{
 ...
 
  flgE0 = 0;
  flgE1 = 0;
  if (pgm_read_byte(&pscode0[i]) == kcode) {
   cnvcode(i);
   cnvreleasecode(i); // !!! Added to mute the beep !!!
  }
 ...
 
  flgSFTCTRL = 0;
  svsftctrl = 0;
  if (pgm_read_byte(&pscode0[i]) == kcode) {
   cnvcode(i);
   cnvreleasecode(i); // !!! Added to mute the beep !!!
  }
 ...
}


int cnvcode(unsigned int codeno)
{
 unsigned char kc;
 int i; 

 serial2port(0xb4);  // 1st byte
    for (i=0; i<4; i++) { // 2nd-5th bytes
  kc = pgm_read_byte(&fmcode0[codeno][i]);
  serial2port(kc);
    }
 PORTB |= _BV(4);  // PORTB = 0x10(KSDATA=H)
// _delay_ms(20);   // important!!! for 2key pressed
 _delay_ms(1);
    return 0;
}

// convert from codeno to serial releasecode
// only the following four release code patterns to be changed
// 1st  2nd byte
// 0xb4,0xcc -> 0xb3,0x4c
// 0xb4,0xcb -> 0xb3,0x4b
// 0xb4,0xb4 -> 0xb3,0x34
// 0xb4,0xb3 -> 0xb3,0x33
int cnvreleasecode(unsigned int codeno)
{
 unsigned char kc;
 int i; 

 serial2port(0xb3);  // 1st byte
 kc = pgm_read_byte(&fmcode0[codeno][0]); // read 2nd byte
 switch (kc) {
  case 0xcc: serial2port(0x4c);
      break;
  case 0xcb: serial2port(0x4b);
      break;
  case 0xb4: serial2port(0x34);
      break;
  case 0xb3: serial2port(0x33);
      break;
 }
    for (i=1; i<4; i++) { // 3rd-5th bytes
  kc = pgm_read_byte(&fmcode0[codeno][i]);
  serial2port(kc);
    }
 PORTB |= _BV(4);  // PORTB = 0x10(KSDATA=H)
// _delay_ms(20);   // important!!! for 2key pressed
 _delay_ms(1);
    return 0;
}

// serial code out to PORTB(bit4)
// In an 8-bit pattern, the 4th bit is always equal to the 3rd bit
// pulse length (8bit->skip the 4th bit)
//  100us,125us,175us,100us,125us,175us
void serial2port(unsigned char kc)
{
 int i;

    for (i=0; i<8; i++) {
     if ((i+1) % 4 != 0) {  // skip bit3,7
      if((kc & 0x80) == 0x80) {
    PORTB &= ~_BV(4); // PORTB = 0x00(KSDATA=L)
   } else {
    PORTB |= _BV(4); // PORTB = 0x10(KSDATA=H)
      }
  }
  // wait100,125,175us();
     switch (i) {
      case 0:
     case 4:
    _delay_us(100);
    break;
      case 1:
      case 5:
    _delay_us(125);   
       break;
      case 2:
     case 6:
    _delay_us(175);
       break;
      case 3:
      case 7:
       break;
     }
     kc = kc << 1;
 }
}



キーコード番号を得て、それを4バイトのキーコードに変換して出力するルーチン中で
関数cnvcode()に続いてcnvreleasecode()を実行しています。
実際にポートに出力する関数serial2port()も手直ししました。
以前は各ビットの出力時間は全て等しく100usでしたが、ysflight.comさんが実機で確認されています長さに合わせて100us,125us,175us(第4ビットはパス)に変更してあります。

また、以前のプログラムではキーが連打されたときにキーコードを正しく認識するためにcnvcode()の末尾に20msのdeleyを入れていましたが、リリースコードでキーが離されたことを認識できますのでそれが不要となりました。(なしにはできず、1msのdelayは必要でしたが。)
結果として、かなりの高速で連打しても正しく入力ができるようになりました。
OneDriveにプログラムを公開してありますので、詳しくはそちらをご覧ください。

貴重なアドバイスをいただいたysflight.comさんに感謝いたします。

【追記】変換器を購入された方で、ご自分でATtiny85に書き込めない方には、新しいプログラムを書き込んだATtiny85をお送りしますので、私からの連絡をお待ちください。


2019年12月31日火曜日

FM-7でPC用のフロッピードライブを使う(その後の訂正・補足)

前回の報告の一部訂正と動作したFDDが増えたという報告です


前回(10月26日)のブログでは動作するFDDはTEAC FD-235HGのみですと書きましたが、その後、報告の内容に間違いがあることに気づきました。

それは、使用したFDCがMB8877AなのでSTEP信号は正論理であるのに、FM77AV40SXのSTEP信号を観測した際に負論理だったので、STEP信号が負論理であると思い込んでしまったことです。
観測したSTEP信号はFDCの出力端子ではなくFDDへの入力端子でしたのに、完全な勘違いでした。
正しいSTEP信号

STEP信号の2倍化回路はFDCの出力直後に入れていますので、正論理のSTEP信号を処理することになります。

ATtiny85のプログラムを信号の立ち上がりで起動するように訂正し、さらに、パルス幅tとパルス間隔をFM77AV40SXのSTEP信号のパルス幅(1.5ms)とパルス間隔(4.5ms)に合わせました。
(割り込みルーチン内でタイマーによるdelay関数を使用しているのは気になるところですが、STEP信号による割り込み以外は生じないということで大丈夫だろうと判断しています。)

また、端子変換やREADY信号生成回路として、前回はK-ichi's memoさんの「MSXでPC用FDDを使う」中のPIC12F675を用いた回路を使用しましたが、FM77AV40SXで常用しているてきとーに。さんの「FM77AV20/40以降のFDD修理というか交換」中のダイオード1個による簡便な変換回路も製作し、両変換回路による違いも確認しました。


実験風景


その結果、手持ちの13台のFDDで確認した結果は以下のようになりました。
(1)両変換回路で動作
 TEAC FD-235HG (7304,7487,8386) 
 SONY MPF920                             
 YE-DATA YD-702D (6637D) 
 MITSUMI D353M3D (3110 2台)
(2)ダイオード1個の変換回路のみで動作
 MITSUMI D353M3 (2552,2553)
(3)PIC12F675の変換回路のみで動作
 MITSUMI D353M3D (4340,6250 2台)
 MITSUMI D359M3D (4372)

何故かMITSUMIのFDDは末尾にDが付いているものは3110のみが動作しましたが、他はどちらかでしか動作しませんでした。設定が異なるのかもしれませんが、MITSUMIのマニュアルが入手できていませんので原因は不明です。
この結果を見る限り、この用途で使う場合にはMITSUMIのFDDは避けた方が良いようです。

運用上の問題ですが、2DDドライブでディスクを初期化しても2Dドライブのヘッド幅の半分しか初期化できないので、2DDドライブで作成したディスクは2Dドライブでは読み書きできない2DDドライブ専用のディスクになるという問題があります。
(全てが2DDドライブのシステムで完結していれば良いのですが、2Dのシステムとの兼用を考えるとこれがネックとなります。)

この問題を解決するために、FM77AV1を入手し、ドライブ2として手持ちの5インチのYD-274(古い!)を接続し、5インチのF-BASICシステムディスクからAV1の3.5インチの2Dドライブで初期化した2Dディスクにシステムをコピーし、元ディスクとしました。
また、上記の実験で使用した2DDドライブで使用するフロッピーもまずAV1の2Dドライブで初期化したものを使用しました。