misc/060tsys/t22thread.s
;----------------------------------------------------------------
;
; スレッド関係のDOSコールのパッチ
;
;----------------------------------------------------------------
.include t01dos.equ
.include t02const.equ
.include t03memory.equ
.include t08debug.equ
;__DEBUG__ equ 1
.cpu 68060
;----------------------------------------------------------------
;_S_MALLOC メインスレッドのメモリ空間からのブロックの確保
;<(a6).w:bit15=プロセス指定フラグ(0=実行中のプロセス,1=(6,a6).lを親プロセスとして使用する)
; 下位8bit=モード(0=下位から,1=必要最小ブロックから,2=上位から,3=最大ブロックから)
;<(2,a6).l:確保するサイズ
;<(6,a6).l:((a6).wのbit15が1のとき)親プロセスのメモリ管理テーブル
;>d0.l:確保したブロックのユーザ領域の先頭
; $81xxxxxx=確保できる最大のサイズ,$82000000=まったく確保できない
;*d0,?d2-d4/a0-a5
dosSMalloc::
debug '|s_malloc in (mode,size,proc)=',3,(-2,a6),(2,a6),(6,a6)
movea.l $1C50.w,a0 ;メインスレッドのスレッド管理テーブル
cmpa.l $1C54.w,a0 ;実行中のスレッドのスレッド管理テーブル
beq dosMalloc2 ;メインスレッド実行中ならば_MALLOC2で済ます
;<a0.l:メインスレッドのスレッド管理テーブル
bsr lockBlocks ;自分を含めたすべてのサブスレッドのブロックをロックする
movea.l $1C50.w,a3 ;メインスレッドのスレッド管理テーブル
movea.l (tMemStart,a3),a4
movea.l (tMemEnd,a3),a5
;<a4.l:メモリ空間の先頭(先頭のブロックのヘッダ)
;<a5.l:メモリ空間の末尾+1(16バイトアラインメント)
movea.l a4,a2
movea.l a5,a3
bra dosMalloc2SMalloc
;----------------------------------------------------------------
;_S_MALLOC2 メインスレッドのメモリ空間からのブロックの確保
;<(a6).w:bit15=プロセス指定フラグ(0=実行中のプロセス,1=(6,a6).lを親プロセスとして使用する)
; 下位8bit=モード(0=下位から,1=必要最小ブロックから,2=上位から,3=最大ブロックから)
;<(2,a6).l:確保するサイズ
;<(6,a6).l:((a6).wのbit15が1のとき)親プロセスのメモリ管理テーブル
;>d0.l:確保したブロックのユーザ領域の先頭
; $8xxxxxxx=確保できる最大のサイズ
;*d0,?d2-d4/a0-a5
dosSMalloc2::
debug '|s_malloc2 in (mode,size,proc)=',3,(-2,a6),(2,a6),(6,a6)
movea.l $1C50.w,a0 ;メインスレッドのスレッド管理テーブル
cmpa.l $1C54.w,a0 ;実行中のスレッドのスレッド管理テーブル
beq dosMalloc4 ;メインスレッド実行中ならば_MALLOC4で済ます
;<a0.l:メインスレッドのスレッド管理テーブル
bsr lockBlocks ;自分を含めたすべてのサブスレッドのブロックをロックする
movea.l $1C50.w,a3 ;メインスレッドのスレッド管理テーブル
movea.l (tMemStart,a3),a4
movea.l (tMemEnd,a3),a5
;<a4.l:メモリ空間の先頭(先頭のブロックのヘッダ)
;<a5.l:メモリ空間の末尾+1(16バイトアラインメント)
movea.l a4,a2
movea.l a5,a3
bra dosMalloc4SMalloc
;----------------------------------------------------------------
;_S_MFREE メインスレッドのメモリ空間からのブロックの開放
; 現在のスレッドのメモリ空間の先頭(先頭のブロックのヘッダ)ならばスレッドを破棄する
; それ以外はメインスレッドのメモリ管理でロックを行わずに_MFREEを行う
;<(a6).l:開放するブロックのユーザ領域の先頭
;>d0.l:エラーコード
;*d0,?d1-d2/a0/a2-a5
dosSMfree::
debug '|s_mfree in (ptr)=',1,(a6)
move.w currentThreadId,d1 ;現在のスレッド番号
beq dosMfree ;メインスレッドを実行中ならば_MFREEするだけ
;<d1.w:現在のスレッド番号
move.l (a6),d2 ;開放するブロックのユーザ領域の先頭
;<d2.l:開放するブロックのユーザ領域の先頭
movea.l $1C50.w,a3 ;メインスレッドのスレッド管理テーブルの先頭アドレス
movea.l (tMemStart,a3),a4
movea.l (tMemEnd,a3),a5
;<a4.l:メインスレッドのメモリ空間の先頭
;<a5.l:メインスレッドのメモリ空間の末尾+1
movea.l $1C54.w,a3 ;現在のスレッドのスレッド管理テーブル
;<a3.l:現在のスレッドのスレッド管理テーブル
move.l (tMemStart,a3),d0 ;現在のスレッドの先頭のブロックのヘッダ
cmpa.l d0,a4
beq dosMfreeSMfree ;メインスレッドと同じメモリ空間ならば_MFREEするだけ
cmp.l d0,d2
bne dosMfreeSMfree ;現在のスレッドの先頭のブロックでなければ_MFREEするだけ
;ブロックを検索する
bsr searchBlock ;メインスレッドのメモリ空間から検索する
bpl dosSMfreeContinuous ;連続メモリ型サブスレッド
moveq.l #$FFFFFFF0,d0
add.l d0,d2
bsr searchBlock ;メインスレッドのメモリ空間から検索する
bmi dosSMfreeParamError ;パラメータが無効
;サブメモリ型サブスレッド
; 排他制御情報を破棄する
; メインスレッドのメモリ空間に変更
; サブスレッドのメモリ空間の親ブロックのフラグを消す
; サブスレッドのメモリ空間の親ブロックのヘッダを削除する
; サブスレッドのメモリ空間をメインスレッドのメモリ空間に結合する
;<d1.w:スレッド番号
;<a2.l:親ブロックのヘッダ
;<a4.l:メインスレッドのメモリ空間の先頭
;<a5.l:メインスレッドのメモリ空間の末尾+1
tst.b backgroundFlag
beq @f
move.w d1,d0
bsr killExclusive ;排他制御情報を破棄する
@@: move.l a4,$1C04.w ;メインスレッドのメモリ空間に変更
move.l a5,$1C00.w
andi.b #LOGICAL_MASK>>24,(Proc,a2) ;親ブロックのフラグを消す
lea.l (User,a2),a0 ;先頭のブロックのヘッダ
move.l (Proc,a2),(Proc,a0) ;先頭のブロックの親プロセスを親ブロックの親プロセスにする
movea.l (a2),a1 ;親ブロックの直前
move.l a1,(Prev,a0) ;先頭のブロックの直前を親ブロックの直前にする
beq @f
move.l a0,(Next,a1) ;親ブロックの直前の直後を先頭のブロックにする
@@:
1: move.l (Next,a0),d0
beq 2f
movea.l d0,a0
move.l (Next,a0),d0
bne 1b
2:
;<a0.l:最後のブロックのヘッダ
movea.l (Next,a2),a1
move.l a1,(Next,a0) ;末尾の直後を親ブロックの直後にする
beq @f
move.l a0,(Prev,a1) ;サブの直後の直前を末尾にする
@@:
bra dosSMfreeSetEnd
;連続メモリ型サブスレッド
; 排他制御情報を破棄する
; メインスレッドのメモリ空間に変更
; サブスレッドのメモリ空間の先頭のブロックのフラグを消す
; サブスレッドのメモリ空間の直後のダミーのブロックのヘッダを削除する
;<d1.w:スレッド番号
;<a2.l:先頭のブロックのヘッダ
;<a3.l:現在のスレッドのスレッド管理テーブル
;<a4.l:メインスレッドのメモリ空間の先頭
;<a5.l:メインスレッドのメモリ空間の末尾+1
dosSMfreeContinuous:
tst.b backgroundFlag
beq @f
move.w d1,d0
bsr killExclusive ;排他制御情報を破棄する
@@: move.l a4,$1C04.w ;メインスレッドのメモリ空間に変更
move.l a5,$1C00.w
andi.b #LOGICAL_MASK>>24,(Proc,a2) ;先頭のブロックのフラグを消す
movea.l (tMemEnd,a3),a5
movea.l a2,a0
move.l a2,d0
1: cmp.l a5,d0
bcc 2f
movea.l d0,a0
move.l (Next,a0),d0
bne 1b
bra 3f
2:
;<d0.l:最後のブロックの次のブロックのヘッダ
;<a0.l:最後のブロックのヘッダ
cmp.l a5,d0
bne 3f ;メモリ空間の直後にブロックがない
movea.l (Next,a5),a1
move.l a1,(Next,a0) ;最後のブロックの直後をダミーのブロックの直後にする
beq @f
move.l a0,(Prev,a1) ;ダミーのブロックの直後の直前を最後のブロックにする
@@:
3:
;<a2.l:先頭のブロックのヘッダ
dosSMfreeSetEnd:
addq.l #4,sp
movem.l (sp)+,d1-d7/a0-a4
debug '|s_mfree done; jump to kill_pr',0
move.l killPrEntry,-(sp) ;_KILL_PRへ
rts
dosSMfreeParamError:
moveq.l #$FFFFFFF2,d0 ;パラメータが無効
debug '|s_mfree out; illegal parameter',0
rts
;----------------------------------------------------------------
;_S_PROCESS サブスレッドのメモリ空間の設定
; サブメモリ型サブスレッドのときサブスレッドのメモリ空間の先頭のブロックのヘッダを作る
; 連続メモリ型サブスレッドのときサブスレッドのメモリ空間の直後にダミーのヘッダを作る
; 排他制御情報を作成する
;<(a6).w:スレッド番号
;<(2,a6).l:ブロックの先頭アドレス
;<(6,a6).l:サブのメモリ管理のサイズ
;<(10,a6).l:先頭のブロックのサイズ
;>d0.l:先頭のブロックのユーザ領域の先頭
; $FFFFxxxx=最大スレッド番号,$FFFFFFF2=ブロックの指定が違う
;*d0,?d1-d4/d7/a0-a2/a4-a5
dosSProcess::
debug '|s_process in (thread-id,ptr,size,head-size)=',4,(-2,a6),(2,a6),(6,a6),(10,a6)
moveq.l #$FFFFFFFF,d0
move.w ($1C58).w,d0 ;processのスレッド数-1
beq dosSProcessEnd ;processが設定されていない
;<d0.l:$FFFF0000+processのスレッド数-1
move.w (a6)+,d1 ;スレッド番号
beq dosSProcessEnd ;メインスレッドは指定できない
cmp.w d0,d1
bhi dosSProcessEnd ;スレッド番号が大きすぎる
;<d1.w:スレッド番号
movea.l $1C50.w,a3
movea.l (tMemStart,a3),a4
movea.l (tMemEnd,a3),a5
;<a4.l:メインスレッドのメモリ空間の先頭
;<a5.l:メインスレッドのメモリ空間の末尾+1
moveq.l #tSize,d2
mulu.w d1,d2
adda.l d2,a3
;<a3.l:スレッド管理テーブル
tst.l (tProcess,a3)
beq dosSProcessEnd ;未使用のスレッド
movem.l (a6)+,d2-d4
;<d2.l:サブスレッドのメモリ空間の先頭
;<d3.l:サブスレッドのメモリ空間のサイズ
;<d4.l:先頭のブロックのサイズ
move.l #LOGICAL_SIZE-1,d0 ;オーバーフローしないようにする
cmp.l d0,d3
bls @f
move.l d0,d3
@@: cmp.l d0,d4
bls @f
move.l d0,d4
@@:
moveq.l #$0000000F,d0
add.l d0,d3
moveq.l #$FFFFFFF0,d0
and.w d0,d3 ;サイズを16の倍数に切り上げる
;ブロックを検索する
bsr searchBlock
bpl dosSProcessContinuous ;連続メモリ型サブスレッド
moveq.l #$FFFFFFF0,d0
add.l d0,d2
bsr searchBlock
bmi dosSProcessParamError ;パラメータが無効
;サブメモリ型サブスレッド
; サブスレッドのメモリ空間の先頭のブロックのヘッダを作る
;<d3.l:サブスレッドのメモリ空間のサイズ
;<d4.l:先頭のブロックのサイズ
;<a2.l:親ブロックのヘッダ
;<a3.l:スレッド管理テーブル
lea.l (User,a2),a4 ;サブスレッドのメモリ空間の先頭
lea.l (a4,d3.l),a5 ;サブスレッドのメモリ空間の末尾+1
;<a4.l:サブスレッドのメモリ空間の先頭
;<a5.l:サブスレッドのメモリ空間の末尾+1
cmpa.l (Tail,a2),a5
bhi dosSProcessParamError ;親ブロックが小さすぎる
lea.l (User,a4,d4.l),a1 ;先頭のブロックの末尾+1
;<a1.l:先頭のブロックの末尾+1
cmpa.l a5,a1
bhi dosSProcessParamError ;先頭のブロックが大きすぎる
movea.l a4,a0 ;先頭のブロックのヘッダを設定
clr.l (a0)+ ;直前
clr.l (a0)+ ;プロセス
move.l a1,(a0)+ ;末尾+1
clr.l (a0) ;直後
bra dosSProcessSetEnd
;連続メモリ型サブスレッド
; サブスレッドのメモリ空間の直後にダミーのヘッダを作る
;<d3.l:サブスレッドのメモリ空間のサイズ
;<d4.l:先頭のブロックのサイズ
;<a2.l:先頭のブロックのヘッダ
;<a3.l:スレッド管理テーブル
dosSProcessContinuous:
movea.l a2,a4 ;サブスレッドのメモリ空間の先頭
lea.l (a4,d3.l),a5 ;サブスレッドのメモリ空間の末尾+1,ダミーのヘッダ
;<a4.l:サブスレッドのメモリ空間の先頭
;<a5.l:サブスレッドのメモリ空間の末尾+1
lea.l (User,a5),a0 ;ダミーのヘッダの末尾+1
cmpa.l (Tail,a2),a0
bhi dosSProcessParamError ;先頭のブロックの現在のサイズが小さすぎる
lea.l (User,a4,d4.l),a1 ;先頭のブロックの末尾+1
;<a1.l:先頭のブロックの末尾+1
cmpa.l a5,a1
bhi dosSProcessParamError ;先頭のブロックが大きすぎる
movea.l a5,a0 ;ダミーのブロックのヘッダを設定
move.l a4,(a0)+ ;直前
clr.l (a0)+ ;プロセス
move.l (Tail,a4),(a0)+ ;末尾+1
move.l (Next,a4),(a0) ;直後
;先頭のブロックのヘッダを設定
move.l a5,(Tail,a4) ;末尾+1
move.l a5,(Next,a5) ;直後
;<d3.l:サブスレッドのメモリ空間のサイズ
;<d4.l:先頭のブロックのサイズ
;<a2.l:先頭のブロックのヘッダ
;<a3.l:スレッド管理テーブル
;<a4.l:サブスレッドのメモリ空間の先頭
;<a5.l:サブスレッドのメモリ空間の末尾+1
dosSProcessSetEnd:
or.b #$C0,(Proc,a2) ;親または先頭のブロックにフラグをセット
move.l a4,(tMemStart,a3) ;サブスレッドのメモリ空間を設定
move.l a5,(tMemEnd,a3)
dosSProcessEnd:
debug '|s_process out (ptr or max-id)=',1,d0
rts
dosSProcessParamError:
moveq.l #$FFFFFFF2,d0 ;パラメータが無効
debug '|s_process out; illegal parameter',0
rts
;----------------------------------------------------------------
;_OPEN_PR追加処理
; スレッドが作成された直後に呼ばれる
; 排他制御情報を作成する
;<d0.w:作成されたスレッド番号
dosOpenPr::
movem.l d0-d2/a0-a2,-(sp)
move.w d0,d1
beq dosOpenPrEnd ;念のため
tst.l (xTable,d1.w*4)
bpl dosOpenPrEnd ;念のため
subq.w #1,d0 ;メインスレッドの分を引く
mulu.w #xSize2,d0
lea.l ([exclusiveStart],d0.l),a2 ;排他制御情報の先頭
move.l a2,(xTable,d1.w*4)
;<a2.l:新しいスレッドの排他制御情報のアドレス
;FPUの状態を作成する
movea.l a2,a0
moveq.l #120/4-1,d2
@@: clr.l (a0)+ ;すべてクリア
dbra d2,@b
move.w #$6000,(xFsave+2,a2) ;NULL
;標準ハンドラを作成する
moveq.l #0,d2
1: move.w d2,d0
bsr callDup ;現在の標準ハンドラを複製する
bpl 2f
moveq.l #-1,d0 ;排他制御情報の標準ハンドラが-1のときは,
;メインスレッドの排他制御情報を使う
2: move.w d0,(xStdin,a2,d2.w*2)
addq.w #1,d2
cmp.w #5,d2
blo 1b
;標準ハンドラ変換テーブルを作成する
movea.l stdHdlDup0,a0 ;現在の標準ハンドラ変換テーブル
lea.l (xDup0Table,a2),a1
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.w (a0)+,(a1)+
;ドライブ管理テーブルのアドレスを設定し,テーブルの本体を作成する
lea.l (xDriveTable,a2),a1 ;ドライブ管理テーブルの先頭
move.l a1,(xDriveTablePtr,a2) ;ドライブ管理テーブルのアドレス
movea.l $1C38.w,a0 ;現在のドライブ管理テーブル
moveq.l #1,d0
add.b $1C74.w,d0 ;ドライブ管理テーブルの個数
mulu.w #dSize,d0 ;ドライブ管理テーブルのサイズ
lsr.w #1,d0
subq.w #1,d0
@@: move.w (a0)+,(a1)+ ;現在のドライブ管理テーブルをコピーする
dbra d0,@b
;カレントドライブを作成する
move.b $1C15.w,(xCurrentDrive,a2) ;現在のカレントドライブ
;breakのモードを作成する
move.b #2,(xBreakMode,a2) ;常にkill
dosOpenPrEnd:
movem.l (sp)+,d0-d2/a0-a2
rts
;----------------------------------------------------------------
;_KILL_PR追加処理
; スレッドが削除された直後に呼ばれる
; 排他制御情報を破棄する
;<d0.w:削除されたスレッド番号-1
dosKillPr::
addq.w #1,d0
;<d0.w:スレッド番号
bsr killExclusive ;排他制御情報を破棄する
subq.w #1,d0
rts
;----------------------------------------------------------------
;_CHANGE_PR追加処理
; スレッドが切り替わった直後に呼ばれる
; 排他制御情報を切り替える
;<d0.w:次のスレッド番号
dosChangePr::
movem.l d0-d2/a0-a3,-(sp)
;排他制御情報の保存
move.w currentThreadId,d1 ;現在のスレッド
cmp.w d1,d0 ;念のため
beq dosChangePrEnd
move.w d0,currentThreadId ;次のスレッド
move.l (xTable,d1.w*4),d0 ;現在の排他制御情報の先頭
bmi dosChangePrLoad ;念のため
movea.l d0,a2
;<a2.l:現在の排他制御情報の先頭
;FPUの状態を保存する
fsave (xFsave,a2)
fmovem.l fpcr/fpsr/fpiar,(xFpcr,a2)
fmovem.x fp0-fp7,(xFp0,a2)
;標準ハンドラを保存する
moveq.l #0,d2
1: move.w (xStdin,a2,d2.w*2),d0
bmi 2f
move.w d2,d1
bsr dup2
2: addq.w #1,d2
cmp.w #5,d2
blo 1b
;標準ハンドラ変換テーブルを保存する
movea.l stdHdlDup0,a0 ;標準ハンドラ変換テーブル
lea.l (xDup0Table,a2),a1
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.w (a0)+,(a1)+
;ドライブ管理テーブルのアドレスを保存する(念のため)
move.l $1C38.w,(xDriveTablePtr,a2)
;カレントドライブを保存する
move.b $1C15.w,(xCurrentDrive,a2)
;breakのモードを保存する
move.b $1C12.w,(xBreakMode,a2)
;排他制御情報の再生
dosChangePrLoad:
move.w currentThreadId,d0 ;次のスレッド番号
beq dosChangePrMain
move.l (xTable,d0.w*4),d0 ;次のスレッドの排他制御情報
bmi dosChangePrMain ;次のスレッドの排他制御情報がなければ,
;メインスレッドの排他制御情報を使う
movea.l d0,a2
lea.l mainExclusive,a3 ;メインスレッドの排他制御情報
;<a2.l:次のスレッドの排他制御情報のアドレス
;<a3.l:メインスレッドの排他制御情報のアドレス
;FPUの状態を再生する
fmovem.x (xFp0,a2),fp0-fp7
fmovem.l (xFpcr,a2),fpcr/fpsr/fpiar
frestore (xFsave,a2)
;標準ハンドラを再生する
moveq.l #0,d2
1: move.w d2,d0
move.w (xStdin,a2,d2.w*2),d1
bpl 2f
move.w (xStdin,a3,d2.w*2),d1
2: bsr dup2
addq.w #1,d2
cmp.w #5,d2
blo 1b
;標準ハンドラ変換テーブルを再生する
lea.l (xDup0Table,a2),a0
movea.l stdHdlDup0,a1 ;標準ハンドラ変換テーブル
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.w (a0)+,(a1)+
;ドライブ管理テーブルを再生する
move.l (xDriveTablePtr,a2),$1C38.w
;カレントドライブを再生する
move.b (xCurrentDrive,a2),$1C15.w
;breakのモードを再生する
move.b #2,$1C12.w ;ここはサブスレッドのみなので常にkill
;
dosChangePrEnd:
movem.l (sp)+,d0-d2/a0-a3
rts
;メインスレッドの排他制御情報を再生する
dosChangePrMain:
bsr loadMainExclusive
bra dosChangePrEnd
;----------------------------------------------------------------
;排他制御情報を破棄する
; 破棄した後、一旦メインスレッドの排他制御情報を再生する
;<d0.w:スレッド番号
killExclusive:
movem.l d0-d2/a2,-(sp)
move.w d0,d1
beq killExclusiveEnd ;メインスレッドの排他制御情報は破棄できない
move.l (xTable,d1.w*4),d0
bmi killExclusiveEnd ;排他制御情報が存在しない
move.l #-1,(xTable,d1.w*4) ;排他制御情報を破棄する
movea.l d0,a2 ;排他制御情報の先頭
;<a2.l:排他制御情報のアドレス
;標準ハンドラを破棄する
moveq.l #0,d2
1: move.w (xStdin,a2,d2.w*2),d0
bmi 2f
bsr callClose
2: addq.w #1,d2
cmp.w #5,d2
blo 1b
;メインスレッドの排他制御情報を再生する
bsr loadMainExclusive
;
killExclusiveEnd:
movem.l (sp)+,d0-d2/a2
rts
;----------------------------------------------------------------
;メインスレッドの排他制御情報を再生する
loadMainExclusive:
movem.l d0/d2/a0-a2,-(sp)
clr.w currentThreadId ;メインスレッドの排他制御情報に移行
lea.l mainExclusive,a2
;<a2.l:メインスレッドの排他制御情報のアドレス
;FPUの状態を再生する
fmovem.x (xFp0,a2),fp0-fp7
fmovem.l (xFpcr,a2),fpcr/fpsr/fpiar
frestore (xFsave,a2)
;標準ハンドラを再生する
moveq.l #0,d2
1: move.w d2,d0
move.w (xStdin,a2,d2.w*2),d1 ;メインスレッドなので負数は有り得ない
bsr dup2
addq.w #1,d2
cmp.w #5,d2
blo 1b
;標準ハンドラ変換テーブルを再生する
lea.l (xDup0Table,a2),a0
movea.l stdHdlDup0,a1 ;標準ハンドラ変換テーブル
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.w (a0)+,(a1)+
;ドライブ管理テーブルを再生する
move.l (xDriveTablePtr,a2),$1C38.w
;カレントドライブを再生する
move.b (xCurrentDrive,a2),$1C15.w
;breakのモードを再生する
move.b (xBreakMode,a2),$1C12.w ;メインスレッドなのでbreakのモードを復元する
;
movem.l (sp)+,d0/d2/a0-a2
rts
;----------------------------------------------------------------
;ハンドラクローズ
; _CLOSEを呼び出す
; ハンドラはHumanのプロセス管理テーブルでクローズする
;<d0.w:ハンドラ番号
;?d0
callClose:
movem.l d1-d7/a0-a6,-(sp)
move.w d0,-(sp)
movea.l sp,a6
movea.l $1C28.w,a0
move.l (a0),-(sp)
move.l $1C20.w,(a0) ;Humanのメモリ管理テーブル
jsr ([$1800+(_CLOSE-$FF00)*4.w])
move.l (sp)+,([$1C28.w])
addq.l #2,sp
movem.l (sp)+,d1-d7/a0-a6
rts
;----------------------------------------------------------------
;ハンドラ複製
; _DUPを呼び出す
; 新しいハンドラはHumanのプロセス管理テーブルでオープンする
;<d0.w:ハンドラ番号
;?d0
callDup:
movem.l d1-d7/a0-a6,-(sp)
move.w d0,-(sp)
movea.l sp,a6
movea.l $1C28.w,a0
move.l (a0),-(sp)
move.l $1C20.w,(a0) ;Humanのメモリ管理テーブル
jsr ([$1800+(_DUP-$FF00)*4.w])
move.l (sp)+,([$1C28.w])
addq.l #2,sp
movem.l (sp)+,d1-d7/a0-a6
tst.l d0
rts
;----------------------------------------------------------------
;強制ハンドラコピー
; _DUP2のエラーチェックをすべて省いたもの
;<d0.w:コピー先のハンドラ番号(オープンされていること)
;<d1.w:コピー元のハンドラ番号(オープンされていること)
;?d0-d1/a0-a1
dup2:
bsr getfcb
subq.b #1,(a0)
move.w d1,d0
move.l a1,d1
bsr getfcb
addq.b #1,(a0)
movea.l d1,a0
move.w (a1),(a0)
rts
;----------------------------------------------------------------
;ハンドラ番号からFCBテーブルのアドレスを求める
; _GETFCBのエラーチェックをすべて省いたもの
;<d0.w:ハンドラ番号
;>a0.l:FCBテーブル
;>a1.l:ハンドラFCB変換テーブル上のアドレス
;*a0-a1,?d0
getfcb:
movea.l stdHdlToFcb,a1 ;ハンドラ番号=0~5のハンドラFCB変換テーブル
cmp.w #6,d0
bcs @f
subq.w #6,d0
movea.l $1C2C.w,a1 ;ハンドラFCB変換テーブルの先頭(1個2バイト)
@@: add.w d0,d0
adda.w d0,a1
move.w (a1),d0
ext.w d0
movea.l stdFcbTable,a0 ;FCB番号=0~5のFCBテーブル
cmp.w #6,d0
bcs @f
subq.w #6,d0
movea.l $1C30.w,a0 ;FCBテーブルの先頭(1個96バイト)
@@: mulu.w #96,d0
adda.w d0,a0
rts