mirror of
https://github.com/holub/mame
synced 2025-04-24 17:30:55 +03:00
(MESS) wswan: converted the video chip to be a device. nw.
This commit is contained in:
parent
31fd590aa6
commit
e6a5e406bf
@ -35,14 +35,14 @@
|
||||
#include "wswan.lh"
|
||||
|
||||
static ADDRESS_MAP_START (wswan_mem, AS_PROGRAM, 8, wswan_state)
|
||||
AM_RANGE(0x00000, 0x03fff) AM_RAM // 16kb RAM / 4 colour tiles
|
||||
AM_RANGE(0x00000, 0x03fff) AM_DEVREADWRITE("vdp", wswan_video_device, vram_r, vram_w) // 16kb RAM / 4 colour tiles
|
||||
AM_RANGE(0x04000, 0x0ffff) AM_NOP // nothing
|
||||
//AM_RANGE(0x10000, 0xeffff) // cart range, setup at machine_start
|
||||
AM_RANGE(0xf0000, 0xfffff) AM_READ(bios_r)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START (wscolor_mem, AS_PROGRAM, 8, wswan_state)
|
||||
AM_RANGE(0x00000, 0x0ffff) AM_RAM // 16kb RAM / 4 colour tiles, 16 colour tiles + palettes
|
||||
AM_RANGE(0x00000, 0x0ffff) AM_DEVREADWRITE("vdp", wswan_video_device, vram_r, vram_w) // 16kb RAM / 4 colour tiles, 16 colour tiles + palettes
|
||||
//AM_RANGE(0x10000, 0xeffff) // cart range, setup at machine_start
|
||||
AM_RANGE(0xf0000, 0xfffff) AM_READ(bios_r)
|
||||
ADDRESS_MAP_END
|
||||
@ -83,7 +83,7 @@ PALETTE_INIT_MEMBER(wswan_state, wswan)
|
||||
}
|
||||
}
|
||||
|
||||
PALETTE_INIT_MEMBER(wswan_state,wscolor)
|
||||
PALETTE_INIT_MEMBER(wswan_state, wscolor)
|
||||
{
|
||||
for (int i = 0; i < 4096; i++)
|
||||
{
|
||||
@ -95,9 +95,9 @@ PALETTE_INIT_MEMBER(wswan_state,wscolor)
|
||||
}
|
||||
|
||||
static SLOT_INTERFACE_START(wswan_cart)
|
||||
SLOT_INTERFACE_INTERNAL("ws_rom", WS_ROM_STD)
|
||||
SLOT_INTERFACE_INTERNAL("ws_sram", WS_ROM_SRAM)
|
||||
SLOT_INTERFACE_INTERNAL("ws_eeprom", WS_ROM_EEPROM)
|
||||
SLOT_INTERFACE_INTERNAL("ws_rom", WS_ROM_STD)
|
||||
SLOT_INTERFACE_INTERNAL("ws_sram", WS_ROM_SRAM)
|
||||
SLOT_INTERFACE_INTERNAL("ws_eeprom", WS_ROM_EEPROM)
|
||||
SLOT_INTERFACE_END
|
||||
|
||||
static MACHINE_CONFIG_START( wswan, wswan_state )
|
||||
@ -106,11 +106,16 @@ static MACHINE_CONFIG_START( wswan, wswan_state )
|
||||
MCFG_CPU_PROGRAM_MAP(wswan_mem)
|
||||
MCFG_CPU_IO_MAP(wswan_io)
|
||||
|
||||
MCFG_DEVICE_ADD("vdp", WSWAN_VIDEO, 0)
|
||||
MCFG_WSWAN_VIDEO_TYPE(VDP_TYPE_WSWAN)
|
||||
MCFG_WSWAN_VIDEO_IRQ_CB(wswan_state, set_irq_line)
|
||||
MCFG_WSWAN_VIDEO_DMASND_CB(wswan_state, dma_sound_cb)
|
||||
|
||||
MCFG_SCREEN_ADD("screen", LCD)
|
||||
MCFG_SCREEN_REFRESH_RATE(75)
|
||||
MCFG_SCREEN_VBLANK_TIME(0)
|
||||
MCFG_SCREEN_UPDATE_DRIVER(wswan_state, screen_update)
|
||||
MCFG_SCREEN_SIZE( WSWAN_X_PIXELS, WSWAN_Y_PIXELS )
|
||||
MCFG_SCREEN_UPDATE_DEVICE("vdp", wswan_video_device, screen_update)
|
||||
MCFG_SCREEN_SIZE(WSWAN_X_PIXELS, WSWAN_Y_PIXELS)
|
||||
MCFG_SCREEN_VISIBLE_AREA(0*8, WSWAN_X_PIXELS - 1, 0, WSWAN_Y_PIXELS - 1)
|
||||
MCFG_SCREEN_PALETTE("palette")
|
||||
|
||||
@ -141,11 +146,14 @@ MACHINE_CONFIG_END
|
||||
static MACHINE_CONFIG_DERIVED( wscolor, wswan )
|
||||
MCFG_CPU_MODIFY("maincpu")
|
||||
MCFG_CPU_PROGRAM_MAP(wscolor_mem)
|
||||
MCFG_MACHINE_START_OVERRIDE(wswan_state, wscolor )
|
||||
MCFG_MACHINE_START_OVERRIDE(wswan_state, wscolor)
|
||||
|
||||
MCFG_DEVICE_MODIFY("vdp")
|
||||
MCFG_WSWAN_VIDEO_TYPE(VDP_TYPE_WSC)
|
||||
|
||||
MCFG_PALETTE_MODIFY("palette")
|
||||
MCFG_PALETTE_ENTRIES(4096)
|
||||
MCFG_PALETTE_INIT_OWNER(wswan_state, wscolor )
|
||||
MCFG_PALETTE_INIT_OWNER(wswan_state, wscolor)
|
||||
|
||||
/* software lists */
|
||||
MCFG_DEVICE_REMOVE("cart_list")
|
||||
|
@ -10,15 +10,13 @@
|
||||
#define WSWAN_TYPE_MONO 0
|
||||
#define WSWAN_TYPE_COLOR 1
|
||||
|
||||
#define WSWAN_X_PIXELS (28*8)
|
||||
#define WSWAN_Y_PIXELS (18*8)
|
||||
|
||||
#define INTERNAL_EEPROM_SIZE 1024
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/v30mz/v30mz.h"
|
||||
#include "audio/wswan_snd.h"
|
||||
#include "machine/nvram.h"
|
||||
#include "audio/wswan_snd.h"
|
||||
#include "video/wswan_video.h"
|
||||
#include "bus/wswan/slot.h"
|
||||
#include "bus/wswan/rom.h"
|
||||
|
||||
@ -30,52 +28,6 @@ struct SoundDMA
|
||||
UINT8 enable; /* Enabled */
|
||||
};
|
||||
|
||||
struct VDP
|
||||
{
|
||||
UINT8 layer_bg_enable; /* Background layer on/off */
|
||||
UINT8 layer_fg_enable; /* Foreground layer on/off */
|
||||
UINT8 sprites_enable; /* Sprites on/off */
|
||||
UINT8 window_sprites_enable; /* Sprite window on/off */
|
||||
UINT8 window_fg_mode; /* 0:inside/outside, 1:??, 2:inside, 3:outside */
|
||||
UINT8 current_line; /* Current scanline : 0-158 (159?) */
|
||||
UINT8 line_compare; /* Line to trigger line interrupt on */
|
||||
UINT32 sprite_table_address; /* Address of the sprite table */
|
||||
UINT8 sprite_table_buffer[512];
|
||||
UINT8 sprite_first; /* First sprite to draw */
|
||||
UINT8 sprite_count; /* Number of sprites to draw */
|
||||
UINT16 layer_bg_address; /* Address of the background screen map */
|
||||
UINT16 layer_fg_address; /* Address of the foreground screen map */
|
||||
UINT8 window_fg_left; /* Left coordinate of foreground window */
|
||||
UINT8 window_fg_top; /* Top coordinate of foreground window */
|
||||
UINT8 window_fg_right; /* Right coordinate of foreground window */
|
||||
UINT8 window_fg_bottom; /* Bottom coordinate of foreground window */
|
||||
UINT8 window_sprites_left; /* Left coordinate of sprites window */
|
||||
UINT8 window_sprites_top; /* Top coordinate of sprites window */
|
||||
UINT8 window_sprites_right; /* Right coordinate of sprites window */
|
||||
UINT8 window_sprites_bottom; /* Bottom coordinate of sprites window */
|
||||
UINT8 layer_bg_scroll_x; /* Background layer X scroll */
|
||||
UINT8 layer_bg_scroll_y; /* Background layer Y scroll */
|
||||
UINT8 layer_fg_scroll_x; /* Foreground layer X scroll */
|
||||
UINT8 layer_fg_scroll_y; /* Foreground layer Y scroll */
|
||||
UINT8 lcd_enable; /* LCD on/off */
|
||||
UINT8 icons; /* FIXME: What do we do with these? Maybe artwork? */
|
||||
UINT8 color_mode; /* monochrome/color mode */
|
||||
UINT8 colors_16; /* 4/16 colors mode */
|
||||
UINT8 tile_packed; /* layered/packed tile mode switch */
|
||||
UINT8 timer_hblank_enable; /* Horizontal blank interrupt on/off */
|
||||
UINT8 timer_hblank_mode; /* Horizontal blank timer mode */
|
||||
UINT16 timer_hblank_reload; /* Horizontal blank timer reload value */
|
||||
UINT16 timer_hblank_count; /* Horizontal blank timer counter value */
|
||||
UINT8 timer_vblank_enable; /* Vertical blank interrupt on/off */
|
||||
UINT8 timer_vblank_mode; /* Vertical blank timer mode */
|
||||
UINT16 timer_vblank_reload; /* Vertical blank timer reload value */
|
||||
UINT16 timer_vblank_count; /* Vertical blank timer counter value */
|
||||
UINT8 *vram; /* pointer to start of ram/vram (set by machine_reset) */
|
||||
UINT8 *palette_vram; /* pointer to start of palette area in ram/vram (set by machine_reset), WSC only */
|
||||
int main_palette[8];
|
||||
emu_timer *timer;
|
||||
};
|
||||
|
||||
|
||||
class wswan_state : public driver_device
|
||||
{
|
||||
@ -83,44 +35,39 @@ public:
|
||||
wswan_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_vdp(*this, "vdp"),
|
||||
m_sound(*this, "custom"),
|
||||
m_cart(*this, "cartslot"),
|
||||
m_cursx(*this, "CURSX"),
|
||||
m_cursy(*this, "CURSY"),
|
||||
m_buttons(*this, "BUTTONS") { }
|
||||
|
||||
virtual void video_start();
|
||||
|
||||
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
m_buttons(*this, "BUTTONS")
|
||||
{ }
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<wswan_video_device> m_vdp;
|
||||
required_device<wswan_sound_device> m_sound;
|
||||
required_device<ws_cart_slot_device> m_cart;
|
||||
DECLARE_READ8_MEMBER(bios_r);
|
||||
DECLARE_READ8_MEMBER(port_r);
|
||||
DECLARE_WRITE8_MEMBER(port_w);
|
||||
|
||||
VDP m_vdp;
|
||||
|
||||
UINT8 m_ws_portram[256];
|
||||
UINT8 m_internal_eeprom[INTERNAL_EEPROM_SIZE];
|
||||
UINT8 m_system_type;
|
||||
SoundDMA m_sound_dma;
|
||||
UINT8 *m_ws_ram;
|
||||
UINT8 *m_ws_bios_bank;
|
||||
UINT8 m_bios_disabled;
|
||||
int m_pal[16][16];
|
||||
bitmap_ind16 m_bitmap;
|
||||
UINT8 m_rotate;
|
||||
|
||||
void wswan_clear_irq_line(int irq);
|
||||
|
||||
void set_irq_line(int irq);
|
||||
void dma_sound_cb();
|
||||
void common_start();
|
||||
virtual void machine_start();
|
||||
virtual void machine_reset();
|
||||
DECLARE_PALETTE_INIT(wswan);
|
||||
DECLARE_MACHINE_START(wscolor);
|
||||
DECLARE_PALETTE_INIT(wscolor);
|
||||
TIMER_CALLBACK_MEMBER(wswan_scanline_interrupt);
|
||||
|
||||
|
||||
protected:
|
||||
/* Interrupt flags */
|
||||
static const UINT8 WSWAN_IFLAG_STX = 0x01;
|
||||
@ -131,7 +78,7 @@ protected:
|
||||
static const UINT8 WSWAN_IFLAG_VBLTMR = 0x20;
|
||||
static const UINT8 WSWAN_IFLAG_VBL = 0x40;
|
||||
static const UINT8 WSWAN_IFLAG_HBLTMR = 0x80;
|
||||
|
||||
|
||||
/* Interrupts */
|
||||
static const UINT8 WSWAN_INT_STX = 0;
|
||||
static const UINT8 WSWAN_INT_KEY = 1;
|
||||
@ -141,22 +88,14 @@ protected:
|
||||
static const UINT8 WSWAN_INT_VBLTMR = 5;
|
||||
static const UINT8 WSWAN_INT_VBL = 6;
|
||||
static const UINT8 WSWAN_INT_HBLTMR = 7;
|
||||
|
||||
|
||||
required_ioport m_cursx;
|
||||
required_ioport m_cursy;
|
||||
required_ioport m_buttons;
|
||||
|
||||
void wswan_register_save();
|
||||
void wswan_postload();
|
||||
void wswan_handle_irqs();
|
||||
void wswan_set_irq_line(int irq);
|
||||
void wswan_setup_palettes();
|
||||
void wswan_draw_background();
|
||||
void wswan_draw_foreground_0();
|
||||
void wswan_draw_foreground_2();
|
||||
void wswan_draw_foreground_3();
|
||||
void wswan_handle_sprites( int mask );
|
||||
void wswan_refresh_scanline( );
|
||||
|
||||
void register_save();
|
||||
void handle_irqs();
|
||||
void clear_irq_line(int irq);
|
||||
};
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1029,7 +1029,7 @@ $(MESSOBJ)/bally.a: \
|
||||
$(MESSOBJ)/bandai.a: \
|
||||
$(MESS_DRIVERS)/sv8000.o \
|
||||
$(MESS_DRIVERS)/rx78.o \
|
||||
$(MESS_DRIVERS)/wswan.o $(MESS_AUDIO)/wswan_snd.o $(MESS_MACHINE)/wswan.o $(MESS_VIDEO)/wswan.o \
|
||||
$(MESS_DRIVERS)/wswan.o $(MESS_AUDIO)/wswan_snd.o $(MESS_MACHINE)/wswan.o $(MESS_VIDEO)/wswan_video.o \
|
||||
|
||||
$(MESSOBJ)/be.a: \
|
||||
$(MESS_DRIVERS)/bebox.o $(MESS_MACHINE)/bebox.o \
|
||||
|
@ -1,583 +0,0 @@
|
||||
/***************************************************************************
|
||||
|
||||
wswan.c
|
||||
|
||||
File to handle video emulation of the Bandai WonderSwan.
|
||||
|
||||
Anthony Kruize
|
||||
Wilbert Pol
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "includes/wswan.h"
|
||||
|
||||
void wswan_state::wswan_setup_palettes()
|
||||
{
|
||||
int i,j;
|
||||
|
||||
if ( m_vdp.color_mode ) {
|
||||
for( i = 0; i < 16; i++ ) {
|
||||
for( j = 0; j < 16; j++ ) {
|
||||
m_pal[i][j] = ( ( m_vdp.palette_vram[ ( i << 5 ) + j*2 + 1 ] << 8 ) | m_vdp.palette_vram[ ( i << 5 ) + j*2 ] ) & 0x0FFF;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for( i = 0; i < 16; i++ ) {
|
||||
m_pal[i][0] = m_ws_portram[ 0x20 + ( i << 1 ) ] & 0x07;
|
||||
m_pal[i][1] = ( m_ws_portram[ 0x20 + ( i << 1 ) ] >> 4 ) & 0x07;
|
||||
m_pal[i][2] = m_ws_portram[ 0x21 + ( i << 1 ) ] & 0x07;
|
||||
m_pal[i][3] = ( m_ws_portram[ 0x21 + ( i << 1 ) ] >> 4 ) & 0x07;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wswan_state::wswan_draw_background()
|
||||
{
|
||||
UINT16 map_addr;
|
||||
UINT8 start_column;
|
||||
int column;
|
||||
|
||||
map_addr = m_vdp.layer_bg_address + ( ( ( m_vdp.current_line + m_vdp.layer_bg_scroll_y ) & 0xF8 ) << 3 );
|
||||
start_column = ( m_vdp.layer_bg_scroll_x >> 3 );
|
||||
for( column = 0; column < 29; column++ ) {
|
||||
int tile_data, tile_number, tile_palette, tile_line, tile_address;
|
||||
UINT32 plane0=0, plane1=0, plane2=0, plane3=0;
|
||||
int x, x_offset;
|
||||
|
||||
tile_data = ( m_vdp.vram[ map_addr + ( ( ( start_column + column ) & 0x1F ) << 1 ) + 1 ] << 8 )
|
||||
| m_vdp.vram[ map_addr + ( ( ( start_column + column ) & 0x1F ) << 1 ) ];
|
||||
tile_number = tile_data & 0x01FF;
|
||||
tile_palette = ( tile_data >> 9 ) & 0x0F;
|
||||
|
||||
tile_line = ( m_vdp.current_line + m_vdp.layer_bg_scroll_y ) & 0x07;
|
||||
if ( tile_data & 0x8000 ) {
|
||||
tile_line = 7 - tile_line;
|
||||
}
|
||||
|
||||
if ( m_vdp.colors_16 ) {
|
||||
tile_address = ( ( tile_data & 0x2000 ) ? 0x8000 : 0x4000 ) + ( tile_number * 32 ) + ( tile_line << 2 );
|
||||
if ( m_vdp.tile_packed ) {
|
||||
plane0 = ( m_vdp.vram[ tile_address + 0 ] << 24 ) | ( m_vdp.vram[ tile_address + 1 ] << 16 ) | ( m_vdp.vram[ tile_address + 2 ] << 8 ) | m_vdp.vram[ tile_address + 3 ];
|
||||
} else {
|
||||
plane0 = m_vdp.vram[ tile_address + 0 ];
|
||||
plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
|
||||
plane2 = m_vdp.vram[ tile_address + 2 ] << 2;
|
||||
plane3 = m_vdp.vram[ tile_address + 3 ] << 3;
|
||||
}
|
||||
} else {
|
||||
tile_address = 0x2000 + ( tile_number * 16 ) + ( tile_line << 1 );
|
||||
if ( m_vdp.tile_packed ) {
|
||||
plane0 = ( m_vdp.vram[ tile_address + 0 ] << 8 ) | m_vdp.vram[ tile_address + 1 ];
|
||||
} else {
|
||||
plane0 = m_vdp.vram[ tile_address + 0 ];
|
||||
plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
|
||||
plane2 = 0;
|
||||
plane3 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for( x = 0; x < 8; x++ ) {
|
||||
int col;
|
||||
if ( m_vdp.tile_packed ) {
|
||||
if ( m_vdp.colors_16 ) {
|
||||
col = plane0 & 0x0F;
|
||||
plane0 = plane0 >> 4;
|
||||
} else {
|
||||
col = plane0 & 0x03;
|
||||
plane0 = plane0 >> 2;
|
||||
}
|
||||
} else {
|
||||
col = ( plane3 & 8 ) | ( plane2 & 4 ) | ( plane1 & 2 ) | ( plane0 & 1 );
|
||||
plane3 = plane3 >> 1;
|
||||
plane2 = plane2 >> 1;
|
||||
plane1 = plane1 >> 1;
|
||||
plane0 = plane0 >> 1;
|
||||
}
|
||||
if ( tile_data & 0x4000 ) {
|
||||
x_offset = x + ( column << 3 ) - ( m_vdp.layer_bg_scroll_x & 0x07 );
|
||||
} else {
|
||||
x_offset = 7 - x + ( column << 3 ) - ( m_vdp.layer_bg_scroll_x & 0x07 );
|
||||
}
|
||||
if ( x_offset >= 0 && x_offset < WSWAN_X_PIXELS ) {
|
||||
if ( m_vdp.colors_16 ) {
|
||||
if ( col ) {
|
||||
if ( m_vdp.color_mode ) {
|
||||
m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
|
||||
} else {
|
||||
/* Hmmmm, what should we do here... Is this correct?? */
|
||||
m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( col || !(tile_palette & 4 ) ) {
|
||||
if ( m_vdp.color_mode ) {
|
||||
m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
|
||||
} else {
|
||||
m_bitmap.pix16(m_vdp.current_line, x_offset) = m_vdp.main_palette[m_pal[tile_palette][col]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wswan_state::wswan_draw_foreground_0()
|
||||
{
|
||||
UINT16 map_addr;
|
||||
UINT8 start_column;
|
||||
int column;
|
||||
map_addr = m_vdp.layer_fg_address + ( ( ( m_vdp.current_line + m_vdp.layer_fg_scroll_y ) & 0xF8 ) << 3 );
|
||||
start_column = ( m_vdp.layer_fg_scroll_x >> 3 );
|
||||
for( column = 0; column < 29; column++ ) {
|
||||
UINT32 plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0;
|
||||
int x, x_offset, tile_line, tile_address;
|
||||
int tile_data = ( m_vdp.vram[ map_addr + ( ( ( start_column + column ) & 0x1F ) << 1 ) + 1 ] << 8 )
|
||||
| m_vdp.vram[ map_addr + ( ( ( start_column + column ) & 0x1F ) << 1 ) ];
|
||||
int tile_number = tile_data & 0x01FF;
|
||||
int tile_palette = ( tile_data >> 9 ) & 0x0F;
|
||||
|
||||
tile_line = ( m_vdp.current_line + m_vdp.layer_fg_scroll_y ) & 0x07;
|
||||
if ( tile_data & 0x8000 ) {
|
||||
tile_line = 7 - tile_line;
|
||||
}
|
||||
|
||||
if ( m_vdp.colors_16 ) {
|
||||
tile_address = ( ( tile_data & 0x2000 ) ? 0x8000 : 0x4000 ) + ( tile_number * 32 ) + ( tile_line << 2 );
|
||||
if ( m_vdp.tile_packed ) {
|
||||
plane0 = ( m_vdp.vram[ tile_address + 0 ] << 24 ) | ( m_vdp.vram[ tile_address + 1 ] << 16 ) | ( m_vdp.vram[ tile_address + 2 ] << 8 ) | m_vdp.vram[ tile_address + 3 ];
|
||||
} else {
|
||||
plane0 = m_vdp.vram[ tile_address + 0 ];
|
||||
plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
|
||||
plane2 = m_vdp.vram[ tile_address + 2 ] << 2;
|
||||
plane3 = m_vdp.vram[ tile_address + 3 ] << 3;
|
||||
}
|
||||
} else {
|
||||
tile_address = 0x2000 + ( tile_number * 16 ) + ( tile_line << 1 );
|
||||
if ( m_vdp.tile_packed ) {
|
||||
plane0 = ( m_vdp.vram[ tile_address + 0 ] << 8 ) | m_vdp.vram[ tile_address + 1 ];
|
||||
} else {
|
||||
plane0 = m_vdp.vram[ tile_address + 0 ];
|
||||
plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
|
||||
plane2 = 0;
|
||||
plane3 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for( x = 0; x < 8; x++ ) {
|
||||
int col;
|
||||
if ( m_vdp.tile_packed ) {
|
||||
if ( m_vdp.colors_16 ) {
|
||||
col = plane0 & 0x0F;
|
||||
plane0 = plane0 >> 4;
|
||||
} else {
|
||||
col = plane0 & 0x03;
|
||||
plane0 = plane0 >> 2;
|
||||
}
|
||||
} else {
|
||||
col = ( plane3 & 8 ) | ( plane2 & 4 ) | ( plane1 & 2 ) | ( plane0 & 1 );
|
||||
plane3 = plane3 >> 1;
|
||||
plane2 = plane2 >> 1;
|
||||
plane1 = plane1 >> 1;
|
||||
plane0 = plane0 >> 1;
|
||||
}
|
||||
if ( tile_data & 0x4000 ) {
|
||||
x_offset = x + ( column << 3 ) - ( m_vdp.layer_fg_scroll_x & 0x07 );
|
||||
} else {
|
||||
x_offset = 7 - x + ( column << 3 ) - ( m_vdp.layer_fg_scroll_x & 0x07 );
|
||||
}
|
||||
if ( x_offset >= 0 && x_offset < WSWAN_X_PIXELS ) {
|
||||
if ( m_vdp.colors_16 ) {
|
||||
if ( col ) {
|
||||
// if ( m_vdp.color_mode ) {
|
||||
m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
|
||||
// } else {
|
||||
// /* Hmmmm, what should we do here... Is this correct?? */
|
||||
// m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
|
||||
// }
|
||||
}
|
||||
} else {
|
||||
if ( col || !(tile_palette & 4 ) ) {
|
||||
if ( m_vdp.color_mode ) {
|
||||
m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
|
||||
} else {
|
||||
m_bitmap.pix16(m_vdp.current_line, x_offset) = m_vdp.main_palette[m_pal[tile_palette][col]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wswan_state::wswan_draw_foreground_2()
|
||||
{
|
||||
UINT16 map_addr;
|
||||
UINT8 start_column;
|
||||
int column;
|
||||
map_addr = m_vdp.layer_fg_address + ( ( ( m_vdp.current_line + m_vdp.layer_fg_scroll_y ) & 0xF8 ) << 3 );
|
||||
start_column = ( m_vdp.layer_fg_scroll_x >> 3 );
|
||||
for( column = 0; column < 29; column++ ) {
|
||||
UINT32 plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0;
|
||||
int x, x_offset, tile_line, tile_address;
|
||||
int tile_data = ( m_vdp.vram[ map_addr + ( ( ( start_column + column ) & 0x1F ) << 1 ) + 1 ] << 8 )
|
||||
| m_vdp.vram[ map_addr + ( ( ( start_column + column ) & 0x1F ) << 1 ) ];
|
||||
int tile_number = tile_data & 0x01FF;
|
||||
int tile_palette = ( tile_data >> 9 ) & 0x0F;
|
||||
|
||||
tile_line = ( m_vdp.current_line + m_vdp.layer_fg_scroll_y ) & 0x07;
|
||||
if ( tile_data & 0x8000 ) {
|
||||
tile_line = 7 - tile_line;
|
||||
}
|
||||
|
||||
if ( m_vdp.colors_16 ) {
|
||||
tile_address = ( ( tile_data & 0x2000 ) ? 0x8000 : 0x4000 ) + ( tile_number * 32 ) + ( tile_line << 2 );
|
||||
if ( m_vdp.tile_packed ) {
|
||||
plane0 = ( m_vdp.vram[ tile_address + 0 ] << 24 ) | ( m_vdp.vram[ tile_address + 1 ] << 16 ) | ( m_vdp.vram[ tile_address + 2 ] << 8 ) | m_vdp.vram[ tile_address + 3 ];
|
||||
} else {
|
||||
plane0 = m_vdp.vram[ tile_address + 0 ];
|
||||
plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
|
||||
plane2 = m_vdp.vram[ tile_address + 2 ] << 2;
|
||||
plane3 = m_vdp.vram[ tile_address + 3 ] << 3;
|
||||
}
|
||||
} else {
|
||||
tile_address = 0x2000 + ( tile_number * 16 ) + ( tile_line << 1 );
|
||||
if ( m_vdp.tile_packed ) {
|
||||
plane0 = ( m_vdp.vram[ tile_address + 0 ] << 8 ) | m_vdp.vram[ tile_address + 1 ];
|
||||
} else {
|
||||
plane0 = m_vdp.vram[ tile_address + 0 ];
|
||||
plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
|
||||
plane2 = 0;
|
||||
plane3 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for( x = 0; x < 8; x++ ) {
|
||||
int col;
|
||||
if ( m_vdp.tile_packed ) {
|
||||
if ( m_vdp.colors_16 ) {
|
||||
col = plane0 & 0x0F;
|
||||
plane0 = plane0 >> 4;
|
||||
} else {
|
||||
col = plane0 & 0x03;
|
||||
plane0 = plane0 >> 2;
|
||||
}
|
||||
} else {
|
||||
col = ( plane3 & 8 ) | ( plane2 & 4 ) | ( plane1 & 2 ) | ( plane0 & 1 );
|
||||
plane3 = plane3 >> 1;
|
||||
plane2 = plane2 >> 1;
|
||||
plane1 = plane1 >> 1;
|
||||
plane0 = plane0 >> 1;
|
||||
}
|
||||
if ( tile_data & 0x4000 ) {
|
||||
x_offset = x + ( column << 3 ) - ( m_vdp.layer_fg_scroll_x & 0x07 );
|
||||
} else {
|
||||
x_offset = 7 - x + ( column << 3 ) - ( m_vdp.layer_fg_scroll_x & 0x07 );
|
||||
}
|
||||
if ( x_offset >= 0 && x_offset >= m_vdp.window_fg_left && x_offset < m_vdp.window_fg_right && x_offset < WSWAN_X_PIXELS ) {
|
||||
if ( m_vdp.colors_16 ) {
|
||||
if ( col ) {
|
||||
if ( m_vdp.color_mode ) {
|
||||
m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
|
||||
} else {
|
||||
/* Hmmmm, what should we do here... Is this correct?? */
|
||||
m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( col || !(tile_palette & 4 ) ) {
|
||||
if ( m_vdp.color_mode ) {
|
||||
m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
|
||||
} else {
|
||||
m_bitmap.pix16(m_vdp.current_line, x_offset) = m_vdp.main_palette[m_pal[tile_palette][col]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wswan_state::wswan_draw_foreground_3()
|
||||
{
|
||||
UINT16 map_addr;
|
||||
UINT8 start_column;
|
||||
int column;
|
||||
map_addr = m_vdp.layer_fg_address + ( ( ( m_vdp.current_line + m_vdp.layer_fg_scroll_y ) & 0xF8 ) << 3 );
|
||||
start_column = ( m_vdp.layer_fg_scroll_x >> 3 );
|
||||
for( column = 0; column < 29; column++ ) {
|
||||
UINT32 plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0;
|
||||
int x, x_offset, tile_line, tile_address;
|
||||
int tile_data = ( m_vdp.vram[ map_addr + ( ( ( start_column + column ) & 0x1F ) << 1 ) + 1 ] << 8 )
|
||||
| m_vdp.vram[ map_addr + ( ( ( start_column + column ) & 0x1F ) << 1 ) ];
|
||||
int tile_number = tile_data & 0x01FF;
|
||||
int tile_palette = ( tile_data >> 9 ) & 0x0F;
|
||||
|
||||
tile_line = ( m_vdp.current_line + m_vdp.layer_fg_scroll_y ) & 0x07;
|
||||
if ( tile_data & 0x8000 ) { // vflip
|
||||
tile_line = 7 - tile_line;
|
||||
}
|
||||
|
||||
if ( m_vdp.colors_16 ) {
|
||||
tile_address = ( ( tile_data & 0x2000 ) ? 0x8000 : 0x4000 ) + ( tile_number * 32 ) + ( tile_line << 2 );
|
||||
if ( m_vdp.tile_packed ) {
|
||||
plane0 = ( m_vdp.vram[ tile_address + 0 ] << 24 ) | ( m_vdp.vram[ tile_address + 1 ] << 16 ) | ( m_vdp.vram[ tile_address + 2 ] << 8 ) | m_vdp.vram[ tile_address + 3 ];
|
||||
} else {
|
||||
plane0 = m_vdp.vram[ tile_address + 0 ];
|
||||
plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
|
||||
plane2 = m_vdp.vram[ tile_address + 2 ] << 2;
|
||||
plane3 = m_vdp.vram[ tile_address + 3 ] << 3;
|
||||
}
|
||||
} else {
|
||||
tile_address = 0x2000 + ( tile_number * 16 ) + ( tile_line << 1 );
|
||||
if ( m_vdp.tile_packed ) {
|
||||
plane0 = ( m_vdp.vram[ tile_address + 0 ] << 8 ) | m_vdp.vram[ tile_address + 1 ];
|
||||
} else {
|
||||
plane0 = m_vdp.vram[ tile_address + 0 ];
|
||||
plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
|
||||
plane2 = 0;
|
||||
plane3 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for( x = 0; x < 8; x++ ) {
|
||||
int col;
|
||||
if ( m_vdp.tile_packed ) {
|
||||
if ( m_vdp.colors_16 ) {
|
||||
col = plane0 & 0x0F;
|
||||
plane0 = plane0 >> 4;
|
||||
} else {
|
||||
col = plane0 & 0x03;
|
||||
plane0 = plane0 >> 2;
|
||||
}
|
||||
} else {
|
||||
col = ( plane3 & 8 ) | ( plane2 & 4 ) | ( plane1 & 2 ) | ( plane0 & 1 );
|
||||
plane3 = plane3 >> 1;
|
||||
plane2 = plane2 >> 1;
|
||||
plane1 = plane1 >> 1;
|
||||
plane0 = plane0 >> 1;
|
||||
}
|
||||
if ( tile_data & 0x4000 ) {
|
||||
x_offset = x + ( column << 3 ) - ( m_vdp.layer_fg_scroll_x & 0x07 );
|
||||
} else {
|
||||
x_offset = 7 - x + ( column << 3 ) - ( m_vdp.layer_fg_scroll_x & 0x07 );
|
||||
}
|
||||
if ( ( x_offset >= 0 && x_offset < m_vdp.window_fg_left ) || ( x_offset >= m_vdp.window_fg_right && x_offset < WSWAN_X_PIXELS ) ) {
|
||||
if ( m_vdp.colors_16 ) {
|
||||
if ( col ) {
|
||||
if ( m_vdp.color_mode ) {
|
||||
m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
|
||||
} else {
|
||||
/* Hmmmm, what should we do here... Is this correct?? */
|
||||
m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( col || !(tile_palette & 4 ) ) {
|
||||
if ( m_vdp.color_mode ) {
|
||||
m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
|
||||
} else {
|
||||
m_bitmap.pix16(m_vdp.current_line, x_offset) = m_vdp.main_palette[m_pal[tile_palette][col]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wswan_state::wswan_handle_sprites(int mask )
|
||||
{
|
||||
int i;
|
||||
if ( m_vdp.sprite_count == 0 )
|
||||
return;
|
||||
for( i = m_vdp.sprite_first + m_vdp.sprite_count - 1; i >= m_vdp.sprite_first; i-- ) {
|
||||
UINT8 x, y;
|
||||
UINT16 tile_data;
|
||||
int tile_line;
|
||||
|
||||
tile_data = ( m_vdp.sprite_table_buffer[ i * 4 + 1 ] << 8 ) | m_vdp.sprite_table_buffer[ i * 4 ];
|
||||
y = m_vdp.sprite_table_buffer[ i * 4 + 2 ];
|
||||
x = m_vdp.sprite_table_buffer[ i * 4 + 3 ];
|
||||
tile_line = m_vdp.current_line - y;
|
||||
tile_line = tile_line & 0xFF;
|
||||
if ( ( tile_line >= 0 ) && ( tile_line < 8 ) && ( ( tile_data & 0x2000 ) == mask ) ) {
|
||||
UINT32 plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0;
|
||||
int j, x_offset, tile_address;
|
||||
int tile_number = tile_data & 0x01FF;
|
||||
int tile_palette = 8 + ( ( tile_data >> 9 ) & 0x07 );
|
||||
int check_clip = 0;
|
||||
if ( tile_data & 0x8000 ) {
|
||||
tile_line = 7 - tile_line;
|
||||
}
|
||||
|
||||
if ( m_vdp.colors_16 ) {
|
||||
tile_address = 0x4000 + ( tile_number * 32 ) + ( tile_line << 2 );
|
||||
if ( m_vdp.tile_packed ) {
|
||||
plane0 = ( m_vdp.vram[ tile_address + 0 ] << 24 ) | ( m_vdp.vram[ tile_address + 1 ] << 16 ) | ( m_vdp.vram[ tile_address + 2 ] << 8 ) | m_vdp.vram[ tile_address + 3 ];
|
||||
} else {
|
||||
plane0 = m_vdp.vram[ tile_address + 0 ];
|
||||
plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
|
||||
plane2 = m_vdp.vram[ tile_address + 2 ] << 2;
|
||||
plane3 = m_vdp.vram[ tile_address + 3 ] << 3;
|
||||
}
|
||||
} else {
|
||||
tile_address = 0x2000 + ( tile_number * 16 ) + ( tile_line << 1 );
|
||||
if ( m_vdp.tile_packed ) {
|
||||
plane0 = ( m_vdp.vram[ tile_address + 0 ] << 8 ) | m_vdp.vram[ tile_address + 1 ];
|
||||
} else {
|
||||
plane0 = m_vdp.vram[ tile_address + 0 ];
|
||||
plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
|
||||
plane2 = 0;
|
||||
plane3 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_vdp.window_sprites_enable ) {
|
||||
if ( tile_data & 0x1000 ) {
|
||||
if ( m_vdp.current_line >= m_vdp.window_sprites_top && m_vdp.current_line <= m_vdp.window_sprites_bottom ) {
|
||||
check_clip = 1;
|
||||
}
|
||||
} else {
|
||||
if ( m_vdp.current_line < m_vdp.window_sprites_top || m_vdp.current_line > m_vdp.window_sprites_bottom ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( j = 0; j < 8; j++ ) {
|
||||
int col;
|
||||
if ( m_vdp.tile_packed ) {
|
||||
if ( m_vdp.colors_16 ) {
|
||||
col = plane0 & 0x0F;
|
||||
plane0 = plane0 >> 4;
|
||||
} else {
|
||||
col = plane0 & 0x03;
|
||||
plane0 = plane0 >> 2;
|
||||
}
|
||||
} else {
|
||||
col = ( plane3 & 8 ) | ( plane2 & 4 ) | ( plane1 & 2 ) | ( plane0 & 1 );
|
||||
plane3 = plane3 >> 1;
|
||||
plane2 = plane2 >> 1;
|
||||
plane1 = plane1 >> 1;
|
||||
plane0 = plane0 >> 1;
|
||||
}
|
||||
if ( tile_data & 0x4000 ) {
|
||||
x_offset = x + j;
|
||||
} else {
|
||||
x_offset = x + 7 - j;
|
||||
}
|
||||
x_offset = x_offset & 0xFF;
|
||||
if ( m_vdp.window_sprites_enable ) {
|
||||
if ( tile_data & 0x1000 && check_clip ) {
|
||||
if ( x_offset >= m_vdp.window_sprites_left && x_offset <= m_vdp.window_sprites_right ) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if ( x_offset < m_vdp.window_sprites_left || x_offset > m_vdp.window_sprites_right ) {
|
||||
// continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( x_offset >= 0 && x_offset < WSWAN_X_PIXELS ) {
|
||||
if ( m_vdp.colors_16 ) {
|
||||
if ( col ) {
|
||||
if ( m_vdp.color_mode ) {
|
||||
m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
|
||||
} else {
|
||||
/* Hmmmm, what should we do here... Is this correct?? */
|
||||
m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( col || !(tile_palette & 4 ) ) {
|
||||
if ( m_vdp.color_mode ) {
|
||||
m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
|
||||
} else {
|
||||
m_bitmap.pix16(m_vdp.current_line, x_offset) = m_vdp.main_palette[m_pal[tile_palette][col]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wswan_state::wswan_refresh_scanline()
|
||||
{
|
||||
wswan_setup_palettes();
|
||||
|
||||
rectangle rec(0, WSWAN_X_PIXELS, m_vdp.current_line, m_vdp.current_line);
|
||||
if ( m_ws_portram[0x14] ) {
|
||||
/* Not sure if these background color checks and settings are correct */
|
||||
if ( m_vdp.color_mode && m_vdp.colors_16 ) {
|
||||
m_bitmap.fill( m_pal[m_ws_portram[0x01]>>4][m_ws_portram[0x01]&0x0F], rec );
|
||||
} else {
|
||||
m_bitmap.fill( m_vdp.main_palette[m_ws_portram[0x01]&0x07], rec );
|
||||
}
|
||||
} else {
|
||||
m_bitmap.fill( 0, rec );
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw background layer
|
||||
*/
|
||||
if ( m_vdp.layer_bg_enable ) {
|
||||
wswan_draw_background();
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw sprites between background and foreground layers
|
||||
*/
|
||||
if ( m_vdp.sprites_enable ) {
|
||||
wswan_handle_sprites(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw foreground layer, taking window settings into account
|
||||
*/
|
||||
if ( m_vdp.layer_fg_enable ) {
|
||||
switch( m_vdp.window_fg_mode ) {
|
||||
case 0: /* FG inside & outside window area */
|
||||
wswan_draw_foreground_0();
|
||||
break;
|
||||
case 1: /* ??? */
|
||||
logerror( "Unknown foreground mode 1 set\n" );
|
||||
break;
|
||||
case 2: /* FG only inside window area */
|
||||
if ( m_vdp.current_line >= m_vdp.window_fg_top && m_vdp.current_line <= m_vdp.window_fg_bottom ) {
|
||||
wswan_draw_foreground_2();
|
||||
}
|
||||
break;
|
||||
case 3: /* FG only outside window area */
|
||||
if ( m_vdp.current_line < m_vdp.window_fg_top || m_vdp.current_line > m_vdp.window_fg_bottom ) {
|
||||
wswan_draw_foreground_0();
|
||||
} else {
|
||||
wswan_draw_foreground_3();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw sprites in front of foreground layer
|
||||
*/
|
||||
if ( m_vdp.sprites_enable ) {
|
||||
wswan_handle_sprites(0x2000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void wswan_state::video_start()
|
||||
{
|
||||
machine().first_screen()->register_screen_bitmap(m_bitmap);
|
||||
save_item(NAME(m_bitmap));
|
||||
}
|
||||
|
||||
UINT32 wswan_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect);
|
||||
return 0;
|
||||
}
|
1211
src/mess/video/wswan_video.c
Normal file
1211
src/mess/video/wswan_video.c
Normal file
File diff suppressed because it is too large
Load Diff
147
src/mess/video/wswan_video.h
Normal file
147
src/mess/video/wswan_video.h
Normal file
@ -0,0 +1,147 @@
|
||||
/**********************************************************************
|
||||
|
||||
wswan.h
|
||||
|
||||
File to handle video emulation of the Bandai WonderSwan.
|
||||
|
||||
Anthony Kruize
|
||||
Wilbert Pol
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef __WSWAN_VIDEO__
|
||||
#define __WSWAN_VIDEO__
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
enum
|
||||
{
|
||||
VDP_TYPE_WSWAN = 0,
|
||||
VDP_TYPE_WSC
|
||||
};
|
||||
|
||||
#define WSWAN_X_PIXELS (28*8)
|
||||
#define WSWAN_Y_PIXELS (18*8)
|
||||
|
||||
|
||||
|
||||
typedef device_delegate<void (int irq)> wswan_video_irq_cb_delegate;
|
||||
#define WSWAN_VIDEO_IRQ_CB_MEMBER(_name) void _name(int irq)
|
||||
|
||||
typedef device_delegate<void (void)> wswan_video_dmasnd_cb_delegate;
|
||||
#define WSWAN_VIDEO_DMASND_CB_MEMBER(_name) void _name(void)
|
||||
|
||||
#define MCFG_WSWAN_VIDEO_IRQ_CB(_class, _method) \
|
||||
wswan_video_device::set_irq_callback(*device, wswan_video_irq_cb_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner)));
|
||||
|
||||
#define MCFG_WSWAN_VIDEO_DMASND_CB(_class, _method) \
|
||||
wswan_video_device::set_dmasnd_callback(*device, wswan_video_dmasnd_cb_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner)));
|
||||
|
||||
#define MCFG_WSWAN_VIDEO_TYPE( _type) \
|
||||
wswan_video_device::set_vdp_type(*device, _type);
|
||||
|
||||
|
||||
class wswan_video_device : public device_t
|
||||
{
|
||||
public:
|
||||
wswan_video_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
~wswan_video_device() {}
|
||||
|
||||
// static configuration
|
||||
static void set_irq_callback(device_t &device, wswan_video_irq_cb_delegate callback) { downcast<wswan_video_device &>(device).m_set_irq_cb = callback; }
|
||||
static void set_dmasnd_callback(device_t &device, wswan_video_dmasnd_cb_delegate callback) { downcast<wswan_video_device &>(device).m_snd_dma_cb = callback; }
|
||||
static void set_vdp_type(device_t &device, int type) { downcast<wswan_video_device &>(device).m_vdp_type = type; }
|
||||
|
||||
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(vram_r);
|
||||
virtual DECLARE_WRITE8_MEMBER(vram_w);
|
||||
virtual DECLARE_READ8_MEMBER(reg_r);
|
||||
virtual DECLARE_WRITE8_MEMBER(reg_w);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
|
||||
|
||||
void setup_palettes();
|
||||
void draw_background();
|
||||
void draw_foreground_0();
|
||||
void draw_foreground_2();
|
||||
void draw_foreground_3();
|
||||
void handle_sprites(int mask);
|
||||
void refresh_scanline();
|
||||
void scanline_interrupt();
|
||||
void common_save();
|
||||
|
||||
bitmap_ind16 m_bitmap;
|
||||
UINT8 m_layer_bg_enable; /* Background layer on/off */
|
||||
UINT8 m_layer_fg_enable; /* Foreground layer on/off */
|
||||
UINT8 m_sprites_enable; /* Sprites on/off */
|
||||
UINT8 m_window_sprites_enable; /* Sprite window on/off */
|
||||
UINT8 m_window_fg_mode; /* 0:inside/outside, 1:??, 2:inside, 3:outside */
|
||||
UINT8 m_bg_control;
|
||||
UINT8 m_current_line; /* Current scanline : 0-158 (159?) */
|
||||
UINT8 m_line_compare; /* Line to trigger line interrupt on */
|
||||
UINT32 m_sprite_table_address; /* Address of the sprite table */
|
||||
UINT8 m_sprite_table_buffer[512];
|
||||
UINT8 m_sprite_first; /* First sprite to draw */
|
||||
UINT8 m_sprite_count; /* Number of sprites to draw */
|
||||
UINT8 m_sprite_first_latch;
|
||||
UINT8 m_sprite_count_latch;
|
||||
UINT16 m_layer_bg_address; /* Address of the background screen map */
|
||||
UINT16 m_layer_fg_address; /* Address of the foreground screen map */
|
||||
UINT8 m_window_fg_left; /* Left coordinate of foreground window */
|
||||
UINT8 m_window_fg_top; /* Top coordinate of foreground window */
|
||||
UINT8 m_window_fg_right; /* Right coordinate of foreground window */
|
||||
UINT8 m_window_fg_bottom; /* Bottom coordinate of foreground window */
|
||||
UINT8 m_window_sprites_left; /* Left coordinate of sprites window */
|
||||
UINT8 m_window_sprites_top; /* Top coordinate of sprites window */
|
||||
UINT8 m_window_sprites_right; /* Right coordinate of sprites window */
|
||||
UINT8 m_window_sprites_bottom; /* Bottom coordinate of sprites window */
|
||||
UINT8 m_layer_bg_scroll_x; /* Background layer X scroll */
|
||||
UINT8 m_layer_bg_scroll_y; /* Background layer Y scroll */
|
||||
UINT8 m_layer_fg_scroll_x; /* Foreground layer X scroll */
|
||||
UINT8 m_layer_fg_scroll_y; /* Foreground layer Y scroll */
|
||||
UINT8 m_lcd_control; /* LCD on/off */
|
||||
UINT8 m_icons; /* FIXME: What do we do with these? Maybe artwork? */
|
||||
UINT8 m_color_mode; /* monochrome/color mode */
|
||||
UINT8 m_colors_16; /* 4/16 colors mode */
|
||||
UINT8 m_tile_packed; /* layered/packed tile mode switch */
|
||||
UINT8 m_timer_hblank_enable; /* Horizontal blank interrupt on/off */
|
||||
UINT8 m_timer_hblank_mode; /* Horizontal blank timer mode */
|
||||
UINT16 m_timer_hblank_reload; /* Horizontal blank timer reload value */
|
||||
UINT16 m_timer_hblank_count; /* Horizontal blank timer counter value */
|
||||
UINT8 m_timer_vblank_enable; /* Vertical blank interrupt on/off */
|
||||
UINT8 m_timer_vblank_mode; /* Vertical blank timer mode */
|
||||
UINT16 m_timer_vblank_reload; /* Vertical blank timer reload value */
|
||||
UINT16 m_timer_vblank_count; /* Vertical blank timer counter value */
|
||||
int m_main_palette[8];
|
||||
emu_timer *m_timer;
|
||||
|
||||
dynamic_buffer m_vram;
|
||||
UINT8 *m_palette_vram;
|
||||
UINT8 m_palette_port[0x20];
|
||||
int m_pal[16][16];
|
||||
UINT8 m_regs[256];
|
||||
|
||||
wswan_video_irq_cb_delegate m_set_irq_cb;
|
||||
wswan_video_dmasnd_cb_delegate m_snd_dma_cb;
|
||||
int m_vdp_type;
|
||||
|
||||
// timer IDs
|
||||
static const device_timer_id TIMER_SCANLINE = 0;
|
||||
|
||||
// interrupt flags
|
||||
// these are the same as the wswan.h ones
|
||||
static const UINT8 WSWAN_VIDEO_IFLAG_LCMP = 0x10;
|
||||
static const UINT8 WSWAN_VIDEO_IFLAG_VBLTMR = 0x20;
|
||||
static const UINT8 WSWAN_VIDEO_IFLAG_VBL = 0x40;
|
||||
static const UINT8 WSWAN_VIDEO_IFLAG_HBLTMR = 0x80;
|
||||
};
|
||||
|
||||
extern const device_type WSWAN_VIDEO;
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user