trunk/src/mess/drivers/pt68k4.c
| r32236 | r32237 | |
| 2 | 2 | // copyright-holders:Robbbert, R. Belmont |
| 3 | 3 | /*************************************************************************** |
| 4 | 4 | |
| 5 | | Peripheral Technology PT68K4 |
| 5 | Peripheral Technology PT68K2/PT68K4 family |
| 6 | 6 | |
| 7 | 7 | 2011-01-03 Skeleton driver. |
| 8 | 8 | 2013-09-30 Connected to a terminal |
| 9 | 9 | 2014-01-03 Connect real DUARTs, FDC, and TimeKeeper. Settings now save properly, floppies can be read. |
| 10 | 10 | 2014-01-19 ISA bus and compatible cards, PC keyboard support, speaker support |
| 11 | | |
| 11 | 2014-09-20 Add PT68K2, add save states, we have a working SK*DOS disk! |
| 12 | |
| 12 | 13 | This has the appearance of a PC, including pc power supply, slots, etc |
| 13 | 14 | on a conventional pc-like motherboard and case. |
| 14 | 15 | |
| 15 | 16 | Some pics: http://www.wormfood.net/old_computers/ |
| 16 | | |
| 17 | |
| 18 | Source code and manuals for the HUMBUG BIOS and SK*DOS are at: |
| 19 | http://www.users.cloud9.net/~stark/sources.html |
| 20 | |
| 21 | Usage: |
| 22 | Start up and press Enter as prompted. Type he to see a command list, or fd to boot from the |
| 23 | first floppy drive. |
| 24 | |
| 25 | The stock NVRAM configures PT68k2 for 2 DSDD 5.25" drives, and PT68k4 for 2 DSHD 5.25" drives. |
| 26 | |
| 17 | 27 | Chips: |
| 18 | 28 | 68230 Parallel Interface/Timer @ FE0081 |
| 19 | 29 | 68681 DUART/Timer (x2) @ FE0001 and FE0041 |
| r32236 | r32237 | |
| 38 | 48 | 5: DUART1 |
| 39 | 49 | 6: PC FDC IRQ |
| 40 | 50 | |
| 41 | | TODO: 68230 device. Better hardware documentation would be nice too, and working OS disks. |
| 42 | | |
| 51 | TODO: 68230 device |
| 52 | This system and SK*DOS don't like our ISA WDXT-GEN emulation so HDD installs are not currently possible. |
| 53 | |
| 43 | 54 | ****************************************************************************/ |
| 44 | 55 | |
| 45 | 56 | #include "emu.h" |
| 46 | 57 | #include "cpu/m68000/m68000.h" |
| 47 | 58 | #include "machine/mc68681.h" |
| 48 | 59 | #include "machine/timekpr.h" |
| 60 | #include "machine/wd_fdc.h" |
| 49 | 61 | #include "machine/pc_fdc.h" |
| 50 | 62 | #include "formats/imd_dsk.h" |
| 51 | 63 | #include "bus/isa/isa.h" |
| r32236 | r32237 | |
| 61 | 73 | #define ISABUS_TAG "isa" |
| 62 | 74 | #define KBDC_TAG "pc_kbdc" |
| 63 | 75 | #define SPEAKER_TAG "speaker" |
| 76 | #define WDFDC_TAG "wdfdc" |
| 64 | 77 | |
| 65 | 78 | class pt68k4_state : public driver_device |
| 66 | 79 | { |
| r32236 | r32237 | |
| 73 | 86 | , m_duart2(*this, DUART2_TAG) |
| 74 | 87 | , m_isa(*this, ISABUS_TAG) |
| 75 | 88 | , m_speaker(*this, SPEAKER_TAG) |
| 89 | , m_wdfdc(*this, WDFDC_TAG) |
| 76 | 90 | { } |
| 77 | 91 | |
| 78 | 92 | DECLARE_READ8_MEMBER(hiram_r); |
| r32236 | r32237 | |
| 80 | 94 | DECLARE_READ8_MEMBER(keyboard_r); |
| 81 | 95 | DECLARE_WRITE8_MEMBER(keyboard_w); |
| 82 | 96 | |
| 97 | DECLARE_READ8_MEMBER(pia_stub_r); |
| 83 | 98 | DECLARE_WRITE8_MEMBER(duart1_out); |
| 84 | 99 | |
| 100 | DECLARE_WRITE8_MEMBER(fdc_select_w); |
| 101 | |
| 85 | 102 | DECLARE_WRITE_LINE_MEMBER(duart1_irq); |
| 86 | 103 | DECLARE_WRITE_LINE_MEMBER(duart2_irq); |
| 87 | 104 | |
| 105 | DECLARE_WRITE_LINE_MEMBER(irq5_w); |
| 106 | |
| 88 | 107 | DECLARE_WRITE_LINE_MEMBER(keyboard_clock_w); |
| 89 | 108 | DECLARE_WRITE_LINE_MEMBER(keyboard_data_w); |
| 90 | 109 | |
| 110 | DECLARE_FLOPPY_FORMATS( floppy_formats ); |
| 111 | |
| 91 | 112 | private: |
| 113 | virtual void machine_start(); |
| 92 | 114 | virtual void machine_reset(); |
| 93 | 115 | required_shared_ptr<UINT16> m_p_base; |
| 94 | 116 | required_device<cpu_device> m_maincpu; |
| r32236 | r32237 | |
| 96 | 118 | required_device<mc68681_device> m_duart2; |
| 97 | 119 | required_device<isa8_device> m_isa; |
| 98 | 120 | required_device<speaker_sound_device> m_speaker; |
| 121 | optional_device<wd1772_t> m_wdfdc; |
| 99 | 122 | |
| 123 | void irq5_update(); |
| 124 | |
| 100 | 125 | UINT8 m_hiram[0x800]; |
| 101 | 126 | |
| 102 | 127 | bool m_kclk; |
| r32236 | r32237 | |
| 104 | 129 | UINT8 m_scancode; |
| 105 | 130 | UINT8 m_kbdflag; |
| 106 | 131 | int m_kbit; |
| 132 | int m_lastdrive; |
| 133 | bool m_irq5_duart1, m_irq5_isa; |
| 107 | 134 | }; |
| 108 | 135 | |
| 136 | FLOPPY_FORMATS_MEMBER( pt68k4_state::floppy_formats ) |
| 137 | FLOPPY_IMD_FORMAT |
| 138 | FLOPPY_FORMATS_END |
| 139 | |
| 140 | static SLOT_INTERFACE_START( pt68k_floppies ) |
| 141 | SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) |
| 142 | SLOT_INTERFACE_END |
| 143 | |
| 109 | 144 | // XT keyboard interface - done in TTL instead of an 804x |
| 110 | 145 | WRITE_LINE_MEMBER(pt68k4_state::keyboard_clock_w) |
| 111 | 146 | { |
| r32236 | r32237 | |
| 148 | 183 | m_speaker->level_w((data >> 3) & 1); |
| 149 | 184 | } |
| 150 | 185 | |
| 186 | READ8_MEMBER(pt68k4_state::pia_stub_r) |
| 187 | { |
| 188 | return 0; |
| 189 | } |
| 190 | |
| 191 | WRITE8_MEMBER(pt68k4_state::fdc_select_w) |
| 192 | { |
| 193 | floppy_connector *con = machine().device<floppy_connector>(WDFDC_TAG":0"); |
| 194 | floppy_connector *con2 = machine().device<floppy_connector>(WDFDC_TAG":1"); |
| 195 | floppy_image_device *floppy = con ? con->get_device() : 0; |
| 196 | floppy_image_device *floppy2 = con2 ? con2->get_device() : 0; |
| 197 | int drive = data & 3; |
| 198 | |
| 199 | if (drive != m_lastdrive) |
| 200 | { |
| 201 | switch (drive) |
| 202 | { |
| 203 | case 0: |
| 204 | m_wdfdc->set_floppy(floppy); |
| 205 | break; |
| 206 | |
| 207 | case 1: |
| 208 | m_wdfdc->set_floppy(floppy2); |
| 209 | break; |
| 210 | |
| 211 | default: |
| 212 | m_wdfdc->set_floppy(NULL); |
| 213 | break; |
| 214 | } |
| 215 | |
| 216 | m_lastdrive = drive; |
| 217 | } |
| 218 | |
| 219 | switch (drive) |
| 220 | { |
| 221 | case 0: |
| 222 | floppy->ss_w((data & 0x40) ? 1 : 0); |
| 223 | break; |
| 224 | |
| 225 | case 1: |
| 226 | floppy2->ss_w((data & 0x40) ? 1 : 0); |
| 227 | break; |
| 228 | |
| 229 | default: |
| 230 | break; |
| 231 | } |
| 232 | } |
| 233 | |
| 234 | static ADDRESS_MAP_START(pt68k2_mem, AS_PROGRAM, 16, pt68k4_state) |
| 235 | ADDRESS_MAP_UNMAP_HIGH |
| 236 | AM_RANGE(0x000000, 0x0fffff) AM_RAM AM_SHARE("rambase") // 1MB RAM |
| 237 | AM_RANGE(0xf80000, 0xf8ffff) AM_ROM AM_REGION("roms", 0) |
| 238 | AM_RANGE(0xc00000, 0xdfffff) AM_DEVREADWRITE8(ISABUS_TAG, isa8_device, prog_r, prog_w, 0x00ff) |
| 239 | AM_RANGE(0xfa0000, 0xfbffff) AM_DEVREADWRITE8(ISABUS_TAG, isa8_device, io_r, io_w, 0x00ff) |
| 240 | AM_RANGE(0xfe0000, 0xfe001f) AM_DEVREADWRITE8(DUART1_TAG, mc68681_device, read, write, 0x00ff) |
| 241 | AM_RANGE(0xfe0040, 0xfe005f) AM_DEVREADWRITE8(DUART2_TAG, mc68681_device, read, write, 0x00ff) |
| 242 | AM_RANGE(0xfe0080, 0xfe00bf) AM_READ8(pia_stub_r, 0x00ff) |
| 243 | AM_RANGE(0xfe00c0, 0xfe00ff) AM_WRITE8(fdc_select_w, 0x00ff) |
| 244 | AM_RANGE(0xfe0100, 0xfe013f) AM_DEVREADWRITE8(WDFDC_TAG, wd1772_t, read, write, 0x00ff) |
| 245 | AM_RANGE(0xfe01c0, 0xfe01c3) AM_READWRITE8(keyboard_r, keyboard_w, 0x00ff) |
| 246 | AM_RANGE(0xff0000, 0xff0fff) AM_READWRITE8(hiram_r, hiram_w, 0xff00) |
| 247 | AM_RANGE(0xff0000, 0xff0fff) AM_DEVREADWRITE8(TIMEKEEPER_TAG, timekeeper_device, read, write, 0x00ff) |
| 248 | ADDRESS_MAP_END |
| 249 | |
| 151 | 250 | static ADDRESS_MAP_START(pt68k4_mem, AS_PROGRAM, 16, pt68k4_state) |
| 152 | 251 | ADDRESS_MAP_UNMAP_HIGH |
| 153 | 252 | AM_RANGE(0x000000, 0x0fffff) AM_RAM AM_SHARE("rambase") // 1MB RAM (OS9 needs more) |
| r32236 | r32237 | |
| 197 | 296 | m_hiram[offset] = data; |
| 198 | 297 | } |
| 199 | 298 | |
| 299 | void pt68k4_state::machine_start() |
| 300 | { |
| 301 | save_item(NAME(m_hiram)); |
| 302 | save_item(NAME(m_kclk)); |
| 303 | save_item(NAME(m_kdata)); |
| 304 | save_item(NAME(m_scancode)); |
| 305 | save_item(NAME(m_kbdflag)); |
| 306 | save_item(NAME(m_kbit)); |
| 307 | save_item(NAME(m_lastdrive)); |
| 308 | save_item(NAME(m_irq5_duart1)); |
| 309 | save_item(NAME(m_irq5_isa)); |
| 310 | } |
| 311 | |
| 200 | 312 | void pt68k4_state::machine_reset() |
| 201 | 313 | { |
| 202 | 314 | UINT8* user1 = memregion("roms")->base(); |
| r32236 | r32237 | |
| 208 | 320 | m_kbit = 0; |
| 209 | 321 | m_scancode = 0; |
| 210 | 322 | m_kbdflag = 0; |
| 323 | m_irq5_duart1 = CLEAR_LINE; |
| 324 | m_irq5_isa = CLEAR_LINE; |
| 211 | 325 | |
| 212 | 326 | // set line to asserted (no key code ready) |
| 213 | 327 | m_duart1->ip2_w(ASSERT_LINE); |
| 328 | |
| 329 | if (m_wdfdc) |
| 330 | { |
| 331 | floppy_connector *con = machine().device<floppy_connector>(WDFDC_TAG":0"); |
| 332 | floppy_image_device *floppy = con ? con->get_device() : 0; |
| 333 | |
| 334 | m_wdfdc->set_floppy(floppy); |
| 335 | floppy->ss_w(0); |
| 336 | |
| 337 | m_lastdrive = 0; |
| 338 | } |
| 214 | 339 | } |
| 215 | 340 | |
| 341 | void pt68k4_state::irq5_update() |
| 342 | { |
| 343 | if ((m_irq5_duart1) || (m_irq5_isa)) |
| 344 | { |
| 345 | m_maincpu->set_input_line(M68K_IRQ_5, ASSERT_LINE); |
| 346 | } |
| 347 | else |
| 348 | { |
| 349 | m_maincpu->set_input_line(M68K_IRQ_5, CLEAR_LINE); |
| 350 | } |
| 351 | } |
| 352 | |
| 216 | 353 | WRITE_LINE_MEMBER(pt68k4_state::duart1_irq) |
| 217 | 354 | { |
| 218 | | m_maincpu->set_input_line(M68K_IRQ_5, state); |
| 355 | m_irq5_duart1 = state; |
| 356 | irq5_update(); |
| 219 | 357 | } |
| 220 | 358 | |
| 359 | WRITE_LINE_MEMBER(pt68k4_state::irq5_w) |
| 360 | { |
| 361 | m_irq5_isa = state; |
| 362 | irq5_update(); |
| 363 | } |
| 364 | |
| 221 | 365 | WRITE_LINE_MEMBER(pt68k4_state::duart2_irq) |
| 222 | 366 | { |
| 223 | 367 | m_maincpu->set_input_line(M68K_IRQ_4, state); |
| r32236 | r32237 | |
| 235 | 379 | SLOT_INTERFACE("xtide", ISA8_XTIDE) // Monk only |
| 236 | 380 | SLOT_INTERFACE_END |
| 237 | 381 | |
| 382 | static MACHINE_CONFIG_START( pt68k2, pt68k4_state ) |
| 383 | /* basic machine hardware */ |
| 384 | MCFG_CPU_ADD(M68K_TAG, M68000, XTAL_16MHz/2) // 68k2 came in 8, 10, and 12 MHz versions |
| 385 | MCFG_CPU_PROGRAM_MAP(pt68k2_mem) |
| 386 | |
| 387 | MCFG_MC68681_ADD("duart1", XTAL_3_6864MHz) |
| 388 | MCFG_MC68681_IRQ_CALLBACK(WRITELINE(pt68k4_state, duart1_irq)) |
| 389 | MCFG_MC68681_OUTPORT_CALLBACK(WRITE8(pt68k4_state, duart1_out)) |
| 390 | |
| 391 | MCFG_MC68681_ADD("duart2", XTAL_3_6864MHz) |
| 392 | |
| 393 | MCFG_DEVICE_ADD(KBDC_TAG, PC_KBDC, 0) |
| 394 | MCFG_PC_KBDC_OUT_CLOCK_CB(WRITELINE(pt68k4_state, keyboard_clock_w)) |
| 395 | MCFG_PC_KBDC_OUT_DATA_CB(WRITELINE(pt68k4_state, keyboard_data_w)) |
| 396 | MCFG_PC_KBDC_SLOT_ADD(KBDC_TAG, "kbd", pc_xt_keyboards, STR_KBD_IBM_PC_XT_83) |
| 397 | |
| 398 | MCFG_M48T02_ADD(TIMEKEEPER_TAG) |
| 399 | |
| 400 | MCFG_WD1772x_ADD(WDFDC_TAG, XTAL_16MHz / 2) |
| 401 | MCFG_FLOPPY_DRIVE_ADD(WDFDC_TAG":0", pt68k_floppies, "525dd", pt68k4_state::floppy_formats) |
| 402 | MCFG_FLOPPY_DRIVE_ADD(WDFDC_TAG":1", pt68k_floppies, "525dd", pt68k4_state::floppy_formats) |
| 403 | |
| 404 | MCFG_DEVICE_ADD(ISABUS_TAG, ISA8, 0) |
| 405 | MCFG_ISA8_CPU(":"M68K_TAG) |
| 406 | MCFG_ISA8_BUS_CUSTOM_SPACES() |
| 407 | MCFG_ISA_OUT_IRQ5_CB(WRITELINE(pt68k4_state, irq5_w)) |
| 408 | MCFG_ISA8_SLOT_ADD(ISABUS_TAG, "isa1", pt68k4_isa8_cards, "cga", false) |
| 409 | MCFG_ISA8_SLOT_ADD(ISABUS_TAG, "isa2", pt68k4_isa8_cards, NULL, false) |
| 410 | MCFG_ISA8_SLOT_ADD(ISABUS_TAG, "isa3", pt68k4_isa8_cards, NULL, false) |
| 411 | MCFG_ISA8_SLOT_ADD(ISABUS_TAG, "isa4", pt68k4_isa8_cards, NULL, false) |
| 412 | MCFG_ISA8_SLOT_ADD(ISABUS_TAG, "isa5", pt68k4_isa8_cards, NULL, false) |
| 413 | MCFG_ISA8_SLOT_ADD(ISABUS_TAG, "isa6", pt68k4_isa8_cards, NULL, false) |
| 414 | |
| 415 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 416 | MCFG_SOUND_ADD(SPEAKER_TAG, SPEAKER_SOUND, 0) |
| 417 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) |
| 418 | |
| 419 | MCFG_SOFTWARE_LIST_ADD("flop525_list", "pt68k2") |
| 420 | MACHINE_CONFIG_END |
| 421 | |
| 238 | 422 | static MACHINE_CONFIG_START( pt68k4, pt68k4_state ) |
| 239 | 423 | /* basic machine hardware */ |
| 240 | 424 | MCFG_CPU_ADD(M68K_TAG, M68000, XTAL_16MHz) |
| r32236 | r32237 | |
| 258 | 442 | MCFG_ISA8_CPU(":"M68K_TAG) |
| 259 | 443 | MCFG_ISA8_BUS_CUSTOM_SPACES() |
| 260 | 444 | MCFG_ISA8_SLOT_ADD(ISABUS_TAG, "isa1", pt68k4_isa8_cards, "fdc_at", false) |
| 261 | | MCFG_ISA8_SLOT_ADD(ISABUS_TAG, "isa2", pt68k4_isa8_cards, "mda", false) |
| 262 | | MCFG_ISA8_SLOT_ADD(ISABUS_TAG, "isa3", pt68k4_isa8_cards, "wdxt_gen", false) |
| 445 | MCFG_ISA8_SLOT_ADD(ISABUS_TAG, "isa2", pt68k4_isa8_cards, "cga", false) |
| 446 | MCFG_ISA8_SLOT_ADD(ISABUS_TAG, "isa3", pt68k4_isa8_cards, NULL, false) |
| 263 | 447 | MCFG_ISA8_SLOT_ADD(ISABUS_TAG, "isa4", pt68k4_isa8_cards, NULL, false) |
| 264 | 448 | MCFG_ISA8_SLOT_ADD(ISABUS_TAG, "isa5", pt68k4_isa8_cards, NULL, false) |
| 265 | 449 | MCFG_ISA8_SLOT_ADD(ISABUS_TAG, "isa6", pt68k4_isa8_cards, NULL, false) |
| r32236 | r32237 | |
| 268 | 452 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 269 | 453 | MCFG_SOUND_ADD(SPEAKER_TAG, SPEAKER_SOUND, 0) |
| 270 | 454 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) |
| 455 | |
| 456 | MCFG_SOFTWARE_LIST_ADD("flop525_list", "pt68k2") |
| 271 | 457 | MACHINE_CONFIG_END |
| 272 | 458 | |
| 273 | 459 | /* ROM definition */ |
| 460 | ROM_START( pt68k2 ) |
| 461 | ROM_REGION16_BE( 0x10000, "roms", 0 ) |
| 462 | ROM_LOAD16_BYTE( "hum_u20.bin", 0x000000, 0x008000, CRC(69db483a) SHA1(9dfea73e4d7deef7c66a27cca92eb7c9ff767215) ) |
| 463 | ROM_LOAD16_BYTE( "hum_u27.bin", 0x000001, 0x008000, CRC(54441b06) SHA1(0e2d63b1cd01f88f37fc4859c11c252c4fea220b) ) |
| 464 | |
| 465 | ROM_REGION(0x800, TIMEKEEPER_TAG, 0) |
| 466 | ROM_LOAD( "u21_ds1220.bin", 0x000000, 0x000800, CRC(7a6b75ce) SHA1(07663860aa6cc21aed04a568ff9c05bc75d62e4f) ) |
| 467 | ROM_END |
| 468 | |
| 274 | 469 | ROM_START( pt68k4 ) |
| 275 | 470 | ROM_REGION16_BE( 0x10000, "roms", 0 ) |
| 276 | 471 | ROM_SYSTEM_BIOS( 0, "humbug", "Humbug" ) |
| r32236 | r32237 | |
| 280 | 475 | ROMX_LOAD( "monk_0.bin", 0x0000, 0x8000, CRC(420d6a4b) SHA1(fca8c53c9c3c8ebd09370499cf34f4cc75ed9463), ROM_SKIP(1) | ROM_BIOS(2)) |
| 281 | 476 | ROMX_LOAD( "monk_1.bin", 0x0001, 0x8000, CRC(fc495e82) SHA1(f7b720d87db4d72a23e6c42d2cdd03216db04b60), ROM_SKIP(1) | ROM_BIOS(2)) |
| 282 | 477 | |
| 478 | ROM_REGION(0x800, TIMEKEEPER_TAG, 0) |
| 479 | ROM_LOAD( "u21_ds1220_k4.bin", 0x000000, 0x000800, CRC(753472e6) SHA1(58dc8bcc86191e4a4429fe6a9b4fdd7788abb0cd) ) |
| 480 | |
| 283 | 481 | ROM_REGION( 0x0900, "proms", 0 ) |
| 284 | 482 | ROM_LOAD_OPTIONAL( "20l8.u71", 0x0000, 0x000149, CRC(77365121) SHA1(5ecf490ead119966a5c097d90740acde60462ab0) ) |
| 285 | 483 | ROM_LOAD_OPTIONAL( "16l8.u53", 0x0200, 0x000109, CRC(cb6a9984) SHA1(45b9b14e7b45cda6f0edfcbb9895b6a14eacb852) ) |
| r32236 | r32237 | |
| 289 | 487 | |
| 290 | 488 | /* Driver */ |
| 291 | 489 | /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ |
| 292 | | COMP( 1990, pt68k4, 0, 0, pt68k4, pt68k4, driver_device, 0, "Peripheral Technology", "PT68K4", GAME_NOT_WORKING ) |
| 490 | COMP( 1988, pt68k2, 0, 0, pt68k2, pt68k4, driver_device, 0, "Peripheral Technology", "PT68K2", GAME_SUPPORTS_SAVE ) |
| 491 | COMP( 1990, pt68k4, 0, 0, pt68k4, pt68k4, driver_device, 0, "Peripheral Technology", "PT68K4", GAME_SUPPORTS_SAVE ) |