From 281957363ea8d87098dcfcb420ac0bfeca3c57ee Mon Sep 17 00:00:00 2001 From: Dirk Best Date: Sat, 25 Feb 2023 19:33:56 +0100 Subject: machine/pccard.cpp, machine/pccard_sram.cpp: Added support for PCMCIA linear SRAM cards. (#10886) * Added callbacks for card detect, battery voltage and write protect to the PCCard interface. * Added helpers to read/write data swapped (similar to the existing support in the ATA device). * Add support for 2 MB and 4 MB SRAM PCMCIA models from Centennial with built-in EEPROM storage for CIS information. * machine/linflash.cpp: Updated the linear Flash PCMCIA card emulation to use the new card detection support. * machine/gayle.cpp: Rewrote the Amiga Gayle emulation, adding support for PCMCIA. * Fixed an issue with Amiga interrupts arriving at the wrong time. --- scripts/src/machine.lua | 12 ++ src/devices/machine/gayle.cpp | 397 ++++++++++++++++++++++++++++-------- src/devices/machine/gayle.h | 115 +++++++++-- src/devices/machine/linflash.cpp | 5 + src/devices/machine/linflash.h | 1 + src/devices/machine/pccard.cpp | 18 +- src/devices/machine/pccard.h | 26 ++- src/devices/machine/pccard_sram.cpp | 288 ++++++++++++++++++++++++++ src/devices/machine/pccard_sram.h | 125 ++++++++++++ src/mame/amiga/amiga.cpp | 108 ++++++++-- src/mame/amiga/amiga_m.cpp | 14 +- src/mame/konami/ksys573.cpp | 18 +- 12 files changed, 991 insertions(+), 136 deletions(-) create mode 100644 src/devices/machine/pccard_sram.cpp create mode 100644 src/devices/machine/pccard_sram.h diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index 1578aae4857..3652709ec1a 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -5138,3 +5138,15 @@ if (MACHINES["MC88200"]~=null) then MAME_DIR .. "src/devices/machine/mc88200.h", } end + +--------------------------------------------------- +-- +--@src/devices/machine/pccard_sram.h,MACHINES["PCCARD_SRAM"] = true +--------------------------------------------------- + +if (MACHINES["PCCARD_SRAM"]~=null) then + files { + MAME_DIR .. "src/devices/machine/pccard_sram.cpp", + MAME_DIR .. "src/devices/machine/pccard_sram.h", + } +end diff --git a/src/devices/machine/gayle.cpp b/src/devices/machine/gayle.cpp index 0e55fcd2bb6..64c76628fbc 100644 --- a/src/devices/machine/gayle.cpp +++ b/src/devices/machine/gayle.cpp @@ -1,22 +1,38 @@ -// license:GPL-2.0+ -// copyright-holders:Dirk Best +// license: GPL-2.0+ +// copyright-holders: Dirk Best /*************************************************************************** GAYLE - Gate array used in the Amiga 600 and Amiga 1200 computers. + Gate array used in the Amiga 600 and Amiga 1200 computers for the + following functions: + - Address decoding and timing for ROM, RAM, CIA, RTC + (and unused: Flash ROM, ArcNet) + - Data buffers for chip RAM + - IDE interface + - Credit card (PCMCIA) interface + - System reset + - Floppy helper + - E clock generation + + TODO: + - Generate bus errors (REG_CHANGE, bit 0) + - Disabling the PCMCIA interface should remove access to PCMCIA memory + - Move more functionality here ***************************************************************************/ #include "emu.h" #include "gayle.h" +//#define LOG_GENERAL (1U << 0) +#define LOG_REG (1U << 1) +#define LOG_IDE (1U << 2) +#define LOG_CC (1U << 3) +#define LOG_ID (1U << 4) -//************************************************************************** -// CONSTANTS -//************************************************************************** - -#define VERBOSE 0 +//#define VERBOSE (LOG_GENERAL | LOG_REG | LOG_CC) +#include "logmacro.h" //************************************************************************** @@ -37,10 +53,10 @@ DEFINE_DEVICE_TYPE(GAYLE, gayle_device, "gayle", "Amiga GAYLE") gayle_device::gayle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, GAYLE, tag, owner, clock), m_int2_w(*this), - m_cs0_read(*this), - m_cs0_write(*this), - m_cs1_read(*this), - m_cs1_write(*this), + m_int6_w(*this), + m_rst_w(*this), + m_ide_cs_r_cb(*this), + m_ide_cs_w_cb(*this), m_gayle_id(0xff), m_gayle_id_count(0) { @@ -54,13 +70,14 @@ void gayle_device::device_start() { // resolve callbacks m_int2_w.resolve_safe(); - m_cs0_read.resolve_safe(0xffff); - m_cs0_write.resolve_safe(); - m_cs1_read.resolve_safe(0xffff); - m_cs1_write.resolve_safe(); + m_int6_w.resolve_safe(); + m_rst_w.resolve_safe(); + m_ide_cs_r_cb.resolve_all_safe(0xffff); + m_ide_cs_w_cb.resolve_all_safe(); save_item(NAME(m_gayle_id_count)); save_item(NAME(m_gayle_reg)); + save_item(NAME(m_line_state)); } //------------------------------------------------- @@ -69,117 +86,321 @@ void gayle_device::device_start() void gayle_device::device_reset() { + // internal registers are cleared to 0 on reset m_gayle_reg[0] = 0; m_gayle_reg[1] = 0; m_gayle_reg[2] = 0; m_gayle_reg[3] = 0; + + // lower interrupts + m_int2_w(0); + m_int6_w(0); +} + + +//************************************************************************** +// ADDRESS MAP +//************************************************************************** + +void gayle_device::register_map(address_map &map) +{ + // base address 0xdaXXXX + map(0x0000, 0x001f).mirror(0x0fe0).rw(FUNC(gayle_device::ide_cs_r<1>), FUNC(gayle_device::ide_cs_w<1>)); + map(0x2000, 0x201f).mirror(0x0fe0).rw(FUNC(gayle_device::ide_cs_r<0>), FUNC(gayle_device::ide_cs_w<0>)); + map(0x8000, 0x8001).rw(FUNC(gayle_device::status_r), FUNC(gayle_device::status_w)); + map(0x9000, 0x9001).rw(FUNC(gayle_device::change_r), FUNC(gayle_device::change_w)); + map(0xa000, 0xa001).rw(FUNC(gayle_device::int_r), FUNC(gayle_device::int_w)); + map(0xb000, 0xb001).rw(FUNC(gayle_device::control_r), FUNC(gayle_device::control_w)); } //************************************************************************** -// IMPLEMENTATION +// INTERNAL //************************************************************************** -uint16_t gayle_device::gayle_r(offs_t offset, uint16_t mem_mask) +void gayle_device::dump_register() +{ + LOGMASKED(LOG_REG, "status = %02x, change = %02x, int = %02x, control = %02x\n", + m_gayle_reg[REG_STATUS], m_gayle_reg[REG_CHANGE], m_gayle_reg[REG_INT], m_gayle_reg[REG_CONTROL]); +} + +void gayle_device::line_change(int line, int state, int level) { - uint16_t data = 0xffff; - offset <<= 1; + LOGMASKED(line == LINE_IDE ? LOG_IDE : LOG_CC, "line_change: %d %d %d\n", line, state, level); - // swap - mem_mask = swapendian_int16(mem_mask); + m_line_state &= ~(1 << line); + m_line_state |= (state << line); - if (BIT(offset, 15)) + // ignore pcmcia line changes if the interface is disabled + if (line != LINE_IDE && BIT(m_gayle_reg[REG_STATUS], 0)) + return; + + // did we change state? + if (BIT(m_gayle_reg[REG_STATUS], line) != state) { - switch (offset & 0x7fff) + // indicate a change to the line + m_gayle_reg[REG_CHANGE] |= 1 << line; + + // special handling for line 6 (credit card detect) + if (line == LINE_CC_DET && BIT(m_gayle_reg[REG_CHANGE], 1)) { - case 0x0000: data = m_gayle_reg[0]; break; - case 0x1000: data = m_gayle_reg[1]; break; - case 0x2000: data = m_gayle_reg[2]; break; - case 0x3000: data = m_gayle_reg[3]; break; + LOGMASKED(LOG_GENERAL, "resetting due to credit card detection change\n"); + + m_rst_w(0); + m_rst_w(1); + reset(); + + return; } - } - else - { - if (!BIT(offset, 14)) + + if (state) + m_gayle_reg[REG_STATUS] |= 1 << line; + else + m_gayle_reg[REG_STATUS] &= ~(1 << line); + + // generate interrupt (if enabled) + if (BIT(m_gayle_reg[REG_INT], line)) { - if (BIT(offset, 13)) - data = m_cs0_read((offset >> 2) & 0x07, mem_mask); + LOGMASKED(line == LINE_IDE ? LOG_IDE : LOG_CC, "line %d int assert\n", line); + + if (level == 2) + m_int2_w(1); else - data = m_cs1_read((offset >> 2) & 0x07, mem_mask); + m_int6_w(1); } } +} + - if (VERBOSE) - logerror("gayle_r(%06x): %04x & %04x\n", offset, data, mem_mask); +//************************************************************************** +// REGISTER +//************************************************************************** - // swap data - data = swapendian_int16(data); +uint16_t gayle_device::status_r() +{ + // 7------- ide interrupt status + // -6------ credit card detect + // --5----- battery voltage 1/status change + // ---4---- battery voltage 2/digital audio + // ----3--- credit card write enable + // -----2-- credit card busy/interrupt request + // ------1- enable pcmcia digital audio + // -------0 disable pcmcia + + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_REG, "status_r: %02x\n", m_gayle_reg[REG_STATUS]); + + return (m_gayle_reg[REG_STATUS] << 8) | m_gayle_reg[REG_STATUS]; +} - return data; +void gayle_device::status_w(uint16_t data) +{ + uint8_t previous = m_gayle_reg[REG_STATUS]; + data >>= 8; + LOGMASKED(LOG_REG, "status_w: %02x\n", data); + + // pcmcia interface disable? + if (BIT(data, 0) == 1) + m_gayle_reg[REG_STATUS] &= 0x03; + + // lowest two bits can be set freely + m_gayle_reg[REG_STATUS] &= ~0x03; + m_gayle_reg[REG_STATUS] |= data & 0x03; + + // status bits can only be set + m_gayle_reg[REG_STATUS] |= data & 0xfc; + + // pcmcia interface re-enabled? + if (BIT(previous, 0) == 1 && BIT(data, 0) == 0) + { + cc_cd_w(BIT(m_line_state, 6)); + cc_bvd1_w(BIT(m_line_state, 5)); + cc_bvd2_w(BIT(m_line_state, 4)); + cc_wp_w(BIT(m_line_state, 3)); + } } -void gayle_device::gayle_w(offs_t offset, uint16_t data, uint16_t mem_mask) +uint16_t gayle_device::change_r() { - offset <<= 1; + // 7------- ide interrupt changed + // -6------ credit card detect changed + // --5----- battery voltage 1/status change changed + // ---4---- battery voltage 2/digital audio changed + // ----3--- credit card write enable changed + // -----2-- credit card busy/interrupt request changed + // ------1- generate reset after cc detect change + // -------0 generate bus error after cc detect change + + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_REG, "change_r: %02x\n", m_gayle_reg[REG_CHANGE]); + + return (m_gayle_reg[REG_CHANGE] << 8) | m_gayle_reg[REG_CHANGE]; +} - // swap - mem_mask = swapendian_int16(mem_mask); - data = swapendian_int16(data) & mem_mask; +void gayle_device::change_w(uint16_t data) +{ + data >>= 8; + LOGMASKED(LOG_REG, "change_w: %02x\n", data); - if (VERBOSE) - logerror("gayle_w(%06x): %04x & %04x\n", offset, data, mem_mask); + // clear ide interrupt? + if (BIT(data, 7) == 0) + { + LOGMASKED(LOG_REG, "ide int cleared\n", data); + m_int2_w(0); + } - if (BIT(offset, 15)) + // clear cc detect interrupt? + if (BIT(data, 6) == 0) { - switch (offset & 0x7fff) - { - case 0x0000: - m_gayle_reg[0] = data; - break; - case 0x1000: - m_gayle_reg[1] &= data; - m_gayle_reg[1] |= data & 0x03; - break; - case 0x2000: - m_gayle_reg[2] = data; - break; - case 0x3000: - m_gayle_reg[3] = data; - break; - } + LOGMASKED(LOG_REG, "cc detect int cleared\n", data); + m_int6_w(0); } - else + + // clear bvd1/sc interrupt? + if (BIT(data, 5) == 0) { - if (!BIT(offset, 14)) - { - if (BIT(offset, 13)) - m_cs0_write((offset >> 2) & 0x07, data, mem_mask); - else - m_cs1_write((offset >> 2) & 0x07, data, mem_mask); - } + LOGMASKED(LOG_REG, "bvd1/sc int cleared\n", data); + if (BIT(m_gayle_reg[REG_INT], 1)) + m_int6_w(0); + else + m_int2_w(0); + } + + // clear bvd2/da interrupt? + if (BIT(data, 4) == 0) + { + LOGMASKED(LOG_REG, "bvd2/da int cleared\n", data); + if (BIT(m_gayle_reg[REG_INT], 1)) + m_int6_w(0); + else + m_int2_w(0); } + + // clear write protect interrupt? + if (BIT(data, 3) == 0) + { + LOGMASKED(LOG_REG, "write protect int cleared\n", data); + m_int2_w(0); + } + + // enabling reset on cc detect change can immediately generate a reset + if (BIT(data, 1) && BIT(m_gayle_reg[REG_CHANGE], 6)) + { + LOGMASKED(LOG_REG, "resetting\n", data); + + m_rst_w(0); + m_rst_w(1); + reset(); + + return; + } + + m_gayle_reg[REG_CHANGE] = (m_gayle_reg[REG_CHANGE] & data) | (data & 0x03); +} + +uint16_t gayle_device::int_r() +{ + // 7------- ide interrupt enable + // -6------ credit card detect interrupt enable + // --5----- battery voltage 1/status change interrupt enable + // ---4---- battery voltage 2/digital audio interrupt enable + // ----3--- write enable interrupt enable + // -----2-- busy/interrupt request interrupt enable + // ------1- set interrupt level for battery voltage 1/2 + // -------0 set interrupt level for busy/interrupt request + + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_REG, "int_r: %02x\n", m_gayle_reg[REG_INT]); + + return (m_gayle_reg[REG_INT] << 8) | m_gayle_reg[REG_INT]; +} + +void gayle_device::int_w(uint16_t data) +{ + data >>= 8; + LOGMASKED(LOG_REG, "int_w: %02x\n", data); + + m_gayle_reg[REG_INT] = data; +} + +uint16_t gayle_device::control_r() +{ + // 7654---- not implemented in hardware + // ----32--- slow mem (250 ns, 150 ns, 100 ns, 720 ns) + // ------1- program 12v + // -------0 program 5v + + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_REG, "control_r: %02x\n", m_gayle_reg[REG_CONTROL]); + + return (m_gayle_reg[REG_CONTROL] << 8) | m_gayle_reg[REG_CONTROL]; +} + +void gayle_device::control_w(uint16_t data) +{ + data >>= 8; + LOGMASKED(LOG_REG, "control_w: %02x\n", data); + + m_gayle_reg[REG_CONTROL] = data; +} + + +//************************************************************************** +// IDE +//************************************************************************** + +template +uint16_t gayle_device::ide_cs_r(offs_t offset, uint16_t mem_mask) +{ + return m_ide_cs_r_cb[N]((offset >> 1) & 0x07, mem_mask); +} + +template +void gayle_device::ide_cs_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + m_ide_cs_w_cb[N]((offset >> 1) & 0x07, data, mem_mask); } WRITE_LINE_MEMBER( gayle_device::ide_interrupt_w ) { - if (VERBOSE) - logerror("ide_interrupt_w: %d\n", state); + LOGMASKED(LOG_IDE, "ide_interrupt_w: %d\n", state); + line_change(7, state, 2); +} - // did we change state? - if (BIT(m_gayle_reg[GAYLE_CS], 7) != state) - m_gayle_reg[GAYLE_IRQ] |= 1 << 7; - // set line state - if (state) - m_gayle_reg[GAYLE_CS] |= 1 << 7; - else - m_gayle_reg[GAYLE_CS] &= ~(1 << 7); +//************************************************************************** +// CREDIT CARD +//************************************************************************** + +WRITE_LINE_MEMBER( gayle_device::cc_cd_w ) +{ + LOGMASKED(LOG_CC, "cc_cd_w: %d\n", state); + line_change(LINE_CC_DET, state, 6); +} - // update interrupts - if (BIT(m_gayle_reg[GAYLE_INTEN], 7)) - m_int2_w(BIT(m_gayle_reg[GAYLE_CS], 7)); +WRITE_LINE_MEMBER( gayle_device::cc_bvd1_w ) +{ + LOGMASKED(LOG_CC, "cc_bvd1_w: %d\n", state); + line_change(LINE_CC_BVD1_SC, state, BIT(m_gayle_reg[REG_INT], 1) ? 6 : 2); } +WRITE_LINE_MEMBER( gayle_device::cc_bvd2_w ) +{ + LOGMASKED(LOG_CC, "cc_bvd2_w: %d\n", state); + line_change(LINE_CC_BVD2_DA, state, BIT(m_gayle_reg[REG_INT], 1) ? 6 : 2); +} + +WRITE_LINE_MEMBER( gayle_device::cc_wp_w ) +{ + LOGMASKED(LOG_CC, "cc_wp_w: %d\n", state); + line_change(LINE_CC_WP, state, 2); +} + + +//************************************************************************** +// ID +//************************************************************************** + uint16_t gayle_device::gayle_id_r(offs_t offset, uint16_t mem_mask) { uint16_t data; @@ -189,16 +410,14 @@ uint16_t gayle_device::gayle_id_r(offs_t offset, uint16_t mem_mask) else data = 0xffff; - if (VERBOSE) - logerror("gayle_id_r(%06x): %04x & %04x (id=%02x)\n", offset, data, mem_mask, m_gayle_id); + LOGMASKED(LOG_ID, "gayle_id_r(%06x): %04x & %04x (id=%02x)\n", offset, data, mem_mask, m_gayle_id); return data; } void gayle_device::gayle_id_w(offs_t offset, uint16_t data, uint16_t mem_mask) { - if (VERBOSE) - logerror("gayle_id_w(%06x): %04x & %04x (id=%02x)\n", offset, data, mem_mask, m_gayle_id); + LOGMASKED(LOG_ID, "gayle_id_w(%06x): %04x & %04x (id=%02x)\n", offset, data, mem_mask, m_gayle_id); m_gayle_id_count = 0; } diff --git a/src/devices/machine/gayle.h b/src/devices/machine/gayle.h index c756e6117b7..5701c7f0783 100644 --- a/src/devices/machine/gayle.h +++ b/src/devices/machine/gayle.h @@ -1,11 +1,56 @@ -// license:GPL-2.0+ -// copyright-holders:Dirk Best +// license: GPL-2.0+ +// copyright-holders: Dirk Best /*************************************************************************** GAYLE Gate array used in the Amiga 600 and Amiga 1200 computers. + 84-pin + + 1 PE12 43 A14 + 2 PE5 44 A15 + 3 GND 45 GND + 4 NOISE 46 A16 + 5 CC-RESET 47 A17 + 6 _CC_ENA 48 A18 + 7 _CC_REG 49 A19 + 8 _CC_CEL 50 A20 + 9 _CC_CEU 51 A21 + 10 E 52 A22 + 11 _FLASH 53 A23 + 12 _IDE_IRQ 54 D7 + 13 _IDE_CS1 55 D6 + 14 _IDE_CS2 56 D5 + 15 _SPARE_CS 57 D4 + 16 _NET_CS 58 D3 + 17 _RTC_CS 59 D2 + 18 _IOWR 60 D1 + 19 _IORD 61 D0 + 20 VCC 62 VCC + 21 _ROMEN 63 _KBRESET + 22 C14M 64 DKWEB + 23 CCK 65 DKWDB + 24 GND 66 GND + 25 XRDY 67 MTRON + 26 _OVR 68 MTRX + 27 _OEL 69 DKWE + 28 _OEB 70 _DKWD + 29 _DBR 71 _MTR + 30 _BLS 72 _SEL + 31 _REGEN 73 _ODD_CIA + 32 _RAMEN 74 _EVEN_CIA + 33 _AS 75 _CC_CD1 + 34 _UDS 76 _CC_CD2 + 35 _LDS 77 _CC_BVD1 + 36 R_W 78 _CC_BVD2 + 37 _DTACK 79 CC_WP + 38 _BGACK 80 _CC_BUSY_IREQ + 39 _HLT 81 _WAIT + 40 _RST 82 _BERR + 41 A12 83 _INT6 + 42 A13 84 _INT2 + ***************************************************************************/ #ifndef MAME_MACHINE_GAYLE_H @@ -28,16 +73,21 @@ public: // callbacks auto int2_handler() { return m_int2_w.bind(); } - auto cs0_read_handler() { return m_cs0_read.bind(); } - auto cs0_write_handler() { return m_cs0_write.bind(); } - auto cs1_read_handler() { return m_cs1_read.bind(); } - auto cs1_write_handler() { return m_cs1_write.bind(); } + auto int6_handler() { return m_int6_w.bind(); } + auto rst_handler() { return m_rst_w.bind(); } + template auto ide_cs_r_cb() { return m_ide_cs_r_cb[N].bind(); } + template auto ide_cs_w_cb() { return m_ide_cs_w_cb[N].bind(); } // interface DECLARE_WRITE_LINE_MEMBER( ide_interrupt_w ); - uint16_t gayle_r(offs_t offset, uint16_t mem_mask = ~0); - void gayle_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + // credit card signals + DECLARE_WRITE_LINE_MEMBER( cc_cd_w ); + DECLARE_WRITE_LINE_MEMBER( cc_bvd1_w ); + DECLARE_WRITE_LINE_MEMBER( cc_bvd2_w ); + DECLARE_WRITE_LINE_MEMBER( cc_wp_w ); + + void register_map(address_map &map); uint16_t gayle_id_r(offs_t offset, uint16_t mem_mask = ~0); void gayle_id_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); @@ -49,24 +99,55 @@ protected: virtual void device_reset() override; private: + void dump_register(); + void line_change(int line, int state, int level); + + template uint16_t ide_cs_r(offs_t offset, uint16_t mem_mask); + template void ide_cs_w(offs_t offset, uint16_t data, uint16_t mem_mask); + + uint16_t status_r(); + void status_w(uint16_t data); + uint16_t change_r(); + void change_w(uint16_t data); + uint16_t int_r(); + void int_w(uint16_t data); + uint16_t control_r(); + void control_w(uint16_t data); + enum { - GAYLE_CS = 0, // interrupt status - GAYLE_IRQ, // interrupt change - GAYLE_INTEN, // interrupt enable register - GAYLE_CFG // config register + REG_STATUS = 0, + REG_CHANGE, + REG_INT, + REG_CONTROL + }; + + enum + { + LINE_IDE = 7, + LINE_CC_DET = 6, + LINE_CC_BVD1_SC = 5, + LINE_CC_BVD2_DA = 4, + LINE_CC_WP = 3, + LINE_CC_BUSY_IREQ = 2 }; devcb_write_line m_int2_w; + devcb_write_line m_int6_w; + devcb_write_line m_rst_w; - devcb_read16 m_cs0_read; - devcb_write16 m_cs0_write; - devcb_read16 m_cs1_read; - devcb_write16 m_cs1_write; + devcb_read16::array<2> m_ide_cs_r_cb; + devcb_write16::array<2> m_ide_cs_w_cb; + // gayle id, bitwise readable by the cpu uint8_t m_gayle_id; - int m_gayle_id_count; + uint8_t m_gayle_id_count; + + // gayle register, readable/writeable by the cpu uint8_t m_gayle_reg[4]; + + // internal latched line state + uint8_t m_line_state; }; // device type definition diff --git a/src/devices/machine/linflash.cpp b/src/devices/machine/linflash.cpp index 25b5257dd0b..dcb87a685ba 100644 --- a/src/devices/machine/linflash.cpp +++ b/src/devices/machine/linflash.cpp @@ -21,6 +21,11 @@ void linear_flash_pccard_device::device_start() m_space = &space(0); } +void linear_flash_pccard_device::device_reset() +{ + m_slot->card_detect_w(1); +} + device_memory_interface::space_config_vector linear_flash_pccard_device::memory_space_config() const { return space_config_vector{ std::make_pair(0, &m_space_config) }; diff --git a/src/devices/machine/linflash.h b/src/devices/machine/linflash.h index 20f4559e98d..5cc489af25f 100644 --- a/src/devices/machine/linflash.h +++ b/src/devices/machine/linflash.h @@ -21,6 +21,7 @@ protected: // device-level overrides virtual void device_start() override; + virtual void device_reset() override; // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; diff --git a/src/devices/machine/pccard.cpp b/src/devices/machine/pccard.cpp index 83a05b99421..ff87767dc2d 100644 --- a/src/devices/machine/pccard.cpp +++ b/src/devices/machine/pccard.cpp @@ -7,8 +7,9 @@ #include "logmacro.h" -device_pccard_interface::device_pccard_interface(const machine_config &mconfig, device_t &device) - : device_interface(device, "pccard") +device_pccard_interface::device_pccard_interface(const machine_config &mconfig, device_t &device) : + device_interface(device, "pccard"), + m_slot(dynamic_cast(device.owner())) { } @@ -43,6 +44,10 @@ DEFINE_DEVICE_TYPE(PCCARD_SLOT, pccard_slot_device, "pccard", "PC Card Slot") pccard_slot_device::pccard_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, PCCARD_SLOT, tag, owner, clock), device_single_card_slot_interface(mconfig, *this), + m_card_detect_cb(*this), + m_battery_voltage_1_cb(*this), + m_battery_voltage_2_cb(*this), + m_write_protect_cb(*this), m_pccard(nullptr) { } @@ -50,11 +55,12 @@ pccard_slot_device::pccard_slot_device(const machine_config &mconfig, const char void pccard_slot_device::device_start() { m_pccard = get_card_device(); -} -READ_LINE_MEMBER(pccard_slot_device::read_line_inserted) -{ - return m_pccard ? 1 : 0; + // resolve callbacks + m_card_detect_cb.resolve_safe(); + m_battery_voltage_1_cb.resolve_safe(); + m_battery_voltage_2_cb.resolve_safe(); + m_write_protect_cb.resolve_safe(); } uint16_t pccard_slot_device::read_memory(offs_t offset, uint16_t mem_mask) diff --git a/src/devices/machine/pccard.h b/src/devices/machine/pccard.h index 9e06018f005..7f5b5621da1 100644 --- a/src/devices/machine/pccard.h +++ b/src/devices/machine/pccard.h @@ -5,6 +5,7 @@ #pragma once +class pccard_slot_device; class device_pccard_interface : public device_interface { @@ -18,6 +19,8 @@ public: protected: device_pccard_interface(const machine_config &mconfig, device_t &device); + + pccard_slot_device *const m_slot; }; DECLARE_DEVICE_TYPE(PCCARD_SLOT, pccard_slot_device) @@ -36,16 +39,37 @@ public: } pccard_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - DECLARE_READ_LINE_MEMBER(read_line_inserted); + // callbacks + auto card_detect_cb() { return m_card_detect_cb.bind(); } + auto battery_voltage_1_cb() { return m_battery_voltage_1_cb.bind(); } + auto battery_voltage_2_cb() { return m_battery_voltage_2_cb.bind(); } + auto write_protect_cb() { return m_write_protect_cb.bind(); } + + // called from card device + DECLARE_WRITE_LINE_MEMBER( card_detect_w ) { m_card_detect_cb(state); } + DECLARE_WRITE_LINE_MEMBER( battery_voltage_1_w ) { m_battery_voltage_1_cb(state); } + DECLARE_WRITE_LINE_MEMBER( battery_voltage_2_w ) { m_battery_voltage_2_cb(state); } + DECLARE_WRITE_LINE_MEMBER( write_protect_w ) { m_write_protect_cb(state); } + uint16_t read_memory(offs_t offset, uint16_t mem_mask = ~0); uint16_t read_reg(offs_t offset, uint16_t mem_mask = ~0); void write_memory(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); void write_reg(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint16_t read_memory_swap(offs_t offset, uint16_t mem_mask = 0xffff) { return swapendian_int16(read_memory(offset, swapendian_int16(mem_mask))); } + uint16_t read_reg_swap(offs_t offset, uint16_t mem_mask = 0xffff) { return swapendian_int16(read_reg(offset, swapendian_int16(mem_mask))); } + void write_memory_swap(offs_t offset, uint16_t data, uint16_t mem_mask = 0xffff) { write_memory(offset, swapendian_int16(data), swapendian_int16(mem_mask)); } + void write_reg_swap(offs_t offset, uint16_t data, uint16_t mem_mask = 0xffff) { write_reg(offset, swapendian_int16(data), swapendian_int16(mem_mask)); } + protected: virtual void device_start() override; private: + devcb_write_line m_card_detect_cb; + devcb_write_line m_battery_voltage_1_cb; + devcb_write_line m_battery_voltage_2_cb; + devcb_write_line m_write_protect_cb; + // internal state device_pccard_interface *m_pccard; }; diff --git a/src/devices/machine/pccard_sram.cpp b/src/devices/machine/pccard_sram.cpp new file mode 100644 index 00000000000..317a8979b85 --- /dev/null +++ b/src/devices/machine/pccard_sram.cpp @@ -0,0 +1,288 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + SRAM PC Cards + +***************************************************************************/ + +#include "emu.h" +#include "pccard_sram.h" +#include "machine/nvram.h" + +//#define LOG_GENERAL (1U << 0) +#define LOG_ATTRIBUTE (1U << 1) + +#define VERBOSE (LOG_GENERAL | LOG_ATTRIBUTE) +#include "logmacro.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(PCCARD_SRAM_CENTENNIAL_2M, pccard_centennial_sl02m_15_11194_device, "centennial_sl02m_15_11194", "Centennial 2 MB SRAM") +DEFINE_DEVICE_TYPE(PCCARD_SRAM_CENTENNIAL_4M, pccard_centennial_sl04m_15_11194_device, "centennial_sl04m_15_11194", "Centennial 4 MB SRAM") + +//------------------------------------------------- +// inputs +//------------------------------------------------- + +static INPUT_PORTS_START( card ) + PORT_START("switches") + PORT_DIPNAME(0x01, 0x00, "Battery Failed") PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, pccard_sram_device, battery_voltage_1_w) + PORT_DIPSETTING( 0x01, DEF_STR(Yes)) + PORT_DIPSETTING( 0x00, DEF_STR(No)) + PORT_DIPNAME(0x02, 0x00, "Battery Low") PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, pccard_sram_device, battery_voltage_2_w) + PORT_DIPSETTING( 0x02, DEF_STR(Yes)) + PORT_DIPSETTING( 0x00, DEF_STR(No)) + PORT_DIPNAME(0x04, 0x04, "Write Protect") PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, pccard_sram_device, write_protect_w) + PORT_DIPSETTING( 0x08, DEF_STR(No)) + PORT_DIPSETTING( 0x00, DEF_STR(Yes)) +INPUT_PORTS_END + +ioport_constructor pccard_sram_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(card); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// pccard_sram_device - constructor +//------------------------------------------------- + +pccard_sram_device::pccard_sram_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, type, tag, owner, clock), + device_memory_interface(mconfig, *this), + device_image_interface(mconfig, *this), + device_pccard_interface(mconfig, *this), + m_card_detect(false), + m_switches(*this, "switches") +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void pccard_sram_device::device_start() +{ +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void pccard_sram_device::device_reset() +{ + // forward initial state of battery/write protect to slot + if (m_card_detect) + { + m_slot->battery_voltage_1_w(BIT(m_switches->read(), 0)); + m_slot->battery_voltage_2_w(BIT(m_switches->read(), 1)); + m_slot->write_protect_w(BIT(m_switches->read(), 2)); + } + else + { + m_slot->battery_voltage_1_w(0); + m_slot->battery_voltage_2_w(0); + m_slot->write_protect_w(0); + } +} + +//------------------------------------------------- +// memory_space_config - configure memory space +//------------------------------------------------- + +device_memory_interface::space_config_vector pccard_sram_device::memory_space_config() const +{ + return space_config_vector + { + std::make_pair(0, &m_memory_space_config), + std::make_pair(1, &m_attribute_space_config) + }; +} + +//------------------------------------------------- +// device_pccard_interface +//------------------------------------------------- + +uint16_t pccard_sram_device::read_memory(offs_t offset, uint16_t mem_mask) +{ + uint16_t data = 0xffff; + + if (m_card_detect) + data = space(0).read_word(offset * 2, mem_mask); + + return data; +} + +void pccard_sram_device::write_memory(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + if (m_card_detect && BIT(m_switches->read(), 3)) + space(0).write_word(offset * 2, data, mem_mask); +} + +uint16_t pccard_sram_device::read_reg(offs_t offset, uint16_t mem_mask) +{ + uint16_t data = 0xffff; + + if (m_card_detect) + data = space(1).read_word(offset * 2, mem_mask); + + LOGMASKED(LOG_ATTRIBUTE, "attribute memory r: %06x = %04x & %04x\n", offset, data, mem_mask); + + return data & 0x00ff; +} + +void pccard_sram_device::write_reg(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + LOGMASKED(LOG_ATTRIBUTE, "attribute memory w: %06x = %04x & %04x\n", offset, data, mem_mask); + + if (m_card_detect && BIT(m_switches->read(), 3)) + space(1).write_word(offset * 2, data & 0x00ff, mem_mask); +} + +void pccard_sram_device::card_inserted(bool state) +{ + m_card_detect = state; + m_slot->card_detect_w(state ? 1 : 0); +} + + +/*************************************************************************** + + Centennial SRAM + + SL02M-15-11194: 2 MB SRAM w/ Write Protect - 150 ns Rechargeable Lithium Battery + SL04M-15-11194: 4 MB SRAM w/ Write Protect - 150 ns Rechargeable Lithium Battery + + TODO: + - Get a real EEPROM dump from a factory new card and verify attribute + memory map + - Add more variants + + Notes: + - EEPROM type is probably 28C64A, possible variants with 28C16A + +***************************************************************************/ + +pccard_centennial_sram_device::pccard_centennial_sram_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + pccard_sram_device(mconfig, type, tag, owner, clock), + m_sram(*this, "sram"), + m_eeprom(*this, "eeprom"), + m_eeprom_default(*this, "eeprom") +{ +} + +image_init_result pccard_centennial_sram_device::call_load() +{ + card_inserted(false); + + if (length() != m_sram.bytes() + m_eeprom.bytes()) + return image_init_result::FAIL; + + if (fread(&m_sram[0], m_sram.bytes()) != m_sram.bytes()) + return image_init_result::FAIL; + + if (fread(&m_eeprom[0], m_eeprom.bytes()) != m_eeprom.bytes()) + return image_init_result::FAIL; + + card_inserted(true); + + return image_init_result::PASS; +} + +image_init_result pccard_centennial_sram_device::call_create(int format_type, util::option_resolution *format_options) +{ + card_inserted(false); + + // clear ram + std::fill_n(&m_sram[0], m_sram.length(), 0); + + // initialize eeprom data from default data + std::copy_n(m_eeprom_default->base(), m_eeprom.length(), &m_eeprom[0]); + + if (fwrite(&m_sram[0], m_sram.bytes()) != m_sram.bytes()) + return image_init_result::FAIL; + + if (fwrite(&m_eeprom[0], m_eeprom.bytes()) != m_eeprom.bytes()) + return image_init_result::FAIL; + + card_inserted(true); + + return image_init_result::PASS; +} + +void pccard_centennial_sram_device::call_unload() +{ + if (m_card_detect && !is_readonly()) + { + fseek(0, SEEK_SET); + fwrite(&m_sram[0], m_sram.bytes()); + fwrite(&m_eeprom[0], m_eeprom.bytes()); + } + + std::fill_n(&m_sram[0], m_sram.length(), 0); + std::fill_n(&m_eeprom[0], m_eeprom.length(), 0); + + card_inserted(false); +} + +pccard_centennial_sl02m_15_11194_device::pccard_centennial_sl02m_15_11194_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + pccard_centennial_sram_device(mconfig, PCCARD_SRAM_CENTENNIAL_2M, tag, owner, clock) +{ + m_memory_space_config = address_space_config("memory", ENDIANNESS_LITTLE, 16, 21, 0, address_map_constructor(FUNC(pccard_centennial_sl02m_15_11194_device::memory_map), this)); + m_attribute_space_config = address_space_config("attribute", ENDIANNESS_LITTLE, 16, 14, 0, address_map_constructor(FUNC(pccard_centennial_sl02m_15_11194_device::attribute_map), this)); +} + +void pccard_centennial_sl02m_15_11194_device::memory_map(address_map &map) +{ + map(0x000000, 0x1fffff).ram().share("sram"); +} + +void pccard_centennial_sl02m_15_11194_device::attribute_map(address_map &map) +{ + map(0x00000, 0x03fff).ram().share("eeprom"); +} + +ROM_START( eeprom_02 ) + ROM_REGION(0x2000, "eeprom", 0) + ROM_LOAD("eeprom.bin", 0x0000, 0x2000, BAD_DUMP CRC(0d094f14) SHA1(a542a7395b306b9e34fd0be42d895b7b30013390)) +ROM_END + +const tiny_rom_entry *pccard_centennial_sl02m_15_11194_device::device_rom_region() const +{ + return ROM_NAME( eeprom_02 ); +} + +pccard_centennial_sl04m_15_11194_device::pccard_centennial_sl04m_15_11194_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + pccard_centennial_sram_device(mconfig, PCCARD_SRAM_CENTENNIAL_4M, tag, owner, clock) +{ + m_memory_space_config = address_space_config("memory", ENDIANNESS_LITTLE, 16, 22, 0, address_map_constructor(FUNC(pccard_centennial_sl04m_15_11194_device::memory_map), this)); + m_attribute_space_config = address_space_config("attribute", ENDIANNESS_LITTLE, 16, 14, 0, address_map_constructor(FUNC(pccard_centennial_sl04m_15_11194_device::attribute_map), this)); +} + +void pccard_centennial_sl04m_15_11194_device::memory_map(address_map &map) +{ + map(0x000000, 0x3fffff).ram().share("sram"); +} + +void pccard_centennial_sl04m_15_11194_device::attribute_map(address_map &map) +{ + map(0x00000, 0x03fff).ram().share("eeprom"); +} + +ROM_START( eeprom_04 ) + ROM_REGION(0x2000, "eeprom", 0) + ROM_LOAD("eeprom.bin", 0x0000, 0x2000, BAD_DUMP CRC(ce38fc21) SHA1(155edb39e554cb78547d3b9934a049ee46edc424)) +ROM_END + +const tiny_rom_entry *pccard_centennial_sl04m_15_11194_device::device_rom_region() const +{ + return ROM_NAME( eeprom_04 ); +} diff --git a/src/devices/machine/pccard_sram.h b/src/devices/machine/pccard_sram.h new file mode 100644 index 00000000000..c285e3d6d25 --- /dev/null +++ b/src/devices/machine/pccard_sram.h @@ -0,0 +1,125 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + SRAM PC Cards + +***************************************************************************/ + +#ifndef MAME_MACHINE_PCCARD_SRAM_H +#define MAME_MACHINE_PCCARD_SRAM_H + +#pragma once + +#include "machine/pccard.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> pccard_sram_device + +class pccard_sram_device : + public device_t, + public device_memory_interface, + public device_image_interface, + public device_pccard_interface +{ +public: + void card_detect_w(int state) { m_slot->card_detect_w(state); } + void battery_voltage_1_w(int state) { m_slot->battery_voltage_1_w(state); } + void battery_voltage_2_w(int state) { m_slot->battery_voltage_2_w(state); } + void write_protect_w(int state) { m_slot->write_protect_w(state); } + +protected: + // construction/destruction + pccard_sram_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + // device_t overrides + virtual ioport_constructor device_input_ports() const override; + virtual void device_start() override; + virtual void device_reset() override; + + // device_memory_interface overrides + virtual space_config_vector memory_space_config() const override; + + // device_image_interface overrides + virtual bool is_readable() const noexcept override { return true; } + virtual bool is_writeable() const noexcept override { return true; } + virtual bool is_creatable() const noexcept override { return true; } + virtual bool is_reset_on_load() const noexcept override { return false; } + virtual bool support_command_line_image_creation() const noexcept override { return true; } + virtual char const *file_extensions() const noexcept override { return "bin"; } + virtual const char *image_type_name() const noexcept override { return "sramcard"; } + virtual const char *image_brief_type_name() const noexcept override { return "sram"; } + + // device_pccard_interface overrides + virtual uint16_t read_memory(offs_t offset, uint16_t mem_mask = ~0) override; + virtual uint16_t read_reg(offs_t offset, uint16_t mem_mask = ~0) override; + virtual void write_memory(offs_t offset, uint16_t data, uint16_t mem_mask = ~0) override; + virtual void write_reg(offs_t offset, uint16_t data, uint16_t mem_mask = ~0) override; + + void card_inserted(bool state); + + address_space_config m_memory_space_config; + address_space_config m_attribute_space_config; + + bool m_card_detect; + +private: + required_ioport m_switches; +}; + +class pccard_centennial_sram_device : public pccard_sram_device +{ +protected: + pccard_centennial_sram_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device_image_interface overrides + virtual image_init_result call_load() override; + virtual image_init_result call_create(int format_type, util::option_resolution *format_options) override; + virtual void call_unload() override; + +private: + required_shared_ptr m_sram; + required_shared_ptr m_eeprom; + required_memory_region m_eeprom_default; +}; + +class pccard_centennial_sl02m_15_11194_device : public pccard_centennial_sram_device +{ +public: + // construction/destruction + pccard_centennial_sl02m_15_11194_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + +protected: + // device_t overrides + virtual const tiny_rom_entry *device_rom_region() const override; + +private: + void memory_map(address_map &map); + void attribute_map(address_map &map); +}; + +class pccard_centennial_sl04m_15_11194_device : public pccard_centennial_sram_device +{ +public: + // construction/destruction + pccard_centennial_sl04m_15_11194_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + +protected: + // device_t overrides + virtual const tiny_rom_entry *device_rom_region() const override; + +private: + void memory_map(address_map &map); + void attribute_map(address_map &map); +}; + +// device type definition +DECLARE_DEVICE_TYPE(PCCARD_SRAM_CENTENNIAL_2M, pccard_centennial_sl02m_15_11194_device) +DECLARE_DEVICE_TYPE(PCCARD_SRAM_CENTENNIAL_4M, pccard_centennial_sl04m_15_11194_device) + +#endif // MAME_MACHINE_PCCARD_SRAM_H diff --git a/src/mame/amiga/amiga.cpp b/src/mame/amiga/amiga.cpp index 43223dffce8..a27eba59a03 100644 --- a/src/mame/amiga/amiga.cpp +++ b/src/mame/amiga/amiga.cpp @@ -24,6 +24,8 @@ #include "machine/mos6526.h" #include "machine/gayle.h" #include "machine/dmac.h" +#include "machine/pccard.h" +#include "machine/pccard_sram.h" #include "machine/nvram.h" #include "machine/i2cmem.h" #include "machine/amigafdc.h" @@ -248,6 +250,7 @@ public: void a1000_bootrom_map(address_map &map); void a1000_mem(address_map &map); void a1000_overlay_map(address_map &map); + protected: virtual void machine_start() override; virtual void machine_reset() override; @@ -281,6 +284,7 @@ public: void a2000(machine_config &config); void a2000n(machine_config &config); void a2000_mem(address_map &map); + protected: virtual void machine_reset() override; @@ -317,6 +321,7 @@ public: void a500n(machine_config &config); void a500(machine_config &config); void a500_mem(address_map &map); + protected: virtual void machine_reset() override; @@ -363,6 +368,7 @@ public: void cdtvn(machine_config &config); void cdtv_mem(address_map &map); void cdtv_rc_mem(address_map &map); + protected: // driver_device overrides virtual void machine_start() override; @@ -401,6 +407,7 @@ public: void a3000(machine_config &config); void a3000n(machine_config &config); void a3000_mem(address_map &map); + protected: private: @@ -426,6 +433,7 @@ public: void a500pn(machine_config &config); void a500p(machine_config &config); void a500p_mem(address_map &map); + protected: virtual void machine_reset() override; @@ -448,10 +456,13 @@ class a600_state : public amiga_state public: a600_state(const machine_config &mconfig, device_type type, const char *tag) : amiga_state(mconfig, type, tag) + , m_gayle(*this, "gayle") + , m_pcmcia(*this, "pcmcia") , m_gayle_int2(0) { } DECLARE_WRITE_LINE_MEMBER( gayle_int2_w ); + DECLARE_WRITE_LINE_MEMBER( gayle_int6_w ); void init_pal(); void init_ntsc(); @@ -461,11 +472,18 @@ public: void a600n(machine_config &config); void a600(machine_config &config); void a600_mem(address_map &map); + protected: + // amiga_state overrides virtual bool int2_pending() override; + virtual bool int6_pending() override; private: + required_device m_gayle; + required_device m_pcmcia; + int m_gayle_int2; + int m_gayle_int6; }; class a1200_state : public amiga_state @@ -473,10 +491,13 @@ class a1200_state : public amiga_state public: a1200_state(const machine_config &mconfig, device_type type, const char *tag) : amiga_state(mconfig, type, tag) + , m_gayle(*this, "gayle") + , m_pcmcia(*this, "pcmcia") , m_gayle_int2(0) { } DECLARE_WRITE_LINE_MEMBER( gayle_int2_w ); + DECLARE_WRITE_LINE_MEMBER( gayle_int6_w ); void init_pal(); void init_ntsc(); @@ -486,11 +507,18 @@ public: void a1200(machine_config &config); void a1200n(machine_config &config); void a1200_mem(address_map &map); + protected: + // amiga_state overrides virtual bool int2_pending() override; + virtual bool int6_pending() override; private: + required_device m_gayle; + required_device m_pcmcia; + int m_gayle_int2; + int m_gayle_int6; }; class a4000_state : public amiga_state @@ -526,6 +554,7 @@ public: void a400030_mem(address_map &map); void a4000_mem(address_map &map); void a4000t_mem(address_map &map); + protected: private: @@ -568,6 +597,7 @@ public: void cd32n(machine_config &config); void cd32(machine_config &config); void cd32_mem(address_map &map); + protected: // amiga_state overrides virtual void potgo_w(u16 data) override; @@ -938,23 +968,45 @@ bool a600_state::int2_pending() return m_cia_0_irq || m_gayle_int2; } +bool a600_state::int6_pending() +{ + return m_cia_1_irq || m_gayle_int6; +} + WRITE_LINE_MEMBER( a600_state::gayle_int2_w ) { m_gayle_int2 = state; update_int2(); } +WRITE_LINE_MEMBER( a600_state::gayle_int6_w ) +{ + m_gayle_int6 = state; + update_int6(); +} + bool a1200_state::int2_pending() { return m_cia_0_irq || m_gayle_int2; } +bool a1200_state::int6_pending() +{ + return m_cia_1_irq || m_gayle_int6; +} + WRITE_LINE_MEMBER( a1200_state::gayle_int2_w ) { m_gayle_int2 = state; update_int2(); } +WRITE_LINE_MEMBER( a1200_state::gayle_int6_w ) +{ + m_gayle_int6 = state; + update_int6(); +} + u32 a4000_state::scsi_r(offs_t offset, u32 mem_mask) { u16 data = 0xffff; @@ -1330,7 +1382,12 @@ void a600_state::a600_mem(address_map &map) { map.unmap_value_high(); map(0x000000, 0x1fffff).m(m_overlay, FUNC(address_map_bank_device::amap16)); - map(0x200000, 0xa7ffff).noprw(); + map(0x200000, 0x5fffff).noprw(); + map(0x600000, 0x9fffff).rw(m_pcmcia, FUNC(pccard_slot_device::read_memory_swap), FUNC(pccard_slot_device::write_memory_swap)); + map(0xa00000, 0xa1ffff).rw(m_pcmcia, FUNC(pccard_slot_device::read_reg_swap), FUNC(pccard_slot_device::write_reg_swap)); + //map(0xa20000, 0xa3ffff) credit card i/o + //map(0xa40000, 0xa5ffff) credit card bits + //map(0xa60000, 0xa7ffff) credit card pc i/o map(0xa80000, 0xafffff).nopw().r(FUNC(a600_state::rom_mirror_r)); map(0xb00000, 0xb7ffff).nopw().r(FUNC(a600_state::rom_mirror_r)); map(0xb80000, 0xbeffff).noprw(); // reserved (cdtv) @@ -1338,7 +1395,7 @@ void a600_state::a600_mem(address_map &map) map(0xc00000, 0xd7ffff).noprw(); // slow mem map(0xd80000, 0xd8ffff).noprw(); // spare chip select map(0xd90000, 0xd9ffff).noprw(); // arcnet chip select - map(0xda0000, 0xdaffff).rw("gayle", FUNC(gayle_device::gayle_r), FUNC(gayle_device::gayle_w)); + map(0xda0000, 0xdaffff).m("gayle", FUNC(gayle_device::register_map)); map(0xdb0000, 0xdbffff).noprw(); // reserved (external ide) map(0xdc0000, 0xdcffff).noprw(); // rtc map(0xdd0000, 0xddffff).noprw(); // reserved (dma controller) @@ -1355,7 +1412,12 @@ void a1200_state::a1200_mem(address_map &map) { map.unmap_value_high(); map(0x000000, 0x1fffff).m(m_overlay, FUNC(address_map_bank_device::amap32)); - map(0x200000, 0xa7ffff).noprw(); + map(0x200000, 0x5fffff).noprw(); + map(0x600000, 0x9fffff).rw(m_pcmcia, FUNC(pccard_slot_device::read_memory_swap), FUNC(pccard_slot_device::write_memory_swap)); + map(0xa00000, 0xa1ffff).rw(m_pcmcia, FUNC(pccard_slot_device::read_reg_swap), FUNC(pccard_slot_device::write_reg_swap)); + //map(0xa20000, 0xa3ffff) credit card i/o + //map(0xa40000, 0xa5ffff) credit card bits + //map(0xa60000, 0xa7ffff) credit card pc i/o map(0xa80000, 0xafffff).nopw().r(FUNC(a1200_state::rom_mirror32_r)); map(0xb00000, 0xb7ffff).nopw().r(FUNC(a1200_state::rom_mirror32_r)); map(0xb80000, 0xbeffff).noprw(); // reserved (cdtv) @@ -1363,7 +1425,7 @@ void a1200_state::a1200_mem(address_map &map) map(0xc00000, 0xd7ffff).noprw(); // slow mem map(0xd80000, 0xd8ffff).noprw(); // spare chip select map(0xd90000, 0xd9ffff).noprw(); // arcnet chip select - map(0xda0000, 0xdaffff).rw("gayle", FUNC(gayle_device::gayle_r), FUNC(gayle_device::gayle_w)); + map(0xda0000, 0xdaffff).m("gayle", FUNC(gayle_device::register_map)); map(0xdb0000, 0xdbffff).noprw(); // reserved (external ide) map(0xdc0000, 0xdcffff).noprw(); // rtc map(0xdd0000, 0xddffff).noprw(); // reserved (dma controller) @@ -1560,6 +1622,12 @@ static void amiga_floppies(device_slot_interface &device) device.option_add("35dd", FLOPPY_35_DD); } +static void pcmcia_devices(device_slot_interface &device) +{ + device.option_add("sram_2m", PCCARD_SRAM_CENTENNIAL_2M); + device.option_add("sram_4m", PCCARD_SRAM_CENTENNIAL_4M); +} + // basic elements common to all amigas void amiga_state::amiga_base(machine_config &config) { @@ -1961,15 +2029,21 @@ void a600_state::a600(machine_config &config) gayle_device &gayle(GAYLE(config, "gayle", amiga_state::CLK_28M_PAL / 2)); gayle.set_id(a600_state::GAYLE_ID); gayle.int2_handler().set(FUNC(a600_state::gayle_int2_w)); - gayle.cs0_read_handler().set("ata", FUNC(ata_interface_device::cs0_r)); - gayle.cs0_write_handler().set("ata", FUNC(ata_interface_device::cs0_w)); - gayle.cs1_read_handler().set("ata", FUNC(ata_interface_device::cs1_r)); - gayle.cs1_write_handler().set("ata", FUNC(ata_interface_device::cs1_w)); + gayle.int6_handler().set(FUNC(a600_state::gayle_int6_w)); + gayle.rst_handler().set(FUNC(a600_state::kbreset_w)); // not really kbreset, but use it for now + gayle.ide_cs_r_cb<0>().set("ata", FUNC(ata_interface_device::cs0_swap_r)); + gayle.ide_cs_r_cb<1>().set("ata", FUNC(ata_interface_device::cs1_swap_r)); + gayle.ide_cs_w_cb<0>().set("ata", FUNC(ata_interface_device::cs0_swap_w)); + gayle.ide_cs_w_cb<1>().set("ata", FUNC(ata_interface_device::cs1_swap_w)); ata_interface_device &ata(ATA_INTERFACE(config, "ata").options(ata_devices, "hdd", nullptr, false)); ata.irq_handler().set("gayle", FUNC(gayle_device::ide_interrupt_w)); - // TODO: pcmcia + PCCARD_SLOT(config, m_pcmcia, pcmcia_devices, nullptr); + m_pcmcia->card_detect_cb().set("gayle", FUNC(gayle_device::cc_cd_w)); + m_pcmcia->battery_voltage_1_cb().set("gayle", FUNC(gayle_device::cc_bvd1_w)); + m_pcmcia->battery_voltage_2_cb().set("gayle", FUNC(gayle_device::cc_bvd2_w)); + m_pcmcia->write_protect_cb().set("gayle", FUNC(gayle_device::cc_wp_w)); // software SOFTWARE_LIST(config, "ecs_list").set_original("amigaecs_flop"); @@ -2017,10 +2091,12 @@ void a1200_state::a1200(machine_config &config) gayle_device &gayle(GAYLE(config, "gayle", amiga_state::CLK_28M_PAL / 2)); gayle.set_id(a1200_state::GAYLE_ID); gayle.int2_handler().set(FUNC(a1200_state::gayle_int2_w)); - gayle.cs0_read_handler().set("ata", FUNC(ata_interface_device::cs0_r)); - gayle.cs0_write_handler().set("ata", FUNC(ata_interface_device::cs0_w)); - gayle.cs1_read_handler().set("ata", FUNC(ata_interface_device::cs1_r)); - gayle.cs1_write_handler().set("ata", FUNC(ata_interface_device::cs1_w)); + gayle.int6_handler().set(FUNC(a1200_state::gayle_int6_w)); + gayle.rst_handler().set(FUNC(a1200_state::kbreset_w)); // not really kbreset, but use it for now + gayle.ide_cs_r_cb<0>().set("ata", FUNC(ata_interface_device::cs0_swap_r)); + gayle.ide_cs_r_cb<1>().set("ata", FUNC(ata_interface_device::cs1_swap_r)); + gayle.ide_cs_w_cb<0>().set("ata", FUNC(ata_interface_device::cs0_swap_w)); + gayle.ide_cs_w_cb<1>().set("ata", FUNC(ata_interface_device::cs1_swap_w)); ata_interface_device &ata(ATA_INTERFACE(config, "ata").options(ata_devices, "hdd", nullptr, false)); ata.irq_handler().set("gayle", FUNC(gayle_device::ide_interrupt_w)); @@ -2030,7 +2106,11 @@ void a1200_state::a1200(machine_config &config) subdevice("kbd").set_default_option("a1200_us"); #endif - // TODO: pcmcia + PCCARD_SLOT(config, m_pcmcia, pcmcia_devices, nullptr); + m_pcmcia->card_detect_cb().set("gayle", FUNC(gayle_device::cc_cd_w)); + m_pcmcia->battery_voltage_1_cb().set("gayle", FUNC(gayle_device::cc_bvd1_w)); + m_pcmcia->battery_voltage_2_cb().set("gayle", FUNC(gayle_device::cc_bvd2_w)); + m_pcmcia->write_protect_cb().set("gayle", FUNC(gayle_device::cc_wp_w)); // software SOFTWARE_LIST(config, "aga_list").set_original("amigaaga_flop"); diff --git a/src/mame/amiga/amiga_m.cpp b/src/mame/amiga/amiga_m.cpp index 4ce49219022..1400d89bb9f 100644 --- a/src/mame/amiga/amiga_m.cpp +++ b/src/mame/amiga/amiga_m.cpp @@ -326,13 +326,6 @@ void amiga_state::update_int6() void amiga_state::update_irqs() { - // if the external interrupt line is still active, set the interrupt request bit - if (int2_pending()) - CUSTOM_REG(REG_INTREQ) |= INTENA_PORTS; - - if (int6_pending()) - CUSTOM_REG(REG_INTREQ) |= INTENA_EXTER; - int ints = CUSTOM_REG(REG_INTENA) & CUSTOM_REG(REG_INTREQ); // master interrupt switch @@ -354,6 +347,13 @@ void amiga_state::update_irqs() m_maincpu->set_input_line(5, CLEAR_LINE); m_maincpu->set_input_line(6, CLEAR_LINE); } + + // int 2 and 6 are level triggered + if (int2_pending()) + CUSTOM_REG(REG_INTREQ) |= INTENA_PORTS; + + if (int6_pending()) + CUSTOM_REG(REG_INTREQ) |= INTENA_EXTER; } TIMER_CALLBACK_MEMBER( amiga_state::amiga_irq_proc ) diff --git a/src/mame/konami/ksys573.cpp b/src/mame/konami/ksys573.cpp index 42f215c6c93..acc3986a3e4 100644 --- a/src/mame/konami/ksys573.cpp +++ b/src/mame/konami/ksys573.cpp @@ -622,6 +622,8 @@ public: DECLARE_READ_LINE_MEMBER( h8_d2_r ); DECLARE_READ_LINE_MEMBER( h8_d3_r ); + template DECLARE_READ_LINE_MEMBER( pccard_cd_r ); + DECLARE_WRITE_LINE_MEMBER( gtrfrks_lamps_b7 ); DECLARE_WRITE_LINE_MEMBER( gtrfrks_lamps_b6 ); DECLARE_WRITE_LINE_MEMBER( gtrfrks_lamps_b5 ); @@ -738,6 +740,8 @@ private: int m_atapi_xferbase; int m_atapi_xfersize; + int m_pccard_cd[2]; + uint32_t m_control; uint16_t m_n_security_control; @@ -1166,6 +1170,12 @@ void ksys573_state::update_disc() } } +template +READ_LINE_MEMBER( ksys573_state::pccard_cd_r ) +{ + return m_pccard_cd[N]; +} + void ksys573_state::driver_start() { m_atapi_timer = timer_alloc( FUNC( ksys573_state::atapi_xfer_end ), this ); @@ -1179,6 +1189,7 @@ void ksys573_state::driver_start() save_item( NAME( m_n_security_control ) ); save_item( NAME( m_control ) ); + save_item( NAME( m_pccard_cd ) ); m_h8_index = 0; } @@ -2520,7 +2531,10 @@ void ksys573_state::konami573(machine_config &config) FUJITSU_29F016A(config, "29f016a.27h"); PCCARD_SLOT(config, m_pccard1, 0); + m_pccard1->card_detect_cb().set([this](int state) { m_pccard_cd[0] = state; }); + PCCARD_SLOT(config, m_pccard2, 0); + m_pccard2->card_detect_cb().set([this](int state) { m_pccard_cd[1] = state; }); ADDRESS_MAP_BANK(config, m_flashbank ).set_map( &ksys573_state::flashbank_map ).set_options( ENDIANNESS_LITTLE, 16, 32, 0x400000); @@ -3116,8 +3130,8 @@ static INPUT_PORTS_START( konami573 ) // PORT_BIT( 0x00800000, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x01000000, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_BIT( 0x02000000, IP_ACTIVE_LOW, IPT_COIN2 ) - PORT_BIT( 0x04000000, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER( "pccard1", pccard_slot_device, read_line_inserted ) - PORT_BIT( 0x08000000, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER( "pccard2", pccard_slot_device, read_line_inserted ) + PORT_BIT( 0x04000000, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER( DEVICE_SELF, ksys573_state, pccard_cd_r<0> ) + PORT_BIT( 0x08000000, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER( DEVICE_SELF, ksys573_state, pccard_cd_r<1> ) PORT_BIT( 0x10000000, IP_ACTIVE_LOW, IPT_SERVICE1 ) // PORT_BIT( 0x20000000, IP_ACTIVE_LOW, IPT_UNKNOWN ) // PORT_BIT( 0x40000000, IP_ACTIVE_LOW, IPT_UNKNOWN ) -- cgit v1.2.3