--- hatari/src/uae-cpu/gencpu.c 2019/04/09 08:54:37 1.1.1.17 +++ hatari/src/uae-cpu/gencpu.c 2019/04/09 08:55:50 1.1.1.18 @@ -73,6 +73,13 @@ /* 2014/04/09 [NP] Similar to CLR on 68000, Scc should do a read before doing the write and can */ /* give 2 wait states (sf $fffa07 in Chart Attack compilation by Gremlin) */ /* 2014/04/11 [NP] Add refill_prefetch for i_Move Dn,(An) (International 3D Tennis) */ +/* 2014/08/15 [NP] Cancel change from 2008/04/26, sz_byte for Areg is not valid for MOVE, */ +/* 'move.b a1,(a0)' should give an illegal exception */ +/* 2012/05/05 [NP] In i_JMP, in case of address error with jmp xxx.w, last_addr_for_exception_3 */ +/* should be pc+2 (The Teller, 'jmp $201.w') */ +/* 2015/07/29 [NP] In the case of an address error, correctly set last_writeaccess_for_exception_3 */ +/* to 0 (read) or 1 (write) (War Heli) */ +/* 2015/07/29 [NP] Add refill_prefetch for i_Bcc (War Heli, 'bra.s -2' ($60fe)) */ const char GenCpu_fileid[] = "Hatari gencpu.c : " __DATE__ " " __TIME__; @@ -305,9 +312,6 @@ static void genamode (amodes mode, const 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; @@ -438,6 +442,11 @@ static void genamode (amodes mode, const printf ("\tif ((%sa & 1) != 0) {\n", name); printf ("\t\tlast_fault_for_exception_3 = %sa;\n", name); printf ("\t\tlast_op_for_exception_3 = opcode;\n"); + printf ("\t\tlast_instructionaccess_for_exception_3 = 0;\n"); + if ( getv == 2 ) + printf ("\t\tlast_writeaccess_for_exception_3 = 1;\n"); /* write */ + else + printf ("\t\tlast_writeaccess_for_exception_3 = 0;\n"); /* read */ printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + %d;\n", m68k_pc_offset); printf ("\t\tException(3, 0, M68000_EXC_SRC_CPU);\n"); printf ("\t\tgoto %s;\n", endlabelstr); @@ -1443,9 +1452,20 @@ static void gen_opcode (unsigned long in if (cpu_level == 0) { genamode (Aipi, "7", sz_word, "sr", 1, 0); genamode (Aipi, "7", sz_long, "pc", 1, 0); - printf ("\tregs.sr = sr; m68k_setpc_rte(pc);\n"); - fill_prefetch_0 (); + printf ("\tregs.sr = sr;\n"); printf ("\tMakeFromSR();\n"); + if (using_exception_3) { + printf ("\tif (pc & 1) {\n"); + printf ("\t\tlast_addr_for_exception_3 = m68k_getpc ();\n"); + printf ("\t\tlast_fault_for_exception_3 = pc;\n"); + printf ("\t\tlast_instructionaccess_for_exception_3 = 1;\n"); + printf ("\t\tlast_writeaccess_for_exception_3 = 0;\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_rte(pc);\n"); + fill_prefetch_0 (); } else { int old_brace_level = n_braces; if (next_cpu_level < 0) @@ -1466,6 +1486,16 @@ static void gen_opcode (unsigned long in printf ("\tregs.sr = newsr; MakeFromSR();\n}\n"); pop_braces (old_brace_level); printf ("\tregs.sr = newsr; MakeFromSR();\n"); + if (using_exception_3) { + printf ("\tif (newpc & 1) {\n"); + printf ("\t\tlast_addr_for_exception_3 = m68k_getpc ();\n"); + printf ("\t\tlast_fault_for_exception_3 = newpc;\n"); + printf ("\t\tlast_instructionaccess_for_exception_3 = 1;\n"); + printf ("\t\tlast_writeaccess_for_exception_3 = 0;\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_rte(newpc);\n"); fill_prefetch_0 (); need_endlabel = 1; @@ -1478,6 +1508,16 @@ static void gen_opcode (unsigned long in genamode (Aipi, "7", sz_long, "pc", 1, 0); genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0); printf ("\tm68k_areg(regs, 7) += offs;\n"); + if (using_exception_3) { + printf ("\tif (pc & 1) {\n"); + printf ("\t\tlast_addr_for_exception_3 = m68k_getpc ();\n"); + printf ("\t\tlast_fault_for_exception_3 = pc;\n"); + printf ("\t\tlast_instructionaccess_for_exception_3 = 1;\n"); + printf ("\t\tlast_writeaccess_for_exception_3 = 0;\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_rte(pc);\n"); fill_prefetch_0 (); /* PC is set and prefetch filled. */ @@ -1498,7 +1538,18 @@ static void gen_opcode (unsigned long in genastore ("old", curi->smode, "srcreg", curi->size, "src"); break; case i_RTS: + printf ("\tuaecptr oldpc = m68k_getpc ();\n"); printf ("\tm68k_do_rts();\n"); + if (using_exception_3) { + printf ("\tif (m68k_getpc () & 1) {\n"); + printf ("\t\tlast_addr_for_exception_3 = oldpc;\n"); + printf ("\t\tlast_fault_for_exception_3 = m68k_getpc ();\n"); + printf ("\t\tlast_instructionaccess_for_exception_3 = 1;\n"); + printf ("\t\tlast_writeaccess_for_exception_3 = 0;\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; + } fill_prefetch_0 (); m68k_pc_offset = 0; insn_n_cycles = 16; @@ -1513,9 +1564,20 @@ static void gen_opcode (unsigned long in genamode (Aipi, "7", sz_word, "sr", 1, 0); genamode (Aipi, "7", sz_long, "pc", 1, 0); printf ("\tregs.sr &= 0xFF00; sr &= 0xFF;\n"); - printf ("\tregs.sr |= sr; m68k_setpc(pc);\n"); - fill_prefetch_0 (); + printf ("\tregs.sr |= sr;\n"); printf ("\tMakeFromSR();\n"); + if (using_exception_3) { + printf ("\tif (pc & 1) {\n"); + printf ("\t\tlast_addr_for_exception_3 = m68k_getpc ();\n"); + printf ("\t\tlast_fault_for_exception_3 = pc;\n"); + printf ("\t\tlast_instructionaccess_for_exception_3 = 1;\n"); + printf ("\t\tlast_writeaccess_for_exception_3 = 0;\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 ("m68k_setpc(pc);\n"); + fill_prefetch_0 (); m68k_pc_offset = 0; insn_n_cycles = 20; break; @@ -1526,6 +1588,8 @@ static void gen_opcode (unsigned long in 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_instructionaccess_for_exception_3 = 1;\n"); + printf ("\t\tlast_writeaccess_for_exception_3 = 0;\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; @@ -1548,8 +1612,13 @@ static void gen_opcode (unsigned long in 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() + %d;\n" , m68k_pc_offset); // [NP] last_addr is not pc+6 + if ( opcode == 0x4ef8 ) // [NP] jmp xxx.w + printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n"); // [NP] last_addr is pc+2 + else + printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + %d;\n" , m68k_pc_offset); // [NP] last_addr is not pc+6 printf ("\t\tlast_fault_for_exception_3 = srca;\n"); + printf ("\t\tlast_instructionaccess_for_exception_3 = 1;\n"); + printf ("\t\tlast_writeaccess_for_exception_3 = 0;\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; @@ -1575,6 +1644,8 @@ 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() + s;\n"); + printf ("\t\tlast_instructionaccess_for_exception_3 = 1;\n"); + printf ("\t\tlast_writeaccess_for_exception_3 = 0;\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; @@ -1591,6 +1662,8 @@ 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_instructionaccess_for_exception_3 = 1;\n"); + printf ("\t\tlast_writeaccess_for_exception_3 = 0;\n"); printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr); need_endlabel = 1; } else { @@ -1604,12 +1677,15 @@ 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_instructionaccess_for_exception_3 = 1;\n"); + printf ("\t\tlast_writeaccess_for_exception_3 = 0;\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_incpc ((uae_s32)src + 2);\n"); fill_prefetch_0 (); + printf("\trefill_prefetch (m68k_getpc(), 0);\n"); // FIXME [NP] need better prefetch emulation (needed in War Heli for 60fe : bra.s -2) printf ("\treturn 10;\n"); printf ("didnt_jump:;\n"); need_endlabel = 1; @@ -1656,6 +1732,8 @@ 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\tlast_instructionaccess_for_exception_3 = 1;\n"); + printf ("\t\tlast_writeaccess_for_exception_3 = 0;\n"); 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;