diff options
Diffstat (limited to 'src/mame/machine/kaypro.cpp')
-rw-r--r-- | src/mame/machine/kaypro.cpp | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/src/mame/machine/kaypro.cpp b/src/mame/machine/kaypro.cpp new file mode 100644 index 00000000000..9b9c3a7bab7 --- /dev/null +++ b/src/mame/machine/kaypro.cpp @@ -0,0 +1,292 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert + + +#include "includes/kaypro.h" + + + + +/*********************************************************** + + PIO + + Port B is unused on both PIOs + +************************************************************/ + +WRITE_LINE_MEMBER( kaypro_state::write_centronics_busy ) +{ + m_centronics_busy = state; +} + +READ8_MEMBER( kaypro_state::pio_system_r ) +{ + UINT8 data = 0; + + /* centronics busy */ + data |= m_centronics_busy << 3; + + /* PA7 is pulled high */ + data |= 0x80; + + return data; +} + +WRITE8_MEMBER( kaypro_state::kayproii_pio_system_w ) +{ +/* d7 bank select + d6 disk drive motors - (0=on) + d5 double-density enable (0=double density) + d4 Centronics strobe + d2 side select (1=side 1) + d1 drive B + d0 drive A */ + + membank("bankr0")->set_entry(BIT(data, 7)); + membank("bank3")->set_entry(BIT(data, 7)); + m_is_motor_off = BIT(data, 6); + + m_floppy = NULL; + if (BIT(data, 0)) + m_floppy = m_floppy0->get_device(); + else + if (BIT(data, 1)) + m_floppy = m_floppy1->get_device(); + + m_fdc->set_floppy(m_floppy); + m_fdc->dden_w(BIT(data, 5)); + + if (m_floppy) + { + m_floppy->mon_w(BIT(data, 6)); // motor on + m_floppy->ss_w(!BIT(data, 2)); // signal exists even though drives are single sided + } + + output_set_value("ledA", BIT(data, 0)); /* LEDs in artwork */ + output_set_value("ledB", BIT(data, 1)); + + m_centronics->write_strobe(BIT(data, 4)); + + m_system_port = data; +} + +WRITE8_MEMBER( kaypro_state::kaypro4_pio_system_w ) +{ + kayproii_pio_system_w(space, offset, data); + + /* side select */ + m_floppy->ss_w(BIT(data, 2)); +} + +/*********************************************************** + + KAYPRO2X SYSTEM PORT + + The PIOs were replaced by a few standard 74xx chips + +************************************************************/ + +READ8_MEMBER( kaypro_state::kaypro2x_system_port_r ) +{ + UINT8 data = m_centronics_busy << 6; + return (m_system_port & 0xbf) | data; +} + +WRITE8_MEMBER( kaypro_state::kaypro2x_system_port_w ) +{ +/* d7 bank select + d6 alternate character set (write only) + d5 double-density enable + d4 disk drive motors (1=on) + d3 Centronics strobe + d2 side select (appears that 0=side 1?) + d1 drive B + d0 drive A */ + + membank("bankr0")->set_entry(BIT(data, 7)); + membank("bank3")->set_entry(BIT(data, 7)); + m_is_motor_off = !BIT(data, 4); + + m_floppy = NULL; + if (!BIT(data, 0)) + m_floppy = m_floppy0->get_device(); + else + if (m_floppy1 && (!BIT(data, 1))) + m_floppy = m_floppy1->get_device(); + + m_fdc->set_floppy(m_floppy); + m_fdc->dden_w(BIT(data, 5)); + + if (m_floppy) + { + m_floppy->mon_w(!BIT(data, 4)); // motor on + m_floppy->ss_w(!BIT(data, 2)); + } + + output_set_value("ledA", BIT(data, 0)); /* LEDs in artwork */ + output_set_value("ledB", BIT(data, 1)); + + m_centronics->write_strobe(BIT(data, 3)); + + m_system_port = data; +} + + +/*********************************************************************** + + SIO + + On Kaypro2x, Channel B on both SIOs is hardwired to 300 baud. + + Both devices on sio2 (printer and modem) are not emulated. + +************************************************************************/ + +/* Set baud rate. bits 0..3 Rx and Tx are tied together. Baud Rate Generator is a AY-5-8116, SMC8116, WD1943, etc. + 00h 50 + 11h 75 + 22h 110 + 33h 134.5 + 44h 150 + 55h 300 + 66h 600 + 77h 1200 + 88h 1800 + 99h 2000 + AAh 2400 + BBh 3600 + CCh 4800 + DDh 7200 + EEh 9600 + FFh 19200 */ + + +READ8_MEMBER(kaypro_state::kaypro_sio_r) +{ + if (offset == 1) + return kay_kbd_d_r(machine()); + else + if (offset == 3) + return kay_kbd_c_r(machine()); + else + return m_sio->cd_ba_r(space, offset); +} + +WRITE8_MEMBER(kaypro_state::kaypro_sio_w) +{ + if (offset == 1) + kay_kbd_d_w(machine(), data); + else + m_sio->cd_ba_w(space, offset, data); +} + + +/************************************************************************************* + + Floppy DIsk + + If DRQ or IRQ is set, and cpu is halted, the NMI goes low. + Since the HALT occurs last (and has no callback mechanism), we need to set + a short delay, to give time for the processor to execute the HALT before NMI + becomes active. + +*************************************************************************************/ + +void kaypro_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + bool halt; + switch (id) + { + case TIMER_FLOPPY: + halt = (bool)m_maincpu->state_int(Z80_HALT); + if (m_is_motor_off) + { + timer_set(attotime::from_hz(10), TIMER_FLOPPY); + break; + } + if ((halt) && (m_fdc_rq & 3) && (m_fdc_rq < 0x80)) + { + m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); + m_fdc_rq |= 0x80; + } + else + if ((m_fdc_rq == 0x80) || ((!halt) && BIT(m_fdc_rq, 7))) + { + m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE); + m_fdc_rq &= 0x7f; + } + timer_set(attotime::from_hz(1e5), TIMER_FLOPPY); + + break; + default: + assert_always(FALSE, "Unknown id in kaypro_state::device_timer"); + } +} + +WRITE_LINE_MEMBER( kaypro_state::fdc_intrq_w ) +{ + m_fdc_rq = (m_fdc_rq & 0x82) | state; +} + +WRITE_LINE_MEMBER( kaypro_state::fdc_drq_w ) +{ + m_fdc_rq = (m_fdc_rq & 0x81) | (state << 1); +} + + +/*********************************************************** + + Machine + +************************************************************/ +MACHINE_START_MEMBER( kaypro_state,kayproii ) +{ + m_pio_s->strobe_a(0); +} + +MACHINE_RESET_MEMBER( kaypro_state,kaypro ) +{ + MACHINE_RESET_CALL_MEMBER(kay_kbd); + membank("bankr0")->set_entry(1); // point at rom + membank("bankw0")->set_entry(0); // always write to ram + membank("bank3")->set_entry(1); // point at video ram + m_system_port = 0x80; + m_fdc_rq = 0; + m_maincpu->reset(); + timer_set(attotime::from_hz(1), TIMER_FLOPPY); /* kick-start the nmi timer */ +} + + +/*********************************************************** + + Quickload + + This loads a .COM file to address 0x100 then jumps + there. Sometimes .COM has been renamed to .CPM to + prevent windows going ballistic. These can be loaded + as well. + +************************************************************/ + +QUICKLOAD_LOAD_MEMBER( kaypro_state, kaypro ) +{ + UINT8 *RAM = memregion("rambank")->base(); + UINT16 i; + UINT8 data; + + /* Load image to the TPA (Transient Program Area) */ + for (i = 0; i < quickload_size; i++) + { + if (image.fread( &data, 1) != 1) return IMAGE_INIT_FAIL; + + RAM[i+0x100] = data; + } + + membank("bankr0")->set_entry(0); + membank("bank3")->set_entry(0); + RAM[0x80]=0; // clear out command tail + RAM[0x81]=0; + m_maincpu->set_pc(0x100); // start program + return IMAGE_INIT_PASS; +} |