~ubuntu-branches/debian/sid/mame/sid

« back to all changes in this revision

Viewing changes to mess/src/mess/machine/wswan.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach, Jordi Mallach, Emmanuel Kasper
  • Date: 2011-12-19 22:56:27 UTC
  • mfrom: (0.1.2)
  • Revision ID: package-import@ubuntu.com-20111219225627-ub5oga1oys4ogqzm
Tags: 0.144-1
[ Jordi Mallach ]
* Fix syntax errors in DEP5 copyright file (lintian).
* Use a versioned copyright Format specification field.
* Update Vcs-* URLs.
* Move transitional packages to the new metapackages section, and make
  them priority extra.
* Remove references to GNU/Linux and MESS sources from copyright.
* Add build variables for s390x.
* Use .xz tarballs as it cuts 4MB for the upstream sources.
* Add nplayers.ini as a patch. Update copyright file to add CC-BY-SA-3.0.

[ Emmanuel Kasper ]
* New upstream release. Closes: #651538.
* Add Free Desktop compliant png icons of various sizes taken from
  the hydroxygen iconset
* Mess is now built from a new source package, to avoid possible source
  incompatibilities between mame and the mess overlay.
* Mame-tools are not built from the mame source package anymore, but
  from the mess source package

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
 
3
 
  wswan.c
4
 
 
5
 
  Machine file to handle emulation of the Bandai WonderSwan.
6
 
 
7
 
  Anthony Kruize
8
 
  Wilbert Pol
9
 
 
10
 
TODO:
11
 
  SRAM sizes should be in kbit instead of kbytes(?). This raises a few
12
 
  interesting issues:
13
 
  - mirror of smaller <64KBYTE/512kbit sram sizes
14
 
  - banking when using 1M or 2M sram sizes
15
 
 
16
 
***************************************************************************/
17
 
 
18
 
#include "emu.h"
19
 
#include "includes/wswan.h"
20
 
#include "imagedev/cartslot.h"
21
 
#include "image.h"
22
 
 
23
 
#define INTERNAL_EEPROM_SIZE    1024
24
 
 
25
 
enum enum_system { TYPE_WSWAN=0, TYPE_WSC };
26
 
enum enum_sram { SRAM_NONE=0, SRAM_64K, SRAM_256K, SRAM_512K, SRAM_1M, SRAM_2M, EEPROM_1K, EEPROM_16K, EEPROM_8K, SRAM_UNKNOWN };
27
 
static const char *const wswan_sram_str[] = { "none", "64Kbit SRAM", "256Kbit SRAM", "512Kbit SRAM", "1Mbit SRAM", "2Mbit SRAM", "1Kbit EEPROM", "16Kbit EEPROM", "8Kbit EEPROM", "Unknown" };
28
 
static const int wswan_sram_size[] = { 0, 64*1024/8, 256*1024/8, 512*1024/8, 1024*1024/8, 2*1024*1024/8,  1024/8, 16*1024/8, 8*1024/8, 0 };
29
 
 
30
 
static TIMER_CALLBACK(wswan_scanline_interrupt);
31
 
 
32
 
 
33
 
static const UINT8 ws_portram_init[256] =
34
 
{
35
 
        0x00, 0x00, 0x00/*?*/, 0xbb, 0x00, 0x00, 0x00, 0x26, 0xfe, 0xde, 0xf9, 0xfb, 0xdb, 0xd7, 0x7f, 0xf5,
36
 
        0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x9e, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x99, 0xfd, 0xb7, 0xdf,
37
 
        0x30, 0x57, 0x75, 0x76, 0x15, 0x73, 0x70/*77?*/, 0x77, 0x20, 0x75, 0x50, 0x36, 0x70, 0x67, 0x50, 0x77,
38
 
        0x57, 0x54, 0x75, 0x77, 0x75, 0x17, 0x37, 0x73, 0x50, 0x57, 0x60, 0x77, 0x70, 0x77, 0x10, 0x73,
39
 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40
 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41
 
        0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00,
42
 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43
 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00,
44
 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
45
 
        0x87, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46
 
        0x00, 0xdb, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x83, 0x00,
47
 
        0x2f, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
48
 
        0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
49
 
        0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
50
 
        0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1
51
 
};
52
 
 
53
 
/*
54
 
    Some fake bios code to initialize some registers and set up some things on the wonderswan.
55
 
    The code from f:ffe0 which gets copied to 0:0400 is taken from a wonderswan crystal's initial
56
 
    memory settings. Lacking real bios dumps we will use this....
57
 
 
58
 
    The setting of SP to 2000h is what's needed to get Wonderswan Colloseum to boot.
59
 
 
60
 
    f000:ffc0
61
 
    FC             cld
62
 
        BC 00 20       mov sp,2000h
63
 
    68 00 00       push 0000h
64
 
    07             pop es
65
 
    68 00 F0       push F000h
66
 
    1F             pop ds
67
 
    BF 00 04       mov di,0400h
68
 
    BE E0 FF       mov si,FFE0h
69
 
    B9 10 00       mov cx,0010h
70
 
    F3 A4          rep movsb
71
 
    B0 2F          mov al,2Fh
72
 
    E6 C0          out al,C0h
73
 
    EA 00 04 00 00 jmp 0000:0400
74
 
 
75
 
    f000:ffe0
76
 
    E4 A0          in al, A0h
77
 
    0C 01          or al,01h
78
 
    E6 A0          out al,A0h
79
 
    EA 00 00 FF FF jmp FFFFh:0000h
80
 
 
81
 
*/
82
 
static const UINT8 ws_fake_bios_code[] = {
83
 
        0xfc, 0xbc, 0x00, 0x20, 0x68, 0x00, 0x00, 0x07, 0x68, 0x00, 0xf0, 0x1f, 0xbf, 0x00, 0x04, 0xbe,
84
 
        0xe0, 0xff, 0xb9, 0x10, 0x00, 0xf3, 0xa4, 0xb0, 0x2f, 0xe6, 0xc0, 0xea, 0x00, 0x04, 0x00, 0x00,
85
 
        0xe4, 0xa0, 0x0c, 0x01, 0xe6, 0xa0, 0xea, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
86
 
        0xea, 0xc0, 0xff, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
87
 
};
88
 
 
89
 
static void wswan_handle_irqs( running_machine &machine )
90
 
{
91
 
        wswan_state *state = machine.driver_data<wswan_state>();
92
 
        if ( state->m_ws_portram[0xb2] & state->m_ws_portram[0xb6] & WSWAN_IFLAG_HBLTMR ) {
93
 
                cputag_set_input_line_and_vector( machine, "maincpu", 0, HOLD_LINE, state->m_ws_portram[0xb0] + WSWAN_INT_HBLTMR );
94
 
        } else if ( state->m_ws_portram[0xb2] & state->m_ws_portram[0xb6] & WSWAN_IFLAG_VBL ) {
95
 
                cputag_set_input_line_and_vector( machine, "maincpu", 0, HOLD_LINE, state->m_ws_portram[0xb0] + WSWAN_INT_VBL );
96
 
        } else if ( state->m_ws_portram[0xb2] & state->m_ws_portram[0xb6] & WSWAN_IFLAG_VBLTMR ) {
97
 
                cputag_set_input_line_and_vector( machine, "maincpu", 0, HOLD_LINE, state->m_ws_portram[0xb0] + WSWAN_INT_VBLTMR );
98
 
        } else if ( state->m_ws_portram[0xb2] & state->m_ws_portram[0xb6] & WSWAN_IFLAG_LCMP ) {
99
 
                cputag_set_input_line_and_vector( machine, "maincpu", 0, HOLD_LINE, state->m_ws_portram[0xb0] + WSWAN_INT_LCMP );
100
 
        } else if ( state->m_ws_portram[0xb2] & state->m_ws_portram[0xb6] & WSWAN_IFLAG_SRX ) {
101
 
                cputag_set_input_line_and_vector( machine, "maincpu", 0, HOLD_LINE, state->m_ws_portram[0xb0] + WSWAN_INT_SRX );
102
 
        } else if ( state->m_ws_portram[0xb2] & state->m_ws_portram[0xb6] & WSWAN_IFLAG_RTC ) {
103
 
                cputag_set_input_line_and_vector( machine, "maincpu", 0, HOLD_LINE, state->m_ws_portram[0xb0] + WSWAN_INT_RTC );
104
 
        } else if ( state->m_ws_portram[0xb2] & state->m_ws_portram[0xb6] & WSWAN_IFLAG_KEY ) {
105
 
                cputag_set_input_line_and_vector( machine, "maincpu", 0, HOLD_LINE, state->m_ws_portram[0xb0] + WSWAN_INT_KEY );
106
 
        } else if ( state->m_ws_portram[0xb2] & state->m_ws_portram[0xb6] & WSWAN_IFLAG_STX ) {
107
 
                cputag_set_input_line_and_vector( machine, "maincpu", 0, HOLD_LINE, state->m_ws_portram[0xb0] + WSWAN_INT_STX );
108
 
        } else {
109
 
                cputag_set_input_line(machine, "maincpu", 0, CLEAR_LINE );
110
 
        }
111
 
}
112
 
 
113
 
static void wswan_set_irq_line( running_machine &machine, int irq)
114
 
{
115
 
        wswan_state *state = machine.driver_data<wswan_state>();
116
 
        if ( state->m_ws_portram[0xb2] & irq )
117
 
        {
118
 
                state->m_ws_portram[0xb6] |= irq;
119
 
                wswan_handle_irqs( machine );
120
 
        }
121
 
}
122
 
 
123
 
static void wswan_clear_irq_line( running_machine &machine, int irq)
124
 
{
125
 
        wswan_state *state = machine.driver_data<wswan_state>();
126
 
        state->m_ws_portram[0xb6] &= ~irq;
127
 
        wswan_handle_irqs( machine );
128
 
}
129
 
 
130
 
static TIMER_CALLBACK(wswan_rtc_callback)
131
 
{
132
 
        wswan_state *state = machine.driver_data<wswan_state>();
133
 
        /* A second passed */
134
 
        state->m_rtc.second = state->m_rtc.second + 1;
135
 
        if ( ( state->m_rtc.second & 0x0F ) > 9 )
136
 
        {
137
 
                state->m_rtc.second = ( state->m_rtc.second & 0xF0 ) + 0x10;
138
 
        }
139
 
 
140
 
        /* Check for minute passed */
141
 
        if ( state->m_rtc.second >= 0x60 )
142
 
        {
143
 
                state->m_rtc.second = 0;
144
 
                state->m_rtc.minute = state->m_rtc.minute + 1;
145
 
                if ( ( state->m_rtc.minute & 0x0F ) > 9 )
146
 
                {
147
 
                        state->m_rtc.minute = ( state->m_rtc.minute & 0xF0 ) + 0x10;
148
 
                }
149
 
        }
150
 
 
151
 
        /* Check for hour passed */
152
 
        if ( state->m_rtc.minute >= 0x60 )
153
 
        {
154
 
                state->m_rtc.minute = 0;
155
 
                state->m_rtc.hour = state->m_rtc.hour + 1;
156
 
                if ( ( state->m_rtc.hour & 0x0F ) > 9 )
157
 
                {
158
 
                        state->m_rtc.hour = ( state->m_rtc.hour & 0xF0 ) + 0x10;
159
 
                }
160
 
                if ( state->m_rtc.hour == 0x12 )
161
 
                {
162
 
                        state->m_rtc.hour |= 0x80;
163
 
                }
164
 
        }
165
 
 
166
 
        /* Check for day passed */
167
 
        if ( state->m_rtc.hour >= 0x24 )
168
 
        {
169
 
                state->m_rtc.hour = 0;
170
 
                state->m_rtc.day = state->m_rtc.day + 1;
171
 
        }
172
 
}
173
 
 
174
 
static void wswan_machine_stop( running_machine &machine )
175
 
{
176
 
        wswan_state *state = machine.driver_data<wswan_state>();
177
 
        device_image_interface *image = dynamic_cast<device_image_interface *>(machine.device("cart"));
178
 
        if ( state->m_eeprom.size )
179
 
        {
180
 
                image->battery_save(state->m_eeprom.data, state->m_eeprom.size );
181
 
        }
182
 
}
183
 
 
184
 
static void wswan_setup_bios( running_machine &machine )
185
 
{
186
 
        wswan_state *state = machine.driver_data<wswan_state>();
187
 
        if ( state->m_ws_bios_bank == NULL )
188
 
        {
189
 
                state->m_ws_bios_bank = auto_alloc_array(machine, UINT8, 0x10000 );
190
 
                memcpy( state->m_ws_bios_bank + 0xffc0, ws_fake_bios_code, 0x40 );
191
 
        }
192
 
}
193
 
 
194
 
MACHINE_START( wswan )
195
 
{
196
 
        wswan_state *state = machine.driver_data<wswan_state>();
197
 
        state->m_ws_bios_bank = NULL;
198
 
        state->m_system_type = TYPE_WSWAN;
199
 
        machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(wswan_machine_stop),&machine));
200
 
        state->m_vdp.timer = machine.scheduler().timer_alloc(FUNC(wswan_scanline_interrupt), &state->m_vdp );
201
 
        state->m_vdp.timer->adjust( attotime::from_ticks( 256, 3072000 ), 0, attotime::from_ticks( 256, 3072000 ) );
202
 
 
203
 
        wswan_setup_bios(machine);
204
 
 
205
 
        /* Set up RTC timer */
206
 
        if ( state->m_rtc.present )
207
 
                machine.scheduler().timer_pulse(attotime::from_seconds(1), FUNC(wswan_rtc_callback));
208
 
}
209
 
 
210
 
MACHINE_START( wscolor )
211
 
{
212
 
        wswan_state *state = machine.driver_data<wswan_state>();
213
 
        state->m_ws_bios_bank = NULL;
214
 
        state->m_system_type = TYPE_WSC;
215
 
        machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(wswan_machine_stop),&machine));
216
 
        state->m_vdp.timer = machine.scheduler().timer_alloc(FUNC(wswan_scanline_interrupt), &state->m_vdp );
217
 
        state->m_vdp.timer->adjust( attotime::from_ticks( 256, 3072000 ), 0, attotime::from_ticks( 256, 3072000 ) );
218
 
 
219
 
        wswan_setup_bios(machine);
220
 
 
221
 
        /* Set up RTC timer */
222
 
        if ( state->m_rtc.present )
223
 
                machine.scheduler().timer_pulse(attotime::from_seconds(1), FUNC(wswan_rtc_callback));
224
 
}
225
 
 
226
 
MACHINE_RESET( wswan )
227
 
{
228
 
        wswan_state *state = machine.driver_data<wswan_state>();
229
 
        address_space *space = machine.device( "maincpu")->memory().space( AS_PROGRAM );
230
 
 
231
 
        /* Intialize ports */
232
 
        memcpy( state->m_ws_portram, ws_portram_init, 256 );
233
 
 
234
 
        /* Initialize VDP */
235
 
        memset( &state->m_vdp, 0, sizeof( state->m_vdp ) );
236
 
 
237
 
        state->m_vdp.vram = (UINT8*)space->get_read_ptr(0);
238
 
        state->m_vdp.palette_vram = (UINT8*)space->get_read_ptr(( state->m_system_type == TYPE_WSC ) ? 0xFE00 : 0 );
239
 
        state->m_vdp.current_line = 145;  /* Randomly chosen, beginning of VBlank period to give cart some time to boot up */
240
 
        state->m_vdp.new_display_vertical = state->m_ROMMap[state->m_ROMBanks-1][0xfffc] & 0x01;
241
 
        state->m_vdp.display_vertical = ~state->m_vdp.new_display_vertical;
242
 
        state->m_vdp.color_mode = 0;
243
 
        state->m_vdp.colors_16 = 0;
244
 
        state->m_vdp.tile_packed = 0;
245
 
 
246
 
        /* Initialize sound DMA */
247
 
        memset( &state->m_sound_dma, 0, sizeof( state->m_sound_dma ) );
248
 
 
249
 
        /* Switch in the banks */
250
 
        memory_set_bankptr( machine, "bank2", state->m_ROMMap[(state->m_ROMBanks - 1) & (state->m_ROMBanks - 1)] );
251
 
        memory_set_bankptr( machine, "bank3", state->m_ROMMap[(state->m_ROMBanks - 1) & (state->m_ROMBanks - 1)] );
252
 
        memory_set_bankptr( machine, "bank4", state->m_ROMMap[(state->m_ROMBanks - 12) & (state->m_ROMBanks - 1)] );
253
 
        memory_set_bankptr( machine, "bank5", state->m_ROMMap[(state->m_ROMBanks - 11) & (state->m_ROMBanks - 1)] );
254
 
        memory_set_bankptr( machine, "bank6", state->m_ROMMap[(state->m_ROMBanks - 10) & (state->m_ROMBanks - 1)] );
255
 
        memory_set_bankptr( machine, "bank7", state->m_ROMMap[(state->m_ROMBanks - 9) & (state->m_ROMBanks - 1)] );
256
 
        memory_set_bankptr( machine, "bank8", state->m_ROMMap[(state->m_ROMBanks - 8) & (state->m_ROMBanks - 1)] );
257
 
        memory_set_bankptr( machine, "bank9", state->m_ROMMap[(state->m_ROMBanks - 7) & (state->m_ROMBanks - 1)] );
258
 
        memory_set_bankptr( machine, "bank10", state->m_ROMMap[(state->m_ROMBanks - 6) & (state->m_ROMBanks - 1)] );
259
 
        memory_set_bankptr( machine, "bank11", state->m_ROMMap[(state->m_ROMBanks - 5) & (state->m_ROMBanks - 1)] );
260
 
        memory_set_bankptr( machine, "bank12", state->m_ROMMap[(state->m_ROMBanks - 4) & (state->m_ROMBanks - 1)] );
261
 
        memory_set_bankptr( machine, "bank13", state->m_ROMMap[(state->m_ROMBanks - 3) & (state->m_ROMBanks - 1)] );
262
 
        memory_set_bankptr( machine, "bank14", state->m_ROMMap[(state->m_ROMBanks - 2) & (state->m_ROMBanks - 1)] );
263
 
        state->m_bios_disabled = 0;
264
 
        memory_set_bankptr( machine, "bank15", state->m_ws_bios_bank );
265
 
//  memory_set_bankptr( machine, 15, state->m_ROMMap[(state->m_ROMBanks - 1) & (state->m_ROMBanks - 1)] );
266
 
}
267
 
 
268
 
NVRAM_HANDLER( wswan )
269
 
{
270
 
        wswan_state *state = machine.driver_data<wswan_state>();
271
 
        if ( read_or_write )
272
 
        {
273
 
                /* Save the EEPROM data */
274
 
                file->write(state->m_internal_eeprom, INTERNAL_EEPROM_SIZE );
275
 
        }
276
 
        else
277
 
        {
278
 
                /* Load the EEPROM data */
279
 
                if ( file )
280
 
                {
281
 
                        file->read(state->m_internal_eeprom, INTERNAL_EEPROM_SIZE );
282
 
                }
283
 
                else
284
 
                {
285
 
                        /* Initialize the EEPROM data */
286
 
                        memset( state->m_internal_eeprom, 0xFF, sizeof( state->m_internal_eeprom ) );
287
 
                }
288
 
        }
289
 
}
290
 
 
291
 
READ8_HANDLER( wswan_sram_r )
292
 
{
293
 
        wswan_state *state = space->machine().driver_data<wswan_state>();
294
 
        if ( state->m_eeprom.data == NULL )
295
 
        {
296
 
                return 0xFF;
297
 
        }
298
 
        return state->m_eeprom.page[ offset & ( state->m_eeprom.size - 1 ) ];
299
 
}
300
 
 
301
 
WRITE8_HANDLER( wswan_sram_w )
302
 
{
303
 
        wswan_state *state = space->machine().driver_data<wswan_state>();
304
 
        if ( state->m_eeprom.data == NULL )
305
 
        {
306
 
                return;
307
 
        }
308
 
        state->m_eeprom.page[ offset & ( state->m_eeprom.size - 1 ) ] = data;
309
 
}
310
 
 
311
 
READ8_HANDLER( wswan_port_r )
312
 
{
313
 
        wswan_state *state = space->machine().driver_data<wswan_state>();
314
 
        UINT8 value = state->m_ws_portram[offset];
315
 
 
316
 
        if ( offset != 2 )
317
 
        logerror( "PC=%X: port read %02X\n", cpu_get_pc( &space->device() ), offset );
318
 
        switch( offset )
319
 
        {
320
 
                case 0x02:              /* Current line */
321
 
                        value = state->m_vdp.current_line;
322
 
                        break;
323
 
                case 0x4A:              /* Sound DMA source address (low) */
324
 
                        value = state->m_sound_dma.source & 0xFF;
325
 
                        break;
326
 
                case 0x4B:              /* Sound DMA source address (high) */
327
 
                        value = ( state->m_sound_dma.source >> 8 ) & 0xFF;
328
 
                        break;
329
 
                case 0x4C:              /* Sound DMA source memory segment */
330
 
                        value = ( state->m_sound_dma.source >> 16 ) & 0xFF;
331
 
                        break;
332
 
                case 0x4E:              /* Sound DMA transfer size (low) */
333
 
                        value = state->m_sound_dma.size & 0xFF;
334
 
                        break;
335
 
                case 0x4F:              /* Sound DMA transfer size (high) */
336
 
                        value = ( state->m_sound_dma.size >> 8 ) & 0xFF;
337
 
                        break;
338
 
                case 0x52:              /* Sound DMA start/stop */
339
 
                        value = state->m_sound_dma.enable;
340
 
                        break;
341
 
                case 0xA0:              /* Hardware type */
342
 
                                        /* Bit 0 - Disable/enable Bios */
343
 
                                        /* Bit 1 - Determine mono/color */
344
 
                                        /* Bit 2 - Determine color/crystal */
345
 
                        value = value & ~ 0x02;
346
 
                        if ( state->m_system_type == TYPE_WSC )
347
 
                        {
348
 
                                value |= 2;
349
 
                        }
350
 
                        break;
351
 
                case 0xA8:
352
 
                        value = state->m_vdp.timer_hblank_count & 0xFF;
353
 
                        break;
354
 
                case 0xA9:
355
 
                        value = state->m_vdp.timer_hblank_count >> 8;
356
 
                        break;
357
 
                case 0xAA:
358
 
                        value = state->m_vdp.timer_vblank_count & 0xFF;
359
 
                        break;
360
 
                case 0xAB:
361
 
                        value = state->m_vdp.timer_vblank_count >> 8;
362
 
                        break;
363
 
                case 0xCB:              /* RTC data */
364
 
                        if ( state->m_ws_portram[0xca] == 0x95 && ( state->m_rtc.index < 7 ) )
365
 
                        {
366
 
                                switch( state->m_rtc.index )
367
 
                                {
368
 
                                case 0: value = state->m_rtc.year; break;
369
 
                                case 1: value = state->m_rtc.month; break;
370
 
                                case 2: value = state->m_rtc.day; break;
371
 
                                case 3: value = state->m_rtc.day_of_week; break;
372
 
                                case 4: value = state->m_rtc.hour; break;
373
 
                                case 5: value = state->m_rtc.minute; break;
374
 
                                case 6: value = state->m_rtc.second; break;
375
 
                                }
376
 
                                state->m_rtc.index++;
377
 
                        }
378
 
        }
379
 
 
380
 
        return value;
381
 
}
382
 
 
383
 
WRITE8_HANDLER( wswan_port_w )
384
 
{
385
 
        wswan_state *state = space->machine().driver_data<wswan_state>();
386
 
        logerror( "PC=%X: port write %02X <- %02X\n", cpu_get_pc( &space->device() ), offset, data );
387
 
        switch( offset )
388
 
        {
389
 
                case 0x00:      /* Display control
390
 
                   Bit 0   - Background layer enable
391
 
                   Bit 1   - Foreground layer enable
392
 
                   Bit 2   - Sprites enable
393
 
                   Bit 3   - Sprite window enable
394
 
                   Bit 4-5 - Foreground window configuration
395
 
                             00 - Foreground layer is displayed inside and outside foreground window area
396
 
                             01 - Unknown
397
 
                             10 - Foreground layer is displayed only inside foreground window area
398
 
                             11 - Foreground layer is displayed outside foreground window area
399
 
                   Bit 6-7 - Unknown
400
 
                */
401
 
                        state->m_vdp.layer_bg_enable = data & 0x1;
402
 
                        state->m_vdp.layer_fg_enable = (data & 0x2) >> 1;
403
 
                        state->m_vdp.sprites_enable = (data & 0x4) >> 2;
404
 
                        state->m_vdp.window_sprites_enable = (data & 0x8) >> 3;
405
 
                        state->m_vdp.window_fg_mode = (data & 0x30) >> 4;
406
 
                        break;
407
 
                case 0x01:      /* Background colour
408
 
                   In 16 colour mode:
409
 
                   Bit 0-3 - Palette index
410
 
                   Bit 4-7 - Palette number
411
 
                   Otherwise:
412
 
                   Bit 0-2 - Main palette index
413
 
                   Bit 3-7 - Unknown
414
 
                */
415
 
                        break;
416
 
                case 0x02:      /* Current scanline
417
 
                   Bit 0-7 - Current scanline (Most likely read-only)
418
 
                */
419
 
                        logerror( "Write to current scanline! Current value: %d  Data to write: %d\n", state->m_vdp.current_line, data );
420
 
                        /* Returning so we don't overwrite the value here, not that it
421
 
             * really matters */
422
 
                        return;
423
 
                case 0x03:      /* Line compare
424
 
                   Bit 0-7 - Line compare
425
 
                */
426
 
                        state->m_vdp.line_compare = data;
427
 
                        break;
428
 
                case 0x04:      /* Sprite table base address
429
 
                   Bit 0-5 - Determine sprite table base address 0 0xxxxxx0 00000000
430
 
                   Bit 6-7 - Unknown
431
 
                */
432
 
                        state->m_vdp.sprite_table_address = ( data & 0x3F ) << 9;
433
 
                        break;
434
 
                case 0x05:      /* Number of sprite to start drawing with
435
 
                   Bit 0-7 - First sprite number
436
 
                */
437
 
                        state->m_vdp.sprite_first = data;
438
 
                        break;
439
 
                case 0x06:      /* Number of sprites to draw
440
 
                   Bit 0-7 - Number of sprites to draw
441
 
                */
442
 
                        state->m_vdp.sprite_count = data;
443
 
                        break;
444
 
                case 0x07:      /* Background/Foreground table base addresses
445
 
                   Bit 0-2 - Determine background table base address 00xxx000 00000000
446
 
                   Bit 3   - Unknown
447
 
                   Bit 4-6 - Determine foreground table base address 00xxx000 00000000
448
 
                   Bit 7   - Unknown
449
 
                */
450
 
                        state->m_vdp.layer_bg_address = (data & 0x7) << 11;
451
 
                        state->m_vdp.layer_fg_address = (data & 0x70) << 7;
452
 
                        break;
453
 
                case 0x08:      /* Left coordinate of foreground window
454
 
                   Bit 0-7 - Left coordinate of foreground window area
455
 
                */
456
 
                        state->m_vdp.window_fg_left = data;
457
 
                        break;
458
 
                case 0x09:      /* Top coordinate of foreground window
459
 
                   Bit 0-7 - Top coordinatte of foreground window area
460
 
                */
461
 
                        state->m_vdp.window_fg_top = data;
462
 
                        break;
463
 
                case 0x0A:      /* Right coordinate of foreground window
464
 
                   Bit 0-7 - Right coordinate of foreground window area
465
 
                */
466
 
                        state->m_vdp.window_fg_right = data;
467
 
                        break;
468
 
                case 0x0B:      /* Bottom coordinate of foreground window
469
 
                   Bit 0-7 - Bottom coordinate of foreground window area
470
 
                */
471
 
                        state->m_vdp.window_fg_bottom = data;
472
 
                        break;
473
 
                case 0x0C:      /* Left coordinate of sprite window
474
 
                   Bit 0-7 - Left coordinate of sprite window area
475
 
                */
476
 
                        state->m_vdp.window_sprites_left = data;
477
 
                        break;
478
 
                case 0x0D:      /* Top coordinate of sprite window
479
 
                   Bit 0-7 - Top coordinate of sprite window area
480
 
                */
481
 
                        state->m_vdp.window_sprites_top = data;
482
 
                        break;
483
 
                case 0x0E:      /* Right coordinate of sprite window
484
 
                   Bit 0-7 - Right coordinate of sprite window area
485
 
                */
486
 
                        state->m_vdp.window_sprites_right = data;
487
 
                        break;
488
 
                case 0x0F:      /* Bottom coordinate of sprite window
489
 
                   Bit 0-7 - Bottom coordiante of sprite window area
490
 
                */
491
 
                        state->m_vdp.window_sprites_bottom = data;
492
 
                        break;
493
 
                case 0x10:      /* Background layer X scroll
494
 
                   Bit 0-7 - Background layer X scroll
495
 
                */
496
 
                        state->m_vdp.layer_bg_scroll_x = data;
497
 
                        break;
498
 
                case 0x11:      /* Background layer Y scroll
499
 
                   Bit 0-7 - Background layer Y scroll
500
 
                */
501
 
                        state->m_vdp.layer_bg_scroll_y = data;
502
 
                        break;
503
 
                case 0x12:      /* Foreground layer X scroll
504
 
                   Bit 0-7 - Foreground layer X scroll
505
 
                */
506
 
                        state->m_vdp.layer_fg_scroll_x = data;
507
 
                        break;
508
 
                case 0x13:      /* Foreground layer Y scroll
509
 
                   Bit 0-7 - Foreground layer Y scroll
510
 
                */
511
 
                        state->m_vdp.layer_fg_scroll_y = data;
512
 
                        break;
513
 
                case 0x14:      /* LCD control
514
 
                   Bit 0   - LCD enable
515
 
                   Bit 1-7 - Unknown
516
 
                */
517
 
                        state->m_vdp.lcd_enable = data & 0x1;
518
 
                        break;
519
 
                case 0x15:      /* LCD icons
520
 
                   Bit 0   - LCD sleep icon enable
521
 
                   Bit 1   - Vertical position icon enable
522
 
                   Bit 2   - Horizontal position icon enable
523
 
                   Bit 3   - Dot 1 icon enable
524
 
                   Bit 4   - Dot 2 icon enable
525
 
                   Bit 5   - Dot 3 icon enable
526
 
                   Bit 6-7 - Unknown
527
 
                */
528
 
                        state->m_vdp.icons = data;      /* ummmmm */
529
 
                        break;
530
 
                case 0x1c:      /* Palette colors 0 and 1
531
 
                   Bit 0-3 - Gray tone setting for main palette index 0
532
 
                   Bit 4-7 - Gray tone setting for main palette index 1
533
 
                */
534
 
                        if ( state->m_system_type == TYPE_WSC )
535
 
                        {
536
 
                                int i = 15 - ( data & 0x0F );
537
 
                                int j = 15 - ( ( data & 0xF0 ) >> 4 );
538
 
                                state->m_vdp.main_palette[0] = ( i << 8 ) | ( i << 4 ) | i;
539
 
                                state->m_vdp.main_palette[1] = ( j << 8 ) | ( j << 4 ) | j;
540
 
                        }
541
 
                        else
542
 
                        {
543
 
                                state->m_vdp.main_palette[0] = data & 0x0F;
544
 
                                state->m_vdp.main_palette[1] = ( data & 0xF0 ) >> 4;
545
 
                        }
546
 
                        break;
547
 
                case 0x1d:      /* Palette colors 2 and 3
548
 
                   Bit 0-3 - Gray tone setting for main palette index 2
549
 
                   Bit 4-7 - Gray tone setting for main palette index 3
550
 
                */
551
 
                        if ( state->m_system_type == TYPE_WSC )
552
 
                        {
553
 
                                int i = 15 - ( data & 0x0F );
554
 
                                int j = 15 - ( ( data & 0xF0 ) >> 4 );
555
 
                                state->m_vdp.main_palette[2] = ( i << 8 ) | ( i << 4 ) | i;
556
 
                                state->m_vdp.main_palette[3] = ( j << 8 ) | ( j << 4 ) | j;
557
 
                        }
558
 
                        else
559
 
                        {
560
 
                                state->m_vdp.main_palette[2] = data & 0x0F;
561
 
                                state->m_vdp.main_palette[3] = ( data & 0xF0 ) >> 4;
562
 
                        }
563
 
                        break;
564
 
                case 0x1e:      /* Palette colors 4 and 5
565
 
                   Bit 0-3 - Gray tone setting for main palette index 4
566
 
                   Bit 4-7 - Gray tone setting for main paeltte index 5
567
 
                */
568
 
                        if ( state->m_system_type == TYPE_WSC )
569
 
                        {
570
 
                                int i = 15 - ( data & 0x0F );
571
 
                                int j = 15 - ( ( data & 0xF0 ) >> 4 );
572
 
                                state->m_vdp.main_palette[4] = ( i << 8 ) | ( i << 4 ) | i;
573
 
                                state->m_vdp.main_palette[5] = ( j << 8 ) | ( j << 4 ) | j;
574
 
                        }
575
 
                        else
576
 
                        {
577
 
                                state->m_vdp.main_palette[4] = data & 0x0F;
578
 
                                state->m_vdp.main_palette[5] = ( data & 0xF0 ) >> 4;
579
 
                        }
580
 
                        break;
581
 
                case 0x1f:      /* Palette colors 6 and 7
582
 
                   Bit 0-3 - Gray tone setting for main palette index 6
583
 
                   Bit 4-7 - Gray tone setting for main palette index 7
584
 
                */
585
 
                        if ( state->m_system_type == TYPE_WSC )
586
 
                        {
587
 
                                int i = 15 - ( data & 0x0F );
588
 
                                int j = 15 - ( ( data & 0xF0 ) >> 4 );
589
 
                                state->m_vdp.main_palette[6] = ( i << 8 ) | ( i << 4 ) | i;
590
 
                                state->m_vdp.main_palette[7] = ( j << 8 ) | ( j << 4 ) | j;
591
 
                        }
592
 
                        else
593
 
                        {
594
 
                                state->m_vdp.main_palette[6] = data & 0x0F;
595
 
                                state->m_vdp.main_palette[7] = ( data & 0xF0 ) >> 4;
596
 
                        }
597
 
                        break;
598
 
                case 0x20:      /* tile/sprite palette settings
599
 
                   Bit 0-3 - Palette 0 index 0
600
 
                   Bit 4-7 - Palette 0 index 1 */
601
 
                case 0x21:      /* Bit 0-3 - Palette 0 index 2
602
 
                   Bit 4-7 - Palette 0 index 3 */
603
 
                case 0x22:      /* Bit 0-3 - Palette 1 index 0
604
 
                   Bit 4-7 - Palette 1 index 1 */
605
 
                case 0x23:      /* Bit 0-3 - Palette 1 index 2
606
 
                   Bit 4-7 - Palette 1 index 3 */
607
 
                case 0x24:      /* Bit 0-3 - Palette 2 index 0
608
 
                   Bit 4-7 - Palette 2 index 1 */
609
 
                case 0x25:      /* Bit 0-3 - Palette 2 index 2
610
 
                   Bit 4-7 - Palette 2 index 3 */
611
 
                case 0x26:      /* Bit 0-3 - Palette 3 index 0
612
 
                   Bit 4-7 - Palette 3 index 1 */
613
 
                case 0x27:      /* Bit 0-3 - Palette 3 index 2
614
 
                   Bit 4-7 - Palette 3 index 3 */
615
 
                case 0x28:      /* Bit 0-3 - Palette 4 index 0
616
 
                   Bit 4-7 - Palette 4 index 1 */
617
 
                case 0x29:      /* Bit 0-3 - Palette 4 index 2
618
 
                   Bit 4-7 - Palette 4 index 3 */
619
 
                case 0x2A:      /* Bit 0-3 - Palette 5 index 0
620
 
                   Bit 4-7 - Palette 5 index 1 */
621
 
                case 0x2B:      /* Bit 0-3 - Palette 5 index 2
622
 
                   Bit 4-7 - Palette 5 index 3 */
623
 
                case 0x2C:      /* Bit 0-3 - Palette 6 index 0
624
 
                   Bit 4-7 - Palette 6 index 1 */
625
 
                case 0x2D:      /* Bit 0-3 - Palette 6 index 2
626
 
                   Bit 4-7 - Palette 6 index 3 */
627
 
                case 0x2E:      /* Bit 0-3 - Palette 7 index 0
628
 
                   Bit 4-7 - Palette 7 index 1 */
629
 
                case 0x2F:      /* Bit 0-3 - Palette 7 index 2
630
 
                   Bit 4-7 - Palette 7 index 3 */
631
 
                case 0x30:      /* Bit 0-3 - Palette 8 / Sprite Palette 0 index 0
632
 
                   Bit 4-7 - Palette 8 / Sprite Palette 0 index 1 */
633
 
                case 0x31:      /* Bit 0-3 - Palette 8 / Sprite Palette 0 index 2
634
 
                   Bit 4-7 - Palette 8 / Sprite Palette 0 index 3 */
635
 
                case 0x32:      /* Bit 0-3 - Palette 9 / Sprite Palette 1 index 0
636
 
                   Bit 4-7 - Palette 9 / Sprite Palette 1 index 1 */
637
 
                case 0x33:      /* Bit 0-3 - Palette 9 / Sprite Palette 1 index 2
638
 
                   Bit 4-7 - Palette 9 / Sprite Palette 1 index 3 */
639
 
                case 0x34:      /* Bit 0-3 - Palette 10 / Sprite Palette 2 index 0
640
 
                   Bit 4-7 - Palette 10 / Sprite Palette 2 index 1 */
641
 
                case 0x35:      /* Bit 0-3 - Palette 10 / Sprite Palette 2 index 2
642
 
                   Bit 4-7 - Palette 10 / Sprite Palette 2 index 3 */
643
 
                case 0x36:      /* Bit 0-3 - Palette 11 / Sprite Palette 3 index 0
644
 
                   Bit 4-7 - Palette 11 / Sprite Palette 3 index 1 */
645
 
                case 0x37:      /* Bit 0-3 - Palette 11 / Sprite Palette 3 index 2
646
 
                   Bit 4-7 - Palette 11 / Sprite Palette 3 index 3 */
647
 
                case 0x38:      /* Bit 0-3 - Palette 12 / Sprite Palette 4 index 0
648
 
                   Bit 4-7 - Palette 12 / Sprite Palette 4 index 1 */
649
 
                case 0x39:      /* Bit 0-3 - Palette 12 / Sprite Palette 4 index 2
650
 
                   Bit 4-7 - Palette 12 / Sprite Palette 4 index 3 */
651
 
                case 0x3A:      /* Bit 0-3 - Palette 13 / Sprite Palette 5 index 0
652
 
                   Bit 4-7 - Palette 13 / Sprite Palette 5 index 1 */
653
 
                case 0x3B:      /* Bit 0-3 - Palette 13 / Sprite Palette 5 index 2
654
 
                   Bit 4-7 - Palette 13 / Sprite Palette 5 index 3 */
655
 
                case 0x3C:      /* Bit 0-3 - Palette 14 / Sprite Palette 6 index 0
656
 
                   Bit 4-7 - Palette 14 / Sprite Palette 6 index 1 */
657
 
                case 0x3D:      /* Bit 0-3 - Palette 14 / Sprite Palette 6 index 2
658
 
                   Bit 4-7 - Palette 14 / Sprite Palette 6 index 3 */
659
 
                case 0x3E:      /* Bit 0-3 - Palette 15 / Sprite Palette 7 index 0
660
 
                   Bit 4-7 - Palette 15 / Sprite Palette 7 index 1 */
661
 
                case 0x3F:      /* Bit 0-3 - Palette 15 / Sprite Palette 7 index 2
662
 
                   Bit 4-7 - Palette 15 / Sprite Palette 7 index 3 */
663
 
                        break;
664
 
                case 0x40:      /* DMA source address (low)
665
 
                   Bit 0-7 - DMA source address bit 0-7
666
 
                */
667
 
                case 0x41:      /* DMA source address (high)
668
 
                   Bit 0-7 - DMA source address bit 8-15
669
 
                */
670
 
                case 0x42:      /* DMA source bank
671
 
                   Bit 0-7 - DMA source bank number
672
 
                */
673
 
                case 0x43:      /* DMA destination bank
674
 
                   Bit 0-7 - DMA destination bank number
675
 
                */
676
 
                case 0x44:      /* DMA destination address (low)
677
 
                   Bit 0-7 - DMA destination address bit 0-7
678
 
                */
679
 
                case 0x45:      /* DMA destination address (high)
680
 
                   Bit 0-7 - DMA destination address bit 8-15
681
 
                */
682
 
                case 0x46:      /* Size of copied data (low)
683
 
                   Bit 0-7 - DMA size bit 0-7
684
 
                */
685
 
                case 0x47:      /* Size of copied data (high)
686
 
                   Bit 0-7 - DMA size bit 8-15
687
 
                */
688
 
                        break;
689
 
                case 0x48:      /* DMA control
690
 
                   Bit 0-6 - Unknown
691
 
                   Bit 7   - DMA stop/start
692
 
                */
693
 
                        if( data & 0x80 )
694
 
                        {
695
 
                                UINT32 src, dst;
696
 
                                UINT16 length;
697
 
 
698
 
                                src = state->m_ws_portram[0x40] + (state->m_ws_portram[0x41] << 8) + (state->m_ws_portram[0x42] << 16);
699
 
                                dst = state->m_ws_portram[0x44] + (state->m_ws_portram[0x45] << 8) + (state->m_ws_portram[0x43] << 16);
700
 
                                length = state->m_ws_portram[0x46] + (state->m_ws_portram[0x47] << 8);
701
 
                                for( ; length > 0; length-- )
702
 
                                {
703
 
                                        space->write_byte(dst, space->read_byte(src ) );
704
 
                                        src++;
705
 
                                        dst++;
706
 
                                }
707
 
#ifdef DEBUG
708
 
                                        logerror( "DMA  src:%X dst:%X length:%d\n", src, dst, length );
709
 
#endif
710
 
                                state->m_ws_portram[0x40] = src & 0xFF;
711
 
                                state->m_ws_portram[0x41] = ( src >> 8 ) & 0xFF;
712
 
                                state->m_ws_portram[0x44] = dst & 0xFF;
713
 
                                state->m_ws_portram[0x45] = ( dst >> 8 ) & 0xFF;
714
 
                                state->m_ws_portram[0x46] = length & 0xFF;
715
 
                                state->m_ws_portram[0x47] = ( length >> 8 ) & 0xFF;
716
 
                                data &= 0x7F;
717
 
                        }
718
 
                        break;
719
 
                case 0x4A:      /* Sound DMA source address (low)
720
 
                   Bit 0-7 - Sound DMA source address bit 0-7
721
 
                */
722
 
                        state->m_sound_dma.source = ( state->m_sound_dma.source & 0x0FFF00 ) | data;
723
 
                        break;
724
 
                case 0x4B:      /* Sound DMA source address (high)
725
 
                   Bit 0-7 - Sound DMA source address bit 8-15
726
 
                */
727
 
                        state->m_sound_dma.source = ( state->m_sound_dma.source & 0x0F00FF ) | ( data << 8 );
728
 
                        break;
729
 
                case 0x4C:      /* Sound DMA source memory segment
730
 
                   Bit 0-3 - Sound DMA source address segment
731
 
                   Bit 4-7 - Unknown
732
 
                */
733
 
                        state->m_sound_dma.source = ( state->m_sound_dma.source & 0xFFFF ) | ( ( data & 0x0F ) << 16 );
734
 
                        break;
735
 
                case 0x4D:      /* Unknown */
736
 
                        break;
737
 
                case 0x4E:      /* Sound DMA transfer size (low)
738
 
                   Bit 0-7 - Sound DMA transfer size bit 0-7
739
 
                */
740
 
                        state->m_sound_dma.size = ( state->m_sound_dma.size & 0xFF00 ) | data;
741
 
                        break;
742
 
                case 0x4F:      /* Sound DMA transfer size (high)
743
 
                   Bit 0-7 - Sound DMA transfer size bit 8-15
744
 
                */
745
 
                        state->m_sound_dma.size = ( state->m_sound_dma.size & 0xFF ) | ( data << 8 );
746
 
                        break;
747
 
                case 0x50:      /* Unknown */
748
 
                case 0x51:      /* Unknown */
749
 
                        break;
750
 
                case 0x52:      /* Sound DMA start/stop
751
 
                   Bit 0-6 - Unknown
752
 
                   Bit 7   - Sound DMA stop/start
753
 
                */
754
 
                        state->m_sound_dma.enable = data;
755
 
                        break;
756
 
                case 0x60:      /* Video mode
757
 
                   Bit 0-4 - Unknown
758
 
                   Bit 5   - Packed mode 0 = not packed mode, 1 = packed mode
759
 
                   Bit 6   - 4/16 colour mode select: 0 = 4 colour mode, 1 = 16 colour mode
760
 
                   Bit 7   - monochrome/colour mode select: 0 = monochrome mode, 1 = colour mode
761
 
                */
762
 
                        /*
763
 
             * 111  - packed, 16 color, use 4000/8000, color
764
 
             * 110  - not packed, 16 color, use 4000/8000, color
765
 
             * 101  - packed, 4 color, use 2000, color
766
 
             * 100  - not packed, 4 color, use 2000, color
767
 
             * 011  - packed, 16 color, use 4000/8000, monochrome
768
 
             * 010  - not packed, 16 color , use 4000/8000, monochrome
769
 
             * 001  - packed, 4 color, use 2000, monochrome
770
 
             * 000  - not packed, 4 color, use 2000, monochrome - Regular WS monochrome
771
 
             */
772
 
                        if ( state->m_system_type == TYPE_WSC )
773
 
                        {
774
 
                                state->m_vdp.color_mode = data & 0x80;
775
 
                                state->m_vdp.colors_16 = data & 0x40;
776
 
                                state->m_vdp.tile_packed = data & 0x20;
777
 
                        }
778
 
                        break;
779
 
                case 0x80:      /* Audio 1 freq (lo)
780
 
                   Bit 0-7 - Audio channel 1 frequency bit 0-7
781
 
                */
782
 
                case 0x81:      /* Audio 1 freq (hi)
783
 
                   Bit 0-7 - Audio channel 1 frequency bit 8-15
784
 
                */
785
 
                case 0x82:      /* Audio 2 freq (lo)
786
 
                   Bit 0-7 - Audio channel 2 frequency bit 0-7
787
 
                */
788
 
                case 0x83:      /* Audio 2 freq (hi)
789
 
                   Bit 0-7 - Audio channel 2 frequency bit 8-15
790
 
                */
791
 
                case 0x84:      /* Audio 3 freq (lo)
792
 
                   Bit 0-7 - Audio channel 3 frequency bit 0-7
793
 
                */
794
 
                case 0x85:      /* Audio 3 freq (hi)
795
 
                   Bit 0-7 - Audio channel 3 frequency bit 8-15
796
 
                */
797
 
                case 0x86:      /* Audio 4 freq (lo)
798
 
                   Bit 0-7 - Audio channel 4 frequency bit 0-7
799
 
                */
800
 
                case 0x87:      /* Audio 4 freq (hi)
801
 
                   Bit 0-7 - Audio channel 4 frequency bit 8-15
802
 
                */
803
 
                case 0x88:      /* Audio 1 volume
804
 
                   Bit 0-3 - Right volume audio channel 1
805
 
                   Bit 4-7 - Left volume audio channel 1
806
 
                */
807
 
                case 0x89:      /* Audio 2 volume
808
 
                   Bit 0-3 - Right volume audio channel 2
809
 
                   Bit 4-7 - Left volume audio channel 2
810
 
                */
811
 
                case 0x8A:      /* Audio 3 volume
812
 
                   Bit 0-3 - Right volume audio channel 3
813
 
                   Bit 4-7 - Left volume audio channel 3
814
 
                */
815
 
                case 0x8B:      /* Audio 4 volume
816
 
                   Bit 0-3 - Right volume audio channel 4
817
 
                   Bit 4-7 - Left volume audio channel 4
818
 
                */
819
 
                case 0x8C:      /* Sweep step
820
 
                   Bit 0-7 - Sweep step
821
 
                */
822
 
                case 0x8D:      /* Sweep time
823
 
                   Bit 0-7 - Sweep time
824
 
                */
825
 
                case 0x8E:      /* Noise control
826
 
                   Bit 0-2 - Noise generator type
827
 
                   Bit 3   - Reset
828
 
                   Bit 4   - Enable
829
 
                   Bit 5-7 - Unknown
830
 
                */
831
 
                case 0x8F:      /* Sample location
832
 
                   Bit 0-7 - Sample address location 0 00xxxxxx xx000000
833
 
                */
834
 
                case 0x90:      /* Audio control
835
 
                   Bit 0   - Audio 1 enable
836
 
                   Bit 1   - Audio 2 enable
837
 
                   Bit 2   - Audio 3 enable
838
 
                   Bit 3   - Audio 4 enable
839
 
                   Bit 4   - Unknown
840
 
                   Bit 5   - Audio 2 voice mode enable
841
 
                   Bit 6   - Audio 3 sweep mode enable
842
 
                   Bit 7   - Audio 4 noise mode enable
843
 
                */
844
 
                case 0x91:      /* Audio output
845
 
                   Bit 0   - Mono select
846
 
                   Bit 1-2 - Output volume
847
 
                   Bit 3   - External stereo
848
 
                   Bit 4-6 - Unknown
849
 
                   Bit 7   - External speaker (Read-only, set by hardware)
850
 
                */
851
 
                case 0x92:      /* Noise counter shift register (lo)
852
 
                   Bit 0-7 - Noise counter shift register bit 0-7
853
 
                */
854
 
                case 0x93:      /* Noise counter shift register (hi)
855
 
                   Bit 0-6 - Noise counter shift register bit 8-14
856
 
                   bit 7   - Unknown
857
 
                */
858
 
                case 0x94:      /* Master volume
859
 
                   Bit 0-3 - Master volume
860
 
                   Bit 4-7 - Unknown
861
 
                */
862
 
                        wswan_sound_port_w( space->machine().device("custom"), offset, data );
863
 
                        break;
864
 
                case 0xa0:      /* Hardware type - this is probably read only
865
 
                   Bit 0   - Enable cartridge slot and/or disable bios
866
 
                   Bit 1   - Hardware type: 0 = WS, 1 = WSC
867
 
                   Bit 2-7 - Unknown
868
 
                */
869
 
                        if ( ( data & 0x01 ) && !state->m_bios_disabled )
870
 
                        {
871
 
                                state->m_bios_disabled = 1;
872
 
                                memory_set_bankptr( space->machine(), "bank15", state->m_ROMMap[ ( ( ( state->m_ws_portram[0xc0] & 0x0F ) << 4 ) | 15 ) & ( state->m_ROMBanks - 1 ) ] );
873
 
                        }
874
 
                        break;
875
 
                case 0xa2:      /* Timer control
876
 
                   Bit 0   - HBlank Timer enable
877
 
                   Bit 1   - HBlank Timer mode: 0 = one shot, 1 = auto reset
878
 
                   Bit 2   - VBlank Timer(1/75s) enable
879
 
                   Bit 3   - VBlank Timer mode: 0 = one shot, 1 = auto reset
880
 
                   Bit 4-7 - Unknown
881
 
                */
882
 
                        state->m_vdp.timer_hblank_enable = data & 0x1;
883
 
                        state->m_vdp.timer_hblank_mode = (data & 0x2) >> 1;
884
 
                        state->m_vdp.timer_vblank_enable = (data & 0x4) >> 2;
885
 
                        state->m_vdp.timer_vblank_mode = (data & 0x8) >> 3;
886
 
                        break;
887
 
                case 0xa4:      /* HBlank timer frequency (low) - reload value
888
 
                   Bit 0-7 - HBlank timer reload value bit 0-7
889
 
                */
890
 
                        state->m_vdp.timer_hblank_reload &= 0xff00;
891
 
                        state->m_vdp.timer_hblank_reload += data;
892
 
                        state->m_vdp.timer_hblank_count = state->m_vdp.timer_hblank_reload;
893
 
                        break;
894
 
                case 0xa5:      /* HBlank timer frequency (high) - reload value
895
 
                   Bit 8-15 - HBlank timer reload value bit 8-15
896
 
                */
897
 
                        state->m_vdp.timer_hblank_reload &= 0xff;
898
 
                        state->m_vdp.timer_hblank_reload += data << 8;
899
 
                        state->m_vdp.timer_hblank_count = state->m_vdp.timer_hblank_reload;
900
 
                        break;
901
 
                case 0xa6:      /* VBlank timer frequency (low) - reload value
902
 
                   Bit 0-7 - VBlank timer reload value bit 0-7
903
 
                */
904
 
                        state->m_vdp.timer_vblank_reload &= 0xff00;
905
 
                        state->m_vdp.timer_vblank_reload += data;
906
 
                        state->m_vdp.timer_vblank_count = state->m_vdp.timer_vblank_reload;
907
 
                        break;
908
 
                case 0xa7:      /* VBlank timer frequency (high) - reload value
909
 
                   Bit 0-7 - VBlank timer reload value bit 8-15
910
 
                */
911
 
                        state->m_vdp.timer_vblank_reload &= 0xff;
912
 
                        state->m_vdp.timer_vblank_reload += data << 8;
913
 
                        state->m_vdp.timer_vblank_count = state->m_vdp.timer_vblank_reload;
914
 
                        break;
915
 
                case 0xa8:      /* HBlank counter (low)
916
 
                   Bit 0-7 - HBlank counter bit 0-7
917
 
                */
918
 
                case 0xa9:      /* HBlank counter (high)
919
 
                   Bit 0-7 - HBlank counter bit 8-15
920
 
                */
921
 
                case 0xaa:      /* VBlank counter (low)
922
 
                   Bit 0-7 - VBlank counter bit 0-7
923
 
                */
924
 
                case 0xab:      /* VBlank counter (high)
925
 
                   Bit 0-7 - VBlank counter bit 8-15
926
 
                */
927
 
                        break;
928
 
 
929
 
                case 0xb0:      /* Interrupt base vector
930
 
                   Bit 0-7 - Interrupt base vector
931
 
                */
932
 
                        break;
933
 
                case 0xb1:      /* Communication byte
934
 
                   Bit 0-7 - Communication byte
935
 
                */
936
 
                        break;
937
 
                case 0xb2:      /* Interrupt enable
938
 
                   Bit 0   - Serial transmit interrupt enable
939
 
                   Bit 1   - Key press interrupt enable
940
 
                   Bit 2   - RTC alarm interrupt enable
941
 
                   Bit 3   - Serial receive interrupt enable
942
 
                   Bit 4   - Drawing line detection interrupt enable
943
 
                   Bit 5   - VBlank timer interrupt enable
944
 
                   Bit 6   - VBlank interrupt enable
945
 
                   Bit 7   - HBlank timer interrupt enable
946
 
                */
947
 
                        break;
948
 
                case 0xb3:      /* serial communication control
949
 
                   Bit 0   - Receive complete
950
 
                   Bit 1   - Error
951
 
                   Bit 2   - Send complete
952
 
                   Bit 3-4 - Unknown
953
 
                   Bit 5   - Send data interrupt generation
954
 
                   Bit 6   - Connection speed: 0 = 9600 bps, 1 = 38400 bps
955
 
                   bit 7   - Receive data interrupt generation
956
 
                */
957
 
//          data |= 0x02;
958
 
                        state->m_ws_portram[0xb1] = 0xFF;
959
 
                        if ( data & 0x80 )
960
 
                        {
961
 
//              state->m_ws_portram[0xb1] = 0x00;
962
 
                                data |= 0x04;
963
 
                        }
964
 
                        if (data & 0x20 )
965
 
                        {
966
 
//              data |= 0x01;
967
 
                        }
968
 
                        break;
969
 
                case 0xb5:      /* Read controls
970
 
                   Bit 0-3 - Current state of input lines (read-only)
971
 
                   Bit 4-6 - Select line of inputs to read
972
 
                             001 - Read Y cursors
973
 
                             010 - Read X cursors
974
 
                             100 - Read START,A,B buttons
975
 
                   Bit 7   - Unknown
976
 
                */
977
 
                        data = data & 0xF0;
978
 
                        switch( data )
979
 
                        {
980
 
                        case 0x10:      /* Read Y cursors: Y1 - Y2 - Y3 - Y4 */
981
 
                                data = data | input_port_read(space->machine(), "CURSY");
982
 
                                break;
983
 
                        case 0x20:      /* Read X cursors: X1 - X2 - X3 - X4 */
984
 
                                data = data | input_port_read(space->machine(), "CURSX");
985
 
                                break;
986
 
                        case 0x40:      /* Read buttons: START - A - B */
987
 
                                data = data | input_port_read(space->machine(), "BUTTONS");
988
 
                                break;
989
 
                        }
990
 
                        break;
991
 
                case 0xb6:      /* Interrupt acknowledge
992
 
                   Bit 0   - Serial transmit interrupt acknowledge
993
 
                   Bit 1   - Key press interrupt acknowledge
994
 
                   Bit 2   - RTC alarm interrupt acknowledge
995
 
                   Bit 3   - Serial receive interrupt acknowledge
996
 
                   Bit 4   - Drawing line detection interrupt acknowledge
997
 
                   Bit 5   - VBlank timer interrupt acknowledge
998
 
                   Bit 6   - VBlank interrupt acknowledge
999
 
                   Bit 7   - HBlank timer interrupt acknowledge
1000
 
                */
1001
 
                        wswan_clear_irq_line( space->machine(), data );
1002
 
                        data = state->m_ws_portram[0xB6];
1003
 
                        break;
1004
 
                case 0xba:      /* Internal EEPROM data (low)
1005
 
                   Bit 0-7 - Internal EEPROM data transfer bit 0-7
1006
 
                */
1007
 
                case 0xbb:      /* Internal EEPROM data (high)
1008
 
                   Bit 0-7 - Internal EEPROM data transfer bit 8-15
1009
 
                */
1010
 
                        break;
1011
 
                case 0xbc:      /* Internal EEPROM address (low)
1012
 
                   Bit 0-7 - Internal EEPROM address bit 1-8
1013
 
                */
1014
 
                case 0xbd:      /* Internal EEPROM address (high)
1015
 
                   Bit 0   - Internal EEPROM address bit 9(?)
1016
 
                   Bit 1-7 - Unknown
1017
 
                   Only 1KByte internal EEPROM??
1018
 
                */
1019
 
                        break;
1020
 
                case 0xbe:      /* Internal EEPROM command
1021
 
                   Bit 0   - Read complete (read only)
1022
 
                   Bit 1   - Write complete (read only)
1023
 
                   Bit 2-3 - Unknown
1024
 
                   Bit 4   - Read
1025
 
                   Bit 5   - Write
1026
 
                   Bit 6   - Protect
1027
 
                   Bit 7   - Initialize
1028
 
                */
1029
 
                        if ( data & 0x20 )
1030
 
                        {
1031
 
                                UINT16 addr = ( ( ( state->m_ws_portram[0xbd] << 8 ) | state->m_ws_portram[0xbc] ) << 1 ) & 0x1FF;
1032
 
                                state->m_internal_eeprom[ addr ] = state->m_ws_portram[0xba];
1033
 
                                state->m_internal_eeprom[ addr + 1 ] = state->m_ws_portram[0xbb];
1034
 
                                data |= 0x02;
1035
 
                        }
1036
 
                        else if ( data & 0x10 )
1037
 
                        {
1038
 
                                UINT16 addr = ( ( ( state->m_ws_portram[0xbd] << 8 ) | state->m_ws_portram[0xbc] ) << 1 ) & 0x1FF;
1039
 
                                state->m_ws_portram[0xba] = state->m_internal_eeprom[ addr ];
1040
 
                                state->m_ws_portram[0xbb] = state->m_internal_eeprom[ addr + 1];
1041
 
                                data |= 0x01;
1042
 
                        }
1043
 
                        else
1044
 
                        {
1045
 
                                logerror( "Unsupported internal EEPROM command: %X\n", data );
1046
 
                        }
1047
 
                        break;
1048
 
                case 0xc0:      /* ROM bank select for banks 4-15
1049
 
                   Bit 0-3 - ROM bank base register for banks 4-15
1050
 
                   Bit 4-7 - Unknown
1051
 
                */
1052
 
                        memory_set_bankptr( space->machine(), "bank4", state->m_ROMMap[ ( ( ( data & 0x0F ) << 4 ) | 4 ) & ( state->m_ROMBanks - 1 ) ] );
1053
 
                        memory_set_bankptr( space->machine(), "bank5", state->m_ROMMap[ ( ( ( data & 0x0F ) << 4 ) | 5 ) & ( state->m_ROMBanks - 1 ) ] );
1054
 
                        memory_set_bankptr( space->machine(), "bank6", state->m_ROMMap[ ( ( ( data & 0x0F ) << 4 ) | 6 ) & ( state->m_ROMBanks - 1 ) ] );
1055
 
                        memory_set_bankptr( space->machine(), "bank7", state->m_ROMMap[ ( ( ( data & 0x0F ) << 4 ) | 7 ) & ( state->m_ROMBanks - 1 ) ] );
1056
 
                        memory_set_bankptr( space->machine(), "bank8", state->m_ROMMap[ ( ( ( data & 0x0F ) << 4 ) | 8 ) & ( state->m_ROMBanks - 1 ) ] );
1057
 
                        memory_set_bankptr( space->machine(), "bank9", state->m_ROMMap[ ( ( ( data & 0x0F ) << 4 ) | 9 ) & ( state->m_ROMBanks - 1 ) ] );
1058
 
                        memory_set_bankptr( space->machine(), "bank10", state->m_ROMMap[ ( ( ( data & 0x0F ) << 4 ) | 10 ) & ( state->m_ROMBanks - 1 ) ] );
1059
 
                        memory_set_bankptr( space->machine(), "bank11", state->m_ROMMap[ ( ( ( data & 0x0F ) << 4 ) | 11 ) & ( state->m_ROMBanks - 1 ) ] );
1060
 
                        memory_set_bankptr( space->machine(), "bank12", state->m_ROMMap[ ( ( ( data & 0x0F ) << 4 ) | 12 ) & ( state->m_ROMBanks - 1 ) ] );
1061
 
                        memory_set_bankptr( space->machine(), "bank13", state->m_ROMMap[ ( ( ( data & 0x0F ) << 4 ) | 13 ) & ( state->m_ROMBanks - 1 ) ] );
1062
 
                        memory_set_bankptr( space->machine(), "bank14", state->m_ROMMap[ ( ( ( data & 0x0F ) << 4 ) | 14 ) & ( state->m_ROMBanks - 1 ) ] );
1063
 
                        if ( state->m_bios_disabled )
1064
 
                        {
1065
 
                                memory_set_bankptr( space->machine(), "bank15", state->m_ROMMap[ ( ( ( data & 0x0F ) << 4 ) | 15 ) & ( state->m_ROMBanks - 1 ) ] );
1066
 
                        }
1067
 
                        break;
1068
 
                case 0xc1:      /* SRAM bank select
1069
 
                   Bit 0-7 - SRAM bank to select
1070
 
                */
1071
 
                        if ( state->m_eeprom.mode == SRAM_64K || state->m_eeprom.mode == SRAM_256K || state->m_eeprom.mode == SRAM_512K || state->m_eeprom.mode == SRAM_1M || state->m_eeprom.mode == SRAM_2M )
1072
 
                        {
1073
 
                                state->m_eeprom.page = &state->m_eeprom.data[ ( data * 64 * 1024 ) & ( state->m_eeprom.size - 1 ) ];
1074
 
                        }
1075
 
                        break;
1076
 
                case 0xc2:      /* ROM bank select for segment 2 (0x20000 - 0x2ffff)
1077
 
                   Bit 0-7 - ROM bank for segment 2
1078
 
                */
1079
 
                        memory_set_bankptr( space->machine(), "bank2", state->m_ROMMap[ data & ( state->m_ROMBanks - 1 ) ]);
1080
 
                        break;
1081
 
                case 0xc3:      /* ROM bank select for segment 3 (0x30000-0x3ffff)
1082
 
                   Bit 0-7 - ROM bank for segment 3
1083
 
                */
1084
 
                        memory_set_bankptr( space->machine(), "bank3", state->m_ROMMap[ data & ( state->m_ROMBanks - 1 ) ]);
1085
 
                        break;
1086
 
                case 0xc6:      /* EEPROM address lower bits port/EEPROM address and command port
1087
 
                   1KBit EEPROM:
1088
 
                   Bit 0-5 - EEPROM address bit 1-6
1089
 
                   Bit 6-7 - Command
1090
 
                             00 - Extended command address bit 4-5:
1091
 
                                  00 - Write disable
1092
 
                                  01 - Write all
1093
 
                                  10 - Erase all
1094
 
                                  11 - Write enable
1095
 
                             01 - Write
1096
 
                             10 - Read
1097
 
                             11 - Erase
1098
 
                   16KBit EEPROM:
1099
 
                   Bit 0-7 - EEPROM address bit 1-8
1100
 
                */
1101
 
                        switch( state->m_eeprom.mode )
1102
 
                        {
1103
 
                        case EEPROM_1K:
1104
 
                                state->m_eeprom.address = data & 0x3F;
1105
 
                                state->m_eeprom.command = data >> 4;
1106
 
                                if ( ( state->m_eeprom.command & 0x0C ) != 0x00 )
1107
 
                                {
1108
 
                                        state->m_eeprom.command = state->m_eeprom.command & 0x0C;
1109
 
                                }
1110
 
                                break;
1111
 
                        case EEPROM_16K:
1112
 
                                state->m_eeprom.address = ( state->m_eeprom.address & 0xFF00 ) | data;
1113
 
                                break;
1114
 
                        default:
1115
 
                                logerror( "Write EEPROM address/register register C6 for unsupported EEPROM type\n" );
1116
 
                                break;
1117
 
                        }
1118
 
                        break;
1119
 
                case 0xc7:      /* EEPROM higher bits/command bits port
1120
 
                   1KBit EEPROM:
1121
 
                   Bit 0   - Start
1122
 
                   Bit 1-7 - Unknown
1123
 
                   16KBit EEPROM:
1124
 
                   Bit 0-1 - EEPROM address bit 9-10
1125
 
                   Bit 2-3 - Command
1126
 
                             00 - Extended command address bit 0-1:
1127
 
                                  00 - Write disable
1128
 
                                  01 - Write all
1129
 
                                  10 - Erase all
1130
 
                                  11 - Write enable
1131
 
                             01 - Write
1132
 
                             10 - Read
1133
 
                         11 - Erase
1134
 
                   Bit 4   - Start
1135
 
                   Bit 5-7 - Unknown
1136
 
                */
1137
 
                        switch( state->m_eeprom.mode )
1138
 
                        {
1139
 
                        case EEPROM_1K:
1140
 
                                state->m_eeprom.start = data & 0x01;
1141
 
                                break;
1142
 
                        case EEPROM_16K:
1143
 
                                state->m_eeprom.address = ( ( data & 0x03 ) << 8 ) | ( state->m_eeprom.address & 0xFF );
1144
 
                                state->m_eeprom.command = data & 0x0F;
1145
 
                                if ( ( state->m_eeprom.command & 0x0C ) != 0x00 )
1146
 
                                {
1147
 
                                        state->m_eeprom.command = state->m_eeprom.command & 0x0C;
1148
 
                                }
1149
 
                                state->m_eeprom.start = ( data >> 4 ) & 0x01;
1150
 
                                break;
1151
 
                        default:
1152
 
                                logerror( "Write EEPROM address/command register C7 for unsupported EEPROM type\n" );
1153
 
                                break;
1154
 
                        }
1155
 
                        break;
1156
 
                case 0xc8:      /* EEPROM command
1157
 
                   Bit 0   - Read complete (read only)
1158
 
                   Bit 1   - Write complete (read only)
1159
 
                   Bit 2-3 - Unknown
1160
 
                   Bit 4   - Read
1161
 
                   Bit 5   - Write
1162
 
                   Bit 6   - Protect
1163
 
                   Bit 7   - Initialize
1164
 
                */
1165
 
                        if ( state->m_eeprom.mode == EEPROM_1K || state->m_eeprom.mode == EEPROM_16K )
1166
 
                        {
1167
 
                                if ( data & 0x80 )
1168
 
                                {       /* Initialize */
1169
 
                                        logerror( "Unsupported EEPROM command 'Initialize'\n" );
1170
 
                                }
1171
 
                                if ( data & 0x40 )
1172
 
                                {       /* Protect */
1173
 
                                        switch( state->m_eeprom.command )
1174
 
                                        {
1175
 
                                        case 0x00:
1176
 
                                                state->m_eeprom.write_enabled = 0;
1177
 
                                                data |= 0x02;
1178
 
                                                break;
1179
 
                                        case 0x03:
1180
 
                                                state->m_eeprom.write_enabled = 1;
1181
 
                                                data |= 0x02;
1182
 
                                                break;
1183
 
                                        default:
1184
 
                                                logerror( "Unsupported 'Protect' command %X\n", state->m_eeprom.command );
1185
 
                                        }
1186
 
                                }
1187
 
                                if ( data & 0x20 )
1188
 
                                {       /* Write */
1189
 
                                        if ( state->m_eeprom.write_enabled )
1190
 
                                        {
1191
 
                                                switch( state->m_eeprom.command )
1192
 
                                                {
1193
 
                                                case 0x04:
1194
 
                                                        state->m_eeprom.data[ ( state->m_eeprom.address << 1 ) + 1 ] = state->m_ws_portram[0xc4];
1195
 
                                                        state->m_eeprom.data[ state->m_eeprom.address << 1 ] = state->m_ws_portram[0xc5];
1196
 
                                                        data |= 0x02;
1197
 
                                                        break;
1198
 
                                                default:
1199
 
                                                        logerror( "Unsupported 'Write' command %X\n", state->m_eeprom.command );
1200
 
                                                }
1201
 
                                        }
1202
 
                                }
1203
 
                                if ( data & 0x10 )
1204
 
                                {       /* Read */
1205
 
                                        state->m_ws_portram[0xc4] = state->m_eeprom.data[ ( state->m_eeprom.address << 1 ) + 1 ];
1206
 
                                        state->m_ws_portram[0xc5] = state->m_eeprom.data[ state->m_eeprom.address << 1 ];
1207
 
                                        data |= 0x01;
1208
 
                                }
1209
 
                        }
1210
 
                        else
1211
 
                        {
1212
 
                                logerror( "EEPROM command for unknown EEPROM type\n" );
1213
 
                        }
1214
 
                        break;
1215
 
                case 0xca:      /* RTC Command
1216
 
                   Bit 0-4 - RTC command
1217
 
                             10000 - Reset
1218
 
                             10010 - Write timer settings (alarm)
1219
 
                             10011 - Read timer settings (alarm)
1220
 
                             10100 - Set time/date
1221
 
                             10101 - Get time/date
1222
 
                   Bit 5-6 - Unknown
1223
 
                   Bit 7   - Command done (read only)
1224
 
                */
1225
 
                        switch( data )
1226
 
                        {
1227
 
                        case 0x10:      /* Reset */
1228
 
                                state->m_rtc.index = 8;
1229
 
                                state->m_rtc.year = 0;
1230
 
                                state->m_rtc.month = 1;
1231
 
                                state->m_rtc.day = 1;
1232
 
                                state->m_rtc.day_of_week = 0;
1233
 
                                state->m_rtc.hour = 0;
1234
 
                                state->m_rtc.minute = 0;
1235
 
                                state->m_rtc.second = 0;
1236
 
                                state->m_rtc.setting = 0xFF;
1237
 
                                data |= 0x80;
1238
 
                                break;
1239
 
                        case 0x12:      /* Write Timer Settings (Alarm) */
1240
 
                                state->m_rtc.index = 8;
1241
 
                                state->m_rtc.setting = state->m_ws_portram[0xcb];
1242
 
                                data |= 0x80;
1243
 
                                break;
1244
 
                        case 0x13:      /* Read Timer Settings (Alarm) */
1245
 
                                state->m_rtc.index = 8;
1246
 
                                state->m_ws_portram[0xcb] = state->m_rtc.setting;
1247
 
                                data |= 0x80;
1248
 
                                break;
1249
 
                        case 0x14:      /* Set Time/Date */
1250
 
                                state->m_rtc.year = state->m_ws_portram[0xcb];
1251
 
                                state->m_rtc.index = 1;
1252
 
                                data |= 0x80;
1253
 
                                break;
1254
 
                        case 0x15:      /* Get Time/Date */
1255
 
                                state->m_rtc.index = 0;
1256
 
                                data |= 0x80;
1257
 
                                state->m_ws_portram[0xcb] = state->m_rtc.year;
1258
 
                                break;
1259
 
                        default:
1260
 
                                logerror( "%X: Unknown RTC command (%X) requested\n", cpu_get_pc( &space->device() ), data );
1261
 
                        }
1262
 
                        break;
1263
 
                case 0xcb:      /* RTC Data */
1264
 
                        if ( state->m_ws_portram[0xca] == 0x94 && state->m_rtc.index < 7 )
1265
 
                        {
1266
 
                                switch( state->m_rtc.index )
1267
 
                                {
1268
 
                                case 0: state->m_rtc.year = data; break;
1269
 
                                case 1: state->m_rtc.month = data; break;
1270
 
                                case 2: state->m_rtc.day = data; break;
1271
 
                                case 3: state->m_rtc.day_of_week = data; break;
1272
 
                                case 4: state->m_rtc.hour = data; break;
1273
 
                                case 5: state->m_rtc.minute = data; break;
1274
 
                                case 6: state->m_rtc.second = data; break;
1275
 
                                }
1276
 
                                state->m_rtc.index++;
1277
 
                        }
1278
 
                        break;
1279
 
                default:
1280
 
                        logerror( "Write to unsupported port: %X - %X\n", offset, data );
1281
 
                        break;
1282
 
        }
1283
 
 
1284
 
        /* Update the port value */
1285
 
        state->m_ws_portram[offset] = data;
1286
 
}
1287
 
 
1288
 
static const char* wswan_determine_sram( wswan_state *state, UINT8 data )
1289
 
{
1290
 
        state->m_eeprom.write_enabled = 0;
1291
 
        state->m_eeprom.mode = SRAM_UNKNOWN;
1292
 
        switch( data )
1293
 
        {
1294
 
        case 0x00: state->m_eeprom.mode = SRAM_NONE; break;
1295
 
        case 0x01: state->m_eeprom.mode = SRAM_64K; break;
1296
 
        case 0x02: state->m_eeprom.mode = SRAM_256K; break;
1297
 
        case 0x03: state->m_eeprom.mode = SRAM_1M; break;
1298
 
        case 0x04: state->m_eeprom.mode = SRAM_2M; break;
1299
 
        case 0x05: state->m_eeprom.mode = SRAM_512K; break;
1300
 
        case 0x10: state->m_eeprom.mode = EEPROM_1K; break;
1301
 
        case 0x20: state->m_eeprom.mode = EEPROM_16K; break;
1302
 
        case 0x50: state->m_eeprom.mode = EEPROM_8K; break;
1303
 
        }
1304
 
        state->m_eeprom.size = wswan_sram_size[ state->m_eeprom.mode ];
1305
 
        return wswan_sram_str[ state->m_eeprom.mode ];
1306
 
}
1307
 
 
1308
 
enum enum_romsize { ROM_4M=0, ROM_8M, ROM_16M, ROM_32M, ROM_64M, ROM_128M, ROM_UNKNOWN };
1309
 
static const char *const wswan_romsize_str[] = {
1310
 
        "4Mbit", "8Mbit", "16Mbit", "32Mbit", "64Mbit", "128Mbit", "Unknown"
1311
 
};
1312
 
 
1313
 
static const char* wswan_determine_romsize( UINT8 data )
1314
 
{
1315
 
        switch( data )
1316
 
        {
1317
 
        case 0x02:      return wswan_romsize_str[ ROM_4M ];
1318
 
        case 0x03:      return wswan_romsize_str[ ROM_8M ];
1319
 
        case 0x04:      return wswan_romsize_str[ ROM_16M ];
1320
 
        case 0x06:      return wswan_romsize_str[ ROM_32M ];
1321
 
        case 0x08:      return wswan_romsize_str[ ROM_64M ];
1322
 
        case 0x09:      return wswan_romsize_str[ ROM_128M ];
1323
 
        }
1324
 
        return wswan_romsize_str[ ROM_UNKNOWN ];
1325
 
}
1326
 
 
1327
 
DEVICE_START(wswan_cart)
1328
 
{
1329
 
        wswan_state *state = device->machine().driver_data<wswan_state>();
1330
 
        /* Initialize EEPROM structure */
1331
 
        memset( &state->m_eeprom, 0, sizeof( state->m_eeprom ) );
1332
 
        state->m_eeprom.data = NULL;
1333
 
        state->m_eeprom.page = NULL;
1334
 
 
1335
 
        /* Initialize RTC structure */
1336
 
        state->m_rtc.present = 0;
1337
 
        state->m_rtc.index = 0;
1338
 
        state->m_rtc.year = 0;
1339
 
        state->m_rtc.month = 0;
1340
 
        state->m_rtc.day = 0;
1341
 
        state->m_rtc.day_of_week = 0;
1342
 
        state->m_rtc.hour = 0;
1343
 
        state->m_rtc.minute = 0;
1344
 
        state->m_rtc.second = 0;
1345
 
        state->m_rtc.setting = 0xFF;
1346
 
}
1347
 
 
1348
 
DEVICE_IMAGE_LOAD(wswan_cart)
1349
 
{
1350
 
        wswan_state *state = image.device().machine().driver_data<wswan_state>();
1351
 
        UINT32 ii, size;
1352
 
        const char *sram_str;
1353
 
 
1354
 
        if (image.software_entry() == NULL)
1355
 
                size = image.length();
1356
 
        else
1357
 
                size = image.get_software_region_length("rom");
1358
 
 
1359
 
        state->m_ws_ram = (UINT8*) image.device().machine().device("maincpu")->memory().space(AS_PROGRAM)->get_read_ptr(0);
1360
 
        memset(state->m_ws_ram, 0, 0xffff);
1361
 
        state->m_ROMBanks = size / 65536;
1362
 
 
1363
 
        for (ii = 0; ii < state->m_ROMBanks; ii++)
1364
 
        {
1365
 
                if ((state->m_ROMMap[ii] = auto_alloc_array(image.device().machine(), UINT8, 0x10000)))
1366
 
                {
1367
 
                        if (image.software_entry() == NULL)
1368
 
                        {
1369
 
                                if (image.fread( state->m_ROMMap[ii], 0x10000) != 0x10000)
1370
 
                                {
1371
 
                                        logerror("Error while reading loading rom!\n");
1372
 
                                        return IMAGE_INIT_FAIL;
1373
 
                                }
1374
 
                        }
1375
 
                        else
1376
 
                                memcpy(state->m_ROMMap[ii], image.get_software_region("rom") + ii * 0x10000, 0x10000);
1377
 
                }
1378
 
                else
1379
 
                {
1380
 
                        logerror("Memory allocation failed reading rom!\n");
1381
 
                        return IMAGE_INIT_FAIL;
1382
 
                }
1383
 
        }
1384
 
 
1385
 
        sram_str = wswan_determine_sram(state, state->m_ROMMap[state->m_ROMBanks - 1][0xfffb]);
1386
 
 
1387
 
        state->m_rtc.present = state->m_ROMMap[state->m_ROMBanks - 1][0xfffd] ? 1 : 0;
1388
 
 
1389
 
        {
1390
 
                int sum = 0;
1391
 
                /* Spit out some info */
1392
 
                logerror("ROM DETAILS\n" );
1393
 
                logerror("\tDeveloper ID: %X\n", state->m_ROMMap[state->m_ROMBanks - 1][0xfff6]);
1394
 
                logerror("\tMinimum system: %s\n", state->m_ROMMap[state->m_ROMBanks - 1][0xfff7] ? "WonderSwan Color" : "WonderSwan");
1395
 
                logerror("\tCart ID: %X\n", state->m_ROMMap[state->m_ROMBanks - 1][0xfff8]);
1396
 
                logerror("\tROM size: %s\n", wswan_determine_romsize(state->m_ROMMap[state->m_ROMBanks - 1][0xfffa]));
1397
 
                logerror("\tSRAM size: %s\n", sram_str);
1398
 
                logerror("\tFeatures: %X\n", state->m_ROMMap[state->m_ROMBanks - 1][0xfffc]);
1399
 
                logerror("\tRTC: %s\n", state->m_ROMMap[state->m_ROMBanks - 1][0xfffd] ? "yes" : "no");
1400
 
                for (ii = 0; ii < state->m_ROMBanks; ii++)
1401
 
                {
1402
 
                        int count;
1403
 
                        for (count = 0; count < 0x10000; count++)
1404
 
                        {
1405
 
                                sum += state->m_ROMMap[ii][count];
1406
 
                        }
1407
 
                }
1408
 
                sum -= state->m_ROMMap[state->m_ROMBanks - 1][0xffff];
1409
 
                sum -= state->m_ROMMap[state->m_ROMBanks - 1][0xfffe];
1410
 
                sum &= 0xffff;
1411
 
                logerror("\tChecksum: %X%X (calculated: %04X)\n", state->m_ROMMap[state->m_ROMBanks - 1][0xffff], state->m_ROMMap[state->m_ROMBanks - 1][0xfffe], sum);
1412
 
        }
1413
 
 
1414
 
        if (state->m_eeprom.size != 0)
1415
 
        {
1416
 
                state->m_eeprom.data = auto_alloc_array(image.device().machine(), UINT8, state->m_eeprom.size);
1417
 
                image.battery_load(state->m_eeprom.data, state->m_eeprom.size, 0x00);
1418
 
                state->m_eeprom.page = state->m_eeprom.data;
1419
 
        }
1420
 
 
1421
 
        if (image.software_entry() == NULL)
1422
 
        {
1423
 
                logerror("Image Name: %s\n", image.longname());
1424
 
                logerror("Image Year: %s\n", image.year());
1425
 
                logerror("Image Manufacturer: %s\n", image.manufacturer());
1426
 
        }
1427
 
 
1428
 
        /* All done */
1429
 
        return IMAGE_INIT_PASS;
1430
 
}
1431
 
 
1432
 
static TIMER_CALLBACK(wswan_scanline_interrupt)
1433
 
{
1434
 
        wswan_state *state = machine.driver_data<wswan_state>();
1435
 
        if( state->m_vdp.current_line < 144 )
1436
 
        {
1437
 
                wswan_refresh_scanline(machine);
1438
 
        }
1439
 
 
1440
 
        /* Decrement 12kHz (HBlank) counter */
1441
 
        if ( state->m_vdp.timer_hblank_enable && state->m_vdp.timer_hblank_reload != 0 )
1442
 
        {
1443
 
                state->m_vdp.timer_hblank_count--;
1444
 
                logerror( "timer_hblank_count: %X\n", state->m_vdp.timer_hblank_count );
1445
 
                if ( state->m_vdp.timer_hblank_count == 0 )
1446
 
                {
1447
 
                        if ( state->m_vdp.timer_hblank_mode )
1448
 
                        {
1449
 
                                state->m_vdp.timer_hblank_count = state->m_vdp.timer_hblank_reload;
1450
 
                        }
1451
 
                        else
1452
 
                        {
1453
 
                                state->m_vdp.timer_hblank_reload = 0;
1454
 
                        }
1455
 
                        logerror( "trigerring hbltmr interrupt\n" );
1456
 
                        wswan_set_irq_line( machine, WSWAN_IFLAG_HBLTMR );
1457
 
                }
1458
 
        }
1459
 
 
1460
 
        /* Handle Sound DMA */
1461
 
        if ( ( state->m_sound_dma.enable & 0x88 ) == 0x80 )
1462
 
        {
1463
 
                address_space *space = machine.device("maincpu")->memory().space(AS_PROGRAM );
1464
 
                /* TODO: Output sound DMA byte */
1465
 
                wswan_port_w( space, 0x89, space->read_byte(state->m_sound_dma.source ) );
1466
 
                state->m_sound_dma.size--;
1467
 
                state->m_sound_dma.source = ( state->m_sound_dma.source + 1 ) & 0x0FFFFF;
1468
 
                if ( state->m_sound_dma.size == 0 )
1469
 
                {
1470
 
                        state->m_sound_dma.enable &= 0x7F;
1471
 
                }
1472
 
        }
1473
 
 
1474
 
//  state->m_vdp.current_line = (state->m_vdp.current_line + 1) % 159;
1475
 
 
1476
 
        if( state->m_vdp.current_line == 144 )
1477
 
        {
1478
 
                wswan_set_irq_line( machine, WSWAN_IFLAG_VBL );
1479
 
                /* Decrement 75Hz (VBlank) counter */
1480
 
                if ( state->m_vdp.timer_vblank_enable && state->m_vdp.timer_vblank_reload != 0 )
1481
 
                {
1482
 
                        state->m_vdp.timer_vblank_count--;
1483
 
                        logerror( "timer_vblank_count: %X\n", state->m_vdp.timer_vblank_count );
1484
 
                        if ( state->m_vdp.timer_vblank_count == 0 )
1485
 
                        {
1486
 
                                if ( state->m_vdp.timer_vblank_mode )
1487
 
                                {
1488
 
                                        state->m_vdp.timer_vblank_count = state->m_vdp.timer_vblank_reload;
1489
 
                                }
1490
 
                                else
1491
 
                                {
1492
 
                                        state->m_vdp.timer_vblank_reload = 0;
1493
 
                                }
1494
 
                                logerror( "triggering vbltmr interrupt\n" );
1495
 
                                wswan_set_irq_line( machine, WSWAN_IFLAG_VBLTMR );
1496
 
                        }
1497
 
                }
1498
 
        }
1499
 
 
1500
 
//  state->m_vdp.current_line = (state->m_vdp.current_line + 1) % 159;
1501
 
 
1502
 
        if ( state->m_vdp.current_line == state->m_vdp.line_compare )
1503
 
        {
1504
 
                wswan_set_irq_line( machine, WSWAN_IFLAG_LCMP );
1505
 
        }
1506
 
 
1507
 
        state->m_vdp.current_line = (state->m_vdp.current_line + 1) % 159;
1508
 
 
1509
 
        if ( state->m_vdp.current_line == 0 )
1510
 
        {
1511
 
                if ( state->m_vdp.display_vertical != state->m_vdp.new_display_vertical )
1512
 
                {
1513
 
                        state->m_vdp.display_vertical = state->m_vdp.new_display_vertical;
1514
 
                        if ( state->m_vdp.display_vertical )
1515
 
                        {
1516
 
                                machine.primary_screen->set_visible_area(5*8, 5*8 + WSWAN_Y_PIXELS - 1, 0, WSWAN_X_PIXELS - 1 );
1517
 
                        }
1518
 
                        else
1519
 
                        {
1520
 
                                machine.primary_screen->set_visible_area(0, WSWAN_X_PIXELS - 1, 5*8, 5*8 + WSWAN_Y_PIXELS - 1 );
1521
 
                        }
1522
 
                }
1523
 
        }
1524
 
}
1525