Previous 199869 Revisions Next

r33044 Tuesday 28th October, 2014 at 14:01:21 UTC by MetalliC
Merge branch 'master' of https://github.com/mamedev/mame
[hash]amiga_workbench.xml vreader.xml
[src/emu/bus/ecbbus]grip.c
[src/mess]mess.mak
[src/mess/drivers]wswan.c
[src/mess/includes]ti85.h wswan.h
[src/mess/machine]ti85.c wswan.c
[src/mess/video]wswan.c wswan_video.c* wswan_video.h*

trunk/hash/amiga_workbench.xml
r241555r241556
212212      </part>
213213   </software>
214214
215   <software name="wb133r3434" cloneof="wbenc133">
216      <description>Workbench 1.3.3 (Rev. 34.34)</description>
215   <!-- 317746-01 Workbench 1.3 (US) -->
216   <!-- 317746-03 Workbench 1.3.2 (US) -->
217
218   <software name="wbenc133_us" cloneof="wbenc133">
219      <description>Workbench 1.3.3 (US)</description>
217220      <year>1990</year>
218221      <publisher>Commodore</publisher>
219
220222      <part name="flop1" interface="floppy_3_5">
221         <feature name="part_id" value="Amiga Workbench Version 1.3.3 (Rev. 34.34)" />
223         <feature name="part_id" value="Workbench 1.3.3" />
222224         <dataarea name="flop" size="901120">
223            <rom name="317746-04_workbench.adf" size="901120" crc="bf299bca" sha1="8bac53a89cd1fe5a7762de9bd61a1592f10af2df" offset="0"/>
225            <rom name="317746-04_workbench.adf" size="901120" crc="bf299bca" sha1="8bac53a89cd1fe5a7762de9bd61a1592f10af2df" status="baddump" offset="0"/>
224226         </dataarea>
225227      </part>
226
227228      <part name="flop2" interface="floppy_3_5">
228         <feature name="part_id" value="Amiga Extras Amiga Basic Printer Drivers Version 1.3" />
229         <feature name="part_id" value="Extras 1.3" />
229230         <dataarea name="flop" size="901120">
230231            <rom name="317748-02_extras.adf" size="901120" crc="256a4b82" sha1="465a65aa89fe4b016fee968ef75ab08de9bdfbc6" offset="0"/>
231232         </dataarea>
trunk/hash/vreader.xml
r241555r241556
4747
4848
4949-->
50</softwarelist>
No newline at end of file
trunk/src/emu/bus/ecbbus/grip.c
r241555r241556
681681{
682682   m_base = m_j7->read();
683683   m_page = 0;
684   m_lps = 0;
684685}
685686
686687
trunk/src/mess/drivers/wswan.c
r241555r241556
3535#include "wswan.lh"
3636
3737static ADDRESS_MAP_START (wswan_mem, AS_PROGRAM, 8, wswan_state)
38   AM_RANGE(0x00000, 0x03fff) AM_RAM       // 16kb RAM / 4 colour tiles
38   AM_RANGE(0x00000, 0x03fff) AM_DEVREADWRITE("vdp", wswan_video_device, vram_r, vram_w)       // 16kb RAM / 4 colour tiles
3939   AM_RANGE(0x04000, 0x0ffff) AM_NOP       // nothing
4040   //AM_RANGE(0x10000, 0xeffff)    // cart range, setup at machine_start
4141   AM_RANGE(0xf0000, 0xfffff) AM_READ(bios_r)
4242ADDRESS_MAP_END
4343
4444static ADDRESS_MAP_START (wscolor_mem, AS_PROGRAM, 8, wswan_state)
45   AM_RANGE(0x00000, 0x0ffff) AM_RAM       // 16kb RAM / 4 colour tiles, 16 colour tiles + palettes
45   AM_RANGE(0x00000, 0x0ffff) AM_DEVREADWRITE("vdp", wswan_video_device, vram_r, vram_w)       // 16kb RAM / 4 colour tiles, 16 colour tiles + palettes
4646   //AM_RANGE(0x10000, 0xeffff)    // cart range, setup at machine_start
4747   AM_RANGE(0xf0000, 0xfffff) AM_READ(bios_r)
4848ADDRESS_MAP_END
r241555r241556
8383   }
8484}
8585
86PALETTE_INIT_MEMBER(wswan_state,wscolor)
86PALETTE_INIT_MEMBER(wswan_state, wscolor)
8787{
8888   for (int i = 0; i < 4096; i++)
8989   {
r241555r241556
9595}
9696
9797static SLOT_INTERFACE_START(wswan_cart)
98   SLOT_INTERFACE_INTERNAL("ws_rom",         WS_ROM_STD)
99   SLOT_INTERFACE_INTERNAL("ws_sram",        WS_ROM_SRAM)
100   SLOT_INTERFACE_INTERNAL("ws_eeprom",      WS_ROM_EEPROM)
98   SLOT_INTERFACE_INTERNAL("ws_rom",     WS_ROM_STD)
99   SLOT_INTERFACE_INTERNAL("ws_sram",    WS_ROM_SRAM)
100   SLOT_INTERFACE_INTERNAL("ws_eeprom",  WS_ROM_EEPROM)
101101SLOT_INTERFACE_END
102102
103103static MACHINE_CONFIG_START( wswan, wswan_state )
r241555r241556
106106   MCFG_CPU_PROGRAM_MAP(wswan_mem)
107107   MCFG_CPU_IO_MAP(wswan_io)
108108
109   MCFG_DEVICE_ADD("vdp", WSWAN_VIDEO, 0)
110   MCFG_WSWAN_VIDEO_TYPE(VDP_TYPE_WSWAN)
111   MCFG_WSWAN_VIDEO_IRQ_CB(wswan_state, set_irq_line)
112   MCFG_WSWAN_VIDEO_DMASND_CB(wswan_state, dma_sound_cb)
113
109114   MCFG_SCREEN_ADD("screen", LCD)
110115   MCFG_SCREEN_REFRESH_RATE(75)
111116   MCFG_SCREEN_VBLANK_TIME(0)
112   MCFG_SCREEN_UPDATE_DRIVER(wswan_state, screen_update)
113   MCFG_SCREEN_SIZE( WSWAN_X_PIXELS, WSWAN_Y_PIXELS )
117   MCFG_SCREEN_UPDATE_DEVICE("vdp", wswan_video_device, screen_update)
118   MCFG_SCREEN_SIZE(WSWAN_X_PIXELS, WSWAN_Y_PIXELS)
114119   MCFG_SCREEN_VISIBLE_AREA(0*8, WSWAN_X_PIXELS - 1, 0, WSWAN_Y_PIXELS - 1)
115120   MCFG_SCREEN_PALETTE("palette")
116121
r241555r241556
141146static MACHINE_CONFIG_DERIVED( wscolor, wswan )
142147   MCFG_CPU_MODIFY("maincpu")
143148   MCFG_CPU_PROGRAM_MAP(wscolor_mem)
144   MCFG_MACHINE_START_OVERRIDE(wswan_state, wscolor )
149   MCFG_MACHINE_START_OVERRIDE(wswan_state, wscolor)
145150
151   MCFG_DEVICE_MODIFY("vdp")
152   MCFG_WSWAN_VIDEO_TYPE(VDP_TYPE_WSC)
153
146154   MCFG_PALETTE_MODIFY("palette")
147155   MCFG_PALETTE_ENTRIES(4096)
148   MCFG_PALETTE_INIT_OWNER(wswan_state, wscolor )
156   MCFG_PALETTE_INIT_OWNER(wswan_state, wscolor)
149157
150158   /* software lists */
151159   MCFG_DEVICE_REMOVE("cart_list")
trunk/src/mess/includes/ti85.h
r241555r241556
8686   UINT8 m_ON_interrupt_status;
8787   UINT8 m_ON_pressed;
8888   UINT8 m_flash_unlocked;
89   UINT8 m_ti8x_memory_page_0;
9089   UINT8 m_ti8x_memory_page_1;
9190   UINT8 m_ti8x_memory_page_2;
9291   UINT8 m_ti8x_memory_page_3;
92   bool m_booting;
9393   UINT8 m_LCD_mask;
9494   UINT8 m_power_mode;
9595   UINT8 m_cpu_speed;
r241555r241556
217217   void ti85_setup_snapshot (UINT8 * data);
218218   void ti86_setup_snapshot (UINT8 * data);
219219   DECLARE_SNAPSHOT_LOAD_MEMBER( ti8x );
220   DECLARE_DIRECT_UPDATE_MEMBER( ti83p_direct_update_handler );
220221   
221222   ti83pse_timer m_ctimer[3];
222223   
trunk/src/mess/includes/wswan.h
r241555r241556
1010#define WSWAN_TYPE_MONO 0
1111#define WSWAN_TYPE_COLOR 1
1212
13#define WSWAN_X_PIXELS  (28*8)
14#define WSWAN_Y_PIXELS  (18*8)
15
1613#define INTERNAL_EEPROM_SIZE    1024
1714
1815#include "emu.h"
1916#include "cpu/v30mz/v30mz.h"
20#include "audio/wswan_snd.h"
2117#include "machine/nvram.h"
18#include "audio/wswan_snd.h"
19#include "video/wswan_video.h"
2220#include "bus/wswan/slot.h"
2321#include "bus/wswan/rom.h"
2422
r241555r241556
3028   UINT8   enable;     /* Enabled */
3129};
3230
33struct VDP
34{
35   UINT8 layer_bg_enable;          /* Background layer on/off */
36   UINT8 layer_fg_enable;          /* Foreground layer on/off */
37   UINT8 sprites_enable;           /* Sprites on/off */
38   UINT8 window_sprites_enable;        /* Sprite window on/off */
39   UINT8 window_fg_mode;           /* 0:inside/outside, 1:??, 2:inside, 3:outside */
40   UINT8 current_line;         /* Current scanline : 0-158 (159?) */
41   UINT8 line_compare;         /* Line to trigger line interrupt on */
42   UINT32 sprite_table_address;        /* Address of the sprite table */
43   UINT8 sprite_table_buffer[512];
44   UINT8 sprite_first;         /* First sprite to draw */
45   UINT8 sprite_count;         /* Number of sprites to draw */
46   UINT16 layer_bg_address;        /* Address of the background screen map */
47   UINT16 layer_fg_address;        /* Address of the foreground screen map */
48   UINT8 window_fg_left;           /* Left coordinate of foreground window */
49   UINT8 window_fg_top;            /* Top coordinate of foreground window */
50   UINT8 window_fg_right;          /* Right coordinate of foreground window */
51   UINT8 window_fg_bottom;         /* Bottom coordinate of foreground window */
52   UINT8 window_sprites_left;      /* Left coordinate of sprites window */
53   UINT8 window_sprites_top;       /* Top coordinate of sprites window */
54   UINT8 window_sprites_right;     /* Right coordinate of sprites window */
55   UINT8 window_sprites_bottom;        /* Bottom coordinate of sprites window */
56   UINT8 layer_bg_scroll_x;        /* Background layer X scroll */
57   UINT8 layer_bg_scroll_y;        /* Background layer Y scroll */
58   UINT8 layer_fg_scroll_x;        /* Foreground layer X scroll */
59   UINT8 layer_fg_scroll_y;        /* Foreground layer Y scroll */
60   UINT8 lcd_enable;           /* LCD on/off */
61   UINT8 icons;                /* FIXME: What do we do with these? Maybe artwork? */
62   UINT8 color_mode;           /* monochrome/color mode */
63   UINT8 colors_16;            /* 4/16 colors mode */
64   UINT8 tile_packed;          /* layered/packed tile mode switch */
65   UINT8 timer_hblank_enable;      /* Horizontal blank interrupt on/off */
66   UINT8 timer_hblank_mode;        /* Horizontal blank timer mode */
67   UINT16 timer_hblank_reload;     /* Horizontal blank timer reload value */
68   UINT16 timer_hblank_count;      /* Horizontal blank timer counter value */
69   UINT8 timer_vblank_enable;      /* Vertical blank interrupt on/off */
70   UINT8 timer_vblank_mode;        /* Vertical blank timer mode */
71   UINT16 timer_vblank_reload;     /* Vertical blank timer reload value */
72   UINT16 timer_vblank_count;      /* Vertical blank timer counter value */
73   UINT8 *vram;                /* pointer to start of ram/vram (set by machine_reset) */
74   UINT8 *palette_vram;            /* pointer to start of palette area in ram/vram (set by machine_reset), WSC only */
75   int main_palette[8];
76   emu_timer *timer;
77};
7831
79
8032class wswan_state : public driver_device
8133{
8234public:
8335   wswan_state(const machine_config &mconfig, device_type type, const char *tag)
8436      : driver_device(mconfig, type, tag),
8537      m_maincpu(*this, "maincpu"),
38      m_vdp(*this, "vdp"),
8639      m_sound(*this, "custom"),
8740      m_cart(*this, "cartslot"),
8841      m_cursx(*this, "CURSX"),
8942      m_cursy(*this, "CURSY"),
90      m_buttons(*this, "BUTTONS") { }
91
92   virtual void video_start();
93
94   UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
95
43      m_buttons(*this, "BUTTONS")
44   { }
45   
9646   required_device<cpu_device> m_maincpu;
47   required_device<wswan_video_device> m_vdp;
9748   required_device<wswan_sound_device> m_sound;
9849   required_device<ws_cart_slot_device> m_cart;
9950   DECLARE_READ8_MEMBER(bios_r);
10051   DECLARE_READ8_MEMBER(port_r);
10152   DECLARE_WRITE8_MEMBER(port_w);
102
103   VDP m_vdp;
53   
10454   UINT8 m_ws_portram[256];
10555   UINT8 m_internal_eeprom[INTERNAL_EEPROM_SIZE];
10656   UINT8 m_system_type;
10757   SoundDMA m_sound_dma;
108   UINT8 *m_ws_ram;
10958   UINT8 *m_ws_bios_bank;
11059   UINT8 m_bios_disabled;
111   int m_pal[16][16];
112   bitmap_ind16 m_bitmap;
11360   UINT8 m_rotate;
114
115   void wswan_clear_irq_line(int irq);
61   
62   void set_irq_line(int irq);
63   void dma_sound_cb();
11664   void common_start();
11765   virtual void machine_start();
11866   virtual void machine_reset();
11967   DECLARE_PALETTE_INIT(wswan);
12068   DECLARE_MACHINE_START(wscolor);
12169   DECLARE_PALETTE_INIT(wscolor);
122   TIMER_CALLBACK_MEMBER(wswan_scanline_interrupt);
123
70   
12471protected:
12572   /* Interrupt flags */
12673   static const UINT8 WSWAN_IFLAG_STX    = 0x01;
r241555r241556
13178   static const UINT8 WSWAN_IFLAG_VBLTMR = 0x20;
13279   static const UINT8 WSWAN_IFLAG_VBL    = 0x40;
13380   static const UINT8 WSWAN_IFLAG_HBLTMR = 0x80;
134
81   
13582   /* Interrupts */
13683   static const UINT8 WSWAN_INT_STX    = 0;
13784   static const UINT8 WSWAN_INT_KEY    = 1;
r241555r241556
14188   static const UINT8 WSWAN_INT_VBLTMR = 5;
14289   static const UINT8 WSWAN_INT_VBL    = 6;
14390   static const UINT8 WSWAN_INT_HBLTMR = 7;
144
91   
14592   required_ioport m_cursx;
14693   required_ioport m_cursy;
14794   required_ioport m_buttons;
148
149   void wswan_register_save();
150   void wswan_postload();
151   void wswan_handle_irqs();
152   void wswan_set_irq_line(int irq);
153   void wswan_setup_palettes();
154   void wswan_draw_background();
155   void wswan_draw_foreground_0();
156   void wswan_draw_foreground_2();
157   void wswan_draw_foreground_3();
158   void wswan_handle_sprites( int mask );
159   void wswan_refresh_scanline( );
95   
96   void register_save();
97   void handle_irqs();
98   void clear_irq_line(int irq);
16099};
161100
162101
trunk/src/mess/machine/ti85.c
r241555r241556
154154{
155155   //address_space &space = m_maincpu->space(AS_PROGRAM);
156156
157   m_membank1->set_bank(0); //Always flash page 0, well allmost
157   m_membank1->set_bank(m_booting ? 0x1f : 0); //Always flash page 0, well allmost
158158   
159159   if (m_ti83p_port4 & 1)
160160   {
r241555r241556
182182{
183183   //address_space &space = m_maincpu->space(AS_PROGRAM);
184184   
185   m_membank1->set_bank(m_ti8x_memory_page_0);
185   m_membank1->set_bank(m_booting ? (m_model==TI84P ? 0x3f : 0x7f) : 0);
186186   
187187   if (m_ti83p_port4 & 1)
188188    {
r241555r241556
273273   m_PCR = 0xc0;
274274}
275275
276DIRECT_UPDATE_MEMBER(ti85_state::ti83p_direct_update_handler)
277{
278   if (m_booting)
279   {
280        if (((m_ti83p_port4 & 1) && (address >= 0x4000 && address < 0xc000)) || (address >= 0x4000 && address < 0x8000))
281        {
282            m_booting = false;
283         update_ti83p_memory();
284      }
285    }
286   return address;
287}
288
289
276290MACHINE_RESET_MEMBER(ti85_state,ti83p)
277291{
278292   m_red_out = 0x00;
279293   m_white_out = 0x00;
280294   m_PCR = 0xc0;
281295
282   m_ti8x_memory_page_0 = 0;//0x1f;
283296
284    if (m_model == TI83P)
285    {
286        m_ti8x_memory_page_1 = 0x1f;
287    }
288    else if (m_model == TI84P)
289    {
290        m_ti8x_memory_page_1 = 0x3f;
291    }
292    else
293    {
294       m_ti8x_memory_page_1 = 0x7f;
295    }
296
297    m_ti8x_memory_page_1 = 0;
297298   m_ti8x_memory_page_2 = 0;
298299   m_ti8x_memory_page_3 = 0;
299300   m_ti83p_port4 = 1;
301   m_booting = true;
300302   if (m_model == TI83P)
301303    {
302304        update_ti83p_memory();
r241555r241556
305307    {
306308        update_ti83pse_memory();
307309    }
308
309   m_maincpu->set_pc(0x8000);
310310}
311311
312312MACHINE_START_MEMBER(ti85_state,ti83p)
r241555r241556
314314   m_model = TI83P;
315315   //address_space &space = m_maincpu->space(AS_PROGRAM);
316316   //m_bios = memregion("flash")->base();
317   m_maincpu->space(AS_PROGRAM).set_direct_update_handler(direct_update_delegate(FUNC(ti85_state::ti83p_direct_update_handler), this));
317318
318319   m_timer_interrupt_mask = 0;
319320   m_timer_interrupt_status = 0;
320321   m_ON_interrupt_mask = 0;
321322   m_ON_interrupt_status = 0;
322323   m_ON_pressed = 0;
323   m_ti8x_memory_page_0 = 0;//0x1f;
324   m_ti8x_memory_page_1 = 0x1f;
324   m_ti8x_memory_page_1 = 0;
325325   m_ti8x_memory_page_2 = 0;
326326   m_ti8x_memory_page_3 = 0;
327327   m_LCD_memory_base = 0;
r241555r241556
334334   m_ti83p_port4 = 1;
335335   m_flash_unlocked = 0;
336336
337   m_booting = true;
338
337339    ti85_state::update_ti83p_memory();
338   m_maincpu->set_pc(0x8000); //this is a hack due to incomplete memory mapping emulation
339340
340341
341342   machine().scheduler().timer_pulse(attotime::from_hz(256), timer_expired_delegate(FUNC(ti85_state::ti83_timer1_callback),this));
r241555r241556
345346   /* save states and debugging */
346347   save_item(NAME(m_timer_interrupt_status));
347348    save_item(NAME(m_timer_interrupt_mask));
348   save_item(NAME(m_ti8x_memory_page_0));
349349   save_item(NAME(m_ti8x_memory_page_1));
350350   save_item(NAME(m_ti8x_memory_page_2));
351351   save_item(NAME(m_ti8x_memory_page_3));
352352   save_item(NAME(m_ti83p_port4));
353   save_item(NAME(m_booting));
353354}
354355
355356void ti85_state::ti8xpse_init_common()
r241555r241556
363364   m_ON_interrupt_mask = 0;
364365   m_ON_interrupt_status = 0;
365366   m_ON_pressed = 0;
366   m_ti8x_memory_page_0 = 00;//0x7f;
367   m_ti8x_memory_page_1 = (m_model != TI84P ) ? 0x7f : 0x3f ;
367   m_ti8x_memory_page_1 = 0;
368368   m_ti8x_memory_page_2 = 0;
369369   m_ti8x_memory_page_3 = 0;
370370   m_LCD_memory_base = 0;
r241555r241556
378378   m_flash_unlocked = 0;
379379
380380   ti85_state::update_ti83pse_memory();
381   m_maincpu->set_pc(0x8000);//same as above, hack to work around incomplete memory mapping emulation
381   m_maincpu->space(AS_PROGRAM).set_direct_update_handler(direct_update_delegate(FUNC(ti85_state::ti83p_direct_update_handler), this));
382382
383383
384384   machine().scheduler().timer_pulse(attotime::from_hz(256), timer_expired_delegate(FUNC(ti85_state::ti83_timer1_callback),this));
r241555r241556
391391      /* save states and debugging */
392392   save_item(NAME(m_ctimer_interrupt_status));
393393   save_item(NAME(m_timer_interrupt_status));
394   save_item(NAME(m_ti8x_memory_page_0));
395394   save_item(NAME(m_ti8x_memory_page_1));
396395   save_item(NAME(m_ti8x_memory_page_2));
397396   save_item(NAME(m_ti8x_memory_page_3));
trunk/src/mess/machine/wswan.c
r241555r241556
7878   0xea, 0xc0, 0xff, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
7979};
8080
81void wswan_state::wswan_handle_irqs()
81void wswan_state::handle_irqs()
8282{
83   if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_HBLTMR )
83   if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_HBLTMR)
8484   {
85      m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_HBLTMR );
85      m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_HBLTMR);
8686   }
87   else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_VBL )
87   else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_VBL)
8888   {
89      m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_VBL );
89      m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_VBL);
9090   }
91   else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_VBLTMR )
91   else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_VBLTMR)
9292   {
93      m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_VBLTMR );
93      m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_VBLTMR);
9494   }
95   else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_LCMP )
95   else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_LCMP)
9696   {
97      m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_LCMP );
97      m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_LCMP);
9898   }
99   else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_SRX )
99   else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_SRX)
100100   {
101      m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_SRX );
101      m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_SRX);
102102   }
103   else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_RTC )
103   else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_RTC)
104104   {
105      m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_RTC );
105      m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_RTC);
106106   }
107   else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_KEY )
107   else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_KEY)
108108   {
109      m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_KEY );
109      m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_KEY);
110110   }
111   else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_STX )
111   else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_STX)
112112   {
113      m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_STX );
113      m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_STX);
114114   }
115115   else
116116   {
117      m_maincpu->set_input_line(0, CLEAR_LINE );
117      m_maincpu->set_input_line(0, CLEAR_LINE);
118118   }
119119}
120120
121void wswan_state::wswan_set_irq_line(int irq)
121void wswan_state::set_irq_line(int irq)
122122{
123   if ( m_ws_portram[0xb2] & irq )
123   if (m_ws_portram[0xb2] & irq)
124124   {
125125      m_ws_portram[0xb6] |= irq;
126      wswan_handle_irqs();
126      handle_irqs();
127127   }
128128}
129129
130void wswan_state::wswan_clear_irq_line(int irq)
130void wswan_state::dma_sound_cb()
131131{
132   if ((m_sound_dma.enable & 0x88) == 0x80)
133   {
134      address_space &space = m_maincpu->space(AS_PROGRAM);
135      /* TODO: Output sound DMA byte */
136      port_w(space, 0x89, space.read_byte(m_sound_dma.source));
137      m_sound_dma.size--;
138      m_sound_dma.source = (m_sound_dma.source + 1) & 0x0fffff;
139      if (m_sound_dma.size == 0)
140      {
141         m_sound_dma.enable &= 0x7F;
142      }
143   }
144}
145
146void wswan_state::clear_irq_line(int irq)
147{
132148   m_ws_portram[0xb6] &= ~irq;
133   wswan_handle_irqs();
149   handle_irqs();
134150}
135151
136void wswan_state::wswan_register_save()
152void wswan_state::register_save()
137153{
138154   save_item(NAME(m_ws_portram));
139155   save_item(NAME(m_internal_eeprom));
140156   save_item(NAME(m_bios_disabled));
141157   save_item(NAME(m_rotate));
142
143   save_item(NAME(m_vdp.layer_bg_enable));
144   save_item(NAME(m_vdp.layer_fg_enable));
145   save_item(NAME(m_vdp.sprites_enable));
146   save_item(NAME(m_vdp.window_sprites_enable));
147   save_item(NAME(m_vdp.window_fg_mode));
148   save_item(NAME(m_vdp.current_line));
149   save_item(NAME(m_vdp.line_compare));
150   save_item(NAME(m_vdp.sprite_table_address));
151   save_item(NAME(m_vdp.sprite_table_buffer));
152   save_item(NAME(m_vdp.sprite_first));
153   save_item(NAME(m_vdp.sprite_count));
154   save_item(NAME(m_vdp.layer_bg_address));
155   save_item(NAME(m_vdp.layer_fg_address));
156   save_item(NAME(m_vdp.window_fg_left));
157   save_item(NAME(m_vdp.window_fg_top));
158   save_item(NAME(m_vdp.window_fg_right));
159   save_item(NAME(m_vdp.window_fg_bottom));
160   save_item(NAME(m_vdp.window_sprites_left));
161   save_item(NAME(m_vdp.window_sprites_top));
162   save_item(NAME(m_vdp.window_sprites_right));
163   save_item(NAME(m_vdp.window_sprites_bottom));
164   save_item(NAME(m_vdp.layer_bg_scroll_x));
165   save_item(NAME(m_vdp.layer_bg_scroll_y));
166   save_item(NAME(m_vdp.layer_fg_scroll_x));
167   save_item(NAME(m_vdp.layer_fg_scroll_y));
168   save_item(NAME(m_vdp.lcd_enable));
169   save_item(NAME(m_vdp.icons));
170   save_item(NAME(m_vdp.color_mode));
171   save_item(NAME(m_vdp.colors_16));
172   save_item(NAME(m_vdp.tile_packed));
173   save_item(NAME(m_vdp.timer_hblank_enable));
174   save_item(NAME(m_vdp.timer_hblank_mode));
175   save_item(NAME(m_vdp.timer_hblank_reload));
176   save_item(NAME(m_vdp.timer_vblank_enable));
177   save_item(NAME(m_vdp.timer_vblank_mode));
178   save_item(NAME(m_vdp.timer_vblank_reload));
179   save_item(NAME(m_vdp.timer_vblank_count));
180   save_item(NAME(m_vdp.main_palette));
181
158   
182159   save_item(NAME(m_sound_dma.source));
183160   save_item(NAME(m_sound_dma.size));
184161   save_item(NAME(m_sound_dma.enable));
185
162   
186163   if (m_cart->exists())
187164      m_cart->save_nvram();
188
189   machine().save().register_postload(save_prepost_delegate(FUNC(wswan_state::wswan_postload), this));
190165}
191166
192void wswan_state::wswan_postload()
193{
194   address_space &space = m_maincpu->space(AS_PROGRAM);
195   // restore the vdp pointers
196   m_vdp.vram = (UINT8*)space.get_read_ptr(0);
197   m_vdp.palette_vram = (UINT8*)space.get_read_ptr((m_system_type == TYPE_WSC) ? 0xfe00 : 0);
198}
199
200167void wswan_state::common_start()
201168{
202169   m_ws_bios_bank = auto_alloc_array(machine(), UINT8, 0x10000);
203170   memcpy(m_ws_bios_bank + 0xffc0, ws_fake_bios_code, 0x40);
204
205   m_vdp.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(wswan_state::wswan_scanline_interrupt),this), &m_vdp);
206   m_vdp.timer->adjust(attotime::from_ticks(256, 3072000), 0, attotime::from_ticks(256, 3072000));
207
208   wswan_register_save();
209
171   
172   register_save();
173   
210174   machine().device<nvram_device>("nvram")->set_base(m_internal_eeprom, INTERNAL_EEPROM_SIZE);
211
175   
212176   if (m_cart->exists())
213177   {
214178      // ROM
215179      m_maincpu->space(AS_PROGRAM).install_read_handler(0x20000, 0x2ffff, read8_delegate(FUNC(ws_cart_slot_device::read_rom20),(ws_cart_slot_device*)m_cart));
216180      m_maincpu->space(AS_PROGRAM).install_read_handler(0x30000, 0x3ffff, read8_delegate(FUNC(ws_cart_slot_device::read_rom30),(ws_cart_slot_device*)m_cart));
217181      m_maincpu->space(AS_PROGRAM).install_read_handler(0x40000, 0xeffff, read8_delegate(FUNC(ws_cart_slot_device::read_rom40),(ws_cart_slot_device*)m_cart));
218
182     
219183      // SRAM
220184      if (m_cart->get_type() == WS_SRAM)
221185      {
r241555r241556
231195   m_system_type = TYPE_WSWAN;
232196}
233197
234MACHINE_START_MEMBER(wswan_state,wscolor)
198MACHINE_START_MEMBER(wswan_state, wscolor)
235199{
236200   common_start();
237201   m_system_type = TYPE_WSC;
r241555r241556
239203
240204void wswan_state::machine_reset()
241205{
242   address_space &space = m_maincpu->space(AS_PROGRAM);
243
244206   m_bios_disabled = 0;
245
246   m_ws_ram = (UINT8*) m_maincpu->space(AS_PROGRAM).get_read_ptr(0);
247   memset(m_ws_ram, 0, 0xffff);
248
207   
249208   if (m_cart->exists())
250209      m_rotate = m_cart->get_is_rotated();
251210   else
252211      m_rotate = 0;
253
212   
254213   /* Intialize ports */
255214   memcpy(m_ws_portram, ws_portram_init, 256);
256
257   /* Initialize VDP */
258   memset(&m_vdp, 0, sizeof(m_vdp));
259
260   m_vdp.vram = (UINT8*)space.get_read_ptr(0);
261   m_vdp.palette_vram = (UINT8*)space.get_read_ptr(( m_system_type == TYPE_WSC ) ? 0xFE00 : 0 );
262   m_vdp.current_line = 145;  /* Randomly chosen, beginning of VBlank period to give cart some time to boot up */
263   m_vdp.color_mode = 0;
264   m_vdp.colors_16 = 0;
265   m_vdp.tile_packed = 0;
266
215   
267216   render_target *target = machine().render().first_target();
268217   target->set_view(m_rotate);
269
218   
270219   /* Initialize sound DMA */
271220   memset(&m_sound_dma, 0, sizeof(m_sound_dma));
272221}
r241555r241556
282231READ8_MEMBER( wswan_state::port_r )
283232{
284233   UINT8 value = m_ws_portram[offset];
285
234   
286235   if (offset != 2)
287236      logerror("PC=%X: port read %02X\n", m_maincpu->pc(), offset);
237   
238   if (offset < 0x40 || (offset >= 0xa1 && offset < 0xb0))
239      return m_vdp->reg_r(space, offset);
240   
288241   switch (offset)
289242   {
290      case 0x02:      // Current line
291         value = m_vdp.current_line;
292         break;
293243      case 0x4a:      // Sound DMA source address (low)
294244         value = m_sound_dma.source & 0xff;
295245         break;
r241555r241556
308258      case 0x52:      // Sound DMA start/stop
309259         value = m_sound_dma.enable;
310260         break;
261      case 0x60:
262         value = m_vdp->reg_r(space, offset);
263         break;
311264      case 0xa0:      // Hardware type
312               // Bit 0 - Disable/enable Bios
313               // Bit 1 - Determine mono/color
314               // Bit 2 - Determine color/crystal
265         // Bit 0 - Disable/enable Bios
266         // Bit 1 - Determine mono/color
267         // Bit 2 - Determine color/crystal
315268         value = value & ~ 0x02;
316269         if (m_system_type == TYPE_WSC)
317270            value |= 2;
318271         break;
319      case 0xa8:
320         value = m_vdp.timer_hblank_count & 0xff;
321         break;
322      case 0xa9:
323         value = m_vdp.timer_hblank_count >> 8;
324         break;
325      case 0xaa:
326         value = m_vdp.timer_vblank_count & 0xff;
327         break;
328      case 0xab:
329         value = m_vdp.timer_vblank_count >> 8;
330         break;
331272      case 0xc0:
332273      case 0xc1:
333274      case 0xc2:
r241555r241556
347288         value = m_cart->read_io(space, offset & 0x0f);
348289         break;
349290   }
350
291   
351292   return value;
352293}
353294
r241555r241556
356297   address_space &mem = m_maincpu->space(AS_PROGRAM);
357298   UINT8 input;
358299   logerror("PC=%X: port write %02X <- %02X\n", m_maincpu->pc(), offset, data);
300   
301   if (offset < 0x40 || (offset >= 0xa1 && offset < 0xb0))
302   {
303      m_vdp->reg_w(space, offset, data);
304      return;
305   }
306   
359307   switch (offset)
360308   {
361      case 0x00:  /* Display control
362                   Bit 0   - Background layer enable
363                   Bit 1   - Foreground layer enable
364                   Bit 2   - Sprites enable
365                   Bit 3   - Sprite window enable
366                   Bit 4-5 - Foreground window configuration
367                             00 - Foreground layer is displayed inside and outside foreground window area
368                             01 - Unknown
369                             10 - Foreground layer is displayed only inside foreground window area
370                             11 - Foreground layer is displayed outside foreground window area
371                   Bit 6-7 - Unknown
372                */
373         m_vdp.layer_bg_enable = data & 0x1;
374         m_vdp.layer_fg_enable = (data & 0x2) >> 1;
375         m_vdp.sprites_enable = (data & 0x4) >> 2;
376         m_vdp.window_sprites_enable = (data & 0x8) >> 3;
377         m_vdp.window_fg_mode = (data & 0x30) >> 4;
378         break;
379      case 0x01:  /* Background colour
380                   In 16 colour mode:
381                   Bit 0-3 - Palette index
382                   Bit 4-7 - Palette number
383                   Otherwise:
384                   Bit 0-2 - Main palette index
385                   Bit 3-7 - Unknown
386                */
387         break;
388      case 0x02:  /* Current scanline
389                   Bit 0-7 - Current scanline (Most likely read-only)
390                */
391         logerror( "Write to current scanline! Current value: %d  Data to write: %d\n", m_vdp.current_line, data );
392         /* Returning so we don't overwrite the value here, not that it
393          * really matters */
394         return;
395      case 0x03:  /* Line compare
396                   Bit 0-7 - Line compare
397                */
398         m_vdp.line_compare = data;
399         logerror( "Write to line compare: %d\n", data );
400         break;
401      case 0x04:  /* Sprite table base address
402                   Bit 0-5 - Determine sprite table base address 0 0xxxxxx0 00000000
403                   Bit 6-7 - Unknown
404                */
405         m_vdp.sprite_table_address = ( data & 0x3F ) << 9;
406         break;
407      case 0x05:  /* Number of sprite to start drawing with
408                   Bit 0-7 - First sprite number
409                */
410         //m_vdp.sprite_first = data;
411         if (data) logerror("non-zero first sprite %d\n", m_vdp.sprite_first);
412         break;
413      case 0x06:  /* Number of sprites to draw
414                   Bit 0-7 - Number of sprites to draw
415                */
416         //m_vdp.sprite_count = data;
417         break;
418      case 0x07:  /* Background/Foreground table base addresses
419                   Bit 0-2 - Determine background table base address 00xxx000 00000000
420                   Bit 3   - Unknown
421                   Bit 4-6 - Determine foreground table base address 00xxx000 00000000
422                   Bit 7   - Unknown
423                */
424         m_vdp.layer_bg_address = (data & 0x7) << 11;
425         m_vdp.layer_fg_address = (data & 0x70) << 7;
426         break;
427      case 0x08:  /* Left coordinate of foreground window
428                   Bit 0-7 - Left coordinate of foreground window area
429                */
430         m_vdp.window_fg_left = data;
431         break;
432      case 0x09:  /* Top coordinate of foreground window
433                   Bit 0-7 - Top coordinatte of foreground window area
434                */
435         m_vdp.window_fg_top = data;
436         break;
437      case 0x0a:  /* Right coordinate of foreground window
438                   Bit 0-7 - Right coordinate of foreground window area
439                */
440         m_vdp.window_fg_right = data;
441         break;
442      case 0x0b:  /* Bottom coordinate of foreground window
443                   Bit 0-7 - Bottom coordinate of foreground window area
444                */
445         m_vdp.window_fg_bottom = data;
446         break;
447      case 0x0c:  /* Left coordinate of sprite window
448                   Bit 0-7 - Left coordinate of sprite window area
449                */
450         m_vdp.window_sprites_left = data;
451         break;
452      case 0x0d:  /* Top coordinate of sprite window
453                   Bit 0-7 - Top coordinate of sprite window area
454                */
455         m_vdp.window_sprites_top = data;
456         break;
457      case 0x0e:  /* Right coordinate of sprite window
458                   Bit 0-7 - Right coordinate of sprite window area
459                */
460         m_vdp.window_sprites_right = data;
461         break;
462      case 0x0f:  /* Bottom coordinate of sprite window
463                   Bit 0-7 - Bottom coordiante of sprite window area
464                */
465         m_vdp.window_sprites_bottom = data;
466         break;
467      case 0x10:  /* Background layer X scroll
468                   Bit 0-7 - Background layer X scroll
469                */
470         m_vdp.layer_bg_scroll_x = data;
471         break;
472      case 0x11:  /* Background layer Y scroll
473                   Bit 0-7 - Background layer Y scroll
474                */
475         m_vdp.layer_bg_scroll_y = data;
476         break;
477      case 0x12:  /* Foreground layer X scroll
478                   Bit 0-7 - Foreground layer X scroll
479                */
480         m_vdp.layer_fg_scroll_x = data;
481         break;
482      case 0x13:  /* Foreground layer Y scroll
483                   Bit 0-7 - Foreground layer Y scroll
484                */
485         m_vdp.layer_fg_scroll_y = data;
486         break;
487      case 0x14:  /* LCD control
488                   Bit 0   - LCD enable
489                   Bit 1-7 - Unknown
490                */
491         m_vdp.lcd_enable = data & 0x1;
492         break;
493      case 0x15:  /* LCD icons
494                   Bit 0   - LCD sleep icon enable
495                   Bit 1   - Vertical position icon enable
496                   Bit 2   - Horizontal position icon enable
497                   Bit 3   - Dot 1 icon enable
498                   Bit 4   - Dot 2 icon enable
499                   Bit 5   - Dot 3 icon enable
500                   Bit 6-7 - Unknown
501                */
502         m_vdp.icons = data; /* ummmmm */
503         break;
504      case 0x1c:  /* Palette colors 0 and 1
505                   Bit 0-3 - Gray tone setting for main palette index 0
506                   Bit 4-7 - Gray tone setting for main palette index 1
507                */
508         if (m_system_type == TYPE_WSC)
509         {
510            int i = 15 - ( data & 0x0F );
511            int j = 15 - ( ( data & 0xF0 ) >> 4 );
512            m_vdp.main_palette[0] = ( i << 8 ) | ( i << 4 ) | i;
513            m_vdp.main_palette[1] = ( j << 8 ) | ( j << 4 ) | j;
514         }
515         else
516         {
517            m_vdp.main_palette[0] = data & 0x0F;
518            m_vdp.main_palette[1] = ( data & 0xF0 ) >> 4;
519         }
520         break;
521      case 0x1d:  /* Palette colors 2 and 3
522                   Bit 0-3 - Gray tone setting for main palette index 2
523                   Bit 4-7 - Gray tone setting for main palette index 3
524                */
525         if (m_system_type == TYPE_WSC)
526         {
527            int i = 15 - ( data & 0x0F );
528            int j = 15 - ( ( data & 0xF0 ) >> 4 );
529            m_vdp.main_palette[2] = ( i << 8 ) | ( i << 4 ) | i;
530            m_vdp.main_palette[3] = ( j << 8 ) | ( j << 4 ) | j;
531         }
532         else
533         {
534            m_vdp.main_palette[2] = data & 0x0F;
535            m_vdp.main_palette[3] = ( data & 0xF0 ) >> 4;
536         }
537         break;
538      case 0x1e:  /* Palette colors 4 and 5
539                   Bit 0-3 - Gray tone setting for main palette index 4
540                   Bit 4-7 - Gray tone setting for main paeltte index 5
541                */
542         if (m_system_type == TYPE_WSC)
543         {
544            int i = 15 - ( data & 0x0F );
545            int j = 15 - ( ( data & 0xF0 ) >> 4 );
546            m_vdp.main_palette[4] = ( i << 8 ) | ( i << 4 ) | i;
547            m_vdp.main_palette[5] = ( j << 8 ) | ( j << 4 ) | j;
548         }
549         else
550         {
551            m_vdp.main_palette[4] = data & 0x0F;
552            m_vdp.main_palette[5] = ( data & 0xF0 ) >> 4;
553         }
554         break;
555      case 0x1f:  /* Palette colors 6 and 7
556                   Bit 0-3 - Gray tone setting for main palette index 6
557                   Bit 4-7 - Gray tone setting for main palette index 7
558                */
559         if (m_system_type == TYPE_WSC)
560         {
561            int i = 15 - ( data & 0x0F );
562            int j = 15 - ( ( data & 0xF0 ) >> 4 );
563            m_vdp.main_palette[6] = ( i << 8 ) | ( i << 4 ) | i;
564            m_vdp.main_palette[7] = ( j << 8 ) | ( j << 4 ) | j;
565         }
566         else
567         {
568            m_vdp.main_palette[6] = data & 0x0F;
569            m_vdp.main_palette[7] = ( data & 0xF0 ) >> 4;
570         }
571         break;
572      case 0x20:  /* tile/sprite palette settings
573                   Bit 0-3 - Palette 0 index 0
574                   Bit 4-7 - Palette 0 index 1 */
575      case 0x21:  /* Bit 0-3 - Palette 0 index 2
576                   Bit 4-7 - Palette 0 index 3 */
577      case 0x22:  /* Bit 0-3 - Palette 1 index 0
578                   Bit 4-7 - Palette 1 index 1 */
579      case 0x23:  /* Bit 0-3 - Palette 1 index 2
580                   Bit 4-7 - Palette 1 index 3 */
581      case 0x24:  /* Bit 0-3 - Palette 2 index 0
582                   Bit 4-7 - Palette 2 index 1 */
583      case 0x25:  /* Bit 0-3 - Palette 2 index 2
584                   Bit 4-7 - Palette 2 index 3 */
585      case 0x26:  /* Bit 0-3 - Palette 3 index 0
586                   Bit 4-7 - Palette 3 index 1 */
587      case 0x27:  /* Bit 0-3 - Palette 3 index 2
588                   Bit 4-7 - Palette 3 index 3 */
589      case 0x28:  /* Bit 0-3 - Palette 4 index 0
590                   Bit 4-7 - Palette 4 index 1 */
591      case 0x29:  /* Bit 0-3 - Palette 4 index 2
592                   Bit 4-7 - Palette 4 index 3 */
593      case 0x2a:  /* Bit 0-3 - Palette 5 index 0
594                   Bit 4-7 - Palette 5 index 1 */
595      case 0x2b:  /* Bit 0-3 - Palette 5 index 2
596                   Bit 4-7 - Palette 5 index 3 */
597      case 0x2c:  /* Bit 0-3 - Palette 6 index 0
598                   Bit 4-7 - Palette 6 index 1 */
599      case 0x2d:  /* Bit 0-3 - Palette 6 index 2
600                   Bit 4-7 - Palette 6 index 3 */
601      case 0x2e:  /* Bit 0-3 - Palette 7 index 0
602                   Bit 4-7 - Palette 7 index 1 */
603      case 0x2f:  /* Bit 0-3 - Palette 7 index 2
604                   Bit 4-7 - Palette 7 index 3 */
605      case 0x30:  /* Bit 0-3 - Palette 8 / Sprite Palette 0 index 0
606                   Bit 4-7 - Palette 8 / Sprite Palette 0 index 1 */
607      case 0x31:  /* Bit 0-3 - Palette 8 / Sprite Palette 0 index 2
608                   Bit 4-7 - Palette 8 / Sprite Palette 0 index 3 */
609      case 0x32:  /* Bit 0-3 - Palette 9 / Sprite Palette 1 index 0
610                   Bit 4-7 - Palette 9 / Sprite Palette 1 index 1 */
611      case 0x33:  /* Bit 0-3 - Palette 9 / Sprite Palette 1 index 2
612                   Bit 4-7 - Palette 9 / Sprite Palette 1 index 3 */
613      case 0x34:  /* Bit 0-3 - Palette 10 / Sprite Palette 2 index 0
614                   Bit 4-7 - Palette 10 / Sprite Palette 2 index 1 */
615      case 0x35:  /* Bit 0-3 - Palette 10 / Sprite Palette 2 index 2
616                   Bit 4-7 - Palette 10 / Sprite Palette 2 index 3 */
617      case 0x36:  /* Bit 0-3 - Palette 11 / Sprite Palette 3 index 0
618                   Bit 4-7 - Palette 11 / Sprite Palette 3 index 1 */
619      case 0x37:  /* Bit 0-3 - Palette 11 / Sprite Palette 3 index 2
620                   Bit 4-7 - Palette 11 / Sprite Palette 3 index 3 */
621      case 0x38:  /* Bit 0-3 - Palette 12 / Sprite Palette 4 index 0
622                   Bit 4-7 - Palette 12 / Sprite Palette 4 index 1 */
623      case 0x39:  /* Bit 0-3 - Palette 12 / Sprite Palette 4 index 2
624                   Bit 4-7 - Palette 12 / Sprite Palette 4 index 3 */
625      case 0x3a:  /* Bit 0-3 - Palette 13 / Sprite Palette 5 index 0
626                   Bit 4-7 - Palette 13 / Sprite Palette 5 index 1 */
627      case 0x3b:  /* Bit 0-3 - Palette 13 / Sprite Palette 5 index 2
628                   Bit 4-7 - Palette 13 / Sprite Palette 5 index 3 */
629      case 0x3c:  /* Bit 0-3 - Palette 14 / Sprite Palette 6 index 0
630                   Bit 4-7 - Palette 14 / Sprite Palette 6 index 1 */
631      case 0x3d:  /* Bit 0-3 - Palette 14 / Sprite Palette 6 index 2
632                   Bit 4-7 - Palette 14 / Sprite Palette 6 index 3 */
633      case 0x3e:  /* Bit 0-3 - Palette 15 / Sprite Palette 7 index 0
634                   Bit 4-7 - Palette 15 / Sprite Palette 7 index 1 */
635      case 0x3f:  /* Bit 0-3 - Palette 15 / Sprite Palette 7 index 2
636                   Bit 4-7 - Palette 15 / Sprite Palette 7 index 3 */
637         break;
638309      case 0x40:  /* DMA source address (low)
639                   Bit 0-7 - DMA source address bit 0-7
640                */
310                Bit 0-7 - DMA source address bit 0-7
311                */
641312      case 0x41:  /* DMA source address (high)
642                   Bit 0-7 - DMA source address bit 8-15
643                */
313                Bit 0-7 - DMA source address bit 8-15
314                */
644315      case 0x42:  /* DMA source bank
645                   Bit 0-7 - DMA source bank number
646                */
316                Bit 0-7 - DMA source bank number
317                */
647318      case 0x43:  /* DMA destination bank
648                   Bit 0-7 - DMA destination bank number
649                */
319                Bit 0-7 - DMA destination bank number
320                */
650321      case 0x44:  /* DMA destination address (low)
651                   Bit 0-7 - DMA destination address bit 0-7
652                */
322                Bit 0-7 - DMA destination address bit 0-7
323                */
653324      case 0x45:  /* DMA destination address (high)
654                   Bit 0-7 - DMA destination address bit 8-15
655                */
325                Bit 0-7 - DMA destination address bit 8-15
326                */
656327      case 0x46:  /* Size of copied data (low)
657                   Bit 0-7 - DMA size bit 0-7
658                */
328                Bit 0-7 - DMA size bit 0-7
329                */
659330      case 0x47:  /* Size of copied data (high)
660                   Bit 0-7 - DMA size bit 8-15
661                */
331                Bit 0-7 - DMA size bit 8-15
332                */
662333         break;
663334      case 0x48:  /* DMA control
664                   Bit 0-6 - Unknown
665                   Bit 7   - DMA stop/start
666                */
335                Bit 0-6 - Unknown
336                Bit 7   - DMA stop/start
337                */
667338         if (data & 0x80)
668339         {
669340            UINT32 src, dst;
670341            UINT16 length;
671
342           
672343            src = m_ws_portram[0x40] + (m_ws_portram[0x41] << 8) + (m_ws_portram[0x42] << 16);
673344            dst = m_ws_portram[0x44] + (m_ws_portram[0x45] << 8) + (m_ws_portram[0x43] << 16);
674345            length = m_ws_portram[0x46] + (m_ws_portram[0x47] << 8);
r241555r241556
679350               dst++;
680351            }
681352#ifdef MAME_DEBUG
682               logerror("DMA  src:%X dst:%X length:%d\n", src, dst, length);
353            logerror("DMA  src:%X dst:%X length:%d\n", src, dst, length);
683354#endif
684355            m_ws_portram[0x40] = src & 0xff;
685356            m_ws_portram[0x41] = (src >> 8) & 0xff;
r241555r241556
691362         }
692363         break;
693364      case 0x4a:  /* Sound DMA source address (low)
694                   Bit 0-7 - Sound DMA source address bit 0-7
695                */
365                Bit 0-7 - Sound DMA source address bit 0-7
366                */
696367         m_sound_dma.source = (m_sound_dma.source & 0x0fff00) | data;
697368         break;
698369      case 0x4b:  /* Sound DMA source address (high)
699                   Bit 0-7 - Sound DMA source address bit 8-15
700                */
370                Bit 0-7 - Sound DMA source address bit 8-15
371                */
701372         m_sound_dma.source = (m_sound_dma.source & 0x0f00ff) | (data << 8);
702373         break;
703374      case 0x4c:  /* Sound DMA source memory segment
704                   Bit 0-3 - Sound DMA source address segment
705                   Bit 4-7 - Unknown
706                */
375                Bit 0-3 - Sound DMA source address segment
376                Bit 4-7 - Unknown
377                */
707378         m_sound_dma.source = (m_sound_dma.source & 0xffff) | ((data & 0x0f) << 16);
708379         break;
709380      case 0x4d:  /* Unknown */
710381         break;
711382      case 0x4e:  /* Sound DMA transfer size (low)
712                   Bit 0-7 - Sound DMA transfer size bit 0-7
713                */
383                Bit 0-7 - Sound DMA transfer size bit 0-7
384                */
714385         m_sound_dma.size = (m_sound_dma.size & 0xff00) | data;
715386         break;
716387      case 0x4f:  /* Sound DMA transfer size (high)
717                   Bit 0-7 - Sound DMA transfer size bit 8-15
718                */
388                Bit 0-7 - Sound DMA transfer size bit 8-15
389                */
719390         m_sound_dma.size = (m_sound_dma.size & 0xff) | (data << 8);
720391         break;
721392      case 0x50:  /* Unknown */
722393      case 0x51:  /* Unknown */
723394         break;
724395      case 0x52:  /* Sound DMA start/stop
725                   Bit 0-6 - Unknown
726                   Bit 7   - Sound DMA stop/start
727                */
396                Bit 0-6 - Unknown
397                Bit 7   - Sound DMA stop/start
398                */
728399         m_sound_dma.enable = data;
729400         break;
730      case 0x60:  /* Video mode
731                   Bit 0-4 - Unknown
732                   Bit 5   - Packed mode 0 = not packed mode, 1 = packed mode
733                   Bit 6   - 4/16 colour mode select: 0 = 4 colour mode, 1 = 16 colour mode
734                   Bit 7   - monochrome/colour mode select: 0 = monochrome mode, 1 = colour mode
735                */
736         /*
737          * 111  - packed, 16 color, use 4000/8000, color
738          * 110  - not packed, 16 color, use 4000/8000, color
739          * 101  - packed, 4 color, use 2000, color
740          * 100  - not packed, 4 color, use 2000, color
741          * 011  - packed, 16 color, use 4000/8000, monochrome
742          * 010  - not packed, 16 color , use 4000/8000, monochrome
743          * 001  - packed, 4 color, use 2000, monochrome
744          * 000  - not packed, 4 color, use 2000, monochrome - Regular WS monochrome
745          */
746         if (m_system_type == TYPE_WSC)
747         {
748            m_vdp.color_mode = data & 0x80;
749            m_vdp.colors_16 = data & 0x40;
750            m_vdp.tile_packed = data & 0x20;
751         }
401      case 0x60:
402         m_vdp->reg_w(space, offset, data);
752403         break;
753404      case 0x80:  /* Audio 1 freq (lo)
754                   Bit 0-7 - Audio channel 1 frequency bit 0-7
755                */
405                Bit 0-7 - Audio channel 1 frequency bit 0-7
406                */
756407      case 0x81:  /* Audio 1 freq (hi)
757                   Bit 0-7 - Audio channel 1 frequency bit 8-15
758                */
408                Bit 0-7 - Audio channel 1 frequency bit 8-15
409                */
759410      case 0x82:  /* Audio 2 freq (lo)
760                   Bit 0-7 - Audio channel 2 frequency bit 0-7
761                */
411                Bit 0-7 - Audio channel 2 frequency bit 0-7
412                */
762413      case 0x83:  /* Audio 2 freq (hi)
763                   Bit 0-7 - Audio channel 2 frequency bit 8-15
764                */
414                Bit 0-7 - Audio channel 2 frequency bit 8-15
415                */
765416      case 0x84:  /* Audio 3 freq (lo)
766                   Bit 0-7 - Audio channel 3 frequency bit 0-7
767                */
417                Bit 0-7 - Audio channel 3 frequency bit 0-7
418                */
768419      case 0x85:  /* Audio 3 freq (hi)
769                   Bit 0-7 - Audio channel 3 frequency bit 8-15
770                */
420                Bit 0-7 - Audio channel 3 frequency bit 8-15
421                */
771422      case 0x86:  /* Audio 4 freq (lo)
772                   Bit 0-7 - Audio channel 4 frequency bit 0-7
773                */
423                Bit 0-7 - Audio channel 4 frequency bit 0-7
424                */
774425      case 0x87:  /* Audio 4 freq (hi)
775                   Bit 0-7 - Audio channel 4 frequency bit 8-15
776                */
426                Bit 0-7 - Audio channel 4 frequency bit 8-15
427                */
777428      case 0x88:  /* Audio 1 volume
778                   Bit 0-3 - Right volume audio channel 1
779                   Bit 4-7 - Left volume audio channel 1
780                */
429                Bit 0-3 - Right volume audio channel 1
430                Bit 4-7 - Left volume audio channel 1
431                */
781432      case 0x89:  /* Audio 2 volume
782                   Bit 0-3 - Right volume audio channel 2
783                   Bit 4-7 - Left volume audio channel 2
784                */
433                Bit 0-3 - Right volume audio channel 2
434                Bit 4-7 - Left volume audio channel 2
435                */
785436      case 0x8a:  /* Audio 3 volume
786                   Bit 0-3 - Right volume audio channel 3
787                   Bit 4-7 - Left volume audio channel 3
788                */
437                Bit 0-3 - Right volume audio channel 3
438                Bit 4-7 - Left volume audio channel 3
439                */
789440      case 0x8b:  /* Audio 4 volume
790                   Bit 0-3 - Right volume audio channel 4
791                   Bit 4-7 - Left volume audio channel 4
792                */
441                Bit 0-3 - Right volume audio channel 4
442                Bit 4-7 - Left volume audio channel 4
443                */
793444      case 0x8c:  /* Sweep step
794                   Bit 0-7 - Sweep step
795                */
445                Bit 0-7 - Sweep step
446                */
796447      case 0x8d:  /* Sweep time
797                   Bit 0-7 - Sweep time
798                */
448                Bit 0-7 - Sweep time
449                */
799450      case 0x8e:  /* Noise control
800                   Bit 0-2 - Noise generator type
801                   Bit 3   - Reset
802                   Bit 4   - Enable
803                   Bit 5-7 - Unknown
804                */
451                Bit 0-2 - Noise generator type
452                Bit 3   - Reset
453                Bit 4   - Enable
454                Bit 5-7 - Unknown
455                */
805456      case 0x8f:  /* Sample location
806                   Bit 0-7 - Sample address location 0 00xxxxxx xx000000
807                */
457                Bit 0-7 - Sample address location 0 00xxxxxx xx000000
458                */
808459      case 0x90:  /* Audio control
809                   Bit 0   - Audio 1 enable
810                   Bit 1   - Audio 2 enable
811                   Bit 2   - Audio 3 enable
812                   Bit 3   - Audio 4 enable
813                   Bit 4   - Unknown
814                   Bit 5   - Audio 2 voice mode enable
815                   Bit 6   - Audio 3 sweep mode enable
816                   Bit 7   - Audio 4 noise mode enable
817                */
460                Bit 0   - Audio 1 enable
461                Bit 1   - Audio 2 enable
462                Bit 2   - Audio 3 enable
463                Bit 3   - Audio 4 enable
464                Bit 4   - Unknown
465                Bit 5   - Audio 2 voice mode enable
466                Bit 6   - Audio 3 sweep mode enable
467                Bit 7   - Audio 4 noise mode enable
468                */
818469      case 0x91:  /* Audio output
819                   Bit 0   - Mono select
820                   Bit 1-2 - Output volume
821                   Bit 3   - External stereo
822                   Bit 4-6 - Unknown
823                   Bit 7   - External speaker (Read-only, set by hardware)
824                */
470                Bit 0   - Mono select
471                Bit 1-2 - Output volume
472                Bit 3   - External stereo
473                Bit 4-6 - Unknown
474                Bit 7   - External speaker (Read-only, set by hardware)
475                */
825476      case 0x92:  /* Noise counter shift register (lo)
826                   Bit 0-7 - Noise counter shift register bit 0-7
827                */
477                Bit 0-7 - Noise counter shift register bit 0-7
478                */
828479      case 0x93:  /* Noise counter shift register (hi)
829                   Bit 0-6 - Noise counter shift register bit 8-14
830                   bit 7   - Unknown
831                */
480                Bit 0-6 - Noise counter shift register bit 8-14
481                bit 7   - Unknown
482                */
832483      case 0x94:  /* Master volume
833                   Bit 0-3 - Master volume
834                   Bit 4-7 - Unknown
835                */
484                Bit 0-3 - Master volume
485                Bit 4-7 - Unknown
486                */
836487         m_sound->port_w(space, offset, data);
837488         break;
838489      case 0xa0:  /* Hardware type - this is probably read only
839                   Bit 0   - Enable cartridge slot and/or disable bios
840                   Bit 1   - Hardware type: 0 = WS, 1 = WSC
841                   Bit 2-7 - Unknown
842                */
490                Bit 0   - Enable cartridge slot and/or disable bios
491                Bit 1   - Hardware type: 0 = WS, 1 = WSC
492                Bit 2-7 - Unknown
493                */
843494         if ((data & 0x01) && !m_bios_disabled)
844495            m_bios_disabled = 1;
845496         break;
846      case 0xa2:  /* Timer control
847                   Bit 0   - HBlank Timer enable
848                   Bit 1   - HBlank Timer mode: 0 = one shot, 1 = auto reset
849                   Bit 2   - VBlank Timer(1/75s) enable
850                   Bit 3   - VBlank Timer mode: 0 = one shot, 1 = auto reset
851                   Bit 4-7 - Unknown
852                */
853         m_vdp.timer_hblank_enable = BIT(data, 0);
854         m_vdp.timer_hblank_mode =   BIT(data, 1);
855         m_vdp.timer_vblank_enable = BIT(data, 2);
856         m_vdp.timer_vblank_mode =   BIT(data, 3);
857         break;
858      case 0xa4:  /* HBlank timer frequency (low) - reload value
859                   Bit 0-7 - HBlank timer reload value bit 0-7
860                */
861         m_vdp.timer_hblank_reload &= 0xff00;
862         m_vdp.timer_hblank_reload += data;
863         m_vdp.timer_hblank_count = m_vdp.timer_hblank_reload;
864         break;
865      case 0xa5:  /* HBlank timer frequency (high) - reload value
866                   Bit 8-15 - HBlank timer reload value bit 8-15
867                */
868         m_vdp.timer_hblank_reload &= 0xff;
869         m_vdp.timer_hblank_reload += data << 8;
870         m_vdp.timer_hblank_count = m_vdp.timer_hblank_reload;
871         break;
872      case 0xa6:  /* VBlank timer frequency (low) - reload value
873                   Bit 0-7 - VBlank timer reload value bit 0-7
874                */
875         m_vdp.timer_vblank_reload &= 0xff00;
876         m_vdp.timer_vblank_reload += data;
877         m_vdp.timer_vblank_count = m_vdp.timer_vblank_reload;
878         break;
879      case 0xa7:  /* VBlank timer frequency (high) - reload value
880                   Bit 0-7 - VBlank timer reload value bit 8-15
881                */
882         m_vdp.timer_vblank_reload &= 0xff;
883         m_vdp.timer_vblank_reload += data << 8;
884         m_vdp.timer_vblank_count = m_vdp.timer_vblank_reload;
885         break;
886      case 0xa8:  /* HBlank counter (low)
887                   Bit 0-7 - HBlank counter bit 0-7
888                */
889      case 0xa9:  /* HBlank counter (high)
890                   Bit 0-7 - HBlank counter bit 8-15
891                */
892      case 0xaa:  /* VBlank counter (low)
893                   Bit 0-7 - VBlank counter bit 0-7
894                */
895      case 0xab:  /* VBlank counter (high)
896                   Bit 0-7 - VBlank counter bit 8-15
897                */
898         break;
899
497         
900498      case 0xb0:  /* Interrupt base vector
901                   Bit 0-7 - Interrupt base vector
902                */
499                Bit 0-7 - Interrupt base vector
500                */
903501         break;
904502      case 0xb1:  /* Communication byte
905                   Bit 0-7 - Communication byte
906                */
503                Bit 0-7 - Communication byte
504                */
907505         break;
908506      case 0xb2:  /* Interrupt enable
909                   Bit 0   - Serial transmit interrupt enable
910                   Bit 1   - Key press interrupt enable
911                   Bit 2   - RTC alarm interrupt enable
912                   Bit 3   - Serial receive interrupt enable
913                   Bit 4   - Drawing line detection interrupt enable
914                   Bit 5   - VBlank timer interrupt enable
915                   Bit 6   - VBlank interrupt enable
916                   Bit 7   - HBlank timer interrupt enable
917                */
507                Bit 0   - Serial transmit interrupt enable
508                Bit 1   - Key press interrupt enable
509                Bit 2   - RTC alarm interrupt enable
510                Bit 3   - Serial receive interrupt enable
511                Bit 4   - Drawing line detection interrupt enable
512                Bit 5   - VBlank timer interrupt enable
513                Bit 6   - VBlank interrupt enable
514                Bit 7   - HBlank timer interrupt enable
515                */
918516         break;
919517      case 0xb3:  /* serial communication control
920                   Bit 0   - Receive complete
921                   Bit 1   - Error
922                   Bit 2   - Send complete
923                   Bit 3-4 - Unknown
924                   Bit 5   - Send data interrupt generation
925                   Bit 6   - Connection speed: 0 = 9600 bps, 1 = 38400 bps
926                   bit 7   - Receive data interrupt generation
927                */
928//          data |= 0x02;
518                Bit 0   - Receive complete
519                Bit 1   - Error
520                Bit 2   - Send complete
521                Bit 3-4 - Unknown
522                Bit 5   - Send data interrupt generation
523                Bit 6   - Connection speed: 0 = 9600 bps, 1 = 38400 bps
524                bit 7   - Receive data interrupt generation
525                */
526         //          data |= 0x02;
929527         m_ws_portram[0xb1] = 0xff;
930528         if (data & 0x80)
931529         {
932//              m_ws_portram[0xb1] = 0x00;
530            //              m_ws_portram[0xb1] = 0x00;
933531            data |= 0x04;
934532         }
935533         if (data & 0x20)
936534         {
937//              data |= 0x01;
535            //              data |= 0x01;
938536         }
939537         break;
940538      case 0xb5:  /* Read controls
941                   Bit 0-3 - Current state of input lines (read-only)
942                   Bit 4-6 - Select line of inputs to read
943                             001 - Read Y cursors
944                             010 - Read X cursors
945                             100 - Read START,A,B buttons
946                   Bit 7   - Unknown
947                */
539                Bit 0-3 - Current state of input lines (read-only)
540                Bit 4-6 - Select line of inputs to read
541                001 - Read Y cursors
542                010 - Read X cursors
543                100 - Read START,A,B buttons
544                Bit 7   - Unknown
545                */
948546         data = data & 0xf0;
949547         switch (data)
950         {
951            case 0x10:  /* Read Y cursors: Y1 - Y2 - Y3 - Y4 */
952               input = m_cursy->read();
953               if (m_rotate) // reorient controls if the console is rotated
954               {
955                  if (input & 0x01) data |= 0x02;
956                  if (input & 0x02) data |= 0x04;
957                  if (input & 0x04) data |= 0x08;
958                  if (input & 0x08) data |= 0x01;
959               }
960               else
961                  data = data | input;
548      {
549         case 0x10:  /* Read Y cursors: Y1 - Y2 - Y3 - Y4 */
550            input = m_cursy->read();
551            if (m_rotate) // reorient controls if the console is rotated
552            {
553               if (input & 0x01) data |= 0x02;
554               if (input & 0x02) data |= 0x04;
555               if (input & 0x04) data |= 0x08;
556               if (input & 0x08) data |= 0x01;
557            }
558            else
559               data = data | input;
962560            break;
963            case 0x20:  /* Read X cursors: X1 - X2 - X3 - X4 */
964               input = m_cursx->read();
965               if (m_rotate) // reorient controls if the console is rotated
966               {
967                  if (input & 0x01) data |= 0x02;
968                  if (input & 0x02) data |= 0x04;
969                  if (input & 0x04) data |= 0x08;
970                  if (input & 0x08) data |= 0x01;
971               }
972               else
973                  data = data | input;
561         case 0x20:  /* Read X cursors: X1 - X2 - X3 - X4 */
562            input = m_cursx->read();
563            if (m_rotate) // reorient controls if the console is rotated
564            {
565               if (input & 0x01) data |= 0x02;
566               if (input & 0x02) data |= 0x04;
567               if (input & 0x04) data |= 0x08;
568               if (input & 0x08) data |= 0x01;
569            }
570            else
571               data = data | input;
974572            break;
975            case 0x40:  /* Read buttons: START - A - B */
976               data = data | m_buttons->read();
573         case 0x40:  /* Read buttons: START - A - B */
574            data = data | m_buttons->read();
977575            break;
978         }
576      }
979577         break;
980578      case 0xb6:  /* Interrupt acknowledge
981                   Bit 0   - Serial transmit interrupt acknowledge
982                   Bit 1   - Key press interrupt acknowledge
983                   Bit 2   - RTC alarm interrupt acknowledge
984                   Bit 3   - Serial receive interrupt acknowledge
985                   Bit 4   - Drawing line detection interrupt acknowledge
986                   Bit 5   - VBlank timer interrupt acknowledge
987                   Bit 6   - VBlank interrupt acknowledge
988                   Bit 7   - HBlank timer interrupt acknowledge
989                */
990         wswan_clear_irq_line(data);
579                Bit 0   - Serial transmit interrupt acknowledge
580                Bit 1   - Key press interrupt acknowledge
581                Bit 2   - RTC alarm interrupt acknowledge
582                Bit 3   - Serial receive interrupt acknowledge
583                Bit 4   - Drawing line detection interrupt acknowledge
584                Bit 5   - VBlank timer interrupt acknowledge
585                Bit 6   - VBlank interrupt acknowledge
586                Bit 7   - HBlank timer interrupt acknowledge
587                */
588         clear_irq_line(data);
991589         data = m_ws_portram[0xb6];
992590         break;
993591      case 0xba:  /* Internal EEPROM data (low)
994                   Bit 0-7 - Internal EEPROM data transfer bit 0-7
995                */
592                Bit 0-7 - Internal EEPROM data transfer bit 0-7
593                */
996594      case 0xbb:  /* Internal EEPROM data (high)
997                   Bit 0-7 - Internal EEPROM data transfer bit 8-15
998                */
595                Bit 0-7 - Internal EEPROM data transfer bit 8-15
596                */
999597         break;
1000598      case 0xbc:  /* Internal EEPROM address (low)
1001                   Bit 0-7 - Internal EEPROM address bit 1-8
1002                */
599                Bit 0-7 - Internal EEPROM address bit 1-8
600                */
1003601      case 0xbd:  /* Internal EEPROM address (high)
1004                   Bit 0   - Internal EEPROM address bit 9(?)
1005                   Bit 1-7 - Unknown
1006                   Only 1KByte internal EEPROM??
1007                */
602                Bit 0   - Internal EEPROM address bit 9(?)
603                Bit 1-7 - Unknown
604                Only 1KByte internal EEPROM??
605                */
1008606         break;
1009607      case 0xbe:  /* Internal EEPROM command
1010                   Bit 0   - Read complete (read only)
1011                   Bit 1   - Write complete (read only)
1012                   Bit 2-3 - Unknown
1013                   Bit 4   - Read
1014                   Bit 5   - Write
1015                   Bit 6   - Protect
1016                   Bit 7   - Initialize
1017                */
608                Bit 0   - Read complete (read only)
609                Bit 1   - Write complete (read only)
610                Bit 2-3 - Unknown
611                Bit 4   - Read
612                Bit 5   - Write
613                Bit 6   - Protect
614                Bit 7   - Initialize
615                */
1018616         if (data & 0x20)
1019617         {
1020618            UINT16 addr = ( ( ( m_ws_portram[0xbd] << 8 ) | m_ws_portram[0xbc] ) << 1 ) & 0x1FF;
r241555r241556
1056654         logerror( "Write to unsupported port: %X - %X\n", offset, data );
1057655         break;
1058656   }
1059
657   
1060658   /* Update the port value */
1061659   m_ws_portram[offset] = data;
1062660}
1063
1064
1065TIMER_CALLBACK_MEMBER(wswan_state::wswan_scanline_interrupt)
1066{
1067   if( m_vdp.current_line < 144 )
1068   {
1069      wswan_refresh_scanline();
1070   }
1071
1072   /* Decrement 12kHz (HBlank) counter */
1073   if ( m_vdp.timer_hblank_enable && m_vdp.timer_hblank_reload != 0 )
1074   {
1075      m_vdp.timer_hblank_count--;
1076      logerror( "timer_hblank_count: %X\n", m_vdp.timer_hblank_count );
1077      if ( m_vdp.timer_hblank_count == 0 )
1078      {
1079         if ( m_vdp.timer_hblank_mode )
1080         {
1081            m_vdp.timer_hblank_count = m_vdp.timer_hblank_reload;
1082         }
1083         else
1084         {
1085            m_vdp.timer_hblank_reload = 0;
1086         }
1087         logerror( "trigerring hbltmr interrupt\n" );
1088         wswan_set_irq_line( WSWAN_IFLAG_HBLTMR );
1089      }
1090   }
1091
1092   /* Handle Sound DMA */
1093   if ( ( m_sound_dma.enable & 0x88 ) == 0x80 )
1094   {
1095      address_space &space = m_maincpu->space(AS_PROGRAM );
1096      /* TODO: Output sound DMA byte */
1097      port_w( space, 0x89, space.read_byte(m_sound_dma.source ) );
1098      m_sound_dma.size--;
1099      m_sound_dma.source = ( m_sound_dma.source + 1 ) & 0x0FFFFF;
1100      if ( m_sound_dma.size == 0 )
1101      {
1102         m_sound_dma.enable &= 0x7F;
1103      }
1104   }
1105
1106//  m_vdp.current_line = (m_vdp.current_line + 1) % 159;
1107
1108   if( m_vdp.current_line == 144 ) // buffer sprite table
1109   {
1110      memcpy(m_vdp.sprite_table_buffer, &m_vdp.vram[m_vdp.sprite_table_address], 512);
1111      m_vdp.sprite_count = m_ws_portram[0x06];
1112      m_vdp.sprite_first = m_ws_portram[0x05]; // always zero?
1113   }
1114
1115   if( m_vdp.current_line == 144 )
1116   {
1117      wswan_set_irq_line( WSWAN_IFLAG_VBL );
1118      /* Decrement 75Hz (VBlank) counter */
1119      if ( m_vdp.timer_vblank_enable && m_vdp.timer_vblank_reload != 0 )
1120      {
1121         m_vdp.timer_vblank_count--;
1122         logerror( "timer_vblank_count: %X\n", m_vdp.timer_vblank_count );
1123         if ( m_vdp.timer_vblank_count == 0 )
1124         {
1125            if ( m_vdp.timer_vblank_mode )
1126            {
1127               m_vdp.timer_vblank_count = m_vdp.timer_vblank_reload;
1128            }
1129            else
1130            {
1131               m_vdp.timer_vblank_reload = 0;
1132            }
1133            logerror( "triggering vbltmr interrupt\n" );
1134            wswan_set_irq_line( WSWAN_IFLAG_VBLTMR );
1135         }
1136      }
1137   }
1138
1139//  m_vdp.current_line = (m_vdp.current_line + 1) % 159;
1140
1141   if ( m_vdp.current_line == m_vdp.line_compare )
1142   {
1143      wswan_set_irq_line( WSWAN_IFLAG_LCMP );
1144   }
1145
1146   m_vdp.current_line = (m_vdp.current_line + 1) % 159;
1147}
trunk/src/mess/mess.mak
r241555r241556
10291029$(MESSOBJ)/bandai.a:            \
10301030   $(MESS_DRIVERS)/sv8000.o    \
10311031   $(MESS_DRIVERS)/rx78.o      \
1032   $(MESS_DRIVERS)/wswan.o $(MESS_AUDIO)/wswan_snd.o $(MESS_MACHINE)/wswan.o $(MESS_VIDEO)/wswan.o \
1032   $(MESS_DRIVERS)/wswan.o $(MESS_AUDIO)/wswan_snd.o $(MESS_MACHINE)/wswan.o $(MESS_VIDEO)/wswan_video.o \
10331033
10341034$(MESSOBJ)/be.a:                \
10351035   $(MESS_DRIVERS)/bebox.o $(MESS_MACHINE)/bebox.o \
trunk/src/mess/video/wswan.c
r241555r241556
1/***************************************************************************
2
3  wswan.c
4
5  File to handle video emulation of the Bandai WonderSwan.
6
7  Anthony Kruize
8  Wilbert Pol
9
10***************************************************************************/
11
12#include "includes/wswan.h"
13
14void wswan_state::wswan_setup_palettes()
15{
16   int i,j;
17
18   if ( m_vdp.color_mode ) {
19      for( i = 0; i < 16; i++ ) {
20         for( j = 0; j < 16; j++ ) {
21            m_pal[i][j] = ( ( m_vdp.palette_vram[ ( i << 5 ) + j*2 + 1 ] << 8 ) | m_vdp.palette_vram[ ( i << 5 ) + j*2 ] ) & 0x0FFF;
22         }
23      }
24   } else {
25      for( i = 0; i < 16; i++ ) {
26         m_pal[i][0] = m_ws_portram[ 0x20 + ( i << 1 ) ] & 0x07;
27         m_pal[i][1] = ( m_ws_portram[ 0x20 + ( i << 1 ) ] >> 4 ) & 0x07;
28         m_pal[i][2] = m_ws_portram[ 0x21 + ( i << 1 ) ] & 0x07;
29         m_pal[i][3] = ( m_ws_portram[ 0x21 + ( i << 1 ) ] >> 4 ) & 0x07;
30      }
31   }
32}
33
34void wswan_state::wswan_draw_background()
35{
36   UINT16  map_addr;
37   UINT8   start_column;
38   int column;
39
40   map_addr = m_vdp.layer_bg_address + ( ( ( m_vdp.current_line + m_vdp.layer_bg_scroll_y ) & 0xF8 ) << 3 );
41   start_column = ( m_vdp.layer_bg_scroll_x >> 3 );
42   for( column = 0; column < 29; column++ ) {
43      int tile_data, tile_number, tile_palette, tile_line, tile_address;
44      UINT32  plane0=0, plane1=0, plane2=0, plane3=0;
45      int x, x_offset;
46
47      tile_data = ( m_vdp.vram[ map_addr + ( ( ( start_column + column ) & 0x1F ) << 1 ) + 1 ] << 8 )
48               | m_vdp.vram[ map_addr + ( ( ( start_column + column ) & 0x1F ) << 1 ) ];
49      tile_number = tile_data & 0x01FF;
50      tile_palette = ( tile_data >> 9 ) & 0x0F;
51
52      tile_line = ( m_vdp.current_line + m_vdp.layer_bg_scroll_y ) & 0x07;
53      if ( tile_data & 0x8000 ) {
54         tile_line = 7 - tile_line;
55      }
56
57      if ( m_vdp.colors_16 ) {
58         tile_address = ( ( tile_data & 0x2000 ) ? 0x8000 : 0x4000 ) + ( tile_number * 32 ) + ( tile_line << 2 );
59         if ( m_vdp.tile_packed ) {
60            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 ];
61         } else {
62            plane0 = m_vdp.vram[ tile_address + 0 ];
63            plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
64            plane2 = m_vdp.vram[ tile_address + 2 ] << 2;
65            plane3 = m_vdp.vram[ tile_address + 3 ] << 3;
66         }
67      } else {
68         tile_address = 0x2000 + ( tile_number * 16 ) + ( tile_line << 1 );
69         if ( m_vdp.tile_packed ) {
70            plane0 = ( m_vdp.vram[ tile_address + 0 ] << 8 ) | m_vdp.vram[ tile_address + 1 ];
71         } else {
72            plane0 = m_vdp.vram[ tile_address + 0 ];
73            plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
74            plane2 = 0;
75            plane3 = 0;
76         }
77      }
78
79      for( x = 0; x < 8; x++ ) {
80         int col;
81         if ( m_vdp.tile_packed ) {
82            if ( m_vdp.colors_16 ) {
83               col = plane0 & 0x0F;
84               plane0 = plane0 >> 4;
85            } else {
86               col = plane0 & 0x03;
87               plane0 = plane0 >> 2;
88            }
89         } else {
90            col = ( plane3 & 8 ) | ( plane2 & 4 ) | ( plane1 & 2 ) | ( plane0 & 1 );
91            plane3 = plane3 >> 1;
92            plane2 = plane2 >> 1;
93            plane1 = plane1 >> 1;
94            plane0 = plane0 >> 1;
95         }
96         if ( tile_data & 0x4000 ) {
97            x_offset = x + ( column << 3 ) - ( m_vdp.layer_bg_scroll_x & 0x07 );
98         } else {
99            x_offset = 7 - x + ( column << 3 ) - ( m_vdp.layer_bg_scroll_x & 0x07 );
100         }
101         if ( x_offset >= 0 && x_offset < WSWAN_X_PIXELS ) {
102            if ( m_vdp.colors_16 ) {
103               if ( col ) {
104                  if ( m_vdp.color_mode ) {
105                     m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
106                  } else {
107                     /* Hmmmm, what should we do here... Is this correct?? */
108                     m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
109                  }
110               }
111            } else {
112               if ( col || !(tile_palette & 4 ) ) {
113                  if ( m_vdp.color_mode ) {
114                     m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
115                  } else {
116                     m_bitmap.pix16(m_vdp.current_line, x_offset) = m_vdp.main_palette[m_pal[tile_palette][col]];
117                  }
118               }
119            }
120         }
121      }
122   }
123}
124
125void wswan_state::wswan_draw_foreground_0()
126{
127   UINT16  map_addr;
128   UINT8   start_column;
129   int column;
130   map_addr = m_vdp.layer_fg_address + ( ( ( m_vdp.current_line + m_vdp.layer_fg_scroll_y ) & 0xF8 ) << 3 );
131   start_column = ( m_vdp.layer_fg_scroll_x >> 3 );
132   for( column = 0; column < 29; column++ ) {
133      UINT32  plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0;
134      int x, x_offset, tile_line, tile_address;
135      int tile_data = ( m_vdp.vram[ map_addr + ( ( ( start_column + column ) & 0x1F ) << 1 ) + 1 ] << 8 )
136                           | m_vdp.vram[ map_addr + ( ( ( start_column + column ) & 0x1F ) << 1 ) ];
137      int tile_number = tile_data & 0x01FF;
138      int tile_palette = ( tile_data >> 9 ) & 0x0F;
139
140      tile_line = ( m_vdp.current_line + m_vdp.layer_fg_scroll_y ) & 0x07;
141      if ( tile_data & 0x8000 ) {
142         tile_line = 7 - tile_line;
143      }
144
145      if ( m_vdp.colors_16 ) {
146         tile_address = ( ( tile_data & 0x2000 ) ? 0x8000 : 0x4000 ) + ( tile_number * 32 ) + ( tile_line << 2 );
147         if ( m_vdp.tile_packed ) {
148            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 ];
149         } else {
150            plane0 = m_vdp.vram[ tile_address + 0 ];
151            plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
152            plane2 = m_vdp.vram[ tile_address + 2 ] << 2;
153            plane3 = m_vdp.vram[ tile_address + 3 ] << 3;
154         }
155      } else {
156         tile_address = 0x2000 + ( tile_number * 16 ) + ( tile_line << 1 );
157         if ( m_vdp.tile_packed ) {
158            plane0 = ( m_vdp.vram[ tile_address + 0 ] << 8 ) | m_vdp.vram[ tile_address + 1 ];
159         } else {
160            plane0 = m_vdp.vram[ tile_address + 0 ];
161            plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
162            plane2 = 0;
163            plane3 = 0;
164         }
165      }
166
167      for( x = 0; x < 8; x++ ) {
168         int col;
169         if ( m_vdp.tile_packed ) {
170            if ( m_vdp.colors_16 ) {
171               col = plane0 & 0x0F;
172               plane0 = plane0 >> 4;
173            } else {
174               col = plane0 & 0x03;
175               plane0 = plane0 >> 2;
176            }
177         } else {
178            col = ( plane3 & 8 ) | ( plane2 & 4 ) | ( plane1 & 2 ) | ( plane0 & 1 );
179            plane3 = plane3 >> 1;
180            plane2 = plane2 >> 1;
181            plane1 = plane1 >> 1;
182            plane0 = plane0 >> 1;
183         }
184         if ( tile_data & 0x4000 ) {
185            x_offset = x + ( column << 3 ) - ( m_vdp.layer_fg_scroll_x & 0x07 );
186         } else {
187            x_offset = 7 - x + ( column << 3 ) - ( m_vdp.layer_fg_scroll_x & 0x07 );
188         }
189         if ( x_offset >= 0 && x_offset < WSWAN_X_PIXELS ) {
190            if ( m_vdp.colors_16 ) {
191               if ( col ) {
192//                      if ( m_vdp.color_mode ) {
193                     m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
194//                      } else {
195//                          /* Hmmmm, what should we do here... Is this correct?? */
196//                          m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
197//                      }
198               }
199            } else {
200               if ( col || !(tile_palette & 4 ) ) {
201                  if ( m_vdp.color_mode ) {
202                     m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
203                  } else {
204                     m_bitmap.pix16(m_vdp.current_line, x_offset) = m_vdp.main_palette[m_pal[tile_palette][col]];
205                  }
206               }
207            }
208         }
209      }
210   }
211}
212
213void wswan_state::wswan_draw_foreground_2()
214{
215   UINT16  map_addr;
216   UINT8   start_column;
217   int column;
218   map_addr = m_vdp.layer_fg_address + ( ( ( m_vdp.current_line + m_vdp.layer_fg_scroll_y ) & 0xF8 ) << 3 );
219   start_column = ( m_vdp.layer_fg_scroll_x >> 3 );
220   for( column = 0; column < 29; column++ ) {
221      UINT32  plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0;
222      int x, x_offset, tile_line, tile_address;
223      int tile_data = ( m_vdp.vram[ map_addr + ( ( ( start_column + column ) & 0x1F ) << 1 ) + 1 ] << 8 )
224                  | m_vdp.vram[ map_addr + ( ( ( start_column + column ) & 0x1F ) << 1 ) ];
225      int tile_number = tile_data & 0x01FF;
226      int tile_palette = ( tile_data >> 9 ) & 0x0F;
227
228      tile_line = ( m_vdp.current_line + m_vdp.layer_fg_scroll_y ) & 0x07;
229      if ( tile_data & 0x8000 ) {
230         tile_line = 7 - tile_line;
231      }
232
233      if ( m_vdp.colors_16 ) {
234         tile_address = ( ( tile_data & 0x2000 ) ? 0x8000 : 0x4000 ) + ( tile_number * 32 ) + ( tile_line << 2 );
235         if ( m_vdp.tile_packed ) {
236            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 ];
237         } else {
238            plane0 = m_vdp.vram[ tile_address + 0 ];
239            plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
240            plane2 = m_vdp.vram[ tile_address + 2 ] << 2;
241            plane3 = m_vdp.vram[ tile_address + 3 ] << 3;
242         }
243      } else {
244         tile_address = 0x2000 + ( tile_number * 16 ) + ( tile_line << 1 );
245         if ( m_vdp.tile_packed ) {
246            plane0 = ( m_vdp.vram[ tile_address + 0 ] << 8 ) | m_vdp.vram[ tile_address + 1 ];
247         } else {
248            plane0 = m_vdp.vram[ tile_address + 0 ];
249            plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
250            plane2 = 0;
251            plane3 = 0;
252         }
253      }
254
255      for( x = 0; x < 8; x++ ) {
256         int col;
257         if ( m_vdp.tile_packed ) {
258            if ( m_vdp.colors_16 ) {
259               col = plane0 & 0x0F;
260               plane0 = plane0 >> 4;
261            } else {
262               col = plane0 & 0x03;
263               plane0 = plane0 >> 2;
264            }
265         } else {
266            col = ( plane3 & 8 ) | ( plane2 & 4 ) | ( plane1 & 2 ) | ( plane0 & 1 );
267            plane3 = plane3 >> 1;
268            plane2 = plane2 >> 1;
269            plane1 = plane1 >> 1;
270            plane0 = plane0 >> 1;
271         }
272         if ( tile_data & 0x4000 ) {
273            x_offset = x + ( column << 3 ) - ( m_vdp.layer_fg_scroll_x & 0x07 );
274         } else {
275            x_offset = 7 - x + ( column << 3 ) - ( m_vdp.layer_fg_scroll_x & 0x07 );
276         }
277         if ( x_offset >= 0 && x_offset >= m_vdp.window_fg_left && x_offset < m_vdp.window_fg_right && x_offset < WSWAN_X_PIXELS ) {
278            if ( m_vdp.colors_16 ) {
279               if ( col ) {
280                  if ( m_vdp.color_mode ) {
281                     m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
282                  } else {
283                     /* Hmmmm, what should we do here... Is this correct?? */
284                     m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
285                  }
286               }
287            } else {
288               if ( col || !(tile_palette & 4 ) ) {
289                  if ( m_vdp.color_mode ) {
290                     m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
291                  } else {
292                     m_bitmap.pix16(m_vdp.current_line, x_offset) = m_vdp.main_palette[m_pal[tile_palette][col]];
293                  }
294               }
295            }
296         }
297      }
298   }
299}
300
301void wswan_state::wswan_draw_foreground_3()
302{
303   UINT16  map_addr;
304   UINT8   start_column;
305   int column;
306   map_addr = m_vdp.layer_fg_address + ( ( ( m_vdp.current_line + m_vdp.layer_fg_scroll_y ) & 0xF8 ) << 3 );
307   start_column = ( m_vdp.layer_fg_scroll_x >> 3 );
308   for( column = 0; column < 29; column++ ) {
309      UINT32  plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0;
310      int x, x_offset, tile_line, tile_address;
311      int tile_data = ( m_vdp.vram[ map_addr + ( ( ( start_column + column ) & 0x1F ) << 1 ) + 1 ] << 8 )
312                  | m_vdp.vram[ map_addr + ( ( ( start_column + column ) & 0x1F ) << 1 ) ];
313      int tile_number = tile_data & 0x01FF;
314      int tile_palette = ( tile_data >> 9 ) & 0x0F;
315
316      tile_line = ( m_vdp.current_line + m_vdp.layer_fg_scroll_y ) & 0x07;
317      if ( tile_data & 0x8000 ) { // vflip
318         tile_line = 7 - tile_line;
319      }
320
321      if ( m_vdp.colors_16 ) {
322         tile_address = ( ( tile_data & 0x2000 ) ? 0x8000 : 0x4000 ) + ( tile_number * 32 ) + ( tile_line << 2 );
323         if ( m_vdp.tile_packed ) {
324            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 ];
325         } else {
326            plane0 = m_vdp.vram[ tile_address + 0 ];
327            plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
328            plane2 = m_vdp.vram[ tile_address + 2 ] << 2;
329            plane3 = m_vdp.vram[ tile_address + 3 ] << 3;
330         }
331      } else {
332         tile_address = 0x2000 + ( tile_number * 16 ) + ( tile_line << 1 );
333         if ( m_vdp.tile_packed ) {
334            plane0 = ( m_vdp.vram[ tile_address + 0 ] << 8 ) | m_vdp.vram[ tile_address + 1 ];
335         } else {
336            plane0 = m_vdp.vram[ tile_address + 0 ];
337            plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
338            plane2 = 0;
339            plane3 = 0;
340         }
341      }
342
343      for( x = 0; x < 8; x++ ) {
344         int col;
345         if ( m_vdp.tile_packed ) {
346            if ( m_vdp.colors_16 ) {
347               col = plane0 & 0x0F;
348               plane0 = plane0 >> 4;
349            } else {
350               col = plane0 & 0x03;
351               plane0 = plane0 >> 2;
352            }
353         } else {
354            col = ( plane3 & 8 ) | ( plane2 & 4 ) | ( plane1 & 2 ) | ( plane0 & 1 );
355            plane3 = plane3 >> 1;
356            plane2 = plane2 >> 1;
357            plane1 = plane1 >> 1;
358            plane0 = plane0 >> 1;
359         }
360         if ( tile_data & 0x4000 ) {
361            x_offset = x + ( column << 3 ) - ( m_vdp.layer_fg_scroll_x & 0x07 );
362         } else {
363            x_offset = 7 - x + ( column << 3 ) - ( m_vdp.layer_fg_scroll_x & 0x07 );
364         }
365         if ( ( x_offset >= 0 && x_offset < m_vdp.window_fg_left ) || ( x_offset >= m_vdp.window_fg_right && x_offset < WSWAN_X_PIXELS ) ) {
366            if ( m_vdp.colors_16 ) {
367               if ( col ) {
368                  if ( m_vdp.color_mode ) {
369                     m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
370                  } else {
371                     /* Hmmmm, what should we do here... Is this correct?? */
372                     m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
373                  }
374               }
375            } else {
376               if ( col || !(tile_palette & 4 ) ) {
377                  if ( m_vdp.color_mode ) {
378                     m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
379                  } else {
380                     m_bitmap.pix16(m_vdp.current_line, x_offset) = m_vdp.main_palette[m_pal[tile_palette][col]];
381                  }
382               }
383            }
384         }
385      }
386   }
387}
388
389void wswan_state::wswan_handle_sprites(int mask )
390{
391   int i;
392   if ( m_vdp.sprite_count == 0 )
393      return;
394   for( i = m_vdp.sprite_first + m_vdp.sprite_count - 1; i >= m_vdp.sprite_first; i-- ) {
395      UINT8   x, y;
396      UINT16  tile_data;
397      int tile_line;
398
399      tile_data = ( m_vdp.sprite_table_buffer[ i * 4 + 1 ] << 8 ) | m_vdp.sprite_table_buffer[ i * 4 ];
400      y = m_vdp.sprite_table_buffer[ i * 4 + 2 ];
401      x = m_vdp.sprite_table_buffer[ i * 4 + 3 ];
402      tile_line = m_vdp.current_line - y;
403      tile_line = tile_line & 0xFF;
404      if ( ( tile_line >= 0 ) && ( tile_line < 8 ) && ( ( tile_data & 0x2000 ) == mask ) ) {
405         UINT32  plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0;
406         int j, x_offset, tile_address;
407         int tile_number = tile_data & 0x01FF;
408         int tile_palette = 8 + ( ( tile_data >> 9 ) & 0x07 );
409         int check_clip = 0;
410         if ( tile_data & 0x8000 ) {
411            tile_line = 7 - tile_line;
412         }
413
414         if ( m_vdp.colors_16 ) {
415            tile_address = 0x4000 + ( tile_number * 32 ) + ( tile_line << 2 );
416            if ( m_vdp.tile_packed ) {
417               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 ];
418            } else {
419               plane0 = m_vdp.vram[ tile_address + 0 ];
420               plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
421               plane2 = m_vdp.vram[ tile_address + 2 ] << 2;
422               plane3 = m_vdp.vram[ tile_address + 3 ] << 3;
423            }
424         } else {
425            tile_address = 0x2000 + ( tile_number * 16 ) + ( tile_line << 1 );
426            if ( m_vdp.tile_packed ) {
427               plane0 = ( m_vdp.vram[ tile_address + 0 ] << 8 ) | m_vdp.vram[ tile_address + 1 ];
428            } else {
429               plane0 = m_vdp.vram[ tile_address + 0 ];
430               plane1 = m_vdp.vram[ tile_address + 1 ] << 1;
431               plane2 = 0;
432               plane3 = 0;
433            }
434         }
435
436         if ( m_vdp.window_sprites_enable ) {
437            if ( tile_data & 0x1000 ) {
438               if ( m_vdp.current_line >= m_vdp.window_sprites_top && m_vdp.current_line <= m_vdp.window_sprites_bottom ) {
439                  check_clip = 1;
440               }
441            } else {
442               if ( m_vdp.current_line < m_vdp.window_sprites_top || m_vdp.current_line > m_vdp.window_sprites_bottom ) {
443                  continue;
444               }
445            }
446         }
447
448         for ( j = 0; j < 8; j++ ) {
449            int col;
450            if ( m_vdp.tile_packed ) {
451               if ( m_vdp.colors_16 ) {
452                  col = plane0 & 0x0F;
453                  plane0 = plane0 >> 4;
454               } else {
455                  col = plane0 & 0x03;
456                  plane0 = plane0 >> 2;
457               }
458            } else {
459               col = ( plane3 & 8 ) | ( plane2 & 4 ) | ( plane1 & 2 ) | ( plane0 & 1 );
460               plane3 = plane3 >> 1;
461               plane2 = plane2 >> 1;
462               plane1 = plane1 >> 1;
463               plane0 = plane0 >> 1;
464            }
465            if ( tile_data & 0x4000 ) {
466               x_offset = x + j;
467            } else {
468               x_offset = x + 7 - j;
469            }
470            x_offset = x_offset & 0xFF;
471            if ( m_vdp.window_sprites_enable ) {
472               if ( tile_data & 0x1000 && check_clip ) {
473                  if ( x_offset >= m_vdp.window_sprites_left && x_offset <= m_vdp.window_sprites_right ) {
474                     continue;
475                  }
476               } else {
477                  if ( x_offset < m_vdp.window_sprites_left || x_offset > m_vdp.window_sprites_right ) {
478//                          continue;
479                  }
480               }
481            }
482            if ( x_offset >= 0 && x_offset < WSWAN_X_PIXELS ) {
483               if ( m_vdp.colors_16 ) {
484                  if ( col ) {
485                     if ( m_vdp.color_mode ) {
486                        m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
487                     } else {
488                        /* Hmmmm, what should we do here... Is this correct?? */
489                        m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
490                     }
491                  }
492               } else {
493                  if ( col || !(tile_palette & 4 ) ) {
494                     if ( m_vdp.color_mode ) {
495                        m_bitmap.pix16(m_vdp.current_line, x_offset) = m_pal[tile_palette][col];
496                     } else {
497                        m_bitmap.pix16(m_vdp.current_line, x_offset) = m_vdp.main_palette[m_pal[tile_palette][col]];
498                     }
499                  }
500               }
501            }
502         }
503      }
504   }
505}
506
507void wswan_state::wswan_refresh_scanline()
508{
509   wswan_setup_palettes();
510
511   rectangle rec(0, WSWAN_X_PIXELS, m_vdp.current_line, m_vdp.current_line);
512   if ( m_ws_portram[0x14] ) {
513      /* Not sure if these background color checks and settings are correct */
514      if ( m_vdp.color_mode && m_vdp.colors_16 ) {
515         m_bitmap.fill( m_pal[m_ws_portram[0x01]>>4][m_ws_portram[0x01]&0x0F], rec );
516      } else {
517         m_bitmap.fill( m_vdp.main_palette[m_ws_portram[0x01]&0x07], rec );
518      }
519   } else {
520      m_bitmap.fill( 0, rec );
521      return;
522   }
523
524   /*
525    * Draw background layer
526    */
527   if ( m_vdp.layer_bg_enable ) {
528      wswan_draw_background();
529   }
530
531   /*
532    * Draw sprites between background and foreground layers
533    */
534   if ( m_vdp.sprites_enable ) {
535      wswan_handle_sprites(0);
536   }
537
538   /*
539    * Draw foreground layer, taking window settings into account
540    */
541   if ( m_vdp.layer_fg_enable ) {
542      switch( m_vdp.window_fg_mode ) {
543      case 0: /* FG inside & outside window area */
544         wswan_draw_foreground_0();
545         break;
546      case 1: /* ??? */
547         logerror( "Unknown foreground mode 1 set\n" );
548         break;
549      case 2: /* FG only inside window area */
550         if ( m_vdp.current_line >= m_vdp.window_fg_top && m_vdp.current_line <= m_vdp.window_fg_bottom ) {
551            wswan_draw_foreground_2();
552         }
553         break;
554      case 3: /* FG only outside window area */
555         if ( m_vdp.current_line < m_vdp.window_fg_top || m_vdp.current_line > m_vdp.window_fg_bottom ) {
556            wswan_draw_foreground_0();
557         } else {
558            wswan_draw_foreground_3();
559         }
560         break;
561      }
562   }
563
564   /*
565    * Draw sprites in front of foreground layer
566    */
567   if ( m_vdp.sprites_enable ) {
568      wswan_handle_sprites(0x2000);
569   }
570}
571
572
573void wswan_state::video_start()
574{
575   machine().first_screen()->register_screen_bitmap(m_bitmap);
576   save_item(NAME(m_bitmap));
577}
578
579UINT32 wswan_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
580{
581   copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect);
582   return 0;
583}
trunk/src/mess/video/wswan_video.c
r0r241556
1/***************************************************************************
2 
3 wswan_video.c
4 
5 File to handle video emulation of the Bandai WonderSwan VDP.
6 
7 Anthony Kruize
8 Wilbert Pol
9 
10 TODO:
11   - remove the redundant parts of m_regs
12   - split the Color VDP from the Mono VDP?
13 
14 ***************************************************************************/
15
16#include "wswan_video.h"
17
18const device_type WSWAN_VIDEO = &device_creator<wswan_video_device>;
19
20
21wswan_video_device::wswan_video_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
22               : device_t(mconfig, WSWAN_VIDEO, "Bandai WonderSwan VDP", tag, owner, clock, "wswan_video", __FILE__),
23               m_vdp_type(VDP_TYPE_WSWAN)
24{
25}
26
27
28void wswan_video_device::common_save()
29{
30   save_item(NAME(m_bitmap));
31   save_item(NAME(m_vram));
32   save_item(NAME(m_palette_port));
33   save_item(NAME(m_pal));
34   save_item(NAME(m_regs));
35   
36   save_item(NAME(m_layer_bg_enable));
37   save_item(NAME(m_layer_fg_enable));
38   save_item(NAME(m_sprites_enable));
39   save_item(NAME(m_window_sprites_enable));
40   save_item(NAME(m_window_fg_mode));
41   save_item(NAME(m_bg_control));
42   save_item(NAME(m_current_line));
43   save_item(NAME(m_line_compare));
44   save_item(NAME(m_sprite_table_address));
45   save_item(NAME(m_sprite_table_buffer));
46   save_item(NAME(m_sprite_first));
47   save_item(NAME(m_sprite_count));
48   save_item(NAME(m_sprite_first_latch));
49   save_item(NAME(m_sprite_count_latch));
50   save_item(NAME(m_layer_bg_address));
51   save_item(NAME(m_layer_fg_address));
52   save_item(NAME(m_window_fg_left));
53   save_item(NAME(m_window_fg_top));
54   save_item(NAME(m_window_fg_right));
55   save_item(NAME(m_window_fg_bottom));
56   save_item(NAME(m_window_sprites_left));
57   save_item(NAME(m_window_sprites_top));
58   save_item(NAME(m_window_sprites_right));
59   save_item(NAME(m_window_sprites_bottom));
60   save_item(NAME(m_layer_bg_scroll_x));
61   save_item(NAME(m_layer_bg_scroll_y));
62   save_item(NAME(m_layer_fg_scroll_x));
63   save_item(NAME(m_layer_fg_scroll_y));
64   save_item(NAME(m_lcd_control));
65   save_item(NAME(m_icons));
66   save_item(NAME(m_color_mode));
67   save_item(NAME(m_colors_16));
68   save_item(NAME(m_tile_packed));
69   save_item(NAME(m_timer_hblank_enable));
70   save_item(NAME(m_timer_hblank_mode));
71   save_item(NAME(m_timer_hblank_reload));
72   save_item(NAME(m_timer_vblank_enable));
73   save_item(NAME(m_timer_vblank_mode));
74   save_item(NAME(m_timer_vblank_reload));
75   save_item(NAME(m_timer_vblank_count));
76   save_item(NAME(m_main_palette));
77}
78
79void wswan_video_device::device_start()
80{
81   machine().first_screen()->register_screen_bitmap(m_bitmap);
82   
83   m_timer = timer_alloc(TIMER_SCANLINE);
84   m_timer->adjust(attotime::from_ticks(256, 3072000), 0, attotime::from_ticks(256, 3072000));
85   
86   // bind callbacks
87   m_set_irq_cb.bind_relative_to(*owner());
88   m_snd_dma_cb.bind_relative_to(*owner());
89
90   if (m_vdp_type == VDP_TYPE_WSC)
91   {
92      m_vram.resize_and_clear(0x10000);
93      m_palette_vram = m_vram + 0xfe00;
94   }
95   else
96   {
97      m_vram.resize_and_clear(0x4000);
98      m_palette_vram = m_vram;
99   }
100
101   common_save();
102}
103
104// This is a copy of ws_portram_init
105// TODO: remove unneeded parts!
106static const UINT8 vdp_regs_init[256] =
107{
108   0x00, 0x00, 0x00/*?*/, 0xbb, 0x00, 0x00, 0x00, 0x26, 0xfe, 0xde, 0xf9, 0xfb, 0xdb, 0xd7, 0x7f, 0xf5,
109   0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x9e, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x99, 0xfd, 0xb7, 0xdf,
110   0x30, 0x57, 0x75, 0x76, 0x15, 0x73, 0x70/*77?*/, 0x77, 0x20, 0x75, 0x50, 0x36, 0x70, 0x67, 0x50, 0x77,
111   0x57, 0x54, 0x75, 0x77, 0x75, 0x17, 0x37, 0x73, 0x50, 0x57, 0x60, 0x77, 0x70, 0x77, 0x10, 0x73,
112   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114   0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00,
115   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00,
117   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
118   0x87, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119   0x00, 0xdb, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x83, 0x00,
120   0x2f, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
121   0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
122   0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
123   0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1
124};
125
126
127void wswan_video_device::device_reset()
128{
129   m_layer_bg_enable = 0;
130   m_layer_fg_enable = 0;
131   m_sprites_enable = 0;
132   m_window_sprites_enable = 0;
133   m_window_fg_mode = 0;
134   m_bg_control = 0;
135   m_current_line = 145;  // Randomly chosen, beginning of VBlank period to give cart some time to boot up
136   m_line_compare = 0;
137   m_sprite_table_address = 0;
138   m_sprite_first = 0;
139   m_sprite_count = 0;
140   m_sprite_first_latch = 0;
141   m_sprite_count_latch = 0;
142   m_layer_bg_address = 0;
143   m_layer_fg_address = 0;
144   m_window_fg_left = 0;
145   m_window_fg_top = 0;
146   m_window_fg_right = 0;
147   m_window_fg_bottom = 0;
148   m_window_sprites_left = 0;
149   m_window_sprites_top = 0;
150   m_window_sprites_right = 0;
151   m_window_sprites_bottom = 0;
152   m_layer_bg_scroll_x = 0;
153   m_layer_bg_scroll_y = 0;
154   m_layer_fg_scroll_x = 0;
155   m_layer_fg_scroll_y = 0;
156   m_lcd_control = 0x01;
157   m_icons = 0;
158   m_color_mode = 0;
159   m_colors_16 = 0;
160   m_tile_packed = 0;
161   m_timer_hblank_enable = 0;
162   m_timer_hblank_mode = 0;
163   m_timer_hblank_reload = 0;
164   m_timer_hblank_count = 0;
165   m_timer_vblank_enable = 0;
166   m_timer_vblank_mode = 0;
167   m_timer_vblank_reload = 0;
168   m_timer_vblank_count = 0;      /* Vertical blank timer counter value */
169   
170   memset(m_sprite_table_buffer, 0, sizeof(m_sprite_table_buffer));
171   memset(m_main_palette, 0, sizeof(m_main_palette));
172   memcpy(m_regs, vdp_regs_init, 256);
173   for (int i = 0; i < 0x20; i++)
174      m_palette_port[i] = m_regs[i + 0x20];
175
176   setup_palettes();
177}
178
179
180void wswan_video_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
181{
182   switch (id)
183   {
184      case TIMER_SCANLINE:
185         scanline_interrupt();
186         break;
187   }
188}
189
190
191void wswan_video_device::setup_palettes()
192{
193   if (m_color_mode)
194   {
195      for (int i = 0; i < 16; i++)
196         for (int j = 0; j < 16; j++)
197            m_pal[i][j] = ((m_palette_vram[(i << 5) + j * 2 + 1] << 8) | m_palette_vram[(i << 5) + j * 2]) & 0x0fff;
198   }
199   else
200   {
201      for (int  i = 0; i < 16; i++)
202      {
203         m_pal[i][0] = (m_palette_port[(i << 1)] >> 0) & 0x07;
204         m_pal[i][1] = (m_palette_port[(i << 1)] >> 4) & 0x07;
205         m_pal[i][2] = (m_palette_port[(i << 1) + 1] >> 0) & 0x07;
206         m_pal[i][3] = (m_palette_port[(i << 1) + 1] >> 4) & 0x07;
207      }
208   }
209}
210
211void wswan_video_device::draw_background()
212{
213   UINT16 map_addr = m_layer_bg_address + (((m_current_line + m_layer_bg_scroll_y) & 0xf8) << 3);
214   UINT8 start_column = (m_layer_bg_scroll_x >> 3);
215   
216   for (int column = 0; column < 29; column++)
217   {
218      UINT32 plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0;
219      int x_offset, tile_line, tile_address;
220      int tile_data =  (m_vram[map_addr + (((start_column + column) & 0x1f) << 1) + 1] << 8)
221                  | m_vram[map_addr + (((start_column + column) & 0x1f) << 1)];
222      int tile_number = tile_data & 0x01ff;
223      int tile_palette = (tile_data >> 9) & 0x0f;
224     
225      tile_line = (m_current_line + m_layer_bg_scroll_y) & 0x07;
226      if (tile_data & 0x8000) // vflip
227         tile_line = 7 - tile_line;
228     
229      if (m_colors_16)
230      {
231         tile_address = ((tile_data & 0x2000) ? 0x8000 : 0x4000) + (tile_number * 32) + (tile_line << 2);
232         if (m_tile_packed)
233         {
234            plane0 = (m_vram[tile_address + 0] << 24) | (m_vram[tile_address + 1] << 16) | (m_vram[tile_address + 2] << 8) | m_vram[tile_address + 3];
235         }
236         else
237         {
238            plane0 = m_vram[tile_address + 0];
239            plane1 = m_vram[tile_address + 1] << 1;
240            plane2 = m_vram[tile_address + 2] << 2;
241            plane3 = m_vram[tile_address + 3] << 3;
242         }
243      }
244      else
245      {
246         tile_address = 0x2000 + (tile_number * 16) + (tile_line << 1);
247         if (m_tile_packed)
248         {
249            plane0 = (m_vram[tile_address + 0] << 8) | m_vram[tile_address + 1];
250         }
251         else
252         {
253            plane0 = m_vram[tile_address + 0];
254            plane1 = m_vram[tile_address + 1] << 1;
255            plane2 = 0;
256            plane3 = 0;
257         }
258      }
259     
260      for (int x = 0; x < 8; x++)
261      {
262         int col;
263         if (m_tile_packed)
264         {
265            if (m_colors_16)
266            {
267               col = plane0 & 0x0f;
268               plane0 = plane0 >> 4;
269            }
270            else
271            {
272               col = plane0 & 0x03;
273               plane0 = plane0 >> 2;
274            }
275         }
276         else
277         {
278            col = (plane3 & 8) | (plane2 & 4) | (plane1 & 2) | (plane0 & 1);
279            plane3 = plane3 >> 1;
280            plane2 = plane2 >> 1;
281            plane1 = plane1 >> 1;
282            plane0 = plane0 >> 1;
283         }
284
285         if (tile_data & 0x4000)
286            x_offset = x + (column << 3) - (m_layer_bg_scroll_x & 0x07);
287         else
288            x_offset = 7 - x + (column << 3) - (m_layer_bg_scroll_x & 0x07);
289
290         if (x_offset >= 0 && x_offset < WSWAN_X_PIXELS)
291         {
292            if (m_colors_16)
293            {
294               if (col)
295               {
296                  if (m_color_mode)
297                     m_bitmap.pix16(m_current_line, x_offset) = m_pal[tile_palette][col];
298                  else
299                  {
300                     /* Hmmmm, what should we do here... Is this correct?? */
301                     m_bitmap.pix16(m_current_line, x_offset) = m_pal[tile_palette][col];
302                  }
303               }
304            }
305            else
306            {
307               if (col || !(tile_palette & 4))
308               {
309                  if (m_color_mode)
310                     m_bitmap.pix16(m_current_line, x_offset) = m_pal[tile_palette][col];
311                  else
312                     m_bitmap.pix16(m_current_line, x_offset) = m_main_palette[m_pal[tile_palette][col]];
313               }
314            }
315         }
316      }
317   }
318}
319
320void wswan_video_device::draw_foreground_0()
321{
322   UINT16 map_addr = m_layer_fg_address + (((m_current_line + m_layer_fg_scroll_y) & 0xf8) << 3);
323   UINT8 start_column = (m_layer_fg_scroll_x >> 3);
324
325   for (int column = 0; column < 29; column++)
326   {
327      UINT32 plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0;
328      int x_offset, tile_line, tile_address;
329      int tile_data =  (m_vram[map_addr + (((start_column + column) & 0x1f) << 1) + 1] << 8)
330                  | m_vram[map_addr + (((start_column + column) & 0x1f) << 1)];
331      int tile_number = tile_data & 0x01ff;
332      int tile_palette = (tile_data >> 9) & 0x0f;
333     
334      tile_line = (m_current_line + m_layer_fg_scroll_y) & 0x07;
335      if (tile_data & 0x8000) // vflip
336         tile_line = 7 - tile_line;
337     
338      if (m_colors_16)
339      {
340         tile_address = ((tile_data & 0x2000) ? 0x8000 : 0x4000) + (tile_number * 32) + (tile_line << 2);
341         if (m_tile_packed)
342         {
343            plane0 = (m_vram[tile_address + 0] << 24) | (m_vram[tile_address + 1] << 16) | (m_vram[tile_address + 2] << 8) | m_vram[tile_address + 3];
344         }
345         else
346         {
347            plane0 = m_vram[tile_address + 0];
348            plane1 = m_vram[tile_address + 1] << 1;
349            plane2 = m_vram[tile_address + 2] << 2;
350            plane3 = m_vram[tile_address + 3] << 3;
351         }
352      }
353      else
354      {
355         tile_address = 0x2000 + (tile_number * 16) + (tile_line << 1);
356         if (m_tile_packed)
357         {
358            plane0 = (m_vram[tile_address + 0] << 8) | m_vram[tile_address + 1];
359         }
360         else
361         {
362            plane0 = m_vram[tile_address + 0];
363            plane1 = m_vram[tile_address + 1] << 1;
364            plane2 = 0;
365            plane3 = 0;
366         }
367      }
368
369      for (int x = 0; x < 8; x++ )
370      {
371         int col;
372         if (m_tile_packed)
373         {
374            if (m_colors_16)
375            {
376               col = plane0 & 0x0f;
377               plane0 = plane0 >> 4;
378            }
379            else
380            {
381               col = plane0 & 0x03;
382               plane0 = plane0 >> 2;
383            }
384         }
385         else
386         {
387            col = (plane3 & 8) | (plane2 & 4) | (plane1 & 2) | (plane0 & 1);
388            plane3 = plane3 >> 1;
389            plane2 = plane2 >> 1;
390            plane1 = plane1 >> 1;
391            plane0 = plane0 >> 1;
392         }
393
394         if (tile_data & 0x4000)
395            x_offset = x + (column << 3) - (m_layer_fg_scroll_x & 0x07);
396         else
397            x_offset = 7 - x + (column << 3) - (m_layer_fg_scroll_x & 0x07);
398
399         if (x_offset >= 0 && x_offset < WSWAN_X_PIXELS)
400         {
401            if (m_colors_16)
402            {
403               if (col)
404               {
405//                      if (m_color_mode) {
406                  m_bitmap.pix16(m_current_line, x_offset) = m_pal[tile_palette][col];
407//                      } else {
408//                          /* Hmmmm, what should we do here... Is this correct?? */
409//                          m_bitmap.pix16(m_current_line, x_offset) = m_pal[tile_palette][col];
410//                      }
411               }
412            }
413            else
414            {
415               if (col || !(tile_palette & 4))
416               {
417                  if (m_color_mode)
418                     m_bitmap.pix16(m_current_line, x_offset) = m_pal[tile_palette][col];
419                  else
420                     m_bitmap.pix16(m_current_line, x_offset) = m_main_palette[m_pal[tile_palette][col]];
421               }
422            }
423         }
424      }
425   }
426}
427
428void wswan_video_device::draw_foreground_2()
429{
430   UINT16 map_addr = m_layer_fg_address + (((m_current_line + m_layer_fg_scroll_y) & 0xf8) << 3);
431   UINT8 start_column = (m_layer_fg_scroll_x >> 3);
432   
433   for (int column = 0; column < 29; column++)
434   {
435      UINT32 plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0;
436      int x_offset, tile_line, tile_address;
437      int tile_data =  (m_vram[map_addr + (((start_column + column) & 0x1f) << 1) + 1] << 8)
438                  | m_vram[map_addr + (((start_column + column) & 0x1f) << 1)];
439      int tile_number = tile_data & 0x01ff;
440      int tile_palette = (tile_data >> 9) & 0x0f;
441     
442      tile_line = (m_current_line + m_layer_fg_scroll_y) & 0x07;
443      if (tile_data & 0x8000) // vflip
444         tile_line = 7 - tile_line;
445
446     
447      if (m_colors_16)
448      {
449         tile_address = ((tile_data & 0x2000) ? 0x8000 : 0x4000) + (tile_number * 32) + (tile_line << 2);
450         if (m_tile_packed)
451         {
452            plane0 = (m_vram[tile_address + 0] << 24) | (m_vram[tile_address + 1] << 16) | (m_vram[tile_address + 2] << 8) | m_vram[tile_address + 3];
453         }
454         else
455         {
456            plane0 = m_vram[tile_address + 0];
457            plane1 = m_vram[tile_address + 1] << 1;
458            plane2 = m_vram[tile_address + 2] << 2;
459            plane3 = m_vram[tile_address + 3] << 3;
460         }
461      }
462      else
463      {
464         tile_address = 0x2000 + (tile_number * 16) + (tile_line << 1);
465         if (m_tile_packed)
466         {
467            plane0 = (m_vram[tile_address + 0] << 8) | m_vram[tile_address + 1];
468         }
469         else
470         {
471            plane0 = m_vram[tile_address + 0];
472            plane1 = m_vram[tile_address + 1] << 1;
473            plane2 = 0;
474            plane3 = 0;
475         }
476      }
477
478      for (int x = 0; x < 8; x++)
479      {
480         int col;
481         if (m_tile_packed)
482         {
483            if (m_colors_16)
484            {
485               col = plane0 & 0x0f;
486               plane0 = plane0 >> 4;
487            }
488            else
489            {
490               col = plane0 & 0x03;
491               plane0 = plane0 >> 2;
492            }
493         }
494         else
495         {
496            col = (plane3 & 8) | (plane2 & 4) | (plane1 & 2) | (plane0 & 1);
497            plane3 = plane3 >> 1;
498            plane2 = plane2 >> 1;
499            plane1 = plane1 >> 1;
500            plane0 = plane0 >> 1;
501         }
502
503         if (tile_data & 0x4000)
504            x_offset = x + (column << 3) - (m_layer_fg_scroll_x & 0x07);
505         else
506            x_offset = 7 - x + (column << 3) - (m_layer_fg_scroll_x & 0x07);
507
508         if (x_offset >= 0 && x_offset >= m_window_fg_left && x_offset < m_window_fg_right && x_offset < WSWAN_X_PIXELS)
509         {
510            if (m_colors_16)
511            {
512               if (col)
513               {
514                  if (m_color_mode)
515                     m_bitmap.pix16(m_current_line, x_offset) = m_pal[tile_palette][col];
516                  else
517                     /* Hmmmm, what should we do here... Is this correct?? */
518                     m_bitmap.pix16(m_current_line, x_offset) = m_pal[tile_palette][col];
519               }
520            }
521            else
522            {
523               if (col || !(tile_palette & 4))
524               {
525                  if (m_color_mode)
526                     m_bitmap.pix16(m_current_line, x_offset) = m_pal[tile_palette][col];
527                  else
528                     m_bitmap.pix16(m_current_line, x_offset) = m_main_palette[m_pal[tile_palette][col]];
529               }
530            }
531         }
532      }
533   }
534}
535
536void wswan_video_device::draw_foreground_3()
537{
538   UINT16 map_addr = m_layer_fg_address + (((m_current_line + m_layer_fg_scroll_y) & 0xf8) << 3);
539   UINT8 start_column = (m_layer_fg_scroll_x >> 3);
540   
541   for (int column = 0; column < 29; column++)
542   {
543      UINT32 plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0;
544      int x_offset, tile_line, tile_address;
545      int tile_data =  (m_vram[map_addr + (((start_column + column) & 0x1f) << 1) + 1] << 8)
546                  | m_vram[map_addr + (((start_column + column) & 0x1f) << 1)];
547      int tile_number = tile_data & 0x01ff;
548      int tile_palette = (tile_data >> 9) & 0x0f;
549
550      tile_line = (m_current_line + m_layer_fg_scroll_y) & 0x07;
551      if (tile_data & 0x8000) // vflip
552         tile_line = 7 - tile_line;
553     
554      if (m_colors_16)
555      {
556         tile_address = ((tile_data & 0x2000) ? 0x8000 : 0x4000) + (tile_number * 32) + (tile_line << 2);
557         if (m_tile_packed)
558         {
559            plane0 = (m_vram[tile_address + 0] << 24) | (m_vram[tile_address + 1] << 16) | (m_vram[tile_address + 2] << 8) | m_vram[tile_address + 3];
560         }
561         else
562         {
563            plane0 = m_vram[tile_address + 0];
564            plane1 = m_vram[tile_address + 1] << 1;
565            plane2 = m_vram[tile_address + 2] << 2;
566            plane3 = m_vram[tile_address + 3] << 3;
567         }
568      }
569      else
570      {
571         tile_address = 0x2000 + (tile_number * 16) + (tile_line << 1);
572         if (m_tile_packed)
573         {
574            plane0 = (m_vram[tile_address + 0] << 8) | m_vram[tile_address + 1];
575         }
576         else
577         {
578            plane0 = m_vram[tile_address + 0];
579            plane1 = m_vram[tile_address + 1] << 1;
580            plane2 = 0;
581            plane3 = 0;
582         }
583      }
584
585      for (int x = 0; x < 8; x++)
586      {
587         int col;
588         if (m_tile_packed)
589         {
590            if (m_colors_16)
591            {
592               col = plane0 & 0x0f;
593               plane0 = plane0 >> 4;
594            }
595            else
596            {
597               col = plane0 & 0x03;
598               plane0 = plane0 >> 2;
599            }
600         }
601         else
602         {
603            col = (plane3 & 8) | (plane2 & 4) | (plane1 & 2) | (plane0 & 1);
604            plane3 = plane3 >> 1;
605            plane2 = plane2 >> 1;
606            plane1 = plane1 >> 1;
607            plane0 = plane0 >> 1;
608         }
609
610         if (tile_data & 0x4000)
611            x_offset = x + (column << 3) - (m_layer_fg_scroll_x & 0x07);
612         else
613            x_offset = 7 - x + (column << 3) - (m_layer_fg_scroll_x & 0x07);
614
615         if ((x_offset >= 0 && x_offset < m_window_fg_left) || (x_offset >= m_window_fg_right && x_offset < WSWAN_X_PIXELS))
616         {
617            if (m_colors_16)
618            {
619               if (col)
620               {
621                  if (m_color_mode)
622                     m_bitmap.pix16(m_current_line, x_offset) = m_pal[tile_palette][col];
623                  else
624                     /* Hmmmm, what should we do here... Is this correct?? */
625                     m_bitmap.pix16(m_current_line, x_offset) = m_pal[tile_palette][col];
626               }
627            }
628            else
629            {
630               if (col || !(tile_palette & 4))
631               {
632                  if (m_color_mode)
633                     m_bitmap.pix16(m_current_line, x_offset) = m_pal[tile_palette][col];
634                  else
635                     m_bitmap.pix16(m_current_line, x_offset) = m_main_palette[m_pal[tile_palette][col]];
636               }
637            }
638         }
639      }
640   }
641}
642
643void wswan_video_device::handle_sprites(int mask)
644{
645   if (m_sprite_count == 0)
646      return;
647
648   for (int i = m_sprite_first + m_sprite_count - 1; i >= m_sprite_first; i--)
649   {
650      UINT16 tile_data = (m_sprite_table_buffer[i * 4 + 1] << 8) | m_sprite_table_buffer[i * 4];
651      UINT8 y = m_sprite_table_buffer[ i * 4 + 2 ];
652      UINT8 x = m_sprite_table_buffer[ i * 4 + 3 ];
653      int tile_line = (m_current_line - y) & 0xff;
654
655      if ((tile_line >= 0) && (tile_line < 8) && ((tile_data & 0x2000) == mask))
656      {
657         UINT32 plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0;
658         int x_offset, tile_address;
659         int tile_number = tile_data & 0x01ff;
660         int tile_palette = 8 + ((tile_data >> 9) & 0x07);
661         int check_clip = 0;
662
663         if (tile_data & 0x8000)
664            tile_line = 7 - tile_line;
665         
666         if (m_colors_16)
667         {
668            tile_address = 0x4000 + (tile_number * 32) + (tile_line << 2);
669            if (m_tile_packed)
670            {
671               plane0 = (m_vram[tile_address + 0] << 24) | (m_vram[tile_address + 1] << 16) | (m_vram[tile_address + 2] << 8) | m_vram[tile_address + 3];
672            }
673            else
674            {
675               plane0 = m_vram[tile_address + 0];
676               plane1 = m_vram[tile_address + 1] << 1;
677               plane2 = m_vram[tile_address + 2] << 2;
678               plane3 = m_vram[tile_address + 3] << 3;
679            }
680         }
681         else
682         {
683            tile_address = 0x2000 + (tile_number * 16) + (tile_line << 1);
684            if (m_tile_packed)
685            {
686               plane0 = (m_vram[tile_address + 0] << 8) | m_vram[tile_address + 1];
687            }
688            else
689            {
690               plane0 = m_vram[tile_address + 0];
691               plane1 = m_vram[tile_address + 1] << 1;
692               plane2 = 0;
693               plane3 = 0;
694            }
695         }
696         
697         if (m_window_sprites_enable)
698         {
699            if (tile_data & 0x1000)
700            {
701               if (m_current_line >= m_window_sprites_top && m_current_line <= m_window_sprites_bottom)
702                  check_clip = 1;
703            }
704            else
705            {
706               if (m_current_line < m_window_sprites_top || m_current_line > m_window_sprites_bottom)
707                  continue;
708            }
709         }
710         
711         for (int j = 0; j < 8; j++)
712         {
713            int col;
714            if (m_tile_packed)
715            {
716               if (m_colors_16)
717               {
718                  col = plane0 & 0x0f;
719                  plane0 = plane0 >> 4;
720               }
721               else
722               {
723                  col = plane0 & 0x03;
724                  plane0 = plane0 >> 2;
725               }
726            }
727            else
728            {
729               col = (plane3 & 8) | (plane2 & 4) | (plane1 & 2) | (plane0 & 1);
730               plane3 = plane3 >> 1;
731               plane2 = plane2 >> 1;
732               plane1 = plane1 >> 1;
733               plane0 = plane0 >> 1;
734            }
735
736            if (tile_data & 0x4000)
737               x_offset = x + j;
738            else
739               x_offset = x + 7 - j;
740
741            x_offset = x_offset & 0xff;
742
743            if (m_window_sprites_enable)
744            {
745               if (tile_data & 0x1000 && check_clip)
746               {
747                  if (x_offset >= m_window_sprites_left && x_offset <= m_window_sprites_right)
748                     continue;
749               }
750               else
751               {
752                  if (x_offset < m_window_sprites_left || x_offset > m_window_sprites_right)
753                  {
754//                          continue;
755                  }
756               }
757            }
758            if (x_offset >= 0 && x_offset < WSWAN_X_PIXELS)
759            {
760               if (m_colors_16)
761               {
762                  if (col)
763                  {
764                     if (m_color_mode)
765                        m_bitmap.pix16(m_current_line, x_offset) = m_pal[tile_palette][col];
766                     else
767                        /* Hmmmm, what should we do here... Is this correct?? */
768                        m_bitmap.pix16(m_current_line, x_offset) = m_pal[tile_palette][col];
769                  }
770               }
771               else
772               {
773                  if (col || !(tile_palette & 4))
774                  {
775                     if (m_color_mode)
776                        m_bitmap.pix16(m_current_line, x_offset) = m_pal[tile_palette][col];
777                     else
778                        m_bitmap.pix16(m_current_line, x_offset) = m_main_palette[m_pal[tile_palette][col]];
779                  }
780               }
781            }
782         }
783      }
784   }
785}
786
787
788void wswan_video_device::refresh_scanline()
789{
790   setup_palettes();
791   
792   rectangle rec(0, WSWAN_X_PIXELS, m_current_line, m_current_line);
793   if (m_lcd_control)
794   {
795      /* Not sure if these background color checks and settings are correct */
796      if (m_color_mode && m_colors_16)
797         m_bitmap.fill(m_pal[m_bg_control >> 4][m_bg_control & 0x0f], rec);
798      else
799         m_bitmap.fill(m_main_palette[m_bg_control & 0x07], rec);
800   }
801   else
802   {
803      m_bitmap.fill(0, rec);
804      return;
805   }
806   
807   // Draw background layer
808   if (m_layer_bg_enable)
809      draw_background();
810   
811   // Draw sprites between background and foreground layers
812   if (m_sprites_enable)
813      handle_sprites(0);
814   
815   // Draw foreground layer, taking window settings into account
816   if (m_layer_fg_enable)
817   {
818      switch (m_window_fg_mode)
819      {
820         case 0: // FG inside & outside window area
821            draw_foreground_0();
822            break;
823         case 1: // ???
824            logerror("Unknown foreground mode 1 set\n");
825            break;
826         case 2: // FG only inside window area
827            if (m_current_line >= m_window_fg_top && m_current_line <= m_window_fg_bottom)
828               draw_foreground_2();
829            break;
830         case 3: // FG only outside window area
831            if (m_current_line < m_window_fg_top || m_current_line > m_window_fg_bottom)
832               draw_foreground_0();
833            else
834               draw_foreground_3();
835            break;
836      }
837   }
838   
839   // Draw sprites in front of foreground layer
840   if (m_sprites_enable)
841      handle_sprites(0x2000);
842}
843
844
845
846UINT32 wswan_video_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
847{
848   copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect);
849   return 0;
850}
851
852
853READ8_MEMBER(wswan_video_device::reg_r)
854{
855   UINT8 value = m_regs[offset];
856
857   if (offset >= 0x20 && offset < 0x40)
858      return m_palette_port[offset & 0x1f];
859
860   switch (offset)
861   {
862      case 0x01:
863         value = m_bg_control;
864         break;
865      case 0x02:
866         value = m_current_line;
867         break;
868      case 0x14:
869         value = m_lcd_control;
870         break;
871      case 0xa8:
872         value = m_timer_hblank_count & 0xff;
873         break;
874      case 0xa9:
875         value = m_timer_hblank_count >> 8;
876         break;
877      case 0xaa:
878         value = m_timer_vblank_count & 0xff;
879         break;
880      case 0xab:
881         value = m_timer_vblank_count >> 8;
882         break;
883   }
884   
885   return value;
886}
887
888
889WRITE8_MEMBER(wswan_video_device::reg_w)
890{
891   if (offset >= 0x20 && offset < 0x40)
892   {
893      // 0x20-0x3f tile/sprite palette settings
894      // even offs
895      //   Bit 0-3 - Palette (offs & 0x1f)/2 index 0
896      //   Bit 4-7 - Palette (offs & 0x1f)/2 index 1
897      // odd offs
898      //   Bit 0-3 - Palette (offs & 0x1f)/2 index 2
899      //   Bit 4-7 - Palette (offs & 0x1f)/2 index 3
900      m_palette_port[offset & 0x1f] = data;
901      return;
902   }
903     
904   switch (offset)
905   {
906      case 0x00:  // Display control
907               // Bit 0   - Background layer enable
908               // Bit 1   - Foreground layer enable
909               // Bit 2   - Sprites enable
910               // Bit 3   - Sprite window enable
911               // Bit 4-5 - Foreground window configuration
912               //      00 - Foreground layer is displayed inside and outside foreground window area
913               //      01 - Unknown
914               //      10 - Foreground layer is displayed only inside foreground window area
915               //      11 - Foreground layer is displayed outside foreground window area
916               // Bit 6-7 - Unknown
917         m_layer_bg_enable = data & 0x1;
918         m_layer_fg_enable = (data & 0x2) >> 1;
919         m_sprites_enable = (data & 0x4) >> 2;
920         m_window_sprites_enable = (data & 0x8) >> 3;
921         m_window_fg_mode = (data & 0x30) >> 4;
922         break;
923      case 0x01:  // Background colour
924               // In 16 colour mode:
925               //   Bit 0-3 - Palette index
926               //   Bit 4-7 - Palette number
927               // Otherwise:
928               //   Bit 0-2 - Main palette index
929               //   Bit 3-7 - Unknown
930         m_bg_control = data;
931         break;
932      case 0x02:  // Current scanline (Most likely read-only)
933         logerror("Write to current scanline! Current value: %d  Data to write: %d\n", m_current_line, data);
934         // Returning so we don't overwrite the value here, not that it really matters
935         return;
936      case 0x03:  // Line compare
937         m_line_compare = data;
938         logerror("Write to line compare: %d\n", data);
939         break;
940      case 0x04:  // Sprite table base address
941               // Bit 0-5 - Determine sprite table base address 0 0xxxxxx0 00000000
942               // Bit 6-7 - Unknown
943         m_sprite_table_address = (data & 0x3f) << 9;
944         break;
945      case 0x05:  // First sprite number (the one we start drawing with)
946         m_sprite_first_latch = data;
947         if (data) logerror("non-zero first sprite %d\n", data);
948         break;
949      case 0x06:  // Number of sprites to draw
950         m_sprite_count_latch = data;
951         break;
952      case 0x07:  // Background/Foreground table base addresses
953               // Bit 0-2 - Determine background table base address 00xxx000 00000000
954               // Bit 3   - Unknown
955               // Bit 4-6 - Determine foreground table base address 00xxx000 00000000
956               // Bit 7   - Unknown
957         m_layer_bg_address = (data & 0x7) << 11;
958         m_layer_fg_address = (data & 0x70) << 7;
959         break;
960      case 0x08:  // Left coordinate of foreground window
961         m_window_fg_left = data;
962         break;
963      case 0x09:  // Top coordinate of foreground window
964         m_window_fg_top = data;
965         break;
966      case 0x0a:  // Right coordinate of foreground window
967         m_window_fg_right = data;
968         break;
969      case 0x0b:  // Bottom coordinate of foreground window
970         m_window_fg_bottom = data;
971         break;
972      case 0x0c:  // Left coordinate of sprite window
973         m_window_sprites_left = data;
974         break;
975      case 0x0d:  // Top coordinate of sprite window
976         m_window_sprites_top = data;
977         break;
978      case 0x0e:  // Right coordinate of sprite window
979         m_window_sprites_right = data;
980         break;
981      case 0x0f:  // Bottom coordinate of sprite window
982         m_window_sprites_bottom = data;
983         break;
984      case 0x10:  // Background layer X scroll
985         m_layer_bg_scroll_x = data;
986         break;
987      case 0x11:  // Background layer Y scroll
988         m_layer_bg_scroll_y = data;
989         break;
990      case 0x12:  // Foreground layer X scroll
991         m_layer_fg_scroll_x = data;
992         break;
993      case 0x13:  // Foreground layer Y scroll
994         m_layer_fg_scroll_y = data;
995         break;
996      case 0x14:  // LCD control
997               // Bit 0   - LCD enable
998               // Bit 1-7 - Unknown
999         m_lcd_control = data;
1000         break;
1001      case 0x15:  // LCD icons
1002               // Bit 0   - LCD sleep icon enable
1003               // Bit 1   - Vertical position icon enable
1004               // Bit 2   - Horizontal position icon enable
1005               // Bit 3   - Dot 1 icon enable
1006               // Bit 4   - Dot 2 icon enable
1007               // Bit 5   - Dot 3 icon enable
1008               // Bit 6-7 - Unknown
1009         m_icons = data; /* ummmmm */
1010         break;
1011      case 0x1c:  // Palette colors 0 and 1
1012               // Bit 0-3 - Gray tone setting for main palette index 0
1013               // Bit 4-7 - Gray tone setting for main palette index 1
1014         if (m_vdp_type == VDP_TYPE_WSC)
1015         {
1016            int i = 15 - (data & 0x0f);
1017            int j = 15 - ((data & 0xf0) >> 4);
1018            m_main_palette[0] = (i << 8) | (i << 4) | i;
1019            m_main_palette[1] = (j << 8) | (j << 4) | j;
1020         }
1021         else
1022         {
1023            m_main_palette[0] = data & 0x0f;
1024            m_main_palette[1] = (data & 0xf0) >> 4;
1025         }
1026         break;
1027      case 0x1d:  // Palette colors 2 and 3
1028               // Bit 0-3 - Gray tone setting for main palette index 2
1029               // Bit 4-7 - Gray tone setting for main palette index 3
1030         if (m_vdp_type == VDP_TYPE_WSC)
1031         {
1032            int i = 15 - (data & 0x0f);
1033            int j = 15 - ((data & 0xf0) >> 4);
1034            m_main_palette[2] = (i << 8) | (i << 4) | i;
1035            m_main_palette[3] = (j << 8) | (j << 4) | j;
1036         }
1037         else
1038         {
1039            m_main_palette[2] = data & 0x0f;
1040            m_main_palette[3] = (data & 0xf0) >> 4;
1041         }
1042         break;
1043      case 0x1e:  // Palette colors 4 and 5
1044               // Bit 0-3 - Gray tone setting for main palette index 4
1045               // Bit 4-7 - Gray tone setting for main palette index 5
1046         if (m_vdp_type == VDP_TYPE_WSC)
1047         {
1048            int i = 15 - (data & 0x0f);
1049            int j = 15 - ((data & 0xf0) >> 4);
1050            m_main_palette[4] = (i << 8) | (i << 4) | i;
1051            m_main_palette[5] = (j << 8) | (j << 4) | j;
1052         }
1053         else
1054         {
1055            m_main_palette[4] = data & 0x0f;
1056            m_main_palette[5] = (data & 0xf0) >> 4;
1057         }
1058         break;
1059      case 0x1f:  // Palette colors 6 and 7
1060               // Bit 0-3 - Gray tone setting for main palette index 6
1061               // Bit 4-7 - Gray tone setting for main palette index 7
1062         if (m_vdp_type == VDP_TYPE_WSC)
1063         {
1064            int i = 15 - (data & 0x0f);
1065            int j = 15 - ((data & 0xf0) >> 4);
1066            m_main_palette[6] = (i << 8) | (i << 4) | i;
1067            m_main_palette[7] = (j << 8) | (j << 4) | j;
1068         }
1069         else
1070         {
1071            m_main_palette[6] = data & 0x0f;
1072            m_main_palette[7] = (data & 0xf0) >> 4;
1073         }
1074         break;
1075      case 0x60:  // Video mode
1076               // Bit 0-4 - Unknown
1077               // Bit 5   - Packed mode 0 = not packed mode, 1 = packed mode
1078               // Bit 6   - 4/16 colour mode select: 0 = 4 colour mode, 1 = 16 colour mode
1079               // Bit 7   - monochrome/colour mode select: 0 = monochrome mode, 1 = colour mode
1080         /*
1081          * 111  - packed, 16 color, use 4000/8000, color
1082          * 110  - not packed, 16 color, use 4000/8000, color
1083          * 101  - packed, 4 color, use 2000, color
1084          * 100  - not packed, 4 color, use 2000, color
1085          * 011  - packed, 16 color, use 4000/8000, monochrome
1086          * 010  - not packed, 16 color , use 4000/8000, monochrome
1087          * 001  - packed, 4 color, use 2000, monochrome
1088          * 000  - not packed, 4 color, use 2000, monochrome - Regular WS monochrome
1089          */
1090         if (m_vdp_type == VDP_TYPE_WSC)
1091         {
1092            m_color_mode = data & 0x80;
1093            m_colors_16 = data & 0x40;
1094            m_tile_packed = data & 0x20;
1095         }
1096         break;
1097      case 0xa2:  // Timer control
1098               // Bit 0   - HBlank Timer enable
1099               // Bit 1   - HBlank Timer mode: 0 = one shot, 1 = auto reset
1100               // Bit 2   - VBlank Timer(1/75s) enable
1101               // Bit 3   - VBlank Timer mode: 0 = one shot, 1 = auto reset
1102               // Bit 4-7 - Unknown
1103         m_timer_hblank_enable = BIT(data, 0);
1104         m_timer_hblank_mode =   BIT(data, 1);
1105         m_timer_vblank_enable = BIT(data, 2);
1106         m_timer_vblank_mode =   BIT(data, 3);
1107         break;
1108      case 0xa4:  // HBlank timer frequency reload value (bits 0-7)
1109         m_timer_hblank_reload &= 0xff00;
1110         m_timer_hblank_reload += data;
1111         m_timer_hblank_count = m_timer_hblank_reload;
1112         break;
1113      case 0xa5:  // HBlank timer frequency reload value (bits 8-15)
1114         m_timer_hblank_reload &= 0xff;
1115         m_timer_hblank_reload += data << 8;
1116         m_timer_hblank_count = m_timer_hblank_reload;
1117         break;
1118      case 0xa6:  // VBlank timer frequency reload value (bits 0-7)
1119         m_timer_vblank_reload &= 0xff00;
1120         m_timer_vblank_reload += data;
1121         m_timer_vblank_count = m_timer_vblank_reload;
1122         break;
1123      case 0xa7:  // VBlank timer frequency reload value (bits 8-15)
1124         m_timer_vblank_reload &= 0xff;
1125         m_timer_vblank_reload += data << 8;
1126         m_timer_vblank_count = m_timer_vblank_reload;
1127         break;
1128      case 0xa8:  // HBlank counter (bits 0-7)
1129      case 0xa9:  // HBlank counter (bits 8-15)
1130      case 0xaa:  // VBlank counter (bits 0-7)
1131      case 0xab:  // VBlank counter (bits 8-15)
1132         break;
1133   }
1134
1135   m_regs[offset] = data;
1136}
1137
1138
1139void wswan_video_device::scanline_interrupt()
1140{
1141   if (m_current_line < 144)
1142      refresh_scanline();
1143   
1144   // Decrement 12kHz (HBlank) counter
1145   if (m_timer_hblank_enable && m_timer_hblank_reload != 0)
1146   {
1147      m_timer_hblank_count--;
1148      logerror("timer_hblank_count: %X\n", m_timer_hblank_count);
1149      if (m_timer_hblank_count == 0)
1150      {
1151         if (m_timer_hblank_mode)
1152            m_timer_hblank_count = m_timer_hblank_reload;
1153         else
1154            m_timer_hblank_reload = 0;
1155         
1156         logerror( "trigerring hbltmr interrupt\n" );
1157         m_set_irq_cb(WSWAN_VIDEO_IFLAG_HBLTMR);
1158      }
1159   }
1160   
1161   // Handle Sound DMA
1162   m_snd_dma_cb();
1163   
1164//  m_current_line = (m_current_line + 1) % 159;
1165   
1166   if (m_current_line == 144) // buffer sprite table
1167   {
1168      memcpy(m_sprite_table_buffer, &m_vram[m_sprite_table_address], 512);
1169      m_sprite_first = m_sprite_first_latch; // always zero?
1170      m_sprite_count = m_sprite_count_latch;
1171   }
1172   
1173   if (m_current_line == 144)
1174   {
1175      m_set_irq_cb(WSWAN_VIDEO_IFLAG_VBL);
1176      /* Decrement 75Hz (VBlank) counter */
1177      if (m_timer_vblank_enable && m_timer_vblank_reload != 0)
1178      {
1179         m_timer_vblank_count--;
1180         logerror("timer_vblank_count: %X\n", m_timer_vblank_count);
1181         if (m_timer_vblank_count == 0)
1182         {
1183            if (m_timer_vblank_mode)
1184               m_timer_vblank_count = m_timer_vblank_reload;
1185            else
1186               m_timer_vblank_reload = 0;
1187           
1188            logerror("triggering vbltmr interrupt\n");
1189            m_set_irq_cb(WSWAN_VIDEO_IFLAG_VBLTMR);
1190         }
1191      }
1192   }
1193   
1194//  m_current_line = (m_current_line + 1) % 159;
1195   
1196   if (m_current_line == m_line_compare)
1197      m_set_irq_cb(WSWAN_VIDEO_IFLAG_LCMP);
1198   
1199   m_current_line = (m_current_line + 1) % 159;
1200}
1201
1202
1203READ8_MEMBER(wswan_video_device::vram_r)
1204{
1205   return m_vram[offset];
1206}
1207
1208WRITE8_MEMBER(wswan_video_device::vram_w)
1209{
1210   m_vram[offset] = data;
1211}
trunk/src/mess/video/wswan_video.h
r0r241556
1/**********************************************************************
2
3 wswan.h
4 
5 File to handle video emulation of the Bandai WonderSwan.
6 
7 Anthony Kruize
8 Wilbert Pol
9
10**********************************************************************/
11
12#ifndef __WSWAN_VIDEO__
13#define __WSWAN_VIDEO__
14
15#include "emu.h"
16
17enum
18{
19   VDP_TYPE_WSWAN = 0,
20   VDP_TYPE_WSC
21};
22
23#define WSWAN_X_PIXELS  (28*8)
24#define WSWAN_Y_PIXELS  (18*8)
25
26
27
28typedef device_delegate<void (int irq)> wswan_video_irq_cb_delegate;
29#define WSWAN_VIDEO_IRQ_CB_MEMBER(_name)   void _name(int irq)
30
31typedef device_delegate<void (void)> wswan_video_dmasnd_cb_delegate;
32#define WSWAN_VIDEO_DMASND_CB_MEMBER(_name)   void _name(void)
33
34#define MCFG_WSWAN_VIDEO_IRQ_CB(_class, _method) \
35   wswan_video_device::set_irq_callback(*device, wswan_video_irq_cb_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner)));
36
37#define MCFG_WSWAN_VIDEO_DMASND_CB(_class, _method) \
38   wswan_video_device::set_dmasnd_callback(*device, wswan_video_dmasnd_cb_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner)));
39
40#define MCFG_WSWAN_VIDEO_TYPE( _type) \
41   wswan_video_device::set_vdp_type(*device, _type);
42
43
44class wswan_video_device : public device_t
45{
46public:
47   wswan_video_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
48   ~wswan_video_device() {}
49
50   // static configuration
51   static void set_irq_callback(device_t &device, wswan_video_irq_cb_delegate callback) { downcast<wswan_video_device &>(device).m_set_irq_cb = callback; }
52   static void set_dmasnd_callback(device_t &device, wswan_video_dmasnd_cb_delegate callback) { downcast<wswan_video_device &>(device).m_snd_dma_cb = callback; }
53   static void set_vdp_type(device_t &device, int type) { downcast<wswan_video_device &>(device).m_vdp_type = type; }
54
55   UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
56
57   virtual DECLARE_READ8_MEMBER(vram_r);
58   virtual DECLARE_WRITE8_MEMBER(vram_w);
59   virtual DECLARE_READ8_MEMBER(reg_r);
60   virtual DECLARE_WRITE8_MEMBER(reg_w);
61
62protected:
63   // device-level overrides
64   virtual void device_start();
65   virtual void device_reset();
66   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
67
68   void setup_palettes();
69   void draw_background();
70   void draw_foreground_0();
71   void draw_foreground_2();
72   void draw_foreground_3();
73   void handle_sprites(int mask);
74   void refresh_scanline();
75   void scanline_interrupt();
76   void common_save();
77   
78   bitmap_ind16 m_bitmap;
79   UINT8 m_layer_bg_enable;          /* Background layer on/off */
80   UINT8 m_layer_fg_enable;          /* Foreground layer on/off */
81   UINT8 m_sprites_enable;           /* Sprites on/off */
82   UINT8 m_window_sprites_enable;        /* Sprite window on/off */
83   UINT8 m_window_fg_mode;           /* 0:inside/outside, 1:??, 2:inside, 3:outside */
84   UINT8 m_bg_control;
85   UINT8 m_current_line;         /* Current scanline : 0-158 (159?) */
86   UINT8 m_line_compare;         /* Line to trigger line interrupt on */
87   UINT32 m_sprite_table_address;        /* Address of the sprite table */
88   UINT8 m_sprite_table_buffer[512];
89   UINT8 m_sprite_first;         /* First sprite to draw */
90   UINT8 m_sprite_count;         /* Number of sprites to draw */
91   UINT8 m_sprite_first_latch;
92   UINT8 m_sprite_count_latch;
93   UINT16 m_layer_bg_address;        /* Address of the background screen map */
94   UINT16 m_layer_fg_address;        /* Address of the foreground screen map */
95   UINT8 m_window_fg_left;           /* Left coordinate of foreground window */
96   UINT8 m_window_fg_top;            /* Top coordinate of foreground window */
97   UINT8 m_window_fg_right;          /* Right coordinate of foreground window */
98   UINT8 m_window_fg_bottom;         /* Bottom coordinate of foreground window */
99   UINT8 m_window_sprites_left;      /* Left coordinate of sprites window */
100   UINT8 m_window_sprites_top;       /* Top coordinate of sprites window */
101   UINT8 m_window_sprites_right;     /* Right coordinate of sprites window */
102   UINT8 m_window_sprites_bottom;        /* Bottom coordinate of sprites window */
103   UINT8 m_layer_bg_scroll_x;        /* Background layer X scroll */
104   UINT8 m_layer_bg_scroll_y;        /* Background layer Y scroll */
105   UINT8 m_layer_fg_scroll_x;        /* Foreground layer X scroll */
106   UINT8 m_layer_fg_scroll_y;        /* Foreground layer Y scroll */
107   UINT8 m_lcd_control;           /* LCD on/off */
108   UINT8 m_icons;                /* FIXME: What do we do with these? Maybe artwork? */
109   UINT8 m_color_mode;           /* monochrome/color mode */
110   UINT8 m_colors_16;            /* 4/16 colors mode */
111   UINT8 m_tile_packed;          /* layered/packed tile mode switch */
112   UINT8 m_timer_hblank_enable;      /* Horizontal blank interrupt on/off */
113   UINT8 m_timer_hblank_mode;        /* Horizontal blank timer mode */
114   UINT16 m_timer_hblank_reload;     /* Horizontal blank timer reload value */
115   UINT16 m_timer_hblank_count;      /* Horizontal blank timer counter value */
116   UINT8 m_timer_vblank_enable;      /* Vertical blank interrupt on/off */
117   UINT8 m_timer_vblank_mode;        /* Vertical blank timer mode */
118   UINT16 m_timer_vblank_reload;     /* Vertical blank timer reload value */
119   UINT16 m_timer_vblank_count;      /* Vertical blank timer counter value */
120   int m_main_palette[8];
121   emu_timer *m_timer;
122
123   dynamic_buffer m_vram;
124   UINT8 *m_palette_vram;
125   UINT8 m_palette_port[0x20];
126   int m_pal[16][16];
127   UINT8 m_regs[256];
128
129   wswan_video_irq_cb_delegate m_set_irq_cb;
130   wswan_video_dmasnd_cb_delegate m_snd_dma_cb;
131   int m_vdp_type;
132
133   // timer IDs
134   static const device_timer_id TIMER_SCANLINE = 0;
135
136   // interrupt flags
137   // these are the same as the wswan.h ones
138   static const UINT8 WSWAN_VIDEO_IFLAG_LCMP   = 0x10;
139   static const UINT8 WSWAN_VIDEO_IFLAG_VBLTMR = 0x20;
140   static const UINT8 WSWAN_VIDEO_IFLAG_VBL    = 0x40;
141   static const UINT8 WSWAN_VIDEO_IFLAG_HBLTMR = 0x80;
142};
143
144extern const device_type WSWAN_VIDEO;
145
146
147#endif


Previous 199869 Revisions Next


© 1997-2024 The MAME Team