diff --git a/src/devices/cpu/clipper/clipper.h b/src/devices/cpu/clipper/clipper.h index 8ce295aeb2b..46ecd8e281c 100644 --- a/src/devices/cpu/clipper/clipper.h +++ b/src/devices/cpu/clipper/clipper.h @@ -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; diff --git a/src/mame/drivers/interpro.cpp b/src/mame/drivers/interpro.cpp index 52fe6f2629d..05d4d06106c 100644 --- a/src/mame/drivers/interpro.cpp +++ b/src/mame/drivers/interpro.cpp @@ -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)) diff --git a/src/mame/includes/interpro.h b/src/mame/includes/interpro.h index daea2fa5c48..df988e85878 100644 --- a/src/mame/includes/interpro.h +++ b/src/mame/includes/interpro.h @@ -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 m_maincpu; + required_device m_main_space; + required_device m_io_space; + required_device m_boot_space; + // FIXME: not sure which one is the escc required_device m_scc1; required_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 \ No newline at end of file