From 8350af40353f73913d0fda938feacb8f5b6d9387 Mon Sep 17 00:00:00 2001 From: Dirk Best Date: Fri, 28 Apr 2023 17:50:20 +0200 Subject: New machines marked as NOT_WORKING ---------------------------------- mc-68000-Computer [Dirk Best, Klaus Loy] --- src/mame/mame.lst | 3 + src/mame/mc/mc68000.cpp | 451 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 454 insertions(+) create mode 100644 src/mame/mc/mc68000.cpp diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 08155a4611c..f9c1248d55f 100755 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -26476,6 +26476,9 @@ screenpl // Screenplay @source:maygay/mmm.cpp mmm_ldip // Lucky Dip +@source:mc/mc68000.cpp +mc68000 // (c) 1984 mc / Franzis Verlag + @source:mchester/ssem.cpp ssem // Manchester Small-Scale Experimental Machine, "Baby" diff --git a/src/mame/mc/mc68000.cpp b/src/mame/mc/mc68000.cpp new file mode 100644 index 00000000000..80477dcd456 --- /dev/null +++ b/src/mame/mc/mc68000.cpp @@ -0,0 +1,451 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/**************************************************************************** + + mc-68000-Computer + + Hardware: + - MC68000 + - 16 MHz XTAL + - 128k or 512k RAM + - 2x 6522 VIA + - 6845 CRTC + - 8 expansion slots + + TODO: + - Better keyboard + - Floppy + - Cassette + - Color/brightness levels + - Sound + - Joysticks + - Centronics + - Serial + - Expansion slots + + Notes: + - This computer was described in the "mc" magazine by Franzis Verlag. + You could build it yourself or order it already assembled. + - Press ESC at the boot prompt to enter the monitor + - A later version is called "System II" and features a built-in floppy + and SASI controller + +****************************************************************************/ + +#include "emu.h" +#include "cpu/m68000/m68000.h" +#include "machine/6522via.h" +#include "machine/input_merger.h" +#include "machine/keyboard.h" +#include "machine/ram.h" +#include "video/mc6845.h" +#include "screen.h" + + +//#define LOG_GENERAL (1U << 0) +#define LOG_IO_READ (1U << 1) +#define LOG_IO_WRITE (1U << 2) + +#define VERBOSE (LOG_GENERAL | LOG_IO_WRITE) +#include "logmacro.h" + + +namespace { + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class mc68000_state : public driver_device +{ +public: + mc68000_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_irq3(*this, "irq3"), + m_ram(*this, RAM_TAG), + m_crtc(*this, "crtc"), + m_via(*this, "via%u", 0U), + m_apm_view(*this, "apm"), + m_eprom(*this, "eprom%u", 0U), + m_switches(*this, "switches") + { } + + void mc68000(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + +private: + required_device m_maincpu; + required_device m_irq3; + required_device m_ram; + required_device m_crtc; + required_device_array m_via; + memory_view m_apm_view; + required_memory_region_array<2> m_eprom; + required_ioport m_switches; + + uint16_t *m_ram_base; + uint32_t m_ram_mask; + + std::unique_ptr m_addr_decode; + + uint8_t m_uvia_porta; + uint8_t m_key; + + void mem_map(address_map &map); + void vector_map(address_map &map); + uint16_t memory_r(offs_t offset, uint16_t mem_mask = ~0); + void memory_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + + void kbd_put(uint8_t data); + + MC6845_UPDATE_ROW(crtc_update_row); + + void uvia_porta_w(uint8_t data); + void addr_decode_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); +}; + + +//************************************************************************** +// ADDRESS MAPS +//************************************************************************** + +void mc68000_state::mem_map(address_map &map) +{ + map(0x000000, 0xffffff).view(m_apm_view); + m_apm_view[0](0x000000, 0x007fff).mirror(0xff8000).rom().region("eprom0", 0); + m_apm_view[0](0x000000, 0xffffff).w(FUNC(mc68000_state::addr_decode_w)); + m_apm_view[1](0x000000, 0xffffff).rw(FUNC(mc68000_state::memory_r), FUNC(mc68000_state::memory_w)); +} + +void mc68000_state::vector_map(address_map &map) +{ + // vector number fetched from memory at 0xfffff0 to 0xffffff + map(0xfffff0, 0xffffff).lr16(NAME([this](offs_t offset) -> uint16_t { return memory_r((0xfffff0 >> 1) | offset); })); +} + +uint16_t mc68000_state::memory_r(offs_t offset, uint16_t mem_mask) +{ + uint8_t code = m_addr_decode[offset >> 13]; + uint16_t data = 0x0000; + + switch (code) + { + // ram + case 0x0: + data = m_ram_base[offset & m_ram_mask]; + break; + + // io + case 0x1: + if (machine().side_effects_disabled()) + break; + + LOGMASKED(LOG_IO_READ, "Read from IO: %06x = %04x & %04x\n", offset << 1, data, mem_mask); + + offset = (offset << 1) & 0x3fff; + + // ic45, 74ls139 + switch (offset >> 12) + { + case 0: + if (ACCESSING_BITS_8_15 && (BIT(offset, 1) == 1)) + data = m_crtc->register_r() << 8; + break; + + case 1: + if (ACCESSING_BITS_0_7) + data |= m_via[0]->read(offset >> 1) << 0; + if (ACCESSING_BITS_8_15) + data |= m_via[1]->read(offset >> 1) << 8; + break; + + case 2: + LOGMASKED(LOG_IO_READ, "Unhandled floppy access\n"); + data = 0xffff; + break; + + case 3: + if (ACCESSING_BITS_8_15 && (BIT(offset, 1) == 0)) + { + data = m_key << 8; + + // a read here also selects switch 1 to be read from cb1 + m_via[1]->write_cb1(1); + m_via[1]->write_cb1(BIT(m_switches->read(), 1)); + } + if (ACCESSING_BITS_8_15 && (BIT(offset, 1) == 1)) + m_apm_view.select(0); + break; + } + + LOGMASKED(LOG_IO_READ, "IO data = %04x\n", data); + + break; + + // second eprom slot + case 0x2: + data = m_eprom[1]->as_u16(offset & 0x3fff); + break; + + // monitor rom + case 0x3: + data = m_eprom[0]->as_u16(offset & 0x3fff); + break; + + // bus error + case 0x6: + if (!machine().side_effects_disabled()) + m_maincpu->trigger_bus_error(); + break; + + default: + LOG("Unhandled code %x: %06x = %04x & %04x\n", code, offset, data, mem_mask); + } + + return data & mem_mask; +} + +void mc68000_state::memory_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + uint8_t code = m_addr_decode[offset >> 13]; + + switch (code) + { + // ram + case 0x0: + COMBINE_DATA(&m_ram_base[offset & m_ram_mask]); + break; + + // io + case 0x1: + LOGMASKED(LOG_IO_WRITE, "Write to IO: %06x = %04x & %04x\n", offset << 1, data, mem_mask); + + offset = (offset << 1) & 0x3fff; + + // ic45, 74ls139 + switch (offset >> 12) + { + case 0: + if (ACCESSING_BITS_8_15 && (BIT(offset, 1) == 0)) + m_crtc->address_w(data >> 8); + if (ACCESSING_BITS_8_15 && (BIT(offset, 1) == 1)) + m_crtc->register_w(data >> 8); + break; + + case 1: + if (ACCESSING_BITS_0_7) + m_via[0]->write(offset >> 1, data >> 0); + if (ACCESSING_BITS_8_15) + m_via[1]->write(offset >> 1, data >> 8); + break; + + case 2: + LOGMASKED(LOG_IO_WRITE, "Unhandled floppy access\n"); + break; + + case 3: + if (ACCESSING_BITS_8_15 && (BIT(offset, 1) == 0)) + { + LOGMASKED(LOG_IO_WRITE, "Centronics latch write\n"); + + // a write here also selects switch 0 to be read from cb1 + m_via[1]->write_cb1(1); + m_via[1]->write_cb1(BIT(m_switches->read(), 0)); + } + if (ACCESSING_BITS_8_15 && (BIT(offset, 1) == 1)) + LOGMASKED(LOG_IO_WRITE, "Unhandled volume latch write\n"); + break; + } + + break; + + // second eprom slot + case 0x2: + LOG("Write to second EPROM: %06x = %04x & %04x\n", offset, data, mem_mask); + break; + + // monitor eprom + case 0x3: + LOG("Write to monitor EPROM: %06x = %04x & %04x\n", offset, data, mem_mask); + break; + + // bus error + case 0x6: + m_maincpu->trigger_bus_error(); + break; + + default: + LOG("Unhandled code %x: %06x = %04x & %04x\n", code, offset, data, mem_mask); + } +} + + +//************************************************************************** +// INPUT DEFINITIONS +//************************************************************************** + +static INPUT_PORTS_START( mc68000 ) + PORT_START("switches") + PORT_DIPNAME(0x01, 0x01, "IO Mode") + PORT_DIPLOCATION("DIL:1") + PORT_DIPSETTING( 0x00, "Terminal") + PORT_DIPSETTING( 0x01, "Internal") + PORT_DIPNAME(0x02, 0x02, "Columns") + PORT_DIPLOCATION("DIL:2") + PORT_DIPSETTING( 0x00, "40") + PORT_DIPSETTING( 0x02, "80") + // DIL:3 and DIL:4 select parallel keyboard strobe polarity +INPUT_PORTS_END + +void mc68000_state::kbd_put(uint8_t data) +{ + m_key = data; + + m_via[0]->write_ca2(1); + m_via[0]->write_ca2(0); +} + + +//************************************************************************** +// VIDEO EMULATION +//************************************************************************** + +MC6845_UPDATE_ROW( mc68000_state::crtc_update_row ) +{ + // page select + offs_t offset = (m_uvia_porta & 0x07 & (m_ram_mask >> 15)) << 16; + + // offset into page + offset |= ((ma & 0x3000) << 2) | ((ra & 0x07) << 11) | (ma & 0x7fe); + + rgb_t fg = rgb_t::white(); + rgb_t bg = rgb_t::black(); + + for (int i = 0; i < x_count / 2; i++) + { + uint16_t data = m_ram_base[(offset >> 1) + i]; + + // cursor + if (cursor_x == (i * 2) + 0) + data |= 0xff00; + else if (cursor_x == (i * 2) + 1) + data |= 0x00ff; + + // lines 8 and 9 are blank + if (ra > 7) + data = 0x0000; + + // draw 16 pixels of the cell + for (int x = 0; x < 16; x++) + bitmap.pix(y, x + i * 16) = BIT(data, 15 - x) ? fg : bg; + } +} + + +//************************************************************************** +// MACHINE EMULATION +//************************************************************************** + +void mc68000_state::uvia_porta_w(uint8_t data) +{ + m_uvia_porta = data; +} + +void mc68000_state::addr_decode_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + if (ACCESSING_BITS_0_7) + m_addr_decode[offset >> 13] = data & 0x0f; + + // a write here deselects the address decoder + if (ACCESSING_BITS_8_15) + m_apm_view.select(1); +} + +void mc68000_state::machine_start() +{ + // allocate space for address decoder ram + m_addr_decode = std::make_unique(0x400); + + // base ram + m_ram_base = reinterpret_cast(m_ram->pointer()); + m_ram_mask = m_ram->mask() >> 1; + + // register for save states + save_pointer(NAME(m_addr_decode), 0x400); + save_item(NAME(m_uvia_porta)); + save_item(NAME(m_key)); +} + +void mc68000_state::machine_reset() +{ + m_apm_view.select(0); +} + + +//************************************************************************** +// MACHINE DEFINTIONS +//************************************************************************** + +void mc68000_state::mc68000(machine_config &config) +{ + M68000(config, m_maincpu, 16_MHz_XTAL / 2); + m_maincpu->set_addrmap(AS_PROGRAM, &mc68000_state::mem_map); + m_maincpu->set_addrmap(m68000_base_device::AS_CPU_SPACE, &mc68000_state::vector_map); + + INPUT_MERGER_ANY_HIGH(config, m_irq3); + m_irq3->output_handler().set_inputline(m_maincpu, INPUT_LINE_IRQ3); + + RAM(config, RAM_TAG).set_default_size("128K").set_extra_options("512K"); + + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_raw(16_MHz_XTAL / 2, 1024, 0, 312, 640, 0, 250); + screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update)); + + MC6845(config, m_crtc, 16_MHz_XTAL / 8); + m_crtc->set_screen("screen"); + m_crtc->set_show_border_area(false); + m_crtc->set_char_width(8); + m_crtc->set_update_row_callback(FUNC(mc68000_state::crtc_update_row)); + m_crtc->out_vsync_callback().set(m_via[1], FUNC(via6522_device::write_ca1)); + + MOS6522(config, m_via[0], 16_MHz_XTAL / 16); // ic55 + m_via[0]->irq_handler().set(m_irq3, FUNC(input_merger_device::in_w<0>)); + + MOS6522(config, m_via[1], 16_MHz_XTAL / 16); // ic56 + m_via[1]->irq_handler().set(m_irq3, FUNC(input_merger_device::in_w<1>)); + m_via[1]->writepa_handler().set(FUNC(mc68000_state::uvia_porta_w)); + + generic_keyboard_device &kbd(GENERIC_KEYBOARD(config, "kbd", 0)); + kbd.set_keyboard_callback(FUNC(mc68000_state::kbd_put)); +} + + +//************************************************************************** +// ROM DEFINITIONS +//************************************************************************** + +ROM_START( mc68000 ) + ROM_REGION16_BE(0x8000, "eprom0", 0) + ROM_LOAD16_BYTE("mc68000_system_1.41_upper.bin", 0x00000, 0x4000, CRC(e57f246f) SHA1(89e59e307ced22f243c4f6619dc07948e714fe71)) + ROM_LOAD16_BYTE("mc68000_system_1.41_lower.bin", 0x00001, 0x4000, CRC(9183494d) SHA1(3be47d956d03e4f89c7ff17e027cd2fe8334d64a)) + + ROM_REGION16_BE(0x8000, "eprom1", 0) + ROM_LOAD16_BYTE("mc68000_cpm_2.0_upper.bin", 0x00000, 0x4000, CRC(9dbe197a) SHA1(a26dcbbf567cdccf026ce5cebb248e52b5a8b24a)) + ROM_LOAD16_BYTE("mc68000_cpm_2.0_lower.bin", 0x00001, 0x4000, CRC(064dcc3b) SHA1(2fa3d1ddf1485bc46ddc90e2a68d9cc654157c27)) +ROM_END + + +} // anonymous namespace + + +//************************************************************************** +// SYSTEM DRIVERS +//************************************************************************** + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1984, mc68000, 0, 0, mc68000, mc68000, mc68000_state, empty_init, "mc / Franzis Verlag", "mc-68000-Computer", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) -- cgit v1.2.3