trunk/src/mess/drivers/pt68k4.c
| r26929 | r26930 | |
| 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 | 11 | This has the appearance of a PC, including pc power supply, slots, etc |
| 11 | 12 | on a conventional pc-like motherboard and case. |
| 12 | 13 | |
| 13 | 14 | Some pics: http://www.wormfood.net/old_computers/ |
| 14 | 15 | |
| 15 | | Note: bios 0 works with the terminal. When first started, press Enter |
| 16 | | to get the logo. Enter HE to get a list of commands. Terminate |
| 17 | | numeric entries with a Space (not Enter!). |
| 16 | Note: bios 0 works with the terminal. When first started, set terminal |
| 17 | to 19200 baud and press Enter to get the logo. Enter HE to get a |
| 18 | list of commands. Terminate numeric entries with a Space (not Enter!). |
| 18 | 19 | |
| 20 | bios 1 works now too, but it's weird. Set the terminal to 2400 baud |
| 21 | then press F3 reset and hit a key or 2. When garbage starts spewing, |
| 22 | bump the terminal to 9600 baud and press "O Enter". The menu should appear. |
| 23 | |
| 19 | 24 | Chips: |
| 20 | | 68230 Parallel Interface/Timer @ FE0080 |
| 21 | | 68681 DUART/Timer (x2) @ FE0000 and FE0040 |
| 22 | | WD37C65 FDC @ FE0101/3/etc (compatible with PC NEC765) |
| 23 | | Floppy drive select @ FE00C1: bits 0/1 drive select 0-3, bit 5 = 1 for double density, bit 6 = side select |
| 24 | | MK48T02 TimeKeeper @ FF0FF1/3/5/etc. |
| 25 | 68230 Parallel Interface/Timer @ FE0081 |
| 26 | 68681 DUART/Timer (x2) @ FE0001 and FE0041 |
| 27 | WD37C65 FDC (PC FDC compatible, even mapped as an ISA device) |
| 28 | MK48T02 TimeKeeper @ odd bytes from FF0001 to FF0FFF. even bytes in that range are a standard SRAM chip which is not backed up. |
| 25 | 29 | Keyboard at FE01C1 (status/IRQ clear)/FE01C3 (AT scan codes) |
| 30 | WD1002 HDD controller @ FE0141-FE014F. "Monk" BIOS also supports an 8-bit ISA IDE card. |
| 26 | 31 | |
| 27 | | Video: ISA MDA or CGA-style boards |
| 28 | | MDA maps VRAM at D60000, 6845 address at FA0769, 6845 data at FA076B, control latch at FA0771 |
| 29 | | CGA maps VRAM at D70000, 6845 address at FA07A9, 6845 data at FA07AB, control port at FA07B1, color set at FA07B3, CGA status at FA07B5 |
| 32 | Video: ISA MDA or CGA/EGA/VGA-style boards |
| 33 | MDA maps VRAM at D60001, 6845 address at FA0769, 6845 data at FA076B, control latch at FA0771 |
| 34 | CGA maps VRAM at D70001, 6845 address at FA07A9, 6845 data at FA07AB, control port at FA07B1, color set at FA07B3, CGA status at FA07B5 |
| 30 | 35 | |
| 36 | ISA memory is C00001-DFFFFF odd bytes only. So the MDA B0000 framebuffer becames (B0000*2) + C00001 = D60001. |
| 37 | ISA I/O is at FA0001-FBFFFF odd bytes only, and the mapping is similar. |
| 38 | |
| 31 | 39 | HUMBUG BIOS tests MDA and CGA VRAM to determine existence, falls back to serial console if neither exists. If both exist, MDA is used. |
| 32 | 40 | VRAM is every other byte for ISA cards. (Only 8 bit cards are supported). |
| 33 | 41 | |
| 42 | OP3 on DUART1 drives a speaker. n68681 needs to handle "OP3 is timer/counter output" mode. |
| 43 | |
| 34 | 44 | IRQs: |
| 35 | | 5: keyboard has new scan code available, all others don't exist |
| 45 | 2: 68230 PIT |
| 46 | 4: DUART2 |
| 47 | 5: keyboard has a new scan code and DUART1 |
| 48 | 6: PC FDC IRQ |
| 36 | 49 | |
| 50 | TODO: 68230 device. Better hardware documentation would be nice too. |
| 51 | ISA interface and keyboard port would greatly improve usability. |
| 52 | How to handle ISA transparently so cards map themselves automatically? |
| 53 | |
| 37 | 54 | ****************************************************************************/ |
| 38 | 55 | |
| 39 | 56 | #include "emu.h" |
| 40 | 57 | #include "cpu/m68000/m68000.h" |
| 41 | 58 | #include "machine/terminal.h" |
| 59 | #include "machine/n68681.h" |
| 60 | #include "machine/timekpr.h" |
| 61 | #include "machine/pc_fdc.h" |
| 62 | #include "formats/imd_dsk.h" |
| 42 | 63 | |
| 64 | #define DUART1_TAG "duart1" |
| 65 | #define DUART2_TAG "duart2" |
| 66 | #define TIMEKEEPER_TAG "timekpr" |
| 67 | #define PCFDC_TAG "pcfdc" |
| 68 | |
| 43 | 69 | class pt68k4_state : public driver_device |
| 44 | 70 | { |
| 45 | 71 | public: |
| 46 | 72 | pt68k4_state(const machine_config &mconfig, device_type type, const char *tag) |
| 47 | 73 | : driver_device(mconfig, type, tag) |
| 48 | 74 | , m_p_base(*this, "rambase") |
| 49 | | , m_p_upper(*this, "upper_ram") |
| 50 | 75 | , m_maincpu(*this, "maincpu") |
| 51 | | , m_terminal(*this, TERMINAL_TAG) |
| 76 | , m_duart1(*this, DUART1_TAG) |
| 77 | , m_duart2(*this, DUART2_TAG) |
| 52 | 78 | { } |
| 53 | 79 | |
| 54 | | DECLARE_WRITE8_MEMBER(kbd_put); |
| 55 | | DECLARE_READ16_MEMBER(status_r); |
| 56 | | DECLARE_READ16_MEMBER(nop_r); |
| 57 | | //virtual void video_start(); |
| 58 | | //UINT32 screen_update_pt68k4(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 80 | DECLARE_READ8_MEMBER(hiram_r); |
| 81 | DECLARE_WRITE8_MEMBER(hiram_w); |
| 82 | DECLARE_READ8_MEMBER(keyboard_r); |
| 83 | DECLARE_WRITE8_MEMBER(keyboard_w); |
| 84 | |
| 85 | DECLARE_WRITE_LINE_MEMBER(duart1_irq); |
| 86 | DECLARE_WRITE_LINE_MEMBER(duart2_irq); |
| 87 | |
| 88 | DECLARE_FLOPPY_FORMATS( floppy_formats ); |
| 89 | |
| 59 | 90 | private: |
| 60 | 91 | virtual void machine_reset(); |
| 61 | 92 | required_shared_ptr<UINT16> m_p_base; |
| 62 | | required_shared_ptr<UINT16> m_p_upper; |
| 63 | 93 | required_device<cpu_device> m_maincpu; |
| 64 | | required_device<generic_terminal_device> m_terminal; |
| 94 | required_device<duartn68681_device> m_duart1; |
| 95 | required_device<duartn68681_device> m_duart2; |
| 96 | |
| 97 | UINT8 m_hiram[0x800]; |
| 65 | 98 | }; |
| 66 | 99 | |
| 100 | FLOPPY_FORMATS_MEMBER( pt68k4_state::floppy_formats ) |
| 101 | FLOPPY_IMD_FORMAT |
| 102 | FLOPPY_FORMATS_END |
| 103 | |
| 67 | 104 | static ADDRESS_MAP_START(pt68k4_mem, AS_PROGRAM, 16, pt68k4_state) |
| 68 | 105 | ADDRESS_MAP_UNMAP_HIGH |
| 69 | | AM_RANGE(0x000000, 0x07ffff) AM_RAM AM_SHARE("rambase") // 512 KB RAM / ROM at boot |
| 106 | AM_RANGE(0x000000, 0x0fffff) AM_RAM AM_SHARE("rambase") // 1MB RAM (OS9 needs more) |
| 70 | 107 | AM_RANGE(0xf80000, 0xf8ffff) AM_ROM AM_REGION("roms", 0) |
| 71 | | AM_RANGE(0xfe0002, 0xfe0003) AM_READ(status_r) |
| 72 | | AM_RANGE(0xfe0006, 0xfe0007) AM_DEVWRITE8(TERMINAL_TAG, generic_terminal_device, write, 0x00ff) |
| 73 | | AM_RANGE(0xfe0012, 0xfe0013) AM_READ(nop_r) |
| 74 | | AM_RANGE(0xff0000, 0xffffff) AM_RAM AM_SHARE("upper_ram") |
| 108 | AM_RANGE(0xfa07e0, 0xfa07ef) AM_DEVICE8(PCFDC_TAG, pc_fdc_at_device, map, 0x00ff) |
| 109 | AM_RANGE(0xfe0000, 0xfe001f) AM_DEVREADWRITE8(DUART1_TAG, duartn68681_device, read, write, 0x00ff) |
| 110 | AM_RANGE(0xfe0040, 0xfe005f) AM_DEVREADWRITE8(DUART2_TAG, duartn68681_device, read, write, 0x00ff) |
| 111 | AM_RANGE(0xfe01c0, 0xfe01c3) AM_READWRITE8(keyboard_r, keyboard_w, 0x00ff) |
| 112 | AM_RANGE(0xff0000, 0xff0fff) AM_READWRITE8(hiram_r, hiram_w, 0xff00) |
| 113 | AM_RANGE(0xff0000, 0xff0fff) AM_DEVREADWRITE8(TIMEKEEPER_TAG, timekeeper_device, read, write, 0x00ff) |
| 75 | 114 | ADDRESS_MAP_END |
| 76 | 115 | |
| 77 | 116 | /* Input ports */ |
| 78 | 117 | static INPUT_PORTS_START( pt68k4 ) |
| 79 | 118 | INPUT_PORTS_END |
| 80 | 119 | |
| 120 | /* built in keyboard: offset 0 reads 0x80 if key ready, 0 if not. If key ready, offset 1 reads scancode. Write (and read?) to offs 0 clears key ready? */ |
| 121 | READ8_MEMBER(pt68k4_state::keyboard_r) |
| 122 | { |
| 123 | return 0; |
| 124 | } |
| 81 | 125 | |
| 126 | WRITE8_MEMBER(pt68k4_state::keyboard_w) |
| 127 | { |
| 128 | } |
| 129 | |
| 130 | READ8_MEMBER(pt68k4_state::hiram_r) |
| 131 | { |
| 132 | return m_hiram[offset]; |
| 133 | } |
| 134 | |
| 135 | WRITE8_MEMBER(pt68k4_state::hiram_w) |
| 136 | { |
| 137 | m_hiram[offset] = data; |
| 138 | } |
| 139 | |
| 82 | 140 | void pt68k4_state::machine_reset() |
| 83 | 141 | { |
| 84 | 142 | UINT8* user1 = memregion("roms")->base(); |
| r26929 | r26930 | |
| 87 | 145 | m_maincpu->reset(); |
| 88 | 146 | } |
| 89 | 147 | |
| 90 | | //void pt68k4_state::video_start() |
| 91 | | //{ |
| 92 | | //} |
| 93 | | |
| 94 | | //UINT32 pt68k4_state::screen_update_pt68k4(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) |
| 95 | | //{ |
| 96 | | // return 0; |
| 97 | | //} |
| 98 | | |
| 99 | | READ16_MEMBER( pt68k4_state::status_r ) |
| 148 | WRITE_LINE_MEMBER(pt68k4_state::duart1_irq) |
| 100 | 149 | { |
| 101 | | return 0x8c; |
| 150 | m_maincpu->set_input_line(M68K_IRQ_5, state); |
| 102 | 151 | } |
| 103 | 152 | |
| 104 | | READ16_MEMBER( pt68k4_state::nop_r ) |
| 153 | WRITE_LINE_MEMBER(pt68k4_state::duart2_irq) |
| 105 | 154 | { |
| 106 | | return 0; |
| 155 | m_maincpu->set_input_line(M68K_IRQ_4, state); |
| 107 | 156 | } |
| 108 | 157 | |
| 109 | | WRITE8_MEMBER( pt68k4_state::kbd_put ) |
| 110 | | { |
| 111 | | m_p_upper[0x64f] = 0x100 | data; |
| 112 | | } |
| 158 | static SLOT_INTERFACE_START( pt68k_floppies ) |
| 159 | SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) |
| 160 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) |
| 161 | SLOT_INTERFACE( "35dd", FLOPPY_35_DD ) |
| 162 | SLOT_INTERFACE( "35hd", FLOPPY_35_HD ) |
| 163 | SLOT_INTERFACE_END |
| 113 | 164 | |
| 114 | | static GENERIC_TERMINAL_INTERFACE( terminal_intf ) |
| 115 | | { |
| 116 | | DEVCB_DRIVER_MEMBER(pt68k4_state, kbd_put) |
| 117 | | }; |
| 118 | | |
| 119 | 165 | static MACHINE_CONFIG_START( pt68k4, pt68k4_state ) |
| 120 | 166 | /* basic machine hardware */ |
| 121 | 167 | MCFG_CPU_ADD("maincpu",M68000, XTAL_16MHz) |
| 122 | 168 | MCFG_CPU_PROGRAM_MAP(pt68k4_mem) |
| 123 | 169 | |
| 124 | | /* video hardware */ |
| 125 | | MCFG_GENERIC_TERMINAL_ADD(TERMINAL_TAG, terminal_intf) |
| 126 | | //MCFG_SCREEN_ADD("screen", RASTER) |
| 127 | | //MCFG_SCREEN_REFRESH_RATE(50) |
| 128 | | //MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ |
| 129 | | //MCFG_SCREEN_SIZE(640, 480) |
| 130 | | //MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1) |
| 131 | | //MCFG_SCREEN_UPDATE_DRIVER(pt68k4_state, screen_update_pt68k4) |
| 132 | | //MCFG_PALETTE_LENGTH(2) |
| 133 | | //MCFG_PALETTE_INIT_OVERRIDE(driver_device, black_and_white) |
| 170 | // add the DUARTS. first one has the console on channel A at 19200. |
| 171 | MCFG_DUARTN68681_ADD("duart1", XTAL_16MHz / 4) |
| 172 | MCFG_DUARTN68681_IRQ_CALLBACK(WRITELINE(pt68k4_state, duart1_irq)) |
| 173 | MCFG_DUARTN68681_A_TX_CALLBACK(DEVWRITELINE("rs232", serial_port_device, tx)) |
| 174 | |
| 175 | MCFG_DUARTN68681_ADD("duart2", XTAL_16MHz / 4) |
| 176 | |
| 177 | MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "serial_terminal") |
| 178 | MCFG_SERIAL_OUT_RX_HANDLER(DEVWRITELINE("duart1", duartn68681_device, rx_a_w)) |
| 179 | |
| 180 | MCFG_M48T02_ADD(TIMEKEEPER_TAG) |
| 181 | |
| 182 | MCFG_PC_FDC_AT_ADD(PCFDC_TAG) |
| 183 | MCFG_FLOPPY_DRIVE_ADD(PCFDC_TAG ":0", pt68k_floppies, "525dd", pt68k4_state::floppy_formats) |
| 134 | 184 | MACHINE_CONFIG_END |
| 135 | 185 | |
| 136 | 186 | /* ROM definition */ |
| r26929 | r26930 | |
| 153 | 203 | /* Driver */ |
| 154 | 204 | |
| 155 | 205 | /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ |
| 156 | | COMP( 1990, pt68k4, 0, 0, pt68k4, pt68k4, driver_device, 0, "Peripheral Technology", "PT68K4", GAME_NOT_WORKING | GAME_NO_SOUND) |
| 206 | COMP( 1990, pt68k4, 0, 0, pt68k4, pt68k4, driver_device, 0, "Peripheral Technology", "PT68K4", GAME_NOT_WORKING | GAME_NO_SOUND) |