mirror of
https://github.com/holub/mame
synced 2025-05-29 00:53:09 +03:00
Commit of Robert Bohms' NES PPU updates (please refer to his -emails for details)
Also, not worth mention, I've done some readability tweaks and fixed some crashes in cham24 and multigam (due to wrong copy and paste in the original diffs). multigam.c games still have some issues (which I'm trying to fix with Rob's help)
This commit is contained in:
parent
6cdff80638
commit
fd631b29b6
@ -60,6 +60,54 @@ Notes:
|
||||
#include "sound/nes_apu.h"
|
||||
#include "video/ppu2c0x.h"
|
||||
|
||||
static UINT8* nt_ram;
|
||||
static UINT8* nt_page[4];
|
||||
|
||||
void cham24_set_mirroring( int mirroring )
|
||||
{
|
||||
switch(mirroring)
|
||||
{
|
||||
case PPU_MIRROR_LOW:
|
||||
nt_page[0] = nt_page[1] = nt_page[2] = nt_page[3] = nt_ram;
|
||||
break;
|
||||
case PPU_MIRROR_HIGH:
|
||||
nt_page[0] = nt_page[1] = nt_page[2] = nt_page[3] = nt_ram + 0x400;
|
||||
break;
|
||||
case PPU_MIRROR_HORZ:
|
||||
nt_page[0] = nt_ram;
|
||||
nt_page[1] = nt_ram;
|
||||
nt_page[2] = nt_ram + 0x400;
|
||||
nt_page[3] = nt_ram + 0x400;
|
||||
break;
|
||||
case PPU_MIRROR_VERT:
|
||||
nt_page[0] = nt_ram;
|
||||
nt_page[1] = nt_ram + 0x400;
|
||||
nt_page[2] = nt_ram;
|
||||
nt_page[3] = nt_ram + 0x400;
|
||||
break;
|
||||
case PPU_MIRROR_NONE:
|
||||
default:
|
||||
nt_page[0] = nt_ram;
|
||||
nt_page[1] = nt_ram + 0x400;
|
||||
nt_page[2] = nt_ram + 0x800;
|
||||
nt_page[3] = nt_ram + 0xc00;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( nt_w )
|
||||
{
|
||||
int page = ((offset & 0xc00) >> 10);
|
||||
nt_page[page][offset & 0x3ff] = data;
|
||||
}
|
||||
|
||||
static READ8_HANDLER( nt_r )
|
||||
{
|
||||
int page = ((offset & 0xc00) >> 10);
|
||||
return nt_page[page][offset & 0x3ff];
|
||||
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( sprite_dma_w )
|
||||
{
|
||||
int source = (data & 7);
|
||||
@ -123,16 +171,15 @@ static WRITE8_HANDLER( cham24_mapper_w )
|
||||
UINT32 prg_bank = (offset >> 7) & 0x1f;
|
||||
UINT32 prg_bank_page_size = (offset >> 12) & 0x01;
|
||||
UINT32 gfx_mirroring = (offset >> 13) & 0x01;
|
||||
const device_config *ppu = devtag_get_device(space->machine, "ppu");
|
||||
|
||||
UINT8* dst = memory_region(space->machine, "maincpu");
|
||||
UINT8* src = memory_region(space->machine, "user1");
|
||||
|
||||
// switch PPU VROM bank
|
||||
ppu2c0x_set_videorom_bank( ppu, 0, 8, gfx_bank, 512 );
|
||||
memory_set_bankptr(space->machine, 1, memory_region(space->machine, "gfx1") + (0x2000 * gfx_bank));
|
||||
|
||||
// set gfx mirroring
|
||||
ppu2c0x_set_mirroring( ppu, gfx_mirroring != 0 ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT );
|
||||
cham24_set_mirroring(gfx_mirroring != 0 ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
|
||||
|
||||
// switch PRG bank
|
||||
if (prg_bank_page_size == 0)
|
||||
@ -188,7 +235,6 @@ static INPUT_PORTS_START( cham24 )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
|
||||
|
||||
INPUT_PORTS_END
|
||||
|
||||
static const nes_interface cham24_interface_1 =
|
||||
@ -239,6 +285,15 @@ static VIDEO_UPDATE( cham24 )
|
||||
|
||||
static DRIVER_INIT( cham24 )
|
||||
{
|
||||
/* uses 8K swapping, all ROM!*/
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0x0000, 0x1fff, 0, 0, SMH_BANK(1), 0);
|
||||
memory_set_bankptr(machine, 1, memory_region(machine, "gfx1"));
|
||||
|
||||
/* need nametable ram, though. I doubt this uses more than 2k, but it starts up configured for 4 */
|
||||
nt_ram = auto_alloc_array(machine, UINT8, 0x1000);
|
||||
|
||||
/* and read/write handlers */
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0x2000, 0x3eff, 0, 0, nt_r, nt_w);
|
||||
}
|
||||
|
||||
static GFXDECODE_START( cham24 )
|
||||
|
@ -45,6 +45,69 @@
|
||||
#include "sound/nes_apu.h"
|
||||
#include "video/ppu2c0x.h"
|
||||
|
||||
/******************************************************
|
||||
|
||||
PPU external bus interface
|
||||
|
||||
*******************************************************/
|
||||
static UINT8* nt_ram;
|
||||
static UINT8* nt_page[4];
|
||||
|
||||
void set_mirroring(int mirroring)
|
||||
{
|
||||
switch(mirroring)
|
||||
{
|
||||
case PPU_MIRROR_LOW:
|
||||
nt_page[0] = nt_page[1] = nt_page[2] = nt_page[3] = nt_ram;
|
||||
break;
|
||||
case PPU_MIRROR_HIGH:
|
||||
nt_page[0] = nt_page[1] = nt_page[2] = nt_page[3] = nt_ram + 0x400;
|
||||
break;
|
||||
case PPU_MIRROR_HORZ:
|
||||
nt_page[0] = nt_ram;
|
||||
nt_page[1] = nt_ram;
|
||||
nt_page[2] = nt_ram + 0x400;
|
||||
nt_page[3] = nt_ram + 0x400;
|
||||
break;
|
||||
case PPU_MIRROR_VERT:
|
||||
nt_page[0] = nt_ram;
|
||||
nt_page[1] = nt_ram + 0x400;
|
||||
nt_page[2] = nt_ram;
|
||||
nt_page[3] = nt_ram + 0x400;
|
||||
break;
|
||||
case PPU_MIRROR_NONE:
|
||||
default:
|
||||
nt_page[0] = nt_ram;
|
||||
nt_page[1] = nt_ram + 0x400;
|
||||
nt_page[2] = nt_ram + 0x800;
|
||||
nt_page[3] = nt_ram + 0xc00;
|
||||
break;
|
||||
}
|
||||
}
|
||||
static WRITE8_HANDLER (multigam_nt_w)
|
||||
{
|
||||
int page = ((offset & 0xc00) >> 10);
|
||||
nt_page[page][offset & 0x3ff] = data;
|
||||
}
|
||||
static READ8_HANDLER (multigam_nt_r)
|
||||
{
|
||||
int page = ((offset & 0xc00) >> 10);
|
||||
return nt_page[page][offset & 0x3ff];
|
||||
}
|
||||
|
||||
void set_videorom_bank(running_machine* machine, int start, int count, int bank, int bank_size_in_kb)
|
||||
{
|
||||
int i, j;
|
||||
int offset = bank * (bank_size_in_kb * 0x400);
|
||||
/* bank_size_in_kb is used to determine how large the "bank" parameter is */
|
||||
/* count determines the size of the area mapped in KB */
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
j = i + start + 1;
|
||||
memory_set_bankptr(machine, j, memory_region(machine, "gfx1") + offset);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
|
||||
NES interface
|
||||
@ -151,9 +214,8 @@ static WRITE8_HANDLER(multigam_switch_prg_rom)
|
||||
|
||||
static WRITE8_HANDLER(multigam_switch_gfx_rom)
|
||||
{
|
||||
const device_config *ppu = devtag_get_device(space->machine, "ppu");
|
||||
ppu2c0x_set_videorom_bank( ppu, 0, 8, data /*& 0x3f*/, 512 );
|
||||
ppu2c0x_set_mirroring( ppu, data & 0x40 ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT );
|
||||
memory_set_bankptr(space->machine, 1, memory_region(space->machine, "gfx1") + (0x2000 * data));
|
||||
set_mirroring(data & 0x40 ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
|
||||
multigam_game_gfx_bank = data;
|
||||
};
|
||||
|
||||
@ -162,8 +224,7 @@ static WRITE8_HANDLER(multigam_mapper2_w)
|
||||
{
|
||||
if (multigam_game_gfx_bank & 0x80)
|
||||
{
|
||||
const device_config *ppu = devtag_get_device(space->machine, "ppu");
|
||||
ppu2c0x_set_videorom_bank( ppu, 0, 8, multigam_game_gfx_bank + (data & 0xf), 512 );
|
||||
memory_set_bankptr(space->machine, 1, memory_region(space->machine, "gfx1") + (0x2000 * ((data & 0xf) + multigam_game_gfx_bank)));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -276,7 +337,7 @@ static WRITE8_HANDLER( multigam3_mmc3_rom_switch_w )
|
||||
case 1: /* char banking */
|
||||
data &= 0xfe;
|
||||
page ^= (cmd << 1);
|
||||
ppu2c0x_set_videorom_bank( ppu, page, 2, 0x180 + data, 64 );
|
||||
set_videorom_bank(space->machine, page, 2, 0x180 + data, 1);
|
||||
break;
|
||||
|
||||
case 2: /* char banking */
|
||||
@ -284,7 +345,7 @@ static WRITE8_HANDLER( multigam3_mmc3_rom_switch_w )
|
||||
case 4: /* char banking */
|
||||
case 5: /* char banking */
|
||||
page ^= cmd + 2;
|
||||
ppu2c0x_set_videorom_bank( ppu, page, 1, 0x180 + data, 64 );
|
||||
set_videorom_bank(space->machine, page, 1, 0x180 + data, 1);
|
||||
break;
|
||||
|
||||
case 6: /* program banking */
|
||||
@ -332,9 +393,9 @@ static WRITE8_HANDLER( multigam3_mmc3_rom_switch_w )
|
||||
if (!multigam3_mmc3_4screen)
|
||||
{
|
||||
if (data & 0x40)
|
||||
ppu2c0x_set_mirroring( ppu, PPU_MIRROR_HIGH );
|
||||
set_mirroring(PPU_MIRROR_HIGH);
|
||||
else
|
||||
ppu2c0x_set_mirroring( ppu, ( data & 1 ) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT );
|
||||
set_mirroring((data & 1) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -385,8 +446,7 @@ static WRITE8_HANDLER(multigm3_mapper2_w)
|
||||
{
|
||||
if (multigam_game_gfx_bank & 0x80)
|
||||
{
|
||||
const device_config *ppu = devtag_get_device(space->machine, "ppu");
|
||||
ppu2c0x_set_videorom_bank( ppu, 0, 8, (multigam_game_gfx_bank & 0xfc) + (data & 0x3), 512 );
|
||||
set_videorom_bank(space->machine, 0, 8, (multigam_game_gfx_bank & 0xfc) + (data & 0x3), 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -580,6 +640,28 @@ static MACHINE_RESET( multigm3 )
|
||||
multigm3_switch_prg_rom(space, 0, 0x01 );
|
||||
};
|
||||
|
||||
static MACHINE_START( multigam )
|
||||
{
|
||||
nt_ram = auto_alloc_array(machine, UINT8, 0x1000);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0x2000, 0x3eff, 0, 0, multigam_nt_r, multigam_nt_w);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0x0000, 0x1fff, 0, 0, SMH_BANK(1), 0);
|
||||
memory_set_bankptr(machine, 1, memory_region(machine, "gfx1"));
|
||||
}
|
||||
|
||||
static MACHINE_START( multigm3 )
|
||||
{
|
||||
nt_ram = auto_alloc_array(machine, UINT8, 0x1000);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0x2000, 0x3eff, 0, 0, multigam_nt_r, multigam_nt_w);
|
||||
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0x0000, 0x03ff, 0, 0, SMH_BANK(1), 0);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0x0400, 0x07ff, 0, 0, SMH_BANK(2), 0);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0x0800, 0x0bff, 0, 0, SMH_BANK(3), 0);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0x0c00, 0x0fff, 0, 0, SMH_BANK(4), 0);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0x1000, 0x13ff, 0, 0, SMH_BANK(5), 0);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0x1400, 0x17ff, 0, 0, SMH_BANK(6), 0);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0x1800, 0x1bff, 0, 0, SMH_BANK(7), 0);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0x1c00, 0x1fff, 0, 0, SMH_BANK(8), 0);
|
||||
};
|
||||
|
||||
static MACHINE_DRIVER_START( multigam )
|
||||
/* basic machine hardware */
|
||||
@ -587,6 +669,7 @@ static MACHINE_DRIVER_START( multigam )
|
||||
MDRV_CPU_PROGRAM_MAP(multigam_map)
|
||||
|
||||
MDRV_MACHINE_RESET( multigam )
|
||||
MDRV_MACHINE_START( multigam )
|
||||
|
||||
/* video hardware */
|
||||
MDRV_SCREEN_ADD("screen", RASTER)
|
||||
@ -620,6 +703,7 @@ static MACHINE_DRIVER_START( multigm3 )
|
||||
MDRV_CPU_MODIFY("maincpu")
|
||||
MDRV_CPU_PROGRAM_MAP(multigm3_map)
|
||||
|
||||
MDRV_MACHINE_START( multigm3 )
|
||||
MDRV_MACHINE_RESET( multigm3 )
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
|
@ -702,6 +702,7 @@ static MACHINE_DRIVER_START( playch10 )
|
||||
MDRV_CPU_PROGRAM_MAP(cart_map)
|
||||
|
||||
MDRV_MACHINE_RESET(pc10)
|
||||
MDRV_MACHINE_START(pc10)
|
||||
|
||||
// video hardware
|
||||
MDRV_GFXDECODE(playch10)
|
||||
@ -746,6 +747,7 @@ MACHINE_DRIVER_END
|
||||
static MACHINE_DRIVER_START( playch10_hboard )
|
||||
MDRV_IMPORT_FROM(playch10)
|
||||
MDRV_VIDEO_START(playch10_hboard)
|
||||
MDRV_MACHINE_START(playch10_hboard)
|
||||
|
||||
MDRV_DEVICE_REMOVE("ppu")
|
||||
MDRV_PPU2C03B_ADD("ppu", playch10_ppu_interface)
|
||||
|
@ -1768,6 +1768,7 @@ static MACHINE_DRIVER_START( vsnes )
|
||||
MDRV_CPU_PROGRAM_MAP(vsnes_cpu1_map)
|
||||
/* some carts also trigger IRQs */
|
||||
MDRV_MACHINE_RESET(vsnes)
|
||||
MDRV_MACHINE_START(vsnes)
|
||||
|
||||
/* video hardware */
|
||||
MDRV_SCREEN_ADD("screen", RASTER)
|
||||
@ -1806,6 +1807,7 @@ static MACHINE_DRIVER_START( vsdual )
|
||||
MDRV_CPU_PROGRAM_MAP(vsnes_cpu2_map)
|
||||
/* some carts also trigger IRQs */
|
||||
MDRV_MACHINE_RESET(vsdual)
|
||||
MDRV_MACHINE_START(vsdual)
|
||||
|
||||
/* video hardware */
|
||||
MDRV_PALETTE_LENGTH(2*8*4*16)
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*----------- defined in machine/playch10.c -----------*/
|
||||
|
||||
MACHINE_RESET( pc10 );
|
||||
MACHINE_START( pc10 );
|
||||
MACHINE_START( playch10_hboard );
|
||||
DRIVER_INIT( playch10 ); /* standard games */
|
||||
DRIVER_INIT( pc_gun ); /* gun games */
|
||||
DRIVER_INIT( pc_hrz ); /* horizontal games */
|
||||
|
@ -15,6 +15,8 @@ extern const ppu2c0x_interface vsnes_ppu_interface_2;
|
||||
|
||||
MACHINE_RESET( vsnes );
|
||||
MACHINE_RESET( vsdual );
|
||||
MACHINE_START( vsnes );
|
||||
MACHINE_START( vsdual );
|
||||
DRIVER_INIT( suprmrio );
|
||||
DRIVER_INIT( excitebk );
|
||||
DRIVER_INIT( excitbkj );
|
||||
|
@ -3,6 +3,22 @@
|
||||
#include "machine/rp5h01.h"
|
||||
#include "includes/playch10.h"
|
||||
|
||||
/* prototypes */
|
||||
void pc10_set_mirroring( int mirroring );
|
||||
WRITE8_HANDLER( pc10_nt_w );
|
||||
READ8_HANDLER( pc10_nt_r );
|
||||
WRITE8_HANDLER( pc10_chr_w );
|
||||
READ8_HANDLER( pc10_chr_r );
|
||||
void pc10_set_videorom_bank( running_machine *machine, int first, int count, int bank, int size );
|
||||
void set_videoram_bank( running_machine *machine, int first, int count, int bank, int size );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int writable; // 1 for RAM, 0 for ROM
|
||||
UINT8* chr; // direct access to the memory
|
||||
} chr_bank;
|
||||
|
||||
|
||||
/* Globals */
|
||||
int pc10_sdcs; /* ShareD Chip Select */
|
||||
int pc10_dispmask; /* Display Mask */
|
||||
@ -21,14 +37,20 @@ static int mirroring;
|
||||
|
||||
static int MMC2_bank[4], MMC2_bank_latch[2];
|
||||
|
||||
static UINT8* vrom; // used for games with cart gfx loaded (a,c,e,f,g,h)
|
||||
static UINT8* vram = NULL; // used for boards h, b, d, i, k (Presumably, 8K. 16K didn't work in MESS)
|
||||
static UINT8* nametable[4]; // For non-mirroring boards, this can be moved to a direct mapping
|
||||
static UINT8* nt_ram = NULL; // Per-board size! Some boards clearly need 4K. Some MAY use 2K. Research needed.
|
||||
static chr_bank chr_page[8]; // Simple wrapper for ROM/RAM, since we could be banking either (Hboard)
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Init machine
|
||||
*
|
||||
*************************************/
|
||||
|
||||
MACHINE_RESET( pc10 )
|
||||
{
|
||||
const device_config *ppu = devtag_get_device(machine, "ppu");
|
||||
const device_config *rp5h01 = devtag_get_device(machine, "rp5h01");
|
||||
|
||||
/* initialize latches and flip-flops */
|
||||
@ -51,7 +73,39 @@ MACHINE_RESET( pc10 )
|
||||
rp5h01_reset_w(rp5h01, 0, 1);
|
||||
rp5h01_enable_w(rp5h01, 0, 1);
|
||||
|
||||
ppu2c0x_set_mirroring( ppu, mirroring );
|
||||
pc10_set_mirroring(mirroring);
|
||||
}
|
||||
|
||||
MACHINE_START( pc10 )
|
||||
{
|
||||
vrom = memory_region(machine, "gfx2");
|
||||
|
||||
/* allocate 4K of nametable ram here */
|
||||
/* move to individual boards as documentation of actual boards allows */
|
||||
nt_ram = auto_alloc_array(machine, UINT8, 0x1000);
|
||||
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0, 0x1fff, 0, 0, pc10_chr_r, pc10_chr_w);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0x2000, 0x3eff, 0, 0, pc10_nt_r, pc10_nt_w);
|
||||
|
||||
if (NULL != vram)
|
||||
set_videoram_bank(machine, 0, 8, 0, 8);
|
||||
else pc10_set_videorom_bank(machine, 0, 8, 0, 8);
|
||||
|
||||
}
|
||||
|
||||
MACHINE_START( playch10_hboard )
|
||||
{
|
||||
vrom = memory_region(machine, "gfx2");
|
||||
|
||||
/* allocate 4K of nametable ram here */
|
||||
/* move to individual boards as documentation of actual boards allows */
|
||||
nt_ram = auto_alloc_array(machine, UINT8, 0x1000);
|
||||
/* allocate vram */
|
||||
|
||||
vram = auto_alloc_array(machine, UINT8, 0x2000);
|
||||
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0, 0x1fff, 0, 0, pc10_chr_r, pc10_chr_w);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0x2000, 0x3eff, 0, 0, pc10_nt_r, pc10_nt_w);
|
||||
}
|
||||
|
||||
/*************************************
|
||||
@ -136,6 +190,7 @@ WRITE8_HANDLER( pc10_CARTSEL_w )
|
||||
* RP5H01 handling
|
||||
*
|
||||
*************************************/
|
||||
|
||||
READ8_HANDLER( pc10_prot_r )
|
||||
{
|
||||
const device_config *rp5h01 = devtag_get_device(space->machine, "rp5h01");
|
||||
@ -179,6 +234,7 @@ WRITE8_HANDLER( pc10_prot_w )
|
||||
* Input Ports
|
||||
*
|
||||
*************************************/
|
||||
|
||||
WRITE8_HANDLER( pc10_in0_w )
|
||||
{
|
||||
/* Toggling bit 0 high then low resets both controllers */
|
||||
@ -256,15 +312,135 @@ READ8_HANDLER( pc10_in1_r )
|
||||
|
||||
return ret;
|
||||
}
|
||||
/*************************************
|
||||
*
|
||||
* PPU External bus handlers
|
||||
*
|
||||
*************************************/
|
||||
|
||||
WRITE8_HANDLER( pc10_nt_w )
|
||||
{
|
||||
int page = ((offset & 0xc00) >> 10);
|
||||
nametable[page][offset & 0x3ff] = data;
|
||||
}
|
||||
|
||||
READ8_HANDLER( pc10_nt_r )
|
||||
{
|
||||
int page = ((offset & 0xc00) >> 10);
|
||||
return nametable[page][offset & 0x3ff];
|
||||
}
|
||||
|
||||
WRITE8_HANDLER( pc10_chr_w )
|
||||
{
|
||||
int bank = offset >> 10;
|
||||
if (chr_page[bank].writable)
|
||||
{
|
||||
chr_page[bank].chr[offset & 0x3ff] = data;
|
||||
}
|
||||
}
|
||||
|
||||
READ8_HANDLER( pc10_chr_r )
|
||||
{
|
||||
int bank = offset >> 10;
|
||||
return chr_page[bank].chr[offset & 0x3ff];
|
||||
}
|
||||
|
||||
|
||||
void pc10_set_mirroring( int mirroring )
|
||||
{
|
||||
switch (mirroring)
|
||||
{
|
||||
case PPU_MIRROR_LOW:
|
||||
nametable[0] = nametable[1] = nametable[2] = nametable[3] = nt_ram;
|
||||
break;
|
||||
case PPU_MIRROR_HIGH:
|
||||
nametable[0] = nametable[1] = nametable[2] = nametable[3] = nt_ram + 0x400;
|
||||
break;
|
||||
case PPU_MIRROR_HORZ:
|
||||
nametable[0] = nt_ram;
|
||||
nametable[1] = nt_ram;
|
||||
nametable[2] = nt_ram + 0x400;
|
||||
nametable[3] = nt_ram + 0x400;
|
||||
break;
|
||||
case PPU_MIRROR_VERT:
|
||||
nametable[0] = nt_ram;
|
||||
nametable[1] = nt_ram + 0x400;
|
||||
nametable[2] = nt_ram;
|
||||
nametable[3] = nt_ram + 0x400;
|
||||
break;
|
||||
case PPU_MIRROR_NONE:
|
||||
default:
|
||||
nametable[0] = nt_ram;
|
||||
nametable[1] = nt_ram + 0x400;
|
||||
nametable[2] = nt_ram + 0x800;
|
||||
nametable[3] = nt_ram + 0xc00;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* SIZE MAPPINGS *\
|
||||
* old new *
|
||||
* 512 8 *
|
||||
* 256 4 *
|
||||
* 128 2 *
|
||||
* 64 1 *
|
||||
\*****************/
|
||||
|
||||
void pc10_set_videorom_bank( running_machine *machine, int first, int count, int bank, int size )
|
||||
{
|
||||
int i, len;
|
||||
/* first = first bank to map */
|
||||
/* count = number of 1K banks to map */
|
||||
/* bank = index of the bank */
|
||||
/* size = size of indexed banks (in KB) */
|
||||
/* note that this follows the original PPU banking and might be overly complex */
|
||||
|
||||
/* yeah, this is probably a horrible assumption to make.*/
|
||||
/* but the driver is 100% consistant */
|
||||
|
||||
len = memory_region_length(machine, "gfx2");
|
||||
len /= 0x400; // convert to KB
|
||||
len /= size; // convert to bank resolution
|
||||
len--; // convert to mask
|
||||
bank &= len; // should be the right mask
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
chr_page[i + first].writable = 0;
|
||||
chr_page[i + first].chr=vrom + (i * 0x400) + (bank * size * 0x400);
|
||||
}
|
||||
}
|
||||
|
||||
void set_videoram_bank( running_machine *machine, int first, int count, int bank, int size )
|
||||
{
|
||||
int i;
|
||||
/* first = first bank to map */
|
||||
/* count = number of 1K banks to map */
|
||||
/* bank = index of the bank */
|
||||
/* size = size of indexed banks (in KB) */
|
||||
/* note that this follows the original PPU banking and might be overly complex */
|
||||
|
||||
/* assumes 8K of vram */
|
||||
/* need 8K to fill address space */
|
||||
/* only pinbot (8k) banks at all */
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
chr_page[i + first].writable = 1;
|
||||
chr_page[i + first].chr = vram + (((i * 0x400) + (bank * size * 0x400)) & 0x1fff);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Common init for all games
|
||||
*
|
||||
*************************************/
|
||||
|
||||
DRIVER_INIT( playch10 )
|
||||
{
|
||||
vram = NULL;
|
||||
|
||||
/* set the controller to default */
|
||||
pc10_gun_controller = 0;
|
||||
|
||||
@ -285,6 +461,9 @@ DRIVER_INIT( pc_gun )
|
||||
/* common init */
|
||||
DRIVER_INIT_CALL(playch10);
|
||||
|
||||
/* we have no vram, make sure switching games doesn't point to an old allocation */
|
||||
vram = NULL;
|
||||
|
||||
/* set the control type */
|
||||
pc10_gun_controller = 1;
|
||||
}
|
||||
@ -337,8 +516,6 @@ static WRITE8_HANDLER( mmc1_rom_switch_w )
|
||||
/* are we done shifting? */
|
||||
if (mmc1_shiftcount == 5)
|
||||
{
|
||||
const device_config *ppu = devtag_get_device(space->machine, "ppu");
|
||||
|
||||
/* reset count */
|
||||
mmc1_shiftcount = 0;
|
||||
|
||||
@ -374,17 +551,17 @@ static WRITE8_HANDLER( mmc1_rom_switch_w )
|
||||
}
|
||||
|
||||
/* apply mirroring */
|
||||
ppu2c0x_set_mirroring( ppu, _mirroring );
|
||||
pc10_set_mirroring(_mirroring);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: /* video rom banking - bank 0 - 4k or 8k */
|
||||
ppu2c0x_set_videorom_bank( ppu, 0, ( vrom4k ) ? 4 : 8, ( mmc1_shiftreg & 0x1f ), 256 );
|
||||
pc10_set_videorom_bank(space->machine, 0, (vrom4k) ? 4 : 8, (mmc1_shiftreg & 0x1f), 4);
|
||||
break;
|
||||
|
||||
case 2: /* video rom banking - bank 1 - 4k only */
|
||||
if (vrom4k)
|
||||
ppu2c0x_set_videorom_bank( ppu, 4, 4, ( mmc1_shiftreg & 0x1f ), 256 );
|
||||
pc10_set_videorom_bank(space->machine, 4, 4, (mmc1_shiftreg & 0x1f), 4);
|
||||
break;
|
||||
|
||||
case 3: /* program banking */
|
||||
@ -418,13 +595,11 @@ static WRITE8_HANDLER( mmc1_rom_switch_w )
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
/* A Board games (Track & Field, Gradius) */
|
||||
|
||||
static WRITE8_HANDLER( aboard_vrom_switch_w )
|
||||
{
|
||||
const device_config *ppu = devtag_get_device(space->machine, "ppu");
|
||||
ppu2c0x_set_videorom_bank( ppu, 0, 8, ( data & 3 ), 512 );
|
||||
pc10_set_videorom_bank(space->machine, 0, 8, (data & 3), 8);
|
||||
}
|
||||
|
||||
DRIVER_INIT( pcaboard )
|
||||
@ -437,10 +612,12 @@ DRIVER_INIT( pcaboard )
|
||||
|
||||
/* set the mirroring here */
|
||||
mirroring = PPU_MIRROR_VERT;
|
||||
|
||||
/* we have no vram, make sure switching games doesn't point to an old allocation */
|
||||
vram = NULL;
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
/* B Board games (Contra, Rush N' Attach, Pro Wrestling) */
|
||||
|
||||
static WRITE8_HANDLER( bboard_rom_switch_w )
|
||||
@ -465,18 +642,21 @@ DRIVER_INIT( pcbboard )
|
||||
/* common init */
|
||||
DRIVER_INIT_CALL(playch10);
|
||||
|
||||
/* allocate vram */
|
||||
vram = auto_alloc_array(machine, UINT8, 0x2000);
|
||||
|
||||
/* set the mirroring here */
|
||||
mirroring = PPU_MIRROR_VERT;
|
||||
/* special init */
|
||||
set_videoram_bank(machine, 0, 8, 0, 8);
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
/* C Board games (The Goonies) */
|
||||
|
||||
static WRITE8_HANDLER( cboard_vrom_switch_w )
|
||||
{
|
||||
const device_config *ppu = devtag_get_device(space->machine, "ppu");
|
||||
ppu2c0x_set_videorom_bank( ppu, 0, 8, ( ( data >> 1 ) & 1 ), 512 );
|
||||
pc10_set_videorom_bank(space->machine, 0, 8, ((data >> 1) & 1), 8);
|
||||
}
|
||||
|
||||
DRIVER_INIT( pccboard )
|
||||
@ -484,12 +664,14 @@ DRIVER_INIT( pccboard )
|
||||
/* switches vrom with writes to $6000 */
|
||||
memory_install_write8_handler(cputag_get_address_space(machine, "cart", ADDRESS_SPACE_PROGRAM), 0x6000, 0x6000, 0, 0, cboard_vrom_switch_w );
|
||||
|
||||
/* we have no vram, make sure switching games doesn't point to an old allocation */
|
||||
vram = NULL;
|
||||
|
||||
/* common init */
|
||||
DRIVER_INIT_CALL(playch10);
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
/* D Board games (Rad Racer) */
|
||||
|
||||
DRIVER_INIT( pcdboard )
|
||||
@ -505,8 +687,13 @@ DRIVER_INIT( pcdboard )
|
||||
/* MMC mapper at writes to $8000-$ffff */
|
||||
memory_install_write8_handler(cputag_get_address_space(machine, "cart", ADDRESS_SPACE_PROGRAM), 0x8000, 0xffff, 0, 0, mmc1_rom_switch_w );
|
||||
|
||||
|
||||
/* common init */
|
||||
DRIVER_INIT_CALL(playch10);
|
||||
/* allocate vram */
|
||||
vram = auto_alloc_array(machine, UINT8, 0x2000);
|
||||
/* special init */
|
||||
set_videoram_bank(machine, 0, 8, 0, 8);
|
||||
}
|
||||
|
||||
/* D Board games with extra ram (Metroid) */
|
||||
@ -519,10 +706,14 @@ DRIVER_INIT( pcdboard_2 )
|
||||
|
||||
/* common init */
|
||||
DRIVER_INIT_CALL(pcdboard);
|
||||
|
||||
/* allocate vram */
|
||||
vram = auto_alloc_array(machine, UINT8, 0x2000);
|
||||
/* special init */
|
||||
set_videoram_bank(machine, 0, 8, 0, 8);
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
/* E Board games (Mike Tyson's Punchout) - BROKEN - FIX ME */
|
||||
|
||||
/* callback for the ppu_latch */
|
||||
@ -532,29 +723,27 @@ static void mapper9_latch( const device_config *ppu, offs_t offset )
|
||||
if((offset & 0x1ff0) == 0x0fd0 && MMC2_bank_latch[0] != 0xfd)
|
||||
{
|
||||
MMC2_bank_latch[0] = 0xfd;
|
||||
ppu2c0x_set_videorom_bank( ppu, 0, 4, MMC2_bank[0], 256 );
|
||||
pc10_set_videorom_bank(ppu->space[0]->machine, 0, 4, MMC2_bank[0], 4);
|
||||
}
|
||||
else if((offset & 0x1ff0) == 0x0fe0 && MMC2_bank_latch[0] != 0xfe)
|
||||
{
|
||||
MMC2_bank_latch[0] = 0xfe;
|
||||
ppu2c0x_set_videorom_bank( ppu, 0, 4, MMC2_bank[1], 256 );
|
||||
pc10_set_videorom_bank(ppu->space[0]->machine, 0, 4, MMC2_bank[1], 4);
|
||||
}
|
||||
else if((offset & 0x1ff0) == 0x1fd0 && MMC2_bank_latch[1] != 0xfd)
|
||||
{
|
||||
MMC2_bank_latch[1] = 0xfd;
|
||||
ppu2c0x_set_videorom_bank( ppu, 4, 4, MMC2_bank[2], 256 );
|
||||
pc10_set_videorom_bank(ppu->space[0]->machine, 4, 4, MMC2_bank[2], 4);
|
||||
}
|
||||
else if((offset & 0x1ff0) == 0x1fe0 && MMC2_bank_latch[1] != 0xfe)
|
||||
{
|
||||
MMC2_bank_latch[1] = 0xfe;
|
||||
ppu2c0x_set_videorom_bank( ppu, 4, 4, MMC2_bank[3], 256 );
|
||||
pc10_set_videorom_bank(ppu->space[0]->machine, 4, 4, MMC2_bank[3], 4);
|
||||
}
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( eboard_rom_switch_w )
|
||||
{
|
||||
const device_config *ppu = devtag_get_device(space->machine, "ppu");
|
||||
|
||||
/* a variation of mapper 9 on a nes */
|
||||
switch (offset & 0x7000)
|
||||
{
|
||||
@ -569,29 +758,29 @@ static WRITE8_HANDLER( eboard_rom_switch_w )
|
||||
case 0x3000: /* gfx bank 0 - 4k */
|
||||
MMC2_bank[0] = data;
|
||||
if (MMC2_bank_latch[0] == 0xfd)
|
||||
ppu2c0x_set_videorom_bank( ppu, 0, 4, data, 256 );
|
||||
pc10_set_videorom_bank(space->machine, 0, 4, data, 4);
|
||||
break;
|
||||
|
||||
case 0x4000: /* gfx bank 0 - 4k */
|
||||
MMC2_bank[1] = data;
|
||||
if (MMC2_bank_latch[0] == 0xfe)
|
||||
ppu2c0x_set_videorom_bank( ppu, 0, 4, data, 256 );
|
||||
pc10_set_videorom_bank(space->machine, 0, 4, data, 4);
|
||||
break;
|
||||
|
||||
case 0x5000: /* gfx bank 1 - 4k */
|
||||
MMC2_bank[2] = data;
|
||||
if (MMC2_bank_latch[1] == 0xfd)
|
||||
ppu2c0x_set_videorom_bank( ppu, 4, 4, data, 256 );
|
||||
pc10_set_videorom_bank(space->machine, 4, 4, data, 4);
|
||||
break;
|
||||
|
||||
case 0x6000: /* gfx bank 1 - 4k */
|
||||
MMC2_bank[3] = data;
|
||||
if (MMC2_bank_latch[1] == 0xfe)
|
||||
ppu2c0x_set_videorom_bank( ppu, 4, 4, data, 256 );
|
||||
pc10_set_videorom_bank(space->machine, 4, 4, data, 4);
|
||||
break;
|
||||
|
||||
case 0x7000: /* mirroring */
|
||||
ppu2c0x_set_mirroring( ppu, data ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT );
|
||||
pc10_set_mirroring(data ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -601,6 +790,9 @@ DRIVER_INIT( pceboard )
|
||||
{
|
||||
UINT8 *prg = memory_region(machine, "cart");
|
||||
|
||||
/* we have no vram, make sure switching games doesn't point to an old allocation */
|
||||
vram = NULL;
|
||||
|
||||
/* We do manual banking, in case the code falls through */
|
||||
/* Copy the initial banks */
|
||||
memcpy(&prg[0x08000], &prg[0x28000], 0x8000);
|
||||
@ -620,13 +812,15 @@ DRIVER_INIT( pceboard )
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
/* F Board games (Ninja Gaiden, Double Dragon) */
|
||||
|
||||
DRIVER_INIT( pcfboard )
|
||||
{
|
||||
UINT8 *prg = memory_region(machine, "cart");
|
||||
|
||||
/* we have no vram, make sure switching games doesn't point to an old allocation */
|
||||
vram = NULL;
|
||||
|
||||
/* We do manual banking, in case the code falls through */
|
||||
/* Copy the initial banks */
|
||||
memcpy(&prg[0x08000], &prg[0x28000], 0x8000);
|
||||
@ -648,12 +842,13 @@ DRIVER_INIT( pcfboard_2 )
|
||||
memory_install_readwrite8_handler(cputag_get_address_space(machine, "cart", ADDRESS_SPACE_PROGRAM), 0x6000, 0x6fff, 0, 0, (read8_space_func)SMH_BANK(1), (write8_space_func)SMH_BANK(1) );
|
||||
memory_set_bankptr(machine, 1, auto_alloc_array(machine, UINT8, 0x1000));
|
||||
|
||||
vram = NULL;
|
||||
|
||||
/* common init */
|
||||
DRIVER_INIT_CALL(pcfboard);
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
/* G Board games (Super Mario Bros. 3) */
|
||||
|
||||
static int gboard_scanline_counter;
|
||||
@ -729,7 +924,7 @@ static WRITE8_HANDLER( gboard_rom_switch_w )
|
||||
case 1: /* char banking */
|
||||
data &= 0xfe;
|
||||
page ^= (cmd << 1);
|
||||
ppu2c0x_set_videorom_bank( ppu, page, 2, data, 64 );
|
||||
pc10_set_videorom_bank(space->machine, page, 2, data, 1);
|
||||
break;
|
||||
|
||||
case 2: /* char banking */
|
||||
@ -737,7 +932,7 @@ static WRITE8_HANDLER( gboard_rom_switch_w )
|
||||
case 4: /* char banking */
|
||||
case 5: /* char banking */
|
||||
page ^= cmd + 2;
|
||||
ppu2c0x_set_videorom_bank( ppu, page, 1, data, 64 );
|
||||
pc10_set_videorom_bank(space->machine, page, 1, data, 1);
|
||||
break;
|
||||
|
||||
case 6: /* program banking */
|
||||
@ -782,9 +977,9 @@ static WRITE8_HANDLER( gboard_rom_switch_w )
|
||||
if (!gboard_4screen)
|
||||
{
|
||||
if (data & 0x40)
|
||||
ppu2c0x_set_mirroring( ppu, PPU_MIRROR_HIGH );
|
||||
pc10_set_mirroring(PPU_MIRROR_HIGH);
|
||||
else
|
||||
ppu2c0x_set_mirroring( ppu, ( data & 1 ) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT );
|
||||
pc10_set_mirroring((data & 1) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -813,6 +1008,7 @@ static WRITE8_HANDLER( gboard_rom_switch_w )
|
||||
DRIVER_INIT( pcgboard )
|
||||
{
|
||||
UINT8 *prg = memory_region(machine, "cart");
|
||||
vram = NULL;
|
||||
|
||||
/* We do manual banking, in case the code falls through */
|
||||
/* Copy the initial banks */
|
||||
@ -838,6 +1034,7 @@ DRIVER_INIT( pcgboard )
|
||||
|
||||
DRIVER_INIT( pcgboard_type2 )
|
||||
{
|
||||
vram = NULL;
|
||||
/* common init */
|
||||
DRIVER_INIT_CALL(pcgboard);
|
||||
|
||||
@ -846,19 +1043,17 @@ DRIVER_INIT( pcgboard_type2 )
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
/* i Board games (Captain Sky Hawk, Solar Jetman) */
|
||||
|
||||
static WRITE8_HANDLER( iboard_rom_switch_w )
|
||||
{
|
||||
int bank = data & 7;
|
||||
const device_config *ppu = devtag_get_device(space->machine, "ppu");
|
||||
UINT8 *prg = memory_region(space->machine, "cart");
|
||||
|
||||
if (data & 0x10)
|
||||
ppu2c0x_set_mirroring( ppu, PPU_MIRROR_HIGH );
|
||||
pc10_set_mirroring(PPU_MIRROR_HIGH);
|
||||
else
|
||||
ppu2c0x_set_mirroring( ppu, PPU_MIRROR_LOW );
|
||||
pc10_set_mirroring(PPU_MIRROR_LOW);
|
||||
|
||||
memcpy(&prg[0x08000], &prg[bank * 0x8000 + 0x10000], 0x8000);
|
||||
}
|
||||
@ -876,16 +1071,18 @@ DRIVER_INIT( pciboard )
|
||||
|
||||
/* common init */
|
||||
DRIVER_INIT_CALL(playch10);
|
||||
|
||||
/* allocate vram */
|
||||
vram = auto_alloc_array(machine, UINT8, 0x2000);
|
||||
/* special init */
|
||||
set_videoram_bank(machine, 0, 8, 0, 8);
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
/* H Board games (PinBot) */
|
||||
|
||||
static WRITE8_HANDLER( hboard_rom_switch_w )
|
||||
{
|
||||
const device_config *ppu = devtag_get_device(space->machine, "ppu");
|
||||
|
||||
switch (offset & 0x7001)
|
||||
{
|
||||
case 0x0001:
|
||||
@ -899,13 +1096,13 @@ static WRITE8_HANDLER( hboard_rom_switch_w )
|
||||
case 1: /* char banking */
|
||||
data &= 0xfe;
|
||||
page ^= (cmd << 1);
|
||||
if ( data & 0x20 )
|
||||
if (data & 0x40)
|
||||
{
|
||||
ppu2c0x_set_videoram_bank( ppu, page, 2, data, 64 );
|
||||
set_videoram_bank(space->machine, page, 2, data, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ppu2c0x_set_videorom_bank( ppu, page, 2, data, 64 );
|
||||
pc10_set_videorom_bank(space->machine, page, 2, data, 1);
|
||||
}
|
||||
return;
|
||||
|
||||
@ -916,11 +1113,11 @@ static WRITE8_HANDLER( hboard_rom_switch_w )
|
||||
page ^= cmd + 2;
|
||||
if (data & 0x40)
|
||||
{
|
||||
ppu2c0x_set_videoram_bank( ppu, page, 1, data, 64 );
|
||||
set_videoram_bank(space->machine, page, 1, data, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ppu2c0x_set_videorom_bank( ppu, page, 1, data, 64 );
|
||||
pc10_set_videorom_bank(space->machine, page, 1, data, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -955,7 +1152,6 @@ DRIVER_INIT( pchboard )
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
/* K Board games (Mario Open Golf) */
|
||||
|
||||
DRIVER_INIT( pckboard )
|
||||
@ -977,4 +1173,9 @@ DRIVER_INIT( pckboard )
|
||||
|
||||
/* common init */
|
||||
DRIVER_INIT_CALL(playch10);
|
||||
|
||||
/* allocate vram */
|
||||
vram = auto_alloc_array(machine, UINT8, 0x2000);
|
||||
/* special init */
|
||||
set_videoram_bank(machine, 0, 8, 0, 8);
|
||||
}
|
||||
|
@ -22,6 +22,25 @@ static const UINT8 *remapped_colortable;
|
||||
static int sound_fix=0;
|
||||
static UINT8 last_bank;
|
||||
|
||||
/* PPU notes */
|
||||
/* nametable is, per Lord Nightmare, always 4K per PPU */
|
||||
/* The vsnes system has relatively few banking options for CHR */
|
||||
/* Each driver will use ROM or RAM for CHR, never both, and RAM is never banked */
|
||||
/* This leads to the memory system being an optimal place to perform banking */
|
||||
|
||||
/* need double pointers for vsdual */
|
||||
static UINT8* vram = NULL;
|
||||
static UINT8* vrom[2];
|
||||
static UINT8* nt_ram[2];
|
||||
static UINT8* nt_page[2][4]; // because mirroring is used.
|
||||
|
||||
/* Prototypes for mapping board components to PPU bus */
|
||||
WRITE8_HANDLER( vsnes_nt0_w );
|
||||
WRITE8_HANDLER( vsnes_nt1_w );
|
||||
READ8_HANDLER( vsnes_nt0_r );
|
||||
READ8_HANDLER( vsnes_nt1_r );
|
||||
void v_set_videorom_bank( running_machine* machine, int start, int count, int bank, int bank_size_in_kb );
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Color Mapping
|
||||
@ -113,6 +132,7 @@ static int remap_colors( const device_config *device, int addr, int data )
|
||||
* Input Ports
|
||||
*
|
||||
*************************************/
|
||||
|
||||
WRITE8_HANDLER( vsnes_in0_w )
|
||||
{
|
||||
/* Toggling bit 0 high then low resets both controllers */
|
||||
@ -148,7 +168,6 @@ static READ8_HANDLER( gun_in0_r )
|
||||
|
||||
}
|
||||
|
||||
|
||||
READ8_HANDLER( vsnes_in0_r )
|
||||
{
|
||||
|
||||
@ -164,7 +183,6 @@ READ8_HANDLER( vsnes_in0_r )
|
||||
|
||||
}
|
||||
|
||||
|
||||
READ8_HANDLER( vsnes_in1_r )
|
||||
{
|
||||
int ret = (input_latch[1]) & 1;
|
||||
@ -238,6 +256,7 @@ MACHINE_RESET( vsnes )
|
||||
* Init machine
|
||||
*
|
||||
*************************************/
|
||||
|
||||
MACHINE_RESET( vsdual )
|
||||
{
|
||||
const device_config *ppu1 = devtag_get_device(machine, "ppu1");
|
||||
@ -254,11 +273,167 @@ MACHINE_RESET( vsdual )
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Machine start functions
|
||||
*
|
||||
*************************************/
|
||||
|
||||
MACHINE_START( vsnes )
|
||||
{
|
||||
/* establish nametable ram */
|
||||
nt_ram[0] = auto_alloc_array(machine, UINT8, 0x1000);
|
||||
/* set mirroring */
|
||||
nt_page[0][0] = nt_ram[0];
|
||||
nt_page[0][1] = nt_ram[0] + 0x400;
|
||||
nt_page[0][2] = nt_ram[0] + 0x800;
|
||||
nt_page[0][3] = nt_ram[0] + 0xc00;
|
||||
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu1"), ADDRESS_SPACE_PROGRAM), 0x2000, 0x3eff, 0, 0, vsnes_nt0_r, vsnes_nt0_w);
|
||||
|
||||
vrom[0] = memory_region(machine, "gfx1");
|
||||
|
||||
/* establish chr banks */
|
||||
/* bank 1 is used already! */
|
||||
/* DRIVER_INIT is called first - means we can handle this different for VRAM games! */
|
||||
if (NULL != vrom[0])
|
||||
{
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu1"), ADDRESS_SPACE_PROGRAM), 0x0000, 0x03ff, 0, 0, SMH_BANK(2), 0);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu1"), ADDRESS_SPACE_PROGRAM), 0x0400, 0x07ff, 0, 0, SMH_BANK(3), 0);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu1"), ADDRESS_SPACE_PROGRAM), 0x0800, 0x0bff, 0, 0, SMH_BANK(4), 0);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu1"), ADDRESS_SPACE_PROGRAM), 0x0c00, 0x0fff, 0, 0, SMH_BANK(5), 0);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu1"), ADDRESS_SPACE_PROGRAM), 0x1000, 0x13ff, 0, 0, SMH_BANK(6), 0);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu1"), ADDRESS_SPACE_PROGRAM), 0x1400, 0x17ff, 0, 0, SMH_BANK(7), 0);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu1"), ADDRESS_SPACE_PROGRAM), 0x1800, 0x1bff, 0, 0, SMH_BANK(8), 0);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu1"), ADDRESS_SPACE_PROGRAM), 0x1c00, 0x1fff, 0, 0, SMH_BANK(9), 0);
|
||||
v_set_videorom_bank(machine, 0, 8, 0, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu1"), ADDRESS_SPACE_PROGRAM), 0x0000, 0x1fff, 0, 0, SMH_BANK(2), SMH_BANK(2));
|
||||
memory_set_bankptr(machine, 2, vram);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Init machine
|
||||
*
|
||||
*************************************/
|
||||
|
||||
MACHINE_START( vsdual )
|
||||
{
|
||||
vrom[0] = memory_region(machine, "gfx1");
|
||||
vrom[1] = memory_region(machine, "gfx2");
|
||||
|
||||
/* establish nametable ram */
|
||||
nt_ram[0] = auto_alloc_array(machine, UINT8, 0x1000);
|
||||
nt_ram[1] = auto_alloc_array(machine, UINT8, 0x1000);
|
||||
/* set mirroring */
|
||||
nt_page[0][0] = nt_ram[0];
|
||||
nt_page[0][1] = nt_ram[0] + 0x400;
|
||||
nt_page[0][2] = nt_ram[0] + 0x800;
|
||||
nt_page[0][3] = nt_ram[0] + 0xc00;
|
||||
nt_page[1][0] = nt_ram[1];
|
||||
nt_page[1][1] = nt_ram[1] + 0x400;
|
||||
nt_page[1][2] = nt_ram[1] + 0x800;
|
||||
nt_page[1][3] = nt_ram[1] + 0xc00;
|
||||
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu1"), ADDRESS_SPACE_PROGRAM), 0x2000, 0x3eff, 0, 0, vsnes_nt0_r, vsnes_nt0_w);
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu2"), ADDRESS_SPACE_PROGRAM), 0x2000, 0x3eff, 0, 0, vsnes_nt1_r, vsnes_nt1_w);
|
||||
// read only!
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu1"), ADDRESS_SPACE_PROGRAM), 0x0000, 0x1fff, 0, 0, SMH_BANK(2), 0);
|
||||
// read only!
|
||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu2"), ADDRESS_SPACE_PROGRAM), 0x0000, 0x1fff, 0, 0, SMH_BANK(3), 0);
|
||||
memory_set_bankptr(machine, 2, vrom[0]);
|
||||
memory_set_bankptr(machine, 3, vrom[1]);
|
||||
}
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* External mappings for PPU bus
|
||||
*
|
||||
*************************************/
|
||||
|
||||
WRITE8_HANDLER( vsnes_nt0_w )
|
||||
{
|
||||
int page = ((offset & 0xc00) >> 10);
|
||||
nt_page[0][page][offset & 0x3ff] = data;
|
||||
|
||||
}
|
||||
|
||||
WRITE8_HANDLER( vsnes_nt1_w )
|
||||
{
|
||||
int page = ((offset & 0xc00) >> 10);
|
||||
nt_page[1][page][offset & 0x3ff] = data;
|
||||
|
||||
}
|
||||
|
||||
READ8_HANDLER( vsnes_nt0_r )
|
||||
{
|
||||
int page = ((offset&0xc00) >> 10);
|
||||
return nt_page[0][page][offset & 0x3ff];
|
||||
}
|
||||
|
||||
READ8_HANDLER( vsnes_nt1_r )
|
||||
{
|
||||
int page = ((offset & 0xc00) >> 10);
|
||||
return nt_page[1][page][offset & 0x3ff];
|
||||
}
|
||||
|
||||
void v_set_mirroring( int ppu, int mirroring )
|
||||
{
|
||||
switch (mirroring)
|
||||
{
|
||||
case PPU_MIRROR_LOW:
|
||||
nt_page[ppu][0] = nt_page[ppu][1] = nt_page[ppu][2] = nt_page[ppu][3] = nt_ram[ppu];
|
||||
break;
|
||||
case PPU_MIRROR_HIGH:
|
||||
nt_page[ppu][0] = nt_page[ppu][1] = nt_page[ppu][2] = nt_page[ppu][3] = nt_ram[ppu] + 0x400;
|
||||
break;
|
||||
case PPU_MIRROR_HORZ:
|
||||
nt_page[ppu][0] = nt_ram[ppu];
|
||||
nt_page[ppu][1] = nt_ram[ppu];
|
||||
nt_page[ppu][2] = nt_ram[ppu] + 0x400;
|
||||
nt_page[ppu][3] = nt_ram[ppu] + 0x400;
|
||||
break;
|
||||
case PPU_MIRROR_VERT:
|
||||
nt_page[ppu][0] = nt_ram[ppu];
|
||||
nt_page[ppu][1] = nt_ram[ppu] + 0x400;
|
||||
nt_page[ppu][2] = nt_ram[ppu];
|
||||
nt_page[ppu][3] = nt_ram[ppu] + 0x400;
|
||||
break;
|
||||
case PPU_MIRROR_NONE:
|
||||
default:
|
||||
nt_page[ppu][0] = nt_ram[ppu];
|
||||
nt_page[ppu][1] = nt_ram[ppu] + 0x400;
|
||||
nt_page[ppu][2] = nt_ram[ppu] + 0x800;
|
||||
nt_page[ppu][3] = nt_ram[ppu] + 0xc00;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void v_set_videorom_bank( running_machine* machine, int start, int count, int bank, int bank_size_in_kb )
|
||||
{
|
||||
int i, j;
|
||||
int offset = bank * (bank_size_in_kb * 0x400);
|
||||
/* automatically add 2 to all start values (because the PPU is bank 2) */
|
||||
/* bank_size_in_kb is used to determine how large the "bank" parameter is */
|
||||
/* count determines the size of the area mapped */
|
||||
for (i = 0; i < count; i++, offset += 0x400)
|
||||
{
|
||||
j = i + start + 2;
|
||||
memory_set_bankptr(machine, j, vrom[0] + offset);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Common init for all games
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static void init_vsnes(running_machine *machine)
|
||||
{
|
||||
/* set the controller to default */
|
||||
@ -276,10 +451,8 @@ static void init_vsnes(running_machine *machine)
|
||||
|
||||
static WRITE8_HANDLER( vsnormal_vrom_banking )
|
||||
{
|
||||
const device_config *ppu1 = devtag_get_device(space->machine, "ppu1");
|
||||
|
||||
/* switch vrom */
|
||||
ppu2c0x_set_videorom_bank( ppu1, 0, 8, ( data & 4 ) ? 1 : 0, 512 );
|
||||
v_set_videorom_bank(space->machine, 0, 8, (data & 4) ? 1 : 0, 8);
|
||||
|
||||
/* bit 1 ( data & 2 ) enables writes to extra ram, we ignore it */
|
||||
|
||||
@ -311,7 +484,6 @@ static WRITE8_HANDLER( ppuRC2C05_protection )
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
/* Super Mario Bros. Extra ram at $6000 (NV?) and remapped colors */
|
||||
|
||||
DRIVER_INIT( suprmrio )
|
||||
@ -333,7 +505,6 @@ DRIVER_INIT( suprmrio )
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
/* Gun Games - VROM Banking in controller 0 write */
|
||||
|
||||
static WRITE8_HANDLER( gun_in0_w )
|
||||
@ -344,7 +515,7 @@ static WRITE8_HANDLER( gun_in0_w )
|
||||
if (vsnes_do_vrom_bank)
|
||||
{
|
||||
/* switch vrom */
|
||||
ppu2c0x_set_videorom_bank( ppu1, 0, 8, ( data & 4 ) ? 1 : 0, 512 );
|
||||
v_set_videorom_bank(space->machine, 0, 8, (data & 4) ? 1 : 0, 8);
|
||||
}
|
||||
|
||||
/* here we do things a little different */
|
||||
@ -401,12 +572,10 @@ DRIVER_INIT( duckhunt )
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
/* The Goonies, VS Gradius: ROMs bankings at $8000-$ffff */
|
||||
|
||||
static WRITE8_HANDLER( goonies_rom_banking )
|
||||
{
|
||||
const device_config *ppu1 = devtag_get_device(space->machine, "ppu1");
|
||||
int reg = (offset >> 12) & 0x07;
|
||||
int bankoffset = (data & 7) * 0x2000 + 0x10000;
|
||||
|
||||
@ -422,11 +591,11 @@ static WRITE8_HANDLER( goonies_rom_banking )
|
||||
break;
|
||||
|
||||
case 6: /* vrom bank 0 */
|
||||
ppu2c0x_set_videorom_bank( ppu1, 0, 4, data, 256 );
|
||||
v_set_videorom_bank(space->machine, 0, 4, data, 4);
|
||||
break;
|
||||
|
||||
case 7: /* vrom bank 1 */
|
||||
ppu2c0x_set_videorom_bank( ppu1, 4, 4, data, 256 );
|
||||
v_set_videorom_bank(space->machine, 4, 4, data, 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -496,7 +665,6 @@ DRIVER_INIT( hogalley )
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
/* Vs. Gumshoe */
|
||||
|
||||
static READ8_HANDLER( vsgshoe_security_r )
|
||||
@ -541,7 +709,6 @@ DRIVER_INIT( vsgshoe )
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
/* Dr Mario: ROMs bankings at $8000-$ffff */
|
||||
|
||||
static int drmario_shiftreg;
|
||||
@ -549,8 +716,6 @@ static int drmario_shiftcount;
|
||||
|
||||
static WRITE8_HANDLER( drmario_rom_banking )
|
||||
{
|
||||
const device_config *ppu1 = devtag_get_device(space->machine, "ppu1");
|
||||
|
||||
/* basically, a MMC1 mapper from the nes */
|
||||
static int size16k, switchlow, vrom4k;
|
||||
|
||||
@ -615,17 +780,17 @@ static WRITE8_HANDLER( drmario_rom_banking )
|
||||
}
|
||||
|
||||
/* apply mirroring */
|
||||
ppu2c0x_set_mirroring( ppu1, mirroring );
|
||||
v_set_mirroring(1, mirroring);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: /* video rom banking - bank 0 - 4k or 8k */
|
||||
ppu2c0x_set_videorom_bank( ppu1, 0, ( vrom4k ) ? 4 : 8, drmario_shiftreg, ( vrom4k ) ? 256 : 512 );
|
||||
v_set_videorom_bank(space->machine, 0, (vrom4k) ? 4 : 8, drmario_shiftreg, (vrom4k) ? 4 : 8);
|
||||
break;
|
||||
|
||||
case 2: /* video rom banking - bank 1 - 4k only */
|
||||
if (vrom4k)
|
||||
ppu2c0x_set_videorom_bank( ppu1, 4, 4, drmario_shiftreg, 256 );
|
||||
v_set_videorom_bank(space->machine, 4, 4, drmario_shiftreg, 4);
|
||||
break;
|
||||
|
||||
case 3: /* program banking */
|
||||
@ -682,7 +847,6 @@ DRIVER_INIT( drmario )
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
/* Excite Bike */
|
||||
|
||||
DRIVER_INIT( excitebk )
|
||||
@ -714,7 +878,6 @@ DRIVER_INIT( excitbkj )
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
/* Mach Rider */
|
||||
|
||||
DRIVER_INIT( machridr )
|
||||
@ -733,7 +896,6 @@ DRIVER_INIT( machridr )
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
/* VS Slalom */
|
||||
|
||||
DRIVER_INIT( vsslalom )
|
||||
@ -748,7 +910,6 @@ DRIVER_INIT( vsslalom )
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
/* Castelvania: ROMs bankings at $8000-$ffff */
|
||||
|
||||
static WRITE8_HANDLER( castlevania_rom_banking )
|
||||
@ -775,10 +936,12 @@ DRIVER_INIT( cstlevna )
|
||||
/* we need to remap color tables */
|
||||
/* this *is* the VS games protection, I guess */
|
||||
remapped_colortable = rp2c04002_colortable;
|
||||
|
||||
/* allocate vram */
|
||||
vram = auto_alloc_array(machine, UINT8, 0x2000);
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
/* VS Top Gun: ROMs bankings at $8000-$ffff, plus some protection */
|
||||
|
||||
static READ8_HANDLER( topgun_security_r )
|
||||
@ -802,6 +965,10 @@ DRIVER_INIT( topgun )
|
||||
|
||||
/* common init */
|
||||
init_vsnes(machine);
|
||||
|
||||
/* allocate vram */
|
||||
vram = auto_alloc_array(machine, UINT8, 0x2000);
|
||||
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
@ -832,14 +999,13 @@ static void mapper4_set_prg (const address_space *space)
|
||||
|
||||
static void mapper4_set_chr (const address_space *space)
|
||||
{
|
||||
const device_config *ppu1 = devtag_get_device(space->machine, "ppu1");
|
||||
UINT8 chr_page = (MMC3_cmd & 0x80) >> 5;
|
||||
ppu2c0x_set_videorom_bank(ppu1, chr_page ^ 0, 2, MMC3_chr[0], 1);
|
||||
ppu2c0x_set_videorom_bank(ppu1, chr_page ^ 2, 2, MMC3_chr[1], 1);
|
||||
ppu2c0x_set_videorom_bank(ppu1, chr_page ^ 4, 1, MMC3_chr[2], 1);
|
||||
ppu2c0x_set_videorom_bank(ppu1, chr_page ^ 5, 1, MMC3_chr[3], 1);
|
||||
ppu2c0x_set_videorom_bank(ppu1, chr_page ^ 6, 1, MMC3_chr[4], 1);
|
||||
ppu2c0x_set_videorom_bank(ppu1, chr_page ^ 7, 1, MMC3_chr[5], 1);
|
||||
v_set_videorom_bank(space->machine, chr_page ^ 0, 2, MMC3_chr[0], 1);
|
||||
v_set_videorom_bank(space->machine, chr_page ^ 2, 2, MMC3_chr[1], 1);
|
||||
v_set_videorom_bank(space->machine, chr_page ^ 4, 1, MMC3_chr[2], 1);
|
||||
v_set_videorom_bank(space->machine, chr_page ^ 5, 1, MMC3_chr[3], 1);
|
||||
v_set_videorom_bank(space->machine, chr_page ^ 6, 1, MMC3_chr[4], 1);
|
||||
v_set_videorom_bank(space->machine, chr_page ^ 7, 1, MMC3_chr[5], 1);
|
||||
}
|
||||
|
||||
#define BOTTOM_VISIBLE_SCANLINE 239 /* The bottommost visible scanline */
|
||||
@ -847,7 +1013,6 @@ static void mapper4_set_chr (const address_space *space)
|
||||
|
||||
static void mapper4_irq( const device_config *device, int scanline, int vblank, int blanked )
|
||||
{
|
||||
mame_printf_debug("entra\n");
|
||||
if ((scanline < BOTTOM_VISIBLE_SCANLINE) || (scanline == NUM_SCANLINE - 1))
|
||||
{
|
||||
if ((IRQ_enable) && !blanked)
|
||||
@ -889,13 +1054,13 @@ static WRITE8_HANDLER( mapper4_w )
|
||||
{
|
||||
case 0: case 1:
|
||||
data &= 0xfe;
|
||||
MMC3_chr[cmd] = data * 64;
|
||||
MMC3_chr[cmd] = data;
|
||||
mapper4_set_chr(space);
|
||||
|
||||
break;
|
||||
|
||||
case 2: case 3: case 4: case 5:
|
||||
MMC3_chr[cmd] = data * 64;
|
||||
MMC3_chr[cmd] = data;
|
||||
mapper4_set_chr(space);
|
||||
|
||||
break;
|
||||
@ -914,13 +1079,13 @@ static WRITE8_HANDLER( mapper4_w )
|
||||
}
|
||||
case 0x2000: /* $a000 */
|
||||
if (data & 0x40)
|
||||
ppu2c0x_set_mirroring(ppu1, PPU_MIRROR_HIGH);
|
||||
v_set_mirroring(1, PPU_MIRROR_HIGH);
|
||||
else
|
||||
{
|
||||
if (data & 0x01)
|
||||
ppu2c0x_set_mirroring(ppu1, PPU_MIRROR_HORZ);
|
||||
v_set_mirroring(1, PPU_MIRROR_HORZ);
|
||||
else
|
||||
ppu2c0x_set_mirroring(ppu1, PPU_MIRROR_VERT);
|
||||
v_set_mirroring(1, PPU_MIRROR_VERT);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1136,24 +1301,22 @@ DRIVER_INIT( vsfdf )
|
||||
|
||||
static WRITE8_HANDLER( mapper68_rom_banking )
|
||||
{
|
||||
const device_config *ppu1 = devtag_get_device(space->machine, "ppu1");
|
||||
|
||||
switch (offset & 0x7000)
|
||||
{
|
||||
case 0x0000:
|
||||
ppu2c0x_set_videorom_bank(ppu1,0,2,data,128);
|
||||
v_set_videorom_bank(space->machine, 0, 2, data, 2);
|
||||
|
||||
break;
|
||||
case 0x1000:
|
||||
ppu2c0x_set_videorom_bank(ppu1,2,2,data,128);
|
||||
v_set_videorom_bank(space->machine, 2, 2, data, 2);
|
||||
|
||||
break;
|
||||
case 0x2000:
|
||||
ppu2c0x_set_videorom_bank(ppu1,4,2,data,128);
|
||||
v_set_videorom_bank(space->machine, 4, 2, data, 2);
|
||||
|
||||
break;
|
||||
case 0x3000: /* ok? */
|
||||
ppu2c0x_set_videorom_bank(ppu1,6,2,data,128);
|
||||
v_set_videorom_bank(space->machine, 6, 2, data, 2);
|
||||
|
||||
break;
|
||||
|
||||
@ -1249,7 +1412,6 @@ DRIVER_INIT( jajamaru )
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
/* Vs. Mighty Bomb Jack */
|
||||
|
||||
static READ8_HANDLER( mightybj_security_r )
|
||||
@ -1274,11 +1436,9 @@ DRIVER_INIT( mightybj )
|
||||
static WRITE8_HANDLER( vstennis_vrom_banking )
|
||||
{
|
||||
const device_config *other_cpu = (space->cpu == cputag_get_cpu(space->machine, "maincpu")) ? cputag_get_cpu(space->machine, "sub") : cputag_get_cpu(space->machine, "maincpu");
|
||||
const device_config *ppu1 = devtag_get_device(space->machine, "ppu1");
|
||||
const device_config *ppu2 = devtag_get_device(space->machine, "ppu2");
|
||||
|
||||
/* switch vrom */
|
||||
ppu2c0x_set_videorom_bank( (space->cpu == cputag_get_cpu(space->machine, "maincpu")) ? ppu1 : ppu2, 0, 8, ( data & 4 ) ? 1 : 0, 512 );
|
||||
(space->cpu == cputag_get_cpu(space->machine, "maincpu")) ? memory_set_bankptr(space->machine, 2, (data & 4) ? vrom[0] + 0x2000 : vrom[0]) : memory_set_bankptr(space->machine, 3, (data & 4) ? vrom[1] + 0x2000 : vrom[1]);
|
||||
|
||||
/* bit 1 ( data & 2 ) triggers irq on the other cpu */
|
||||
cpu_set_input_line(other_cpu, 0, (data & 2) ? CLEAR_LINE : ASSERT_LINE);
|
||||
@ -1311,7 +1471,6 @@ DRIVER_INIT( vstennis )
|
||||
DRIVER_INIT( wrecking )
|
||||
{
|
||||
/* only differance between this and vstennis is the colors */
|
||||
|
||||
DRIVER_INIT_CALL(vstennis);
|
||||
remapped_colortable = rp2c04002_colortable;
|
||||
}
|
||||
@ -1322,7 +1481,6 @@ DRIVER_INIT( wrecking )
|
||||
DRIVER_INIT( balonfgt )
|
||||
{
|
||||
/* only differance between this and vstennis is the colors */
|
||||
|
||||
DRIVER_INIT_CALL(vstennis);
|
||||
|
||||
remapped_colortable = rp2c04003_colortable;
|
||||
@ -1335,11 +1493,9 @@ DRIVER_INIT( balonfgt )
|
||||
DRIVER_INIT( vsbball )
|
||||
{
|
||||
/* only differance between this and vstennis is the colors */
|
||||
|
||||
DRIVER_INIT_CALL(vstennis);
|
||||
|
||||
remapped_colortable = rp2c04001_colortable;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1349,15 +1505,14 @@ DRIVER_INIT( vsbball )
|
||||
DRIVER_INIT( iceclmrj )
|
||||
{
|
||||
/* only differance between this and vstennis is the colors */
|
||||
|
||||
DRIVER_INIT_CALL(vstennis);
|
||||
|
||||
remapped_colortable = rp2c05004_colortable;
|
||||
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/* Battle City */
|
||||
|
||||
DRIVER_INIT( btlecity )
|
||||
{
|
||||
init_vsnes(machine);
|
||||
@ -1367,6 +1522,7 @@ DRIVER_INIT( btlecity )
|
||||
|
||||
/***********************************************************************/
|
||||
/* Tetris */
|
||||
|
||||
DRIVER_INIT( vstetris )
|
||||
{
|
||||
/* extra ram at $6000 is enabled with bit 1 of $4016 */
|
||||
|
@ -5,9 +5,8 @@
|
||||
Written by Ernesto Corvi.
|
||||
This code is heavily based on Brad Oliver's MESS implementation.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
2009-04: Changed NES PPU to be a device (Nathan Woods)
|
||||
2009-07: Changed NES PPU to use a device memory map (Robert Bohms)
|
||||
|
||||
Current known bugs
|
||||
|
||||
@ -19,7 +18,6 @@ General:
|
||||
NES-specific:
|
||||
|
||||
* Micro Machines has minor rendering glitches (needs better timing).
|
||||
|
||||
* Mach Rider has minor road rendering glitches (needs better timing).
|
||||
|
||||
******************************************************************************/
|
||||
@ -36,7 +34,7 @@ NES-specific:
|
||||
/* constant definitions */
|
||||
#define VISIBLE_SCREEN_WIDTH (32*8) /* Visible screen width */
|
||||
#define VISIBLE_SCREEN_HEIGHT (30*8) /* Visible screen height */
|
||||
#define VIDEOMEM_SIZE 0x4000 /* videomem size */
|
||||
#define VIDEOMEM_SIZE 0x1000 /* videomem size */
|
||||
#define VIDEOMEM_PAGE_SIZE 0x400 /* videomem page size */
|
||||
#define SPRITERAM_SIZE 0x100 /* spriteram size */
|
||||
#define SPRITERAM_MASK (0x100-1) /* spriteram size */
|
||||
@ -113,6 +111,7 @@ typedef struct
|
||||
int back_color; /* background color */
|
||||
UINT8 *ppu_page[4]; /* ppu pages */
|
||||
int nes_vram[8]; /* keep track of 8 .5k vram pages to speed things up */
|
||||
UINT8 palette_ram[0x20]; /* shouldn't be in main memory! */
|
||||
int scan_scale; /* scan scale */
|
||||
int scanlines_per_frame; /* number of scanlines per frame */
|
||||
int mirror_state;
|
||||
@ -120,7 +119,6 @@ typedef struct
|
||||
} ppu2c0x_chip;
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
PROTOTYPES
|
||||
***************************************************************************/
|
||||
@ -133,6 +131,16 @@ static TIMER_CALLBACK( nmi_callback );
|
||||
|
||||
void (*ppu_latch)( const device_config *device, offs_t offset );
|
||||
|
||||
/* palette handlers */
|
||||
WRITE8_HANDLER( ppu2c0x_palette_write );
|
||||
READ8_HANDLER( ppu2c0x_palette_read );
|
||||
/* name and attribute table functions */
|
||||
WRITE8_HANDLER( ppu2c0x_name_write );
|
||||
READ8_HANDLER( ppu2c0x_name_read );
|
||||
/* name and attribute table functions */
|
||||
WRITE8_HANDLER( ppu2c0x_chr_write );
|
||||
READ8_HANDLER( ppu2c0x_chr_read );
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
INLINE FUNCTIONS
|
||||
@ -167,6 +175,13 @@ INLINE const ppu2c0x_interface *get_interface(const device_config *device)
|
||||
* PPU Palette Initialization
|
||||
*
|
||||
*************************************/
|
||||
|
||||
/* default address map */
|
||||
// make this INTERNAL, default should just be enough to avoid compile errors, print error messages!
|
||||
static ADDRESS_MAP_START( ppu2c0x, 0, 8 )
|
||||
AM_RANGE(0x3f00, 0x3fff) AM_READWRITE (ppu2c0x_palette_read, ppu2c0x_palette_write)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
void ppu2c0x_init_palette( running_machine *machine, int first_entry )
|
||||
{
|
||||
|
||||
@ -302,9 +317,8 @@ static const gfx_layout ppu_charlayout =
|
||||
|
||||
static DEVICE_START( ppu2c0x )
|
||||
{
|
||||
UINT32 total;
|
||||
ppu2c0x_chip *chip = get_token(device);
|
||||
const ppu2c0x_interface *intf = get_interface(device);
|
||||
// const ppu2c0x_interface *intf = get_interface(device);
|
||||
|
||||
memset(chip, 0, sizeof(*chip));
|
||||
chip->scanlines_per_frame = (int) device_get_info_int(device, PPU2C0XINFO_INT_SCANLINES_PER_FRAME);
|
||||
@ -318,58 +332,9 @@ static DEVICE_START( ppu2c0x )
|
||||
|
||||
/* allocate a screen bitmap, videomem and spriteram, a dirtychar array and the monochromatic colortable */
|
||||
chip->bitmap = auto_bitmap_alloc(device->machine, VISIBLE_SCREEN_WIDTH, VISIBLE_SCREEN_HEIGHT, video_screen_get_format(device->machine->primary_screen));
|
||||
chip->videomem = auto_alloc_array_clear(device->machine, UINT8, VIDEOMEM_SIZE );
|
||||
chip->videoram = auto_alloc_array_clear(device->machine, UINT8, VIDEOMEM_SIZE );
|
||||
chip->spriteram = auto_alloc_array_clear(device->machine, UINT8, SPRITERAM_SIZE);
|
||||
chip->colortable = auto_alloc_array(device->machine, pen_t, ARRAY_LENGTH(default_colortable));
|
||||
chip->colortable_mono = auto_alloc_array(device->machine, pen_t, ARRAY_LENGTH(default_colortable_mono));
|
||||
|
||||
memset( chip->videoram_banks_indices, 0xff, sizeof(chip->videoram_banks_indices) );
|
||||
|
||||
if ( intf->vram_enabled )
|
||||
{
|
||||
chip->has_videoram = 1;
|
||||
}
|
||||
|
||||
/* initialize the video ROM portion, if available */
|
||||
if ( ( intf->vrom_region != NULL ) && ( memory_region( device->machine, intf->vrom_region ) != 0 ) )
|
||||
{
|
||||
/* mark that we have a videorom */
|
||||
chip->has_videorom = 1;
|
||||
|
||||
/* find out how many banks */
|
||||
chip->videorom_banks = memory_region_length( device->machine, intf->vrom_region ) / 0x2000;
|
||||
|
||||
/* tweak the layout accordingly */
|
||||
if ( chip->has_videoram )
|
||||
{
|
||||
total = CHARGEN_NUM_CHARS;
|
||||
}
|
||||
else
|
||||
{
|
||||
total = chip->videorom_banks * CHARGEN_NUM_CHARS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
chip->has_videorom = chip->videorom_banks = 0;
|
||||
|
||||
/* we need to reset this in case of mame running multisession */
|
||||
total = CHARGEN_NUM_CHARS;
|
||||
}
|
||||
|
||||
/* now create the gfx region */
|
||||
{
|
||||
gfx_layout gl;
|
||||
UINT8 *src = (chip->has_videorom && !chip->has_videoram) ? memory_region( device->machine, intf->vrom_region ) : chip->videomem;
|
||||
|
||||
memcpy(&gl, &ppu_charlayout, sizeof(gl));
|
||||
gl.total = total;
|
||||
device->machine->gfx[intf->gfx_layout_number] = gfx_element_alloc( device->machine, &gl, src, 8, 0 );
|
||||
}
|
||||
|
||||
/* setup our videomem handlers based on mirroring */
|
||||
ppu2c0x_set_mirroring( device, intf->mirroring );
|
||||
}
|
||||
|
||||
static TIMER_CALLBACK( hblank_callback )
|
||||
@ -413,22 +378,19 @@ static void draw_background(const device_config *device, UINT8 *line_priority )
|
||||
const int *ppu_regs = &this_ppu->regs[0];
|
||||
const int scanline = this_ppu->scanline;
|
||||
const int refresh_data = this_ppu->refresh_data;
|
||||
const int gfx_bank = intf->gfx_layout_number;
|
||||
const int total_elements = device->machine->gfx[gfx_bank]->total_elements;
|
||||
const int *nes_vram = &this_ppu->nes_vram[0];
|
||||
const int tile_page = this_ppu->tile_page;
|
||||
const int line_modulo = device->machine->gfx[gfx_bank]->line_modulo;
|
||||
UINT8 **ppu_page = this_ppu->ppu_page;
|
||||
|
||||
int start_x = (this_ppu->x_fine ^ 0x07) - 7;
|
||||
UINT16 back_pen;
|
||||
UINT16 *dest;
|
||||
|
||||
UINT8 scroll_x_coarse, scroll_y_coarse, scroll_y_fine, color_mask;
|
||||
int x, tile_index, start, i;
|
||||
int x, tile_index, i;
|
||||
|
||||
const pen_t *color_table;
|
||||
const pen_t *paldata;
|
||||
const UINT8 *sd;
|
||||
// const UINT8 *sd;
|
||||
|
||||
int tilecount = 0;
|
||||
|
||||
@ -474,17 +436,20 @@ static void draw_background(const device_config *device, UINT8 *line_priority )
|
||||
|
||||
index1 = tile_index + x;
|
||||
|
||||
|
||||
// this is attribute table stuff! (actually read 2 in PPUspeak)!
|
||||
/* Figure out which byte in the color table to use */
|
||||
pos = ((index1 & 0x380) >> 4) | ((index1 & 0x1f) >> 2);
|
||||
page = (index1 & 0x0c00) >> 10;
|
||||
address = 0x3c0 + pos;
|
||||
color_byte = ppu_page[page][address];
|
||||
color_byte = memory_read_byte(device->space[0], (((page * 0x400) + address) & 0xfff) + 0x2000);
|
||||
|
||||
/* figure out which bits in the color table to use */
|
||||
color_bits = ((index1 & 0x40) >> 4) + (index1 & 0x02);
|
||||
|
||||
// page2 is the output of the nametable read (this section is the FIRST read per tile!)
|
||||
address = index1 & 0x3ff;
|
||||
page2 = ppu_page[page][address];
|
||||
page2 = memory_read_byte(device->space[0], index1);
|
||||
index2 = nes_vram[(page2 >> 6) | tile_page] + (page2 & 0x3f);
|
||||
|
||||
// 27/12/2002
|
||||
@ -495,18 +460,35 @@ static void draw_background(const device_config *device, UINT8 *line_priority )
|
||||
|
||||
if (start_x < VISIBLE_SCREEN_WIDTH)
|
||||
{
|
||||
UINT8 plane1, plane2; // use extended size so I can shift!
|
||||
paldata = &color_table[4 * (((color_byte >> color_bits) & 0x03))];
|
||||
start = scroll_y_fine * line_modulo;
|
||||
sd = gfx_element_get_data(device->machine->gfx[gfx_bank], index2 % total_elements) + start;
|
||||
// start = scroll_y_fine * line_modulo;
|
||||
|
||||
// need to read 0x0000 or 0x1000 + 16*nametable data
|
||||
address = ((this_ppu->tile_page) ? 0x1000 : 0) + (page2 * 16);
|
||||
// plus something that accounts for y
|
||||
// address -= (scanline % 8);
|
||||
address += scroll_y_fine;
|
||||
|
||||
plane1 = memory_read_byte(device->space[0], (address & 0x1fff));
|
||||
plane2 = memory_read_byte(device->space[0], (address + 8) & 0x1fff);
|
||||
// plane2 = plane2 << 1;
|
||||
|
||||
// sd = gfx_element_get_data(device->machine->gfx[gfx_bank], index2 % total_elements) + start;
|
||||
|
||||
/* render the pixel */
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
UINT8 pix;
|
||||
pix = ((plane1 >> 7) & 1) | (((plane2 >> 7) & 1) << 1);
|
||||
plane1 = plane1 << 1;
|
||||
plane2 = plane2 << 1;
|
||||
if ((start_x + i) >= 0 && (start_x + i) < VISIBLE_SCREEN_WIDTH)
|
||||
{
|
||||
if ( sd[i] )
|
||||
|
||||
if (pix)
|
||||
{
|
||||
pen = paldata[sd[i]];
|
||||
pen = paldata[pix];
|
||||
line_priority[start_x + i] |= 0x02;
|
||||
}
|
||||
else
|
||||
@ -545,16 +527,13 @@ static void draw_background(const device_config *device, UINT8 *line_priority )
|
||||
|
||||
static void draw_sprites( const device_config *device, UINT8 *line_priority )
|
||||
{
|
||||
const ppu2c0x_interface *intf = get_interface(device);
|
||||
// const ppu2c0x_interface *intf = get_interface(device);
|
||||
ppu2c0x_chip *this_ppu = get_token(device);
|
||||
|
||||
/* cache some values locally */
|
||||
bitmap_t *bitmap = this_ppu->bitmap;
|
||||
const int scanline = this_ppu->scanline;
|
||||
const int gfx_bank = intf->gfx_layout_number;
|
||||
const int total_elements = device->machine->gfx[gfx_bank]->total_elements;
|
||||
const int sprite_page = this_ppu->sprite_page;
|
||||
const int line_modulo = device->machine->gfx[gfx_bank]->line_modulo;
|
||||
const UINT8 *sprite_ram = this_ppu->spriteram;
|
||||
pen_t *color_table = this_ppu->colortable;
|
||||
int *ppu_regs = &this_ppu->regs[0];
|
||||
@ -568,12 +547,11 @@ static void draw_sprites(const device_config *device, UINT8 *line_priority )
|
||||
int spriteCount = 0;
|
||||
int sprite_line;
|
||||
int drawn;
|
||||
int start;
|
||||
|
||||
int first_pixel;
|
||||
|
||||
const pen_t *paldata;
|
||||
const UINT8 *sd;
|
||||
// const UINT8 *sd;
|
||||
int pixel;
|
||||
|
||||
/* determine if the sprites are 8x8 or 8x16 */
|
||||
@ -583,6 +561,9 @@ static void draw_sprites(const device_config *device, UINT8 *line_priority )
|
||||
|
||||
for (spriteIndex = 0; spriteIndex < SPRITERAM_SIZE; spriteIndex += 4)
|
||||
{
|
||||
UINT8 plane1;
|
||||
UINT8 plane2;
|
||||
|
||||
spriteYPos = sprite_ram[spriteIndex] + 1;
|
||||
spriteXPos = sprite_ram[spriteIndex + 3];
|
||||
|
||||
@ -629,7 +610,7 @@ static void draw_sprites(const device_config *device, UINT8 *line_priority )
|
||||
page = (tile >> 6) | sprite_page;
|
||||
|
||||
|
||||
index1 = this_ppu->nes_vram[page] + ( tile & 0x3f );
|
||||
// index1 = this_ppu->nes_vram[page] + (tile & 0x3f);
|
||||
|
||||
if (ppu_latch)
|
||||
(*ppu_latch)(device, (sprite_page << 10) | ((tile & 0xff) << 4));
|
||||
@ -637,22 +618,50 @@ static void draw_sprites(const device_config *device, UINT8 *line_priority )
|
||||
/* compute the character's line to draw */
|
||||
sprite_line = scanline - spriteYPos;
|
||||
|
||||
|
||||
if (flipy)
|
||||
sprite_line = (size - 1) - sprite_line;
|
||||
|
||||
paldata = &color_table[4 * color];
|
||||
start = sprite_line * line_modulo;
|
||||
sd = gfx_element_get_data(device->machine->gfx[gfx_bank], index1 % total_elements) + start;
|
||||
if (size > 8)
|
||||
gfx_element_get_data(device->machine->gfx[gfx_bank], (index1 + 1) % total_elements);
|
||||
|
||||
if (size == 16 && sprite_line > 7)
|
||||
{
|
||||
tile++;
|
||||
sprite_line -= 8;
|
||||
}
|
||||
|
||||
index1 = tile * 16;
|
||||
if (size == 8)
|
||||
index1 += ((sprite_page == 0) ? 0 : 0x1000);
|
||||
|
||||
plane1 = memory_read_byte(device->space[0], (index1 + sprite_line) & 0x1fff);
|
||||
plane2 = memory_read_byte(device->space[0], (index1 + sprite_line + 8) & 0x1fff);
|
||||
|
||||
// sd = gfx_element_get_data(device->machine->gfx[gfx_bank], index1 % total_elements) + start;
|
||||
// if (size > 8)
|
||||
// gfx_element_get_data(device->machine->gfx[gfx_bank], (index1 + 1) % total_elements);
|
||||
|
||||
if (pri)
|
||||
{
|
||||
/* draw the low-priority sprites */
|
||||
|
||||
for (pixel = 0; pixel < 8; pixel++)
|
||||
{
|
||||
UINT8 pixelData = flipx ? sd[7-pixel] : sd[pixel];
|
||||
// UINT8 pixelData = flipx ? sd[7-pixel] : sd[pixel];
|
||||
UINT8 pixelData;
|
||||
if (flipx)
|
||||
{
|
||||
pixelData = (plane1 & 1) + ((plane2 & 1) << 1);
|
||||
plane1 = plane1 >> 1;
|
||||
plane2 = plane2 >> 1;
|
||||
// sd[7 - pixel]
|
||||
}
|
||||
else
|
||||
{
|
||||
pixelData = ((plane1 >> 7) & 1) | (((plane2 >> 7) & 1) << 1);
|
||||
plane1 = plane1 << 1;
|
||||
plane2 = plane2 << 1;
|
||||
// sd[pixel];
|
||||
}
|
||||
|
||||
/* is this pixel non-transparent? */
|
||||
if (spriteXPos + pixel >= first_pixel)
|
||||
@ -681,10 +690,23 @@ static void draw_sprites(const device_config *device, UINT8 *line_priority )
|
||||
else
|
||||
{
|
||||
/* draw the high-priority sprites */
|
||||
|
||||
for (pixel = 0; pixel < 8; pixel++)
|
||||
{
|
||||
UINT8 pixelData = flipx ? sd[7-pixel] : sd[pixel];
|
||||
UINT8 pixelData;
|
||||
if (flipx)
|
||||
{
|
||||
pixelData = (plane1 & 1) + ((plane2 & 1) << 1);
|
||||
plane1 = plane1 >> 1;
|
||||
plane2 = plane2 >> 1;
|
||||
// sd[7 - pixel]
|
||||
}
|
||||
else
|
||||
{
|
||||
pixelData = ((plane1 >> 7) & 1) | (((plane2 >> 7) & 1) << 1);
|
||||
plane1 = plane1 << 1;
|
||||
plane2 = plane2 << 1;
|
||||
// sd[pixel];
|
||||
}
|
||||
|
||||
/* is this pixel non-transparent? */
|
||||
if (spriteXPos + pixel >= first_pixel)
|
||||
@ -732,6 +754,7 @@ static void draw_sprites(const device_config *device, UINT8 *line_priority )
|
||||
* Scanline Rendering and Update
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static void render_scanline( const device_config *device )
|
||||
{
|
||||
ppu2c0x_chip *this_ppu = get_token(device);
|
||||
@ -825,9 +848,9 @@ static void update_scanline(const device_config *device)
|
||||
int penNum;
|
||||
|
||||
if (this_ppu->videomem_addr & 0x03)
|
||||
penNum = this_ppu->videomem[this_ppu->videomem_addr & 0x3f1f] & 0x3f;
|
||||
penNum = this_ppu->palette_ram[this_ppu->videomem_addr & 0x1f];
|
||||
else
|
||||
penNum = this_ppu->videomem[this_ppu->videomem_addr & 0x3f00] & 0x3f;
|
||||
penNum = this_ppu->palette_ram[0];
|
||||
|
||||
back_pen = penNum + intf->color_base;
|
||||
}
|
||||
@ -885,7 +908,7 @@ static TIMER_CALLBACK( scanline_callback )
|
||||
/* Note: this is called at the _end_ of each scanline */
|
||||
if (this_ppu->scanline == PPU_VBLANK_FIRST_SCANLINE)
|
||||
{
|
||||
logerror("vlbank starting\n");
|
||||
// logerror("vblank starting\n");
|
||||
/* We just entered VBLANK */
|
||||
ppu_regs[PPU_STATUS] |= PPU_STATUS_VBLANK;
|
||||
|
||||
@ -902,7 +925,7 @@ logerror("vlbank starting\n");
|
||||
|
||||
if (this_ppu->scanline == this_ppu->scanlines_per_frame - 1)
|
||||
{
|
||||
logerror("vlbank ending\n");
|
||||
// logerror("vblank ending\n");
|
||||
/* clear the vblank & sprite hit flag */
|
||||
ppu_regs[PPU_STATUS] &= ~(PPU_STATUS_VBLANK | PPU_STATUS_SPRITE0_HIT);
|
||||
}
|
||||
@ -995,10 +1018,58 @@ static DEVICE_RESET( ppu2c0x )
|
||||
for (i = 0; i < 8; i++)
|
||||
this_ppu->nes_vram[i] = i * 64;
|
||||
|
||||
if ( this_ppu->has_videorom )
|
||||
ppu2c0x_set_videorom_bank( device, 0, 8, 0, 512 );
|
||||
// if (this_ppu->has_videorom)
|
||||
// ppu2c0x_set_videorom_bank(device, 0, 8, 0, 512);
|
||||
}
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* PPU Memory functions
|
||||
*
|
||||
*************************************/
|
||||
|
||||
WRITE8_HANDLER( ppu2c0x_palette_write )
|
||||
{
|
||||
ppu2c0x_chip *this_ppu = get_token(space->cpu);
|
||||
const ppu2c0x_interface *intf = get_interface(space->cpu);
|
||||
int color_base = intf->color_base;
|
||||
|
||||
int colorEmphasis = (this_ppu->regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS) * 2;
|
||||
// it's a palette
|
||||
// transparent pens are mirrored!
|
||||
if (offset & 0x3)
|
||||
{
|
||||
this_ppu->palette_ram[offset & 0x1f] = data;
|
||||
this_ppu->colortable[offset & 0x1f] = color_base + data + colorEmphasis;
|
||||
this_ppu->colortable_mono[offset & 0x1f] = color_base + (data & 0xf0) + colorEmphasis;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
if (0 == (offset & 0xf))
|
||||
{
|
||||
this_ppu->back_color = data;
|
||||
for (i = 0; i < 32; i += 4)
|
||||
{
|
||||
this_ppu->colortable[i] = color_base + data + colorEmphasis;
|
||||
this_ppu->colortable_mono[i] = color_base + (data & 0xf0) + colorEmphasis;
|
||||
}
|
||||
}
|
||||
this_ppu->palette_ram[offset & 0xf] = this_ppu->palette_ram[(offset & 0xf) + 0x10] = data;
|
||||
}
|
||||
}
|
||||
|
||||
READ8_HANDLER( ppu2c0x_palette_read )
|
||||
{
|
||||
ppu2c0x_chip *this_ppu = get_token(space->cpu);
|
||||
{
|
||||
// it's a palette
|
||||
// ERROR: doesn't currently handle monochrome!
|
||||
if (this_ppu->regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO)
|
||||
return (this_ppu->palette_ram[offset & 0x1f] & 0x30);
|
||||
else return (this_ppu->palette_ram[offset & 0x1f] & 0x3f);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************
|
||||
*
|
||||
@ -1037,22 +1108,20 @@ READ8_DEVICE_HANDLER( ppu2c0x_r )
|
||||
break;
|
||||
|
||||
case PPU_DATA:
|
||||
if ( this_ppu->videomem_addr >= 0x3f00 )
|
||||
{
|
||||
this_ppu->data_latch = this_ppu->videomem[this_ppu->videomem_addr & 0x3F1F];
|
||||
if (this_ppu->regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO)
|
||||
this_ppu->data_latch &= 0x30;
|
||||
}
|
||||
else
|
||||
this_ppu->data_latch = this_ppu->buffered_data;
|
||||
|
||||
if (ppu_latch)
|
||||
(*ppu_latch)(device, this_ppu->videomem_addr & 0x3fff);
|
||||
|
||||
if ( ( this_ppu->videomem_addr >= 0x2000 ) && ( this_ppu->videomem_addr <= 0x3fff ) )
|
||||
this_ppu->buffered_data = this_ppu->ppu_page[ ( this_ppu->videomem_addr & 0xc00) >> 10][ this_ppu->videomem_addr & 0x3ff ];
|
||||
if (this_ppu->videomem_addr >= 0x3f00)
|
||||
{
|
||||
this_ppu->data_latch = memory_read_byte(device->space[0], this_ppu->videomem_addr);
|
||||
// buffer the mirrored NT data
|
||||
this_ppu->buffered_data = memory_read_byte(device->space[0], this_ppu->videomem_addr & 0x2fff);
|
||||
}
|
||||
else
|
||||
this_ppu->buffered_data = this_ppu->videomem[ this_ppu->videomem_addr & 0x3fff ];
|
||||
{
|
||||
this_ppu->data_latch = this_ppu->buffered_data;
|
||||
this_ppu->buffered_data = memory_read_byte(device->space[0], this_ppu->videomem_addr);
|
||||
}
|
||||
|
||||
this_ppu->videomem_addr += this_ppu->add;
|
||||
break;
|
||||
@ -1117,7 +1186,7 @@ WRITE8_DEVICE_HANDLER( ppu2c0x_w )
|
||||
int i;
|
||||
for (i = 0; i <= 0x1f; i ++)
|
||||
{
|
||||
UINT8 oldColor = this_ppu->videomem[i+0x3f00];
|
||||
UINT8 oldColor = this_ppu->palette_ram[i];
|
||||
|
||||
this_ppu->colortable[i] = color_base + oldColor + (data & PPU_CONTROL1_COLOR_EMPHASIS) * 2;
|
||||
}
|
||||
@ -1207,60 +1276,17 @@ WRITE8_DEVICE_HANDLER( ppu2c0x_w )
|
||||
else
|
||||
{
|
||||
/* store the data */
|
||||
this_ppu->videomem[tempAddr] = data;
|
||||
memory_write_byte(device->space[0], tempAddr, data);
|
||||
|
||||
/* mark the char dirty */
|
||||
gfx_element_mark_dirty(device->machine->gfx[intf->gfx_layout_number], tempAddr >> 4);
|
||||
// gfx_element_mark_dirty(device->machine->gfx[intf->gfx_layout_number], tempAddr >> 4);
|
||||
}
|
||||
}
|
||||
|
||||
else if ( tempAddr >= 0x3f00 )
|
||||
{
|
||||
int colorEmphasis = (this_ppu->regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS) * 2;
|
||||
|
||||
/* store the data */
|
||||
if (tempAddr & 0x03)
|
||||
this_ppu->videomem[tempAddr & 0x3F1F] = data;
|
||||
else
|
||||
{
|
||||
this_ppu->videomem[0x3F10+(tempAddr&0xF)] = data;
|
||||
this_ppu->videomem[0x3F00+(tempAddr&0xF)] = data;
|
||||
memory_write_byte(device->space[0], tempAddr, data);
|
||||
}
|
||||
|
||||
/* As usual, some games attempt to write values > the number of colors so we must mask the data. */
|
||||
data &= 0x3f;
|
||||
|
||||
if ( tempAddr & 0x03 )
|
||||
{
|
||||
this_ppu->colortable[ tempAddr & 0x1f ] = color_base + data + colorEmphasis;
|
||||
this_ppu->colortable_mono[tempAddr & 0x1f] = color_base + (data & 0xf0) + colorEmphasis;
|
||||
}
|
||||
|
||||
/* The only valid background colors are writes to 0x3f00 and 0x3f10 */
|
||||
/* and even then, they are mirrors of each other. */
|
||||
if ( ( tempAddr & 0x0f ) == 0 )
|
||||
{
|
||||
int i;
|
||||
|
||||
this_ppu->back_color = data;
|
||||
for( i = 0; i < 32; i += 4 )
|
||||
{
|
||||
this_ppu->colortable[ i ] = color_base + data + colorEmphasis;
|
||||
this_ppu->colortable_mono[i] = color_base + (data & 0xf0) + colorEmphasis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* everything else */
|
||||
/* writes to $3000-$3eff are mirrors of $2000-$2eff */
|
||||
else
|
||||
{
|
||||
int page = ( tempAddr & 0x0c00) >> 10;
|
||||
int address = tempAddr & 0x3ff;
|
||||
|
||||
this_ppu->ppu_page[page][address] = data;
|
||||
}
|
||||
|
||||
/* increment the address */
|
||||
this_ppu->videomem_addr += this_ppu->add;
|
||||
}
|
||||
@ -1277,6 +1303,7 @@ WRITE8_DEVICE_HANDLER( ppu2c0x_w )
|
||||
* Sprite DMA
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void ppu2c0x_spriteram_dma( const address_space *space, const device_config *device, const UINT8 page )
|
||||
{
|
||||
int i;
|
||||
@ -1286,7 +1313,8 @@ void ppu2c0x_spriteram_dma (const address_space *space, const device_config *dev
|
||||
for (i = 0; i < SPRITERAM_SIZE; i++)
|
||||
{
|
||||
UINT8 spriteData = memory_read_byte(space, address + i);
|
||||
ppu2c0x_w (device, PPU_SPRITE_DATA, spriteData);
|
||||
memory_write_byte(space, 0x2004, spriteData);
|
||||
// ppu2c0x_w(device, PPU_SPRITE_DATA, spriteData);
|
||||
}
|
||||
|
||||
// should last 513 CPU cycles.
|
||||
@ -1317,97 +1345,6 @@ void ppu2c0x_render( const device_config *device, bitmap_t *bitmap, int flipx, i
|
||||
copybitmap(bitmap, this_ppu->bitmap, flipx, flipy, sx, sy, 0);
|
||||
}
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* PPU VideoROM banking
|
||||
*
|
||||
*************************************/
|
||||
void ppu2c0x_set_videorom_bank( const device_config *device, int start_page, int num_pages, int bank, int bank_size )
|
||||
{
|
||||
ppu2c0x_chip *this_ppu = get_token(device);
|
||||
const ppu2c0x_interface *intf = get_interface(device);
|
||||
int i;
|
||||
|
||||
if ( !this_ppu->has_videorom )
|
||||
{
|
||||
logerror( "PPU(set vrom bank): Attempting to switch videorom banks and no rom is mapped\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
bank &= ( this_ppu->videorom_banks * ( CHARGEN_NUM_CHARS / bank_size ) ) - 1;
|
||||
|
||||
if (this_ppu->has_videoram)
|
||||
{
|
||||
for ( i = start_page; i < start_page + num_pages; i++ )
|
||||
{
|
||||
int elemnum;
|
||||
|
||||
if ( this_ppu->videoram_banks_indices[i] != -1 )
|
||||
{
|
||||
memcpy( &this_ppu->videoram[this_ppu->videoram_banks_indices[i]*0x400], &this_ppu->videomem[i*0x400], 0x400);
|
||||
}
|
||||
this_ppu->videoram_banks_indices[i] = -1;
|
||||
for (elemnum = 0; elemnum < (num_pages*0x400 >> 4); elemnum++)
|
||||
gfx_element_mark_dirty(device->machine->gfx[intf->gfx_layout_number], (start_page*0x400 >> 4) + elemnum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = start_page; i < ( start_page + num_pages ); i++ )
|
||||
this_ppu->nes_vram[i] = bank * bank_size + 64 * ( i - start_page );
|
||||
}
|
||||
|
||||
{
|
||||
int vram_start = start_page * 0x400;
|
||||
int count = num_pages * 0x400;
|
||||
int rom_start = bank * bank_size * 16;
|
||||
|
||||
memcpy( &this_ppu->videomem[vram_start], &memory_region( device->machine, intf->vrom_region )[rom_start], count );
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* PPU VideoRAM banking
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void ppu2c0x_set_videoram_bank( const device_config *device, int start_page, int num_pages, int bank, int bank_size )
|
||||
{
|
||||
ppu2c0x_chip *this_ppu = get_token(device);
|
||||
const ppu2c0x_interface *intf = get_interface(device);
|
||||
int i;
|
||||
|
||||
if ( !this_ppu->has_videoram )
|
||||
{
|
||||
logerror( "PPU(set vram bank): Attempting to switch videoram banks and no ram is mapped\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
bank &= ( CHARGEN_NUM_CHARS / bank_size ) - 1;
|
||||
|
||||
for ( i = start_page; i < start_page + num_pages; i++ )
|
||||
{
|
||||
int elemnum;
|
||||
if ( this_ppu->videoram_banks_indices[i] != -1 )
|
||||
{
|
||||
memcpy( &this_ppu->videoram[this_ppu->videoram_banks_indices[i]*0x400], &this_ppu->videomem[i*0x400], 0x400);
|
||||
}
|
||||
this_ppu->videoram_banks_indices[i] = (bank * bank_size * 16)/0x400 + (i - start_page);
|
||||
for (elemnum = 0; elemnum < (num_pages*0x400 >> 4); elemnum++)
|
||||
gfx_element_mark_dirty(device->machine->gfx[intf->gfx_layout_number], (start_page*0x400 >> 4) + elemnum);
|
||||
}
|
||||
|
||||
{
|
||||
int vram_start = start_page * 0x400;
|
||||
int count = num_pages * 0x400;
|
||||
int ram_start = bank * bank_size * 16;
|
||||
|
||||
logerror( "ppu2c0x_set_videoram_bank: vram_start = %04x, count = %04x, ram_start = %04x\n", vram_start, count, ram_start );
|
||||
memcpy( &this_ppu->videomem[vram_start], &this_ppu->videoram[ram_start], count );
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Utility functions
|
||||
@ -1439,60 +1376,6 @@ int ppu2c0x_get_current_scanline( const device_config *device )
|
||||
return this_ppu->scanline;
|
||||
}
|
||||
|
||||
void ppu2c0x_set_mirroring( const device_config *device, int mirroring )
|
||||
{
|
||||
ppu2c0x_chip *this_ppu = get_token(device);
|
||||
|
||||
// Once we've set 4-screen mirroring, do not change. Some games
|
||||
// (notably Gauntlet) use mappers that can change the mirroring
|
||||
// state, but are also hard-coded for 4-screen VRAM.
|
||||
if (this_ppu->mirror_state == PPU_MIRROR_4SCREEN)
|
||||
return;
|
||||
|
||||
/* setup our videomem handlers based on mirroring */
|
||||
switch( mirroring )
|
||||
{
|
||||
case PPU_MIRROR_VERT:
|
||||
this_ppu->ppu_page[0] = &(this_ppu->videomem[0x2000]);
|
||||
this_ppu->ppu_page[1] = &(this_ppu->videomem[0x2400]);
|
||||
this_ppu->ppu_page[2] = &(this_ppu->videomem[0x2000]);
|
||||
this_ppu->ppu_page[3] = &(this_ppu->videomem[0x2400]);
|
||||
break;
|
||||
|
||||
case PPU_MIRROR_HORZ:
|
||||
this_ppu->ppu_page[0] = &(this_ppu->videomem[0x2000]);
|
||||
this_ppu->ppu_page[1] = &(this_ppu->videomem[0x2000]);
|
||||
this_ppu->ppu_page[2] = &(this_ppu->videomem[0x2400]);
|
||||
this_ppu->ppu_page[3] = &(this_ppu->videomem[0x2400]);
|
||||
break;
|
||||
|
||||
case PPU_MIRROR_HIGH:
|
||||
this_ppu->ppu_page[0] = &(this_ppu->videomem[0x2400]);
|
||||
this_ppu->ppu_page[1] = &(this_ppu->videomem[0x2400]);
|
||||
this_ppu->ppu_page[2] = &(this_ppu->videomem[0x2400]);
|
||||
this_ppu->ppu_page[3] = &(this_ppu->videomem[0x2400]);
|
||||
break;
|
||||
|
||||
case PPU_MIRROR_LOW:
|
||||
this_ppu->ppu_page[0] = &(this_ppu->videomem[0x2000]);
|
||||
this_ppu->ppu_page[1] = &(this_ppu->videomem[0x2000]);
|
||||
this_ppu->ppu_page[2] = &(this_ppu->videomem[0x2000]);
|
||||
this_ppu->ppu_page[3] = &(this_ppu->videomem[0x2000]);
|
||||
break;
|
||||
|
||||
case PPU_MIRROR_NONE:
|
||||
case PPU_MIRROR_4SCREEN:
|
||||
default:
|
||||
this_ppu->ppu_page[0] = &(this_ppu->videomem[0x2000]);
|
||||
this_ppu->ppu_page[1] = &(this_ppu->videomem[0x2400]);
|
||||
this_ppu->ppu_page[2] = &(this_ppu->videomem[0x2800]);
|
||||
this_ppu->ppu_page[3] = &(this_ppu->videomem[0x2c00]);
|
||||
break;
|
||||
}
|
||||
|
||||
this_ppu->mirror_state = mirroring;
|
||||
}
|
||||
|
||||
void ppu2c0x_set_scanline_callback( const device_config *device, ppu2c0x_scanline_cb cb )
|
||||
{
|
||||
ppu2c0x_chip *this_ppu = get_token(device);
|
||||
@ -1531,6 +1414,14 @@ DEVICE_GET_INFO(ppu2c02)
|
||||
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break;
|
||||
case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_PERIPHERAL; break;
|
||||
case PPU2C0XINFO_INT_SCANLINES_PER_FRAME: info->i = PPU_NTSC_SCANLINES_PER_FRAME; break;
|
||||
case DEVINFO_INT_DATABUS_WIDTH_0: info->i = 8; break;
|
||||
case DEVINFO_INT_ADDRBUS_WIDTH_0: info->i = 14; break;
|
||||
case DEVINFO_INT_ADDRBUS_SHIFT_0: info->i = 0; break;
|
||||
|
||||
|
||||
/* --- the following bits of info are returned as pointers to data --- */
|
||||
case DEVINFO_PTR_DEFAULT_MEMORY_MAP_0: info->default_map8 = ADDRESS_MAP_NAME(ppu2c0x);break;
|
||||
|
||||
|
||||
/* --- the following bits of info are returned as pointers to data or functions --- */
|
||||
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(ppu2c0x); break;
|
||||
|
@ -109,14 +109,11 @@ DEVICE_GET_INFO(ppu2c07);
|
||||
/* routines */
|
||||
void ppu2c0x_init_palette(running_machine *machine, int first_entry ) ATTR_NONNULL(1);
|
||||
|
||||
void ppu2c0x_set_videorom_bank( const device_config *device, int start_page, int num_pages, int bank, int bank_size ) ATTR_NONNULL(1);
|
||||
void ppu2c0x_set_videoram_bank( const device_config *device, int start_page, int num_pages, int bank, int bank_size ) ATTR_NONNULL(1);
|
||||
void ppu2c0x_spriteram_dma(const address_space *space, const device_config *device, const UINT8 page ) ATTR_NONNULL(1);
|
||||
void ppu2c0x_render( const device_config *device, bitmap_t *bitmap, int flipx, int flipy, int sx, int sy ) ATTR_NONNULL(1);
|
||||
int ppu2c0x_get_pixel( const device_config *device, int x, int y ) ATTR_NONNULL(1);
|
||||
int ppu2c0x_get_colorbase( const device_config *device ) ATTR_NONNULL(1);
|
||||
int ppu2c0x_get_current_scanline( const device_config *device ) ATTR_NONNULL(1);
|
||||
void ppu2c0x_set_mirroring( const device_config *device, int mirroring ) ATTR_NONNULL(1);
|
||||
void ppu2c0x_set_scanline_callback( const device_config *device, ppu2c0x_scanline_cb cb ) ATTR_NONNULL(1);
|
||||
void ppu2c0x_set_hblank_callback( const device_config *device, ppu2c0x_scanline_cb cb ) ATTR_NONNULL(1);
|
||||
void ppu2c0x_set_vidaccess_callback( const device_config *device, ppu2c0x_vidaccess_cb cb ) ATTR_NONNULL(1);
|
||||
|
Loading…
Reference in New Issue
Block a user