mirror of
https://github.com/holub/mame
synced 2025-04-20 23:42:22 +03:00
initial pull request
This commit is contained in:
parent
24dba19f8c
commit
875f3c9d12
@ -2416,3 +2416,19 @@ end
|
||||
if (CPUS["MB86901"]~=null or _OPTIONS["with-tools"]) then
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/sparc/sparcdasm.cpp")
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
-- Intergraph CLIPPER (C100/C300/C400) series
|
||||
--@src/devices/cpu/clipper/clipper.h,CPUS["CLIPPER"] = true
|
||||
--------------------------------------------------
|
||||
|
||||
if (CPUS["CLIPPER"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/cpu/clipper/clipper.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/clipper/clipper.h",
|
||||
}
|
||||
end
|
||||
|
||||
if (CPUS["CLIPPER"]~=null or _OPTIONS["with-tools"]) then
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/clipper/clipperd.cpp")
|
||||
end
|
@ -2073,6 +2073,22 @@ files {
|
||||
MAME_DIR .. "src/mame/drivers/tim100.cpp",
|
||||
}
|
||||
|
||||
createMESSProjects(_target, _subtarget, "interpro")
|
||||
files {
|
||||
MAME_DIR .. "src/mame/drivers/interpro.cpp",
|
||||
MAME_DIR .. "src/mame/includes/interpro.h",
|
||||
MAME_DIR .. "src/mame/machine/cammu.h",
|
||||
MAME_DIR .. "src/mame/machine/cammu.cpp",
|
||||
MAME_DIR .. "src/mame/machine/interpro_ioga.h",
|
||||
MAME_DIR .. "src/mame/machine/interpro_ioga.cpp",
|
||||
MAME_DIR .. "src/mame/machine/interpro_ioga.h",
|
||||
MAME_DIR .. "src/mame/machine/interpro_ioga.cpp",
|
||||
MAME_DIR .. "src/mame/machine/interpro_mcga.h",
|
||||
MAME_DIR .. "src/mame/machine/interpro_mcga.cpp",
|
||||
MAME_DIR .. "src/mame/machine/interpro_sga.h",
|
||||
MAME_DIR .. "src/mame/machine/interpro_sga.cpp",
|
||||
}
|
||||
|
||||
createMESSProjects(_target, _subtarget, "interton")
|
||||
files {
|
||||
MAME_DIR .. "src/mame/drivers/vc4000.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)
|
||||
|
@ -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"
|
||||
#define INTERPRO_MCGA_TAG "mcga"
|
||||
#define INTERPRO_SGA_TAG "sga"
|
||||
#define INTERPRO_SCSI_ADAPTER_TAG "adapter"
|
||||
|
||||
// TODO: RTC is actually a DS12887, but the only difference is the 128 byte NVRAM, same as the DS12885
|
||||
// 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
|
@ -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?)
|
||||
|
@ -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); }
|
||||
|
89
src/mame/machine/interpro_mcga.cpp
Normal file
89
src/mame/machine/interpro_mcga.cpp
Normal file
@ -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];
|
||||
}
|
||||
}
|
45
src/mame/machine/interpro_mcga.h
Normal file
45
src/mame/machine/interpro_mcga.h
Normal file
@ -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
|
88
src/mame/machine/interpro_sga.cpp
Normal file
88
src/mame/machine/interpro_sga.cpp
Normal file
@ -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)
|
||||
}
|
||||
}
|
71
src/mame/machine/interpro_sga.h
Normal file
71
src/mame/machine/interpro_sga.h
Normal file
@ -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
|
@ -14769,6 +14769,9 @@ instruct //
|
||||
hector1 //
|
||||
interact //
|
||||
|
||||
@source:interpro.cpp
|
||||
ip2800 // Intergraph InterPro 28xx workstation
|
||||
|
||||
@source:intrscti.cpp
|
||||
intrscti // ????
|
||||
|
||||
|
@ -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) },
|
||||
|
Loading…
Reference in New Issue
Block a user