Previous 199869 Revisions Next

r33042 Tuesday 28th October, 2014 at 08:27:03 UTC by MetalliC
line endings
[hash]amiga_workbench.xml vreader.xml
[src/emu/bus]bus.mak
[src/emu/bus/astrocde]exp.c exp.h ram.c ram.h
[src/emu/bus/ecbbus]grip.c
[src/mame/drivers]psychic5.c
[src/mame/includes]psychic5.h
[src/mame/machine]zndip.h
[src/mame/video]psychic5.c
[src/mess]mess.mak
[src/mess/drivers]astrocde.c 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
r241553r241554
212212      </part>
213213   </software>
214214
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>
215   <software name="wb133r3434" cloneof="wbenc133">
216      <description>Workbench 1.3.3 (Rev. 34.34)</description>
220217      <year>1990</year>
221218      <publisher>Commodore</publisher>
219
222220      <part name="flop1" interface="floppy_3_5">
223         <feature name="part_id" value="Workbench 1.3.3" />
221         <feature name="part_id" value="Amiga Workbench Version 1.3.3 (Rev. 34.34)" />
224222         <dataarea name="flop" size="901120">
225            <rom name="317746-04_workbench.adf" size="901120" crc="bf299bca" sha1="8bac53a89cd1fe5a7762de9bd61a1592f10af2df" status="baddump" offset="0"/>
223            <rom name="317746-04_workbench.adf" size="901120" crc="bf299bca" sha1="8bac53a89cd1fe5a7762de9bd61a1592f10af2df" offset="0"/>
226224         </dataarea>
227225      </part>
226
228227      <part name="flop2" interface="floppy_3_5">
229         <feature name="part_id" value="Extras 1.3" />
228         <feature name="part_id" value="Amiga Extras Amiga Basic Printer Drivers Version 1.3" />
230229         <dataarea name="flop" size="901120">
231230            <rom name="317748-02_extras.adf" size="901120" crc="256a4b82" sha1="465a65aa89fe4b016fee968ef75ab08de9bdfbc6" offset="0"/>
232231         </dataarea>
trunk/hash/vreader.xml
r241553r241554
4747
4848
4949-->
50</softwarelist>
No newline at end of file
trunk/src/emu/bus/astrocde/exp.c
r241553r241554
1// license:BSD-3-Clause
2// copyright-holders:etabeta
3/***********************************************************************************************************
4
5    Bally Astrocade Expansion port
6
7 ***********************************************************************************************************/
8
9
10#include "emu.h"
11#include "exp.h"
12
13//**************************************************************************
14//  GLOBAL VARIABLES
15//**************************************************************************
16
17const device_type ASTROCADE_EXP_SLOT = &device_creator<astrocade_exp_device>;
18
19
20device_astrocade_card_interface::device_astrocade_card_interface(const machine_config &mconfig, device_t &device)
21   : device_slot_card_interface(mconfig, device)
22{
23}
24
25
26device_astrocade_card_interface::~device_astrocade_card_interface()
27{
28}
29
30
31//**************************************************************************
32//  LIVE DEVICE
33//**************************************************************************
34
35//-------------------------------------------------
36//  astrocade_exp_device - constructor
37//-------------------------------------------------
38astrocade_exp_device::astrocade_exp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
39                  device_t(mconfig, ASTROCADE_EXP_SLOT, "Bally Astrocade expansion", tag, owner, clock, "astrocde_exp", __FILE__),
40                  device_slot_interface(mconfig, *this)
41{
42}
43
44
45//-------------------------------------------------
46//  astrocade_exp_device - destructor
47//-------------------------------------------------
48
49astrocade_exp_device::~astrocade_exp_device()
50{
51}
52
53//-------------------------------------------------
54//  device_start - device-specific startup
55//-------------------------------------------------
56
57void astrocade_exp_device::device_start()
58{
59   m_card = dynamic_cast<device_astrocade_card_interface *>(get_card_device());
60}
61
62/*-------------------------------------------------
63 read
64 -------------------------------------------------*/
65
66READ8_MEMBER(astrocade_exp_device::read)
67{
68   if (m_card)
69      return m_card->read(space, offset);
70   else
71      return 0xff;
72}
73
74/*-------------------------------------------------
75 write
76 -------------------------------------------------*/
77
78WRITE8_MEMBER(astrocade_exp_device::write)
79{
80   if (m_card)
81      m_card->write(space, offset, data);
82}
trunk/src/emu/bus/astrocde/exp.h
r241553r241554
1// license:BSD-3-Clause
2// copyright-holders:etabeta
3#ifndef __ASTROCADE_EXP_H
4#define __ASTROCADE_EXP_H
5
6// ======================> device_astrocade_card_interface
7
8class device_astrocade_card_interface : public device_slot_card_interface
9{
10public:
11   // construction/destruction
12   device_astrocade_card_interface(const machine_config &mconfig, device_t &device);
13   virtual ~device_astrocade_card_interface();
14
15   // reading and writing
16   virtual DECLARE_READ8_MEMBER(read) { return 0; }
17   virtual DECLARE_WRITE8_MEMBER(write) {}
18
19protected:
20};
21
22
23// ======================> astrocade_exp_device
24
25class astrocade_exp_device : public device_t,
26                        public device_slot_interface
27{
28public:
29   // construction/destruction
30   astrocade_exp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
31   virtual ~astrocade_exp_device();
32
33   // device-level overrides
34   virtual void device_start();
35
36   // reading and writing
37   virtual DECLARE_READ8_MEMBER(read);
38   virtual DECLARE_WRITE8_MEMBER(write);
39
40protected:
41
42   device_astrocade_card_interface* m_card;
43};
44
45
46
47// device type definition
48extern const device_type ASTROCADE_EXP_SLOT;
49
50
51#define MCFG_ASTROCADE_EXPANSION_SLOT_ADD(_tag, _slot_intf, _def_slot) \
52   MCFG_DEVICE_ADD(_tag, ASTROCADE_EXP_SLOT, 0) \
53   MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
54
55#endif
trunk/src/emu/bus/astrocde/ram.c
r241553r241554
1// license:BSD-3-Clause
2// copyright-holders:etabeta
3/***********************************************************************************************************
4
5
6  Bally Astrocade RAM expansion emulation
7
8      RAM Expansions (info below courtesy of Paul Thacker)
9
10      Several third party RAM expansions have been made for the Astrocade.  These
11      allow access to various ranges of the expansion memory ($5000 to $FFFF).
12      A RAM expansion is required to use extended BASIC programs like Blue RAM BASIC
13      and VIPERSoft BASIC.  All of the expansions also have a RAM protect switch, which
14      can be flipped at any time to make the RAM act like ROM.  Extended BASIC
15      programs need access to the RAM and won't work with RAM protect enabled, but
16      this can be useful with Bally and Astrocade BASIC.  They also have a range switch
17      (not implemented).  The default position is 6K, but it can be switched to
18      2K.  This means that the expanded memory starting at $6000 will instead be
19      mapped to the cartridge memory starting at $2000.  So it would be possible to
20      load a cartridge program from tape into the expansion memory, then flip the range
21      switch and run it as a cartridge.  This is useful for cartridge development.
22     
23      Blue RAM -- available in 4K, 16K, and 32K.  These also use an INS8154 chip,
24      (not yet implemented) which has an additional $80 bytes of RAM mapped
25      immediately after the end of the expansion address space.  This memory
26      can't be write protected.  The INS8154 has I/O features needed for loading
27      tape programs into Blue RAM BASIC, as well as running the Blue RAM Utility cart.
28      4K:  $6000 to $6FFF (can't run VIPERSoft BASIC, because this program needs memory
29      past this range)
30      16K:  $6000 to $9FFF
31      32K:  $6000 to $DFFF
32     
33      VIPER System 1 -- This is available in 16K only.  It also includes a keyboard (not implemented).
34      16K:  $6000 to $9FFF
35     
36      Lil' WHITE RAM -- This is available in 32K only.  Attempts to read and write
37      to memory outside of its address range ($D000 to $FFFF) are mapped to the expansion
38      memory $5000 to $7FFF.  The current implementation won't allow the shadow RAM area
39      to be accessed when RAM protect is on, but there is no known software that will
40      access the upper range of the expansion RAM when RAM protect is enabled.
41      32K:  $5000 to $CFFF
42     
43      R&L 64K RAM Board -- This is a highly configurable kit.  RAM can be installed in
44      2K increments.  So, the entire 44K expansion memory can be filled.  It is also
45      possible to override the rest of the memory map with RAM (not implemented).
46      There are 32 switches allowing users to activate and deactivate each 2K block (not implemented).
47      RAM write protection can be implemented in three ranges through jumpers or by
48      installing switches.  The ranges are $0000 to $0FFF (first 4K), $0000 to $3FFF (first 16K),
49      and $0000 to $FFFF (all 64K).  The current implementation is for 44K expansion memory mapped from
50      $5000 to $FFFF, with only a single write protect covering this entire range.
51 
52 ***********************************************************************************************************/
53
54
55#include "emu.h"
56#include "ram.h"
57
58
59//-------------------------------------------------
60//  astrocade_rom_device - constructor
61//-------------------------------------------------
62
63const device_type ASTROCADE_BLUERAM_4K  = &device_creator<astrocade_blueram_4k_device>;
64const device_type ASTROCADE_BLUERAM_16K = &device_creator<astrocade_blueram_16k_device>;
65const device_type ASTROCADE_BLUERAM_32K = &device_creator<astrocade_blueram_32k_device>;
66const device_type ASTROCADE_VIPER_SYS1  = &device_creator<astrocade_viper_sys1_device>;
67const device_type ASTROCADE_WHITERAM    = &device_creator<astrocade_whiteram_device>;
68const device_type ASTROCADE_RL64RAM     = &device_creator<astrocade_rl64ram_device>;
69
70
71astrocade_blueram_4k_device::astrocade_blueram_4k_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
72               : device_t(mconfig, type, name, tag, owner, clock, shortname, source),
73                  device_astrocade_card_interface(mconfig, *this),
74                  m_write_prot(*this, "RAM_PROTECT")
75{
76}
77
78astrocade_blueram_4k_device::astrocade_blueram_4k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
79               : device_t(mconfig, ASTROCADE_BLUERAM_4K, "Bally Astrocade Blue RAM 4K", tag, owner, clock, "astrocade_br4", __FILE__),
80                  device_astrocade_card_interface(mconfig, *this),
81                  m_write_prot(*this, "RAM_PROTECT")
82{
83}
84
85astrocade_blueram_16k_device::astrocade_blueram_16k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
86               : astrocade_blueram_4k_device(mconfig, ASTROCADE_BLUERAM_16K, "Bally Astrocade Blue RAM 16K", tag, owner, clock, "astrocade_br16", __FILE__)
87{
88}
89
90astrocade_blueram_32k_device::astrocade_blueram_32k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
91               : astrocade_blueram_4k_device(mconfig, ASTROCADE_BLUERAM_32K, "Bally Astrocade Blue RAM 32K", tag, owner, clock, "astrocade_br32", __FILE__)
92{
93}
94
95astrocade_viper_sys1_device::astrocade_viper_sys1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
96               : device_t(mconfig, ASTROCADE_VIPER_SYS1, "Bally Astrocade Viper System 1", tag, owner, clock, "astrocade_vs1", __FILE__),
97                  device_astrocade_card_interface(mconfig, *this),
98                  m_write_prot(*this, "RAM_PROTECT")
99{
100}
101
102astrocade_whiteram_device::astrocade_whiteram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
103               : device_t(mconfig, ASTROCADE_WHITERAM, "Bally Astrocade Lil' White RAM 32K", tag, owner, clock, "astrocade_lwr", __FILE__),
104                  device_astrocade_card_interface(mconfig, *this),
105                  m_write_prot(*this, "RAM_PROTECT")
106{
107}
108
109astrocade_rl64ram_device::astrocade_rl64ram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
110               : device_t(mconfig, ASTROCADE_RL64RAM, "Bally Astrocade R&L RAM 64K", tag, owner, clock, "astrocade_rl64", __FILE__),
111                  device_astrocade_card_interface(mconfig, *this),
112                  m_write_prot(*this, "RAM_PROTECT")
113{
114}
115
116
117//-------------------------------------------------
118//  RAM Write protect switch
119//-------------------------------------------------
120
121static INPUT_PORTS_START( exp_switches )
122   PORT_START("RAM_PROTECT")
123   PORT_CONFNAME( 0x01, 0x00, "Write Protect RAM")
124   PORT_CONFSETTING( 0x00, DEF_STR(Off))
125   PORT_CONFSETTING( 0x01, DEF_STR(On))
126INPUT_PORTS_END
127
128
129ioport_constructor astrocade_blueram_4k_device::device_input_ports() const
130{
131   return INPUT_PORTS_NAME( exp_switches );
132}
133
134ioport_constructor astrocade_viper_sys1_device::device_input_ports() const
135{
136   return INPUT_PORTS_NAME( exp_switches );
137}
138
139ioport_constructor astrocade_whiteram_device::device_input_ports() const
140{
141   return INPUT_PORTS_NAME( exp_switches );
142}
143
144ioport_constructor astrocade_rl64ram_device::device_input_ports() const
145{
146   return INPUT_PORTS_NAME( exp_switches );
147}
148
149/*-------------------------------------------------
150 specific handlers
151 -------------------------------------------------*/
152
153// Blue RAM expansions have RAM starting at 0x6000, up to the RAM size
154READ8_MEMBER(astrocade_blueram_4k_device::read)
155{
156   if (offset >= 0x1000 && offset < 0x1000 + m_ram.bytes())
157      return m_ram[offset - 0x1000];
158   else
159      return 0;
160}
161
162WRITE8_MEMBER(astrocade_blueram_4k_device::write)
163{
164   if (offset >= 0x1000 && offset < 0x1000 + m_ram.bytes() && !m_write_prot->read())
165      m_ram[offset - 0x1000] = data;
166}
167
168
169
170// Viper System 1 expansion has RAM in 0x6000-0x9fff
171READ8_MEMBER(astrocade_viper_sys1_device::read)
172{
173   if (offset >= 0x1000 && offset < 0xa000)
174      return m_ram[offset - 0x1000];
175   else
176      return 0;
177}
178
179WRITE8_MEMBER(astrocade_viper_sys1_device::write)
180{
181   if (offset >= 0x1000 && offset < 0xa000 && !m_write_prot->read())
182      m_ram[offset - 0x1000] = data;
183}
184
185
186
187// Lil' WHITE RAM expansion has RAM in 0x5000-0xcfff + a mirror of the first 0x3000 bytes up to 0xffff
188READ8_MEMBER(astrocade_whiteram_device::read)
189{
190   return m_ram[offset % 0x8000];
191}
192
193WRITE8_MEMBER(astrocade_whiteram_device::write)
194{
195   if (!m_write_prot->read())
196      m_ram[offset % 0x8000] = data;
197}
198
199
200
201// R&L 64K RAM Board (44KB installed) has RAM in 0x5000-0xffff
202READ8_MEMBER(astrocade_rl64ram_device::read)
203{
204   return m_ram[offset];
205}
206
207WRITE8_MEMBER(astrocade_rl64ram_device::write)
208{
209   if (!m_write_prot->read())
210      m_ram[offset] = data;
211}
212
213
trunk/src/emu/bus/astrocde/ram.h
r241553r241554
1// license:BSD-3-Clause
2// copyright-holders:etabeta
3#ifndef __ASTROCADE_RAM_H
4#define __ASTROCADE_RAM_H
5
6#include "exp.h"
7
8
9// ======================> astrocade_blueram_4k_device
10
11class astrocade_blueram_4k_device : public device_t,
12                        public device_astrocade_card_interface
13{
14public:
15   // construction/destruction
16   astrocade_blueram_4k_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
17   astrocade_blueram_4k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
18
19   // device-level overrides
20   virtual void device_start() { m_ram.resize(0x1000); save_item(NAME(m_ram)); }
21   virtual void device_reset() {}
22   virtual ioport_constructor device_input_ports() const;
23
24   // reading and writing
25   virtual DECLARE_READ8_MEMBER(read);
26   virtual DECLARE_WRITE8_MEMBER(write);
27
28protected:
29   dynamic_buffer m_ram;
30   required_ioport m_write_prot;
31};
32
33// ======================> astrocade_blueram_16k_device
34
35class astrocade_blueram_16k_device : public astrocade_blueram_4k_device
36{
37public:
38   // construction/destruction
39   astrocade_blueram_16k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
40   
41   virtual void device_start() { m_ram.resize(0x4000); save_item(NAME(m_ram)); }
42};
43
44// ======================> astrocade_blueram_32k_device
45
46class astrocade_blueram_32k_device : public astrocade_blueram_4k_device
47{
48public:
49   // construction/destruction
50   astrocade_blueram_32k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
51   
52   virtual void device_start() { m_ram.resize(0x8000); save_item(NAME(m_ram)); }
53};
54
55// ======================> astrocade_viper_sys1_device
56
57class astrocade_viper_sys1_device : public device_t,
58                        public device_astrocade_card_interface
59{
60public:
61   // construction/destruction
62   astrocade_viper_sys1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
63   
64   // device-level overrides
65   virtual void device_start() { m_ram.resize(0x4000); save_item(NAME(m_ram)); }
66   virtual void device_reset() {}
67   virtual ioport_constructor device_input_ports() const;
68
69   // reading and writing
70   virtual DECLARE_READ8_MEMBER(read);
71   virtual DECLARE_WRITE8_MEMBER(write);
72   
73private:
74   dynamic_buffer m_ram;
75   required_ioport m_write_prot;
76};
77
78// ======================> astrocade_whiteram_device
79
80class astrocade_whiteram_device : public device_t,
81                        public device_astrocade_card_interface
82{
83public:
84   // construction/destruction
85   astrocade_whiteram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
86   
87   // device-level overrides
88   virtual void device_start() { m_ram.resize(0x8000); save_item(NAME(m_ram)); }
89   virtual void device_reset() {}
90   virtual ioport_constructor device_input_ports() const;
91   
92   // reading and writing
93   virtual DECLARE_READ8_MEMBER(read);
94   virtual DECLARE_WRITE8_MEMBER(write);
95   
96private:
97   dynamic_buffer m_ram;
98   required_ioport m_write_prot;
99};
100
101// ======================> astrocade_rl64ram_device
102
103class astrocade_rl64ram_device : public device_t,
104                     public device_astrocade_card_interface
105{
106public:
107   // construction/destruction
108   astrocade_rl64ram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
109   
110   // device-level overrides
111   virtual void device_start() { m_ram.resize(0xb000); save_item(NAME(m_ram)); }
112   virtual void device_reset() {}
113   virtual ioport_constructor device_input_ports() const;
114   
115   // reading and writing
116   virtual DECLARE_READ8_MEMBER(read);
117   virtual DECLARE_WRITE8_MEMBER(write);
118   
119private:
120   dynamic_buffer m_ram;
121   required_ioport m_write_prot;
122};
123
124
125
126// device type definition
127extern const device_type ASTROCADE_BLUERAM_4K;
128extern const device_type ASTROCADE_BLUERAM_16K;
129extern const device_type ASTROCADE_BLUERAM_32K;
130extern const device_type ASTROCADE_VIPER_SYS1;
131extern const device_type ASTROCADE_WHITERAM;
132extern const device_type ASTROCADE_RL64RAM;
133
134
135#endif
trunk/src/emu/bus/bus.mak
r241553r241554
129129OBJDIRS += $(BUSOBJ)/astrocde
130130BUSOBJS += $(BUSOBJ)/astrocde/slot.o
131131BUSOBJS += $(BUSOBJ)/astrocde/rom.o
132BUSOBJS += $(BUSOBJ)/astrocde/exp.o
133BUSOBJS += $(BUSOBJ)/astrocde/ram.o
134132endif
135133
136134
trunk/src/emu/bus/ecbbus/grip.c
r241553r241554
681681{
682682   m_base = m_j7->read();
683683   m_page = 0;
684   m_lps = 0;
685684}
686685
687686
trunk/src/mame/drivers/psychic5.c
r241553r241554
408408static ADDRESS_MAP_START( psychic5_main_map, AS_PROGRAM, 8, psychic5_state )
409409   AM_RANGE(0x0000, 0x7fff) AM_ROM
410410   AM_RANGE(0x8000, 0xbfff) AM_RAMBANK("bank1")
411   AM_RANGE(0xc000, 0xdfff) AM_DEVICE("vrambank", address_map_bank_device, amap8)
411   AM_RANGE(0xc000, 0xdfff) AM_READWRITE(psychic5_paged_ram_r, psychic5_paged_ram_w)
412412   AM_RANGE(0xe000, 0xefff) AM_RAM
413413   AM_RANGE(0xf000, 0xf000) AM_WRITE(soundlatch_byte_w)
414414   AM_RANGE(0xf001, 0xf001) AM_READNOP AM_WRITE(psychic5_coin_counter_w)
r241553r241554
421421   AM_RANGE(0xf800, 0xffff) AM_RAM
422422ADDRESS_MAP_END
423423
424
425static ADDRESS_MAP_START( psychic5_vrambank_map, AS_PROGRAM, 8, psychic5_state )
426   AM_RANGE(0x0000, 0x0fff) AM_RAM_WRITE(bg_videoram_w) AM_SHARE("bg_videoram")
427   AM_RANGE(0x1000, 0x1fff) AM_RAM
428
429   AM_RANGE(0x2000, 0x2000) AM_READ_PORT("SYSTEM")
430   AM_RANGE(0x2001, 0x2001) AM_READ_PORT("P1")
431   AM_RANGE(0x2002, 0x2002) AM_READ_PORT("P2")
432   AM_RANGE(0x2003, 0x2003) AM_READ_PORT("DSW1")
433   AM_RANGE(0x2004, 0x2004) AM_READ_PORT("DSW2")
434
435   AM_RANGE(0x2308, 0x230c) AM_RAM AM_SHARE("bg_control")
436
437   AM_RANGE(0x2400, 0x25ff) AM_RAM_WRITE(sprite_col_w) AM_SHARE("palette_ram_sp")
438   AM_RANGE(0x2800, 0x29ff) AM_RAM_WRITE(bg_col_w) AM_SHARE("palette_ram_bg")
439   AM_RANGE(0x2a00, 0x2bff) AM_RAM_WRITE(tx_col_w) AM_SHARE("palette_ram_tx")
440
441   AM_RANGE(0x3000, 0x37ff) AM_RAM_WRITE(fg_videoram_w) AM_SHARE("fg_videoram")
442
443ADDRESS_MAP_END
444
445
446424static ADDRESS_MAP_START( psychic5_sound_map, AS_PROGRAM, 8, psychic5_state )
447425   AM_RANGE(0x0000, 0x7fff) AM_ROM
448426   AM_RANGE(0xc000, 0xc7ff) AM_RAM
r241553r241554
472450   AM_RANGE(0xd200, 0xd7ff) AM_RAM AM_SHARE("spriteram")
473451   AM_RANGE(0xd800, 0xdfff) AM_RAM
474452
475   AM_RANGE(0xe000, 0xffff) AM_DEVICE("vrambank", address_map_bank_device, amap8)
453   AM_RANGE(0xe000, 0xffff) AM_READWRITE(psychic5_paged_ram_r, bombsa_paged_ram_w)
476454ADDRESS_MAP_END
477455
478456static ADDRESS_MAP_START( bombsa_sound_map, AS_PROGRAM, 8, psychic5_state )
r241553r241554
488466   AM_RANGE(0x80, 0x81) AM_DEVREADWRITE("ym2", ym2203_device, read, write)
489467ADDRESS_MAP_END
490468
491static ADDRESS_MAP_START( bombsa_vrambank_map, AS_PROGRAM, 8, psychic5_state )
492   AM_RANGE(0x0000, 0x1fff) AM_RAM_WRITE(bg_videoram_w) AM_SHARE("bg_videoram")
493469
494   AM_RANGE(0x2000, 0x2000) AM_READ_PORT("SYSTEM")
495   AM_RANGE(0x2001, 0x2001) AM_READ_PORT("P1")
496   AM_RANGE(0x2002, 0x2002) AM_READ_PORT("P2")
497   AM_RANGE(0x2003, 0x2003) AM_READ_PORT("DSW1")
498   AM_RANGE(0x2004, 0x2004) AM_READ_PORT("DSW2")
499
500   AM_RANGE(0x2308, 0x230c) AM_RAM AM_SHARE("bg_control")
501
502   AM_RANGE(0x3000, 0x31ff) AM_RAM_WRITE(sprite_col_w) AM_SHARE("palette_ram_sp")
503   AM_RANGE(0x3200, 0x33ff) AM_RAM_WRITE(bg_col_w) AM_SHARE("palette_ram_bg")
504   AM_RANGE(0x3400, 0x35ff) AM_RAM_WRITE(tx_col_w) AM_SHARE("palette_ram_tx")
505
506   AM_RANGE(0x2800, 0x2fff) AM_RAM_WRITE(fg_videoram_w) AM_SHARE("fg_videoram")
507ADDRESS_MAP_END
508
509
510470static INPUT_PORTS_START( psychic5 )
511471   PORT_START("SYSTEM")    /* system control */
512472   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 )
r241553r241554
695655   MCFG_CPU_PROGRAM_MAP(psychic5_main_map)
696656   MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", psychic5_state, psychic5_scanline, "screen", 0, 1)
697657
698   MCFG_DEVICE_ADD("vrambank", ADDRESS_MAP_BANK, 0)
699   MCFG_DEVICE_PROGRAM_MAP(psychic5_vrambank_map)
700   MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE)
701   MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8)
702   MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(14)
703   MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000)
704
705658   MCFG_CPU_ADD("audiocpu", Z80, XTAL_5MHz)
706659   MCFG_CPU_PROGRAM_MAP(psychic5_sound_map)
707660   MCFG_CPU_IO_MAP(psychic5_soundport_map)
r241553r241554
747700   MCFG_CPU_PROGRAM_MAP(bombsa_main_map)
748701   MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", psychic5_state, psychic5_scanline, "screen", 0, 1)
749702
750   MCFG_DEVICE_ADD("vrambank", ADDRESS_MAP_BANK, 0)
751   MCFG_DEVICE_PROGRAM_MAP(bombsa_vrambank_map)
752   MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE)
753   MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8)
754   MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(14)
755   MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000)
756
757703   MCFG_CPU_ADD("audiocpu", Z80, XTAL_5MHz )
758704   MCFG_CPU_PROGRAM_MAP(bombsa_sound_map)
759705   MCFG_CPU_IO_MAP(bombsa_soundport_map)
r241553r241554
772718   MCFG_PALETTE_ADD("palette", 768)
773719
774720   MCFG_VIDEO_START_OVERRIDE(psychic5_state,bombsa)
775   MCFG_VIDEO_RESET_OVERRIDE(psychic5_state,psychic5)
721   MCFG_VIDEO_RESET_OVERRIDE(psychic5_state,bombsa)
776722
777723   /* sound hardware */
778724   MCFG_SPEAKER_STANDARD_MONO("mono")
trunk/src/mame/includes/psychic5.h
r241553r241554
1#include "machine/bankdev.h"
2
31class psychic5_state : public driver_device
42{
53public:
r241553r241554
97      m_maincpu(*this, "maincpu"),
108      m_audiocpu(*this, "audiocpu"),
119      m_gfxdecode(*this, "gfxdecode"),
12      m_palette(*this, "palette"),
13      m_vrambank(*this, "vrambank"),
14      m_fg_videoram(*this, "fg_videoram"),
15      m_bg_videoram(*this, "bg_videoram"),
16      m_bg_control(*this, "bg_control"),
10      m_palette(*this, "palette")  { }
1711
18      m_ps5_palette_ram_bg(*this, "palette_ram_bg"),
19      m_ps5_palette_ram_sp(*this, "palette_ram_sp"),
20      m_ps5_palette_ram_tx(*this, "palette_ram_tx")
21
22   { }
23
2412   UINT8 m_bank_latch;
2513   UINT8 m_ps5_vram_page;
2614   UINT8 m_bg_clip_mode;
2715   UINT8 m_title_screen;
28
16   UINT8 m_bg_status;
17   UINT8 *m_ps5_pagedram[2];
18   UINT8 *m_bg_videoram;
19   UINT8 *m_ps5_dummy_bg_ram;
20   UINT8 *m_ps5_io_ram;
21   UINT8 *m_ps5_palette_ram;
22   UINT8 *m_fg_videoram;
2923   tilemap_t *m_bg_tilemap;
3024   tilemap_t *m_fg_tilemap;
25   int m_bg_palette_ram_base;
26   int m_bg_palette_base;
3127   UINT16 m_palette_intensity;
3228   UINT8 m_bombsa_unknown;
3329   int m_sx1;
r241553r241554
4238   DECLARE_READ8_MEMBER(psychic5_vram_page_select_r);
4339   DECLARE_WRITE8_MEMBER(psychic5_vram_page_select_w);
4440   DECLARE_WRITE8_MEMBER(psychic5_title_screen_w);
41   DECLARE_READ8_MEMBER(psychic5_paged_ram_r);
42   DECLARE_WRITE8_MEMBER(psychic5_paged_ram_w);
43   DECLARE_WRITE8_MEMBER(bombsa_paged_ram_w);
4544   DECLARE_WRITE8_MEMBER(bombsa_unknown_w);
4645   TILE_GET_INFO_MEMBER(get_bg_tile_info);
4746   TILE_GET_INFO_MEMBER(get_fg_tile_info);
r241553r241554
4948   DECLARE_VIDEO_START(psychic5);
5049   DECLARE_VIDEO_RESET(psychic5);
5150   DECLARE_VIDEO_START(bombsa);
51   DECLARE_VIDEO_RESET(bombsa);
5252   UINT32 screen_update_psychic5(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
5353   UINT32 screen_update_bombsa(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
5454   TIMER_DEVICE_CALLBACK_MEMBER(psychic5_scanline);
55   void psychic5_change_palette(int offset, UINT8* palram, int palbase);
55   void psychic5_change_palette(int color, int offset);
5656   void psychic5_change_bg_palette(int color, int lo_offs, int hi_offs);
5757   void set_background_palette_intensity();
5858   void draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect);
r241553r241554
6262   required_device<cpu_device> m_audiocpu;
6363   required_device<gfxdecode_device> m_gfxdecode;
6464   required_device<palette_device> m_palette;
65   optional_device<address_map_bank_device> m_vrambank;
66   required_shared_ptr<UINT8> m_fg_videoram;
67   required_shared_ptr<UINT8> m_bg_videoram;
68   required_shared_ptr<UINT8> m_bg_control;
69
70   required_shared_ptr<UINT8> m_ps5_palette_ram_bg;
71   required_shared_ptr<UINT8> m_ps5_palette_ram_sp;
72   required_shared_ptr<UINT8> m_ps5_palette_ram_tx;
73
74
75
76   DECLARE_WRITE8_MEMBER(fg_videoram_w);
77   DECLARE_WRITE8_MEMBER(bg_videoram_w);
78   DECLARE_WRITE8_MEMBER(sprite_col_w);
79   DECLARE_WRITE8_MEMBER(bg_col_w);
80   DECLARE_WRITE8_MEMBER(tx_col_w);
81
8265};
trunk/src/mame/machine/zndip.h
r241553r241554
4242
4343   int m_select;
4444   int m_clock;
45   int m_datain;
4546
4647   UINT8 m_bit;
4748   emu_timer *m_dip_timer;
trunk/src/mame/video/psychic5.c
r241553r241554
1010#include "video/jalblend.h"
1111#include "includes/psychic5.h"
1212
13
13#define BG_SCROLLX_LSB      0x308
14#define BG_SCROLLX_MSB      0x309
15#define BG_SCROLLY_LSB      0x30a
16#define BG_SCROLLY_MSB      0x30b
17#define BG_SCREEN_MODE      0x30c
1418#define BG_PAL_INTENSITY_RG 0x1fe
1519#define BG_PAL_INTENSITY_BU 0x1ff
1620
r241553r241554
1923  Palette color
2024***************************************************************************/
2125
22void psychic5_state::psychic5_change_palette(int offset, UINT8* palram, int palbase)
26void psychic5_state::psychic5_change_palette(int color, int offset)
2327{
24   UINT8 lo = palram[(offset) & ~1];
25   UINT8 hi = palram[(offset) | 1];
26
27   int color = offset >> 1;
28
29   jal_blend_set(palbase + color, hi & 0x0f);
30   m_palette->set_pen_color(palbase + color, pal4bit(lo >> 4), pal4bit(lo), pal4bit(hi >> 4));
28   UINT8 lo = m_ps5_palette_ram[offset & ~1];
29   UINT8 hi = m_ps5_palette_ram[offset | 1];
30   jal_blend_set(color, hi & 0x0f);
31   m_palette->set_pen_color(color, pal4bit(lo >> 4), pal4bit(lo), pal4bit(hi >> 4));
3132}
3233
3334void psychic5_state::psychic5_change_bg_palette(int color, int lo_offs, int hi_offs)
r241553r241554
4344
4445   irgb = rgb_t(ir,ig,ib);
4546
46   lo = m_ps5_palette_ram_bg[lo_offs];
47   hi = m_ps5_palette_ram_bg[hi_offs];
47   lo = m_ps5_palette_ram[lo_offs];
48   hi = m_ps5_palette_ram[hi_offs];
4849
4950   /* red,green,blue component */
5051   r = pal4bit(lo >> 4);
r241553r241554
5253   b = pal4bit(hi >> 4);
5354
5455   /* Grey background enable */
55   if (m_bg_control[4] & 2)
56   if (m_bg_status & 2)
5657   {
5758      UINT8 val = (r + g + b) / 3;        /* Grey */
5859      /* Just leave plain grey */
r241553r241554
7273void psychic5_state::set_background_palette_intensity()
7374{
7475   int i;
75   m_palette_intensity = m_ps5_palette_ram_sp[BG_PAL_INTENSITY_BU] |
76                  (m_ps5_palette_ram_sp[BG_PAL_INTENSITY_RG]<<8);
76   m_palette_intensity = m_ps5_palette_ram[BG_PAL_INTENSITY_BU] |
77                  (m_ps5_palette_ram[BG_PAL_INTENSITY_RG]<<8);
7778
7879   /* for all of the background palette */
7980   for (i = 0; i < 0x100; i++)
80      psychic5_change_bg_palette(i+0x100,i*2,i*2+1);
81      psychic5_change_bg_palette(m_bg_palette_base+i,m_bg_palette_ram_base+i*2,m_bg_palette_ram_base+i*2+1);
8182}
8283
8384
r241553r241554
9394WRITE8_MEMBER(psychic5_state::psychic5_vram_page_select_w)
9495{
9596   m_ps5_vram_page = data & 1;
96   m_vrambank->set_bank(data);
9797}
9898
9999WRITE8_MEMBER(psychic5_state::psychic5_title_screen_w)
r241553r241554
101101   m_title_screen = data;
102102}
103103
104READ8_MEMBER(psychic5_state::psychic5_paged_ram_r)
105{
106   if (m_ps5_vram_page == 1)
107   {
108      switch (offset)
109      {
110         case 0x00: return ioport("SYSTEM")->read();
111         case 0x01: return ioport("P1")->read();
112         case 0x02: return ioport("P2")->read();
113         case 0x03: return ioport("DSW1")->read();
114         case 0x04: return ioport("DSW2")->read();
115      }
116   }
104117
105
106WRITE8_MEMBER(psychic5_state::sprite_col_w)
107{
108   m_ps5_palette_ram_sp[offset] = data;
109   psychic5_change_palette(offset,m_ps5_palette_ram_sp, 0x000);
118   return m_ps5_pagedram[m_ps5_vram_page][offset];
110119}
111120
112WRITE8_MEMBER(psychic5_state::bg_col_w)
121WRITE8_MEMBER(psychic5_state::psychic5_paged_ram_w)
113122{
114   m_ps5_palette_ram_bg[offset] = data;
115   psychic5_change_palette(offset,m_ps5_palette_ram_bg, 0x100);
116}
123   m_ps5_pagedram[m_ps5_vram_page][offset] = data;
117124
118WRITE8_MEMBER(psychic5_state::tx_col_w)
119{
120   m_ps5_palette_ram_tx[offset] = data;
121   psychic5_change_palette(offset,m_ps5_palette_ram_tx, 0x200);
125   if (m_ps5_vram_page == 0)
126   {
127      if (offset <= 0xfff)
128         m_bg_tilemap->mark_tile_dirty(offset >> 1);
129   }
130   else
131   {
132      if (offset == BG_SCROLLX_LSB || offset == BG_SCROLLX_MSB)
133      {
134         UINT16 bg_scrollx = m_ps5_io_ram[BG_SCROLLX_LSB] | (m_ps5_io_ram[BG_SCROLLX_MSB] << 8);
135         m_bg_tilemap->set_scrollx(0, bg_scrollx);
136      }
137      else if (offset == BG_SCROLLY_LSB || offset == BG_SCROLLY_MSB)
138      {
139         UINT16 bg_scrolly = m_ps5_io_ram[BG_SCROLLY_LSB] | (m_ps5_io_ram[BG_SCROLLY_MSB] << 8);
140         m_bg_tilemap->set_scrolly(0, bg_scrolly);
141      }
142      else if (offset == BG_SCREEN_MODE)
143      {
144         m_bg_status = m_ps5_io_ram[BG_SCREEN_MODE];
145      }
146      else if (offset >= 0x400 && offset <= 0x5ff)    /* Sprite color */
147         psychic5_change_palette(((offset >> 1) & 0xff)+0x000,offset-0x400);
148      else if (offset >= 0x800 && offset <= 0x9ff)    /* BG color */
149         psychic5_change_palette(((offset >> 1) & 0xff)+0x100,offset-0x400);
150      else if (offset >= 0xa00 && offset <= 0xbff)    /* Text color */
151         psychic5_change_palette(((offset >> 1) & 0xff)+0x200,offset-0x400);
152      else if (offset >= 0x1000)
153         m_fg_tilemap->mark_tile_dirty((offset-0x1000) >> 1);
154   }
122155}
123156
124
125WRITE8_MEMBER(psychic5_state::fg_videoram_w)
157WRITE8_MEMBER(psychic5_state::bombsa_paged_ram_w)
126158{
127   m_fg_videoram[offset] = data;
128   m_fg_tilemap->mark_tile_dirty(offset >> 1);
129}
159   m_ps5_pagedram[m_ps5_vram_page][offset] = data;
130160
131WRITE8_MEMBER( psychic5_state::bg_videoram_w )
132{   
133   m_bg_videoram[offset] = data;
134   m_bg_tilemap->mark_tile_dirty(offset >> 1);
161   if (m_ps5_vram_page == 0)
162   {
163      m_bg_tilemap->mark_tile_dirty(offset >> 1);
164   }
165   else
166   {
167      if (offset == BG_SCROLLX_LSB || offset == BG_SCROLLX_MSB)
168      {
169         UINT16 bg_scrollx = m_ps5_io_ram[BG_SCROLLX_LSB] | (m_ps5_io_ram[BG_SCROLLX_MSB] << 8);
170         m_bg_tilemap->set_scrollx(0, bg_scrollx);
171      }
172      else if (offset == BG_SCROLLY_LSB || offset == BG_SCROLLY_MSB)
173      {
174         UINT16 bg_scrolly = m_ps5_io_ram[BG_SCROLLY_LSB] | (m_ps5_io_ram[BG_SCROLLY_MSB] << 8);
175         m_bg_tilemap->set_scrolly(0, bg_scrolly);
176      }
177      else if (offset == BG_SCREEN_MODE)
178      {
179         m_bg_status = m_ps5_io_ram[BG_SCREEN_MODE];
180      }
181      else if (offset >= 0x0800 && offset <= 0x0fff)
182         m_fg_tilemap->mark_tile_dirty((offset & 0x7ff) >> 1);
183      else if (offset >= 0x1000 && offset <= 0x15ff)
184         psychic5_change_palette((offset >> 1) & 0x3ff, offset-0x1000);
185   }
135186}
136187
137
138
139188WRITE8_MEMBER(psychic5_state::bombsa_unknown_w)
140189{
141190   m_bombsa_unknown = data;
r241553r241554
175224
176225VIDEO_START_MEMBER(psychic5_state,psychic5)
177226{
227   /*                          info              offset             w   h  col  row */
178228   m_bg_tilemap = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(psychic5_state::get_bg_tile_info),this), TILEMAP_SCAN_COLS, 16, 16, 64, 32);
179229   m_fg_tilemap = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(psychic5_state::get_fg_tile_info),this), TILEMAP_SCAN_COLS,  8,  8, 32, 32);
230
180231   m_fg_tilemap->set_transparent_pen(15);
232
233   m_ps5_pagedram[0] = auto_alloc_array(machine(), UINT8, 0x2000);
234   m_ps5_pagedram[1] = auto_alloc_array(machine(), UINT8, 0x2000);
235
236   m_bg_videoram  = &m_ps5_pagedram[0][0x0000];
237   m_ps5_dummy_bg_ram      = &m_ps5_pagedram[0][0x1000];
238   m_ps5_io_ram            = &m_ps5_pagedram[1][0x0000];
239   m_ps5_palette_ram       = &m_ps5_pagedram[1][0x0400];
240   m_fg_videoram  = &m_ps5_pagedram[1][0x1000];
241
181242   jal_blend_init(machine(), 1);
182243
244   m_bg_palette_ram_base = 0x400;
245   m_bg_palette_base = 0x100;
183246}
184247
185248VIDEO_START_MEMBER(psychic5_state,bombsa)
186249{
250   /*                          info              offset             w   h   col  row */
187251   m_bg_tilemap = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(psychic5_state::get_bg_tile_info),this), TILEMAP_SCAN_COLS, 16, 16, 128, 32);
188252   m_fg_tilemap = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(psychic5_state::get_fg_tile_info),this), TILEMAP_SCAN_COLS,  8,  8,  32, 32);
253
189254   m_fg_tilemap->set_transparent_pen(15);
255
256   m_ps5_pagedram[0] = auto_alloc_array(machine(), UINT8, 0x2000);
257   m_ps5_pagedram[1] = auto_alloc_array(machine(), UINT8, 0x2000);
258
259   m_bg_videoram  = &m_ps5_pagedram[0][0x0000];
260   m_ps5_dummy_bg_ram      = &m_ps5_pagedram[0][0x1000];
261   m_ps5_io_ram            = &m_ps5_pagedram[1][0x0000];
262   m_fg_videoram  = &m_ps5_pagedram[1][0x0800];
263   m_ps5_palette_ram       = &m_ps5_pagedram[1][0x1000];
264
190265   jal_blend_init(machine(), 0);
266
267   m_bg_palette_ram_base = 0x000;
268   m_bg_palette_base = 0x000;
191269}
192270
193271VIDEO_RESET_MEMBER(psychic5_state,psychic5)
194272{
195273   m_bg_clip_mode = 0;
196274   m_ps5_vram_page = 0;
275   m_bg_status = 0;
276   memset(m_ps5_pagedram[0],0,0x2000);
277   memset(m_ps5_pagedram[1],0,0x2000);
278   m_palette_intensity = 0;
279}
280
281VIDEO_RESET_MEMBER(psychic5_state,bombsa)
282{
283   m_ps5_vram_page = 0;
284   m_bg_status = 0;
197285   m_title_screen = 0;
286   memset(m_ps5_pagedram[0],0,0x2000);
287   memset(m_ps5_pagedram[1],0,0x2000);
198288   m_palette_intensity = 0;
199289}
200290
201291
202
203292/***************************************************************************
204293  Screen refresh
205294***************************************************************************/
r241553r241554
317406
318407UINT32 psychic5_state::screen_update_psychic5(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
319408{
320   UINT16 bg_scrollx = m_bg_control[0] | (m_bg_control[1] << 8);
321   m_bg_tilemap->set_scrollx(0, bg_scrollx);
322   UINT16 bg_scrolly = m_bg_control[2] | (m_bg_control[3] << 8);
323   m_bg_tilemap->set_scrolly(0, bg_scrolly);
324
325409   bitmap.fill(m_palette->black_pen(), cliprect);
326   if (m_bg_control[4] & 1)    /* Backgound enable */
410   if (m_bg_status & 1)    /* Backgound enable */
327411      draw_background(screen, bitmap, cliprect);
328412   if (!(m_title_screen & 1))
329413      draw_sprites(bitmap, cliprect);
r241553r241554
333417
334418UINT32 psychic5_state::screen_update_bombsa(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
335419{
336   UINT16 bg_scrollx = m_bg_control[0] | (m_bg_control[1] << 8);
337   m_bg_tilemap->set_scrollx(0, bg_scrollx);
338   UINT16 bg_scrolly = m_bg_control[2] | (m_bg_control[3] << 8);
339   m_bg_tilemap->set_scrolly(0, bg_scrolly);
340   bitmap.fill(m_palette->black_pen(), cliprect);
341
342   if (m_bg_control[4] & 1)    /* Backgound enable */
420   if (m_bg_status & 1)    /* Backgound enable */
343421      m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
344422   else
345423      bitmap.fill(m_palette->pen(0x0ff), cliprect);
trunk/src/mess/drivers/astrocde.c
r241553r241554
1414#include "sound/astrocde.h"
1515#include "bus/astrocde/slot.h"
1616#include "bus/astrocde/rom.h"
17#include "bus/astrocde/exp.h"
18#include "bus/astrocde/ram.h"
1917
2018class astrocde_mess_state : public astrocde_state
2119{
r241553r241554
2624      { }
2725
2826   required_device<astrocade_cart_slot_device> m_cart;
27   void get_ram_expansion_settings(int &ram_expansion_installed, int &write_protect_on, int &expansion_ram_start, int &expansion_ram_end, int &shadow_ram_end);
2928   DECLARE_MACHINE_START(astrocde);
29   DECLARE_MACHINE_RESET(astrocde);
30   DECLARE_INPUT_CHANGED_MEMBER(set_write_protect);
3031};
3132
32/*********************************************************************************
33/*************************************
3334 *
3435 *  Memory maps
3536 *
r241553r241554
4142 * by an extended BASIC program.  Bally and Astrocade BASIC can access from
4243 * $5000 to $7FFF if available.
4344 *
44 *********************************************************************************/
45 *  RAM Expansions
46 *
47 * Several third party RAM expansions have been made for the Astrocade.  These
48 * allow access to various ranges of the expansion memory ($5000 to $FFFF).
49 * A RAM expansion is required to use extended BASIC programs like Blue RAM BASIC
50 * and VIPERSoft BASIC.  All of the expansions also have a RAM protect switch, which
51 * can be flipped at any time to make the RAM act like ROM.  Extended BASIC
52 * programs need access to the RAM and won't work with RAM protect enabled, but
53 * this can be useful with Bally and Astrocade BASIC.  They also have a range switch
54 * (not implemented).  The default position is 6K, but it can be switched to
55 * 2K.  This means that the expanded memory starting at $6000 will instead be
56 * mapped to the cartridge memory starting at $2000.  So it would be possible to
57 * load a cartridge program from tape into the expansion memory, then flip the range
58 * switch and run it as a cartridge.  This is useful for cartridge development.
59 *
60 * NOTE:  If you have any trouble running cartridges with a RAM expansion installed, hit reset.
61 *
62 * Blue RAM -- available in 4K, 16K, and 32K.  These also use an INS8154 chip,
63 * (not yet implemented) which has an additional $80 bytes of RAM mapped
64 * immediately after the end of the expansion address space.  This memory
65 * can't be write protected.  The INS8154 has I/O features needed for loading
66 * tape programs into Blue RAM BASIC, as well as running the Blue RAM Utility cart.
67 * 4K:  $6000 to $6FFF (can't run VIPERSoft BASIC, because this program needs memory
68 * past this range)
69 * 16K:  $6000 to $9FFF
70 * 32K:  $6000 to $DFFF
71 *
72 * VIPER System 1 -- This is available in 16K only.  It also includes a keyboard (not implemented).
73 * 16K:  $6000 to $9FFF
74 *
75 * Lil' WHITE RAM -- This is available in 32K only.  Attempts to read and write
76 * to memory outside of its address range ($D000 to $FFFF) are mapped to the expansion
77 * memory $5000 to $7FFF.  The current implementation won't allow the shadow RAM area
78 * to be accessed when RAM protect is on, but there is no known software that will
79 * access the upper range of the expansion RAM when RAM protect is enabled.
80 * 32K:  $5000 to $CFFF
81 *
82 * R&L 64K RAM Board -- This is a highly configurable kit.  RAM can be installed in
83 * 2K increments.  So, the entire 44K expansion memory can be filled.  It is also
84 * possible to override the rest of the memory map with RAM (not implemented).
85 * There are 32 switches allowing users to activate and deactivate each 2K block (not implemented).
86 * RAM write protection can be implemented in three ranges through jumpers or by
87 * installing switches.  The ranges are $0000 to $0FFF (first 4K), $0000 to $3FFF (first 16K),
88 * and $0000 to $FFFF (all 64K).  The current implementation is for 44K expansion memory mapped from
89 * $5000 to $FFFF, with only a single write protect covering this entire range.
90 *
91 *************************************/
4592
4693static ADDRESS_MAP_START( astrocade_mem, AS_PROGRAM, 8, astrocde_mess_state )
4794   AM_RANGE(0x0000, 0x0fff) AM_ROM AM_WRITE(astrocade_funcgen_w)
4895   AM_RANGE(0x1000, 0x3fff) AM_ROM /* Star Fortress writes in here?? */
4996   AM_RANGE(0x4000, 0x4fff) AM_RAM AM_SHARE("videoram") /* ASG */
50   AM_RANGE(0x5000, 0xffff) AM_DEVREADWRITE("exp", astrocade_exp_device, read, write)
5197ADDRESS_MAP_END
5298
5399
r241553r241554
55101   AM_RANGE(0x00, 0x1f) AM_MIRROR(0xff00) AM_MASK(0xffff) AM_READWRITE(astrocade_data_chip_register_r, astrocade_data_chip_register_w)
56102ADDRESS_MAP_END
57103
104INPUT_CHANGED_MEMBER(astrocde_mess_state::set_write_protect)  // run when RAM expansion write protect switch is changed
105{
106   int ram_expansion_installed = 0, write_protect_on = 0, expansion_ram_start = 0, expansion_ram_end = 0, shadow_ram_end = 0;
107   address_space &space = m_maincpu->space(AS_PROGRAM);
108   UINT8 *expram = machine().device<ram_device>("ram_tag")->pointer();
109
110   get_ram_expansion_settings(ram_expansion_installed, write_protect_on, expansion_ram_start, expansion_ram_end, shadow_ram_end);  // passing by reference
111
112   if (ram_expansion_installed == 1)
113   {
114      if (write_protect_on == 0)  // write protect off, so install memory normally
115      {
116         space.install_ram(expansion_ram_start, expansion_ram_end, expram);
117         if (shadow_ram_end > expansion_ram_end)
118            space.install_ram(expansion_ram_end + 1, shadow_ram_end, expram);
119      }
120      else  // write protect on, so make memory read only
121      {
122         space.nop_write(expansion_ram_start, expansion_ram_end);
123      }
124   }
125}
126
58127/*************************************
59128 *
60129 *  Input ports
r241553r241554
158227
159228   PORT_START("P4_KNOB")
160229   PORT_BIT(0xff, 0x00, IPT_PADDLE) PORT_INVERT PORT_SENSITIVITY(85) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) PORT_MINMAX(0,255) PORT_CODE_DEC(KEYCODE_Y) PORT_CODE_INC(KEYCODE_U) PORT_PLAYER(4)
230
231   PORT_START("CFG")   /* machine config */
232   PORT_DIPNAME( 0x3f, 0x00, "RAM Expansion")
233   PORT_DIPSETTING(    0x00, "No RAM Expansion")
234   PORT_DIPSETTING(    0x01, "16KB Viper System 1 RAM Expansion")
235   PORT_DIPSETTING(    0x02, "32KB Lil' WHITE RAM Expansion")
236   PORT_DIPSETTING(    0x04, "R&L 64K RAM Board (44K installed)")
237   PORT_DIPSETTING(    0x08, "4KB Blue RAM Expansion")
238   PORT_DIPSETTING(    0x10, "16KB Blue RAM Expansion")
239   PORT_DIPSETTING(    0x20, "32KB Blue RAM Expansion")
240
241   PORT_START("PROTECT")  /* Write protect RAM */
242   PORT_DIPNAME( 0x01, 0x00, "Write Protect RAM") PORT_CHANGED_MEMBER(DEVICE_SELF, astrocde_mess_state, set_write_protect, 0)
243   PORT_DIPSETTING( 0x00, "Write Protect Off")
244   PORT_DIPSETTING( 0x01, "Write Protect On")
161245INPUT_PORTS_END
162246
163247
r241553r241554
173257   SLOT_INTERFACE_INTERNAL("rom_512k",  ASTROCADE_ROM_512K)
174258SLOT_INTERFACE_END
175259
176static SLOT_INTERFACE_START(astrocade_exp)
177   SLOT_INTERFACE("blue_ram_4k",   ASTROCADE_BLUERAM_4K)
178   SLOT_INTERFACE("blue_ram_16k",  ASTROCADE_BLUERAM_16K)
179   SLOT_INTERFACE("blue_ram_32k",  ASTROCADE_BLUERAM_32K)
180   SLOT_INTERFACE("viper_sys1",    ASTROCADE_VIPER_SYS1)
181   SLOT_INTERFACE("lil_white_ram", ASTROCADE_WHITERAM)
182   SLOT_INTERFACE("rl64_ram",      ASTROCADE_RL64RAM)
183SLOT_INTERFACE_END
184260
185
186261static MACHINE_CONFIG_START( astrocde, astrocde_mess_state )
187262   /* basic machine hardware */
188263   MCFG_CPU_ADD("maincpu", Z80, ASTROCADE_CLOCK/4)        /* 1.789 MHz */
r241553r241554
190265   MCFG_CPU_IO_MAP(astrocade_io)
191266
192267   MCFG_MACHINE_START_OVERRIDE(astrocde_mess_state, astrocde)
268   MCFG_MACHINE_RESET_OVERRIDE(astrocde_mess_state, astrocde)
193269
194270   /* video hardware */
195271   MCFG_SCREEN_ADD("screen", RASTER)
r241553r241554
205281   MCFG_SOUND_ADD("astrocade1", ASTROCADE, ASTROCADE_CLOCK/4)
206282   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
207283
208   /* expansion port */
209   MCFG_ASTROCADE_EXPANSION_SLOT_ADD("exp", astrocade_exp, NULL)
284   /* optional expansion ram (installed in machine_reset)*/
285   MCFG_RAM_ADD("ram_tag")
286   MCFG_RAM_DEFAULT_SIZE("32k")
210287
211288   /* cartridge */
212289   MCFG_ASTROCADE_CARTRIDGE_ADD("cartslot", astrocade_cart, NULL)
r241553r241554
254331      m_maincpu->space(AS_PROGRAM).install_read_handler(0x2000, 0x3fff, read8_delegate(FUNC(astrocade_cart_slot_device::read_rom),(astrocade_cart_slot_device*)m_cart));
255332}
256333
334MACHINE_RESET_MEMBER(astrocde_mess_state, astrocde)
335{
336   int ram_expansion_installed = 0, write_protect_on = 0, expansion_ram_start = 0, expansion_ram_end = 0, shadow_ram_end = 0;
337   address_space &space = m_maincpu->space(AS_PROGRAM);
338   UINT8 *expram = machine().device<ram_device>("ram_tag")->pointer();
339   space.unmap_readwrite(0x5000, 0xffff);  // unmap any previously installed expansion RAM
340
341   get_ram_expansion_settings(ram_expansion_installed, write_protect_on, expansion_ram_start, expansion_ram_end, shadow_ram_end);  // passing by reference
342
343   if (ram_expansion_installed == 1)
344   {
345      if (write_protect_on == 0)  // write protect off, so install memory normally
346      {
347         space.install_ram(expansion_ram_start, expansion_ram_end, expram);
348         if (shadow_ram_end > expansion_ram_end)
349            space.install_ram(expansion_ram_end + 1, shadow_ram_end, expram);
350      }
351      else  // write protect on, so make memory read only
352      {
353         space.nop_write(expansion_ram_start, expansion_ram_end);
354      }
355   }
356}
357
358void astrocde_mess_state::get_ram_expansion_settings(int &ram_expansion_installed, int &write_protect_on, int &expansion_ram_start, int &expansion_ram_end, int &shadow_ram_end)
359{
360   if (ioport("PROTECT")->read() == 0x01)
361      write_protect_on = 1;
362   else
363      write_protect_on = 0;
364
365   ram_expansion_installed = 1;
366
367   switch(ioport("CFG")->read())  // check RAM expansion configuration and set address ranges
368   {
369      case 0x00:  // No RAM Expansion
370            ram_expansion_installed = 0;
371            break;
372      case 0x01:  // 16KB Viper System 1 RAM Expansion
373            expansion_ram_start = 0x6000;
374            expansion_ram_end = 0x9fff;
375            shadow_ram_end = 0;
376            break;
377      case 0x02:  // "32KB Lil' WHITE RAM Expansion
378            expansion_ram_start = 0x5000;
379            expansion_ram_end = 0xcfff;
380            shadow_ram_end = 0xffff;
381            break;
382      case 0x04:  // R&L 64K RAM Board (44KB installed)
383            expansion_ram_start = 0x5000;
384            expansion_ram_end = 0xffff;
385            shadow_ram_end = 0;
386            break;
387      case 0x08:  // 4KB Blue RAM Expansion
388            expansion_ram_start = 0x6000;
389            expansion_ram_end = 0x6fff;
390            shadow_ram_end = 0;
391            break;
392      case 0x10:  // 16KB Blue RAM Expansion
393            expansion_ram_start = 0x6000;
394            expansion_ram_end = 0x9fff;
395            shadow_ram_end = 0;
396            break;
397      case 0x20:  // 32KB Blue RAM Expansion
398            expansion_ram_start = 0x6000;
399            expansion_ram_end = 0xdfff;
400            shadow_ram_end = 0;
401            break;
402      default:
403         break;
404   }
405}
406
407
257408/*************************************
258409 *
259410 *  Driver definitions
trunk/src/mess/drivers/wswan.c
r241553r241554
3535#include "wswan.lh"
3636
3737static ADDRESS_MAP_START (wswan_mem, AS_PROGRAM, 8, wswan_state)
38   AM_RANGE(0x00000, 0x03fff) AM_DEVREADWRITE("vdp", wswan_video_device, vram_r, vram_w)       // 16kb RAM / 4 colour tiles
38   AM_RANGE(0x00000, 0x03fff) AM_RAM       // 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_DEVREADWRITE("vdp", wswan_video_device, vram_r, vram_w)       // 16kb RAM / 4 colour tiles, 16 colour tiles + palettes
45   AM_RANGE(0x00000, 0x0ffff) AM_RAM       // 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
r241553r241554
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   {
r241553r241554
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 )
r241553r241554
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
114109   MCFG_SCREEN_ADD("screen", LCD)
115110   MCFG_SCREEN_REFRESH_RATE(75)
116111   MCFG_SCREEN_VBLANK_TIME(0)
117   MCFG_SCREEN_UPDATE_DEVICE("vdp", wswan_video_device, screen_update)
118   MCFG_SCREEN_SIZE(WSWAN_X_PIXELS, WSWAN_Y_PIXELS)
112   MCFG_SCREEN_UPDATE_DRIVER(wswan_state, screen_update)
113   MCFG_SCREEN_SIZE( WSWAN_X_PIXELS, WSWAN_Y_PIXELS )
119114   MCFG_SCREEN_VISIBLE_AREA(0*8, WSWAN_X_PIXELS - 1, 0, WSWAN_Y_PIXELS - 1)
120115   MCFG_SCREEN_PALETTE("palette")
121116
r241553r241554
146141static MACHINE_CONFIG_DERIVED( wscolor, wswan )
147142   MCFG_CPU_MODIFY("maincpu")
148143   MCFG_CPU_PROGRAM_MAP(wscolor_mem)
149   MCFG_MACHINE_START_OVERRIDE(wswan_state, wscolor)
144   MCFG_MACHINE_START_OVERRIDE(wswan_state, wscolor )
150145
151   MCFG_DEVICE_MODIFY("vdp")
152   MCFG_WSWAN_VIDEO_TYPE(VDP_TYPE_WSC)
153
154146   MCFG_PALETTE_MODIFY("palette")
155147   MCFG_PALETTE_ENTRIES(4096)
156   MCFG_PALETTE_INIT_OWNER(wswan_state, wscolor)
148   MCFG_PALETTE_INIT_OWNER(wswan_state, wscolor )
157149
158150   /* software lists */
159151   MCFG_DEVICE_REMOVE("cart_list")
trunk/src/mess/includes/ti85.h
r241553r241554
8686   UINT8 m_ON_interrupt_status;
8787   UINT8 m_ON_pressed;
8888   UINT8 m_flash_unlocked;
89   UINT8 m_ti8x_memory_page_0;
8990   UINT8 m_ti8x_memory_page_1;
9091   UINT8 m_ti8x_memory_page_2;
9192   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;
r241553r241554
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 );
221220   
222221   ti83pse_timer m_ctimer[3];
223222   
trunk/src/mess/includes/wswan.h
r241553r241554
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
1316#define INTERNAL_EEPROM_SIZE    1024
1417
1518#include "emu.h"
1619#include "cpu/v30mz/v30mz.h"
20#include "audio/wswan_snd.h"
1721#include "machine/nvram.h"
18#include "audio/wswan_snd.h"
19#include "video/wswan_video.h"
2022#include "bus/wswan/slot.h"
2123#include "bus/wswan/rom.h"
2224
r241553r241554
2830   UINT8   enable;     /* Enabled */
2931};
3032
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};
3178
79
3280class wswan_state : public driver_device
3381{
3482public:
3583   wswan_state(const machine_config &mconfig, device_type type, const char *tag)
3684      : driver_device(mconfig, type, tag),
3785      m_maincpu(*this, "maincpu"),
38      m_vdp(*this, "vdp"),
3986      m_sound(*this, "custom"),
4087      m_cart(*this, "cartslot"),
4188      m_cursx(*this, "CURSX"),
4289      m_cursy(*this, "CURSY"),
43      m_buttons(*this, "BUTTONS")
44   { }
45   
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
4696   required_device<cpu_device> m_maincpu;
47   required_device<wswan_video_device> m_vdp;
4897   required_device<wswan_sound_device> m_sound;
4998   required_device<ws_cart_slot_device> m_cart;
5099   DECLARE_READ8_MEMBER(bios_r);
51100   DECLARE_READ8_MEMBER(port_r);
52101   DECLARE_WRITE8_MEMBER(port_w);
53   
102
103   VDP m_vdp;
54104   UINT8 m_ws_portram[256];
55105   UINT8 m_internal_eeprom[INTERNAL_EEPROM_SIZE];
56106   UINT8 m_system_type;
57107   SoundDMA m_sound_dma;
108   UINT8 *m_ws_ram;
58109   UINT8 *m_ws_bios_bank;
59110   UINT8 m_bios_disabled;
111   int m_pal[16][16];
112   bitmap_ind16 m_bitmap;
60113   UINT8 m_rotate;
61   
62   void set_irq_line(int irq);
63   void dma_sound_cb();
114
115   void wswan_clear_irq_line(int irq);
64116   void common_start();
65117   virtual void machine_start();
66118   virtual void machine_reset();
67119   DECLARE_PALETTE_INIT(wswan);
68120   DECLARE_MACHINE_START(wscolor);
69121   DECLARE_PALETTE_INIT(wscolor);
70   
122   TIMER_CALLBACK_MEMBER(wswan_scanline_interrupt);
123
71124protected:
72125   /* Interrupt flags */
73126   static const UINT8 WSWAN_IFLAG_STX    = 0x01;
r241553r241554
78131   static const UINT8 WSWAN_IFLAG_VBLTMR = 0x20;
79132   static const UINT8 WSWAN_IFLAG_VBL    = 0x40;
80133   static const UINT8 WSWAN_IFLAG_HBLTMR = 0x80;
81   
134
82135   /* Interrupts */
83136   static const UINT8 WSWAN_INT_STX    = 0;
84137   static const UINT8 WSWAN_INT_KEY    = 1;
r241553r241554
88141   static const UINT8 WSWAN_INT_VBLTMR = 5;
89142   static const UINT8 WSWAN_INT_VBL    = 6;
90143   static const UINT8 WSWAN_INT_HBLTMR = 7;
91   
144
92145   required_ioport m_cursx;
93146   required_ioport m_cursy;
94147   required_ioport m_buttons;
95   
96   void register_save();
97   void handle_irqs();
98   void clear_irq_line(int irq);
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( );
99160};
100161
101162
trunk/src/mess/machine/ti85.c
r241553r241554
154154{
155155   //address_space &space = m_maincpu->space(AS_PROGRAM);
156156
157   m_membank1->set_bank(m_booting ? 0x1f : 0); //Always flash page 0, well allmost
157   m_membank1->set_bank(0); //Always flash page 0, well allmost
158158   
159159   if (m_ti83p_port4 & 1)
160160   {
r241553r241554
182182{
183183   //address_space &space = m_maincpu->space(AS_PROGRAM);
184184   
185   m_membank1->set_bank(m_booting ? (m_model==TI84P ? 0x3f : 0x7f) : 0);
185   m_membank1->set_bank(m_ti8x_memory_page_0);
186186   
187187   if (m_ti83p_port4 & 1)
188188    {
r241553r241554
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
290276MACHINE_RESET_MEMBER(ti85_state,ti83p)
291277{
292278   m_red_out = 0x00;
293279   m_white_out = 0x00;
294280   m_PCR = 0xc0;
295281
282   m_ti8x_memory_page_0 = 0;//0x1f;
296283
297    m_ti8x_memory_page_1 = 0;
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
298297   m_ti8x_memory_page_2 = 0;
299298   m_ti8x_memory_page_3 = 0;
300299   m_ti83p_port4 = 1;
301   m_booting = true;
302300   if (m_model == TI83P)
303301    {
304302        update_ti83p_memory();
r241553r241554
307305    {
308306        update_ti83pse_memory();
309307    }
308
309   m_maincpu->set_pc(0x8000);
310310}
311311
312312MACHINE_START_MEMBER(ti85_state,ti83p)
r241553r241554
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));
318317
319318   m_timer_interrupt_mask = 0;
320319   m_timer_interrupt_status = 0;
321320   m_ON_interrupt_mask = 0;
322321   m_ON_interrupt_status = 0;
323322   m_ON_pressed = 0;
324   m_ti8x_memory_page_1 = 0;
323   m_ti8x_memory_page_0 = 0;//0x1f;
324   m_ti8x_memory_page_1 = 0x1f;
325325   m_ti8x_memory_page_2 = 0;
326326   m_ti8x_memory_page_3 = 0;
327327   m_LCD_memory_base = 0;
r241553r241554
334334   m_ti83p_port4 = 1;
335335   m_flash_unlocked = 0;
336336
337   m_booting = true;
338
339337    ti85_state::update_ti83p_memory();
338   m_maincpu->set_pc(0x8000); //this is a hack due to incomplete memory mapping emulation
340339
341340
342341   machine().scheduler().timer_pulse(attotime::from_hz(256), timer_expired_delegate(FUNC(ti85_state::ti83_timer1_callback),this));
r241553r241554
346345   /* save states and debugging */
347346   save_item(NAME(m_timer_interrupt_status));
348347    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));
354353}
355354
356355void ti85_state::ti8xpse_init_common()
r241553r241554
364363   m_ON_interrupt_mask = 0;
365364   m_ON_interrupt_status = 0;
366365   m_ON_pressed = 0;
367   m_ti8x_memory_page_1 = 0;
366   m_ti8x_memory_page_0 = 00;//0x7f;
367   m_ti8x_memory_page_1 = (m_model != TI84P ) ? 0x7f : 0x3f ;
368368   m_ti8x_memory_page_2 = 0;
369369   m_ti8x_memory_page_3 = 0;
370370   m_LCD_memory_base = 0;
r241553r241554
378378   m_flash_unlocked = 0;
379379
380380   ti85_state::update_ti83pse_memory();
381   m_maincpu->space(AS_PROGRAM).set_direct_update_handler(direct_update_delegate(FUNC(ti85_state::ti83p_direct_update_handler), this));
381   m_maincpu->set_pc(0x8000);//same as above, hack to work around incomplete memory mapping emulation
382382
383383
384384   machine().scheduler().timer_pulse(attotime::from_hz(256), timer_expired_delegate(FUNC(ti85_state::ti83_timer1_callback),this));
r241553r241554
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));
394395   save_item(NAME(m_ti8x_memory_page_1));
395396   save_item(NAME(m_ti8x_memory_page_2));
396397   save_item(NAME(m_ti8x_memory_page_3));
trunk/src/mess/machine/wswan.c
r241553r241554
7878   0xea, 0xc0, 0xff, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
7979};
8080
81void wswan_state::handle_irqs()
81void wswan_state::wswan_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::set_irq_line(int irq)
121void wswan_state::wswan_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      handle_irqs();
126      wswan_handle_irqs();
127127   }
128128}
129129
130void wswan_state::dma_sound_cb()
130void wswan_state::wswan_clear_irq_line(int irq)
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{
148132   m_ws_portram[0xb6] &= ~irq;
149   handle_irqs();
133   wswan_handle_irqs();
150134}
151135
152void wswan_state::register_save()
136void wswan_state::wswan_register_save()
153137{
154138   save_item(NAME(m_ws_portram));
155139   save_item(NAME(m_internal_eeprom));
156140   save_item(NAME(m_bios_disabled));
157141   save_item(NAME(m_rotate));
158   
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
159182   save_item(NAME(m_sound_dma.source));
160183   save_item(NAME(m_sound_dma.size));
161184   save_item(NAME(m_sound_dma.enable));
162   
185
163186   if (m_cart->exists())
164187      m_cart->save_nvram();
188
189   machine().save().register_postload(save_prepost_delegate(FUNC(wswan_state::wswan_postload), this));
165190}
166191
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
167200void wswan_state::common_start()
168201{
169202   m_ws_bios_bank = auto_alloc_array(machine(), UINT8, 0x10000);
170203   memcpy(m_ws_bios_bank + 0xffc0, ws_fake_bios_code, 0x40);
171   
172   register_save();
173   
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
174210   machine().device<nvram_device>("nvram")->set_base(m_internal_eeprom, INTERNAL_EEPROM_SIZE);
175   
211
176212   if (m_cart->exists())
177213   {
178214      // ROM
179215      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));
180216      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));
181217      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));
182     
218
183219      // SRAM
184220      if (m_cart->get_type() == WS_SRAM)
185221      {
r241553r241554
195231   m_system_type = TYPE_WSWAN;
196232}
197233
198MACHINE_START_MEMBER(wswan_state, wscolor)
234MACHINE_START_MEMBER(wswan_state,wscolor)
199235{
200236   common_start();
201237   m_system_type = TYPE_WSC;
r241553r241554
203239
204240void wswan_state::machine_reset()
205241{
242   address_space &space = m_maincpu->space(AS_PROGRAM);
243
206244   m_bios_disabled = 0;
207   
245
246   m_ws_ram = (UINT8*) m_maincpu->space(AS_PROGRAM).get_read_ptr(0);
247   memset(m_ws_ram, 0, 0xffff);
248
208249   if (m_cart->exists())
209250      m_rotate = m_cart->get_is_rotated();
210251   else
211252      m_rotate = 0;
212   
253
213254   /* Intialize ports */
214255   memcpy(m_ws_portram, ws_portram_init, 256);
215   
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
216267   render_target *target = machine().render().first_target();
217268   target->set_view(m_rotate);
218   
269
219270   /* Initialize sound DMA */
220271   memset(&m_sound_dma, 0, sizeof(m_sound_dma));
221272}
r241553r241554
231282READ8_MEMBER( wswan_state::port_r )
232283{
233284   UINT8 value = m_ws_portram[offset];
234   
285
235286   if (offset != 2)
236287      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   
241288   switch (offset)
242289   {
290      case 0x02:      // Current line
291         value = m_vdp.current_line;
292         break;
243293      case 0x4a:      // Sound DMA source address (low)
244294         value = m_sound_dma.source & 0xff;
245295         break;
r241553r241554
258308      case 0x52:      // Sound DMA start/stop
259309         value = m_sound_dma.enable;
260310         break;
261      case 0x60:
262         value = m_vdp->reg_r(space, offset);
263         break;
264311      case 0xa0:      // Hardware type
265         // Bit 0 - Disable/enable Bios
266         // Bit 1 - Determine mono/color
267         // Bit 2 - Determine color/crystal
312               // Bit 0 - Disable/enable Bios
313               // Bit 1 - Determine mono/color
314               // Bit 2 - Determine color/crystal
268315         value = value & ~ 0x02;
269316         if (m_system_type == TYPE_WSC)
270317            value |= 2;
271318         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;
272331      case 0xc0:
273332      case 0xc1:
274333      case 0xc2:
r241553r241554
288347         value = m_cart->read_io(space, offset & 0x0f);
289348         break;
290349   }
291   
350
292351   return value;
293352}
294353
r241553r241554
297356   address_space &mem = m_maincpu->space(AS_PROGRAM);
298357   UINT8 input;
299358   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   
307359   switch (offset)
308360   {
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;
309638      case 0x40:  /* DMA source address (low)
310                Bit 0-7 - DMA source address bit 0-7
311                */
639                   Bit 0-7 - DMA source address bit 0-7
640                */
312641      case 0x41:  /* DMA source address (high)
313                Bit 0-7 - DMA source address bit 8-15
314                */
642                   Bit 0-7 - DMA source address bit 8-15
643                */
315644      case 0x42:  /* DMA source bank
316                Bit 0-7 - DMA source bank number
317                */
645                   Bit 0-7 - DMA source bank number
646                */
318647      case 0x43:  /* DMA destination bank
319                Bit 0-7 - DMA destination bank number
320                */
648                   Bit 0-7 - DMA destination bank number
649                */
321650      case 0x44:  /* DMA destination address (low)
322                Bit 0-7 - DMA destination address bit 0-7
323                */
651                   Bit 0-7 - DMA destination address bit 0-7
652                */
324653      case 0x45:  /* DMA destination address (high)
325                Bit 0-7 - DMA destination address bit 8-15
326                */
654                   Bit 0-7 - DMA destination address bit 8-15
655                */
327656      case 0x46:  /* Size of copied data (low)
328                Bit 0-7 - DMA size bit 0-7
329                */
657                   Bit 0-7 - DMA size bit 0-7
658                */
330659      case 0x47:  /* Size of copied data (high)
331                Bit 0-7 - DMA size bit 8-15
332                */
660                   Bit 0-7 - DMA size bit 8-15
661                */
333662         break;
334663      case 0x48:  /* DMA control
335                Bit 0-6 - Unknown
336                Bit 7   - DMA stop/start
337                */
664                   Bit 0-6 - Unknown
665                   Bit 7   - DMA stop/start
666                */
338667         if (data & 0x80)
339668         {
340669            UINT32 src, dst;
341670            UINT16 length;
342           
671
343672            src = m_ws_portram[0x40] + (m_ws_portram[0x41] << 8) + (m_ws_portram[0x42] << 16);
344673            dst = m_ws_portram[0x44] + (m_ws_portram[0x45] << 8) + (m_ws_portram[0x43] << 16);
345674            length = m_ws_portram[0x46] + (m_ws_portram[0x47] << 8);
r241553r241554
350679               dst++;
351680            }
352681#ifdef MAME_DEBUG
353            logerror("DMA  src:%X dst:%X length:%d\n", src, dst, length);
682               logerror("DMA  src:%X dst:%X length:%d\n", src, dst, length);
354683#endif
355684            m_ws_portram[0x40] = src & 0xff;
356685            m_ws_portram[0x41] = (src >> 8) & 0xff;
r241553r241554
362691         }
363692         break;
364693      case 0x4a:  /* Sound DMA source address (low)
365                Bit 0-7 - Sound DMA source address bit 0-7
366                */
694                   Bit 0-7 - Sound DMA source address bit 0-7
695                */
367696         m_sound_dma.source = (m_sound_dma.source & 0x0fff00) | data;
368697         break;
369698      case 0x4b:  /* Sound DMA source address (high)
370                Bit 0-7 - Sound DMA source address bit 8-15
371                */
699                   Bit 0-7 - Sound DMA source address bit 8-15
700                */
372701         m_sound_dma.source = (m_sound_dma.source & 0x0f00ff) | (data << 8);
373702         break;
374703      case 0x4c:  /* Sound DMA source memory segment
375                Bit 0-3 - Sound DMA source address segment
376                Bit 4-7 - Unknown
377                */
704                   Bit 0-3 - Sound DMA source address segment
705                   Bit 4-7 - Unknown
706                */
378707         m_sound_dma.source = (m_sound_dma.source & 0xffff) | ((data & 0x0f) << 16);
379708         break;
380709      case 0x4d:  /* Unknown */
381710         break;
382711      case 0x4e:  /* Sound DMA transfer size (low)
383                Bit 0-7 - Sound DMA transfer size bit 0-7
384                */
712                   Bit 0-7 - Sound DMA transfer size bit 0-7
713                */
385714         m_sound_dma.size = (m_sound_dma.size & 0xff00) | data;
386715         break;
387716      case 0x4f:  /* Sound DMA transfer size (high)
388                Bit 0-7 - Sound DMA transfer size bit 8-15
389                */
717                   Bit 0-7 - Sound DMA transfer size bit 8-15
718                */
390719         m_sound_dma.size = (m_sound_dma.size & 0xff) | (data << 8);
391720         break;
392721      case 0x50:  /* Unknown */
393722      case 0x51:  /* Unknown */
394723         break;
395724      case 0x52:  /* Sound DMA start/stop
396                Bit 0-6 - Unknown
397                Bit 7   - Sound DMA stop/start
398                */
725                   Bit 0-6 - Unknown
726                   Bit 7   - Sound DMA stop/start
727                */
399728         m_sound_dma.enable = data;
400729         break;
401      case 0x60:
402         m_vdp->reg_w(space, offset, data);
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         }
403752         break;
404753      case 0x80:  /* Audio 1 freq (lo)
405                Bit 0-7 - Audio channel 1 frequency bit 0-7
406                */
754                   Bit 0-7 - Audio channel 1 frequency bit 0-7
755                */
407756      case 0x81:  /* Audio 1 freq (hi)
408                Bit 0-7 - Audio channel 1 frequency bit 8-15
409                */
757                   Bit 0-7 - Audio channel 1 frequency bit 8-15
758                */
410759      case 0x82:  /* Audio 2 freq (lo)
411                Bit 0-7 - Audio channel 2 frequency bit 0-7
412                */
760                   Bit 0-7 - Audio channel 2 frequency bit 0-7
761                */
413762      case 0x83:  /* Audio 2 freq (hi)
414                Bit 0-7 - Audio channel 2 frequency bit 8-15
415                */
763                   Bit 0-7 - Audio channel 2 frequency bit 8-15
764                */
416765      case 0x84:  /* Audio 3 freq (lo)
417                Bit 0-7 - Audio channel 3 frequency bit 0-7
418                */
766                   Bit 0-7 - Audio channel 3 frequency bit 0-7
767                */
419768      case 0x85:  /* Audio 3 freq (hi)
420                Bit 0-7 - Audio channel 3 frequency bit 8-15
421                */
769                   Bit 0-7 - Audio channel 3 frequency bit 8-15
770                */
422771      case 0x86:  /* Audio 4 freq (lo)
423                Bit 0-7 - Audio channel 4 frequency bit 0-7
424                */
772                   Bit 0-7 - Audio channel 4 frequency bit 0-7
773                */
425774      case 0x87:  /* Audio 4 freq (hi)
426                Bit 0-7 - Audio channel 4 frequency bit 8-15
427                */
775                   Bit 0-7 - Audio channel 4 frequency bit 8-15
776                */
428777      case 0x88:  /* Audio 1 volume
429                Bit 0-3 - Right volume audio channel 1
430                Bit 4-7 - Left volume audio channel 1
431                */
778                   Bit 0-3 - Right volume audio channel 1
779                   Bit 4-7 - Left volume audio channel 1
780                */
432781      case 0x89:  /* Audio 2 volume
433                Bit 0-3 - Right volume audio channel 2
434                Bit 4-7 - Left volume audio channel 2
435                */
782                   Bit 0-3 - Right volume audio channel 2
783                   Bit 4-7 - Left volume audio channel 2
784                */
436785      case 0x8a:  /* Audio 3 volume
437                Bit 0-3 - Right volume audio channel 3
438                Bit 4-7 - Left volume audio channel 3
439                */
786                   Bit 0-3 - Right volume audio channel 3
787                   Bit 4-7 - Left volume audio channel 3
788                */
440789      case 0x8b:  /* Audio 4 volume
441                Bit 0-3 - Right volume audio channel 4
442                Bit 4-7 - Left volume audio channel 4
443                */
790                   Bit 0-3 - Right volume audio channel 4
791                   Bit 4-7 - Left volume audio channel 4
792                */
444793      case 0x8c:  /* Sweep step
445                Bit 0-7 - Sweep step
446                */
794                   Bit 0-7 - Sweep step
795                */
447796      case 0x8d:  /* Sweep time
448                Bit 0-7 - Sweep time
449                */
797                   Bit 0-7 - Sweep time
798                */
450799      case 0x8e:  /* Noise control
451                Bit 0-2 - Noise generator type
452                Bit 3   - Reset
453                Bit 4   - Enable
454                Bit 5-7 - Unknown
455                */
800                   Bit 0-2 - Noise generator type
801                   Bit 3   - Reset
802                   Bit 4   - Enable
803                   Bit 5-7 - Unknown
804                */
456805      case 0x8f:  /* Sample location
457                Bit 0-7 - Sample address location 0 00xxxxxx xx000000
458                */
806                   Bit 0-7 - Sample address location 0 00xxxxxx xx000000
807                */
459808      case 0x90:  /* Audio control
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                */
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                */
469818      case 0x91:  /* Audio output
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                */
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                */
476825      case 0x92:  /* Noise counter shift register (lo)
477                Bit 0-7 - Noise counter shift register bit 0-7
478                */
826                   Bit 0-7 - Noise counter shift register bit 0-7
827                */
479828      case 0x93:  /* Noise counter shift register (hi)
480                Bit 0-6 - Noise counter shift register bit 8-14
481                bit 7   - Unknown
482                */
829                   Bit 0-6 - Noise counter shift register bit 8-14
830                   bit 7   - Unknown
831                */
483832      case 0x94:  /* Master volume
484                Bit 0-3 - Master volume
485                Bit 4-7 - Unknown
486                */
833                   Bit 0-3 - Master volume
834                   Bit 4-7 - Unknown
835                */
487836         m_sound->port_w(space, offset, data);
488837         break;
489838      case 0xa0:  /* Hardware type - this is probably read only
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                */
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                */
494843         if ((data & 0x01) && !m_bios_disabled)
495844            m_bios_disabled = 1;
496845         break;
497         
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
498900      case 0xb0:  /* Interrupt base vector
499                Bit 0-7 - Interrupt base vector
500                */
901                   Bit 0-7 - Interrupt base vector
902                */
501903         break;
502904      case 0xb1:  /* Communication byte
503                Bit 0-7 - Communication byte
504                */
905                   Bit 0-7 - Communication byte
906                */
505907         break;
506908      case 0xb2:  /* Interrupt enable
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                */
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                */
516918         break;
517919      case 0xb3:  /* serial communication control
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;
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;
527929         m_ws_portram[0xb1] = 0xff;
528930         if (data & 0x80)
529931         {
530            //              m_ws_portram[0xb1] = 0x00;
932//              m_ws_portram[0xb1] = 0x00;
531933            data |= 0x04;
532934         }
533935         if (data & 0x20)
534936         {
535            //              data |= 0x01;
937//              data |= 0x01;
536938         }
537939         break;
538940      case 0xb5:  /* Read controls
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                */
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                */
546948         data = data & 0xf0;
547949         switch (data)
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;
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;
560962            break;
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;
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;
572974            break;
573         case 0x40:  /* Read buttons: START - A - B */
574            data = data | m_buttons->read();
975            case 0x40:  /* Read buttons: START - A - B */
976               data = data | m_buttons->read();
575977            break;
576      }
978         }
577979         break;
578980      case 0xb6:  /* Interrupt acknowledge
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);
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);
589991         data = m_ws_portram[0xb6];
590992         break;
591993      case 0xba:  /* Internal EEPROM data (low)
592                Bit 0-7 - Internal EEPROM data transfer bit 0-7
593                */
994                   Bit 0-7 - Internal EEPROM data transfer bit 0-7
995                */
594996      case 0xbb:  /* Internal EEPROM data (high)
595                Bit 0-7 - Internal EEPROM data transfer bit 8-15
596                */
997                   Bit 0-7 - Internal EEPROM data transfer bit 8-15
998                */
597999         break;
5981000      case 0xbc:  /* Internal EEPROM address (low)
599                Bit 0-7 - Internal EEPROM address bit 1-8
600                */
1001                   Bit 0-7 - Internal EEPROM address bit 1-8
1002                */
6011003      case 0xbd:  /* Internal EEPROM address (high)
602                Bit 0   - Internal EEPROM address bit 9(?)
603                Bit 1-7 - Unknown
604                Only 1KByte internal EEPROM??
605                */
1004                   Bit 0   - Internal EEPROM address bit 9(?)
1005                   Bit 1-7 - Unknown
1006                   Only 1KByte internal EEPROM??
1007                */
6061008         break;
6071009      case 0xbe:  /* Internal EEPROM command
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                */
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                */
6161018         if (data & 0x20)
6171019         {
6181020            UINT16 addr = ( ( ( m_ws_portram[0xbd] << 8 ) | m_ws_portram[0xbc] ) << 1 ) & 0x1FF;
r241553r241554
6541056         logerror( "Write to unsupported port: %X - %X\n", offset, data );
6551057         break;
6561058   }
657   
1059
6581060   /* Update the port value */
6591061   m_ws_portram[offset] = data;
6601062}
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
r241553r241554
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_video.o \
1032   $(MESS_DRIVERS)/wswan.o $(MESS_AUDIO)/wswan_snd.o $(MESS_MACHINE)/wswan.o $(MESS_VIDEO)/wswan.o \
10331033
10341034$(MESSOBJ)/be.a:                \
10351035   $(MESS_DRIVERS)/bebox.o $(MESS_MACHINE)/bebox.o \
trunk/src/mess/video/wswan.c
r0r241554
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
r241553r241554
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
r241553r241554
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