summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Patrick Mackinlay <pmackinlay@hotmail.com>2017-01-24 21:53:51 +0700
committer Patrick Mackinlay <pmackinlay@hotmail.com>2017-01-24 21:53:51 +0700
commit875f3c9d12a7c0ce43e7c7a3c402d581d4b5309e (patch)
tree3037a5e6ad3554b4c9abf94384d1f490aab3e7d7 /src
parent24dba19f8cbd9cc5187ce32a9ff5a7cd8b042111 (diff)
initial pull request
Diffstat (limited to 'src')
-rw-r--r--src/mame/drivers/interpro.cpp328
-rw-r--r--src/mame/includes/interpro.h109
-rw-r--r--src/mame/machine/interpro_ioga.cpp43
-rw-r--r--src/mame/machine/interpro_ioga.h29
-rw-r--r--src/mame/machine/interpro_mcga.cpp89
-rw-r--r--src/mame/machine/interpro_mcga.h45
-rw-r--r--src/mame/machine/interpro_sga.cpp88
-rw-r--r--src/mame/machine/interpro_sga.h71
-rw-r--r--src/mame/mame.lst3
-rw-r--r--src/tools/unidasm.cpp2
10 files changed, 447 insertions, 360 deletions
diff --git a/src/mame/drivers/interpro.cpp b/src/mame/drivers/interpro.cpp
index c7b8a5b5468..03889931734 100644
--- a/src/mame/drivers/interpro.cpp
+++ b/src/mame/drivers/interpro.cpp
@@ -6,251 +6,84 @@
#define VERBOSE 0
#if VERBOSE
-#define LOG_EMERALD(...) logerror(__VA_ARGS__)
-#define LOG_MCGA(...) logerror(__VA_ARGS__)
+#define LOG_SYSTEM(...) logerror(__VA_ARGS__)
#define LOG_IDPROM(...) logerror(__VA_ARGS__)
#else
-#define LOG_EMERALD(...) {}
-#define LOG_MCGA(...) {}
+#define LOG_SYSTEM(...) {}
#define LOG_IDPROM(...) {}
#endif
-/*
-* MCGA Control Register definitions.
-*/
-#define MCGA_CTRL_OPTMASK 0x00000003
-#define MCGA_CTRL_CBITFRCRD 0x00000004
-#define MCGA_CTRL_CBITFRCSUB 0x00000008
-#define MCGA_CTRL_ENREFRESH 0x00000010
-#define MCGA_CTRL_ENMSBE 0x00000100
-#define MCGA_CTRL_ENMMBE 0x00000200 // multi-master bus enable?
-#define MCGA_CTRL_ENECC 0x00000400
-#define MCGA_CTRL_WRPROT 0x00008000
-/*
-* MCGA Error Register definitions.
-*/
-#define MCGA_ERROR_SYNDMASK 0x000000ff
-#define MCGA_ERROR_SYNDSHIFT 0
-#define MCGA_ERROR_SYND(X) (((X) & MCGA_ERROR_SYNDMASK) >> \
- MCGA_ERROR_SYNDSHIFT)
-#define MCGA_ERROR_MMBE 0x00000100
-#define MCGA_ERROR_MSBE 0x00000200
-#define MCGA_ERROR_ADDRMASK 0x00001C00
-#define MCGA_ERROR_ADDRSHIFT 7
-#define MCGA_ERROR_ADDR(X) (((X) & MCGA_ERROR_ADDRMASK) >> \
- MCGA_ERROR_ADDRSHIFT)
-#define MCGA_ERROR_VALID 0x00008000
-
-/*
-* MCGA Control Register definitions.
-*/
-#define MCGA_MEMSIZE_ADDRMASK 0x0000007F
-#define MCGA_MEMSIZE_ADDRSHIFT 24
-#define MCGA_MEMSIZE_ADDR(X) (((X) & MCGA_MEMSIZE_ADDRMASK) << \
- MCGA_MEMSIZE_ADDRSHIFT)
-
-#define E_SREG_LED 0
-#define E_SREG_ERROR 0
-#define E_SREG_STATUS 1
-#define E_SREG_CTRL1 2
-#define E_SREG_CTRL2 3
-
-/*
-* Error Register Bit Definitions
-* WARNING: Some definitions apply only to certain hardware
-* (ie: E_SERR_SRX* is only valid on 6600 class machines)
-*/
-#define E_SERR_BPID4 0x0001
-#define E_SERR_SRXMMBE 0x0002
-#define E_SERR_SRXHOG 0x0004
-#define E_SERR_SRXNEM 0x0008
-#define E_SERR_SRXVALID 0x0010
-#define E_SERR_CBUSNMI 0x0020
-#define E_SERR_CBGMASK 0x00c0
-#define E_SERR_CBGSHIFT 6
-#define E_SERR_BG_MASK 0x0070
-#define E_SERR_BG_SHIFT 4
-#define E_SERR_BUSHOG 0x0080
-#define E_SERR_BG(X) (((X) & E_SERR_BG_MASK) >> E_SERR_BG_SHIFT)
-#define CBUS_ID(X) (((X) & E_SERR_CBGMASK) >> E_SERR_CBGSHIFT)
-
-/*
-* Status Register Bit Definitions
-*/
-#define E_STAT_YELLOW_ZONE 0x0001
-#define E_STAT_SRNMI 0x0002
-#define E_STAT_PWRLOSS 0x0004
-#define E_STAT_RED_ZONE 0x0008
-#define E_STAT_BP_MASK 0x00f0
-#define E_STAT_BP_SHIFT 4
-#define E_STAT_BP(X) (((X) & E_STAT_BP_MASK) >> E_STAT_BP_SHIFT)
-
-/*
-* Control/Status Register 1 Bit Definitions
-*/
-#define E_CTRL1_FLOPLOW 0x0001
-#define E_CTRL1_FLOPRDY 0x0002
-#define E_CTRL1_LEDENA 0x0004
-#define E_CTRL1_LEDDP 0x0008
-#define E_CTRL1_ETHLOOP 0x0010
-#define E_CTRL1_ETHDTR 0x0020
-#define E_CTRL1_ETHRMOD 0x0040
-#define E_CTRL1_CLIPRESET 0x0040
-#define E_CTRL1_FIFOACTIVE 0x0080
-
-/*
-* Control/Status Register 2 Bit Definitions
-*/
-#define E_CTRL2_PWRUP 0x0001
-#define E_CTRL2_PWRENA 0x0002
-#define E_CTRL2_HOLDOFF 0x0004
-#define E_CTRL2_EXTNMIENA 0x0008
-#define E_CTRL2_COLDSTART 0x0010
-#define E_CTRL2_RESET 0x0020
-#define E_CTRL2_BUSENA 0x0040
-#define E_CTRL2_FRCPARITY 0x0080
-#define E_CTRL2_FLASHEN 0x0080
-#define E_CTRL2_WMASK 0x000f
-#define E_SET_CTRL2(X) E_SREG_CTRL2 = (E_SREG_CTRL2 & \
- E_CTRL2_WMASK) | (X)
-#define E_CLR_CTRL2(X) E_SREG_CTRL2 &= E_CTRL2_WMASK & ~(X)
-
// machine start
void interpro_state::machine_start()
{
- m_emerald_reg[E_SREG_CTRL2] = E_CTRL2_COLDSTART | E_CTRL2_PWRENA | E_CTRL2_PWRUP;
+ m_system_reg[SREG_CTRL2] = CTRL2_COLDSTART | CTRL2_PWRENA | CTRL2_PWRUP;
}
void interpro_state::machine_reset()
{
// flash rom requires the following values
- m_emerald_reg[E_SREG_ERROR] = 0x00;
- m_emerald_reg[E_SREG_STATUS] = 0x400;
- m_emerald_reg[E_SREG_CTRL1] = E_CTRL1_FLOPRDY;
-
- m_mcga[0] = 0x00ff; // 0x00
- m_mcga[2] = MCGA_CTRL_ENREFRESH | MCGA_CTRL_CBITFRCSUB | MCGA_CTRL_CBITFRCRD; // 0x08 ctrl
- //m_mcga[4] = 0x8000; // 0x10 error
- m_mcga[10] = 0x00ff; // 0x28
- m_mcga[14] = 0x0340; // 0x38 memsize
+ m_system_reg[SREG_ERROR] = 0x00;
+ m_system_reg[SREG_STATUS] = 0x400;
+ m_system_reg[SREG_CTRL1] = CTRL1_FLOPRDY;
}
-WRITE16_MEMBER(interpro_state::emerald_w)
+WRITE16_MEMBER(interpro_state::system_w)
{
switch (offset)
{
- case E_SREG_LED:
- LOG_EMERALD("LED value %d at pc 0x%08x\n", data, space.device().safe_pc());
+ case SREG_LED:
+ LOG_SYSTEM("LED value %d at pc 0x%08x\n", data, space.device().safe_pc());
break;
- case E_SREG_STATUS: // not sure if writable?
+ case SREG_STATUS: // not sure if writable?
break;
- case E_SREG_CTRL1:
- LOG_EMERALD("emerald write offset %d data 0x%x pc 0x%08x\n", offset, data, space.device().safe_pc());
+ 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_emerald_reg[offset]) & E_CTRL1_LEDDP)
- LOG_EMERALD("LED decimal point %s\n", data & E_CTRL1_LEDDP ? "on" : "off");
+ if ((data ^ m_system_reg[offset]) & CTRL1_LEDDP)
+ LOG_SYSTEM("LED decimal point %s\n", data & CTRL1_LEDDP ? "on" : "off");
- m_emerald_reg[offset] = data;
+ m_system_reg[offset] = data;
break;
- case E_SREG_CTRL2:
- LOG_EMERALD("emerald write offset %d data 0x%x pc 0x%08x\n", offset, data, space.device().safe_pc());
- if (data & E_CTRL2_RESET)
+ 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_emerald_reg[E_SREG_CTRL2] &= ~E_CTRL2_COLDSTART;
+ m_system_reg[SREG_CTRL2] &= ~CTRL2_COLDSTART;
machine().schedule_soft_reset();
}
else
- m_emerald_reg[offset] = data & 0x0f; // top four bits are not persistent
+ m_system_reg[offset] = data & 0x0f; // top four bits are not persistent
break;
}
}
-READ16_MEMBER(interpro_state::emerald_r)
+READ16_MEMBER(interpro_state::system_r)
{
- LOG_EMERALD("emerald read offset %d pc 0x%08x\n", offset, space.device().safe_pc());
+ LOG_SYSTEM("system register read offset %d pc 0x%08x\n", offset, space.device().safe_pc());
switch (offset)
{
- case E_SREG_ERROR:
- case E_SREG_STATUS:
- case E_SREG_CTRL1:
- case E_SREG_CTRL2:
+ case SREG_ERROR:
+ case SREG_STATUS:
+ case SREG_CTRL1:
+ case SREG_CTRL2:
default:
- return m_emerald_reg[offset];
+ return m_system_reg[offset];
break;
}
}
-WRITE16_MEMBER(interpro_state::mcga_w)
-{
- /*
- read MEMSIZE 0x38 mask 0xffff
- read 0x00 mask 0x0000
- write CBSUB 0x20 mask 0x00ff data 0
- write FRCRD 0x18 mask 0x00ff data 0
- read ERROR 0x10 mask 0xffff
- read 0x00 mask 0xffff
-
- (0x38 >> 8) & 0xF == 3?
-
- if (0x00 != 0xFF) -> register reset error
-
- 0x00 = 0x0055 (test value & 0xff)
- r7 = 0x00 & 0xff
- */
- LOG_MCGA("mcga write offset = 0x%08x, mask = 0x%08x, data = 0x%08x, pc = 0x%08x\n", offset, mem_mask, data, space.device().safe_pc());
- switch (offset)
- {
- case 0x02: // MCGA_CTRL
- // HACK: set or clear error status depending on ENMMBE bit
- if (data & MCGA_CTRL_ENMMBE)
- m_mcga[4] |= MCGA_ERROR_VALID;
-// else
-// m_mcga[4] &= ~MCGA_ERROR_VALID;
-
- default:
- m_mcga[offset] = data;
- break;
- }
-}
-
-READ16_MEMBER(interpro_state::mcga_r)
-{
- LOG_MCGA("mcga read offset = 0x%08x, mask = 0x%08x, pc = 0x%08x\n", offset, mem_mask, space.device().safe_pc());
-
- switch (offset)
- {
- default:
- return m_mcga[offset];
- }
-}
-
-/*
-* ID Prom Structure
-*/
-struct IDprom {
- char i_board[8]; /* string of board type */
- char i_eco[8]; /* ECO flags */
- char i_feature[8]; /* feature flags */
- char i_reserved[2]; /* reserved (all 1's) */
- short i_family; /* family code */
- char i_footprint[4]; /* footprint/checksum */
-};
-
-
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
uint32_t speed = 70000000;
- // idprom is copied to 0x2258 by boot rom
-
static uint8_t idprom[] = {
-#if 1
// module type id
'M', 'P', 'C', 'B',
'*', '*', '*', '*',
@@ -275,14 +108,7 @@ READ32_MEMBER(interpro_state::idprom_r)
// if not, read speed from feature bytes 4-7
//0x41, 0x00, // 2800-series CPU
0x24, 0x00, // 2000-series system board
-#else
- // Carl Friend's 2020
- 0x00, 0x00, 0x00, 0x00, '9', '6', '2', 'A', // board
- 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // eco
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // feature
- 0xff, 0xff, // reserved
- 0x24, 0x00, // family: 2000-series system board
-#endif
+
// footprint and checksum
0x55, 0xaa, 0x55, 0x00
};
@@ -307,9 +133,7 @@ READ32_MEMBER(interpro_state::idprom_r)
READ32_MEMBER(interpro_state::slot0_r)
{
- //static struct IDprom slot0 = { "bordtyp", "ecoflgs", "featurs", { '\xff', '\xff' }, 0x7ead, "chk" };
-
- // Carl Friend's Turqoise graphics board
+ // 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
@@ -363,64 +187,27 @@ READ8_MEMBER(interpro_state::rtc_r)
READ8_MEMBER(interpro_state::scsi_r)
{
- return m_scsi->read(space, offset, mem_mask);
+ return m_scsi->read(space, offset >> 6, mem_mask);
}
WRITE8_MEMBER(interpro_state::scsi_w)
{
- m_scsi->write(space, offset, data, mem_mask);
-}
-
-
-WRITE32_MEMBER(interpro_state::sga_ddtc1_w)
-{
- // we assume that when this register is written, we should start a
- // memory to memory dma transfer
-
- logerror("sga: gcs = 0x%08x dmacs = 0x%08x\n", m_sga_gcs, m_sga_dmacs);
- logerror(" ipoll = 0x%08x imask = 0x%08x\n", m_sga_ipoll, m_sga_imask);
- logerror(" dspad1 = 0x%08x dsoff1 = 0x%08x\n", m_sga_dspad1, m_sga_dsoff1);
- logerror(" unk1 = 0x%08x unk2 = 0x%08x\n", m_sga_unknown1, m_sga_unknown2);
- logerror("sga: ddtc1 = 0x%08x\n", data);
-
- m_sga_ddtc1 = data;
-
- // when complete, we indicate by setting DMAEND(2) - 2 is probably the channel
- // we also turn off the INTBERR and INTMMBE flags
- m_sga_ipoll &= ~(0x20000 | 0x10000);
- m_sga_ipoll |= 0x200;
-
- // if the address is invalid, fake a bus error
- if (m_sga_dspad1 == 0x40000000 || m_sga_unknown1 == 0x40000000
- || m_sga_dspad1 == 0x40000200 || m_sga_unknown1 == 0x40000200)
- {
- m_sga_ipoll |= 0x10000;
-
- // error cycle - bit 0x10 indicates source address error (dspad1)
- // now expecting 0x5463?
- if ((m_sga_dspad1 & 0xfffff000) == 0x40000000)
- m_ioga->bus_error(m_sga_dspad1, 0x5433);
- else
- m_ioga->bus_error(m_sga_unknown1, 0x5423);
-
- // 0x5423 = BERR|SNAPOK | BG(ICAMMU)? | CT(23)
- // 0x5433 = BERR|SNAPOK | BG(ICAMMU)? | CT(33)
- // 0x5463 = BERR|SNAPOK | BG(ICAMMU)? | TAG(1) | CT(23)
- }
+ 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_CAMMU_TAG, cammu_device, mmu_r, 0xffffffff)
+ 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_CAMMU_TAG, cammu_device, mmu_r, mmu_w, 0xffffffff)
+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
@@ -432,33 +219,21 @@ static ADDRESS_MAP_START(interpro_main_map, AS_0, 32, interpro_state)
ADDRESS_MAP_END
static ADDRESS_MAP_START(interpro_io_map, AS_1, 32, interpro_state)
- AM_RANGE(0x00000000, 0x00000fff) AM_DEVICE32(INTERPRO_CAMMU_TAG, cammu_device, map, 0xffffffff)
+ AM_RANGE(0x00000000, 0x00000fff) AM_DEVICE(INTERPRO_MMU_TAG, cammu_device, map)
AM_RANGE(0x00001000, 0x00001fff) AM_RAM
- AM_RANGE(0x40000000, 0x4000003f) AM_READWRITE16(mcga_r, mcga_w, 0xffff)
-
- AM_RANGE(0x4f007e00, 0x4f007e03) AM_READWRITE(sga_gcs_r, sga_gcs_w)
- AM_RANGE(0x4f007e04, 0x4f007e07) AM_READWRITE(sga_ipoll_r, sga_ipoll_w)
- AM_RANGE(0x4f007e08, 0x4f007e0b) AM_READWRITE(sga_imask_r, sga_imask_w)
- AM_RANGE(0x4f007e0c, 0x4f007e0f) AM_READWRITE(sga_range_base_r, sga_range_base_w)
- AM_RANGE(0x4f007e10, 0x4f007e13) AM_READWRITE(sga_range_end_r, sga_range_end_w)
- AM_RANGE(0x4f007e14, 0x4f007e17) AM_READWRITE(sga_cttag_r, sga_cttag_w)
- AM_RANGE(0x4f007e18, 0x4f007e1b) AM_READWRITE(sga_address_r, sga_address_w)
- AM_RANGE(0x4f007e1c, 0x4f007e1f) AM_READWRITE(sga_dmacs_r, sga_dmacs_w)
- AM_RANGE(0x4f007e20, 0x4f007e23) AM_READWRITE(sga_edmacs_r, sga_edmacs_w)
- AM_RANGE(0x4f007ea4, 0x4f007ea7) AM_READWRITE(sga_dspad1_r, sga_dspad1_w)
- AM_RANGE(0x4f007ea8, 0x4f007eab) AM_READWRITE(sga_dsoff1_r, sga_dsoff1_w)
- AM_RANGE(0x4f007eb4, 0x4f007eb7) AM_READWRITE(sga_unknown1_r, sga_unknown1_w)
- AM_RANGE(0x4f007eb8, 0x4f007ebb) AM_READWRITE(sga_unknown2_r, sga_unknown2_w)
- AM_RANGE(0x4f007ebc, 0x4f007ebf) AM_READWRITE(sga_ddtc1_r, sga_ddtc1_w)
+ 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)
- AM_RANGE(0x7f000200, 0x7f0002ff) AM_READWRITE8(scsi_r, scsi_w, 0xff)
- AM_RANGE(0x7f000300, 0x7f00030f) AM_READWRITE16(emerald_r, emerald_w, 0xffff)
+ // 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)
@@ -484,15 +259,16 @@ static INPUT_PORTS_START(ip2800)
INPUT_PORTS_END
static MACHINE_CONFIG_START(ip2800, interpro_state)
- MCFG_CPU_ADD(INTERPRO_CPU_TAG, CLIPPER, XTAL_10MHz)
+ 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_CAMMU_TAG, CAMMU, 0)
+ 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)
@@ -528,10 +304,12 @@ static MACHINE_CONFIG_START(ip2800, interpro_state)
MCFG_FLOPPY_DRIVE_SOUND(false)
// scsi
- MCFG_DEVICE_ADD("scsiport", SCSI_PORT, 0)
+ 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_TAG, NCR539X, XTAL_12_5MHz)
- MCFG_LEGACY_SCSI_PORT("scsiport")
+ 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))
@@ -546,6 +324,12 @@ static MACHINE_CONFIG_START(ip2800, interpro_state)
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)
diff --git a/src/mame/includes/interpro.h b/src/mame/includes/interpro.h
index cf98a797d62..6ae135b552c 100644
--- a/src/mame/includes/interpro.h
+++ b/src/mame/includes/interpro.h
@@ -12,18 +12,23 @@
#include "machine/cammu.h"
#include "machine/interpro_ioga.h"
+#include "machine/interpro_mcga.h"
+#include "machine/interpro_sga.h"
#include "machine/z80scc.h"
#include "machine/mc146818.h"
#include "machine/upd765.h"
#include "machine/ncr539x.h"
+#include "bus/scsi/scsi.h"
+#include "bus/scsi/scsicd.h"
+#include "bus/scsi/scsihd.h"
#include "bus/rs232/rs232.h"
#include "formats/pc_dsk.h"
#define INTERPRO_CPU_TAG "cpu"
-#define INTERPRO_CAMMU_TAG "cammu"
+#define INTERPRO_MMU_TAG "mmu"
#define INTERPRO_RTC_TAG "rtc"
#define INTERPRO_SCC1_TAG "scc1"
@@ -34,8 +39,39 @@
#define INTERPRO_FDC_TAG "fdc"
#define INTERPRO_SCSI_TAG "scsi"
#define INTERPRO_IOGA_TAG "ioga"
-
-// TODO: RTC is actually a DS12887, but the only difference is the 128 byte NVRAM, same as the DS12885
+#define INTERPRO_MCGA_TAG "mcga"
+#define INTERPRO_SGA_TAG "sga"
+#define INTERPRO_SCSI_ADAPTER_TAG "adapter"
+
+// system board register offsets
+#define SREG_LED 0
+#define SREG_ERROR 0
+#define SREG_STATUS 1
+#define SREG_CTRL1 2
+#define SREG_CTRL2 3
+
+// control register 1
+#define CTRL1_FLOPLOW 0x0001
+#define CTRL1_FLOPRDY 0x0002
+#define CTRL1_LEDENA 0x0004
+#define CTRL1_LEDDP 0x0008
+#define CTRL1_ETHLOOP 0x0010
+#define CTRL1_ETHDTR 0x0020
+#define CTRL1_ETHRMOD 0x0040
+#define CTRL1_CLIPRESET 0x0040
+#define CTRL1_FIFOACTIVE 0x0080
+
+// control register 2
+#define CTRL2_PWRUP 0x0001
+#define CTRL2_PWRENA 0x0002
+#define CTRL2_HOLDOFF 0x0004
+#define CTRL2_EXTNMIENA 0x0008
+#define CTRL2_COLDSTART 0x0010
+#define CTRL2_RESET 0x0020
+#define CTRL2_BUSENA 0x0040
+#define CTRL2_FRCPARITY 0x0080
+#define CTRL2_FLASHEN 0x0080
+#define CTRL2_WMASK 0x000f
class interpro_state : public driver_device
{
@@ -43,35 +79,35 @@ public:
interpro_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, INTERPRO_CPU_TAG),
- m_cammu(*this, INTERPRO_CAMMU_TAG),
+ m_mmu(*this, INTERPRO_MMU_TAG),
m_scc1(*this, INTERPRO_SCC1_TAG),
m_scc2(*this, INTERPRO_SCC2_TAG),
m_rtc(*this, INTERPRO_RTC_TAG),
m_fdc(*this, INTERPRO_FDC_TAG),
- m_scsi(*this, INTERPRO_SCSI_TAG),
- m_ioga(*this, INTERPRO_IOGA_TAG)
+ m_scsi(*this, INTERPRO_SCSI_ADAPTER_TAG),
+ m_ioga(*this, INTERPRO_IOGA_TAG),
+ m_mcga(*this, INTERPRO_MCGA_TAG),
+ m_sga(*this, INTERPRO_SGA_TAG)
{ }
required_device<clipper_device> m_maincpu;
- required_device<cammu_device> m_cammu;
+ required_device<cammu_device> m_mmu;
// FIXME: not sure which one is the escc
required_device<z80scc_device> m_scc1;
required_device<z80scc_device> m_scc2;
-
required_device<mc146818_device> m_rtc;
required_device<n82077aa_device> m_fdc;
required_device<ncr539x_device> m_scsi;
required_device<interpro_ioga_device> m_ioga;
+ required_device<interpro_mcga_device> m_mcga;
+ required_device<interpro_sga_device> m_sga;
DECLARE_DRIVER_INIT(ip2800);
- DECLARE_WRITE16_MEMBER(emerald_w);
- DECLARE_READ16_MEMBER(emerald_r);
-
- DECLARE_WRITE16_MEMBER(mcga_w);
- DECLARE_READ16_MEMBER(mcga_r);
+ DECLARE_WRITE16_MEMBER(system_w);
+ DECLARE_READ16_MEMBER(system_r);
DECLARE_WRITE8_MEMBER(rtc_w);
DECLARE_READ8_MEMBER(rtc_r);
@@ -84,57 +120,12 @@ public:
DECLARE_FLOPPY_FORMATS(floppy_formats);
- DECLARE_READ32_MEMBER(sga_gcs_r) { return m_sga_gcs; }
- DECLARE_WRITE32_MEMBER(sga_gcs_w) { m_sga_gcs = data; }
- DECLARE_READ32_MEMBER(sga_ipoll_r) { return m_sga_ipoll; }
- DECLARE_WRITE32_MEMBER(sga_ipoll_w) { m_sga_ipoll = data; }
- DECLARE_READ32_MEMBER(sga_imask_r) { return m_sga_imask; }
- DECLARE_WRITE32_MEMBER(sga_imask_w) { m_sga_imask = data; }
- DECLARE_READ32_MEMBER(sga_range_base_r) { return m_sga_range_base; }
- DECLARE_WRITE32_MEMBER(sga_range_base_w) { m_sga_range_base = data; }
- DECLARE_READ32_MEMBER(sga_range_end_r) { return m_sga_range_end; }
- DECLARE_WRITE32_MEMBER(sga_range_end_w) { m_sga_range_end = data; }
- DECLARE_READ32_MEMBER(sga_cttag_r) { return m_sga_cttag; }
- DECLARE_WRITE32_MEMBER(sga_cttag_w) { m_sga_cttag = data; }
- DECLARE_READ32_MEMBER(sga_address_r) { return m_sga_address; }
- DECLARE_WRITE32_MEMBER(sga_address_w) { m_sga_address = data; }
- DECLARE_READ32_MEMBER(sga_dmacs_r) { return m_sga_dmacs; }
- DECLARE_WRITE32_MEMBER(sga_dmacs_w) { m_sga_dmacs = data; }
- DECLARE_READ32_MEMBER(sga_edmacs_r) { return m_sga_edmacs; }
- DECLARE_WRITE32_MEMBER(sga_edmacs_w) { m_sga_edmacs = data; }
- DECLARE_READ32_MEMBER(sga_dspad1_r) { return m_sga_dspad1; }
- DECLARE_WRITE32_MEMBER(sga_dspad1_w) { m_sga_dspad1 = data; }
- DECLARE_READ32_MEMBER(sga_dsoff1_r) { return m_sga_dsoff1; }
- DECLARE_WRITE32_MEMBER(sga_dsoff1_w) { m_sga_dsoff1 = data; }
- DECLARE_READ32_MEMBER(sga_unknown1_r) { return m_sga_unknown1; }
- DECLARE_WRITE32_MEMBER(sga_unknown1_w) { m_sga_unknown1 = data; }
- DECLARE_READ32_MEMBER(sga_unknown2_r) { return m_sga_unknown2; }
- DECLARE_WRITE32_MEMBER(sga_unknown2_w) { m_sga_unknown2 = data; }
- DECLARE_READ32_MEMBER(sga_ddtc1_r) { return m_sga_ddtc1; }
- DECLARE_WRITE32_MEMBER(sga_ddtc1_w);
-
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
private:
- uint16_t m_emerald_reg[4];
- uint16_t m_mcga[32];
-
- uint32_t m_sga_gcs; // general control/status
- uint32_t m_sga_ipoll; // interrupt poll
- uint32_t m_sga_imask; // interrupt mask
- uint32_t m_sga_range_base;
- uint32_t m_sga_range_end;
- uint32_t m_sga_cttag; // error cycletype/tag
- uint32_t m_sga_address;
- uint32_t m_sga_dmacs; // dma control/status
- uint32_t m_sga_edmacs; // extended dma control/status
- uint32_t m_sga_dspad1;
- uint32_t m_sga_dsoff1;
- uint32_t m_sga_unknown1;
- uint32_t m_sga_unknown2;
- uint32_t m_sga_ddtc1;
+ uint16_t m_system_reg[4];
};
#endif \ No newline at end of file
diff --git a/src/mame/machine/interpro_ioga.cpp b/src/mame/machine/interpro_ioga.cpp
index d0f932ec2d5..67a47f2cfd0 100644
--- a/src/mame/machine/interpro_ioga.cpp
+++ b/src/mame/machine/interpro_ioga.cpp
@@ -1,6 +1,20 @@
// license:BSD-3-Clause
// copyright-holders:Patrick Mackinlay
+/*
+ * An implementation of the IOGA device found on Intergraph InterPro family workstations. There is no
+ * public documentation on this device, so the implementation is being built to follow the logic of the
+ * system boot ROM and its diagnostic tests.
+ *
+ * The device handles most of the I/O for the system, including timers, interrupts, DMA and target device
+ * interfacing. There remains a significant amount of work to be completed before the boot diagnostics will
+ * pass without errors, let alone successfully booting CLIX.
+ *
+ * Please be aware that code in here is not only broken, it's likely wrong in many cases.
+ *
+ * TODO
+ * - too long to list
+ */
#include "interpro_ioga.h"
#define VERBOSE 0
@@ -64,8 +78,9 @@ void interpro_ioga_device::device_start()
m_out_int_func.resolve();
// TODO: parameterise the cammu name and space number
+ // grab the main memory space from the mmu so we can do DMA to/from it
device_memory_interface *mmu;
- siblingdevice("cammu")->interface(mmu);
+ siblingdevice("mmu")->interface(mmu);
m_memory_space = &mmu->space(AS_0);
for (int i = 0; i < IOGA_DMA_CHANNELS; i++)
@@ -595,32 +610,6 @@ void interpro_ioga_device::drq(int state, int channel)
m_dma_timer->adjust(attotime::zero, channel);
}
}
-// write values
-#define IOGA_DMA_CTRL_WMASK 0xfd000e00
-#define IOGA_DMA_CTRL_RESET_L 0x61000000 // do not clear bus error bit
-#define IOGA_DMA_CTRL_RESET 0x60400000 // clear bus error bit
-
-#define IOGA_DMA_CTRL_START 0x63000800 // perhaps start a transfer? - maybe the 8 is the channel?
-#define IOGA_DMA_CTRL_UNK1 0x60000000 // don't know yet
-#define IOGA_DMA_CTRL_UNK2 0x67000600 // forced berr with nmi and interrupts disabled
-
-// read values
-#define IOGA_DMA_CTRL_BUSY 0x02000000
-#define IOGA_DMA_CTRL_BERR 0x00400000 // iogadiag code expects 0x60400000 on bus error
-// iogadiag expects 0x64400800 after forced berr with nmi/interrupts disabled
-
-
-
-#define IOGA_ARBCTL_BGR_ETHC 0x0001
-#define IOGA_ARBCTL_BGR_SCSI 0x0002
-#define IOGA_ARBCTL_BGR_PLOT 0x0004
-#define IOGA_ARBCTL_BGR_FDC 0x0008
-#define IOGA_ARBCTL_BGR_SER0 0x0010
-#define IOGA_ARBCTL_BGR_SER1 0x0020
-#define IOGA_ARBCTL_BGR_SER2 0x0040
-#define IOGA_ARBCTL_BGR_ETHB 0x0080
-#define IOGA_ARBCTL_BGR_ETHA 0x0100
-
/*
0x94: error address reg: expect 0x7f200000 after bus error (from dma virtual address)
0x98: error cycle type: expect 0x52f0 (after failed dma?)
diff --git a/src/mame/machine/interpro_ioga.h b/src/mame/machine/interpro_ioga.h
index c66f37e9d5c..a31f3aba9fc 100644
--- a/src/mame/machine/interpro_ioga.h
+++ b/src/mame/machine/interpro_ioga.h
@@ -66,10 +66,35 @@
#define IOGA_DMA_FLOPPY 2
#define IOGA_DMA_SERIAL 3
+// dma write values
+#define IOGA_DMA_CTRL_WMASK 0xfd000e00
+#define IOGA_DMA_CTRL_RESET_L 0x61000000 // do not clear bus error bit
+#define IOGA_DMA_CTRL_RESET 0x60400000 // clear bus error bit
+
+#define IOGA_DMA_CTRL_START 0x63000800 // perhaps start a transfer? - maybe the 8 is the channel?
+#define IOGA_DMA_CTRL_UNK1 0x60000000 // don't know yet
+#define IOGA_DMA_CTRL_UNK2 0x67000600 // forced berr with nmi and interrupts disabled
+
+// read values
+#define IOGA_DMA_CTRL_BUSY 0x02000000
+#define IOGA_DMA_CTRL_BERR 0x00400000 // iogadiag code expects 0x60400000 on bus error
+// iogadiag expects 0x64400800 after forced berr with nmi/interrupts disabled
+
+
+// bus arbitration bus grant bits
+#define IOGA_ARBCTL_BGR_ETHC 0x0001
+#define IOGA_ARBCTL_BGR_SCSI 0x0002
+#define IOGA_ARBCTL_BGR_PLOT 0x0004
+#define IOGA_ARBCTL_BGR_FDC 0x0008
+#define IOGA_ARBCTL_BGR_SER0 0x0010
+#define IOGA_ARBCTL_BGR_SER1 0x0020
+#define IOGA_ARBCTL_BGR_SER2 0x0040
+#define IOGA_ARBCTL_BGR_ETHB 0x0080
+#define IOGA_ARBCTL_BGR_ETHA 0x0100
+
class interpro_ioga_device : public device_t
{
public:
- // construction/destruction
interpro_ioga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template<class _Object> static devcb_base &static_set_out_nmi_callback(device_t &device, _Object object) { return downcast<interpro_ioga_device &>(device).m_out_nmi_func.set_callback(object); }
@@ -80,7 +105,7 @@ public:
template<class _Object> static devcb_base &static_set_fdc_tc_callback(device_t &device, _Object object) { return downcast<interpro_ioga_device &>(device).m_fdc_tc_func.set_callback(object); }
- virtual DECLARE_ADDRESS_MAP(map, 8);
+ virtual DECLARE_ADDRESS_MAP(map, 32);
// external interrupt lines
DECLARE_WRITE_LINE_MEMBER(ir0_w) { set_irq_line(2, state); }
diff --git a/src/mame/machine/interpro_mcga.cpp b/src/mame/machine/interpro_mcga.cpp
new file mode 100644
index 00000000000..d807f571bab
--- /dev/null
+++ b/src/mame/machine/interpro_mcga.cpp
@@ -0,0 +1,89 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+/*
+* An implementation of the MCGA device found on Intergraph InterPro family workstations. There is no
+* public documentation on this device, so the implementation is being built to follow the logic of the
+* system boot ROM and its diagnostic tests.
+*
+* Please be aware that code in here is not only broken, it's likely wrong in many cases.
+*
+* TODO
+* - too long to list
+*/
+#include "interpro_mcga.h"
+
+#define VERBOSE 0
+#if VERBOSE
+#define LOG_MCGA(...) logerror(__VA_ARGS__)
+#else
+#define LOG_MCGA(...) {}
+#endif
+
+DEVICE_ADDRESS_MAP_START(map, 16, interpro_mcga_device)
+ AM_RANGE(0x00, 0x3f) AM_READWRITE16(read, write, 0xffff)
+ADDRESS_MAP_END
+
+const device_type INTERPRO_MCGA = &device_creator<interpro_mcga_device>;
+
+interpro_mcga_device::interpro_mcga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, INTERPRO_MCGA, "InterPro MCGA", tag, owner, clock, "mcga", __FILE__)
+{
+}
+
+void interpro_mcga_device::device_start()
+{
+}
+
+void interpro_mcga_device::device_reset()
+{
+ m_reg[0] = 0x00ff; // 0x00
+ m_reg[2] = MCGA_CTRL_ENREFRESH | MCGA_CTRL_CBITFRCSUB | MCGA_CTRL_CBITFRCRD; // 0x08 ctrl
+ //m_mcga[4] = 0x8000; // 0x10 error
+ m_reg[10] = 0x00ff; // 0x28
+ m_reg[14] = 0x0340; // 0x38 memsize
+}
+
+WRITE16_MEMBER(interpro_mcga_device::write)
+{
+ /*
+ read MEMSIZE 0x38 mask 0xffff
+ read 0x00 mask 0x0000
+ write CBSUB 0x20 mask 0x00ff data 0
+ write FRCRD 0x18 mask 0x00ff data 0
+ read ERROR 0x10 mask 0xffff
+ read 0x00 mask 0xffff
+
+ (0x38 >> 8) & 0xF == 3?
+
+ if (0x00 != 0xFF) -> register reset error
+
+ 0x00 = 0x0055 (test value & 0xff)
+ r7 = 0x00 & 0xff
+ */
+ LOG_MCGA("mcga write offset = 0x%08x, mask = 0x%08x, data = 0x%08x, pc = 0x%08x\n", offset, mem_mask, data, space.device().safe_pc());
+ switch (offset)
+ {
+ case 0x02: // MCGA_CTRL
+ // HACK: set or clear error status depending on ENMMBE bit
+ if (data & MCGA_CTRL_ENMMBE)
+ m_reg[4] |= MCGA_ERROR_VALID;
+ // else
+ // m_reg[4] &= ~MCGA_ERROR_VALID;
+
+ default:
+ m_reg[offset] = data;
+ break;
+ }
+}
+
+READ16_MEMBER(interpro_mcga_device::read)
+{
+ LOG_MCGA("mcga read offset = 0x%08x, mask = 0x%08x, pc = 0x%08x\n", offset, mem_mask, space.device().safe_pc());
+
+ switch (offset)
+ {
+ default:
+ return m_reg[offset];
+ }
+} \ No newline at end of file
diff --git a/src/mame/machine/interpro_mcga.h b/src/mame/machine/interpro_mcga.h
new file mode 100644
index 00000000000..4f3ecde78cc
--- /dev/null
+++ b/src/mame/machine/interpro_mcga.h
@@ -0,0 +1,45 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+#pragma once
+
+#ifndef INTERPRO_MCGA_H_
+#define INTERPRO_MCGA_H_
+
+#include "emu.h"
+
+// mcga control register
+#define MCGA_CTRL_OPTMASK 0x00000003
+#define MCGA_CTRL_CBITFRCRD 0x00000004
+#define MCGA_CTRL_CBITFRCSUB 0x00000008
+#define MCGA_CTRL_ENREFRESH 0x00000010
+#define MCGA_CTRL_ENMSBE 0x00000100
+#define MCGA_CTRL_ENMMBE 0x00000200
+#define MCGA_CTRL_ENECC 0x00000400
+#define MCGA_CTRL_WRPROT 0x00008000
+
+// mcga error register
+#define MCGA_ERROR_VALID 0x00008000
+
+class interpro_mcga_device : public device_t
+{
+public:
+ interpro_mcga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ virtual DECLARE_ADDRESS_MAP(map, 32);
+
+ DECLARE_WRITE16_MEMBER(write);
+ DECLARE_READ16_MEMBER(read);
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ uint16_t m_reg[32];
+};
+
+// device type definition
+extern const device_type INTERPRO_MCGA;
+
+#endif \ No newline at end of file
diff --git a/src/mame/machine/interpro_sga.cpp b/src/mame/machine/interpro_sga.cpp
new file mode 100644
index 00000000000..102c58a2f0b
--- /dev/null
+++ b/src/mame/machine/interpro_sga.cpp
@@ -0,0 +1,88 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+/*
+* An implementation of the SGA device found on Intergraph InterPro family workstations. There is no
+* public documentation on this device, so the implementation is being built to follow the logic of the
+* system boot ROM and its diagnostic tests.
+*
+* Please be aware that code in here is not only broken, it's likely wrong in many cases.
+*
+* TODO
+* - too long to list
+*/
+#include "interpro_sga.h"
+
+#define VERBOSE 0
+
+DEVICE_ADDRESS_MAP_START(map, 32, interpro_sga_device)
+ AM_RANGE(0x00, 0x03) AM_READWRITE(gcs_r, gcs_w)
+ AM_RANGE(0x04, 0x07) AM_READWRITE(ipoll_r, ipoll_w)
+ AM_RANGE(0x08, 0x0b) AM_READWRITE(imask_r, imask_w)
+ AM_RANGE(0x0c, 0x0f) AM_READWRITE(range_base_r, range_base_w)
+ AM_RANGE(0x10, 0x13) AM_READWRITE(range_end_r, range_end_w)
+ AM_RANGE(0x14, 0x17) AM_READWRITE(cttag_r, cttag_w)
+ AM_RANGE(0x18, 0x1b) AM_READWRITE(address_r, address_w)
+ AM_RANGE(0x1c, 0x1f) AM_READWRITE(dmacs_r, dmacs_w)
+ AM_RANGE(0x20, 0x23) AM_READWRITE(edmacs_r, edmacs_w)
+
+ AM_RANGE(0xa4, 0xa7) AM_READWRITE(dspad1_r, dspad1_w)
+ AM_RANGE(0xa8, 0xab) AM_READWRITE(dsoff1_r, dsoff1_w)
+
+ AM_RANGE(0xb4, 0xb7) AM_READWRITE(unknown1_r, unknown1_w)
+ AM_RANGE(0xb8, 0xbb) AM_READWRITE(unknown2_r, unknown2_w)
+ AM_RANGE(0xbc, 0xbf) AM_READWRITE(ddtc1_r, ddtc1_w)
+ADDRESS_MAP_END
+
+const device_type INTERPRO_SGA = &device_creator<interpro_sga_device>;
+
+interpro_sga_device::interpro_sga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, INTERPRO_SGA, "InterPro SGA", tag, owner, clock, "sga", __FILE__)
+{
+}
+
+void interpro_sga_device::device_start()
+{
+}
+
+void interpro_sga_device::device_reset()
+{
+}
+
+WRITE32_MEMBER(interpro_sga_device::ddtc1_w)
+{
+ // we assume that when this register is written, we should start a
+ // memory to memory dma transfer
+
+ logerror(" gcs = 0x%08x dmacs = 0x%08x\n", m_gcs, m_dmacs);
+ logerror(" ipoll = 0x%08x imask = 0x%08x\n", m_ipoll, m_imask);
+ logerror("dspad1 = 0x%08x dsoff1 = 0x%08x\n", m_dspad1, m_dsoff1);
+ logerror(" unk1 = 0x%08x unk2 = 0x%08x\n", m_unknown1, m_unknown2);
+ logerror(" ddtc1 = 0x%08x\n", data);
+
+ m_ddtc1 = data;
+
+ // when complete, we indicate by setting DMAEND(2) - 2 is probably the channel
+ // we also turn off the INTBERR and INTMMBE flags
+ m_ipoll &= ~(0x20000 | 0x10000);
+ m_ipoll |= 0x200;
+
+ // if the address is invalid, fake a bus error
+ if (m_dspad1 == 0x40000000 || m_unknown1 == 0x40000000
+ || m_dspad1 == 0x40000200 || m_unknown1 == 0x40000200)
+ {
+ m_ipoll |= 0x10000;
+
+ // error cycle - bit 0x10 indicates source address error (dspad1)
+ // now expecting 0x5463?
+#if 0
+ if ((m_dspad1 & 0xfffff000) == 0x40000000)
+ m_ioga->bus_error(m_dspad1, 0x5433);
+ else
+ m_ioga->bus_error(m_unknown1, 0x5423);
+#endif
+ // 0x5423 = BERR|SNAPOK | BG(ICAMMU)? | CT(23)
+ // 0x5433 = BERR|SNAPOK | BG(ICAMMU)? | CT(33)
+ // 0x5463 = BERR|SNAPOK | BG(ICAMMU)? | TAG(1) | CT(23)
+ }
+}
diff --git a/src/mame/machine/interpro_sga.h b/src/mame/machine/interpro_sga.h
new file mode 100644
index 00000000000..06c2d1fba8f
--- /dev/null
+++ b/src/mame/machine/interpro_sga.h
@@ -0,0 +1,71 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+#pragma once
+
+#ifndef INTERPRO_SGA_H_
+#define INTERPRO_SGA_H_
+
+#include "emu.h"
+
+class interpro_sga_device : public device_t
+{
+public:
+ interpro_sga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ virtual DECLARE_ADDRESS_MAP(map, 32);
+
+ DECLARE_READ32_MEMBER(gcs_r) { return m_gcs; }
+ DECLARE_WRITE32_MEMBER(gcs_w) { m_gcs = data; }
+ DECLARE_READ32_MEMBER(ipoll_r) { return m_ipoll; }
+ DECLARE_WRITE32_MEMBER(ipoll_w) { m_ipoll = data; }
+ DECLARE_READ32_MEMBER(imask_r) { return m_imask; }
+ DECLARE_WRITE32_MEMBER(imask_w) { m_imask = data; }
+ DECLARE_READ32_MEMBER(range_base_r) { return m_range_base; }
+ DECLARE_WRITE32_MEMBER(range_base_w) { m_range_base = data; }
+ DECLARE_READ32_MEMBER(range_end_r) { return m_range_end; }
+ DECLARE_WRITE32_MEMBER(range_end_w) { m_range_end = data; }
+ DECLARE_READ32_MEMBER(cttag_r) { return m_cttag; }
+ DECLARE_WRITE32_MEMBER(cttag_w) { m_cttag = data; }
+ DECLARE_READ32_MEMBER(address_r) { return m_address; }
+ DECLARE_WRITE32_MEMBER(address_w) { m_address = data; }
+ DECLARE_READ32_MEMBER(dmacs_r) { return m_dmacs; }
+ DECLARE_WRITE32_MEMBER(dmacs_w) { m_dmacs = data; }
+ DECLARE_READ32_MEMBER(edmacs_r) { return m_edmacs; }
+ DECLARE_WRITE32_MEMBER(edmacs_w) { m_edmacs = data; }
+ DECLARE_READ32_MEMBER(dspad1_r) { return m_dspad1; }
+ DECLARE_WRITE32_MEMBER(dspad1_w) { m_dspad1 = data; }
+ DECLARE_READ32_MEMBER(dsoff1_r) { return m_dsoff1; }
+ DECLARE_WRITE32_MEMBER(dsoff1_w) { m_dsoff1 = data; }
+ DECLARE_READ32_MEMBER(unknown1_r) { return m_unknown1; }
+ DECLARE_WRITE32_MEMBER(unknown1_w) { m_unknown1 = data; }
+ DECLARE_READ32_MEMBER(unknown2_r) { return m_unknown2; }
+ DECLARE_WRITE32_MEMBER(unknown2_w) { m_unknown2 = data; }
+ DECLARE_READ32_MEMBER(ddtc1_r) { return m_ddtc1; }
+ DECLARE_WRITE32_MEMBER(ddtc1_w);
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ uint32_t m_gcs; // general control/status
+ uint32_t m_ipoll; // interrupt poll
+ uint32_t m_imask; // interrupt mask
+ uint32_t m_range_base;
+ uint32_t m_range_end;
+ uint32_t m_cttag; // error cycletype/tag
+ uint32_t m_address;
+ uint32_t m_dmacs; // dma control/status
+ uint32_t m_edmacs; // extended dma control/status
+ uint32_t m_dspad1;
+ uint32_t m_dsoff1;
+ uint32_t m_unknown1;
+ uint32_t m_unknown2;
+ uint32_t m_ddtc1;
+};
+
+// device type definition
+extern const device_type INTERPRO_SGA;
+
+#endif \ No newline at end of file
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index 814e9ed6883..79056da3775 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -14769,6 +14769,9 @@ instruct //
hector1 //
interact //
+@source:interpro.cpp
+ip2800 // Intergraph InterPro 28xx workstation
+
@source:intrscti.cpp
intrscti // ????
diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp
index e1667a9b9e7..0a8c8680438 100644
--- a/src/tools/unidasm.cpp
+++ b/src/tools/unidasm.cpp
@@ -79,6 +79,7 @@ CPU_DISASSEMBLE( avr8 );
CPU_DISASSEMBLE( ccpu );
CPU_DISASSEMBLE( cdp1801 );
CPU_DISASSEMBLE( cdp1802 );
+CPU_DISASSEMBLE( clipper );
CPU_DISASSEMBLE( coldfire );
CPU_DISASSEMBLE( cop410 );
CPU_DISASSEMBLE( cop420 );
@@ -248,6 +249,7 @@ static const dasm_table_entry dasm_table[] =
{ "ccpu", _8bit, 0, CPU_DISASSEMBLE_NAME(ccpu) },
{ "cdp1801", _8bit, 0, CPU_DISASSEMBLE_NAME(cdp1801) },
{ "cdp1802", _8bit, 0, CPU_DISASSEMBLE_NAME(cdp1802) },
+ { "clipper", _16le, 0, CPU_DISASSEMBLE_NAME(clipper) },
{ "coldfire", _16be, 0, CPU_DISASSEMBLE_NAME(coldfire) },
{ "cop410", _8bit, 0, CPU_DISASSEMBLE_NAME(cop410) },
{ "cop420", _8bit, 0, CPU_DISASSEMBLE_NAME(cop420) },