misc/060tsys/t13sysstat.s
;----------------------------------------------------------------
;
;	IOCS _SYS_STAT
;
;----------------------------------------------------------------

	.include	t01dos.equ
	.include	t02const.equ
	.include	t08debug.equ
	.include	t09version.equ

;__DEBUG__	equ	1

	.cpu	68060

;----------------------------------------------------------------
;IOCS _SYS_STAT($AC)
;システム環境の取得と設定
;<d1.w:モード
;	$0000	MPUステータスの取得
;		>d0.l:MPUステータス
;			bit0~7		MPUの種類(6=68060)
;			bit14		MMUの有無(0=なし,1=あり)
;			bit15		FPUの有無(0=なし,1=あり)
;			bit16~31	クロックスピード*10
;	$0001	キャッシュ状態の取得
;		>d0.l:現在のキャッシュ状態
;			bit0	命令キャッシュの状態(0=OFF,1=ON)
;			bit1	データキャッシュの状態(0=OFF,1=ON)
;	$0002	キャッシュの状態をSRAM設定値にする
;		>d0.l:設定後のキャッシュ状態
;			bit0	命令キャッシュの状態(0=OFF,1=ON)
;			bit1	データキャッシュの状態(0=OFF,1=ON)
;	$0003	キャッシュのプッシュおよび無効化
;	$0004	キャッシュ設定
;		<d2.b:キャッシュの設定
;			bit0	命令キャッシュの状態(0=OFF,1=ON)
;			bit1	データキャッシュの状態(0=OFF,1=ON)
;		>d0.l:設定前のキャッシュ状態
;			bit0	命令キャッシュの状態(0=OFF,1=ON)
;			bit1	データキャッシュの状態(0=OFF,1=ON)
;	$4000	ローカルメモリの情報の取得
;		>d0.l:ローカルメモリのバイト数
;			0	ローカルメモリがない
;			-1	エラー
;		>a1.l:ローカルメモリの先頭の物理アドレス
;	$4001	物理アドレスがローカルメモリを指しているか調べる
;		<a1.l:物理アドレス
;		>d0.l:結果
;			0	ローカルメモリを指している
;			-1	ローカルメモリではない
;	$4002	論理アドレスがローカルメモリを指しているか調べる
;		<a1.l:論理アドレス
;		>d0.l:結果
;			-1	無効な論理アドレスまたはローカルメモリではない
;			0	ローカルメモリを指している
;	$4003	論理アドレスがDMA転送可能かどうか調べる
;		<a1.l:論理アドレス
;		>d0.l:結果
;			-1	DMA転送不可能
;			0	DMA転送可能
;	$4004	論理アドレスの範囲がDMA転送可能かどうか調べる
;		<d2.l:サイズ
;		<a1.l:論理アドレス
;		>d0.l:結果
;			-1	DMA転送不可能
;			0	DMA転送可能
;	$5000	実行プログラムをローカルメモリにロードして実行する
;		<a1.l:実行ファイル名
;		<a2.l:コマンドライン
;		<a3.l:環境のアドレス
;		>d0.l:_EXECの返却値
;	$5001	現在実行中のプロセスを終了してから,
;		指定された実行プログラムをローカルメモリにロードして実行し,
;		親プロセスに復帰する
;		<d2.w:モード
;			bit0	1=ローカルメモリが不足していたらメインメモリで実行する
;		<a1.l:実行ファイル名
;		<a2.l:コマンドライン
;		<a3.l:環境のアドレス(0=親プロセスの環境,実行中のプロセスの領域は不可)
;		復帰しない(_EXECの返却値を親プロセスに返す)
;	$8000	バージョン取得
;		>d0.l:バージョン番号
;		>a1.l:'060T'
;	$8001	指定論理アドレスのキャッシュモードの取得
;		<a1.l:論理アドレス
;		>d0.l:キャッシュモード
;			0	キャッシュ許可,ライトスルー
;			1	キャッシュ許可,コピーバック
;			2	キャッシュ禁止,ストアバッファ禁止
;			3	キャッシュ禁止,ストアバッファ許可
;			-1	エラー(ページデスクリプタがない,非常駐)
;	$8004	指定論理アドレスのキャッシュモードの設定(ページ単位)
;		<d2.l:キャッシュモード
;			0	キャッシュ許可,ライトスルー
;			1	キャッシュ許可,コピーバック
;			2	キャッシュ禁止,ストアバッファ禁止
;			3	キャッシュ禁止,ストアバッファ許可
;		<a1.l:論理アドレス
;		>d0.l:変更前のキャッシュモード
;			-1	エラー(ページデスクリプタがない,非常駐)
;	$C000	互換モード
;		>d0.l:
;			0	正常終了
;			-1	既に互換モードになっている
;	$C001	拡張モード
;		>d0.l:
;			0	正常終了
;			-1	既に拡張モードになっている
;	$C002	現在のモードを取得する
;		>d0.l:モード
;			0	互換モード
;			1	拡張モード
;	$C003	モード切り替え時シグナルの設定
;		<a1.l:シグナルハンドラ
;		>d0.l:
;			0	正常終了
;			-1	シグナル数オーバー
;	$C004	モード切り替え時シグナルの解除
;		<a1.l:シグナルハンドラ
;		>d0.l:
;			0	正常終了
;			-1	不正なシグナルハンドラ
;	$C005	メモリ情報テーブルの取得
;		<a1.l:テーブル格納アドレス
;	$C006	キャッシュとスーパースケーラの状態の取得
;		>d0.l:キャッシュとスーパースケーラの状態
;			bit0	データキャッシュの状態(0=OFF,1=ON)
;			bit1	命令キャッシュの状態(0=OFF,1=ON)
;			bit2	ストアバッファの状態(0=OFF,1=ON)
;			bit3	ブランチキャッシュの状態(0=OFF,1=ON)
;			bit4	スーパースケーラの状態(0=OFF,1=ON)
;	$C007	キャッシュとスーパースケーラの状態の設定
;		<d2.l:キャッシュとスーパースケーラの状態
;			bit0	データキャッシュの状態(0=OFF,1=ON)
;			bit1	命令キャッシュの状態(0=OFF,1=ON)
;			bit2	ストアバッファの状態(0=OFF,1=ON)
;			bit3	ブランチキャッシュの状態(0=OFF,1=ON)
;			bit4	スーパースケーラの状態(0=OFF,1=ON)
;		>d0.l:変更前のキャッシュとスーパースケーラの状態
;	$F000	論理アドレスから物理アドレスを求める
;		<a1.l:論理アドレス
;		>d0.l:物理アドレス
;			$00000000~$3FFFFFFF	物理アドレス
;			-1	エラー(ページデスクリプタがない,非常駐)
;	$F001	アドレス変換の設定(ページ単位)
;		<d2.l:物理ページアドレス
;		<a1.l:論理ページアドレス
;		>d0.l:ページ属性
;			-1	エラー(ページデスクリプタがない,非常駐,デスクリプタの領域が不足している)
;	$F002	論理ページの属性の取得と設定
;		<d2.l:ページ属性
;			-1	取得のみ
;		<a1.l:論理ページアドレス
;		>d0.l:変更前のページ属性
;			-1	エラー
	.dc.l	VERSION
	.dc.l	'060T'
iocsSysStat::
	movem.l	d1-d2/a0,-(sp)
	cmpi.b	#4,$0CBC.w
	bhs	10f			;040/060はすべて有効
	cmp.w	#4,d1
	bhi	40f			;000/010/020/030はモード0-4以外はエラー
	cmpi.b	#2,$0CBC.w
	bhs	10f			;020/030はモード0-4は有効
	tst.w	d1
	bne	40f			;000/010はモード0以外はエラー
10:	lea.l	100f(pc),a0
20:	move.w	(a0)+,d0		;オフセット
	beq	40f			;見つからなかった
	cmp.w	(a0)+,d1		;番号
	bne	20b
	jsr	(a0,d0.w)
30:	movem.l	(sp)+,d1-d2/a0
	rts

40:	moveq.l	#-1,d0
	bra	30b

100:	.dc.w	mpu_status-(*+4),$0000
	.dc.w	cache_get-(*+4),$0001
	.dc.w	cache_default-(*+4),$0002
	.dc.w	cache_flush-(*+4),$0003
	.dc.w	cache_set-(*+4),$0004
	.dc.w	sysStat_4000-(*+4),$4000
	.dc.w	sysStat_4001-(*+4),$4001
	.dc.w	sysStat_4002-(*+4),$4002
	.dc.w	sysStat_4003-(*+4),$4003
	.dc.w	sysStat_4004-(*+4),$4004
	.dc.w	sysStat_5000-(*+4),$5000
	.dc.w	sysStat_5001-(*+4),$5001
	.dc.w	sysStat_5002-(*+4),$5002
	.dc.w	sysStat_5003-(*+4),$5003
	.dc.w	sysStat_8000-(*+4),$8000
	.dc.w	sysStat_8001-(*+4),$8001
	.dc.w	sysStat_8004-(*+4),$8004
	.dc.w	sysStat_C000-(*+4),$C000
	.dc.w	sysStat_C001-(*+4),$C001
	.dc.w	sysStat_C002-(*+4),$C002
	.dc.w	sysStat_C003-(*+4),$C003
	.dc.w	sysStat_C004-(*+4),$C004
	.dc.w	sysStat_C005-(*+4),$C005
	.dc.w	sysStat_C006-(*+4),$C006
	.dc.w	sysStat_C007-(*+4),$C007
	.dc.w	sysStat_F000-(*+4),$F000
	.dc.w	sysStat_F001-(*+4),$F001
	.dc.w	sysStat_F002-(*+4),$F002
	.dc.w	0

;----------------------------------------------------------------
;$0000	MPUステータス取得
;>d0.l:MPUステータス
;	bit31-16	MPUの動作周波数。MHz値*10
;	bit15		FPU/FPCPの有無。0=なし,1=あり
;	bit14		MMUの有無。0=なし,1=あり
;	bit7-0		MPUの種類。0=68000,1=68010,2=68020,3=68030,4=68040,6=68060
mpu_status::
	moveq.l	#12,d0			;000/010
	cmpi.b #2,$0CBC.w
	blo	10f
	moveq.l	#6,d0			;020/030/040/060
10:	mulu.w	$0CB8.w,d0		;000/010はMHz値*1000/12、020/030/040/060はMHz値*1000/6。MHz値*1000
	add.l	#50,d0
	divu.w	#100,d0			;MHz値*10
	swap.w	d0			;ssssssss ssssssss ........ ........
	clr.w	d0			;ssssssss ssssssss 00000000 00000000
	tst.b	$0CBE.w
	sne.b	d0			;ssssssss ssssssss 00000000 mmmmmmmm
	ror.w	#1,d0			;ssssssss ssssssss m0000000 0mmmmmmm
	tst.b	$0CBD.w
	sne.b	d0			;ssssssss ssssssss m0000000 ffffffff
	ror.w	#1,d0			;ssssssss ssssssss fm000000 0fffffff
	move.b	$0CBC.w,d0		;ssssssss ssssssss fm000000 pppppppp
	rts

;----------------------------------------------------------------
;$0001	キャッシュ取得
;>d0.l:現在のキャッシュの状態
;	bit1	データキャッシュは0=OFF,1=ON
;	bit0	命令キャッシュは0=OFF,1=ON
;	000/010のときは0を返す
cache_get::
	moveq.l	#0,d0
	cmpi.b	#2,$0CBC.w
	blo	30f			;000/010
;020/030/040/060
	movec.l	cacr,d0
	cmpi.b	#4,$0CBC.w
	bhs	10f			;040/060
;020/030
					;........ ........ .......d .......i
	ror.l	#1,d0			;i....... ........ ........ d.......
	rol.b	#1,d0			;i....... ........ ........ .......d
	bra	20f
;040/060
10:					;d....... ........ i....... ........
	swap.w	d0			;i....... ........ d....... ........
	rol.w	#1,d0			;i....... ........ ........ .......d
20:	rol.l	#1,d0			;........ ........ ........ ......di
	and.l	#3,d0			;00000000 00000000 00000000 000000di
30:	rts

;----------------------------------------------------------------
;$0002	キャッシュ設定(SRAM設定値)
;>d0.l:設定後のキャッシュの状態
;	bit1	データキャッシュを0=OFF,1=ONにした
;	bit0	命令キャッシュを0=OFF,1=ONにした
;	000/010のときは0を返す
cache_default::
	move.l	d2,-(sp)
	moveq.l	#0,d2
	move.b	$00ED0090,d2		;キャッシュ設定。------|データ|命令
	bsr	cache_set		;キャッシュ設定
	move.l	(sp)+,d2
	rts

;----------------------------------------------------------------
;$0003	キャッシュフラッシュ
cache_flush::
	cmpi.b	#2,$0CBC.w
	blo	20f			;000/010
;020/030/040/060
	cmpi.b	#4,$0CBC.w
	bhs	10f			;040/060
;020/030
	move.l	d0,-(sp)
	movec.l	cacr,d0
	or.w	#$0808,d0
	movec.l	d0,cacr
	move.l	(sp)+,d0
	bra	20f
;040/060
10:	cpusha	bc
20:	rts

;----------------------------------------------------------------
;$0004	キャッシュ設定
;<d2.l:設定後のキャッシュの状態
;	bit1	データキャッシュを0=OFF,1=ONにする
;	bit0	命令キャッシュを0=OFF,1=ONにする
;	000/010のときは何もしない
;>d0.l:設定前のキャッシュの状態
;	bit1	データキャッシュは0=OFF,1=ONだった
;	bit0	命令キャッシュは0=OFF,1=ONだった
;	000/010のときは0を返す
cache_set::
	moveq.l	#0,d0
	cmpi.b	#2,$0CBC.w
	blo	50f			;000/010
;020/030/040/060
	movem.l	d1-d3,-(sp)
	moveq.l	#3,d3			;d3 00000000 00000000 00000000 00000011
	and.l	d3,d2			;d2 00000000 00000000 00000000 000000di
	ror.l	#1,d2			;   i0000000 00000000 00000000 0000000d
	movec.l	cacr,d0
	cmpi.b	#4,$0CBC.w
	bhs	10f			;040/060
;020/030
					;d0 ........ ........ .......d .......i
	neg.w	d2			;d2 i0000000 00000000 dddddddd dddddddd
	and.w	#$2101.shr.1,d2		;   i0000000 00000000 000d0000 d0000000
	rol.l	#1,d2			;   00000000 00000000 00d0000d 0000000i
	move.l	d0,d1			;d1 ........ ........ .......d .......i
	and.w	#.notw.$2101,d1		;   ........ ........ ..0....0 .......0
	or.w	d2,d1			;   ........ ........ ..d....d .......i
	movec.l	d1,cacr
	ror.l	#1,d0			;d0 i....... ........ ........ d.......
	rol.b	#1,d0			;   i....... ........ ........ .......d
	bra	40f
;040/060
10:					;d0 d....... ........ i....... ........
	ror.w	#1,d2			;d2 i0000000 00000000 d0000000 00000000
	swap.w	d2			;   d0000000 00000000 i0000000 00000000
	move.l	d0,d1			;d1 d....... ........ i....... ........
	and.l	#.not.$80008000,d1	;   0....... ........ 0....... ........
	or.l	d2,d1			;   d....... ........ i....... ........
	movec.l	d1,cacr
	not.l	d2
	and.l	d0,d2			;設定前&~設定後
	bpl	20f
;データキャッシュがON→OFF
	cpusha	dc			;データキャッシュをプッシュして無効化
20:	tst.w	d2
	bpl	30f
;命令キャッシュがON→OFF
	cinva	ic			;命令キャッシュと分岐キャッシュを無効化
30:	swap.w	d0			;d0 i....... ........ d....... ........
	rol.w	#1,d0			;   i....... ........ ........ .......d
40:	rol.l	#1,d0			;   ........ ........ ........ ......di
	and.l	d3,d0			;   00000000 00000000 00000000 000000di
	movem.l	(sp)+,d1-d3
50:	rts

;----------------------------------------------------------------
;$8000	バージョン取得
;>d0.l:バージョン番号
;>a1.l:'060T'
sysStat_8000::
	move.l	#VERSION,d0
	movea.l	#'060T',a1
	rts

;----------------------------------------------------------------
;$8001	指定論理アドレスのキャッシュモードの取得
;<a1.l:論理アドレス
;>d0.l:キャッシュモード
;	0	キャッシュ許可,ライトスルー
;	1	キャッシュ許可,コピーバック
;	2	キャッシュ禁止,ストアバッファ禁止
;	3	キャッシュ禁止,ストアバッファ許可
;	-1	エラー(ページデスクリプタがない,非常駐)
sysStat_8001::
	PUSH_MMU_SFC_DFC	d0
	bsr	getDesc
	bmi	8f			;ページデスクリプタがない
	beq	9f			;非常駐
	and.l	#PD_CM_MASK,d0		;キャッシュモード
	lsr.l	#PD_CM_BIT,d0
8:	POP_SFC_DFC	d1
	rts

9:	moveq.l	#-1,d0
	bra	8b

;----------------------------------------------------------------
;$8004	指定論理アドレスのキャッシュモードの設定(ページ単位)
;<d2.l:キャッシュモード
;	0	キャッシュ許可,ライトスルー
;	1	キャッシュ許可,コピーバック
;	2	キャッシュ禁止,ストアバッファ禁止
;	3	キャッシュ禁止,ストアバッファ許可
;<a1.l:論理アドレス
;>d0.l:変更前のキャッシュモード
;	-1	エラー(ページデスクリプタがない,非常駐)
sysStat_8004::
	PUSH_MMU_SFC_DFC	d0
	bsr	getDesc			;ページデスクリプタを得る
	bmi	8f			;ページデスクリプタがない
	beq	9f			;非常駐
	move.l	d0,d1
	lsl.l	#PD_CM_BIT,d2
	and.l	#PD_CM_MASK,d2		;新しいキャッシュモード
	and.l	#.not.PD_CM_MASK,d1
	or.l	d1,d2
	moves.l	d2,(a0)			;ページデスクリプタを変更する
					;setDescは2箇所以上から参照されていると
					;複製してしまう
	pflusha				;pflush (a1)では
					;TM_USER_DATA,TM_USER_CODE,TM_SUPER_DATA,TM_SUPER_CODE
					;の4つともフラッシュしなければならない
	and.l	#PD_CM_MASK,d0
	lsr.l	#PD_CM_BIT,d0		;変更前のキャッシュモード
	cmp.b	#2,d0
	bcc	8f
;	and.l	#PAGE_MASK,d2
	movea.l	d2,a0
	cpushp	dc,(a0)
	cinvp	bc,(a0)
8:	POP_SFC_DFC	d1
	rts

9:	moveq.l	#-1,d0
	bra	8b

;----------------------------------------------------------------
;$C000	互換モード
;>d0.l:
;	0	正常終了
;	-1	既に互換モードになっている
sysStat_C000::
	moveq.l	#-1,d0
	rts

;----------------------------------------------------------------
;$C001	拡張モード
;>d0.l:
;	0	正常終了
;	-1	既に拡張モードになっている
sysStat_C001::
	tst.b	useJointMode
	beq	9f
	tst.b	jointMode
	bne	9f
	move.l	jointBlockHeader,d0	;Human本体のこともある
	beq	9f
	movea.l	d0,a0
	move.l	himemAreaStart,d0
	move.l	d0,(Next,a0)
	exg.l	d0,a0
	move.l	d0,(Prev,a0)
;;;	clr.l	(Next,a0)		;ここではハイメモリ側を初期化しない
	move.l	himemAreaEnd,$1C00.w
	st.b	jointMode
	moveq.l	#0,d0
	rts

9:	moveq.l	#-1,d0
	rts

;----------------------------------------------------------------
;$C002	現在のモードを取得する
;>d0.l:モード
;	0	互換モード
;	1	拡張モード
sysStat_C002::
	tst.b	jointMode
	bne	@f
	moveq.l	#0,d0
	rts

@@:	moveq.l	#1,d1
	rts

;----------------------------------------------------------------
;$C003	モード切り替え時シグナルの設定
;<a1.l:シグナルハンドラ
;>d0.l:
;	0	正常終了
;	-1	シグナル数オーバー
sysStat_C003::
	moveq.l	#-1,d0
	rts

;----------------------------------------------------------------
;$C004	モード切り替え時シグナルの解除
;<a1.l:シグナルハンドラ
;>d0.l:
;	0	正常終了
;	-1	不正なシグナルハンドラ
sysStat_C004::
	moveq.l	#-1,d0
	rts

;----------------------------------------------------------------
;$C005	メモリ情報テーブルの取得
;<a1.l:テーブル格納アドレス
sysStat_C005::
	suba.l	a1,a1
	moveq.l	#-1,d0
	rts

;----------------------------------------------------------------
;$C006	キャッシュとスーパースケーラの状態の取得
;>d0.l:キャッシュとスーパースケーラの状態
;	bit0	データキャッシュの状態(0=OFF,1=ON)
;	bit1	命令キャッシュの状態(0=OFF,1=ON)
;	bit2	ストアバッファの状態(0=OFF,1=ON)
;	bit3	ブランチキャッシュの状態(0=OFF,1=ON)
;	bit4	スーパースケーラの状態(0=OFF,1=ON)
sysStat_C006::
	moveq.l	#-1,d0
	cmpi.b	#6,$0CBC.w
	bne	90f
	movec.l	pcr,d1
	moveq.l	#1,d0
	and.l	d1,d0
	lsl.l	#8,d0
	movec.l	cacr,d1
	btst.l	#CACR_EBC_BIT,d1
	sne.b	d0
	lsl.l	#1,d0
	btst.l	#CACR_ESB_BIT,d1
	sne.b	d0
	lsl.l	#1,d0
	tst.w	d1	;	btst.l	#CACR_EIC_BIT,d1
	smi.b	d0	;	sne.b	d0
	lsl.l	#1,d0
	tst.l	d1	;	btst.l	#CACR_EDC_BIT,d1
	smi.b	d0	;	sne.b	d0
	lsr.l	#7,d0
90:	rts

;----------------------------------------------------------------
;$C007	キャッシュとスーパースケーラの状態の設定
;	設定後、無条件にキャッシュのプッシュと無効化を行います
;<d2.l:キャッシュとスーパースケーラの状態
;	bit0	データキャッシュの状態(0=OFF,1=ON)
;	bit1	命令キャッシュの状態(0=OFF,1=ON)
;	bit2	ストアバッファの状態(0=OFF,1=ON)
;	bit3	ブランチキャッシュの状態(0=OFF,1=ON)
;	bit4	スーパースケーラの状態(0=OFF,1=ON)
;>d0.l:変更前のキャッシュとスーパースケーラの状態
sysStat_C007::
	moveq.l	#-1,d0
	cmpi.b	#6,$0CBC.w
	bne	90f
	bsr	sysStat_C006
	movec.l	cacr,d1
	and.l	#.not.(CACR_EDC|CACR_ESB|CACR_EBC|CACR_EIC),d1
	lsr.l	#1,d2
	bcc	@f
	bset.l	#CACR_EDC_BIT,d1
@@:	lsr.l	#1,d2
	bcc	@f
	bset.l	#CACR_EIC_BIT,d1
@@:	lsr.l	#1,d2
	bcc	@f
	bset.l	#CACR_ESB_BIT,d1
@@:	lsr.l	#1,d2
	bcc	@f
	bset.l	#CACR_EBC_BIT,d1
@@:	movec.l	d1,cacr
	CACHE_FLUSH	d1
	movec.l	pcr,d1
	lsr.l	#1,d1
	lsr.l	#1,d2
	roxl.l	#1,d1
	movec.l	d1,pcr
90:	rts

;----------------------------------------------------------------
;$F000	論理アドレスから物理アドレスを求める
;<a1.l:論理アドレス
;>d0.l:物理アドレス
;	$00000000~$3FFFFFFF	物理アドレス
;	-1	エラー(ページデスクリプタがない,非常駐)
sysStat_F000::
	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:	POP_SFC_DFC	d1
	rts

9:	moveq.l	#-1,d0
	bra	8b

;----------------------------------------------------------------
;$F001	アドレス変換の設定(ページ単位)
;	変更前の論理ページが有効だった場合は、その論理ページが指していた物理ページに
;		含まれるキャッシュをプッシュおよび無効化します
;	アドレス変換を設定してその変換を有効にします
;<d2.l:物理ページアドレス
;<a1.l:論理ページアドレス
;>d0.l:ページ属性
;	-1	エラー(ページデスクリプタがない,非常駐,デスクリプタの領域が不足している)
sysStat_F001::
	PUSH_MMU_SFC_DFC	d0
	bsr	getDesc
	bmi	9f
	beq	9f
	and.l	pageOffsetMask,d0
	and.l	pageMask,d2
	or.l	d0,d2
	moves.l	d2,(a0)
	pflusha
8:	POP_SFC_DFC	d1
	rts

9:	moveq.l	#-1,d0
	bra	8b

;----------------------------------------------------------------
;$F002	論理ページの属性の取得と設定
;	間接ページデスクリプタは削除されます
;<d2.l:ページ属性
;	0	非常駐
;	-1	取得のみ
;<a1.l:論理ページアドレス
;>d0.l:変更前のページ属性
;	-1	エラー(ページデスクリプタがない,非常駐)
sysStat_F002::
	PUSH_MMU_SFC_DFC	d0
	bsr	getDesc
	bmi	9f
	tst.l	d2
	bmi	3f			;取得のみ
	beq	1f			;非常駐
	move.l	d0,d1
	and.l	pageOffsetMask,d2
	and.l	pageMask,d1
	or.l	d1,d2
	moves.l	d2,(a0)
	bra	2f

1:	bsr	invDesc
	bmi	8f
2:	pflusha
3:	and.l	pageOffsetMask,d0
8:	POP_SFC_DFC	d1
	rts

9:	moveq.l	#-1,d0
	bra	8b

;----------------------------------------------------------------
;$4000	ローカルメモリの情報の取得
;>d0.l:ローカルメモリのバイト数
;	0	ローカルメモリがない
;	-1	エラー
;>a1.l:ローカルメモリの先頭の物理アドレス
sysStat_4000::
	move.l	localMemorySize,d0
	movea.l	localMemoryStart,a1
	rts

;----------------------------------------------------------------
;$4001	物理アドレスがローカルメモリを指しているか調べる
;<a1.l:物理アドレス
;>d0.l:結果
;	0	ローカルメモリを指している
;	-1	ローカルメモリではない
sysStat_4001::
	move.l	a1,d0
	bsr	physicalToLocal
	bmi	8f
	moveq.l	#0,d0
8:	rts

;----------------------------------------------------------------
;$4002	論理アドレスがローカルメモリを指しているか調べる
;<a1.l:論理アドレス
;>d0.l:結果
;	-1	無効な論理アドレスまたはローカルメモリではない
;	0	ローカルメモリを指している
sysStat_4002::
	bsr	sysStat_F000
	bmi	8f
	bsr	physicalToLocal
	bmi	8f
	moveq.l	#0,d0
8:	rts

;----------------------------------------------------------------
;$4003	論理アドレスがDMA転送可能かどうか調べる
;<a1.l:論理アドレス
;>d0.l:結果
;	-1	DMA転送不可能
;	0	DMA転送可能
sysStat_4003::
	moveq.l	#0,d0			;メモリへ書き込み
	move.l	a1,d1			;先頭
	move.l	d1,d2			;末尾+1
	bsr	dmaAccessCheck
	smi.b	d0			;-1=DMA転送不可能,0=DMA転送可能
	extb.l	d0
	rts

;----------------------------------------------------------------
;$4004	論理アドレスの範囲がDMA転送可能かどうか調べる
;<d2.l:サイズ
;<a1.l:論理アドレス
;>d0.l:結果
;	-1	DMA転送不可能
;	0	DMA転送可能
sysStat_4004::
	moveq.l	#0,d0			;メモリへ書き込み
	move.l	a1,d1			;先頭
	add.l	d1,d2			;末尾+1
	bsr	dmaAccessCheck
	smi.b	d0			;-1=DMA転送不可能,0=DMA転送可能
	extb.l	d0
	rts

;----------------------------------------------------------------
;$5000	実行プログラムをローカルメモリにロードして実行する
;<d2.l:モジュール番号*256
;<a1.l:実行ファイル名
;<a2.l:コマンドライン
;<a3.l:環境のアドレス
;>d0.l:_EXECの返却値
sysStat_5000::
	movem.l	d1-d7/a1-a6,-(sp)
	movem.l	a1-a3,-(sp)
	clr.b	d2
	move.w	d2,-(sp)
	st.b	execLoadHigh
	DOS	_EXEC
	clr.b	execLoadHigh
	lea.l	(14,sp),sp
	movem.l	(sp)+,d1-d7/a1-a6
	rts

;----------------------------------------------------------------
;$5001	現在実行中のプロセスを終了してから,
;	指定された実行プログラムをローカルメモリにロードして実行し,
;	親プロセスに復帰する
;<d2.l:モード+モジュール番号*256
;	bit0	1=ローカルメモリが不足していたらメインメモリで実行する
;<a1.l:実行ファイル名
;<a2.l:コマンドライン
;<a3.l:環境のアドレス(0=親プロセスの環境,実行中のプロセスの領域は不可)
;復帰しない(_EXECの返却値を親プロセスに返す)
sysStat_5001::
;実行ファイル名とコマンドラインをコピーする
;(指定された文字列は実行前に壊れる可能性があるため)
  debug '|5001(d2,a1,a2,a3)',4,d2,a1,a2,a3
	lea.l	(5f,pc),a0
	move.w	#255-1,d0
@@:	move.b	(a1)+,(a0)+
	dbeq	d0,@b
	clr.b	(a0)
	movea.l	userAreaWork,a0		;コマンドラインはユーザモードの領域にコピーする必要がある
	cmpi.l	#'#HUP',(-8,a2)
	bne	1f
	cmpi.l	#'AIR'<<8,(-4,a2)
	bne	1f
	move.l	#'#HUP',(a0)+
	move.l	#'AIR'<<8,(a0)+
	move.w	#4096-256-8-1,d0
@@:	move.b	(a2)+,(a0)+
	dbeq	d0,@b
	move.w	#256-1,d0
	bra	2f

1:	clr.l	(a0)+
	clr.l	(a0)+
	move.w	#4096-8-1,d0
2:	move.b	(a2)+,(a0)+
	dbeq	d0,2b
	clr.b	(a0)
;環境のアドレスを保存する
	move.l	a3,7f
;現在のアボート時のsrと_EXITVCを保存する
	movea.l	([$1C28.w]),a0		;現在実行中のプロセスのメモリ管理テーブルの先頭
  debug '|5001(psp)',1,a0
	move.w	(p_Sr,a0),3f		;sr
	move.l	(pExitvc,a0),4f		;_EXITVC
  debugWord '|5001(sr)',1,3f
  debug '|5001(exitvc)',1,4f
;モードを保存する
	move.w	d2,8f
;アボート時のsrと_EXITVCを変更してからプロセスを終了する
	move.w	#$2000,(p_Sr,a0)	;srを変更する
					;060turbo.sysがスーパーバイザ領域にあるので,
					;スーパーバイザモードで戻る必要がある
	move.l	#1f,(pExitvc,a0)	;_EXITVCを変更する
	DOS	_EXIT			;親プロセスに戻る

;親プロセスの_EXECの直後に飛ぶ代わりにここから実行
1:
  debug '|5001(d0)',1,d0
	tst.w	d0
	bne	9f			;アボートしたときはスキップ(念のため)
					;(_EXITで0以外(特に$4000)が返ったとき)
;ローカルメモリにロード
  debug '|5001(try8001)',0
	move.l	7f,-(sp)
	pea.l	([userAreaWork],8)
	pea.l	(5f,pc)
	move.w	#1,-(sp)
	move.b	8f,(sp)			;モジュール番号
	st.b	execLoadHigh
	DOS	_EXEC			;ローカルメモリにロード
	clr.b	execLoadHigh
	lea.l	(14,sp),sp
  debug '|5001(8001)',1,d0
	tst.l	d0
	bpl	2f
	cmp.l	#$FFFF0000,d0
	bcc	9f			;メモリ不足以外のエラー
;メインメモリにロード
	btst.b	#0,8f+1
	beq	9f			;メインメモリは使わない
  debug '|5001(try0001)',0
	move.l	7f,-(sp)
	pea.l	([userAreaWork],8)
	pea.l	(5f,pc)
	move.w	#1,-(sp)
	move.b	8f,(sp)			;モジュール番号
	DOS	_EXEC			;メインメモリにロード
	lea.l	(14,sp),sp
	tst.l	d0
	bmi	9f
;実行
2:
  debug '|5001(loadok)',1,d0
  debug '|5001(try0004)',0
	clr.w	-(sp)			;_EXECの中で再帰する可能性があるので先にスタックに積んでおく
	move.l	4f,-(sp)		;_EXITVC
	move.w	3f,-(sp)		;sr
	move.l	d0,-(sp)
	move.w	#4,-(sp)
	DOS	_EXEC			;実行
	addq.l	#6,sp
  debug '|5001(done)',1,d0
	rte

;何もしないで終了
9:	clr.w	-(sp)
	move.l	4f,-(sp)		;_EXITVC
	move.w	3f,-(sp)		;sr
  debug '|5001(error)',1,d0
	rte

3:	.ds.w	1	;sr
4:	.ds.l	1	;_EXITVC
5:	.ds.b	256	;実行ファイル名
7:	.ds.l	1	;環境のアドレス
8:	.ds.w	1	;モード+モジュール番号*256
	.even

;----------------------------------------------------------------
;$5002	defaultLoadAreaの指定
;<d2.l:ロードするメモリ空間の指定
;	0	下位のみ
;	1	上位のみ
;	2	親と同じ側のみ
;	3	親と反対側のみ
;	4	制限なし,下位優先
;	5	制限なし,上位優先
;	6	制限なし,親と同じ側優先
;	7	制限なし,親と反対側優先
;	8	制限なし,優先なし
;>d0.l:変更前の指定
sysStat_5002::
	moveq.l	#0,d0
	move.b	defaultLoadArea,d0
	cmp.l	#-1,d2
	beq	1f
	cmp.l	#9,d2
	bcc	9f
	move.b	d2,defaultLoadArea
1:	rts

9:	moveq.l	#-1,d0
	rts

;----------------------------------------------------------------
;$5003	defaultAllocAreaの指定
;<d2.l:アロケートするメモリ空間の指定
;	0	下位のみ
;	1	上位のみ
;	2	親と同じ側のみ
;	3	親と反対側のみ
;	4	制限なし,下位優先
;	5	制限なし,上位優先
;	6	制限なし,親と同じ側優先
;	7	制限なし,親と反対側優先
;	8	制限なし,優先なし
;>d0.l:変更前の指定
sysStat_5003::
	moveq.l	#0,d0
	move.b	defaultAllocArea,d0
	cmp.l	#-1,d2
	beq	1f
	cmp.l	#9,d2
	bcc	9f
	move.b	d2,defaultAllocArea
1:	rts

9:	moveq.l	#-1,d0
	rts