--- hatari/src/uae-cpu/gencpu.c 2019/04/01 07:13:46 1.1.1.8 +++ hatari/src/uae-cpu/gencpu.c 2019/04/09 08:50:32 1.1.1.14 @@ -57,10 +57,15 @@ /* 2008/01/26 [NP] On ST, d8(An,Xn) takes 2 cycles more when used with ADDA/SUBA (ULM Demo Menu) */ /* but not when used with MOVE (e.g. 'move.l 0(a5,d1),(a4)' takes 26 cycles and so */ /* can pair with a lsr) (Anomaly Demo Intro). */ +/* 2008/04/26 [NP] Handle sz_byte for Areg in genamode, as 'move.b a1,(a0)' ($1089) is possible */ +/* on ST (fix Blood Money on Superior 65) */ +/* 2010/04/05 [NP] On ST, d8(An,Xn) takes 2 cycles more (which can generate pairing). */ +/* Use BusCyclePenalty to properly handle the 2/4 cycles added in that case when */ +/* addressing mode is Ad8r or PC8r (ULM Demo Menu, Anomaly Demo Intro, DHS */ +/* Sommarhack 2010) (see m68000.h) */ - -const char GenCpu_rcsid[] = "Hatari $Id: gencpu.c,v 1.1.1.8 2019/04/01 07:13:46 root Exp $"; +const char GenCpu_fileid[] = "Hatari gencpu.c : " __DATE__ " " __TIME__; #include #include @@ -101,7 +106,9 @@ static void read_counts (void) file = fopen ("frequent.68k", "r"); if (file) { - fscanf (file, "Total: %lu\n", &total); + if (fscanf (file, "Total: %lu\n", &total) == EOF) { + perror("read_counts"); + } while (fscanf (file, "%lx: %lu %s\n", &opcode, &count, name) == 3) { opcode_next_clev[nr] = 4; opcode_last_postfix[nr] = -1; @@ -260,7 +267,8 @@ static void sync_m68k_pc (void) /* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0, * the calling routine handles Apdi and Aipi modes. * gb-- movem == 2 means the same thing but for a MOVE16 instruction */ -static void genamode (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem) +static void genamode (amodes mode, const char *reg, wordsizes size, + const char *name, int getv, int movem) { start_brace (); switch (mode) { @@ -287,6 +295,9 @@ static void genamode (amodes mode, char abort (); if (getv == 1) switch (size) { + case sz_byte: // [NP] Areg with .b is possible in MOVE source */ + printf ("\tuae_s8 %s = m68k_areg(regs, %s);\n", name, reg); + break; case sz_word: printf ("\tuae_s16 %s = m68k_areg(regs, %s);\n", name, reg); break; @@ -338,6 +349,7 @@ static void genamode (amodes mode, char } else { printf ("\tuaecptr %sa = get_disp_ea_000(m68k_areg(regs, %s), %s);\n", name, reg, gen_nextiword ()); } + printf ("\tBusCyclePenalty += 2;\n"); break; case PC16: @@ -359,6 +371,7 @@ static void genamode (amodes mode, char printf ("\tuaecptr tmppc = m68k_getpc() + %d;\n", m68k_pc_offset); printf ("\tuaecptr %sa = get_disp_ea_000(tmppc, %s);\n", name, gen_nextiword ()); } + printf ("\tBusCyclePenalty += 2;\n"); break; case absw: @@ -416,7 +429,7 @@ static void genamode (amodes mode, char printf ("\t\tlast_fault_for_exception_3 = %sa;\n", name); printf ("\t\tlast_op_for_exception_3 = opcode;\n"); printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + %d;\n", m68k_pc_offset); - printf ("\t\tException(3, 0);\n"); + printf ("\t\tException(3, 0, M68000_EXC_SRC_CPU);\n"); printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t}\n"); need_endlabel = 1; @@ -466,7 +479,8 @@ static void genamode (amodes mode, char } } -static void genastore (char *from, amodes mode, char *reg, wordsizes size, char *to) +static void genastore (const char *from, amodes mode, const char *reg, + wordsizes size, const char *to) { switch (mode) { case Dreg: @@ -648,7 +662,8 @@ typedef enum } flagtypes; -static void genflags_normal (flagtypes type, wordsizes size, char *value, char *src, char *dst) +static void genflags_normal (flagtypes type, wordsizes size, const char *value, + const char *src, const char *dst) { char vstr[100], sstr[100], dstr[100]; char usstr[100], udstr[100]; @@ -789,7 +804,8 @@ static void genflags_normal (flagtypes t } } -static void genflags (flagtypes type, wordsizes size, char *value, char *src, char *dst) +static void genflags (flagtypes type, wordsizes size, const char *value, + const char *src, const char *dst) { /* Temporarily deleted 68k/ARM flag optimizations. I'd prefer to have them in the appropriate m68k.h files and use just one copy of this @@ -931,14 +947,14 @@ static void gen_opcode (unsigned long in /* fall through */ case 2: /* priviledged */ - printf ("if (!regs.s) { Exception(8,0); goto %s; }\n", endlabelstr); + printf ("if (!regs.s) { Exception(8,0,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr); need_endlabel = 1; start_brace (); break; case 3: /* privileged if size == word */ if (curi->size == sz_byte) break; - printf ("if (!regs.s) { Exception(8,0); goto %s; }\n", endlabelstr); + printf ("if (!regs.s) { Exception(8,0,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr); need_endlabel = 1; start_brace (); break; @@ -1012,8 +1028,6 @@ static void gen_opcode (unsigned long in insn_n_cycles += 2; else insn_n_cycles += 4; - if( (curi->smode==Ad8r) || (curi->smode==PC8r) ) /* [NP] on 68000 ST, d8(An,Xn) takes 2 cycles more */ - insn_n_cycles += 2; break; case i_SUBX: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); @@ -1076,8 +1090,6 @@ static void gen_opcode (unsigned long in insn_n_cycles += 2; else insn_n_cycles += 4; - if( (curi->smode==Ad8r) || (curi->smode==PC8r) ) /* [NP] on 68000 ST, d8(An,Xn) takes 2 cycles more */ - insn_n_cycles += 2; break; case i_ADDX: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); @@ -1264,10 +1276,10 @@ static void gen_opcode (unsigned long in printf ("\tuaecptr memp = m68k_areg(regs, dstreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword ()); if (curi->size == sz_word) { - printf ("\tput_byte(memp, src >> 8); put_byte(memp + 2, src);\n"); + printf ("\tMovepByteNbr=1; put_byte(memp, src >> 8); MovepByteNbr=2; put_byte(memp + 2, src);\n"); } else { - printf ("\tput_byte(memp, src >> 24); put_byte(memp + 2, src >> 16);\n"); - printf ("\tput_byte(memp + 4, src >> 8); put_byte(memp + 6, src);\n"); + printf ("\tMovepByteNbr=1; put_byte(memp, src >> 24); MovepByteNbr=2; put_byte(memp + 2, src >> 16);\n"); + printf ("\tMovepByteNbr=3; put_byte(memp + 4, src >> 8); MovepByteNbr=4; put_byte(memp + 6, src);\n"); } if(curi->size==sz_long) insn_n_cycles=24; else insn_n_cycles=16; break; @@ -1362,7 +1374,7 @@ static void gen_opcode (unsigned long in case i_TRAP: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); sync_m68k_pc (); - printf ("\tException(src+32,0);\n"); + printf ("\tException(src+32,0,M68000_EXC_SRC_CPU);\n"); m68k_pc_offset = 0; break; case i_MVR2USP: @@ -1409,7 +1421,7 @@ static void gen_opcode (unsigned long in printf ("\telse if ((format & 0xF000) == 0x9000) { m68k_areg(regs, 7) += 12; break; }\n"); printf ("\telse if ((format & 0xF000) == 0xa000) { m68k_areg(regs, 7) += 24; break; }\n"); printf ("\telse if ((format & 0xF000) == 0xb000) { m68k_areg(regs, 7) += 84; break; }\n"); - printf ("\telse { Exception(14,0); goto %s; }\n", endlabelstr); + printf ("\telse { Exception(14,0,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr); printf ("\tregs.sr = newsr; MakeFromSR();\n}\n"); pop_braces (old_brace_level); printf ("\tregs.sr = newsr; MakeFromSR();\n"); @@ -1452,7 +1464,7 @@ static void gen_opcode (unsigned long in break; case i_TRAPV: sync_m68k_pc (); - printf ("\tif (GET_VFLG) { Exception(7,m68k_getpc()); goto %s; }\n", endlabelstr); + printf ("\tif (GET_VFLG) { Exception(7,m68k_getpc(),M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr); need_endlabel = 1; break; case i_RTR: @@ -1468,6 +1480,15 @@ static void gen_opcode (unsigned long in break; case i_JSR: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); + printf ("\tuaecptr oldpc = m68k_getpc () + %d;\n", m68k_pc_offset); + if (using_exception_3) { + printf ("\tif (srca & 1) {\n"); + printf ("\t\tlast_addr_for_exception_3 = oldpc;\n"); + printf ("\t\tlast_fault_for_exception_3 = srca;\n"); + printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr); + printf ("\t}\n"); + need_endlabel = 1; + } printf ("\tm68k_do_jsr(m68k_getpc() + %d, srca);\n", m68k_pc_offset); fill_prefetch_0 (); m68k_pc_offset = 0; @@ -1484,6 +1505,14 @@ static void gen_opcode (unsigned long in break; case i_JMP: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); + if (using_exception_3) { + printf ("\tif (srca & 1) {\n"); + printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + 6;\n"); + printf ("\t\tlast_fault_for_exception_3 = srca;\n"); + printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr); + printf ("\t}\n"); + need_endlabel = 1; + } printf ("\tm68k_setpc(srca);\n"); fill_prefetch_0 (); m68k_pc_offset = 0; @@ -1503,9 +1532,9 @@ static void gen_opcode (unsigned long in printf ("\tuae_s32 s = (uae_s32)src + 2;\n"); if (using_exception_3) { printf ("\tif (src & 1) {\n"); - printf ("\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n"); // [NP] FIXME should be +4, not +2 (same as DBcc) ? + printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n"); // [NP] FIXME should be +4, not +2 (same as DBcc) ? printf ("\t\tlast_fault_for_exception_3 = m68k_getpc() + s;\n"); - printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0); goto %s;\n", endlabelstr); + printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr); printf ("\t}\n"); need_endlabel = 1; } @@ -1521,7 +1550,7 @@ static void gen_opcode (unsigned long in printf ("\tif (!cctrue(%d)) goto %s;\n", curi->cc, endlabelstr); printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n"); printf ("\t\tlast_fault_for_exception_3 = m68k_getpc() + 1;\n"); - printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0); goto %s;\n", endlabelstr); + printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr); need_endlabel = 1; } else { if (next_cpu_level < 1) @@ -1534,7 +1563,7 @@ static void gen_opcode (unsigned long in printf ("\tif (src & 1) {\n"); printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n"); // [NP] FIXME should be +4, not +2 (same as DBcc) ? printf ("\t\tlast_fault_for_exception_3 = m68k_getpc() + 2 + (uae_s32)src;\n"); - printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0); goto %s;\n", endlabelstr); + printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr); printf ("\t}\n"); need_endlabel = 1; } @@ -1586,7 +1615,7 @@ static void gen_opcode (unsigned long in printf ("\t\t\tif (offs & 1) {\n"); printf ("\t\t\tlast_addr_for_exception_3 = m68k_getpc() + 2 + 2;\n"); // [NP] last_addr is pc+4, not pc+2 printf ("\t\t\tlast_fault_for_exception_3 = m68k_getpc() + 2 + (uae_s32)offs + 2;\n"); - printf ("\t\t\tlast_op_for_exception_3 = opcode; Exception(3,0); goto %s;\n", endlabelstr); + printf ("\t\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr); printf ("\t\t}\n"); need_endlabel = 1; } @@ -1623,7 +1652,7 @@ static void gen_opcode (unsigned long in sync_m68k_pc (); /* Clear V flag when dividing by zero - Alcatraz Odyssey demo depends * on this (actually, it's doing a DIVS). */ - printf ("\tif (src == 0) { SET_VFLG (0); Exception (5, oldpc); goto %s; } else {\n", endlabelstr); + printf ("\tif (src == 0) { SET_VFLG (0); Exception (5, oldpc,M68000_EXC_SRC_CPU); goto %s; } else {\n", endlabelstr); printf ("\tuae_u32 newv = (uae_u32)dst / (uae_u32)(uae_u16)src;\n"); printf ("\tuae_u32 rem = (uae_u32)dst %% (uae_u32)(uae_u16)src;\n"); /* The N flag appears to be set each time there is an overflow. @@ -1644,7 +1673,7 @@ static void gen_opcode (unsigned long in genamode (curi->smode, "srcreg", sz_word, "src", 1, 0); genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0); sync_m68k_pc (); - printf ("\tif (src == 0) { SET_VFLG (0); Exception(5,oldpc); goto %s; } else {\n", endlabelstr); + printf ("\tif (src == 0) { SET_VFLG (0); Exception(5,oldpc,M68000_EXC_SRC_CPU); goto %s; } else {\n", endlabelstr); printf ("\tuae_s32 newv = (uae_s32)dst / (uae_s32)(uae_s16)src;\n"); printf ("\tuae_u16 rem = (uae_s32)dst %% (uae_s32)(uae_s16)src;\n"); printf ("\tif ((newv & 0xffff8000) != 0 && (newv & 0xffff8000) != 0xffff8000) { SET_VFLG (1); SET_NFLG (1); SET_CFLG (0); } else\n\t{\n"); @@ -1690,8 +1719,8 @@ static void gen_opcode (unsigned long in genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); sync_m68k_pc (); - printf ("\tif ((uae_s32)dst < 0) { SET_NFLG (1); Exception(6,oldpc); goto %s; }\n", endlabelstr); - printf ("\telse if (dst > src) { SET_NFLG (0); Exception(6,oldpc); goto %s; }\n", endlabelstr); + printf ("\tif ((uae_s32)dst < 0) { SET_NFLG (1); Exception(6,oldpc,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr); + printf ("\telse if (dst > src) { SET_NFLG (0); Exception(6,oldpc,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr); need_endlabel = 1; insn_n_cycles += 6; break; @@ -1719,7 +1748,7 @@ static void gen_opcode (unsigned long in printf ("\tSET_ZFLG (upper == reg || lower == reg);\n"); printf ("\tSET_CFLG (lower <= upper ? reg < lower || reg > upper : reg > upper || reg < lower);\n"); sync_m68k_pc (); - printf ("\tif ((extra & 0x800) && GET_CFLG) { Exception(6,oldpc); goto %s; }\n}\n", endlabelstr); + printf ("\tif ((extra & 0x800) && GET_CFLG) { Exception(6,oldpc,M68000_EXC_SRC_CPU); goto %s; }\n}\n", endlabelstr); need_endlabel = 1; break; @@ -2255,7 +2284,7 @@ static void gen_opcode (unsigned long in case i_TRAPcc: if (curi->smode != am_unknown && curi->smode != am_illg) genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0); - printf ("\tif (cctrue(%d)) { Exception(7,m68k_getpc()); goto %s; }\n", curi->cc, endlabelstr); + printf ("\tif (cctrue(%d)) { Exception(7,m68k_getpc(),M68000_EXC_SRC_CPU); goto %s; }\n", curi->cc, endlabelstr); need_endlabel = 1; break; case i_DIVL: @@ -2689,7 +2718,10 @@ int main (int argc, char **argv) headerfile = fopen ("cputbl.h", "wb"); stblfile = fopen ("cpustbl.c", "wb"); - freopen ("cpuemu.c", "wb", stdout); + if (freopen ("cpuemu.c", "wb", stdout) == NULL) { + perror("cpuemu.c"); + return -1; + } generate_includes (stdout); generate_includes (stblfile);