summaryrefslogtreecommitdiffstats
path: root/src/mame/drivers/interpro.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/interpro.cpp')
-rw-r--r--src/mame/drivers/interpro.cpp348
1 files changed, 348 insertions, 0 deletions
diff --git a/src/mame/drivers/interpro.cpp b/src/mame/drivers/interpro.cpp
new file mode 100644
index 00000000000..9cc9264f608
--- /dev/null
+++ b/src/mame/drivers/interpro.cpp
@@ -0,0 +1,348 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+#include "includes/interpro.h"
+#include "debugger.h"
+
+#define VERBOSE 0
+#if VERBOSE
+#define LOG_SYSTEM(...) logerror(__VA_ARGS__)
+#define LOG_IDPROM(...) logerror(__VA_ARGS__)
+#else
+#define LOG_SYSTEM(...) {}
+#define LOG_IDPROM(...) {}
+#endif
+
+// machine start
+void interpro_state::machine_start()
+{
+ m_system_reg[SREG_CTRL2] = CTRL2_COLDSTART | CTRL2_PWRENA | CTRL2_PWRUP;
+}
+
+void interpro_state::machine_reset()
+{
+ // flash rom requires the following values
+ m_system_reg[SREG_ERROR] = 0x00;
+ m_system_reg[SREG_STATUS] = 0x400;
+ m_system_reg[SREG_CTRL1] = CTRL1_FLOPRDY;
+}
+
+WRITE16_MEMBER(interpro_state::system_w)
+{
+ switch (offset)
+ {
+ case SREG_LED:
+ LOG_SYSTEM("LED value %d at pc 0x%08x\n", data, space.device().safe_pc());
+ break;
+
+ case SREG_STATUS: // not sure if writable?
+ break;
+
+ case SREG_CTRL1:
+ LOG_SYSTEM("system control register 1 write data 0x%x pc 0x%08x\n", data, space.device().safe_pc());
+
+ if ((data ^ m_system_reg[offset]) & CTRL1_LEDDP)
+ LOG_SYSTEM("LED decimal point %s\n", data & CTRL1_LEDDP ? "on" : "off");
+
+ m_system_reg[offset] = data;
+ break;
+
+ case SREG_CTRL2:
+ LOG_SYSTEM("system control register 2 write data 0x%x pc 0x%08x\n", data, space.device().safe_pc());
+ if (data & CTRL2_RESET)
+ {
+ m_system_reg[SREG_CTRL2] &= ~CTRL2_COLDSTART;
+
+ machine().schedule_soft_reset();
+ }
+ else
+ m_system_reg[offset] = data & 0x0f; // top four bits are not persistent
+ break;
+ }
+}
+
+READ16_MEMBER(interpro_state::system_r)
+{
+ LOG_SYSTEM("system register read offset %d pc 0x%08x\n", offset, space.device().safe_pc());
+ switch (offset)
+ {
+ case SREG_ERROR:
+ case SREG_STATUS:
+ case SREG_CTRL1:
+ case SREG_CTRL2:
+ default:
+ return m_system_reg[offset];
+ break;
+ }
+}
+
+READ32_MEMBER(interpro_state::idprom_r)
+{
+ LOG_IDPROM("idprom read offset 0x%x mask 0x%08x at 0x%08x\n", offset, mem_mask, space.device().safe_pc());
+
+ // abitrary fake number for now, not working properly
+ u32 speed = 70000000;
+ u32 speed1 = speed >> 24;
+ u32 speed2 = speed >> 16;
+ u32 speed3 = speed >> 8;
+
+ static uint8_t idprom[] = {
+ // module type id
+ 'M', 'P', 'C', 'B',
+ '*', '*', '*', '*',
+
+ // ECO bytes
+ 0x87, 0x65, 0x43, 0x21,
+ 0xbb, 0xcc, 0xdd, 0xee,
+
+ // the following 8 bytes are "feature bytes"
+ // the feature bytes contain a 32 bit word which is divided by 40000
+ // if they're empty, a default value of 50 000 000 is used
+ // perhaps this is a system speed (50MHz)?
+ 0x2, 0x34, 0x56, 0x78,
+ (u8)speed1, (u8)speed2, (u8)speed3, (u8)speed,
+
+ // reserved bytes
+ 0xff, 0xff,
+
+ // family
+ // boot rom tests for family == 0x41 or 0x42
+ // if so, speed read from feature bytes 2 & 3
+ // if not, read speed from feature bytes 4-7
+ //0x41, 0x00, // 2800-series CPU
+ 0x24, 0x00, // 2000-series system board
+
+ // footprint and checksum
+ 0x55, 0xaa, 0x55, 0x00
+ };
+
+ switch (offset)
+ {
+ case 0x1f:
+ {
+ uint8_t sum = 0;
+
+ // compute the checksum (sum of all bytes must be == 0x00)
+ for (int i = 0; i < 0x20; i++)
+ sum += idprom[i];
+
+ return 0x100 - (sum & 0xff);
+ }
+
+ default:
+ return idprom[offset];
+ }
+}
+
+READ32_MEMBER(interpro_state::slot0_r)
+{
+ // a known graphics board idprom
+ static uint8_t slot0[] = {
+ 0x00, 0x00, 0x00, 0x00, '9', '6', '3', 'A', // board
+ 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // eco
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // features
+ 0xff, 0xff, // reserved
+ 0x22, 0x00, // family
+ 0x55, 0xaa, 0x55, 0x00
+ };
+
+ return ((uint8_t *)&slot0)[offset % 32];
+}
+
+WRITE8_MEMBER(interpro_state::rtc_w)
+{
+ switch (offset)
+ {
+ case 0x00:
+ // write to RTC register
+ m_rtc->write(space, 1, data);
+ break;
+
+ case 0x40:
+ // set RTC read/write address
+ m_rtc->write(space, 0, data);
+ break;
+
+ default:
+ logerror("rtc: write to unknown offset 0x%02x data 0x%02x at pc 0x%08x\n", offset, data, space.device().safe_pc());
+ break;
+ }
+}
+
+READ8_MEMBER(interpro_state::rtc_r)
+{
+ switch (offset)
+ {
+ case 0x00:
+ // read from RTC register
+ return m_rtc->read(space, 1);
+
+ // read from InterPro system ID PROM (contains MAC address)
+ case 0x40: return 0x12;
+ case 0x41: return 0x34;
+ case 0x42: return 0x56;
+
+ default:
+ logerror("rtc: read from unknown offset 0x%02x at pc 0x%08x\n", offset, space.device().safe_pc());
+ return 0xff;
+ }
+}
+
+READ8_MEMBER(interpro_state::scsi_r)
+{
+ return m_scsi->read(space, offset >> 6, mem_mask);
+}
+
+WRITE8_MEMBER(interpro_state::scsi_w)
+{
+ m_scsi->write(space, offset >> 6, data, mem_mask);
+}
+
+// driver init
+DRIVER_INIT_MEMBER(interpro_state, ip2800)
+{
+ //address_space &as = m_mmu->space(AS_1);
+}
+
+// these maps point the cpu virtual addresses to the mmu
+static ADDRESS_MAP_START(clipper_insn_map, AS_PROGRAM, 32, interpro_state)
+ AM_RANGE(0x00000000, 0xffffffff) AM_DEVREAD32(INTERPRO_MMU_TAG, cammu_device, mmu_r, 0xffffffff)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(clipper_data_map, AS_DATA, 32, interpro_state)
+AM_RANGE(0x00000000, 0xffffffff) AM_DEVREADWRITE32(INTERPRO_MMU_TAG, cammu_device, mmu_r, mmu_w, 0xffffffff)
+ADDRESS_MAP_END
+
+// these maps represent the real main, i/o and boot spaces of the system
+static ADDRESS_MAP_START(interpro_main_map, AS_0, 32, interpro_state)
+ AM_RANGE(0x00000000, 0x00ffffff) AM_RAM // 16M RAM
+
+ AM_RANGE(0x7f100000, 0x7f11ffff) AM_ROM AM_REGION(INTERPRO_ROM_TAG, 0)
+ AM_RANGE(0x7f180000, 0x7f1bffff) AM_ROM AM_REGION(INTERPRO_EEPROM_TAG, 0)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(interpro_io_map, AS_1, 32, interpro_state)
+ AM_RANGE(0x00000000, 0x00000fff) AM_DEVICE(INTERPRO_MMU_TAG, cammu_device, map)
+ AM_RANGE(0x00001000, 0x00001fff) AM_RAM
+
+ AM_RANGE(0x40000000, 0x4000003f) AM_DEVICE16(INTERPRO_MCGA_TAG, interpro_mcga_device, map, 0xffff)
+ AM_RANGE(0x4f007e00, 0x4f007eff) AM_DEVICE(INTERPRO_SGA_TAG, interpro_sga_device, map)
+
+ AM_RANGE(0x7f000100, 0x7f00011f) AM_DEVICE8(INTERPRO_FDC_TAG, n82077aa_device, map, 0xff)
+ // this is probably the srx arbiter ga
+ AM_RANGE(0x7f000200, 0x7f0002ff) AM_RAM
+ AM_RANGE(0x7f000300, 0x7f00030f) AM_READWRITE16(system_r, system_w, 0xffff)
+ AM_RANGE(0x7f000400, 0x7f00040f) AM_DEVREADWRITE8(INTERPRO_SCC1_TAG, scc85C30_device, ba_cd_inv_r, ba_cd_inv_w, 0xff)
+ AM_RANGE(0x7f000410, 0x7f00041f) AM_DEVREADWRITE8(INTERPRO_SCC2_TAG, scc85230_device, ba_cd_inv_r, ba_cd_inv_w, 0xff)
+ AM_RANGE(0x7f000500, 0x7f0006ff) AM_READWRITE8(rtc_r, rtc_w, 0xff)
+ AM_RANGE(0x7f000700, 0x7f00077f) AM_READ(idprom_r)
+ AM_RANGE(0x7f001000, 0x7f001fff) AM_READWRITE8(scsi_r, scsi_w, 0x0000ff00)
+
+ AM_RANGE(0x7f0fff00, 0x7f0fffff) AM_DEVICE(INTERPRO_IOGA_TAG, interpro_ioga_device, map)
+
+ AM_RANGE(0x08000000, 0x08000fff) AM_NOP // bogus
+ AM_RANGE(0x8f000000, 0x8f0fffff) AM_READ(slot0_r)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(interpro_boot_map, AS_2, 32, interpro_state)
+ AM_RANGE(0x00000000, 0x00001fff) AM_RAM
+ADDRESS_MAP_END
+
+FLOPPY_FORMATS_MEMBER(interpro_state::floppy_formats)
+ FLOPPY_PC_FORMAT
+FLOPPY_FORMATS_END
+
+static SLOT_INTERFACE_START(interpro_floppies)
+ SLOT_INTERFACE("525dd", FLOPPY_525_DD)
+ SLOT_INTERFACE("35hd", FLOPPY_35_HD)
+SLOT_INTERFACE_END
+
+// input ports
+static INPUT_PORTS_START(ip2800)
+INPUT_PORTS_END
+
+static MACHINE_CONFIG_START(ip2800, interpro_state)
+ MCFG_CPU_ADD(INTERPRO_CPU_TAG, CLIPPER_C400, XTAL_10MHz)
+ MCFG_CPU_PROGRAM_MAP(clipper_insn_map)
+ MCFG_CPU_DATA_MAP(clipper_data_map)
+ MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE(INTERPRO_IOGA_TAG, interpro_ioga_device, inta_cb)
+
+ MCFG_DEVICE_ADD(INTERPRO_MMU_TAG, CAMMU_C4T, 0)
+ MCFG_DEVICE_ADDRESS_MAP(AS_0, interpro_main_map)
+ MCFG_DEVICE_ADDRESS_MAP(AS_1, interpro_io_map)
+ MCFG_DEVICE_ADDRESS_MAP(AS_2, interpro_boot_map)
+ MCFG_CAMMU_SSW_CB(DEVREADLINE(INTERPRO_CPU_TAG, clipper_device, ssw))
+
+ // serial controllers and rs232 bus
+ MCFG_SCC85C30_ADD(INTERPRO_SCC1_TAG, XTAL_4_9152MHz, 0, 0, 0, 0)
+
+ MCFG_Z80SCC_OUT_TXDA_CB(DEVWRITELINE("rs232a", rs232_port_device, write_txd))
+ MCFG_Z80SCC_OUT_TXDB_CB(DEVWRITELINE("rs232b", rs232_port_device, write_txd))
+ MCFG_Z80SCC_OUT_INT_CB(DEVWRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir11_w))
+
+ MCFG_RS232_PORT_ADD("rs232a", default_rs232_devices, nullptr)
+ MCFG_RS232_RXD_HANDLER(DEVWRITELINE(INTERPRO_SCC1_TAG, z80scc_device, rxa_w))
+ MCFG_RS232_DCD_HANDLER(DEVWRITELINE(INTERPRO_SCC1_TAG, z80scc_device, dcda_w))
+ MCFG_RS232_CTS_HANDLER(DEVWRITELINE(INTERPRO_SCC1_TAG, z80scc_device, ctsa_w))
+
+ // the following port is known as "port 2"
+ MCFG_RS232_PORT_ADD("rs232b", default_rs232_devices, "terminal")
+ MCFG_RS232_RXD_HANDLER(DEVWRITELINE(INTERPRO_SCC1_TAG, z80scc_device, rxb_w))
+ MCFG_RS232_DCD_HANDLER(DEVWRITELINE(INTERPRO_SCC1_TAG, z80scc_device, dcdb_w))
+ MCFG_RS232_CTS_HANDLER(DEVWRITELINE(INTERPRO_SCC1_TAG, z80scc_device, ctsb_w))
+
+ MCFG_SCC85230_ADD(INTERPRO_SCC2_TAG, XTAL_4_9152MHz, 0, 0, 0, 0)
+
+ // real-time clock/non-volatile memory
+ MCFG_MC146818_ADD(INTERPRO_RTC_TAG, XTAL_32_768kHz)
+ MCFG_MC146818_UTC(true)
+ MCFG_MC146818_IRQ_HANDLER(DEVWRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir9_w))
+
+ // floppy
+ MCFG_N82077AA_ADD(INTERPRO_FDC_TAG, n82077aa_device::MODE_PS2)
+ MCFG_UPD765_INTRQ_CALLBACK(DEVWRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir1_w))
+ MCFG_UPD765_DRQ_CALLBACK(DEVWRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, drq_floppy))
+ MCFG_FLOPPY_DRIVE_ADD("fdc:0", interpro_floppies, "525dd", interpro_state::floppy_formats)
+ MCFG_FLOPPY_DRIVE_ADD("fdc:1", interpro_floppies, "35hd", interpro_state::floppy_formats)
+ MCFG_FLOPPY_DRIVE_SOUND(false)
+
+ // scsi
+ MCFG_DEVICE_ADD(INTERPRO_SCSI_TAG, SCSI_PORT, 0)
+ MCFG_SCSIDEV_ADD(INTERPRO_SCSI_TAG ":" SCSI_PORT_DEVICE1, "harddisk", SCSIHD, SCSI_ID_0)
+ MCFG_SCSIDEV_ADD(INTERPRO_SCSI_TAG ":" SCSI_PORT_DEVICE2, "cdrom", SCSICD, SCSI_ID_3)
+
+ MCFG_DEVICE_ADD(INTERPRO_SCSI_ADAPTER_TAG, NCR539X, XTAL_12_5MHz)
+ MCFG_LEGACY_SCSI_PORT(INTERPRO_SCSI_TAG)
+ MCFG_NCR539X_OUT_IRQ_CB(DEVWRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir0_w))
+ MCFG_NCR539X_OUT_DRQ_CB(DEVWRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, drq_scsi))
+
+ // i/o gate array
+ MCFG_INTERPRO_IOGA_ADD(INTERPRO_IOGA_TAG)
+ MCFG_INTERPRO_IOGA_NMI_CB(INPUTLINE(INTERPRO_CPU_TAG, INPUT_LINE_NMI))
+ MCFG_INTERPRO_IOGA_IRQ_CB(INPUTLINE(INTERPRO_CPU_TAG, INPUT_LINE_IRQ0))
+ //MCFG_INTERPRO_IOGA_DMA_CB(IOGA_DMA_CHANNEL_PLOTTER, unknown)
+ //MCFG_INTERPRO_IOGA_DMA_CB(IOGA_DMA_SCSI, DEVREAD8(INTERPRO_SCSI_TAG, ncr539x_device, dma_read_data), DEVWRITE8(INTERPRO_SCSI_TAG, ncr539x_device, dma_write_data))
+ MCFG_INTERPRO_IOGA_DMA_CB(IOGA_DMA_FLOPPY, DEVREAD8(INTERPRO_FDC_TAG, n82077aa_device, mdma_r), DEVWRITE8(INTERPRO_FDC_TAG, n82077aa_device, mdma_w))
+ MCFG_INTERPRO_IOGA_DMA_CB(IOGA_DMA_SERIAL, DEVREAD8(INTERPRO_SCC1_TAG, z80scc_device, da_r), DEVWRITE8(INTERPRO_SCC1_TAG, z80scc_device, da_w))
+ MCFG_INTERPRO_IOGA_FDCTC_CB(DEVWRITELINE(INTERPRO_FDC_TAG, n82077aa_device, tc_line_w))
+ MCFG_INTERPRO_IOGA_DMA_BUS(INTERPRO_CAMMU_TAG, AS_0)
+
+ // memory control gate array
+ MCFG_DEVICE_ADD(INTERPRO_MCGA_TAG, INTERPRO_MCGA, 0)
+
+ // srx gate array
+ MCFG_DEVICE_ADD(INTERPRO_SGA_TAG, INTERPRO_SGA, 0)
+
+MACHINE_CONFIG_END
+
+ROM_START(ip2800)
+ ROM_REGION(0x0020000, INTERPRO_ROM_TAG, 0)
+ ROM_SYSTEM_BIOS(0, "IP2830", "IP2830")
+ ROMX_LOAD("ip2830_rom.bin", 0x00000, 0x20000, CRC(467ce7bd) SHA1(53faee40d5df311f53b24c930e434cbf94a5c4aa), ROM_BIOS(1))
+
+ ROM_REGION(0x0040000, INTERPRO_EEPROM_TAG, 0)
+ ROM_LOAD_OPTIONAL("ip2830_eeprom.bin", 0x00000, 0x40000, CRC(a0c0899f) SHA1(dda6fbca81f9885a1a76ca3c25e80463a83a0ef7))
+ROM_END
+
+/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
+COMP( 1990, ip2800, 0, 0, ip2800, ip2800, interpro_state, ip2800, "Intergraph", "InterPro 2800", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)