// license:BSD-3-Clause // copyright-holders:AJR /*************************************************************************** Mark 1 FORTH Computer (Copyright © Andrew Holme, 2003) This is a homebrew fig-FORTH interpreter using an original TTL CPU, operating at 1 microinstruction per microsecond. Neither the microcode nor the FORTH bytecode fills very much of the 2764 EPROMs specified. Notes on the I/O board design: * The second peripheral was supposed to be a 8255, but the port pins were never connected to anything and its socket was left empty. * RxC and TxC rates are generated by a HEF4060BP divider. The original plan was to operate the 82C51 in 1x mode at 38400, 19200 or 9600 baud, but reliable 1x asynchronous reception could not be obtained. 9600 baud is the maximum rate obtainable in 16x mode. * Before the ALU was designed, the RxRDY signal was buffered directly onto the data bus to be tested as a skip condition. Since this could not be guaranteed to be stable through an entire instruction cycle, an open-drain IRQ signal had to be added to the bus, with the requisite termination and synchronization provided on the ALU board. ***************************************************************************/ #include "emu.h" #include "bus/rs232/rs232.h" #include "cpu/mk1/mk1.h" #include "machine/clock.h" #include "machine/input_merger.h" #include "machine/i8251.h" class mk1forth_state : public driver_device { public: mk1forth_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) { } void mk1forth(machine_config &config); private: void ucode_map(address_map &map); void data_map(address_map &map); void stack_map(address_map &map); }; void mk1forth_state::ucode_map(address_map &map) { map(0x000, 0xfff).rom().region("ucode", 0); } void mk1forth_state::data_map(address_map &map) { map(0x0000, 0x1fff).rom().region("forth", 0); map(0x2000, 0x7fff).ram(); map(0xe000, 0xe001).mirror(0xffe).rw("uart", FUNC(i8251_device::read), FUNC(i8251_device::write)); //map(0xf000, 0xf003).mirror(0xffc).rw("pio", FUNC(i8255_device::read), FUNC(i8255_device::write)); } void mk1forth_state::stack_map(address_map &map) { map(0x000, 0x3ff).ram(); } void mk1forth_state::mk1forth(machine_config &config) { mk1_cpu_device &maincpu(MK1_CPU(config, "maincpu", 2_MHz_XTAL / 2)); maincpu.set_addrmap(AS_PROGRAM, &mk1forth_state::ucode_map); maincpu.set_addrmap(AS_DATA, &mk1forth_state::data_map); maincpu.set_addrmap(mk1_cpu_device::AS_STACK, &mk1forth_state::stack_map); INPUT_MERGER_ANY_HIGH(config, "uartirq").output_handler().set_inputline("maincpu", mk1_cpu_device::IRQ_LINE); i8251_device &uart(I8251(config, "uart", 2.4576_MHz_XTAL)); uart.rxrdy_handler().set("uartirq", FUNC(input_merger_device::in_w<0>)); uart.txrdy_handler().set("uartirq", FUNC(input_merger_device::in_w<1>)); uart.txd_handler().set("rs232", FUNC(rs232_port_device::write_txd)); uart.dtr_handler().set("rs232", FUNC(rs232_port_device::write_rts)); uart.dtr_handler().append("rs232", FUNC(rs232_port_device::write_dtr)); uart.write_cts(0); clock_device &clock(CLOCK(config, "baudclock", 2.4576_MHz_XTAL / 16)); clock.signal_handler().set("uart", FUNC(i8251_device::write_rxc)); clock.signal_handler().append("uart", FUNC(i8251_device::write_txc)); rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "terminal")); rs232.rxd_handler().set("uart", FUNC(i8251_device::write_rxd)); rs232.cts_handler().set("uart", FUNC(i8251_device::write_dsr)); } ROM_START(mk1forth) ROM_REGION(0x2000, "ucode", 0) ROM_LOAD("rom.bin", 0x0000, 0x2000, CRC(d55d8a09) SHA1(8043a276826d40aa35b4ab8c94b99e3862fb62e7)) ROM_REGION(0x2000, "forth", 0) ROM_LOAD("forth.bin", 0x0000, 0x2000, CRC(8b2863fa) SHA1(cc1d0662f10cf767f3f2581270ca2b4711121ffc)) ROM_END COMP(2003, mk1forth, 0, 0, mk1forth, 0, mk1forth_state, empty_init, "Andrew Holme", "Mark 1 FORTH Computer", MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE)