tunozemichanの日記 / tunozemichan's diary

SORD社のコンピューターM68やM68MXの解析についての備忘録です。This blog is a memorandum about the analysis of SORD's computers M68 and M68MX.

FDC(MB8877)の制御コードについて(RESTORE,SEEK,READ)

SORD M68のFDCは富士通のMB8877Aです。これはWD系と呼ばれるFDCの系統の一つで、特にMB8877は日本のマイコンに広く用いられています。

今回は、このMB8877の制御コードを具体例を書いていきます。分かりにくくなるため、エラー処理などは書きません。この辺は成書で補ってください。実際のところGOTEKやHxCなどFDDエミュレータを使う場合は、ほぼ確実に動作は成功しますので、エラー処理せずとも何とかなるケースが多いです。

基本的に、RESTORE、SEEK、READ、WRITEが出来れば、ひとまず何とかデバイスドライバの格好はつきます。

 

0. FDCコマンド発行サブルーチン

まずはFDCコマンドを発行するサブルーチンを書いておきます。


;
; FDC COMMAND OUT subroutine
;
FDCOUT:
    OUT (FDC_COMMAND_REG),A
    LD A,30H
WLOOP: DEC A
    JR NZ,WLOOP
LOOP2:
    IN A,(FDC_STATUS_REG)
    BIT 0x0,A ; BUSY IS CLEAR?
    JR NZ,LOOP2
    RET
;

 

コマンドをFDCのコマンドレジスタに入れた後、少しだけ待ちますが、SORD M68のBOOT ROMのコピーです。これは必要なディレイの様です。BUSYフラグがクリアされていれば、リターンします。

 

1.RESTORE

RESTOREはFDDのヘッドをトラック0に移動します。MB8877では、以下のようにすると良いようです。

;
; RESTORE subroutine
;
RESTORE:
RESTORE_LOOP:
    LD A,44H ;  \DDENS is HIGH. Low density mode.
    OUT (FDC_CONTROL_REG),A
    LD A,0CH ; restore command
    CALL FDCOUT
    BIT 7,A ; Not Ready?
    JR NZ,RESTORE_LOOP
    AND 98H
    JR NZ,RESTORE
    RET

 

RESTOREは、基本的にLow density(単密度/FM記録)モードで行うようです。RESTOREコマンドは0xCです。問題なく実行された場合は、00でリターンします。

 

2.SEEK

SEEKは、目標トラックにヘッドを動かす動作です。MB8877では、density(記録密度)をFDDコントロールレジスタに設定した後に、FDCデータレジスタに目標トラックを設定して、SEEKコマンド0x1Cを発行します。

 

SEEK:
    LD A,D
    OUT (FDC_CONTROL_REG),A
    LD A,E
    OUT (FDC_DATA_REG),A
    LD A,1CH ; SEEK COMMAND
    CALL FDCOUT
    AND 98H
    RET

 

成功すると0が返ってきます。

 

3. READ

READは、文字通りフロッピーディスクからデータを取り出す動作です。具体的には、現在ヘッドが置かれているトラックから、指定されたセクタのデータを読み取り、それをFDCデータレジスタに出力します。

DMAがあるマシンでは、DMAを使う方がコードは短くなります。

まずは、DMAを設定、起動するコードを書きます。

 

DMA_ON:
    PUSH HL
    PUSH BC
    LD B,(HL)
    INC HL
    LD C,DMA_ADDRESS
    OTIR
    POP BC
    POP HL
    RET

 

DMAは、コマンドチェーンというコマンドの連なりで設定するのが効率的です。SORD M68の場合は、以下のようになっています。

DMA_COMMANDS:
    DB 15H,0C3H,0C3H,0C3H,0C3H,03CH,0C3H
    DB 0BBH,01H,9BFH
    DB 6DH,0CBH,0FFH,00H,02CH,010H,08DH
    DB 80H,00H ; CP/M defaults dma address is 0080H
    DB 9AH
    DB 0CFH,87H

 

コマンドの詳細は、「試験に出るX1」を参照してください。名著です。最初の0x15はコマンドの数です。最後の二つの命令(0xCF,0x87)でDMAが起動します。

 

;
; DMA setting & FDD read FOR SIDE 0
; C is Sector No.
; D is Control word.
;
GO_DMA_AND_READ0:
    LD A,C
    OUT (FDC_SECTOR_REG),A
    LD A,D
    OUT (FDC_CONTROL_REG),A
    LD HL,DMA_COMMANDS
    CALL DMA_ON
    AND 20H
    LD A,82H ; READ DATA COMMAND for Side 0
    CALL FDCOUT
    AND 0FCH
    RET

 

セクタレジスタにセクタ番号を入れて、FDDコントロールポートには読み取りたいトラックの記録密度とサイドを入力します。SORD M68で、単密度で読むなら、0x44です。その後に、サイド0に対するFDCリードコマンド0x82を発行します。

これだけで、DMAに設定したアドレスに、設定したバイト数(今回は0xFF(256バイト))、データが転送されます。