--- hatari/src/uae-cpu/hatari-glue.c 2019/04/01 07:10:40 1.1.1.6 +++ hatari/src/uae-cpu/hatari-glue.c 2019/04/01 07:13:46 1.1.1.11 @@ -7,12 +7,13 @@ This file contains some code to glue the UAE CPU core to the rest of the emulator and Hatari's "illegal" opcodes. */ -static char rcsid[] = "Hatari $Id: hatari-glue.c,v 1.1.1.6 2019/04/01 07:10:40 root Exp $"; +const char HatariGlue_rcsid[] = "Hatari $Id: hatari-glue.c,v 1.1.1.11 2019/04/01 07:13:46 root Exp $"; #include #include "../includes/main.h" +#include "../includes/configuration.h" #include "../includes/int.h" #include "../includes/tos.h" #include "../includes/gemdos.h" @@ -24,6 +25,7 @@ static char rcsid[] = "Hatari $Id: hatar #include "maccess.h" #include "memory.h" #include "newcpu.h" +#include "hatari-glue.h" #ifndef FALSE #define FALSE 0 @@ -31,43 +33,51 @@ static char rcsid[] = "Hatari $Id: hatar #endif -int illegal_mem = FALSE; -int address_space_24 = TRUE; -int cpu_level = 0; /* 68000 (default) */ -int cpu_compatible = FALSE; +struct uae_prefs currprefs, changed_prefs; -int requestedInterrupt = -1; - -long STmem_size = 0x400000; /* 4MB */ -long TTmem_size = 0; +int pendingInterrupts = 0; /* Reset custom chips */ void customreset(void) { - requestedInterrupt = -1; + pendingInterrupts = 0; } -/* Return interrupt number (1 - 7), -1 means no interrupt. */ +/* Return interrupt number (1 - 7), -1 means no interrupt. + * Note that the interrupt stays pending if it can't be executed yet + * due to the interrupt level field in the SR. */ int intlev(void) { - int ret = requestedInterrupt; - requestedInterrupt = -1; + /* There are only VBL and HBL autovector interrupts in the ST... */ + assert((pendingInterrupts & ~((1<<4)|(1<<2))) == 0); - return ret; + if(pendingInterrupts & (1 << 4)) /* VBL interrupt? */ + { + if(regs.intmask < 4) + pendingInterrupts &= ~(1 << 4); + return 4; + } + else if(pendingInterrupts & (1 << 2)) /* HBL interrupt? */ + { + if(regs.intmask < 2) + pendingInterrupts &= ~(1 << 2); + return 2; + } + + return -1; } /* Initialize 680x0 emulation */ int Init680x0(void) { - memory_init(); + currprefs.cpu_level = changed_prefs.cpu_level = ConfigureParams.System.nCpuLevel; + currprefs.cpu_compatible = changed_prefs.cpu_compatible = ConfigureParams.System.bCompatibleCpu; + currprefs.address_space_24 = changed_prefs.address_space_24 = TRUE; init_m68k(); -#ifdef USE_COMPILER - compiler_init(); -#endif return TRUE; } @@ -75,87 +85,49 @@ int Init680x0(void) /* Deinitialize 680x0 emulation */ void Exit680x0(void) { -} - + memory_uninit(); -/* Reset and start 680x0 emulation */ -void Start680x0(void) -{ - m68k_reset(); - m68k_go(TRUE); + free(table68k); + table68k = NULL; } /* Check if the CPU type has been changed */ -void check_prefs_changed_cpu(int new_level, int new_compatible) +void check_prefs_changed_cpu(void) { - if(cpu_level!=new_level || cpu_compatible!=new_compatible) + if (currprefs.cpu_level != changed_prefs.cpu_level + || currprefs.cpu_compatible != changed_prefs.cpu_compatible) { - cpu_level = new_level; - cpu_compatible = new_compatible; + currprefs.cpu_level = changed_prefs.cpu_level; + currprefs.cpu_compatible = changed_prefs.cpu_compatible; + set_special(SPCFLAG_MODE_CHANGE); build_cpufunctbl (); } } - /* ----------------------------------------------------------------------- */ /* - We use an illegal opcode to set ConnectedDrives, as TOS (or an HD driver) - alters this value we cannot set it on init. - This opcode replaces the RTS at the end of the DMA bus boot routine + This function will be called at system init by the cartridge routine + (after gemdos init, before booting floppies). + + The GEMDOS vector (#$84) is setup and we also initialize the connected + drive mask and Line-A variables (for an extended VDI resolution) from here. */ -unsigned long OpCode_ConnectedDrive(uae_u32 opcode) +unsigned long OpCode_SysInit(uae_u32 opcode) { - fprintf(stderr, "OpCode_ConnectedDrive handled (%x)\n",ConnectedDriveMask ); - /* Set connected drives */ - STMemory_WriteLong(0x4c2, ConnectedDriveMask); - /* do an RTS (the opcode we replaced) */ - m68k_setpc(longget(m68k_areg(regs, 7))); - m68k_areg(regs, 7) += 4; + /* Initialize the connected drive mask */ + STMemory_WriteLong(0x4c2, ConnectedDriveMask); - fill_prefetch_0(); - return 4; -} - - -/* ----------------------------------------------------------------------- */ -/* - Re-direct execution to old GEMDOS calls, used in 'cart.s' -*/ -unsigned long OpCode_OldGemDos(uae_u32 opcode) -{ - m68k_setpc( STMemory_ReadLong(CART_OLDGEMDOS) ); - fill_prefetch_0(); - return 4; -} - - -/* ----------------------------------------------------------------------- */ -/* - Intercept GEMDOS calls (setup vector $84) - The vector is setup when the gemdos-opcode is run the first time, by - the cartridge routine. (after gemdos init, before booting floppies) - - After this, our vector will be used, and handled by the GemDOS_OpCode - routine in gemdos.c -*/ -unsigned long OpCode_GemDos(uae_u32 opcode) -{ if(!bInitGemDOS) { - /* Init on boot - see cartimg.c */ + /* Init on boot - see cart.c */ GemDOS_Boot(); - /* We use this to get pointer to Line-A structure details - * (to fix for extended VDI res) */ - LineABase = regs.regs[0]; /* D0 */ - FontBase = regs.regs[9]; /* A1 */ - VDI_LineA(); - } - else - { - GemDOS_OpCode(); /* handler code in gemdos.c */ + /* Update LineA for extended VDI res + * D0: LineA base, A1: Font base + */ + VDI_LineA(regs.regs[0], regs.regs[9]); } m68k_incpc(2); @@ -166,21 +138,14 @@ unsigned long OpCode_GemDos(uae_u32 opco /* ----------------------------------------------------------------------- */ /* - Modify TimerD in GEMDos to gain more desktop performance + Intercept GEMDOS calls - Obviously, we need to emulate all timers correctly but GemDOS set's up Timer D at a very - high rate(every couple of instructions). The interrupts isn't enabled but WinSTon still - needs to process the interrupt table and this HALVES our frame rate!!! (It causes a cache - reload each time). Some games actually reference this timer but don't set it up(eg Paradroid, - Speedball I) so we simply intercept the Timer D setup code in GemDOS and fix the numbers - with more 'laid-back' values. This still keeps 100% compatibility + Used for GEMDOS HD emulation (see gemdos.c). */ -unsigned long OpCode_TimerD(uae_u32 opcode) +unsigned long OpCode_GemDos(uae_u32 opcode) { - /*fprintf(stderr, "OpCode_TimerD handled\n");*/ - m68k_dreg(regs,0)=3; /* 3 = Select Timer D */ - m68k_dreg(regs,1)=7; /* 1 = /4 for 9600 baud(used /200) */ - m68k_dreg(regs,2)=100; /* 2 = 9600 baud(100) */ + GemDOS_OpCode(); /* handler code in gemdos.c */ + m68k_incpc(2); fill_prefetch_0(); return 4;