]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
cputester IPL timing test support
authorToni Wilen <twilen@winuae.net>
Fri, 15 Apr 2022 18:22:05 +0000 (21:22 +0300)
committerToni Wilen <twilen@winuae.net>
Fri, 15 Apr 2022 18:22:05 +0000 (21:22 +0300)
cfgfile.cpp
cia.cpp
cputest.cpp
cputest/asm.S
cputest/cputest_defines.h
cputest/cputestgen.ini
cputest/main.c
custom.cpp
include/newcpu.h
include/options.h
inputdevice.cpp

index 64648c2d75754029c29076c25ea14cfa79f5a4a4..50f7fb93ca491c3d63d8cc2dc805e3e25356e787 100644 (file)
@@ -2235,6 +2235,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_dwrite_bool (f, _T("tablet_library"), p->tablet_library);
        cfgfile_dwrite_bool (f, _T("clipboard_sharing"), p->clipboard_sharing);
        cfgfile_dwrite_bool(f, _T("native_code"), p->native_code);
+       cfgfile_dwrite_bool(f, _T("cputester"), p->cputester);
 
        cfgfile_write (f, _T("gfx_display"), _T("%d"), p->gfx_apmode[APMODE_NATIVE].gfx_display);
        cfgfile_write_str (f, _T("gfx_display_friendlyname"), target_get_display_name (p->gfx_apmode[APMODE_NATIVE].gfx_display, true));
@@ -3496,6 +3497,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
                || cfgfile_yesno(option, value, _T("clipboard_sharing"), &p->clipboard_sharing)
                || cfgfile_yesno(option, value, _T("native_code"), &p->native_code)
                || cfgfile_yesno(option, value, _T("tablet_library"), &p->tablet_library)
+               || cfgfile_yesno(option, value, _T("cputester"), &p->cputester)
                || cfgfile_yesno(option, value, _T("bsdsocket_emu"), &p->socket_emu))
                return 1;
 
diff --git a/cia.cpp b/cia.cpp
index 5aed86b424ee913f42e65a734ef4aa7074d7b402..148b4cf96f1c108e37e4c9c7581975aafb2c65f6 100644 (file)
--- a/cia.cpp
+++ b/cia.cpp
@@ -2497,6 +2497,11 @@ static uae_u32 REGPARAM2 clock_bget (uaecptr addr)
        return getclockreg (addr, ct);
 }
 
+static void cputester_event(uae_u32 v)
+{
+       IRQ_forced(1, 64 / 2);
+}
+
 static void REGPARAM2 clock_lput (uaecptr addr, uae_u32 value)
 {
        if ((addr & 0xffff) >= 0x8000 && currprefs.cs_fatgaryrev >= 0) {
@@ -2523,6 +2528,10 @@ static void REGPARAM2 clock_bput (uaecptr addr, uae_u32 value)
 {
 //     write_log(_T("W: %x (%x): %x, PC=%08x\n"), addr, (addr & 0xff) >> 2, value & 0xff, M68K_GETPC);
 
+       if (currprefs.cputester && (addr & 65535) == 0) {
+               event2_newevent_xx(-1, CYCLE_UNIT * (64 / 2), 0, cputester_event);
+       }
+
        if ((addr & 0xffff) >= 0x8000 && currprefs.cs_fatgaryrev >= 0) {
                dummy_put(addr, 1, value);
                return;
index 04f7b9cde1a3ddaf149dbbad749fd91a683c1517..ed113d580427fd5cdfc06d7d3d6dd628c40cf5c6 100644 (file)
@@ -142,6 +142,7 @@ static uae_u32 trace_store_pc;
 static uae_u16 trace_store_sr;
 static int generate_address_mode;
 static int test_memory_access_mask;
+static uae_u32 opcode_memory_address;
 
 static uae_u8 imm8_cnt;
 static uae_u16 imm16_cnt;
@@ -372,8 +373,8 @@ static void count_interrupt_cycles(int cycles)
                return;
        interrupt_cycle_cnt -= cycles;
        if (interrupt_cycle_cnt <= 0) {
+               regs.ipl_pin = 1;
                interrupt_cycle_cnt = 0;
-               Exception(24 + 6);
        }
 }
 
@@ -473,8 +474,9 @@ uae_u32 get_ilong_test(uaecptr addr)
 uae_u16 get_word_test_prefetch(int o)
 {
        // no real prefetch
-       if (cpu_lvl < 2)
+       if (cpu_lvl < 2) {
                o -= 2;
+       }
        add_memory_cycles(-1);
        regs.irc = get_iword_test(m68k_getpci() + o + 2);
        read_buffer_prev = regs.read_buffer;
@@ -517,6 +519,11 @@ void put_byte_test(uaecptr addr, uae_u32 v)
 {
        if (!testing_active && is_nowrite_address(addr, 1))
                return;
+       if (feature_interrupts == 2 && addr == IPL_TRIGGER_ADDR) {
+               add_memory_cycles(1);
+               interrupt_cycle_cnt = INTERRUPT_CYCLES - 2;
+               return;
+       }
        check_bus_error(addr, 1, regs.s ? 5 : 1);
        uae_u8 *p = get_addr(addr, 1, 2);
        if (!out_of_test_space && !noaccesshistory && !hardware_bus_error_fake) {
@@ -821,6 +828,9 @@ bool is_cycle_ce(uaecptr addr)
 
 void ipl_fetch(void)
 {
+       if (regs.ipl_pin) {
+               regs.ipl = regs.ipl_pin;
+       }
 }
 
 int intlev(void)
@@ -3925,6 +3935,7 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp, bool
        cpu_cycles = 0;
        regs.loop_mode = 0;
        regs.ipl_pin = 0;
+       regs.ipl = 0;
        interrupt_level = 0;
        interrupt_cycle_cnt = 0;
 
@@ -3942,7 +3953,7 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp, bool
                cnt = 100;
        }
        if (feature_interrupts == 2) {
-               interrupt_cycle_cnt = SERPER * 10 - 20;
+               interrupt_cycle_cnt = INTERRUPT_CYCLES;
        }
 
        for (;;) {
@@ -4048,6 +4059,18 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp, bool
                        break;
                }
 
+               if (feature_interrupts == 2) {
+                       if (regs.ipl > regs.intmask) {
+                               Exception(24 + regs.ipl);
+                               break;
+                       }
+               } else {
+                       if (regs.ipl_pin > regs.intmask) {
+                               Exception(24 + regs.ipl_pin);
+                               break;
+                       }
+               }
+
                if (regs.pc == endpc || regs.pc == targetpc) {
                        // Trace is only added as an exception if there was no other exceptions
                        // Trace stacked with other exception is handled later
@@ -4064,11 +4087,6 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp, bool
                if (!valid_address(regs.pc, 2, 0))
                        break;
 
-               if (regs.ipl_pin > regs.intmask) {
-                       Exception(24 + regs.ipl_pin);
-                       break;
-               }
-
                if (!feature_loop_mode_jit && !feature_loop_mode_68010) {
                        // trace after NOP
                        if (SPCFLAG_DOTRACE) {
@@ -4110,6 +4128,24 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp, bool
                opc = regs.ir;
        }
 
+       if (feature_interrupts == 2) {
+               // IPL test must cause some exception
+               if (!test_exception) {
+                       test_exception = -1;
+               }
+               // Interrupt start must be before test instruction,
+               // after test instruction
+               // or after end NOP instruction
+               if (test_exception >= 24 && test_exception <= 24 + 8) {
+                       if (test_exception_addr != opcode_memory_address &&
+                               test_exception_addr != opcode_memory_address - 2 &&
+                               test_exception_addr != test_instruction_end_pc)
+                       {
+                               test_exception = -1;
+                       }
+               }
+       }
+
        testing_active = 0;
 
        if (regs.s) {
@@ -4532,6 +4568,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
        full_format_cnt = 0;
        last_exception_len = -1;
        interrupt_count = 0;
+       interrupt_delay_cnt = 0;
 
        int sr_override = 0;
 
@@ -4546,7 +4583,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                target_address_bak = target_address;
                target_opcode_address_bak = target_opcode_address;
 
-               uae_u32 opcode_memory_address = opcode_memory_start;
+               opcode_memory_address = opcode_memory_start;
                uae_u8 *opcode_memory_ptr = opcode_memory;
                if (target_opcode_address != 0xffffffff) {
                        opcode_memory_address += target_opcode_address;
@@ -4592,10 +4629,6 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                int branch_target_swap_mode_old = 0;
                int doopcodeswap = 1;
 
-               if (feature_interrupts == 2) {
-                       doopcodeswap = 0;
-               }
-
                if (verbose) {
                        if (target_ea[0] != 0xffffffff)
                                wprintf(_T(" Target EA SRC=%08x\n"), target_ea[0]);
@@ -4771,16 +4804,16 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                        // interrupt timing test mode
                                        if (feature_interrupts == 2) {
                                                pc -= 2;
-                                               // move.w #x,0xdff032 (SERDAT) (20 cycles)
-                                               put_long_test(pc + 0, (0x33fc << 16) | 0x100 | '!');
-                                               put_long_test(pc + 4, 0x00dff030);
-//                                             // moveq #x,d0 (4 cycles)
-//                                             put_word_test(pc + 8, 0x7000 | interrupt_delay_cnt);
+                                               // moveq #x,d0 (4)
+                                               put_word_test(pc + 0, 0x7000 | interrupt_delay_cnt);
+                                               // move.b d0,0xdcfffc (RTCW) (8 + 4 + 4)
+                                               put_word_test(pc + 2, 0x13c0);
+                                               put_long_test(pc + 4, IPL_TRIGGER_ADDR);
                                                // ror.l d0,d0 (4 + 4 + d0 * 2 cycles)
                                                put_word_test(pc + 8, 0xe0b8);
                                                put_word_test(pc + 10, NOP_OPCODE); // (4 cycles)
                                                pc += 12;
-                                               opcode_memory_address = startpc = pc;
+                                               opcode_memory_address = pc;
                                                pc += 2;
                                        }
 
@@ -5095,8 +5128,9 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                if (dstaddr != 0xffffffff && srcaddr != dstaddr) {
                                                        outbytes(_T("D"), dstaddr);
                                                }
-                                               if (feature_loop_mode_jit || feature_loop_mode_68010) {
+                                               if (feature_loop_mode_jit || feature_loop_mode_68010) { // || feature_interrupts == 2) {
                                                        wprintf(_T("\n"));
+                                                       nextpc = opcode_memory_start;
                                                        for (int i = 0; i < 20; i++) {
                                                                out_of_test_space = false;
                                                                if (get_word_test(nextpc) == ILLG_OPCODE)
@@ -5294,12 +5328,6 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                dst = store_reg(dst, CT_AREG + 7, 0, target_usp_address, sz_long);
                                        }
 
-                                       if (feature_interrupts == 2) {
-                                               *dst++ = CT_EDATA;
-                                               *dst++ = CT_EDATA_IRQ_CYCLES;
-                                               *dst++ = interrupt_delay_cnt;
-                                       }
-
                                        // pre-test data end
                                        *dst++ = CT_END_INIT;
 
@@ -5316,7 +5344,6 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                        int t_cnt = 0;
 
                                        int extraccr = 0;
-                                       interrupt_delay_cnt = -1;
 
                                        // extra loops for supervisor and trace
                                        uae_u16 sr_allowed_mask = feature_sr_mask & 0xf000;
@@ -5372,9 +5399,6 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                *dst++ = (uae_u8)(maxflag | (fpumode ? 0x80 : 0x00) | (flagmode ? 0x40 : 0x00));
 
                                                maxflagcnt = maxflag;
-                                               if (feature_interrupts == 2) {
-                                                       maxflagcnt *= 64;
-                                               }
 
                                                // Test every CPU CCR or FPU SR/rounding/precision combination
                                                for (int ccrcnt = 0; ccrcnt < maxflagcnt; ccrcnt++) {
@@ -5502,10 +5526,6 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                        }
                                                        regs.sr |= feature_min_interrupt_mask << 8;
 
-                                                       if (feature_interrupts == 2) {
-                                                               regs.regs[0] = ccrcnt >> maxflagshift;
-                                                       }
-
                                                        // override special register values
                                                        for (int i = 0; i < regdatacnt; i++) {
                                                                struct regdata *rd = &regdatas[i];
@@ -5858,7 +5878,8 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                }
                                        }
                                        if (verbose) {
-                                               wprintf(_T(" OK=%d OB=%d S=%d/%d T=%d STP=%d I=%d"), ok, exception_array[0], prev_s_cnt, s_cnt, t_cnt, cnt_stopped, interrupt_delay_cnt);
+                                               wprintf(_T(" OK=%d OB=%d S=%d/%d T=%d STP=%d I=%d/%d %08x"), ok, exception_array[0],
+                                                       prev_s_cnt, s_cnt, t_cnt, cnt_stopped, interrupt_delay_cnt, interrupt_cycle_cnt, test_exception_addr);
                                                if (!ccr_done)
                                                        wprintf(_T(" X"));
                                                for (int i = 2; i < 128; i++) {
@@ -5948,18 +5969,16 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                        nextround = true;
                }
 
-#if 0
-               // interrupt delay test from 0 to 63
+               // interrupt delay test
                if (feature_interrupts == 2) {
                        interrupt_delay_cnt++;
-                       if (interrupt_delay_cnt >= 64) {
+                       if (interrupt_delay_cnt >= MAX_INTERRUPT_DELAY) {
                                break;
                        } else {
                                nextround = true;
                                rounds = 1;
                        }
                }
-#endif
 
                if (target_opcode_address != 0xffffffff || target_usp_address != 0xffffffff) {
                        nextround = false;
index 5ff07086f32e72dcbe8d5a58cdaafa9a85f51275..40faacaf29a10c26260a985044a4438d43fa3198 100644 (file)
@@ -50,6 +50,8 @@ S_FPSR = S_FPCR+4
 S_FSAVE = S_FPSR+4
 S_NEXT = S_FSAVE+216
 
+asm_start:
+
        | v1, v2, limit
        | abs((v2 - v1) / v1) > limit
 _fpucomp:
@@ -356,6 +358,21 @@ exception:
 _cyclereg_address4:
        move.w CYCLEREG,cycles+2
        move.w #0,ACTIVITYREG
+       | exception start inside this assembly code?
+       cmp.l #asm_start,2+4+2(sp)
+       bcs.s .okpc
+       cmp.l #asm_end,2+4+2(sp)
+       bhi.s .okpc
+       | interrupt?
+       cmp.l #_exceptiontable000+24*2,2(sp)
+       bcs.s .okpc
+       cmp.l #_exceptiontable000+(24+8)*2,2(sp)
+       bcc.s .okpc
+       | possibly IPL tester spurious interrupt
+       | ignore it
+       addq.l #2+4,sp
+       rte
+.okpc:
        move.l a0,-(sp)
        move.l datapointer(pc),a0
        movem.l d0-d7/a0-a6,(a0)
@@ -377,6 +394,18 @@ _cyclereg_address4:
        move.w (sp),S_EXC+0(a0)
        addq.w #8,sp
 .noaddresserror:
+       cmp.w #24,d0
+       bcs.s .nointerrupt
+       cmp.w #24+8,d0
+       bcc.s .nointerrupt
+       | possible IPL test run, delay a bit
+       | to make sure tester hardware is not pulling
+       | IPL line down anymore
+       moveq #16-1,d1
+.delay1:
+       dbf d1,.delay1
+.nointerrupt:
+
        move.w (sp)+,S_SR+2(a0)
        move.l (sp)+,S_PC(a0)
 
@@ -753,3 +782,4 @@ temp:
        dc.l 0
 nullframe:
        dc.l 0,0,0
+asm_end:
index 4bca3244a591a3322b070f9b9c222ee81fb0873b..f98548b6f988efb30986858caff51085cbfa7fa4 100644 (file)
@@ -58,4 +58,6 @@
 #define ILLG_OPCODE 0x4afc
 #define LM_OPCODE 0x42db
 
-#define SERPER 8
+#define INTERRUPT_CYCLES 64
+#define MAX_INTERRUPT_DELAY 64
+#define IPL_TRIGGER_ADDR 0xdc0000
index a5d97cbf1ef0593f1bc6b87ab5ad76877f54e88f..4d193156dd18d78e05f3e3346fc5d719b3799140 100644 (file)
@@ -124,7 +124,7 @@ feature_usp=0
 feature_exception_vectors=
 
 ; global exception disable/enable
-; -<exception number> = disable all except listed. <exception number> = enable only listed
+; -<exception number> = disable listed, enable all others. <exception number> = enable only listed
 ; default: all enabled
 exceptions=
 
@@ -236,10 +236,11 @@ mode=all
 ; interrupt timing test
 [test=IPL]
 cpu=68000-68010
-enabled=0
+enabled=1
+verbose=0
 feature_undefined_ccr=1
 feature_interrupts=2
-mode=exg,neg,not,ror,rol,swap
+mode=all
 
 ; interrupt exception
 [test=IRQ]
index 6049ff8caf16fc4cf3d4b8638368bbd44f0a4dc2..28f0dd86103eb685ce702d180fd9ef430cb64a86 100644 (file)
@@ -61,15 +61,6 @@ struct registers
        uae_u16 fpeaset;
 };
 
-
-struct irqresult
-{
-       uae_u32 pc;
-       uae_u16 sr;
-};
-
-static struct irqresult irqresults[64 + 1], irqresults2[64 + 1];
-
 static short continue_on_error;
 static struct registers test_regs;
 static struct registers last_regs;
@@ -318,29 +309,6 @@ uae_s32 lls(uae_u16 *p)
        return (uae_s32)llu(p);
 }
 
-static void interrupt_results(void)
-{
-       if (interrupttest == 2) {
-               short pvcnt = 0;
-               for(short i = 0; i < 64; i++) {
-                       struct irqresult *irq1 = &irqresults[i];
-                       struct irqresult *irq2 = &irqresults[i + 1];
-                       if (irq1->pc == irq2->pc && irq1->sr == irq2->sr && i < 63) {
-                               pvcnt++;
-                       }
-                       if (irq1->pc != irq2->pc || irq1->sr != irq2->sr || i == 63) {
-                               if (irq1->sr == 0x6000) {
-                                       printf("S%02d-%02d: %08x ", i - pvcnt, i, irq1->pc);
-                               } else {
-                                       printf("U%02d-%02d: %08x ", i - pvcnt, i, irq1->pc);
-                               }
-                               pvcnt = 0;
-                       }
-               }
-               printf("\n");
-       }
-}
-
 static void endinfo(void)
 {
        printf("Last test: %u\n", testcnt);
@@ -2176,16 +2144,6 @@ static int get_cycles_amiga(void)
 
 static uae_u16 test_intena, test_intreq;
 
-static void set_interrupt_sertest(void)
-{
-       volatile uae_u16 *intena = (uae_u16 *)0xdff09a;
-       volatile uae_u16 *serper = (uae_u16 *)0xdff032;
-       // enable serial receive interrupt
-       *intena = 0x8000 | 0x4000 | 0x0800;
-       // serial period
-       *serper = SERPER;
-}
-
 static void set_interrupt(void)
 {
        if (interrupt_count < 15) {
@@ -2426,12 +2384,6 @@ static uae_u8 *validate_test(uae_u8 *p, short ignore_errors, short ignore_sr, st
        uae_u8 fpiar_changed = 0, fpsr_changed = 0, fpcr_changed = 0;
        short exc = -1;
 
-       if (interrupttest == 2) {
-               struct irqresult *irq = &irqresults[interrupt_delay_cnt];
-               irq->pc = tregs->pc;
-               irq->sr = tregs->sr & 0xff00;
-       }
-
        if (loop_mode_jit) {
                memset(lmtable1, 0xff, sizeof(lmtable1));
                memset(lmtable2, 0xff, sizeof(lmtable2));
@@ -2934,7 +2886,7 @@ static uae_u8 *validate_test(uae_u8 *p, short ignore_errors, short ignore_sr, st
                outbp += strlen(outbp);
                out_regs(tregs, tregs, lregs, sregs, 0, branched2);
 #ifdef AMIGA
-               if (interrupttest) {
+               if (interrupttest == 1) {
                        sprintf(outbp, "INTREQ: %04x INTENA: %04x\n", test_intreq, test_intena);
                        outbp += strlen(outbp);
                }
@@ -3063,17 +3015,8 @@ static void process_test(uae_u8 *p)
 
        short doopcodeswap = 1;
 
-       if (interrupttest == 2) {
-               doopcodeswap = 0;
-       }
-
        for (;;) {
 
-               if (interrupttest == 2) {
-                       memcpy(irqresults2, irqresults, sizeof(irqresults));
-                       memset(irqresults, 0, sizeof(irqresults));
-               }
-
                cur_regs.endpc = endpc;
                cur_regs.pc = startpc;
 
@@ -3137,9 +3080,6 @@ static void process_test(uae_u8 *p)
                                ccrshift++;
                        }
                        ccrshift--;
-                       if (interrupttest == 2) {
-                               maxccr *= 64;
-                       }
                        testcntsubmax = maxccr;
                        testcntsub = 0;
                        for (short ccrcnt = 0; ccrcnt < maxccr; ccrcnt++, testcntsub++) {
@@ -3260,11 +3200,6 @@ static void process_test(uae_u8 *p)
 
                                test_regs.expsr = test_regs.sr | 0x2000;
 
-                               if (interrupttest == 2) {
-                                       interrupt_delay_cnt = ccrcnt >> ccrshift;
-                                       cur_regs.regs[0] = test_regs.regs[0] = interrupt_delay_cnt;
-                               }
-
                                // internally modified registers become part of cur_regs
                                cur_regs.sr = test_regs.sr;
                                cur_regs.expsr = test_regs.expsr;
@@ -3318,8 +3253,6 @@ static void process_test(uae_u8 *p)
 #ifdef AMIGA
                                                if (interrupttest == 1) {
                                                        set_interrupt();
-                                               } else  if (interrupttest == 2) {
-                                                       set_interrupt_sertest();
                                                }
 #endif
                                                if (cpu_lvl == 1) {
@@ -3384,29 +3317,26 @@ static void process_test(uae_u8 *p)
                                        fpu_approxcnt++;
                                }
 
-                               if (interrupttest != 2) {
-
-                                       if (quit || errors) {
-                                               if (!quit && errorcnt > 0 && totalerrors < errorcnt) {
-                                                       if (totalerrors > 0) {
-                                                               strcat(stored_outbuffer, "----------------------------------------\n");
-                                                       }
-                                                       if (strlen(stored_outbuffer) + strlen(outbuffer) + 40 >= outbuffer_size) {
-                                                               goto end;
-                                                       }
-                                                       strcat(stored_outbuffer, outbuffer);
-                                                       outbp = stored_outbuffer + strlen(stored_outbuffer);
-                                                       out_endinfo();
-                                                       infoadded = 0;
-                                                       errors = 0;
-                                                       outbuffer[0] = 0;
-                                                       outbuffer2[0] = 0;
-                                                       outbp = outbuffer2;
-                                               } else {
+                               if (quit || errors) {
+                                       if (!quit && errorcnt > 0 && totalerrors < errorcnt) {
+                                               if (totalerrors > 0) {
+                                                       strcat(stored_outbuffer, "----------------------------------------\n");
+                                               }
+                                               if (strlen(stored_outbuffer) + strlen(outbuffer) + 40 >= outbuffer_size) {
                                                        goto end;
                                                }
-                                               totalerrors++;
+                                               strcat(stored_outbuffer, outbuffer);
+                                               outbp = stored_outbuffer + strlen(stored_outbuffer);
+                                               out_endinfo();
+                                               infoadded = 0;
+                                               errors = 0;
+                                               outbuffer[0] = 0;
+                                               outbuffer2[0] = 0;
+                                               outbp = outbuffer2;
+                                       } else {
+                                               goto end;
                                        }
+                                       totalerrors++;
                                }
                        }
 
@@ -3426,21 +3356,6 @@ static void process_test(uae_u8 *p)
                }
 
                restoreahist();
-
-               // increase count when interrupt test returns different results
-               if (interrupttest == 2) {
-                       if (memcmp(irqresults, irqresults2, sizeof(irqresults))) {
-                               interrupttest_diff_cnt++;
-                               if (interrupttest_diff_cnt == irqcnt) {
-                                       end_test();
-                                       printf(outbuffer);
-                                       printf("Interrupt test count expired\n");
-                                       interrupt_results();
-                                       exit(0);
-                               }
-                       }
-               }
-
        }
 
 end:
@@ -3455,9 +3370,6 @@ end:
                        printf("%s", outbuffer);
                }
        }
-       if (interrupttest == 2) {
-               interrupt_results();
-       }
 }
 
 static void freestuff(void)
@@ -3710,7 +3622,7 @@ static int test_mnemo(const char *opcode)
 
 static int getparamval(const char *p)
 {
-       ULONG inv = 0;
+       uae_u32 inv = 0;
        if (p[0] == '~') {
                inv = 0xffffffff;
                p++;
index cfe8b30a5a0643b84eb58bd5b5024eb8b892ce4e..baec81c66b7477305d408557760b22ce5fabd5a3 100644 (file)
@@ -7325,20 +7325,29 @@ static void DMACON(int hpos, uae_u16 v)
        }
 }
 
-static int irq_nmi;
+static int irq_forced, irq_delay;
 
-void NMI_delayed(void)
+void IRQ_forced(int lvl, int delay)
 {
-       irq_nmi = 1;
+       irq_forced = lvl;
+       irq_delay = -1;
+       if (delay > 0 && currprefs.cpu_compatible) {
+               irq_delay = get_cycles() + irq_delay * CYCLE_UNIT;
+       }
+       doint();
 }
 
 int intlev(void)
 {
-       uae_u16 imask = intreq & intena;
-       if (irq_nmi) {
-               irq_nmi = 0;
-               return 7;
+       if (irq_forced) {
+               int lvl = irq_forced;
+               if (irq_delay == -1 || ((int)get_cycles()) - irq_delay > 0) {
+                       irq_forced = 0;
+                       irq_delay = -1;
+               }
+               return lvl;
        }
+       uae_u16 imask = intreq & intena;
        if (!(imask && (intena & 0x4000)))
                return -1;
        if (imask & (0x4000 | 0x2000))                                          // 13 14
index cb339844b5196627886a9a26be23ad088d8eb4f3..27fa82443cda330f2bcd3f79cb36872cc345f28b 100644 (file)
@@ -686,7 +686,7 @@ extern void REGPARAM3 Exception_cpu(int) REGPARAM;
 extern void REGPARAM3 Exception_cpu_oldpc(int, uaecptr) REGPARAM;
 extern void REGPARAM3 ExceptionL (int, uaecptr) REGPARAM;
 extern void NMI (void);
-extern void NMI_delayed (void);
+extern void IRQ_forced(int, int);
 extern void prepare_interrupt (uae_u32);
 extern void doint (void);
 extern void dump_counts (void);
index 76d9cf4c59abf0ce63cf3b971fdbc9ec7e77d4ae..b29adb05b0d6c686a658881f79d2e4a1eb8bd4b6 100644 (file)
@@ -795,6 +795,7 @@ struct uae_prefs {
        bool obs_sound_toccata_mixer;
        bool obs_sound_es1370;
        bool obs_sound_fm801;
+       bool cputester;
 
        int mountitems;
        struct uaedev_config_data mountconfig[MOUNT_CONFIG_SIZE];
index 573c66dcfabc7ae93f8fb6120d450931f550a05a..a1a02845ad82bbae641a180404b95ef216ab8aad 100644 (file)
@@ -4423,7 +4423,7 @@ static bool inputdevice_handle_inputcode2(int monid, int code, int state, const
                changed_prefs.cdslots[0].inuse = false;
                break;
        case AKS_IRQ7:
-               NMI_delayed ();
+               IRQ_forced(7, 0);
                break;
        case AKS_PAUSE:
                pausemode(newstate > 0 ? 1 : newstate);