misc/060tsys/t19himem.s- Source code ソースコード - XEiJ - STUDIO KAMADA
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

STUDIO KAMADA
Copyright © 1999-2026 Makoto Kamada