diff options
author | 2014-10-05 11:51:41 +0000 | |
---|---|---|
committer | 2014-10-05 11:51:41 +0000 | |
commit | 66fab3cf5c75cd1eca9e4d1b1df29964c052ada3 (patch) | |
tree | 8e8d5f30a02229312cd04ecf1ed3aaa85c575146 /src/mess/machine/wswan.c | |
parent | 218bf5c577b9fa2bdfb3c786a990ae1582e04af8 (diff) |
(MESS) wswan.c: converted to use slot devices for carts. [Fabio Priuli]
out of whatsnew: another case of on-cart SRAM & EEPROM pointers removed from the main system...
Diffstat (limited to 'src/mess/machine/wswan.c')
-rw-r--r-- | src/mess/machine/wswan.c | 844 |
1 files changed, 177 insertions, 667 deletions
diff --git a/src/mess/machine/wswan.c b/src/mess/machine/wswan.c index 1295dc7e6e6..d8a219e37d1 100644 --- a/src/mess/machine/wswan.c +++ b/src/mess/machine/wswan.c @@ -20,11 +20,6 @@ TODO: #define INTERNAL_EEPROM_SIZE 1024 enum enum_system { TYPE_WSWAN=0, TYPE_WSC }; -enum enum_sram { SRAM_NONE=0, SRAM_64K, SRAM_256K, SRAM_512K, SRAM_1M, SRAM_2M, EEPROM_1K, EEPROM_16K, EEPROM_8K, SRAM_UNKNOWN }; -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" }; -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 }; - - static const UINT8 ws_portram_init[256] = @@ -138,82 +133,12 @@ void wswan_state::wswan_clear_irq_line(int irq) wswan_handle_irqs(); } -TIMER_CALLBACK_MEMBER(wswan_state::wswan_rtc_callback) -{ - /* A second passed */ - m_rtc.second = m_rtc.second + 1; - if ( ( m_rtc.second & 0x0F ) > 9 ) - { - m_rtc.second = ( m_rtc.second & 0xF0 ) + 0x10; - } - - /* Check for minute passed */ - if ( m_rtc.second >= 0x60 ) - { - m_rtc.second = 0; - m_rtc.minute = m_rtc.minute + 1; - if ( ( m_rtc.minute & 0x0F ) > 9 ) - { - m_rtc.minute = ( m_rtc.minute & 0xF0 ) + 0x10; - } - } - - /* Check for hour passed */ - if ( m_rtc.minute >= 0x60 ) - { - m_rtc.minute = 0; - m_rtc.hour = m_rtc.hour + 1; - if ( ( m_rtc.hour & 0x0F ) > 9 ) - { - m_rtc.hour = ( m_rtc.hour & 0xF0 ) + 0x10; - } - if ( m_rtc.hour == 0x12 ) - { - m_rtc.hour |= 0x80; - } - } - - /* Check for day passed */ - if ( m_rtc.hour >= 0x24 ) - { - m_rtc.hour = 0; - m_rtc.day = m_rtc.day + 1; - } -} - -void wswan_state::wswan_machine_stop() -{ - device_image_interface *image = dynamic_cast<device_image_interface *>(machine().device("cart")); - if ( m_eeprom.size ) - { - image->battery_save(m_eeprom.data, m_eeprom.size ); - } -} - -void wswan_state::wswan_setup_bios() -{ - if ( m_ws_bios_bank == NULL ) - { - m_ws_bios_bank = auto_alloc_array(machine(), UINT8, 0x10000 ); - memcpy( m_ws_bios_bank + 0xffc0, ws_fake_bios_code, 0x40 ); - } -} - -void wswan_state::wswan_setup_banks() -{ - static const char *rom_bank_tags[14] = { "rom1", "rom2", "rom3", "rom4", "rom5", "rom6", "rom7", - "rom8", "rom9", "rom10", "rom11", "rom12", "rom13", "rom14" }; - for (int i = 0; i < 14; i++) - m_rom_bank[i] = membank(rom_bank_tags[i]); -} - void wswan_state::wswan_register_save() { save_item(NAME(m_ws_portram)); save_item(NAME(m_internal_eeprom)); save_item(NAME(m_bios_disabled)); save_item(NAME(m_rotate)); - save_item(NAME(m_bank_base)); save_item(NAME(m_vdp.layer_bg_enable)); save_item(NAME(m_vdp.layer_fg_enable)); @@ -254,30 +179,13 @@ void wswan_state::wswan_register_save() save_item(NAME(m_vdp.timer_vblank_count)); save_item(NAME(m_vdp.main_palette)); - save_item(NAME(m_eeprom.mode)); - save_item(NAME(m_eeprom.address)); - save_item(NAME(m_eeprom.command)); - save_item(NAME(m_eeprom.start)); - save_item(NAME(m_eeprom.write_enabled)); - save_item(NAME(m_eeprom.size)); - if (m_eeprom.size) - save_pointer(NAME(m_eeprom.data), m_eeprom.size); - - save_item(NAME(m_rtc.present)); - save_item(NAME(m_rtc.setting)); - save_item(NAME(m_rtc.year)); - save_item(NAME(m_rtc.month)); - save_item(NAME(m_rtc.day)); - save_item(NAME(m_rtc.day_of_week)); - save_item(NAME(m_rtc.hour)); - save_item(NAME(m_rtc.minute)); - save_item(NAME(m_rtc.second)); - save_item(NAME(m_rtc.index)); - save_item(NAME(m_sound_dma.source)); save_item(NAME(m_sound_dma.size)); save_item(NAME(m_sound_dma.enable)); + if (m_cart->exists()) + m_cart->save_nvram(); + machine().save().register_postload(save_prepost_delegate(FUNC(wswan_state::wswan_postload), this)); } @@ -286,55 +194,63 @@ void wswan_state::wswan_postload() address_space &space = m_maincpu->space(AS_PROGRAM); // restore the vdp pointers m_vdp.vram = (UINT8*)space.get_read_ptr(0); - m_vdp.palette_vram = (UINT8*)space.get_read_ptr(( m_system_type == TYPE_WSC ) ? 0xFE00 : 0 ); - // restore banks - for (int i = 0; i < 14; i++) - m_rom_bank[i]->set_entry(m_bank_base[i]); + m_vdp.palette_vram = (UINT8*)space.get_read_ptr((m_system_type == TYPE_WSC) ? 0xfe00 : 0); } +void wswan_state::common_start() +{ + m_ws_bios_bank = auto_alloc_array(machine(), UINT8, 0x10000); + memcpy(m_ws_bios_bank + 0xffc0, ws_fake_bios_code, 0x40); + + m_vdp.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(wswan_state::wswan_scanline_interrupt),this), &m_vdp); + m_vdp.timer->adjust(attotime::from_ticks(256, 3072000), 0, attotime::from_ticks(256, 3072000)); + + wswan_register_save(); + + machine().device<nvram_device>("nvram")->set_base(m_internal_eeprom, INTERNAL_EEPROM_SIZE); + + if (m_cart->exists()) + { + // ROM + m_maincpu->space(AS_PROGRAM).install_read_handler(0x20000, 0x2ffff, read8_delegate(FUNC(ws_cart_slot_device::read_rom20),(ws_cart_slot_device*)m_cart)); + m_maincpu->space(AS_PROGRAM).install_read_handler(0x30000, 0x3ffff, read8_delegate(FUNC(ws_cart_slot_device::read_rom30),(ws_cart_slot_device*)m_cart)); + m_maincpu->space(AS_PROGRAM).install_read_handler(0x40000, 0xeffff, read8_delegate(FUNC(ws_cart_slot_device::read_rom40),(ws_cart_slot_device*)m_cart)); + + // SRAM + if (m_cart->get_type() == WS_SRAM) + { + m_maincpu->space(AS_PROGRAM).install_read_handler(0x10000, 0x1ffff, read8_delegate(FUNC(ws_cart_slot_device::read_ram),(ws_cart_slot_device*)m_cart)); + m_maincpu->space(AS_PROGRAM).install_write_handler(0x10000, 0x1ffff, write8_delegate(FUNC(ws_cart_slot_device::write_ram),(ws_cart_slot_device*)m_cart)); + } + } +} void wswan_state::machine_start() { - m_ws_bios_bank = NULL; + common_start(); m_system_type = TYPE_WSWAN; - machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(wswan_state::wswan_machine_stop),this)); - m_vdp.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(wswan_state::wswan_scanline_interrupt),this), &m_vdp ); - m_vdp.timer->adjust( attotime::from_ticks( 256, 3072000 ), 0, attotime::from_ticks( 256, 3072000 ) ); - - wswan_setup_bios(); - wswan_setup_banks(); - wswan_register_save(); - - /* Set up RTC timer */ - if (m_rtc.present) - machine().scheduler().timer_pulse(attotime::from_seconds(1), timer_expired_delegate(FUNC(wswan_state::wswan_rtc_callback),this)); - - machine().device<nvram_device>("nvram")->set_base(m_internal_eeprom, INTERNAL_EEPROM_SIZE); } MACHINE_START_MEMBER(wswan_state,wscolor) { - m_ws_bios_bank = NULL; + common_start(); m_system_type = TYPE_WSC; - machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(wswan_state::wswan_machine_stop),this)); - m_vdp.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(wswan_state::wswan_scanline_interrupt),this), &m_vdp ); - m_vdp.timer->adjust( attotime::from_ticks( 256, 3072000 ), 0, attotime::from_ticks( 256, 3072000 ) ); - - wswan_setup_bios(); - wswan_setup_banks(); - wswan_register_save(); - - /* Set up RTC timer */ - if (m_rtc.present) - machine().scheduler().timer_pulse(attotime::from_seconds(1), timer_expired_delegate(FUNC(wswan_state::wswan_rtc_callback),this)); - - machine().device<nvram_device>("nvram")->set_base(m_internal_eeprom, INTERNAL_EEPROM_SIZE); } void wswan_state::machine_reset() { address_space &space = m_maincpu->space(AS_PROGRAM); + m_bios_disabled = 0; + + m_ws_ram = (UINT8*) m_maincpu->space(AS_PROGRAM).get_read_ptr(0); + memset(m_ws_ram, 0, 0xffff); + + if (m_cart->exists()) + m_rotate = m_cart->get_is_rotated(); + else + m_rotate = 0; + /* Intialize ports */ memcpy(m_ws_portram, ws_portram_init, 256); @@ -353,131 +269,94 @@ void wswan_state::machine_reset() /* Initialize sound DMA */ memset(&m_sound_dma, 0, sizeof(m_sound_dma)); - - /* Switch in the banks */ - for (int bank = 0; bank < 14; bank++) - { - for (int i = 0; i < m_ROMBanks; i++) - m_rom_bank[bank]->configure_entries(i, 1, m_ROMMap[i], 0x10000); - } - m_rom_bank[13]->configure_entries(m_ROMBanks, 1, m_ws_bios_bank, 0x10000); - - m_bank_base[0] = (m_ROMBanks - 1) & (m_ROMBanks - 1); - m_bank_base[1] = (m_ROMBanks - 1) & (m_ROMBanks - 1); - m_bank_base[2] = (m_ROMBanks - 12) & (m_ROMBanks - 1); - m_bank_base[3] = (m_ROMBanks - 11) & (m_ROMBanks - 1); - m_bank_base[4] = (m_ROMBanks - 10) & (m_ROMBanks - 1); - m_bank_base[5] = (m_ROMBanks - 9) & (m_ROMBanks - 1); - m_bank_base[6] = (m_ROMBanks - 8) & (m_ROMBanks - 1); - m_bank_base[7] = (m_ROMBanks - 7) & (m_ROMBanks - 1); - m_bank_base[8] = (m_ROMBanks - 6) & (m_ROMBanks - 1); - m_bank_base[9] = (m_ROMBanks - 5) & (m_ROMBanks - 1); - m_bank_base[10] = (m_ROMBanks - 4) & (m_ROMBanks - 1); - m_bank_base[11] = (m_ROMBanks - 3) & (m_ROMBanks - 1); - m_bank_base[12] = (m_ROMBanks - 2) & (m_ROMBanks - 1); - m_bank_base[13] = m_ROMBanks; // the last bank is mapped to bios at start! - - m_bios_disabled = 0; - - for (int i = 0; i < 14; i++) - m_rom_bank[i]->set_entry(m_bank_base[i]); } -READ8_MEMBER( wswan_state::wswan_sram_r ) +READ8_MEMBER( wswan_state::bios_r ) { - if ( m_eeprom.data == NULL ) - { - return 0xFF; - } - return m_eeprom.page[ offset & ( m_eeprom.size - 1 ) ]; -} - -WRITE8_MEMBER( wswan_state::wswan_sram_w ) -{ - if ( m_eeprom.data == NULL ) - { - return; - } - m_eeprom.page[ offset & ( m_eeprom.size - 1 ) ] = data; + if (!m_bios_disabled) + return m_ws_bios_bank[offset]; + else + return m_cart->read_rom40(space, offset + 0xb0000); } -READ8_MEMBER( wswan_state::wswan_port_r ) +READ8_MEMBER( wswan_state::port_r ) { UINT8 value = m_ws_portram[offset]; - if ( offset != 2 ) - logerror( "PC=%X: port read %02X\n", m_maincpu->pc(), offset ); - switch( offset ) + if (offset != 2) + logerror("PC=%X: port read %02X\n", m_maincpu->pc(), offset); + switch (offset) { - case 0x02: /* Current line */ + case 0x02: // Current line value = m_vdp.current_line; break; - case 0x4A: /* Sound DMA source address (low) */ - value = m_sound_dma.source & 0xFF; + case 0x4a: // Sound DMA source address (low) + value = m_sound_dma.source & 0xff; break; - case 0x4B: /* Sound DMA source address (high) */ - value = ( m_sound_dma.source >> 8 ) & 0xFF; + case 0x4b: // Sound DMA source address (high) + value = (m_sound_dma.source >> 8) & 0xff; break; - case 0x4C: /* Sound DMA source memory segment */ - value = ( m_sound_dma.source >> 16 ) & 0xFF; + case 0x4c: // Sound DMA source memory segment + value = (m_sound_dma.source >> 16) & 0xff; break; - case 0x4E: /* Sound DMA transfer size (low) */ - value = m_sound_dma.size & 0xFF; + case 0x4e: // Sound DMA transfer size (low) + value = m_sound_dma.size & 0xff; break; - case 0x4F: /* Sound DMA transfer size (high) */ - value = ( m_sound_dma.size >> 8 ) & 0xFF; + case 0x4f: // Sound DMA transfer size (high) + value = (m_sound_dma.size >> 8) & 0xff; break; - case 0x52: /* Sound DMA start/stop */ + case 0x52: // Sound DMA start/stop value = m_sound_dma.enable; break; - case 0xA0: /* Hardware type */ - /* Bit 0 - Disable/enable Bios */ - /* Bit 1 - Determine mono/color */ - /* Bit 2 - Determine color/crystal */ + case 0xa0: // Hardware type + // Bit 0 - Disable/enable Bios + // Bit 1 - Determine mono/color + // Bit 2 - Determine color/crystal value = value & ~ 0x02; - if ( m_system_type == TYPE_WSC ) - { + if (m_system_type == TYPE_WSC) value |= 2; - } break; - case 0xA8: - value = m_vdp.timer_hblank_count & 0xFF; + case 0xa8: + value = m_vdp.timer_hblank_count & 0xff; break; - case 0xA9: + case 0xa9: value = m_vdp.timer_hblank_count >> 8; break; - case 0xAA: - value = m_vdp.timer_vblank_count & 0xFF; + case 0xaa: + value = m_vdp.timer_vblank_count & 0xff; break; - case 0xAB: + case 0xab: value = m_vdp.timer_vblank_count >> 8; break; - case 0xCB: /* RTC data */ - if ( m_ws_portram[0xca] == 0x95 && ( m_rtc.index < 7 ) ) - { - switch( m_rtc.index ) - { - case 0: value = m_rtc.year; break; - case 1: value = m_rtc.month; break; - case 2: value = m_rtc.day; break; - case 3: value = m_rtc.day_of_week; break; - case 4: value = m_rtc.hour; break; - case 5: value = m_rtc.minute; break; - case 6: value = m_rtc.second; break; - } - m_rtc.index++; - } + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc4: // EEPROM data + case 0xc5: // EEPROM data + case 0xc6: + case 0xc7: + case 0xc8: + case 0xc9: + case 0xca: + case 0xcb: // RTC data + case 0xcc: + case 0xcd: + case 0xce: + case 0xcf: + value = m_cart->read_io(space, offset & 0x0f); + break; } return value; } -WRITE8_MEMBER( wswan_state::wswan_port_w ) +WRITE8_MEMBER( wswan_state::port_w ) { address_space &mem = m_maincpu->space(AS_PROGRAM); UINT8 input; - logerror( "PC=%X: port write %02X <- %02X\n", m_maincpu->pc(), offset, data ); - switch( offset ) + logerror("PC=%X: port write %02X <- %02X\n", m_maincpu->pc(), offset, data); + switch (offset) { case 0x00: /* Display control Bit 0 - Background layer enable @@ -555,32 +434,32 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) */ m_vdp.window_fg_top = data; break; - case 0x0A: /* Right coordinate of foreground window + case 0x0a: /* Right coordinate of foreground window Bit 0-7 - Right coordinate of foreground window area */ m_vdp.window_fg_right = data; break; - case 0x0B: /* Bottom coordinate of foreground window + case 0x0b: /* Bottom coordinate of foreground window Bit 0-7 - Bottom coordinate of foreground window area */ m_vdp.window_fg_bottom = data; break; - case 0x0C: /* Left coordinate of sprite window + case 0x0c: /* Left coordinate of sprite window Bit 0-7 - Left coordinate of sprite window area */ m_vdp.window_sprites_left = data; break; - case 0x0D: /* Top coordinate of sprite window + case 0x0d: /* Top coordinate of sprite window Bit 0-7 - Top coordinate of sprite window area */ m_vdp.window_sprites_top = data; break; - case 0x0E: /* Right coordinate of sprite window + case 0x0e: /* Right coordinate of sprite window Bit 0-7 - Right coordinate of sprite window area */ m_vdp.window_sprites_right = data; break; - case 0x0F: /* Bottom coordinate of sprite window + case 0x0f: /* Bottom coordinate of sprite window Bit 0-7 - Bottom coordiante of sprite window area */ m_vdp.window_sprites_bottom = data; @@ -626,7 +505,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 0-3 - Gray tone setting for main palette index 0 Bit 4-7 - Gray tone setting for main palette index 1 */ - if ( m_system_type == TYPE_WSC ) + if (m_system_type == TYPE_WSC) { int i = 15 - ( data & 0x0F ); int j = 15 - ( ( data & 0xF0 ) >> 4 ); @@ -643,7 +522,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 0-3 - Gray tone setting for main palette index 2 Bit 4-7 - Gray tone setting for main palette index 3 */ - if ( m_system_type == TYPE_WSC ) + if (m_system_type == TYPE_WSC) { int i = 15 - ( data & 0x0F ); int j = 15 - ( ( data & 0xF0 ) >> 4 ); @@ -660,7 +539,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 0-3 - Gray tone setting for main palette index 4 Bit 4-7 - Gray tone setting for main paeltte index 5 */ - if ( m_system_type == TYPE_WSC ) + if (m_system_type == TYPE_WSC) { int i = 15 - ( data & 0x0F ); int j = 15 - ( ( data & 0xF0 ) >> 4 ); @@ -677,7 +556,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 0-3 - Gray tone setting for main palette index 6 Bit 4-7 - Gray tone setting for main palette index 7 */ - if ( m_system_type == TYPE_WSC ) + if (m_system_type == TYPE_WSC) { int i = 15 - ( data & 0x0F ); int j = 15 - ( ( data & 0xF0 ) >> 4 ); @@ -711,17 +590,17 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 4-7 - Palette 4 index 1 */ case 0x29: /* Bit 0-3 - Palette 4 index 2 Bit 4-7 - Palette 4 index 3 */ - case 0x2A: /* Bit 0-3 - Palette 5 index 0 + case 0x2a: /* Bit 0-3 - Palette 5 index 0 Bit 4-7 - Palette 5 index 1 */ - case 0x2B: /* Bit 0-3 - Palette 5 index 2 + case 0x2b: /* Bit 0-3 - Palette 5 index 2 Bit 4-7 - Palette 5 index 3 */ - case 0x2C: /* Bit 0-3 - Palette 6 index 0 + case 0x2c: /* Bit 0-3 - Palette 6 index 0 Bit 4-7 - Palette 6 index 1 */ - case 0x2D: /* Bit 0-3 - Palette 6 index 2 + case 0x2d: /* Bit 0-3 - Palette 6 index 2 Bit 4-7 - Palette 6 index 3 */ - case 0x2E: /* Bit 0-3 - Palette 7 index 0 + case 0x2e: /* Bit 0-3 - Palette 7 index 0 Bit 4-7 - Palette 7 index 1 */ - case 0x2F: /* Bit 0-3 - Palette 7 index 2 + case 0x2f: /* Bit 0-3 - Palette 7 index 2 Bit 4-7 - Palette 7 index 3 */ case 0x30: /* Bit 0-3 - Palette 8 / Sprite Palette 0 index 0 Bit 4-7 - Palette 8 / Sprite Palette 0 index 1 */ @@ -743,17 +622,17 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 4-7 - Palette 12 / Sprite Palette 4 index 1 */ case 0x39: /* Bit 0-3 - Palette 12 / Sprite Palette 4 index 2 Bit 4-7 - Palette 12 / Sprite Palette 4 index 3 */ - case 0x3A: /* Bit 0-3 - Palette 13 / Sprite Palette 5 index 0 + case 0x3a: /* Bit 0-3 - Palette 13 / Sprite Palette 5 index 0 Bit 4-7 - Palette 13 / Sprite Palette 5 index 1 */ - case 0x3B: /* Bit 0-3 - Palette 13 / Sprite Palette 5 index 2 + case 0x3b: /* Bit 0-3 - Palette 13 / Sprite Palette 5 index 2 Bit 4-7 - Palette 13 / Sprite Palette 5 index 3 */ - case 0x3C: /* Bit 0-3 - Palette 14 / Sprite Palette 6 index 0 + case 0x3c: /* Bit 0-3 - Palette 14 / Sprite Palette 6 index 0 Bit 4-7 - Palette 14 / Sprite Palette 6 index 1 */ - case 0x3D: /* Bit 0-3 - Palette 14 / Sprite Palette 6 index 2 + case 0x3d: /* Bit 0-3 - Palette 14 / Sprite Palette 6 index 2 Bit 4-7 - Palette 14 / Sprite Palette 6 index 3 */ - case 0x3E: /* Bit 0-3 - Palette 15 / Sprite Palette 7 index 0 + case 0x3e: /* Bit 0-3 - Palette 15 / Sprite Palette 7 index 0 Bit 4-7 - Palette 15 / Sprite Palette 7 index 1 */ - case 0x3F: /* Bit 0-3 - Palette 15 / Sprite Palette 7 index 2 + case 0x3f: /* Bit 0-3 - Palette 15 / Sprite Palette 7 index 2 Bit 4-7 - Palette 15 / Sprite Palette 7 index 3 */ break; case 0x40: /* DMA source address (low) @@ -785,7 +664,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 0-6 - Unknown Bit 7 - DMA stop/start */ - if( data & 0x80 ) + if (data & 0x80) { UINT32 src, dst; UINT16 length; @@ -793,51 +672,51 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) src = m_ws_portram[0x40] + (m_ws_portram[0x41] << 8) + (m_ws_portram[0x42] << 16); dst = m_ws_portram[0x44] + (m_ws_portram[0x45] << 8) + (m_ws_portram[0x43] << 16); length = m_ws_portram[0x46] + (m_ws_portram[0x47] << 8); - for( ; length > 0; length-- ) + for ( ; length > 0; length--) { - mem.write_byte(dst, mem.read_byte(src ) ); + mem.write_byte(dst, mem.read_byte(src)); src++; dst++; } #ifdef MAME_DEBUG - logerror( "DMA src:%X dst:%X length:%d\n", src, dst, length ); + logerror("DMA src:%X dst:%X length:%d\n", src, dst, length); #endif - m_ws_portram[0x40] = src & 0xFF; - m_ws_portram[0x41] = ( src >> 8 ) & 0xFF; - m_ws_portram[0x44] = dst & 0xFF; - m_ws_portram[0x45] = ( dst >> 8 ) & 0xFF; - m_ws_portram[0x46] = length & 0xFF; - m_ws_portram[0x47] = ( length >> 8 ) & 0xFF; - data &= 0x7F; + m_ws_portram[0x40] = src & 0xff; + m_ws_portram[0x41] = (src >> 8) & 0xff; + m_ws_portram[0x44] = dst & 0xff; + m_ws_portram[0x45] = (dst >> 8) & 0xff; + m_ws_portram[0x46] = length & 0xff; + m_ws_portram[0x47] = (length >> 8) & 0xff; + data &= 0x7f; } break; - case 0x4A: /* Sound DMA source address (low) + case 0x4a: /* Sound DMA source address (low) Bit 0-7 - Sound DMA source address bit 0-7 */ - m_sound_dma.source = ( m_sound_dma.source & 0x0FFF00 ) | data; + m_sound_dma.source = (m_sound_dma.source & 0x0fff00) | data; break; - case 0x4B: /* Sound DMA source address (high) + case 0x4b: /* Sound DMA source address (high) Bit 0-7 - Sound DMA source address bit 8-15 */ - m_sound_dma.source = ( m_sound_dma.source & 0x0F00FF ) | ( data << 8 ); + m_sound_dma.source = (m_sound_dma.source & 0x0f00ff) | (data << 8); break; - case 0x4C: /* Sound DMA source memory segment + case 0x4c: /* Sound DMA source memory segment Bit 0-3 - Sound DMA source address segment Bit 4-7 - Unknown */ - m_sound_dma.source = ( m_sound_dma.source & 0xFFFF ) | ( ( data & 0x0F ) << 16 ); + m_sound_dma.source = (m_sound_dma.source & 0xffff) | ((data & 0x0f) << 16); break; - case 0x4D: /* Unknown */ + case 0x4d: /* Unknown */ break; - case 0x4E: /* Sound DMA transfer size (low) + case 0x4e: /* Sound DMA transfer size (low) Bit 0-7 - Sound DMA transfer size bit 0-7 */ - m_sound_dma.size = ( m_sound_dma.size & 0xFF00 ) | data; + m_sound_dma.size = (m_sound_dma.size & 0xff00) | data; break; - case 0x4F: /* Sound DMA transfer size (high) + case 0x4f: /* Sound DMA transfer size (high) Bit 0-7 - Sound DMA transfer size bit 8-15 */ - m_sound_dma.size = ( m_sound_dma.size & 0xFF ) | ( data << 8 ); + m_sound_dma.size = (m_sound_dma.size & 0xff) | (data << 8); break; case 0x50: /* Unknown */ case 0x51: /* Unknown */ @@ -864,7 +743,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) * 001 - packed, 4 color, use 2000, monochrome * 000 - not packed, 4 color, use 2000, monochrome - Regular WS monochrome */ - if ( m_system_type == TYPE_WSC ) + if (m_system_type == TYPE_WSC) { m_vdp.color_mode = data & 0x80; m_vdp.colors_16 = data & 0x40; @@ -903,27 +782,27 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 0-3 - Right volume audio channel 2 Bit 4-7 - Left volume audio channel 2 */ - case 0x8A: /* Audio 3 volume + case 0x8a: /* Audio 3 volume Bit 0-3 - Right volume audio channel 3 Bit 4-7 - Left volume audio channel 3 */ - case 0x8B: /* Audio 4 volume + case 0x8b: /* Audio 4 volume Bit 0-3 - Right volume audio channel 4 Bit 4-7 - Left volume audio channel 4 */ - case 0x8C: /* Sweep step + case 0x8c: /* Sweep step Bit 0-7 - Sweep step */ - case 0x8D: /* Sweep time + case 0x8d: /* Sweep time Bit 0-7 - Sweep time */ - case 0x8E: /* Noise control + case 0x8e: /* Noise control Bit 0-2 - Noise generator type Bit 3 - Reset Bit 4 - Enable Bit 5-7 - Unknown */ - case 0x8F: /* Sample location + case 0x8f: /* Sample location Bit 0-7 - Sample address location 0 00xxxxxx xx000000 */ case 0x90: /* Audio control @@ -954,7 +833,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 0-3 - Master volume Bit 4-7 - Unknown */ - m_sound->port_w( space, offset, data ); + m_sound->port_w(space, offset, data); break; case 0xa0: /* Hardware type - this is probably read only Bit 0 - Enable cartridge slot and/or disable bios @@ -962,11 +841,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 2-7 - Unknown */ if ((data & 0x01) && !m_bios_disabled) - { m_bios_disabled = 1; - m_bank_base[13] = (((m_ws_portram[0xc0] & 0x0f) << 4) | 15) & (m_ROMBanks - 1); - m_rom_bank[13]->set_entry(m_bank_base[13]); - } break; case 0xa2: /* Timer control Bit 0 - HBlank Timer enable @@ -975,10 +850,10 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 3 - VBlank Timer mode: 0 = one shot, 1 = auto reset Bit 4-7 - Unknown */ - m_vdp.timer_hblank_enable = data & 0x1; - m_vdp.timer_hblank_mode = (data & 0x2) >> 1; - m_vdp.timer_vblank_enable = (data & 0x4) >> 2; - m_vdp.timer_vblank_mode = (data & 0x8) >> 3; + m_vdp.timer_hblank_enable = BIT(data, 0); + m_vdp.timer_hblank_mode = BIT(data, 1); + m_vdp.timer_vblank_enable = BIT(data, 2); + m_vdp.timer_vblank_mode = BIT(data, 3); break; case 0xa4: /* HBlank timer frequency (low) - reload value Bit 0-7 - HBlank timer reload value bit 0-7 @@ -1051,13 +926,13 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) bit 7 - Receive data interrupt generation */ // data |= 0x02; - m_ws_portram[0xb1] = 0xFF; - if ( data & 0x80 ) + m_ws_portram[0xb1] = 0xff; + if (data & 0x80) { // m_ws_portram[0xb1] = 0x00; data |= 0x04; } - if (data & 0x20 ) + if (data & 0x20) { // data |= 0x01; } @@ -1070,8 +945,8 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) 100 - Read START,A,B buttons Bit 7 - Unknown */ - data = data & 0xF0; - switch( data ) + data = data & 0xf0; + switch (data) { case 0x10: /* Read Y cursors: Y1 - Y2 - Y3 - Y4 */ input = m_cursy->read(); @@ -1113,7 +988,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 7 - HBlank timer interrupt acknowledge */ wswan_clear_irq_line(data); - data = m_ws_portram[0xB6]; + data = m_ws_portram[0xb6]; break; case 0xba: /* Internal EEPROM data (low) Bit 0-7 - Internal EEPROM data transfer bit 0-7 @@ -1140,7 +1015,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 6 - Protect Bit 7 - Initialize */ - if ( data & 0x20 ) + if (data & 0x20) { UINT16 addr = ( ( ( m_ws_portram[0xbd] << 8 ) | m_ws_portram[0xbc] ) << 1 ) & 0x1FF; m_internal_eeprom[ addr ] = m_ws_portram[0xba]; @@ -1159,240 +1034,23 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) logerror( "Unsupported internal EEPROM command: %X\n", data ); } break; - case 0xc0: - // Bit 0-3 - ROM bank base register for rom3-rom14 - // Bit 4-7 - Unknown - m_bank_base[2] = (((data & 0x0f) << 4) | 4) & (m_ROMBanks - 1); - m_bank_base[3] = (((data & 0x0f) << 4) | 5) & (m_ROMBanks - 1); - m_bank_base[4] = (((data & 0x0f) << 4) | 6) & (m_ROMBanks - 1); - m_bank_base[5] = (((data & 0x0f) << 4) | 7) & (m_ROMBanks - 1); - m_bank_base[6] = (((data & 0x0f) << 4) | 8) & (m_ROMBanks - 1); - m_bank_base[7] = (((data & 0x0f) << 4) | 9) & (m_ROMBanks - 1); - m_bank_base[8] = (((data & 0x0f) << 4) | 10) & (m_ROMBanks - 1); - m_bank_base[9] = (((data & 0x0f) << 4) | 11) & (m_ROMBanks - 1); - m_bank_base[10] = (((data & 0x0f) << 4) | 12) & (m_ROMBanks - 1); - m_bank_base[11] = (((data & 0x0f) << 4) | 13) & (m_ROMBanks - 1); - m_bank_base[12] = (((data & 0x0f) << 4) | 14) & (m_ROMBanks - 1); - for (int i = 2; i < 13; i++) - m_rom_bank[i]->set_entry(m_bank_base[i]); - - m_bank_base[13] = m_ROMBanks; // the last bank is mapped to bios at start! - if (m_bios_disabled) - { - m_bank_base[13] = (((data & 0x0f) << 4) | 14) & (m_ROMBanks - 1); - m_rom_bank[13]->set_entry(m_bank_base[13]); - } - break; - case 0xc1: /* SRAM bank select - Bit 0-7 - SRAM bank to select - */ - if ( m_eeprom.mode == SRAM_64K || m_eeprom.mode == SRAM_256K || m_eeprom.mode == SRAM_512K || m_eeprom.mode == SRAM_1M || m_eeprom.mode == SRAM_2M ) - { - m_eeprom.page = &m_eeprom.data[ ( data * 64 * 1024 ) & ( m_eeprom.size - 1 ) ]; - } - break; - case 0xc2: - // Bit 0-7 - ROM bank for segment 2 (0x20000 - 0x2ffff) - m_bank_base[0] = data & (m_ROMBanks - 1); - m_rom_bank[0]->set_entry(m_bank_base[0]); - break; - case 0xc3: - // Bit 0-7 - ROM bank for segment 3 (0x30000 - 0x3ffff) - m_bank_base[1] = data & (m_ROMBanks - 1); - m_rom_bank[1]->set_entry(m_bank_base[1]); - break; - case 0xc6: /* EEPROM address lower bits port/EEPROM address and command port - 1KBit EEPROM: - Bit 0-5 - EEPROM address bit 1-6 - Bit 6-7 - Command - 00 - Extended command address bit 4-5: - 00 - Write disable - 01 - Write all - 10 - Erase all - 11 - Write enable - 01 - Write - 10 - Read - 11 - Erase - 16KBit EEPROM: - Bit 0-7 - EEPROM address bit 1-8 - */ - switch( m_eeprom.mode ) - { - case EEPROM_1K: - m_eeprom.address = data & 0x3F; - m_eeprom.command = data >> 4; - if ( ( m_eeprom.command & 0x0C ) != 0x00 ) - { - m_eeprom.command = m_eeprom.command & 0x0C; - } - break; - case EEPROM_16K: - m_eeprom.address = ( m_eeprom.address & 0xFF00 ) | data; - break; - default: - logerror( "Write EEPROM address/register register C6 for unsupported EEPROM type\n" ); - break; - } - break; - case 0xc7: /* EEPROM higher bits/command bits port - 1KBit EEPROM: - Bit 0 - Start - Bit 1-7 - Unknown - 16KBit EEPROM: - Bit 0-1 - EEPROM address bit 9-10 - Bit 2-3 - Command - 00 - Extended command address bit 0-1: - 00 - Write disable - 01 - Write all - 10 - Erase all - 11 - Write enable - 01 - Write - 10 - Read - 11 - Erase - Bit 4 - Start - Bit 5-7 - Unknown - */ - switch( m_eeprom.mode ) - { - case EEPROM_1K: - m_eeprom.start = data & 0x01; - break; - case EEPROM_16K: - m_eeprom.address = ( ( data & 0x03 ) << 8 ) | ( m_eeprom.address & 0xFF ); - m_eeprom.command = data & 0x0F; - if ( ( m_eeprom.command & 0x0C ) != 0x00 ) - { - m_eeprom.command = m_eeprom.command & 0x0C; - } - m_eeprom.start = ( data >> 4 ) & 0x01; - break; - default: - logerror( "Write EEPROM address/command register C7 for unsupported EEPROM type\n" ); - break; - } - break; - case 0xc8: /* EEPROM command - Bit 0 - Read complete (read only) - Bit 1 - Write complete (read only) - Bit 2-3 - Unknown - Bit 4 - Read - Bit 5 - Write - Bit 6 - Protect - Bit 7 - Initialize - */ - if ( m_eeprom.mode == EEPROM_1K || m_eeprom.mode == EEPROM_16K ) - { - if ( data & 0x80 ) - { /* Initialize */ - logerror( "Unsupported EEPROM command 'Initialize'\n" ); - } - if ( data & 0x40 ) - { /* Protect */ - switch( m_eeprom.command ) - { - case 0x00: - m_eeprom.write_enabled = 0; - data |= 0x02; - break; - case 0x03: - m_eeprom.write_enabled = 1; - data |= 0x02; - break; - default: - logerror( "Unsupported 'Protect' command %X\n", m_eeprom.command ); - } - } - if ( data & 0x20 ) - { /* Write */ - if ( m_eeprom.write_enabled ) - { - switch( m_eeprom.command ) - { - case 0x04: - m_eeprom.data[ ( m_eeprom.address << 1 ) + 1 ] = m_ws_portram[0xc4]; - m_eeprom.data[ m_eeprom.address << 1 ] = m_ws_portram[0xc5]; - data |= 0x02; - break; - default: - logerror( "Unsupported 'Write' command %X\n", m_eeprom.command ); - } - } - } - if ( data & 0x10 ) - { /* Read */ - m_ws_portram[0xc4] = m_eeprom.data[ ( m_eeprom.address << 1 ) + 1 ]; - m_ws_portram[0xc5] = m_eeprom.data[ m_eeprom.address << 1 ]; - data |= 0x01; - } - } - else - { - logerror( "EEPROM command for unknown EEPROM type\n" ); - } - break; - case 0xca: /* RTC Command - Bit 0-4 - RTC command - 10000 - Reset - 10010 - Write timer settings (alarm) - 10011 - Read timer settings (alarm) - 10100 - Set time/date - 10101 - Get time/date - Bit 5-6 - Unknown - Bit 7 - Command done (read only) - */ - switch( data ) - { - case 0x10: /* Reset */ - m_rtc.index = 8; - m_rtc.year = 0; - m_rtc.month = 1; - m_rtc.day = 1; - m_rtc.day_of_week = 0; - m_rtc.hour = 0; - m_rtc.minute = 0; - m_rtc.second = 0; - m_rtc.setting = 0xFF; - data |= 0x80; - break; - case 0x12: /* Write Timer Settings (Alarm) */ - m_rtc.index = 8; - m_rtc.setting = m_ws_portram[0xcb]; - data |= 0x80; - break; - case 0x13: /* Read Timer Settings (Alarm) */ - m_rtc.index = 8; - m_ws_portram[0xcb] = m_rtc.setting; - data |= 0x80; - break; - case 0x14: /* Set Time/Date */ - m_rtc.year = m_ws_portram[0xcb]; - m_rtc.index = 1; - data |= 0x80; - break; - case 0x15: /* Get Time/Date */ - m_rtc.index = 0; - data |= 0x80; - m_ws_portram[0xcb] = m_rtc.year; - break; - default: - logerror( "%X: Unknown RTC command (%X) requested\n", mem.device().safe_pc(), data ); - } - break; - case 0xcb: /* RTC Data */ - if ( m_ws_portram[0xca] == 0x94 && m_rtc.index < 7 ) - { - switch( m_rtc.index ) - { - case 0: m_rtc.year = data; break; - case 1: m_rtc.month = data; break; - case 2: m_rtc.day = data; break; - case 3: m_rtc.day_of_week = data; break; - case 4: m_rtc.hour = data; break; - case 5: m_rtc.minute = data; break; - case 6: m_rtc.second = data; break; - } - m_rtc.index++; - } + case 0xc0: // ROM bank $40000-$fffff + case 0xc1: // SRAM bank + case 0xc2: // ROM bank $20000-$2ffff + case 0xc3: // ROM bank $30000-$3ffff + case 0xc4: + case 0xc5: + case 0xc6: // EEPROM address / command + case 0xc7: // EEPROM address / command + case 0xc8: // EEPROM command + case 0xc9: + case 0xca: // RTC command + case 0xcb: // RTC data + case 0xcc: + case 0xcd: + case 0xce: + case 0xcf: + m_cart->write_io(space, offset & 0x0f, data); break; default: logerror( "Write to unsupported port: %X - %X\n", offset, data ); @@ -1403,154 +1061,6 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) m_ws_portram[offset] = data; } -const char* wswan_state::wswan_determine_sram(UINT8 data ) -{ - m_eeprom.write_enabled = 0; - m_eeprom.mode = SRAM_UNKNOWN; - switch( data ) - { - case 0x00: m_eeprom.mode = SRAM_NONE; break; - case 0x01: m_eeprom.mode = SRAM_64K; break; - case 0x02: m_eeprom.mode = SRAM_256K; break; - case 0x03: m_eeprom.mode = SRAM_1M; break; - case 0x04: m_eeprom.mode = SRAM_2M; break; - case 0x05: m_eeprom.mode = SRAM_512K; break; - case 0x10: m_eeprom.mode = EEPROM_1K; break; - case 0x20: m_eeprom.mode = EEPROM_16K; break; - case 0x50: m_eeprom.mode = EEPROM_8K; break; - } - m_eeprom.size = wswan_sram_size[ m_eeprom.mode ]; - return wswan_sram_str[ m_eeprom.mode ]; -} - -enum enum_romsize { ROM_4M=0, ROM_8M, ROM_16M, ROM_32M, ROM_64M, ROM_128M, ROM_UNKNOWN }; -static const char *const wswan_romsize_str[] = { - "4Mbit", "8Mbit", "16Mbit", "32Mbit", "64Mbit", "128Mbit", "Unknown" -}; - -const char* wswan_state::wswan_determine_romsize( UINT8 data ) -{ - switch( data ) - { - case 0x02: return wswan_romsize_str[ ROM_4M ]; - case 0x03: return wswan_romsize_str[ ROM_8M ]; - case 0x04: return wswan_romsize_str[ ROM_16M ]; - case 0x06: return wswan_romsize_str[ ROM_32M ]; - case 0x08: return wswan_romsize_str[ ROM_64M ]; - case 0x09: return wswan_romsize_str[ ROM_128M ]; - } - return wswan_romsize_str[ ROM_UNKNOWN ]; -} - - -DRIVER_INIT_MEMBER(wswan_state, wswan) -{ - /* Initialize EEPROM structure */ - memset( &m_eeprom, 0, sizeof( m_eeprom ) ); - m_eeprom.data = NULL; - m_eeprom.page = NULL; - - /* Initialize RTC structure */ - m_rtc.present = 0; - m_rtc.index = 0; - m_rtc.year = 0; - m_rtc.month = 0; - m_rtc.day = 0; - m_rtc.day_of_week = 0; - m_rtc.hour = 0; - m_rtc.minute = 0; - m_rtc.second = 0; - m_rtc.setting = 0xFF; -} - - -DEVICE_IMAGE_LOAD_MEMBER(wswan_state,wswan_cart) -{ - UINT32 size; - const char *sram_str; - - if (image.software_entry() == NULL) - size = image.length(); - else - size = image.get_software_region_length("rom"); - - m_ws_ram = (UINT8*) m_maincpu->space(AS_PROGRAM).get_read_ptr(0); - memset(m_ws_ram, 0, 0xffff); - m_ROMBanks = size / 65536; - - for (int i = 0; i < m_ROMBanks; i++) - { - if ((m_ROMMap[i] = auto_alloc_array(machine(), UINT8, 0x10000))) - { - if (image.software_entry() == NULL) - { - if (image.fread( m_ROMMap[i], 0x10000) != 0x10000) - { - image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Wrongly sized ROM"); - image.message(" Wrongly sized ROM"); - logerror("Error while reading loading rom!\n"); - return IMAGE_INIT_FAIL; - } - } - else - memcpy(m_ROMMap[i], image.get_software_region("rom") + i * 0x10000, 0x10000); - } - else - { - image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Unable to allocate memory for ROM"); - image.message(" Unable to allocate memory for ROM"); - logerror("Memory allocation failed reading rom!\n"); - return IMAGE_INIT_FAIL; - } - } - - sram_str = wswan_determine_sram(m_ROMMap[m_ROMBanks - 1][0xfffb]); - - m_rtc.present = m_ROMMap[m_ROMBanks - 1][0xfffd] ? 1 : 0; - m_rotate = m_ROMMap[m_ROMBanks-1][0xfffc] & 0x01; - - { - int sum = 0; - /* Spit out some info */ - logerror("ROM DETAILS\n" ); - logerror("\tDeveloper ID: %X\n", m_ROMMap[m_ROMBanks - 1][0xfff6]); - logerror("\tMinimum system: %s\n", m_ROMMap[m_ROMBanks - 1][0xfff7] ? "WonderSwan Color" : "WonderSwan"); - logerror("\tCart ID: %X\n", m_ROMMap[m_ROMBanks - 1][0xfff8]); - logerror("\tROM size: %s\n", wswan_determine_romsize(m_ROMMap[m_ROMBanks - 1][0xfffa])); - logerror("\tSRAM size: %s\n", sram_str); - logerror("\tFeatures: %X\n", m_ROMMap[m_ROMBanks - 1][0xfffc]); - logerror("\tRTC: %s\n", m_ROMMap[m_ROMBanks - 1][0xfffd] ? "yes" : "no"); - for (int i = 0; i < m_ROMBanks; i++) - { - int count; - for (count = 0; count < 0x10000; count++) - { - sum += m_ROMMap[i][count]; - } - } - sum -= m_ROMMap[m_ROMBanks - 1][0xffff]; - sum -= m_ROMMap[m_ROMBanks - 1][0xfffe]; - sum &= 0xffff; - logerror("\tChecksum: %X%X (calculated: %04X)\n", m_ROMMap[m_ROMBanks - 1][0xffff], m_ROMMap[m_ROMBanks - 1][0xfffe], sum); - } - - if (m_eeprom.size != 0) - { - m_eeprom.data = auto_alloc_array(machine(), UINT8, m_eeprom.size); - image.battery_load(m_eeprom.data, m_eeprom.size, 0x00); - m_eeprom.page = m_eeprom.data; - } - - if (image.software_entry() == NULL) - { - logerror("Image Name: %s\n", image.longname()); - logerror("Image Year: %s\n", image.year()); - logerror("Image Manufacturer: %s\n", image.manufacturer()); - } - - /* All done */ - return IMAGE_INIT_PASS; -} TIMER_CALLBACK_MEMBER(wswan_state::wswan_scanline_interrupt) { @@ -1584,7 +1094,7 @@ TIMER_CALLBACK_MEMBER(wswan_state::wswan_scanline_interrupt) { address_space &space = m_maincpu->space(AS_PROGRAM ); /* TODO: Output sound DMA byte */ - wswan_port_w( space, 0x89, space.read_byte(m_sound_dma.source ) ); + port_w( space, 0x89, space.read_byte(m_sound_dma.source ) ); m_sound_dma.size--; m_sound_dma.source = ( m_sound_dma.source + 1 ) & 0x0FFFFF; if ( m_sound_dma.size == 0 ) |