diff options
Diffstat (limited to 'src/devices/bus/vme/sys68k_cpu1.cpp')
-rw-r--r-- | src/devices/bus/vme/sys68k_cpu1.cpp | 671 |
1 files changed, 671 insertions, 0 deletions
diff --git a/src/devices/bus/vme/sys68k_cpu1.cpp b/src/devices/bus/vme/sys68k_cpu1.cpp new file mode 100644 index 00000000000..160a14ad3e8 --- /dev/null +++ b/src/devices/bus/vme/sys68k_cpu1.cpp @@ -0,0 +1,671 @@ +// license:BSD-3-Clause +// copyright-holders:Joakim Larsson Edstrom +/*************************************************************************** + * + * Force SYS68K CPU-1/CPU-6 VME SBC drivers, initially based on the 68ksbc.c + * + * 13/06/2015 + * + * The info found on the links below is for a later revisions of the board I have + * but it is somewhat compatible so I got the system ROM up and running in terminal. + * My CPU-1 board has proms from 1983 and the PCB has no rev markings so probably + * the original or a very early design. The board real estate differs from the later + * CPU-1:s I found pictures of but has the same main chips and functions. + * + * http://bitsavers.trailing-edge.com/pdf/forceComputers/1988_Force_VMEbus_Products.pdf + * http://www.artisantg.com/info/P_wUovN.pdf + * + * Some info from those documents: + * + * Address Map + * ---------------------------------------------------------- + * Address Range Description + * ---------------------------------------------------------- + * 000 000 - 000 007 Initialisation vectors from system EPROM + * 000 008 - 01F FFF Dynamic RAM on CPU-1 B + * 000 008 - 07F FFF Dynamic RAM on CPU-1 D + * 080 008 - 09F FFF SYSTEM EPROM Area + * OAO 000 - OBF FFF USER EPROMArea + * 0C0 041 - 0C0 043 ACIA (P3) Host + * 0C0 080 - 0C0 082 ACIA (P4) Terminal + * 0C0 101 - 0C0 103 ACIA (P5) Remote device (eg serial printer) + * 0C0 401 - 0C0 42F RTC + * OEO 001 - 0E0 035 PI/T (eg centronics printer) + * OEO 200 - 0E0 2FF FPU + * OEO 300 - 0E0 300 Reset Off + * OEO 380 - 0E0 380 Reset On + * 100 000 - FEF FFF VMEbus addresses (A24) + * FFO 000 - FFF FFF VMEbus Short I/O (A16) + * ---------------------------------------------------------- + * + * Interrupt sources + * ---------------------------------------------------------- + * Description Device Lvl IRQ VME board + * /Board Vector Address + * ---------------------------------------------------------- + * On board Sources + * ABORT Switch 7 31 + * Real Time Clock (RTC) 58167A 6 30 + * Parallel/Timer (PI/T) 68230 5 29 + * Terminal ACIA 6850 4 28 + * Remote ACIA 6850 3 27 + * Host ACIA 6850 2 26 + * ACFAIL, SYSFAIL VME 5 29 + * Off board Sources (other VME boards) + * 6 Port Serial I/O board SIO 4 64-75 0xb00000 + * 8 Port Serial I/O board ISIO 4 76-83 0x960000 + * Disk Controller WFC 3 119 0xb01000 + * SCSI Controller ISCSI 4 119 0xa00000 + * Slot 1 Controller Board ASCU 7 31 0xb02000 + * ---------------------------------------------------------- + * + * TODO: + * - Add internal layout with switches and leds + * + ****************************************************************************/ + +#include "emu.h" +#include "sys68k_cpu1.h" + +#include "bus/rs232/rs232.h" +#include "cpu/m68000/m68000.h" +#include "machine/clock.h" +#include "softlist.h" + +/* + * The baudrate on the Force68k CPU-1 to CPU-6 is generated by a Motorola 14411 bitrate generator + * The CPU-6 documents matches the circuits that I could find on the CPU-1 board. + * + * From the documents: + * + * 3 RS232C interfaces, strap selectable baud rate from 110-9600 or 600-19200 baud (CPU-1B datasheet) + * or + * 3 RS232C interfaces, strap selectable baud rate from 60-9600 or 240-38400 baud (CPU-6 Users manual) + * + * Default Jumper Settings of B7: + * -------------------------------- + * GND 10 - 11 RSA input on 14411 + * F1 on 14411 1 - 20 Baud selector of the terminal port + * F1 on 14411 3 - 18 Baud selector of the host port + * F1 on 14411 5 - 16 Baud selector of the remote port + * + * The RSB input on the 14411 is kept high always so RSA=0, RSB=1 and a 1.8432MHz crystal + * generates 153600 on the F1 output pin which by default strapping is connected to all + * three 6850 acias on the board. These can be strapped separatelly to speedup downloads. + * + * The selectable outputs from 14411, F1-F16: + * X16 RSA=0,RSB=1: 153600, 115200, 76800, 57600, 38400, 28800, 19200, 9600, 4800, 3200, 2153.3, 1758.8, 1200, 921600, 1843000 + * X64 RSA=1,RSB=1: 614400, 460800, 307200, 230400, 153600, 115200, 76800, 57600, 38400, 28800, 19200, 9600, 4800, 921600, 1843000 + * + * However, the datasheet says baudrate is strapable for 110-9600 but the output is 153600 + * so the system rom MUST setup the acia to divide by 16 to generate the correct baudrate. + * + * There are multiple ways to achieve some of the baud rates and we have only seen a CPU-6 users manual so + * emulation mimics a CPU-6 board at the moment until further information has been gathered. + */ + +//************************************************************************** +// CONFIGURABLE LOGGING +//************************************************************************** + +#define LOG_SETUP (1U << 1) + +//#define VERBOSE (LOG_GENERAL | LOG_SETUP) +//#define LOG_OUTPUT_FUNC printf +#include "logmacro.h" + +// #define LOG(...) LOGMASKED(LOG_SETUP, __VA_ARGS__) // defined in logmacro.h +#define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__) + +//************************************************************************** +// MACROS / CONSTANTS +//************************************************************************** + +#ifdef _MSC_VER +#define FUNCNAME __func__ +#else +#define FUNCNAME __PRETTY_FUNCTION__ +#endif + + +DEFINE_DEVICE_TYPE(VME_SYS68K_CPU1, vme_sys68k_cpu1_card_device, "sys68k_cpu1", "Force Computers SYS68K/CPU-1") + +vme_sys68k_cpu1_card_device::vme_sys68k_cpu1_card_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : device_t(mconfig, VME_SYS68K_CPU1, tag, owner, clock) + , device_vme_card_interface(mconfig, *this) + , m_maincpu(*this, "maincpu") + , m_rtc(*this, "rtc") + , m_pit(*this, "pit") + , m_brg(*this, "brg") + , m_aciahost(*this, "aciahost") + , m_aciaterm(*this, "aciaterm") + , m_aciaremt(*this, "aciaremt") + , m_centronics(*this, "centronics") + , m_centronics_ack(0) + , m_centronics_busy(0) + , m_centronics_perror(0) + , m_centronics_select(0) + , m_serial_brf(*this, "SERIAL_BRF") + , m_serial_p3(*this, "SERIAL_P3") + , m_serial_p4(*this, "SERIAL_P4") + , m_serial_p5(*this, "SERIAL_P5") + , m_cart(*this, "exp_rom1") + , m_eprom(*this, "eprom") + , m_ram(*this, "ram") +{ +} + +void vme_sys68k_cpu1_card_device::force68k_mem(address_map &map) +{ + map.unmap_value_high(); + map(0x000000, 0x01ffff).ram().share("ram"); /* DRAM CPU-1B */ +// map(0x020000, 0x07ffff).ram(); /* Additional DRAM CPU-1D */ + map(0x080000, 0x09ffff).rom().region("eprom", 0); /* System EPROM Area 128Kb DEBUGGER supplied as default on CPU-1B/D */ + //map(0x0a0000, 0x0bffff).rom().region("user", 0); /* User EPROM/SRAM Area, max 128Kb mapped by a cartslot */ + map(0x0c0040, 0x0c0043).rw(m_aciahost, FUNC(acia6850_device::read), FUNC(acia6850_device::write)).umask16(0x00ff); + map(0x0c0080, 0x0c0083).rw(m_aciaterm, FUNC(acia6850_device::read), FUNC(acia6850_device::write)).umask16(0xff00); + map(0x0c0100, 0x0c0103).rw(m_aciaremt, FUNC(acia6850_device::read), FUNC(acia6850_device::write)).umask16(0x00ff); + map(0x0c0400, 0x0c042f).rw(m_rtc, FUNC(mm58167_device::read), FUNC(mm58167_device::write)).umask16(0x00ff); + map(0x0e0000, 0x0e0035).rw(m_pit, FUNC(pit68230_device::read), FUNC(pit68230_device::write)).umask16(0x00ff); +// map(0x0e0200, 0x0e0380).rw(FUNC(vme_sys68k_cpu1_card_device::fpu_r), FUNC(vme_sys68k_cpu1_card_device::fpu_w)); /* optional FPCP 68881 FPU interface */ + map(0x100000, 0xfeffff).rw(FUNC(vme_sys68k_cpu1_card_device::vme_a24_r), FUNC(vme_sys68k_cpu1_card_device::vme_a24_w)); /* VMEbus Rev B addresses (24 bits) */ + map(0xff0000, 0xffffff).rw(FUNC(vme_sys68k_cpu1_card_device::vme_a16_r), FUNC(vme_sys68k_cpu1_card_device::vme_a16_w)); /* VMEbus Rev B addresses (16 bits) */ +} + +/* Input ports */ +static INPUT_PORTS_START (sys68k_cpu1) + + PORT_START("SERIAL_BRF") + PORT_CONFNAME(0x80 , 0x00 , "Baud Rate Factor") // RSA pin on MC14411 + PORT_CONFSETTING(0x00, "1x (Lo)") + PORT_CONFSETTING(0x80, "4x (Hi)") + + PORT_START("SERIAL_P3") + PORT_CONFNAME(0x0F , 0x00 , "P3 Host Baud Lo/Hi") // F1-Fx pins on MC14411 + PORT_CONFSETTING(mc14411_device::TIMER_F1, "9600/38400") // RSA=1x/16x + PORT_CONFSETTING(mc14411_device::TIMER_F3, "4800/19200") + PORT_CONFSETTING(mc14411_device::TIMER_F5, "2400/9600") + PORT_CONFSETTING(mc14411_device::TIMER_F7, "1200/4800") + PORT_CONFSETTING(mc14411_device::TIMER_F8, "600/2400") + PORT_CONFSETTING(mc14411_device::TIMER_F9, "300/1200") + PORT_CONFSETTING(mc14411_device::TIMER_F11, "150/600") + PORT_CONFSETTING(mc14411_device::TIMER_F13, "110/440") + PORT_CONFSETTING(mc14411_device::TIMER_F15, "60/240") + + PORT_START("SERIAL_P4") + PORT_CONFNAME(0x0F , 0x00 , "P4 Terminal Baud Lo/Hi") // F1-Fx pins on MC14411 + PORT_CONFSETTING(mc14411_device::TIMER_F1, "9600/38400") // RSA=1x/16x + PORT_CONFSETTING(mc14411_device::TIMER_F3, "4800/19200") + PORT_CONFSETTING(mc14411_device::TIMER_F5, "2400/9600") + PORT_CONFSETTING(mc14411_device::TIMER_F7, "1200/4800") + PORT_CONFSETTING(mc14411_device::TIMER_F8, "600/2400") + PORT_CONFSETTING(mc14411_device::TIMER_F9, "300/1200") + PORT_CONFSETTING(mc14411_device::TIMER_F11, "150/600") + PORT_CONFSETTING(mc14411_device::TIMER_F13, "110/440") + PORT_CONFSETTING(mc14411_device::TIMER_F15, "60/240") + + PORT_START("SERIAL_P5") + PORT_CONFNAME(0x0F , 0x00 , "P5 Remote Baud Lo/Hi") // F1-Fx pins on MC14411 + PORT_CONFSETTING(mc14411_device::TIMER_F1, "9600/38400") // RSA=1x/16x + PORT_CONFSETTING(mc14411_device::TIMER_F3, "4800/19200") + PORT_CONFSETTING(mc14411_device::TIMER_F5, "2400/9600") + PORT_CONFSETTING(mc14411_device::TIMER_F7, "1200/4800") + PORT_CONFSETTING(mc14411_device::TIMER_F8, "600/2400") + PORT_CONFSETTING(mc14411_device::TIMER_F9, "300/1200") + PORT_CONFSETTING(mc14411_device::TIMER_F11, "150/600") + PORT_CONFSETTING(mc14411_device::TIMER_F13, "110/440") + PORT_CONFSETTING(mc14411_device::TIMER_F15, "60/240") + +INPUT_PORTS_END + +/* + * Centronics support + * + * The system ROMs has support for a parallel printer interface but the signals are just routed to row A + * of the VME P2 connector so no on board Centronics connector is available but assumed to be added on a + * separate I/O board. After some detective work I found that the ROM works as follows: + * + * The 'PA' (Printer Attach) command issues a <cr> on Port A and sends a strobe on H2 it then loops over + * the select signal, bit 0 on Port B, and the ack signal on HS1, both to be non zero. The support is really + * flawed as the strobe signal goes high instead of low ( this might assume an inverting driver on the + * P2 board ) and the busy signal is not checked at all. Or I might have assumed it all wrong, but it now + * works with the generic centronics printer driver. Need the printer board documentation to improve further. + * + * When the 'PA' command is successful everything printed to screen is mirrored on the printer. Use the + * 'NOPA' command to stop mirroring. I had no printer ROMs so could not test it with a "real" printer. + * + * Force CPU-1 init sequence for MC68230 PIT + * ----------------------------------------- + * 0801E6 0E0000 W 00 -> PGCR Mode 0 (uni8), H34 dis, H12 dis, H1234 HZ + * 0801E6 0E0002 W 00 -> PSRR PC4, PC5, H1S>H2S>H3S>H4S + * 0801E6 0E0004 W FF -> PADDR Port A all Outputs + * 0801E6 0E0006 W 00 -> PBDDR Port B all Inputs + * 0801EA 0E000C W 60 -> PACR Port A Mode 01, pin def, dbfr H1 data rec, H2 status/int, H2 output neg, H2S clrd + * 0801F0 0E000E W A0 -> PBCR Port B mode 1x, H4 output neg, H4S clrd, H3 int dis, H3 edg input, H3S set by assrt edg + * 0801F6 0E0000 W 30 -> PGCR H34 enable, H12enable + * 0801FC 0E000E W A8 -> PBCR +H4 asserted + * 08020A 0E000E W A0 -> PBCR +H4 negated + * + * Upon PA (Printer Attach) command enabling the Centronics printer mode + * --------------------------------------------------------------------- + * 081DB4 0E0011 W D0 -> PADR Data to Port A + * 081DB8 0E000D W 68 -> PACR H2 output asserted Centronics Strobe + * 081DC0 0E000D W 60 -> PACR H2 output negated + * 081DD0 0E0013 R 00 <- PBDR Port B polled for 01 (data) & 03 (mask) + * + */ + +/* Centronics ACK handler + * The centronics ack signal is expected by the ROM to arrive at H1 input line + */ +void vme_sys68k_cpu1_card_device::centronics_ack_w(int state) +{ + LOG("%s(%d)\n", FUNCNAME, state); + m_centronics_ack = state; + m_pit->h1_set(state); +} + +/* Centronics BUSY handler + * The centronics busy signal is not used by the ROM driver afaik + */ +void vme_sys68k_cpu1_card_device::centronics_busy_w(int state) +{ + LOG("%s(%d)\n", FUNCNAME, state); + m_centronics_busy = state; +} + +/* Centronics PERROR handler + * The centronics perror signal is not used by the ROM driver afaik + */ +void vme_sys68k_cpu1_card_device::centronics_perror_w(int state) +{ + LOG("%s(%d)\n", FUNCNAME, state); + m_centronics_perror = state; +} + +/* Centronics SELECT handler + * The centronics select signal is expected by the ROM on Port B bit 0 + */ +void vme_sys68k_cpu1_card_device::centronics_select_w(int state) +{ + LOG("%s(%d)\n", FUNCNAME, state); + m_centronics_select = state; + m_pit->portb_setbit(0, state); +} + +/* Start it up */ +void vme_sys68k_cpu1_card_device::device_start() +{ + LOG("%s\n", FUNCNAME); + + save_item(NAME(m_centronics_busy)); + save_item(NAME(m_centronics_ack)); + save_item(NAME(m_centronics_select)); + save_item(NAME(m_centronics_perror)); + + /* Map user ROM/RAM socket(s) */ + if (m_cart->exists()) + { + m_usrrom = (uint16_t*)m_cart->get_rom_base(); +#if 0 // This should be the correct way but produces odd and even bytes swapped + m_maincpu->space(AS_PROGRAM).install_read_handler(0xa0000, 0xbffff, read16sm_delegate(*m_cart, FUNC(generic_slot_device::read16_rom))); +#else // So we install a custom very inefficient handler for now until we understand how to solve the problem better + m_maincpu->space(AS_PROGRAM).install_read_handler(0xa0000, 0xbffff, read16sm_delegate(*this, FUNC(vme_sys68k_cpu1_card_device::read16_rom))); +#endif + } +} + +/* Reset it */ +void vme_sys68k_cpu1_card_device::device_reset() +{ + LOG("%s\n", FUNCNAME); + + // Set up the BRG divider. RSA is a jumper setting and RSB is always set High + m_brg->rsa_w(m_serial_brf->read() == 0x80 ? ASSERT_LINE : CLEAR_LINE); + m_brg->rsb_w(ASSERT_LINE); + + // Disable all configured timers, only enabling the used ones + m_brg->timer_disable_all(); + m_brg->timer_enable((mc14411_device::timer_id) m_serial_p3->read(), true); + m_brg->timer_enable((mc14411_device::timer_id) m_serial_p4->read(), true); + m_brg->timer_enable((mc14411_device::timer_id) m_serial_p5->read(), true); + + m_maincpu->space(AS_PROGRAM).install_rom(0, m_eprom->bytes() - 1, m_eprom->base()); + + m_boot_mph = m_maincpu->space(AS_PROGRAM).install_read_tap(0x000006, 0x000007, "boot", + [this](offs_t offset, uint16_t &data, uint16_t mem_mask) + { + if (!machine().side_effects_disabled() && ACCESSING_BITS_0_7) + { + m_maincpu->space(AS_PROGRAM).install_ram(0, m_ram.bytes() - 1, m_ram.target()); + m_boot_mph.remove(); + } + }); +} + +/* A very inefficient User cart emulation of two 8 bit sockets (odd and even) */ +uint16_t vme_sys68k_cpu1_card_device::read16_rom(offs_t offset) +{ + offset = offset % m_cart->common_get_size("rom"); // Don't read outside buffer... + return swapendian_int16(m_usrrom [offset]); +} + +/* 10. The VMEbus (text from board documentation) + * --------------- + * The implemented VMEbus Interface includes 24 address, 16 data, + * 6 address modifier and the asynchronous control signals. + * A single level bus arbiter is provided to build multi master + * systems. In addition to the bus arbiter, a separate slave bus + * arbitration allows selection of the arbitration level (0-3). + * + * The address modifier range .,Short 110 Access can be selected + * via a jumper for variable system generation. The 7 interrupt + * request levels of the VMEbus are fully supported from the + * SYS68K1CPU-1 B/D. For multi-processing, each IRQ signal can be + * enabled/disabled via a jumper field. + * + * Additionally, the SYS68K1CPU-1 B/D supports the ACFAIL, SYSRESET, + * SYSFAIL and SYSCLK signal (16 MHz). + */ + +/* Dummy VME access methods until the VME bus device is ready for use */ +uint16_t vme_sys68k_cpu1_card_device::vme_a24_r() +{ + LOG("%s\n", FUNCNAME); + return (uint16_t) 0; +} + +void vme_sys68k_cpu1_card_device::vme_a24_w(uint16_t data) +{ + LOG("%s\n", FUNCNAME); +} + +uint16_t vme_sys68k_cpu1_card_device::vme_a16_r() +{ + LOG("%s\n", FUNCNAME); + return (uint16_t) 0; +} + +void vme_sys68k_cpu1_card_device::vme_a16_w(uint16_t data) +{ + LOG("%s\n", FUNCNAME); +} + +/* + * Serial port clock sources can all be driven by different or the same output(s) of the MC14411 + */ +void vme_sys68k_cpu1_card_device::write_acia_clocks(int id, int state) +{ + if (id == m_serial_p3->read()) + { + m_aciahost->write_txc(state); + m_aciahost->write_rxc(state); + } + if (id == m_serial_p4->read()) + { + m_aciaterm->write_txc(state); + m_aciaterm->write_rxc(state); + } + if (id == m_serial_p5->read()) + { + m_aciaremt->write_txc(state); + m_aciaremt->write_rxc(state); + } +} + +/* + * 4. The USER Area (Text from the board manual) + The USER area contains two 28 pin sockets with JEDEC compatible pin out. + To allow the usage of static RAM's, the access to the USER area is byte + oriented. Table 3. lists the usable device types. + + Bits Bytes EPROM SRAM + -------------------------- + 2Kx16 4 Kbyte 2716 6116 + 4Kx16 8 Kbyte 2732 + 8Kx16 16 Kbyte 2764 6264 + 16Kx16 32 Kbyte 27128 + 32Kx16 64 Kbyte 27256 + -------------------------- +*/ +// Implementation of static 2 x 64K EPROM in sockets J10/J11 as 16 bit wide cartridge for easier +// software handling. TODO: make configurable according to table above. +void vme_sys68k_cpu1_card_device::fccpu1_eprom_sockets(machine_config &config) +{ + generic_cartslot_device &exp_rom1(GENERIC_CARTSLOT(config, "exp_rom1", generic_plain_slot, "fccpu1_cart", "bin,rom")); + exp_rom1.set_width(GENERIC_ROM16_WIDTH); + exp_rom1.set_endian(ENDIANNESS_BIG); + exp_rom1.set_device_load(FUNC(vme_sys68k_cpu1_card_device::exp1_load)); +// SOFTWARE_LIST(config, "cart_list").set_original("fccpu1_cart"); +} + +/*************************** + Rom loading functions +****************************/ +std::pair<std::error_condition, std::string> vme_sys68k_cpu1_card_device::force68k_load_cart(device_image_interface &image, generic_slot_device *slot) +{ + uint32_t size = slot->common_get_size("rom"); + + if (size > 0x2'0000) // Max 128Kb + { + return std::make_pair( + image_error::INVALIDLENGTH, + util::string_format("Cartridge size %d exceeds max size (128K)", size)); + } + + slot->rom_alloc(size, GENERIC_ROM16_WIDTH, ENDIANNESS_BIG); + slot->common_load_rom(slot->get_rom_base(), size, "rom"); + + return std::make_pair(std::error_condition(), std::string()); +} + +/* + * Machine configuration + */ +void vme_sys68k_cpu1_card_device::device_add_mconfig(machine_config &config) +{ + /* basic machine hardware */ + M68000(config, m_maincpu, XTAL(16'000'000) / 2); + m_maincpu->set_addrmap(AS_PROGRAM, &vme_sys68k_cpu1_card_device::force68k_mem); + + /* P3/Host Port config + * LO command causes ROM monitor to expect S-records on HOST port by default + * Implementation through nullmodem currently does not support handshakes so + * the ROM monitor is over-run while checking for checksums etc if used with + * UI mount <file> feature. + */ + ACIA6850(config, m_aciahost, 0); + m_aciahost->txd_handler().set("rs232host", FUNC(rs232_port_device::write_txd)); + m_aciahost->rts_handler().set("rs232host", FUNC(rs232_port_device::write_rts)); + + rs232_port_device &rs232host(RS232_PORT(config, "rs232host", default_rs232_devices, "null_modem")); + rs232host.rxd_handler().set(m_aciahost, FUNC(acia6850_device::write_rxd)); + rs232host.cts_handler().set(m_aciahost, FUNC(acia6850_device::write_cts)); + + /* P4/Terminal Port config */ + ACIA6850(config, m_aciaterm, 0); + m_aciaterm->txd_handler().set("rs232trm", FUNC(rs232_port_device::write_txd)); + m_aciaterm->rts_handler().set("rs232trm", FUNC(rs232_port_device::write_rts)); + + rs232_port_device &rs232trm(RS232_PORT(config, "rs232trm", default_rs232_devices, "terminal")); + rs232trm.rxd_handler().set(m_aciaterm, FUNC(acia6850_device::write_rxd)); + rs232trm.cts_handler().set(m_aciaterm, FUNC(acia6850_device::write_cts)); + + /* P5/Remote Port config */ + ACIA6850(config, m_aciaremt, 0); + + /* Bit Rate Generator */ + MC14411(config, m_brg, XTAL(1'843'200)); + m_brg->out_f<1>().set(FUNC(vme_sys68k_cpu1_card_device::write_f1_clock)); + m_brg->out_f<3>().set(FUNC(vme_sys68k_cpu1_card_device::write_f3_clock)); + m_brg->out_f<5>().set(FUNC(vme_sys68k_cpu1_card_device::write_f5_clock)); + m_brg->out_f<7>().set(FUNC(vme_sys68k_cpu1_card_device::write_f7_clock)); + m_brg->out_f<8>().set(FUNC(vme_sys68k_cpu1_card_device::write_f8_clock)); + m_brg->out_f<9>().set(FUNC(vme_sys68k_cpu1_card_device::write_f9_clock)); + m_brg->out_f<11>().set(FUNC(vme_sys68k_cpu1_card_device::write_f11_clock)); + m_brg->out_f<13>().set(FUNC(vme_sys68k_cpu1_card_device::write_f13_clock)); + m_brg->out_f<15>().set(FUNC(vme_sys68k_cpu1_card_device::write_f15_clock)); + + /* RTC Real Time Clock device */ + MM58167(config, m_rtc, XTAL(32'768)); + + /* PIT Parallel Interface and Timer device, assuming strapped for on board clock */ + PIT68230(config, m_pit, XTAL(16'000'000) / 2); + m_pit->pa_out_callback().set("cent_data_out", FUNC(output_latch_device::write)); + m_pit->h2_out_callback().set(m_centronics, FUNC(centronics_device::write_strobe)); + + // Centronics + CENTRONICS(config, m_centronics, centronics_devices, "printer"); + m_centronics->ack_handler().set(FUNC(vme_sys68k_cpu1_card_device::centronics_ack_w)); + m_centronics->busy_handler().set(FUNC(vme_sys68k_cpu1_card_device::centronics_busy_w)); + m_centronics->perror_handler().set(FUNC(vme_sys68k_cpu1_card_device::centronics_perror_w)); + m_centronics->select_handler().set(FUNC(vme_sys68k_cpu1_card_device::centronics_select_w)); + + output_latch_device &latch(OUTPUT_LATCH(config, "cent_data_out")); + m_centronics->set_output_latch(latch); + + // EPROM sockets + fccpu1_eprom_sockets(config); +} + +#if 0 /* + * CPU-6 family is device and adressmap compatible with CPU-1 but with additions + * such as an optional 68881 FPU + */ +void vme_sys68k_cpu1_card_device::fccpu6(machine_config &config) +{ + M68000(config, m_maincpu, XTAL(8'000'000)); /* Jumper B10 Mode B */ + m_maincpu->set_addrmap(AS_PROGRAM, &vme_sys68k_cpu1_card_device::force68k_mem); +} + +void vme_sys68k_cpu1_card_device::fccpu6a(machine_config &config) +{ + M68000(config, m_maincpu, XTAL(12'500'000)); /* Jumper B10 Mode A */ + m_maincpu->set_addrmap(AS_PROGRAM, &vme_sys68k_cpu1_card_device::force68k_mem); +} + +void vme_sys68k_cpu1_card_device::fccpu6v(machine_config &config) +{ + M68010(config, m_maincpu, XTAL(8'000'000)); /* Jumper B10 Mode B */ + m_maincpu->set_addrmap(AS_PROGRAM, &vme_sys68k_cpu1_card_device::force68k_mem); +} + +void vme_sys68k_cpu1_card_device::fccpu6va(machine_config &config) +{ + M68010(config, m_maincpu, XTAL(12'500'000)); /* Jumper B10 Mode A */ + m_maincpu->set_addrmap(AS_PROGRAM, &vme_sys68k_cpu1_card_device::force68k_mem); +} + +void vme_sys68k_cpu1_card_device::fccpu6vb(machine_config &config) +{ + M68010(config, m_maincpu, XTAL(12'500'000)); /* Jumper B10 Mode A */ + m_maincpu->set_addrmap(AS_PROGRAM, &vme_sys68k_cpu1_card_device::force68k_mem); +} +#endif + +/* ROM definitions */ +ROM_START (sys68k_cpu1) + ROM_REGION16_BE(0x20000, "eprom", 0) + ROM_DEFAULT_BIOS("forcebug-1.1") + + ROM_SYSTEM_BIOS(0, "forcemon-1.0l", "Force Computers SYS68K/CPU-1 Force Monitor 1.0L") + ROMX_LOAD ("fccpu1v1.0l.j8.bin", 0x0001, 0x2000, CRC (3ac6f08f) SHA1 (502f6547b508d8732bd68bbbb2402d8c30fefc3b), ROM_SKIP(1) | ROM_BIOS(0)) + ROMX_LOAD ("fccpu1v1.0l.j9.bin", 0x0000, 0x2000, CRC (035315fb) SHA1 (90dc44d9c25d28428233e6846da6edce2d69e440), ROM_SKIP(1) | ROM_BIOS(0)) + + ROM_SYSTEM_BIOS(1, "forcebug-1.1", "Force Computers SYS68K/CPU-1 Force Debugger 1.1") + ROMX_LOAD ("fccpu1v1.1.j8.bin", 0x0001, 0x4000, CRC (116dcbf0) SHA1 (6870b71606933f84afe27ad031c651d201b93f99), ROM_SKIP(1) | ROM_BIOS(1)) + ROMX_LOAD ("fccpu1v1.1.j9.bin", 0x0000, 0x4000, CRC (aefd5b0b) SHA1 (1e24530a6d5dc4fb77fde67acae08d371e59fc0f), ROM_SKIP(1) | ROM_BIOS(1)) + +/* + * System ROM terminal commands + * + * COMMAND SUMMARY DESCRIPTION (From CPU-1B datasheet, ROMs were dumped + * from a CPU-1 board so some features might be missing or different) + * --------------------------------------------------------------------------- + * BF <address1> <address2> <data> <CR> Block Fill memory - from addr1 through addr2 with data + * BM <address1> <address2> <address 3> <CR> Block Move - move from addr1 through addr2to addr3 + * BR [<address> [; <count>] ... ] <CR> Set/display Breakpoint + * BS <address1> <address2> <data> <CR> Block Search - search addr1 through addr2 for data + * BT <address1> <address2> <CR> Block Test of memory + * DC <expression> <CR> Data Conversion + * DF <CR> Display Formatted registers + * DU [n] <address1> <address2>[<string>] <CR> Dump memory to object file + * GO or G [<address] <CR> Execute program. + * GD [<address] <CR> Go Direct + * GT <address> <CR> Exec prog: temporary breakpoint + * HE<CR> Help; display monitor commands + * LO [n] [;<options] <CR> Load Object file + * MD <address> [<count>] <CR> Memory Display + * MM or M <address> [<data<][;<options>] <CR> Memory Modify + * MS <address> <data1 > <data2> < ... <CR> Memory Set - starting at addr with data 1. data 2 ... + * NOBR [<address> ... ] <CR> Remove Breakpoint + * NOPA <CR> Printer Detach (Centronics on PIT/P2) + * OF <CR> Offset + * PA <CR> Printer Attach (Centronics on PIT/P2) + * PF[n] <CR> Set/display Port Format + * RM <CR> Register Modify + * TM [<exit character>] <CR> Transparent Mode + * TR OR T [<count] <CR> Trace + * TT <address> <CR> Trace: temporary breakpoint + * VE [n] [<string] <CR> Verify memory/object file + * ---------------------------------------------------------------------------- + * .AO - .A7 [<expression] <CR> Display/set address register + * .00 - .07 [<expression] <CR> Display/set data register + * .RO - .R6 [<expression] <CR> Display/set offset register + * .PC [<expression] <CR> Display/set program counter + * .SR [<expression] <CR> Display/set status register + * .SS [<expression] <CR> Display/set supervisor stack + * .US [<expression] <CR> Display/set user stack + * ---------------------------------------------------------------------------- + * MD <address> [<count>]; DI <CR> Disassemble memory location + * MM <address>; DI <CR> Disassemble/Assemble memory location + * ---------------------------------------------------------------------------- + * Undocumented commands found in ROM table at address 0x80308 + * .* No WHAT message displayed, no action seen. + */ +ROM_END + +/* + * CPU-6 ROMs were generally based om VMEPROM which contained the PDOS RTOS from Eyring Research. + * I don't have these but if anyone can dump them and send to me I can verify that they work as expected. + */ +#if 0 +ROM_START (fccpu6) + ROM_REGION (0x1000000, "maincpu", 0) +ROM_END + +ROM_START (fccpu6a) + ROM_REGION (0x1000000, "maincpu", 0) +ROM_END + +ROM_START (fccpu6v) + ROM_REGION (0x1000000, "maincpu", 0) +ROM_END + +ROM_START (fccpu6va) + ROM_REGION (0x1000000, "maincpu", 0) +ROM_END + +ROM_START (fccpu6vb) + ROM_REGION (0x1000000, "maincpu", 0) +ROM_END +#endif + +const tiny_rom_entry *vme_sys68k_cpu1_card_device::device_rom_region() const +{ + return ROM_NAME(sys68k_cpu1); +} + +ioport_constructor vme_sys68k_cpu1_card_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(sys68k_cpu1); +} + +/* Driver */ +/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ +//COMP( 1983, fccpu1, 0, 0, fccpu1, force68k, vme_sys68k_cpu1_card_device, empty_init, "Force Computers GmbH", "SYS68K/CPU-1", MACHINE_NO_SOUND_HW ) +//COMP( 1989, fccpu6, 0, 0, fccpu6, force68k, vme_sys68k_cpu1_card_device, empty_init, "Force Computers GmbH", "SYS68K/CPU-6", MACHINE_NO_SOUND | MACHINE_NOT_WORKING ) +//COMP( 1989, fccpu6a, 0, 0, fccpu6a, force68k, vme_sys68k_cpu1_card_device, empty_init, "Force Computers GmbH", "SYS68K/CPU-6a", MACHINE_NO_SOUND | MACHINE_NOT_WORKING ) +//COMP( 1989, fccpu6v, 0, 0, fccpu6v, force68k, vme_sys68k_cpu1_card_device, empty_init, "Force Computers GmbH", "SYS68K/CPU-6v", MACHINE_NO_SOUND | MACHINE_NOT_WORKING ) +//COMP( 1989, fccpu6va, 0, 0, fccpu6va, force68k, vme_sys68k_cpu1_card_device, empty_init, "Force Computers GmbH", "SYS68K/CPU-6va", MACHINE_NO_SOUND | MACHINE_NOT_WORKING ) +//COMP( 1989, fccpu6vb, 0, 0, fccpu6vb, force68k, vme_sys68k_cpu1_card_device, empty_init, "Force Computers GmbH", "SYS68K/CPU-6vb", MACHINE_NO_SOUND | MACHINE_NOT_WORKING ) |