diff options
| author | 2025-12-01 13:08:05 +0100 | |
|---|---|---|
| committer | 2025-12-01 13:08:12 +0100 | |
| commit | e53a4fc1f8d2922b50417f59313011bb6f5ebed9 (patch) | |
| tree | 8f012d67401eb6dd9208326a3334507a169d5cb8 | |
| parent | c5e10711b0fac71ce1921a56cf24cd7317f690ae (diff) | |
bus/pc98_cbus/lha201.cpp: add enough remapping so it can coexist with base IDE BIOS
| -rw-r--r-- | src/devices/bus/pc98_cbus/lha201.cpp | 103 | ||||
| -rw-r--r-- | src/devices/bus/pc98_cbus/lha201.h | 10 | ||||
| -rw-r--r-- | src/devices/bus/pc98_cbus/pc9801_55.cpp | 21 | ||||
| -rw-r--r-- | src/devices/bus/pc98_cbus/pc9801_55.h | 7 |
4 files changed, 95 insertions, 46 deletions
diff --git a/src/devices/bus/pc98_cbus/lha201.cpp b/src/devices/bus/pc98_cbus/lha201.cpp index d65074bbd83..75a80df6129 100644 --- a/src/devices/bus/pc98_cbus/lha201.cpp +++ b/src/devices/bus/pc98_cbus/lha201.cpp @@ -6,10 +6,22 @@ Logitec LHA-201/20B SCSI-2 PC-9801-92 derived? +https://98epjunk.shakunage.net/sw/ext_card/ext_card_doc/lha201.txt +Maximum -chs 13329,15,63 according to link above (for LHA-20B BIOS, TBD for LHA-201) + TODO: -- currently keeps pinging port 30 reset line; -- stuck at "Negate ACK" just like base devices; -- PnP; +- stuck at "Negate ACK" just like base devices (cfr. issue #14532); +- Can't IPL boot as standalone (requires a bootable IDE BIOS and moving of ROM window here), + uses SC_MODE_SENSE_6 pages 0xc3 and 0xc4, then SC_READ_CAPACITY, finally keeps SC_TEST_UNIT_READY + -> SC_REQUEST_SENSE with length = 0x16 trimmed internally with 18 (?). + What it reads comes from initial device_reset sense request. +- Need data throttle between here, wd33c9x and/or NSCSI harddisk, otherwise executing anything will + fail; +- PIO mode (involves port $cc6 and a ready flag in port $37 bit 0) +- Tends to miss BIOS ROM loading at first boot, need to refactor C-Bus to actually have slots + as children (and make remapping phase less arbitrary, can't read required input port at + device_start); +- Remaining remap options; **************************************************************************************************/ @@ -27,7 +39,7 @@ lha201_device::lha201_device(const machine_config &mconfig, const char *tag, dev ROM_START( lha201 ) ROM_REGION16_LE( 0x10000, "bios", ROMREGION_ERASEFF ) - ROM_LOAD("lha201-20b.ic3", 0x0000, 0x8000, CRC(a5995180) SHA1(4316fd50ce03d1b8f522327c8caa79edc88ac55a) ) + ROM_LOAD("lha-201_ver1.33.ic3", 0x0000, 0x8000, CRC(a5995180) SHA1(4316fd50ce03d1b8f522327c8caa79edc88ac55a) ) ROM_END const tiny_rom_entry *lha201_device::device_rom_region() const @@ -45,7 +57,8 @@ void lha201_device::device_add_mconfig(machine_config &config) { wd33c9x_base_device &adapter = downcast<wd33c9x_base_device &>(*device); - adapter.set_clock(20'000'000); + // FIXME: check frequency select in wd core + adapter.set_clock(20'000'000 / 4); adapter.irq_cb().set(*this, FUNC(lha201_device::scsi_irq_w)); adapter.drq_cb().set(*this, FUNC(lha201_device::scsi_drq_w)); } @@ -111,8 +124,7 @@ static INPUT_PORTS_START( lha201 ) PORT_DIPSETTING( 0x01, "0xcd0") PORT_DIPSETTING( 0x02, "0xce0") PORT_DIPSETTING( 0x03, "0xcf0") - // TODO: default is bus master - PORT_DIPNAME( 0x04, 0x04, "LHA-201: Transfer mode setting") PORT_DIPLOCATION("SCSI_SW3:!3") + PORT_DIPNAME( 0x04, 0x00, "LHA-201: Transfer mode setting") PORT_DIPLOCATION("SCSI_SW3:!3") PORT_DIPSETTING( 0x00, "Automatic selection (bus master)" ) PORT_DIPSETTING( 0x04, "I/O transfer fixed") // following are all "system use" @@ -151,11 +163,8 @@ ioport_constructor lha201_device::device_input_ports() const void lha201_device::device_start() { pc9801_55_device::device_start(); -// save_item(NAME(m_ar)); -// save_item(NAME(m_port30)); -// save_item(NAME(m_rom_bank)); -// save_item(NAME(m_pkg_id)); -// save_item(NAME(m_dma_enable)); + save_item(NAME(m_port34)); + save_item(NAME(m_port36)); m_bus->set_dma_channel(0, this, false); } @@ -168,36 +177,62 @@ void lha201_device::device_start() void lha201_device::device_reset() { pc9801_55_device::device_reset(); + // TODO: INT5/INT6 + m_int_line = (m_dsw1->read() & 0x18) >> 3; + m_port34 = 0; + m_port36 = 0; } -//void lha201_device::remap(int space_id, offs_t start, offs_t end) -//{ -// if (space_id == AS_PROGRAM) -// { -// logerror("map ROM at 0x000dc000-0x000dcfff (bank %d)\n", m_rom_bank); -// m_bus->space(AS_PROGRAM).install_rom( -// 0xdc000, -// 0xdcfff, -// m_bios->base() + m_rom_bank * 0x1000 -// ); -// } -// else if (space_id == AS_IO) -// { -// m_bus->install_device(0x0000, 0x3fff, *this, &lha201_device::io_map); -// } -//} -// -//void lha201_device::io_map(address_map &map) -//{ -// // ... -//} +void lha201_device::remap(int space_id, offs_t start, offs_t end) +{ + if (space_id == AS_PROGRAM) + { + const u32 m_memory_base = 0x000d0000 + ((m_dsw2->read() & 7) * 0x2000); + m_bus->space(AS_PROGRAM).install_rom( + m_memory_base, + m_memory_base + 0xfff, + m_bios->base() + m_rom_bank * 0x1000 + ); + } + else if (space_id == AS_IO) + { + m_bus->install_device(0x0000, 0x3fff, *this, &lha201_device::io_map); + } +} + +void lha201_device::io_map(address_map &map) +{ + pc9801_55_device::io_map(map); +// 0xcc6 direct FIFO read/write in PIO mode +} void lha201_device::internal_map(address_map &map) { pc9801_55_device::internal_map(map); - // 0x36 <unknown> + + // FIFO int guard on NEC, unknown here + map(0x34, 0x34).lrw8( + NAME([this] (offs_t offset) { + return m_port34; + }), + NAME([this] (offs_t offset, u8 data) { + logerror("Port $34 write %02x\n", data); + m_port34 = data; + }) + ); + // unknown + map(0x36, 0x36).lrw8( + NAME([this] (offs_t offset) { + return m_port36; + }), + NAME([this] (offs_t offset, u8 data) { + logerror("Port $36 write %02x\n", data); + m_port36 = data; + }) + ); map(0x37, 0x37).lr8( NAME([this] (offs_t offset) { + // TODO: not all of it, bit 0 at least is for a status ready in PIO mode (FFE?) return m_dsw3->read(); }) ); diff --git a/src/devices/bus/pc98_cbus/lha201.h b/src/devices/bus/pc98_cbus/lha201.h index 30df65f491e..7b7544d114e 100644 --- a/src/devices/bus/pc98_cbus/lha201.h +++ b/src/devices/bus/pc98_cbus/lha201.h @@ -21,20 +21,24 @@ public: static constexpr feature_type unemulated_features() { return feature::DISK; } protected: -// virtual void device_validity_check(validity_checker &valid) const override; +// virtual void device_validity_check(validity_checker &valid) const override; virtual void device_start() override ATTR_COLD; virtual void device_reset() override ATTR_COLD; virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; virtual ioport_constructor device_input_ports() const override ATTR_COLD; virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; -// virtual space_config_vector memory_space_config() const override; -// virtual void remap(int space_id, offs_t start, offs_t end) override; +// virtual space_config_vector memory_space_config() const override; + virtual void remap(int space_id, offs_t start, offs_t end) override; virtual void internal_map(address_map &map) override ATTR_COLD; + virtual void io_map(address_map &map) override ATTR_COLD; private: required_ioport m_dsw3; + + u8 m_port34; + u8 m_port36; }; DECLARE_DEVICE_TYPE(LHA201, lha201_device) diff --git a/src/devices/bus/pc98_cbus/pc9801_55.cpp b/src/devices/bus/pc98_cbus/pc9801_55.cpp index a5017bbd93d..3d940c2cb73 100644 --- a/src/devices/bus/pc98_cbus/pc9801_55.cpp +++ b/src/devices/bus/pc98_cbus/pc9801_55.cpp @@ -10,7 +10,7 @@ HDDs apparently needs to be with 8 heads and 25 cylinders only https://www7b.biglobe.ne.jp/~drachen6jp/98scsi.html TODO: -- hangs on wdc core with a Negate ACK command when not initiator; +- hangs on wdc core with a Negate ACK command when not initiator (cfr. issue #14532); - Wants to read "NEC" around PC=dc632, currently reads " SE" (from nscsi/hd.cpp " SEAGATE" inquiry) \- Wants specifically -ss 256 in chdman, DOS will throw a "run-time error R6003 otherwise". \- Should really require a nscsi/hd.cpp subclass, seems to detect 130 MB hdd from mode sense 6 pages @@ -84,7 +84,7 @@ const tiny_rom_entry *pc9801_55l_device::device_rom_region() const void pc9801_55_device::scsi_irq_w(int state) { - m_bus->int_w(3, BIT(m_port30, 2) && state); + m_bus->int_w(m_int_line, BIT(m_port30, 2) && state); } void pc9801_55_device::scsi_drq_w(int state) @@ -214,6 +214,8 @@ void pc9801_55_device::device_start() void pc9801_55_device::device_reset() { + m_int_line = 3; + m_rom_bank = 0; m_pkg_id = 0xfd; @@ -226,6 +228,7 @@ void pc9801_55_device::remap(int space_id, offs_t start, offs_t end) { if (space_id == AS_PROGRAM) { + // incredibly verbose for LHA-201 // logerror("map ROM at 0x000dc000-0x000dcfff (bank %d)\n", m_rom_bank); m_bus->space(AS_PROGRAM).install_rom( 0xdc000, @@ -240,7 +243,7 @@ void pc9801_55_device::remap(int space_id, offs_t start, offs_t end) } // required by MS-DOS to actually detect the disk size for format. -// Mimic wdc33c9x core here +// Mimic wd33c9x core here void pc9801_55_device::increment_addr() { if (machine().side_effects_disabled()) return; @@ -298,14 +301,20 @@ void pc9801_55_device::internal_map(address_map &map) // xx-- ---- ROM bank // ---- x--- MEM1 allow memory access (DMA?) // ---- -x-- IRE1 allow interrupts - // ---- --x- WRS1 SCSI bus RST (active low) + // ---- --x- WRS1 SCSI bus RST (1 -> 0) map(0x30, 0x30).lrw8( NAME([this] (offs_t offset) { return m_port30; }), NAME([this] (offs_t offset, u8 data) { - // logerror("$30 Memory Bank %02x\n", data); - m_wdc->reset_w(!BIT(data, 1)); + if ((m_port30 & 0x3f) != (data & 0x3f)) + logerror("$30 Memory Bank %02x\n", data); + + if (BIT(m_port30, 1) && !(BIT(data, 1))) + { + m_wdc->reset_w(1); + m_wdc->reset_w(0); + } if ((data & 0xc0) != (m_port30 & 0xc0)) { diff --git a/src/devices/bus/pc98_cbus/pc9801_55.h b/src/devices/bus/pc98_cbus/pc9801_55.h index 142bc998dae..692565666bf 100644 --- a/src/devices/bus/pc98_cbus/pc9801_55.h +++ b/src/devices/bus/pc98_cbus/pc9801_55.h @@ -51,23 +51,24 @@ protected: virtual void dack_w(int line, u8 data) override; virtual void internal_map(address_map &map) ATTR_COLD; + virtual void io_map(address_map &map) ATTR_COLD; address_space_config m_space_io_config; -private: required_device<nscsi_bus_device> m_scsi_bus; required_device<wd33c9x_base_device> m_wdc; required_memory_region m_bios; required_ioport m_dsw1; required_ioport m_dsw2; - void io_map(address_map &map) ATTR_COLD; + u8 m_rom_bank; + int m_int_line; +private: void increment_addr(); u8 m_ar; u8 m_port30; u8 m_pkg_id; - u8 m_rom_bank; bool m_dma_enable; }; |
