misc/060tsys/t19himem.s
;----------------------------------------------------------------
;
; _HIMEM
;
;----------------------------------------------------------------
.include t02const.equ
.include t08debug.equ
.include t09version.equ
;__DEBUG__ equ 1
;TS16_VERSION
; TS16DRV.Xでのバージョン
; TS16DRV.Xの最後のバージョンが$12なので、$13にしておく
TS16_VERSION equ $13
.cpu 68060
;----------------------------------------------------------------
;IOCS _HIMEM($F8) ハイメモリ操作
; TS-6BE16の添付ディスクに入っているHIMEM.SYS v1.0とほぼ上位互換
; 拡張メモリTS-6BE16管理ドライバ(TS16DRV.X)とほぼ上位互換
;<d1.w:コマンドコード
; 1 HIMEM_MALLOC
; ブロックの確保
; 下位アドレスから確保する
; <d2.l:確保するブロックのサイズ
; >d0.l:0=成功,-1=失敗
; >a1.l:0=失敗,0以外=確保したブロックのユーザ領域の先頭
; 2 HIMEM_FREE
; ブロックの開放
; <d2.l:開放するブロックのユーザ領域の先頭
; 0=実行中のプロセスが確保したブロックをすべて開放
; >d0.l:0=成功,-1=失敗
; 3 HIMEM_GETSIZE
; 確保できるサイズの取得
; >d0.l:確保できるサイズの合計
; >d1.l:一度に確保できる最大のサイズ
; 4 HIMEM_RESIZE
; ブロックのサイズ変更
; ブロックは移動しない
; 新しいサイズが0ならばブロックを開放する
; <d2.l:サイズを変更するブロックのユーザ領域の先頭
; <d3.l:新しいサイズ(0=ブロックを開放する)
; >d0.l:0=成功,-1=失敗
; 以降のコールはHIMEM.SYS v1.0にはない
; 5 HIMEM_VERSION
; _HIMEMのバージョンの取得
; >d0.l:'060T'
; >d1.l:バージョン
; 6 HIMEM_CALLOC
; 配列のためのブロックの確保
; 下位アドレスから確保する
; 確保したブロックは0で初期化される
; <d2.l:配列要素数
; <d3.l:配列要素サイズ
; >d0.l:0=成功,-1=失敗
; >a1.l:0=失敗,0以外=確保したブロックのユーザ領域の先頭
; 7 HIMEM_REALLOC
; ブロックのサイズ変更
; ブロックが移動することがある
; 移動するとき新しいブロックは下位から確保する
; 移動してもブロックを確保したプロセスは変化しない
; 新しいサイズが0ならばブロックを開放する
; <d2.l:サイズを変更するブロックのユーザ領域の先頭
; <d3.l:新しいサイズ(0=ブロックを開放する)
; >d0.l:0=成功,-1=失敗
; >a1.l:0=失敗,0以外=移動後のブロックのユーザ領域の先頭
; 8 HIMEM_MALLOC2
; ブロックの確保
; <d2.l:確保するサイズ
; <d3.w:bit15=プロセス指定フラグ
; 0 実行中のプロセス
; 1 d4.lを親プロセスとして使用する
; 下位8bit=モード
; 0 下位から
; 1 必要最小ブロックから
; 2 上位から
; 3 最大ブロックから
; <d4.l:(d3.wのbit15が1のとき)親プロセスのメモリ管理テーブル
; >d0.l:0=成功,$81xxxxxx=確保できる最大のサイズ,$82000000=まったく確保できない
; >a1.l:0=失敗,0以外=確保したブロックのユーザ領域の先頭
; 9 HIMEM_PSFREE
; 特定のプロセスが確保したブロックの開放
; 子プロセスが確保したブロックも開放する
; <d2.l:開放するブロックを確保したプロセスのメモリ管理テーブル
; >d0.l:0=成功,-1=失敗
; 10 HIMEM_GETAREA
; _HIMEMでアクセスできるメモリ空間の取得
; >d0.l:メモリ空間の先頭(先頭のブロックのヘッダ),-1=失敗
; >d1.l:メモリ空間の末尾+1,-1=失敗
;?d0,d1-d7/a0-a6は返却に使われるものを除いて破壊されない
.dc.b '060T'
.dc.b 'TS16DRV',TS16_VERSION
.dc.b 'HIMEM',0
iocsHimem::
cmp.w #(himemJumpTableEnd-himemJumpTable)/4,d1
bcc himemUnknownCall
jmp ([himemJumpTable,pc,d1.w*4])
himemReserved:
himemUnknownCall:
moveq.l #-1,d0
rts
himemJumpTable:
.dc.l himemReserved
.dc.l himemMalloc
.dc.l himemFree
.dc.l himemGetSize
.dc.l himemResize
.dc.l himemVersion
.dc.l himemCalloc
.dc.l himemRealloc
.dc.l himemMalloc2
.dc.l himemPsfree
.dc.l himemGetArea
himemJumpTableEnd:
;----------------------------------------------------------------
;_HIMEM 1 ブロックの確保
; 下位アドレスから確保する
;<d2.l:確保するブロックのサイズ
;>d0.l:0=成功,-1=失敗
;>a1.l:0=失敗,0以外=確保したブロックのユーザ領域の先頭
himemMalloc::
debug '|himemMalloc in (size)=',1,d2
movem.l d4/a4-a5,-(sp)
bsr himemAreaSet
bmi himemMallocFailed
;<a4.l:メモリ空間の先頭(先頭のブロックのヘッダ)
;<a5.l:メモリ空間の末尾+1(16バイトアラインメント)
bsr getProc
;<d4.l:実行中のプロセスのメモリ管理テーブル
bsr malloc20 ;ブロックの確保(下位から)
;<d0.l:0=成功,$8xxxxxxx=確保できる最大のサイズ
;<a1.l:0=失敗,0以外=確保したブロックのユーザ領域の先頭
bpl himemMallocEnd
moveq.l #-1,d0
himemMallocEnd:
debug '|himemMalloc out (err,ptr)=',2,d0,a1
movem.l (sp)+,d4/a4-a5
rts
himemMallocFailed:
suba.l a1,a1
bra himemMallocEnd
;----------------------------------------------------------------
;_HIMEM 2 ブロックの開放
;<d2.l:開放するブロックのユーザ領域の先頭
; 0=実行中のプロセスが確保したブロックをすべて開放
;>d0.l:0=成功,-1=失敗
himemFree::
debug '|himemFree in (ptr)=',1,d2
movem.l a4-a5,-(sp)
bsr himemAreaSet
bmi himemFreeEnd
;<a4.l:メモリ空間の先頭(先頭のブロックのヘッダ)
;<a5.l:メモリ空間の末尾+1(16バイトアラインメント)
tst.l d2
beq himemFreeProc ;実行中のプロセスが確保したブロックをすべて開放
bsr free
;<d0.l:0=成功,-1=ヘッダが見つからない
himemFreeEnd:
debug '|himemFree out (err)=',1,d0
movem.l (sp)+,a4-a5
rts
;実行中のプロセスが確保したブロックをすべて開放
himemFreeProc:
move.l d4,-(sp)
bsr getProc
;<d4.l:実行中のプロセスのメモリ管理テーブル
bsr psfree
;<d0.l:0(常に成功する)
move.l (sp)+,d4
tst.l d0
bra himemFreeEnd
;----------------------------------------------------------------
;_HIMEM 3 確保できるサイズの取得
;>d0.l:確保できるサイズの合計
;>d1.l:一度に確保できる最大のサイズ
;*d0-d1
himemGetSize::
debug '|himemGetSize in',0
movem.l a4-a5,-(sp)
bsr himemAreaSet
bmi himemGetSizeFailed
;<a4.l:メモリ空間の先頭(先頭のブロックのヘッダ)
;<a5.l:メモリ空間の末尾+1(16バイトアラインメント)
bsr getSize
;<d0.l:確保できるサイズの合計
;<d1.l:一度に確保できる最大のサイズ
himemGetSizeEnd:
debug '|himemGetSize out (ttl,max)=',2,d0,d1
movem.l (sp)+,a4-a5
rts
himemGetSizeFailed:
moveq.l #0,d0
moveq.l #0,d1
bra himemGetSizeEnd
;----------------------------------------------------------------
;_HIMEM 4 ブロックのサイズ変更
; ブロックは移動しない
; 新しいサイズが0ならばブロックを開放する
;<d2.l:サイズを変更するブロックのユーザ領域の先頭
;<d3.l:新しいサイズ(0=ブロックを開放する)
;>d0.l:0=成功,-1=失敗
;*d0
himemResize::
debug '|himemResize in (ptr,size)=',2,d2,d3
movem.l a4-a5,-(sp)
bsr himemAreaSet
bmi himemResizeEnd
;<a4.l:メモリ空間の先頭(先頭のブロックのヘッダ)
;<a5.l:メモリ空間の末尾+1(16バイトアラインメント)
bsr resizeOrFree
;<d0.l:0=成功,-1=ヘッダが見つからない,$8xxxxxxx=確保できる最大のサイズ
bpl himemResizeEnd
moveq.l #-1,d0
himemResizeEnd:
debug '|himemResize out (err)=',1,d0
movem.l (sp)+,a4-a5
rts
;----------------------------------------------------------------
;_HIMEM 5 _HIMEMのバージョンの取得
;>d0.l:'060T'
;>d1.l:バージョン
;*d0-d1
himemVersion::
move.l #'060T',d0
move.l #VERSION,d1
rts
;----------------------------------------------------------------
;_HIMEM 6 配列のためのブロックの確保
; 下位アドレスから確保する
; 確保したブロックは0で初期化される
;<d2.l:配列要素数
;<d3.l:配列要素サイズ
;>d0.l:0=成功,-1=失敗
;>a1.l:0=失敗,0以外=確保したブロックのユーザ領域の先頭
himemCalloc::
debug '|himemCalloc in (cnt,size)=',2,d2,d3
movem.l d1-d2/d4/a2/a4-a5,-(sp)
bsr himemAreaSet
bmi himemCallocFailed
;<a4.l:メモリ空間の先頭(先頭のブロックのヘッダ)
;<a5.l:メモリ空間の末尾+1(16バイトアラインメント)
move.l d2,d0
move.l d3,d1
bsr imul ;32bit×32bit→64bit乗算(符号なし)
tst.l d0
bne himemCallocFailed ;オーバーフロー
move.l d1,d2
bmi himemCallocFailed ;オーバーフロー
bsr getProc
;<d4.l:実行中のプロセスのメモリ管理テーブル
bsr malloc20 ;ブロックの確保(下位から)
;<d0.l:0=成功,$8xxxxxxx=確保できる最大のサイズ
;<a1.l:0=失敗,0以外=確保したブロックのユーザ領域の先頭
bmi himemCallocFailed ;確保できない
movea.l a1,a2 ;確保したブロックのユーザ領域の先頭
subq.l #1,d2
bcs himemCallocDone ;サイズが0
moveq.l #0,d0
lsr.l #4,d2 ;(サイズ-1)/16=(サイズ+15)/16-1
swap.w d2
himemCallocClear1:
swap.w d2
himemCallocClear0:
move.l d0,(a2)+
move.l d0,(a2)+
move.l d0,(a2)+
move.l d0,(a2)+
dbra d2,himemCallocClear0
swap.w d2
dbra d2,himemCallocClear1
himemCallocDone:
moveq.l #0,d0
himemCallocEnd:
debug '|himemCalloc out (err,ptr)=',2,d0,a1
movem.l (sp)+,d1-d2/d4/a2/a4-a5
rts
himemCallocFailed:
suba.l a1,a1
moveq.l #-1,d0
bra himemCallocEnd
;----------------------------------------------------------------
;_HIMEM 7 ブロックのサイズ変更
; ブロックが移動することがある
; 移動するとき新しいブロックは下位から確保する
; 移動してもブロックを確保したプロセスは変化しない
; 新しいサイズが0ならばブロックを開放する
;<d2.l:サイズを変更するブロックのユーザ領域の先頭
;<d3.l:新しいサイズ(0=ブロックを開放する)
;>d0.l:0=成功,-1=失敗
;>a1.l:0=失敗,0以外=移動後のブロックのユーザ領域の先頭
himemRealloc::
debug '|himemRealloc in (ptr,size)=',2,d2,d3
movem.l d1-d2/a2/a4-a5,-(sp)
bsr himemAreaSet
bmi himemReallocFailed
;<a4.l:メモリ空間の先頭(先頭のブロックのヘッダ)
;<a5.l:メモリ空間の末尾+1(16バイトアラインメント)
bsr reallocOrFree
;>d0.l:0=成功,$8xxxxxxx=確保できる最大のサイズ
;>a1.l:0=失敗,0以外=移動後のブロックのユーザ領域の先頭
bmi himemReallocFailed
himemReallocEnd:
debug '|himemRealloc out (err,ptr,)=',2,d0,a1
movem.l (sp)+,d1-d2/a2/a4-a5
rts
himemReallocFailed:
suba.l a1,a1
moveq.l #-1,d0
bra himemReallocEnd
;----------------------------------------------------------------
;_HIMEM 8 ブロックの確保
;<d2.l:確保するサイズ
;<d3.w:bit15=プロセス指定フラグ
; 0 実行中のプロセス
; 1 d4.lを親プロセスとして使用する
; 下位8bit=モード
; 0 下位から
; 1 必要最小ブロックから
; 2 上位から
; 3 最大ブロックから
;<d4.l:(d3.wのbit15が1のとき)親プロセスのメモリ管理テーブル
;>d0.l:0=成功,$8xxxxxxx=確保できる最大のサイズ
;>a1.l:0=失敗,0以外=確保したブロックのユーザ領域の先頭
;*d0/a1
himemMalloc2::
debug '|himemMalloc2 in (size,mode,proc)=',3,d2,d3,d4
movem.l d4/a4-a5,-(sp)
bsr himemAreaSet
bmi himemMalloc2Failed
;<a4.l:メモリ空間の先頭(先頭のブロックのヘッダ)
;<a5.l:メモリ空間の末尾+1(16バイトアラインメント)
move.w d3,d0
bmi @f
bsr getProc
@@:
;<d4.l:実行中のプロセスのメモリ管理テーブル
and.w #$00FF,d0
cmp.w #4,d0
bcc himemMalloc2Failed
jsr ([malloc2Table,pc,d0.w*4]) ;ブロックの確保
;<d0.l:0=成功,$8xxxxxxx=確保できる最大のサイズ
;<a1.l:0=失敗,0以外=確保したブロックのユーザ領域の先頭
bpl himemMalloc2End
moveq.l #-1,d0
himemMalloc2End:
debug '|himemMalloc2 out (err,ptr)=',2,d0,a1
movem.l (sp)+,d4/a4-a5
rts
himemMalloc2Failed:
suba.l a1,a1
moveq.l #-1,d0
bra himemMalloc2End
;----------------------------------------------------------------
;_HIMEM 9 特定のプロセスが確保したブロックの開放
; 子プロセスが確保したブロックも開放する
;<d2.l:開放するブロックを確保したプロセスのメモリ管理テーブル
;>d0.l:0=成功,-1=失敗
;*d0
himemPsfree::
debug '|himemPsfree in (proc)=',1,d2
movem.l d4/a4-a5,-(sp)
bsr himemAreaSet
bmi himemPsfreeEnd
;<a4.l:メモリ空間の先頭(先頭のブロックのヘッダ)
;<a5.l:メモリ空間の末尾+1(16バイトアラインメント)
move.l d2,d4
;<d4.l:開放するブロックを確保したプロセスのメモリ管理テーブル
bsr psfree
;<d0.l:0(常に成功する)
himemPsfreeEnd:
debug '|himemPsfree out (err)=',1,d0
movem.l (sp)+,d4/a4-a5
rts
;----------------------------------------------------------------
;_HIMEM 10 _HIMEMでアクセスできるメモリ空間の取得
;>d0.l:メモリ空間の先頭(先頭のブロックのヘッダ),-1=失敗
;>d1.l:メモリ空間の末尾+1,-1=失敗
;*d0-d1
himemGetArea::
debug '|himemGetArea in',0
movem.l a4-a5,-(sp)
bsr himemAreaSet
bmi himemGetAreaFailed
;<a4.l:メモリ空間の先頭(先頭のブロックのヘッダ)
;<a5.l:メモリ空間の末尾+1(16バイトアラインメント)
move.l a4,d0
move.l a5,d1
;<d0.l:メモリ空間の先頭(先頭のブロック)
;<d1.l:メモリ空間の末尾+1
himemGetAreaEnd:
debug '|himemGetArea out (top,btm)=',2,d0,d1
movem.l (sp)+,a4-a5
rts
himemGetAreaFailed:
moveq.l #-1,d0
moveq.l #-1,d1
bra himemGetAreaEnd
;----------------------------------------------------------------
;----------------------------------------------------------------
;拡張メモリ空間をアクセスできるか調べる
; 新しいmpusw.rは_HIMEM使用中に68000モードに切り替えられないようになっている
;>d0.l:0=成功,-1=失敗
;>a4.l:メモリ空間の先頭(先頭のブロックのヘッダ)
;>a5.l:メモリ空間の末尾+1(16バイトアラインメント)
himemAreaSet::
tst.l himemAreaSize
beq 9f ;拡張メモリ空間使用不可
movea.l himemAreaStart,a4
movea.l himemAreaEnd,a5
moveq.l #0,d0
rts
9: moveq.l #-1,d0
rts
;----------------------------------------------------------------
;32bit×32bit→64bit乗算(符号なし)
;<d0.l:被乗数
;<d1.l:乗数
;>d0.l:結果(上位)
;>d1.l:結果(下位)
;*d0-d1
imul::
movem.l d2-d4,-(sp)
move.l d0,d3
move.l d1,d4
swap.w d3
swap.w d4
move.w d3,d2
mulu.w d1,d2
mulu.w d0,d1
mulu.w d4,d0
mulu.w d3,d4
add.l d2,d0
clr.w d3
addx.w d3,d3
swap.w d1
add.w d0,d1
swap.w d1
move.w d3,d0
swap.w d0
addx.l d4,d0
movem.l (sp)+,d2-d4
rts