(MESS) gameboy: converted the various LCD types (DMG, MGB, CGB...) to be devices. [Fabio Priuli]

This commit is contained in:
Fabio Priuli 2013-06-23 14:44:29 +00:00
parent 299b67a1ce
commit 38c0ecb8c4
4 changed files with 2507 additions and 2342 deletions

View File

@ -556,16 +556,16 @@ WRITE8_MEMBER(megaduck_state::bank2_w)
static ADDRESS_MAP_START(gameboy_map, AS_PROGRAM, 8, gb_state )
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x0000, 0x7fff) AM_READWRITE(gb_cart_r, gb_bank_w)
AM_RANGE(0x8000, 0x9fff) AM_READWRITE(gb_vram_r, gb_vram_w) /* 8k VRAM */
AM_RANGE(0x8000, 0x9fff) AM_DEVREADWRITE("lcd", gb_lcd_device, vram_r, vram_w) /* 8k VRAM */
AM_RANGE(0xa000, 0xbfff) AM_READWRITE(gb_ram_r, gb_ram_w) /* 8k switched RAM bank (cartridge) */
AM_RANGE(0xc000, 0xdfff) AM_RAM /* 8k low RAM */
AM_RANGE(0xe000, 0xfdff) AM_READWRITE(gb_echo_r, gb_echo_w) /* echo RAM */
AM_RANGE(0xfe00, 0xfeff) AM_READWRITE(gb_oam_r, gb_oam_w) /* OAM RAM */
AM_RANGE(0xfe00, 0xfeff) AM_DEVREADWRITE("lcd", gb_lcd_device, oam_r, oam_w) /* OAM RAM */
AM_RANGE(0xff00, 0xff0f) AM_READWRITE(gb_io_r, gb_io_w) /* I/O */
AM_RANGE(0xff10, 0xff26) AM_DEVREADWRITE("custom", gameboy_sound_device, sound_r, sound_w) /* sound registers */
AM_RANGE(0xff27, 0xff2f) AM_NOP /* unused */
AM_RANGE(0xff30, 0xff3f) AM_DEVREADWRITE("custom", gameboy_sound_device, wave_r, wave_w) /* Wave ram */
AM_RANGE(0xff40, 0xff7f) AM_READWRITE(gb_video_r, gb_io2_w) /* Video controller & BIOS flip-flop */
AM_RANGE(0xff40, 0xff7f) AM_DEVREAD("lcd", gb_lcd_device, video_r) AM_WRITE(gb_io2_w) /* Video controller & BIOS flip-flop */
AM_RANGE(0xff80, 0xfffe) AM_RAM /* High RAM */
AM_RANGE(0xffff, 0xffff) AM_READWRITE(gb_ie_r, gb_ie_w) /* Interrupt enable register */
ADDRESS_MAP_END
@ -573,16 +573,16 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START(sgb_map, AS_PROGRAM, 8, gb_state )
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x0000, 0x7fff) AM_READWRITE(gb_cart_r, gb_bank_w)
AM_RANGE(0x8000, 0x9fff) AM_READWRITE(gb_vram_r, gb_vram_w) /* 8k VRAM */
AM_RANGE(0x8000, 0x9fff) AM_DEVREADWRITE("lcd", sgb_lcd_device, vram_r, vram_w) /* 8k VRAM */
AM_RANGE(0xa000, 0xbfff) AM_READWRITE(gb_ram_r, gb_ram_w) /* 8k switched RAM bank (cartridge) */
AM_RANGE(0xc000, 0xdfff) AM_RAM /* 8k low RAM */
AM_RANGE(0xe000, 0xfdff) AM_READWRITE(gb_echo_r, gb_echo_w) /* echo RAM */
AM_RANGE(0xfe00, 0xfeff) AM_READWRITE(gb_oam_r, gb_oam_w) /* OAM RAM */
AM_RANGE(0xfe00, 0xfeff) AM_DEVREADWRITE("lcd", sgb_lcd_device, oam_r, oam_w) /* OAM RAM */
AM_RANGE(0xff00, 0xff0f) AM_READWRITE(gb_io_r, sgb_io_w) /* I/O */
AM_RANGE(0xff10, 0xff26) AM_DEVREADWRITE("custom", gameboy_sound_device, sound_r, sound_w) /* sound registers */
AM_RANGE(0xff27, 0xff2f) AM_NOP /* unused */
AM_RANGE(0xff30, 0xff3f) AM_DEVREADWRITE("custom", gameboy_sound_device, wave_r, wave_w) /* Wave RAM */
AM_RANGE(0xff40, 0xff7f) AM_READWRITE(gb_video_r, gb_io2_w) /* Video controller & BIOS flip-flop */
AM_RANGE(0xff40, 0xff7f) AM_DEVREAD("lcd", sgb_lcd_device, video_r) AM_WRITE(gb_io2_w) /* Video controller & BIOS flip-flop */
AM_RANGE(0xff80, 0xfffe) AM_RAM /* High RAM */
AM_RANGE(0xffff, 0xffff) AM_READWRITE(gb_ie_r, gb_ie_w) /* Interrupt enable register */
ADDRESS_MAP_END
@ -590,17 +590,17 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START(gbc_map, AS_PROGRAM, 8, gb_state )
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x0000, 0x7fff) AM_READWRITE(gbc_cart_r, gb_bank_w)
AM_RANGE(0x8000, 0x9fff) AM_READWRITE(gb_vram_r, gb_vram_w) /* 8k VRAM */
AM_RANGE(0x8000, 0x9fff) AM_DEVREADWRITE("lcd", cgb_lcd_device, vram_r, vram_w) /* 8k VRAM */
AM_RANGE(0xa000, 0xbfff) AM_READWRITE(gb_ram_r, gb_ram_w) /* 8k switched RAM bank (cartridge) */
AM_RANGE(0xc000, 0xcfff) AM_RAM /* 4k fixed RAM bank */
AM_RANGE(0xd000, 0xdfff) AM_RAMBANK("cgb_ram") /* 4k switched RAM bank */
AM_RANGE(0xe000, 0xfdff) AM_READWRITE(gb_echo_r, gb_echo_w) /* echo RAM */
AM_RANGE(0xfe00, 0xfeff) AM_READWRITE(gb_oam_r, gb_oam_w) /* OAM RAM */
AM_RANGE(0xfe00, 0xfeff) AM_DEVREADWRITE("lcd", cgb_lcd_device, oam_r, oam_w) /* OAM RAM */
AM_RANGE(0xff00, 0xff0f) AM_READWRITE(gb_io_r, gb_io_w) /* I/O */
AM_RANGE(0xff10, 0xff26) AM_DEVREADWRITE("custom", gameboy_sound_device, sound_r, sound_w) /* sound controller */
AM_RANGE(0xff27, 0xff2f) AM_NOP /* unused */
AM_RANGE(0xff30, 0xff3f) AM_DEVREADWRITE("custom", gameboy_sound_device, wave_r, wave_w) /* Wave RAM */
AM_RANGE(0xff40, 0xff7f) AM_READWRITE(gbc_io2_r, gbc_io2_w) /* Other I/O and video controller */
AM_RANGE(0xff40, 0xff7f) AM_DEVREAD("lcd", cgb_lcd_device, video_r) AM_WRITE(gbc_io2_w) /* Other I/O and video controller */
AM_RANGE(0xff80, 0xfffe) AM_RAM /* high RAM */
AM_RANGE(0xffff, 0xffff) AM_READWRITE(gb_ie_r, gb_ie_w) /* Interrupt enable register */
ADDRESS_MAP_END
@ -608,12 +608,12 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START(megaduck_map, AS_PROGRAM, 8, megaduck_state )
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x0000, 0x7fff) AM_READWRITE(cart_r, bank1_w)
AM_RANGE(0x8000, 0x9fff) AM_READWRITE(gb_vram_r, gb_vram_w) /* 8k VRAM */
AM_RANGE(0x8000, 0x9fff) AM_DEVREADWRITE("lcd", gb_lcd_device, vram_r, vram_w) /* 8k VRAM */
AM_RANGE(0xa000, 0xafff) AM_NOP /* unused? */
AM_RANGE(0xb000, 0xb000) AM_WRITE(bank2_w)
AM_RANGE(0xb001, 0xbfff) AM_NOP /* unused? */
AM_RANGE(0xc000, 0xfe9f) AM_RAM /* 8k low RAM, echo RAM */
AM_RANGE(0xfe00, 0xfeff) AM_READWRITE(gb_oam_r, gb_oam_w) /* OAM RAM */
AM_RANGE(0xfe00, 0xfeff) AM_DEVREADWRITE("lcd", gb_lcd_device, oam_r, oam_w) /* OAM RAM */
AM_RANGE(0xff00, 0xff0f) AM_READWRITE(gb_io_r, gb_io_w) /* I/O */
AM_RANGE(0xff10, 0xff1f) AM_READWRITE(megaduck_video_r, megaduck_video_w) /* video controller */
AM_RANGE(0xff20, 0xff2f) AM_READWRITE(megaduck_sound_r1, megaduck_sound_w1) /* sound controller pt1 */
@ -687,7 +687,7 @@ static MACHINE_CONFIG_START( gameboy, gb_state )
MCFG_SCREEN_ADD("screen", LCD)
MCFG_SCREEN_REFRESH_RATE(DMG_FRAMES_PER_SECOND)
MCFG_SCREEN_VBLANK_TIME(0)
MCFG_SCREEN_UPDATE_DRIVER(gb_state, screen_update)
MCFG_SCREEN_UPDATE_DEVICE("lcd", gb_lcd_device, screen_update)
MCFG_DEFAULT_LAYOUT(layout_lcd)
// MCFG_SCREEN_SIZE(20*8, 18*8)
MCFG_SCREEN_SIZE( 458, 154 )
@ -697,6 +697,8 @@ static MACHINE_CONFIG_START( gameboy, gb_state )
MCFG_PALETTE_LENGTH(4)
MCFG_PALETTE_INIT_OVERRIDE(gb_state,gb)
MCFG_GB_LCD_DMG_ADD( "lcd" )
/* sound hardware */
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MCFG_SOUND_ADD("custom", GAMEBOY, 0)
@ -728,6 +730,9 @@ static MACHINE_CONFIG_DERIVED( supergb, gameboy )
MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 28*8-1)
MCFG_PALETTE_LENGTH(32768)
MCFG_PALETTE_INIT_OVERRIDE(gb_state,sgb)
MCFG_DEVICE_REMOVE("lcd")
MCFG_GB_LCD_SGB_ADD( "lcd" )
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( gbpocket, gameboy )
@ -739,6 +744,9 @@ static MACHINE_CONFIG_DERIVED( gbpocket, gameboy )
MCFG_MACHINE_START_OVERRIDE(gb_state, gbpocket)
MCFG_MACHINE_RESET_OVERRIDE(gb_state, gbpocket)
MCFG_PALETTE_INIT_OVERRIDE(gb_state,gbp)
MCFG_DEVICE_REMOVE("lcd")
MCFG_GB_LCD_MGB_ADD( "lcd" )
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( gbcolor, gameboy )
@ -752,6 +760,9 @@ static MACHINE_CONFIG_DERIVED( gbcolor, gameboy )
MCFG_PALETTE_LENGTH(32768)
MCFG_PALETTE_INIT_OVERRIDE(gb_state,gbc)
MCFG_DEVICE_REMOVE("lcd")
MCFG_GB_LCD_CGB_ADD( "lcd" )
/* internal ram */
MCFG_RAM_ADD(RAM_TAG)
MCFG_RAM_DEFAULT_SIZE("48K") /* 2 pages of 8KB VRAM, 8 pages of 4KB RAM */
@ -779,7 +790,7 @@ static MACHINE_CONFIG_START( megaduck, megaduck_state )
MCFG_MACHINE_START_OVERRIDE(megaduck_state, megaduck )
MCFG_MACHINE_RESET_OVERRIDE(megaduck_state, megaduck )
MCFG_SCREEN_UPDATE_DRIVER(gb_state, screen_update)
MCFG_SCREEN_UPDATE_DEVICE("lcd", gb_lcd_device, screen_update)
MCFG_SCREEN_SIZE(20*8, 18*8)
MCFG_SCREEN_VISIBLE_AREA(0*8, 20*8-1, 0*8, 18*8-1)
@ -788,6 +799,8 @@ static MACHINE_CONFIG_START( megaduck, megaduck_state )
MCFG_PALETTE_LENGTH(4)
MCFG_PALETTE_INIT_OVERRIDE(megaduck_state,megaduck)
MCFG_GB_LCD_DMG_ADD( "lcd" )
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MCFG_SOUND_ADD("custom", GAMEBOY, 0)
MCFG_SOUND_ROUTE(0, "lspeaker", 0.50)

View File

@ -40,70 +40,6 @@
#define _NR_GB_VID_REGS 0x40
struct layer_struct {
UINT8 enabled;
UINT8 *bg_tiles;
UINT8 *bg_map;
UINT8 xindex;
UINT8 xshift;
UINT8 xstart;
UINT8 xend;
/* GBC specific */
UINT8 *gbc_map;
INT16 bgline;
};
struct gb_lcd_t {
int window_lines_drawn;
UINT8 gb_vid_regs[_NR_GB_VID_REGS];
UINT8 bg_zbuf[160];
UINT16 cgb_bpal[32]; /* CGB current background palette table */
UINT16 cgb_spal[32]; /* CGB current sprite palette table */
UINT8 gb_bpal[4]; /* Background palette */
UINT8 gb_spal0[4]; /* Sprite 0 palette */
UINT8 gb_spal1[4]; /* Sprite 1 palette */
/* Things used to render current line */
int current_line; /* Current line */
int cmp_line; /* Compare line */
int sprCount; /* Number of sprites on current line */
int sprite[10]; /* References to sprites to draw on current line */
int previous_line; /* Previous line we've drawn in */
int start_x; /* Pixel to start drawing from (inclusive) */
int end_x; /* Pixel to end drawing (exclusive) */
int mode; /* Keep track of internal STAT mode */
int state; /* Current state of the video state machine */
int lcd_irq_line;
int triggering_line_irq;
int line_irq;
int triggering_mode_irq;
int mode_irq;
int delayed_line_irq;
int sprite_cycles;
int scrollx_adjust;
int oam_locked;
int vram_locked;
int pal_locked;
int hdma_enabled;
int hdma_possible;
struct layer_struct layer[2];
emu_timer *lcd_timer;
int gbc_mode;
UINT8 *gb_vram; // Pointer to VRAM
UINT8 *gb_oam; // Pointer to OAM memory
UINT8 gb_tile_no_mod;
UINT32 gb_chrgen_offs; // GB Character generator
UINT32 gb_bgdtab_offs; // GB Background character table
UINT32 gb_wndtab_offs; // GB Window character table
UINT32 gbc_chrgen_offs; // CGB Character generator
UINT32 gbc_bgdtab_offs; // CGB Background character table
UINT32 gbc_wndtab_offs; // CGB Window character table
int gb_vram_bank;
};
@ -120,14 +56,6 @@ public:
m_inputs(*this, "INPUTS"),
m_ram(*this, RAM_TAG) { }
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
UINT16 m_sgb_pal_data[4096];
UINT8 m_sgb_pal_map[20][18];
UINT16 m_sgb_pal[128];
UINT8 *m_sgb_tile_data;
UINT8 m_sgb_tile_map[2048];
UINT8 m_sgb_window_mask;
//gb_state driver_data;
UINT8 m_gb_io[0x10];
@ -143,7 +71,6 @@ public:
emu_timer *m_gb_serial_timer;
/* SGB variables */
UINT8 m_sgb_atf_data[4050]; /* (SGB) Attributes files */
INT8 m_sgb_packets;
UINT8 m_sgb_bitcount;
UINT8 m_sgb_bytecount;
@ -152,18 +79,13 @@ public:
UINT8 m_sgb_controller_no;
UINT8 m_sgb_controller_mode;
UINT8 m_sgb_data[0x100];
UINT32 m_sgb_atf;
/* CGB variables */
UINT8 *m_gbc_rammap[8]; /* (CGB) Addresses of internal RAM banks */
UINT8 m_gbc_rambank; /* (CGB) Current CGB RAM bank */
gb_lcd_t m_lcd;
void (gb_state::*update_scanline) ();
int m_bios_disable;
bitmap_ind16 m_bitmap;
DECLARE_WRITE8_MEMBER(gb_io_w);
DECLARE_WRITE8_MEMBER(gb_io2_w);
DECLARE_WRITE8_MEMBER(sgb_io_w);
@ -172,14 +94,6 @@ public:
DECLARE_READ8_MEMBER(gb_io_r);
DECLARE_WRITE8_MEMBER(gbc_io2_w);
DECLARE_READ8_MEMBER(gbc_io2_r);
DECLARE_READ8_MEMBER(gb_video_r);
DECLARE_READ8_MEMBER(gb_vram_r);
DECLARE_WRITE8_MEMBER(gb_vram_w);
DECLARE_READ8_MEMBER(gb_oam_r);
DECLARE_WRITE8_MEMBER(gb_oam_w);
DECLARE_WRITE8_MEMBER(gb_video_w);
DECLARE_READ8_MEMBER(gbc_video_r);
DECLARE_WRITE8_MEMBER(gbc_video_w);
DECLARE_MACHINE_START(gb);
DECLARE_MACHINE_RESET(gb);
DECLARE_PALETTE_INIT(gb);
@ -194,9 +108,6 @@ public:
DECLARE_PALETTE_INIT(gbc);
INTERRUPT_GEN_MEMBER(gb_scanline_interrupt);
TIMER_CALLBACK_MEMBER(gb_serial_timer_proc);
TIMER_CALLBACK_MEMBER(gb_video_init_vbl);
TIMER_CALLBACK_MEMBER(gb_lcd_timer_proc);
TIMER_CALLBACK_MEMBER(gbc_lcd_timer_proc);
DECLARE_WRITE8_MEMBER(gb_timer_callback);
DECLARE_READ8_MEMBER(gb_cart_r);
@ -220,27 +131,12 @@ protected:
void gb_timer_check_irq();
void gb_init();
void gb_init_regs();
void gb_select_sprites();
void gb_update_sprites();
void gb_update_scanline();
void sgb_update_sprites();
void sgb_refresh_border();
void sgb_update_scanline();
void cgb_update_sprites();
void cgb_update_scanline();
void gb_video_reset(int mode);
void gb_video_start(int mode);
void gbc_hdma(UINT16 length);
void gb_increment_scanline();
void gb_lcd_switch_on();
inline void gb_plot_pixel(bitmap_ind16 &bitmap, int x, int y, UINT32 color);
void save_gb_base();
void save_gb_video();
void save_gbc_only();
void save_sgb_only();
void gb_videoptr_restore();
void gbc_videoptr_restore();
};
@ -288,4 +184,202 @@ enum
};
struct layer_struct {
UINT8 enabled;
UINT8 *bg_tiles;
UINT8 *bg_map;
UINT8 xindex;
UINT8 xshift;
UINT8 xstart;
UINT8 xend;
/* GBC specific */
UINT8 *gbc_map;
INT16 bgline;
};
class gb_lcd_device : public device_t
{
public:
gb_lcd_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
gb_lcd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
DECLARE_READ8_MEMBER(vram_r);
DECLARE_WRITE8_MEMBER(vram_w);
DECLARE_READ8_MEMBER(oam_r);
DECLARE_WRITE8_MEMBER(oam_w);
virtual DECLARE_READ8_MEMBER(video_r);
virtual DECLARE_WRITE8_MEMBER(video_w);
// FIXME: remove it when proper sgb support is added
void set_sgb_hack(bool val) { m_sgb_border_hack = val ? 1 : 0; }
protected:
inline void plot_pixel(bitmap_ind16 &bitmap, int x, int y, UINT32 color);
void select_sprites();
virtual void update_sprites();
virtual void update_scanline();
// device-level overrides
virtual void device_start();
virtual void device_reset();
void common_start();
void common_reset();
// pointer to the main system
cpu_device *m_maincpu;
screen_device *m_screen;
// state variables
bitmap_ind16 m_bitmap;
UINT8 m_sgb_atf_data[4050]; /* (SGB) Attributes files */
UINT32 m_sgb_atf;
UINT16 m_sgb_pal_data[4096];
UINT8 m_sgb_pal_map[20][18];
UINT16 m_sgb_pal[128];
UINT8 *m_sgb_tile_data;
UINT8 m_sgb_tile_map[2048];
UINT8 m_sgb_window_mask;
// this is temporarily needed for a bunch of games which draw the border differently...
int m_sgb_border_hack;
int m_window_lines_drawn;
UINT8 m_vid_regs[_NR_GB_VID_REGS];
UINT8 m_bg_zbuf[160];
UINT16 m_cgb_bpal[32]; /* CGB current background palette table */
UINT16 m_cgb_spal[32]; /* CGB current sprite palette table */
UINT8 m_gb_bpal[4]; /* Background palette */
UINT8 m_gb_spal0[4]; /* Sprite 0 palette */
UINT8 m_gb_spal1[4]; /* Sprite 1 palette */
/* Things used to render current line */
int m_current_line; /* Current line */
int m_cmp_line; /* Compare line */
int m_sprCount; /* Number of sprites on current line */
int m_sprite[10]; /* References to sprites to draw on current line */
int m_previous_line; /* Previous line we've drawn in */
int m_start_x; /* Pixel to start drawing from (inclusive) */
int m_end_x; /* Pixel to end drawing (exclusive) */
int m_mode; /* Keep track of internal STAT mode */
int m_state; /* Current state of the video state machine */
int m_lcd_irq_line;
int m_triggering_line_irq;
int m_line_irq;
int m_triggering_mode_irq;
int m_mode_irq;
int m_delayed_line_irq;
int m_sprite_cycles;
int m_scrollx_adjust;
int m_oam_locked;
int m_vram_locked;
int m_pal_locked;
int m_hdma_enabled;
int m_hdma_possible;
struct layer_struct m_layer[2];
emu_timer *m_lcd_timer;
int m_gbc_mode;
UINT8 *m_vram; // Pointer to VRAM
UINT8 *m_oam; // Pointer to OAM memory
UINT8 m_gb_tile_no_mod;
UINT32 m_gb_chrgen_offs; // GB Character generator
UINT32 m_gb_bgdtab_offs; // GB Background character table
UINT32 m_gb_wndtab_offs; // GB Window character table
UINT32 m_gbc_chrgen_offs; // CGB Character generator
UINT32 m_gbc_bgdtab_offs; // CGB Background character table
UINT32 m_gbc_wndtab_offs; // CGB Window character table
int m_vram_bank;
TIMER_CALLBACK_MEMBER(video_init_vbl);
virtual TIMER_CALLBACK_MEMBER(lcd_timer_proc);
virtual void videoptr_restore();
void save_gb_video();
void increment_scanline();
void lcd_switch_on();
};
class mgb_lcd_device : public gb_lcd_device
{
public:
mgb_lcd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
};
class sgb_lcd_device : public gb_lcd_device
{
public:
sgb_lcd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
void sgb_io_write_pal(int offs, UINT8 *data);
protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
virtual void update_sprites();
virtual void update_scanline();
void refresh_border();
};
class cgb_lcd_device : public gb_lcd_device
{
public:
cgb_lcd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
virtual DECLARE_READ8_MEMBER(video_r);
virtual DECLARE_WRITE8_MEMBER(video_w);
protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
virtual void update_sprites();
virtual void update_scanline();
virtual TIMER_CALLBACK_MEMBER(lcd_timer_proc);
virtual void videoptr_restore();
void hdma_trans(UINT16 length);
};
extern const device_type GB_LCD_DMG;
extern const device_type GB_LCD_MGB;
extern const device_type GB_LCD_SGB;
extern const device_type GB_LCD_CGB;
#define MCFG_GB_LCD_DMG_ADD(_tag ) \
MCFG_DEVICE_ADD( _tag, GB_LCD_DMG, 0 )
#define MCFG_GB_LCD_MGB_ADD(_tag ) \
MCFG_DEVICE_ADD( _tag, GB_LCD_MGB, 0 )
#define MCFG_GB_LCD_SGB_ADD(_tag ) \
MCFG_DEVICE_ADD( _tag, GB_LCD_SGB, 0 )
#define MCFG_GB_LCD_CGB_ADD(_tag ) \
MCFG_DEVICE_ADD( _tag, GB_LCD_CGB, 0 )
#endif /* GB_H_ */

View File

@ -135,11 +135,6 @@ void gb_state::save_gbc_only()
void gb_state::save_sgb_only()
{
save_item(NAME(m_sgb_pal));
save_item(NAME(m_sgb_tile_map));
save_item(NAME(m_sgb_window_mask));
save_item(NAME(m_sgb_pal_data));
save_item(NAME(m_sgb_atf_data));
save_item(NAME(m_sgb_packets));
save_item(NAME(m_sgb_bitcount));
save_item(NAME(m_sgb_bytecount));
@ -148,10 +143,6 @@ void gb_state::save_sgb_only()
save_item(NAME(m_sgb_controller_no));
save_item(NAME(m_sgb_controller_mode));
save_item(NAME(m_sgb_data));
save_item(NAME(m_sgb_atf));
save_pointer(NAME(m_sgb_tile_data), 0x2000);
save_item(NAME(m_sgb_pal_map));
}
@ -184,7 +175,6 @@ MACHINE_START_MEMBER(gb_state,gb)
m_gb_serial_timer->enable( 0 );
save_gb_base();
gb_video_start(GB_VIDEO_DMG);
}
MACHINE_START_MEMBER(gb_state,gbpocket)
@ -194,7 +184,6 @@ MACHINE_START_MEMBER(gb_state,gbpocket)
m_gb_serial_timer->enable( 0 );
save_gb_base();
gb_video_start(GB_VIDEO_MGB);
}
MACHINE_START_MEMBER(gb_state,gbc)
@ -208,14 +197,12 @@ MACHINE_START_MEMBER(gb_state,gbc)
save_gb_base();
save_gbc_only();
gb_video_start(GB_VIDEO_CGB);
}
MACHINE_START_MEMBER(gb_state,sgb)
{
m_sgb_packets = -1;
m_sgb_tile_data = auto_alloc_array_clear(machine(), UINT8, 0x2000);
/* Allocate the serial timer, and disable it */
m_gb_serial_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gb_state::gb_serial_timer_proc),this));
@ -223,15 +210,15 @@ MACHINE_START_MEMBER(gb_state,sgb)
save_gb_base();
save_sgb_only();
gb_video_start(GB_VIDEO_SGB);
if (m_cartslot && m_cartslot->get_sgb_hack())
machine().device<sgb_lcd_device>("lcd")->set_sgb_hack(TRUE);
}
MACHINE_RESET_MEMBER(gb_state,gb)
{
gb_init();
gb_video_reset(GB_VIDEO_DMG);
/* Enable BIOS rom */
m_bios_disable = 0;
@ -242,8 +229,6 @@ MACHINE_RESET_MEMBER(gb_state,gbpocket)
{
gb_init();
gb_video_reset(GB_VIDEO_MGB);
gb_init_regs();
m_bios_disable = 1;
@ -260,8 +245,6 @@ MACHINE_RESET_MEMBER(gb_state,gbc)
{
gb_init();
gb_video_reset( GB_VIDEO_CGB );
gb_init_regs();
/* Enable BIOS rom */
@ -275,20 +258,11 @@ MACHINE_RESET_MEMBER(gb_state,sgb)
{
gb_init();
gb_video_reset(GB_VIDEO_SGB);
gb_init_regs();
/* Enable BIOS rom */
m_bios_disable = 0;
memset(m_sgb_tile_data, 0, 0x2000);
m_sgb_window_mask = 0;
memset(m_sgb_pal_map, 0, sizeof(m_sgb_pal_map));
memset(m_sgb_atf_data, 0, sizeof(m_sgb_atf_data));
m_divcount = 0x0004;
}
@ -376,7 +350,7 @@ WRITE8_MEMBER(gb_state::gb_io2_w)
//printf("here again?\n");
}
else
gb_video_w(space, offset, data);
machine().device<gb_lcd_device>("lcd")->video_w(space, offset, data);
}
#ifdef MAME_DEBUG
@ -473,398 +447,20 @@ WRITE8_MEMBER(gb_state::sgb_io_w)
m_sgb_packets = sgb_data[0] & 0x07;
m_sgb_start = 0;
}
if (m_sgb_bytecount == (m_sgb_packets << 4) )
if (m_sgb_bytecount == (m_sgb_packets << 4))
{
switch( sgb_data[0] >> 3 )
switch (sgb_data[0] >> 3)
{
case 0x00: /* PAL01 */
m_sgb_pal[0*4 + 0] = sgb_data[1] | (sgb_data[2] << 8);
m_sgb_pal[0*4 + 1] = sgb_data[3] | (sgb_data[4] << 8);
m_sgb_pal[0*4 + 2] = sgb_data[5] | (sgb_data[6] << 8);
m_sgb_pal[0*4 + 3] = sgb_data[7] | (sgb_data[8] << 8);
m_sgb_pal[1*4 + 0] = sgb_data[1] | (sgb_data[2] << 8);
m_sgb_pal[1*4 + 1] = sgb_data[9] | (sgb_data[10] << 8);
m_sgb_pal[1*4 + 2] = sgb_data[11] | (sgb_data[12] << 8);
m_sgb_pal[1*4 + 3] = sgb_data[13] | (sgb_data[14] << 8);
break;
case 0x01: /* PAL23 */
m_sgb_pal[2*4 + 0] = sgb_data[1] | (sgb_data[2] << 8);
m_sgb_pal[2*4 + 1] = sgb_data[3] | (sgb_data[4] << 8);
m_sgb_pal[2*4 + 2] = sgb_data[5] | (sgb_data[6] << 8);
m_sgb_pal[2*4 + 3] = sgb_data[7] | (sgb_data[8] << 8);
m_sgb_pal[3*4 + 0] = sgb_data[1] | (sgb_data[2] << 8);
m_sgb_pal[3*4 + 1] = sgb_data[9] | (sgb_data[10] << 8);
m_sgb_pal[3*4 + 2] = sgb_data[11] | (sgb_data[12] << 8);
m_sgb_pal[3*4 + 3] = sgb_data[13] | (sgb_data[14] << 8);
break;
case 0x02: /* PAL03 */
m_sgb_pal[0*4 + 0] = sgb_data[1] | (sgb_data[2] << 8);
m_sgb_pal[0*4 + 1] = sgb_data[3] | (sgb_data[4] << 8);
m_sgb_pal[0*4 + 2] = sgb_data[5] | (sgb_data[6] << 8);
m_sgb_pal[0*4 + 3] = sgb_data[7] | (sgb_data[8] << 8);
m_sgb_pal[3*4 + 0] = sgb_data[1] | (sgb_data[2] << 8);
m_sgb_pal[3*4 + 1] = sgb_data[9] | (sgb_data[10] << 8);
m_sgb_pal[3*4 + 2] = sgb_data[11] | (sgb_data[12] << 8);
m_sgb_pal[3*4 + 3] = sgb_data[13] | (sgb_data[14] << 8);
break;
case 0x03: /* PAL12 */
m_sgb_pal[1*4 + 0] = sgb_data[1] | (sgb_data[2] << 8);
m_sgb_pal[1*4 + 1] = sgb_data[3] | (sgb_data[4] << 8);
m_sgb_pal[1*4 + 2] = sgb_data[5] | (sgb_data[6] << 8);
m_sgb_pal[1*4 + 3] = sgb_data[7] | (sgb_data[8] << 8);
m_sgb_pal[2*4 + 0] = sgb_data[1] | (sgb_data[2] << 8);
m_sgb_pal[2*4 + 1] = sgb_data[9] | (sgb_data[10] << 8);
m_sgb_pal[2*4 + 2] = sgb_data[11] | (sgb_data[12] << 8);
m_sgb_pal[2*4 + 3] = sgb_data[13] | (sgb_data[14] << 8);
break;
case 0x04: /* ATTR_BLK */
{
UINT8 I, J, K, o;
for( K = 0; K < sgb_data[1]; K++ )
{
o = K * 6;
if( sgb_data[o + 2] & 0x1 )
{
for( I = sgb_data[ o + 4]; I <= sgb_data[o + 6]; I++ )
{
for( J = sgb_data[o + 5]; J <= sgb_data[o + 7]; J++ )
{
m_sgb_pal_map[I][J] = sgb_data[o + 3] & 0x3;
}
}
}
}
}
break;
case 0x05: /* ATTR_LIN */
{
UINT8 J, K;
if( sgb_data[1] > 15 )
sgb_data[1] = 15;
for( K = 0; K < sgb_data[1]; K++ )
{
if( sgb_data[K + 1] & 0x80 )
{
for( J = 0; J < 20; J++ )
{
m_sgb_pal_map[J][sgb_data[K + 1] & 0x1f] = (sgb_data[K + 1] & 0x60) >> 5;
}
}
else
{
for( J = 0; J < 18; J++ )
{
m_sgb_pal_map[sgb_data[K + 1] & 0x1f][J] = (sgb_data[K + 1] & 0x60) >> 5;
}
}
}
}
break;
case 0x06: /* ATTR_DIV */
{
UINT8 I, J;
if( sgb_data[1] & 0x40 ) /* Vertical */
{
for( I = 0; I < sgb_data[2]; I++ )
{
for( J = 0; J < 20; J++ )
{
m_sgb_pal_map[J][I] = (sgb_data[1] & 0xC) >> 2;
}
}
for( J = 0; J < 20; J++ )
{
m_sgb_pal_map[J][sgb_data[2]] = (sgb_data[1] & 0x30) >> 4;
}
for( I = sgb_data[2] + 1; I < 18; I++ )
{
for( J = 0; J < 20; J++ )
{
m_sgb_pal_map[J][I] = sgb_data[1] & 0x3;
}
}
}
else /* Horizontal */
{
for( I = 0; I < sgb_data[2]; I++ )
{
for( J = 0; J < 18; J++ )
{
m_sgb_pal_map[I][J] = (sgb_data[1] & 0xC) >> 2;
}
}
for( J = 0; J < 18; J++ )
{
m_sgb_pal_map[sgb_data[2]][J] = (sgb_data[1] & 0x30) >> 4;
}
for( I = sgb_data[2] + 1; I < 20; I++ )
{
for( J = 0; J < 18; J++ )
{
m_sgb_pal_map[I][J] = sgb_data[1] & 0x3;
}
}
}
}
break;
case 0x07: /* ATTR_CHR */
{
UINT16 I, sets;
UINT8 x, y;
sets = (sgb_data[3] | (sgb_data[4] << 8) );
if( sets > 360 )
sets = 360;
sets >>= 2;
sets += 6;
x = sgb_data[1];
y = sgb_data[2];
if( sgb_data[5] ) /* Vertical */
{
for( I = 6; I < sets; I++ )
{
m_sgb_pal_map[x][y++] = (sgb_data[I] & 0xC0) >> 6;
if( y > 17 )
{
y = 0;
x++;
if( x > 19 )
x = 0;
}
m_sgb_pal_map[x][y++] = (sgb_data[I] & 0x30) >> 4;
if( y > 17 )
{
y = 0;
x++;
if( x > 19 )
x = 0;
}
m_sgb_pal_map[x][y++] = (sgb_data[I] & 0xC) >> 2;
if( y > 17 )
{
y = 0;
x++;
if( x > 19 )
x = 0;
}
m_sgb_pal_map[x][y++] = sgb_data[I] & 0x3;
if( y > 17 )
{
y = 0;
x++;
if( x > 19 )
x = 0;
}
}
}
else /* horizontal */
{
for( I = 6; I < sets; I++ )
{
m_sgb_pal_map[x++][y] = (sgb_data[I] & 0xC0) >> 6;
if( x > 19 )
{
x = 0;
y++;
if( y > 17 )
y = 0;
}
m_sgb_pal_map[x++][y] = (sgb_data[I] & 0x30) >> 4;
if( x > 19 )
{
x = 0;
y++;
if( y > 17 )
y = 0;
}
m_sgb_pal_map[x++][y] = (sgb_data[I] & 0xC) >> 2;
if( x > 19 )
{
x = 0;
y++;
if( y > 17 )
y = 0;
}
m_sgb_pal_map[x++][y] = sgb_data[I] & 0x3;
if( x > 19 )
{
x = 0;
y++;
if( y > 17 )
y = 0;
}
}
}
}
break;
case 0x08: /* SOUND */
/* This command enables internal sound effects */
/* Not Implemented */
break;
case 0x09: /* SOU_TRN */
/* This command sends data to the SNES sound processor.
We'll need to emulate that for this to be used */
/* Not Implemented */
break;
case 0x0A: /* PAL_SET */
{
UINT16 index_, J, I;
/* Palette 0 */
index_ = (UINT16)(sgb_data[1] | (sgb_data[2] << 8)) * 4;
m_sgb_pal[0] = m_sgb_pal_data[index_];
m_sgb_pal[1] = m_sgb_pal_data[index_ + 1];
m_sgb_pal[2] = m_sgb_pal_data[index_ + 2];
m_sgb_pal[3] = m_sgb_pal_data[index_ + 3];
/* Palette 1 */
index_ = (UINT16)(sgb_data[3] | (sgb_data[4] << 8)) * 4;
m_sgb_pal[4] = m_sgb_pal_data[index_];
m_sgb_pal[5] = m_sgb_pal_data[index_ + 1];
m_sgb_pal[6] = m_sgb_pal_data[index_ + 2];
m_sgb_pal[7] = m_sgb_pal_data[index_ + 3];
/* Palette 2 */
index_ = (UINT16)(sgb_data[5] | (sgb_data[6] << 8)) * 4;
m_sgb_pal[8] = m_sgb_pal_data[index_];
m_sgb_pal[9] = m_sgb_pal_data[index_ + 1];
m_sgb_pal[10] = m_sgb_pal_data[index_ + 2];
m_sgb_pal[11] = m_sgb_pal_data[index_ + 3];
/* Palette 3 */
index_ = (UINT16)(sgb_data[7] | (sgb_data[8] << 8)) * 4;
m_sgb_pal[12] = m_sgb_pal_data[index_];
m_sgb_pal[13] = m_sgb_pal_data[index_ + 1];
m_sgb_pal[14] = m_sgb_pal_data[index_ + 2];
m_sgb_pal[15] = m_sgb_pal_data[index_ + 3];
/* Attribute File */
if( sgb_data[9] & 0x40 )
m_sgb_window_mask = 0;
m_sgb_atf = (sgb_data[9] & 0x3f) * (18 * 5);
if( sgb_data[9] & 0x80 )
{
for( J = 0; J < 18; J++ )
{
for( I = 0; I < 5; I++ )
{
m_sgb_pal_map[I * 4][J] = (m_sgb_atf_data[(J * 5) + m_sgb_atf + I] & 0xC0) >> 6;
m_sgb_pal_map[(I * 4) + 1][J] = (m_sgb_atf_data[(J * 5) + m_sgb_atf + I] & 0x30) >> 4;
m_sgb_pal_map[(I * 4) + 2][J] = (m_sgb_atf_data[(J * 5) + m_sgb_atf + I] & 0xC) >> 2;
m_sgb_pal_map[(I * 4) + 3][J] = m_sgb_atf_data[(J * 5) + m_sgb_atf + I] & 0x3;
}
}
}
}
break;
case 0x0B: /* PAL_TRN */
{
UINT16 I, col;
for( I = 0; I < 2048; I++ )
{
col = (m_lcd.gb_vram[0x0800 + (I*2) + 1] << 8) | m_lcd.gb_vram[0x0800 + (I*2)];
m_sgb_pal_data[I] = col;
}
}
break;
case 0x0C: /* ATRC_EN */
/* Not Implemented */
break;
case 0x0D: /* TEST_EN */
/* Not Implemented */
break;
case 0x0E: /* ICON_EN */
/* Not Implemented */
break;
case 0x0F: /* DATA_SND */
/* Not Implemented */
break;
case 0x10: /* DATA_TRN */
/* Not Implemented */
break;
case 0x11: /* MLT_REQ - Multi controller request */
if (sgb_data[1] == 0x00)
m_sgb_controller_mode = 0;
else if (sgb_data[1] == 0x01)
m_sgb_controller_mode = 2;
break;
case 0x12: /* JUMP */
/* Not Implemented */
break;
case 0x13: /* CHR_TRN */
if (sgb_data[1] & 0x1)
memcpy(m_sgb_tile_data + 4096, m_lcd.gb_vram + 0x0800, 4096);
else
memcpy(m_sgb_tile_data, m_lcd.gb_vram + 0x0800, 4096);
break;
case 0x14: /* PCT_TRN */
{
int I;
UINT16 col;
if (m_cartslot && m_cartslot->get_sgb_hack())
{
memcpy(m_sgb_tile_map, m_lcd.gb_vram + 0x1000, 2048);
for( I = 0; I < 64; I++ )
{
col = (m_lcd.gb_vram[0x0800 + (I*2) + 1 ] << 8) | m_lcd.gb_vram[0x0800 + (I*2)];
m_sgb_pal[SGB_BORDER_PAL_OFFSET + I] = col;
}
}
else /* Do things normally */
{
memcpy(m_sgb_tile_map, m_lcd.gb_vram + 0x0800, 2048);
for( I = 0; I < 64; I++ )
{
col = (m_lcd.gb_vram[0x1000 + (I*2) + 1] << 8) | m_lcd.gb_vram[0x1000 + (I*2)];
m_sgb_pal[SGB_BORDER_PAL_OFFSET + I] = col;
}
}
}
break;
case 0x15: /* ATTR_TRN */
memcpy( m_sgb_atf_data, m_lcd.gb_vram + 0x0800, 4050 );
break;
case 0x16: /* ATTR_SET */
{
UINT8 J, I;
/* Attribute File */
if( sgb_data[1] & 0x40 )
m_sgb_window_mask = 0;
m_sgb_atf = (sgb_data[1] & 0x3f) * (18 * 5);
for( J = 0; J < 18; J++ )
{
for( I = 0; I < 5; I++ )
{
m_sgb_pal_map[I * 4][J] = (m_sgb_atf_data[(J * 5) + m_sgb_atf + I] & 0xC0) >> 6;
m_sgb_pal_map[(I * 4) + 1][J] = (m_sgb_atf_data[(J * 5) + m_sgb_atf + I] & 0x30) >> 4;
m_sgb_pal_map[(I * 4) + 2][J] = (m_sgb_atf_data[(J * 5) + m_sgb_atf + I] & 0xC) >> 2;
m_sgb_pal_map[(I * 4) + 3][J] = m_sgb_atf_data[(J * 5) + m_sgb_atf + I] & 0x3;
}
}
}
break;
case 0x17: /* MASK_EN */
m_sgb_window_mask = sgb_data[1];
break;
case 0x18: /* OBJ_TRN */
/* Not Implemnted */
break;
case 0x19: /* ? */
/* Called by: dkl,dkl2,dkl3,zeldadx
But I don't know what it is for. */
/* Not Implemented */
break;
case 0x1E: /* Used by bootrom to transfer the gb cart header */
break;
case 0x1F: /* Used by bootrom to transfer the gb cart header */
break;
default:
logerror( "SGB: Unknown Command 0x%02x!\n", sgb_data[0] >> 3 );
machine().device<sgb_lcd_device>("lcd")->sgb_io_write_pal(sgb_data[0] >> 3, &sgb_data[0]);
break;
}
m_sgb_start = 0;
m_sgb_bytecount = 0;
m_sgb_packets = -1;
@ -1040,7 +636,7 @@ WRITE8_MEMBER(gb_state::gbc_io2_w)
default:
break;
}
gbc_video_w( space, offset, data );
machine().device<cgb_lcd_device>("lcd")->video_w(space, offset, data);
}
READ8_MEMBER(gb_state::gbc_io2_r)
@ -1056,7 +652,7 @@ READ8_MEMBER(gb_state::gbc_io2_r)
default:
break;
}
return gbc_video_r( space, offset );
return machine().device<cgb_lcd_device>("lcd")->video_r(space, offset);
}
/****************************************************************************
@ -1072,7 +668,6 @@ MACHINE_START_MEMBER(megaduck_state,megaduck)
m_gb_serial_timer->enable( 0 );
save_gb_base();
gb_video_start(GB_VIDEO_DMG);
}
MACHINE_RESET_MEMBER(megaduck_state,megaduck)
@ -1081,8 +676,6 @@ MACHINE_RESET_MEMBER(megaduck_state,megaduck)
gb_init();
m_bios_disable = 1;
gb_video_reset( GB_VIDEO_DMG );
}
/*
@ -1125,11 +718,11 @@ READ8_MEMBER(megaduck_state::megaduck_video_r)
{
UINT8 data;
if ( (offset & 0x0C) && ((offset & 0x0C) ^ 0x0C) )
if ((offset & 0x0C) && ((offset & 0x0C) ^ 0x0C))
{
offset ^= 0x0C;
}
data = gb_video_r( space, offset );
data = machine().device<gb_lcd_device>("lcd")->video_r(space, offset);
if ( offset )
return data;
return BITSWAP8(data,7,0,5,4,6,3,2,1);
@ -1137,15 +730,15 @@ READ8_MEMBER(megaduck_state::megaduck_video_r)
WRITE8_MEMBER(megaduck_state::megaduck_video_w)
{
if ( !offset )
if (!offset)
{
data = BITSWAP8(data,7,3,5,4,2,1,0,6);
}
if ( (offset & 0x0C) && ((offset & 0x0C) ^ 0x0C) )
if ((offset & 0x0C) && ((offset & 0x0C) ^ 0x0C))
{
offset ^= 0x0C;
}
gb_video_w(space, offset, data );
machine().device<gb_lcd_device>("lcd")->video_w(space, offset, data);
}
/* Map megaduck audio offset to game boy audio offsets */

File diff suppressed because it is too large Load Diff