File:  [Isaki's NoNo m68k/m88k emulator] / nono / exp / ptest1.has
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:05:59 2026 UTC (2 months, 3 weeks ago) by root
Branches: MAIN, Isaki
CVS tags: v027, HEAD
nono 1.7.0

;
; nono
; Copyright (C) 2022 nono project
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions
; are met:
; 1. Redistributions of source code must retain the above copyright
;    notice, this list of conditions and the following disclaimer.
; 2. Redistributions in binary form must reproduce the above copyright
;    notice, this list of conditions and the following disclaimer in the
;    documentation and/or other materials provided with the distribution.
;
; THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
; IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
; SUCH DAMAGE.

;
; m68030 PTEST 命令のテスト
;

; How to build
;  > has ptest1.has
;  > hlk ptest1.o si_util.o

	.include	doscall.mac
	.include	iocscall.mac
	.xref	hexstr_word
	.xref	hexstr_long
	.xref	decstr

MMUSR_B	.equ	0x8000
MMUSR_L	.equ	0x4000
MMUSR_S	.equ	0x2000
MMUSR_W	.equ	0x0800
MMUSR_I	.equ	0x0400
MMUSR_M	.equ	0x0200
MMUSR_T	.equ	0x0040
MMUSR_N	.equ	0x0007

PRINT	.macro	str
	movem.l	a1,-(sp)
	lea.l	str,a1
	IOCS	_B_PRINT
	movem.l	(sp)+,a1
	.endm

	.cpu	68030
	.list
	.text
	.even
start:
	clr.l	-(sp)
	DOS	_SUPER
	addq.l	#4,sp

	; F ライン例外ハンドラを差し替える
	movec	vbr,a0
	move.l	44(a0),fline_backup
	lea.l	fline_handler,a1
	move.l	a1,44(a0)

	; MMU テーブルを作成。
	;
	; $00'000000 +
	;            | Pass through (1:1 mapping)
	;    $ed0000 .. $ed7fff | TIB で WP をセット。ここは SRAM。
	;    $f00000 .. $ffffff | TIA で WP をセット。ここは ROM。
	; $01'000000 +
	;            | Invalid
	; $02'000000 +
	;            | TT0 アクセス用に使う
	; $03'000000 +
	;            :
	;
	;    3                   2                   1                   0
	;  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
	; +-------------+---------+---------+-----------------------------+
	; |I I I I I I I|A A A A A|B B B B B|P P P P P P P P P P P P P P P|
	; +-------------+---------+---------+-----------------------------+
	; IS=7           TIA=5     TIB=5     PS=15
	;                32MB      1MB       32KB
	;
	; 1段目 = 32 [entry] * 4 [byte] = 128 [byte]
	; 2段目 = 32 [entry] * 4 [byte] = 128 [byte] / 1段目エントリ
NUM_A	.equ	32
NUM_B	.equ	32

	; Table A を作成。
	; 前半 16 エントリ(16MB) が X68k 全空間に相当し tableB を指す。
	; 後半 16 エントリ(16MB) は Invalid にする。
	lea.l	tableB,a0
	move.l	a0,d0
	lea.l	tableA,a0
	addq.l	#2,d0			; DT=Short
	moveq.l	#(NUM_A/2-1),d2		; First half
@@:
	move.l	d0,(a0)+
	addi.l	#(NUM_B*4),d0
	dbra	d2,@b

	moveq.l	#0,d0			; DT=Invalid
	moveq.l	#(NUM_A/2-1),d2		; Second half
@@:
	move.l	d0,(a0)+
	dbra	d2,@b

	; Table B を作成。16MB 全域を 1:1 マッピング。
	lea.l	tableB,a0
	moveq.l	#1,d0			; PageAddr=0, DT=Page
	move.l	#0x8000,d1		; 32KB
	move.l	#(NUM_A/2*NUM_B-1),d2
@@:
	move.l	d0,(a0)+
	add.l	d1,d0
	dbra	d2,@b

	; Table A のうち最後の1エントリ、$00'f00000(1MB) を WP にしておく。
	lea.l	tableA,a0
	moveq.l	#15,d0
	ori.l	#4,(a0,d0.w*4)		; 4=WP
	; Table B のうち $00'ed0000(32KB) を WP にしておく。
	; これは TIA 14番の中の TIB 26番目のエントリ。
	lea.l	tableB+(14*32*4),a0
	moveq.l	#26,d0
	ori.l	#4,(a0,d0.w*4)		; 4=WP

	pmove.q	srp_data,srp		; Set SRP
	pflusha
	pmove.l	tc_data,tc		; ここで MMU Enable!!

	nop				; For debugger

	; 引数なしのテストを実行するマクロ
TEST	.macro	F
	pea	F		; 2nd arg = func
	pea	msg_&F		; 1st arg = message
	bsr	test
	addq.l	#8,sp
	.endm

	; アドレスの引数を1つ持つテストを実行するマクロ
TEST1	.macro	func, arg1
	lea.l	arg1,a1
	TEST	func
	.endm

	;
	; ここからテストエントリ。
	;
	TEST	ptestr0_an
	TEST	ptestw0_an
	;TEST	ptest_dt1		; not yet

	TEST1	ptestr0, set_r0_1
	TEST1	ptestr0, set_r0_2
	TEST1	ptestr0, set_r0_3
	TEST1	ptestr0, set_r0_4
	TEST1	ptestr0, set_r0_5
	TEST1	ptestr0, set_r0_6
	TEST1	ptestr0, set_r0_7
	TEST1	ptestr0, set_r0_8
	TEST1	ptestr0, set_r0_9
	TEST1	ptestr0, set_r0_a
	TEST1	ptestw0, set_w0_1
	TEST1	ptestw0, set_w0_2
	TEST1	ptestw0, set_w0_3
	TEST1	ptestw0, set_w0_4
	TEST1	ptestw0, set_w0_5
	TEST1	ptestw0, set_w0_6
	TEST1	ptestw0, set_w0_7
	TEST1	ptestw0, set_w0_8
	TEST1	ptestw0, set_w0_9
	TEST1	ptestw0, set_w0_a

	TEST1	ptestr1, set_r1_1
	TEST1	ptestr1, set_r1_2
	TEST1	ptestr1, set_r1_3
	TEST1	ptestr1, set_r1_4
	TEST1	ptestr1, set_r1_5
	TEST1	ptestr1, set_r1_6
	TEST1	ptestr1, set_r1_7
	TEST1	ptestr1, set_r1_8
	TEST1	ptestw1, set_w1_1
	TEST1	ptestw1, set_w1_2
	TEST1	ptestw1, set_w1_3
	TEST1	ptestw1, set_w1_4
	TEST1	ptestw1, set_w1_5
	TEST1	ptestw1, set_w1_6
	TEST1	ptestr1, set_w1_7
	TEST1	ptestr1, set_w1_8

	TEST1	ptestr7, set_r7_1
	TEST1	ptestr7, set_r7_2
	TEST1	ptestr7, set_r7_3
	TEST1	ptestr7, set_r7_4
	TEST1	ptestr7, set_r7_5
	TEST1	ptestr7, set_r7_6
	TEST1	ptestr7, set_r7_7
	TEST1	ptestr7, set_r7_8
	TEST1	ptestw7, set_w7_1
	TEST1	ptestw7, set_w7_2
	TEST1	ptestw7, set_w7_3
	TEST1	ptestw7, set_w7_4
	TEST1	ptestw7, set_w7_5
	TEST1	ptestw7, set_w7_6
	TEST1	ptestw7, set_w7_7
	TEST1	ptestw7, set_w7_8
done:
	; テスト終了
	pmove.l	tc_restore,tc		; MMU 変換オフ
	movec	vbr,a0
	move.l	fline_backup,44(a0)	; F ライン例外ハンドラを戻す
	; 結果発表
	lea.l	buf(pc),a0
	move.l	testcount(pc),d0
	bsr	decstr
	move.l	#((' '<<24)|('t'<<16)|('e'<<8)|'s'),(a0)+
	move.l	#(('t'<<24)|('s'<<16)|(','<<8)|' '),(a0)+
	move.l	failcount(pc),d0
	bne	@f
	move.l	#(('a'<<24)|('l'<<16)|('l'<<8)|' '),(a0)+
	move.l	#(('p'<<24)|('a'<<16)|('s'<<8)|'s'),(a0)+
	move.l	#0x0d0a0000,(a0)
	bra	exit
@@:
	bsr	decstr
	move.l	#((' '<<24)|('F'<<16)|('A'<<8)|'I'),(a0)+
	move.l	#(('L'<<24)|('E'<<16)|('D'<<8)|'!'),(a0)+
	move.l	#0x0d0a0000,(a0)
exit:
	lea.l	buf(pc),a1
	IOCS	_B_PRINT
	DOS	_EXIT

	; テスト実行
	; 8(a6):  テスト名
	; 12(a6): テスト関数
test:
	link	a6,#0
	movem.l	a1,-(sp)
	move.l	8(a6),a1
	IOCS	_B_PRINT
	movem.l	(sp)+,a1
	addi.l	#1,testcount
	move.l	12(a6),a0
	jsr	(a0)
	add.l	d0,failcount
	tst.l	d0
	bne	@f			; エラーなら呼出先で何か表示してある
	PRINT	msg_ok(pc)
@@:
	unlk	a6
	rts

error:
	PRINT	msg_fail(pc)
	moveq.l	#1,d0
	rts

	;
	; ここから個別テスト。
	;

ptestr0_an:
	; PTESTR <fc>,<ea>,#0,An 形式は F ライン例外になる。
	lea.l	done,a0			; アドレスは何でもいい
	clr.b	fline_trap_occured
	ptestr	#1,(a0),#0,a0
	tst.b	fline_trap_occured
	beq	error
	moveq.l	#0,d0
	rts

ptestw0_an:
	; PTESTW <fc>,<ea>,#0,An 形式は F ライン例外になる。
	lea.l	done,a0			; アドレスは何でもいい
	clr.b	fline_trap_occured
	ptestw	#1,(a0),#0,a0
	tst.b	fline_trap_occured
	beq	error
	moveq.l	#0,d0
	rts

; XXX PTEST on xRP.DT==$1(Page).
; 日本語 68030 本によると、この場合アドレスレジスタに $0 が返ってくるらしいが
; 実機だとそうはなってないようなので、ちょっと保留。
ptest_dt1:
	move.l	#0x00_010000,d0		; tableA[1]
	movea.l	d0,a0
	pmove.q	crp_dt1,crp		; CRP を DT=1 で有効にする
	clr.b	fline_trap_occured
	ptestr	#5,(a0),#1,a0
	pmove.q	crp_disable,crp		; CRP を戻す
	tst.b	fline_trap_occured
	bne	error
	tst.l	a0			; ??? a0 is not zero?
	bne	@f
	moveq.l	#0,d0
	rts
@@:
	move.l	a0,d0
	lea.l	buf(pc),a0
	move.b	#':',(a0)+
	bsr	hexstr_long
	move.b	#0,(a0)
	PRINT	buf(pc)
	moveq.l	#1,d0
	rts

; PTEST<R/W> <fc>,<ea>,#0 形式のテストマクロ (Lv0 は An オペランドなし)。
; マクロの引数は ptestr か ptestw 命令。
;
; 入力パラメータは (a1) 渡し。
; (a1)+$0.l: <fc>
; (a1)+$4.l: <ea>
; (a1)+$8.l: TT0
; (a1)+$c.l: mmusr の期待値
PTEST_LV0	.macro	ptestRW
	moveq.l	#0,d0
	bsr	print_ptest
	move.l	0(a1),d1
	movea.l	4(a1),a0
	pmovefd	8(a1),tt0		; ATC をフラッシュせず TT0 を設定
	pflush	#6,#7
	nop
	clr.b	fline_trap_occured
	ptestRW	d1,(a0),#0
	pmove.l	tt_disable,tt0		; TT0 無効
	tst.b	fline_trap_occured
	bne	error
	move.l	12(a1),d1
	bsr	cmp_mmusr
	bne	error
	moveq.l	#0,d0
	rts
	.endm

; PTEST<R/W> <fc>,<ea>,#<lv>,An 形式のテストマクロ (Lv1-7 用)。
; マクロの引数は ptestRW が ptestr か ptestw 命令、LV がレベル。
;
; 入力パラメータは (a1) 渡し。
; (a1)+$0.l: <fc>
; (a1)+$4.l: <ea>
; (a1)+$8.l: TT0
; (a1)+$c.l: mmusr の期待値
; (a1)+$10.l: 期待する An (を tableA 先頭からのインデックスで表したもの)。
;             例えば $c00000 を期待する場合これは TIA[12] なので $c になる。
;             TIB は TIA (32エントリ)の直後から始まっている。
PTEST_LV	.macro	ptestRW, LV
	moveq.l	#LV,d0
	bsr	print_ptest
	move.l	0(a1),d1
	movea.l	4(a1),a0
	pmovefd	8(a1),tt0		; ATC をフラッシュせず TT0 を設定
	pflush	#6,#7
	nop
	clr.b	fline_trap_occured
	ptestRW	d1,(a0),#LV,a2
	pmove.l	tt_disable,tt0		; TT0 無効
	tst.b	fline_trap_occured
	bne	error
	move.l	12(a1),d1
	bsr	cmp_mmusr
	bne	error
	bsr	cmp_addr
	bne	error
	moveq.l	#0,d0
	rts
	.endm

ptestr0:
	PTEST_LV0 ptestr
ptestw0:
	PTEST_LV0 ptestw
ptestr1:
	PTEST_LV ptestr, 1
ptestw1:
	PTEST_LV ptestw, 1
ptestr7:
	PTEST_LV ptestr, 7
ptestw7:
	PTEST_LV ptestw, 7

; TT 設定値のショートカット
TT00	.equ	0x0000_0000		; $00'000000(16MB)
TT01	.equ	0x0100_0000		; $01'000000(16MB)
TT02	.equ	0x0200_0000		; $02'000000(16MB)
TT_R	.equ	0x8607			; Read  のみ透過変換
TT_W	.equ	0x8407			; Write のみ透過変換
TT_RW	.equ	0x8507			; RD/WR とも透過変換

; PTESTR Lv0
;
; 1 TTx 無効、ATC にないアドレス
; 2 TTx 無効、ATC にあるアドレス
; 3 TTx 有効、TTx に(アドレスが)ヒットせず、ATC にないアドレス
; 4 TTx 有効、TTx にヒットし、ATC にないアドレス
; 5 TTx 有効、TTx に(R/W属性で) ヒットせず。ATC にないアドレス
; 6 TTx 有効、TTx に(アドレスが)ヒットせず、ATC にあるアドレス
; 7 TTx 有効、TTx にヒットし、ATC にあるアドレス
; 8 TTx 有効、TTx に(R/W属性で) ヒットせず、ATC にあるアドレス
; 9 TTx 無効、TIA が WProtect で ATC にあるアドレス
; a TTx 無効、TIB が WProtect で ATC にあるアドレス
;
; - ATC に載ってるはずのエントリとして <ea>=ptestr0 を使っている。
; - TT02|TT_RW は論理 $02'000000(16MB) を物理 $02'000000(16MB) に透過変換で
;   あり、素の X68030 実機では A31-A24 が非接続のため、この状態での $02'c00000
;   へのアクセスは $c00000 (GVRAM) へのアクセスになる。
; - $00'c00000 は GVRAM を指しており FC=6 は命令スペースなので ATC にはない。
;
;		fc ea		tt		result
set_r0_1: .dc.l	6, 0x00_c00000,	0,		MMUSR_I
set_r0_2: .dc.l	6, ptestr0,	0,		MMUSR_M
set_r0_3: .dc.l	6, 0x00_c00000,	TT02|TT_RW,	MMUSR_I
set_r0_4: .dc.l	6, 0x02_c00000,	TT02|TT_R,	MMUSR_I|MMUSR_T
set_r0_5: .dc.l	6, 0x02_c00000,	TT02|TT_W,	MMUSR_I
set_r0_6: .dc.l	6, ptestr0,	TT02|TT_RW,	MMUSR_M
; XXX 実機だと I+T が返るようだ。なぜ?
set_r0_7: .dc.l	6, ptestr0,	TT00|TT_R,	MMUSR_I|MMUSR_T
set_r0_8: .dc.l	6, ptestr0,	TT00|TT_W,	MMUSR_M
set_r0_9: .dc.l	5, 0x00_f00000, 0,		MMUSR_W
set_r0_a: .dc.l	5, 0x00_ed3000, 0,		MMUSR_W

; PTESTW Lv0
;
; 1 TTx 無効、ATC にないアドレス
; 2 TTx 無効、ATC にあるアドレス
; 3 TTx 有効、TTx に(アドレスが)ヒットせず、ATC にないアドレス
; 4 TTx 有効、TTx に(R/W属性で) ヒットせず。ATC にないアドレス
; 5 TTx 有効、TTx にヒットし、ATC にないアドレス
; 6 TTx 有効、TTx に(アドレスが)ヒットせず、ATC にあるアドレス
; 7 TTx 有効、TTx に(R/W属性で) ヒットせず、ATC にあるアドレス
; 8 TTx 有効、TTx にヒットし、ATC にあるアドレス
; 9 TTx 無効、TIA が WProtect で ATC にあるアドレス
; a TTx 無効、TIB が WProtect で ATC にあるアドレス
;
;		fc ea		tt		result
set_w0_1: .dc.l	6, 0x00_c00000,	0,		MMUSR_I
set_w0_2: .dc.l	6, ptestw0,	0,		MMUSR_M
set_w0_3: .dc.l	6, 0x00_c00000,	TT02|TT_RW,	MMUSR_I
set_w0_4: .dc.l	6, 0x02_c00000,	TT02|TT_R,	MMUSR_I
set_w0_5: .dc.l	6, 0x02_c00000,	TT02|TT_W,	MMUSR_I|MMUSR_T
set_w0_6: .dc.l	6, ptestw0,	TT02|TT_RW,	MMUSR_M
set_w0_7: .dc.l	6, ptestw0,	TT00|TT_R,	MMUSR_I
set_w0_8: .dc.l	6, ptestw0,	TT00|TT_W,	MMUSR_M|MMUSR_T
set_w0_9: .dc.l	5, 0x00_f00000,	0,		MMUSR_W
set_w0_a: .dc.l	5, 0x00_ed3000,	0,		MMUSR_W

; PTESTR Lv1
;
; 1 TTx 無効、ea はサーチ中に見付かる
; 2 TTx 無効、ea はサーチ中に Invalid になる
; 3 TTx 有効、ea はサーチ中に見付かる
; 4 TTx 有効、ea はサーチ中に Invalid になる
; 5 TTx 有効、ea は TT とマッチして有効
; 6 TTx 有効、ea は TT とマッチするが Invalid
; 7 ea は TIA でライトプロテクトされているので Lv1 サーチでは W が見付かる
; 8 ea は TIB でライトプロテクトされているので Lv1 サーチではまだ W にならない
;
;		fc ea		tt		result		addr(index)
set_r1_1: .dc.l	6, 0x00_c00000,	0,		1,		0x0c
set_r1_2: .dc.l	6, 0x01_000000,	0,		1|MMUSR_I,	0x10
set_r1_3: .dc.l	6, 0x00_c00000,	TT02|TT_RW,	1,		0x0c
set_r1_4: .dc.l	6, 0x01_000000,	TT02|TT_RW,	1|MMUSR_I,	0x10
set_r1_5: .dc.l	6, 0x00_c00000,	TT00|TT_RW,	1,		0x0c
set_r1_6: .dc.l	6, 0x01_000000,	TT01|TT_RW,	1|MMUSR_I,	0x10
set_r1_7: .dc.l	5, 0x00_f00000,	0,		1|MMUSR_W,	0x0f
set_r1_8: .dc.l	5, 0x00_ed3000,	0,		1,		0x0e

; PTESTW Lv1
;		fc ea		tt		result		addr(index)
set_w1_1: .dc.l	6, 0x00_c00000,	0,		1,		0x0c
set_w1_2: .dc.l	6, 0x01_000000,	0,		1|MMUSR_I,	0x10
set_w1_3: .dc.l	6, 0x00_c00000,	TT02|TT_RW,	1,		0x0c
set_w1_4: .dc.l	6, 0x01_000000,	TT02|TT_RW,	1|MMUSR_I,	0x10
set_w1_5: .dc.l	6, 0x00_c00000,	TT00|TT_RW,	1,		0x0c
set_w1_6: .dc.l	6, 0x01_000000,	TT01|TT_RW,	1|MMUSR_I,	0x10
set_w1_7: .dc.l	5, 0x00_f00000,	0,		1|MMUSR_W,	0x0f
set_w1_8: .dc.l	5, 0x00_ed3000,	0,		1,		0x0e

; PTESTR Lv7
;		fc ea		tt		result		addr(index)
set_r7_1: .dc.l	6, 0x00_c00000,	0,		2,		NUM_A+0x0c00/8
set_r7_2: .dc.l	6, 0x01_000000,	0,		1|MMUSR_I,	0x10
set_r7_3: .dc.l	6, 0x00_c00000,	TT02|TT_RW,	2,		NUM_A+0x0c00/8
set_r7_4: .dc.l	6, 0x01_000000,	TT02|TT_RW,	1|MMUSR_I,	0x10
set_r7_5: .dc.l	6, 0x00_c00000,	TT00|TT_RW,	2,		NUM_A+0x0c00/8
set_r7_6: .dc.l	6, 0x01_000000,	TT01|TT_RW,	1|MMUSR_I,	0x10
set_r7_7: .dc.l	5, 0x00_f00000,	0,		2|MMUSR_W,	NUM_A+0x0f00/8
set_r7_8: .dc.l	5, 0x00_ed3000,	0,		2|MMUSR_W,	NUM_A+0x0ed3/8

; PTESTW Lv7
;		fc ea		tt		result		addr(index)
set_w7_1: .dc.l	6, 0x00_c00000,	0,		2,		NUM_A+0x0c00/8
set_w7_2: .dc.l	6, 0x01_000000,	0,		1|MMUSR_I,	0x10
set_w7_3: .dc.l	6, 0x00_c00000,	TT02|TT_RW,	2,		NUM_A+0x0c00/8
set_w7_4: .dc.l	6, 0x01_000000,	TT02|TT_RW,	1|MMUSR_I,	0x10
set_w7_5: .dc.l	6, 0x00_c00000,	TT00|TT_RW,	2,		NUM_A+0x0c00/8
set_w7_6: .dc.l	6, 0x01_000000,	TT01|TT_RW,	1|MMUSR_I,	0x10
set_w7_7: .dc.l	5, 0x00_f00000,	0,		2|MMUSR_W,	NUM_A+0x0f00/8
set_w7_8: .dc.l	5, 0x00_ed3000,	0,		2|MMUSR_W,	NUM_A+0x0ed3/8

; テストパラメータを表示する。
; in: d0 レベル
;     a1 パラメータセットの先頭アドレス
; use: -
print_ptest:
	movem.l	d0-d2/a0-a1,-(sp)
	move.l	d0,d2			; level を退避
	lea.l	buf(pc),a0
	move.l	0(a1),d0		; fc
	add.b	#'0',d0
	move.b	d0,(a0)+
	move.b	#',',(a0)+
	move.l	4(a1),d0		; ea
	bsr	hexstr_long
	move.w	#((','<<8)|'#'),(a0)+
	addi.b	#'0',d2			; level
	move.b	d2,(a0)+
	move.l	#((' '<<24)|('t'<<16)|('t'<<8)|' '),(a0)+
	move.l	8(a1),d0		; tt
	bsr	hexstr_long
	move.b	#0,(a0)
	lea.l	buf(pc),a1
	IOCS	_B_PRINT

	; 表示ではないけどついでにここで
	; $f0'0000 と $ed'0000 を ATC#5 に載せておく。
	move.l	#$f00000,d0
	movea.l	d0,a0
	move.b	(a0),d0
	move.l	#$ed3000,d0
	movea.l	d0,a0
	move.b	(a0),d0

	movem.l	(sp)+,d0-d2/a0-a1
	rts


; MMUSR とその期待値(d1)を比較する。
; in  d1: 期待値
; out d0: 一致すれば 0、そうでなければ 1 を返す
; use --
cmp_mmusr:
	movem.l	d2-d3/a0-a1,-(sp)
	moveq.l	#0,d0
	lea.l	mmusr_buf(pc),a0
	pmove	mmusr,(a0)
	move.w	(a0),d2
	cmp.w	d1,d2
	beq	cmp_mmusr_done
	; fail
	PRINT	msg_mmusr1(pc)
	lea.l	buf(pc),a0
	move.w	d1,d0
	swap	d0
	bsr	hexstr_word
	bsr	put_mmusrbits
	move.l	#((' '<<24)|('b'<<16)|('u'<<8)|'t'),(a0)+
	move.b	#' ',(a0)+
	move.w	d2,d0
	swap	d0
	bsr	hexstr_word
	bsr	put_mmusrbits
	move.b	#0,(a0)
	PRINT	buf(pc)
	moveq.l	#1,d0
cmp_mmusr_done:
	movem.l	(sp)+,d2-d3/a0-a1
	rts

; in  d0.hw: MMUSR
;     a0   : バッファアドレス
; use d3
;     a1
put_mmusrbits:
	lea.l	mmusr_str(pc),a1
	move.b	#'(',(a0)+

BITSTR	.macro	BIT, OFFSET
	clr.w	d3
	btst.l	#(16+BIT),d0
	seq	d3
	neg.b	d3
	move.b	OFFSET(a1,d3.w*1),(a0)+
	.endm

	BITSTR	15, 0	; B
	BITSTR	14, 2	; L
	BITSTR	13, 4	; S
	BITSTR	11, 6	; W
	BITSTR	10, 8	; I
	BITSTR	9, 10	; M
	BITSTR	6, 12	; T

	move.b	#')',(a0)+
	rts

; アドレスをパラメータセットのアドレスインデックスと比較する。
; a2 が実際の結果、16(a1) に期待するアドレスインデックス。
; アドレスインデックスは TableA の先頭からのインデックス。
; in  a1: パラメータセットの先頭アドレス
;     a2: 実際の結果
; out d0: 一致すれば 0、そうでなければ 1 を返す
; use --
cmp_addr:
	movem.l	d2/a0,-(sp)
	moveq.l	#0,d0
	move.l	16(a1),d2
	lsl.l	#2,d2
	addi.l	#tableA,d2
	cmp.l	a2,d2
	beq	cmp_addr_done
	; fail
	PRINT	msg_an(pc)
	lea.l	buf(pc),a0
	move.l	d2,d0
	bsr	hexstr_long
	move.l	#((' '<<24)|('b'<<16)|('u'<<8)|'t'),(a0)+
	move.b	#' ',(a0)+
	move.l	a2,d0
	bsr	hexstr_long
	move.b	#0,(a0)
	PRINT	buf(pc)
	moveq.l	#1,d0
cmp_addr_done:
	movem.l	(sp)+,d2/a0
	rts

; F ライン例外ハンドラ。
; F ライン例外が起きるのは PTEST 命令だけと仮定してハードコードしてある。
fline_handler:
	st	fline_trap_occured
	addi.l	#4,2(sp)		; 戻りアドレスは PTEST 命令の次
	rte

srp_data:
	.dc.l	0x8000_0002, tableA
tc_data:
	.dc.l	0x82f75500
tc_restore:
	.dc.l	0x00000000
tt_disable:
	.dc.l	0x00000000
crp_disable:
	.dc.l	0x0000_0001, 0x0000_0000
crp_dt1:
	.dc.l	0x8000_0001, tableA

msg_ptestr0_an:
	.dc.b	"PTESTR fc,ea,#0,An",0
msg_ptestw0_an:
	.dc.b	"PTESTW fc,ea,#0,An",0
msg_ptest_dt1:
	.dc.b	"PTEST on xRP.DT=1",0
msg_ptestr0:
msg_ptestr1:
msg_ptestr7:
	.dc.b	"PTESTR #",0
msg_ptestw0:
msg_ptestw1:
msg_ptestw7:
	.dc.b	"PTESTW #",0
msg_fail:
	.dc.b	": FAILED!",$d,$a,0
msg_ok:
	.dc.b	": ok"
msg_crlf:
	.dc.b	$d,$a,0
msg_mmusr1:
	.dc.b	": MMUSR expects ",0
msg_an:
	.dc.b	": An expects ",0
mmusr_str:
	.dc.b	"B-L-S-W-I-M-T-"

	.bss
	.even
fline_backup:
	.ds.l	1
fline_trap_occured:
	.ds.l	1
testcount:
	.ds.l	1
failcount:
	.ds.l	1
buf:
	.ds.b	128
mmusr_buf:
	.ds.l	1

	.align	16
tableA:	.ds.l	NUM_A

tableB:	.ds.l	NUM_A * NUM_B

	.end
; vi:set ts=8:

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.