misc/060tsys/t14mmu.s
;----------------------------------------------------------------
;
; アドレス変換に関連するルーチン群
;
;----------------------------------------------------------------
.include t02const.equ
.include t08debug.equ
;__DEBUG__ equ 1
.cpu 68060
;----------------------------------------------------------------
;アドレス変換テーブル(デスクリプタの領域)
;
; アドレス変換テーブルはメインメモリまたはローカルメモリ上に配置
; アドレス変換テーブルは$00002000(8KB)で割り切れるアドレスに置く
;
; アドレス変換テーブルはスーパーバイザ領域とする
; アドレス変換テーブルはライトプロテクトする
; アドレス変換テーブルへのアクセスはFC_MMU_DATAに対するMOVESで行う
;
; アドレス変換テーブルは次の3つのデスクリプタテーブルから成る
; ルートデスクリプタテーブル
; ポインタデスクリプタテーブル
; ページデスクリプタテーブル
;
; ルートデスクリプタテーブルは下位側に固定
; ポインタデスクリプタテーブルは下位側から上位側へ伸長(末尾を動かす)
; ページデスクリプタテーブルは上位側から下位側へ伸長(先頭を動かす)
;
; 無効なデスクリプタは必ず32ビットすべてを0にする
; デスクリプタテーブルの内容がすべて無効になったらテーブルごと開放する
;
; ページデスクリプタテーブルの後にデスクリプタの参照数カウンタのテーブルが続く
; ポインタデスクリプタ参照数カウンタテーブル
; ページデスクリプタ参照数カウンタテーブル
;
; 参照数カウンタのテーブルの内容は参照数-1
; 参照数カウンタが-1のデスクリプタテーブルは未使用であることを意味する
;
; 論理アドレスが30ビットなので、アドレスの上位2ビットの違いは無視される
; ルートデスクリプタテーブルは16個のデスクリプタのセットを8個並べたものになる
; 論理アドレスの上位2ビットが0でないルートデスクリプタは参照数カウンタに影響しない
;
; 内容 アドレスを保持している変数
; ┏━━━━━━━━━━━━━━┓descHead/rootDescHead
; ┃ ルートデスクリプタテーブル ┃
; ┗━━━━━━━━━━━━━━┛rootDescTail
; ┏━━━━━━━━━━━━━━┓pointerDescHead
; ┃ポインタデスクリプタテーブル┃
; ┠──────────────┨
; ┃ポインタデスクリプタテーブル┃
; ┠──────────────┨
; ┃ 未使用 ┃
; ┠──────────────┨
; ┃ポインタデスクリプタテーブル┃
; ┠──────────────┨
; ┃ 未使用 ┃
; ┠──────────────┨
; ┃ポインタデスクリプタテーブル┃
; ┣━━━━━━━━━━━━━━┫pointerDescTail
; ┃ ↓ ┃
; ┃ ┃
; ┃ 未使用 ┃
; ┃ ┃
; ┃ ↑ ┃
; ┣━━━━━━━━━━━━━━┫pageDescHead
; ┃ ページデスクリプタテーブル ┃
; ┠──────────────┨
; ┃ ページデスクリプタテーブル ┃
; ┠──────────────┨
; ┃ 未使用 ┃
; ┠──────────────┨
; ┃ 未使用 ┃
; ┠──────────────┨
; ┃ ページデスクリプタテーブル ┃
; ┗━━━━━━━━━━━━━━┛pageDescTail
; ┏━━━━━━━━━━━━━━┓pointerCounterHead
; ┃ 0以上 ┃
; ┠──────────────┨
; ┃ 0以上 ┃
; ┠──────────────┨
; ┃ -1 ┃
; ┠──────────────┨
; ┃ 0以上 ┃
; ┠──────────────┨
; ┃ -1 ┃
; ┠──────────────┨
; ┃ 0以上 ┃
; ┠──────────────┨
; ┃ ↓ ┃
; ┃ ┃
; ┃ 未使用 ┃
; ┃ ┃
; ┃ ↑ ┃
; ┠──────────────┨
; ┃ 0以上 ┃
; ┠──────────────┨
; ┃ 0以上 ┃
; ┠──────────────┨
; ┃ -1 ┃
; ┠──────────────┨
; ┃ -1 ┃
; ┠──────────────┨
; ┃ 0以上 ┃
; ┗━━━━━━━━━━━━━━┛pageCounterTail/descTail
;
;----------------------------------------------------------------
;----------------------------------------------------------------
;デスクリプタの無効化
;<a1.l:論理アドレス
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
;>d0.l:更新前のページデスクリプタ
; -1 デスクリプタの領域が不足している
invDesc::
movem.l d7/a0/a2,-(sp)
bsr getDesc
move.l d0,d7
bmi 8f ;デスクリプタが存在しない
beq 8f ;デスクリプタが無効
moveq.l #0,d0
moves.l d0,(a0)
;デスクリプタテーブルを検索
move.l rootDescHead,d0
bsr getRootDesc
movea.l a0,a2 ;ルートデスクリプタのアドレス
and.l #POINTER_DESC_MASK,d0 ;ポインタデスクリプタテーブルの先頭
bsr getPointerDesc
;ページデスクリプタテーブル全体が無効になったらポインタデスクリプタを無効化する
move.l a0,d0 ;ポインタデスクリプタのアドレス
bsr invUpPageDescTable
bne 8f
;ポインタデスクリプタテーブル全体が無効になったらルートデスクリプタを無効化する
move.l a2,d0 ;ルートデスクリプタのアドレス
bsr invUpPointerDescTable
8: move.l d7,d0
movem.l (sp)+,d7/a0/a2
rts
;----------------------------------------------------------------
;共有デスクリプタの設定(間接ページデスクリプタを含む)
;<d2.l:論理アドレス(ページデスクリプタが存在すること)
;<a1.l:論理アドレス
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
;>d0.l:更新前のページデスクリプタ
; -1 デスクリプタの領域が不足している
; -2 変換先のページデスクリプタが存在しない
comDesc::
movem.l d1-d2/d7/a0-a6,-(sp)
exg.l d2,a1
bsr getDesc ;変換先のページデスクリプタを求める
bmi 9f
movea.l d2,a1
move.l a0,d2 ;ページデスクリプタのアドレス
addq.l #%10,d2 ;PDT=%10(間接)
bsr setDesc ;間接ページデスクリプタを設定する
move.l d0,d7
bmi 8f
;デスクリプタテーブルを検索
move.l rootDescHead,d0
bsr getRootDesc
movea.l a0,a2 ;ルートデスクリプタのアドレス
and.l #POINTER_DESC_MASK,d0
movea.l d0,a3 ;ポインタデスクリプタテーブルの先頭
bsr getPointerDesc
movea.l a0,a4 ;ポインタデスクリプタのアドレス
and.l pageDescMask,d0
movea.l d0,a5 ;ページデスクリプタテーブルの先頭
;ページデスクリプタテーブルのすべてのページデスクリプタが、
;一様に他のページデスクリプタテーブルへの間接ページデスクリプタかどうか調べる
movea.l a5,a0
moves.l (a0)+,d0 ;先頭のページデスクリプタ
moveq.l #%11,d1
and.l d0,d1 ;PDT
subq.l #%10,d1
bne 8f ;間接でない
subq.l #%10,d0
move.l d0,d1
and.l pageDescMask,d0
cmp.l d1,d0
bne 8f ;ページデスクリプタテーブルの先頭でない
movea.l d0,a6 ;間接ページデスクリプタが指していたページデスクリプタテーブルの先頭
addq.l #%10,d1
moveq.l #PAGE_INDEX_SIZE-1-1,d2
@@: addq.l #4,d1
moves.l (a0)+,d0
cmp.l d1,d0 ;間接ページデスクリプタなのでそのまま比較できる
dbne d2,@b
bne 8f ;異なるページデスクリプタがある
;ページデスクリプタテーブルを切り離して、
;間接ページデスクリプタが指していたページデスクリプタテーブルに繋ぐ
move.l a3,d0
move.l a6,d1 ;ページデスクリプタテーブルの先頭
; U W UDT
addq.l #%0_0_11,d1
bsr setPointerDesc
;論理アドレスの上位8ビットをクリアした場合のデスクリプタテーブルを検索
move.l a1,d0
and.l #$00FFFFFF,d0
cmpa.l d0,a1
beq 8f ;$00xxxxxxなので関係ない
move.l a1,-(sp)
movea.l d0,a1 ;論理アドレス変更
move.l rootDescHead,d0
bsr getRootDesc
movea.l (sp)+,a1
bmi 8f ;ないはずはないが念のため
movea.l a0,a4 ;ルートデスクリプタのアドレス
and.l #POINTER_DESC_MASK,d0
movea.l d0,a5 ;ポインタデスクリプタテーブルの先頭
cmpa.l a3,a5
beq 8f ;同じポインタデスクリプタテーブルなので関係ない
;ポインタデスクリプタテーブルのすべてのポインタデスクリプタが、
;論理アドレスの上位8ビットをクリアした場合のポインタデスクリプタテーブルと、
;一致しているか調べる
move.l a1,-(sp)
movea.l a3,a0 ;ポインタデスクリプタテーブルの先頭
movea.l a5,a1 ;論理アドレスの上位8ビットをクリアした場合の
;ポインタデスクリプタテーブルの先頭
bsr cmpPointerDescTable
movea.l (sp)+,a1
bne 8f ;一致しない
;ポインタデスクリプタテーブルを切り離して、
;論理アドレスの上位8ビットをクリアした場合のポインタデスクリプタテーブルに繋ぐ
move.l rootDescHead,d0
moves.l (a4),d1 ;ルートデスクリプタ
bsr setRootDesc
8: move.l d7,d0
movem.l (sp)+,d1-d2/d7/a0-a6
rts
9: moveq.l #-2,d7
bra 8b
;----------------------------------------------------------------
;ページデスクリプタの設定
; このプログラム自身や割り込みルーチンで使用中の領域は指定しないこと
;<d2.l:ページデスクリプタ
;<a1.l:論理アドレス
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
;>d0.l:更新前のページデスクリプタ
; -1 デスクリプタの領域が不足している
setDesc::
movem.l d1-d2/d7/a0/a2-a5,-(sp)
moveq.l #0,d7 ;更新前のページデスクリプタ
;PDT=%00ならば全体を0にする
moveq.l #%11,d0
and.l d2,d0 ;PDT
bne @f
moveq.l #0,d2 ;PDT=%00ならば全体を0にする
@@:
;$00000000~$00FFFFFFのページデスクリプタは無効や間接にできない
cmpa.l #$01000000,a1
bhs @f
btst.l #0,d2
beq 9f ;PDT=%00(無効),%10(間接)
@@:
;デスクリプタテーブルを辿る
move.l rootDescHead,d0
beq 9f ;ルートデスクリプタテーブルがない
;ルートデスクリプタテーブルが存在する
bsr getRootDesc
movea.l a0,a2 ;ルートデスクリプタのアドレス
beq 1f ;ルートデスクリプタが無効(ポインタデスクリプタテーブルがない)
;ポインタデスクリプタテーブルが存在する
and.l #POINTER_DESC_MASK,d0
movea.l d0,a3 ;ポインタデスクリプタテーブルの先頭
bsr getPointerDesc
movea.l a0,a4 ;ポインタデスクリプタのアドレス
beq 2f ;ポインタデスクリプタが無効(ページデスクリプタテーブルがない)
;ページデスクリプタテーブルが存在する
and.l pageDescMask,d0
movea.l d0,a5 ;ページデスクリプタテーブルの先頭
bsr getPageDesc
move.l d0,d7 ;更新前のページデスクリプタ
beq 3f ;ページデスクリプタが無効
;ページデスクリプタが有効
;キャッシュフラッシュ
and.l pageMask,d0 ;物理ページアドレス
movea.l d0,a2 ;物理ページアドレス
cpushp dc,(a2) ;データキャッシュプッシュ
cinvp bc,(a2) ;キャッシュ無効化
;ページデスクリプタの参照数をチェック
3: move.l a5,d0 ;ページデスクリプタテーブルの先頭
bsr getPageDescCount ;参照数カウンタを調べる
beq 4f ;1箇所だけから参照されている
;ページデスクリプタテーブルが2箇所以上から参照されているので新しく作る
movea.l a5,a0 ;ページデスクリプタテーブルの先頭
bsr dupPageDescTable ;ページデスクリプタテーブルを複製する
bra 6f
;ポインタデスクリプタが無効(ページデスクリプタテーブルがない)
2: bsr callocPageDescTable ;ページデスクリプタテーブルを作る
6: bmi 9f ;デスクリプタの領域が不足している
movea.l d0,a5 ;ページデスクリプタテーブルの先頭
;ポインタデスクリプタの参照数をチェック
move.l a3,d0 ;ポインタデスクリプタテーブルの先頭
bsr getPointerDescCount
beq 5f ;1箇所だけから参照されている
;ポインタデスクリプタテーブルが2箇所以上から参照されているので新しく作る
movea.l a3,a0 ;ポインタデスクリプタテーブルの先頭
bsr dupPointerDescTable ;ポインタデスクリプタテーブルを複製する
bra 7f
;ルートデスクリプタが無効(ポインタデスクリプタテーブルがない)
1: bsr callocPageDescTable ;ページデスクリプタテーブルを作る
bmi 9f ;デスクリプタの領域が不足している
movea.l d0,a5 ;ページデスクリプタテーブルの先頭
bsr callocPointerDescTable ;ポインタデスクリプタテーブルを作る
7: bmi 9f ;デスクリプタの領域が不足している
movea.l d0,a3 ;ポインタデスクリプタテーブルの先頭
bsr getPointerDesc
movea.l a0,a4 ;ポインタデスクリプタのアドレス
;ルートデスクリプタを更新する
move.l rootDescHead,d0 ;ルートデスクリプタテーブルの先頭
move.l a3,d1 ;ポインタデスクリプタテーブルの先頭
; U W UDT
addq.l #%0_0_11,d1 ;UDT=%11(有効)
bsr setRootDesc ;ルートデスクリプタを更新
;ポインタデスクリプタが1箇所だけから参照されているので直接更新する
5: move.l a3,d0 ;ポインタデスクリプタテーブルの先頭
move.l a5,d1 ;ページデスクリプタテーブルの先頭
; U W UDT
addq.l #%0_0_11,d1 ;UDT=%11(有効)
bsr setPointerDesc ;ポインタデスクリプタを更新
;ページデスクリプタテーブルが1箇所だけから参照されているので直接更新する
;間接ページデスクリプタによる参照があった場合はそれも更新されることになる
4: move.l a5,d0 ;ページデスクリプタテーブルの先頭
move.l d2,d1 ;ページデスクリプタ
bsr setPageDesc ;ページデスクリプタを更新
;後始末
8: bsr cleanPointerDesc
bsr cleanPageDesc
;更新前のページデスクリプタを返す
move.l d7,d0
movem.l (sp)+,d1-d2/d7/a0/a2-a5
rts
9: moveq.l #-1,d7
bra 8b
;----------------------------------------------------------------
;論理アドレスからページデスクリプタを求める
;<a1.l:論理アドレス
;<sfc.l:FC_MMU_DATA
;>d0.l:ページデスクリプタ
; -1 ページデスクリプタがない
; 0 ページデスクリプタが無効
;>a0.l:ページデスクリプタのアドレス(間接ページデスクリプタのとき(a0)≠d0)
; 0 ページデスクリプタがない
;>n-flag:mi=ページデスクリプタがない,pl=ページデスクリプタがある
;>z-flag:(pl)ne=ページデスクリプタが有効,eq=ページデスクリプタが無効
getDesc::
move.l rootDescHead,d0
beq 9f ;ルートデスクリプタテーブルがない
bsr getRootDesc ;ルートデスクリプタを得る
beq 9f ;ルートデスクリプタが無効
;<d0.l:ルートデスクリプタ
;<a0.l:ルートデスクリプタのアドレス
and.l #POINTER_DESC_MASK,d0
;<d0.l:ポインタデスクリプタテーブルの先頭
bsr getPointerDesc ;ポインタデスクリプタを得る
beq 9f ;ポインタデスクリプタが無効
;<d0.l:ポインタデスクリプタ
;<a0.l:ポインタデスクリプタのアドレス
and.l pageDescMask,d0
;<d0.l:ページデスクリプタテーブルの先頭
bsr getPageDesc ;ページデスクリプタを得る
;<d0.l:ページデスクリプタ
;<a0.l:ページデスクリプタのアドレス(間接ページデスクリプタのとき(a0)≠d0)
;<n-flag:pl
;<z-flag:ne=ページデスクリプタが有効,eq=ページデスクリプタが無効
rts
9: moveq.l #-1,d0
suba.l a0,a0
;<d0.l:-1
;<a0.l:0
;<n-flag:mi
rts
;----------------------------------------------------------------
;
; ルートデスクリプタの操作
;
;----------------------------------------------------------------
;----------------------------------------------------------------
;ルートデスクリプタをコピーする
;<d0.l:コピー元の論理アドレス
;<a1.l:コピー先の論理アドレス
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
;>d0.l:変更前のルートデスクリプタ
; -1 エラー
copyRootDesc::
movem.l d1/a0-a1,-(sp)
move.l a1,d1 ;コピー先の論理アドレス
movea.l d0,a1 ;コピー元の論理アドレス
move.l rootDescHead,d0
beq 9f
bsr getRootDesc ;コピー元のルートデスクリプタを求める
movea.l d1,a1 ;コピー先の論理アドレス
move.l d0,d1 ;コピー元のルートデスクリプタ
move.l rootDescHead,d0
bsr setRootDesc ;ルートデスクリプタを変更する
8: movem.l (sp)+,d1/a0-a1
rts
9: moveq.l #-1,d0
bra 8b
;----------------------------------------------------------------
;ルートデスクリプタを更新する
;<d0.l:ルートデスクリプタテーブルの先頭
;<d1.l:ルートデスクリプタ
;<a1.l:論理アドレス
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
;>d0.l:更新前のルートデスクリプタ
; 0 ルートデスクリプタが無効
;>n-flag:pl
;>z-flag:ne=ルートデスクリプタが有効,eq=ルートデスクリプタが無効
setRootDesc::
movem.l d2/d7/a0/a2,-(sp)
bsr getRootDesc ;ルートデスクリプタを求める
move.l d0,d7
;新しいポインタデスクリプタテーブルのカウンタを1増やす
;減らす方を先に行うと、減らした段階でデスクリプタテーブルが開放されてしまって
;増やせなくなく可能性があるので、増やす方を先に行う
move.l d1,d0
beq 1f
and.l #POINTER_DESC_MASK,d0
bsr incPointerDescCount
1:
;元のポインタデスクリプタテーブルのカウンタを1減らす
move.l d7,d0
beq 2f
and.l #POINTER_DESC_MASK,d0
bsr decPointerDescCount
2:
;ルートデスクリプタを更新する
movea.l a0,a2
moveq.l #(1<<(32-LOGICAL_WIDTH))-1,d2
@@: moves.l d1,(a2) ;ルートデスクリプタを更新する
lea.l (4<<(LOGICAL_WIDTH-25),a2),a2
dbra d2,@b
move.l d7,d0
movem.l (sp)+,d2/d7/a0/a2
rts
;----------------------------------------------------------------
;ルートデスクリプタを取得する
;<d0.l:ルートデスクリプタテーブルの先頭
;<a1.l:論理アドレス
; 無効なビットは無視される
;<sfc.l:FC_MMU_DATA
;>d0.l:ルートデスクリプタ
; 0 ルートデスクリプタが無効
;>a0.l:ルートデスクリプタのアドレス
;>n-flag:pl
;>z-flag:ne=ルートデスクリプタが有効,eq=ルートデスクリプタが無効
getRootDesc::
movea.l d0,a0 ;ルートデスクリプタテーブルの先頭
move.l a1,d0 ;論理アドレス
bfextu d0{32-LOGICAL_WIDTH:LOGICAL_WIDTH-25},d0 ;ルートインデックスフィールド
; 無効なビットを無視する
lea.l (a0,d0.l*4),a0 ;ルートデスクリプタのアドレス
moves.l (a0),d0 ;ルートデスクリプタ
btst.l #1,d0
bne 8f ;UDT=%10,%11(有効)
moveq.l #0,d0
8: tst.l d0
rts
;----------------------------------------------------------------
;
; ポインタデスクリプタの操作
;
;----------------------------------------------------------------
;----------------------------------------------------------------
;ポインタデスクリプタをコピーする
;<d0.l:コピー元の論理アドレス
;<a1.l:コピー先の論理アドレス
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
;>d0.l:変更前のポインタデスクリプタ
; -1 エラー
copyPointerDesc::
movem.l d1/a0-a1,-(sp)
move.l a1,d1 ;コピー先の論理アドレス
movea.l d0,a1 ;コピー元の論理アドレス
move.l rootDescHead,d0
beq 9f
bsr getRootDesc ;コピー元のルートデスクリプタを求める
beq 9f
and.l #POINTER_DESC_MASK,d0
bsr getPointerDesc ;コピー元のポインタデスクリプタを求める
movea.l d1,a1 ;コピー先の論理アドレス
move.l d0,d1 ;コピー元のポインタデスクリプタ
move.l rootDescHead,d0
bsr getRootDesc ;コピー先のルートデスクリプタを求める
beq 9f
and.l #POINTER_DESC_MASK,d0
bsr setPointerDesc ;ルートデスクリプタを変更する
8: movem.l (sp)+,d1/a0-a1
rts
9: moveq.l #-1,d0
bra 8b
;----------------------------------------------------------------
;ポインタデスクリプタを更新する
;<d0.l:ポインタデスクリプタテーブルの先頭
;<d1.l:ポインタデスクリプタ
;<a1.l:論理アドレス
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
;>d0.l:ポインタデスクリプタ
; 0 ポインタデスクリプタが無効
;>n-flag:pl
;>z-flag:ne=ポインタデスクリプタが有効,eq=ポインタデスクリプタが無効
setPointerDesc::
movem.l d3/d7/a0,-(sp)
move.l d0,d3
bsr getPointerDescCount
exg.l d0,d3
addq.l #1,d3 ;参照数
bsr getPointerDesc
move.l d0,d7
;新しいページデスクリプタテーブルのカウンタを増やす
;減らす方を先に行うと、減らした段階でデスクリプタテーブルが開放されてしまって
;増やせなくなく可能性があるので、増やす方を先に行う
move.l d1,d0
beq 1f
and.l pageDescMask,d0
bsr addPageDescCount
1:
;元のページデスクリプタテーブルのカウンタを減らす
move.l d7,d0
beq 1f
and.l pageDescMask,d0
bsr subPageDescCount
1:
;ポインタデスクリプタを更新する
moves.l d1,(a0)
move.l d7,d0
movem.l (sp)+,d3/d7/a0
rts
;----------------------------------------------------------------
;ポインタデスクリプタを取得する
;<d0.l:ポインタデスクリプタテーブルの先頭
;<a1.l:論理アドレス
;<sfc.l:FC_MMU_DATA
;>d0.l:ポインタデスクリプタ
; 0 ポインタデスクリプタが無効
;>a0.l:ポインタデスクリプタのアドレス
;>n-flag:pl
;>z-flag:ne=ポインタデスクリプタが有効,eq=ポインタデスクリプタが無効
getPointerDesc::
movea.l d0,a0 ;ポインタデスクリプタテーブルの先頭
move.l a1,d0 ;論理アドレス
bfextu d0{7:7},d0 ;ポインタインデックスフィールド
lea.l (a0,d0.l*4),a0 ;ポインタデスクリプタのアドレス
moves.l (a0),d0 ;ポインタデスクリプタ
btst.l #1,d0
bne 8f ;UDT=%10,%11(有効)
moveq.l #0,d0
8: tst.l d0
rts
;----------------------------------------------------------------
;ポインタデスクリプタテーブルを1つ確保して0クリアする
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
;>d0.l:ポインタデスクリプタテーブルのアドレス(0クリアされている)
; -1 デスクリプタの領域が不足している
;>n-flag:pl=正常終了,mi=デスクリプタの領域が不足している
callocPointerDescTable::
bsr allocPointerDescTable
bmi 9f
bsr clearPointerDescTable
tst.l d0
9: rts
;----------------------------------------------------------------
;ポインタデスクリプタテーブルを1つ複製する
;<a0.l:複製するポインタデスクリプタテーブルのアドレス
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
;>d0.l:複製されたポインタデスクリプタテーブルのアドレス
; -1 デスクリプタの領域が不足している
;>n-flag:pl=正常終了,mi=デスクリプタの領域が不足している
dupPointerDescTable::
bsr allocPointerDescTable
bmi 9f
bsr copyPointerDescTable
tst.l d0
9: rts
;----------------------------------------------------------------
;ポインタデスクリプタテーブルを1つ確保する
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
;>d0.l:ポインタデスクリプタテーブルのアドレス
; -1 デスクリプタの領域が不足している
;>n-flag:pl=正常終了,mi=デスクリプタの領域が不足している
allocPointerDescTable::
movem.l a0-a1,-(sp)
movea.l pointerCounterHead,a0
movea.l pointerDescHead,a1
bra 2f
1: moves.l (a0),d0 ;参照数-1
tst.l d0
bmi 3f ;途中に未使用の領域があった
addq.l #4,a0
lea.l (POINTER_DESC_SIZE,a1),a1
2: cmpa.l pointerDescTail,a1
bne 1b
;途中には未使用の領域がなかった
lea.l (POINTER_DESC_SIZE,a1),a1 ;ポインタデスクリプタテーブルの領域を伸ばしてみる
cmpa.l pageDescHead,a1
bhi 9f ;デスクリプタテーブルの領域が不足している
move.l a1,pointerDescTail ;ポインタデスクリプタテーブルの領域を伸ばす
lea.l (-POINTER_DESC_SIZE,a1),a1
;途中に未使用の領域があった
3: moveq.l #-1,d0
moves.l d0,(a0) ;参照数に0を設定
move.l a1,d0
8: movem.l (sp)+,a0-a1
rts
;デスクリプタテーブルの領域が不足している
9: moveq.l #-1,d0
bra 8b
;----------------------------------------------------------------
;ポインタデスクリプタテーブルがすべて無効ならばルートデスクリプタを無効にする
;<d0.l:ルートデスクリプタのアドレス
;>z-flag:eq=デスクリプタを無効にした,ne=デスクリプタを無効にしなかった
invUpPointerDescTable::
movem.l d0-d1/a0-a2,-(sp)
movea.l d0,a2 ;ルートデスクリプタのアドレス
moves.l (a2),d1 ;ルートデスクリプタ
and.l #POINTER_DESC_MASK,d1 ;ポインタデスクリプタテーブルのアドレス
movea.l d1,a0
lea.l (POINTER_DESC_SIZE,a0.l),a1
1: moves.l (a0)+,d0 ;ポインタデスクリプタ
tst.l d0
bne 9f
cmpa.l a1,a0
blo 1b
moveq.l #0,d0
moves.l d0,(a2) ;ルートデスクリプタを無効化する
move.l d1,d0
bsr freePointerDescTable ;ポインタデスクリプタテーブルを削除する
moveq.l #0,d0
9: movem.l (sp)+,d0-d1/a0-a2
rts
;----------------------------------------------------------------
;ポインタデスクリプタテーブルの参照数カウンタを1増やす
; 含まれるページデスクリプタテーブルの参照数カウンタもすべて1ずつ増やす
;<d0.l:ポインタデスクリプタテーブルの先頭
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
incPointerDescCount::
movem.l d0/a0-a2,-(sp)
and.l #POINTER_DESC_MASK,d0
movea.l d0,a1 ;ポインタデスクリプタテーブルの先頭
bsr getPointerDescCount
;現在の参照数が0でも処理すること
;ポインタデスクリプタテーブルの参照数を1増やす
addq.l #1,d0
moves.l d0,(a0) ;ポインタデスクリプタテーブルの参照数を1増やす
;含まれるページデスクリプタテーブルの参照数も1ずつ増やす
lea.l (POINTER_DESC_SIZE,a1),a2
1: moves.l (a1)+,d0 ;ポインタデスクリプタ
btst.l #1,d0
beq 2f ;UDT=%00,%01(無効)
bsr incPageDescCount ;ページデスクリプタテーブルの参照数を1増やす
2: cmpa.l a2,a1
blo 1b
movem.l (sp)+,d0/a0-a2
rts
;----------------------------------------------------------------
;ポインタデスクリプタテーブルの参照数カウンタを1減らす
; 含まれるページデスクリプタテーブルの参照数カウンタもすべて1ずつ減らす
;<d0.l:ポインタデスクリプタテーブルの先頭
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
decPointerDescCount::
movem.l d0/a0-a2,-(sp)
and.l #POINTER_DESC_MASK,d0
movea.l d0,a1 ;ポインタデスクリプタテーブルの先頭
bsr getPointerDescCount
bmi 8f
beq 3f ;ポインタデスクリプタテーブルがなくなるとき
;ページデスクリプタテーブルの参照数を減らしすぎないようにする
;含まれるページデスクリプタテーブルの参照数を1ずつ減らす
lea.l (POINTER_DESC_SIZE,a1),a2
1: moves.l (a1)+,d0 ;ポインタデスクリプタ
btst.l #1,d0
beq 2f ;UDT=%00,%01(無効)
bsr decPageDescCount ;ページデスクリプタテーブルの参照数を1減らす
2: cmpa.l a2,a1
blo 1b
;ポインタデスクリプタテーブルの参照数を1減らす
moves.l (a0),d0
3: subq.l #1,d0
moves.l d0,(a0) ;ポインタデスクリプタテーブルの参照数を1減らす
bcc 8f
bsr freePointerDescTable ;どこからも参照されないので開放する
8: movem.l (sp)+,d0/a0-a2
rts
;----------------------------------------------------------------
;ポインタデスクリプタテーブルを1つ開放する
;<d0.l:ポインタデスクリプタテーブルのアドレス
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
freePointerDescTable::
movem.l d0/d3/a0-a2,-(sp)
and.l #POINTER_DESC_MASK,d0
movea.l d0,a1 ;ポインタデスクリプタテーブルのアドレス
bsr getPointerDescCount
bmi 9f
move.l d0,d3 ;ポインタデスクリプタテーブルの参照数-1
addq.l #1,d3 ;参照数
;ポインタデスクリプタテーブルの参照数を0にする
moveq.l #-1,d0
moves.l d0,(a0) ;参照数を0にする
;含まれるポインタデスクリプタが無効でなければページデスクリプタテーブルの参照数を減らす
lea.l (POINTER_DESC_SIZE,a1),a2
1: moves.l (a1)+,d0
tst.l d0
bne 2f
bsr subPageDescCount
2: cmpa.l a2,a1
blo 1b
9: bsr cleanPointerDesc
movem.l (sp)+,d0/d3/a0-a2
rts
;----------------------------------------------------------------
;作りかけのポインタデスクリプタテーブルがあれば開放する
;<sfc.l:FC_MMU_DATA
cleanPointerDesc::
movem.l d0/a0-a1,-(sp)
move.l pointerDescTail,d0
cmp.l pointerDescHead,d0
beq 9f ;ポインタデスクリプタテーブルがない
sub.l #POINTER_DESC_SIZE,d0 ;末尾のポインタデスクリプタテーブル
movea.l d0,a1 ;末尾のポインタデスクリプタテーブル
bsr getPointerDescCount
bpl 9f ;作りかけのポインタデスクリプタテーブルはない
1: cmpa.l pointerDescHead,a1
beq 8f ;全部作りかけだった?
lea.l (-POINTER_DESC_SIZE,a1),a1 ;1つ手前へ
moves.l -(a0),d0 ;参照数
tst.l d0
bmi 1b
8: move.l a1,pointerDescTail
9: movem.l (sp)+,d0/a0-a1
rts
;----------------------------------------------------------------
;ポインタデスクリプタテーブルを1つ0クリアする
;<d0.l:ポインタデスクリプタテーブルのアドレス
;<dfc.l:FC_MMU_DATA
clearPointerDescTable::
movem.l d0/a1-a2,-(sp)
movea.l d0,a1
lea.l (POINTER_DESC_SIZE,a1),a2
moveq.l #0,d0
@@: moves.l d0,(a1)+
cmpa.l a2,a1
blo @b
movem.l (sp)+,d0/a1-a2
rts
;----------------------------------------------------------------
;ポインタデスクリプタテーブルを1つコピーする
;<d0.l:コピー先のポインタデスクリプタテーブルのアドレス
;<a0.l:コピー元のポインタデスクリプタテーブルのアドレス
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
copyPointerDescTable::
movem.l d0/a0-a2,-(sp)
movea.l d0,a1
lea.l (POINTER_DESC_SIZE,a1),a2
@@: moves.l (a0)+,d0
moves.l d0,(a1)+
cmpa.l a2,a1
blo @b
movem.l (sp)+,d0/a0-a2
rts
;----------------------------------------------------------------
;ポインタデスクリプタテーブルを比較する
;<d0.l:ポインタデスクリプタテーブルのアドレス
;<a0.l:ポインタデスクリプタテーブルのアドレス
;<sfc.l:FC_MMU_DATA
;>z-flag:eq=一致,ne=不一致
cmpPointerDescTable::
movem.l d0-d1/a0-a2,-(sp)
movea.l d0,a1
lea.l (POINTER_DESC_SIZE,a1),a2
1: moves.l (a0)+,d0
moves.l (a1)+,d1
; U W UDT
and.w #%1111111_11111_0_1_11,d0
and.w #%1111111_11111_0_1_11,d1
cmp.l d1,d0
bne 2f
cmpa.l a2,a1
blo 1b
moveq.l #0,d0
2: movem.l (sp)+,d0-d1/a0-a2
rts
;----------------------------------------------------------------
;ポインタデスクリプタテーブルの参照数カウンタを求める
;<d0.l:ポインタデスクリプタテーブルの先頭
;<sfc.l:FC_MMU_DATA
;>d0.l:参照数カウンタ
; -1 どこからも参照されていない
; 0 1箇所だけから参照されている
;>a0.l:参照数カウンタのアドレス
;>n-flag:mi=どこからも参照されていない(未使用),pl=参照されている(使用中)
;>z-flag:(pl)eq=1箇所だけから参照されている,ne=2箇所以上から参照されている
getPointerDescCount::
and.l #POINTER_DESC_MASK,d0
sub.l pointerDescHead,d0
asr.l #7,d0
lea.l ([pointerCounterHead],d0.l),a0
moves.l (a0),d0
tst.l d0
bpl @f
moveq.l #-1,d0
@@: rts
;----------------------------------------------------------------
;
; ページデスクリプタの操作
;
;----------------------------------------------------------------
;----------------------------------------------------------------
;ページデスクリプタを更新する
;<d0.l:ページデスクリプタテーブルの先頭
;<d1.l:ページデスクリプタ
;<a1.l:論理アドレス
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
;>d0.l:更新前のページデスクリプタ
; 0 ページデスクリプタが無効
;>z-flag:ne=ページデスクリプタが有効,eq=ページデスクリプタが無効
;>n-flag:pl
setPageDesc::
move.l a0,-(sp)
bsr getPageDesc
moves.l d1,(a0)
movea.l (sp)+,a0
rts
;----------------------------------------------------------------
;ページデスクリプタを取得する
;<d0.l:ページデスクリプタテーブルの先頭
;<a1.l:論理アドレス
;<sfc.l:FC_MMU_DATA
;>d0.l:ページデスクリプタ
; 0 ページデスクリプタが無効
;>a0.l:ページデスクリプタのアドレス(間接ページデスクリプタのとき(a0)≠d0)
;>z-flag:ne=ページデスクリプタが有効,eq=ページデスクリプタが無効
;>n-flag:pl
getPageDesc::
move.l d1,-(sp)
movea.l d0,a0
move.l a1,d0 ;論理アドレス
move.l pageIndexWidth,d1 ;ページインデックスフィールドのビット数(5~6)
bfextu d0{14:d1},d0 ;ページインデックスフィールド
lea.l (a0,d0.l*4),a0 ;ページデスクリプタのアドレス
moves.l (a0),d0 ;ページデスクリプタ
moveq.l #%11,d1
and.l d0,d1 ;PDT
beq 9f ;PDT=%00(無効)
subq.l #%10,d1
bne 8f ;PDT=%01,%11(有効)
moves.l (-2,za0,d0.l),d0 ;ページデスクリプタ
btst.l #0,d0
bne 8f ;PDT=%01,%11(有効)
9: moveq.l #0,d0
8: move.l (sp)+,d1
tst.l d0
rts
;----------------------------------------------------------------
;ページデスクリプタテーブルを1つ確保して0クリアする
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
;>d0.l:ページデスクリプタテーブルのアドレス(0クリアされている)
; -1 デスクリプタの領域が不足している
;>n-flag:pl=正常終了,mi=デスクリプタの領域が不足している
callocPageDescTable::
bsr allocPageDescTable
bmi 9f
bsr clearPageDescTable
tst.l d0
9: rts
;----------------------------------------------------------------
;ページデスクリプタテーブルを1つ複製する
;<a0.l:複製するページデスクリプタテーブルのアドレス
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
;>d0.l:複製されたページデスクリプタテーブルのアドレス
; -1 デスクリプタの領域が不足している
;>n-flag:pl=正常終了,mi=デスクリプタの領域が不足している
dupPageDescTable::
bsr allocPageDescTable
bmi 9f
bsr copyPageDescTable
tst.l d0
9: rts
;----------------------------------------------------------------
;ページデスクリプタテーブルを1つ確保する
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
;>d0.l:ページデスクリプタテーブルのアドレス
; -1 デスクリプタの領域が不足している
;>n-flag:pl=正常終了,mi=デスクリプタの領域が不足している
allocPageDescTable::
movem.l a0-a1,-(sp)
movea.l pageCounterTail,a0
movea.l pageDescTail,a1
bra 2f
1: suba.l pageDescSize,a1
moves.l -(a0),d0 ;参照数-1
tst.l d0
bmi 3f ;途中に未使用の領域があった
2: cmpa.l pageDescHead,a1
bne 1b
;途中には未使用の領域がなかった
suba.l pageDescSize,a1 ;ページデスクリプタテーブルの領域を伸ばしてみる
cmpa.l pointerDescTail,a1
blo 9f ;デスクリプタテーブルの領域が不足している
move.l a1,pageDescHead ;ページデスクリプタテーブルの領域を伸ばす
subq.l #4,a0
;途中に未使用の領域があった
3: moveq.l #-1,d0
moves.l d0,(a0) ;参照数に0を設定
move.l a1,d0
8: movem.l (sp)+,a0-a1
rts
;デスクリプタテーブルの領域が不足している
9: moveq.l #-1,d0
bra 8b
;----------------------------------------------------------------
;ページデスクリプタテーブルがすべて無効ならばデスクリプタを無効にする
;<d0.l:ポインタデスクリプタのアドレス
;>z-flag:eq=デスクリプタを無効にした,ne=デスクリプタを無効にしなかった
invUpPageDescTable::
movem.l d0-d1/a0-a2,-(sp)
movea.l d0,a2 ;ポインタデスクリプタのアドレス
moves.l (a2),d1 ;ポインタデスクリプタ
and.l pageDescMask,d1 ;ページデスクリプタテーブルのアドレス
movea.l d1,a0
lea.l ([pageDescSize],a0.l),a1
1: moves.l (a0)+,d0 ;ページデスクリプタ
tst.l d0
bne 9f
cmpa.l a1,a0
blo 1b
moveq.l #0,d0
moves.l d0,(a2) ;ポインタデスクリプタを無効化する
move.l d1,d0
bsr freePageDescTable ;ページデスクリプタテーブルを削除する
moveq.l #0,d0
9: movem.l (sp)+,d0-d1/a0-a2
rts
;----------------------------------------------------------------
;ページデスクリプタテーブルの参照数を1増やす
;<d0.l:ページデスクリプタテーブルの先頭
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
incPageDescCount::
move.l d3,-(sp)
moveq.l #1,d3
bsr addPageDescCount
move.l (sp)+,d3
rts
;----------------------------------------------------------------
;ページデスクリプタテーブルの参照数を増やす
;<d0.l:ページデスクリプタテーブルの先頭
;<d3.l:増やす数
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
addPageDescCount::
movem.l d0/a0,-(sp)
bsr getPageDescCount
;現在の参照数が0でも処理すること
add.l d3,d0
moves.l d0,(a0) ;ページデスクリプタテーブルの参照数を増やす
movem.l (sp)+,d0/a0
rts
;----------------------------------------------------------------
;ページデスクリプタテーブルの参照数を1減らす
;<d0.l:ページデスクリプタテーブルの先頭
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
decPageDescCount::
move.l d3,-(sp)
moveq.l #1,d3
bsr subPageDescCount
move.l (sp)+,d3
rts
;----------------------------------------------------------------
;ページデスクリプタテーブルの参照数を減らす
;<d0.l:ページデスクリプタテーブルの先頭
;<d3.l:減らす数
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
subPageDescCount::
movem.l d0/a0,-(sp)
bsr getPageDescCount
bmi 8f
sub.l d3,d0
moves.l d0,(a0)
bcc 8f
bsr freePageDescTable ;どこからも参照されないので開放する
8: movem.l (sp)+,d0/a0
rts
;----------------------------------------------------------------
;ページデスクリプタテーブルを1つ開放する
;<d0.l:ページデスクリプタテーブルのアドレス
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
freePageDescTable::
movem.l d0/a0,-(sp)
and.l pageDescMask,d0
bsr getPageDescCount
bmi 9f
moveq.l #-1,d0
moves.l d0,(a0) ;参照数を0にする
9: bsr cleanPageDesc
movem.l (sp)+,d0/a0
rts
;----------------------------------------------------------------
;作りかけのページデスクリプタテーブルがあれば開放する
;<sfc.l:FC_MMU_DATA
cleanPageDesc::
movem.l d0/a0-a1,-(sp)
move.l pageDescHead,d0
cmp.l pageDescTail,d0
beq 9f ;ページデスクリプタテーブルがない
movea.l d0,a1 ;先頭のページデスクリプタテーブル
bsr getPageDescCount
bpl 9f ;作りかけのページデスクリプタテーブルはない
1: lea.l ([pageDescSize],a1.l),a1 ;1つ後ろへ
addq.l #4,a0
cmpa.l pageDescTail,a1
beq 8f ;全部作りかけだった?
moves.l (a0),d0 ;参照数
tst.l d0
bmi 1b
8: move.l a1,pageDescHead
9: movem.l (sp)+,d0/a0-a1
rts
;----------------------------------------------------------------
;ページデスクリプタテーブルを1つ0クリアする
;<d0.l:ページデスクリプタテーブルのアドレス
;<dfc.l:FC_MMU_DATA
clearPageDescTable::
movem.l d0/a1-a2,-(sp)
movea.l d0,a1
lea.l ([pageDescSize],a1.l),a2
moveq.l #0,d0
@@: moves.l d0,(a1)+
cmpa.l a2,a1
blo @b
movem.l (sp)+,d0/a1-a2
rts
;----------------------------------------------------------------
;ページデスクリプタテーブルを1つコピーする
;<d0.l:コピー先のページデスクリプタテーブルのアドレス
;<a0.l:コピー元のページデスクリプタテーブルのアドレス
;<dfc.l:FC_MMU_DATA
;<sfc.l:FC_MMU_DATA
copyPageDescTable::
movem.l d0/a0-a2,-(sp)
movea.l d0,a1
lea.l ([pageDescSize],a1.l),a2
@@: moves.l (a0)+,d0
moves.l d0,(a1)+
cmpa.l a2,a1
blo @b
movem.l (sp)+,d0/a0-a2
rts
;----------------------------------------------------------------
;ページデスクリプタテーブルを比較する
;<d0.l:ページデスクリプタテーブルのアドレス
;<a0.l:ページデスクリプタテーブルのアドレス
;<sfc.l:FC_MMU_DATA
;>z-flag:eq=一致,ne=不一致
cmpPageDescTable::
movem.l d0-d1/a0-a2,-(sp)
movea.l d0,a1
lea.l ([pageDescSize],a1.l),a2
1: moves.l (a0)+,d0
moves.l (a1)+,d1
; UR G U1U0 S CM M U W PDT
and.w #%111_11_1__11__1_11_0_0_1_11,d0
and.w #%111_11_1__11__1_11_0_0_1_11,d1
cmp.l d1,d0
bne 2f
cmpa.l a2,a1
blo 1b
moveq.l #0,d0
2: movem.l (sp)+,d0-d1/a0-a2
rts
;----------------------------------------------------------------
;ページデスクリプタテーブルの参照数カウンタを求める
;<d0.l:ページデスクリプタテーブルの先頭
;<sfc.l:FC_MMU_DATA
;>d0.l:参照数カウンタ
; -1 どこからも参照されていない
; 0 1箇所だけから参照されている
;>a0.l:参照数カウンタのアドレス
;>n-flag:mi=どこからも参照されていない(未使用),pl=参照されている(使用中)
;>z-flag:(pl)eq=1箇所だけから参照されている,ne=2箇所以上から参照されている
getPageDescCount::
and.l pageDescMask,d0
sub.l pageDescTail,d0
move.l d1,-(sp)
move.l pageIndexWidth,d1
asr.l d1,d0 ;d0は負数なのでlsrは不可
move.l (sp)+,d1
lea.l ([pageCounterTail],d0.l),a0
moves.l (a0),d0
tst.l d0
bpl @f
moveq.l #-1,d0
@@: rts
;----------------------------------------------------------------
;
; ローカルメモリ
;
;----------------------------------------------------------------
;----------------------------------------------------------------
;論理アドレス範囲がDMA転送可能か調べる
; 範囲内に非常駐ページがあるとアクセスエラーが発生してしまう
;<d0.l:転送方向
; 0 デバイスから読み出し(メモリへ書き込み)
; 1 デバイスへ書き込み(メモリから読み出し)
;<d1.l:論理アドレス(先頭)
;<d2.l:論理アドレス(末尾+1)
;>n-flag:mi=DMA転送不可能,pl=DMA転送可能
dmaAccessCheck::
movem.l d0-d3/a0-a1,-(sp)
debug '|dmaAccessCheck in (top,btm)=',2,d1,d2
and.l pageMask,d1 ;先頭があるページの先頭
;pageMaskはLOGICAL_MASKを伴うこと
and.l #LOGICAL_MASK,d2 ;末尾+1
;bit31が1になっているときd1だけマスクすると
;範囲が2GB以上になってしまう
tst.b localSystemArea
bne @f
cmp.l ([$1C20.w],Tail),d2 ;(-lsでないとき)Humanの中ならばチェックは省略
blo 4f
@@: lea.l (readTranslation,pc),a0
tst.l d0
beq @f
lea.l (writeTranslation,pc),a0
@@: movec.l dfc,d3
moveq.l #FC_SUPER_DATA,d0
movec.l d0,dfc
1: movea.l d1,a1
;<a1.l:論理アドレス
jsr (a0) ;論理アドレスを物理アドレスに変換
;<a1.l:物理アドレス
cmpa.l d1,a1
bne 2f ;物理アドレスが論理アドレスと異なる
;$00000000と$01000000でも異なると判断される
move.l a1,d0
bsr physicalToLocal
bpl 2f ;ローカルメモリ
add.l pageOffsetSize,d1 ;次のページの先頭
cmp.l d2,d1 ;ページの先頭が末尾+1以上ならば終了
blo 1b
4: moveq.l #0,d0 ;DMA転送可能
bra 3f
2: moveq.l #-1,d0 ;DMA転送不可能
3:
debug '|dmaAccessCheck out (0=DMA enable)=',1,d0
movec.l d3,dfc
tst.l d0
movem.l (sp)+,d0-d3/a0-a1
rts
;物理アドレスのチェック(デバイスからメモリへ転送)
;<a1.l:論理アドレス
;<dfc:チェックするアドレス空間
;>a1.l:物理アドレス
readTranslation:
tst.b noTranslation
bne 90f
movem.l d0-d1/a0,-(sp)
PUSH_MMU_SFC_DFC d0
bsr getDesc ;論理アドレスからページデスクリプタを求める
bmi 9f ;ページデスクリプタがない
beq 9f ;非常駐
btst.l #PD_W_BIT,d0
bne 9f ;ライトプロテクトされている
and.l pageMask,d0 ;ページの先頭アドレス
move.l a1,d1
and.l pageOffsetMask,d1 ;オフセット
or.l d1,d0 ;ページの先頭アドレスにオフセットを合成する
8: movea.l d0,a1 ;物理アドレス
POP_SFC_DFC d1
movem.l (sp)+,d0-d1/a0
90: rts
9: moveq.l #-1,d0 ;失敗
bra 8b
;物理アドレスのチェック(メモリからデバイスへ転送)
;<a1.l:論理アドレス
;<dfc:チェックするアドレス空間
;>a1.l:物理アドレス
writeTranslation:
tst.b noTranslation
bne 90f
movem.l d0-d1/a0,-(sp)
PUSH_MMU_SFC_DFC d0
bsr getDesc ;論理アドレスからページデスクリプタを求める
bmi 9f ;ページデスクリプタがない
beq 9f ;非常駐
and.l pageMask,d0 ;ページの先頭アドレス
move.l a1,d1
and.l pageOffsetMask,d1 ;オフセット
or.l d1,d0 ;ページの先頭アドレスにオフセットを合成する
8: movea.l d0,a1 ;物理アドレス
POP_SFC_DFC d1
movem.l (sp)+,d0-d1/a0
90: rts
9: moveq.l #-1,d0 ;失敗
bra 8b
;----------------------------------------------------------------
;物理アドレスがローカルメモリを指しているか調べる
;<d0.l:物理アドレス
;>d0.l:結果
; -1 ローカルメモリではない
; その他 ローカルメモリの物理アドレス
;>n-flag:mi=ローカルメモリではない,pl=ローカルメモリ
physicalToLocal::
tst.l localMemorySize
beq 9f
and.l #LOGICAL_MASK,d0
sub.l localMemoryStart,d0
cmp.l localMemorySize,d0
bcc 9f
add.l localMemoryStart,d0
rts
9: moveq.l #-1,d0
rts