1
/***************************************************************************
5
Machine file to handle emulation of the Bandai WonderSwan.
11
SRAM sizes should be in kbit instead of kbytes(?). This raises a few
13
- mirror of smaller <64KBYTE/512kbit sram sizes
14
- banking when using 1M or 2M sram sizes
16
***************************************************************************/
19
#include "includes/wswan.h"
20
#include "imagedev/cartslot.h"
23
#define INTERNAL_EEPROM_SIZE 1024
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 };
30
static TIMER_CALLBACK(wswan_scanline_interrupt);
33
static const UINT8 ws_portram_init[256] =
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
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....
58
The setting of SP to 2000h is what's needed to get Wonderswan Colloseum to boot.
73
EA 00 04 00 00 jmp 0000:0400
79
EA 00 00 FF FF jmp FFFFh:0000h
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
89
static void wswan_handle_irqs( running_machine &machine )
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 );
109
cputag_set_input_line(machine, "maincpu", 0, CLEAR_LINE );
113
static void wswan_set_irq_line( running_machine &machine, int irq)
115
wswan_state *state = machine.driver_data<wswan_state>();
116
if ( state->m_ws_portram[0xb2] & irq )
118
state->m_ws_portram[0xb6] |= irq;
119
wswan_handle_irqs( machine );
123
static void wswan_clear_irq_line( running_machine &machine, int irq)
125
wswan_state *state = machine.driver_data<wswan_state>();
126
state->m_ws_portram[0xb6] &= ~irq;
127
wswan_handle_irqs( machine );
130
static TIMER_CALLBACK(wswan_rtc_callback)
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 )
137
state->m_rtc.second = ( state->m_rtc.second & 0xF0 ) + 0x10;
140
/* Check for minute passed */
141
if ( state->m_rtc.second >= 0x60 )
143
state->m_rtc.second = 0;
144
state->m_rtc.minute = state->m_rtc.minute + 1;
145
if ( ( state->m_rtc.minute & 0x0F ) > 9 )
147
state->m_rtc.minute = ( state->m_rtc.minute & 0xF0 ) + 0x10;
151
/* Check for hour passed */
152
if ( state->m_rtc.minute >= 0x60 )
154
state->m_rtc.minute = 0;
155
state->m_rtc.hour = state->m_rtc.hour + 1;
156
if ( ( state->m_rtc.hour & 0x0F ) > 9 )
158
state->m_rtc.hour = ( state->m_rtc.hour & 0xF0 ) + 0x10;
160
if ( state->m_rtc.hour == 0x12 )
162
state->m_rtc.hour |= 0x80;
166
/* Check for day passed */
167
if ( state->m_rtc.hour >= 0x24 )
169
state->m_rtc.hour = 0;
170
state->m_rtc.day = state->m_rtc.day + 1;
174
static void wswan_machine_stop( running_machine &machine )
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 )
180
image->battery_save(state->m_eeprom.data, state->m_eeprom.size );
184
static void wswan_setup_bios( running_machine &machine )
186
wswan_state *state = machine.driver_data<wswan_state>();
187
if ( state->m_ws_bios_bank == NULL )
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 );
194
MACHINE_START( wswan )
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 ) );
203
wswan_setup_bios(machine);
205
/* Set up RTC timer */
206
if ( state->m_rtc.present )
207
machine.scheduler().timer_pulse(attotime::from_seconds(1), FUNC(wswan_rtc_callback));
210
MACHINE_START( wscolor )
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 ) );
219
wswan_setup_bios(machine);
221
/* Set up RTC timer */
222
if ( state->m_rtc.present )
223
machine.scheduler().timer_pulse(attotime::from_seconds(1), FUNC(wswan_rtc_callback));
226
MACHINE_RESET( wswan )
228
wswan_state *state = machine.driver_data<wswan_state>();
229
address_space *space = machine.device( "maincpu")->memory().space( AS_PROGRAM );
231
/* Intialize ports */
232
memcpy( state->m_ws_portram, ws_portram_init, 256 );
235
memset( &state->m_vdp, 0, sizeof( state->m_vdp ) );
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;
246
/* Initialize sound DMA */
247
memset( &state->m_sound_dma, 0, sizeof( state->m_sound_dma ) );
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)] );
268
NVRAM_HANDLER( wswan )
270
wswan_state *state = machine.driver_data<wswan_state>();
273
/* Save the EEPROM data */
274
file->write(state->m_internal_eeprom, INTERNAL_EEPROM_SIZE );
278
/* Load the EEPROM data */
281
file->read(state->m_internal_eeprom, INTERNAL_EEPROM_SIZE );
285
/* Initialize the EEPROM data */
286
memset( state->m_internal_eeprom, 0xFF, sizeof( state->m_internal_eeprom ) );
291
READ8_HANDLER( wswan_sram_r )
293
wswan_state *state = space->machine().driver_data<wswan_state>();
294
if ( state->m_eeprom.data == NULL )
298
return state->m_eeprom.page[ offset & ( state->m_eeprom.size - 1 ) ];
301
WRITE8_HANDLER( wswan_sram_w )
303
wswan_state *state = space->machine().driver_data<wswan_state>();
304
if ( state->m_eeprom.data == NULL )
308
state->m_eeprom.page[ offset & ( state->m_eeprom.size - 1 ) ] = data;
311
READ8_HANDLER( wswan_port_r )
313
wswan_state *state = space->machine().driver_data<wswan_state>();
314
UINT8 value = state->m_ws_portram[offset];
317
logerror( "PC=%X: port read %02X\n", cpu_get_pc( &space->device() ), offset );
320
case 0x02: /* Current line */
321
value = state->m_vdp.current_line;
323
case 0x4A: /* Sound DMA source address (low) */
324
value = state->m_sound_dma.source & 0xFF;
326
case 0x4B: /* Sound DMA source address (high) */
327
value = ( state->m_sound_dma.source >> 8 ) & 0xFF;
329
case 0x4C: /* Sound DMA source memory segment */
330
value = ( state->m_sound_dma.source >> 16 ) & 0xFF;
332
case 0x4E: /* Sound DMA transfer size (low) */
333
value = state->m_sound_dma.size & 0xFF;
335
case 0x4F: /* Sound DMA transfer size (high) */
336
value = ( state->m_sound_dma.size >> 8 ) & 0xFF;
338
case 0x52: /* Sound DMA start/stop */
339
value = state->m_sound_dma.enable;
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 )
352
value = state->m_vdp.timer_hblank_count & 0xFF;
355
value = state->m_vdp.timer_hblank_count >> 8;
358
value = state->m_vdp.timer_vblank_count & 0xFF;
361
value = state->m_vdp.timer_vblank_count >> 8;
363
case 0xCB: /* RTC data */
364
if ( state->m_ws_portram[0xca] == 0x95 && ( state->m_rtc.index < 7 ) )
366
switch( state->m_rtc.index )
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;
376
state->m_rtc.index++;
383
WRITE8_HANDLER( wswan_port_w )
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 );
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
397
10 - Foreground layer is displayed only inside foreground window area
398
11 - Foreground layer is displayed outside foreground window area
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;
407
case 0x01: /* Background colour
409
Bit 0-3 - Palette index
410
Bit 4-7 - Palette number
412
Bit 0-2 - Main palette index
416
case 0x02: /* Current scanline
417
Bit 0-7 - Current scanline (Most likely read-only)
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
423
case 0x03: /* Line compare
424
Bit 0-7 - Line compare
426
state->m_vdp.line_compare = data;
428
case 0x04: /* Sprite table base address
429
Bit 0-5 - Determine sprite table base address 0 0xxxxxx0 00000000
432
state->m_vdp.sprite_table_address = ( data & 0x3F ) << 9;
434
case 0x05: /* Number of sprite to start drawing with
435
Bit 0-7 - First sprite number
437
state->m_vdp.sprite_first = data;
439
case 0x06: /* Number of sprites to draw
440
Bit 0-7 - Number of sprites to draw
442
state->m_vdp.sprite_count = data;
444
case 0x07: /* Background/Foreground table base addresses
445
Bit 0-2 - Determine background table base address 00xxx000 00000000
447
Bit 4-6 - Determine foreground table base address 00xxx000 00000000
450
state->m_vdp.layer_bg_address = (data & 0x7) << 11;
451
state->m_vdp.layer_fg_address = (data & 0x70) << 7;
453
case 0x08: /* Left coordinate of foreground window
454
Bit 0-7 - Left coordinate of foreground window area
456
state->m_vdp.window_fg_left = data;
458
case 0x09: /* Top coordinate of foreground window
459
Bit 0-7 - Top coordinatte of foreground window area
461
state->m_vdp.window_fg_top = data;
463
case 0x0A: /* Right coordinate of foreground window
464
Bit 0-7 - Right coordinate of foreground window area
466
state->m_vdp.window_fg_right = data;
468
case 0x0B: /* Bottom coordinate of foreground window
469
Bit 0-7 - Bottom coordinate of foreground window area
471
state->m_vdp.window_fg_bottom = data;
473
case 0x0C: /* Left coordinate of sprite window
474
Bit 0-7 - Left coordinate of sprite window area
476
state->m_vdp.window_sprites_left = data;
478
case 0x0D: /* Top coordinate of sprite window
479
Bit 0-7 - Top coordinate of sprite window area
481
state->m_vdp.window_sprites_top = data;
483
case 0x0E: /* Right coordinate of sprite window
484
Bit 0-7 - Right coordinate of sprite window area
486
state->m_vdp.window_sprites_right = data;
488
case 0x0F: /* Bottom coordinate of sprite window
489
Bit 0-7 - Bottom coordiante of sprite window area
491
state->m_vdp.window_sprites_bottom = data;
493
case 0x10: /* Background layer X scroll
494
Bit 0-7 - Background layer X scroll
496
state->m_vdp.layer_bg_scroll_x = data;
498
case 0x11: /* Background layer Y scroll
499
Bit 0-7 - Background layer Y scroll
501
state->m_vdp.layer_bg_scroll_y = data;
503
case 0x12: /* Foreground layer X scroll
504
Bit 0-7 - Foreground layer X scroll
506
state->m_vdp.layer_fg_scroll_x = data;
508
case 0x13: /* Foreground layer Y scroll
509
Bit 0-7 - Foreground layer Y scroll
511
state->m_vdp.layer_fg_scroll_y = data;
513
case 0x14: /* LCD control
517
state->m_vdp.lcd_enable = data & 0x1;
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
528
state->m_vdp.icons = data; /* ummmmm */
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
534
if ( state->m_system_type == TYPE_WSC )
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;
543
state->m_vdp.main_palette[0] = data & 0x0F;
544
state->m_vdp.main_palette[1] = ( data & 0xF0 ) >> 4;
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
551
if ( state->m_system_type == TYPE_WSC )
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;
560
state->m_vdp.main_palette[2] = data & 0x0F;
561
state->m_vdp.main_palette[3] = ( data & 0xF0 ) >> 4;
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
568
if ( state->m_system_type == TYPE_WSC )
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;
577
state->m_vdp.main_palette[4] = data & 0x0F;
578
state->m_vdp.main_palette[5] = ( data & 0xF0 ) >> 4;
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
585
if ( state->m_system_type == TYPE_WSC )
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;
594
state->m_vdp.main_palette[6] = data & 0x0F;
595
state->m_vdp.main_palette[7] = ( data & 0xF0 ) >> 4;
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 */
664
case 0x40: /* DMA source address (low)
665
Bit 0-7 - DMA source address bit 0-7
667
case 0x41: /* DMA source address (high)
668
Bit 0-7 - DMA source address bit 8-15
670
case 0x42: /* DMA source bank
671
Bit 0-7 - DMA source bank number
673
case 0x43: /* DMA destination bank
674
Bit 0-7 - DMA destination bank number
676
case 0x44: /* DMA destination address (low)
677
Bit 0-7 - DMA destination address bit 0-7
679
case 0x45: /* DMA destination address (high)
680
Bit 0-7 - DMA destination address bit 8-15
682
case 0x46: /* Size of copied data (low)
683
Bit 0-7 - DMA size bit 0-7
685
case 0x47: /* Size of copied data (high)
686
Bit 0-7 - DMA size bit 8-15
689
case 0x48: /* DMA control
691
Bit 7 - DMA stop/start
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-- )
703
space->write_byte(dst, space->read_byte(src ) );
708
logerror( "DMA src:%X dst:%X length:%d\n", src, dst, length );
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;
719
case 0x4A: /* Sound DMA source address (low)
720
Bit 0-7 - Sound DMA source address bit 0-7
722
state->m_sound_dma.source = ( state->m_sound_dma.source & 0x0FFF00 ) | data;
724
case 0x4B: /* Sound DMA source address (high)
725
Bit 0-7 - Sound DMA source address bit 8-15
727
state->m_sound_dma.source = ( state->m_sound_dma.source & 0x0F00FF ) | ( data << 8 );
729
case 0x4C: /* Sound DMA source memory segment
730
Bit 0-3 - Sound DMA source address segment
733
state->m_sound_dma.source = ( state->m_sound_dma.source & 0xFFFF ) | ( ( data & 0x0F ) << 16 );
735
case 0x4D: /* Unknown */
737
case 0x4E: /* Sound DMA transfer size (low)
738
Bit 0-7 - Sound DMA transfer size bit 0-7
740
state->m_sound_dma.size = ( state->m_sound_dma.size & 0xFF00 ) | data;
742
case 0x4F: /* Sound DMA transfer size (high)
743
Bit 0-7 - Sound DMA transfer size bit 8-15
745
state->m_sound_dma.size = ( state->m_sound_dma.size & 0xFF ) | ( data << 8 );
747
case 0x50: /* Unknown */
748
case 0x51: /* Unknown */
750
case 0x52: /* Sound DMA start/stop
752
Bit 7 - Sound DMA stop/start
754
state->m_sound_dma.enable = data;
756
case 0x60: /* Video mode
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
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
772
if ( state->m_system_type == TYPE_WSC )
774
state->m_vdp.color_mode = data & 0x80;
775
state->m_vdp.colors_16 = data & 0x40;
776
state->m_vdp.tile_packed = data & 0x20;
779
case 0x80: /* Audio 1 freq (lo)
780
Bit 0-7 - Audio channel 1 frequency bit 0-7
782
case 0x81: /* Audio 1 freq (hi)
783
Bit 0-7 - Audio channel 1 frequency bit 8-15
785
case 0x82: /* Audio 2 freq (lo)
786
Bit 0-7 - Audio channel 2 frequency bit 0-7
788
case 0x83: /* Audio 2 freq (hi)
789
Bit 0-7 - Audio channel 2 frequency bit 8-15
791
case 0x84: /* Audio 3 freq (lo)
792
Bit 0-7 - Audio channel 3 frequency bit 0-7
794
case 0x85: /* Audio 3 freq (hi)
795
Bit 0-7 - Audio channel 3 frequency bit 8-15
797
case 0x86: /* Audio 4 freq (lo)
798
Bit 0-7 - Audio channel 4 frequency bit 0-7
800
case 0x87: /* Audio 4 freq (hi)
801
Bit 0-7 - Audio channel 4 frequency bit 8-15
803
case 0x88: /* Audio 1 volume
804
Bit 0-3 - Right volume audio channel 1
805
Bit 4-7 - Left volume audio channel 1
807
case 0x89: /* Audio 2 volume
808
Bit 0-3 - Right volume audio channel 2
809
Bit 4-7 - Left volume audio channel 2
811
case 0x8A: /* Audio 3 volume
812
Bit 0-3 - Right volume audio channel 3
813
Bit 4-7 - Left volume audio channel 3
815
case 0x8B: /* Audio 4 volume
816
Bit 0-3 - Right volume audio channel 4
817
Bit 4-7 - Left volume audio channel 4
819
case 0x8C: /* Sweep step
822
case 0x8D: /* Sweep time
825
case 0x8E: /* Noise control
826
Bit 0-2 - Noise generator type
831
case 0x8F: /* Sample location
832
Bit 0-7 - Sample address location 0 00xxxxxx xx000000
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
840
Bit 5 - Audio 2 voice mode enable
841
Bit 6 - Audio 3 sweep mode enable
842
Bit 7 - Audio 4 noise mode enable
844
case 0x91: /* Audio output
846
Bit 1-2 - Output volume
847
Bit 3 - External stereo
849
Bit 7 - External speaker (Read-only, set by hardware)
851
case 0x92: /* Noise counter shift register (lo)
852
Bit 0-7 - Noise counter shift register bit 0-7
854
case 0x93: /* Noise counter shift register (hi)
855
Bit 0-6 - Noise counter shift register bit 8-14
858
case 0x94: /* Master volume
859
Bit 0-3 - Master volume
862
wswan_sound_port_w( space->machine().device("custom"), offset, data );
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
869
if ( ( data & 0x01 ) && !state->m_bios_disabled )
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 ) ] );
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
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;
887
case 0xa4: /* HBlank timer frequency (low) - reload value
888
Bit 0-7 - HBlank timer reload value bit 0-7
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;
894
case 0xa5: /* HBlank timer frequency (high) - reload value
895
Bit 8-15 - HBlank timer reload value bit 8-15
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;
901
case 0xa6: /* VBlank timer frequency (low) - reload value
902
Bit 0-7 - VBlank timer reload value bit 0-7
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;
908
case 0xa7: /* VBlank timer frequency (high) - reload value
909
Bit 0-7 - VBlank timer reload value bit 8-15
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;
915
case 0xa8: /* HBlank counter (low)
916
Bit 0-7 - HBlank counter bit 0-7
918
case 0xa9: /* HBlank counter (high)
919
Bit 0-7 - HBlank counter bit 8-15
921
case 0xaa: /* VBlank counter (low)
922
Bit 0-7 - VBlank counter bit 0-7
924
case 0xab: /* VBlank counter (high)
925
Bit 0-7 - VBlank counter bit 8-15
929
case 0xb0: /* Interrupt base vector
930
Bit 0-7 - Interrupt base vector
933
case 0xb1: /* Communication byte
934
Bit 0-7 - Communication byte
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
948
case 0xb3: /* serial communication control
949
Bit 0 - Receive complete
951
Bit 2 - Send complete
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
958
state->m_ws_portram[0xb1] = 0xFF;
961
// state->m_ws_portram[0xb1] = 0x00;
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
974
100 - Read START,A,B buttons
980
case 0x10: /* Read Y cursors: Y1 - Y2 - Y3 - Y4 */
981
data = data | input_port_read(space->machine(), "CURSY");
983
case 0x20: /* Read X cursors: X1 - X2 - X3 - X4 */
984
data = data | input_port_read(space->machine(), "CURSX");
986
case 0x40: /* Read buttons: START - A - B */
987
data = data | input_port_read(space->machine(), "BUTTONS");
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
1001
wswan_clear_irq_line( space->machine(), data );
1002
data = state->m_ws_portram[0xB6];
1004
case 0xba: /* Internal EEPROM data (low)
1005
Bit 0-7 - Internal EEPROM data transfer bit 0-7
1007
case 0xbb: /* Internal EEPROM data (high)
1008
Bit 0-7 - Internal EEPROM data transfer bit 8-15
1011
case 0xbc: /* Internal EEPROM address (low)
1012
Bit 0-7 - Internal EEPROM address bit 1-8
1014
case 0xbd: /* Internal EEPROM address (high)
1015
Bit 0 - Internal EEPROM address bit 9(?)
1017
Only 1KByte internal EEPROM??
1020
case 0xbe: /* Internal EEPROM command
1021
Bit 0 - Read complete (read only)
1022
Bit 1 - Write complete (read only)
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];
1036
else if ( data & 0x10 )
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];
1045
logerror( "Unsupported internal EEPROM command: %X\n", data );
1048
case 0xc0: /* ROM bank select for banks 4-15
1049
Bit 0-3 - ROM bank base register for banks 4-15
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 )
1065
memory_set_bankptr( space->machine(), "bank15", state->m_ROMMap[ ( ( ( data & 0x0F ) << 4 ) | 15 ) & ( state->m_ROMBanks - 1 ) ] );
1068
case 0xc1: /* SRAM bank select
1069
Bit 0-7 - SRAM bank to select
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 )
1073
state->m_eeprom.page = &state->m_eeprom.data[ ( data * 64 * 1024 ) & ( state->m_eeprom.size - 1 ) ];
1076
case 0xc2: /* ROM bank select for segment 2 (0x20000 - 0x2ffff)
1077
Bit 0-7 - ROM bank for segment 2
1079
memory_set_bankptr( space->machine(), "bank2", state->m_ROMMap[ data & ( state->m_ROMBanks - 1 ) ]);
1081
case 0xc3: /* ROM bank select for segment 3 (0x30000-0x3ffff)
1082
Bit 0-7 - ROM bank for segment 3
1084
memory_set_bankptr( space->machine(), "bank3", state->m_ROMMap[ data & ( state->m_ROMBanks - 1 ) ]);
1086
case 0xc6: /* EEPROM address lower bits port/EEPROM address and command port
1088
Bit 0-5 - EEPROM address bit 1-6
1090
00 - Extended command address bit 4-5:
1099
Bit 0-7 - EEPROM address bit 1-8
1101
switch( state->m_eeprom.mode )
1104
state->m_eeprom.address = data & 0x3F;
1105
state->m_eeprom.command = data >> 4;
1106
if ( ( state->m_eeprom.command & 0x0C ) != 0x00 )
1108
state->m_eeprom.command = state->m_eeprom.command & 0x0C;
1112
state->m_eeprom.address = ( state->m_eeprom.address & 0xFF00 ) | data;
1115
logerror( "Write EEPROM address/register register C6 for unsupported EEPROM type\n" );
1119
case 0xc7: /* EEPROM higher bits/command bits port
1124
Bit 0-1 - EEPROM address bit 9-10
1126
00 - Extended command address bit 0-1:
1137
switch( state->m_eeprom.mode )
1140
state->m_eeprom.start = data & 0x01;
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 )
1147
state->m_eeprom.command = state->m_eeprom.command & 0x0C;
1149
state->m_eeprom.start = ( data >> 4 ) & 0x01;
1152
logerror( "Write EEPROM address/command register C7 for unsupported EEPROM type\n" );
1156
case 0xc8: /* EEPROM command
1157
Bit 0 - Read complete (read only)
1158
Bit 1 - Write complete (read only)
1165
if ( state->m_eeprom.mode == EEPROM_1K || state->m_eeprom.mode == EEPROM_16K )
1169
logerror( "Unsupported EEPROM command 'Initialize'\n" );
1173
switch( state->m_eeprom.command )
1176
state->m_eeprom.write_enabled = 0;
1180
state->m_eeprom.write_enabled = 1;
1184
logerror( "Unsupported 'Protect' command %X\n", state->m_eeprom.command );
1189
if ( state->m_eeprom.write_enabled )
1191
switch( state->m_eeprom.command )
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];
1199
logerror( "Unsupported 'Write' command %X\n", state->m_eeprom.command );
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 ];
1212
logerror( "EEPROM command for unknown EEPROM type\n" );
1215
case 0xca: /* RTC Command
1216
Bit 0-4 - RTC command
1218
10010 - Write timer settings (alarm)
1219
10011 - Read timer settings (alarm)
1220
10100 - Set time/date
1221
10101 - Get time/date
1223
Bit 7 - Command done (read only)
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;
1239
case 0x12: /* Write Timer Settings (Alarm) */
1240
state->m_rtc.index = 8;
1241
state->m_rtc.setting = state->m_ws_portram[0xcb];
1244
case 0x13: /* Read Timer Settings (Alarm) */
1245
state->m_rtc.index = 8;
1246
state->m_ws_portram[0xcb] = state->m_rtc.setting;
1249
case 0x14: /* Set Time/Date */
1250
state->m_rtc.year = state->m_ws_portram[0xcb];
1251
state->m_rtc.index = 1;
1254
case 0x15: /* Get Time/Date */
1255
state->m_rtc.index = 0;
1257
state->m_ws_portram[0xcb] = state->m_rtc.year;
1260
logerror( "%X: Unknown RTC command (%X) requested\n", cpu_get_pc( &space->device() ), data );
1263
case 0xcb: /* RTC Data */
1264
if ( state->m_ws_portram[0xca] == 0x94 && state->m_rtc.index < 7 )
1266
switch( state->m_rtc.index )
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;
1276
state->m_rtc.index++;
1280
logerror( "Write to unsupported port: %X - %X\n", offset, data );
1284
/* Update the port value */
1285
state->m_ws_portram[offset] = data;
1288
static const char* wswan_determine_sram( wswan_state *state, UINT8 data )
1290
state->m_eeprom.write_enabled = 0;
1291
state->m_eeprom.mode = SRAM_UNKNOWN;
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;
1304
state->m_eeprom.size = wswan_sram_size[ state->m_eeprom.mode ];
1305
return wswan_sram_str[ state->m_eeprom.mode ];
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"
1313
static const char* wswan_determine_romsize( UINT8 data )
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 ];
1324
return wswan_romsize_str[ ROM_UNKNOWN ];
1327
DEVICE_START(wswan_cart)
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;
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;
1348
DEVICE_IMAGE_LOAD(wswan_cart)
1350
wswan_state *state = image.device().machine().driver_data<wswan_state>();
1352
const char *sram_str;
1354
if (image.software_entry() == NULL)
1355
size = image.length();
1357
size = image.get_software_region_length("rom");
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;
1363
for (ii = 0; ii < state->m_ROMBanks; ii++)
1365
if ((state->m_ROMMap[ii] = auto_alloc_array(image.device().machine(), UINT8, 0x10000)))
1367
if (image.software_entry() == NULL)
1369
if (image.fread( state->m_ROMMap[ii], 0x10000) != 0x10000)
1371
logerror("Error while reading loading rom!\n");
1372
return IMAGE_INIT_FAIL;
1376
memcpy(state->m_ROMMap[ii], image.get_software_region("rom") + ii * 0x10000, 0x10000);
1380
logerror("Memory allocation failed reading rom!\n");
1381
return IMAGE_INIT_FAIL;
1385
sram_str = wswan_determine_sram(state, state->m_ROMMap[state->m_ROMBanks - 1][0xfffb]);
1387
state->m_rtc.present = state->m_ROMMap[state->m_ROMBanks - 1][0xfffd] ? 1 : 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++)
1403
for (count = 0; count < 0x10000; count++)
1405
sum += state->m_ROMMap[ii][count];
1408
sum -= state->m_ROMMap[state->m_ROMBanks - 1][0xffff];
1409
sum -= state->m_ROMMap[state->m_ROMBanks - 1][0xfffe];
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);
1414
if (state->m_eeprom.size != 0)
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;
1421
if (image.software_entry() == NULL)
1423
logerror("Image Name: %s\n", image.longname());
1424
logerror("Image Year: %s\n", image.year());
1425
logerror("Image Manufacturer: %s\n", image.manufacturer());
1429
return IMAGE_INIT_PASS;
1432
static TIMER_CALLBACK(wswan_scanline_interrupt)
1434
wswan_state *state = machine.driver_data<wswan_state>();
1435
if( state->m_vdp.current_line < 144 )
1437
wswan_refresh_scanline(machine);
1440
/* Decrement 12kHz (HBlank) counter */
1441
if ( state->m_vdp.timer_hblank_enable && state->m_vdp.timer_hblank_reload != 0 )
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 )
1447
if ( state->m_vdp.timer_hblank_mode )
1449
state->m_vdp.timer_hblank_count = state->m_vdp.timer_hblank_reload;
1453
state->m_vdp.timer_hblank_reload = 0;
1455
logerror( "trigerring hbltmr interrupt\n" );
1456
wswan_set_irq_line( machine, WSWAN_IFLAG_HBLTMR );
1460
/* Handle Sound DMA */
1461
if ( ( state->m_sound_dma.enable & 0x88 ) == 0x80 )
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 )
1470
state->m_sound_dma.enable &= 0x7F;
1474
// state->m_vdp.current_line = (state->m_vdp.current_line + 1) % 159;
1476
if( state->m_vdp.current_line == 144 )
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 )
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 )
1486
if ( state->m_vdp.timer_vblank_mode )
1488
state->m_vdp.timer_vblank_count = state->m_vdp.timer_vblank_reload;
1492
state->m_vdp.timer_vblank_reload = 0;
1494
logerror( "triggering vbltmr interrupt\n" );
1495
wswan_set_irq_line( machine, WSWAN_IFLAG_VBLTMR );
1500
// state->m_vdp.current_line = (state->m_vdp.current_line + 1) % 159;
1502
if ( state->m_vdp.current_line == state->m_vdp.line_compare )
1504
wswan_set_irq_line( machine, WSWAN_IFLAG_LCMP );
1507
state->m_vdp.current_line = (state->m_vdp.current_line + 1) % 159;
1509
if ( state->m_vdp.current_line == 0 )
1511
if ( state->m_vdp.display_vertical != state->m_vdp.new_display_vertical )
1513
state->m_vdp.display_vertical = state->m_vdp.new_display_vertical;
1514
if ( state->m_vdp.display_vertical )
1516
machine.primary_screen->set_visible_area(5*8, 5*8 + WSWAN_Y_PIXELS - 1, 0, WSWAN_X_PIXELS - 1 );
1520
machine.primary_screen->set_visible_area(0, WSWAN_X_PIXELS - 1, 5*8, 5*8 + WSWAN_Y_PIXELS - 1 );