(MESS) wswan: converted the video chip to be a device. nw.

This commit is contained in:
etabeta78 2014-10-28 14:18:33 +01:00
parent 31fd590aa6
commit e6a5e406bf
7 changed files with 1657 additions and 1422 deletions

View File

@ -35,14 +35,14 @@
#include "wswan.lh" #include "wswan.lh"
static ADDRESS_MAP_START (wswan_mem, AS_PROGRAM, 8, wswan_state) 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(0x04000, 0x0ffff) AM_NOP // nothing
//AM_RANGE(0x10000, 0xeffff) // cart range, setup at machine_start //AM_RANGE(0x10000, 0xeffff) // cart range, setup at machine_start
AM_RANGE(0xf0000, 0xfffff) AM_READ(bios_r) AM_RANGE(0xf0000, 0xfffff) AM_READ(bios_r)
ADDRESS_MAP_END ADDRESS_MAP_END
static ADDRESS_MAP_START (wscolor_mem, AS_PROGRAM, 8, wswan_state) 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(0x10000, 0xeffff) // cart range, setup at machine_start
AM_RANGE(0xf0000, 0xfffff) AM_READ(bios_r) AM_RANGE(0xf0000, 0xfffff) AM_READ(bios_r)
ADDRESS_MAP_END 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++) for (int i = 0; i < 4096; i++)
{ {
@ -106,11 +106,16 @@ static MACHINE_CONFIG_START( wswan, wswan_state )
MCFG_CPU_PROGRAM_MAP(wswan_mem) MCFG_CPU_PROGRAM_MAP(wswan_mem)
MCFG_CPU_IO_MAP(wswan_io) 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_ADD("screen", LCD)
MCFG_SCREEN_REFRESH_RATE(75) MCFG_SCREEN_REFRESH_RATE(75)
MCFG_SCREEN_VBLANK_TIME(0) MCFG_SCREEN_VBLANK_TIME(0)
MCFG_SCREEN_UPDATE_DRIVER(wswan_state, screen_update) MCFG_SCREEN_UPDATE_DEVICE("vdp", wswan_video_device, screen_update)
MCFG_SCREEN_SIZE( WSWAN_X_PIXELS, WSWAN_Y_PIXELS ) 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_VISIBLE_AREA(0*8, WSWAN_X_PIXELS - 1, 0, WSWAN_Y_PIXELS - 1)
MCFG_SCREEN_PALETTE("palette") MCFG_SCREEN_PALETTE("palette")
@ -141,11 +146,14 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( wscolor, wswan ) static MACHINE_CONFIG_DERIVED( wscolor, wswan )
MCFG_CPU_MODIFY("maincpu") MCFG_CPU_MODIFY("maincpu")
MCFG_CPU_PROGRAM_MAP(wscolor_mem) 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_MODIFY("palette")
MCFG_PALETTE_ENTRIES(4096) MCFG_PALETTE_ENTRIES(4096)
MCFG_PALETTE_INIT_OWNER(wswan_state, wscolor ) MCFG_PALETTE_INIT_OWNER(wswan_state, wscolor)
/* software lists */ /* software lists */
MCFG_DEVICE_REMOVE("cart_list") MCFG_DEVICE_REMOVE("cart_list")

View File

@ -10,15 +10,13 @@
#define WSWAN_TYPE_MONO 0 #define WSWAN_TYPE_MONO 0
#define WSWAN_TYPE_COLOR 1 #define WSWAN_TYPE_COLOR 1
#define WSWAN_X_PIXELS (28*8)
#define WSWAN_Y_PIXELS (18*8)
#define INTERNAL_EEPROM_SIZE 1024 #define INTERNAL_EEPROM_SIZE 1024
#include "emu.h" #include "emu.h"
#include "cpu/v30mz/v30mz.h" #include "cpu/v30mz/v30mz.h"
#include "audio/wswan_snd.h"
#include "machine/nvram.h" #include "machine/nvram.h"
#include "audio/wswan_snd.h"
#include "video/wswan_video.h"
#include "bus/wswan/slot.h" #include "bus/wswan/slot.h"
#include "bus/wswan/rom.h" #include "bus/wswan/rom.h"
@ -30,52 +28,6 @@ struct SoundDMA
UINT8 enable; /* Enabled */ 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 class wswan_state : public driver_device
{ {
@ -83,43 +35,38 @@ public:
wswan_state(const machine_config &mconfig, device_type type, const char *tag) wswan_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag), : driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"), m_maincpu(*this, "maincpu"),
m_vdp(*this, "vdp"),
m_sound(*this, "custom"), m_sound(*this, "custom"),
m_cart(*this, "cartslot"), m_cart(*this, "cartslot"),
m_cursx(*this, "CURSX"), m_cursx(*this, "CURSX"),
m_cursy(*this, "CURSY"), m_cursy(*this, "CURSY"),
m_buttons(*this, "BUTTONS") { } m_buttons(*this, "BUTTONS")
{ }
virtual void video_start();
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
required_device<cpu_device> m_maincpu; required_device<cpu_device> m_maincpu;
required_device<wswan_video_device> m_vdp;
required_device<wswan_sound_device> m_sound; required_device<wswan_sound_device> m_sound;
required_device<ws_cart_slot_device> m_cart; required_device<ws_cart_slot_device> m_cart;
DECLARE_READ8_MEMBER(bios_r); DECLARE_READ8_MEMBER(bios_r);
DECLARE_READ8_MEMBER(port_r); DECLARE_READ8_MEMBER(port_r);
DECLARE_WRITE8_MEMBER(port_w); DECLARE_WRITE8_MEMBER(port_w);
VDP m_vdp;
UINT8 m_ws_portram[256]; UINT8 m_ws_portram[256];
UINT8 m_internal_eeprom[INTERNAL_EEPROM_SIZE]; UINT8 m_internal_eeprom[INTERNAL_EEPROM_SIZE];
UINT8 m_system_type; UINT8 m_system_type;
SoundDMA m_sound_dma; SoundDMA m_sound_dma;
UINT8 *m_ws_ram;
UINT8 *m_ws_bios_bank; UINT8 *m_ws_bios_bank;
UINT8 m_bios_disabled; UINT8 m_bios_disabled;
int m_pal[16][16];
bitmap_ind16 m_bitmap;
UINT8 m_rotate; UINT8 m_rotate;
void wswan_clear_irq_line(int irq); void set_irq_line(int irq);
void dma_sound_cb();
void common_start(); void common_start();
virtual void machine_start(); virtual void machine_start();
virtual void machine_reset(); virtual void machine_reset();
DECLARE_PALETTE_INIT(wswan); DECLARE_PALETTE_INIT(wswan);
DECLARE_MACHINE_START(wscolor); DECLARE_MACHINE_START(wscolor);
DECLARE_PALETTE_INIT(wscolor); DECLARE_PALETTE_INIT(wscolor);
TIMER_CALLBACK_MEMBER(wswan_scanline_interrupt);
protected: protected:
/* Interrupt flags */ /* Interrupt flags */
@ -146,17 +93,9 @@ protected:
required_ioport m_cursy; required_ioport m_cursy;
required_ioport m_buttons; required_ioport m_buttons;
void wswan_register_save(); void register_save();
void wswan_postload(); void handle_irqs();
void wswan_handle_irqs(); void clear_irq_line(int irq);
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( );
}; };

View File

@ -78,123 +78,90 @@ static const UINT8 ws_fake_bios_code[] = {
0xea, 0xc0, 0xff, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0xea, 0xc0, 0xff, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
void wswan_state::wswan_handle_irqs() void wswan_state::handle_irqs()
{ {
if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_HBLTMR ) if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_HBLTMR)
{ {
m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_HBLTMR ); m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_HBLTMR);
} }
else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_VBL ) else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_VBL)
{ {
m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_VBL ); m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_VBL);
} }
else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_VBLTMR ) else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_VBLTMR)
{ {
m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_VBLTMR ); m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_VBLTMR);
} }
else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_LCMP ) else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_LCMP)
{ {
m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_LCMP ); m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_LCMP);
} }
else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_SRX ) else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_SRX)
{ {
m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_SRX ); m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_SRX);
} }
else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_RTC ) else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_RTC)
{ {
m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_RTC ); m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_RTC);
} }
else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_KEY ) else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_KEY)
{ {
m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_KEY ); m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_KEY);
} }
else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_STX ) else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_STX)
{ {
m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_STX ); m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_STX);
} }
else else
{ {
m_maincpu->set_input_line(0, CLEAR_LINE ); m_maincpu->set_input_line(0, CLEAR_LINE);
} }
} }
void wswan_state::wswan_set_irq_line(int irq) void wswan_state::set_irq_line(int irq)
{ {
if ( m_ws_portram[0xb2] & irq ) if (m_ws_portram[0xb2] & irq)
{ {
m_ws_portram[0xb6] |= irq; m_ws_portram[0xb6] |= irq;
wswan_handle_irqs(); handle_irqs();
} }
} }
void wswan_state::wswan_clear_irq_line(int irq) void wswan_state::dma_sound_cb()
{ {
m_ws_portram[0xb6] &= ~irq; if ((m_sound_dma.enable & 0x88) == 0x80)
wswan_handle_irqs(); {
address_space &space = m_maincpu->space(AS_PROGRAM);
/* TODO: Output sound DMA byte */
port_w(space, 0x89, space.read_byte(m_sound_dma.source));
m_sound_dma.size--;
m_sound_dma.source = (m_sound_dma.source + 1) & 0x0fffff;
if (m_sound_dma.size == 0)
{
m_sound_dma.enable &= 0x7F;
}
}
} }
void wswan_state::wswan_register_save() void wswan_state::clear_irq_line(int irq)
{
m_ws_portram[0xb6] &= ~irq;
handle_irqs();
}
void wswan_state::register_save()
{ {
save_item(NAME(m_ws_portram)); save_item(NAME(m_ws_portram));
save_item(NAME(m_internal_eeprom)); save_item(NAME(m_internal_eeprom));
save_item(NAME(m_bios_disabled)); save_item(NAME(m_bios_disabled));
save_item(NAME(m_rotate)); save_item(NAME(m_rotate));
save_item(NAME(m_vdp.layer_bg_enable));
save_item(NAME(m_vdp.layer_fg_enable));
save_item(NAME(m_vdp.sprites_enable));
save_item(NAME(m_vdp.window_sprites_enable));
save_item(NAME(m_vdp.window_fg_mode));
save_item(NAME(m_vdp.current_line));
save_item(NAME(m_vdp.line_compare));
save_item(NAME(m_vdp.sprite_table_address));
save_item(NAME(m_vdp.sprite_table_buffer));
save_item(NAME(m_vdp.sprite_first));
save_item(NAME(m_vdp.sprite_count));
save_item(NAME(m_vdp.layer_bg_address));
save_item(NAME(m_vdp.layer_fg_address));
save_item(NAME(m_vdp.window_fg_left));
save_item(NAME(m_vdp.window_fg_top));
save_item(NAME(m_vdp.window_fg_right));
save_item(NAME(m_vdp.window_fg_bottom));
save_item(NAME(m_vdp.window_sprites_left));
save_item(NAME(m_vdp.window_sprites_top));
save_item(NAME(m_vdp.window_sprites_right));
save_item(NAME(m_vdp.window_sprites_bottom));
save_item(NAME(m_vdp.layer_bg_scroll_x));
save_item(NAME(m_vdp.layer_bg_scroll_y));
save_item(NAME(m_vdp.layer_fg_scroll_x));
save_item(NAME(m_vdp.layer_fg_scroll_y));
save_item(NAME(m_vdp.lcd_enable));
save_item(NAME(m_vdp.icons));
save_item(NAME(m_vdp.color_mode));
save_item(NAME(m_vdp.colors_16));
save_item(NAME(m_vdp.tile_packed));
save_item(NAME(m_vdp.timer_hblank_enable));
save_item(NAME(m_vdp.timer_hblank_mode));
save_item(NAME(m_vdp.timer_hblank_reload));
save_item(NAME(m_vdp.timer_vblank_enable));
save_item(NAME(m_vdp.timer_vblank_mode));
save_item(NAME(m_vdp.timer_vblank_reload));
save_item(NAME(m_vdp.timer_vblank_count));
save_item(NAME(m_vdp.main_palette));
save_item(NAME(m_sound_dma.source)); save_item(NAME(m_sound_dma.source));
save_item(NAME(m_sound_dma.size)); save_item(NAME(m_sound_dma.size));
save_item(NAME(m_sound_dma.enable)); save_item(NAME(m_sound_dma.enable));
if (m_cart->exists()) if (m_cart->exists())
m_cart->save_nvram(); m_cart->save_nvram();
machine().save().register_postload(save_prepost_delegate(FUNC(wswan_state::wswan_postload), this));
}
void wswan_state::wswan_postload()
{
address_space &space = m_maincpu->space(AS_PROGRAM);
// restore the vdp pointers
m_vdp.vram = (UINT8*)space.get_read_ptr(0);
m_vdp.palette_vram = (UINT8*)space.get_read_ptr((m_system_type == TYPE_WSC) ? 0xfe00 : 0);
} }
void wswan_state::common_start() void wswan_state::common_start()
@ -202,10 +169,7 @@ void wswan_state::common_start()
m_ws_bios_bank = auto_alloc_array(machine(), UINT8, 0x10000); m_ws_bios_bank = auto_alloc_array(machine(), UINT8, 0x10000);
memcpy(m_ws_bios_bank + 0xffc0, ws_fake_bios_code, 0x40); memcpy(m_ws_bios_bank + 0xffc0, ws_fake_bios_code, 0x40);
m_vdp.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(wswan_state::wswan_scanline_interrupt),this), &m_vdp); register_save();
m_vdp.timer->adjust(attotime::from_ticks(256, 3072000), 0, attotime::from_ticks(256, 3072000));
wswan_register_save();
machine().device<nvram_device>("nvram")->set_base(m_internal_eeprom, INTERNAL_EEPROM_SIZE); machine().device<nvram_device>("nvram")->set_base(m_internal_eeprom, INTERNAL_EEPROM_SIZE);
@ -231,7 +195,7 @@ void wswan_state::machine_start()
m_system_type = TYPE_WSWAN; m_system_type = TYPE_WSWAN;
} }
MACHINE_START_MEMBER(wswan_state,wscolor) MACHINE_START_MEMBER(wswan_state, wscolor)
{ {
common_start(); common_start();
m_system_type = TYPE_WSC; m_system_type = TYPE_WSC;
@ -239,13 +203,8 @@ MACHINE_START_MEMBER(wswan_state,wscolor)
void wswan_state::machine_reset() void wswan_state::machine_reset()
{ {
address_space &space = m_maincpu->space(AS_PROGRAM);
m_bios_disabled = 0; m_bios_disabled = 0;
m_ws_ram = (UINT8*) m_maincpu->space(AS_PROGRAM).get_read_ptr(0);
memset(m_ws_ram, 0, 0xffff);
if (m_cart->exists()) if (m_cart->exists())
m_rotate = m_cart->get_is_rotated(); m_rotate = m_cart->get_is_rotated();
else else
@ -254,16 +213,6 @@ void wswan_state::machine_reset()
/* Intialize ports */ /* Intialize ports */
memcpy(m_ws_portram, ws_portram_init, 256); memcpy(m_ws_portram, ws_portram_init, 256);
/* Initialize VDP */
memset(&m_vdp, 0, sizeof(m_vdp));
m_vdp.vram = (UINT8*)space.get_read_ptr(0);
m_vdp.palette_vram = (UINT8*)space.get_read_ptr(( m_system_type == TYPE_WSC ) ? 0xFE00 : 0 );
m_vdp.current_line = 145; /* Randomly chosen, beginning of VBlank period to give cart some time to boot up */
m_vdp.color_mode = 0;
m_vdp.colors_16 = 0;
m_vdp.tile_packed = 0;
render_target *target = machine().render().first_target(); render_target *target = machine().render().first_target();
target->set_view(m_rotate); target->set_view(m_rotate);
@ -285,11 +234,12 @@ READ8_MEMBER( wswan_state::port_r )
if (offset != 2) if (offset != 2)
logerror("PC=%X: port read %02X\n", m_maincpu->pc(), offset); logerror("PC=%X: port read %02X\n", m_maincpu->pc(), offset);
if (offset < 0x40 || (offset >= 0xa1 && offset < 0xb0))
return m_vdp->reg_r(space, offset);
switch (offset) switch (offset)
{ {
case 0x02: // Current line
value = m_vdp.current_line;
break;
case 0x4a: // Sound DMA source address (low) case 0x4a: // Sound DMA source address (low)
value = m_sound_dma.source & 0xff; value = m_sound_dma.source & 0xff;
break; break;
@ -308,6 +258,9 @@ READ8_MEMBER( wswan_state::port_r )
case 0x52: // Sound DMA start/stop case 0x52: // Sound DMA start/stop
value = m_sound_dma.enable; value = m_sound_dma.enable;
break; break;
case 0x60:
value = m_vdp->reg_r(space, offset);
break;
case 0xa0: // Hardware type case 0xa0: // Hardware type
// Bit 0 - Disable/enable Bios // Bit 0 - Disable/enable Bios
// Bit 1 - Determine mono/color // Bit 1 - Determine mono/color
@ -316,18 +269,6 @@ READ8_MEMBER( wswan_state::port_r )
if (m_system_type == TYPE_WSC) if (m_system_type == TYPE_WSC)
value |= 2; value |= 2;
break; break;
case 0xa8:
value = m_vdp.timer_hblank_count & 0xff;
break;
case 0xa9:
value = m_vdp.timer_hblank_count >> 8;
break;
case 0xaa:
value = m_vdp.timer_vblank_count & 0xff;
break;
case 0xab:
value = m_vdp.timer_vblank_count >> 8;
break;
case 0xc0: case 0xc0:
case 0xc1: case 0xc1:
case 0xc2: case 0xc2:
@ -356,285 +297,15 @@ WRITE8_MEMBER( wswan_state::port_w )
address_space &mem = m_maincpu->space(AS_PROGRAM); address_space &mem = m_maincpu->space(AS_PROGRAM);
UINT8 input; UINT8 input;
logerror("PC=%X: port write %02X <- %02X\n", m_maincpu->pc(), offset, data); logerror("PC=%X: port write %02X <- %02X\n", m_maincpu->pc(), offset, data);
if (offset < 0x40 || (offset >= 0xa1 && offset < 0xb0))
{
m_vdp->reg_w(space, offset, data);
return;
}
switch (offset) switch (offset)
{ {
case 0x00: /* Display control
Bit 0 - Background layer enable
Bit 1 - Foreground layer enable
Bit 2 - Sprites enable
Bit 3 - Sprite window enable
Bit 4-5 - Foreground window configuration
00 - Foreground layer is displayed inside and outside foreground window area
01 - Unknown
10 - Foreground layer is displayed only inside foreground window area
11 - Foreground layer is displayed outside foreground window area
Bit 6-7 - Unknown
*/
m_vdp.layer_bg_enable = data & 0x1;
m_vdp.layer_fg_enable = (data & 0x2) >> 1;
m_vdp.sprites_enable = (data & 0x4) >> 2;
m_vdp.window_sprites_enable = (data & 0x8) >> 3;
m_vdp.window_fg_mode = (data & 0x30) >> 4;
break;
case 0x01: /* Background colour
In 16 colour mode:
Bit 0-3 - Palette index
Bit 4-7 - Palette number
Otherwise:
Bit 0-2 - Main palette index
Bit 3-7 - Unknown
*/
break;
case 0x02: /* Current scanline
Bit 0-7 - Current scanline (Most likely read-only)
*/
logerror( "Write to current scanline! Current value: %d Data to write: %d\n", m_vdp.current_line, data );
/* Returning so we don't overwrite the value here, not that it
* really matters */
return;
case 0x03: /* Line compare
Bit 0-7 - Line compare
*/
m_vdp.line_compare = data;
logerror( "Write to line compare: %d\n", data );
break;
case 0x04: /* Sprite table base address
Bit 0-5 - Determine sprite table base address 0 0xxxxxx0 00000000
Bit 6-7 - Unknown
*/
m_vdp.sprite_table_address = ( data & 0x3F ) << 9;
break;
case 0x05: /* Number of sprite to start drawing with
Bit 0-7 - First sprite number
*/
//m_vdp.sprite_first = data;
if (data) logerror("non-zero first sprite %d\n", m_vdp.sprite_first);
break;
case 0x06: /* Number of sprites to draw
Bit 0-7 - Number of sprites to draw
*/
//m_vdp.sprite_count = data;
break;
case 0x07: /* Background/Foreground table base addresses
Bit 0-2 - Determine background table base address 00xxx000 00000000
Bit 3 - Unknown
Bit 4-6 - Determine foreground table base address 00xxx000 00000000
Bit 7 - Unknown
*/
m_vdp.layer_bg_address = (data & 0x7) << 11;
m_vdp.layer_fg_address = (data & 0x70) << 7;
break;
case 0x08: /* Left coordinate of foreground window
Bit 0-7 - Left coordinate of foreground window area
*/
m_vdp.window_fg_left = data;
break;
case 0x09: /* Top coordinate of foreground window
Bit 0-7 - Top coordinatte of foreground window area
*/
m_vdp.window_fg_top = data;
break;
case 0x0a: /* Right coordinate of foreground window
Bit 0-7 - Right coordinate of foreground window area
*/
m_vdp.window_fg_right = data;
break;
case 0x0b: /* Bottom coordinate of foreground window
Bit 0-7 - Bottom coordinate of foreground window area
*/
m_vdp.window_fg_bottom = data;
break;
case 0x0c: /* Left coordinate of sprite window
Bit 0-7 - Left coordinate of sprite window area
*/
m_vdp.window_sprites_left = data;
break;
case 0x0d: /* Top coordinate of sprite window
Bit 0-7 - Top coordinate of sprite window area
*/
m_vdp.window_sprites_top = data;
break;
case 0x0e: /* Right coordinate of sprite window
Bit 0-7 - Right coordinate of sprite window area
*/
m_vdp.window_sprites_right = data;
break;
case 0x0f: /* Bottom coordinate of sprite window
Bit 0-7 - Bottom coordiante of sprite window area
*/
m_vdp.window_sprites_bottom = data;
break;
case 0x10: /* Background layer X scroll
Bit 0-7 - Background layer X scroll
*/
m_vdp.layer_bg_scroll_x = data;
break;
case 0x11: /* Background layer Y scroll
Bit 0-7 - Background layer Y scroll
*/
m_vdp.layer_bg_scroll_y = data;
break;
case 0x12: /* Foreground layer X scroll
Bit 0-7 - Foreground layer X scroll
*/
m_vdp.layer_fg_scroll_x = data;
break;
case 0x13: /* Foreground layer Y scroll
Bit 0-7 - Foreground layer Y scroll
*/
m_vdp.layer_fg_scroll_y = data;
break;
case 0x14: /* LCD control
Bit 0 - LCD enable
Bit 1-7 - Unknown
*/
m_vdp.lcd_enable = data & 0x1;
break;
case 0x15: /* LCD icons
Bit 0 - LCD sleep icon enable
Bit 1 - Vertical position icon enable
Bit 2 - Horizontal position icon enable
Bit 3 - Dot 1 icon enable
Bit 4 - Dot 2 icon enable
Bit 5 - Dot 3 icon enable
Bit 6-7 - Unknown
*/
m_vdp.icons = data; /* ummmmm */
break;
case 0x1c: /* Palette colors 0 and 1
Bit 0-3 - Gray tone setting for main palette index 0
Bit 4-7 - Gray tone setting for main palette index 1
*/
if (m_system_type == TYPE_WSC)
{
int i = 15 - ( data & 0x0F );
int j = 15 - ( ( data & 0xF0 ) >> 4 );
m_vdp.main_palette[0] = ( i << 8 ) | ( i << 4 ) | i;
m_vdp.main_palette[1] = ( j << 8 ) | ( j << 4 ) | j;
}
else
{
m_vdp.main_palette[0] = data & 0x0F;
m_vdp.main_palette[1] = ( data & 0xF0 ) >> 4;
}
break;
case 0x1d: /* Palette colors 2 and 3
Bit 0-3 - Gray tone setting for main palette index 2
Bit 4-7 - Gray tone setting for main palette index 3
*/
if (m_system_type == TYPE_WSC)
{
int i = 15 - ( data & 0x0F );
int j = 15 - ( ( data & 0xF0 ) >> 4 );
m_vdp.main_palette[2] = ( i << 8 ) | ( i << 4 ) | i;
m_vdp.main_palette[3] = ( j << 8 ) | ( j << 4 ) | j;
}
else
{
m_vdp.main_palette[2] = data & 0x0F;
m_vdp.main_palette[3] = ( data & 0xF0 ) >> 4;
}
break;
case 0x1e: /* Palette colors 4 and 5
Bit 0-3 - Gray tone setting for main palette index 4
Bit 4-7 - Gray tone setting for main paeltte index 5
*/
if (m_system_type == TYPE_WSC)
{
int i = 15 - ( data & 0x0F );
int j = 15 - ( ( data & 0xF0 ) >> 4 );
m_vdp.main_palette[4] = ( i << 8 ) | ( i << 4 ) | i;
m_vdp.main_palette[5] = ( j << 8 ) | ( j << 4 ) | j;
}
else
{
m_vdp.main_palette[4] = data & 0x0F;
m_vdp.main_palette[5] = ( data & 0xF0 ) >> 4;
}
break;
case 0x1f: /* Palette colors 6 and 7
Bit 0-3 - Gray tone setting for main palette index 6
Bit 4-7 - Gray tone setting for main palette index 7
*/
if (m_system_type == TYPE_WSC)
{
int i = 15 - ( data & 0x0F );
int j = 15 - ( ( data & 0xF0 ) >> 4 );
m_vdp.main_palette[6] = ( i << 8 ) | ( i << 4 ) | i;
m_vdp.main_palette[7] = ( j << 8 ) | ( j << 4 ) | j;
}
else
{
m_vdp.main_palette[6] = data & 0x0F;
m_vdp.main_palette[7] = ( data & 0xF0 ) >> 4;
}
break;
case 0x20: /* tile/sprite palette settings
Bit 0-3 - Palette 0 index 0
Bit 4-7 - Palette 0 index 1 */
case 0x21: /* Bit 0-3 - Palette 0 index 2
Bit 4-7 - Palette 0 index 3 */
case 0x22: /* Bit 0-3 - Palette 1 index 0
Bit 4-7 - Palette 1 index 1 */
case 0x23: /* Bit 0-3 - Palette 1 index 2
Bit 4-7 - Palette 1 index 3 */
case 0x24: /* Bit 0-3 - Palette 2 index 0
Bit 4-7 - Palette 2 index 1 */
case 0x25: /* Bit 0-3 - Palette 2 index 2
Bit 4-7 - Palette 2 index 3 */
case 0x26: /* Bit 0-3 - Palette 3 index 0
Bit 4-7 - Palette 3 index 1 */
case 0x27: /* Bit 0-3 - Palette 3 index 2
Bit 4-7 - Palette 3 index 3 */
case 0x28: /* Bit 0-3 - Palette 4 index 0
Bit 4-7 - Palette 4 index 1 */
case 0x29: /* Bit 0-3 - Palette 4 index 2
Bit 4-7 - Palette 4 index 3 */
case 0x2a: /* Bit 0-3 - Palette 5 index 0
Bit 4-7 - Palette 5 index 1 */
case 0x2b: /* Bit 0-3 - Palette 5 index 2
Bit 4-7 - Palette 5 index 3 */
case 0x2c: /* Bit 0-3 - Palette 6 index 0
Bit 4-7 - Palette 6 index 1 */
case 0x2d: /* Bit 0-3 - Palette 6 index 2
Bit 4-7 - Palette 6 index 3 */
case 0x2e: /* Bit 0-3 - Palette 7 index 0
Bit 4-7 - Palette 7 index 1 */
case 0x2f: /* Bit 0-3 - Palette 7 index 2
Bit 4-7 - Palette 7 index 3 */
case 0x30: /* Bit 0-3 - Palette 8 / Sprite Palette 0 index 0
Bit 4-7 - Palette 8 / Sprite Palette 0 index 1 */
case 0x31: /* Bit 0-3 - Palette 8 / Sprite Palette 0 index 2
Bit 4-7 - Palette 8 / Sprite Palette 0 index 3 */
case 0x32: /* Bit 0-3 - Palette 9 / Sprite Palette 1 index 0
Bit 4-7 - Palette 9 / Sprite Palette 1 index 1 */
case 0x33: /* Bit 0-3 - Palette 9 / Sprite Palette 1 index 2
Bit 4-7 - Palette 9 / Sprite Palette 1 index 3 */
case 0x34: /* Bit 0-3 - Palette 10 / Sprite Palette 2 index 0
Bit 4-7 - Palette 10 / Sprite Palette 2 index 1 */
case 0x35: /* Bit 0-3 - Palette 10 / Sprite Palette 2 index 2
Bit 4-7 - Palette 10 / Sprite Palette 2 index 3 */
case 0x36: /* Bit 0-3 - Palette 11 / Sprite Palette 3 index 0
Bit 4-7 - Palette 11 / Sprite Palette 3 index 1 */
case 0x37: /* Bit 0-3 - Palette 11 / Sprite Palette 3 index 2
Bit 4-7 - Palette 11 / Sprite Palette 3 index 3 */
case 0x38: /* Bit 0-3 - Palette 12 / Sprite Palette 4 index 0
Bit 4-7 - Palette 12 / Sprite Palette 4 index 1 */
case 0x39: /* Bit 0-3 - Palette 12 / Sprite Palette 4 index 2
Bit 4-7 - Palette 12 / Sprite Palette 4 index 3 */
case 0x3a: /* Bit 0-3 - Palette 13 / Sprite Palette 5 index 0
Bit 4-7 - Palette 13 / Sprite Palette 5 index 1 */
case 0x3b: /* Bit 0-3 - Palette 13 / Sprite Palette 5 index 2
Bit 4-7 - Palette 13 / Sprite Palette 5 index 3 */
case 0x3c: /* Bit 0-3 - Palette 14 / Sprite Palette 6 index 0
Bit 4-7 - Palette 14 / Sprite Palette 6 index 1 */
case 0x3d: /* Bit 0-3 - Palette 14 / Sprite Palette 6 index 2
Bit 4-7 - Palette 14 / Sprite Palette 6 index 3 */
case 0x3e: /* Bit 0-3 - Palette 15 / Sprite Palette 7 index 0
Bit 4-7 - Palette 15 / Sprite Palette 7 index 1 */
case 0x3f: /* Bit 0-3 - Palette 15 / Sprite Palette 7 index 2
Bit 4-7 - Palette 15 / Sprite Palette 7 index 3 */
break;
case 0x40: /* DMA source address (low) case 0x40: /* DMA source address (low)
Bit 0-7 - DMA source address bit 0-7 Bit 0-7 - DMA source address bit 0-7
*/ */
@ -727,28 +398,8 @@ WRITE8_MEMBER( wswan_state::port_w )
*/ */
m_sound_dma.enable = data; m_sound_dma.enable = data;
break; break;
case 0x60: /* Video mode case 0x60:
Bit 0-4 - Unknown m_vdp->reg_w(space, offset, data);
Bit 5 - Packed mode 0 = not packed mode, 1 = packed mode
Bit 6 - 4/16 colour mode select: 0 = 4 colour mode, 1 = 16 colour mode
Bit 7 - monochrome/colour mode select: 0 = monochrome mode, 1 = colour mode
*/
/*
* 111 - packed, 16 color, use 4000/8000, color
* 110 - not packed, 16 color, use 4000/8000, color
* 101 - packed, 4 color, use 2000, color
* 100 - not packed, 4 color, use 2000, color
* 011 - packed, 16 color, use 4000/8000, monochrome
* 010 - not packed, 16 color , use 4000/8000, monochrome
* 001 - packed, 4 color, use 2000, monochrome
* 000 - not packed, 4 color, use 2000, monochrome - Regular WS monochrome
*/
if (m_system_type == TYPE_WSC)
{
m_vdp.color_mode = data & 0x80;
m_vdp.colors_16 = data & 0x40;
m_vdp.tile_packed = data & 0x20;
}
break; break;
case 0x80: /* Audio 1 freq (lo) case 0x80: /* Audio 1 freq (lo)
Bit 0-7 - Audio channel 1 frequency bit 0-7 Bit 0-7 - Audio channel 1 frequency bit 0-7
@ -843,59 +494,6 @@ WRITE8_MEMBER( wswan_state::port_w )
if ((data & 0x01) && !m_bios_disabled) if ((data & 0x01) && !m_bios_disabled)
m_bios_disabled = 1; m_bios_disabled = 1;
break; break;
case 0xa2: /* Timer control
Bit 0 - HBlank Timer enable
Bit 1 - HBlank Timer mode: 0 = one shot, 1 = auto reset
Bit 2 - VBlank Timer(1/75s) enable
Bit 3 - VBlank Timer mode: 0 = one shot, 1 = auto reset
Bit 4-7 - Unknown
*/
m_vdp.timer_hblank_enable = BIT(data, 0);
m_vdp.timer_hblank_mode = BIT(data, 1);
m_vdp.timer_vblank_enable = BIT(data, 2);
m_vdp.timer_vblank_mode = BIT(data, 3);
break;
case 0xa4: /* HBlank timer frequency (low) - reload value
Bit 0-7 - HBlank timer reload value bit 0-7
*/
m_vdp.timer_hblank_reload &= 0xff00;
m_vdp.timer_hblank_reload += data;
m_vdp.timer_hblank_count = m_vdp.timer_hblank_reload;
break;
case 0xa5: /* HBlank timer frequency (high) - reload value
Bit 8-15 - HBlank timer reload value bit 8-15
*/
m_vdp.timer_hblank_reload &= 0xff;
m_vdp.timer_hblank_reload += data << 8;
m_vdp.timer_hblank_count = m_vdp.timer_hblank_reload;
break;
case 0xa6: /* VBlank timer frequency (low) - reload value
Bit 0-7 - VBlank timer reload value bit 0-7
*/
m_vdp.timer_vblank_reload &= 0xff00;
m_vdp.timer_vblank_reload += data;
m_vdp.timer_vblank_count = m_vdp.timer_vblank_reload;
break;
case 0xa7: /* VBlank timer frequency (high) - reload value
Bit 0-7 - VBlank timer reload value bit 8-15
*/
m_vdp.timer_vblank_reload &= 0xff;
m_vdp.timer_vblank_reload += data << 8;
m_vdp.timer_vblank_count = m_vdp.timer_vblank_reload;
break;
case 0xa8: /* HBlank counter (low)
Bit 0-7 - HBlank counter bit 0-7
*/
case 0xa9: /* HBlank counter (high)
Bit 0-7 - HBlank counter bit 8-15
*/
case 0xaa: /* VBlank counter (low)
Bit 0-7 - VBlank counter bit 0-7
*/
case 0xab: /* VBlank counter (high)
Bit 0-7 - VBlank counter bit 8-15
*/
break;
case 0xb0: /* Interrupt base vector case 0xb0: /* Interrupt base vector
Bit 0-7 - Interrupt base vector Bit 0-7 - Interrupt base vector
@ -925,16 +523,16 @@ WRITE8_MEMBER( wswan_state::port_w )
Bit 6 - Connection speed: 0 = 9600 bps, 1 = 38400 bps Bit 6 - Connection speed: 0 = 9600 bps, 1 = 38400 bps
bit 7 - Receive data interrupt generation bit 7 - Receive data interrupt generation
*/ */
// data |= 0x02; // data |= 0x02;
m_ws_portram[0xb1] = 0xff; m_ws_portram[0xb1] = 0xff;
if (data & 0x80) if (data & 0x80)
{ {
// m_ws_portram[0xb1] = 0x00; // m_ws_portram[0xb1] = 0x00;
data |= 0x04; data |= 0x04;
} }
if (data & 0x20) if (data & 0x20)
{ {
// data |= 0x01; // data |= 0x01;
} }
break; break;
case 0xb5: /* Read controls case 0xb5: /* Read controls
@ -987,7 +585,7 @@ WRITE8_MEMBER( wswan_state::port_w )
Bit 6 - VBlank interrupt acknowledge Bit 6 - VBlank interrupt acknowledge
Bit 7 - HBlank timer interrupt acknowledge Bit 7 - HBlank timer interrupt acknowledge
*/ */
wswan_clear_irq_line(data); clear_irq_line(data);
data = m_ws_portram[0xb6]; data = m_ws_portram[0xb6];
break; break;
case 0xba: /* Internal EEPROM data (low) case 0xba: /* Internal EEPROM data (low)
@ -1060,88 +658,3 @@ WRITE8_MEMBER( wswan_state::port_w )
/* Update the port value */ /* Update the port value */
m_ws_portram[offset] = data; m_ws_portram[offset] = data;
} }
TIMER_CALLBACK_MEMBER(wswan_state::wswan_scanline_interrupt)
{
if( m_vdp.current_line < 144 )
{
wswan_refresh_scanline();
}
/* Decrement 12kHz (HBlank) counter */
if ( m_vdp.timer_hblank_enable && m_vdp.timer_hblank_reload != 0 )
{
m_vdp.timer_hblank_count--;
logerror( "timer_hblank_count: %X\n", m_vdp.timer_hblank_count );
if ( m_vdp.timer_hblank_count == 0 )
{
if ( m_vdp.timer_hblank_mode )
{
m_vdp.timer_hblank_count = m_vdp.timer_hblank_reload;
}
else
{
m_vdp.timer_hblank_reload = 0;
}
logerror( "trigerring hbltmr interrupt\n" );
wswan_set_irq_line( WSWAN_IFLAG_HBLTMR );
}
}
/* Handle Sound DMA */
if ( ( m_sound_dma.enable & 0x88 ) == 0x80 )
{
address_space &space = m_maincpu->space(AS_PROGRAM );
/* TODO: Output sound DMA byte */
port_w( space, 0x89, space.read_byte(m_sound_dma.source ) );
m_sound_dma.size--;
m_sound_dma.source = ( m_sound_dma.source + 1 ) & 0x0FFFFF;
if ( m_sound_dma.size == 0 )
{
m_sound_dma.enable &= 0x7F;
}
}
// m_vdp.current_line = (m_vdp.current_line + 1) % 159;
if( m_vdp.current_line == 144 ) // buffer sprite table
{
memcpy(m_vdp.sprite_table_buffer, &m_vdp.vram[m_vdp.sprite_table_address], 512);
m_vdp.sprite_count = m_ws_portram[0x06];
m_vdp.sprite_first = m_ws_portram[0x05]; // always zero?
}
if( m_vdp.current_line == 144 )
{
wswan_set_irq_line( WSWAN_IFLAG_VBL );
/* Decrement 75Hz (VBlank) counter */
if ( m_vdp.timer_vblank_enable && m_vdp.timer_vblank_reload != 0 )
{
m_vdp.timer_vblank_count--;
logerror( "timer_vblank_count: %X\n", m_vdp.timer_vblank_count );
if ( m_vdp.timer_vblank_count == 0 )
{
if ( m_vdp.timer_vblank_mode )
{
m_vdp.timer_vblank_count = m_vdp.timer_vblank_reload;
}
else
{
m_vdp.timer_vblank_reload = 0;
}
logerror( "triggering vbltmr interrupt\n" );
wswan_set_irq_line( WSWAN_IFLAG_VBLTMR );
}
}
}
// m_vdp.current_line = (m_vdp.current_line + 1) % 159;
if ( m_vdp.current_line == m_vdp.line_compare )
{
wswan_set_irq_line( WSWAN_IFLAG_LCMP );
}
m_vdp.current_line = (m_vdp.current_line + 1) % 159;
}

View File

@ -1029,7 +1029,7 @@ $(MESSOBJ)/bally.a: \
$(MESSOBJ)/bandai.a: \ $(MESSOBJ)/bandai.a: \
$(MESS_DRIVERS)/sv8000.o \ $(MESS_DRIVERS)/sv8000.o \
$(MESS_DRIVERS)/rx78.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: \ $(MESSOBJ)/be.a: \
$(MESS_DRIVERS)/bebox.o $(MESS_MACHINE)/bebox.o \ $(MESS_DRIVERS)/bebox.o $(MESS_MACHINE)/bebox.o \

View File

@ -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

File diff suppressed because it is too large Load Diff

View 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