--- nono/exp/fmovemc.php 2026/04/29 17:04:28 1.1 +++ nono/exp/fmovemc.php 2026/04/29 17:05:36 1.1.1.4 @@ -1,14 +1,35 @@ ; ; nono -; Copyright (C) 2019 isaki@NetBSD.org +; Copyright (C) 2020 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. ; How to compile: -; > has fmovem.has -; > hlk fmovem.o si_util.o +; > has fmovemc.has +; > hlk fmovemc.o si_util.o .xref hexstr_long .include doscall.mac + .include iocscall.mac .list .cpu 68030 @@ -18,18 +39,11 @@ PRINT .macro msg addq.l #4,sp .endm -SET_FLINE_TRAP .macro - move.l (a5),a4 - lea.l fline_handler(pc),a1 - move.l a1,(a5) - .endm - -RESTORE_FLINE_TRAP .macro - move.l a4,(a5) - .endm - .text .even +start: + bra start2 + , function subr_success_to($regs, $id) { + $cpureg = eanum2mnem($id); $regnum = reg2num($regs); $mnem = regnum2mnemonic($regnum); $label = eanum2label($id); $funcname = "fmovem_{$label}_to_{$regs}"; - addfunc($funcname); + addfunc($funcname, "to", $mnem, $cpureg); + out(" PRINT msg_{$funcname}"); $w1 = 0xf200 | eanum2word($id); $w2 = 0x8000 | ($regnum << 10); - $cpureg = eanum2mnem($id); // count は指定されたレジスタ数 (0..3) // txcount は転送するレジスタ数 (1..3) $count = regnum2count($regnum); @@ -321,7 +354,7 @@ function subr_success_to($regs, $id) break; } - out(" SET_FLINE_TRAP"); + out(" bsr set_fline"); out(" moveq.l #0,d7"); out(" lea.l @f,a3"); // 実行 @@ -336,7 +369,7 @@ function subr_success_to($regs, $id) } out("@@:"); - out(" RESTORE_FLINE_TRAP"); + out(" bsr restore_fline"); // 例外は起きないはずなので D7 はゼロなら成功(次へ) out(" tst.l d7"); out(" beq @f"); @@ -408,7 +441,7 @@ function subr_success_to($regs, $id) out(" move.l #$%08x,a1", $expected[$i] & regmask(1)); $i++; } else { - out(" move.l d7,a1 ; d7=0"); + out(" suba.l a1,a1"); } out(" cmpa.l a1,a0"); out(" beq @f"); @@ -426,16 +459,17 @@ function subr_success_to($regs, $id) // アクセス可能な場合のテスト。FMOVEM , function subr_success_from($regs, $id) { + $cpureg = eanum2mnem($id); $regnum = reg2num($regs); $mnem = regnum2mnemonic($regnum); $label = eanum2label($id); $funcname = "fmovem_{$regs}_to_{$label}"; - addfunc($funcname); + addfunc($funcname, "from", $mnem, $cpureg); + out(" PRINT msg_{$funcname}"); $w1 = 0xf200 | eanum2word($id); $w2 = 0xa000 | ($regnum << 10); - $cpureg = eanum2mnem($id); // count は指定されたレジスタ数 (0..3) // txcount は転送するレジスタ数 (1..3) $count = regnum2count($regnum); @@ -468,7 +502,7 @@ function subr_success_from($regs, $id) break; } - out(" SET_FLINE_TRAP"); + out(" bsr set_fline"); out(" moveq.l #0,d7"); out(" lea.l @f,a3"); // 実行 @@ -478,7 +512,7 @@ function subr_success_from($regs, $id) out(" fmovem.l {$mnem},{$cpureg}"); out("@@:"); - out(" RESTORE_FLINE_TRAP"); + out(" bsr restore_fline"); // 例外は起きないはずなので D7 はゼロなら成功(次へ) out(" tst.l d7"); out(" beq @f"); @@ -520,7 +554,7 @@ function subr_success_from($regs, $id) $i++; out(" cmp.l d1,d0"); out(" beq @f"); - out_result("msg_fail", "d1", "d0"); + out_result("msg_fail_dst", "d1", "d0"); out("@@:"); } } @@ -533,7 +567,7 @@ function subr_success_from($regs, $id) $i++; out(" cmp.l a1,a0"); out(" beq @f"); - out_result("msg_fail", "a1", "a0"); + out_result("msg_fail_dst", "a1", "a0"); out("@@:"); } } @@ -548,7 +582,8 @@ function subr_success_from($regs, $id) out(" cmp.l workarea+%d,d1", $i * 4); $i++; out(" beq @f"); - out_result("msg_fail", "d1", sprintf("workarea+%d", $i * 4)); + out_result("msg_fail_dst", + "d1", sprintf("workarea+%d", $i * 4)); out("@@:"); } } @@ -563,22 +598,39 @@ function subr_success_from($regs, $id) out(""); } ?> - -start: +start2: clr.l -(sp) DOS _SUPER - movem.l d7/a3-a5,-(sp) - moveq.l #$2c,d0 ; alternate of "lea.l $2c,a5" - move.l d0,a5 ; + movem.l d7/a3-a4,-(sp) + ; rough argument check + cmpi.b #4,(a2)+ ; strlen(arg)>=4 ? + bcs @f + cmpi.l #$68617264,(a2) ; "hard" + seq.b is_hard +@@: + tst.b is_hard(pc) + beq disp_easy +disp_hard: + PRINT msg_hard + bra @f +disp_easy: + PRINT msg_easy +@@: $text) { + // FPcr が1つもないケースは hard の時だけ実行。 + $undef_case = preg_match("/____/", $name); + if ($undef_case) { + out(" tst.b is_hard(pc)"); + out(" beq @f"); + } out(" bsr test_{$name}"); + if ($undef_case) { + out("@@:"); + } } ?> - movem.l (sp)+,d7/a3-a5 + movem.l (sp)+,d7/a3-a4 DOS _EXIT ; 結果表示 @@ -597,7 +649,7 @@ result: PRINT buf PRINT msg_but - move.l 8+0(a6),a0 + move.l 8+0(a6),d0 lea.l buf(pc),a0 bsr hexstr_long PRINT buf @@ -608,6 +660,28 @@ result: unlk a6 rts +; Fライン例外をテスト用のものに差し替える。 +; 変更前のアドレスを a4 に格納する。 +; a1 は破壊する。 +set_fline: + movem.l d0-d1,-(sp) + moveq.l #$b,d1 + lea.l fline_handler(pc),a1 + IOCS _B_INTVCS + movea.l d0,a4 + movem.l (sp)+,d0-d1 + rts + +; Fライン例外を元に戻す。 +; a1 は破壊する。 +restore_fline: + movem.l d0-d1,-(sp) + moveq.l #$b,d1 + movea.l a4,a1 + IOCS _B_INTVCS + movem.l (sp)+,d0-d1 + rts + ; Fライン例外ハンドラ ; a3 に戻りアドレスをセットしてあること ; d7 を 1 にして帰る @@ -616,29 +690,32 @@ fline_handler: move.l a3,2(sp) rte +msg_hard: .dc.b "hard mode",$d,$a,0 +msg_easy: .dc.b "easy mode",$d,$a,0 msg_oktrap: .dc.b $9,"ok(trap)",$d,$a,0, 0,0 msg_fail_notrap: .dc.b $9,"FAIL: trap expected but not occured",$d,$a,0 msg_fail_trap: .dc.b $9,"FAIL: unexpected trap occured",$d,$a,0 msg_ok: .dc.b $9,"ok",$d,$a,0 -msg_fail: .dc.b $9,"fail",$d,$a,0 msg_fail_cr: .dc.b $9,"FAIL: fpcr expects ",0 msg_fail_sr: .dc.b $9,"FAIL: fpsr expects ",0 msg_fail_ir: .dc.b $9,"FAIL: fpiar expects ",0 msg_fail_addr: .dc.b $9,"FAIL: an expects ",0 +msg_fail_dst: .dc.b $9,"FAIL: dst expects ",0 msg_but: .dc.b " but ",0 msg_crlf: .dc.b $d,$a,0 $text) { + out("msg_{$name}: .dc.b \"{$text}\",0"); } ?> .data .even workarea: .ds.b 24 -buf: .dc.b 20 +buf: .ds.b 20 +is_hard: .ds.b 1 .end start