Merge git://github.com/ekeeke/Genesis-Plus-GX

This commit is contained in:
twinaphex 2013-04-24 02:59:58 +02:00
commit 68b69717a2
11 changed files with 218 additions and 140 deletions

View File

@ -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)
{

View File

@ -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)
{

View File

@ -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
{

View File

@ -67,6 +67,7 @@ void gen_init(void)
{
/* initialize main 68k */
m68k_init();
m68k.aerr_enabled = config.addr_error;
/* initialize main 68k memory map */

View File

@ -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,21 +679,9 @@ 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;
}
}
}
/* Save auto-detected system hardware */
romtype = system_hw;

View File

@ -39,9 +39,9 @@
/* ================================ INCLUDES ============================== */
/* ======================================================================== */
#include <setjmp.h>
#include "macros.h"
/* ======================================================================== */
/* ==================== ARCHITECTURE-DEPENDANT DEFINES ==================== */
/* ======================================================================== */
@ -250,11 +250,10 @@ typedef struct
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 */

View File

@ -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) */

View File

@ -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) */

View File

@ -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;
}

View File

@ -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;

View File

@ -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 */