From d291bd3ee1680d7921109970b1f033f9fda3acb4 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Fri, 15 Apr 2022 21:22:05 +0300 Subject: [PATCH] cputester IPL timing test support --- cfgfile.cpp | 2 + cia.cpp | 9 +++ cputest.cpp | 97 +++++++++++++++++------------ cputest/asm.S | 30 +++++++++ cputest/cputest_defines.h | 4 +- cputest/cputestgen.ini | 7 ++- cputest/main.c | 126 ++++++-------------------------------- custom.cpp | 23 ++++--- include/newcpu.h | 2 +- include/options.h | 1 + inputdevice.cpp | 2 +- 11 files changed, 144 insertions(+), 159 deletions(-) diff --git a/cfgfile.cpp b/cfgfile.cpp index 64648c2d..50f7fb93 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -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 5aed86b4..148b4cf9 100644 --- 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; diff --git a/cputest.cpp b/cputest.cpp index 04f7b9cd..ed113d58 100644 --- a/cputest.cpp +++ b/cputest.cpp @@ -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 = ®datas[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; diff --git a/cputest/asm.S b/cputest/asm.S index 5ff07086..40faacaf 100644 --- a/cputest/asm.S +++ b/cputest/asm.S @@ -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: diff --git a/cputest/cputest_defines.h b/cputest/cputest_defines.h index 4bca3244..f98548b6 100644 --- a/cputest/cputest_defines.h +++ b/cputest/cputest_defines.h @@ -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 diff --git a/cputest/cputestgen.ini b/cputest/cputestgen.ini index a5d97cbf..4d193156 100644 --- a/cputest/cputestgen.ini +++ b/cputest/cputestgen.ini @@ -124,7 +124,7 @@ feature_usp=0 feature_exception_vectors= ; global exception disable/enable -; - = disable all except listed. = enable only listed +; - = disable listed, enable all others. = 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] diff --git a/cputest/main.c b/cputest/main.c index 6049ff8c..28f0dd86 100644 --- a/cputest/main.c +++ b/cputest/main.c @@ -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++; diff --git a/custom.cpp b/custom.cpp index cfe8b30a..baec81c6 100644 --- a/custom.cpp +++ b/custom.cpp @@ -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 diff --git a/include/newcpu.h b/include/newcpu.h index cb339844..27fa8244 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -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); diff --git a/include/options.h b/include/options.h index 76d9cf4c..b29adb05 100644 --- a/include/options.h +++ b/include/options.h @@ -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]; diff --git a/inputdevice.cpp b/inputdevice.cpp index 573c66dc..a1a02845 100644 --- a/inputdevice.cpp +++ b/inputdevice.cpp @@ -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); -- 2.47.3