From 77ac4068ef2abfdf92ab4c6e51c742397061e20b Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Thu, 26 Dec 2019 20:16:44 +0200 Subject: [PATCH] Remaining bus error prefetch updates and other fixes. --- cputest.cpp | 36 +++-- cputest/adis/decode_ea.c | 14 +- cputest/adis/defs.h | 2 +- cputest/adis/util.c | 15 +- cputest/asm.S | 20 +-- cputest/cputest_defines.h | 3 +- cputest/main.c | 46 ++++-- gencpu.cpp | 330 +++++++++++++++++++++++++++----------- include/newcpu.h | 3 +- newcpu_common.cpp | 7 +- 10 files changed, 334 insertions(+), 142 deletions(-) diff --git a/cputest.cpp b/cputest.cpp index 0bfd73e4..05a214ab 100644 --- a/cputest.cpp +++ b/cputest.cpp @@ -159,7 +159,7 @@ struct accesshistory static int ahcnt_current, ahcnt_written; static int noaccesshistory = 0; -#define MAX_ACCESSHIST 80 +#define MAX_ACCESSHIST 128 static struct accesshistory ahist[MAX_ACCESSHIST]; static int is_superstack_use_required(void) @@ -2953,6 +2953,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi int quick = 0; int rounds = feature_test_rounds; int subtest_count = 0; + int data_saved = 0; int count = 0; @@ -3074,6 +3075,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi uae_u32 dstaddr = 0xffffffff; uae_u32 branchtarget_old = 0xffffffff; uae_u32 instructionendpc_old = opcode_memory_start; + uae_u32 startpc_old = opcode_memory_start; int branch_target_swap_mode_old = 0; if (verbose) { @@ -3189,11 +3191,8 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi printf(""); - uaecptr pc = opcode_memory_start + 2; - - if (is_nowrite_address(pc, 1)) { - goto nextopcode; - } + uaecptr startpc = opcode_memory_start; + uaecptr pc = startpc + 2; if (target_opcode_address != 0xffffffff) { pc -= 2; @@ -3207,6 +3206,13 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi abort(); } } + startpc = opcode_memory_address; + } + + // Start address to start address + 3 must be accessible or + // jump prefetch would cause early bus error which we don't want + if (is_nowrite_address(startpc, 4)) { + goto nextopcode; } if (dp->mnemo != i_ILLG) { @@ -3494,13 +3500,17 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi dst = store_mem_writes(dst, 1); uae_u32 instructionendpc_old_prev = instructionendpc_old; + uae_u32 startpc_old_prev = startpc_old; uae_u32 branchtarget_old_prev = branchtarget_old; uae_u32 srcaddr_old_prev = srcaddr_old; uae_u32 dstaddr_old_prev = dstaddr_old; - // PC before test: end address of test intruction + if (startpc != startpc_old) { + dst = store_reg(dst, CT_PC, startpc_old, startpc, -1); + startpc_old = startpc; + } if (instructionendpc != instructionendpc_old) { - dst = store_reg(dst, CT_PC, instructionendpc_old, instructionendpc, -1); + dst = store_reg(dst, CT_ENDPC, instructionendpc_old, instructionendpc, -1); instructionendpc_old = instructionendpc; } if (srcaddr != srcaddr_old && (dflags & 1)) { @@ -3623,7 +3633,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi // initialize CPU state - regs.pc = opcode_memory_start; + regs.pc = startpc; regs.ir = get_word_test(regs.pc + 0); regs.irc = get_word_test(regs.pc + 2); @@ -3906,8 +3916,10 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi dstaddr_old = dstaddr_old_prev; branchtarget_old = branchtarget_old_prev; instructionendpc_old = instructionendpc_old_prev; + startpc_old = startpc_old_prev; } else { full_format_cnt++; + data_saved = 1; } if (verbose) { wprintf(_T(" OK=%d OB=%d S=%d/%d T=%d STP=%d"), ok, exception_array[0], prev_s_cnt, s_cnt, t_cnt, cnt_stopped); @@ -3927,6 +3939,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi srcaddr_old = 0xffffffff; dstaddr_old = 0xffffffff; instructionendpc_old = opcode_memory_start; + startpc_old = opcode_memory_start; } dst = storage_buffer; for (int i = 0; i < MAX_REGISTERS; i++) { @@ -3957,8 +3970,9 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi nextopcode:; } - if (subtest_count > 0) { + if (data_saved) { save_data(dst, dir); + data_saved = 0; } dst = storage_buffer; @@ -4006,6 +4020,8 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi target_ea_opcode_cnt = 0; if (target_ea_opcode_max > 0) nextround = true; + } else { + quick = 0; } target_opcode_address = feature_target_ea[target_ea_opcode_cnt][2]; target_ea[2] = opcode_memory_address + target_opcode_address; diff --git a/cputest/adis/decode_ea.c b/cputest/adis/decode_ea.c index 24874dda..3f4b39ed 100644 --- a/cputest/adis/decode_ea.c +++ b/cputest/adis/decode_ea.c @@ -139,19 +139,25 @@ switch (mode) /****************** address register indirect indexed ***************/ case 6: + if ((first_ext_w & 0x100) && !cpu68020) + first_ext_w &= ~0x100; if (first_ext_w & 0x100) { if (cpu68020) return (full_extension (to, code + first_ext, mode, reg)); +#if 0 else { instr_bad = TRUE; return (0); } - } +#endif + } else { UWORD size = (first_ext_w >> 9) & 0x3; + if (size != 0 && !cpu68020) + size = 0; #if 0 if (!cpu68020 && size != 0) /* Only size of 1 allowed for 68000 */ { @@ -263,7 +269,9 @@ switch (mode) /***************** PC memory indirect with index ************/ case 3: - if (first_ext_w & 0x0100) + if ((first_ext_w & 0x100) && !cpu68020) + first_ext_w &= ~0x100; + if (first_ext_w & 0x0100) { /* long extension word */ if (cpu68020) @@ -279,6 +287,8 @@ switch (mode) else { UWORD size = (first_ext_w >> 9) & 0x3; + if (size != 0 && !cpu68020) + size = 0; #if 0 if (!cpu68020 && size != 0) /* Only size of 1 allowed for 68000 */ { diff --git a/cputest/adis/defs.h b/cputest/adis/defs.h index 63c24544..1a1c53d0 100644 --- a/cputest/adis/defs.h +++ b/cputest/adis/defs.h @@ -319,7 +319,7 @@ void analyze_code (UBYTE *seg); uint decode_ea (char *to, ushort mode, ushort reg, UWORD access, ushort first_ext); /* disasm_code.c */ -uint disasm_instr (UWORD *instr, char*); +uint disasm_instr (UWORD *instr, char*, int); void disasm_code (UBYTE *seg, ULONG seg_size); /* disasm_data.c */ diff --git a/cputest/adis/util.c b/cputest/adis/util.c index 6280b541..8df07bde 100644 --- a/cputest/adis/util.c +++ b/cputest/adis/util.c @@ -960,7 +960,7 @@ ULONG next_ref(ULONG from, ULONG to, UWORD *access_type) return 0; } -uint disasm_instr(UWORD *instr, char *out) +uint disasm_instr(UWORD *instr, char *out, int cpu_lvl) /**********************************************************************/ /* Returns number of 16 bit words disassembled */ @@ -973,6 +973,19 @@ uint disasm_instr(UWORD *instr, char *out) first_ref = 0; last_ref = 0xffffffff; current_ref = (ULONG)instr; + if (cpu_lvl < 5) { + cpu68060 = 0; + } + if (cpu_lvl < 4) { + cpu68040 = 0; + } + if (cpu_lvl < 3) { + cpu68030 = 0; + } + if (cpu_lvl < 2) { + cpu68020 = 0; + fpu68881 = 0; + } set_pass3; diff --git a/cputest/asm.S b/cputest/asm.S index beee98ff..c37f5f82 100644 --- a/cputest/asm.S +++ b/cputest/asm.S @@ -122,10 +122,7 @@ _execute_test000: move.l S_SSP(a0),sp move.l S_PC(a0),a1 move.l a1,-(sp) - move.w (a1)+,d0 - move.w (a1),d1 - eor.w d1,d0 - move.w d0,ACTIVITYREG | opcode^first param = background color + move.w (a1),ACTIVITYREG | opcode = background color move.w S_SR+2(a0),-(sp) move.l S_AREG+7*4(a0),a1 move.l a1,USP @@ -144,10 +141,7 @@ _execute_test010: move.l S_PC(a0),a1 clr.w -(sp) move.l a1,-(sp) - move.w (a1)+,d0 - move.w (a1),d1 - eor.w d1,d0 - move.w d0,ACTIVITYREG | opcode^first param = background color + move.w (a1),ACTIVITYREG | opcode = background color move.w S_SR+2(a0),-(sp) move.l S_AREG+7*4(a0),a1 move.l a1,USP @@ -169,10 +163,7 @@ _execute_test020: move.l S_PC(a0),a1 clr.w -(sp) move.l a1,-(sp) - move.w (a1)+,d0 - move.w (a1),d1 - eor.w d1,d0 - move.w d0,ACTIVITYREG | opcode^first param = background color + move.w (a1),ACTIVITYREG | opcode = background color move.w S_SR+2(a0),-(sp) move.l S_AREG+7*4(a0),a1 move.l a1,USP @@ -196,10 +187,7 @@ _execute_testfpu: move.l S_PC(a0),a1 clr.w -(sp) move.l a1,-(sp) - move.w (a1)+,d0 - move.w (a1),d1 - eor.w d1,d0 - move.w d0,ACTIVITYREG | opcode^first param = background color + move.w (a1),ACTIVITYREG | opcode = background color move.w S_SR+2(a0),-(sp) move.l S_AREG+7*4(a0),a1 move.l a1,USP diff --git a/cputest/cputest_defines.h b/cputest/cputest_defines.h index e50b27ac..33d15780 100644 --- a/cputest/cputest_defines.h +++ b/cputest/cputest_defines.h @@ -1,5 +1,5 @@ -#define DATA_VERSION 10 +#define DATA_VERSION 11 #define CT_FPREG 0 #define CT_DREG 0 @@ -11,6 +11,7 @@ #define CT_FPIAR 20 #define CT_FPSR 21 #define CT_FPCR 22 +#define CT_ENDPC 26 #define CT_BRANCHTARGET 27 #define CT_SRCADDR 28 #define CT_DSTADDR 29 diff --git a/cputest/main.c b/cputest/main.c index 0eb1e8aa..a54b4fd6 100644 --- a/cputest/main.c +++ b/cputest/main.c @@ -50,6 +50,7 @@ struct registers uae_u16 tracedata[6]; uae_u32 srcaddr, dstaddr, branchtarget; uae_u8 branchtarget_mode; + uae_u32 endpc; }; static struct registers test_regs; @@ -97,7 +98,7 @@ static int high_memory_offset; static uae_u32 vbr[256]; static int exceptioncount[3][128]; static int supercnt; -static uae_u32 endpc; +static uae_u32 startpc, endpc; static char inst_name[16+1]; #ifndef M68K @@ -115,6 +116,7 @@ static int quit; static uae_u8 ccr_mask; static uae_u32 addressing_mask = 0x00ffffff; static uae_u32 interrupt_mask; +static int disasm; #define SIZE_STORED_ADDRESS_OFFSET 8 #define SIZE_STORED_ADDRESS 16 @@ -878,6 +880,9 @@ static uae_u8 *restore_data(uae_u8 *p) } else if (mode == CT_DSTADDR) { int size; p = restore_value(p, ®s.dstaddr, &size); + } else if (mode == CT_ENDPC) { + int size; + p = restore_value(p, ®s.endpc, &size); } else if (mode == CT_PC) { int size; p = restore_value(p, ®s.pc, &size); @@ -959,7 +964,7 @@ static void addinfo_bytes(char *name, uae_u8 *src, uae_u32 address, int offset, *outbp++ = '\n'; } -extern uae_u16 disasm_instr(uae_u16 *, char *); +extern uae_u16 disasm_instr(uae_u16 *, char *, int); static void out_disasm(uae_u8 *mem) { @@ -985,7 +990,7 @@ static void out_disasm(uae_u8 *mem) } tmpbuffer[0] = 0; if (!(((uae_u32)code) & 1)) { - v = disasm_instr(code + offset, tmpbuffer); + v = disasm_instr(code + offset, tmpbuffer, cpu_lvl); sprintf(outbp, "%08lx ", p); outbp += strlen(outbp); for (int i = 0; i < v; i++) { @@ -1024,7 +1029,9 @@ static void addinfo(void) if (!dooutput) return; - out_disasm(opcode_memory); + if (disasm) { + out_disasm(opcode_memory); + } if (regs.branchtarget != 0xffffffff) { out_disasm((uae_u8*)regs.branchtarget); @@ -1055,8 +1062,8 @@ static void addinfo(void) uae_u8 *b = (uae_u8 *)regs.branchtarget - SIZE_STORED_ADDRESS_OFFSET; addinfo_bytes("B", b, regs.branchtarget, -SIZE_STORED_ADDRESS_OFFSET, SIZE_STORED_ADDRESS); } - //sprintf(outbp, "ENDPC=%08lx\n", endpc); - //outbp += strlen(outbp); + sprintf(outbp, "STARTPC=%08lx ENDPC=%08lx\n", startpc, endpc); + outbp += strlen(outbp); } struct srbit @@ -1541,8 +1548,13 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr) if ((val & (sr_undefined_mask & test_ccrignoremask)) != (test_regs.sr & (sr_undefined_mask & test_ccrignoremask)) && !ignore_errors && !ignore_sr) { addinfo(); if (dooutput) { - sprintf(outbp, "SR: expected %04x -> %04x but got %04x (%04x)\n", test_sr & 0xffff, val & 0xffff, test_regs.sr & 0xffff, test_ccrignoremask); + sprintf(outbp, "SR: expected %04x -> %04x but got %04x", test_sr & 0xffff, val & 0xffff, test_regs.sr & 0xffff); outbp += strlen(outbp); + if (test_ccrignoremask != 0xffff) { + sprintf(outbp, " (%04x)", test_ccrignoremask); + outbp += strlen(outbp); + } + *outbp++ = '\n'; } errors++; } @@ -1779,6 +1791,7 @@ static void process_test(uae_u8 *p) regs.branchtarget = 0xffffffff; endpc = opcode_memory_addr; + startpc = opcode_memory_addr; start_test(); @@ -1791,7 +1804,9 @@ static void process_test(uae_u8 *p) outbp = outbuffer; #endif - regs.pc = endpc; + regs.endpc = endpc; + regs.pc = startpc; + for (;;) { uae_u8 v = *p; if (v == CT_END_INIT || v == CT_END_FINISH) @@ -1805,14 +1820,14 @@ static void process_test(uae_u8 *p) store_addr(regs.srcaddr, srcaddr); store_addr(regs.dstaddr, dstaddr); store_addr(regs.branchtarget, branchtarget); - endpc = regs.pc; + startpc = regs.pc; + endpc = regs.endpc; uae_u8 *opcode_memory_end = (uae_u8*)endpc; xmemcpy(&last_registers, ®s, sizeof(struct registers)); int fpumode = fpu_model && (opcode_memory[0] & 0xf0) == 0xf0; - uae_u32 pc = opcode_memory_addr; uae_u32 originalopcodeend = 0x4afc4e71; uae_u32 opcodeend = originalopcodeend; int extraccr = 0; @@ -1823,8 +1838,8 @@ static void process_test(uae_u8 *p) validendsize = 1; } - uae_u32 last_pc = opcode_memory_addr; - uae_u32 last_fpiar = opcode_memory_addr; + uae_u32 last_pc = startpc; + uae_u32 last_fpiar = startpc; int old_super = -1; for (;;) { @@ -1866,8 +1881,8 @@ static void process_test(uae_u8 *p) regs.ssp = super_stack_memory - 0x80; regs.msp = super_stack_memory; - regs.pc = opcode_memory_addr; - regs.fpiar = opcode_memory_addr; + regs.pc = startpc; + regs.fpiar = startpc; #ifdef M68K xmemcpy((void*)regs.ssp, (void*)regs.regs[15], 0x20); @@ -2291,6 +2306,7 @@ int main(int argc, char *argv[]) check_undefined_sr = 1; ccr_mask = 0xff; + disasm = 1; for (int i = 1; i < argc; i++) { char *s = argv[i]; char *next = i + 1 < argc ? argv[i + 1] : NULL; @@ -2318,6 +2334,8 @@ int main(int argc, char *argv[]) cpu_lvl = 4; } else if (!_stricmp(s, "68060")) { cpu_lvl = 5; + } else if (!_stricmp(s, "nodisasm")) { + disasm = 0; } } diff --git a/gencpu.cpp b/gencpu.cpp index a6f6172b..9e746b81 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -4134,6 +4134,7 @@ static void gen_opcode (unsigned int opcode) g_instr = curi; g_srcname[0] = 0; bus_error_code[0] = 0; + bus_error_code2[0] = 0; // do not unnecessarily create useless mmuop030 // functions when CPU is not 68030 @@ -4183,9 +4184,9 @@ static void gen_opcode (unsigned int opcode) c += 2; if (curi->smode == imm || curi->smode == Dreg) { c += 2; - fill_prefetch_next_after("\t\tccr_68000_long_move_ae_LZN(src);\n\t\treg_68000_long_replace_low(dstreg, src);\n"); + fill_prefetch_next_after("\t\tccr_68000_long_move_ae_LZN(src);\n\t\tdreg_68000_long_replace_low(dstreg, src);\n"); } else { - fill_prefetch_next_after("\t\treg_68000_long_replace_low(dstreg, src);\n"); + fill_prefetch_next_after("\t\tdreg_68000_long_replace_low(dstreg, src);\n"); } } else { fill_prefetch_next_after("\t\tccr_68000_long_move_ae_LZN(src);\n"); @@ -4210,35 +4211,22 @@ static void gen_opcode (unsigned int opcode) } break; } - // all SR/CCR modifications does full prefetch + // all SR/CCR modifications do full prefetch case i_ORSR: + case i_ANDSR: case i_EORSR: - printf("\tMakeSR ();\n"); + printf("\tMakeSR();\n"); genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0); if (curi->size == sz_byte) { printf("\tsrc &= 0xFF;\n"); } else { check_trace(); } - addcycles000 (8); - printf("\tregs.sr %c= src;\n", curi->mnemo == i_EORSR ? '^' : '|'); + addcycles000(8); + printf("\tregs.sr %c= src;\n", curi->mnemo == i_ORSR ? '|' : curi->mnemo == i_ANDSR ? '&' : '^'); makefromsr_t0(); - sync_m68k_pc (); - fill_prefetch_full_ntx(0); - break; - case i_ANDSR: - printf("\tMakeSR ();\n"); - genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0); - if (curi->size == sz_byte) { - printf("\tsrc |= 0xFF00;\n"); - } else { - check_trace(); - } - addcycles000 (8); - printf("\tregs.sr &= src;\n"); - makefromsr_t0(); - sync_m68k_pc (); - fill_prefetch_full_ntx(0); + sync_m68k_pc(); + fill_prefetch_full_ntx(1); break; case i_SUB: { @@ -4246,21 +4234,54 @@ static void gen_opcode (unsigned int opcode) genamodedual (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, curi->dmode, "dstreg", curi->size, "dst", 1, GF_RMW); - //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0); - //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_RMW); - if (curi->dmode == Dreg) { - if (curi->size == sz_long) { + genflags(flag_sub, curi->size, "newv", "src", "dst"); + if (curi->size == sz_long) { + if (curi->dmode == Dreg) { c += 2; - if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg || curi->smode == Areg) + if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg || curi->smode == Areg) { c += 2; + fill_prefetch_next_after( + "\t\tuae_s16 bnewv = (uae_s16)dst - (uae_s16)src;\n" + "\t\tint bflgs = ((uae_s16)(src)) < 0;\n" + "\t\tint bflgo = ((uae_s16)(dst)) < 0;\n" + "\t\tint bflgn = bnewv < 0;\n" + "\t\tccr_68000_long_move_ae_LZN(bnewv);\n" + "\t\tSET_CFLG(((uae_u16)(src)) > ((uae_u16)(dst)));\n" + "\t\tSET_XFLG(GET_CFLG());\n" + "\t\tSET_VFLG((bflgs ^ bflgo) & (bflgn ^ bflgo));\n" + "\t\tdreg_68000_long_replace_low(dstreg, bnewv);\n"); + } else { + fill_prefetch_next_after("\t\tdreg_68000_long_replace_low(dstreg, newv);\n"); + } + } else { + fill_prefetch_next_after( + "\t\tuae_s16 bnewv = (uae_s16)dst - (uae_s16)src;\n" + "\t\tint bflgs = ((uae_s16)(src)) < 0;\n" + "\t\tint bflgo = ((uae_s16)(dst)) < 0;\n" + "\t\tint bflgn = bnewv < 0;\n" + "\t\tccr_68000_long_move_ae_LZN(bnewv);\n" + "\t\tSET_CFLG(((uae_u16)(src)) > ((uae_u16)(dst)));\n" + "\t\tSET_XFLG(GET_CFLG());\n" + "\t\tSET_VFLG((bflgs ^ bflgo) & (bflgn ^ bflgo));\n"); + } + if (c > 0) + addcycles000(c); + genastore_rev("newv", curi->dmode, "dstreg", curi->size, "dst"); + } else { + if (curi->dmode == Dreg) { + genastore_rev("newv", curi->dmode, "dstreg", curi->size, "dst"); + } + if ((curi->smode >= imm || curi->smode == Dreg) && curi->dmode != Dreg) { + fill_prefetch_next_after(NULL); + } else { + fill_prefetch_next(); + } + if (c > 0) + addcycles000(c); + if (curi->dmode != Dreg) { + genastore_rev("newv", curi->dmode, "dstreg", curi->size, "dst"); } } - fill_prefetch_next (); - if (c > 0) - addcycles000 (c); - start_brace (); - genflags (flag_sub, curi->size, "newv", "src", "dst"); - genastore_rev ("newv", curi->dmode, "dstreg", curi->size, "dst"); break; } case i_SUBA: @@ -4269,8 +4290,7 @@ static void gen_opcode (unsigned int opcode) genamodedual (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, curi->dmode, "dstreg", sz_long, "dst", 1, GF_RMW); - //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0); - //genamode (curi, curi->dmode, "dstreg", sz_long, "dst", 1, 0, GF_RMW); + printf("\tuae_u32 newv = dst - src;\n"); if (curi->smode == immi) { // SUBAQ.x is always 8 cycles c += 4; @@ -4279,11 +4299,9 @@ static void gen_opcode (unsigned int opcode) if (islongimm (curi)) c += 2; } - fill_prefetch_next (); + fill_prefetch_next_after("\t\tareg_68000_long_replace_low(dstreg, newv);\n"); if (c > 0) addcycles000 (c); - start_brace (); - printf("\tuae_u32 newv = dst - src;\n"); genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); break; } @@ -4316,7 +4334,7 @@ static void gen_opcode (unsigned int opcode) "\t\tSET_XFLG(GET_CFLG());\n" "\t\tif (newv & 0xffff) SET_ZFLG(0);\n" "\t\tSET_NFLG(newv & 0x8000); \n" - "\t\treg_68000_long_replace_low(dstreg, newv);\n"); + "\t\tdreg_68000_long_replace_low(dstreg, newv);\n"); } else { fill_prefetch_next(); } @@ -4372,21 +4390,54 @@ static void gen_opcode (unsigned int opcode) genamodedual (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, curi->dmode, "dstreg", curi->size, "dst", 1, GF_RMW); - //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0); - //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_RMW); - if (curi->dmode == Dreg) { - if (curi->size == sz_long) { + genflags(flag_add, curi->size, "newv", "src", "dst"); + if (curi->size == sz_long) { + if (curi->dmode == Dreg) { c += 2; - if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg || curi->smode == Areg) + if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg || curi->smode == Areg) { c += 2; + fill_prefetch_next_after( + "\t\tuae_s16 bnewv = (uae_s16)dst + (uae_s16)src;\n" + "\t\tint bflgs = ((uae_s16)(src)) < 0;\n" + "\t\tint bflgo = ((uae_s16)(dst)) < 0;\n" + "\t\tint bflgn = bnewv < 0;\n" + "\t\tccr_68000_long_move_ae_LZN(bnewv);\n" + "\t\tSET_CFLG(((uae_u16)(~dst)) < ((uae_u16)(src)));\n" + "\t\tSET_XFLG(GET_CFLG());\n" + "\t\tSET_VFLG((bflgs ^ bflgn) & (bflgo ^ bflgn));\n" + "\t\tdreg_68000_long_replace_low(dstreg, bnewv);\n"); + } else { + fill_prefetch_next_after("\t\tdreg_68000_long_replace_low(dstreg, newv);\n"); + } + } else { + fill_prefetch_next_after( + "\t\tuae_s16 bnewv = (uae_s16)dst + (uae_s16)src;\n" + "\t\tint bflgs = ((uae_s16)(src)) < 0;\n" + "\t\tint bflgo = ((uae_s16)(dst)) < 0;\n" + "\t\tint bflgn = bnewv < 0;\n" + "\t\tccr_68000_long_move_ae_LZN(bnewv);\n" + "\t\tSET_CFLG(((uae_u16)(~dst)) < ((uae_u16)(src)));\n" + "\t\tSET_XFLG(GET_CFLG());\n" + "\t\tSET_VFLG((bflgs ^ bflgn) & (bflgo ^ bflgn));\n"); + } + if (c > 0) + addcycles000(c); + genastore_rev("newv", curi->dmode, "dstreg", curi->size, "dst"); + } else { + if (curi->dmode == Dreg) { + genastore_rev("newv", curi->dmode, "dstreg", curi->size, "dst"); + } + if ((curi->smode >= imm || curi->smode == Dreg) && curi->dmode != Dreg) { + fill_prefetch_next_after(NULL); + } else { + fill_prefetch_next(); + } + if (c > 0) + addcycles000(c); + if (curi->dmode != Dreg) { + genastore_rev("newv", curi->dmode, "dstreg", curi->size, "dst"); } } - fill_prefetch_next (); - if (c > 0) - addcycles000 (c); - start_brace (); - genflags (flag_add, curi->size, "newv", "src", "dst"); - genastore_rev ("newv", curi->dmode, "dstreg", curi->size, "dst"); break; } case i_ADDA: @@ -4395,8 +4446,7 @@ static void gen_opcode (unsigned int opcode) genamodedual (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, curi->dmode, "dstreg", sz_long, "dst", 1, GF_RMW); - //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0); - //genamode (curi, curi->dmode, "dstreg", sz_long, "dst", 1, 0, GF_RMW); + printf("\tuae_u32 newv = dst + src;\n"); if (curi->smode == immi) { // ADDAQ.x is always 8 cycles c += 4; @@ -4405,12 +4455,10 @@ static void gen_opcode (unsigned int opcode) if (islongimm (curi)) c += 2; } - fill_prefetch_next (); + fill_prefetch_next_after("\t\tareg_68000_long_replace_low(dstreg, newv);\n"); if (c > 0) addcycles000 (c); - start_brace (); - printf("\tuae_u32 newv = dst + src;\n"); - genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); + genastore("newv", curi->dmode, "dstreg", sz_long, "dst"); break; } case i_ADDX: @@ -4443,7 +4491,7 @@ static void gen_opcode (unsigned int opcode) "\t\tSET_XFLG(GET_CFLG());\n" "\t\tif (newv & 0xffff) SET_ZFLG(0);\n" "\t\tSET_NFLG(newv & 0x8000); \n" - "\t\treg_68000_long_replace_low(dstreg, newv);\n"); + "\t\tdreg_68000_long_replace_low(dstreg, newv);\n"); } else { fill_prefetch_next(); } @@ -4498,17 +4546,35 @@ static void gen_opcode (unsigned int opcode) genamode(curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW); genflags(flag_sub, curi->size, "dst", "src", "0"); if (curi->smode == Dreg) { - genastore_rev("dst", curi->smode, "srcreg", curi->size, "src"); if (curi->size == sz_long) { // prefetch bus error and long register: only low word is updated // N flag from high word. Z both. - fill_prefetch_next_after("\t\treg_68000_long_replace_low(srcreg, dst);\n\t\tSET_VFLG(0);SET_ZFLG(!dst);SET_NFLG(dst & 0x80000000);SET_CFLG(!GET_ZFLG());SET_XFLG(GET_CFLG());\n"); + fill_prefetch_next_after( + "\t\tdreg_68000_long_replace_low(srcreg, dst);\n" + "\t\tint bflgs = ((uae_s16)(src)) < 0;\n" + "\t\tint bflgo = ((uae_s16)(0)) < 0;\n" + "\t\tint bflgn = ((uae_s16)(dst)) < 0;\n" + "\t\tSET_ZFLG(((uae_s16)(dst)) == 0);\n" + "\t\tSET_VFLG((bflgs ^ bflgo) & (bflgn ^ bflgo));\n" + "\t\tSET_CFLG(((uae_u16)(src)) > ((uae_u16)(0)));\n" + "\t\tSET_NFLG(dst & 0x80000000);\n" + "\t\tSET_XFLG(GET_CFLG());\n"); + genastore_rev("dst", curi->smode, "srcreg", curi->size, "src"); } else { + genastore_rev("dst", curi->smode, "srcreg", curi->size, "src"); fill_prefetch_next(); } } else if (curi->size == sz_long) { // prefetch bus error and long memory: only low word CCR decoded - fill_prefetch_next_after("\t\tSET_VFLG(0);SET_ZFLG(!(dst & 0xffff));SET_NFLG(dst & 0x8000);SET_CFLG(!GET_ZFLG());SET_XFLG(GET_CFLG());\n"); + fill_prefetch_next_after( + "\t\tint bflgs = ((uae_s16)(src)) < 0;\n" + "\t\tint bflgo = ((uae_s16)(0)) < 0;\n" + "\t\tint bflgn = ((uae_s16)(dst)) < 0;\n" + "\t\tSET_ZFLG(((uae_s16)(dst)) == 0);\n" + "\t\tSET_VFLG((bflgs ^ bflgo) & (bflgn ^ bflgo));\n" + "\t\tSET_CFLG(((uae_u16)(src)) > ((uae_u16)(0)));\n" + "\t\tSET_NFLG(bflgn != 0);\n" + "\t\tSET_XFLG(GET_CFLG());\n"); } else { fill_prefetch_next_after(NULL); } @@ -4524,17 +4590,35 @@ static void gen_opcode (unsigned int opcode) genflags(flag_subx, curi->size, "newv", "src", "0"); genflags(flag_zn, curi->size, "newv", "", ""); if (curi->smode == Dreg) { - genastore_rev("newv", curi->smode, "srcreg", curi->size, "src"); if (curi->size == sz_long) { // prefetch bus error and long register: only low word is updated // N flag from high word. Z both. - fill_prefetch_next_after("\t\treg_68000_long_replace_low(srcreg, newv);\n\t\tSET_VFLG(0);SET_ZFLG(!newv);SET_NFLG(newv & 0x80000000);SET_CFLG(!GET_ZFLG());SET_XFLG(GET_CFLG());\n"); + fill_prefetch_next_after( + "\t\tdreg_68000_long_replace_low(srcreg, newv);\n" + "\t\tint bflgs = ((uae_s16)(src)) < 0;\n" + "\t\tint bflgo = ((uae_s16)(0)) < 0;\n" + "\t\tint bflgn = ((uae_s16)(newv)) < 0;\n" + "\t\tSET_VFLG((bflgs ^ bflgo) & (bflgo ^ bflgn));\n" + "\t\tSET_CFLG(bflgs ^ ((bflgs ^ bflgn) & (bflgo ^ bflgn)));\n" + "\t\tSET_ZFLG(GET_ZFLG() & (((uae_s16)(newv)) == 0));\n" + "\t\tSET_NFLG(((uae_s32)(newv)) < 0);\n" + "\t\tSET_XFLG(GET_CFLG());\n"); + genastore_rev("newv", curi->smode, "srcreg", curi->size, "src"); } else { + genastore_rev("newv", curi->smode, "srcreg", curi->size, "src"); fill_prefetch_next(); } } else if (curi->size == sz_long) { // prefetch bus error and long memory: only low word CCR decoded - fill_prefetch_next_after("\t\tSET_VFLG(0);SET_ZFLG(!(newv & 0xffff));SET_NFLG(newv & 0x8000);SET_CFLG(!GET_ZFLG());SET_XFLG(GET_CFLG());\n"); + fill_prefetch_next_after( + "\t\tint bflgs = ((uae_s16)(src)) < 0;\n" + "\t\tint bflgo = ((uae_s16)(0)) < 0;\n" + "\t\tint bflgn = ((uae_s16)(newv)) < 0;\n" + "\t\tSET_VFLG((bflgs ^ bflgo) & (bflgo ^ bflgn));\n" + "\t\tSET_CFLG(bflgs ^ ((bflgs ^ bflgn) & (bflgo ^ bflgn)));\n" + "\t\tSET_ZFLG(GET_ZFLG() & (((uae_s16)(newv)) == 0));\n" + "\t\tSET_NFLG(((uae_s16)(newv)) < 0);\n" + "\t\tSET_XFLG(GET_CFLG());\n"); } else { fill_prefetch_next_after(NULL); } @@ -4585,12 +4669,15 @@ static void gen_opcode (unsigned int opcode) genamode(curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0); genflags(flag_logical, curi->size, "0", "", ""); if (curi->smode == Dreg) { - genastore_rev("0", curi->smode, "srcreg", curi->size, "src"); if (curi->size == sz_long) { // prefetch bus error and long register: only low word is updated // N flag from high word. Z both. - fill_prefetch_next_after("\t\tm68k_dreg(regs, srcreg) = (src & 0xffff0000);\n\t\tSET_VFLG(0);SET_ZFLG(1);SET_NFLG(0);SET_CFLG(0);\n"); + fill_prefetch_next_after( + "\t\tm68k_dreg(regs, srcreg) = (src & 0xffff0000);\n" + "\t\tSET_VFLG(0);SET_ZFLG(1);SET_NFLG(0);SET_CFLG(0);\n"); + genastore_rev("0", curi->smode, "srcreg", curi->size, "src"); } else { + genastore_rev("0", curi->smode, "srcreg", curi->size, "src"); fill_prefetch_next(); } } else if (curi->size == sz_long) { @@ -4632,17 +4719,26 @@ static void gen_opcode (unsigned int opcode) printf("\tuae_u32 dst = ~src;\n"); genflags(flag_logical, curi->size, "dst", "", ""); if (curi->smode == Dreg) { - genastore_rev("dst", curi->smode, "srcreg", curi->size, "src"); if (curi->size == sz_long) { // prefetch bus error and long register: only low word is updated // N flag from high word. Z both. - fill_prefetch_next_after("\t\treg_68000_long_replace_low(srcreg, dst);\n\t\tSET_VFLG(0);SET_ZFLG(!dst);SET_NFLG(dst & 0x80000000);SET_CFLG(0);\n"); + fill_prefetch_next_after( + "\t\tdreg_68000_long_replace_low(srcreg, dst);\n" + "\t\tSET_VFLG(0);SET_ZFLG(!dst);\n" + "\t\tSET_NFLG(dst & 0x80000000);\n" + "\t\tSET_CFLG(0);\n"); + genastore_rev("dst", curi->smode, "srcreg", curi->size, "src"); } else { + genastore_rev("dst", curi->smode, "srcreg", curi->size, "src"); fill_prefetch_next(); } } else if (curi->size == sz_long) { // prefetch bus error and long memory: only low word CCR decoded - fill_prefetch_next_after("\t\tSET_VFLG(0);SET_ZFLG(!(dst & 0xffff));SET_NFLG(dst & 0x8000);SET_CFLG(0);\n"); + fill_prefetch_next_after( + "\t\tSET_VFLG(0);\n" + "\t\tSET_ZFLG(!(dst & 0xffff));\n" + "\t\tSET_NFLG(dst & 0x8000);\n" + "\t\tSET_CFLG(0);\n"); } else { fill_prefetch_next_after(NULL); } @@ -4691,6 +4787,10 @@ static void gen_opcode (unsigned int opcode) curi->dmode, "dstreg", curi->size, "dst", 1, GF_RMW); if (curi->size == sz_long) { fill_prefetch_next_after(NULL); + } else { + if (curi->smode == Dreg || curi->smode >= imm) { + fill_prefetch_next_after(NULL); + } } bsetcycles(curi); // bclr needs 1 extra cycle @@ -4707,7 +4807,9 @@ static void gen_opcode (unsigned int opcode) printf("\tdst |= (1 << src);\n"); } if (curi->size != sz_long) { - fill_prefetch_next(); + if (curi->smode < imm && curi->smode != Dreg) { + fill_prefetch_next(); + } } genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); break; @@ -4735,7 +4837,11 @@ static void gen_opcode (unsigned int opcode) curi->smode, "srcreg", curi->size, "src", 1, 0, curi->dmode, "dstreg", sz_long, "dst", 1, 0); genflags(flag_cmp, sz_long, "newv", "src", "dst"); - fill_prefetch_next(); + if (curi->dmode == Areg) { + fill_prefetch_next_after(NULL); + } else { + fill_prefetch_next(); + } addcycles000(2); break; /* The next two are coded a little unconventional, but they are doing @@ -4780,7 +4886,7 @@ static void gen_opcode (unsigned int opcode) check_bus_error("memp", 2, 0, 0, NULL, 1); // upper word gets updated after two bytes (makes only difference if bus error is possible) - printf("\treg_68000_long_replace_low(dstreg, val);\n"); + printf("\tdreg_68000_long_replace_low(dstreg, val);\n"); printf("\tval |= (%s(mempa + 4) & 0xff) << 8;\n", srcb); check_bus_error("memp", 4, 0, 0, NULL, 1 | 0x10000); @@ -4897,9 +5003,24 @@ static void gen_opcode (unsigned int opcode) if (curi->mnemo == i_MOVE) { if (curi->size == sz_long) { if (curi->smode == imm) { + if (curi->dmode == absw) { + strcpy(bus_error_code, "\t\tccr_68000_long_move_ae_LZN(src);\n"); + } else if (curi->dmode == absl) { + strcpy(bus_error_code2, "\t\tccr_68000_long_move_ae_LZN(src);\n"); + } + } else if (curi->smode == Dreg || curi->smode == Areg) { if (curi->dmode == absl) { + strcpy(bus_error_code, "\t\t// nothing;\n"); + strcpy(bus_error_code2, "\t\tccr_68000_long_move_ae_LZN(src);\n"); + } else if (curi->dmode == absw) { strcpy(bus_error_code, "\t\tccr_68000_long_move_ae_LZN(src);\n"); + } + } else { + if (curi->dmode == absl) { + strcpy(bus_error_code, "\t\t// nothing;\n"); strcpy(bus_error_code2, "\t\tccr_68000_long_move_ae_LZN(src);\n"); + } else { + strcpy(bus_error_code, "\t\tccr_68000_long_move_ae_LZN(src);\n"); } } } else { @@ -4926,13 +5047,19 @@ static void gen_opcode (unsigned int opcode) if (curi->dmode == Apdi) { // -(an) decrease is not done if bus error if (curi->size == sz_long) { - fill_prefetch_next_after("\t\tm68k_areg(regs, dstreg) += 4;\n"); + fill_prefetch_next_after( + "\t\tm68k_areg(regs, dstreg) += 4;\n" + "\t\tccr_68000_long_move_ae_LZN(src);\n" + ); } else { // x,-(an): flags are set before prefetch detects possible bus error if (curi->mnemo == i_MOVE) { - fill_prefetch_next_after("\t\tm68k_areg(regs, dstreg) += 2;\n\t\tccr_68000_word_move_ae_normal((uae_s16)src);"); + fill_prefetch_next_after( + "\t\tm68k_areg(regs, dstreg) += 2;\n" + "\t\tccr_68000_word_move_ae_normal((uae_s16)src);"); } else { - fill_prefetch_next_after("\t\tm68k_areg(regs, dstreg) += 2;\n"); + fill_prefetch_next_after( + "\t\tm68k_areg(regs, dstreg) += 2;\n"); } } prefetch_done = 1; @@ -4950,6 +5077,9 @@ static void gen_opcode (unsigned int opcode) } } + bus_error_code[0] = 0; + bus_error_code2[0] = 0; + if (curi->size == sz_long) { if ((curi->dmode == Ad16 || curi->dmode == PC16) && curi->smode == imm) { // lots more needed.. @@ -5011,7 +5141,7 @@ static void gen_opcode (unsigned int opcode) if (curi->size == sz_byte) { // MOVE TO CCR addcycles000 (4); - printf("\tMakeSR ();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n"); + printf("\tMakeSR();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n"); } else { // MOVE TO SR check_trace(); @@ -5094,14 +5224,9 @@ static void gen_opcode (unsigned int opcode) fill_prefetch_next(); break; case i_RESET: - fill_prefetch_next (); - printf("\tcpureset ();\n"); - sync_m68k_pc (); - addcycles000 (128); - if (using_prefetch) { - printf("\t%s(2);\n", prefetch_word); - clear_m68k_offset(); - } + printf("\tcpureset();\n"); + addcycles000(128); + fill_prefetch_next(); break; case i_NOP: fill_prefetch_next(); @@ -5208,7 +5333,7 @@ static void gen_opcode (unsigned int opcode) printf("\t\t\tException_cpu(14);\n"); printf("\t\t\tgoto %s; \n", endlabelstr); printf("\t\t}\n"); - printf("\t\tregs.sr = newsr; MakeFromSR ();\n}\n"); + printf("\t\tregs.sr = newsr; MakeFromSR();\n}\n"); pop_braces (old_brace_level); printf("\tregs.sr = newsr;\n"); makefromsr(); @@ -5463,7 +5588,14 @@ static void gen_opcode (unsigned int opcode) break; case i_TRAPV: sync_m68k_pc(); - fill_prefetch_next_noopcodecopy("\t\tif (GET_VFLG()) { ; } else opcode = regs.ir;\n"); + // If V is set but prefetch causes bus error: S is set. + fill_prefetch_next_after( + "\t\tif (GET_VFLG()) {\n" + "\t\t\tregs.sr |= 0x2000;\n" + "\t\t\tMakeFromSR();\n" + "\t\t} else {\n" + "\t\t\topcode = regs.ir;\n" + "\t\t}\n"); printf("\tif (GET_VFLG()) {\n"); printf("\t\tException_cpu(7);\n"); printf("\t\tgoto %s;\n", endlabelstr); @@ -5472,7 +5604,7 @@ static void gen_opcode (unsigned int opcode) break; case i_RTR: printf("\tuaecptr oldpc = %s;\n", getpc); - printf("\tMakeSR ();\n"); + printf("\tMakeSR();\n"); genamode (NULL, Aipi, "7", sz_word, "sr", 1, 0, 0); genamode (NULL, Aipi, "7", sz_long, "pc", 1, 0, 0); if (cpu_level >= 4) { @@ -5790,15 +5922,19 @@ bccl_not68020: case i_LEA: if (curi->smode == Ad8r || curi->smode == PC8r) addcycles000 (2); + if (curi->smode == absl) { + strcpy(bus_error_code, "\t\tm68k_areg(regs, dstreg) = (m68k_areg(regs, dstreg) & 0x0000ffff) | (srca & 0xffff0000);\n"); + strcpy(bus_error_code2, "\t\tm68k_areg(regs, dstreg) = (srca);\n"); + } else if (curi->smode != Ad8r && curi->smode != PC8r) { + strcpy(bus_error_code, "\t\tm68k_areg(regs, dstreg) = (srca);\n"); + } genamodedual (curi, curi->smode, "srcreg", curi->size, "src", 0, GF_AA, curi->dmode, "dstreg", curi->size, "dst", 2, GF_AA); - //genamode (curi, curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA); - //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, GF_AA); if (curi->smode == Ad8r || curi->smode == PC8r) addcycles000 (2); + genastore("srca", curi->dmode, "dstreg", curi->size, "dst"); fill_prefetch_next (); - genastore ("srca", curi->dmode, "dstreg", curi->size, "dst"); break; case i_PEA: if (curi->smode == Ad8r || curi->smode == PC8r) @@ -5927,7 +6063,6 @@ bccl_not68020: addcycles000_3("\t\t"); } addcycles000_nonces("\t\t", "(getDivu68kCycles((uae_u32)dst, (uae_u16)src)) - 4"); - fill_prefetch_next(); printf("\t\tif (newv > 0xffff) {\n"); printf("\t\t\tsetdivuflags((uae_u32)dst, (uae_u16)src);\n"); printf("\t\t} else {\n"); @@ -5937,6 +6072,7 @@ bccl_not68020: printf("\t\t"); genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); printf("\t\t}\n"); + fill_prefetch_next(); sync_m68k_pc(); count_ncycles++; insn_n_cycles += 136 - (136 - 76) / 2; /* average */ @@ -5961,7 +6097,6 @@ bccl_not68020: addcycles000_3("\t\t"); } addcycles000_nonces("\t\t", "(getDivs68kCycles((uae_s32)dst, (uae_s16)src)) - 4"); - fill_prefetch_next (); printf("\tif (dst == 0x80000000 && src == -1) {\n"); printf("\t\tsetdivsflags((uae_s32)dst, (uae_s16)src);\n"); printf("\t} else {\n"); @@ -5977,6 +6112,7 @@ bccl_not68020: genastore("newv", curi->dmode, "dstreg", sz_long, "dst"); printf("\t\t}\n"); printf("\t}\n"); + fill_prefetch_next(); sync_m68k_pc(); count_ncycles++; insn_n_cycles += 156 - (156 - 120) / 2; /* average */ @@ -5988,8 +6124,10 @@ bccl_not68020: genamodedual (curi, curi->smode, "srcreg", sz_word, "src", 1, 0, curi->dmode, "dstreg", sz_word, "dst", 1, 0); - fill_prefetch_next(); - start_brace (); + fill_prefetch_next_after( + "\t\tCLEAR_CZNV();\n" + "\t\tSET_ZFLG(1);\n" + "\t\tm68k_dreg(regs, dstreg) &= 0xffff0000;\n"); printf("\tuae_u32 newv = (uae_u32)(uae_u16)dst * (uae_u32)(uae_u16)src;\n"); if (using_ce) printf("\tint cycles = 38 - 4, bits;\n"); @@ -6012,8 +6150,10 @@ bccl_not68020: genamodedual (curi, curi->smode, "srcreg", sz_word, "src", 1, 0, curi->dmode, "dstreg", sz_word, "dst", 1, 0); - fill_prefetch_next(); - start_brace (); + fill_prefetch_next_after( + "\t\tCLEAR_CZNV();\n" + "\t\tSET_ZFLG(1);\n" + "\t\tm68k_dreg(regs, dstreg) &= 0xffff0000;\n"); printf("\tuae_u32 newv = (uae_s32)(uae_s16)dst * (uae_s32)(uae_s16)src;\n"); if (using_ce) { printf("\tint cycles = 38 - 4, bits;\n"); diff --git a/include/newcpu.h b/include/newcpu.h index 47cd11b1..318b4fa3 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -702,7 +702,8 @@ void ccr_68000_long_move_ae_LN(uae_s32 src); void ccr_68000_long_move_ae_HNZ(uae_s32 src); void ccr_68000_long_move_ae_normal(uae_s32 src); void ccr_68000_word_move_ae_normal(uae_s16 src); -void reg_68000_long_replace_low(int reg, uae_u16 v); +void dreg_68000_long_replace_low(int reg, uae_u16 v); +void areg_68000_long_replace_low(int reg, uae_u16 v); extern void mmu_op (uae_u32, uae_u32); extern bool mmu_op30 (uaecptr, uae_u32, uae_u16, uaecptr); diff --git a/newcpu_common.cpp b/newcpu_common.cpp index 0a10a80d..83a3d9dc 100644 --- a/newcpu_common.cpp +++ b/newcpu_common.cpp @@ -1618,11 +1618,16 @@ void ccr_68000_word_move_ae_normal(uae_s16 src) SET_NFLG(src < 0); } -void reg_68000_long_replace_low(int reg, uae_u16 v) +void dreg_68000_long_replace_low(int reg, uae_u16 v) { m68k_dreg(regs, reg) = (m68k_dreg(regs, reg) & 0xffff0000) | v; } +void areg_68000_long_replace_low(int reg, uae_u16 v) +{ + m68k_areg(regs, reg) = (m68k_areg(regs, reg) & 0xffff0000) | v; +} + // Change F-line to privilege violation if missing co-pro bool privileged_copro_instruction(uae_u16 opcode) { -- 2.47.3