diff options
Diffstat (limited to 'src/mame/drivers/mekd1.cpp')
-rw-r--r-- | src/mame/drivers/mekd1.cpp | 475 |
1 files changed, 0 insertions, 475 deletions
diff --git a/src/mame/drivers/mekd1.cpp b/src/mame/drivers/mekd1.cpp deleted file mode 100644 index 601b9dec456..00000000000 --- a/src/mame/drivers/mekd1.cpp +++ /dev/null @@ -1,475 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:68bit -/*************************************************************************** - -Motorola Evaluation Kit 6800 D1 - MEK6800D1 - -The monitor is supplied in the MCM6830L7 ROM and named MIKBUG rev 9. MIKBUG is -a 512 byte monitor. The MIKBUG commands are: - -M aaaa - memory examine and change at address 'aaaa'. - <space>hh - modify content with hex value 'hh' and increase address. If the - memory can not be changed then it prints '?' and exits the - memory examine. - <space> and any other key exits the memory examine. The documentation - suggests using a carriage return. - Any other key increases the address. - -R - Register display: CC B A X PC SP. The registers can be modified at: - 0xa043 CC - 0xa044 B - 0xa045 A - 0xa046 X high - 0xa047 X low - 0xa048 PC high - 0xa049 PC low - 0xa008 SP high - 0xa009 SP low - -L - Loads data, in S19 format, as generated by the assembler. If there is a - checksum failure then it prints '?' and exits the load. An 'S9' record - exits the load. Note that the MIKBUG punch command 'P' does not write a - 'S9' record so it is necessary to manually enter a 'S9' sequence at the - end of the load when loading a MIKBUG generated tape! - -P - Print or Punch memory dump. The start address is loaded from 0xa002 to - 0xa003, and the end address is loaded from 0xa004 to 0xa005. The output is - in S19 format and can be loaded with the 'L' command, but the end-of-file - 'S9' record is not emitted. - -G - Go to user code. The registers are loaded from the addresses noted above - 0xa043 to 0xa049 and 0xa008 to 0xa009 for the stack pointer. Breakpoints - can be manually set by inserting a SWI (0x3f) instruction, and when these - are encountered control returns to MIKBUG and the registers are save and - printed. - -An IRQ handler can be defined at 0xa000 to 0xa001. -An NMI handler can be defined at 0xa006 to 0xa007. - -MIKBUG was designed to work with the ASR33 Teletypewriter and drives the -'reader control' line high during a 'load' operation intended for a reader -relay control which was a common modification. There is no signal line driven -for a 'punch' operation. TODO might be able to at least use this 'reader -control' line to switch to input from a tape. - -MIKBUG was designed to work with the Texas Instruments 733 ASR twin tape -cassette terminal with automatic device control and issues the following -control codes when loading and 'punching' a tape. TODO perhaps these could -be detected and serial I/O diverted to a cassette. - Code 0x11 DC1 - Tape playback on - Code 0x12 DC2 - Tape record on. - Code 0x13 DC3 - Tape playback off. - Code 0x14 DC4 - Tape record off. - -The serial bit rate is controlled by a MC14536 timer and is variable. Common -rates are 110 baud and 300 baud, for the ASR33 and 733 ASR terminals -respectively, but is was practical to run at higher rates up to about 4800 -baud. - -Memory is expandable off-board with some modifications, to at least 8K. There -were versions of the resident editor and assembler for use with MIKBUG, that -required the expanded RAM. - -The board hosts a MC6850 ACIA but this is not used by MIKBUG so it is a user -ACIA. The clock is supplied off board and the documentation offers a design -suggestion using the MC14411 and this is emulated here as documented. - -TODO could add a reset button, and an NMI button, and an LED for the reader -relay line. Might want to default the terminal to echo characters. - -References: -1. Assembly Instructions for the Motorola M6800 Design Evaluation Kit, 1975. -2. Engineering Note 100, MCM6830L7 MIKBUG/MINIBUG ROM. - -****************************************************************************/ - -#include "emu.h" -#include "cpu/m6800/m6800.h" -#include "machine/6821pia.h" -#include "machine/6850acia.h" -#include "machine/mc14411.h" -#include "machine/input_merger.h" -#include "machine/timer.h" -#include "bus/rs232/rs232.h" -#include "machine/terminal.h" - -class mekd1_state : public driver_device -{ -public: - mekd1_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_maincpu(*this, "maincpu") - , m_pia0(*this, "pia0") - , m_pia1(*this, "pia1") - , m_acia(*this, "acia") - , m_brg(*this, "brg") - , m_rs232(*this, "rs232") - , m_baud_rate(*this, "BAUD_RATE") - , m_stop_bits(*this, "STOP_BITS") - , m_acia_baud_rate(*this, "ACIA_BAUD_RATE") - { } - - void mekd1(machine_config &config); - - enum - { - TIMER_BIT_RATE, - TIMER_BIT_RATE_HALF - }; - -private: - virtual void machine_reset() override; - virtual void machine_start() override; - - void mem_map(address_map &map); - - required_device<cpu_device> m_maincpu; - required_device<pia6821_device> m_pia0; - required_device<pia6821_device> m_pia1; - required_device<acia6850_device> m_acia; - required_device<mc14411_device> m_brg; - required_device<rs232_port_device> m_rs232; - required_ioport m_baud_rate; - required_ioport m_stop_bits; - required_ioport m_acia_baud_rate; - - DECLARE_READ8_MEMBER(pia0_pa_r); - DECLARE_READ8_MEMBER(pia0_pb_r); - DECLARE_WRITE8_MEMBER(pia0_pa_w); - DECLARE_WRITE8_MEMBER(pia0_pb_w); - DECLARE_WRITE_LINE_MEMBER(pia0_cb2_w); - - // Clocks - DECLARE_WRITE_LINE_MEMBER(write_f1_clock); - DECLARE_WRITE_LINE_MEMBER(write_f2_clock); - DECLARE_WRITE_LINE_MEMBER(write_f4_clock); - DECLARE_WRITE_LINE_MEMBER(write_f5_clock); - DECLARE_WRITE_LINE_MEMBER(write_f7_clock); - DECLARE_WRITE_LINE_MEMBER(write_f8_clock); - DECLARE_WRITE_LINE_MEMBER(write_f9_clock); - DECLARE_WRITE_LINE_MEMBER(write_f11_clock); - DECLARE_WRITE_LINE_MEMBER(write_f13_clock); - - virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - - emu_timer *m_bit_rate_timer; - emu_timer *m_bit_rate_half_timer; - - bool m_bit_rate_out; - bool m_bit_rate_half_out; - bool m_bit_rate_reset; - bool m_bit_rate_select; -}; - -void mekd1_state::mem_map(address_map &map) -{ - map.unmap_value_high(); - map(0x0000, 0x027f).mirror(0x7c00).ram(); - - // The emulated addressing for these is not exact. The hardware uses - // A3, A4, and A5 to select between these respectively. For example - // the first PIA is selected when A3 is high, but it ignores A4 and - // A5, etc. So it is possible that more than one are selected at once - // which is not emulated here. Here it is assumed that A3, A4, and A5 - // are completely decoded and that only one device is selected at a - // time. - map(0x8004, 0x8007).mirror(0x5fe0).rw(m_pia0, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); - map(0x8008, 0x800b).mirror(0x5fe0).rw(m_pia1, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); - map(0x8010, 0x8011).mirror(0x5fe2).rw(m_acia, FUNC(acia6850_device::read), FUNC(acia6850_device::write)); - - map(0xa000, 0xa07f).mirror(0x0f80).ram(); - - // Although the ROM is 1k, MIKBUG uses only the first 512 bytes and - // when using MIKBUG the A9 ROM input is connected to 0V. - map(0xe000, 0xe1ff).mirror(0x1e00).rom().region("mcm6830l7", 0); -} - -static INPUT_PORTS_START( mekd1 ) - - PORT_START("BAUD_RATE") - PORT_CONFNAME(0x3fff, 416, "RS232 Baud Rate") - PORT_CONFSETTING(9091, "110") - PORT_CONFSETTING(3333, "300") - PORT_CONFSETTING(1667, "600") - PORT_CONFSETTING( 833, "1200") - PORT_CONFSETTING( 416, "2400") - PORT_CONFSETTING( 208, "4800") - PORT_CONFSETTING( 139, "7200") - PORT_CONFSETTING( 104, "9600") - - PORT_START("STOP_BITS") - PORT_CONFNAME(0x01, 0, "Stop bits") - PORT_CONFSETTING(0x00, "1") - PORT_CONFSETTING(0x01, "2") - - PORT_START("ACIA_BAUD_RATE") - PORT_CONFNAME(0xf, 1, "ACIA Baud Rate") - PORT_CONFSETTING(13, "110") - PORT_CONFSETTING(11, "150") - PORT_CONFSETTING(9, "300") - PORT_CONFSETTING(8, "600") - PORT_CONFSETTING(7, "1200") - PORT_CONFSETTING(5, "2400") - PORT_CONFSETTING(4, "3600") - PORT_CONFSETTING(2, "4800") - PORT_CONFSETTING(1, "9600") - -INPUT_PORTS_END - - - -READ8_MEMBER(mekd1_state::pia0_pa_r) -{ - return m_rs232->rxd_r() << 7; -} - -READ8_MEMBER(mekd1_state::pia0_pb_r) -{ - bool timer_out; - uint8_t stop_bits = m_stop_bits->read(); - - if (m_bit_rate_select) - timer_out = m_bit_rate_out; - else - timer_out = m_bit_rate_half_out; - - return (timer_out << 7) | (stop_bits << 6); -} - -WRITE8_MEMBER(mekd1_state::pia0_pa_w) -{ - m_rs232->write_txd(BIT(data, 0)); -} - -WRITE8_MEMBER(mekd1_state::pia0_pb_w) -{ - m_bit_rate_select = BIT(data, 2); - - if (BIT(data, 0) == 1) - { - // Reset - m_bit_rate_timer->reset(); - m_bit_rate_half_timer->reset(); - m_bit_rate_out = 0; - m_bit_rate_half_out = 0; - m_bit_rate_reset = 1; - return; - } - - if (m_bit_rate_reset) - { - // Timer has just been taken out of reset. - m_bit_rate_reset = 0; - uint16_t delay = m_baud_rate->read(); - // An adjustment is subtracted from the delay for the CPU - // instruction processing paths as the CPU polls the timer - // output, and this would vary with the CPU clock. In - // hardware, variable resisters needed to be tuned to achieve - // the correct timing which was not hard at the lower baud - // rates. - m_bit_rate_timer->adjust(attotime::from_usec(delay - 31)); - m_bit_rate_half_timer->adjust(attotime::from_usec((delay / 2 ) - 31)); - } -} - -WRITE_LINE_MEMBER(mekd1_state::pia0_cb2_w) -{ - // This is a tape reader control line. -} - -void mekd1_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - switch (id) - { - case TIMER_BIT_RATE: - m_bit_rate_out = 1; - break; - case TIMER_BIT_RATE_HALF: - m_bit_rate_half_out = 1; - break; - default: - throw emu_fatalerror("Unknown id in mekd1_state::device_timer"); - } -} - - -WRITE_LINE_MEMBER(mekd1_state::write_f1_clock) -{ - if (m_acia_baud_rate->read() == 1) - { - m_acia->write_txc(state); - m_acia->write_rxc(state); - } -} - -WRITE_LINE_MEMBER(mekd1_state::write_f2_clock) -{ - if (m_acia_baud_rate->read() == 2) - { - m_acia->write_txc(state); - m_acia->write_rxc(state); - } -} - -WRITE_LINE_MEMBER(mekd1_state::write_f4_clock) -{ - if (m_acia_baud_rate->read() == 4) - { - m_acia->write_txc(state); - m_acia->write_rxc(state); - } -} - -WRITE_LINE_MEMBER(mekd1_state::write_f5_clock) -{ - if (m_acia_baud_rate->read() == 5) - { - m_acia->write_txc(state); - m_acia->write_rxc(state); - } -} - -WRITE_LINE_MEMBER(mekd1_state::write_f7_clock) -{ - if (m_acia_baud_rate->read() == 7) - { - m_acia->write_txc(state); - m_acia->write_rxc(state); - } -} - -WRITE_LINE_MEMBER(mekd1_state::write_f8_clock) -{ - if (m_acia_baud_rate->read() == 8) - { - m_acia->write_txc(state); - m_acia->write_rxc(state); - } -} - -WRITE_LINE_MEMBER(mekd1_state::write_f9_clock) -{ - if (m_acia_baud_rate->read() == 9) - { - m_acia->write_txc(state); - m_acia->write_rxc(state); - } -} - -WRITE_LINE_MEMBER(mekd1_state::write_f11_clock) -{ - if (m_acia_baud_rate->read() == 11) - { - m_acia->write_txc(state); - m_acia->write_rxc(state); - } -} - -WRITE_LINE_MEMBER(mekd1_state::write_f13_clock) -{ - if (m_acia_baud_rate->read() == 13) - { - m_acia->write_txc(state); - m_acia->write_rxc(state); - } -} - - -void mekd1_state::machine_reset() -{ - m_pia0->reset(); - m_pia1->reset(); - m_brg->rsa_w(CLEAR_LINE); - m_brg->rsb_w(ASSERT_LINE); - m_bit_rate_timer->reset(); - m_bit_rate_half_timer->reset(); - m_bit_rate_out = 0; - m_bit_rate_half_out = 0; - m_bit_rate_select = 0; - m_bit_rate_reset = 1; -} - -void mekd1_state::machine_start() -{ - // Allocate timers - m_bit_rate_timer = timer_alloc(TIMER_BIT_RATE); - m_bit_rate_half_timer = timer_alloc(TIMER_BIT_RATE_HALF); - - save_item(NAME(m_bit_rate_out)); - save_item(NAME(m_bit_rate_half_out)); - save_item(NAME(m_bit_rate_reset)); - save_item(NAME(m_bit_rate_select)); -} - -static DEVICE_INPUT_DEFAULTS_START(terminal) - DEVICE_INPUT_DEFAULTS("RS232_RXBAUD", 0xff, RS232_BAUD_2400) - DEVICE_INPUT_DEFAULTS("RS232_TXBAUD", 0xff, RS232_BAUD_2400) - DEVICE_INPUT_DEFAULTS("RS232_STARTBITS", 0xff, RS232_STARTBITS_1) - DEVICE_INPUT_DEFAULTS("RS232_DATABITS", 0xff, RS232_DATABITS_7) - DEVICE_INPUT_DEFAULTS("RS232_PARITY", 0xff, RS232_PARITY_SPACE) - DEVICE_INPUT_DEFAULTS("RS232_STOPBITS", 0xff, RS232_STOPBITS_1) -DEVICE_INPUT_DEFAULTS_END - -void mekd1_state::mekd1(machine_config &config) -{ - // The clock rate was adjustable from 100KHz to 1MHz. - M6800(config, m_maincpu, 2_MHz_XTAL / 2); - m_maincpu->set_addrmap(AS_PROGRAM, &mekd1_state::mem_map); - - INPUT_MERGER_ANY_HIGH(config, "mainirq").output_handler().set_inputline(m_maincpu, M6800_IRQ_LINE); - - // Terminal I/O. - // The design uses a 6820 which is slightly different to the emulated 6821. - // PA0 serial output. - // PA7 serial input. - // PB0 resets the rite rate timer when high. - // PB2 selects the bit rate timer output: 0 half time, 1 full time. - // PB6 jumper input: 0 for 1 stop bit, 1 for 2 stop bits. - // PB7 input from the bit rate timer that goes high after the timer period elapses. - // CB2 "reader control" output - // IRQA and IRQB are NC. - PIA6821(config, m_pia0, 0); - m_pia0->readpa_handler().set(FUNC(mekd1_state::pia0_pa_r)); - m_pia0->readpb_handler().set(FUNC(mekd1_state::pia0_pb_r)); - m_pia0->writepa_handler().set(FUNC(mekd1_state::pia0_pa_w)); - m_pia0->writepb_handler().set(FUNC(mekd1_state::pia0_pb_w)); - m_pia0->cb2_handler().set(FUNC(mekd1_state::pia0_cb2_w)); - - // User PIA. All the I/O lines are available at P2. - PIA6821(config, m_pia1, 0); - m_pia1->irqa_handler().set("mainirq", FUNC(input_merger_device::in_w<0>)); - m_pia1->irqb_handler().set("mainirq", FUNC(input_merger_device::in_w<1>)); - - // User ACIA. Available at P2. - // /CTS is pulled low, but may be driven. - // /DCD is pulled low, but may be driven. - ACIA6850(config, m_acia, 0); - m_acia->irq_handler().set("mainirq", FUNC(input_merger_device::in_w<2>)); - - // Off-board clock for the on-board MC6850. - MC14411(config, m_brg, XTAL(1'843'200)); - m_brg->out_f<1>().set(FUNC(mekd1_state::write_f1_clock)); - m_brg->out_f<2>().set(FUNC(mekd1_state::write_f2_clock)); - m_brg->out_f<4>().set(FUNC(mekd1_state::write_f4_clock)); - m_brg->out_f<4>().set(FUNC(mekd1_state::write_f5_clock)); - m_brg->out_f<7>().set(FUNC(mekd1_state::write_f7_clock)); - m_brg->out_f<8>().set(FUNC(mekd1_state::write_f8_clock)); - m_brg->out_f<9>().set(FUNC(mekd1_state::write_f9_clock)); - m_brg->out_f<11>().set(FUNC(mekd1_state::write_f11_clock)); - m_brg->out_f<13>().set(FUNC(mekd1_state::write_f13_clock)); - - RS232_PORT(config, m_rs232, default_rs232_devices, "terminal"); - m_rs232->set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal)); -} - - -/* ROM definition */ -ROM_START( mekd1 ) - ROM_REGION( 0x0200, "mcm6830l7", 0 ) - ROM_LOAD("mikbugv9.bin", 0x0000, 0x0200, CRC(f5ff896f) SHA1(32990115ad9eebe7a1a5a03b4b1ea83360b1820f)) -ROM_END - -/* Driver */ - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1975, mekd1, 0, 0, mekd1, mekd1, mekd1_state, empty_init, "Motorola", "MEK6800D1", MACHINE_NO_SOUND_HW ) |