src/mess/drivers/mpf1.c
| r6531 | r6532 | |
| 12 | 12 | |
| 13 | 13 | /* |
| 14 | 14 | |
| 15 | | Artwork picture downloaded from: |
| 16 | | |
| 17 | | http://members.lycos.co.uk/leeedavison/z80/mpf1/ |
| 18 | | |
| 19 | | */ |
| 20 | | |
| 21 | | /* |
| 22 | | |
| 23 | 15 | TODO: |
| 24 | 16 | |
| 17 | - mpf1b doesn't use artwork for some reason |
| 18 | - remove halt callback |
| 25 | 19 | - crt board |
| 26 | 20 | - speech board |
| 27 | 21 | - printers |
| 28 | | - intr key |
| 29 | | - moni key |
| 30 | | - |
| 22 | - clickable artwork |
| 31 | 23 | |
| 32 | 24 | */ |
| 33 | 25 | |
| r6531 | r6532 | |
| 86 | 78 | |
| 87 | 79 | /* Input Ports */ |
| 88 | 80 | |
| 81 | static INPUT_CHANGED( trigger_nmi ) |
| 82 | { |
| 83 | cputag_set_input_line(field->port->machine, Z80_TAG, INPUT_LINE_NMI, newval ? CLEAR_LINE : ASSERT_LINE); |
| 84 | } |
| 85 | |
| 86 | static INPUT_CHANGED( trigger_irq ) |
| 87 | { |
| 88 | cputag_set_input_line(field->port->machine, Z80_TAG, INPUT_LINE_IRQ0, newval ? CLEAR_LINE : ASSERT_LINE); |
| 89 | } |
| 90 | |
| 89 | 91 | static INPUT_PORTS_START( mpf1 ) |
| 90 | 92 | PORT_START("PC0") |
| 91 | 93 | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3 HL") PORT_CODE(KEYCODE_3) |
| r6531 | r6532 | |
| 137 | 139 | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("MOVE") PORT_CODE(KEYCODE_QUOTE) |
| 138 | 140 | PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED) |
| 139 | 141 | |
| 140 | | PORT_START("user") |
| 141 | | PORT_BIT(0x3f, IP_ACTIVE_LOW, IPT_UNUSED) |
| 142 | | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("USER KEY") PORT_CODE(KEYCODE_U) |
| 143 | | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) |
| 144 | | |
| 145 | | PORT_START("extra") // interrupt keys |
| 146 | | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("MONI") PORT_CODE(KEYCODE_M) // causes NMI ? |
| 147 | | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("INTR") PORT_CODE(KEYCODE_I) // causes INT |
| 142 | PORT_START("SPECIAL") |
| 143 | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("USER KEY") PORT_CODE(KEYCODE_U) |
| 144 | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("MONI") PORT_CODE(KEYCODE_M) PORT_CHANGED(trigger_nmi, 0) |
| 145 | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("INTR") PORT_CODE(KEYCODE_I) PORT_CHANGED(trigger_irq, 0) |
| 148 | 146 | INPUT_PORTS_END |
| 149 | 147 | |
| 150 | 148 | static INPUT_PORTS_START( mpf1b ) |
| r6531 | r6532 | |
| 198 | 196 | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL/left") PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_LEFT) |
| 199 | 197 | PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED) |
| 200 | 198 | |
| 201 | | PORT_START("user") |
| 202 | | PORT_BIT(0x3f, IP_ACTIVE_LOW, IPT_UNUSED) |
| 203 | | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) |
| 204 | | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) |
| 205 | | |
| 206 | | PORT_START("extra") // interrupt keys |
| 207 | | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("MONI") PORT_CODE(KEYCODE_M) // causes NMI ? |
| 208 | | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("INTR") PORT_CODE(KEYCODE_I) // causes INT |
| 199 | PORT_START("SPECIAL") |
| 200 | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("USER KEY") PORT_CODE(KEYCODE_U) |
| 201 | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("MONI") PORT_CODE(KEYCODE_M) PORT_CHANGED(trigger_nmi, 0) |
| 202 | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("INTR") PORT_CODE(KEYCODE_I) PORT_CHANGED(trigger_irq, 0) |
| 209 | 203 | INPUT_PORTS_END |
| 210 | 204 | |
| 211 | 205 | /* Intel 8255A Interface */ |
| r6531 | r6532 | |
| 236 | 230 | if (!BIT(state->lednum, 5)) data &= input_port_read(device->machine, "PC5"); |
| 237 | 231 | |
| 238 | 232 | /* bit 6, user key */ |
| 239 | | data &= input_port_read(device->machine, "user"); |
| 233 | data &= BIT(input_port_read(device->machine, "SPECIAL"), 0) << 6; |
| 240 | 234 | |
| 241 | 235 | /* bit 7, tape input */ |
| 242 | 236 | data |= (cassette_input(state->cassette) > 0 ? 1 : 0) << 7; |
| r6531 | r6532 | |
| 264 | 258 | timer_adjust_oneshot(state->led_refresh_timer, attotime_never, 0); |
| 265 | 259 | |
| 266 | 260 | /* bit 6, monitor break control */ |
| 261 | state->_break = BIT(data, 6); |
| 267 | 262 | |
| 263 | if (state->_break) |
| 264 | { |
| 265 | state->m1 = 0; |
| 266 | cputag_set_input_line(device->machine, Z80_TAG, INPUT_LINE_NMI, CLEAR_LINE); |
| 267 | } |
| 268 | |
| 268 | 269 | /* bit 7, tape output, tone and led */ |
| 269 | 270 | set_led_status(device->machine, 0, !BIT(data, 7)); |
| 270 | 271 | speaker_level_w(state->speaker, BIT(data, 7)); |
| r6531 | r6532 | |
| 345 | 346 | set_led_status(machine, 1, led_halt); |
| 346 | 347 | } |
| 347 | 348 | |
| 348 | | static TIMER_CALLBACK( irq0_callback ) |
| 349 | | { |
| 350 | | irq0_line_hold( cputag_get_cpu(machine, Z80_TAG) ); |
| 351 | | } |
| 352 | | |
| 353 | 349 | static MACHINE_START( mpf1 ) |
| 354 | 350 | { |
| 355 | 351 | mpf1_state *state = machine->driver_data; |
| r6531 | r6532 | |
| 361 | 357 | state->led_refresh_timer = timer_alloc(machine, led_refresh, 0); |
| 362 | 358 | |
| 363 | 359 | /* register for state saving */ |
| 360 | state_save_register_global(machine, state->_break); |
| 361 | state_save_register_global(machine, state->m1); |
| 364 | 362 | state_save_register_global(machine, state->lednum); |
| 365 | 363 | } |
| 366 | 364 | |
| r6531 | r6532 | |
| 370 | 368 | |
| 371 | 369 | state->lednum = 0; |
| 372 | 370 | |
| 373 | | timer_pulse(machine, ATTOTIME_IN_HZ(1), NULL, 0, check_halt_callback ); |
| 374 | | timer_pulse(machine, ATTOTIME_IN_HZ(60), NULL, 0, irq0_callback ); |
| 371 | timer_pulse(machine, ATTOTIME_IN_HZ(1), NULL, 0, check_halt_callback); |
| 375 | 372 | } |
| 376 | 373 | |
| 377 | 374 | /* Machine Drivers */ |
| r6531 | r6532 | |
| 484 | 481 | |
| 485 | 482 | /* System Drivers */ |
| 486 | 483 | |
| 487 | | COMP( 1979, mpf1, 0, 0, mpf1, mpf1, 0, 0, "Multitech", "Micro Professor 1", 0) |
| 488 | | COMP( 1979, mpf1b, mpf1, 0, mpf1b,mpf1b, 0, 0, "Multitech", "Micro Professor 1B", 0) |
| 489 | | COMP( 1982, mpf1p, mpf1, 0, mpf1p,mpf1b, 0, 0, "Multitech", "Micro Professor 1 Plus", GAME_NOT_WORKING) |
| 484 | static DIRECT_UPDATE_HANDLER( mpf1_direct_update_handler ) |
| 485 | { |
| 486 | mpf1_state *state = space->machine->driver_data; |
| 487 | |
| 488 | if (!state->_break) |
| 489 | { |
| 490 | state->m1++; |
| 491 | |
| 492 | if (state->m1 == 5) |
| 493 | { |
| 494 | cputag_set_input_line(space->machine, Z80_TAG, INPUT_LINE_NMI, ASSERT_LINE); |
| 495 | } |
| 496 | } |
| 497 | |
| 498 | return 0; |
| 499 | } |
| 500 | |
| 501 | static DRIVER_INIT( mpf1 ) |
| 502 | { |
| 503 | memory_set_direct_update_handler(cputag_get_address_space(machine, Z80_TAG, ADDRESS_SPACE_PROGRAM), mpf1_direct_update_handler); |
| 504 | } |
| 505 | |
| 506 | COMP( 1979, mpf1, 0, 0, mpf1, mpf1, mpf1, 0, "Multitech", "Micro Professor 1", 0) |
| 507 | COMP( 1979, mpf1b, mpf1, 0, mpf1b,mpf1b, mpf1, 0, "Multitech", "Micro Professor 1B", 0) |
| 508 | COMP( 1982, mpf1p, mpf1, 0, mpf1p,mpf1b, mpf1, 0, "Multitech", "Micro Professor 1 Plus", GAME_NOT_WORKING) |