/****************************************************************************** Nintendo 2C0x PPU emulation. Written by Ernesto Corvi. This code is heavily based on Brad Oliver's MESS implementation. ******************************************************************************/ #ifndef __PPU_2C03B_H__ #define __PPU_2C03B_H__ #include "devlegcy.h" /*************************************************************************** CONSTANTS ***************************************************************************/ /* mirroring types */ #define PPU_MIRROR_NONE 0 #define PPU_MIRROR_VERT 1 #define PPU_MIRROR_HORZ 2 #define PPU_MIRROR_HIGH 3 #define PPU_MIRROR_LOW 4 #define PPU_MIRROR_4SCREEN 5 // Same effect as NONE, but signals that we should never mirror /* registers definition */ enum { PPU_CONTROL0 = 0, PPU_CONTROL1, PPU_STATUS, PPU_SPRITE_ADDRESS, PPU_SPRITE_DATA, PPU_SCROLL, PPU_ADDRESS, PPU_DATA, PPU_MAX_REG }; /* bit definitions for (some of) the registers */ enum { PPU_CONTROL0_INC = 0x04, PPU_CONTROL0_SPR_SELECT = 0x08, PPU_CONTROL0_CHR_SELECT = 0x10, PPU_CONTROL0_SPRITE_SIZE = 0x20, PPU_CONTROL0_NMI = 0x80, PPU_CONTROL1_DISPLAY_MONO = 0x01, PPU_CONTROL1_BACKGROUND_L8 = 0x02, PPU_CONTROL1_SPRITES_L8 = 0x04, PPU_CONTROL1_BACKGROUND = 0x08, PPU_CONTROL1_SPRITES = 0x10, PPU_CONTROL1_COLOR_EMPHASIS = 0xe0, PPU_STATUS_8SPRITES = 0x20, PPU_STATUS_SPRITE0_HIT = 0x40, PPU_STATUS_VBLANK = 0x80 }; enum { PPU_NTSC_SCANLINES_PER_FRAME = 262, PPU_PAL_SCANLINES_PER_FRAME = 312, PPU_BOTTOM_VISIBLE_SCANLINE = 239, PPU_VBLANK_FIRST_SCANLINE = 241, PPU_VBLANK_LAST_SCANLINE_NTSC = 260, PPU_VBLANK_LAST_SCANLINE_PAL = 310 // Both the sacnline immediately before and immediately after VBLANK // are non-rendering and non-vblank. }; /* callback datatypes */ typedef void (*ppu2c0x_scanline_cb)( device_t *device, int scanline, int vblank, int blanked ); typedef void (*ppu2c0x_hblank_cb)( device_t *device, int scanline, int vblank, int blanked ); typedef void (*ppu2c0x_nmi_cb)( device_t *device, int *ppu_regs ); typedef int (*ppu2c0x_vidaccess_cb)( device_t *device, int address, int data ); typedef struct _ppu2c0x_interface ppu2c0x_interface; struct _ppu2c0x_interface { 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 */ }; /*************************************************************************** PROTOTYPES ***************************************************************************/ DECLARE_LEGACY_MEMORY_DEVICE(PPU_2C02, ppu2c02); // NTSC NES DECLARE_LEGACY_MEMORY_DEVICE(PPU_2C03B, ppu2c03b); // Playchoice 10 DECLARE_LEGACY_MEMORY_DEVICE(PPU_2C04, ppu2c04); // Vs. Unisystem // The PPU_2C05 variants have different protection value, set at DEVICE_START, but otherwise are all the same... DECLARE_LEGACY_MEMORY_DEVICE(PPU_2C05_01, ppu2c05_01); // Vs. Unisystem (Ninja Jajamaru Kun) DECLARE_LEGACY_MEMORY_DEVICE(PPU_2C05_02, ppu2c05_02); // Vs. Unisystem (Mighty Bomb Jack) DECLARE_LEGACY_MEMORY_DEVICE(PPU_2C05_03, ppu2c05_03); // Vs. Unisystem (Gumshoe) DECLARE_LEGACY_MEMORY_DEVICE(PPU_2C05_04, ppu2c05_04); // Vs. Unisystem (Top Gun) DECLARE_LEGACY_MEMORY_DEVICE(PPU_2C07, ppu2c07); // PAL NES /* routines */ void ppu2c0x_init_palette(running_machine &machine, int first_entry ); void ppu2c0x_init_palette_rgb(running_machine &machine, int first_entry ); void ppu2c0x_spriteram_dma(address_space *space, device_t *device, const UINT8 page ) ATTR_NONNULL(1); void ppu2c0x_render( device_t *device, bitmap_t *bitmap, int flipx, int flipy, int sx, int sy ) ATTR_NONNULL(1); int ppu2c0x_get_pixel( device_t *device, int x, int y ) ATTR_NONNULL(1); int ppu2c0x_get_colorbase( device_t *device ) ATTR_NONNULL(1); int ppu2c0x_get_current_scanline( device_t *device ) ATTR_NONNULL(1); int ppu2c0x_is_sprite_8x16( device_t *device ) ATTR_NONNULL(1); void ppu2c0x_set_scanline_callback( device_t *device, ppu2c0x_scanline_cb cb ) ATTR_NONNULL(1); void ppu2c0x_set_hblank_callback( device_t *device, ppu2c0x_scanline_cb cb ) ATTR_NONNULL(1); void ppu2c0x_set_vidaccess_callback( device_t *device, ppu2c0x_vidaccess_cb cb ) ATTR_NONNULL(1); void ppu2c0x_set_scanlines_per_frame( device_t *device, int scanlines ) ATTR_NONNULL(1); //27/12/2002 (HACK!) void ppu2c0x_set_latch( device_t *device, void (*ppu_latch_t)( device_t *device, offs_t offset )); WRITE8_DEVICE_HANDLER( ppu2c0x_w ); READ8_DEVICE_HANDLER( ppu2c0x_r ); /*************************************************************************** DEVICE CONFIGURATION MACROS ***************************************************************************/ #define MCFG_PPU2C02_ADD(_tag, _intrf) \ MCFG_DEVICE_ADD(_tag, PPU_2C02, 0) \ MCFG_DEVICE_CONFIG(_intrf) #define MCFG_PPU2C03B_ADD(_tag, _intrf) \ MCFG_DEVICE_ADD(_tag, PPU_2C03B, 0) \ MCFG_DEVICE_CONFIG(_intrf) #define MCFG_PPU2C04_ADD(_tag, _intrf) \ MCFG_DEVICE_ADD(_tag, PPU_2C04, 0) \ MCFG_DEVICE_CONFIG(_intrf) #define MCFG_PPU2C05_01_ADD(_tag, _intrf) \ MCFG_DEVICE_ADD(_tag, PPU_2C05_01, 0) \ MCFG_DEVICE_CONFIG(_intrf) #define MCFG_PPU2C05_02_ADD(_tag, _intrf) \ MCFG_DEVICE_ADD(_tag, PPU_2C05_02, 0) \ MCFG_DEVICE_CONFIG(_intrf) #define MCFG_PPU2C05_03_ADD(_tag, _intrf) \ MCFG_DEVICE_ADD(_tag, PPU_2C05_03, 0) \ MCFG_DEVICE_CONFIG(_intrf) #define MCFG_PPU2C05_04_ADD(_tag, _intrf) \ MCFG_DEVICE_ADD(_tag, PPU_2C05_04, 0) \ MCFG_DEVICE_CONFIG(_intrf) #define MCFG_PPU2C07_ADD(_tag, _intrf) \ MCFG_DEVICE_ADD(_tag, PPU_2C07, 0) \ MCFG_DEVICE_CONFIG(_intrf) #endif /* __PPU_2C0X_H__ */