mirror of
https://github.com/holub/mame
synced 2025-07-05 18:08:04 +03:00
snes.c: greatly simplified tile drawing routines, fixed a couple of small bugs in mosaic support, reworked debug functions to be detected properly in all games [Fabio Priuli]
This commit is contained in:
parent
211b0da94e
commit
2d3f8cd3b5
@ -410,17 +410,17 @@ static INPUT_PORTS_START( snes )
|
|||||||
PORT_CONFSETTING( 0x80, "BG4A (higher) only" )
|
PORT_CONFSETTING( 0x80, "BG4A (higher) only" )
|
||||||
|
|
||||||
PORT_START("DEBUG2")
|
PORT_START("DEBUG2")
|
||||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 1") PORT_CODE(KEYCODE_1_PAD)
|
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 1") PORT_CODE(KEYCODE_1_PAD) PORT_TOGGLE
|
||||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 2") PORT_CODE(KEYCODE_2_PAD)
|
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 2") PORT_CODE(KEYCODE_2_PAD) PORT_TOGGLE
|
||||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 3") PORT_CODE(KEYCODE_3_PAD)
|
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 3") PORT_CODE(KEYCODE_3_PAD) PORT_TOGGLE
|
||||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 4") PORT_CODE(KEYCODE_4_PAD)
|
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 4") PORT_CODE(KEYCODE_4_PAD) PORT_TOGGLE
|
||||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Objects") PORT_CODE(KEYCODE_5_PAD)
|
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Objects") PORT_CODE(KEYCODE_5_PAD) PORT_TOGGLE
|
||||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Main/Sub") PORT_CODE(KEYCODE_6_PAD)
|
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Main/Sub") PORT_CODE(KEYCODE_6_PAD) PORT_TOGGLE
|
||||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Color Math") PORT_CODE(KEYCODE_7_PAD)
|
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Color Math") PORT_CODE(KEYCODE_7_PAD) PORT_TOGGLE
|
||||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Windows") PORT_CODE(KEYCODE_8_PAD)
|
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Windows") PORT_CODE(KEYCODE_8_PAD) PORT_TOGGLE
|
||||||
|
|
||||||
PORT_START("DEBUG3")
|
PORT_START("DEBUG3")
|
||||||
PORT_BIT( 0x4, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mosaic") PORT_CODE(KEYCODE_9_PAD)
|
PORT_BIT( 0x4, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mosaic") PORT_CODE(KEYCODE_9_PAD) PORT_TOGGLE
|
||||||
PORT_CONFNAME( 0x70, 0x00, "Select OAM priority" )
|
PORT_CONFNAME( 0x70, 0x00, "Select OAM priority" )
|
||||||
PORT_CONFSETTING( 0x00, "All" )
|
PORT_CONFSETTING( 0x00, "All" )
|
||||||
PORT_CONFSETTING( 0x10, "OAM0 only" )
|
PORT_CONFSETTING( 0x10, "OAM0 only" )
|
||||||
@ -432,14 +432,14 @@ static INPUT_PORTS_START( snes )
|
|||||||
PORT_CONFSETTING( 0x80, DEF_STR( On ) )
|
PORT_CONFSETTING( 0x80, DEF_STR( On ) )
|
||||||
|
|
||||||
PORT_START("DEBUG4")
|
PORT_START("DEBUG4")
|
||||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 0 draw")
|
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 0 draw") PORT_TOGGLE
|
||||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 1 draw")
|
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 1 draw") PORT_TOGGLE
|
||||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 2 draw")
|
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 2 draw") PORT_TOGGLE
|
||||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 3 draw")
|
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 3 draw") PORT_TOGGLE
|
||||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 4 draw")
|
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 4 draw") PORT_TOGGLE
|
||||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 5 draw")
|
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 5 draw") PORT_TOGGLE
|
||||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 6 draw")
|
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 6 draw") PORT_TOGGLE
|
||||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 7 draw")
|
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 7 draw") PORT_TOGGLE
|
||||||
#endif
|
#endif
|
||||||
INPUT_PORTS_END
|
INPUT_PORTS_END
|
||||||
|
|
||||||
|
@ -351,17 +351,17 @@ static INPUT_PORTS_START( snes_common )
|
|||||||
PORT_CONFSETTING( 0x80, "BG4A (higher) only" )
|
PORT_CONFSETTING( 0x80, "BG4A (higher) only" )
|
||||||
|
|
||||||
PORT_START("DEBUG2")
|
PORT_START("DEBUG2")
|
||||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 1") PORT_CODE(KEYCODE_1_PAD)
|
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 1") PORT_CODE(KEYCODE_1_PAD) PORT_TOGGLE
|
||||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 2") PORT_CODE(KEYCODE_2_PAD)
|
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 2") PORT_CODE(KEYCODE_2_PAD) PORT_TOGGLE
|
||||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 3") PORT_CODE(KEYCODE_3_PAD)
|
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 3") PORT_CODE(KEYCODE_3_PAD) PORT_TOGGLE
|
||||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 4") PORT_CODE(KEYCODE_4_PAD)
|
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle BG 4") PORT_CODE(KEYCODE_4_PAD) PORT_TOGGLE
|
||||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Objects") PORT_CODE(KEYCODE_5_PAD)
|
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Objects") PORT_CODE(KEYCODE_5_PAD) PORT_TOGGLE
|
||||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Main/Sub") PORT_CODE(KEYCODE_6_PAD)
|
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Main/Sub") PORT_CODE(KEYCODE_6_PAD) PORT_TOGGLE
|
||||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Color Math") PORT_CODE(KEYCODE_7_PAD)
|
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Color Math") PORT_CODE(KEYCODE_7_PAD) PORT_TOGGLE
|
||||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Windows") PORT_CODE(KEYCODE_8_PAD)
|
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Windows") PORT_CODE(KEYCODE_8_PAD) PORT_TOGGLE
|
||||||
|
|
||||||
PORT_START("DEBUG3")
|
PORT_START("DEBUG3")
|
||||||
PORT_BIT( 0x4, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mosaic") PORT_CODE(KEYCODE_9_PAD)
|
PORT_BIT( 0x4, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mosaic") PORT_CODE(KEYCODE_9_PAD) PORT_TOGGLE
|
||||||
PORT_CONFNAME( 0x70, 0x00, "Select OAM priority" )
|
PORT_CONFNAME( 0x70, 0x00, "Select OAM priority" )
|
||||||
PORT_CONFSETTING( 0x00, "All" )
|
PORT_CONFSETTING( 0x00, "All" )
|
||||||
PORT_CONFSETTING( 0x10, "OAM0 only" )
|
PORT_CONFSETTING( 0x10, "OAM0 only" )
|
||||||
@ -373,14 +373,14 @@ static INPUT_PORTS_START( snes_common )
|
|||||||
PORT_CONFSETTING( 0x80, DEF_STR( On ) )
|
PORT_CONFSETTING( 0x80, DEF_STR( On ) )
|
||||||
|
|
||||||
PORT_START("DEBUG4")
|
PORT_START("DEBUG4")
|
||||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 0 draw")
|
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 0 draw") PORT_TOGGLE
|
||||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 1 draw")
|
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 1 draw") PORT_TOGGLE
|
||||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 2 draw")
|
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 2 draw") PORT_TOGGLE
|
||||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 3 draw")
|
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 3 draw") PORT_TOGGLE
|
||||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 4 draw")
|
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 4 draw") PORT_TOGGLE
|
||||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 5 draw")
|
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 5 draw") PORT_TOGGLE
|
||||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 6 draw")
|
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 6 draw") PORT_TOGGLE
|
||||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 7 draw")
|
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 7 draw") PORT_TOGGLE
|
||||||
#endif
|
#endif
|
||||||
INPUT_PORTS_END
|
INPUT_PORTS_END
|
||||||
|
|
||||||
|
@ -301,11 +301,11 @@ static void snes_dynamic_res_change( running_machine *machine )
|
|||||||
attoseconds_t refresh;
|
attoseconds_t refresh;
|
||||||
|
|
||||||
visarea.min_x = visarea.min_y = 0;
|
visarea.min_x = visarea.min_y = 0;
|
||||||
visarea.max_y = snes_ppu.beam.last_visible_line * snes_ppu.interlace - 1;
|
visarea.max_y = snes_ppu.beam.last_visible_line*snes_ppu.interlace - 1;
|
||||||
visarea.max_x = (SNES_SCR_WIDTH * 2) - 1;
|
visarea.max_x = (SNES_SCR_WIDTH * 2) - 1;
|
||||||
|
|
||||||
// fixme: should compensate for SNES_DBG_video
|
// fixme: should compensate for SNES_DBG_video
|
||||||
if (snes_ppu.mode == 5 || snes_ppu.mode == 6 || snes_ppu.pseudo_hires)
|
if (snes_ppu.mode == 5 || snes_ppu.mode == 6 )
|
||||||
state->htmult = 2;
|
state->htmult = 2;
|
||||||
else
|
else
|
||||||
state->htmult = 1;
|
state->htmult = 1;
|
||||||
@ -317,9 +317,9 @@ static void snes_dynamic_res_change( running_machine *machine )
|
|||||||
refresh = HZ_TO_ATTOSECONDS(DOTCLK_PAL) * SNES_HTOTAL * SNES_VTOTAL_PAL;
|
refresh = HZ_TO_ATTOSECONDS(DOTCLK_PAL) * SNES_HTOTAL * SNES_VTOTAL_PAL;
|
||||||
|
|
||||||
if ((snes_ram[STAT78] & 0x10) == SNES_NTSC)
|
if ((snes_ram[STAT78] & 0x10) == SNES_NTSC)
|
||||||
video_screen_configure(machine->primary_screen, SNES_HTOTAL * 2, SNES_VTOTAL_NTSC * snes_ppu.interlace, &visarea, refresh);
|
video_screen_configure(machine->primary_screen, SNES_HTOTAL*2, SNES_VTOTAL_NTSC*snes_ppu.interlace, &visarea, refresh);
|
||||||
else
|
else
|
||||||
video_screen_configure(machine->primary_screen, SNES_HTOTAL * 2, SNES_VTOTAL_PAL * snes_ppu.interlace, &visarea, refresh);
|
video_screen_configure(machine->primary_screen, SNES_HTOTAL*2, SNES_VTOTAL_PAL*snes_ppu.interlace, &visarea, refresh);
|
||||||
}
|
}
|
||||||
|
|
||||||
static READ8_HANDLER( snes_open_bus_r )
|
static READ8_HANDLER( snes_open_bus_r )
|
||||||
@ -411,37 +411,30 @@ READ8_HANDLER( snes_r_io )
|
|||||||
case WBGLOG:
|
case WBGLOG:
|
||||||
return snes_ppu.ppu1_open_bus;
|
return snes_ppu.ppu1_open_bus;
|
||||||
|
|
||||||
// According to BSNES, these should return snes_open_bus_r!
|
|
||||||
// case OAMADDL:
|
|
||||||
// case OAMADDH:
|
|
||||||
// case VMADDH:
|
|
||||||
// case CGADD:
|
|
||||||
// case CGDATA:
|
|
||||||
// return snes_ram[offset];
|
|
||||||
case MPYL: /* Multiplication result (low) */
|
case MPYL: /* Multiplication result (low) */
|
||||||
{
|
{
|
||||||
/* Perform 16bit * 8bit multiply */
|
/* Perform 16bit * 8bit multiply */
|
||||||
UINT32 c = snes_ppu.mode7.matrix_a * (INT8)(snes_ppu.mode7.matrix_b >> 8);
|
UINT32 c = (INT16)snes_ppu.mode7.matrix_a * (INT8)(snes_ppu.mode7.matrix_b >> 8);
|
||||||
snes_ppu.ppu1_open_bus = c & 0xff;
|
snes_ppu.ppu1_open_bus = c & 0xff;
|
||||||
return snes_ppu.ppu1_open_bus;
|
return snes_ppu.ppu1_open_bus;
|
||||||
}
|
}
|
||||||
case MPYM: /* Multiplication result (mid) */
|
case MPYM: /* Multiplication result (mid) */
|
||||||
{
|
{
|
||||||
/* Perform 16bit * 8bit multiply */
|
/* Perform 16bit * 8bit multiply */
|
||||||
UINT32 c = snes_ppu.mode7.matrix_a * (INT8)(snes_ppu.mode7.matrix_b >> 8);
|
UINT32 c = (INT16)snes_ppu.mode7.matrix_a * (INT8)(snes_ppu.mode7.matrix_b >> 8);
|
||||||
snes_ppu.ppu1_open_bus = (c >> 8) & 0xff;
|
snes_ppu.ppu1_open_bus = (c >> 8) & 0xff;
|
||||||
return snes_ppu.ppu1_open_bus;
|
return snes_ppu.ppu1_open_bus;
|
||||||
}
|
}
|
||||||
case MPYH: /* Multiplication result (high) */
|
case MPYH: /* Multiplication result (high) */
|
||||||
{
|
{
|
||||||
/* Perform 16bit * 8bit multiply */
|
/* Perform 16bit * 8bit multiply */
|
||||||
UINT32 c = snes_ppu.mode7.matrix_a * (INT8)(snes_ppu.mode7.matrix_b >> 8);
|
UINT32 c = (INT16)snes_ppu.mode7.matrix_a * (INT8)(snes_ppu.mode7.matrix_b >> 8);
|
||||||
snes_ppu.ppu1_open_bus = (c >> 16) & 0xff;
|
snes_ppu.ppu1_open_bus = (c >> 16) & 0xff;
|
||||||
return snes_ppu.ppu1_open_bus;
|
return snes_ppu.ppu1_open_bus;
|
||||||
}
|
}
|
||||||
case SLHV: /* Software latch for H/V counter */
|
case SLHV: /* Software latch for H/V counter */
|
||||||
snes_latch_counters(space->machine);
|
snes_latch_counters(space->machine);
|
||||||
return snes_open_bus_r(space,0); /* Return value is meaningless */
|
return snes_open_bus_r(space, 0); /* Return value is meaningless */
|
||||||
case ROAMDATA: /* Read data from OAM (DR) */
|
case ROAMDATA: /* Read data from OAM (DR) */
|
||||||
{
|
{
|
||||||
int oam_addr = snes_ppu.oam.address;
|
int oam_addr = snes_ppu.oam.address;
|
||||||
@ -489,8 +482,9 @@ READ8_HANDLER( snes_r_io )
|
|||||||
snes_ram[VMADDL] = addr & 0xff;
|
snes_ram[VMADDL] = addr & 0xff;
|
||||||
snes_ram[VMADDH] = (addr >> 8) & 0xff;
|
snes_ram[VMADDH] = (addr >> 8) & 0xff;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return snes_ppu.ppu1_open_bus;
|
return snes_ppu.ppu1_open_bus;
|
||||||
|
}
|
||||||
case RVMDATAH: /* Read data from VRAM (high) */
|
case RVMDATAH: /* Read data from VRAM (high) */
|
||||||
{
|
{
|
||||||
UINT32 addr = (snes_ram[VMADDH] << 8) | snes_ram[VMADDL];
|
UINT32 addr = (snes_ram[VMADDH] << 8) | snes_ram[VMADDL];
|
||||||
@ -515,8 +509,9 @@ READ8_HANDLER( snes_r_io )
|
|||||||
snes_ram[VMADDL] = addr & 0xff;
|
snes_ram[VMADDL] = addr & 0xff;
|
||||||
snes_ram[VMADDH] = (addr >> 8) & 0xff;
|
snes_ram[VMADDH] = (addr >> 8) & 0xff;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return snes_ppu.ppu1_open_bus;
|
return snes_ppu.ppu1_open_bus;
|
||||||
|
}
|
||||||
case RCGDATA: /* Read data from CGRAM */
|
case RCGDATA: /* Read data from CGRAM */
|
||||||
if (!(state->cgram_address & 0x01))
|
if (!(state->cgram_address & 0x01))
|
||||||
{
|
{
|
||||||
@ -570,7 +565,7 @@ READ8_HANDLER( snes_r_io )
|
|||||||
state->read_ophct = 0;
|
state->read_ophct = 0;
|
||||||
state->read_opvct = 0;
|
state->read_opvct = 0;
|
||||||
value = snes_ram[offset];
|
value = snes_ram[offset];
|
||||||
value |= (snes_ppu.ppu1_open_bus & 0x20);
|
value |= (snes_ppu.ppu2_open_bus & 0x20);
|
||||||
value |= (snes_ppu.ppu2_version & 0x0f);
|
value |= (snes_ppu.ppu2_version & 0x0f);
|
||||||
snes_ram[offset] = value; // not sure if this is needed...
|
snes_ram[offset] = value; // not sure if this is needed...
|
||||||
snes_ppu.ppu2_open_bus = value;
|
snes_ppu.ppu2_open_bus = value;
|
||||||
@ -618,11 +613,11 @@ READ8_HANDLER( snes_r_io )
|
|||||||
case VTIMEH:
|
case VTIMEH:
|
||||||
return snes_ram[offset];
|
return snes_ram[offset];
|
||||||
case RDNMI: /* NMI flag by v-blank and version number */
|
case RDNMI: /* NMI flag by v-blank and version number */
|
||||||
value = (snes_ram[offset] & 0x8f) | (snes_open_bus_r(space,0) & 0x70);
|
value = (snes_ram[offset] & 0x8f) | (snes_open_bus_r(space, 0) & 0x70);
|
||||||
snes_ram[offset] &= 0x7f; /* NMI flag is reset on read */
|
snes_ram[offset] &= 0x7f; /* NMI flag is reset on read */
|
||||||
return value;
|
return value;
|
||||||
case TIMEUP: /* IRQ flag by H/V count timer */
|
case TIMEUP: /* IRQ flag by H/V count timer */
|
||||||
value = (snes_open_bus_r(space,0) & 0x7f) | (snes_ram[TIMEUP] & 0x80);
|
value = (snes_open_bus_r(space, 0) & 0x7f) | (snes_ram[TIMEUP] & 0x80);
|
||||||
cpu_set_input_line(state->maincpu, G65816_LINE_IRQ, CLEAR_LINE );
|
cpu_set_input_line(state->maincpu, G65816_LINE_IRQ, CLEAR_LINE );
|
||||||
snes_ram[TIMEUP] = 0;
|
snes_ram[TIMEUP] = 0;
|
||||||
return value;
|
return value;
|
||||||
@ -630,7 +625,7 @@ READ8_HANDLER( snes_r_io )
|
|||||||
// electronics test says hcounter 272 is start of hblank, which is beampos 363
|
// electronics test says hcounter 272 is start of hblank, which is beampos 363
|
||||||
// if (video_screen_get_hpos(space->machine->primary_screen) >= 363) snes_ram[offset] |= 0x40;
|
// if (video_screen_get_hpos(space->machine->primary_screen) >= 363) snes_ram[offset] |= 0x40;
|
||||||
// else snes_ram[offset] &= ~0x40;
|
// else snes_ram[offset] &= ~0x40;
|
||||||
return (snes_ram[offset] & 0xc1) | (snes_open_bus_r(space,0) & 0x3e);
|
return (snes_ram[offset] & 0xc1) | (snes_open_bus_r(space, 0) & 0x3e);
|
||||||
case RDIO: /* Programmable I/O port - echos back what's written to WRIO */
|
case RDIO: /* Programmable I/O port - echos back what's written to WRIO */
|
||||||
return snes_ram[WRIO];
|
return snes_ram[WRIO];
|
||||||
case RDDIVL: /* Quotient of divide result (low) */
|
case RDDIVL: /* Quotient of divide result (low) */
|
||||||
@ -654,31 +649,30 @@ READ8_HANDLER( snes_r_io )
|
|||||||
return state->joy4l;
|
return state->joy4l;
|
||||||
case JOY4H: /* Joypad 4 status register (high) */
|
case JOY4H: /* Joypad 4 status register (high) */
|
||||||
return state->joy4h;
|
return state->joy4h;
|
||||||
case DMAP0:
|
case DMAP0: case DMAP1: case DMAP2: case DMAP3: /*0x43n0*/
|
||||||
case DMAP1:
|
case DMAP4: case DMAP5: case DMAP6: case DMAP7:
|
||||||
case DMAP2:
|
case BBAD0: case BBAD1: case BBAD2: case BBAD3: /*0x43n1*/
|
||||||
case DMAP3:
|
case BBAD4: case BBAD5: case BBAD6: case BBAD7:
|
||||||
case DMAP4:
|
case A1T0L: case A1T1L: case A1T2L: case A1T3L: /*0x43n2*/
|
||||||
case DMAP5:
|
case A1T4L: case A1T5L: case A1T6L: case A1T7L:
|
||||||
case DMAP6:
|
case A1T0H: case A1T1H: case A1T2H: case A1T3H: /*0x43n3*/
|
||||||
case DMAP7:
|
case A1T4H: case A1T5H: case A1T6H: case A1T7H:
|
||||||
// return (snes_ram[offset] & 0xdf) | (snes_open_bus_r(space,0) & 0x20);
|
case A1B0: case A1B1: case A1B2: case A1B3: /*0x43n4*/
|
||||||
case BBAD0: case A1T0L: case A1T0H: case A1B0: case DAS0L:
|
case A1B4: case A1B5: case A1B6: case A1B7:
|
||||||
case DAS0H: case DSAB0: case A2A0L: case A2A0H: case NTRL0:
|
case DAS0L: case DAS1L: case DAS2L: case DAS3L: /*0x43n5*/
|
||||||
case BBAD1: case A1T1L: case A1T1H: case A1B1: case DAS1L:
|
case DAS4L: case DAS5L: case DAS6L: case DAS7L:
|
||||||
case DAS1H: case DSAB1: case A2A1L: case A2A1H: case NTRL1:
|
case DAS0H: case DAS1H: case DAS2H: case DAS3H: /*0x43n6*/
|
||||||
case BBAD2: case A1T2L: case A1T2H: case A1B2: case DAS2L:
|
case DAS4H: case DAS5H: case DAS6H: case DAS7H:
|
||||||
case DAS2H: case DSAB2: case A2A2L: case A2A2H: case NTRL2:
|
case DSAB0: case DSAB1: case DSAB2: case DSAB3: /*0x43n7*/
|
||||||
case BBAD3: case A1T3L: case A1T3H: case A1B3: case DAS3L:
|
case DSAB4: case DSAB5: case DSAB6: case DSAB7:
|
||||||
case DAS3H: case DSAB3: case A2A3L: case A2A3H: case NTRL3:
|
case A2A0L: case A2A1L: case A2A2L: case A2A3L: /*0x43n8*/
|
||||||
case BBAD4: case A1T4L: case A1T4H: case A1B4: case DAS4L:
|
case A2A4L: case A2A5L: case A2A6L: case A2A7L:
|
||||||
case DAS4H: case DSAB4: case A2A4L: case A2A4H: case NTRL4:
|
case A2A0H: case A2A1H: case A2A2H: case A2A3H: /*0x43n9*/
|
||||||
case BBAD5: case A1T5L: case A1T5H: case A1B5: case DAS5L:
|
case A2A4H: case A2A5H: case A2A6H: case A2A7H:
|
||||||
case DAS5H: case DSAB5: case A2A5L: case A2A5H: case NTRL5:
|
case NTRL0: case NTRL1: case NTRL2: case NTRL3: /*0x43na*/
|
||||||
case BBAD6: case A1T6L: case A1T6H: case A1B6: case DAS6L:
|
case NTRL4: case NTRL5: case NTRL6: case NTRL7:
|
||||||
case DAS6H: case DSAB6: case A2A6L: case A2A6H: case NTRL6:
|
case 0x430b: case 0x431b: case 0x432b: case 0x433b: /* according to bsnes, this does not return open_bus (even if its precise effect is unknown) */
|
||||||
case BBAD7: case A1T7L: case A1T7H: case A1B7: case DAS7L:
|
case 0x434b: case 0x435b: case 0x436b: case 0x437b:
|
||||||
case DAS7H: case DSAB7: case A2A7L: case A2A7H: case NTRL7:
|
|
||||||
return snes_ram[offset];
|
return snes_ram[offset];
|
||||||
|
|
||||||
#ifndef MESS
|
#ifndef MESS
|
||||||
@ -696,7 +690,7 @@ READ8_HANDLER( snes_r_io )
|
|||||||
//printf("unsupported read: offset == %08x\n", offset);
|
//printf("unsupported read: offset == %08x\n", offset);
|
||||||
|
|
||||||
/* Unsupported reads returns open bus */
|
/* Unsupported reads returns open bus */
|
||||||
// printf("%02x %02x\n",offset,snes_open_bus_r(space,0));
|
// printf("%02x %02x\n",offset,snes_open_bus_r(space, 0));
|
||||||
return snes_open_bus_r(space, 0);
|
return snes_open_bus_r(space, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -840,7 +834,6 @@ WRITE8_HANDLER( snes_w_io )
|
|||||||
snes_ppu.update_offsets = 1;
|
snes_ppu.update_offsets = 1;
|
||||||
break;
|
break;
|
||||||
case MOSAIC: /* Size and screen designation for mosaic */
|
case MOSAIC: /* Size and screen designation for mosaic */
|
||||||
/* FIXME: We support horizontal mosaic only partially */
|
|
||||||
snes_ppu.mosaic_size = (data & 0xf0) >> 4;
|
snes_ppu.mosaic_size = (data & 0xf0) >> 4;
|
||||||
snes_ppu.layer[SNES_BG1].mosaic_enabled = BIT(data, 0);
|
snes_ppu.layer[SNES_BG1].mosaic_enabled = BIT(data, 0);
|
||||||
snes_ppu.layer[SNES_BG2].mosaic_enabled = BIT(data, 1);
|
snes_ppu.layer[SNES_BG2].mosaic_enabled = BIT(data, 1);
|
||||||
@ -1322,22 +1315,30 @@ WRITE8_HANDLER( snes_w_io )
|
|||||||
#endif /* MAME_DEBUG */
|
#endif /* MAME_DEBUG */
|
||||||
return;
|
return;
|
||||||
/* Below is all DMA related */
|
/* Below is all DMA related */
|
||||||
case DMAP0: case BBAD0: case A1T0L: case A1T0H: case A1B0: case DAS0L:
|
case DMAP0: case DMAP1: case DMAP2: case DMAP3: /*0x43n0*/
|
||||||
case DAS0H: case DSAB0: case A2A0L: case A2A0H: case NTRL0:
|
case DMAP4: case DMAP5: case DMAP6: case DMAP7:
|
||||||
case DMAP1: case BBAD1: case A1T1L: case A1T1H: case A1B1: case DAS1L:
|
case BBAD0: case BBAD1: case BBAD2: case BBAD3: /*0x43n1*/
|
||||||
case DAS1H: case DSAB1: case A2A1L: case A2A1H: case NTRL1:
|
case BBAD4: case BBAD5: case BBAD6: case BBAD7:
|
||||||
case DMAP2: case BBAD2: case A1T2L: case A1T2H: case A1B2: case DAS2L:
|
case A1T0L: case A1T1L: case A1T2L: case A1T3L: /*0x43n2*/
|
||||||
case DAS2H: case DSAB2: case A2A2L: case A2A2H: case NTRL2:
|
case A1T4L: case A1T5L: case A1T6L: case A1T7L:
|
||||||
case DMAP3: case BBAD3: case A1T3L: case A1T3H: case A1B3: case DAS3L:
|
case A1T0H: case A1T1H: case A1T2H: case A1T3H: /*0x43n3*/
|
||||||
case DAS3H: case DSAB3: case A2A3L: case A2A3H: case NTRL3:
|
case A1T4H: case A1T5H: case A1T6H: case A1T7H:
|
||||||
case DMAP4: case BBAD4: case A1T4L: case A1T4H: case A1B4: case DAS4L:
|
case A1B0: case A1B1: case A1B2: case A1B3: /*0x43n4*/
|
||||||
case DAS4H: case DSAB4: case A2A4L: case A2A4H: case NTRL4:
|
case A1B4: case A1B5: case A1B6: case A1B7:
|
||||||
case DMAP5: case BBAD5: case A1T5L: case A1T5H: case A1B5: case DAS5L:
|
case DAS0L: case DAS1L: case DAS2L: case DAS3L: /*0x43n5*/
|
||||||
case DAS5H: case DSAB5: case A2A5L: case A2A5H: case NTRL5:
|
case DAS4L: case DAS5L: case DAS6L: case DAS7L:
|
||||||
case DMAP6: case BBAD6: case A1T6L: case A1T6H: case A1B6: case DAS6L:
|
case DAS0H: case DAS1H: case DAS2H: case DAS3H: /*0x43n6*/
|
||||||
case DAS6H: case DSAB6: case A2A6L: case A2A6H: case NTRL6:
|
case DAS4H: case DAS5H: case DAS6H: case DAS7H:
|
||||||
case DMAP7: case BBAD7: case A1T7L: case A1T7H: case A1B7: case DAS7L:
|
case DSAB0: case DSAB1: case DSAB2: case DSAB3: /*0x43n7*/
|
||||||
case DAS7H: case DSAB7: case A2A7L: case A2A7H: case NTRL7:
|
case DSAB4: case DSAB5: case DSAB6: case DSAB7:
|
||||||
|
case A2A0L: case A2A1L: case A2A2L: case A2A3L: /*0x43n8*/
|
||||||
|
case A2A4L: case A2A5L: case A2A6L: case A2A7L:
|
||||||
|
case A2A0H: case A2A1H: case A2A2H: case A2A3H: /*0x43n9*/
|
||||||
|
case A2A4H: case A2A5H: case A2A6H: case A2A7H:
|
||||||
|
case NTRL0: case NTRL1: case NTRL2: case NTRL3: /*0x43na*/
|
||||||
|
case NTRL4: case NTRL5: case NTRL6: case NTRL7:
|
||||||
|
case 0x430b: case 0x431b: case 0x432b: case 0x433b:
|
||||||
|
case 0x434b: case 0x435b: case 0x436b: case 0x437b:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,6 @@
|
|||||||
#ifdef SNES_LAYER_DEBUG
|
#ifdef SNES_LAYER_DEBUG
|
||||||
struct DEBUGOPTS
|
struct DEBUGOPTS
|
||||||
{
|
{
|
||||||
UINT8 input_count;
|
|
||||||
UINT8 bg_disabled[5];
|
UINT8 bg_disabled[5];
|
||||||
UINT8 mode_disabled[8];
|
UINT8 mode_disabled[8];
|
||||||
UINT8 draw_subscreen;
|
UINT8 draw_subscreen;
|
||||||
@ -97,7 +96,7 @@ struct DEBUGOPTS
|
|||||||
static struct DEBUGOPTS debug_options;
|
static struct DEBUGOPTS debug_options;
|
||||||
/* red green blue purple yellow cyan grey white */
|
/* red green blue purple yellow cyan grey white */
|
||||||
static const UINT16 dbg_mode_colours[8] = { 0x1f, 0x3e0, 0x7c00, 0x7c1f, 0x3ff, 0x7fe0, 0x4210, 0x7fff };
|
static const UINT16 dbg_mode_colours[8] = { 0x1f, 0x3e0, 0x7c00, 0x7c1f, 0x3ff, 0x7fe0, 0x4210, 0x7fff };
|
||||||
static UINT8 snes_dbg_video(running_machine *machine, bitmap_t *bitmap, UINT16 curline);
|
static UINT8 snes_dbg_video(running_machine *machine, UINT16 curline);
|
||||||
#endif /* SNES_LAYER_DEBUG */
|
#endif /* SNES_LAYER_DEBUG */
|
||||||
|
|
||||||
static const UINT16 table_obj_offset[8][8] =
|
static const UINT16 table_obj_offset[8][8] =
|
||||||
@ -132,407 +131,249 @@ enum
|
|||||||
SNES_COLOR_DEPTH_8BPP
|
SNES_COLOR_DEPTH_8BPP
|
||||||
};
|
};
|
||||||
|
|
||||||
/**********************************************************************************
|
/*****************************************
|
||||||
* TODO: the draw_tile routines below should be merged/reworked to reduce everything
|
* snes_get_bgcolor()
|
||||||
* to a single routine with the additional parameters: OAM/BG (to decide if checking
|
*
|
||||||
* against priority or not) and tile length (16 for hires BG, 8 otherwise)
|
* Get the proper color (direct or from cgram)
|
||||||
**********************************************************************************/
|
*****************************************/
|
||||||
|
|
||||||
|
INLINE UINT16 snes_get_bgcolor( UINT8 direct_colors, UINT16 palette, UINT8 color )
|
||||||
|
{
|
||||||
|
UINT16 c = 0;
|
||||||
|
|
||||||
|
if (direct_colors)
|
||||||
|
{
|
||||||
|
/* format is 0 | BBb00 | GGGg0 | RRRr0, HW confirms that the data is zero padded. */
|
||||||
|
c = ((color & 0x07) << 2) | ((color & 0x38) << 4) | ((color & 0xc0) << 7);
|
||||||
|
c |= ((palette & 0x04) >> 1) | ((palette & 0x08) << 3) | ((palette & 0x10) << 8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
c = snes_cgram[(palette + color) % FIXED_COLOUR];
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************
|
||||||
|
* snes_set_scanline_pixel()
|
||||||
|
*
|
||||||
|
* Store pixel color, priority, layer and
|
||||||
|
* color math exception (for OAM) in the
|
||||||
|
* proper scanline
|
||||||
|
*****************************************/
|
||||||
|
|
||||||
|
INLINE void snes_set_scanline_pixel( int screen, INT16 x, UINT16 color, UINT8 priority, UINT8 layer, int blend )
|
||||||
|
{
|
||||||
|
scanlines[screen].buffer[x] = color;
|
||||||
|
scanlines[screen].priority[x] = priority;
|
||||||
|
scanlines[screen].layer[x] = layer;
|
||||||
|
scanlines[screen].blend_exception[x] = blend;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************************************
|
||||||
|
* SNES tiles
|
||||||
|
*
|
||||||
|
* The way vram is accessed to draw tiles is basically the same for both BG and OAM tiles. Main
|
||||||
|
* differences are bit planes (variable for BG and fixed for OAM) and a few details of the scanline
|
||||||
|
* output (since OAM has neither mosaic, nor hires, nor direct colors).
|
||||||
|
* Hence, we use a common function to take data from VRAM and then we call specific routines for
|
||||||
|
* OAM vs BG vs Hi-Res BG tiles.
|
||||||
|
*************************************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************
|
||||||
|
* snes_draw_bgtile_lores()
|
||||||
|
* snes_draw_bgtile_hires()
|
||||||
|
* snes_draw_oamtile_()
|
||||||
|
*
|
||||||
|
* Check if a pixel is clipped or not, and
|
||||||
|
* copy it to the scanline buffer when
|
||||||
|
* appropriate. The actual way to perform
|
||||||
|
* such operations depends on the source
|
||||||
|
* (BG or OAM) and on the resolution (hires
|
||||||
|
* or lores)
|
||||||
|
*****************************************/
|
||||||
|
|
||||||
|
INLINE void snes_draw_bgtile_lores( UINT8 layer, INT16 ii, UINT8 colour, UINT16 pal, UINT8 direct_colors, UINT8 priority )
|
||||||
|
{
|
||||||
|
int screen;
|
||||||
|
UINT16 c;
|
||||||
|
|
||||||
|
for (screen = SNES_MAINSCREEN; screen <= SNES_SUBSCREEN; screen++)
|
||||||
|
{
|
||||||
|
if (ii >= 0 && ii < SNES_SCR_WIDTH && scanlines[screen].enable)
|
||||||
|
{
|
||||||
|
if (scanlines[screen].priority[ii] <= priority)
|
||||||
|
{
|
||||||
|
UINT8 clr = colour;
|
||||||
|
UINT8 clipmask = snes_ppu.clipmasks[layer][ii];
|
||||||
|
|
||||||
|
#ifdef SNES_LAYER_DEBUG
|
||||||
|
if (debug_options.windows_disabled)
|
||||||
|
clipmask = 0xff;
|
||||||
|
#endif /* SNES_LAYER_DEBUG */
|
||||||
|
|
||||||
|
/* Clip to windows */
|
||||||
|
if (scanlines[screen].clip)
|
||||||
|
clr &= clipmask;
|
||||||
|
|
||||||
|
/* Only draw if we have a colour (0 == transparent) */
|
||||||
|
if (clr)
|
||||||
|
{
|
||||||
|
c = snes_get_bgcolor(direct_colors, pal, clr);
|
||||||
|
snes_set_scanline_pixel(screen, ii, c, priority, layer, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE void snes_draw_bgtile_hires( UINT8 layer, INT16 ii, UINT8 colour, UINT16 pal, UINT8 direct_colors, UINT8 priority )
|
||||||
|
{
|
||||||
|
int screen;
|
||||||
|
UINT16 c;
|
||||||
|
|
||||||
|
for (screen = SNES_MAINSCREEN; screen <= SNES_SUBSCREEN; screen++)
|
||||||
|
{
|
||||||
|
// odd pixels to main screen, even pixels to sub screen
|
||||||
|
if (ii >= 0 && ii < (SNES_SCR_WIDTH << 1) && ((ii & 1) ^ screen) && scanlines[screen].enable)
|
||||||
|
{
|
||||||
|
if (scanlines[screen].priority[ii >> 1] <= priority)
|
||||||
|
{
|
||||||
|
UINT8 clr = colour;
|
||||||
|
UINT8 clipmask = snes_ppu.clipmasks[layer][ii];
|
||||||
|
|
||||||
|
#ifdef SNES_LAYER_DEBUG
|
||||||
|
if (debug_options.windows_disabled)
|
||||||
|
clipmask = 0xff;
|
||||||
|
#endif /* SNES_LAYER_DEBUG */
|
||||||
|
|
||||||
|
/* Clip to windows */
|
||||||
|
if (scanlines[screen].clip)
|
||||||
|
clr &= clipmask;
|
||||||
|
|
||||||
|
/* Only draw if we have a colour (0 == transparent) */
|
||||||
|
if (clr)
|
||||||
|
{
|
||||||
|
c = snes_get_bgcolor(direct_colors, pal, clr);
|
||||||
|
snes_set_scanline_pixel(screen, ii >> 1, c, priority, layer, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE void snes_draw_oamtile( INT16 ii, UINT8 colour, UINT16 pal, UINT8 priority )
|
||||||
|
{
|
||||||
|
int screen;
|
||||||
|
int blend;
|
||||||
|
UINT16 c;
|
||||||
|
INT16 pos = ii & 0x1ff;
|
||||||
|
|
||||||
|
for (screen = SNES_MAINSCREEN; screen <= SNES_SUBSCREEN; screen++)
|
||||||
|
{
|
||||||
|
if (pos >= 0 && pos < SNES_SCR_WIDTH && scanlines[screen].enable)
|
||||||
|
{
|
||||||
|
UINT8 clr = colour;
|
||||||
|
UINT8 clipmask = snes_ppu.clipmasks[SNES_OAM][pos];
|
||||||
|
|
||||||
|
#ifdef SNES_LAYER_DEBUG
|
||||||
|
if (debug_options.windows_disabled)
|
||||||
|
clipmask = 0xff;
|
||||||
|
#endif /* SNES_LAYER_DEBUG */
|
||||||
|
|
||||||
|
/* Clip to windows */
|
||||||
|
if (scanlines[screen].clip)
|
||||||
|
clr &= clipmask;
|
||||||
|
|
||||||
|
/* Only draw if we have a colour (0 == transparent) */
|
||||||
|
if (clr)
|
||||||
|
{
|
||||||
|
c = snes_cgram[(pal + clr) % FIXED_COLOUR];
|
||||||
|
blend = (pal + clr < 192) ? 1 : 0;
|
||||||
|
snes_set_scanline_pixel(screen, pos, c, priority, SNES_OAM, blend);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************
|
/*****************************************
|
||||||
* snes_draw_tile()
|
* snes_draw_tile()
|
||||||
*
|
*
|
||||||
* Draw BG tiles with variable bit planes
|
* Get pixel color with variable bit planes
|
||||||
|
* from snes_vram and draw the tiles by
|
||||||
|
* calling the appropriate routine
|
||||||
*****************************************/
|
*****************************************/
|
||||||
|
|
||||||
INLINE void snes_draw_tile( UINT8 planes, UINT8 layer, UINT16 tileaddr, INT16 x, UINT8 priority, UINT8 flip, UINT8 direct_colors, UINT16 pal, UINT8 hires )
|
INLINE void snes_draw_tile( UINT8 planes, UINT8 layer, UINT16 tileaddr, INT16 x, int tile_size, UINT8 priority, UINT8 flip, UINT8 direct_colors, UINT16 pal, UINT8 hires )
|
||||||
{
|
{
|
||||||
UINT8 mask, plane[8];
|
UINT8 plane[8];
|
||||||
UINT16 c;
|
INT16 ii, jj, start_pixel;
|
||||||
INT16 ii, jj;
|
int tile, x_mos;
|
||||||
|
|
||||||
|
start_pixel = x;
|
||||||
|
|
||||||
|
/* if 8x8 tile we draw once; if 16x16 we draw twice */
|
||||||
|
for (tile = 0; tile < (1 << tile_size); tile++)
|
||||||
|
{
|
||||||
for (ii = 0; ii < planes / 2; ii++)
|
for (ii = 0; ii < planes / 2; ii++)
|
||||||
{
|
{
|
||||||
plane[2 * ii] = snes_vram[tileaddr + 16 * ii];
|
plane[2 * ii] = snes_vram[tileaddr + 16 * ii];
|
||||||
plane[2 * ii + 1] = snes_vram[tileaddr + 16 * ii + 1];
|
plane[2 * ii + 1] = snes_vram[tileaddr + 16 * ii + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flip)
|
|
||||||
mask = 0x1;
|
|
||||||
else
|
|
||||||
mask = 0x80;
|
|
||||||
|
|
||||||
for (ii = x; ii < (x + 8); ii++)
|
for (ii = x; ii < (x + 8); ii++)
|
||||||
{
|
{
|
||||||
UINT8 colour = 0;
|
UINT8 colour = 0;
|
||||||
|
UINT8 mosaic = snes_ppu.layer[layer].mosaic_enabled;
|
||||||
|
|
||||||
|
#ifdef SNES_LAYER_DEBUG
|
||||||
|
if (debug_options.mosaic_disabled)
|
||||||
|
mosaic = 0;
|
||||||
|
#endif /* SNES_LAYER_DEBUG */
|
||||||
|
|
||||||
if (flip)
|
if (flip)
|
||||||
{
|
{
|
||||||
for (jj = 0; jj < planes; jj++)
|
for (jj = 0; jj < planes; jj++)
|
||||||
colour |= plane[jj] & mask ? (1 << jj) : 0;
|
colour |= BIT(plane[jj], ii - x) ? (1 << jj) : 0;
|
||||||
|
|
||||||
mask <<= 1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (jj = 0; jj < planes; jj++)
|
for (jj = 0; jj < planes; jj++)
|
||||||
colour |= plane[jj] & mask ? (1 << jj) : 0;
|
colour |= BIT(plane[jj], 7 - (ii - x)) ? (1 << jj) : 0;
|
||||||
|
|
||||||
mask >>= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (layer == SNES_OAM)
|
||||||
if (!hires)
|
snes_draw_oamtile(ii, colour, pal, priority);
|
||||||
|
else if (!hires)
|
||||||
{
|
{
|
||||||
if (ii >= 0 && ii < (SNES_SCR_WIDTH << hires) && scanlines[SNES_MAINSCREEN].enable)
|
if (mosaic)
|
||||||
{
|
{
|
||||||
if (scanlines[SNES_MAINSCREEN].priority[ii] <= priority)
|
for (x_mos = 0; x_mos < (snes_ppu.mosaic_size + 1); x_mos++)
|
||||||
{
|
snes_draw_bgtile_lores(layer, ii + x_mos, colour, pal, direct_colors, priority);
|
||||||
UINT8 clr = colour;
|
|
||||||
UINT8 clipmask = snes_ppu.clipmasks[layer][ii];
|
|
||||||
UINT8 mosaic = snes_ppu.layer[SNES_MAINSCREEN].mosaic_enabled;
|
|
||||||
|
|
||||||
#ifdef SNES_LAYER_DEBUG
|
|
||||||
if (debug_options.windows_disabled)
|
|
||||||
clipmask = 0xff;
|
|
||||||
if (debug_options.mosaic_disabled)
|
|
||||||
mosaic = 0;
|
|
||||||
#endif /* SNES_LAYER_DEBUG */
|
|
||||||
|
|
||||||
/* Clip to windows */
|
|
||||||
if (scanlines[SNES_MAINSCREEN].clip)
|
|
||||||
clr &= clipmask;
|
|
||||||
|
|
||||||
/* Only draw if we have a colour (0 == transparent) */
|
|
||||||
if (clr)
|
|
||||||
{
|
|
||||||
if (direct_colors)
|
|
||||||
{
|
|
||||||
/* format is 0 | BBb00 | GGGg0 | RRRr0, HW confirms that the data is zero padded. */
|
|
||||||
c = ((clr & 0x07) << 2) | ((clr & 0x38) << 4) | ((clr & 0xc0) << 7);
|
|
||||||
c |= ((pal & 0x04) >> 1) | ((pal & 0x08) << 3) | ((pal & 0x10) << 8);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
c = snes_cgram[(pal + clr) % FIXED_COLOUR];
|
|
||||||
|
|
||||||
if (mosaic) // handle horizontal mosaic
|
|
||||||
{
|
|
||||||
int x_mos;
|
|
||||||
|
|
||||||
//TODO: 512 modes has the h values doubled.
|
|
||||||
for (x_mos = 0; x_mos < (snes_ppu.mosaic_size + 1) ; x_mos++)
|
|
||||||
{
|
|
||||||
scanlines[SNES_MAINSCREEN].buffer[ii + x_mos] = c;
|
|
||||||
scanlines[SNES_MAINSCREEN].priority[ii + x_mos] = priority;
|
|
||||||
scanlines[SNES_MAINSCREEN].layer[ii + x_mos] = layer;
|
|
||||||
scanlines[SNES_MAINSCREEN].blend_exception[ii + x_mos] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ii += x_mos - 1;
|
ii += x_mos - 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
snes_draw_bgtile_lores(layer, ii, colour, pal, direct_colors, priority);
|
||||||
scanlines[SNES_MAINSCREEN].buffer[ii] = c;
|
|
||||||
scanlines[SNES_MAINSCREEN].priority[ii] = priority;
|
|
||||||
scanlines[SNES_MAINSCREEN].layer[ii] = layer;
|
|
||||||
scanlines[SNES_MAINSCREEN].blend_exception[ii] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ii >= 0 && ii < (SNES_SCR_WIDTH << hires) && scanlines[SNES_SUBSCREEN].enable)
|
|
||||||
{
|
|
||||||
if (scanlines[SNES_SUBSCREEN].priority[ii] <= priority)
|
|
||||||
{
|
|
||||||
UINT8 clr = colour;
|
|
||||||
UINT8 clipmask = snes_ppu.clipmasks[layer][ii];
|
|
||||||
UINT8 mosaic = snes_ppu.layer[SNES_SUBSCREEN].mosaic_enabled;
|
|
||||||
|
|
||||||
#ifdef SNES_LAYER_DEBUG
|
|
||||||
if (debug_options.windows_disabled)
|
|
||||||
clipmask = 0xff;
|
|
||||||
if (debug_options.mosaic_disabled)
|
|
||||||
mosaic = 0;
|
|
||||||
#endif /* SNES_LAYER_DEBUG */
|
|
||||||
|
|
||||||
/* Clip to windows */
|
|
||||||
if (scanlines[SNES_SUBSCREEN].clip)
|
|
||||||
clr &= clipmask;
|
|
||||||
|
|
||||||
/* Only draw if we have a colour (0 == transparent) */
|
|
||||||
if (clr)
|
|
||||||
{
|
|
||||||
if (direct_colors)
|
|
||||||
{
|
|
||||||
/* format is 0 | BBb00 | GGGg0 | RRRr0, HW confirms that the data is zero padded. */
|
|
||||||
c = ((clr & 0x07) << 2) | ((clr & 0x38) << 4) | ((clr & 0xc0) << 7);
|
|
||||||
c |= ((pal & 0x04) >> 1) | ((pal & 0x08) << 3) | ((pal & 0x10) << 8);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
c = snes_cgram[(pal + clr) % FIXED_COLOUR];
|
|
||||||
|
|
||||||
if (mosaic) // handle horizontal mosaic
|
|
||||||
{
|
|
||||||
int x_mos;
|
|
||||||
|
|
||||||
//TODO: 512 modes has the h values doubled.
|
|
||||||
for (x_mos = 0; x_mos < (snes_ppu.mosaic_size + 1) ; x_mos++)
|
|
||||||
{
|
|
||||||
scanlines[SNES_SUBSCREEN].buffer[ii + x_mos] = c;
|
|
||||||
scanlines[SNES_SUBSCREEN].priority[ii + x_mos] = priority;
|
|
||||||
scanlines[SNES_SUBSCREEN].layer[ii + x_mos] = layer;
|
|
||||||
scanlines[SNES_SUBSCREEN].blend_exception[ii + x_mos] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ii += x_mos - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
scanlines[SNES_SUBSCREEN].buffer[ii] = c;
|
|
||||||
scanlines[SNES_SUBSCREEN].priority[ii] = priority;
|
|
||||||
scanlines[SNES_SUBSCREEN].layer[ii] = layer;
|
|
||||||
scanlines[SNES_SUBSCREEN].blend_exception[ii] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else /* hires */
|
else /* hires */
|
||||||
{
|
{
|
||||||
if (ii >= 0 && ii < (SNES_SCR_WIDTH << hires) && (ii & 1) && scanlines[SNES_MAINSCREEN].enable)
|
if (mosaic)
|
||||||
{
|
{
|
||||||
if (scanlines[SNES_MAINSCREEN].priority[ii >> 1] <= priority)
|
for (x_mos = 0; x_mos < (snes_ppu.mosaic_size + 1); x_mos++)
|
||||||
{
|
snes_draw_bgtile_hires(layer, ii + x_mos, colour, pal, direct_colors, priority);
|
||||||
UINT8 clr = colour;
|
|
||||||
UINT8 clipmask = snes_ppu.clipmasks[layer][ii];
|
|
||||||
UINT8 mosaic = snes_ppu.layer[SNES_MAINSCREEN].mosaic_enabled;
|
|
||||||
|
|
||||||
#ifdef SNES_LAYER_DEBUG
|
|
||||||
if (debug_options.windows_disabled)
|
|
||||||
clipmask = 0xff;
|
|
||||||
if (debug_options.mosaic_disabled)
|
|
||||||
mosaic = 0;
|
|
||||||
#endif /* SNES_LAYER_DEBUG */
|
|
||||||
|
|
||||||
/* Clip to windows */
|
|
||||||
if (scanlines[SNES_MAINSCREEN].clip)
|
|
||||||
clr &= clipmask;
|
|
||||||
|
|
||||||
/* Only draw if we have a colour (0 == transparent) */
|
|
||||||
if (clr)
|
|
||||||
{
|
|
||||||
if (direct_colors)
|
|
||||||
{
|
|
||||||
/* format is 0 | BBb00 | GGGg0 | RRRr0, HW confirms that the data is zero padded. */
|
|
||||||
c = ((clr & 0x07) << 2) | ((clr & 0x38) << 4) | ((clr & 0xc0) << 7);
|
|
||||||
c |= ((pal & 0x04) >> 1) | ((pal & 0x08) << 3) | ((pal & 0x10) << 8);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
c = snes_cgram[(pal + clr) % FIXED_COLOUR];
|
|
||||||
|
|
||||||
if (mosaic) // handle horizontal mosaic
|
|
||||||
{
|
|
||||||
int x_mos;
|
|
||||||
|
|
||||||
//TODO: 512 modes has the h values doubled.
|
|
||||||
for (x_mos = 0; x_mos < (snes_ppu.mosaic_size + 1) ; x_mos++)
|
|
||||||
{
|
|
||||||
scanlines[SNES_MAINSCREEN].buffer[(ii + x_mos) >> 1] = c;
|
|
||||||
scanlines[SNES_MAINSCREEN].priority[(ii + x_mos) >> 1] = priority;
|
|
||||||
scanlines[SNES_MAINSCREEN].layer[(ii + x_mos) >> 1] = layer;
|
|
||||||
scanlines[SNES_MAINSCREEN].blend_exception[(ii + x_mos) >> 1] = 0;
|
|
||||||
}
|
|
||||||
ii += x_mos - 1;
|
ii += x_mos - 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
snes_draw_bgtile_hires(layer, ii, colour, pal, direct_colors, priority);
|
||||||
scanlines[SNES_MAINSCREEN].buffer[ii >> 1] = c;
|
|
||||||
scanlines[SNES_MAINSCREEN].priority[ii >> 1] = priority;
|
|
||||||
scanlines[SNES_MAINSCREEN].layer[ii >> 1] = layer;
|
|
||||||
scanlines[SNES_MAINSCREEN].blend_exception[ii >> 1] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ii >= 0 && ii < (SNES_SCR_WIDTH << hires) && !(ii & 1) && scanlines[SNES_SUBSCREEN].enable)
|
/* adjust tileaddr & x in case we have to draw again (for 16x16 tiles) */
|
||||||
{
|
if (!flip)
|
||||||
if (scanlines[SNES_SUBSCREEN].priority[ii >> 1] <= priority)
|
tileaddr += (8 * planes);
|
||||||
{
|
|
||||||
UINT8 clr = colour;
|
|
||||||
UINT8 clipmask = snes_ppu.clipmasks[layer][ii];
|
|
||||||
UINT8 mosaic = snes_ppu.layer[SNES_SUBSCREEN].mosaic_enabled;
|
|
||||||
|
|
||||||
#ifdef SNES_LAYER_DEBUG
|
|
||||||
if (debug_options.windows_disabled)
|
|
||||||
clipmask = 0xff;
|
|
||||||
if (debug_options.mosaic_disabled)
|
|
||||||
mosaic = 0;
|
|
||||||
#endif /* SNES_LAYER_DEBUG */
|
|
||||||
|
|
||||||
/* Clip to windows */
|
|
||||||
if (scanlines[SNES_SUBSCREEN].clip)
|
|
||||||
clr &= clipmask;
|
|
||||||
|
|
||||||
/* Only draw if we have a colour (0 == transparent) */
|
|
||||||
if (clr)
|
|
||||||
{
|
|
||||||
if (direct_colors)
|
|
||||||
{
|
|
||||||
/* format is 0 | BBb00 | GGGg0 | RRRr0, HW confirms that the data is zero padded. */
|
|
||||||
c = ((clr & 0x07) << 2) | ((clr & 0x38) << 4) | ((clr & 0xc0) << 7);
|
|
||||||
c |= ((pal & 0x04) >> 1) | ((pal & 0x08) << 3) | ((pal & 0x10) << 8);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
c = snes_cgram[(pal + clr) % FIXED_COLOUR];
|
tileaddr -= (8 * planes);
|
||||||
|
|
||||||
if (mosaic) // handle horizontal mosaic
|
x += 8;
|
||||||
{
|
|
||||||
int x_mos;
|
|
||||||
|
|
||||||
//TODO: 512 modes has the h values doubled.
|
|
||||||
for (x_mos = 0; x_mos < (snes_ppu.mosaic_size + 1) ; x_mos++)
|
|
||||||
{
|
|
||||||
scanlines[SNES_SUBSCREEN].buffer[(ii + x_mos) >> 1] = c;
|
|
||||||
scanlines[SNES_SUBSCREEN].priority[(ii + x_mos) >> 1] = priority;
|
|
||||||
scanlines[SNES_SUBSCREEN].layer[(ii + x_mos) >> 1] = layer;
|
|
||||||
scanlines[SNES_SUBSCREEN].blend_exception[(ii + x_mos) >> 1] = 0;
|
|
||||||
}
|
|
||||||
ii += x_mos - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
scanlines[SNES_SUBSCREEN].buffer[ii >> 1] = c;
|
|
||||||
scanlines[SNES_SUBSCREEN].priority[ii >> 1] = priority;
|
|
||||||
scanlines[SNES_SUBSCREEN].layer[ii >> 1] = layer;
|
|
||||||
scanlines[SNES_SUBSCREEN].blend_exception[ii >> 1] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************
|
|
||||||
* snes_draw_tile_x2()
|
|
||||||
*
|
|
||||||
* Draw 2 tiles with variable bit planes
|
|
||||||
*****************************************/
|
|
||||||
|
|
||||||
INLINE void snes_draw_tile_x2( UINT8 planes, UINT8 layer, UINT16 tileaddr, INT16 x, UINT8 priority, UINT8 flip, UINT8 direct_colors, UINT16 pal, UINT8 hires )
|
|
||||||
{
|
|
||||||
if (flip)
|
|
||||||
{
|
|
||||||
snes_draw_tile(planes, layer, tileaddr + (8 * planes), x, priority, flip, direct_colors, pal, hires);
|
|
||||||
snes_draw_tile(planes, layer, tileaddr, x + 8, priority, flip, direct_colors, pal, hires);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
snes_draw_tile(planes, layer, tileaddr, x, priority, flip, direct_colors, pal, hires);
|
|
||||||
snes_draw_tile(planes, layer, tileaddr + (8 * planes), x + 8, priority, flip, direct_colors, pal, hires);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************
|
|
||||||
* snes_draw_tile_object()
|
|
||||||
*
|
|
||||||
* Draw OAM tiles with 4 bit planes(16 colors)
|
|
||||||
*****************************************/
|
|
||||||
|
|
||||||
INLINE void snes_draw_tile_object( UINT16 tileaddr, INT16 x, UINT8 priority, UINT8 flip, UINT16 pal )
|
|
||||||
{
|
|
||||||
UINT8 mask, plane[4];
|
|
||||||
UINT16 c;
|
|
||||||
int blend;
|
|
||||||
INT16 ii, jj;
|
|
||||||
|
|
||||||
plane[0] = snes_vram[tileaddr];
|
|
||||||
plane[1] = snes_vram[tileaddr + 1];
|
|
||||||
plane[2] = snes_vram[tileaddr + 16];
|
|
||||||
plane[3] = snes_vram[tileaddr + 17];
|
|
||||||
|
|
||||||
if (flip)
|
|
||||||
mask = 0x01;
|
|
||||||
else
|
|
||||||
mask = 0x80;
|
|
||||||
|
|
||||||
for (ii = x; ii < (x + 8); ii++)
|
|
||||||
{
|
|
||||||
UINT8 colour = 0;
|
|
||||||
if (flip)
|
|
||||||
{
|
|
||||||
for (jj = 0; jj < 4; jj++)
|
|
||||||
colour |= plane[jj] & mask ? (1 << jj) : 0;
|
|
||||||
|
|
||||||
mask <<= 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (jj = 0; jj < 4; jj++)
|
|
||||||
colour |= plane[jj] & mask ? (1 << jj) : 0;
|
|
||||||
|
|
||||||
mask >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
INT16 pos = ii & 0x1ff;
|
|
||||||
|
|
||||||
if (pos >= 0 && pos < SNES_SCR_WIDTH && scanlines[SNES_MAINSCREEN].enable)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
UINT8 clr = colour;
|
|
||||||
UINT8 clipmask = snes_ppu.clipmasks[SNES_OAM][pos];
|
|
||||||
|
|
||||||
#ifdef SNES_LAYER_DEBUG
|
|
||||||
if (debug_options.windows_disabled)
|
|
||||||
clipmask = 0xff;
|
|
||||||
#endif /* SNES_LAYER_DEBUG */
|
|
||||||
|
|
||||||
/* Clip to windows */
|
|
||||||
if (scanlines[SNES_MAINSCREEN].clip)
|
|
||||||
clr &= clipmask;
|
|
||||||
|
|
||||||
/* Only draw if we have a colour (0 == transparent) */
|
|
||||||
if (clr)
|
|
||||||
{
|
|
||||||
c = snes_cgram[(pal + clr) % FIXED_COLOUR];
|
|
||||||
blend = (pal + clr < 192) ? 1 : 0;
|
|
||||||
|
|
||||||
scanlines[SNES_MAINSCREEN].buffer[pos] = c;
|
|
||||||
scanlines[SNES_MAINSCREEN].priority[pos] = priority;
|
|
||||||
scanlines[SNES_MAINSCREEN].layer[pos] = SNES_OAM;
|
|
||||||
scanlines[SNES_MAINSCREEN].blend_exception[pos] = blend;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pos >= 0 && pos < SNES_SCR_WIDTH && scanlines[SNES_SUBSCREEN].enable)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
UINT8 clr = colour;
|
|
||||||
UINT8 clipmask = snes_ppu.clipmasks[SNES_OAM][pos];
|
|
||||||
|
|
||||||
#ifdef SNES_LAYER_DEBUG
|
|
||||||
if (debug_options.windows_disabled)
|
|
||||||
clipmask = 0xff;
|
|
||||||
#endif /* SNES_LAYER_DEBUG */
|
|
||||||
|
|
||||||
/* Clip to windows */
|
|
||||||
if (scanlines[SNES_SUBSCREEN].clip)
|
|
||||||
clr &= clipmask;
|
|
||||||
|
|
||||||
/* Only draw if we have a colour (0 == transparent) */
|
|
||||||
if (clr)
|
|
||||||
{
|
|
||||||
c = snes_cgram[(pal + clr) % FIXED_COLOUR];
|
|
||||||
blend = (pal + clr < 192) ? 1 : 0;
|
|
||||||
|
|
||||||
scanlines[SNES_SUBSCREEN].buffer[pos] = c;
|
|
||||||
scanlines[SNES_SUBSCREEN].priority[pos] = priority;
|
|
||||||
scanlines[SNES_SUBSCREEN].layer[pos] = SNES_OAM;
|
|
||||||
scanlines[SNES_SUBSCREEN].blend_exception[pos] = blend;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -596,7 +437,6 @@ INLINE void snes_update_line( UINT16 curline, UINT8 layer, UINT8 priority_b, UIN
|
|||||||
UINT16 opt_bit = (layer == SNES_BG1) ? 13 : (layer == SNES_BG2) ? 14 : 0;
|
UINT16 opt_bit = (layer == SNES_BG1) ? 13 : (layer == SNES_BG2) ? 14 : 0;
|
||||||
UINT8 tile_size;
|
UINT8 tile_size;
|
||||||
/* variables depending on color_depth */
|
/* variables depending on color_depth */
|
||||||
UINT8 tile_divider = (color_depth == SNES_COLOR_DEPTH_8BPP) ? 4 : 2;
|
|
||||||
UINT8 color_planes = 2 << color_depth;
|
UINT8 color_planes = 2 << color_depth;
|
||||||
/* below we cheat to simplify the code: 8BPP should have 0 pal offset, not 0x100 (but we take care of this by later using pal % FIXED_COLOUR) */
|
/* below we cheat to simplify the code: 8BPP should have 0 pal offset, not 0x100 (but we take care of this by later using pal % FIXED_COLOUR) */
|
||||||
UINT8 color_shift = 2 << color_depth;
|
UINT8 color_shift = 2 << color_depth;
|
||||||
@ -715,56 +555,39 @@ INLINE void snes_update_line( UINT16 curline, UINT8 layer, UINT8 priority_b, UIN
|
|||||||
}
|
}
|
||||||
#endif /* SNES_LAYER_DEBUG */
|
#endif /* SNES_LAYER_DEBUG */
|
||||||
|
|
||||||
|
|
||||||
/* figure out which line to draw */
|
/* figure out which line to draw */
|
||||||
yscroll = ypos & ((8 << tile_size) - 1);
|
yscroll = ypos & ((8 << tile_size) - 1);
|
||||||
|
|
||||||
if (yscroll > ((8 << tile_size) - 1)) /* scrolled into the next tile */
|
if (tile_size)
|
||||||
yscroll -= (8 << tile_size);
|
if ((yscroll & 8) != vflip)
|
||||||
|
tile += 16;
|
||||||
|
|
||||||
|
if (yscroll > 7)
|
||||||
|
yscroll &= 7;
|
||||||
|
|
||||||
if (vflip)
|
if (vflip)
|
||||||
{
|
|
||||||
if (tile_size)
|
|
||||||
{
|
|
||||||
if (yscroll > 7)
|
|
||||||
{
|
|
||||||
yscroll -= 8;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tile += 32 / tile_divider;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
yscroll = -yscroll + 7;
|
yscroll = -yscroll + 7;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (yscroll > 7)
|
|
||||||
{
|
|
||||||
tile += 32 / tile_divider;
|
|
||||||
yscroll -= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
yscroll <<= 1;
|
yscroll <<= 1;
|
||||||
|
|
||||||
/* below, only color_planes depends on color_depth */
|
if (hires)
|
||||||
if (hires) /* Hi-Res: 2bpp & 4bpp */
|
|
||||||
{
|
{
|
||||||
snes_draw_tile_x2(color_planes, layer, charaddr + (tile * 8 * color_planes) + yscroll, (ii - xscroll) * 2, priority, hflip, direct_colors, direct_colors ? pal_direct : pal, hires);
|
/* adjust tile for horizontal flip */
|
||||||
|
if (hflip)
|
||||||
|
tile += 1;
|
||||||
|
|
||||||
|
/* draw 16 pixels (the routine will automatically send half of them to the mainscreen scanline and half to the subscreen one) */
|
||||||
|
snes_draw_tile(color_planes, layer, charaddr + (tile * 8 * color_planes) + yscroll, (ii - xscroll) * 2, 1, priority, hflip, direct_colors, direct_colors ? pal_direct : pal, hires);
|
||||||
ii += 8;
|
ii += 8;
|
||||||
}
|
}
|
||||||
else /* tile_size = 0 */
|
else
|
||||||
{
|
{
|
||||||
if (tile_size)
|
/* adjust tile for horizontal flip */
|
||||||
{
|
if (tile_size && hflip)
|
||||||
snes_draw_tile_x2(color_planes, layer, charaddr + (tile * 8 * color_planes) + yscroll, ii - xscroll, priority, hflip, direct_colors, direct_colors ? pal_direct : pal, hires);
|
tile += 1;
|
||||||
ii += 16;
|
|
||||||
}
|
snes_draw_tile(color_planes, layer, charaddr + (tile * 8 * color_planes) + yscroll, ii - xscroll, tile_size, priority, hflip, direct_colors, direct_colors ? pal_direct : pal, hires);
|
||||||
else /* No Hi-Res: 2bpp, 4bpp & 8bpp */
|
ii += (8 << tile_size);
|
||||||
{
|
|
||||||
snes_draw_tile(color_planes, layer, charaddr + (tile * 8 * color_planes) + yscroll, ii - xscroll, priority, hflip, direct_colors, direct_colors ? pal_direct : pal, hires);
|
|
||||||
ii += 8;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -787,6 +610,7 @@ static void snes_update_line_mode7( UINT16 curline, UINT8 layer, UINT8 priority_
|
|||||||
UINT8 colour = 0;
|
UINT8 colour = 0;
|
||||||
UINT16 *mosaic_x, *mosaic_y;
|
UINT16 *mosaic_x, *mosaic_y;
|
||||||
UINT16 c;
|
UINT16 c;
|
||||||
|
int screen;
|
||||||
|
|
||||||
#ifdef SNES_LAYER_DEBUG
|
#ifdef SNES_LAYER_DEBUG
|
||||||
if (debug_options.bg_disabled[layer])
|
if (debug_options.bg_disabled[layer])
|
||||||
@ -910,7 +734,9 @@ static void snes_update_line_mode7( UINT16 curline, UINT8 layer, UINT8 priority_
|
|||||||
#endif /* SNES_LAYER_DEBUG */
|
#endif /* SNES_LAYER_DEBUG */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scanlines[SNES_MAINSCREEN].enable)
|
for (screen = SNES_MAINSCREEN; screen <= SNES_SUBSCREEN; screen++)
|
||||||
|
{
|
||||||
|
if (scanlines[screen].enable)
|
||||||
{
|
{
|
||||||
UINT8 clr = colour;
|
UINT8 clr = colour;
|
||||||
UINT8 clipmask = snes_ppu.clipmasks[layer][xpos];
|
UINT8 clipmask = snes_ppu.clipmasks[layer][xpos];
|
||||||
@ -921,56 +747,18 @@ static void snes_update_line_mode7( UINT16 curline, UINT8 layer, UINT8 priority_
|
|||||||
#endif /* SNES_LAYER_DEBUG */
|
#endif /* SNES_LAYER_DEBUG */
|
||||||
|
|
||||||
/* Clip to windows */
|
/* Clip to windows */
|
||||||
if (scanlines[SNES_MAINSCREEN].clip)
|
if (scanlines[screen].clip)
|
||||||
clr &= clipmask;
|
clr &= clipmask;
|
||||||
|
|
||||||
/* Draw pixel if appropriate */
|
/* Draw pixel if appropriate */
|
||||||
if (scanlines[SNES_MAINSCREEN].priority[xpos] <= priority && clr > 0)
|
if (scanlines[screen].priority[xpos] <= priority && clr > 0)
|
||||||
{
|
{
|
||||||
/* Direct select, but only outside EXTBG! */
|
/* Direct select, but only outside EXTBG! */
|
||||||
if (snes_ppu.direct_color && layer == SNES_BG1)
|
// Direct color format is: 0 | BB000 | GGG00 | RRR00, HW confirms that the data is zero padded.
|
||||||
{
|
// In other words, like normal direct color, with pal = 0
|
||||||
/* 0 | BB000 | GGG00 | RRR00, HW confirms that the data is zero padded. */
|
c = snes_get_bgcolor(snes_ppu.direct_color && layer == SNES_BG1, 0, clr);
|
||||||
c = ((clr & 0x07) << 2) | ((clr & 0x38) << 4) | ((clr & 0xc0) << 7);
|
snes_set_scanline_pixel(screen, xpos, c, priority, layer, 0);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
c = snes_cgram[clr];
|
|
||||||
|
|
||||||
scanlines[SNES_MAINSCREEN].buffer[xpos] = c;
|
|
||||||
scanlines[SNES_MAINSCREEN].priority[xpos] = priority;
|
|
||||||
scanlines[SNES_MAINSCREEN].layer[xpos] = layer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scanlines[SNES_SUBSCREEN].enable)
|
|
||||||
{
|
|
||||||
UINT8 clr = colour;
|
|
||||||
UINT8 clipmask = snes_ppu.clipmasks[layer][xpos];
|
|
||||||
|
|
||||||
#ifdef SNES_LAYER_DEBUG
|
|
||||||
if (debug_options.windows_disabled)
|
|
||||||
clipmask = 0xff;
|
|
||||||
#endif /* SNES_LAYER_DEBUG */
|
|
||||||
|
|
||||||
/* Clip to windows */
|
|
||||||
if (scanlines[SNES_SUBSCREEN].clip)
|
|
||||||
clr &= clipmask;
|
|
||||||
|
|
||||||
/* Draw pixel if appropriate */
|
|
||||||
if (scanlines[SNES_SUBSCREEN].priority[xpos] <= priority && clr > 0)
|
|
||||||
{
|
|
||||||
/* Direct select, but only outside EXTBG! */
|
|
||||||
if (snes_ppu.direct_color && layer == SNES_BG1)
|
|
||||||
{
|
|
||||||
/* 0 | BB000 | GGG00 | RRR00, HW confirms that the data is zero padded. */
|
|
||||||
c = ((clr & 0x07) << 2) | ((clr & 0x38) << 4) | ((clr & 0xc0) << 7);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
c = snes_cgram[clr];
|
|
||||||
|
|
||||||
scanlines[SNES_SUBSCREEN].buffer[xpos] = c;
|
|
||||||
scanlines[SNES_SUBSCREEN].priority[xpos] = priority;
|
|
||||||
scanlines[SNES_SUBSCREEN].layer[xpos] = layer;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1327,7 +1115,8 @@ static void snes_update_objects( UINT8 priority_oam0, UINT8 priority_oam1, UINT8
|
|||||||
}
|
}
|
||||||
#endif /* SNES_LAYER_DEBUG */
|
#endif /* SNES_LAYER_DEBUG */
|
||||||
|
|
||||||
snes_draw_tile_object(charaddr + oam_tilelist[tile].tileaddr, oam_tilelist[tile].x, pri, oam_tilelist[tile].hflip, oam_tilelist[tile].pal);
|
/* OAM tiles have fixed planes (4), fixed tile_size (8x8), no direct color and no hires, but otherwise work the same as BG ones */
|
||||||
|
snes_draw_tile(4, SNES_OAM, charaddr + oam_tilelist[tile].tileaddr, oam_tilelist[tile].x, 0, pri, oam_tilelist[tile].hflip, 0, oam_tilelist[tile].pal, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1763,7 +1552,7 @@ static void snes_refresh_scanline( running_machine *machine, bitmap_t *bitmap, U
|
|||||||
snes_update_obsel();
|
snes_update_obsel();
|
||||||
|
|
||||||
#ifdef SNES_LAYER_DEBUG
|
#ifdef SNES_LAYER_DEBUG
|
||||||
if (snes_dbg_video(machine, bitmap, curline))
|
if (snes_dbg_video(machine, curline))
|
||||||
{
|
{
|
||||||
profiler_mark_end();
|
profiler_mark_end();
|
||||||
return;
|
return;
|
||||||
@ -1870,7 +1659,6 @@ VIDEO_START( snes )
|
|||||||
{
|
{
|
||||||
#ifdef SNES_LAYER_DEBUG
|
#ifdef SNES_LAYER_DEBUG
|
||||||
memset(&debug_options, 0, sizeof(debug_options));
|
memset(&debug_options, 0, sizeof(debug_options));
|
||||||
debug_options.input_count = 5;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1891,13 +1679,21 @@ VIDEO_UPDATE( snes )
|
|||||||
|
|
||||||
#ifdef SNES_LAYER_DEBUG
|
#ifdef SNES_LAYER_DEBUG
|
||||||
|
|
||||||
static UINT8 snes_dbg_video( running_machine *machine, bitmap_t *bitmap, UINT16 curline )
|
#define DEBUG_TOGGLE(bit, debug_settings, MSG1, MSG2) \
|
||||||
|
if (BIT(toggles, bit) && !debug_settings) \
|
||||||
|
{ \
|
||||||
|
debug_settings = 1; \
|
||||||
|
popmessage MSG1; \
|
||||||
|
} \
|
||||||
|
else if (!BIT(toggles, bit) && debug_settings) \
|
||||||
|
{ \
|
||||||
|
debug_settings = 0; \
|
||||||
|
popmessage MSG2; \
|
||||||
|
} \
|
||||||
|
|
||||||
|
|
||||||
|
static UINT8 snes_dbg_video( running_machine *machine, UINT16 curline )
|
||||||
{
|
{
|
||||||
/* Check if the user has enabled or disabled stuff */
|
|
||||||
if (curline == 1)
|
|
||||||
{
|
|
||||||
if (!debug_options.input_count--)
|
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
UINT8 toggles = input_port_read_safe(machine, "DEBUG1", 0);
|
UINT8 toggles = input_port_read_safe(machine, "DEBUG1", 0);
|
||||||
debug_options.select_pri[SNES_BG1] = (toggles & 0x03);
|
debug_options.select_pri[SNES_BG1] = (toggles & 0x03);
|
||||||
@ -1907,57 +1703,25 @@ static UINT8 snes_dbg_video( running_machine *machine, bitmap_t *bitmap, UINT16
|
|||||||
|
|
||||||
toggles = input_port_read_safe(machine, "DEBUG2", 0);
|
toggles = input_port_read_safe(machine, "DEBUG2", 0);
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
{
|
DEBUG_TOGGLE(i, debug_options.bg_disabled[i], ("Debug: Disabled BG%d.\n", i + 1), ("Debug: Enabled BG%d.\n", i + 1))
|
||||||
if (BIT(toggles, i))
|
DEBUG_TOGGLE(4, debug_options.bg_disabled[SNES_OAM], ("Debug: Disabled OAM.\n"), ("Debug: Enabled OAM.\n"))
|
||||||
{
|
DEBUG_TOGGLE(5, debug_options.draw_subscreen, ("Debug: Switched screens.\n"), ("Debug: Switched screens.\n"))
|
||||||
debug_options.bg_disabled[i] = !debug_options.bg_disabled[i];
|
DEBUG_TOGGLE(6, debug_options.colormath_disabled, ("Debug: Disabled Color Math.\n"), ("Debug: Enabled Color Math.\n"))
|
||||||
popmessage("Debug: %s BG%d.\n", debug_options.bg_disabled[i] ? "Disabled" : "Enabled", i + 1);
|
DEBUG_TOGGLE(7, debug_options.windows_disabled, ("Debug: Disabled Window Masks.\n"), ("Debug: Enabled Window Masks.\n"))
|
||||||
}
|
|
||||||
}
|
|
||||||
if (BIT(toggles, 4))
|
|
||||||
{
|
|
||||||
debug_options.bg_disabled[SNES_OAM] = !debug_options.bg_disabled[SNES_OAM];
|
|
||||||
popmessage("Debug: %s OAM.\n", debug_options.bg_disabled[SNES_OAM] ? "Disabled" : "Enabled");
|
|
||||||
}
|
|
||||||
if (BIT(toggles, 5))
|
|
||||||
{
|
|
||||||
debug_options.draw_subscreen = !debug_options.draw_subscreen;
|
|
||||||
popmessage("Debug: Switched screens.\n");
|
|
||||||
}
|
|
||||||
if (BIT(toggles, 6))
|
|
||||||
{
|
|
||||||
debug_options.colormath_disabled = !debug_options.colormath_disabled;
|
|
||||||
popmessage("Debug: %s Color Math.\n", debug_options.colormath_disabled ? "Disabled" : "Enabled");
|
|
||||||
}
|
|
||||||
if (BIT(toggles, 7))
|
|
||||||
{
|
|
||||||
debug_options.windows_disabled = !debug_options.windows_disabled;
|
|
||||||
popmessage("Debug: %s Window Masks.\n", debug_options.windows_disabled ? "Disabled" : "Enabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
toggles = input_port_read_safe(machine, "DEBUG4", 0);
|
toggles = input_port_read_safe(machine, "DEBUG4", 0);
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
{
|
DEBUG_TOGGLE(i, debug_options.mode_disabled[i], ("Debug: Disabled Mode %d drawing.\n", i), ("Debug: Enabled Mode %d drawing.\n", i))
|
||||||
if (BIT(toggles, i))
|
|
||||||
{
|
|
||||||
debug_options.mode_disabled[i] = !debug_options.mode_disabled[i];
|
|
||||||
popmessage("Debug: %s Mode %d drawing.\n", debug_options.mode_disabled[i] ? "Disabled" : "Enabled", i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
toggles = input_port_read_safe(machine, "DEBUG3", 0);
|
toggles = input_port_read_safe(machine, "DEBUG3", 0);
|
||||||
if (toggles & 0x4)
|
DEBUG_TOGGLE(2, debug_options.mosaic_disabled, ("Debug: Disabled Mosaic.\n"), ("Debug: Enabled Mosaic.\n"))
|
||||||
{
|
|
||||||
debug_options.mosaic_disabled = !debug_options.mosaic_disabled;
|
|
||||||
popmessage("Debug: %s Mosaic.\n", debug_options.mosaic_disabled ? "Disabled" : "Enabled");
|
|
||||||
}
|
|
||||||
debug_options.sprite_reversed = BIT(toggles, 7);
|
debug_options.sprite_reversed = BIT(toggles, 7);
|
||||||
debug_options.select_pri[SNES_OAM] = (toggles & 0x70) >> 4;
|
debug_options.select_pri[SNES_OAM] = (toggles & 0x70) >> 4;
|
||||||
|
|
||||||
debug_options.input_count = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MAME_DEBUG
|
#ifdef MAME_DEBUG
|
||||||
|
/* Once per frame, log video properties */
|
||||||
|
if (curline == 1)
|
||||||
|
{
|
||||||
static const char WINLOGIC[4] = { '|', '&', '^', '!' };
|
static const char WINLOGIC[4] = { '|', '&', '^', '!' };
|
||||||
|
|
||||||
logerror("%s", debug_options.windows_disabled?" ":"W");
|
logerror("%s", debug_options.windows_disabled?" ":"W");
|
||||||
@ -2046,8 +1810,8 @@ static UINT8 snes_dbg_video( running_machine *machine, bitmap_t *bitmap, UINT16
|
|||||||
logerror("Mode7: A %5d B %5d", snes_ppu.mode7.matrix_a, snes_ppu.mode7.matrix_b );
|
logerror("Mode7: A %5d B %5d", snes_ppu.mode7.matrix_a, snes_ppu.mode7.matrix_b );
|
||||||
logerror(" %s%s%s C %5d D %5d", (snes_ram[M7SEL] & 0xc0)?((snes_ram[M7SEL] & 0x40)?"0":"C"):"R", (snes_ram[M7SEL] & 0x1)?"H":" ", (snes_ram[M7SEL] & 0x2)?"V":" ", snes_ppu.mode7.matrix_c, snes_ppu.mode7.matrix_d );
|
logerror(" %s%s%s C %5d D %5d", (snes_ram[M7SEL] & 0xc0)?((snes_ram[M7SEL] & 0x40)?"0":"C"):"R", (snes_ram[M7SEL] & 0x1)?"H":" ", (snes_ram[M7SEL] & 0x2)?"V":" ", snes_ppu.mode7.matrix_c, snes_ppu.mode7.matrix_d );
|
||||||
logerror(" X %5d Y %5d", snes_ppu.mode7.origin_x, snes_ppu.mode7.origin_y );
|
logerror(" X %5d Y %5d", snes_ppu.mode7.origin_x, snes_ppu.mode7.origin_y );
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user