misc/060tsys/t11ramdisk.s
;----------------------------------------------------------------
;
; RAMDISKドライバ
;
;----------------------------------------------------------------
.cpu 68060
;----------------------------------------------------------------
;RAMDISKドライバの転送速度に関するメモ
; 68060は奇数番地のロングワード転送が可能だがキャッシュがミスすると非常に遅くなる
; キャッシュ可でもキャッシュが溢れるときはコピーバックよりもライトスルーの方が速い
; move16は転送前後のアドレスの下位4ビットが一致している必要がある
; move16はキャッシュモードによらず転送速度が一定
; move16の読み出しはコピーバックキャッシュのダーティデータも読み出せる
; move16の書き込みはデータキャッシュにもライトアロケートされる
; つまりコピーバック領域のアクセスにmove16を混ぜても問題は生じない
; 大量転送の所要時間
; wt,cbでキャッシュがヒットするとき
; move<movem<move16
; wt,cbでキャッシュがヒットしないとき
; move16<move<movem
; is,psのとき
; move16<movem<move
; move,movemのとき
; wt<cb<is<ps
; move16のとき
; wt=cb=is=ps
; RAMDISK領域をキャッシュ可にするのはデータキャッシュを食い潰すだけで無意味
; RAMDISK領域はキャッシュ不可にしてmove16で転送するのが望ましい
; move16が使えなければライトスルーにしてmoveで転送するのが望ましい
;
; requestHeaderは設定されていない場合があるので使わないこと
;----------------------------------------------------------------
;メディアチェック
;<a5.l:リクエストヘッダ
deviceCheck::
move.b (1,a5),d0 ;ユニット番号
bsr mediaCheck
sne.b (14,a5) ;0=正常,-1=壊れている
moveq.l #0,d0
rts
;----------------------------------------------------------------
;状態取得
;<a5.l:リクエストヘッダ
deviceSense::
move.b (1,a5),d0
bsr mediaCheck
bne 1f
; イジェクト禁止
; |
; |
; | プロテクト
; | |レディ
; | ||メディア挿入
; | |||誤挿入
; | ||||
move.b #%01000010,(13,a5)
bra 2f
1: move.b #%01000100,(13,a5)
2: moveq.l #0,d0
rts
;----------------------------------------------------------------
;メディアチェックルーチン
; RAMDISK.SYSと同じく先頭の3バイトだけチェックしている
; 本当はもっと厳密に調べたほうがよい
;<d0.b:ユニット番号
;>d0.w:ユニット番号
;>z-flag:eq=OK,ne=ERROR
;*d0
mediaCheck::
move.l a0,-(sp)
ext.w d0
movea.l ([bpbTablePointer,d0.w*4],16),a0
cmpi.w #$F9FF,(a0)+
bne @f
cmpi.b #$FF,(a0)
@@: movea.l (sp)+,a0
rts
;----------------------------------------------------------------
;壊れていて入出力できないとき
mediaError:
move.w #$5007,d0
rts
;----------------------------------------------------------------
;出力
; 出力のときはメディアチェックをしてエラーを出してはならない
; (フォーマットできなくなるので)
;<a5.l:リクエストヘッダ
deviceOutput::
movem.l d1-d2/a0-a3,-(sp)
move.l (14,a5),d0 ;バッファの先頭
;<d0.l:バッファの先頭
cmpi.b #4,$0CBC.W
blo @f
lea.l (outputMove16,pc),a0
moveq.l #$0F,d2
and.l d0,d2
beq transfer
@@: lea.l (outputMove,pc),a0
bra transfer
;----------------------------------------------------------------
;入力
;<a5.l:リクエストヘッダ
deviceInput::
move.b (1,a5),d0
bsr mediaCheck
bne mediaError ;壊れている
movem.l d1-d2/a0-a3,-(sp)
move.l (14,a5),d0 ;バッファの先頭
;<d0.l:バッファの先頭
cmpi.b #4,$0CBC.W
blo @f
lea.l (inputMove16,pc),a0
moveq.l #$0F,d2
and.l d0,d2
beq transfer
@@: lea.l (inputMove,pc),a0
; bra transfer
;----------------------------------------------------------------
;転送ルーチン
;<d0.l:バッファの先頭
;<a5.l:リクエストヘッダ
transfer:
movea.l d0,a2
;<a2.l:バッファの先頭
moveq.l #0,d0
move.b (1,a5),d0 ;ユニット番号
movea.l (bpbTablePointer,d0.l*4),a3 ;BPBテーブルのアドレス
bsr toggleAccessLamp ;アクセスランプ反転
;<a1.l:BPBテーブルのアドレス
move.l (18,a5),d0
;<d0.l:転送セクタ数
move.l d0,d1
;<d1.l:転送セクタ数
move.l (22,a5),d2
;<d2.l:先頭のセクタ番号
add.l d2,d1
;<d1.l:末尾のセクタ番号+1
cmp.l (12,a3),d1
bhi sectorError ;範囲外
lsl.l #8,d2
lsl.l #2,d2
;<d2.l:先頭のセクタまでのオフセット
movea.l (16,a3),a1 ;先頭アドレス
adda.l d2,a1
;<a1.l:先頭のセクタのアドレス
jsr (a0) ;転送
moveq.l #0,d0
transferError:
bsr toggleAccessLamp ;アクセスランプ反転
movem.l (sp)+,d1-d2/a0-a3
rts
;セクタ番号の指定がおかしい
sectorError:
move.w #$5008,d0
bra transferError
;----------------------------------------------------------------
;アクセスランプ反転
;<a3.l:BPBテーブルのアドレス
toggleAccessLamp:
tst.b (24,a3)
beq @f
bset.b #0,$00E8A01B ;TIMER-LED反転
eori.b #%00000111,$00E8A001 ;
@@: rts
;----------------------------------------------------------------
;出力(バッファアドレスの下位4bitが0)
outputMove16:
exg.l a1,a2
; bra transferMove16
;----------------------------------------------------------------
;入力(バッファアドレスの下位4bitが0)
inputMove16:
; bra transferMove16
;----------------------------------------------------------------
;入出力(バッファアドレスの下位4bitが0)
;<d0.l:転送セクタ数
;<a1.l:転送元アドレス(下位4bitが0)
;<a2.l:転送先アドレス(下位4bitが0)
transferMove16:
@@: moveq.l #4-1,d1
1: .rept 16
move16 (a1)+,(a2)+
.endm
dbra d1,1b
subq.l #1,d0
bne @b
rts
;----------------------------------------------------------------
;出力(バッファアドレスの下位4bitが0でない)
outputMove:
exg.l a1,a2
; bra transferMove
;----------------------------------------------------------------
;入力(バッファアドレスの下位4bitが0でない)
inputMove:
; bra transferMove
;----------------------------------------------------------------
;入出力(バッファアドレスの下位4bitが0でない)
;<d0.l:転送セクタ数
;<a1.l:転送元アドレス
;<a2.l:転送先アドレス
transferMove:
@@: moveq.l #16-1,d1
1: .rept 16
move.l (a1)+,(a2)+
.endm
dbra d1,1b
subq.l #1,d0
bne @b
rts