mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-27 19:51:48 +01:00
~optimized 68k execution/interruptions
~re-enabled Address Error emulation
This commit is contained in:
parent
7bddb27c2b
commit
aa970d66a6
@ -7,7 +7,7 @@ Genesis Plus GX 1.3.2 (??/??/????) (Eke-Eke)
|
|||||||
|
|
||||||
* optimized SN76489 core
|
* optimized SN76489 core
|
||||||
* modified SN76489 cut-off frequency (thanks to Steve Snake)
|
* modified SN76489 cut-off frequency (thanks to Steve Snake)
|
||||||
* added SN76489 linear interpolation using Blip Buffer (thanks to Blargg)
|
* added SN76489 linear synthesis using Blip Buffer (thanks to Blargg)
|
||||||
* added an option to boost SN76489 Noise Channel
|
* added an option to boost SN76489 Noise Channel
|
||||||
* removed now outdated Gens YM2612 core
|
* removed now outdated Gens YM2612 core
|
||||||
* improved YM2612 emulation accuracy (SSG-EG, CSM mode...) (thanks to Nemesis for his tests on real hardware)
|
* improved YM2612 emulation accuracy (SSG-EG, CSM mode...) (thanks to Nemesis for his tests on real hardware)
|
||||||
|
@ -26,10 +26,11 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
#include "m68kcpu.h"
|
|
||||||
|
|
||||||
#define CART_CNT 26
|
#define CART_CNT 26
|
||||||
|
|
||||||
|
extern int emulate_address_error;
|
||||||
|
|
||||||
/* Global Variables */
|
/* Global Variables */
|
||||||
T_CART_HW cart_hw;
|
T_CART_HW cart_hw;
|
||||||
uint8 j_cart;
|
uint8 j_cart;
|
||||||
|
@ -78,7 +78,7 @@ static inline void lightgun_update(int num)
|
|||||||
if (io_reg[5] & 0x80)
|
if (io_reg[5] & 0x80)
|
||||||
{
|
{
|
||||||
/* External Interrupt ? */
|
/* External Interrupt ? */
|
||||||
if (reg[11] & 0x08) {irq_status &= 0xff; irq_status |= 0x12;}
|
if (reg[11] & 0x08) irq_status = (irq_status & ~0x40) | 0x12;
|
||||||
|
|
||||||
/* HVC Latch:
|
/* HVC Latch:
|
||||||
1) some games does not set HVC latch but instead use bigger X offset
|
1) some games does not set HVC latch but instead use bigger X offset
|
||||||
|
@ -157,7 +157,7 @@
|
|||||||
* access a word or longword at an odd address.
|
* access a word or longword at an odd address.
|
||||||
* NOTE: This is only emulated properly for 68000 mode.
|
* NOTE: This is only emulated properly for 68000 mode.
|
||||||
*/
|
*/
|
||||||
#define M68K_EMULATE_ADDRESS_ERROR OPT_OFF
|
#define M68K_EMULATE_ADDRESS_ERROR OPT_ON
|
||||||
|
|
||||||
|
|
||||||
/* Turn ON to enable logging of illegal instruction calls.
|
/* Turn ON to enable logging of illegal instruction calls.
|
||||||
|
@ -75,7 +75,9 @@ const char *const m68ki_cpu_names[] =
|
|||||||
m68ki_cpu_core m68ki_cpu = {0};
|
m68ki_cpu_core m68ki_cpu = {0};
|
||||||
|
|
||||||
#if M68K_EMULATE_ADDRESS_ERROR
|
#if M68K_EMULATE_ADDRESS_ERROR
|
||||||
|
#include <setjmp.h>
|
||||||
jmp_buf m68ki_aerr_trap;
|
jmp_buf m68ki_aerr_trap;
|
||||||
|
int emulate_address_error = 0;
|
||||||
#endif /* M68K_EMULATE_ADDRESS_ERROR */
|
#endif /* M68K_EMULATE_ADDRESS_ERROR */
|
||||||
|
|
||||||
uint m68ki_aerr_address;
|
uint m68ki_aerr_address;
|
||||||
@ -505,13 +507,6 @@ static void default_instr_hook_callback(unsigned int pc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if M68K_EMULATE_ADDRESS_ERROR
|
|
||||||
#include <setjmp.h>
|
|
||||||
jmp_buf m68ki_aerr_trap;
|
|
||||||
int emulate_address_error = 0;
|
|
||||||
#endif /* M68K_EMULATE_ADDRESS_ERROR */
|
|
||||||
|
|
||||||
|
|
||||||
/* ======================================================================== */
|
/* ======================================================================== */
|
||||||
/* ================================= API ================================== */
|
/* ================================= API ================================== */
|
||||||
/* ======================================================================== */
|
/* ======================================================================== */
|
||||||
@ -781,64 +776,42 @@ void m68k_set_cpu_type(unsigned int cpu_type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute some instructions until we use up num_cycles clock cycles */
|
/* Execute a single instruction */
|
||||||
/* ASG: removed per-instruction interrupt checks */
|
INLINE int m68k_execute(void)
|
||||||
INLINE int m68k_execute(int num_cycles)
|
|
||||||
{
|
{
|
||||||
/* Make sure we're not stopped */
|
|
||||||
if(!CPU_STOPPED)
|
|
||||||
{
|
|
||||||
/* Set our pool of clock cycles available */
|
/* Set our pool of clock cycles available */
|
||||||
SET_CYCLES(num_cycles);
|
SET_CYCLES(0);
|
||||||
m68ki_initial_cycles = num_cycles;
|
|
||||||
|
/* Set tracing accodring to T1. (T0 is done inside instruction) */
|
||||||
|
m68ki_trace_t1(); /* auto-disable (see m68kcpu.h) */
|
||||||
|
|
||||||
|
/* Set the address space for reads */
|
||||||
|
m68ki_use_data_space(); /* auto-disable (see m68kcpu.h) */
|
||||||
|
|
||||||
|
/* Call external hook to peek at CPU */
|
||||||
|
m68ki_instr_hook(REG_PC); /* auto-disable (see m68kcpu.h) */
|
||||||
|
|
||||||
|
/* Record previous program counter */
|
||||||
|
REG_PPC = REG_PC;
|
||||||
|
|
||||||
|
/* Read an instruction and call its handler */
|
||||||
|
REG_IR = m68ki_read_imm_16();
|
||||||
|
m68ki_instruction_jump_table[REG_IR]();
|
||||||
|
USE_CYCLES(CYC_INSTRUCTION[REG_IR]);
|
||||||
|
|
||||||
|
/* Trace m68k_exception, if necessary */
|
||||||
|
m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */
|
||||||
|
|
||||||
/* ASG: update cycles */
|
/* ASG: update cycles */
|
||||||
USE_CYCLES(CPU_INT_CYCLES);
|
USE_CYCLES(CPU_INT_CYCLES);
|
||||||
CPU_INT_CYCLES = 0;
|
CPU_INT_CYCLES = 0;
|
||||||
|
|
||||||
/* Return point if we had an address error */
|
|
||||||
m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */
|
|
||||||
|
|
||||||
/* Main loop. Keep going until we run out of clock cycles */
|
|
||||||
do
|
|
||||||
{
|
|
||||||
/* Set tracing accodring to T1. (T0 is done inside instruction) */
|
|
||||||
m68ki_trace_t1(); /* auto-disable (see m68kcpu.h) */
|
|
||||||
|
|
||||||
/* Set the address space for reads */
|
|
||||||
m68ki_use_data_space(); /* auto-disable (see m68kcpu.h) */
|
|
||||||
|
|
||||||
/* Call external hook to peek at CPU */
|
|
||||||
m68ki_instr_hook(REG_PC); /* auto-disable (see m68kcpu.h) */
|
|
||||||
|
|
||||||
/* Record previous program counter */
|
|
||||||
REG_PPC = REG_PC;
|
|
||||||
|
|
||||||
/* Read an instruction and call its handler */
|
|
||||||
REG_IR = m68ki_read_imm_16();
|
|
||||||
m68ki_instruction_jump_table[REG_IR]();
|
|
||||||
USE_CYCLES(CYC_INSTRUCTION[REG_IR]);
|
|
||||||
|
|
||||||
/* Trace m68k_exception, if necessary */
|
|
||||||
m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */
|
|
||||||
} while(GET_CYCLES() > 0);
|
|
||||||
|
|
||||||
/* set previous PC to current PC for the next entry into the loop */
|
/* set previous PC to current PC for the next entry into the loop */
|
||||||
REG_PPC = REG_PC;
|
REG_PPC = REG_PC;
|
||||||
|
|
||||||
/* ASG: update cycles */
|
|
||||||
USE_CYCLES(CPU_INT_CYCLES);
|
|
||||||
CPU_INT_CYCLES = 0;
|
|
||||||
|
|
||||||
/* return how many clocks we used */
|
/* return how many clocks we used */
|
||||||
return m68ki_initial_cycles - GET_CYCLES();
|
return - GET_CYCLES();
|
||||||
}
|
|
||||||
|
|
||||||
/* We get here if the CPU is stopped or halted */
|
|
||||||
SET_CYCLES(0);
|
|
||||||
CPU_INT_CYCLES = 0;
|
|
||||||
|
|
||||||
return num_cycles;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ASG: rewrote so that the int_level is a mask of the IPL0/IPL1/IPL2 bits */
|
/* ASG: rewrote so that the int_level is a mask of the IPL0/IPL1/IPL2 bits */
|
||||||
@ -858,12 +831,23 @@ INLINE void m68k_set_irq(unsigned int int_level)
|
|||||||
m68ki_check_interrupts(); /* Level triggered (IRQ) */
|
m68ki_check_interrupts(); /* Level triggered (IRQ) */
|
||||||
}
|
}
|
||||||
|
|
||||||
extern uint16 irq_status;
|
extern uint8 irq_status;
|
||||||
extern uint32 count_m68k;
|
extern uint32 count_m68k;
|
||||||
|
|
||||||
void m68k_run (int cyc)
|
void m68k_run (int cyc)
|
||||||
{
|
{
|
||||||
|
/* Make sure we're not stopped */
|
||||||
|
if(CPU_STOPPED)
|
||||||
|
{
|
||||||
|
count_m68k = cyc;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int temp;
|
int temp;
|
||||||
|
|
||||||
|
/* Return point if we had an address error */
|
||||||
|
m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */
|
||||||
|
|
||||||
while (count_m68k < cyc)
|
while (count_m68k < cyc)
|
||||||
{
|
{
|
||||||
/* check interrupt updates */
|
/* check interrupt updates */
|
||||||
@ -871,18 +855,23 @@ void m68k_run (int cyc)
|
|||||||
{
|
{
|
||||||
irq_status &= ~0x10;
|
irq_status &= ~0x10;
|
||||||
|
|
||||||
|
temp = irq_status & 6;
|
||||||
|
|
||||||
/* hardware latency */
|
/* hardware latency */
|
||||||
temp = irq_status >> 8;
|
if (irq_status & 0x40)
|
||||||
if (temp) count_m68k += m68k_execute(temp);
|
count_m68k += m68k_execute();
|
||||||
|
|
||||||
/* interrupt level */
|
/* interrupt level */
|
||||||
temp = irq_status & 6;
|
|
||||||
if (temp == 6) irq_status |= 0x20;
|
if (temp == 6) irq_status |= 0x20;
|
||||||
m68k_set_irq(temp);
|
m68k_set_irq(temp);
|
||||||
|
|
||||||
|
/* ASG: update cycles */
|
||||||
|
count_m68k += CPU_INT_CYCLES;
|
||||||
|
CPU_INT_CYCLES = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* execute a single instruction */
|
/* execute a single instruction */
|
||||||
count_m68k += m68k_execute(1);
|
count_m68k += m68k_execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,7 +554,7 @@
|
|||||||
#if M68K_EMULATE_ADDRESS_ERROR
|
#if M68K_EMULATE_ADDRESS_ERROR
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
extern jmp_buf m68ki_aerr_trap;
|
extern jmp_buf m68ki_aerr_trap;
|
||||||
extern int emulate_address_error;
|
extern int emulate_address_error;
|
||||||
|
|
||||||
#define m68ki_set_address_error_trap() \
|
#define m68ki_set_address_error_trap() \
|
||||||
if(setjmp(m68ki_aerr_trap) != 0) \
|
if(setjmp(m68ki_aerr_trap) != 0) \
|
||||||
@ -564,7 +564,6 @@
|
|||||||
{ \
|
{ \
|
||||||
SET_CYCLES(0); \
|
SET_CYCLES(0); \
|
||||||
CPU_INT_CYCLES = 0; \
|
CPU_INT_CYCLES = 0; \
|
||||||
return m68ki_initial_cycles; \
|
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1063,13 +1062,13 @@ INLINE uint m68ki_read_imm_16(void)
|
|||||||
if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)
|
if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)
|
||||||
{
|
{
|
||||||
CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);
|
CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);
|
||||||
CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR));
|
CPU_PREF_DATA = m68k_read_immediate_32(CPU_PREF_ADDR);
|
||||||
}
|
}
|
||||||
REG_PC += 2;
|
REG_PC += 2;
|
||||||
return MASK_OUT_ABOVE_16(CPU_PREF_DATA >> ((2-((REG_PC-2)&2))<<3));
|
return MASK_OUT_ABOVE_16(CPU_PREF_DATA >> ((2-((REG_PC-2)&2))<<3));
|
||||||
#else
|
#else
|
||||||
REG_PC += 2;
|
REG_PC += 2;
|
||||||
return m68k_read_immediate_16(ADDRESS_68K(REG_PC-2));
|
return m68k_read_immediate_16(REG_PC-2);
|
||||||
#endif /* M68K_EMULATE_PREFETCH */
|
#endif /* M68K_EMULATE_PREFETCH */
|
||||||
}
|
}
|
||||||
INLINE uint m68ki_read_imm_32(void)
|
INLINE uint m68ki_read_imm_32(void)
|
||||||
@ -1082,14 +1081,14 @@ INLINE uint m68ki_read_imm_32(void)
|
|||||||
if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)
|
if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)
|
||||||
{
|
{
|
||||||
CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);
|
CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);
|
||||||
CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR));
|
CPU_PREF_DATA = m68k_read_immediate_32(CPU_PREF_ADDR);
|
||||||
}
|
}
|
||||||
temp_val = CPU_PREF_DATA;
|
temp_val = CPU_PREF_DATA;
|
||||||
REG_PC += 2;
|
REG_PC += 2;
|
||||||
if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)
|
if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)
|
||||||
{
|
{
|
||||||
CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);
|
CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);
|
||||||
CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR));
|
CPU_PREF_DATA = m68k_read_immediate_32(CPU_PREF_ADDR);
|
||||||
temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | (CPU_PREF_DATA >> 16));
|
temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | (CPU_PREF_DATA >> 16));
|
||||||
}
|
}
|
||||||
REG_PC += 2;
|
REG_PC += 2;
|
||||||
@ -1099,7 +1098,7 @@ INLINE uint m68ki_read_imm_32(void)
|
|||||||
m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
|
m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
|
||||||
m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
|
m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
|
||||||
REG_PC += 4;
|
REG_PC += 4;
|
||||||
return m68k_read_immediate_32(ADDRESS_68K(REG_PC-4));
|
return m68k_read_immediate_32(REG_PC-4);
|
||||||
#endif /* M68K_EMULATE_PREFETCH */
|
#endif /* M68K_EMULATE_PREFETCH */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1119,7 +1118,7 @@ INLINE uint m68ki_read_8_fc(uint address, uint fc)
|
|||||||
|
|
||||||
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||||
|
|
||||||
if (temp->read8) return (*temp->read8)(address);
|
if (temp->read8) return (*temp->read8)(ADDRESS_68K(address));
|
||||||
else return READ_BYTE(temp->base, (address) & 0xffff);
|
else return READ_BYTE(temp->base, (address) & 0xffff);
|
||||||
}
|
}
|
||||||
INLINE uint m68ki_read_16_fc(uint address, uint fc)
|
INLINE uint m68ki_read_16_fc(uint address, uint fc)
|
||||||
@ -1128,7 +1127,7 @@ INLINE uint m68ki_read_16_fc(uint address, uint fc)
|
|||||||
m68ki_check_address_error_010_less(address, MODE_READ, fc); /* auto-disable (see m68kcpu.h) */
|
m68ki_check_address_error_010_less(address, MODE_READ, fc); /* auto-disable (see m68kcpu.h) */
|
||||||
|
|
||||||
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||||
if (temp->read16) return (*temp->read16)(address);
|
if (temp->read16) return (*temp->read16)(ADDRESS_68K(address));
|
||||||
else return *(uint16 *)(temp->base + ((address) & 0xffff));
|
else return *(uint16 *)(temp->base + ((address) & 0xffff));
|
||||||
}
|
}
|
||||||
INLINE uint m68ki_read_32_fc(uint address, uint fc)
|
INLINE uint m68ki_read_32_fc(uint address, uint fc)
|
||||||
@ -1137,7 +1136,7 @@ INLINE uint m68ki_read_32_fc(uint address, uint fc)
|
|||||||
m68ki_check_address_error_010_less(address, MODE_READ, fc); /* auto-disable (see m68kcpu.h) */
|
m68ki_check_address_error_010_less(address, MODE_READ, fc); /* auto-disable (see m68kcpu.h) */
|
||||||
|
|
||||||
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||||
if (temp->read16) return ((*temp->read16)(address) << 16) | ((*temp->read16)(address + 2));
|
if (temp->read16) return ((*temp->read16)(ADDRESS_68K(address)) << 16) | ((*temp->read16)(ADDRESS_68K(address + 2)));
|
||||||
else return m68k_read_immediate_32(address);
|
else return m68k_read_immediate_32(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1145,7 +1144,7 @@ INLINE void m68ki_write_8_fc(uint address, uint fc, uint value)
|
|||||||
{
|
{
|
||||||
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
|
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
|
||||||
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||||
if (temp->write8) (*temp->write8)(address,value);
|
if (temp->write8) (*temp->write8)(ADDRESS_68K(address),value);
|
||||||
else WRITE_BYTE(temp->base, (address) & 0xffff, value);
|
else WRITE_BYTE(temp->base, (address) & 0xffff, value);
|
||||||
}
|
}
|
||||||
INLINE void m68ki_write_16_fc(uint address, uint fc, uint value)
|
INLINE void m68ki_write_16_fc(uint address, uint fc, uint value)
|
||||||
@ -1153,7 +1152,7 @@ INLINE void m68ki_write_16_fc(uint address, uint fc, uint value)
|
|||||||
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
|
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
|
||||||
m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
|
m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
|
||||||
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||||
if (temp->write16) (*temp->write16)(address,value);
|
if (temp->write16) (*temp->write16)(ADDRESS_68K(address),value);
|
||||||
else *(uint16 *)(temp->base + ((address) & 0xffff)) = value;
|
else *(uint16 *)(temp->base + ((address) & 0xffff)) = value;
|
||||||
}
|
}
|
||||||
INLINE void m68ki_write_32_fc(uint address, uint fc, uint value)
|
INLINE void m68ki_write_32_fc(uint address, uint fc, uint value)
|
||||||
@ -1163,8 +1162,8 @@ INLINE void m68ki_write_32_fc(uint address, uint fc, uint value)
|
|||||||
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||||
if (temp->write16)
|
if (temp->write16)
|
||||||
{
|
{
|
||||||
(*temp->write16)(address,value>>16);
|
(*temp->write16)(ADDRESS_68K(address),value>>16);
|
||||||
(*temp->write16)(address+2,value&0xffff);
|
(*temp->write16)(ADDRESS_68K(address+2),value&0xffff);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1958,7 +1957,6 @@ INLINE void m68ki_exception_address_error(void)
|
|||||||
*/
|
*/
|
||||||
if(CPU_RUN_MODE == RUN_MODE_BERR_AERR_RESET)
|
if(CPU_RUN_MODE == RUN_MODE_BERR_AERR_RESET)
|
||||||
{
|
{
|
||||||
m68k_read_memory_8(0x00ffff01);
|
|
||||||
CPU_STOPPED = STOP_LEVEL_HALT;
|
CPU_STOPPED = STOP_LEVEL_HALT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1975,7 +1973,7 @@ INLINE void m68ki_exception_address_error(void)
|
|||||||
|
|
||||||
|
|
||||||
/* Service an interrupt request and start exception processing */
|
/* Service an interrupt request and start exception processing */
|
||||||
void m68ki_exception_interrupt(uint int_level)
|
INLINE void m68ki_exception_interrupt(uint int_level)
|
||||||
{
|
{
|
||||||
uint vector;
|
uint vector;
|
||||||
uint sr;
|
uint sr;
|
||||||
|
@ -7,20 +7,20 @@
|
|||||||
|
|
||||||
#define READ_WORD(BASE, ADDR) (((BASE)[ADDR]<<8) | (BASE)[(ADDR)+1])
|
#define READ_WORD(BASE, ADDR) (((BASE)[ADDR]<<8) | (BASE)[(ADDR)+1])
|
||||||
|
|
||||||
#define READ_WORD_LONG(BASE, ADDR) (((BASE)[ADDR]<<24) | \
|
#define READ_WORD_LONG(BASE, ADDR) (((BASE)[(ADDR)+1]<<24) | \
|
||||||
((BASE)[(ADDR)+1]<<16) | \
|
((BASE)[(ADDR)]<<16) | \
|
||||||
((BASE)[(ADDR)+2]<<8) | \
|
((BASE)[(ADDR)+3]<<8) | \
|
||||||
(BASE)[(ADDR)+3])
|
(BASE)[(ADDR)+1])
|
||||||
|
|
||||||
#define WRITE_BYTE(BASE, ADDR, VAL) (BASE)[(ADDR)^1] = (VAL)&0xff
|
#define WRITE_BYTE(BASE, ADDR, VAL) (BASE)[(ADDR)^1] = (VAL)&0xff
|
||||||
|
|
||||||
#define WRITE_WORD(BASE, ADDR, VAL) (BASE)[ADDR] = ((VAL)>>8) & 0xff; \
|
#define WRITE_WORD(BASE, ADDR, VAL) (BASE)[ADDR] = ((VAL)>>8) & 0xff; \
|
||||||
(BASE)[(ADDR)+1] = (VAL)&0xff
|
(BASE)[(ADDR)+1] = (VAL)&0xff
|
||||||
|
|
||||||
#define WRITE_WORD_LONG(BASE, ADDR, VAL) (BASE)[(ADDR] = ((VAL)>>24) & 0xff; \
|
#define WRITE_WORD_LONG(BASE, ADDR, VAL) (BASE)[(ADDR+1)] = ((VAL)>>24) & 0xff; \
|
||||||
(BASE)[(ADDR)+1] = ((VAL)>>16)&0xff; \
|
(BASE)[(ADDR)] = ((VAL)>>16)&0xff; \
|
||||||
(BASE)[(ADDR)+2] = ((VAL)>>8)&0xff; \
|
(BASE)[(ADDR+3)] = ((VAL)>>8)&0xff; \
|
||||||
(BASE)[(ADDR)+3] = (VAL)&0xff
|
(BASE)[(ADDR+2)] = (VAL)&0xff
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@ -388,7 +388,7 @@ int system_frame (int do_skip)
|
|||||||
{
|
{
|
||||||
h_counter = reg[10];
|
h_counter = reg[10];
|
||||||
hint_pending = 1;
|
hint_pending = 1;
|
||||||
if (reg[0] & 0x10) irq_status = (irq_status & 0xff) | 0x14;
|
if (reg[0] & 0x10) irq_status = (irq_status & ~0x40) | 0x14;
|
||||||
|
|
||||||
/* adjust timings to take further decrement in account (see below) */
|
/* adjust timings to take further decrement in account (see below) */
|
||||||
if ((line != 0) || (h_counter == 0)) aim_m68k += 36;
|
if ((line != 0) || (h_counter == 0)) aim_m68k += 36;
|
||||||
@ -430,10 +430,11 @@ int system_frame (int do_skip)
|
|||||||
|
|
||||||
/* V Interrupt */
|
/* V Interrupt */
|
||||||
status |= 0x80;
|
status |= 0x80;
|
||||||
vint_pending = 1;
|
|
||||||
|
|
||||||
/* 36 cycles latency after VINT occurence flag (Ex-Mutants, Tyrant) */
|
/* 36 cycles latency after VINT occurence flag (Ex-Mutants, Tyrant) */
|
||||||
if (reg[1] & 0x20) irq_status = (irq_status & 0xff) | 0x2416;
|
m68k_run(line_m68k + 113);
|
||||||
|
vint_pending = 1;
|
||||||
|
if (reg[1] & 0x20) irq_status = (irq_status & ~0x40) | 0x16;
|
||||||
}
|
}
|
||||||
else if (!do_skip)
|
else if (!do_skip)
|
||||||
{
|
{
|
||||||
|
10
source/vdp.c
10
source/vdp.c
@ -50,7 +50,7 @@ uint16 status; /* VDP status flags */
|
|||||||
uint8 dmafill; /* next VDP Write is DMA Fill */
|
uint8 dmafill; /* next VDP Write is DMA Fill */
|
||||||
uint8 hint_pending; /* 0= Line interrupt is pending */
|
uint8 hint_pending; /* 0= Line interrupt is pending */
|
||||||
uint8 vint_pending; /* 1= Frame interrupt is pending */
|
uint8 vint_pending; /* 1= Frame interrupt is pending */
|
||||||
uint16 irq_status; /* Interrupt lines updated */
|
uint8 irq_status; /* Interrupt lines updated */
|
||||||
|
|
||||||
/* Global variables */
|
/* Global variables */
|
||||||
uint16 ntab; /* Name table A base address */
|
uint16 ntab; /* Name table A base address */
|
||||||
@ -651,7 +651,7 @@ static inline void reg_w(unsigned int r, unsigned int d)
|
|||||||
{
|
{
|
||||||
/* update IRQ status */
|
/* update IRQ status */
|
||||||
irq_status &= 0x20;
|
irq_status &= 0x20;
|
||||||
irq_status |= 0x10;
|
irq_status |= 0x50;
|
||||||
if (vint_pending && (reg[1] & 0x20)) irq_status |= 6;
|
if (vint_pending && (reg[1] & 0x20)) irq_status |= 6;
|
||||||
else if (d & 0x10) irq_status |= 4;
|
else if (d & 0x10) irq_status |= 4;
|
||||||
}
|
}
|
||||||
@ -677,7 +677,7 @@ static inline void reg_w(unsigned int r, unsigned int d)
|
|||||||
{
|
{
|
||||||
/* update IRQ status */
|
/* update IRQ status */
|
||||||
irq_status &= 0x20;
|
irq_status &= 0x20;
|
||||||
irq_status |= 0x110;
|
irq_status |= 0x50;
|
||||||
if (d & 0x20) irq_status |= 6;
|
if (d & 0x20) irq_status |= 6;
|
||||||
else if (hint_pending && (reg[0] & 0x10)) irq_status |= 4;
|
else if (hint_pending && (reg[0] & 0x10)) irq_status |= 4;
|
||||||
}
|
}
|
||||||
@ -697,7 +697,7 @@ static inline void reg_w(unsigned int r, unsigned int d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Display activated/blanked during Horizontal Blanking */
|
/* Display activated/blanked during Horizontal Blanking */
|
||||||
if (((d&0x40) != (reg[1]&0x40)) && (v_counter < bitmap.viewport.h))
|
if (((d&0x40) != (reg[1]&0x40)) && !(status & 8))
|
||||||
{
|
{
|
||||||
if (count_m68k <= (hint_m68k + 120))
|
if (count_m68k <= (hint_m68k + 120))
|
||||||
{
|
{
|
||||||
@ -748,7 +748,7 @@ static inline void reg_w(unsigned int r, unsigned int d)
|
|||||||
color_update(0x00, *(uint16 *)&cram[(border << 1)]);
|
color_update(0x00, *(uint16 *)&cram[(border << 1)]);
|
||||||
|
|
||||||
/* background color modified during Horizontal Blanking */
|
/* background color modified during Horizontal Blanking */
|
||||||
if ((v_counter < bitmap.viewport.h) && (count_m68k <= (line_m68k + 84)))
|
if (!(status & 8) && (count_m68k <= (line_m68k + 84)))
|
||||||
{
|
{
|
||||||
/* remap current line (see Road Rash I,II,III) */
|
/* remap current line (see Road Rash I,II,III) */
|
||||||
reg[7] = d;
|
reg[7] = d;
|
||||||
|
@ -38,7 +38,7 @@ extern uint16 status;
|
|||||||
extern uint8 dmafill;
|
extern uint8 dmafill;
|
||||||
extern uint8 hint_pending;
|
extern uint8 hint_pending;
|
||||||
extern uint8 vint_pending;
|
extern uint8 vint_pending;
|
||||||
extern uint16 irq_status;
|
extern uint8 irq_status;
|
||||||
|
|
||||||
/* Global variables */
|
/* Global variables */
|
||||||
extern uint16 ntab;
|
extern uint16 ntab;
|
||||||
|
Loading…
Reference in New Issue
Block a user