diff options
author | Nathan Woods <npwoods@mess.org> | 2009-04-13 17:15:17 +0000 |
---|---|---|
committer | Nathan Woods <npwoods@mess.org> | 2009-04-13 17:15:17 +0000 |
commit | 4312fdc9cba01873b1d1910c72d11622a3b25c8f (patch) | |
tree | b2fed687eace2f76b63a661345e925e07b7e43fa | |
parent | 545285d8fa97951f084723e7573c2515efd8d6a5 (diff) |
Changed the PPU2C0x implementation to be a device
-rw-r--r-- | src/mame/drivers/cham24.c | 34 | ||||
-rw-r--r-- | src/mame/drivers/multigam.c | 59 | ||||
-rw-r--r-- | src/mame/drivers/playch10.c | 9 | ||||
-rw-r--r-- | src/mame/drivers/vsnes.c | 17 | ||||
-rw-r--r-- | src/mame/includes/playch10.h | 3 | ||||
-rw-r--r-- | src/mame/includes/vsnes.h | 3 | ||||
-rw-r--r-- | src/mame/machine/playch10.c | 84 | ||||
-rw-r--r-- | src/mame/machine/vsnes.c | 103 | ||||
-rw-r--r-- | src/mame/video/playch10.c | 46 | ||||
-rw-r--r-- | src/mame/video/ppu2c0x.c | 724 | ||||
-rw-r--r-- | src/mame/video/ppu2c0x.h | 127 | ||||
-rw-r--r-- | src/mame/video/vsnes.c | 45 |
12 files changed, 635 insertions, 619 deletions
diff --git a/src/mame/drivers/cham24.c b/src/mame/drivers/cham24.c index fb0dd9c9b5b..6a57af22018 100644 --- a/src/mame/drivers/cham24.c +++ b/src/mame/drivers/cham24.c @@ -63,7 +63,7 @@ Notes: static WRITE8_HANDLER( sprite_dma_w ) { int source = ( data & 7 ); - ppu2c0x_spriteram_dma( space, 0, source ); + ppu2c0x_spriteram_dma( space, devtag_get_device(space->machine, "ppu"), source ); } static READ8_DEVICE_HANDLER( psg_4015_r ) @@ -123,15 +123,16 @@ 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( 0, 0, 8, gfx_bank, 512 ); + ppu2c0x_set_videorom_bank( ppu, 0, 8, gfx_bank, 512 ); // set gfx mirroring - ppu2c0x_set_mirroring( 0, gfx_mirroring != 0 ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT ); + ppu2c0x_set_mirroring( ppu, gfx_mirroring != 0 ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT ); // switch PRG bank if ( prg_bank_page_size == 0 ) @@ -158,7 +159,7 @@ static WRITE8_HANDLER( cham24_mapper_w ) static ADDRESS_MAP_START( cham24_map, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x0000, 0x07ff) AM_RAM /* NES RAM */ - AM_RANGE(0x2000, 0x3fff) AM_READWRITE(ppu2c0x_0_r, ppu2c0x_0_w) + AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu", ppu2c0x_r, ppu2c0x_w) AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("nes", nes_psg_r, nes_psg_w) /* PSG primary registers */ AM_RANGE(0x4014, 0x4014) AM_WRITE(sprite_dma_w) AM_RANGE(0x4015, 0x4015) AM_DEVREADWRITE("nes", psg_4015_r, psg_4015_w) /* PSG status / first control register */ @@ -203,10 +204,6 @@ static MACHINE_RESET( cham24 ) memcpy( &dst[0x8000], &src[0x0f8000], 0x4000 ); memcpy( &dst[0xc000], &src[0x0f8000], 0x4000 ); - device_reset(machine->cpu[0]); - - /* reset the ppu */ - ppu2c0x_reset( machine, 0, 1 ); } static PALETTE_INIT( cham24 ) @@ -214,32 +211,29 @@ static PALETTE_INIT( cham24 ) ppu2c0x_init_palette(machine, 0 ); } -static void ppu_irq( running_machine *machine, int num, int *ppu_regs ) +static void ppu_irq( const device_config *device, int *ppu_regs ) { - cpu_set_input_line(machine->cpu[num], INPUT_LINE_NMI, PULSE_LINE ); + cpu_set_input_line(device->machine->cpu[0], INPUT_LINE_NMI, PULSE_LINE ); } /* our ppu interface */ static const ppu2c0x_interface ppu_interface = { - PPU_2C04, /* type */ - 1, /* num */ - { "gfx1" }, /* vrom gfx region */ - { 0 }, /* gfxlayout num */ - { 0 }, /* color base */ - { PPU_MIRROR_NONE }, /* mirroring */ - { ppu_irq } /* irq */ + "gfx1", /* vrom gfx region */ + 0, /* gfxlayout num */ + 0, /* color base */ + PPU_MIRROR_NONE, /* mirroring */ + ppu_irq /* irq */ }; static VIDEO_START( cham24 ) { - ppu2c0x_init(machine, &ppu_interface ); } static VIDEO_UPDATE( cham24 ) { /* render the ppu */ - ppu2c0x_render( 0, bitmap, 0, 0, 0, 0 ); + ppu2c0x_render( devtag_get_device(screen->machine, "ppu"), bitmap, 0, 0, 0, 0 ); return 0; } @@ -272,6 +266,8 @@ static MACHINE_DRIVER_START( cham24 ) MDRV_VIDEO_START(cham24) MDRV_VIDEO_UPDATE(cham24) + MDRV_PPU2C04_ADD("ppu", ppu_interface) + /* sound hardware */ MDRV_SPEAKER_STANDARD_MONO("mono") diff --git a/src/mame/drivers/multigam.c b/src/mame/drivers/multigam.c index 956896abd40..c62feb7d90e 100644 --- a/src/mame/drivers/multigam.c +++ b/src/mame/drivers/multigam.c @@ -54,7 +54,7 @@ static WRITE8_HANDLER( sprite_dma_w ) { int source = ( data & 7 ); - ppu2c0x_spriteram_dma( space, 0, source ); + ppu2c0x_spriteram_dma( space, devtag_get_device(space->machine, "ppu"), source ); } static READ8_DEVICE_HANDLER( psg_4015_r ) @@ -151,8 +151,9 @@ static WRITE8_HANDLER(multigam_switch_prg_rom) static WRITE8_HANDLER(multigam_switch_gfx_rom) { - ppu2c0x_set_videorom_bank( 0, 0, 8, data /*& 0x3f*/, 512 ); - ppu2c0x_set_mirroring( 0, data & 0x40 ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT ); + 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 ); multigam_game_gfx_bank = data; }; @@ -161,7 +162,8 @@ static WRITE8_HANDLER(multigam_mapper2_w) { if ( multigam_game_gfx_bank & 0x80 ) { - ppu2c0x_set_videorom_bank( 0, 0, 8, multigam_game_gfx_bank + (data & 0xf), 512 ); + const device_config *ppu = devtag_get_device(space->machine, "ppu"); + ppu2c0x_set_videorom_bank( ppu, 0, 8, multigam_game_gfx_bank + (data & 0xf), 512 ); } else { @@ -178,7 +180,7 @@ static WRITE8_HANDLER(multigam_mapper2_w) static ADDRESS_MAP_START( multigam_map, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x0000, 0x07ff) AM_RAM /* NES RAM */ AM_RANGE(0x0800, 0x0fff) AM_RAM /* additional RAM */ - AM_RANGE(0x2000, 0x3fff) AM_READWRITE(ppu2c0x_0_r, ppu2c0x_0_w) + AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu", ppu2c0x_r, ppu2c0x_w) AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("nes", nes_psg_r, nes_psg_w) /* PSG primary registers */ AM_RANGE(0x4014, 0x4014) AM_WRITE(sprite_dma_w) AM_RANGE(0x4015, 0x4015) AM_DEVREADWRITE("nes", psg_4015_r, psg_4015_w) /* PSG status / first control register */ @@ -206,20 +208,22 @@ static int multigam3_mmc3_4screen; static int multigam3_mmc3_last_bank; static UINT8* multigmc_mmc3_6000_ram; -static void multigam3_mmc3_scanline_cb( running_machine *machine, int num, int scanline, int vblank, int blanked ) +static void multigam3_mmc3_scanline_cb( const device_config *device, int scanline, int vblank, int blanked ) { if ( !vblank && !blanked ) { if ( --multigam3_mmc3_scanline_counter == -1 ) { multigam3_mmc3_scanline_counter = multigam3_mmc3_scanline_latch; - generic_pulse_irq_line(machine->cpu[0], 0); + generic_pulse_irq_line(device->machine->cpu[0], 0); } } } static WRITE8_HANDLER( multigam3_mmc3_rom_switch_w ) { + const device_config *ppu = devtag_get_device(space->machine, "ppu"); + /* basically, a MMC3 mapper from the nes */ static int multigam3_mmc3_command; @@ -271,7 +275,7 @@ static WRITE8_HANDLER( multigam3_mmc3_rom_switch_w ) case 1: /* char banking */ data &= 0xfe; page ^= ( cmd << 1 ); - ppu2c0x_set_videorom_bank( 0, page, 2, 0x100 + data, 64 ); + ppu2c0x_set_videorom_bank( ppu, page, 2, 0x100 + data, 64 ); break; case 2: /* char banking */ @@ -279,7 +283,7 @@ static WRITE8_HANDLER( multigam3_mmc3_rom_switch_w ) case 4: /* char banking */ case 5: /* char banking */ page ^= cmd + 2; - ppu2c0x_set_videorom_bank( 0, page, 1, 0x100 + data, 64 ); + ppu2c0x_set_videorom_bank( ppu, page, 1, 0x100 + data, 64 ); break; case 6: /* program banking */ @@ -324,9 +328,9 @@ static WRITE8_HANDLER( multigam3_mmc3_rom_switch_w ) if( !multigam3_mmc3_4screen ) { if ( data & 0x40 ) - ppu2c0x_set_mirroring( 0, PPU_MIRROR_HIGH ); + ppu2c0x_set_mirroring( ppu, PPU_MIRROR_HIGH ); else - ppu2c0x_set_mirroring( 0, ( data & 1 ) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT ); + ppu2c0x_set_mirroring( ppu, ( data & 1 ) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT ); } break; @@ -343,11 +347,11 @@ static WRITE8_HANDLER( multigam3_mmc3_rom_switch_w ) break; case 0x6000: /* disable irqs */ - ppu2c0x_set_scanline_callback( 0, 0 ); + ppu2c0x_set_scanline_callback( ppu, 0 ); break; case 0x6001: /* enable irqs */ - ppu2c0x_set_scanline_callback( 0, multigam3_mmc3_scanline_cb ); + ppu2c0x_set_scanline_callback( ppu, multigam3_mmc3_scanline_cb ); break; } } @@ -377,7 +381,8 @@ static WRITE8_HANDLER(multigm3_mapper2_w) { if ( multigam_game_gfx_bank & 0x80 ) { - ppu2c0x_set_videorom_bank( 0, 0, 8, (multigam_game_gfx_bank & 0xfc) + (data & 0x3), 512 ); + 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 ); } else { @@ -426,7 +431,7 @@ static WRITE8_HANDLER(multigm3_switch_prg_rom) static ADDRESS_MAP_START( multigm3_map, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x0000, 0x07ff) AM_RAM /* NES RAM */ AM_RANGE(0x0800, 0x0fff) AM_RAM /* additional RAM */ - AM_RANGE(0x2000, 0x3fff) AM_READWRITE(ppu2c0x_0_r, ppu2c0x_0_w) + AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu", ppu2c0x_r, ppu2c0x_w) AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("nes", nes_psg_r, nes_psg_w) /* PSG primary registers */ AM_RANGE(0x4014, 0x4014) AM_WRITE(sprite_dma_w) AM_RANGE(0x4015, 0x4015) AM_DEVREADWRITE("nes", psg_4015_r, psg_4015_w) /* PSG status / first control register */ @@ -513,32 +518,29 @@ static PALETTE_INIT( multigam ) ppu2c0x_init_palette(machine, 0 ); } -static void ppu_irq( running_machine *machine, int num, int *ppu_regs ) +static void ppu_irq( const device_config *device, int *ppu_regs ) { - cpu_set_input_line(machine->cpu[num], INPUT_LINE_NMI, PULSE_LINE ); + cpu_set_input_line(device->machine->cpu[0], INPUT_LINE_NMI, PULSE_LINE ); } /* our ppu interface */ static const ppu2c0x_interface ppu_interface = { - PPU_2C04, /* type */ - 1, /* num */ - { "gfx1" }, /* vrom gfx region */ - { 0 }, /* gfxlayout num */ - { 0 }, /* color base */ - { PPU_MIRROR_NONE }, /* mirroring */ - { ppu_irq } /* irq */ + "gfx1", /* vrom gfx region */ + 0, /* gfxlayout num */ + 0, /* color base */ + PPU_MIRROR_NONE, /* mirroring */ + ppu_irq /* irq */ }; static VIDEO_START( multigam ) { - ppu2c0x_init(machine, &ppu_interface ); } static VIDEO_UPDATE( multigam ) { /* render the ppu */ - ppu2c0x_render( 0, bitmap, 0, 0, 0, 0 ); + ppu2c0x_render( devtag_get_device(screen->machine, "ppu"), bitmap, 0, 0, 0, 0 ); return 0; } @@ -554,15 +556,12 @@ GFXDECODE_END static MACHINE_RESET( multigam ) { - /* reset the ppu */ - ppu2c0x_reset( machine, 0, 1 ); } static MACHINE_RESET( multigm3 ) { const address_space *space = cpu_get_address_space(machine->cpu[0], ADDRESS_SPACE_PROGRAM); /* reset the ppu */ - ppu2c0x_reset( machine, 0, 1 ); multigm3_switch_prg_rom(space, 0, 0x01 ); }; @@ -588,6 +587,8 @@ static MACHINE_DRIVER_START( multigam ) MDRV_VIDEO_START(multigam) MDRV_VIDEO_UPDATE(multigam) + MDRV_PPU2C04_ADD("ppu", ppu_interface) + /* sound hardware */ MDRV_SPEAKER_STANDARD_MONO("mono") diff --git a/src/mame/drivers/playch10.c b/src/mame/drivers/playch10.c index 8966384889f..7802bdc3ca5 100644 --- a/src/mame/drivers/playch10.c +++ b/src/mame/drivers/playch10.c @@ -333,7 +333,7 @@ static WRITE8_HANDLER( ram_8w_w ) static WRITE8_HANDLER( sprite_dma_w ) { int source = ( data & 7 ); - ppu2c0x_spriteram_dma( space, 0, source ); + ppu2c0x_spriteram_dma( space, devtag_get_device(space->machine, "ppu"), source ); } static NVRAM_HANDLER( playch10 ) @@ -407,7 +407,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( cart_map, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x0000, 0x07ff) AM_RAM AM_MIRROR(0x1800) AM_BASE(&work_ram) - AM_RANGE(0x2000, 0x3fff) AM_READWRITE(ppu2c0x_0_r, ppu2c0x_0_w) + AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu", ppu2c0x_r, ppu2c0x_w) AM_RANGE(0x4011, 0x4011) AM_DEVWRITE("dac", dac_w) AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("nes", nes_psg_r, nes_psg_w) AM_RANGE(0x4014, 0x4014) AM_WRITE(sprite_dma_w) @@ -717,6 +717,8 @@ static MACHINE_DRIVER_START( playch10 ) MDRV_VIDEO_START(playch10) MDRV_VIDEO_UPDATE(playch10) + MDRV_PPU2C03B_ADD("ppu", playch10_ppu_interface) + // sound hardware MDRV_SPEAKER_STANDARD_MONO("mono") MDRV_SOUND_ADD("nes", NES, N2A03_DEFAULTCLOCK) @@ -735,6 +737,9 @@ MACHINE_DRIVER_END static MACHINE_DRIVER_START( playch10_hboard ) MDRV_IMPORT_FROM(playch10) MDRV_VIDEO_START(playch10_hboard) + + MDRV_DEVICE_REMOVE("ppu") + MDRV_PPU2C03B_ADD("ppu", playch10_ppu_interface) MACHINE_DRIVER_END /*************************************************************************** diff --git a/src/mame/drivers/vsnes.c b/src/mame/drivers/vsnes.c index 12c70a2c471..f188d0ee6e5 100644 --- a/src/mame/drivers/vsnes.c +++ b/src/mame/drivers/vsnes.c @@ -148,14 +148,14 @@ static int coin; static WRITE8_HANDLER( sprite_dma_0_w ) { - int source = ( data & 7 ); - ppu2c0x_spriteram_dma( space, 0, source ); + int source = ( data & 7 ); + ppu2c0x_spriteram_dma( space, devtag_get_device(space->machine, "ppu1"), source ); } static WRITE8_HANDLER( sprite_dma_1_w ) { - int source = ( data & 7 ); - ppu2c0x_spriteram_dma( space, 1, source ); + int source = ( data & 7 ); + ppu2c0x_spriteram_dma( space, devtag_get_device(space->machine, "ppu2"), source ); } static WRITE8_HANDLER( vsnes_coin_counter_w ) @@ -203,7 +203,7 @@ static WRITE8_DEVICE_HANDLER( psg_4017_w ) static ADDRESS_MAP_START( vsnes_cpu1_map, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x0000, 0x07ff) AM_MIRROR(0x1800) AM_RAM AM_BASE(&work_ram) - AM_RANGE(0x2000, 0x3fff) AM_READWRITE(ppu2c0x_0_r, ppu2c0x_0_w) + AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu1", ppu2c0x_r, ppu2c0x_w) AM_RANGE(0x4011, 0x4011) AM_DEVWRITE("dac1", dac_w) AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("nes1", nes_psg_r, nes_psg_w) AM_RANGE(0x4014, 0x4014) AM_WRITE(sprite_dma_0_w) @@ -216,7 +216,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( vsnes_cpu2_map, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x0000, 0x07ff) AM_MIRROR(0x1800) AM_RAM AM_BASE(&work_ram_1) - AM_RANGE(0x2000, 0x3fff) AM_READWRITE(ppu2c0x_1_r, ppu2c0x_1_w) + AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu2", ppu2c0x_r, ppu2c0x_w) AM_RANGE(0x4011, 0x4011) AM_DEVWRITE("dac2", dac_w) AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("nes2", nes_psg_r, nes_psg_w) AM_RANGE(0x4014, 0x4014) AM_WRITE(sprite_dma_1_w) @@ -1782,6 +1782,8 @@ static MACHINE_DRIVER_START( vsnes ) MDRV_VIDEO_START(vsnes) MDRV_VIDEO_UPDATE(vsnes) + MDRV_PPU2C04_ADD("ppu1", vsnes_ppu_interface_1) + /* sound hardware */ MDRV_SPEAKER_STANDARD_MONO("mono") @@ -1825,6 +1827,9 @@ static MACHINE_DRIVER_START( vsdual ) MDRV_VIDEO_START(vsdual) MDRV_VIDEO_UPDATE(vsdual) + MDRV_PPU2C04_ADD("ppu1", vsnes_ppu_interface_1) + MDRV_PPU2C04_ADD("ppu2", vsnes_ppu_interface_2) + /* sound hardware */ MDRV_SPEAKER_STANDARD_MONO("mono") diff --git a/src/mame/includes/playch10.h b/src/mame/includes/playch10.h index a6a1a987d1a..56f66b64a43 100644 --- a/src/mame/includes/playch10.h +++ b/src/mame/includes/playch10.h @@ -46,6 +46,9 @@ extern int pc10_dispmask_old; /*----------- defined in video/playch10.c -----------*/ +extern const ppu2c0x_interface playch10_ppu_interface; +extern const ppu2c0x_interface playch10_ppu_interface_hboard; + WRITE8_HANDLER( playch10_videoram_w ); PALETTE_INIT( playch10 ); VIDEO_START( playch10 ); diff --git a/src/mame/includes/vsnes.h b/src/mame/includes/vsnes.h index f5fe59a36d2..f356d18f7b7 100644 --- a/src/mame/includes/vsnes.h +++ b/src/mame/includes/vsnes.h @@ -7,6 +7,9 @@ VIDEO_START( vsdual ); VIDEO_UPDATE( vsdual ); PALETTE_INIT( vsdual ); +extern const ppu2c0x_interface vsnes_ppu_interface_1; +extern const ppu2c0x_interface vsnes_ppu_interface_2; + /*----------- defined in machine/vsnes.c -----------*/ diff --git a/src/mame/machine/playch10.c b/src/mame/machine/playch10.c index eb87ede52cd..67c5f511c52 100644 --- a/src/mame/machine/playch10.c +++ b/src/mame/machine/playch10.c @@ -29,6 +29,8 @@ static int MMC2_bank[4], MMC2_bank_latch[2]; MACHINE_RESET( pc10 ) { const address_space *space = cpu_get_address_space(machine->cpu[0], ADDRESS_SPACE_PROGRAM); + const device_config *ppu = devtag_get_device(machine, "ppu"); + /* initialize latches and flip-flops */ pc10_nmi_enable = pc10_dog_di = pc10_dispmask = pc10_sdcs = pc10_int_detect = 0; @@ -49,10 +51,7 @@ MACHINE_RESET( pc10 ) RP5H01_0_reset_w( space, 0, 1 ); RP5H01_enable_w( 0, 1 ); - /* reset the ppu */ - ppu2c0x_reset( machine, 0, /* video_screen_get_scan_period(machine->primary_screen) * */ 1 ); - - ppu2c0x_set_mirroring( 0, mirroring ); + ppu2c0x_set_mirroring( ppu, mirroring ); } /************************************* @@ -115,7 +114,7 @@ WRITE8_HANDLER( pc10_GAMESTOP_w ) WRITE8_HANDLER( pc10_PPURES_w ) { if ( data & 1 ) - ppu2c0x_reset( space->machine, 0, /* video_screen_get_scan_period(space->machine->primary_screen) * */ 1 ); + devtag_reset(space->machine, "ppu"); } READ8_HANDLER( pc10_detectclr_r ) @@ -220,6 +219,7 @@ READ8_HANDLER( pc10_in1_r ) /* do the gun thing */ if ( pc10_gun_controller ) { + const device_config *ppu = devtag_get_device(space->machine, "ppu"); int trigger = input_port_read(space->machine, "P1"); int x = input_port_read(space->machine, "GUNX"); int y = input_port_read(space->machine, "GUNY"); @@ -229,10 +229,10 @@ READ8_HANDLER( pc10_in1_r ) ret |= 0x08; /* get the pixel at the gun position */ - pix = ppu2c0x_get_pixel( 0, x, y ); + pix = ppu2c0x_get_pixel( ppu, x, y ); /* get the color base from the ppu */ - color_base = ppu2c0x_get_colorbase( 0 ); + color_base = ppu2c0x_get_colorbase( ppu ); /* look at the screen and see if the cursor is over a bright pixel */ if ( ( pix == color_base+0x20 ) || ( pix == color_base+0x30 ) || @@ -348,6 +348,8 @@ 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; @@ -383,17 +385,17 @@ static WRITE8_HANDLER( mmc1_rom_switch_w ) } /* apply mirroring */ - ppu2c0x_set_mirroring( 0, _mirroring ); + ppu2c0x_set_mirroring( ppu, _mirroring ); } break; case 1: /* video rom banking - bank 0 - 4k or 8k */ - ppu2c0x_set_videorom_bank( 0, 0, ( vrom4k ) ? 4 : 8, ( mmc1_shiftreg & 0x1f ), 256 ); + ppu2c0x_set_videorom_bank( ppu, 0, ( vrom4k ) ? 4 : 8, ( mmc1_shiftreg & 0x1f ), 256 ); break; case 2: /* video rom banking - bank 1 - 4k only */ if ( vrom4k ) - ppu2c0x_set_videorom_bank( 0, 4, 4, ( mmc1_shiftreg & 0x1f ), 256 ); + ppu2c0x_set_videorom_bank( ppu, 4, 4, ( mmc1_shiftreg & 0x1f ), 256 ); break; case 3: /* program banking */ @@ -432,7 +434,8 @@ static WRITE8_HANDLER( mmc1_rom_switch_w ) static WRITE8_HANDLER( aboard_vrom_switch_w ) { - ppu2c0x_set_videorom_bank( 0, 0, 8, ( data & 3 ), 512 ); + const device_config *ppu = devtag_get_device(space->machine, "ppu"); + ppu2c0x_set_videorom_bank( ppu, 0, 8, ( data & 3 ), 512 ); } DRIVER_INIT( pcaboard ) @@ -483,7 +486,8 @@ DRIVER_INIT( pcbboard ) static WRITE8_HANDLER( cboard_vrom_switch_w ) { - ppu2c0x_set_videorom_bank( 0, 0, 8, ( ( data >> 1 ) & 1 ), 512 ); + const device_config *ppu = devtag_get_device(space->machine, "ppu"); + ppu2c0x_set_videorom_bank( ppu, 0, 8, ( ( data >> 1 ) & 1 ), 512 ); } DRIVER_INIT( pccboard ) @@ -533,32 +537,35 @@ DRIVER_INIT( pcdboard_2 ) /* E Board games (Mike Tyson's Punchout) - BROKEN - FIX ME */ /* callback for the ppu_latch */ -static void mapper9_latch( offs_t offset ) +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( 0, 0, 4, MMC2_bank[0], 256 ); + ppu2c0x_set_videorom_bank( ppu, 0, 4, MMC2_bank[0], 256 ); } else if( (offset & 0x1ff0) == 0x0fe0 && MMC2_bank_latch[0] != 0xfe ) { MMC2_bank_latch[0] = 0xfe; - ppu2c0x_set_videorom_bank( 0, 0, 4, MMC2_bank[1], 256 ); + ppu2c0x_set_videorom_bank( ppu, 0, 4, MMC2_bank[1], 256 ); } else if( (offset & 0x1ff0) == 0x1fd0 && MMC2_bank_latch[1] != 0xfd ) { MMC2_bank_latch[1] = 0xfd; - ppu2c0x_set_videorom_bank( 0, 4, 4, MMC2_bank[2], 256 ); + ppu2c0x_set_videorom_bank( ppu, 4, 4, MMC2_bank[2], 256 ); } else if( (offset & 0x1ff0) == 0x1fe0 && MMC2_bank_latch[1] != 0xfe ) { MMC2_bank_latch[1] = 0xfe; - ppu2c0x_set_videorom_bank( 0, 4, 4, MMC2_bank[3], 256 ); + ppu2c0x_set_videorom_bank( ppu, 4, 4, MMC2_bank[3], 256 ); } } 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 ) { @@ -573,29 +580,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( 0, 0, 4, data, 256 ); + ppu2c0x_set_videorom_bank( ppu, 0, 4, data, 256 ); break; case 0x4000: /* gfx bank 0 - 4k */ MMC2_bank[1] = data; if( MMC2_bank_latch[0] == 0xfe ) - ppu2c0x_set_videorom_bank( 0, 0, 4, data, 256 ); + ppu2c0x_set_videorom_bank( ppu, 0, 4, data, 256 ); break; case 0x5000: /* gfx bank 1 - 4k */ MMC2_bank[2] = data; if( MMC2_bank_latch[1] == 0xfd ) - ppu2c0x_set_videorom_bank( 0, 4, 4, data, 256 ); + ppu2c0x_set_videorom_bank( ppu, 4, 4, data, 256 ); break; case 0x6000: /* gfx bank 1 - 4k */ MMC2_bank[3] = data; if( MMC2_bank_latch[1] == 0xfe ) - ppu2c0x_set_videorom_bank( 0, 4, 4, data, 256 ); + ppu2c0x_set_videorom_bank( ppu, 4, 4, data, 256 ); break; case 0x7000: /* mirroring */ - ppu2c0x_set_mirroring( 0, data ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT ); + ppu2c0x_set_mirroring( ppu, data ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT ); break; } @@ -667,20 +674,22 @@ static int gboard_4screen; static int gboard_last_bank; static int gboard_command; -static void gboard_scanline_cb( running_machine *machine, int num, int scanline, int vblank, int blanked ) +static void gboard_scanline_cb( const device_config *device, int scanline, int vblank, int blanked ) { if ( !vblank && !blanked ) { if ( --gboard_scanline_counter == -1 ) { gboard_scanline_counter = gboard_scanline_latch; - generic_pulse_irq_line(machine->cpu[1], 0); + generic_pulse_irq_line(device->machine->cpu[1], 0); } } } static WRITE8_HANDLER( gboard_rom_switch_w ) { + const device_config *ppu = devtag_get_device(space->machine, "ppu"); + /* basically, a MMC3 mapper from the nes */ switch( offset & 0x7001 ) @@ -731,7 +740,7 @@ static WRITE8_HANDLER( gboard_rom_switch_w ) case 1: /* char banking */ data &= 0xfe; page ^= ( cmd << 1 ); - ppu2c0x_set_videorom_bank( 0, page, 2, data, 64 ); + ppu2c0x_set_videorom_bank( ppu, page, 2, data, 64 ); break; case 2: /* char banking */ @@ -739,7 +748,7 @@ static WRITE8_HANDLER( gboard_rom_switch_w ) case 4: /* char banking */ case 5: /* char banking */ page ^= cmd + 2; - ppu2c0x_set_videorom_bank( 0, page, 1, data, 64 ); + ppu2c0x_set_videorom_bank( ppu, page, 1, data, 64 ); break; case 6: /* program banking */ @@ -784,9 +793,9 @@ static WRITE8_HANDLER( gboard_rom_switch_w ) if( !gboard_4screen ) { if ( data & 0x40 ) - ppu2c0x_set_mirroring( 0, PPU_MIRROR_HIGH ); + ppu2c0x_set_mirroring( ppu, PPU_MIRROR_HIGH ); else - ppu2c0x_set_mirroring( 0, ( data & 1 ) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT ); + ppu2c0x_set_mirroring( ppu, ( data & 1 ) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT ); } break; @@ -803,11 +812,11 @@ static WRITE8_HANDLER( gboard_rom_switch_w ) break; case 0x6000: /* disable irqs */ - ppu2c0x_set_scanline_callback( 0, 0 ); + ppu2c0x_set_scanline_callback( ppu, 0 ); break; case 0x6001: /* enable irqs */ - ppu2c0x_set_scanline_callback( 0, gboard_scanline_cb ); + ppu2c0x_set_scanline_callback( ppu, gboard_scanline_cb ); break; } } @@ -854,12 +863,13 @@ DRIVER_INIT( pcgboard_type2 ) 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( 0, PPU_MIRROR_HIGH ); + ppu2c0x_set_mirroring( ppu, PPU_MIRROR_HIGH ); else - ppu2c0x_set_mirroring( 0, PPU_MIRROR_LOW ); + ppu2c0x_set_mirroring( ppu, PPU_MIRROR_LOW ); memcpy( &prg[0x08000], &prg[bank * 0x8000 + 0x10000], 0x8000 ); } @@ -885,6 +895,8 @@ DRIVER_INIT( pciboard ) static WRITE8_HANDLER( hboard_rom_switch_w ) { + const device_config *ppu = devtag_get_device(space->machine, "ppu"); + switch( offset & 0x7001 ) { case 0x0001: @@ -900,11 +912,11 @@ static WRITE8_HANDLER( hboard_rom_switch_w ) page ^= ( cmd << 1 ); if ( data & 0x20 ) { - ppu2c0x_set_videoram_bank( 0, page, 2, data, 64 ); + ppu2c0x_set_videoram_bank( ppu, page, 2, data, 64 ); } else { - ppu2c0x_set_videorom_bank( 0, page, 2, data, 64 ); + ppu2c0x_set_videorom_bank( ppu, page, 2, data, 64 ); } return; @@ -915,11 +927,11 @@ static WRITE8_HANDLER( hboard_rom_switch_w ) page ^= cmd + 2; if ( data & 0x40 ) { - ppu2c0x_set_videoram_bank( 0, page, 1, data, 64 ); + ppu2c0x_set_videoram_bank( ppu, page, 1, data, 64 ); } else { - ppu2c0x_set_videorom_bank( 0, page, 1, data, 64 ); + ppu2c0x_set_videorom_bank( ppu, page, 1, data, 64 ); } return; } diff --git a/src/mame/machine/vsnes.c b/src/mame/machine/vsnes.c index f5061ec42db..d7eb634912b 100644 --- a/src/mame/machine/vsnes.c +++ b/src/mame/machine/vsnes.c @@ -87,7 +87,7 @@ static const UINT8 rp2c05004_colortable[] = /* remap callback */ -static int remap_colors( running_machine *machine, int num, int addr, int data ) +static int remap_colors( const device_config *device, int addr, int data ) { /* this is the protection. color codes are shuffled around */ /* the ones with value 0xff are unknown */ @@ -221,17 +221,16 @@ READ8_HANDLER( vsnes_in1_1_r ) MACHINE_RESET( vsnes ) { + const device_config *ppu = devtag_get_device(machine, "ppu1"); + last_bank = 0xff; sound_fix = 0; input_latch[0] = input_latch[1] = 0; input_latch[2] = input_latch[3] = 0; - /* reset the ppu */ - ppu2c0x_reset( machine, 0, 1 ); - /* if we need to remap, install the callback */ if ( remapped_colortable ) - ppu2c0x_set_vidaccess_callback( 0, remap_colors ); + ppu2c0x_set_vidaccess_callback( ppu, remap_colors ); } /************************************* @@ -241,18 +240,17 @@ MACHINE_RESET( vsnes ) *************************************/ MACHINE_RESET( vsdual ) { + const device_config *ppu1 = devtag_get_device(machine, "ppu1"); + const device_config *ppu2 = devtag_get_device(machine, "ppu2"); + input_latch[0] = input_latch[1] = 0; input_latch[2] = input_latch[3] = 0; - /* reset the ppu */ - ppu2c0x_reset( machine,0,1 ); - ppu2c0x_reset( machine,1,1 ); - /* if we need to remap, install the callback */ if ( remapped_colortable ) { - ppu2c0x_set_vidaccess_callback( 0, remap_colors ); - ppu2c0x_set_vidaccess_callback( 1, remap_colors ); + ppu2c0x_set_vidaccess_callback( ppu1, remap_colors ); + ppu2c0x_set_vidaccess_callback( ppu2, remap_colors ); } } @@ -278,8 +276,10 @@ 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( 0, 0, 8, ( data & 4 ) ? 1 : 0, 512 ); + ppu2c0x_set_videorom_bank( ppu1, 0, 8, ( data & 4 ) ? 1 : 0, 512 ); /* bit 1 ( data & 2 ) enables writes to extra ram, we ignore it */ @@ -297,15 +297,17 @@ DRIVER_INIT( vsnormal ) static WRITE8_HANDLER( ppuRC2C05_protection ) { + const device_config *ppu1 = devtag_get_device(space->machine, "ppu1"); + /* This PPU has registers mapped at $2000 and $2001 inverted */ /* and no remapped color */ if ( offset == 0 ) { - ppu2c0x_0_w( space, 1, data ); + ppu2c0x_w( ppu1, 1, data ); return; } - ppu2c0x_0_w( space, 0, data ); + ppu2c0x_w( ppu1, 0, data ); } /**********************************************************************************/ @@ -336,12 +338,13 @@ DRIVER_INIT( suprmrio ) static WRITE8_HANDLER( gun_in0_w ) { + const device_config *ppu1 = devtag_get_device(space->machine, "ppu1"); static int zapstore; if (vsnes_do_vrom_bank) { /* switch vrom */ - ppu2c0x_set_videorom_bank( 0, 0, 8, ( data & 4 ) ? 1 : 0, 512 ); + ppu2c0x_set_videorom_bank( ppu1, 0, 8, ( data & 4 ) ? 1 : 0, 512 ); } /* here we do things a little different */ @@ -359,10 +362,10 @@ static WRITE8_HANDLER( gun_in0_w ) UINT32 pix, color_base; /* get the pixel at the gun position */ - pix = ppu2c0x_get_pixel( 0, x, y ); + pix = ppu2c0x_get_pixel( ppu1, x, y ); /* get the color base from the ppu */ - color_base = ppu2c0x_get_colorbase( 0 ); + color_base = ppu2c0x_get_colorbase( ppu1 ); /* look at the screen and see if the cursor is over a bright pixel */ if ( ( pix == color_base+0x20 ) || ( pix == color_base+0x30 ) || @@ -403,6 +406,7 @@ DRIVER_INIT( duckhunt ) 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; @@ -418,11 +422,11 @@ static WRITE8_HANDLER( goonies_rom_banking ) break; case 6: /* vrom bank 0 */ - ppu2c0x_set_videorom_bank( 0, 0, 4, data, 256 ); + ppu2c0x_set_videorom_bank( ppu1, 0, 4, data, 256 ); break; case 7: /* vrom bank 1 */ - ppu2c0x_set_videorom_bank( 0, 4, 4, data, 256 ); + ppu2c0x_set_videorom_bank( ppu1, 4, 4, data, 256 ); break; } } @@ -498,7 +502,7 @@ DRIVER_INIT( hogalley ) static READ8_HANDLER( vsgshoe_security_r ) { /* low part must be 0x1c */ - return ppu2c0x_0_r( space, 2 ) | 0x1c; + return ppu2c0x_r( devtag_get_device(space->machine, "ppu"), 2 ) | 0x1c; } static WRITE8_HANDLER( vsgshoe_gun_in0_w ) @@ -545,6 +549,8 @@ 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; @@ -609,17 +615,17 @@ static WRITE8_HANDLER( drmario_rom_banking ) } /* apply mirroring */ - ppu2c0x_set_mirroring( 0, mirroring ); + ppu2c0x_set_mirroring( ppu1, mirroring ); } break; case 1: /* video rom banking - bank 0 - 4k or 8k */ - ppu2c0x_set_videorom_bank( 0, 0, ( vrom4k ) ? 4 : 8, drmario_shiftreg, ( vrom4k ) ? 256 : 512 ); + ppu2c0x_set_videorom_bank( ppu1, 0, ( vrom4k ) ? 4 : 8, drmario_shiftreg, ( vrom4k ) ? 256 : 512 ); break; case 2: /* video rom banking - bank 1 - 4k only */ if ( vrom4k ) - ppu2c0x_set_videorom_bank( 0, 4, 4, drmario_shiftreg, 256 ); + ppu2c0x_set_videorom_bank( ppu1, 4, 4, drmario_shiftreg, 256 ); break; case 3: /* program banking */ @@ -778,7 +784,7 @@ DRIVER_INIT( cstlevna ) static READ8_HANDLER( topgun_security_r ) { /* low part must be 0x1b */ - return ppu2c0x_0_r( space, 2 ) | 0x1b; + return ppu2c0x_r( devtag_get_device(space->machine, "ppu"), 2 ) | 0x1b; } DRIVER_INIT( topgun ) @@ -826,19 +832,20 @@ 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(0, chr_page ^ 0, 2, MMC3_chr[0], 1); - ppu2c0x_set_videorom_bank(0, chr_page ^ 2, 2, MMC3_chr[1], 1); - ppu2c0x_set_videorom_bank(0, chr_page ^ 4, 1, MMC3_chr[2], 1); - ppu2c0x_set_videorom_bank(0, chr_page ^ 5, 1, MMC3_chr[3], 1); - ppu2c0x_set_videorom_bank(0, chr_page ^ 6, 1, MMC3_chr[4], 1); - ppu2c0x_set_videorom_bank(0, chr_page ^ 7, 1, MMC3_chr[5], 1); + 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); } #define BOTTOM_VISIBLE_SCANLINE 239 /* The bottommost visible scanline */ #define NUM_SCANLINE 262 -static void mapper4_irq ( running_machine *machine, int num, int scanline, int vblank, int blanked ) +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)) @@ -848,7 +855,7 @@ static void mapper4_irq ( running_machine *machine, int num, int scanline, int v if (IRQ_count == 0) { IRQ_count = IRQ_count_latch; - cpu_set_input_line (machine->cpu[0], 0, HOLD_LINE); + cpu_set_input_line (device->machine->cpu[0], 0, HOLD_LINE); } IRQ_count --; } @@ -857,6 +864,8 @@ static void mapper4_irq ( running_machine *machine, int num, int scanline, int v static WRITE8_HANDLER( mapper4_w ) { + const device_config *ppu1 = devtag_get_device(space->machine, "ppu1"); + switch (offset & 0x7001) { case 0x0000: /* $8000 */ @@ -905,13 +914,13 @@ static WRITE8_HANDLER( mapper4_w ) } case 0x2000: /* $a000 */ if (data & 0x40) - ppu2c0x_set_mirroring(0, PPU_MIRROR_HIGH); + ppu2c0x_set_mirroring(ppu1, PPU_MIRROR_HIGH); else { if (data & 0x01) - ppu2c0x_set_mirroring(0, PPU_MIRROR_HORZ); + ppu2c0x_set_mirroring(ppu1, PPU_MIRROR_HORZ); else - ppu2c0x_set_mirroring(0, PPU_MIRROR_VERT); + ppu2c0x_set_mirroring(ppu1, PPU_MIRROR_VERT); } break; @@ -934,13 +943,13 @@ static WRITE8_HANDLER( mapper4_w ) IRQ_enable = 0; IRQ_count = IRQ_count_latch; - ppu2c0x_set_scanline_callback (0, 0); + ppu2c0x_set_scanline_callback (ppu1, 0); break; case 0x6001: /* $e001 - Enable IRQs */ IRQ_enable = 1; - ppu2c0x_set_scanline_callback (0, mapper4_irq); + ppu2c0x_set_scanline_callback (ppu1, mapper4_irq); break; @@ -1125,24 +1134,26 @@ DRIVER_INIT( vsfdf ) /**********************************************************************************/ /* Platoon rom banking */ -static WRITE8_HANDLER( mapper68_rom_banking ){ +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(0,0,2,data,128); + ppu2c0x_set_videorom_bank(ppu1,0,2,data,128); break; case 0x1000: - ppu2c0x_set_videorom_bank(0,2,2,data,128); + ppu2c0x_set_videorom_bank(ppu1,2,2,data,128); break; case 0x2000: - ppu2c0x_set_videorom_bank(0,4,2,data,128); + ppu2c0x_set_videorom_bank(ppu1,4,2,data,128); break; case 0x3000: /* ok? */ - ppu2c0x_set_videorom_bank(0,6,2,data,128); + ppu2c0x_set_videorom_bank(ppu1,6,2,data,128); break; @@ -1217,7 +1228,7 @@ DRIVER_INIT( bnglngby ) static READ8_HANDLER( jajamaru_security_r ) { /* low part must be 0x40 */ - return ppu2c0x_0_r( space, 2 ) | 0x40; + return ppu2c0x_r( devtag_get_device(space->machine, "ppu"), 2 ) | 0x40; } DRIVER_INIT( jajamaru ) @@ -1244,7 +1255,7 @@ DRIVER_INIT( jajamaru ) static READ8_HANDLER( mightybj_security_r ) { /* low part must be 0x3d */ - return ppu2c0x_0_r( space, 2 ) | 0x3d; + return ppu2c0x_r( devtag_get_device(space->machine, "ppu"), 2 ) | 0x3d; } DRIVER_INIT( mightybj ) @@ -1263,9 +1274,11 @@ DRIVER_INIT( mightybj ) static WRITE8_HANDLER( vstennis_vrom_banking ) { const device_config *other_cpu = (space->cpu == space->machine->cpu[0]) ? space->machine->cpu[1] : space->machine->cpu[0]; + 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 == space->machine->cpu[0]) ? 0 : 1, 0, 8, ( data & 4 ) ? 1 : 0, 512 ); + ppu2c0x_set_videorom_bank( (space->cpu == space->machine->cpu[0]) ? ppu1 : ppu2, 0, 8, ( data & 4 ) ? 1 : 0, 512 ); /* bit 1 ( data & 2 ) triggers irq on the other cpu */ cpu_set_input_line(other_cpu, 0, ( data & 2 ) ? CLEAR_LINE : ASSERT_LINE ); diff --git a/src/mame/video/playch10.c b/src/mame/video/playch10.c index f6a291c776e..9420c245021 100644 --- a/src/mame/video/playch10.c +++ b/src/mame/video/playch10.c @@ -57,9 +57,9 @@ PALETTE_INIT( playch10 ) ppu2c0x_init_palette(machine, 256 ); } -static void ppu_irq( running_machine *machine, int num, int *ppu_regs ) +static void ppu_irq( const device_config *device, int *ppu_regs ) { - cpu_set_input_line(machine->cpu[1], INPUT_LINE_NMI, PULSE_LINE ); + cpu_set_input_line(device->machine->cpu[1], INPUT_LINE_NMI, PULSE_LINE ); pc10_int_detect = 1; } @@ -67,28 +67,24 @@ static void ppu_irq( running_machine *machine, int num, int *ppu_regs ) /* things like mirroring and whether to use vrom or vram */ /* can be set by calling 'ppu2c0x_override_hardware_options' */ -static const ppu2c0x_interface ppu_interface = +const ppu2c0x_interface playch10_ppu_interface = { - PPU_2C03B, /* type */ - 1, /* num */ - { "gfx2" }, /* vrom gfx region */ - { 1 }, /* gfxlayout num */ - { 256 }, /* color base */ - { PPU_MIRROR_NONE }, /* mirroring */ - { ppu_irq }, /* irq */ - { 0 } /* vram */ + "gfx2", /* vrom gfx region */ + 1, /* gfxlayout num */ + 256, /* color base */ + PPU_MIRROR_NONE, /* mirroring */ + ppu_irq, /* irq */ + 0 /* vram */ }; -static const ppu2c0x_interface ppu_interface_hboard = +const ppu2c0x_interface playch10_ppu_interface_hboard = { - PPU_2C03B, /* type */ - 1, /* num */ - { "gfx2" }, /* vrom gfx region */ - { 1 }, /* gfxlayout num */ - { 256 }, /* color base */ - { PPU_MIRROR_NONE }, /* mirroring */ - { ppu_irq }, /* irq */ - { 1 } /* vram */ + "gfx2", /* vrom gfx region */ + 1, /* gfxlayout num */ + 256, /* color base */ + PPU_MIRROR_NONE, /* mirroring */ + ppu_irq, /* irq */ + 1 /* vram */ }; static TILE_GET_INFO( get_bg_tile_info ) @@ -107,8 +103,6 @@ VIDEO_START( playch10 ) bg_tilemap = tilemap_create(machine, get_bg_tile_info, tilemap_scan_rows, 8, 8, 32, 32); - - ppu2c0x_init(machine, &ppu_interface ); } VIDEO_START( playch10_hboard ) @@ -118,8 +112,6 @@ VIDEO_START( playch10_hboard ) bg_tilemap = tilemap_create(machine, get_bg_tile_info, tilemap_scan_rows, 8, 8, 32, 32); - - ppu2c0x_init(machine, &ppu_interface_hboard ); } /*************************************************************************** @@ -130,6 +122,8 @@ VIDEO_START( playch10_hboard ) VIDEO_UPDATE( playch10 ) { + const device_config *ppu = devtag_get_device(screen->machine, "ppu"); + /* Dual monitor version */ if (pc10_bios == 1) { @@ -145,7 +139,7 @@ VIDEO_UPDATE( playch10 ) { if ( !pc10_dispmask ) /* render the ppu */ - ppu2c0x_render( 0, bitmap, 0, 0, 0, 0 ); + ppu2c0x_render( ppu, bitmap, 0, 0, 0, 0 ); else bitmap_fill(bitmap, cliprect, 0); } @@ -175,7 +169,7 @@ VIDEO_UPDATE( playch10 ) if ( pc10_game_mode ) /* render the ppu */ - ppu2c0x_render( 0, bitmap, 0, 0, 0, 0 ); + ppu2c0x_render( ppu, bitmap, 0, 0, 0, 0 ); else { /* When the bios is accessing vram, the video circuitry can't access it */ diff --git a/src/mame/video/ppu2c0x.c b/src/mame/video/ppu2c0x.c index 1e15f720b6e..475146535f5 100644 --- a/src/mame/video/ppu2c0x.c +++ b/src/mame/video/ppu2c0x.c @@ -28,6 +28,11 @@ NES-specific: #include "profiler.h" #include "video/ppu2c0x.h" + +/*************************************************************************** + CONSTANTS +***************************************************************************/ + /* constant definitions */ #define VISIBLE_SCREEN_WIDTH (32*8) /* Visible screen width */ #define VISIBLE_SCREEN_HEIGHT (30*8) /* Visible screen height */ @@ -37,6 +42,11 @@ NES-specific: #define SPRITERAM_MASK (0x100-1) /* spriteram size */ #define CHARGEN_NUM_CHARS 512 /* max number of characters handled by the chargen */ +enum +{ + PPU2C0XINFO_INT_SCANLINES_PER_FRAME = DEVINFO_INT_DEVICE_SPECIFIC +}; + /* default monochromatic colortable */ static const pen_t default_colortable_mono[] = { @@ -63,9 +73,14 @@ static const pen_t default_colortable[] = 0,29,30,31, }; + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + /* our chip state */ -typedef struct { - running_machine *machine; /* execution context */ +typedef struct +{ bitmap_t *bitmap; /* target bitmap */ UINT8 *videomem; /* video mem */ UINT8 *videoram; /* video ram */ @@ -104,20 +119,48 @@ typedef struct { rgb_t palette[64*4]; /* palette for this chip */ } ppu2c0x_chip; -/* our local copy of the interface */ -static ppu2c0x_interface *intf; -/* chips state - allocated at init time */ -static ppu2c0x_chip *chips = 0; -static void update_scanline(running_machine *machine, int num ); +/*************************************************************************** + PROTOTYPES +***************************************************************************/ + +static void update_scanline(const device_config *device); static TIMER_CALLBACK( scanline_callback ); static TIMER_CALLBACK( hblank_callback ); static TIMER_CALLBACK( nmi_callback ); -void (*ppu_latch)( offs_t offset ); +void (*ppu_latch)( const device_config *device, offs_t offset ); + + +/*************************************************************************** + INLINE FUNCTIONS +***************************************************************************/ + +INLINE ppu2c0x_chip *get_token(const device_config *device) +{ + assert(device != NULL); + assert((device->type == PPU_2C02) || (device->type == PPU_2C03B) + || (device->type == PPU_2C04) || (device->type == PPU_2C05) + || (device->type == PPU_2C07)); + return (ppu2c0x_chip *) device->token; +} + + +INLINE const ppu2c0x_interface *get_interface(const device_config *device) +{ + assert(device != NULL); + assert((device->type == PPU_2C02) || (device->type == PPU_2C03B) + || (device->type == PPU_2C04) || (device->type == PPU_2C05) + || (device->type == PPU_2C07)); + return (const ppu2c0x_interface *) device->static_config; +} + +/*************************************************************************** + IMPLEMENTATION +***************************************************************************/ /************************************* * @@ -254,159 +297,131 @@ static const gfx_layout ppu_charlayout = * PPU Initialization and Disposal * *************************************/ -void ppu2c0x_init(running_machine *machine, const ppu2c0x_interface *interface ) + +static DEVICE_START( ppu2c0x ) { - int i; UINT32 total; + ppu2c0x_chip *chip = get_token(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); + + /* initialize the scanline handling portion */ + chip->scanline_timer = timer_alloc(device->machine, scanline_callback, (void *) device); + chip->hblank_timer = timer_alloc(device->machine, hblank_callback, (void *) device); + chip->nmi_timer = timer_alloc(device->machine, nmi_callback, (void *) device); + chip->scanline = 0; + chip->scan_scale = 1; + + /* allocate a screen bitmap, videomem and spriteram, a dirtychar array and the monochromatic colortable */ + chip->bitmap = auto_bitmap_alloc( VISIBLE_SCREEN_WIDTH, VISIBLE_SCREEN_HEIGHT, video_screen_get_format(device->machine->primary_screen)); + chip->videomem = auto_malloc( VIDEOMEM_SIZE ); + chip->videoram = auto_malloc( VIDEOMEM_SIZE ); + chip->spriteram = auto_malloc( SPRITERAM_SIZE ); + chip->colortable = auto_malloc( sizeof( default_colortable ) ); + chip->colortable_mono = auto_malloc( sizeof( default_colortable_mono ) ); + + /* clear videomem & spriteram */ + memset( chip->videomem, 0, VIDEOMEM_SIZE ); + memset( chip->videoram, 0, VIDEOMEM_SIZE ); + memset( chip->spriteram, 0, SPRITERAM_SIZE ); + memset( chip->videoram_banks_indices, 0xff, sizeof(chip->videoram_banks_indices) ); + + if ( intf->vram_enabled ) + { + chip->has_videoram = 1; + } - /* keep a local copy of the interface */ - intf = auto_malloc(sizeof(*interface)); - memcpy(intf, interface, sizeof(*interface)); - - /* safety check */ - assert_always ( intf->num > 0, "Invalid intf->num" ); - - chips = auto_malloc( intf->num * sizeof( ppu2c0x_chip ) ); - memset(chips, 0, intf->num * sizeof( ppu2c0x_chip )); - - /* intialize our virtual chips */ - for( i = 0; i < intf->num; i++ ) + /* initialize the video ROM portion, if available */ + if ( ( intf->vrom_region != NULL ) && ( memory_region( device->machine, intf->vrom_region ) != 0 ) ) { - chips[i].machine = machine; + /* mark that we have a videorom */ + chip->has_videorom = 1; - switch (intf->type) - { - case PPU_2C02: - chips[i].scanlines_per_frame = PPU_NTSC_SCANLINES_PER_FRAME; - break; - case PPU_2C03B: - chips[i].scanlines_per_frame = PPU_NTSC_SCANLINES_PER_FRAME; - break; - case PPU_2C04: - chips[i].scanlines_per_frame = PPU_NTSC_SCANLINES_PER_FRAME; - break; - case PPU_2C05: - chips[i].scanlines_per_frame = PPU_NTSC_SCANLINES_PER_FRAME; - break; - case PPU_2C07: - chips[i].scanlines_per_frame = PPU_PAL_SCANLINES_PER_FRAME; - break; - default: - chips[i].scanlines_per_frame = PPU_NTSC_SCANLINES_PER_FRAME; - break; - } + /* find out how many banks */ + chip->videorom_banks = memory_region_length( device->machine, intf->vrom_region ) / 0x2000; - /* initialize the scanline handling portion */ - chips[i].scanline_timer = timer_alloc(machine, scanline_callback, NULL); - chips[i].hblank_timer = timer_alloc(machine, hblank_callback, NULL); - chips[i].nmi_timer = timer_alloc(machine, nmi_callback, NULL); - chips[i].scanline = 0; - chips[i].scan_scale = 1; - - /* allocate a screen bitmap, videomem and spriteram, a dirtychar array and the monochromatic colortable */ - chips[i].bitmap = auto_bitmap_alloc( VISIBLE_SCREEN_WIDTH, VISIBLE_SCREEN_HEIGHT, video_screen_get_format(machine->primary_screen)); - chips[i].videomem = auto_malloc( VIDEOMEM_SIZE ); - chips[i].videoram = auto_malloc( VIDEOMEM_SIZE ); - chips[i].spriteram = auto_malloc( SPRITERAM_SIZE ); - chips[i].colortable = auto_malloc( sizeof( default_colortable ) ); - chips[i].colortable_mono = auto_malloc( sizeof( default_colortable_mono ) ); - - /* clear videomem & spriteram */ - memset( chips[i].videomem, 0, VIDEOMEM_SIZE ); - memset( chips[i].videoram, 0, VIDEOMEM_SIZE ); - memset( chips[i].spriteram, 0, SPRITERAM_SIZE ); - memset( chips[i].videoram_banks_indices, 0xff, sizeof(chips[i].videoram_banks_indices) ); - - if ( intf->vram_enabled[i] ) + /* tweak the layout accordingly */ + if ( chip->has_videoram ) { - chips[i].has_videoram = 1; - } - - /* initialize the video ROM portion, if available */ - if ( ( intf->vrom_region[i] != NULL ) && ( memory_region( machine, intf->vrom_region[i] ) != 0 ) ) - { - /* mark that we have a videorom */ - chips[i].has_videorom = 1; - - /* find out how many banks */ - chips[i].videorom_banks = memory_region_length( machine, intf->vrom_region[i] ) / 0x2000; - - /* tweak the layout accordingly */ - if ( chips[i].has_videoram ) - { - total = CHARGEN_NUM_CHARS; - } - else - { - total = chips[i].videorom_banks * CHARGEN_NUM_CHARS; - } + total = CHARGEN_NUM_CHARS; } else { - chips[i].has_videorom = chips[i].videorom_banks = 0; - - /* we need to reset this in case of mame running multisession */ - total = CHARGEN_NUM_CHARS; + total = chip->videorom_banks * CHARGEN_NUM_CHARS; } + } + else + { + chip->has_videorom = chip->videorom_banks = 0; - /* now create the gfx region */ - { - gfx_layout gl; - UINT8 *src = (chips[i].has_videorom && !chips[i].has_videoram) ? memory_region( machine, intf->vrom_region[i] ) : chips[i].videomem; + /* we need to reset this in case of mame running multisession */ + total = CHARGEN_NUM_CHARS; + } - memcpy(&gl, &ppu_charlayout, sizeof(gl)); - gl.total = total; - machine->gfx[intf->gfx_layout_number[i]] = gfx_element_alloc( machine, &gl, src, 8, 0 ); - } + /* 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; - /* setup our videomem handlers based on mirroring */ - ppu2c0x_set_mirroring( i, intf->mirroring[i] ); + 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 ) { - int num = param; - ppu2c0x_chip* this_ppu = &chips[num]; - int *ppu_regs = &chips[num].regs[0]; + const device_config *device = ptr; + ppu2c0x_chip *this_ppu = get_token(device); + int *ppu_regs = &this_ppu->regs[0]; int blanked = ( ppu_regs[PPU_CONTROL1] & ( PPU_CONTROL1_BACKGROUND | PPU_CONTROL1_SPRITES ) ) == 0; int vblank = ((this_ppu->scanline >= PPU_VBLANK_FIRST_SCANLINE-1) && (this_ppu->scanline < this_ppu->scanlines_per_frame-1)) ? 1 : 0; -// update_scanline (machine, num); +// update_scanline (device); if (this_ppu->hblank_callback_proc) - (*this_ppu->hblank_callback_proc) (machine, num, this_ppu->scanline, vblank, blanked); + (*this_ppu->hblank_callback_proc) (device, this_ppu->scanline, vblank, blanked); - timer_adjust_oneshot(chips[num].hblank_timer, attotime_never, num); + timer_adjust_oneshot(this_ppu->hblank_timer, attotime_never, 0); } static TIMER_CALLBACK( nmi_callback ) { - int num = param; - int *ppu_regs = &chips[num].regs[0]; + const device_config *device = ptr; + ppu2c0x_chip *this_ppu = get_token(device); + const ppu2c0x_interface *intf = get_interface(device); + int *ppu_regs = &this_ppu->regs[0]; // Actually fire the VMI - if (intf->nmi_handler[num]) - (*intf->nmi_handler[num]) (machine, num, ppu_regs); + if (intf->nmi_handler != NULL) + (*intf->nmi_handler) (device, ppu_regs); - timer_adjust_oneshot(chips[num].nmi_timer, attotime_never, num); + timer_adjust_oneshot(this_ppu->nmi_timer, attotime_never, 0); } -static void draw_background(running_machine *machine, int num, UINT8 *line_priority ) +static void draw_background(const device_config *device, UINT8 *line_priority ) { + const ppu2c0x_interface *intf = get_interface(device); + ppu2c0x_chip *this_ppu = get_token(device); + /* cache some values locally */ - bitmap_t *bitmap = chips[num].bitmap; - const int *ppu_regs = &chips[num].regs[0]; - const int scanline = chips[num].scanline; - const int refresh_data = chips[num].refresh_data; - const int gfx_bank = intf->gfx_layout_number[num]; - const int total_elements = chips[num].machine->gfx[gfx_bank]->total_elements; - const int *nes_vram = &chips[num].nes_vram[0]; - const int tile_page = chips[num].tile_page; - const int line_modulo = chips[num].machine->gfx[gfx_bank]->line_modulo; - UINT8 **ppu_page = chips[num].ppu_page; - int start_x = ( chips[num].x_fine ^ 0x07 ) - 7; + bitmap_t *bitmap = this_ppu->bitmap; + 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; @@ -423,16 +438,16 @@ static void draw_background(running_machine *machine, int num, UINT8 *line_prior if ( ppu_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO ) { color_mask = 0xf0; - color_table = chips[num].colortable_mono; + color_table = this_ppu->colortable_mono; } else { color_mask = 0xff; - color_table = chips[num].colortable; + color_table = this_ppu->colortable; } /* cache the background pen */ - back_pen = (chips[num].back_color & color_mask)+intf->color_base[num]; + back_pen = (this_ppu->back_color & color_mask)+intf->color_base; /* determine where in the nametable to start drawing from */ /* based on the current scanline and scroll regs */ @@ -477,14 +492,14 @@ static void draw_background(running_machine *machine, int num, UINT8 *line_prior //27/12/2002 if( ppu_latch ) { - (*ppu_latch)(( tile_page << 10 ) | ( page2 << 4 )); + (*ppu_latch)(device, ( tile_page << 10 ) | ( page2 << 4 )); } if(start_x < VISIBLE_SCREEN_WIDTH ) { paldata = &color_table[ 4 * ( ( ( color_byte >> color_bits ) & 0x03 ) ) ]; start = scroll_y_fine * line_modulo; - sd = gfx_element_get_data(chips[num].machine->gfx[gfx_bank], index2 % total_elements) + start; + sd = gfx_element_get_data(device->machine->gfx[gfx_bank], index2 % total_elements) + start; /* render the pixel */ for( i = 0; i < 8; i++ ) @@ -530,18 +545,21 @@ static void draw_background(running_machine *machine, int num, UINT8 *line_prior } } -static void draw_sprites(running_machine *machine, int num, UINT8 *line_priority ) +static void draw_sprites(const device_config *device, UINT8 *line_priority ) { + const ppu2c0x_interface *intf = get_interface(device); + ppu2c0x_chip *this_ppu = get_token(device); + /* cache some values locally */ - bitmap_t *bitmap = chips[num].bitmap; - const int scanline = chips[num].scanline; - const int gfx_bank = intf->gfx_layout_number[num]; - const int total_elements = chips[num].machine->gfx[gfx_bank]->total_elements; - const int sprite_page = chips[num].sprite_page; - const int line_modulo = chips[num].machine->gfx[gfx_bank]->line_modulo; - const UINT8 *sprite_ram = chips[num].spriteram; - pen_t *color_table = chips[num].colortable; - int *ppu_regs = &chips[num].regs[0]; + 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]; int spriteXPos, spriteYPos, spriteIndex; int tile, index1, page; @@ -613,10 +631,10 @@ static void draw_sprites(running_machine *machine, int num, UINT8 *line_priority page = ( tile >> 6 ) | sprite_page; - index1 = chips[num].nes_vram[page] + ( tile & 0x3f ); + index1 = this_ppu->nes_vram[page] + ( tile & 0x3f ); if ( ppu_latch ) - (*ppu_latch)(( sprite_page << 10 ) | ( (tile & 0xff) << 4 )); + (*ppu_latch)(device, ( sprite_page << 10 ) | ( (tile & 0xff) << 4 )); /* compute the character's line to draw */ sprite_line = scanline - spriteYPos; @@ -626,9 +644,9 @@ static void draw_sprites(running_machine *machine, int num, UINT8 *line_priority paldata = &color_table[4 * color]; start = sprite_line * line_modulo; - sd = gfx_element_get_data(chips[num].machine->gfx[gfx_bank], index1 % total_elements) + start; + sd = gfx_element_get_data(device->machine->gfx[gfx_bank], index1 % total_elements) + start; if (size > 8) - gfx_element_get_data(chips[num].machine->gfx[gfx_bank], (index1 + 1) % total_elements); + gfx_element_get_data(device->machine->gfx[gfx_bank], (index1 + 1) % total_elements); if ( pri ) { @@ -716,13 +734,15 @@ static void draw_sprites(running_machine *machine, int num, UINT8 *line_priority * Scanline Rendering and Update * *************************************/ -static void render_scanline(running_machine *machine, int num) +static void render_scanline(const device_config *device) { + ppu2c0x_chip *this_ppu = get_token(device); + const ppu2c0x_interface *intf = get_interface(device); UINT8 line_priority[VISIBLE_SCREEN_WIDTH]; - int *ppu_regs = &chips[num].regs[0]; + int *ppu_regs = &this_ppu->regs[0]; /* lets see how long it takes */ - profiler_mark(PROFILER_USER1+num); + profiler_mark(PROFILER_USER1); /* clear the line priority for this scanline */ memset( line_priority, 0, VISIBLE_SCREEN_WIDTH ); @@ -732,11 +752,11 @@ static void render_scanline(running_machine *machine, int num) /* see if we need to render the background */ if ( ppu_regs[PPU_CONTROL1] & PPU_CONTROL1_BACKGROUND ) - draw_background(machine, num, line_priority ); + draw_background(device, line_priority ); else { - bitmap_t *bitmap = chips[num].bitmap; - const int scanline = chips[num].scanline; + bitmap_t *bitmap = this_ppu->bitmap; + const int scanline = this_ppu->scanline; UINT8 color_mask; UINT16 back_pen; int i; @@ -748,7 +768,7 @@ static void render_scanline(running_machine *machine, int num) color_mask = 0xff; /* cache the background pen */ - back_pen = (chips[num].back_color & color_mask)+intf->color_base[num]; + back_pen = (this_ppu->back_color & color_mask)+intf->color_base; // Fill this scanline with the background pen. for (i = 0; i < bitmap->width; i ++) @@ -757,19 +777,18 @@ static void render_scanline(running_machine *machine, int num) /* if sprites are on, draw them */ if ( ppu_regs[PPU_CONTROL1] & PPU_CONTROL1_SPRITES ) - draw_sprites( machine, num, line_priority ); + draw_sprites( device, line_priority ); /* done updating, whew */ profiler_mark(PROFILER_END); } -static void update_scanline(running_machine *machine, int num ) +static void update_scanline(const device_config *device) { - ppu2c0x_chip* this_ppu; - int scanline = chips[num].scanline; - int *ppu_regs = &chips[num].regs[0]; - - this_ppu = &chips[num]; + ppu2c0x_chip *this_ppu = get_token(device); + const ppu2c0x_interface *intf = get_interface(device); + int scanline = this_ppu->scanline; + int *ppu_regs = &this_ppu->regs[0]; if ( scanline <= PPU_BOTTOM_VISIBLE_SCANLINE ) { @@ -782,7 +801,7 @@ static void update_scanline(running_machine *machine, int num ) this_ppu->refresh_data |= ( this_ppu->refresh_latch & 0x041f ); //logerror(" updating refresh_data: %04x (scanline: %d)\n", this_ppu->refresh_data, this_ppu->scanline); - render_scanline( machine, num ); + render_scanline( device ); } else { @@ -812,10 +831,10 @@ static void update_scanline(running_machine *machine, int num ) else penNum = this_ppu->videomem[this_ppu->videomem_addr & 0x3f00] & 0x3f; - back_pen = penNum + intf->color_base[num]; + back_pen = penNum + intf->color_base; } else - back_pen = (this_ppu->back_color & color_mask)+intf->color_base[num]; + back_pen = (this_ppu->back_color & color_mask)+intf->color_base; // Fill this scanline with the background pen. for (i = 0; i < bitmap->width; i ++) @@ -846,24 +865,24 @@ static void update_scanline(running_machine *machine, int num ) static TIMER_CALLBACK( scanline_callback ) { - int num = param; - ppu2c0x_chip* this_ppu = &chips[num]; - int *ppu_regs = &chips[num].regs[0]; + const device_config *device = ptr; + ppu2c0x_chip *this_ppu = get_token(device); + int *ppu_regs = &this_ppu->regs[0]; int blanked = ( ppu_regs[PPU_CONTROL1] & ( PPU_CONTROL1_BACKGROUND | PPU_CONTROL1_SPRITES ) ) == 0; int vblank = ((this_ppu->scanline >= PPU_VBLANK_FIRST_SCANLINE-1) && (this_ppu->scanline < this_ppu->scanlines_per_frame-1)) ? 1 : 0; int next_scanline; /* if a callback is available, call it */ - if ( this_ppu->scanline_callback_proc ) - (*this_ppu->scanline_callback_proc)( machine, num, this_ppu->scanline, vblank, blanked ); + if ( this_ppu->scanline_callback_proc != NULL ) + (*this_ppu->scanline_callback_proc)( device, this_ppu->scanline, vblank, blanked ); /* update the scanline that just went by */ - update_scanline( machine, num ); + update_scanline( device ); /* increment our scanline count */ this_ppu->scanline++; -//logerror("starting scanline %d (MAME %d, beam %d)\n", this_ppu->scanline, video_screen_get_vpos(machine->primary_screen), video_screen_get_hpos(machine->primary_screen)); +//logerror("starting scanline %d (MAME %d, beam %d)\n", this_ppu->scanline, video_screen_get_vpos(device->machine->primary_screen), video_screen_get_hpos(device->machine->primary_screen)); /* Note: this is called at the _end_ of each scanline */ if (this_ppu->scanline == PPU_VBLANK_FIRST_SCANLINE) @@ -879,7 +898,7 @@ logerror("vlbank starting\n"); // a game can read the high bit of $2002 before the NMI is called (potentially resetting the bit // via a read from $2002 in the NMI handler). // B-Wings is an example game that needs this. - timer_adjust_oneshot(this_ppu->nmi_timer, cpu_clocks_to_attotime(machine->cpu[0], 4), num); + timer_adjust_oneshot(this_ppu->nmi_timer, cpu_clocks_to_attotime(device->machine->cpu[0], 4), 0); } } @@ -907,10 +926,10 @@ logerror("vlbank ending\n"); next_scanline = 0; // Call us back when the hblank starts for this scanline - timer_adjust_oneshot(this_ppu->hblank_timer, cpu_clocks_to_attotime(machine->cpu[0], 86.67), num); // ??? FIXME - hardcoding NTSC, need better calculation + timer_adjust_oneshot(this_ppu->hblank_timer, cpu_clocks_to_attotime(device->machine->cpu[0], 86.67), 0); // ??? FIXME - hardcoding NTSC, need better calculation // trigger again at the start of the next scanline - timer_adjust_oneshot(this_ppu->scanline_timer, video_screen_get_time_until_pos(machine->primary_screen, next_scanline * this_ppu->scan_scale, 0), num); + timer_adjust_oneshot(this_ppu->scanline_timer, video_screen_get_time_until_pos(device->machine->primary_screen, next_scanline * this_ppu->scan_scale, 0), 0); } /************************************* @@ -918,71 +937,68 @@ logerror("vlbank ending\n"); * PPU Reset * *************************************/ -void ppu2c0x_reset(running_machine *machine, int num, int scan_scale) + +static DEVICE_RESET( ppu2c0x ) { + ppu2c0x_chip *this_ppu = get_token(device); + const ppu2c0x_interface *intf = get_interface(device); + int scan_scale = 1; int i; - /* check bounds */ - if ( num >= intf->num ) - { - logerror( "PPU(reset): Attempting to access an unmapped chip\n" ); - return; - } - /* reset the scanline count */ - chips[num].scanline = 0; + this_ppu->scanline = 0; /* set the scan scale (this is for dual monitor vertical setups) */ - chips[num].scan_scale = scan_scale; + this_ppu->scan_scale = scan_scale; - timer_adjust_oneshot(chips[num].nmi_timer, attotime_never, num); + timer_adjust_oneshot(this_ppu->nmi_timer, attotime_never, 0); // Call us back when the hblank starts for this scanline - timer_adjust_oneshot(chips[num].hblank_timer, cpu_clocks_to_attotime(machine->cpu[0], 86.67), num); // ??? FIXME - hardcoding NTSC, need better calculation + timer_adjust_oneshot(this_ppu->hblank_timer, cpu_clocks_to_attotime(device->machine->cpu[0], 86.67), 0); // ??? FIXME - hardcoding NTSC, need better calculation // Call us back at the start of the next scanline - timer_adjust_oneshot(chips[num].scanline_timer, video_screen_get_time_until_pos(machine->primary_screen, 1, 0), num); + timer_adjust_oneshot(this_ppu->scanline_timer, video_screen_get_time_until_pos(device->machine->primary_screen, 1, 0), 0); /* reset the callbacks */ - chips[num].scanline_callback_proc = 0; - chips[num].vidaccess_callback_proc = 0; + this_ppu->scanline_callback_proc = 0; + this_ppu->vidaccess_callback_proc = 0; for( i = 0; i < PPU_MAX_REG; i++ ) - chips[num].regs[i] = 0; + this_ppu->regs[i] = 0; /* initialize the rest of the members */ - chips[num].refresh_data = 0; - chips[num].refresh_latch = 0; - chips[num].x_fine = 0; - chips[num].toggle = 0; - chips[num].add = 1; - chips[num].videomem_addr = 0; - chips[num].addr_latch = 0; - chips[num].data_latch = 0; - chips[num].tile_page = 0; - chips[num].sprite_page = 0; - chips[num].back_color = 0; + this_ppu->refresh_data = 0; + this_ppu->refresh_latch = 0; + this_ppu->x_fine = 0; + this_ppu->toggle = 0; + this_ppu->add = 1; + this_ppu->videomem_addr = 0; + this_ppu->addr_latch = 0; + this_ppu->data_latch = 0; + this_ppu->tile_page = 0; + this_ppu->sprite_page = 0; + this_ppu->back_color = 0; /* initialize the color tables */ { - int color_base = intf->color_base[num]; + int color_base = intf->color_base; for( i = 0; i < ARRAY_LENGTH( default_colortable_mono ); i++ ) { /* monochromatic table */ - chips[num].colortable_mono[i] = default_colortable_mono[i] + color_base; + this_ppu->colortable_mono[i] = default_colortable_mono[i] + color_base; /* color table */ - chips[num].colortable[i] = default_colortable[i] + color_base; + this_ppu->colortable[i] = default_colortable[i] + color_base; } } /* set the vram bank-switch values to the default */ for( i = 0; i < 8; i++ ) - chips[num].nes_vram[i] = i * 64; + this_ppu->nes_vram[i] = i * 64; - if ( chips[num].has_videorom ) - ppu2c0x_set_videorom_bank( num, 0, 8, 0, 512 ); + if ( this_ppu->has_videorom ) + ppu2c0x_set_videorom_bank( device, 0, 8, 0, 512 ); } @@ -991,22 +1007,14 @@ void ppu2c0x_reset(running_machine *machine, int num, int scan_scale) * PPU Registers Read * *************************************/ -int ppu2c0x_r( const address_space *space, offs_t offset, int num ) -{ - ppu2c0x_chip* this_ppu; - - /* check bounds */ - if ( num >= intf->num ) - { - logerror( "PPU %d(r): Attempting to access an unmapped chip\n", num ); - return 0; - } - this_ppu = &chips[num]; +READ8_DEVICE_HANDLER( ppu2c0x_r ) +{ + ppu2c0x_chip *this_ppu = get_token(device); if ( offset >= PPU_MAX_REG ) { - logerror( "PPU %d(r): Attempting to read past the chip\n", num ); + logerror( "PPU %s(r): Attempting to read past the chip\n", device->tag ); offset &= PPU_MAX_REG - 1; } @@ -1041,7 +1049,7 @@ int ppu2c0x_r( const address_space *space, offs_t offset, int num ) this_ppu->data_latch = this_ppu->buffered_data; if ( ppu_latch ) - (*ppu_latch)( this_ppu->videomem_addr & 0x3fff ); + (*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 ]; @@ -1064,20 +1072,14 @@ int ppu2c0x_r( const address_space *space, offs_t offset, int num ) * PPU Registers Write * *************************************/ -void ppu2c0x_w( const address_space *space, offs_t offset, UINT8 data, int num ) + +WRITE8_DEVICE_HANDLER( ppu2c0x_w ) { - ppu2c0x_chip* this_ppu; + ppu2c0x_chip *this_ppu = get_token(device); + const ppu2c0x_interface *intf = get_interface(device); int color_base; - /* check bounds */ - if ( num >= intf->num ) - { - logerror( "PPU(w): Attempting to access an unmapped chip\n" ); - return; - } - - this_ppu = &chips[num]; - color_base = intf->color_base[num]; + color_base = intf->color_base; if ( offset >= PPU_MAX_REG ) { @@ -1188,11 +1190,11 @@ void ppu2c0x_w( const address_space *space, offs_t offset, UINT8 data, int num ) int tempAddr = this_ppu->videomem_addr & 0x3fff; if ( ppu_latch ) - (*ppu_latch)( tempAddr ); + (*ppu_latch)( device, tempAddr ); /* if there's a callback, call it now */ if ( this_ppu->vidaccess_callback_proc ) - data = (*this_ppu->vidaccess_callback_proc)( space->machine, num, tempAddr, data ); + data = (*this_ppu->vidaccess_callback_proc)( device, tempAddr, data ); /* see if it's on the chargen portion */ if ( tempAddr < 0x2000 ) @@ -1210,7 +1212,7 @@ void ppu2c0x_w( const address_space *space, offs_t offset, UINT8 data, int num ) this_ppu->videomem[tempAddr] = data; /* mark the char dirty */ - gfx_element_mark_dirty(this_ppu->machine->gfx[intf->gfx_layout_number[num]], tempAddr >> 4); + gfx_element_mark_dirty(device->machine->gfx[intf->gfx_layout_number], tempAddr >> 4); } } @@ -1277,23 +1279,16 @@ void ppu2c0x_w( const address_space *space, offs_t offset, UINT8 data, int num ) * Sprite DMA * *************************************/ -void ppu2c0x_spriteram_dma (const address_space *space, int num, const UINT8 page) +void ppu2c0x_spriteram_dma (const address_space *space, const device_config *device, const UINT8 page) { int i; int address = page << 8; - /* check bounds */ - if ( num >= intf->num ) - { - logerror( "PPU(w): Attempting to access an unmapped chip\n" ); - return; - } - -//logerror(" sprite DMA: %d (scanline: %d)\n", page, chips[num].scanline); +//logerror(" sprite DMA: %d (scanline: %d)\n", page, this_ppu->scanline); for (i = 0; i < SPRITERAM_SIZE; i++) { UINT8 spriteData = memory_read_byte(space, address + i); - ppu2c0x_w (space, PPU_SPRITE_DATA, spriteData, num); + ppu2c0x_w (device, PPU_SPRITE_DATA, spriteData); } // should last 513 CPU cycles. @@ -1304,12 +1299,10 @@ void ppu2c0x_spriteram_dma (const address_space *space, int num, const UINT8 pag // the scanline timers should catch us up before drawing actually happens. #if 0 { - ppu2c0x_chip* this_ppu = &chips[num]; - - scanline_callback(this_ppu->machine, num); - scanline_callback(this_ppu->machine, num); - scanline_callback(this_ppu->machine, num); - scanline_callback(this_ppu->machine, num); + scanline_callback(device); + scanline_callback(device); + scanline_callback(device); + scanline_callback(device); } #endif } @@ -1319,16 +1312,11 @@ void ppu2c0x_spriteram_dma (const address_space *space, int num, const UINT8 pag * PPU Rendering * *************************************/ -void ppu2c0x_render( int num, bitmap_t *bitmap, int flipx, int flipy, int sx, int sy ) -{ - /* check bounds */ - if ( num >= intf->num ) - { - logerror( "PPU(render): Attempting to access an unmapped chip\n" ); - return; - } - copybitmap( bitmap, chips[num].bitmap, flipx, flipy, sx, sy, 0 ); +void ppu2c0x_render( const device_config *device, bitmap_t *bitmap, int flipx, int flipy, int sx, int sy ) +{ + ppu2c0x_chip *this_ppu = get_token(device); + copybitmap( bitmap, this_ppu->bitmap, flipx, flipy, sx, sy, 0 ); } /************************************* @@ -1336,44 +1324,39 @@ void ppu2c0x_render( int num, bitmap_t *bitmap, int flipx, int flipy, int sx, in * PPU VideoROM banking * *************************************/ -void ppu2c0x_set_videorom_bank( int num, int start_page, int num_pages, int bank, int bank_size ) +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; - /* check bounds */ - if ( num >= intf->num ) - { - logerror( "PPU(set vrom bank): Attempting to access an unmapped chip\n" ); - return; - } - - if ( !chips[num].has_videorom ) + if ( !this_ppu->has_videorom ) { logerror( "PPU(set vrom bank): Attempting to switch videorom banks and no rom is mapped\n" ); return; } - bank &= ( chips[num].videorom_banks * ( CHARGEN_NUM_CHARS / bank_size ) ) - 1; + bank &= ( this_ppu->videorom_banks * ( CHARGEN_NUM_CHARS / bank_size ) ) - 1; - if (chips[num].has_videoram) + if (this_ppu->has_videoram) { for ( i = start_page; i < start_page + num_pages; i++ ) { int elemnum; - if ( chips[num].videoram_banks_indices[i] != -1 ) + if ( this_ppu->videoram_banks_indices[i] != -1 ) { - memcpy( &chips[num].videoram[chips[num].videoram_banks_indices[i]*0x400], &chips[num].videomem[i*0x400], 0x400); + memcpy( &this_ppu->videoram[this_ppu->videoram_banks_indices[i]*0x400], &this_ppu->videomem[i*0x400], 0x400); } - chips[num].videoram_banks_indices[i] = -1; + this_ppu->videoram_banks_indices[i] = -1; for (elemnum = 0; elemnum < (num_pages*0x400 >> 4); elemnum++) - gfx_element_mark_dirty(chips[num].machine->gfx[intf->gfx_layout_number[num]], (start_page*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++ ) - chips[num].nes_vram[i] = bank * bank_size + 64 * ( i - start_page ); + this_ppu->nes_vram[i] = bank * bank_size + 64 * ( i - start_page ); } { @@ -1381,7 +1364,7 @@ void ppu2c0x_set_videorom_bank( int num, int start_page, int num_pages, int bank int count = num_pages * 0x400; int rom_start = bank * bank_size * 16; - memcpy( &chips[num].videomem[vram_start], &memory_region( chips[num].machine, intf->vrom_region[num] )[rom_start], count ); + memcpy( &this_ppu->videomem[vram_start], &memory_region( device->machine, intf->vrom_region )[rom_start], count ); } } @@ -1390,18 +1373,14 @@ void ppu2c0x_set_videorom_bank( int num, int start_page, int num_pages, int bank * PPU VideoRAM banking * *************************************/ -void ppu2c0x_set_videoram_bank( int num, int start_page, int num_pages, int bank, int bank_size ) + +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; - /* check bounds */ - if ( num >= intf->num ) - { - logerror( "PPU(set vrom bank): Attempting to access an unmapped chip\n" ); - return; - } - - if ( !chips[num].has_videoram ) + if ( !this_ppu->has_videoram ) { logerror( "PPU(set vram bank): Attempting to switch videoram banks and no ram is mapped\n" ); return; @@ -1412,13 +1391,13 @@ void ppu2c0x_set_videoram_bank( int num, int start_page, int num_pages, int bank for ( i = start_page; i < start_page + num_pages; i++ ) { int elemnum; - if ( chips[num].videoram_banks_indices[i] != -1 ) + if ( this_ppu->videoram_banks_indices[i] != -1 ) { - memcpy( &chips[num].videoram[chips[num].videoram_banks_indices[i]*0x400], &chips[num].videomem[i*0x400], 0x400); + memcpy( &this_ppu->videoram[this_ppu->videoram_banks_indices[i]*0x400], &this_ppu->videomem[i*0x400], 0x400); } - chips[num].videoram_banks_indices[i] = (bank * bank_size * 16)/0x400 + (i - start_page); + 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(chips[num].machine->gfx[intf->gfx_layout_number[num]], (start_page*0x400 >> 4) + elemnum); + gfx_element_mark_dirty(device->machine->gfx[intf->gfx_layout_number], (start_page*0x400 >> 4) + elemnum); } { @@ -1427,7 +1406,7 @@ void ppu2c0x_set_videoram_bank( int num, int start_page, int num_pages, int bank 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( &chips[num].videomem[vram_start], &chips[num].videoram[ram_start], count ); + memcpy( &this_ppu->videomem[vram_start], &this_ppu->videoram[ram_start], count ); } } @@ -1436,14 +1415,10 @@ void ppu2c0x_set_videoram_bank( int num, int start_page, int num_pages, int bank * Utility functions * *************************************/ -int ppu2c0x_get_pixel( int num, int x, int y ) + +int ppu2c0x_get_pixel( const device_config *device, int x, int y ) { - /* check bounds */ - if ( num >= intf->num ) - { - logerror( "PPU(get_pixel): Attempting to access an unmapped chip\n" ); - return 0; - } + ppu2c0x_chip *this_ppu = get_token(device); if ( x >= VISIBLE_SCREEN_WIDTH ) x = VISIBLE_SCREEN_WIDTH - 1; @@ -1451,45 +1426,24 @@ int ppu2c0x_get_pixel( int num, int x, int y ) if ( y >= VISIBLE_SCREEN_HEIGHT ) y = VISIBLE_SCREEN_HEIGHT - 1; - return *BITMAP_ADDR16(chips[num].bitmap, y, x); + return *BITMAP_ADDR16(this_ppu->bitmap, y, x); } -int ppu2c0x_get_colorbase( int num ) +int ppu2c0x_get_colorbase( const device_config *device ) { - /* check bounds */ - if ( num >= intf->num ) - { - logerror( "PPU(get_colorbase): Attempting to access an unmapped chip\n" ); - return 0; - } - - return intf->color_base[num]; + const ppu2c0x_interface *intf = get_interface(device); + return intf->color_base; } -int ppu2c0x_get_current_scanline( int num ) +int ppu2c0x_get_current_scanline( const device_config *device ) { - /* check bounds */ - if ( num >= intf->num ) - { - logerror( "PPU(get_colorbase): Attempting to access an unmapped chip\n" ); - return 0; - } - - return chips[num].scanline; + ppu2c0x_chip *this_ppu = get_token(device); + return this_ppu->scanline; } -void ppu2c0x_set_mirroring( int num, int mirroring ) +void ppu2c0x_set_mirroring( const device_config *device, int mirroring ) { - ppu2c0x_chip* this_ppu; - - /* check bounds */ - if ( num >= intf->num ) - { - logerror( "PPU %d: Attempting to access an unmapped chip\n", num ); - return; - } - - this_ppu = &chips[num]; + 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 @@ -1541,90 +1495,96 @@ void ppu2c0x_set_mirroring( int num, int mirroring ) this_ppu->mirror_state = mirroring; } -#ifdef UNUSED_FUNCTION -void ppu2c0x_set_nmi_callback( int num, ppu2c0x_nmi_cb cb ) +void ppu2c0x_set_scanline_callback( const device_config *device, ppu2c0x_scanline_cb cb ) { - /* check bounds */ - if ( num >= intf->num ) - { - logerror( "PPU(set_nmi_callback): Attempting to access an unmapped chip\n" ); - return; - } - - intf->nmi_handler[num] = cb; + ppu2c0x_chip *this_ppu = get_token(device); + this_ppu->scanline_callback_proc = cb; } -#endif -void ppu2c0x_set_scanline_callback( int num, ppu2c0x_scanline_cb cb ) +void ppu2c0x_set_hblank_callback( const device_config *device, ppu2c0x_hblank_cb cb ) { - /* check bounds */ - if ( num >= intf->num ) - { - logerror( "PPU(set_scanline_callback): Attempting to access an unmapped chip\n" ); - return; - } - - chips[num].scanline_callback_proc = cb; + ppu2c0x_chip *this_ppu = get_token(device); + this_ppu->hblank_callback_proc = cb; } -void ppu2c0x_set_hblank_callback( int num, ppu2c0x_hblank_cb cb ) +void ppu2c0x_set_vidaccess_callback( const device_config *device, ppu2c0x_vidaccess_cb cb ) { - /* check bounds */ - if ( num >= intf->num ) - { - logerror( "PPU(set_scanline_callback): Attempting to access an unmapped chip\n" ); - return; - } - - chips[num].hblank_callback_proc = cb; + ppu2c0x_chip *this_ppu = get_token(device); + this_ppu->vidaccess_callback_proc = cb; } -void ppu2c0x_set_vidaccess_callback( int num, ppu2c0x_vidaccess_cb cb ) +void ppu2c0x_set_scanlines_per_frame( const device_config *device, int scanlines ) { - /* check bounds */ - if ( num >= intf->num ) - { - logerror( "PPU(set_vidaccess_callback): Attempting to access an unmapped chip\n" ); - return; - } - - chips[num].vidaccess_callback_proc = cb; + ppu2c0x_chip *this_ppu = get_token(device); + this_ppu->scanlines_per_frame = scanlines; } -void ppu2c0x_set_scanlines_per_frame( int num, int scanlines ) + +/*************************************************************************** + GET INFO FUNCTIONS +***************************************************************************/ + +DEVICE_GET_INFO(ppu2c02) { - /* check bounds */ - if ( num >= intf->num ) + switch (state) { - logerror( "PPU(set_scanlines_per_frame): Attempting to access an unmapped chip\n" ); - return; + /* --- the following bits of info are returned as 64-bit signed integers --- */ + case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(ppu2c0x_chip); break; + 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; + + /* --- the following bits of info are returned as pointers to data or functions --- */ + case DEVINFO_FCT_SET_INFO: /* Nothing */ break; + case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(ppu2c0x); break; + case DEVINFO_FCT_STOP: /* Nothing */ break; + case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(ppu2c0x); break; + + /* --- the following bits of info are returned as NULL-terminated strings --- */ + case DEVINFO_STR_NAME: strcpy(info->s, "2C02 PPU"); break; + case DEVINFO_STR_FAMILY: strcpy(info->s, "2C0X PPU"); break; + case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break; + case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; + case DEVINFO_STR_CREDITS: /* Nothing */ break; } - - chips[num].scanlines_per_frame = scanlines; } -/************************************* - * - * Accesors - * - *************************************/ - -READ8_HANDLER( ppu2c0x_0_r ) +DEVICE_GET_INFO(ppu2c03b) { - return ppu2c0x_r( space, offset, 0 ); + switch (state) + { + case DEVINFO_STR_NAME: strcpy(info->s, "2C02B PPU"); break; + case PPU2C0XINFO_INT_SCANLINES_PER_FRAME: info->i = PPU_NTSC_SCANLINES_PER_FRAME; break; + default: DEVICE_GET_INFO_CALL(ppu2c02); break; + } } -READ8_HANDLER( ppu2c0x_1_r ) +DEVICE_GET_INFO(ppu2c04) { - return ppu2c0x_r( space, offset, 1 ); + switch (state) + { + case DEVINFO_STR_NAME: strcpy(info->s, "2C04 PPU"); break; + case PPU2C0XINFO_INT_SCANLINES_PER_FRAME: info->i = PPU_NTSC_SCANLINES_PER_FRAME; break; + default: DEVICE_GET_INFO_CALL(ppu2c02); break; + } } -WRITE8_HANDLER( ppu2c0x_0_w ) +DEVICE_GET_INFO(ppu2c05) { - ppu2c0x_w( space, offset, data, 0 ); + switch (state) + { + case DEVINFO_STR_NAME: strcpy(info->s, "2C05 PPU"); break; + case PPU2C0XINFO_INT_SCANLINES_PER_FRAME: info->i = PPU_NTSC_SCANLINES_PER_FRAME; break; + default: DEVICE_GET_INFO_CALL(ppu2c02); break; + } } -WRITE8_HANDLER( ppu2c0x_1_w ) +DEVICE_GET_INFO(ppu2c07) { - ppu2c0x_w( space, offset, data, 1 ); + switch (state) + { + case DEVINFO_STR_NAME: strcpy(info->s, "2C07 PPU"); break; + case PPU2C0XINFO_INT_SCANLINES_PER_FRAME: info->i = PPU_PAL_SCANLINES_PER_FRAME; break; + default: DEVICE_GET_INFO_CALL(ppu2c02); break; + } } diff --git a/src/mame/video/ppu2c0x.h b/src/mame/video/ppu2c0x.h index 92564401b8f..8c9571f6943 100644 --- a/src/mame/video/ppu2c0x.h +++ b/src/mame/video/ppu2c0x.h @@ -6,11 +6,14 @@ This code is heavily based on Brad Oliver's MESS implementation. ******************************************************************************/ + #ifndef __PPU_2C03B_H__ #define __PPU_2C03B_H__ -/* increment to use more chips */ -#define MAX_PPU 2 + +/*************************************************************************** + CONSTANTS +***************************************************************************/ /* mirroring types */ #define PPU_MIRROR_NONE 0 @@ -69,63 +72,85 @@ enum // are non-rendering and non-vblank. }; -typedef enum -{ - PPU_2C02, // NTSC NES - PPU_2C03B, // Playchoice 10 - PPU_2C04, // Vs. Unisystem - PPU_2C05, // Vs. Unisystem, Famicom Titler - PPU_2C07 // PAL NES -} ppu_t; +#define PPU_2C02 DEVICE_GET_INFO_NAME(ppu2c02) // NTSC NES +#define PPU_2C03B DEVICE_GET_INFO_NAME(ppu2c03b) // Playchoice 10 +#define PPU_2C04 DEVICE_GET_INFO_NAME(ppu2c04) // Vs. Unisystem +#define PPU_2C05 DEVICE_GET_INFO_NAME(ppu2c05) // Vs. Unisystem, Famicom Titler +#define PPU_2C07 DEVICE_GET_INFO_NAME(ppu2c07) // PAL NES /* callback datatypes */ -typedef void (*ppu2c0x_scanline_cb)( running_machine *machine, int num, int scanline, int vblank, int blanked ); -typedef void (*ppu2c0x_hblank_cb)( running_machine *machine, int num, int scanline, int vblank, int blanked ); -typedef void (*ppu2c0x_nmi_cb)( running_machine *machine, int num, int *ppu_regs ); -typedef int (*ppu2c0x_vidaccess_cb)( running_machine *machine, int num, int address, int data ); +typedef void (*ppu2c0x_scanline_cb)( const device_config *device, int scanline, int vblank, int blanked ); +typedef void (*ppu2c0x_hblank_cb)( const device_config *device, int scanline, int vblank, int blanked ); +typedef void (*ppu2c0x_nmi_cb)( const device_config *device, int *ppu_regs ); +typedef int (*ppu2c0x_vidaccess_cb)( const device_config *device, int address, int data ); typedef struct _ppu2c0x_interface ppu2c0x_interface; struct _ppu2c0x_interface { - ppu_t type; // model/version of the PPU - int num; /* number of chips ( 1 to MAX_PPU ) */ - const char * vrom_region[MAX_PPU]; /* region id of gfx vrom (or REGION_INVALID if none) */ - int gfx_layout_number[MAX_PPU]; /* gfx layout number used by each chip */ - int color_base[MAX_PPU]; /* color base to use per ppu */ - int mirroring[MAX_PPU]; /* mirroring options (PPU_MIRROR_* flag) */ - ppu2c0x_nmi_cb nmi_handler[MAX_PPU]; /* NMI handler */ - int vram_enabled[MAX_PPU]; /* PPU uses vram together with vrom */ + const char * vrom_region; /* region id of gfx vrom (or REGION_INVALID if none) */ + int gfx_layout_number; /* gfx layout number used by each chip */ + int color_base; /* color base to use per ppu */ + int mirroring; /* mirroring options (PPU_MIRROR_* flag) */ + ppu2c0x_nmi_cb nmi_handler; /* NMI handler */ + int vram_enabled; /* PPU uses vram together with vrom */ }; + +/*************************************************************************** + PROTOTYPES +***************************************************************************/ + +DEVICE_GET_INFO(ppu2c02); +DEVICE_GET_INFO(ppu2c03b); +DEVICE_GET_INFO(ppu2c04); +DEVICE_GET_INFO(ppu2c05); +DEVICE_GET_INFO(ppu2c07); + /* routines */ -void ppu2c0x_init_palette(running_machine *machine, int first_entry ); -void ppu2c0x_init(running_machine *machine, const ppu2c0x_interface *interface ); - -void ppu2c0x_reset( running_machine *machine, int num, int scan_scale ); -void ppu2c0x_set_videorom_bank( int num, int start_page, int num_pages, int bank, int bank_size ); -void ppu2c0x_set_videoram_bank( int num, int start_page, int num_pages, int bank, int bank_size ); -void ppu2c0x_spriteram_dma(const address_space *space, int num, const UINT8 page ); -void ppu2c0x_render( int num, bitmap_t *bitmap, int flipx, int flipy, int sx, int sy ); -int ppu2c0x_get_pixel( int num, int x, int y ); -int ppu2c0x_get_colorbase( int num ); -int ppu2c0x_get_current_scanline( int num ); -void ppu2c0x_set_mirroring( int num, int mirroring ); -void ppu2c0x_set_scanline_callback( int num, ppu2c0x_scanline_cb cb ); -void ppu2c0x_set_hblank_callback( int num, ppu2c0x_scanline_cb cb ); -void ppu2c0x_set_vidaccess_callback( int num, ppu2c0x_vidaccess_cb cb ); -void ppu2c0x_set_scanlines_per_frame( int num, int scanlines ); - -//27/12/2002 -extern void (*ppu_latch)( offs_t offset ); - -void ppu2c0x_w( const address_space *space, offs_t offset, UINT8 data, int num ); -int ppu2c0x_r( const address_space *space, offs_t offset, int num ); - -/* accesors */ -READ8_HANDLER( ppu2c0x_0_r ); -READ8_HANDLER( ppu2c0x_1_r ); - -WRITE8_HANDLER( ppu2c0x_0_w ); -WRITE8_HANDLER( ppu2c0x_1_w ); +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); +void ppu2c0x_set_scanlines_per_frame( const device_config *device, int scanlines ) ATTR_NONNULL(1); + +//27/12/2002 (HACK!) +extern void (*ppu_latch)( const device_config *device, offs_t offset ); + +WRITE8_DEVICE_HANDLER( ppu2c0x_w ); +READ8_DEVICE_HANDLER( ppu2c0x_r ); + + +/*************************************************************************** + DEVICE CONFIGURATION MACROS +***************************************************************************/ + +#define MDRV_PPU2C02_ADD(_tag, _intrf) \ + MDRV_DEVICE_ADD(_tag, PPU_2C02, 0) \ + MDRV_DEVICE_CONFIG(_intrf) + +#define MDRV_PPU2C03B_ADD(_tag, _intrf) \ + MDRV_DEVICE_ADD(_tag, PPU_2C03B, 0) \ + MDRV_DEVICE_CONFIG(_intrf) + +#define MDRV_PPU2C04_ADD(_tag, _intrf) \ + MDRV_DEVICE_ADD(_tag, PPU_2C04, 0) \ + MDRV_DEVICE_CONFIG(_intrf) + +#define MDRV_PPU2C05_ADD(_tag, _intrf) \ + MDRV_DEVICE_ADD(_tag, PPU_2C05, 0) \ + MDRV_DEVICE_CONFIG(_intrf) + +#define MDRV_PPU2C07_ADD(_tag, _intrf) \ + MDRV_DEVICE_ADD(_tag, PPU_2C07, 0) \ + MDRV_DEVICE_CONFIG(_intrf) #endif /* __PPU_2C0X_H__ */ diff --git a/src/mame/video/vsnes.c b/src/mame/video/vsnes.c index 84e047b62c3..477b4f210f6 100644 --- a/src/mame/video/vsnes.c +++ b/src/mame/video/vsnes.c @@ -14,43 +14,42 @@ PALETTE_INIT( vsdual ) ppu2c0x_init_palette(machine, 8*4*16 ); } -static void ppu_irq( running_machine *machine, int num, int *ppu_regs ) +static void ppu_irq_1( const device_config *device, int *ppu_regs ) { - cpu_set_input_line(machine->cpu[num], INPUT_LINE_NMI, PULSE_LINE ); + cpu_set_input_line(device->machine->cpu[0], INPUT_LINE_NMI, PULSE_LINE ); +} + +static void ppu_irq_2( const device_config *device, int *ppu_regs ) +{ + cpu_set_input_line(device->machine->cpu[1], INPUT_LINE_NMI, PULSE_LINE ); } /* our ppu interface */ -static const ppu2c0x_interface ppu_interface = +const ppu2c0x_interface vsnes_ppu_interface_1 = { - PPU_2C04, /* type */ - 1, /* num */ - { "gfx1" }, /* vrom gfx region */ - { 0 }, /* gfxlayout num */ - { 0 }, /* color base */ - { PPU_MIRROR_NONE }, /* mirroring */ - { ppu_irq } /* irq */ + "gfx1", /* vrom gfx region */ + 0, /* gfxlayout num */ + 0, /* color base */ + PPU_MIRROR_NONE, /* mirroring */ + ppu_irq_1 /* irq */ }; /* our ppu interface for dual games */ -static const ppu2c0x_interface ppu_dual_interface = +const ppu2c0x_interface vsnes_ppu_interface_2 = { - PPU_2C04, /* type */ - 2, /* num */ - { "gfx1", "gfx2" }, /* vrom gfx region */ - { 0, 1 }, /* gfxlayout num */ - { 0, 64 }, /* color base */ - { PPU_MIRROR_NONE, PPU_MIRROR_NONE }, /* mirroring */ - { ppu_irq, ppu_irq } /* irq */ + "gfx2", /* vrom gfx region */ + 1, /* gfxlayout num */ + 64, /* color base */ + PPU_MIRROR_NONE, /* mirroring */ + ppu_irq_2 /* irq */ }; VIDEO_START( vsnes ) { - ppu2c0x_init(machine, &ppu_interface ); } VIDEO_START( vsdual ) { - ppu2c0x_init(machine, &ppu_dual_interface ); } /*************************************************************************** @@ -61,7 +60,7 @@ VIDEO_START( vsdual ) VIDEO_UPDATE( vsnes ) { /* render the ppu */ - ppu2c0x_render( 0, bitmap, 0, 0, 0, 0 ); + ppu2c0x_render( devtag_get_device(screen->machine, "ppu1"), bitmap, 0, 0, 0, 0 ); return 0; } @@ -73,9 +72,9 @@ VIDEO_UPDATE( vsdual ) /* render the ppu's */ if (screen == top_screen) - ppu2c0x_render(0, bitmap, 0, 0, 0, 0); + ppu2c0x_render(devtag_get_device(screen->machine, "ppu1"), bitmap, 0, 0, 0, 0); else if (screen == bottom_screen) - ppu2c0x_render(1, bitmap, 0, 0, 0, 0); + ppu2c0x_render(devtag_get_device(screen->machine, "ppu2"), bitmap, 0, 0, 0, 0); return 0; } |