// license:BSD-3-Clause // copyright-holders:Robbbert /*************************************************************************** Imsai MPU-B. One of the earliest single-board computers on a S100 card. 2013-09-11 Skeleton driver. Chips used: i8085, i8251, i8253, 3622 fusable prom. XTAL 6MHz Press any key to start the monitor program. ToDo: - Banking - Dipswitches ****************************************************************************/ #include "emu.h" #include "cpu/i8085/i8085.h" //#include "bus/s100/s100.h" #include "machine/i8251.h" #include "machine/pit8253.h" #include "machine/terminal.h" class imsai_state : public driver_device { public: imsai_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") , m_rom(*this, "maincpu") , m_terminal(*this, "terminal") , m_pit(*this, "pit") { } void imsai(machine_config &config); private: void kbd_put(u8 data); u8 keyin_r(); u8 status_r(); void control_w(u8 data); void io_map(address_map &map); void mem_map(address_map &map); u8 m_term_data; void machine_reset() override; void machine_start() override; memory_passthrough_handler *m_rom_shadow_tap; required_device m_maincpu; required_region_ptr m_rom; required_device m_terminal; required_device m_pit; }; void imsai_state::mem_map(address_map &map) { map.unmap_value_high(); map(0xd000, 0xd0ff).ram(); map(0xd100, 0xd103).rw(m_pit, FUNC(pit8253_device::read), FUNC(pit8253_device::write)); map(0xd800, 0xdfff).rom().region("maincpu", 0); } void imsai_state::io_map(address_map &map) { map.unmap_value_high(); map.global_mask(0xff); map(0x02, 0x02).r(FUNC(imsai_state::keyin_r)).w(m_terminal, FUNC(generic_terminal_device::write)); map(0x03, 0x03).r(FUNC(imsai_state::status_r)); map(0x04, 0x05).rw("uart", FUNC(i8251_device::read), FUNC(i8251_device::write)); map(0x12, 0x13).rw("uart", FUNC(i8251_device::read), FUNC(i8251_device::write)); map(0x14, 0x14).r(FUNC(imsai_state::keyin_r)).w(m_terminal, FUNC(generic_terminal_device::write)); map(0x15, 0x15).r(FUNC(imsai_state::status_r)); map(0xf3, 0xf3).w(FUNC(imsai_state::control_w)); } /* Input ports */ static INPUT_PORTS_START( imsai ) INPUT_PORTS_END u8 imsai_state::keyin_r() { u8 ret = m_term_data; m_term_data = 0; return ret; } u8 imsai_state::status_r() { return (m_term_data) ? 3 : 1; } void imsai_state::kbd_put(u8 data) { m_term_data = data; } void imsai_state::control_w(u8 data) { } void imsai_state::machine_reset() { m_term_data = 0; address_space &program = m_maincpu->space(AS_PROGRAM); program.install_rom(0x0000, 0x07ff, m_rom); // do it here for F3 m_rom_shadow_tap = program.install_read_tap(0xd800, 0xdfff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask) { if (!machine().side_effects_disabled()) { // delete this tap m_rom_shadow_tap->remove(); // remove from the memory map m_maincpu->space(AS_PROGRAM).unmap_readwrite(0x0000, 0x07ff); } // return the original data return data; }); } void imsai_state::machine_start() { save_item(NAME(m_term_data)); } void imsai_state::imsai(machine_config &config) { /* basic machine hardware */ I8085A(config, m_maincpu, XTAL(6'000'000)); m_maincpu->set_addrmap(AS_PROGRAM, &imsai_state::mem_map); m_maincpu->set_addrmap(AS_IO, &imsai_state::io_map); /* video hardware */ GENERIC_TERMINAL(config, m_terminal, 0); m_terminal->set_keyboard_callback(FUNC(imsai_state::kbd_put)); /* Devices */ I8251(config, "uart", 0); PIT8253(config, m_pit, 0); m_pit->set_clk<0>(6_MHz_XTAL / 3); // Timer 0: baud rate gen for 8251 m_pit->out_handler<0>().set("uart", FUNC(i8251_device::write_txc)); m_pit->out_handler<0>().append("uart", FUNC(i8251_device::write_rxc)); m_pit->set_clk<1>(6_MHz_XTAL / 3); // Timer 1: user m_pit->set_clk<2>(6_MHz_XTAL / 3); // Timer 2: user } /* ROM definition */ ROM_START( imsai ) ROM_REGION( 0x800, "maincpu", 0 ) // 2716 or 2708 program PROM ROM_LOAD( "vdb-80.rom", 0x0000, 0x0800, CRC(0afc4683) SHA1(a5419aaee00badf339d7c627f50ef8b2538e42e2) ) ROM_REGION( 0x200, "decode", 0 ) // 512x4 address decoder ROM ROM_LOAD( "3622.u31", 0x000, 0x200, NO_DUMP ) ROM_REGION( 0x20, "status", 0 ) // PROM for decoding 8085 status signals ROM_LOAD( "74s288.u38", 0x00, 0x20, NO_DUMP ) ROM_END /* Driver */ // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS COMP( 1978, imsai, 0, 0, imsai, imsai, imsai_state, empty_init, "Imsai", "MPU-B", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE )