trunk/src/mess/machine/lisa.c
| r20518 | r20519 | |
| 36 | 36 | Raphael Nabet, 2000-2003 |
| 37 | 37 | */ |
| 38 | 38 | |
| 39 | | #include "emu.h" |
| 40 | 39 | #include "includes/lisa.h" |
| 41 | | #include "machine/6522via.h" |
| 42 | | #include "machine/applefdc.h" |
| 43 | | #include "devices/sonydriv.h" |
| 44 | | #include "cpu/m68000/m68000.h" |
| 45 | | #include "sound/speaker.h" |
| 46 | 40 | |
| 47 | 41 | |
| 48 | 42 | /* |
| r20518 | r20519 | |
| 91 | 85 | a hard disk |
| 92 | 86 | */ |
| 93 | 87 | |
| 94 | | static void COPS_via_irq_func(device_t *device, int val); |
| 95 | | |
| 96 | | |
| 97 | 88 | const via6522_interface lisa_via6522_0_intf = |
| 98 | 89 | { |
| 99 | 90 | /* COPS via */ |
| r20518 | r20519 | |
| 103 | 94 | DEVCB_DRIVER_MEMBER(lisa_state,COPS_via_out_a), DEVCB_DRIVER_MEMBER(lisa_state,COPS_via_out_b), |
| 104 | 95 | DEVCB_DRIVER_MEMBER(lisa_state,COPS_via_out_ca2), DEVCB_DRIVER_MEMBER(lisa_state,COPS_via_out_cb2), |
| 105 | 96 | DEVCB_NULL, DEVCB_NULL, |
| 106 | | DEVCB_LINE(COPS_via_irq_func), |
| 97 | DEVCB_DRIVER_LINE_MEMBER(lisa_state,COPS_via_irq_func) |
| 107 | 98 | }; |
| 108 | 99 | |
| 109 | 100 | const via6522_interface lisa_via6522_1_intf = |
| r20518 | r20519 | |
| 114 | 105 | DEVCB_NULL, DEVCB_NULL, |
| 115 | 106 | DEVCB_NULL, DEVCB_NULL, |
| 116 | 107 | DEVCB_NULL, DEVCB_NULL, |
| 117 | | DEVCB_NULL, DEVCB_NULL, |
| 108 | DEVCB_NULL, DEVCB_NULL |
| 118 | 109 | }; |
| 119 | 110 | |
| 120 | 111 | /* |
| r20518 | r20519 | |
| 149 | 140 | Interrupt handling |
| 150 | 141 | */ |
| 151 | 142 | |
| 152 | | static void lisa_field_interrupts(running_machine &machine) |
| 143 | void lisa_state::field_interrupts() |
| 153 | 144 | { |
| 154 | | lisa_state *state = machine.driver_data<lisa_state>(); |
| 155 | | if (state->m_parity_error_pending) |
| 145 | if (m_parity_error_pending) |
| 156 | 146 | return; /* don't touch anything... */ |
| 157 | 147 | |
| 158 | 148 | #if 0 |
| 159 | 149 | if (RSIR) |
| 160 | 150 | // serial interrupt |
| 161 | | machine.device("maincpu")->execute().set_input_line_and_vector(M68K_IRQ_6, ASSERT_LINE, M68K_INT_ACK_AUTOVECTOR); |
| 151 | m_maincpu->set_input_line_and_vector(M68K_IRQ_6, ASSERT_LINE, M68K_INT_ACK_AUTOVECTOR); |
| 162 | 152 | else if (int0) |
| 163 | 153 | // external interrupt |
| 164 | | machine.device("maincpu")->execute().set_input_line_and_vector(M68K_IRQ_5, ASSERT_LINE, M68K_INT_ACK_AUTOVECTOR); |
| 154 | m_maincpu->set_input_line_and_vector(M68K_IRQ_5, ASSERT_LINE, M68K_INT_ACK_AUTOVECTOR); |
| 165 | 155 | else if (int1) |
| 166 | 156 | // external interrupt |
| 167 | | machine.device("maincpu")->execute().set_input_line_and_vector(M68K_IRQ_4, ASSERT_LINE, M68K_INT_ACK_AUTOVECTOR); |
| 157 | m_maincpu->set_input_line_and_vector(M68K_IRQ_4, ASSERT_LINE, M68K_INT_ACK_AUTOVECTOR); |
| 168 | 158 | else if (int2) |
| 169 | 159 | // external interrupt |
| 170 | | machine.device("maincpu")->execute().set_input_line_and_vector(M68K_IRQ_3, ASSERT_LINE, M68K_INT_ACK_AUTOVECTOR); |
| 160 | m_maincpu->set_input_line_and_vector(M68K_IRQ_3, ASSERT_LINE, M68K_INT_ACK_AUTOVECTOR); |
| 171 | 161 | else |
| 172 | 162 | #endif |
| 173 | | if (state->m_KBIR) |
| 163 | if (m_KBIR) |
| 174 | 164 | /* COPS VIA interrupt */ |
| 175 | | machine.device("maincpu")->execute().set_input_line_and_vector(M68K_IRQ_2, ASSERT_LINE, M68K_INT_ACK_AUTOVECTOR); |
| 176 | | else if (state->m_FDIR || state->m_VTIR) |
| 165 | m_maincpu->set_input_line_and_vector(M68K_IRQ_2, ASSERT_LINE, M68K_INT_ACK_AUTOVECTOR); |
| 166 | else if (m_FDIR || m_VTIR) |
| 177 | 167 | /* floppy disk or VBl */ |
| 178 | | machine.device("maincpu")->execute().set_input_line_and_vector(M68K_IRQ_1, ASSERT_LINE, M68K_INT_ACK_AUTOVECTOR); |
| 168 | m_maincpu->set_input_line_and_vector(M68K_IRQ_1, ASSERT_LINE, M68K_INT_ACK_AUTOVECTOR); |
| 179 | 169 | else |
| 180 | 170 | /* clear all interrupts */ |
| 181 | | machine.device("maincpu")->execute().set_input_line_and_vector(M68K_IRQ_1, CLEAR_LINE, M68K_INT_ACK_AUTOVECTOR); |
| 171 | m_maincpu->set_input_line_and_vector(M68K_IRQ_1, CLEAR_LINE, M68K_INT_ACK_AUTOVECTOR); |
| 182 | 172 | } |
| 183 | 173 | |
| 184 | | static void set_parity_error_pending(running_machine &machine, int value) |
| 174 | void lisa_state::set_parity_error_pending(int value) |
| 185 | 175 | { |
| 186 | | lisa_state *state = machine.driver_data<lisa_state>(); |
| 187 | 176 | #if 1 |
| 188 | 177 | /* does not work well due to bugs in 68k cores */ |
| 189 | | state->m_parity_error_pending = value; |
| 190 | | if (state->m_parity_error_pending) |
| 178 | m_parity_error_pending = value; |
| 179 | if (m_parity_error_pending) |
| 191 | 180 | { |
| 192 | | machine.device("maincpu")->execute().set_input_line_and_vector(M68K_IRQ_7, ASSERT_LINE, M68K_INT_ACK_AUTOVECTOR); |
| 181 | m_maincpu->set_input_line_and_vector(M68K_IRQ_7, ASSERT_LINE, M68K_INT_ACK_AUTOVECTOR); |
| 193 | 182 | } |
| 194 | 183 | else |
| 195 | 184 | { |
| 196 | | machine.device("maincpu")->execute().set_input_line(M68K_IRQ_7, CLEAR_LINE); |
| 185 | m_maincpu->set_input_line(M68K_IRQ_7, CLEAR_LINE); |
| 197 | 186 | } |
| 198 | 187 | #else |
| 199 | 188 | /* work-around... */ |
| 200 | | if ((! state->m_parity_error_pending) && value) |
| 189 | if ((! m_parity_error_pending) && value) |
| 201 | 190 | { |
| 202 | | state->m_parity_error_pending = 1; |
| 203 | | machine.device("maincpu")->execute().set_input_line_and_vector(M68K_IRQ_7, PULSE_LINE, M68K_INT_ACK_AUTOVECTOR); |
| 191 | m_parity_error_pending = 1; |
| 192 | m_maincpu->set_input_line_and_vector(M68K_IRQ_7, PULSE_LINE, M68K_INT_ACK_AUTOVECTOR); |
| 204 | 193 | } |
| 205 | | else if (state->m_parity_error_pending && (! value)) |
| 194 | else if (m_parity_error_pending && (! value)) |
| 206 | 195 | { |
| 207 | | state->m_parity_error_pending = 0; |
| 208 | | lisa_field_interrupts(machine); |
| 196 | m_parity_error_pending = 0; |
| 197 | field_interrupts(); |
| 209 | 198 | } |
| 210 | 199 | #endif |
| 211 | 200 | } |
| 212 | 201 | |
| 213 | | INLINE void set_VTIR(running_machine &machine, int value) |
| 202 | void lisa_state::set_VTIR(int value) |
| 214 | 203 | { |
| 215 | | lisa_state *state = machine.driver_data<lisa_state>(); |
| 216 | | if (state->m_VTIR != value) |
| 204 | if (m_VTIR != value) |
| 217 | 205 | { |
| 218 | | state->m_VTIR = value; |
| 219 | | if (state->m_VTIR==1) |
| 220 | | lisa_field_interrupts(machine); |
| 206 | m_VTIR = value; |
| 207 | if (m_VTIR==1) |
| 208 | field_interrupts(); |
| 221 | 209 | } |
| 222 | 210 | } |
| 223 | 211 | |
| r20518 | r20519 | |
| 227 | 215 | keyboard interface (COPS simulation; our COPS CPU core is too broken and too esoteric to emulate this correctly, I tried) |
| 228 | 216 | */ |
| 229 | 217 | |
| 230 | | INLINE void COPS_send_data_if_possible(running_machine &machine) |
| 218 | void lisa_state::COPS_send_data_if_possible() |
| 231 | 219 | { |
| 232 | | lisa_state *state = machine.driver_data<lisa_state>(); |
| 233 | | via6522_device *via_0 = machine.device<via6522_device>("via6522_0"); |
| 234 | | address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM); |
| 220 | address_space &space = m_maincpu->space(AS_PROGRAM); |
| 235 | 221 | |
| 236 | | if ((! state->m_hold_COPS_data) && state->m_fifo_size && (! state->m_COPS_Ready)) |
| 222 | if ((! m_hold_COPS_data) && m_fifo_size && (! m_COPS_Ready)) |
| 237 | 223 | { |
| 238 | | // printf("COPsim: sending %02x to VIA\n", state->m_fifo_data[state->m_fifo_head]); |
| 224 | // printf("COPsim: sending %02x to VIA\n", m_fifo_data[m_fifo_head]); |
| 239 | 225 | |
| 240 | | via_0->write_porta(space, 0, state->m_fifo_data[state->m_fifo_head]); /* output data */ |
| 241 | | if (state->m_fifo_head == state->m_mouse_data_offset) |
| 242 | | state->m_mouse_data_offset = -1; /* we just phased out the mouse data in buffer */ |
| 243 | | state->m_fifo_head = (state->m_fifo_head+1) & 0x7; |
| 244 | | state->m_fifo_size--; |
| 245 | | via_0->write_ca1(1); /* pulse ca1 so that VIA reads it */ |
| 246 | | via_0->write_ca1(0); /* BTW, I have no idea how a real COPS does it ! */ |
| 226 | m_via0->write_porta(space, 0, m_fifo_data[m_fifo_head]); /* output data */ |
| 227 | if (m_fifo_head == m_mouse_data_offset) |
| 228 | m_mouse_data_offset = -1; /* we just phased out the mouse data in buffer */ |
| 229 | m_fifo_head = (m_fifo_head+1) & 0x7; |
| 230 | m_fifo_size--; |
| 231 | m_via0->write_ca1(1); /* pulse ca1 so that VIA reads it */ |
| 232 | m_via0->write_ca1(0); /* BTW, I have no idea how a real COPS does it ! */ |
| 247 | 233 | } |
| 248 | 234 | } |
| 249 | 235 | |
| 250 | 236 | /* send data (queue it into the FIFO if needed) */ |
| 251 | | static void COPS_queue_data(running_machine &machine, const UINT8 *data, int len) |
| 237 | void lisa_state::COPS_queue_data(const UINT8 *data, int len) |
| 252 | 238 | { |
| 253 | | lisa_state *state = machine.driver_data<lisa_state>(); |
| 254 | 239 | #if 0 |
| 255 | | if (state->m_fifo_size + len <= 8) |
| 240 | if (m_fifo_size + len <= 8) |
| 256 | 241 | #else |
| 257 | 242 | /* trash old data */ |
| 258 | | while (state->m_fifo_size > 8 - len) |
| 243 | while (m_fifo_size > 8 - len) |
| 259 | 244 | { |
| 260 | | if (state->m_fifo_head == state->m_mouse_data_offset) |
| 261 | | state->m_mouse_data_offset = -1; /* we just phased out the mouse data in buffer */ |
| 262 | | state->m_fifo_head = (state->m_fifo_head+1) & 0x7; |
| 263 | | state->m_fifo_size--; |
| 245 | if (m_fifo_head == m_mouse_data_offset) |
| 246 | m_mouse_data_offset = -1; /* we just phased out the mouse data in buffer */ |
| 247 | m_fifo_head = (m_fifo_head+1) & 0x7; |
| 248 | m_fifo_size--; |
| 264 | 249 | } |
| 265 | 250 | #endif |
| 266 | 251 | |
| r20518 | r20519 | |
| 269 | 254 | |
| 270 | 255 | while (len--) |
| 271 | 256 | { |
| 272 | | state->m_fifo_data[state->m_fifo_tail] = * (data++); |
| 273 | | state->m_fifo_tail = (state->m_fifo_tail+1) & 0x7; |
| 274 | | state->m_fifo_size++; |
| 257 | m_fifo_data[m_fifo_tail] = * (data++); |
| 258 | m_fifo_tail = (m_fifo_tail+1) & 0x7; |
| 259 | m_fifo_size++; |
| 275 | 260 | } |
| 276 | 261 | |
| 277 | 262 | /*logerror("COPS_queue_data : trying to send data to VIA\n");*/ |
| 278 | | COPS_send_data_if_possible(machine); |
| 263 | COPS_send_data_if_possible(); |
| 279 | 264 | } |
| 280 | 265 | } |
| 281 | 266 | |
| r20518 | r20519 | |
| 288 | 273 | |
| 289 | 274 | /* keyboard matrix to detect transition */ |
| 290 | 275 | |
| 291 | | static void scan_keyboard(running_machine &machine) |
| 276 | void lisa_state::scan_keyboard() |
| 292 | 277 | { |
| 293 | | lisa_state *state = machine.driver_data<lisa_state>(); |
| 294 | 278 | int i, j; |
| 295 | | int keybuf; |
| 296 | 279 | UINT8 keycode; |
| 297 | | static const char *const keynames[] = { "LINE0", "LINE1", "LINE2", "LINE3", "LINE4", "LINE5", "LINE6", "LINE7" }; |
| 280 | UINT8 keybuf[8] = { m_io_line0->read(), m_io_line1->read(), m_io_line2->read(), m_io_line3->read(), |
| 281 | m_io_line4->read(), m_io_line5->read(), m_io_line6->read(), m_io_line7->read() }; |
| 298 | 282 | |
| 299 | | if (! state->m_COPS_force_unplug) |
| 283 | if (! m_COPS_force_unplug) |
| 300 | 284 | for (i=0; i<8; i++) |
| 301 | 285 | { |
| 302 | | keybuf = machine.root_device().ioport(keynames[i])->read(); |
| 303 | | |
| 304 | | if (keybuf != state->m_key_matrix[i]) |
| 286 | if (keybuf[i] != m_key_matrix[i]) |
| 305 | 287 | { /* if state has changed, find first bit which has changed */ |
| 306 | 288 | /*logerror("keyboard state changed, %d %X\n", i, keybuf);*/ |
| 307 | 289 | |
| 308 | 290 | for (j=0; j<16; j++) |
| 309 | 291 | { |
| 310 | | if (((keybuf ^ state->m_key_matrix[i]) >> j) & 1) |
| 292 | if (((keybuf[i] ^ m_key_matrix[i]) >> j) & 1) |
| 311 | 293 | { |
| 312 | 294 | /* update key_matrix */ |
| 313 | | state->m_key_matrix[i] = (state->m_key_matrix[i] & ~ (1 << j)) | (keybuf & (1 << j)); |
| 295 | m_key_matrix[i] = (m_key_matrix[i] & ~ (1 << j)) | (keybuf[i] & (1 << j)); |
| 314 | 296 | |
| 315 | 297 | /* create key code */ |
| 316 | 298 | keycode = (i << 4) | j; |
| 317 | | if (keybuf & (1 << j)) |
| 299 | if (keybuf[i] & (1 << j)) |
| 318 | 300 | { /* key down */ |
| 319 | 301 | keycode |= 0x80; |
| 320 | 302 | } |
| 321 | 303 | #if 0 |
| 322 | | if (keycode == state->m_NMIcode) |
| 304 | if (keycode == m_NMIcode) |
| 323 | 305 | { /* generate NMI interrupt */ |
| 324 | | machine.device("maincpu")->execute().set_input_line(M68K_IRQ_7, PULSE_LINE); |
| 325 | | machine.device("maincpu")->execute().set_input_line_vector(M68K_IRQ_7, M68K_INT_ACK_AUTOVECTOR); |
| 306 | m_maincpu->set_input_line(M68K_IRQ_7, PULSE_LINE); |
| 307 | m_maincpu->set_input_line_vector(M68K_IRQ_7, M68K_INT_ACK_AUTOVECTOR); |
| 326 | 308 | } |
| 327 | 309 | #endif |
| 328 | | COPS_queue_data(machine, & keycode, 1); |
| 310 | COPS_queue_data(&keycode, 1); |
| 329 | 311 | } |
| 330 | 312 | } |
| 331 | 313 | } |
| r20518 | r20519 | |
| 344 | 326 | return; /* ???? */ |
| 345 | 327 | #endif |
| 346 | 328 | |
| 347 | | new_mx = machine().root_device().ioport("MOUSE_X")->read(); |
| 348 | | new_my = machine().root_device().ioport("MOUSE_Y")->read(); |
| 329 | new_mx = m_io_mouse_x->read(); |
| 330 | new_my = m_io_mouse_y->read(); |
| 349 | 331 | |
| 350 | 332 | /* see if it moved in the x coord */ |
| 351 | 333 | if (new_mx != m_last_mx) |
| r20518 | r20519 | |
| 407 | 389 | m_fifo_size += 3; |
| 408 | 390 | |
| 409 | 391 | /*logerror("handle_mouse : trying to send data to VIA\n");*/ |
| 410 | | COPS_send_data_if_possible(machine()); |
| 392 | COPS_send_data_if_possible(); |
| 411 | 393 | } |
| 412 | 394 | /* else, mouse data is lost forever (correct ??) */ |
| 413 | 395 | } |
| r20518 | r20519 | |
| 418 | 400 | TIMER_CALLBACK_MEMBER(lisa_state::read_COPS_command) |
| 419 | 401 | { |
| 420 | 402 | int command; |
| 421 | | via6522_device *via_0 = machine().device<via6522_device>("via6522_0"); |
| 422 | | address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM); |
| 403 | address_space &space = m_maincpu->space(AS_PROGRAM); |
| 423 | 404 | |
| 424 | 405 | m_COPS_Ready = 0; |
| 425 | 406 | |
| 426 | 407 | /*logerror("read_COPS_command : trying to send data to VIA\n");*/ |
| 427 | | COPS_send_data_if_possible(machine()); |
| 408 | COPS_send_data_if_possible(); |
| 428 | 409 | |
| 429 | 410 | /* some pull-ups allow the COPS to read 1s when the VIA port is not set as output */ |
| 430 | | command = (m_COPS_command | (~ via_0->read(space, VIA_DDRA))) & 0xff; |
| 411 | command = (m_COPS_command | (~ m_via0->read(space, VIA_DDRA))) & 0xff; |
| 431 | 412 | |
| 432 | 413 | // printf("Dropping Ready, command = %02x\n", command); |
| 433 | 414 | |
| r20518 | r20519 | |
| 581 | 562 | reply[5] = (m_clock_regs.minutes2 << 4) | m_clock_regs.seconds1; |
| 582 | 563 | reply[6] = (m_clock_regs.seconds2 << 4) | m_clock_regs.tenths; |
| 583 | 564 | |
| 584 | | COPS_queue_data(machine(), reply, 7); |
| 565 | COPS_queue_data(reply, 7); |
| 585 | 566 | } |
| 586 | 567 | break; |
| 587 | 568 | } |
| r20518 | r20519 | |
| 597 | 578 | machine().scheduler().timer_set(attotime::from_usec(20), timer_expired_delegate(FUNC(lisa_state::read_COPS_command),this)); |
| 598 | 579 | } |
| 599 | 580 | |
| 600 | | static void reset_COPS(lisa_state *state) |
| 581 | void lisa_state::reset_COPS() |
| 601 | 582 | { |
| 602 | 583 | int i; |
| 603 | 584 | |
| 604 | | state->m_fifo_size = 0; |
| 605 | | state->m_fifo_head = 0; |
| 606 | | state->m_fifo_tail = 0; |
| 607 | | state->m_mouse_data_offset = -1; |
| 585 | m_fifo_size = 0; |
| 586 | m_fifo_head = 0; |
| 587 | m_fifo_tail = 0; |
| 588 | m_mouse_data_offset = -1; |
| 608 | 589 | |
| 609 | 590 | for (i=0; i<8; i++) |
| 610 | | state->m_key_matrix[i] = 0; |
| 591 | m_key_matrix[i] = 0; |
| 611 | 592 | |
| 612 | | state->m_mouse_timer->reset(); |
| 593 | m_mouse_timer->reset(); |
| 613 | 594 | } |
| 614 | 595 | |
| 615 | | static void unplug_keyboard(running_machine &machine) |
| 596 | void lisa_state::unplug_keyboard() |
| 616 | 597 | { |
| 617 | 598 | static const UINT8 cmd[2] = |
| 618 | 599 | { |
| r20518 | r20519 | |
| 620 | 601 | 0xFD /* keyboard unplugged */ |
| 621 | 602 | }; |
| 622 | 603 | |
| 623 | | COPS_queue_data(machine, cmd, 2); |
| 604 | COPS_queue_data(cmd, 2); |
| 624 | 605 | } |
| 625 | 606 | |
| 626 | | |
| 627 | | static void plug_keyboard(running_machine &machine) |
| 607 | void lisa_state::plug_keyboard() |
| 628 | 608 | { |
| 629 | 609 | /* |
| 630 | 610 | possible keyboard IDs according to Lisa Hardware Manual and boot ROM source code |
| r20518 | r20519 | |
| 648 | 628 | 0x3f /* keyboard ID - US for now */ |
| 649 | 629 | }; |
| 650 | 630 | |
| 651 | | COPS_queue_data(machine, cmd, 2); |
| 631 | COPS_queue_data(cmd, 2); |
| 652 | 632 | } |
| 653 | 633 | |
| 654 | 634 | |
| 655 | 635 | /* called at power-up */ |
| 656 | | static void init_COPS(running_machine &machine) |
| 636 | void lisa_state::init_COPS() |
| 657 | 637 | { |
| 658 | | lisa_state *state = machine.driver_data<lisa_state>(); |
| 659 | | state->m_COPS_Ready = 0; |
| 638 | m_COPS_Ready = 0; |
| 660 | 639 | |
| 661 | | reset_COPS(state); |
| 640 | reset_COPS(); |
| 662 | 641 | } |
| 663 | 642 | |
| 664 | 643 | |
| r20518 | r20519 | |
| 683 | 662 | /*logerror("COPS CA2 line state : %d\n", val);*/ |
| 684 | 663 | |
| 685 | 664 | /*logerror("COPS_via_out_ca2 : trying to send data to VIA\n");*/ |
| 686 | | COPS_send_data_if_possible(machine()); |
| 665 | COPS_send_data_if_possible(); |
| 687 | 666 | } |
| 688 | 667 | |
| 689 | 668 | /* |
| r20518 | r20519 | |
| 715 | 694 | |
| 716 | 695 | WRITE8_MEMBER(lisa_state::COPS_via_out_b) |
| 717 | 696 | { |
| 718 | | via6522_device *via_0 = machine().device<via6522_device>("via6522_0"); |
| 719 | | |
| 720 | 697 | /* pull-up */ |
| 721 | | data |= (~ via_0->read(space,VIA_DDRA)) & 0x01; |
| 698 | data |= (~ m_via0->read(space,VIA_DDRA)) & 0x01; |
| 722 | 699 | |
| 723 | 700 | if (data & 0x01) |
| 724 | 701 | { |
| 725 | 702 | if (m_COPS_force_unplug) |
| 726 | 703 | { |
| 727 | 704 | m_COPS_force_unplug = 0; |
| 728 | | plug_keyboard(machine()); |
| 705 | plug_keyboard(); |
| 729 | 706 | } |
| 730 | 707 | } |
| 731 | 708 | else |
| r20518 | r20519 | |
| 733 | 710 | if (! m_COPS_force_unplug) |
| 734 | 711 | { |
| 735 | 712 | m_COPS_force_unplug = 1; |
| 736 | | unplug_keyboard(machine()); |
| 713 | unplug_keyboard(); |
| 737 | 714 | //reset_COPS(state); |
| 738 | 715 | } |
| 739 | 716 | } |
| r20518 | r20519 | |
| 741 | 718 | |
| 742 | 719 | WRITE8_MEMBER(lisa_state::COPS_via_out_cb2) |
| 743 | 720 | { |
| 744 | | device_t *speaker = machine().device(SPEAKER_TAG); |
| 745 | | speaker_level_w(speaker, data); |
| 721 | speaker_level_w(m_speaker, data); |
| 746 | 722 | } |
| 747 | 723 | |
| 748 | | static void COPS_via_irq_func(device_t *device, int val) |
| 724 | void lisa_state::COPS_via_irq_func(int val) |
| 749 | 725 | { |
| 750 | | lisa_state *state = device->machine().driver_data<lisa_state>(); |
| 751 | | if (state->m_KBIR != val) |
| 726 | if (m_KBIR != val) |
| 752 | 727 | { |
| 753 | | state->m_KBIR = val; |
| 754 | | lisa_field_interrupts(device->machine()); |
| 728 | m_KBIR = val; |
| 729 | field_interrupts(); |
| 755 | 730 | } |
| 756 | 731 | } |
| 757 | 732 | |
| r20518 | r20519 | |
| 835 | 810 | lisa_state *state = machine.driver_data<lisa_state>(); |
| 836 | 811 | /* upper 7 bits -> segment # */ |
| 837 | 812 | int segment = (address >> 17) & 0x7f; |
| 838 | | int the_seg = state->m_seg; |
| 813 | int the_seg = m_seg; |
| 839 | 814 | |
| 840 | 815 | address &= 0xffffff; |
| 841 | 816 | |
| 842 | 817 | printf("lisa: logical address %x\n", address); |
| 843 | 818 | |
| 844 | | if (state->m_setup) |
| 819 | if (m_setup) |
| 845 | 820 | { |
| 846 | 821 | if (address & 0x004000) |
| 847 | 822 | { |
| r20518 | r20519 | |
| 855 | 830 | } |
| 856 | 831 | else |
| 857 | 832 | { /* system ROMs */ |
| 858 | | direct.explicit_configure((address & 0xffc000), (address & 0xffc000) + 0x003fff, 0xffffff, state->m_rom_ptr - (address & 0x3fff)); |
| 833 | direct.explicit_configure((address & 0xffc000), (address & 0xffc000) + 0x003fff, 0xffffff, m_rom_ptr - (address & 0x3fff)); |
| 859 | 834 | } |
| 860 | 835 | |
| 861 | 836 | return -1; |
| r20518 | r20519 | |
| 863 | 838 | |
| 864 | 839 | } |
| 865 | 840 | |
| 866 | | if (machine.device("maincpu")->state().state_int(M68K_SR) & 0x2000) |
| 841 | if (m_maincpu->state_int(M68K_SR) & 0x2000) |
| 867 | 842 | { |
| 868 | 843 | /* supervisor mode -> force register file 0 */ |
| 869 | 844 | the_seg = 0; |
| r20518 | r20519 | |
| 873 | 848 | int seg_offset = address & 0x01ffff; |
| 874 | 849 | |
| 875 | 850 | /* add revelant origin -> address */ |
| 876 | | offs_t mapped_address = (state->m_mmu_regs[the_seg][segment].sorg + seg_offset) & 0x1fffff; |
| 851 | offs_t mapped_address = (m_mmu_regs[the_seg][segment].sorg + seg_offset) & 0x1fffff; |
| 877 | 852 | |
| 878 | | switch ((mmu_entry_t)state->m_mmu_regs[the_seg][segment].type) |
| 853 | switch ((mmu_entry_t)m_mmu_regs[the_seg][segment].type) |
| 879 | 854 | { |
| 880 | 855 | case RAM_r: |
| 881 | 856 | case RAM_rw: |
| 882 | | if (seg_offset > state->m_mmu_regs[the_seg][segment].slim) |
| 857 | if (seg_offset > m_mmu_regs[the_seg][segment].slim) |
| 883 | 858 | { |
| 884 | 859 | /* out of segment limits : bus error */ |
| 885 | 860 | printf("illegal opbase address%lX\n", (long) address); |
| 886 | 861 | } |
| 887 | | direct.explicit_configure((address & 0xffc000), (address & 0xffc000) + 0x003fff, 0xffffff, state->m_ram_ptr + mapped_address - address); |
| 862 | direct.explicit_configure((address & 0xffc000), (address & 0xffc000) + 0x003fff, 0xffffff, m_ram_ptr + mapped_address - address); |
| 888 | 863 | printf("RAM\n"); |
| 889 | 864 | break; |
| 890 | 865 | |
| r20518 | r20519 | |
| 897 | 872 | break; |
| 898 | 873 | |
| 899 | 874 | case special_IO: |
| 900 | | direct.explicit_configure((address & 0xffc000), (address & 0xffc000) + 0x003fff, 0xffffff, state->m_rom_ptr + (mapped_address & 0x003fff) - address); |
| 875 | direct.explicit_configure((address & 0xffc000), (address & 0xffc000) + 0x003fff, 0xffffff, m_rom_ptr + (mapped_address & 0x003fff) - address); |
| 901 | 876 | printf("ROM\n"); |
| 902 | 877 | break; |
| 903 | 878 | } |
| r20518 | r20519 | |
| 912 | 887 | NVRAM_HANDLER(lisa) |
| 913 | 888 | { |
| 914 | 889 | lisa_state *state = machine.driver_data<lisa_state>(); |
| 890 | |
| 915 | 891 | if (read_or_write) |
| 916 | 892 | { |
| 917 | 893 | file->write(state->m_fdc_ram, 1024); |
| r20518 | r20519 | |
| 950 | 926 | #if 0 |
| 951 | 927 | UINT32 temp32; |
| 952 | 928 | SINT8 temp8; |
| 953 | | temp32 = (state->m_clock_regs.alarm << 12) | (state->m_clock_regs.years << 8) | (state->m_clock_regs.days1 << 4) |
| 954 | | | state->m_clock_regs.days2; |
| 929 | temp32 = (m_clock_regs.alarm << 12) | (m_clock_regs.years << 8) | (m_clock_regs.days1 << 4) |
| 930 | | m_clock_regs.days2; |
| 955 | 931 | |
| 956 | | temp32 = (state->m_clock_regs.days3 << 28) | (state->m_clock_regs.hours1 << 24) | (state->m_clock_regs.hours2 << 20) |
| 957 | | | (state->m_clock_regs.minutes1 << 16) | (state->m_clock_regs.minutes2 << 12) |
| 958 | | | (state->m_clock_regs.seconds1 << 8) | (state->m_clock_regs.seconds2 << 4) | state->m_clock_regs.tenths; |
| 932 | temp32 = (m_clock_regs.days3 << 28) | (m_clock_regs.hours1 << 24) | (m_clock_regs.hours2 << 20) |
| 933 | | (m_clock_regs.minutes1 << 16) | (m_clock_regs.minutes2 << 12) |
| 934 | | (m_clock_regs.seconds1 << 8) | (m_clock_regs.seconds2 << 4) | m_clock_regs.tenths; |
| 959 | 935 | |
| 960 | 936 | temp8 = clock_mode; /* clock mode */ |
| 961 | 937 | |
| 962 | | temp8 = state->m_clock_regs.clock_write_ptr; /* clock byte to be written next (-1 if clock write disabled) */ |
| 938 | temp8 = m_clock_regs.clock_write_ptr; /* clock byte to be written next (-1 if clock write disabled) */ |
| 963 | 939 | #endif |
| 964 | 940 | } |
| 965 | 941 | |
| r20518 | r20519 | |
| 967 | 943 | void init_lisa1(void) |
| 968 | 944 | { |
| 969 | 945 | lisa_state *state = machine.driver_data<lisa_state>(); |
| 970 | | state->m_model = lisa1; |
| 971 | | state->m_features.has_fast_timers = 0; |
| 972 | | state->m_features.floppy_hardware = twiggy; |
| 973 | | state->m_features.has_double_sided_floppy = 1; |
| 974 | | state->m_features.has_mac_xl_video = 0; |
| 946 | m_model = lisa1; |
| 947 | m_features.has_fast_timers = 0; |
| 948 | m_features.floppy_hardware = twiggy; |
| 949 | m_features.has_double_sided_floppy = 1; |
| 950 | m_features.has_mac_xl_video = 0; |
| 975 | 951 | } |
| 976 | 952 | #endif |
| 977 | 953 | |
| 978 | 954 | DRIVER_INIT_MEMBER(lisa_state,lisa2) |
| 979 | 955 | { |
| 980 | | m_ram_ptr = machine().root_device().memregion("maincpu")->base() + RAM_OFFSET; |
| 956 | m_ram_ptr = memregion("maincpu")->base() + RAM_OFFSET; |
| 981 | 957 | m_rom_ptr = memregion("maincpu")->base() + ROM_OFFSET; |
| 982 | 958 | m_model = lisa2; |
| 983 | 959 | m_features.has_fast_timers = 0; |
| r20518 | r20519 | |
| 990 | 966 | |
| 991 | 967 | DRIVER_INIT_MEMBER(lisa_state,lisa210) |
| 992 | 968 | { |
| 993 | | m_ram_ptr = machine().root_device().memregion("maincpu")->base() + RAM_OFFSET; |
| 969 | m_ram_ptr = memregion("maincpu")->base() + RAM_OFFSET; |
| 994 | 970 | m_rom_ptr = memregion("maincpu")->base() + ROM_OFFSET; |
| 995 | 971 | m_model = lisa210; |
| 996 | 972 | m_features.has_fast_timers = 1; |
| r20518 | r20519 | |
| 1003 | 979 | |
| 1004 | 980 | DRIVER_INIT_MEMBER(lisa_state,mac_xl) |
| 1005 | 981 | { |
| 1006 | | m_ram_ptr = machine().root_device().memregion("maincpu")->base() + RAM_OFFSET; |
| 982 | m_ram_ptr = memregion("maincpu")->base() + RAM_OFFSET; |
| 1007 | 983 | m_rom_ptr = memregion("maincpu")->base() + ROM_OFFSET; |
| 1008 | 984 | m_model = mac_xl; |
| 1009 | 985 | m_features.has_fast_timers = 1; |
| r20518 | r20519 | |
| 1024 | 1000 | |
| 1025 | 1001 | void lisa_state::machine_reset() |
| 1026 | 1002 | { |
| 1027 | | m_ram_ptr = machine().root_device().memregion("maincpu")->base() + RAM_OFFSET; |
| 1028 | | m_rom_ptr = machine().root_device().memregion("maincpu")->base() + ROM_OFFSET; |
| 1003 | m_ram_ptr = memregion("maincpu")->base() + RAM_OFFSET; |
| 1004 | m_rom_ptr = memregion("maincpu")->base() + ROM_OFFSET; |
| 1029 | 1005 | m_videoROM_ptr = memregion("gfx1")->base(); |
| 1030 | 1006 | |
| 1031 | | // machine().device("maincpu")->memory().space(AS_PROGRAM).set_direct_update_handler(direct_update_delegate_create_static(lisa_OPbaseoverride, *machine())); |
| 1032 | | // m68k_set_reset_callback(machine().device("maincpu"), /*lisa_reset_instr_callback*/NULL); |
| 1007 | // m_maincpu->memory().space(AS_PROGRAM).set_direct_update_handler(direct_update_delegate_create_static(lisa_OPbaseoverride, *machine())); |
| 1008 | // m68k_set_reset_callback(m_maincpu, /*lisa_reset_instr_callback*/NULL); |
| 1033 | 1009 | |
| 1034 | 1010 | /* init MMU */ |
| 1035 | 1011 | m_setup = 1; |
| r20518 | r20519 | |
| 1046 | 1022 | /* init video */ |
| 1047 | 1023 | |
| 1048 | 1024 | m_VTMSK = 0; |
| 1049 | | set_VTIR(machine(), 0); |
| 1025 | set_VTIR(0); |
| 1050 | 1026 | |
| 1051 | 1027 | m_video_address_latch = 0; |
| 1052 | 1028 | m_videoram_ptr = (UINT16 *) m_ram_ptr; |
| 1053 | 1029 | |
| 1054 | 1030 | /* reset COPS keyboard/mouse controller */ |
| 1055 | | init_COPS(machine()); |
| 1031 | init_COPS(); |
| 1056 | 1032 | |
| 1057 | 1033 | { |
| 1058 | 1034 | COPS_via_out_ca2(generic_space(), 0, 0); /* VIA core forgets to do so */ |
| r20518 | r20519 | |
| 1062 | 1038 | { |
| 1063 | 1039 | if (m_features.floppy_hardware == sony_lisa2) |
| 1064 | 1040 | { |
| 1065 | | sony_set_enable_lines(machine().device("fdc"),1); /* on lisa2, drive unit 1 is always selected (?) */ |
| 1041 | sony_set_enable_lines(m_fdc, 1); /* on lisa2, drive unit 1 is always selected (?) */ |
| 1066 | 1042 | } |
| 1067 | 1043 | } |
| 1068 | 1044 | |
| 1069 | 1045 | /* reset 68k to pick up proper vectors from MMU */ |
| 1070 | | machine().device("maincpu")->reset(); |
| 1046 | m_maincpu->reset(); |
| 1071 | 1047 | } |
| 1072 | 1048 | |
| 1073 | 1049 | INTERRUPT_GEN_MEMBER(lisa_state::lisa_interrupt) |
| r20518 | r20519 | |
| 1092 | 1068 | 0x80, /* RESET code */ |
| 1093 | 1069 | 0xFC /* timer time-out */ |
| 1094 | 1070 | }; |
| 1095 | | COPS_queue_data(machine(), cmd, 2); |
| 1071 | COPS_queue_data(cmd, 2); |
| 1096 | 1072 | |
| 1097 | 1073 | m_clock_regs.alarm = 0xfffffL; |
| 1098 | 1074 | } |
| r20518 | r20519 | |
| 1159 | 1135 | |
| 1160 | 1136 | /* set VBI */ |
| 1161 | 1137 | if (m_VTMSK) |
| 1162 | | set_VTIR(machine(), 1); |
| 1138 | set_VTIR(1); |
| 1163 | 1139 | else |
| 1164 | | set_VTIR(machine(), 0); |
| 1140 | set_VTIR(0); |
| 1165 | 1141 | |
| 1166 | 1142 | /* do keyboard scan */ |
| 1167 | | scan_keyboard(machine()); |
| 1143 | scan_keyboard(); |
| 1168 | 1144 | } |
| 1169 | 1145 | |
| 1170 | 1146 | /* |
| r20518 | r20519 | |
| 1174 | 1150 | cannot support 2 floppy drives)... |
| 1175 | 1151 | */ |
| 1176 | 1152 | |
| 1177 | | INLINE void lisa_fdc_ttl_glue_access(running_machine &machine, offs_t offset) |
| 1153 | void lisa_state::lisa_fdc_ttl_glue_access(offs_t offset) |
| 1178 | 1154 | { |
| 1179 | | lisa_state *state = machine.driver_data<lisa_state>(); |
| 1180 | 1155 | switch ((offset & 0x000E) >> 1) |
| 1181 | 1156 | { |
| 1182 | 1157 | case 0: |
| r20518 | r20519 | |
| 1189 | 1164 | /* enable/disable the motor on Lisa 1 */ |
| 1190 | 1165 | /* can disable the motor on Lisa 2/10, too (although it is not useful) */ |
| 1191 | 1166 | /* On lisa 2, commands the loading of the speed register on lisalite board */ |
| 1192 | | if (state->m_features.floppy_hardware == sony_lisa2) |
| 1167 | if (m_features.floppy_hardware == sony_lisa2) |
| 1193 | 1168 | { |
| 1194 | | int oldMT1 = state->m_MT1; |
| 1195 | | state->m_MT1 = offset & 1; |
| 1196 | | if (state->m_MT1 && ! oldMT1) |
| 1169 | int oldMT1 = m_MT1; |
| 1170 | m_MT1 = offset & 1; |
| 1171 | if (m_MT1 && ! oldMT1) |
| 1197 | 1172 | { |
| 1198 | | applefdc_base_device *fdc = machine.device<applefdc_base_device>("fdc"); |
| 1199 | | |
| 1200 | | state->m_PWM_floppy_motor_speed = (state->m_PWM_floppy_motor_speed << 1) & 0xff; |
| 1201 | | if (fdc->get_lines() & APPLEFDC_PH0) |
| 1202 | | state->m_PWM_floppy_motor_speed |= 1; |
| 1203 | | sony_set_speed(((256-state->m_PWM_floppy_motor_speed) * 1.3) + 237); |
| 1173 | m_PWM_floppy_motor_speed = (m_PWM_floppy_motor_speed << 1) & 0xff; |
| 1174 | if (m_fdc->get_lines() & APPLEFDC_PH0) |
| 1175 | m_PWM_floppy_motor_speed |= 1; |
| 1176 | sony_set_speed(((256-m_PWM_floppy_motor_speed) * 1.3) + 237); |
| 1204 | 1177 | } |
| 1205 | 1178 | } |
| 1206 | 1179 | /*else |
| 1207 | | state->m_MT1 = offset & 1;*/ |
| 1180 | m_MT1 = offset & 1;*/ |
| 1208 | 1181 | break; |
| 1209 | 1182 | case 4: |
| 1210 | 1183 | /*DIS = offset & 1;*/ /* forbids access from the 68000 to our RAM */ |
| r20518 | r20519 | |
| 1212 | 1185 | case 5: |
| 1213 | 1186 | /*HDS = offset & 1;*/ /* head select (-> disk side) on twiggy */ |
| 1214 | 1187 | #if 0 |
| 1215 | | if (state->m_features.floppy_hardware == twiggy) |
| 1188 | if (m_features.floppy_hardware == twiggy) |
| 1216 | 1189 | twiggy_set_head_line(offset & 1); |
| 1217 | 1190 | else |
| 1218 | 1191 | #endif |
| 1219 | | if (state->m_features.floppy_hardware == sony_lisa210) |
| 1220 | | sony_set_sel_line(machine.device("fdc"), offset & 1); |
| 1192 | if (m_features.floppy_hardware == sony_lisa210) |
| 1193 | sony_set_sel_line(m_fdc, offset & 1); |
| 1221 | 1194 | break; |
| 1222 | 1195 | case 6: |
| 1223 | | state->m_DISK_DIAG = offset & 1; |
| 1196 | m_DISK_DIAG = offset & 1; |
| 1224 | 1197 | break; |
| 1225 | 1198 | case 7: |
| 1226 | | state->m_FDIR = offset & 1; /* Interrupt request to 68k */ |
| 1227 | | lisa_field_interrupts(machine); |
| 1199 | m_FDIR = offset & 1; /* Interrupt request to 68k */ |
| 1200 | field_interrupts(); |
| 1228 | 1201 | break; |
| 1229 | 1202 | } |
| 1230 | 1203 | } |
| r20518 | r20519 | |
| 1232 | 1205 | READ8_MEMBER(lisa_state::lisa_fdc_io_r) |
| 1233 | 1206 | { |
| 1234 | 1207 | int answer=0; |
| 1235 | | applefdc_base_device *fdc = machine().device<applefdc_base_device>("fdc"); |
| 1236 | 1208 | |
| 1237 | 1209 | switch ((offset & 0x0030) >> 4) |
| 1238 | 1210 | { |
| 1239 | 1211 | case 0: /* IWM */ |
| 1240 | | answer = fdc->read(offset); |
| 1212 | answer = m_fdc->read(offset); |
| 1241 | 1213 | break; |
| 1242 | 1214 | |
| 1243 | 1215 | case 1: /* TTL glue */ |
| 1244 | | lisa_fdc_ttl_glue_access(machine(), offset); |
| 1216 | lisa_fdc_ttl_glue_access(offset); |
| 1245 | 1217 | answer = 0; /* ??? */ |
| 1246 | 1218 | break; |
| 1247 | 1219 | |
| r20518 | r20519 | |
| 1259 | 1231 | |
| 1260 | 1232 | WRITE8_MEMBER(lisa_state::lisa_fdc_io_w) |
| 1261 | 1233 | { |
| 1262 | | applefdc_base_device *fdc = machine().device<applefdc_base_device>("fdc"); |
| 1263 | | |
| 1264 | 1234 | switch ((offset & 0x0030) >> 4) |
| 1265 | 1235 | { |
| 1266 | 1236 | case 0: /* IWM */ |
| 1267 | | fdc->write(offset, data); |
| 1237 | m_fdc->write(offset, data); |
| 1268 | 1238 | break; |
| 1269 | 1239 | |
| 1270 | 1240 | case 1: /* TTL glue */ |
| 1271 | | lisa_fdc_ttl_glue_access(machine(), offset); |
| 1241 | lisa_fdc_ttl_glue_access(offset); |
| 1272 | 1242 | break; |
| 1273 | 1243 | |
| 1274 | 1244 | case 2: /* writes the PWM register */ |
| r20518 | r20519 | |
| 1391 | 1361 | } |
| 1392 | 1362 | } |
| 1393 | 1363 | |
| 1394 | | if (machine().device("maincpu")->state().state_int(M68K_SR) & 0x2000) |
| 1364 | if (m_maincpu->state_int(M68K_SR) & 0x2000) |
| 1395 | 1365 | /* supervisor mode -> force register file 0 */ |
| 1396 | 1366 | the_seg = 0; |
| 1397 | 1367 | |
| r20518 | r20519 | |
| 1420 | 1390 | && (m_bad_parity_table[address >> 3] & (0x3 << (address & 0x7)))) |
| 1421 | 1391 | { |
| 1422 | 1392 | m_mem_err_addr_latch = address >> 5; |
| 1423 | | set_parity_error_pending(machine(), 1); |
| 1393 | set_parity_error_pending(1); |
| 1424 | 1394 | } |
| 1425 | 1395 | |
| 1426 | 1396 | break; |
| r20518 | r20519 | |
| 1438 | 1408 | && (m_bad_parity_table[address >> 3] & (0x3 << (address & 0x7)))) |
| 1439 | 1409 | { |
| 1440 | 1410 | m_mem_err_addr_latch = address >> 5; |
| 1441 | | set_parity_error_pending(machine(), 1); |
| 1411 | set_parity_error_pending(1); |
| 1442 | 1412 | } |
| 1443 | 1413 | |
| 1444 | 1414 | break; |
| r20518 | r20519 | |
| 1493 | 1463 | if ((time_in_frame >= 364) && (time_in_frame <= 375)) |
| 1494 | 1464 | { |
| 1495 | 1465 | answer = m_videoROM_ptr[m_videoROM_address|0x80] << 8; |
| 1496 | | logerror("reading1 %06X=%04x PC=%06x time=%d\n", address, answer, machine().device("maincpu")->safe_pc(), time_in_frame); |
| 1466 | logerror("reading1 %06X=%04x %s time=%d\n", address, answer, machine().describe_context(), time_in_frame); |
| 1497 | 1467 | } |
| 1498 | 1468 | else |
| 1499 | 1469 | { |
| 1500 | 1470 | answer = m_videoROM_ptr[m_videoROM_address] << 8; |
| 1501 | | logerror("reading2 %06X=%04x PC=%06x time=%d\n", address, answer, machine().device("maincpu")->safe_pc(), time_in_frame); |
| 1471 | logerror("reading2 %06X=%04x %s time=%d\n", address, answer, machine().describe_context(), time_in_frame); |
| 1502 | 1472 | } |
| 1503 | 1473 | } |
| 1504 | 1474 | |
| r20518 | r20519 | |
| 1597 | 1567 | } |
| 1598 | 1568 | } |
| 1599 | 1569 | |
| 1600 | | if (machine().device("maincpu")->state().state_int(M68K_SR) & 0x2000) |
| 1570 | if (m_maincpu->state_int(M68K_SR) & 0x2000) |
| 1601 | 1571 | /* supervisor mode -> force register file 0 */ |
| 1602 | 1572 | the_seg = 0; |
| 1603 | 1573 | |
| r20518 | r20519 | |
| 1728 | 1698 | * * |
| 1729 | 1699 | \**************************************************************************************/ |
| 1730 | 1700 | |
| 1731 | | INLINE void cpu_board_control_access(running_machine &machine, offs_t offset) |
| 1701 | void lisa_state::cpu_board_control_access(offs_t offset) |
| 1732 | 1702 | { |
| 1733 | | lisa_state *state = machine.driver_data<lisa_state>(); |
| 1734 | 1703 | switch ((offset & 0x03ff) << 1) |
| 1735 | 1704 | { |
| 1736 | 1705 | case 0x0002: /* Set DIAG1 Latch */ |
| 1737 | 1706 | case 0x0000: /* Reset DIAG1 Latch */ |
| 1738 | 1707 | break; |
| 1739 | 1708 | case 0x0006: /* Set Diag2 Latch */ |
| 1740 | | state->m_diag2 = 1; |
| 1709 | m_diag2 = 1; |
| 1741 | 1710 | break; |
| 1742 | 1711 | case 0x0004: /* ReSet Diag2 Latch */ |
| 1743 | | state->m_diag2 = 0; |
| 1712 | m_diag2 = 0; |
| 1744 | 1713 | break; |
| 1745 | 1714 | case 0x000A: /* SEG1 Context Selection bit SET */ |
| 1746 | 1715 | /*logerror("seg bit 0 set\n");*/ |
| 1747 | | state->m_seg |= 1; |
| 1716 | m_seg |= 1; |
| 1748 | 1717 | break; |
| 1749 | 1718 | case 0x0008: /* SEG1 Context Selection bit RESET */ |
| 1750 | 1719 | /*logerror("seg bit 0 clear\n");*/ |
| 1751 | | state->m_seg &= ~1; |
| 1720 | m_seg &= ~1; |
| 1752 | 1721 | break; |
| 1753 | 1722 | case 0x000E: /* SEG2 Context Selection bit SET */ |
| 1754 | 1723 | /*logerror("seg bit 1 set\n");*/ |
| 1755 | | state->m_seg |= 2; |
| 1724 | m_seg |= 2; |
| 1756 | 1725 | break; |
| 1757 | 1726 | case 0x000C: /* SEG2 Context Selection bit RESET */ |
| 1758 | 1727 | /*logerror("seg bit 1 clear\n");*/ |
| 1759 | | state->m_seg &= ~2; |
| 1728 | m_seg &= ~2; |
| 1760 | 1729 | break; |
| 1761 | 1730 | case 0x0010: /* SETUP register SET */ |
| 1762 | | logerror("setup SET PC=%x\n", machine.device("maincpu")->safe_pc()); |
| 1763 | | state->m_setup = 1; |
| 1731 | logerror("setup SET %s\n", machine().describe_context()); |
| 1732 | m_setup = 1; |
| 1764 | 1733 | break; |
| 1765 | 1734 | case 0x0012: /* SETUP register RESET */ |
| 1766 | | logerror("setup UNSET PC=%x\n", machine.device("maincpu")->safe_pc()); |
| 1767 | | state->m_setup = 0; |
| 1735 | logerror("setup UNSET %s\n", machine().describe_context()); |
| 1736 | m_setup = 0; |
| 1768 | 1737 | break; |
| 1769 | 1738 | case 0x001A: /* Enable Vertical Retrace Interrupt */ |
| 1770 | | logerror("enable retrace PC=%x\n", machine.device("maincpu")->safe_pc()); |
| 1771 | | state->m_VTMSK = 1; |
| 1739 | logerror("enable retrace %s\n", machine().describe_context()); |
| 1740 | m_VTMSK = 1; |
| 1772 | 1741 | break; |
| 1773 | 1742 | case 0x0018: /* Disable Vertical Retrace Interrupt */ |
| 1774 | | logerror("disable retrace PC=%x\n", machine.device("maincpu")->safe_pc()); |
| 1775 | | state->m_VTMSK = 0; |
| 1776 | | set_VTIR(machine, 2); |
| 1743 | logerror("disable retrace %s\n", machine().describe_context()); |
| 1744 | m_VTMSK = 0; |
| 1745 | set_VTIR(2); |
| 1777 | 1746 | break; |
| 1778 | 1747 | case 0x0016: /* Enable Soft Error Detect. */ |
| 1779 | 1748 | case 0x0014: /* Disable Soft Error Detect. */ |
| 1780 | 1749 | break; |
| 1781 | 1750 | case 0x001E: /* Enable Hard Error Detect */ |
| 1782 | | state->m_test_parity = 1; |
| 1751 | m_test_parity = 1; |
| 1783 | 1752 | break; |
| 1784 | 1753 | case 0x001C: /* Disable Hard Error Detect */ |
| 1785 | | state->m_test_parity = 0; |
| 1786 | | set_parity_error_pending(machine, 0); |
| 1754 | m_test_parity = 0; |
| 1755 | set_parity_error_pending(0); |
| 1787 | 1756 | break; |
| 1788 | 1757 | } |
| 1789 | 1758 | } |
| 1790 | 1759 | |
| 1791 | 1760 | READ16_MEMBER(lisa_state::lisa_IO_r) |
| 1792 | 1761 | { |
| 1793 | | via6522_device *via_0 = machine().device<via6522_device>("via6522_0"); |
| 1794 | | via6522_device *via_1 = machine().device<via6522_device>("via6522_1"); |
| 1795 | 1762 | int answer=0; |
| 1796 | 1763 | |
| 1797 | 1764 | switch ((offset & 0x7000) >> 12) |
| r20518 | r20519 | |
| 1841 | 1808 | case 2: /* parallel port */ |
| 1842 | 1809 | /* 1 VIA located at 0xD901 */ |
| 1843 | 1810 | if (ACCESSING_BITS_0_7) |
| 1844 | | answer = via_1->read(space, (offset >> 2) & 0xf); |
| 1811 | answer = m_via1->read(space, (offset >> 2) & 0xf); |
| 1845 | 1812 | break; |
| 1846 | 1813 | |
| 1847 | 1814 | case 3: /* keyboard/mouse cops via */ |
| 1848 | 1815 | /* 1 VIA located at 0xDD81 */ |
| 1849 | 1816 | if (ACCESSING_BITS_0_7) |
| 1850 | | answer = via_0->read(space, offset & 0xf); |
| 1817 | answer = m_via0->read(space, offset & 0xf); |
| 1851 | 1818 | break; |
| 1852 | 1819 | } |
| 1853 | 1820 | } |
| r20518 | r20519 | |
| 1858 | 1825 | switch ((offset & 0x0C00) >> 10) |
| 1859 | 1826 | { |
| 1860 | 1827 | case 0x0: /* cpu board control */ |
| 1861 | | cpu_board_control_access(machine(), offset & 0x03ff); |
| 1828 | cpu_board_control_access(offset & 0x03ff); |
| 1862 | 1829 | break; |
| 1863 | 1830 | |
| 1864 | 1831 | case 0x1: /* Video Address Latch */ |
| r20518 | r20519 | |
| 1905 | 1872 | else |
| 1906 | 1873 | answer |= 0x04; |
| 1907 | 1874 | /* huh... we need to emulate some other bits */ |
| 1908 | | logerror("read status PC=%x val=%x\n", machine().device("maincpu")->safe_pc(), answer); |
| 1875 | logerror("read status %s val=%x\n", machine().describe_context(), answer); |
| 1909 | 1876 | |
| 1910 | 1877 | break; |
| 1911 | 1878 | } |
| r20518 | r20519 | |
| 1917 | 1884 | |
| 1918 | 1885 | WRITE16_MEMBER(lisa_state::lisa_IO_w) |
| 1919 | 1886 | { |
| 1920 | | via6522_device *via_0 = machine().device<via6522_device>("via6522_0"); |
| 1921 | | via6522_device *via_1 = machine().device<via6522_device>("via6522_1"); |
| 1922 | | |
| 1923 | 1887 | switch ((offset & 0x7000) >> 12) |
| 1924 | 1888 | { |
| 1925 | 1889 | case 0x0: |
| r20518 | r20519 | |
| 1967 | 1931 | |
| 1968 | 1932 | case 2: /* paralel port */ |
| 1969 | 1933 | if (ACCESSING_BITS_0_7) |
| 1970 | | via_1->write(space, (offset >> 2) & 0xf, data & 0xff); |
| 1934 | m_via1->write(space, (offset >> 2) & 0xf, data & 0xff); |
| 1971 | 1935 | break; |
| 1972 | 1936 | |
| 1973 | 1937 | case 3: /* keyboard/mouse cops via */ |
| 1974 | 1938 | if (ACCESSING_BITS_0_7) |
| 1975 | | via_0->write(space, offset & 0xf, data & 0xff); |
| 1939 | m_via0->write(space, offset & 0xf, data & 0xff); |
| 1976 | 1940 | break; |
| 1977 | 1941 | } |
| 1978 | 1942 | } |
| r20518 | r20519 | |
| 1983 | 1947 | switch ((offset & 0x0C00) >> 10) |
| 1984 | 1948 | { |
| 1985 | 1949 | case 0x0: /* cpu board control */ |
| 1986 | | cpu_board_control_access(machine(), offset & 0x03ff); |
| 1950 | cpu_board_control_access(offset & 0x03ff); |
| 1987 | 1951 | break; |
| 1988 | 1952 | |
| 1989 | 1953 | case 0x1: /* Video Address Latch */ |