initial sga and mmu support

This commit is contained in:
Patrick Mackinlay 2017-01-17 17:42:33 +08:00
parent ccee0ea2b7
commit 59ed58e518
3 changed files with 239 additions and 26 deletions

View File

@ -186,6 +186,8 @@ class clipper_device : public cpu_device
public:
clipper_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
bool supervisor_mode() { return SSW(U) == 0; }
bool mapped_mode() { return SSW(M) != 0; }
protected:
// device-level overrides
virtual void device_start() override;

View File

@ -319,7 +319,7 @@ READ32_MEMBER(interpro_state::slot0_r)
0x55, 0xaa, 0x55, 0x00
};
return ((uint8_t *)&slot0)[offset];
return ((uint8_t *)&slot0)[offset % 32];
}
WRITE8_MEMBER(interpro_state::interpro_rtc_w)
@ -361,53 +361,174 @@ READ8_MEMBER(interpro_state::interpro_rtc_r)
}
}
/*
MCGA: 40000xxx - refer iopsysreg.h
00: 0005
08: CTRL 0010 // control register (hword)
10: ERROR 0400 // error register (hword)
18: 0000 // frcrd register (byte)
20: 0000 // cbsub register (byte)
28: 0088
30: 001B
38: MEMSIZE 0004
READ8_MEMBER(interpro_state::scsi_r)
{
return m_scsi->read(space, offset, 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)
}
}
READ32_MEMBER(interpro_state::interpro_mmu_r)
{
// handle htlb
if (m_maincpu->supervisor_mode() && (offset & ~0x1FFF) == 0)
{
switch (offset & 0x3C00)
{
case 0x000:
case 0x400:
case 0x800:
case 0xC00:
return m_main_space->read32(space, offset, mem_mask);
case 0x1000:
case 0x1400:
return m_io_space->read32(space, offset & 0x7ff, mem_mask);
case 0x1800:
case 0x1C00:
return m_boot_space->read32(space, offset & 0x7ff, mem_mask);
}
}
// address with upper bytes 0 or 0x7f1
if ((offset >> 22) == 0x00 || (offset >> 18) == 0x7f1)
return m_main_space->read32(space, offset, mem_mask);
else
return m_io_space->read32(space, offset, mem_mask);
}
WRITE32_MEMBER(interpro_state::interpro_mmu_w)
{
// handle htlb
if (m_maincpu->supervisor_mode() && (offset & ~0x1FFF) == 0)
{
switch (offset & 0x3C00)
{
case 0x000:
case 0x400:
case 0x800:
case 0xC00:
// pages 0-3: main space
m_main_space->write32(space, offset, data, mem_mask);
return;
case 0x1000:
case 0x1400:
// pages 4-5: pages 0-1 i/o space
m_io_space->write32(space, offset & 0x7ff, data, mem_mask);
return;
case 0x1800:
case 0x1C00:
// pages 6-7: pages 0-1 boot space
m_boot_space->write32(space, offset & 0x7ff, data, mem_mask);
return;
}
}
// address with upper byte 0x00 or upper 3 bytes 0x7f1
if ((offset >> 22) == 0x00 || (offset >> 18) == 0x7f1)
m_main_space->write32(space, offset, data, mem_mask);
else
m_io_space->write32(space, offset, data, mem_mask);
}
// driver init
DRIVER_INIT_MEMBER(interpro_state, ip2800)
{
}
static ADDRESS_MAP_START(ip2800_map, AS_PROGRAM, 32, interpro_state)
ADDRESS_MAP_UNMAP_LOW
static ADDRESS_MAP_START(interpro_map, AS_PROGRAM, 32, interpro_state)
AM_RANGE(0x00000000, 0xffffffff) AM_READWRITE(interpro_mmu_r, interpro_mmu_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START(interpro_main_map, AS_PROGRAM, 32, interpro_state)
AM_RANGE(0x00000000, 0x00ffffff) AM_RAM // 16M RAM
AM_RANGE(0x08000000, 0x0800001f) AM_RAM // bogus
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_PROGRAM, 32, interpro_state)
// really cammus
AM_RANGE(0x00000000, 0x00000fff) AM_RAM
AM_RANGE(0x00001000, 0x00001fff) AM_RAM
AM_RANGE(0x40000000, 0x4000003f) AM_READWRITE16(mcga_r, mcga_w, 0xffff)
AM_RANGE(0x4f007e00, 0x4f007f7f) AM_RAM // treat SRX GA as ram for now
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(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)
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(0x7f000300, 0x7f00030f) AM_READWRITE16(emerald_r, emerald_w, 0xffff)
AM_RANGE(0x7f000500, 0x7f0006ff) AM_READWRITE8(interpro_rtc_r, interpro_rtc_w, 0xff)
AM_RANGE(0x7f000700, 0x7f00077f) AM_READ(idprom_r)
AM_RANGE(0x7f0fff00, 0x7f0fffff) AM_DEVICE(INTERPRO_IOGA_TAG, interpro_ioga_device, map)
AM_RANGE(0x7f100000, 0x7f11ffff) AM_ROM AM_REGION(INTERPRO_ROM_TAG, 0)
AM_RANGE(0x7f180000, 0x7f1bffff) AM_ROM AM_REGION(INTERPRO_EEPROM_TAG, 0)
AM_RANGE(0x8f007f80, 0x8f007fff) AM_READ(slot0_r)
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_PROGRAM, 32, interpro_state)
AM_RANGE(0x00000000, 0x00001fff) AM_RAM
ADDRESS_MAP_END
FLOPPY_FORMATS_MEMBER(interpro_state::floppy_formats)
@ -425,9 +546,31 @@ INPUT_PORTS_END
static MACHINE_CONFIG_START(ip2800, interpro_state)
MCFG_CPU_ADD(INTERPRO_CPU_TAG, CLIPPER, 10000000)
MCFG_CPU_PROGRAM_MAP(ip2800_map)
MCFG_CPU_PROGRAM_MAP(interpro_map)
MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE(INTERPRO_IOGA_TAG, interpro_ioga_device, inta_cb)
// mmu main memory space
MCFG_DEVICE_ADD(INTERPRO_MAINSPACE_TAG, ADDRESS_MAP_BANK, 0)
MCFG_DEVICE_PROGRAM_MAP(interpro_main_map)
MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE)
MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32)
MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000000)
// mmu i/o space
MCFG_DEVICE_ADD(INTERPRO_IOSPACE_TAG, ADDRESS_MAP_BANK, 0)
MCFG_DEVICE_PROGRAM_MAP(interpro_io_map)
MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE)
MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32)
MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000000)
// mmu boot space
MCFG_DEVICE_ADD(INTERPRO_BOOTSPACE_TAG, ADDRESS_MAP_BANK, 0)
MCFG_DEVICE_PROGRAM_MAP(interpro_boot_map)
MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE)
MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32)
MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000000)
// 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))
@ -447,10 +590,12 @@ static MACHINE_CONFIG_START(ip2800, interpro_state)
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))
@ -458,13 +603,15 @@ static MACHINE_CONFIG_START(ip2800, interpro_state)
MCFG_FLOPPY_DRIVE_ADD("fdc:1", interpro_floppies, "35hd", interpro_state::floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(false)
// scsi
MCFG_DEVICE_ADD("scsiport", SCSI_PORT, 0)
MCFG_DEVICE_ADD(INTERPRO_SCSI_TAG, NCR539X, 12500000)
MCFG_DEVICE_ADD(INTERPRO_SCSI_TAG, NCR539X, XTAL_12_5MHz)
MCFG_LEGACY_SCSI_PORT("scsiport")
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))

View File

@ -10,6 +10,8 @@
#include "cpu/clipper/clipper.h"
#include "machine/bankdev.h"
#include "machine/z80scc.h"
#include "machine/mc146818.h"
#include "machine/upd765.h"
@ -21,6 +23,11 @@
#include "formats/pc_dsk.h"
#define INTERPRO_CPU_TAG "cpu"
#define INTERPRO_MAINSPACE_TAG "main_space"
#define INTERPRO_IOSPACE_TAG "io_space"
#define INTERPRO_BOOTSPACE_TAG "boot_space"
#define INTERPRO_RTC_TAG "rtc"
#define INTERPRO_SCC1_TAG "scc1"
#define INTERPRO_SCC2_TAG "scc2"
@ -39,6 +46,9 @@ 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_main_space(*this, INTERPRO_MAINSPACE_TAG),
m_io_space(*this, INTERPRO_IOSPACE_TAG),
m_boot_space(*this, INTERPRO_BOOTSPACE_TAG),
m_scc1(*this, INTERPRO_SCC1_TAG),
m_scc2(*this, INTERPRO_SCC2_TAG),
m_rtc(*this, INTERPRO_RTC_TAG),
@ -49,6 +59,10 @@ public:
required_device<clipper_device> m_maincpu;
required_device<address_map_bank_device> m_main_space;
required_device<address_map_bank_device> m_io_space;
required_device<address_map_bank_device> m_boot_space;
// FIXME: not sure which one is the escc
required_device<z80scc_device> m_scc1;
required_device<z80scc_device> m_scc2;
@ -61,6 +75,9 @@ public:
DECLARE_DRIVER_INIT(ip2800);
DECLARE_READ32_MEMBER(interpro_mmu_r);
DECLARE_WRITE32_MEMBER(interpro_mmu_w);
DECLARE_WRITE16_MEMBER(emerald_w);
DECLARE_READ16_MEMBER(emerald_r);
@ -73,8 +90,40 @@ public:
DECLARE_READ32_MEMBER(idprom_r);
DECLARE_READ32_MEMBER(slot0_r);
DECLARE_READ8_MEMBER(scsi_r);
DECLARE_WRITE8_MEMBER(scsi_w);
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;
@ -82,6 +131,21 @@ protected:
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;
};
#endif