mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-09-10 16:53:15 +02:00
Merge git://github.com/ekeeke/Genesis-Plus-GX
This commit is contained in:
commit
68b69717a2
@ -520,11 +520,6 @@ void md_cart_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
#if M68K_EMULATE_ADDRESS_ERROR
|
||||
/* default behavior */
|
||||
m68k.aerr_enabled = config.addr_error;
|
||||
#endif
|
||||
|
||||
/* detect specific mappers */
|
||||
if (strstr(rominfo.domestic,"SUPER STREET FIGHTER2") != NULL)
|
||||
{
|
||||
|
@ -90,6 +90,26 @@ static const uint32 toc_shadow[15] =
|
||||
11637, 2547, 2521, 3856, 900
|
||||
};
|
||||
|
||||
static const uint32 toc_dungeon[13] =
|
||||
{
|
||||
2250, 22950, 16350, 24900, 13875, 19950, 13800, 15375, 17400, 17100,
|
||||
3325, 6825, 25275
|
||||
};
|
||||
|
||||
static const uint32 toc_ffight[26] =
|
||||
{
|
||||
11994, 9742, 10136, 9685, 9553, 14588, 9430, 8721, 9975, 9764,
|
||||
9704, 12796, 585, 754, 951, 624, 9047, 1068, 817, 9191, 1024,
|
||||
14562, 10320, 8627, 3795, 3047
|
||||
};
|
||||
|
||||
static const uint32 toc_ffightj[29] =
|
||||
{
|
||||
11994, 9752, 10119, 9690, 9567, 14575, 9431, 8731, 9965, 9763,
|
||||
9716, 12791, 579, 751, 958, 630, 9050, 1052, 825, 9193, 1026,
|
||||
14553, 9834, 10542, 1699, 1792, 1781, 3783, 3052
|
||||
};
|
||||
|
||||
/* supported WAVE file header (16-bit stereo samples @44.1kHz) */
|
||||
static const unsigned char waveHeader[32] =
|
||||
{
|
||||
@ -641,6 +661,45 @@ int cdd_load(char *filename, char *header)
|
||||
}
|
||||
while (cdd.toc.last < 15);
|
||||
}
|
||||
else if (strstr(header + 0x180,"T-143025") != NULL)
|
||||
{
|
||||
/* Dungeon Explorer */
|
||||
cdd.toc.last = cdd.toc.end = 0;
|
||||
do
|
||||
{
|
||||
cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
|
||||
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_dungeon[cdd.toc.last];
|
||||
cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
|
||||
cdd.toc.last++;
|
||||
}
|
||||
while (cdd.toc.last < 13);
|
||||
}
|
||||
else if (strstr(header + 0x180,"MK-4410") != NULL)
|
||||
{
|
||||
/* Final Fight CD (USA, Europe) */
|
||||
cdd.toc.last = cdd.toc.end = 0;
|
||||
do
|
||||
{
|
||||
cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
|
||||
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_ffight[cdd.toc.last];
|
||||
cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
|
||||
cdd.toc.last++;
|
||||
}
|
||||
while (cdd.toc.last < 26);
|
||||
}
|
||||
else if (strstr(header + 0x180,"G-6013") != NULL)
|
||||
{
|
||||
/* Final Fight CD (Japan) */
|
||||
cdd.toc.last = cdd.toc.end = 0;
|
||||
do
|
||||
{
|
||||
cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
|
||||
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_ffightj[cdd.toc.last];
|
||||
cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
|
||||
cdd.toc.last++;
|
||||
}
|
||||
while (cdd.toc.last < 29);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* default TOC (99 tracks & 2s per audio tracks) */
|
||||
@ -1081,11 +1140,24 @@ void cdd_process(void)
|
||||
if (!cdd.latency)
|
||||
{
|
||||
/* Fixes a few games hanging during intro because they expect data to be read with some delay */
|
||||
/* Wolf Team games (Anet Futatabi, Cobra Command, Road Avenger & Time Gal) need at least 6 interrupts delay */
|
||||
/* Radical Rex needs at least one interrupt delay */
|
||||
/* Jeopardy needs at least 9 interrupts delay */
|
||||
/* Space Adventure Cobra (2nd morgue scene) needs at least 13 interrupts delay */
|
||||
cdd.latency = 13;
|
||||
/* Wolf Team games (Anet Futatabi, Cobra Command, Road Avenger & Time Gal) need at least 6 interrupts delay */
|
||||
/* Space Adventure Cobra (2nd morgue scene) needs at least 13 interrupts delay (incl. seek time, so 6 here is OK) */
|
||||
/* Jeopardy & ESPN Sunday Night NFL are picky about this as well: 7 interrupts delay (+ seek time) seems OK */
|
||||
cdd.latency = 7;
|
||||
}
|
||||
|
||||
/* CD drive seek time */
|
||||
/* Some delay is especially needed when playing audio tracks located at the end of the disc (ex: Sonic CD intro) */
|
||||
/* max. seek time = 1.5s = 1.5 x 75 = 112.5 CDD interrupts (rounded to 120) for 270000 sectors max on disc */
|
||||
/* Note: this is only a rough approximation, on real hardware, drive seek time is much likely not linear */
|
||||
if (lba < cdd.lba)
|
||||
{
|
||||
cdd.latency += (((cdd.lba - lba) * 120) / 270000);
|
||||
}
|
||||
else
|
||||
{
|
||||
cdd.latency += (((lba - cdd.lba) * 120) / 270000);
|
||||
}
|
||||
|
||||
/* update current track index */
|
||||
@ -1110,19 +1182,6 @@ void cdd_process(void)
|
||||
}
|
||||
else if (cdd.toc.tracks[index].fd)
|
||||
{
|
||||
/* CD drive seek time */
|
||||
/* Some delay is also needed when playing AUDIO tracks located at the end of the disc (ex: Sonic CD intro) */
|
||||
/* max. seek time = 1.5s = 1.5 x 75 = 112.5 CDD interrupts (rounded to 120) for 270000 sectors max on disc */
|
||||
/* Note: this is only a rough approximation, on real hardware, drive seek time is much likely not linear */
|
||||
if (lba < cdd.lba)
|
||||
{
|
||||
cdd.latency += (((cdd.lba - lba) * 120) / 270000);
|
||||
}
|
||||
else
|
||||
{
|
||||
cdd.latency += (((lba - cdd.lba) * 120) / 270000);
|
||||
}
|
||||
|
||||
/* seek AUDIO track */
|
||||
if (lba < cdd.toc.tracks[index].start)
|
||||
{
|
||||
|
@ -212,7 +212,7 @@ static void s68k_poll_detect(reg)
|
||||
}
|
||||
|
||||
/* restart SUB-CPU polling detection */
|
||||
s68k.poll.cycle = s68k.cycles + 320;
|
||||
s68k.poll.cycle = s68k.cycles + 392;
|
||||
s68k.poll.pc = s68k.pc;
|
||||
}
|
||||
|
||||
@ -412,7 +412,7 @@ static unsigned int scd_read_word(unsigned int address)
|
||||
/* relative MAIN-CPU cycle counter */
|
||||
unsigned int cycles = (s68k.cycles * MCYCLES_PER_LINE) / SCYCLES_PER_LINE;
|
||||
|
||||
/* sync MAIN-CPU with SUB-CPU */
|
||||
/* sync MAIN-CPU with SUB-CPU (Mighty Morphin Power Rangers) */
|
||||
if (!m68k.stopped && (m68k.cycles < cycles))
|
||||
{
|
||||
m68k_run(cycles);
|
||||
@ -1062,7 +1062,7 @@ void scd_init(void)
|
||||
{
|
||||
if (i & 2)
|
||||
{
|
||||
/* PRG-RAM (first 128KB bank, mirrored) */
|
||||
/* $020000-$03FFFF (resp. $420000-$43FFFF): PRG-RAM (first 128KB bank, mirrored each 256KB) */
|
||||
m68k.memory_map[i].base = scd.prg_ram + ((i & 1) << 16);
|
||||
m68k.memory_map[i].read8 = NULL;
|
||||
m68k.memory_map[i].read16 = NULL;
|
||||
@ -1074,7 +1074,8 @@ void scd_init(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* internal ROM (128KB mirrored) (Flux expects it to be mapped at $440000-$45FFFF) */
|
||||
/* $000000-$01FFFF (resp. $400000-$41FFFF): internal ROM (128KB, mirrored each 256KB) */
|
||||
/* NB: Flux expects it to be mapped at $440000-$45FFFF */
|
||||
m68k.memory_map[i].base = scd.bootrom + ((i & 1) << 16);
|
||||
m68k.memory_map[i].read8 = NULL;
|
||||
m68k.memory_map[i].read16 = NULL;
|
||||
@ -1116,7 +1117,6 @@ void scd_init(void)
|
||||
/* $080000-$0BFFFF: Word-RAM in 2M mode (256KB)*/
|
||||
for (i=0x08; i<0x0c; i++)
|
||||
{
|
||||
/* allow Word-RAM access from both CPU in 2M mode (fixes sync issues in Mortal Kombat) */
|
||||
s68k.memory_map[i].base = scd.word_ram_2M + ((i & 3) << 16);
|
||||
s68k.memory_map[i].read8 = NULL;
|
||||
s68k.memory_map[i].read16 = NULL;
|
||||
@ -1167,6 +1167,8 @@ void scd_reset(int hard)
|
||||
/* TODO: figure what exactly is resetted when RESET bit is cleared by SUB-CPU */
|
||||
if (hard)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Clear all ASIC registers by default */
|
||||
memset(scd.regs, 0, sizeof(scd.regs));
|
||||
|
||||
@ -1183,6 +1185,14 @@ void scd_reset(int hard)
|
||||
|
||||
/* 2M mode */
|
||||
word_ram_switch(0);
|
||||
|
||||
/* reset PRG-RAM banking on MAIN-CPU side */
|
||||
for (i=scd.cartridge.boot+0x02; i<scd.cartridge.boot+0x20; i+=4)
|
||||
{
|
||||
/* MAIN-CPU: $020000-$03FFFF (resp. $420000-$43FFFF) mapped to first 128KB PRG-RAM bank (mirrored each 256KB) */
|
||||
m68k.memory_map[i].base = scd.prg_ram;
|
||||
m68k.memory_map[i+1].base = scd.prg_ram + 0x10000;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -67,6 +67,7 @@ void gen_init(void)
|
||||
{
|
||||
/* initialize main 68k */
|
||||
m68k_init();
|
||||
m68k.aerr_enabled = config.addr_error;
|
||||
|
||||
/* initialize main 68k memory map */
|
||||
|
||||
|
@ -601,7 +601,7 @@ int load_rom(char *filename)
|
||||
/* Mega Drive hardware (Genesis mode) */
|
||||
system_hw = SYSTEM_MD;
|
||||
|
||||
/* Decode .MDX format */
|
||||
/* decode .MDX format */
|
||||
if (!memcmp("MDX", &extension[0], 3))
|
||||
{
|
||||
for (i = 4; i < size - 1; i++)
|
||||
@ -610,6 +610,18 @@ int load_rom(char *filename)
|
||||
}
|
||||
size = size - 5;
|
||||
}
|
||||
|
||||
/* auto-detect byte-swapped dumps */
|
||||
if (!memcmp((char *)(cart.rom + 0x100),"ESAGM GE ARDVI E", 16) ||
|
||||
!memcmp((char *)(cart.rom + 0x100),"ESAGG NESESI", 12))
|
||||
{
|
||||
for(i = 0; i < size; i += 2)
|
||||
{
|
||||
uint8 temp = cart.rom[i];
|
||||
cart.rom[i] = cart.rom[i+1];
|
||||
cart.rom[i+1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* auto-detect 512 byte extra header */
|
||||
@ -656,10 +668,10 @@ int load_rom(char *filename)
|
||||
scd.cartridge.boot = 0x00;
|
||||
}
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
/* 16-bit ROM specific */
|
||||
else if (system_hw == SYSTEM_MD)
|
||||
{
|
||||
#ifdef LSB_FIRST
|
||||
/* Byteswap ROM to optimize 16-bit access */
|
||||
for (i = 0; i < cart.romsize; i += 2)
|
||||
{
|
||||
@ -667,20 +679,8 @@ int load_rom(char *filename)
|
||||
cart.rom[i] = cart.rom[i+1];
|
||||
cart.rom[i+1] = temp;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* byteswapped RADICA dumps (from Haze) */
|
||||
if (((strstr(rominfo.product,"-K0101") != NULL) && (rominfo.checksum == 0xf424)) ||
|
||||
((strstr(rominfo.product,"-K0109") != NULL) && (rominfo.checksum == 0x4f10)))
|
||||
{
|
||||
for(i = 0; i < cart.romsize; i += 2)
|
||||
{
|
||||
uint8 temp = cart.rom[i];
|
||||
cart.rom[i] = cart.rom[i+1];
|
||||
cart.rom[i+1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Save auto-detected system hardware */
|
||||
romtype = system_hw;
|
||||
|
@ -39,9 +39,9 @@
|
||||
/* ================================ INCLUDES ============================== */
|
||||
/* ======================================================================== */
|
||||
|
||||
#include <setjmp.h>
|
||||
#include "macros.h"
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ==================== ARCHITECTURE-DEPENDANT DEFINES ==================== */
|
||||
/* ======================================================================== */
|
||||
@ -231,30 +231,29 @@ typedef struct
|
||||
{
|
||||
cpu_memory_map memory_map[256]; /* memory mapping */
|
||||
|
||||
cpu_idle_t poll; /* polling detection */
|
||||
cpu_idle_t poll; /* polling detection */
|
||||
|
||||
uint cycles; /* current master cycle count */
|
||||
uint cycle_end; /* aimed master cycle count for current execution frame */
|
||||
uint cycles; /* current master cycle count */
|
||||
uint cycle_end; /* aimed master cycle count for current execution frame */
|
||||
|
||||
uint dar[16]; /* Data and Address Registers */
|
||||
uint pc; /* Program Counter */
|
||||
uint sp[5]; /* User and Interrupt Stack Pointers */
|
||||
uint ir; /* Instruction Register */
|
||||
uint t1_flag; /* Trace 1 */
|
||||
uint s_flag; /* Supervisor */
|
||||
uint x_flag; /* Extend */
|
||||
uint n_flag; /* Negative */
|
||||
uint not_z_flag; /* Zero, inverted for speedups */
|
||||
uint v_flag; /* Overflow */
|
||||
uint c_flag; /* Carry */
|
||||
uint int_mask; /* I0-I2 */
|
||||
uint int_level; /* State of interrupt pins IPL0-IPL2 -- ASG: changed from ints_pending */
|
||||
uint stopped; /* Stopped state */
|
||||
|
||||
uint pref_addr; /* Last prefetch address */
|
||||
uint pref_data; /* Data in the prefetch queue */
|
||||
|
||||
uint dar[16]; /* Data and Address Registers */
|
||||
uint pc; /* Program Counter */
|
||||
uint sp[5]; /* User and Interrupt Stack Pointers */
|
||||
uint ir; /* Instruction Register */
|
||||
uint t1_flag; /* Trace 1 */
|
||||
uint s_flag; /* Supervisor */
|
||||
uint x_flag; /* Extend */
|
||||
uint n_flag; /* Negative */
|
||||
uint not_z_flag; /* Zero, inverted for speedups */
|
||||
uint v_flag; /* Overflow */
|
||||
uint c_flag; /* Carry */
|
||||
uint int_mask; /* I0-I2 */
|
||||
uint int_level; /* State of interrupt pins IPL0-IPL2 -- ASG: changed from ints_pending */
|
||||
uint stopped; /* Stopped state */
|
||||
#if M68K_EMULATE_PREFETCH
|
||||
uint pref_addr; /* Last prefetch address */
|
||||
uint pref_data; /* Data in the prefetch queue */
|
||||
#endif
|
||||
#if M68K_EMULATE_ADDRESS_ERROR
|
||||
uint instr_mode; /* Stores whether we are in instruction mode or group 0/1 exception mode */
|
||||
uint run_mode; /* Stores whether we are processing a reset, bus error, address error, or something else */
|
||||
uint aerr_enabled; /* Enables/deisables address error checks at runtime */
|
||||
@ -262,27 +261,16 @@ typedef struct
|
||||
uint aerr_address; /* Address error location */
|
||||
uint aerr_write_mode; /* Address error write mode */
|
||||
uint aerr_fc; /* Address error FC code */
|
||||
#endif
|
||||
#if M68K_EMULATE_TRACE
|
||||
|
||||
uint tracing; /* Tracing enable flag */
|
||||
#endif
|
||||
#if M68K_EMULATE_FC
|
||||
|
||||
uint address_space; /* Current FC code */
|
||||
#endif
|
||||
|
||||
/* Callbacks to host */
|
||||
#if M68K_EMULATE_INT_ACK == OPT_ON
|
||||
int (*int_ack_callback)(int int_line); /* Interrupt Acknowledge */
|
||||
#endif
|
||||
#if M68K_EMULATE_RESET == OPT_ON
|
||||
void (*reset_instr_callback)(void); /* Called when a RESET instruction is encountered */
|
||||
#endif
|
||||
#if M68K_TAS_HAS_CALLBACK == OPT_ON
|
||||
int (*tas_instr_callback)(void); /* Called when a TAS instruction is encountered, allows / disallows writeback */
|
||||
#endif
|
||||
#if M68K_EMULATE_FC == OPT_ON
|
||||
void (*set_fc_callback)(unsigned int new_fc); /* Called when the CPU function code changes */
|
||||
#endif
|
||||
} m68ki_cpu_core;
|
||||
|
||||
/* CPU cores */
|
||||
|
@ -205,9 +205,6 @@ void m68k_update_irq(unsigned int mask)
|
||||
#ifdef LOGVDP
|
||||
error("[%d(%d)][%d(%d)] IRQ Level = %d(0x%02x) (%x)\n", v_counter, m68k.cycles/3420, m68k.cycles, m68k.cycles%3420,CPU_INT_LEVEL>>8,FLAG_INT_MASK,m68k_get_reg(M68K_REG_PC));
|
||||
#endif
|
||||
|
||||
/* Check interrupt mask to process IRQ */
|
||||
m68ki_check_interrupts();
|
||||
}
|
||||
|
||||
void m68k_set_irq(unsigned int int_level)
|
||||
@ -218,9 +215,6 @@ void m68k_set_irq(unsigned int int_level)
|
||||
#ifdef LOGVDP
|
||||
error("[%d(%d)][%d(%d)] IRQ Level = %d(0x%02x) (%x)\n", v_counter, m68k.cycles/3420, m68k.cycles, m68k.cycles%3420,CPU_INT_LEVEL>>8,FLAG_INT_MASK,m68k_get_reg(M68K_REG_PC));
|
||||
#endif
|
||||
|
||||
/* Check interrupt mask to process IRQ */
|
||||
m68ki_check_interrupts();
|
||||
}
|
||||
|
||||
/* IRQ latency (Fatal Rewind, Sesame's Street Counting Cafe)*/
|
||||
@ -261,6 +255,15 @@ void m68k_set_irq_delay(unsigned int int_level)
|
||||
|
||||
void m68k_run(unsigned int cycles)
|
||||
{
|
||||
/* Make sure CPU is not already ahead */
|
||||
if (m68k.cycles >= cycles)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check interrupt mask to process IRQ if needed */
|
||||
m68ki_check_interrupts();
|
||||
|
||||
/* Make sure we're not stopped */
|
||||
if (CPU_STOPPED)
|
||||
{
|
||||
@ -268,12 +271,12 @@ void m68k_run(unsigned int cycles)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Return point for when we have an address error (TODO: use goto) */
|
||||
m68ki_set_address_error_trap() /* auto-disable (see m68kcpu.h) */
|
||||
|
||||
/* Save end cycles count for when CPU is stopped */
|
||||
m68k.cycle_end = cycles;
|
||||
|
||||
/* Return point for when we have an address error (TODO: use goto) */
|
||||
m68ki_set_address_error_trap() /* auto-disable (see m68kcpu.h) */
|
||||
|
||||
#ifdef LOGVDP
|
||||
error("[%d][%d] m68k run to %d cycles (%x)\n", v_counter, m68k.cycles, cycles, m68k.pc);
|
||||
#endif
|
||||
@ -290,8 +293,8 @@ void m68k_run(unsigned int cycles)
|
||||
REG_IR = m68ki_read_imm_16();
|
||||
|
||||
/* Execute instruction */
|
||||
m68ki_instruction_jump_table[REG_IR](); /* TODO: use labels table with goto */
|
||||
USE_CYCLES(CYC_INSTRUCTION[REG_IR]); /* TODO: move into instruction handlers */
|
||||
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) */
|
||||
|
@ -215,13 +215,19 @@ void s68k_update_irq(unsigned int mask)
|
||||
#ifdef LOG_SCD
|
||||
error("[%d][%d] IRQ Level = %d(0x%02x) (%x)\n", v_counter, s68k.cycles, CPU_INT_LEVEL>>8,FLAG_INT_MASK,s68k.pc);
|
||||
#endif
|
||||
|
||||
/* Check interrupt mask to process IRQ */
|
||||
m68ki_check_interrupts();
|
||||
}
|
||||
|
||||
void s68k_run(unsigned int cycles)
|
||||
{
|
||||
/* Make sure CPU is not already ahead */
|
||||
if (s68k.cycles >= cycles)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check interrupt mask to process IRQ if needed */
|
||||
m68ki_check_interrupts();
|
||||
|
||||
/* Make sure we're not stopped */
|
||||
if (CPU_STOPPED)
|
||||
{
|
||||
@ -229,11 +235,12 @@ void s68k_run(unsigned int cycles)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save end cycles count for when CPU is stopped */
|
||||
s68k.cycle_end = cycles;
|
||||
|
||||
/* Return point for when we have an address error (TODO: use goto) */
|
||||
m68ki_set_address_error_trap() /* auto-disable (see m68kcpu.h) */
|
||||
|
||||
/* Save end cycles count for when CPU is stopped */
|
||||
s68k.cycle_end = cycles;
|
||||
#ifdef LOG_SCD
|
||||
error("[%d][%d] s68k run to %d cycles (%x), irq mask = %x (%x)\n", v_counter, s68k.cycles, cycles, s68k.pc,FLAG_INT_MASK, CPU_INT_LEVEL);
|
||||
#endif
|
||||
@ -249,10 +256,9 @@ void s68k_run(unsigned int cycles)
|
||||
/* Decode next instruction */
|
||||
REG_IR = m68ki_read_imm_16();
|
||||
|
||||
|
||||
/* Execute instruction */
|
||||
m68ki_instruction_jump_table[REG_IR](); /* TODO: use labels table with goto */
|
||||
USE_CYCLES(CYC_INSTRUCTION[REG_IR]); /* TODO: move into instruction handlers */
|
||||
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) */
|
||||
|
@ -48,7 +48,7 @@ unsigned int m68k_read_bus_8(unsigned int address)
|
||||
#ifdef LOGERROR
|
||||
error("Unused read8 %08X (%08X)\n", address, m68k_get_reg(M68K_REG_PC));
|
||||
#endif
|
||||
address = m68k.pc | (address & 1);
|
||||
address = m68k.pc | (address & 1);
|
||||
return READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff);
|
||||
}
|
||||
|
||||
@ -238,6 +238,13 @@ static void m68k_poll_detect(reg)
|
||||
#endif
|
||||
m68k.cycles = m68k.cycle_end;
|
||||
m68k.stopped = 1 << reg;
|
||||
|
||||
/* return to current instruction */
|
||||
do
|
||||
{
|
||||
m68k.pc -= 2;
|
||||
}
|
||||
while (m68k.ir != *(uint16 *)(m68k.memory_map[(m68k.pc>>16)&0xff].base + (m68k.pc & 0xffff)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -249,7 +256,7 @@ static void m68k_poll_detect(reg)
|
||||
}
|
||||
|
||||
/* restart MAIN-CPU polling detection */
|
||||
m68k.poll.cycle = m68k.cycles + 280;
|
||||
m68k.poll.cycle = m68k.cycles + 840;
|
||||
m68k.poll.pc = m68k.pc;
|
||||
}
|
||||
|
||||
@ -335,6 +342,15 @@ unsigned int ctrl_io_read_byte(unsigned int address)
|
||||
/* SUB-CPU communication flags */
|
||||
if (index == 0x0f)
|
||||
{
|
||||
/* relative SUB-CPU cycle counter */
|
||||
unsigned int cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE;
|
||||
|
||||
/* sync SUB-CPU with MAIN-CPU (Dracula Unleashed w/ Sega CD Model 2 OS ROM) */
|
||||
if (!s68k.stopped && (s68k.cycles < cycles))
|
||||
{
|
||||
s68k_run(cycles);
|
||||
}
|
||||
|
||||
m68k_poll_detect(0x0f);
|
||||
return scd.regs[0x0f>>1].byte.l;
|
||||
}
|
||||
|
@ -2976,7 +2976,7 @@ static void vdp_dma_68k_io(unsigned int length)
|
||||
static void vdp_dma_copy(unsigned int length)
|
||||
{
|
||||
/* VRAM read/write operation only */
|
||||
if ((code & 0x1F) == 0x10)
|
||||
if ((code & 0x1E) == 0x10)
|
||||
{
|
||||
int name;
|
||||
uint8 data;
|
||||
|
@ -1521,11 +1521,11 @@ void render_bg_m5(int line, int width)
|
||||
#ifdef LSB_FIRST
|
||||
uint32 shift = (xscroll >> 16) & 0x0F;
|
||||
uint32 index = pf_col_mask + 1 - ((xscroll >> 20) & pf_col_mask);
|
||||
uint32 v_line = (line + ((yscroll >> 16) & 0x3FF)) & pf_row_mask;
|
||||
uint32 v_line = (line + (yscroll >> 16)) & pf_row_mask;
|
||||
#else
|
||||
uint32 shift = (xscroll & 0x0F);
|
||||
uint32 index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask);
|
||||
uint32 v_line = (line + (yscroll & 0x3FF)) & pf_row_mask;
|
||||
uint32 v_line = (line + yscroll) & pf_row_mask;
|
||||
#endif
|
||||
|
||||
/* Plane B name table */
|
||||
@ -1578,11 +1578,11 @@ void render_bg_m5(int line, int width)
|
||||
#ifdef LSB_FIRST
|
||||
shift = (xscroll & 0x0F);
|
||||
index = pf_col_mask + start + 1 - ((xscroll >> 4) & pf_col_mask);
|
||||
v_line = (line + (yscroll & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + yscroll) & pf_row_mask;
|
||||
#else
|
||||
shift = (xscroll >> 16) & 0x0F;
|
||||
index = pf_col_mask + start + 1 - ((xscroll >> 20) & pf_col_mask);
|
||||
v_line = (line + ((yscroll >> 16) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (yscroll >> 16)) & pf_row_mask;
|
||||
#endif
|
||||
|
||||
/* Plane A name table */
|
||||
@ -1683,7 +1683,6 @@ void render_bg_m5_vs(int line, int width)
|
||||
if (reg[12] & 1)
|
||||
{
|
||||
yscroll = vs[19] & (vs[19] >> 16);
|
||||
yscroll &= 0x3FF;
|
||||
}
|
||||
|
||||
if(shift)
|
||||
@ -1713,9 +1712,9 @@ void render_bg_m5_vs(int line, int width)
|
||||
{
|
||||
/* Plane B vertical scroll */
|
||||
#ifdef LSB_FIRST
|
||||
v_line = (line + ((vs[column] >> 16) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (vs[column] >> 16)) & pf_row_mask;
|
||||
#else
|
||||
v_line = (line + (vs[column] & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + vs[column]) & pf_row_mask;
|
||||
#endif
|
||||
|
||||
/* Plane B name table */
|
||||
@ -1793,9 +1792,9 @@ void render_bg_m5_vs(int line, int width)
|
||||
{
|
||||
/* Plane A vertical scroll */
|
||||
#ifdef LSB_FIRST
|
||||
v_line = (line + (vs[column] & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + vs[column]) & pf_row_mask;
|
||||
#else
|
||||
v_line = (line + ((vs[column] >> 16) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (vs[column] >> 16)) & pf_row_mask;
|
||||
#endif
|
||||
|
||||
/* Plane A name table */
|
||||
@ -1858,11 +1857,11 @@ void render_bg_m5_im2(int line, int width)
|
||||
#ifdef LSB_FIRST
|
||||
uint32 shift = (xscroll >> 16) & 0x0F;
|
||||
uint32 index = pf_col_mask + 1 - ((xscroll >> 20) & pf_col_mask);
|
||||
uint32 v_line = (line + ((yscroll >> 17) & 0x3FF)) & pf_row_mask;
|
||||
uint32 v_line = (line + (yscroll >> 17)) & pf_row_mask;
|
||||
#else
|
||||
uint32 shift = (xscroll & 0x0F);
|
||||
uint32 index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask);
|
||||
uint32 v_line = (line + ((yscroll >> 1) & 0x3FF)) & pf_row_mask;
|
||||
uint32 v_line = (line + (yscroll >> 1)) & pf_row_mask;
|
||||
#endif
|
||||
|
||||
/* Plane B name table */
|
||||
@ -1915,11 +1914,11 @@ void render_bg_m5_im2(int line, int width)
|
||||
#ifdef LSB_FIRST
|
||||
shift = (xscroll & 0x0F);
|
||||
index = pf_col_mask + start + 1 - ((xscroll >> 4) & pf_col_mask);
|
||||
v_line = (line + ((yscroll >> 1) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (yscroll >> 1)) & pf_row_mask;
|
||||
#else
|
||||
shift = (xscroll >> 16) & 0x0F;
|
||||
index = pf_col_mask + start + 1 - ((xscroll >> 20) & pf_col_mask);
|
||||
v_line = (line + ((yscroll >> 17) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (yscroll >> 17)) & pf_row_mask;
|
||||
#endif
|
||||
|
||||
/* Plane A name table */
|
||||
@ -2021,7 +2020,6 @@ void render_bg_m5_im2_vs(int line, int width)
|
||||
if (reg[12] & 1)
|
||||
{
|
||||
yscroll = (vs[19] >> 1) & (vs[19] >> 17);
|
||||
yscroll &= 0x3FF;
|
||||
}
|
||||
|
||||
if(shift)
|
||||
@ -2051,9 +2049,9 @@ void render_bg_m5_im2_vs(int line, int width)
|
||||
{
|
||||
/* Plane B vertical scroll */
|
||||
#ifdef LSB_FIRST
|
||||
v_line = (line + ((vs[column] >> 17) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (vs[column] >> 17)) & pf_row_mask;
|
||||
#else
|
||||
v_line = (line + ((vs[column] >> 1) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (vs[column] >> 1)) & pf_row_mask;
|
||||
#endif
|
||||
|
||||
/* Plane B name table */
|
||||
@ -2131,9 +2129,9 @@ void render_bg_m5_im2_vs(int line, int width)
|
||||
{
|
||||
/* Plane A vertical scroll */
|
||||
#ifdef LSB_FIRST
|
||||
v_line = (line + ((vs[column] >> 1) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (vs[column] >> 1)) & pf_row_mask;
|
||||
#else
|
||||
v_line = (line + ((vs[column] >> 17) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (vs[column] >> 17)) & pf_row_mask;
|
||||
#endif
|
||||
|
||||
/* Plane A name table */
|
||||
@ -2178,6 +2176,7 @@ void render_bg_m5(int line, int width)
|
||||
int column, start, end;
|
||||
uint32 atex, atbuf, *src, *dst;
|
||||
uint32 shift, index, v_line, *nt;
|
||||
uint8 *lb;
|
||||
|
||||
/* Scroll Planes common data */
|
||||
uint32 xscroll = *(uint32 *)&vram[hscb + ((line & hscroll_mask) << 2)];
|
||||
@ -2223,11 +2222,11 @@ void render_bg_m5(int line, int width)
|
||||
#ifdef LSB_FIRST
|
||||
shift = (xscroll & 0x0F);
|
||||
index = pf_col_mask + start + 1 - ((xscroll >> 4) & pf_col_mask);
|
||||
v_line = (line + (yscroll & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + yscroll) & pf_row_mask;
|
||||
#else
|
||||
shift = (xscroll >> 16) & 0x0F;
|
||||
index = pf_col_mask + start + 1 - ((xscroll >> 20) & pf_col_mask);
|
||||
v_line = (line + ((yscroll >> 16) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (yscroll >> 16)) & pf_row_mask;
|
||||
#endif
|
||||
|
||||
/* Background line buffer */
|
||||
@ -2297,11 +2296,11 @@ void render_bg_m5(int line, int width)
|
||||
#ifdef LSB_FIRST
|
||||
shift = (xscroll >> 16) & 0x0F;
|
||||
index = pf_col_mask + 1 - ((xscroll >> 20) & pf_col_mask);
|
||||
v_line = (line + ((yscroll >> 16) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (yscroll >> 16)) & pf_row_mask;
|
||||
#else
|
||||
shift = (xscroll & 0x0F);
|
||||
index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask);
|
||||
v_line = (line + (yscroll & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + yscroll) & pf_row_mask;
|
||||
#endif
|
||||
|
||||
/* Plane B name table */
|
||||
@ -2311,7 +2310,7 @@ void render_bg_m5(int line, int width)
|
||||
v_line = (v_line & 7) << 3;
|
||||
|
||||
/* Background line buffer */
|
||||
uint8 *lb = &linebuf[0][0x20];
|
||||
lb = &linebuf[0][0x20];
|
||||
|
||||
if(shift)
|
||||
{
|
||||
@ -2334,6 +2333,7 @@ void render_bg_m5_vs(int line, int width)
|
||||
int column, start, end;
|
||||
uint32 atex, atbuf, *src, *dst;
|
||||
uint32 shift, index, v_line, *nt;
|
||||
uint8 *lb;
|
||||
|
||||
/* Scroll Planes common data */
|
||||
uint32 xscroll = *(uint32 *)&vram[hscb + ((line & hscroll_mask) << 2)];
|
||||
@ -2372,7 +2372,6 @@ void render_bg_m5_vs(int line, int width)
|
||||
if (reg[12] & 1)
|
||||
{
|
||||
yscroll = vs[19] & (vs[19] >> 16);
|
||||
yscroll &= 0x3FF;
|
||||
}
|
||||
|
||||
/* Number of columns to draw */
|
||||
@ -2428,9 +2427,9 @@ void render_bg_m5_vs(int line, int width)
|
||||
{
|
||||
/* Plane A vertical scroll */
|
||||
#ifdef LSB_FIRST
|
||||
v_line = (line + (vs[column] & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + vs[column]) & pf_row_mask;
|
||||
#else
|
||||
v_line = (line + ((vs[column] >> 16) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (vs[column] >> 16)) & pf_row_mask;
|
||||
#endif
|
||||
|
||||
/* Plane A name table */
|
||||
@ -2483,7 +2482,7 @@ void render_bg_m5_vs(int line, int width)
|
||||
#endif
|
||||
|
||||
/* Background line buffer */
|
||||
uint8 *lb = &linebuf[0][0x20];
|
||||
lb = &linebuf[0][0x20];
|
||||
|
||||
if(shift)
|
||||
{
|
||||
@ -2507,9 +2506,9 @@ void render_bg_m5_vs(int line, int width)
|
||||
{
|
||||
/* Plane B vertical scroll */
|
||||
#ifdef LSB_FIRST
|
||||
v_line = (line + ((vs[column] >> 16) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (vs[column] >> 16)) & pf_row_mask;
|
||||
#else
|
||||
v_line = (line + (vs[column] & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + vs[column]) & pf_row_mask;
|
||||
#endif
|
||||
|
||||
/* Plane B name table */
|
||||
@ -2528,6 +2527,7 @@ void render_bg_m5_im2(int line, int width)
|
||||
int column, start, end;
|
||||
uint32 atex, atbuf, *src, *dst;
|
||||
uint32 shift, index, v_line, *nt;
|
||||
uint8 *lb;
|
||||
|
||||
/* Scroll Planes common data */
|
||||
int odd = odd_frame;
|
||||
@ -2574,11 +2574,11 @@ void render_bg_m5_im2(int line, int width)
|
||||
#ifdef LSB_FIRST
|
||||
shift = (xscroll & 0x0F);
|
||||
index = pf_col_mask + start + 1 - ((xscroll >> 4) & pf_col_mask);
|
||||
v_line = (line + ((yscroll >> 1) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (yscroll >> 1)) & pf_row_mask;
|
||||
#else
|
||||
shift = (xscroll >> 16) & 0x0F;
|
||||
index = pf_col_mask + start + 1 - ((xscroll >> 20) & pf_col_mask);
|
||||
v_line = (line + ((yscroll >> 17) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (yscroll >> 17)) & pf_row_mask;
|
||||
#endif
|
||||
|
||||
/* Background line buffer */
|
||||
@ -2648,11 +2648,11 @@ void render_bg_m5_im2(int line, int width)
|
||||
#ifdef LSB_FIRST
|
||||
shift = (xscroll >> 16) & 0x0F;
|
||||
index = pf_col_mask + 1 - ((xscroll >> 20) & pf_col_mask);
|
||||
v_line = (line + ((yscroll >> 17) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (yscroll >> 17)) & pf_row_mask;
|
||||
#else
|
||||
shift = (xscroll & 0x0F);
|
||||
index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask);
|
||||
v_line = (line + ((yscroll >> 1) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (yscroll >> 1)) & pf_row_mask;
|
||||
#endif
|
||||
|
||||
/* Plane B name table */
|
||||
@ -2662,7 +2662,7 @@ void render_bg_m5_im2(int line, int width)
|
||||
v_line = (((v_line & 7) << 1) | odd) << 3;
|
||||
|
||||
/* Background line buffer */
|
||||
uint8 *lb = &linebuf[0][0x20];
|
||||
lb = &linebuf[0][0x20];
|
||||
|
||||
if(shift)
|
||||
{
|
||||
@ -2685,6 +2685,7 @@ void render_bg_m5_im2_vs(int line, int width)
|
||||
int column, start, end;
|
||||
uint32 atex, atbuf, *src, *dst;
|
||||
uint32 shift, index, v_line, *nt;
|
||||
uint8 *lb;
|
||||
|
||||
/* common data */
|
||||
int odd = odd_frame;
|
||||
@ -2725,7 +2726,6 @@ void render_bg_m5_im2_vs(int line, int width)
|
||||
{
|
||||
/* only in 40-cell mode, verified on MD2 */
|
||||
yscroll = (vs[19] >> 1) & (vs[19] >> 17);
|
||||
yscroll &= 0x3FF;
|
||||
}
|
||||
|
||||
/* Number of columns to draw */
|
||||
@ -2781,9 +2781,9 @@ void render_bg_m5_im2_vs(int line, int width)
|
||||
{
|
||||
/* Plane A vertical scroll */
|
||||
#ifdef LSB_FIRST
|
||||
v_line = (line + ((vs[column] >> 1) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (vs[column] >> 1)) & pf_row_mask;
|
||||
#else
|
||||
v_line = (line + ((vs[column] >> 17) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (vs[column] >> 17)) & pf_row_mask;
|
||||
#endif
|
||||
|
||||
/* Plane A name table */
|
||||
@ -2836,7 +2836,7 @@ void render_bg_m5_im2_vs(int line, int width)
|
||||
#endif
|
||||
|
||||
/* Background line buffer */
|
||||
uint8 *lb = &linebuf[0][0x20];
|
||||
lb = &linebuf[0][0x20];
|
||||
|
||||
if(shift)
|
||||
{
|
||||
@ -2860,9 +2860,9 @@ void render_bg_m5_im2_vs(int line, int width)
|
||||
{
|
||||
/* Plane B vertical scroll */
|
||||
#ifdef LSB_FIRST
|
||||
v_line = (line + ((vs[column] >> 17) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (vs[column] >> 17)) & pf_row_mask;
|
||||
#else
|
||||
v_line = (line + ((vs[column] >> 1) & 0x3FF)) & pf_row_mask;
|
||||
v_line = (line + (vs[column] >> 1)) & pf_row_mask;
|
||||
#endif
|
||||
|
||||
/* Plane B name table */
|
||||
|
Loading…
Reference in New Issue
Block a user