misc/060tsys/t17hupat.s
;----------------------------------------------------------------
;
; Human302のパッチルーチン(常駐部)
;
;----------------------------------------------------------------
.include t00iocs.equ
.include t01dos.equ
.include t02const.equ
.include t08debug.equ
;__DEBUG__ equ 1
.cpu 68060
;----------------------------------------------------------------
;Trap#10
;ROMやシステムをローカルメモリにコピーして使っているときのソフトリセット対策
.text
.align 4,$2048
humanTrap10::
movem.l d0-d1/a0,-(sp)
PUSH_SR_DI
;ベクタテーブル復活
tst.b localSystemArea
beq 2f
movec.l dfc,d1
moveq.l #FC_MMU_DATA,d0
movec.l d0,dfc
suba.l a0,a0
1: move.l (a0),d0 ;現在のデータ
moves.l d0,(a0)+ ;本来のアドレスに戻す
cmpa.l mainLowerStart,a0
blo 1b
movec.l d1,dfc
2:
;キャッシュ機能停止
moveq.l #0,d0
movec.l d0,cacr
bsr cache_flush
;MMU機能停止
tst.b noTranslation
bne 99f
; E P NAD NAI FOTC FITC DCO DUO DWO DCI DUI
; 15 14 13 12 11 10 98 76 5 43 21
move.l #%0__0__0__0___0____0____10__00__0___00__00_0,d0
movec.l d0,tc
pflusha
;トランスペアレント変換機能停止
; moveq.l #0,d0
movec.l d0,itt0
movec.l d0,itt1
movec.l d0,dtt0
movec.l d0,dtt1
99:
POP_SR
movem.l (sp)+,d0-d1/a0
jmp ([vectorOldHumanTrap10])
;----------------------------------------------------------------
;スーパーバイザ領域設定
;EXCONFIGの実行開始前とSHELLの起動前に呼ばれるルーチン
;ただし、DEVICEで組み込む限り、EXCONFIGの実行開始前には機能しない
;HUMAN.SYSにバインドした場合はEXCONFIGの実行開始前にも使用されることになる
;これは領域設定後は常駐している必要がないが、最後のデバイスドライバを登録するまで
;残っていないと困るので常駐部に置く
;変更前
; $00006A96:
; move.l $1C24.w,d0 ;空きエリアの先頭アドレス
; add.l #$00001FFF,d0
; and.l #$00FFE000,d0
; move.l d0,$0000837A ;Humanの末尾のアドレス+1
; lsr.l #8,d0
; lsr.l #5,d0
; subq.w #1,d0
; cmp.w #$0100,d0
; bcs.s $00006ABA
; moveq.l #$FF,d0
; $00006ABA:
; move.b d0,$00E86001
; rts
;$00006A96
.text
.align 4,$2048
human302_superarea::
movem.l d1-d4/a0-a1,-(sp)
moveq.l #0,d4
debug '|IOCS($92-$93)=',2,$0192.w*4.w,$0193*4.w
move.l $1C24.w,d2 ;空きエリアの先頭アドレス
add.l #$00001FFF,d2 ;ページサイズに関わらず8KB単位に切り上げる
and.l #LOGICAL_MASK.and.$FFFFE000,d2
move.l d2,([$1C20.w],Tail) ;Humanの末尾のアドレス+1
move.l d2,d0
lsr.l #8,d0
lsr.l #5,d0
subq.l #1,d0
cmp.w #$00FF,d0
bls @f
move.w #$00FF,d0
@@: move.b d0,$00E86001 ;スーパーバイザエリア設定
suba.l a1,a1
;指定された領域をスーパーバイザプロテクトする
;<d2.l:サイズ(ページサイズの倍数)
;<a1.l:先頭アドレス(ページの先頭)
tst.b noTranslation
bne 99f
PUSH_MMU_SFC_DFC d0
add.l a1,d2
@@: bsr getDesc
bset.l #PD_S_BIT,d0
moves.l d0,(a0)
pflusha
adda.l pageOffsetSize,a1
cmpa.l d2,a1
blo @b
POP_SFC_DFC d0
;
tst.l d4
bne @f
moveq.l #1,d4
pea.l (crlfMessage,pc)
DOS _PRINT
addq.l #4,sp
@@:
pea.l (superareaMessage,pc)
DOS _PRINT
addq.l #4,sp
99:
;ユーザモードの領域を1ページ分だけ確保する
move.l ([$1C20.w],Tail),d0 ;Humanの末尾のアドレス+1
move.l d0,userAreaWork
add.l #PAGE_OFFSET_SIZE,d0
move.l d0,([$1C20.w],Tail) ;Humanの末尾のアドレス+1
;拡張モード
tst.l ([$1C20.w],Next)
bne 1f
move.l mainMemorySize,d2 ;メインメモリサイズの指定(MBの倍数)
bmi 1f
cmp.l ([$1C20.w],Tail),d2
bhi @f
move.l ([$1C20.w],Tail),d2 ;デバイスの末尾(ページサイズの倍数)
move.l d2,mainMemorySize ;デバイスの末尾よりも短くできない
@@:
;<d2.l:メインメモリのサイズ
move.l $1C00.w,d0
and.l pageMask,d0 ;他のデバイスが切り詰めた可能性があるので
;ページサイズに切り直す
cmp.l d0,d2
bhi 1f ;不足のとき(未対応)
;拡張実行
move.l d0,$1C00.w ;他のデバイスが確保した領域から
;ページサイズまで切り下げる
sub.l d2,d0
cmp.l #128*1024,d0 ;メインメモリが128KBに満たないときは,
bcc @f ;ロードとアロケーションの領域を上位のみにする
move.b #1,defaultLoadArea
move.b #1,defaultAllocArea
@@:
movea.l himemAreaEnd,a1 ;ハイメモリ領域の現在の末尾
tst.l himemAreaSize
bne 5f ;ハイメモリ領域がある
movea.l localUpperStart,a1 ;ローカルメモリの末尾かデスクリプタまたはROMの先頭
tst.l localMemorySize
bne 4f ;ローカルメモリはあるがハイメモリ領域がないので
;himemAreaStartを設定する
movea.l #$10000000,a1 ;ローカルメモリがないとき
4: move.l a1,himemAreaStart ;ハイメモリ領域がないのでhimemAreaStartを設定する
5:
;<d2.l:移動元の先頭
;<a1.l:移動先の先頭
move.l d2,-(sp) ;移動元の先頭
;元→先 デスクリプタ
;d2→a1
PUSH_MMU_SFC_DFC d0
2: move.l a1,d3 ;d2→d3/a1
movea.l d2,a1 ;d2/a1→d3
; bsr invDesc ;移動元のデスクリプタを除去する
move.l userAreaWork,d2
; UR G U1U0 S CM M U W PDT
or.l #%00_1__00__0_00_0_0_0_01,d2
bsr setDesc ;ユーザモードのワークエリアを割り当てる
move.l d0,d2 ;a1→d3 d2
exg.l d3,a1 ;d3→a1 d2
bsr setDesc ;移動先に設定する
pflusha
debug '|拡張モード setDesc(a1,d2,d0)=',3,a1,d2,d0
move.l d3,d2 ;d2→a1
move.l pageOffsetSize,d0
add.l d0,d2
adda.l d0,a1
add.l d0,himemAreaSize
cmp.l $1C00.w,d2 ;他のデバイスが確保した領域の手前まで
blo 2b
POP_SFC_DFC d0
move.l a1,himemAreaEnd ;ハイメモリの領域を伸ばす
move.l (sp)+,$1C00.w ;移動元の先頭から切り捨てる
;ハイメモリ領域の先頭のブロックを設定する
movea.l himemAreaStart,a0
lea.l (User,a0),a1
cmpi.l #'060t',(a1)
beq 3f ;初期化されている
move.l #'060t',(a1)+
move.l #'urbo',(a1)+
move.l #'HIME',(a1)+
move.l #'M'<<24,(a1)+
clr.l (Prev,a0)
move.l $1C20.w,(Proc,a0) ;Humanのメモリ管理ポインタ
move.l a1,(Tail,a0)
clr.l (Next,a0)
3:
tst.l d4
bne @f
moveq.l #1,d4
pea.l (crlfMessage,pc)
DOS _PRINT
addq.l #4,sp
@@:
pea.l (extendedMessage,pc)
DOS _PRINT
addq.l #4,sp
1:
;結合モード
tst.l ([$1C20.w],Next)
bne 1f
tst.b useJointMode
beq 1f
tst.l himemAreaSize
beq 1f
move.l $1C20.w,jointBlockHeader
movea.l $1C00.w,a0
cmpa.l ([$1C20.w],Tail),a0
beq 2f ;デバイスドライバの後ろをすべて押し出したので
;ジョイントブロックを作らない
suba.l jointBlockSize,a0
lea.l (-User,a0),a0
move.l a0,jointBlockHeader
move.l a0,([$1C20.w],Next)
move.l $1C20.w,(a0)+ ;Prev
move.l $1C20.w,(a0)+ ;Proc
addq.l #4,a0
clr.l (a0)+ ;Next
move.l #'join',(a0)+
move.l #'tBlo',(a0)+
move.w #'ck',(a0)+
2: movea.l jointBlockHeader,a0 ;ジョイントブロックまたはHumanの先頭
move.l himemAreaStart,d0
move.l d0,(Tail,a0)
move.l d0,$1C00.w
;結合モードにする
tst.b jointMode
beq 1f
sf.b jointMode ;一旦クリアする
bsr sysStat_C001 ;結合モードへ
tst.l d0
bmi 1f
tst.l d4
bne @f
moveq.l #1,d4
pea.l (crlfMessage,pc)
DOS _PRINT
addq.l #4,sp
@@:
pea.l (jointMessage,pc)
DOS _PRINT
addq.l #4,sp
1:
;
debug '|$1C00.w=',1,$1C00.w
debug '|#deviceHeader=',1,#deviceHeader
debug '|#vectorTable=',1,#vectorTable
debug '|mainLower(Start,End)=',2,mainLowerStart,mainLowerEnd
debug '|mainUpper(Start,End)=',2,mainUpperStart,mainUpperEnd
debug '|localLower(Start,End)=',2,localLowerStart,localLowerEnd
debug '|localUpper(Start,End)=',2,localUpperStart,localUpperEnd
debug '|dosBusErr(Vbr,Ssp)=',2,dosBusErrVbr,dosBusErrSsp
debug '|localRom(Start,End)=',2,localRomStart,localRomEnd
debug '|localSystem(Start,End)=',2,localSystemStart,localSystemEnd
debugKeyWait
debug '|pageIndex(Width,Size,Mask)=',3,pageIndexWidth,pageIndexSize,pageIndexMask
debug '|pageOffset(Width,Size,Mask)=',3,pageOffsetWidth,pageOffsetSize,pageOffsetMask
debug '|pageMask=',1,pageMask
debug '|pageDesc(Size,Mask)=',2,pageDescSize,pageDescMask
debug '|descArea(Start,End,Size)=',3,descAreaStart,descAreaEnd,descAreaSize
debug '|desc(Head,Tail)=',2,descHead,descTail
debug '|rootDesc(Head,Tail)=',2,rootDescHead,rootDescTail
debug '|pointerDesc(Head,Tail)=',2,pointerDescHead,pointerDescTail
debug '|pointerCounterHead=',1,pointerCounterHead
debug '|pageCounterTail=',1,pageCounterTail
debugKeyWait
debug '|tempBuffer(Start,End,Size)=',3,tempBufferStart,tempBufferEnd,tempBufferSize
debug '|localMemory(Start,End,Size)=',3,localMemoryStart,localMemoryEnd,localMemorySize
debug '|himemArea(Start,End,Size)=',3,himemAreaStart,himemAreaEnd,himemAreaSize
debug '|mainMemorySize=',1,mainMemorySize
debug '|jointBlock(Header,Size)=',2,jointBlockHeader,jointBlockSize
debug '|jointBlockHeader(Prev,Proc,Tail,Next)=',4,([jointBlockHeader],Prev),([jointBlockHeader],Proc),([jointBlockHeader],Tail),([jointBlockHeader],Next)
debug '|exclusive(Start,End)=',2,exclusiveStart,exclusiveEnd
debug '|#xTable=',1,#xTable
debug '|#mainExclusive=',1,#mainExclusive
debug '|localRamdiskArea(Start,End,Size)=',3,localRamdiskAreaStart,localRamdiskAreaEnd,localRamdiskAreaSize
debug '|mainRamdiskArea(Start,End,Size)=',3,mainRamdiskAreaStart,mainRamdiskAreaEnd,mainRamdiskAreaSize
debug '|#bpbTablePointer=',1,#bpbTablePointer
debug '|#bpbTable=',1,#bpbTable
debugKeyWait
movem.l (sp)+,d1-d4/a0-a1
rts
superareaMessage:
.dc.b 'OSをスーパーバイザ保護しました',13,10,0
extendedMessage:
.dc.b '拡張モードに切り替えました',13,10,0
jointMessage:
.dc.b 'ローカルメモリを結合しました'
crlfMessage:
.dc.b 13,10,0
.even
;----------------------------------------------------------------
;_EXIT,_KEEPPR,_EXIT2 プロセスが使っていたメモリブロックの開放
;実行中のプロセスが使っていたメモリブロックをすべて開放する
;親プロセスに戻る
;子プロセスが確保したブロックもすべて開放する
;変更前
; プロセスが使っていたメモリブロックをすべて開放し親プロセスに戻る
; <a0.l:実行中のプロセスのメモリ管理ポインタ
; $000092B8
; movem.l d0-d1/a0-a2,-(sp)
; movea.l $0000.w(a0),a1
; move.l a1,d0 ;先頭のメモリブロックはHumanなので開放しない
; beq.s $000092E0
; move.l $000C(a0),d0
; move.l d0,$000C(a1)
; beq.s $000092D4
; movea.l d0,a2
; move.l a1,$0000.w(a2)
; $000092D4:
; move.l $0004(a0),$00013D0A ;実行中のプロセスのメモリ管理テーブル
; move.l a0,d0
; bsr.s $000092E6 ;プロセスが使っていたメモリブロックの開放
; $000092E0:
; movem.l (sp)+,d0-d1/a0-a2
; rts
;
; 子プロセスが使っていたメモリブロックの開放
; <d0.l:開放する親プロセスのメモリ管理ポインタ
; $000092E6:
; move.l $1C04.w,d1 ;_MALLOCできるメモリ空間の先頭アドレス
; $000092EA:
; movea.l d1,a0
; move.l $000C(a0),d1
; beq.s $00009310
; cmp.l $0004(a0),d0
; bne.s $000092EA
; tst.l $0000.w(a0)
; beq.s $0000932A
; movea.l $0000.w(a0),a1
; move.l d1,$000C(a1)
; movea.l d1,a2
; move.l a1,$0000.w(a2)
; bsr.s $0000931E
; bra.s $000092E6 ;プロセスが使っていたメモリブロックの開放
;
; $00009310:
; cmp.l $0004(a0),d0
; bne.s $0000932A
; movea.l $0000.w(a0),a1
; move.l d1,$000C(a1)
; $0000931E:
; movem.l d0-d1,-(sp)
; move.l a0,d0
; bsr.s $000092E6 ;プロセスが使っていたメモリブロックの開放
; movem.l (sp)+,d0-d1
; $0000932A:
; rts
;<a0.l:実行中のプロセスのメモリ管理ポインタ
.text
.align 4,$2048
human302_exitfreepat::
movem.l d0/d2/d4/a4-a5,-(sp)
tst.l (Prev,a0)
beq 9f ;Human自身ならば何もしない
movea.l $1C04.w,a4 ;メモリ空間の先頭
movea.l $1C00.w,a5 ;メモリ空間の末尾+1
move.l a0,d4
bsr psfree ;実行中のプロセスが確保したブロックを開放する
;子プロセスが確保したブロックも開放する
move.l (Proc,a0),([$1C28.w])
move.l a0,d2
add.l #User,d2
bsr free ;自分自身を開放する
9: movem.l (sp)+,d0/d2/d4/a4-a5
rts
;----------------------------------------------------------------
;_EXEC [3]実行ファイルの形式指定
;変更前
; $00009510
; _dos_exec_3_x:
; bsr.w $0000997C ;実行ファイル名の拡張子の先頭の文字を小文字化して返す
; cmp.b #'x',d0
; beq.s _dos_exec_3_x
; cmp.b #'r',d0
; beq.s _dos_exec_3_r
; cmp.b #'z',d0
; beq.s _dos_exec_3_z
; move.l a1,d0
; rol.l #8,d0
; $0000952A
;$00009510
.text
.align 4,$2048
human302_exec3pat::
bsr human302_exec013pat
jmp $0000952A.l
;----------------------------------------------------------------
;_EXEC [0][1]実行ファイルの形式指定
;変更前
; $0000961A
; _dos_exec_01::
; move.l a1,$1CB2.w ;_EXECで起動するファイル名
; bsr.w $0000997C ;実行ファイル名の拡張子の先頭の文字を小文字化して返す
; cmp.b #'x',d0
; beq.w _dos_exec_01_x
; cmp.b #'r',d0
; beq.w _dos_exec_01_r
; cmp.b #'z',d0
; beq.s _dos_exec_01_z
; move.l a1,d0
; rol.l #8,d0
; $0000963C
;$0000961A
.text
.align 4,$2048
human302_exec01pat::
bsr human302_exec013pat
move.l a1,$1CB2.w ;_EXECで起動するファイル名
jmp $0000963C.l
;----------------------------------------------------------------
;_EXEC [0][1][3]実行ファイルの形式指定
; ファイル名のアドレスの最上位バイトで実行ファイルの形式を指定できる
; 指定よりも拡張子の方が優先する
;<a1.l:ファイル名のアドレス
; 最上位バイトは実行ファイルのタイプ(0=拡張子,1=r,2=z,3=x)
;>d0.l:実行ファイルの形式(0=不明,1=r,2=z,3=x)
;>a1.l:ファイル名のアドレス
; 最上位バイトが修正されている
.text
.align 4,$2048
human302_exec013pat::
;実行ファイルの形式の指定を取得し、ファイル名のアドレスの最上位バイトを修正する
move.l a1,-(sp)
moveq.l #LOGICAL_MASK>>24,d0
and.b (sp),d0 ;ファイル名の最上位バイト
beq @f
cmp.b #3,d0
bls 1f ;ファイル名の最上位バイトが1~3
;ファイル名の最上位バイトが4以上
tst.l himemAreaSize
beq 4f
move.l (sp),d0
cmp.l himemAreaEnd,d0
blo 3f
cmp.l #$14000000,d0
blo 2f
3: moveq.l #0,d0
bra @f
;ファイル名の最上位バイトがローカルメモリ
2: rol.l #8,d0
4: and.l #$00000003,d0
;ファイル名の最上位バイトを修正する
1: movea.l $1C5C.w,a1
move.b (dosPC,a1),(sp) ;pcの最上位バイトを補う
@@: movea.l (sp)+,a1 ;最上位バイトが修正されている
;<d0.l:実行ファイルの形式の指定(0=拡張子,1=r,2=z,3=x)
;<a1.l:最上位バイトが修正されたファイル名のアドレス
move.l d0,-(sp)
jsr $0000997C.l ;ファイル名の拡張子の先頭の文字を小文字化して返す
;>d0.b:拡張子の先頭の文字を小文字化したもの(拡張子がなければ0)
cmp.b #'x',d0
beq 3f
cmp.b #'r',d0
beq 1f
cmp.b #'z',d0
beq 2f
;拡張子では見分けがつかないので指定に従う
move.l (sp)+,d0
rts
;R形式
1: moveq.l #1,d0
addq.l #4,sp
rts
;Z形式
2: moveq.l #2,d0
addq.l #4,sp
rts
;X形式
3: moveq.l #3,d0
addq.l #4,sp
rts
.comment !!!
; ファイル名のアドレスの最上位バイトが
; ・$00のとき
; 形式0がmove(またはand)されている可能性がある
; ・$01~$03のとき
; 形式1~3がmove(または0にaddまたはor)されている可能性が高い
; ・ハイメモリの下限+1以上、ハイメモリの上限+3以下のとき
; 形式1~3がaddされている可能性がある
; ・ハイメモリの下限|1以上、ハイメモリの上限|3以下で下位2ビットが0でないとき
; 形式1~3がorされている可能性がある
;
; ファイル名のアドレスの最上位バイトの復元を試みる
; 復元できたかどうかは以下の条件で判別する
; ・アドレスをアクセスできるかどうか(範囲内かどうか)
; ・ファイル名として正しいかどうか
; ・ファイルが存在して少なくとも2バイト読み込めるかどうか
; 最初にそのままの状態で試す
; 形式がmoveされている可能性があるときはpcおよびspの最上位バイトの前後を試す
; 形式がaddまたはorされている可能性があるときはその可能性がある範囲を試す
;
; 以下の場合はファイルの先頭2バイトで形式を判別する
; ・形式の指定がなくて拡張子がR,Z,Xのいずれでもない場合
; ・ファイル名のアドレスを復元できたが形式をaddしたのかorしたのかわからない場合
; ファイルの先頭2バイトが
; ・'HU'のとき
; X形式の実行ファイル
; ・$601Aのとき
; Z形式の実行ファイル
; ・その他
; R形式の実行ファイル
;
; 今後の課題
; シンボリックリンクへの対応
; (他のDOSコールも対応させる必要がある)
; ファイルの先頭2バイトが'#!'のときはスクリプトと見なす
; (引数を変える必要があるのでこのパッチの範囲では処理できない)
movem.l d1-d3/a1,-(sp)
;最初にファイル名のアドレスをLOGICAL_MASKでマスクして余計なフラグ類を消す
;この方法ではハイメモリ領域256MBの末尾で形式1~3がaddされて論理アドレス空間512MBから
;溢れた場合に対処できない
move.w #LOGICAL_MASK>>24,d0
and.b (4*3,sp),d0 ;a1の最上位バイト,スタック注意
;<d0.w:ファイル名のアドレスの最上位バイト(0拡張)
cmp.b #3,d0
bhi @f
;ファイル名のアドレスの最上位バイトが$00~$03
move.l #$0001_0001,d3
lsl.l d0,d3
lsl.b #2,d0
lsl.w d0,d3
;<d3.l:
; $0001_0001 最上位バイトが$00
; 距離0で形式0がaddされた可能性
; 距離0で形式0がorされた可能性
; 距離不明で形式0がmoveされた可能性
; $0002_0020 最上位バイトが$01
; 距離1で形式1がaddされた可能性
; 距離1で形式1がorされた可能性
; 距離不明で形式1がmoveされた可能性
; $0004_0400 最上位バイトが$02
; 距離2で形式2がaddされた可能性
; 距離2で形式2がorされた可能性
; 距離不明で形式2がmoveされた可能性
; $0008_8000 最上位バイトが$03
; 距離3で形式3がaddされた可能性
; 距離3で形式3がorされた可能性
; 距離不明で形式3がmoveされた可能性
bra 9f
@@:
;ファイル名のアドレスの最上位バイトが$04以上
tst.l himemAreaSize
beq 90f ;ハイメモリ領域がない
moveq.l #0,d3
move.l himemAreaStart,d1
rol.l #8,d1
;<d1.b:ハイメモリ領域の先頭のアドレスの最上位バイト
sub.b d0,d1
;<d1.b:ファイル名のアドレスの最上位バイトからハイメモリ領域の先頭のアドレスの最上位バイトまでの距離
; 1以上は範囲外
; 0は距離0が有効
; -1は距離0~1が有効
; -2は距離0~2が有効
; -3以下は距離0~3が有効
bgt 90f ;1以上なので範囲外
move.l #$0000_FFFF,d3
addq.b #3,d1
; 3は距離0が有効
; 2は距離0~1が有効
; 1は距離0~2が有効
; 0以下は距離0~3が有効
bcc @f
lsl.b #2,d1
lsr.w d1,d3
@@:
;<d3.w:ハイメモリ領域の下限による距離の条件
; $FFFF 距離0~3が有効
; $0FFF 距離0~2が有効
; $00FF 距離0~1が有効
; $000F 距離0が有効
move.l himemAreaEnd,d1
subq.l #1,d1
rol.l #8,d1
;<d1.b:ハイメモリ領域の末尾のアドレスの最上位バイト
sub.b d0,d1
;<d1.b:ファイル名のアドレスの最上位バイトからハイメモリ領域の末尾のアドレスの最上位バイトまでの距離
; 0以上は距離0~3が有効
; -1は距離1~3が有効
; -2は距離2~3が有効
; -3は距離3が有効
; -4以下は範囲外
bge @f ;0以上なので範囲内
addq.b #3,d1
bmi 90f ;範囲外
; 2は距離1~3が有効
; 1は距離2~3が有効
; 0は距離3が有効
lsl.b #2,d1
move.l #$0000_FFFF,d2
lsl.w d1,d2
;<d2.w:ハイメモリ領域の上限による距離の条件
; $FFFF 距離0~3が有効
; $FFF0 距離1~3が有効
; $FF00 距離2~3が有効
; $F000 距離3が有効
and.w d2,d3
@@:
;<d3.w:ハイメモリ領域の条件
;ファイル名のアドレスの最上位バイトがハイメモリ領域を指している場合
and.b #3,d0 ;下位2ビット
bne @f
and.w #$0001,d3 ;下位2ビットが0
; 距離0で形式0がorされた可能性(0|0=0)
bra 1f
@@:
subq.b #2,d0
bcc @f
and.w #$0023,d3 ;下位2ビットが1
; 距離0で形式0がorされた可能性(1|0=1)
; 距離0で形式1がorされた可能性(1|1=1)
; 距離1で形式1がorされた可能性(0|1=1)
bra 1f
@@:
bne @f
and.w #$0405,d3 ;下位2ビットが2
; 距離0で形式0がorされた可能性(2|0=2)
; 距離0で形式2がorされた可能性(2|2=2)
; 距離2で形式2がorされた可能性(0|2=2)
bra 1f
@@:
and.w #$86AF,d3 ;下位2ビットが3
; 距離0で形式0がorされた可能性(3|0=3)
; 距離0で形式1がorされた可能性(3|1=3)
; 距離0で形式2がorされた可能性(3|2=3)
; 距離0で形式3がorされた可能性(3|3=3)
; 距離1で形式1がorされた可能性(2|1=3)
; 距離1で形式3がorされた可能性(2|3=3)
; 距離2で形式2がorされた可能性(1|2=3)
; 距離2で形式3がorされた可能性(1|3=3)
; 距離3で形式3がorされた可能性(0|3=3)
1:
tst.l d3
beq 90f
9:
;<d3.l:ファイル名のアドレスの最上位バイトの範囲による条件
; bit0 1=距離0で形式0が指定された可能性がある
; bit1 1=距離0で形式1が指定された可能性がある
; bit2 1=距離0で形式2が指定された可能性がある
; bit3 1=距離0で形式3が指定された可能性がある
; bit4 1=距離1で形式0が指定された可能性がある
; bit5 1=距離1で形式1が指定された可能性がある
; bit6 1=距離1で形式2が指定された可能性がある
; bit7 1=距離1で形式3が指定された可能性がある
; bit8 1=距離2で形式0が指定された可能性がある
; bit9 1=距離2で形式1が指定された可能性がある
; bit10 1=距離2で形式2が指定された可能性がある
; bit11 1=距離2で形式3が指定された可能性がある
; bit12 1=距離3で形式0が指定された可能性がある
; bit13 1=距離3で形式1が指定された可能性がある
; bit14 1=距離3で形式2が指定された可能性がある
; bit15 1=距離3で形式3が指定された可能性がある
; bit16 1=距離不明(pc,spの前後)で形式0が指定された可能性がある
; bit17 1=距離不明(pc,spの前後)で形式1が指定された可能性がある
; bit18 1=距離不明(pc,spの前後)で形式2が指定された可能性がある
; bit19 1=距離不明(pc,spの前後)で形式3が指定された可能性がある
;距離0~3を順にチェックする
30:
;この距離だった可能性があるか
moveq.l #$0F,d1
and.w d3,d1
beq 39f ;この距離ではない
;<d1.l:形式の候補
;<a1.l:ファイル名のアドレス
bsr checkExecFil
39:
suba.l #$01000000,a1
lsr.w #4,d3
bne 30b
movem.l (sp)+,d1-d3/a1,-(sp)
rts
;判別失敗
90:
movem.l (sp)+,d1-d3/a1,-(sp)
moveq.l #0,d0
rts
;ファイル名のアドレスが正しいか調べる
;<d1.l:形式の候補(複数指定可)
; bit0 拡張子で判別
; bit1 R形式
; bit2 Z形式
; bit3 X形式
;<a1.l:ファイル名のアドレス
;>d0.l:-1=エラー
;>d1.l:形式
; 2 R
; 4 Z
; 8 X
.text
.align 4,$2048
checkExecFil::
movem.l a2-a3,-(sp)
lea.l (-ncSize-fSize,sp),sp
;ファイル名として正しいか
move.l a1,-(sp)
DOS _NAMECK
addq.l #4,sp
tst.l d0
bne 90f ;エラーまたはワイルドカードがある
;拡張子を確認しておく
move.l (ncExt,sp),d0 ;拡張子(ncExtは偶数)
and.l #$FFDFFF00,d0 ;1文字目を大文字化,3文字目を無視
cmp.l #'.R'<<16,d0
bne 1f
moveq.l #$02,d1
bra 3f
1: cmp.l #'.Z'<<16,d0
bne 2f
moveq.l #$04,d1
bra 3f
2: cmp.l #'.X'<<16,d0
bne 3f
moveq.l #$08,d1
3:
;ドライブの準備ができているか
moveq.l #$1F,d0
and.b (ncDrive,sp),d0 ;ドライブ番号(1=A:)
move.w d0,-(sp)
DOS _DRVCTRL
addq.l #2,sp
and.b #$02,d0
beq 90f ;ドライブの準備ができていない
;フルパスのファイル名を作る
lea.l (ncPath,sp),a3
@@: tst.b (a3)+
bne @b
subq.l #1,a3
lea.l (ncName,sp),a2
@@: move.b (a2)+,(a3)+
bne @b
subq.l #1,a3
lea.l (ncExt,sp),a2
@@: move.b (a2)+,(a3)+
bne @b
;ファイルを検索する
move.w #$0020,-(sp) ;ファイルのみ
pea.l (2,sp)
pea.l (4+2+ncSize,sp)
DOS _FILES
lea.l (10,sp),sp
tst.l d0
bne 90f ;ファイルが見つからない
;先頭の2バイトを読み込んでみる
99:
lea.l (ncSize+fSize,sp),sp
movem.l (sp)+,a2-a3
rts
90:
moveq.l #-1,d0
bra 99b
!!!
;----------------------------------------------------------------
;_EXEC スーパーバイザモード選択
;変更前
; $00009748
; and.l #$00FFFFFF,d0
; cmp.l $0000837A,d0 ;Humanの末尾のアドレス+1
; bcc.s $0000975E
; $00009756
; ori.w #$2000,($38,a5) ;スーパーバイザモードで起動する
; rts
; $0000975E
; cmp.l #$00C00000,d0
; bcc.s $00009756
; andi.w #$DFFF,($38,a5) ;ユーザモードで起動する
; rts
;$00009748
.text
.align 4,$2048
human302_execsuperpat::
and.l #LOGICAL_MASK,d0
cmp.l $0000837A.l,d0
bcc 2f
;スーパーバイザモードで起動する
1: ori.w #$2000,(dosSR,a5)
rts
2: cmp.l #$00C00000,d0
bcs 3f
cmp.l #$01000000,d0
bcs 1b
;ユーザモードで起動する
3: andi.w #$DFFF,(dosSR,a5)
rts
;----------------------------------------------------------------
;_KEEPPR 常駐フラグの設定
;変更前
; $0000A064
; ori.l #$FF000000,$0004(a0) ;常駐フラグを設定
;$0000A064
.text
.align 4,$2048
human302_keeppr::
;親のアドレスの最上位バイトに常駐フラグ$FFを書き込む
;親がハイメモリにあるとアドレスが破壊される
;親はいつまでも健在とは限らないのでそもそも辿ってよい情報ではないが
;念のため始祖であるHuman68kのメモリ管理テーブルのアドレスを入れておく
tst.b (Proc,a0)
beq @f
move.l $1C20.w,(Proc,a0) ;Humanのメモリ管理テーブル
@@: ori.l #$FF000000,(Proc,a0) ;常駐フラグを設定
jmp $0000A06C
;----------------------------------------------------------------
;_S_MFREE メモリ管理が破壊されるバグ
;変更前
; $0000DF9A
; movea.l d2,a0 ;先頭
; movea.l (-16,a0),a1 ;サブの直前
; movea.l (-16+12,a0),a2 ;サブの直後
; move.l a1,(a0) ;先頭のブロックの直前をサブの直前にする
; clr.b (-16+4,a0) ;サブの親のフラグを消す
; move.l (-16+4,a0),(4,a0) ;先頭のブロックの親をサブの親にする
; $0000DFB0
; move.l (12,a0),d0 ;末尾のブロックまでスキップ
; beq.s $0000DFBA
; movea.l d0,a0
; bra.s $0000DFB0
; $0000DFBA
; move.l a2,(12,a0) ;末尾のブロックの直後をサブの直後にする
; $0000DFBE
;$0000DF9A
.text
.align 4,$2048
human302_smfreepat::
movea.l d2,a0 ;先頭
movea.l (-16,a0),a1 ;サブの直前
movea.l (-16+12,a0),a2 ;サブの直後
move.l a1,(a0) ;先頭の直前をサブの直前にする
beq 1f
move.l a0,(12,a1) ;サブの直前の直後を先頭にする
1: andi.l #LOGICAL_MASK,(-16+4,a0) ;サブの親のフラグを消す
move.l (-16+4,a0),(4,a0) ;先頭の親をサブの親にする
move.l d2,d0 ;先頭
2: movea.l d0,a0
move.l (12,a0),d0 ;末尾までスキップ
bne 2b
move.l a2,(12,a0) ;末尾の直後をサブの直後にする
beq 3f
move.l a0,(a2) ;サブの直後の直前を末尾にする
3: jmp $0000DFBE.l
;----------------------------------------------------------------
;バスエラーチェック(_BUS_ERRの下請けルーチン)
;<d1.w:サイズ
; 1 バイト
; 2 ワード
; 4 ロングワード
;<a0.l:読み出すアドレス
;<a1.l:書き込むアドレス
;>d0.l:バスエラーの発生状況
; 0 読み書き成功
; 1 読み出し成功,書き込み失敗
; 2 読み書き失敗
; -1 パラメータがおかしい
;$0000E28A
.text
.align 4,$2048
human302_buserr::
debug '|buserr in (size,read,write)=',3,d1,a0,a1
debug '|buserrtrap=',1,#human302_buserr_trap
PUSH_SR_DI
PUSH_CACR_DISABLE_DC d0
;仮のベクタテーブルを作る
movec.l vbr,a5 ;a5=元のvbr
movea.l dosBusErrVbr,a6
movec.l a6,vbr ;ベクタテーブルを本体メモリへ
;どうせベクタテーブルを作っている最中に
;割り込まれても処理できないので先に設定する
move.w #256-1,d0 ;仮のベクタテーブルはすべてトラップ
@@: move.l #human302_buserr_trap,(a6)+
dbra d0,@b
;仮のスーパーバイザスタックを使う
movea.l sp,a6 ;a6=元のssp
movea.l dosBusErrSsp,sp ;sspを本体メモリへ
;
moveq.l #2,d0
cmp.w #1,d1
beq 1f
cmp.w #2,d1
beq 2f
cmp.w #4,d1
beq 4f
9: moveq.l #-1,d0
8: movea.l a6,sp
movec.l a5,vbr
POP_CACR d1
POP_SR
debug '|buserr out (err)=',1,d0
rts
human302_buserr_trap:
movea.l a6,sp
bra 8b
1: nop
move.b (a0),d1
nop
moveq.l #1,d0
nop
move.b d1,(a1)
nop
moveq.l #0,d0
bra 8b
2: move.l a0,d1
lsr.l #1,d1
bcs 9b
move.l a1,d1
lsr.l #1,d1
bcs 9b
nop
move.w (a0),d1
nop
moveq.l #1,d0
nop
move.w d1,(a1)
nop
moveq.l #0,d0
bra 8b
4: move.l a0,d1
lsr.l #1,d1
bcs 9b
move.l a1,d1
lsr.l #1,d1
bcs 9b
nop
move.l (a0),d1
nop
moveq.l #1,d0
nop
move.l d1,(a1)
nop
moveq.l #0,d0
bra 8b
;----------------------------------------------------------------
;DISK2HDデバイスドライバの処理ルーチンの取得と設定
; $00010A20
; move.w (a6)+,(a4)+
; dbra d0,$00010A20
;$00010A20
.text
.align 4,$2048
human302_disk2hd_jmp::
@@: move.w (a6)+,(a4)
addq.l #2,a4
dbra d0,@b
bsr cache_flush
rts