--- hatari/src/uae-cpu/newcpu.c 2019/04/01 07:10:42 1.1.1.6 +++ hatari/src/uae-cpu/newcpu.c 2019/04/01 07:11:01 1.1.1.7 @@ -10,16 +10,16 @@ * This file is distributed under the GNU Public License, version 2 or at * your option any later version. Read the file gpl.txt for details. */ -static char rcsid[] = "Hatari $Id: newcpu.c,v 1.1.1.6 2019/04/01 07:10:42 root Exp $"; +static char rcsid[] = "Hatari $Id: newcpu.c,v 1.1.1.7 2019/04/01 07:11:01 root Exp $"; #include "sysdeps.h" #include "hatari-glue.h" #include "maccess.h" #include "memory.h" #include "newcpu.h" -#include "compiler.h" #include "events.h" #include "../includes/main.h" +#include "../includes/m68000.h" #include "../includes/tos.h" #include "../includes/vdi.h" #include "../includes/cart.h" @@ -50,8 +50,6 @@ int fpp_movem_next[256]; cpuop_func *cpufunctbl[65536]; -static uae_u32 busAddressErrPC = 0; /* Needed to store the right PC when bus-/address error occurs */ - #define COUNT_INSTRS 0 @@ -157,8 +155,7 @@ void build_cpufunctbl(void) /* Hatari's illegal opcodes: */ cpufunctbl[GEMDOS_OPCODE] = OpCode_GemDos; cpufunctbl[RUNOLDGEMDOS_OPCODE] = OpCode_OldGemDos; - cpufunctbl[CONDRV_OPCODE] = OpCode_ConnectedDrive; - cpufunctbl[TIMERD_OPCODE] = OpCode_TimerD; + cpufunctbl[SYSINIT_OPCODE] = OpCode_SysInit; cpufunctbl[VDI_OPCODE] = OpCode_VDI; } @@ -226,7 +223,7 @@ void init_m68k (void) if (cpu_compatible) write_log (" (compatible mode)"); write_log ("\n"); - + read_table68k (); do_merges (); @@ -677,8 +674,8 @@ void Exception(int nr, uaecptr oldpc) /*if( nr>=2 && nr<10 ) fprintf(stderr,"Exception (-> %i bombs)!\n",nr);*/ - /* Intercept exceptions... - FIXME: Find a better way to do this! */ - if(bUseVDIRes && nr == 0x22) /* Trap 2 - intercept VDI call */ + /* Intercept VDI exception (Trap #2 with D0 = 0x73) */ + if(bUseVDIRes && nr == 0x22 && regs.regs[0] == 0x73) { if(!VDI()) { @@ -690,7 +687,6 @@ void Exception(int nr, uaecptr oldpc) } } - compiler_flush_jsr_stack(); MakeSR(); if (!regs.s) { @@ -742,10 +738,13 @@ void Exception(int nr, uaecptr oldpc) put_word (m68k_areg(regs, 7), regs.sr); /* 68000 bus/address errors: */ + /* Well these 8 more bytes are not here just for debuging. + It seems adebug expects them to be on the stack when it receives + a bus error... */ if (cpu_level==0 && (nr==2 || nr==3)) { m68k_areg(regs, 7) -= 8; if (nr == 3) { /* Address error */ - put_word (m68k_areg(regs, 7), regs.sr); /*?*/ + put_word (m68k_areg(regs, 7), 0); /* FIXME: Add real function code value */ put_long (m68k_areg(regs, 7)+2, last_fault_for_exception_3); put_word (m68k_areg(regs, 7)+6, last_op_for_exception_3); put_long (m68k_areg(regs, 7)+10, last_addr_for_exception_3); @@ -755,11 +754,11 @@ void Exception(int nr, uaecptr oldpc) } } else { /* Bus error */ - put_word (m68k_areg(regs, 7), regs.sr); /*?*/ + put_word (m68k_areg(regs, 7), 0); /* FIXME: Add real function code value */ put_long (m68k_areg(regs, 7)+2, BusAddressLocation); - put_word (m68k_areg(regs, 7)+6, get_word(currpc)); + put_word (m68k_areg(regs, 7)+6, BusErrorOpcode); if( bEnableDebug && BusAddressLocation!=0xff8a00) { - fprintf(stderr,"Bus Error at address $%lx, PC=$%lx\n",BusAddressLocation,(long)currpc); + fprintf(stderr,"Bus Error at address $%x, PC=$%lx\n",BusAddressLocation,(long)currpc); DebugUI(); } } @@ -770,12 +769,39 @@ void Exception(int nr, uaecptr oldpc) regs.t1 = regs.t0 = regs.m = 0; unset_special (SPCFLAG_TRACE | SPCFLAG_DOTRACE); - /* Store a backup of the PC after bus-/address error: */ - if(nr==2 || nr==3) { - busAddressErrPC = regs.pc; + /* Handle exception cycles: */ + if(nr >= 24 && nr <= 31) + { + ADD_CYCLES(44+4, 5, 3); /* Interrupt */ + } + else if(nr >= 32 && nr <= 47) + { + ADD_CYCLES(34, 5, 3); /* Trap */ + } + else switch(nr) + { + case 2: ADD_CYCLES(50, 4, 7); break; /* Bus error */ + case 3: ADD_CYCLES(50, 4, 7); break; /* Address error */ + case 4: ADD_CYCLES(34, 4, 3); break; /* Illegal instruction */ + case 5: ADD_CYCLES(38, 4, 3); break; /* Div by zero */ + case 6: ADD_CYCLES(40, 4, 3); break; /* CHK */ + case 7: ADD_CYCLES(34, 5, 3); break; /* TRAPV */ + case 8: ADD_CYCLES(34, 4, 3); break; /* Privilege violation */ + case 9: ADD_CYCLES(34, 4, 3); break; /* Trace */ + case 10: ADD_CYCLES(34, 4, 3); break; /* Line-A - probably wrong */ + case 11: ADD_CYCLES(34, 4, 3); break; /* Line-F - probably wrong */ + default: +#if 0 /* Hatari currently seems to run more instable when adding MFP cycles */ + if(nr < 64) + ADD_CYCLES(0, 0, 0); /* Coprocessor and unassigned exceptions (???) */ + else + ADD_CYCLES(44+4, 5, 3); /* Must be a MFP interrupt */ +#endif + break; } } + static void Interrupt(int nr) { assert(nr < 8 && nr >= 0); @@ -787,8 +813,10 @@ static void Interrupt(int nr) set_special (SPCFLAG_INT); } + static uae_u32 caar, cacr, itt0, itt1, dtt0, dtt1, tc, mmusr, urp, srp; + int m68k_move2c (int regno, uae_u32 *regp) { if ((cpu_level == 1 && (regno & 0x7FF) > 1) @@ -808,7 +836,7 @@ int m68k_move2c (int regno, uae_u32 *reg case 5: itt1 = *regp & 0xffffe364; break; case 6: dtt0 = *regp & 0xffffe364; break; case 7: dtt1 = *regp & 0xffffe364; break; - + case 0x800: regs.usp = *regp; break; case 0x801: regs.vbr = *regp; break; case 0x802: caar = *regp & 0xfc; break; @@ -1117,9 +1145,6 @@ static char* ccnames[] = void m68k_reset (void) { - m68k_areg(regs, 7) = get_long(0); - m68k_setpc(get_long(4)); - refill_prefetch (m68k_getpc (), 0); regs.s = 1; regs.m = 0; regs.stopped = 0; @@ -1130,17 +1155,20 @@ void m68k_reset (void) SET_CFLG (0); SET_VFLG (0); SET_NFLG (0); - regs.spcflags = 0; + regs.spcflags &= SPCFLAG_MODE_CHANGE; /* Clear specialflags except mode-change */ regs.intmask = 7; regs.vbr = regs.sfc = regs.dfc = 0; regs.fpcr = regs.fpsr = regs.fpiar = 0; + + m68k_areg(regs, 7) = get_long(0); + m68k_setpc(get_long(4)); + refill_prefetch (m68k_getpc(), 0); } unsigned long REGPARAM2 op_illg (uae_u32 opcode) { uaecptr pc = m68k_getpc (); - compiler_flush_jsr_stack (); if (opcode == 0x4E7B && get_long (0x10) == 0 ) { write_log ("This program requires a 68020 CPU!\n"); broken_in = 1; @@ -1218,7 +1246,14 @@ static void do_trace (void) static int do_specialties (void) { - run_compiled_code(); + if(regs.spcflags & SPCFLAG_BUSERROR) { + /* We can not execute bus errors directly in the memory handler + * functions since the PC should point to the address of the next + * instruction, so we're executing the bus errors here: */ + unset_special(SPCFLAG_BUSERROR); + Exception(2,0); + } + if (regs.spcflags & SPCFLAG_DOTRACE) { Exception (9,last_trace_ad); } @@ -1297,15 +1332,6 @@ static void m68k_run_1 (void) cycles = (*cpufunctbl[opcode])(opcode); - /* Unfortunately needed at the moment: */ - /* Check if we had an bus/address error and correct the PC then... */ - if(busAddressErrPC) { - /*write_log("Fixed PC to $%x instead of $%x after bus-/address error!\n", - busAddressErrPC, m68k_getpc());*/ - m68k_setpc(busAddressErrPC); - busAddressErrPC = 0; - } - #ifdef DEBUG_PREFETCH if (memcmp (saved_bytes, oldpcp, 20) != 0) { fprintf (stderr, "Self-modifying code detected.\n"); @@ -1344,15 +1370,6 @@ static void m68k_run_2 (void) cycles = (*cpufunctbl[opcode])(opcode); - /* Unfortunately needed at the moment: */ - /* Check if we had an bus/address error and correct the PC then... */ - if(busAddressErrPC) { - /*write_log("Fixed PC to $%x instead of $%x after bus-/address error!\n", - busAddressErrPC, m68k_getpc());*/ - m68k_setpc(busAddressErrPC); - busAddressErrPC = 0; - } - do_cycles (cycles); if (regs.spcflags) { if (do_specialties ())