trunk/src/mess/machine/wswan.c
| r20448 | r20449 | |
| 83 | 83 | 0xea, 0xc0, 0xff, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| 84 | 84 | }; |
| 85 | 85 | |
| 86 | | static void wswan_handle_irqs( running_machine &machine ) |
| 86 | void wswan_state::wswan_handle_irqs() |
| 87 | 87 | { |
| 88 | | wswan_state *state = machine.driver_data<wswan_state>(); |
| 89 | | if ( state->m_ws_portram[0xb2] & state->m_ws_portram[0xb6] & WSWAN_IFLAG_HBLTMR ) { |
| 90 | | machine.device("maincpu")->execute().set_input_line_and_vector(0, HOLD_LINE, state->m_ws_portram[0xb0] + WSWAN_INT_HBLTMR ); |
| 91 | | } else if ( state->m_ws_portram[0xb2] & state->m_ws_portram[0xb6] & WSWAN_IFLAG_VBL ) { |
| 92 | | machine.device("maincpu")->execute().set_input_line_and_vector(0, HOLD_LINE, state->m_ws_portram[0xb0] + WSWAN_INT_VBL ); |
| 93 | | } else if ( state->m_ws_portram[0xb2] & state->m_ws_portram[0xb6] & WSWAN_IFLAG_VBLTMR ) { |
| 94 | | machine.device("maincpu")->execute().set_input_line_and_vector(0, HOLD_LINE, state->m_ws_portram[0xb0] + WSWAN_INT_VBLTMR ); |
| 95 | | } else if ( state->m_ws_portram[0xb2] & state->m_ws_portram[0xb6] & WSWAN_IFLAG_LCMP ) { |
| 96 | | machine.device("maincpu")->execute().set_input_line_and_vector(0, HOLD_LINE, state->m_ws_portram[0xb0] + WSWAN_INT_LCMP ); |
| 97 | | } else if ( state->m_ws_portram[0xb2] & state->m_ws_portram[0xb6] & WSWAN_IFLAG_SRX ) { |
| 98 | | machine.device("maincpu")->execute().set_input_line_and_vector(0, HOLD_LINE, state->m_ws_portram[0xb0] + WSWAN_INT_SRX ); |
| 99 | | } else if ( state->m_ws_portram[0xb2] & state->m_ws_portram[0xb6] & WSWAN_IFLAG_RTC ) { |
| 100 | | machine.device("maincpu")->execute().set_input_line_and_vector(0, HOLD_LINE, state->m_ws_portram[0xb0] + WSWAN_INT_RTC ); |
| 101 | | } else if ( state->m_ws_portram[0xb2] & state->m_ws_portram[0xb6] & WSWAN_IFLAG_KEY ) { |
| 102 | | machine.device("maincpu")->execute().set_input_line_and_vector(0, HOLD_LINE, state->m_ws_portram[0xb0] + WSWAN_INT_KEY ); |
| 103 | | } else if ( state->m_ws_portram[0xb2] & state->m_ws_portram[0xb6] & WSWAN_IFLAG_STX ) { |
| 104 | | machine.device("maincpu")->execute().set_input_line_and_vector(0, HOLD_LINE, state->m_ws_portram[0xb0] + WSWAN_INT_STX ); |
| 105 | | } else { |
| 106 | | machine.device("maincpu")->execute().set_input_line(0, CLEAR_LINE ); |
| 88 | if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_HBLTMR ) |
| 89 | { |
| 90 | m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_HBLTMR ); |
| 107 | 91 | } |
| 92 | else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_VBL ) |
| 93 | { |
| 94 | m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_VBL ); |
| 95 | } |
| 96 | else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_VBLTMR ) |
| 97 | { |
| 98 | m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_VBLTMR ); |
| 99 | } |
| 100 | else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_LCMP ) |
| 101 | { |
| 102 | m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_LCMP ); |
| 103 | } |
| 104 | else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_SRX ) |
| 105 | { |
| 106 | m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_SRX ); |
| 107 | } |
| 108 | else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_RTC ) |
| 109 | { |
| 110 | m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_RTC ); |
| 111 | } |
| 112 | else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_KEY ) |
| 113 | { |
| 114 | m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_KEY ); |
| 115 | } |
| 116 | else if ( m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_STX ) |
| 117 | { |
| 118 | m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_STX ); |
| 119 | } |
| 120 | else |
| 121 | { |
| 122 | m_maincpu->set_input_line(0, CLEAR_LINE ); |
| 123 | } |
| 108 | 124 | } |
| 109 | 125 | |
| 110 | | static void wswan_set_irq_line( running_machine &machine, int irq) |
| 126 | void wswan_state::wswan_set_irq_line(int irq) |
| 111 | 127 | { |
| 112 | | wswan_state *state = machine.driver_data<wswan_state>(); |
| 113 | | if ( state->m_ws_portram[0xb2] & irq ) |
| 128 | if ( m_ws_portram[0xb2] & irq ) |
| 114 | 129 | { |
| 115 | | state->m_ws_portram[0xb6] |= irq; |
| 116 | | wswan_handle_irqs( machine ); |
| 130 | m_ws_portram[0xb6] |= irq; |
| 131 | wswan_handle_irqs(); |
| 117 | 132 | } |
| 118 | 133 | } |
| 119 | 134 | |
| 120 | 135 | void wswan_state::wswan_clear_irq_line(int irq) |
| 121 | 136 | { |
| 122 | 137 | m_ws_portram[0xb6] &= ~irq; |
| 123 | | wswan_handle_irqs( machine() ); |
| 138 | wswan_handle_irqs(); |
| 124 | 139 | } |
| 125 | 140 | |
| 126 | 141 | TIMER_CALLBACK_MEMBER(wswan_state::wswan_rtc_callback) |
| r20448 | r20449 | |
| 176 | 191 | } |
| 177 | 192 | } |
| 178 | 193 | |
| 179 | | static void wswan_setup_bios( running_machine &machine ) |
| 194 | void wswan_state::wswan_setup_bios() |
| 180 | 195 | { |
| 181 | | wswan_state *state = machine.driver_data<wswan_state>(); |
| 182 | | if ( state->m_ws_bios_bank == NULL ) |
| 196 | if ( m_ws_bios_bank == NULL ) |
| 183 | 197 | { |
| 184 | | state->m_ws_bios_bank = auto_alloc_array(machine, UINT8, 0x10000 ); |
| 185 | | memcpy( state->m_ws_bios_bank + 0xffc0, ws_fake_bios_code, 0x40 ); |
| 198 | m_ws_bios_bank = auto_alloc_array(machine(), UINT8, 0x10000 ); |
| 199 | memcpy( m_ws_bios_bank + 0xffc0, ws_fake_bios_code, 0x40 ); |
| 186 | 200 | } |
| 187 | 201 | } |
| 188 | 202 | |
| r20448 | r20449 | |
| 194 | 208 | m_vdp.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(wswan_state::wswan_scanline_interrupt),this), &m_vdp ); |
| 195 | 209 | m_vdp.timer->adjust( attotime::from_ticks( 256, 3072000 ), 0, attotime::from_ticks( 256, 3072000 ) ); |
| 196 | 210 | |
| 197 | | wswan_setup_bios(machine()); |
| 211 | wswan_setup_bios(); |
| 198 | 212 | |
| 199 | 213 | /* Set up RTC timer */ |
| 200 | 214 | if ( m_rtc.present ) |
| r20448 | r20449 | |
| 211 | 225 | m_vdp.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(wswan_state::wswan_scanline_interrupt),this), &m_vdp ); |
| 212 | 226 | m_vdp.timer->adjust( attotime::from_ticks( 256, 3072000 ), 0, attotime::from_ticks( 256, 3072000 ) ); |
| 213 | 227 | |
| 214 | | wswan_setup_bios(machine()); |
| 228 | wswan_setup_bios(); |
| 215 | 229 | |
| 216 | 230 | /* Set up RTC timer */ |
| 217 | 231 | if ( m_rtc.present ) |
| r20448 | r20449 | |
| 222 | 236 | |
| 223 | 237 | void wswan_state::machine_reset() |
| 224 | 238 | { |
| 225 | | address_space &space = machine().device( "maincpu")->memory().space( AS_PROGRAM ); |
| 239 | address_space &space = m_maincpu->space( AS_PROGRAM ); |
| 226 | 240 | |
| 227 | 241 | /* Intialize ports */ |
| 228 | 242 | memcpy( m_ws_portram, ws_portram_init, 256 ); |
| r20448 | r20449 | |
| 285 | 299 | UINT8 value = m_ws_portram[offset]; |
| 286 | 300 | |
| 287 | 301 | if ( offset != 2 ) |
| 288 | | logerror( "PC=%X: port read %02X\n", machine().device("maincpu") ->safe_pc( ), offset ); |
| 302 | logerror( "PC=%X: port read %02X\n", m_maincpu->pc(), offset ); |
| 289 | 303 | switch( offset ) |
| 290 | 304 | { |
| 291 | 305 | case 0x02: /* Current line */ |
| r20448 | r20449 | |
| 354 | 368 | WRITE8_MEMBER( wswan_state::wswan_port_w ) |
| 355 | 369 | { |
| 356 | 370 | address_space &mem = m_maincpu->space(AS_PROGRAM); |
| 357 | | wswan_state *state = machine().driver_data<wswan_state>(); |
| 358 | 371 | UINT8 input; |
| 359 | | logerror( "PC=%X: port write %02X <- %02X\n", mem.device().safe_pc(), offset, data ); |
| 372 | logerror( "PC=%X: port write %02X <- %02X\n", m_maincpu->pc(), offset, data ); |
| 360 | 373 | switch( offset ) |
| 361 | 374 | { |
| 362 | 375 | case 0x00: /* Display control |
| r20448 | r20449 | |
| 953 | 966 | switch( data ) |
| 954 | 967 | { |
| 955 | 968 | case 0x10: /* Read Y cursors: Y1 - Y2 - Y3 - Y4 */ |
| 956 | | input = ioport("CURSY")->read(); |
| 957 | | if (state->m_rotate) // reorient controls if the console is rotated |
| 969 | input = m_cursy->read(); |
| 970 | if (m_rotate) // reorient controls if the console is rotated |
| 958 | 971 | { |
| 959 | 972 | if (input & 0x01) data |= 0x02; |
| 960 | 973 | if (input & 0x02) data |= 0x04; |
| r20448 | r20449 | |
| 965 | 978 | data = data | input; |
| 966 | 979 | break; |
| 967 | 980 | case 0x20: /* Read X cursors: X1 - X2 - X3 - X4 */ |
| 968 | | input = ioport("CURSX")->read(); |
| 969 | | if (state->m_rotate) // reorient controls if the console is rotated |
| 981 | input = m_cursx->read(); |
| 982 | if (m_rotate) // reorient controls if the console is rotated |
| 970 | 983 | { |
| 971 | 984 | if (input & 0x01) data |= 0x02; |
| 972 | 985 | if (input & 0x02) data |= 0x04; |
| r20448 | r20449 | |
| 977 | 990 | data = data | input; |
| 978 | 991 | break; |
| 979 | 992 | case 0x40: /* Read buttons: START - A - B */ |
| 980 | | data = data | ioport("BUTTONS")->read(); |
| 993 | data = data | m_buttons->read(); |
| 981 | 994 | break; |
| 982 | 995 | } |
| 983 | 996 | break; |
| r20448 | r20449 | |
| 1349 | 1362 | else |
| 1350 | 1363 | size = image.get_software_region_length("rom"); |
| 1351 | 1364 | |
| 1352 | | state->m_ws_ram = (UINT8*) image.device().machine().device("maincpu")->memory().space(AS_PROGRAM).get_read_ptr(0); |
| 1365 | state->m_ws_ram = (UINT8*) state->m_maincpu->space(AS_PROGRAM).get_read_ptr(0); |
| 1353 | 1366 | memset(state->m_ws_ram, 0, 0xffff); |
| 1354 | 1367 | state->m_ROMBanks = size / 65536; |
| 1355 | 1368 | |
| r20448 | r20449 | |
| 1450 | 1463 | m_vdp.timer_hblank_reload = 0; |
| 1451 | 1464 | } |
| 1452 | 1465 | logerror( "trigerring hbltmr interrupt\n" ); |
| 1453 | | wswan_set_irq_line( machine(), WSWAN_IFLAG_HBLTMR ); |
| 1466 | wswan_set_irq_line( WSWAN_IFLAG_HBLTMR ); |
| 1454 | 1467 | } |
| 1455 | 1468 | } |
| 1456 | 1469 | |
| 1457 | 1470 | /* Handle Sound DMA */ |
| 1458 | 1471 | if ( ( m_sound_dma.enable & 0x88 ) == 0x80 ) |
| 1459 | 1472 | { |
| 1460 | | address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM ); |
| 1473 | address_space &space = m_maincpu->space(AS_PROGRAM ); |
| 1461 | 1474 | /* TODO: Output sound DMA byte */ |
| 1462 | 1475 | wswan_port_w( space, 0x89, space.read_byte(m_sound_dma.source ) ); |
| 1463 | 1476 | m_sound_dma.size--; |
| r20448 | r20449 | |
| 1479 | 1492 | |
| 1480 | 1493 | if( m_vdp.current_line == 144 ) |
| 1481 | 1494 | { |
| 1482 | | wswan_set_irq_line( machine(), WSWAN_IFLAG_VBL ); |
| 1495 | wswan_set_irq_line( WSWAN_IFLAG_VBL ); |
| 1483 | 1496 | /* Decrement 75Hz (VBlank) counter */ |
| 1484 | 1497 | if ( m_vdp.timer_vblank_enable && m_vdp.timer_vblank_reload != 0 ) |
| 1485 | 1498 | { |
| r20448 | r20449 | |
| 1496 | 1509 | m_vdp.timer_vblank_reload = 0; |
| 1497 | 1510 | } |
| 1498 | 1511 | logerror( "triggering vbltmr interrupt\n" ); |
| 1499 | | wswan_set_irq_line( machine(), WSWAN_IFLAG_VBLTMR ); |
| 1512 | wswan_set_irq_line( WSWAN_IFLAG_VBLTMR ); |
| 1500 | 1513 | } |
| 1501 | 1514 | } |
| 1502 | 1515 | } |
| r20448 | r20449 | |
| 1505 | 1518 | |
| 1506 | 1519 | if ( m_vdp.current_line == m_vdp.line_compare ) |
| 1507 | 1520 | { |
| 1508 | | wswan_set_irq_line( machine(), WSWAN_IFLAG_LCMP ); |
| 1521 | wswan_set_irq_line( WSWAN_IFLAG_LCMP ); |
| 1509 | 1522 | } |
| 1510 | 1523 | |
| 1511 | 1524 | m_vdp.current_line = (m_vdp.current_line + 1) % 159; |
trunk/src/mess/includes/wswan.h
| r20448 | r20449 | |
| 13 | 13 | #define WSWAN_X_PIXELS (28*8) |
| 14 | 14 | #define WSWAN_Y_PIXELS (18*8) |
| 15 | 15 | |
| 16 | | /* Interrupt flags */ |
| 17 | | #define WSWAN_IFLAG_STX 0x1 |
| 18 | | #define WSWAN_IFLAG_KEY 0x2 |
| 19 | | #define WSWAN_IFLAG_RTC 0x4 |
| 20 | | #define WSWAN_IFLAG_SRX 0x8 |
| 21 | | #define WSWAN_IFLAG_LCMP 0x10 |
| 22 | | #define WSWAN_IFLAG_VBLTMR 0x20 |
| 23 | | #define WSWAN_IFLAG_VBL 0x40 |
| 24 | | #define WSWAN_IFLAG_HBLTMR 0x80 |
| 25 | | /* Interrupts */ |
| 26 | | #define WSWAN_INT_STX 0 |
| 27 | | #define WSWAN_INT_KEY 1 |
| 28 | | #define WSWAN_INT_RTC 2 |
| 29 | | #define WSWAN_INT_SRX 3 |
| 30 | | #define WSWAN_INT_LCMP 4 |
| 31 | | #define WSWAN_INT_VBLTMR 5 |
| 32 | | #define WSWAN_INT_VBL 6 |
| 33 | | #define WSWAN_INT_HBLTMR 7 |
| 34 | | |
| 35 | 16 | #define INTERNAL_EEPROM_SIZE 1024 |
| 36 | 17 | |
| 37 | 18 | #include "emu.h" |
| r20448 | r20449 | |
| 123 | 104 | { |
| 124 | 105 | public: |
| 125 | 106 | wswan_state(const machine_config &mconfig, device_type type, const char *tag) |
| 126 | | : driver_device(mconfig, type, tag), |
| 127 | | m_maincpu(*this, "maincpu") |
| 107 | : driver_device(mconfig, type, tag) |
| 108 | , m_maincpu(*this, "maincpu") |
| 109 | , m_cursx(*this, "CURSX") |
| 110 | , m_cursy(*this, "CURSY") |
| 111 | , m_buttons(*this, "BUTTONS") |
| 128 | 112 | { } |
| 129 | 113 | |
| 130 | 114 | virtual void video_start(); |
| r20448 | r20449 | |
| 159 | 143 | DECLARE_PALETTE_INIT(wscolor); |
| 160 | 144 | TIMER_CALLBACK_MEMBER(wswan_rtc_callback); |
| 161 | 145 | TIMER_CALLBACK_MEMBER(wswan_scanline_interrupt); |
| 146 | |
| 147 | protected: |
| 148 | /* Interrupt flags */ |
| 149 | static const UINT8 WSWAN_IFLAG_STX = 0x01; |
| 150 | static const UINT8 WSWAN_IFLAG_KEY = 0x02; |
| 151 | static const UINT8 WSWAN_IFLAG_RTC = 0x04; |
| 152 | static const UINT8 WSWAN_IFLAG_SRX = 0x08; |
| 153 | static const UINT8 WSWAN_IFLAG_LCMP = 0x10; |
| 154 | static const UINT8 WSWAN_IFLAG_VBLTMR = 0x20; |
| 155 | static const UINT8 WSWAN_IFLAG_VBL = 0x40; |
| 156 | static const UINT8 WSWAN_IFLAG_HBLTMR = 0x80; |
| 157 | |
| 158 | /* Interrupts */ |
| 159 | static const UINT8 WSWAN_INT_STX = 0; |
| 160 | static const UINT8 WSWAN_INT_KEY = 1; |
| 161 | static const UINT8 WSWAN_INT_RTC = 2; |
| 162 | static const UINT8 WSWAN_INT_SRX = 3; |
| 163 | static const UINT8 WSWAN_INT_LCMP = 4; |
| 164 | static const UINT8 WSWAN_INT_VBLTMR = 5; |
| 165 | static const UINT8 WSWAN_INT_VBL = 6; |
| 166 | static const UINT8 WSWAN_INT_HBLTMR = 7; |
| 167 | |
| 168 | required_ioport m_cursx; |
| 169 | required_ioport m_cursy; |
| 170 | required_ioport m_buttons; |
| 171 | |
| 172 | void wswan_setup_bios(); |
| 173 | void wswan_handle_irqs(); |
| 174 | void wswan_set_irq_line(int irq); |
| 162 | 175 | }; |
| 163 | 176 | |
| 164 | 177 | |