summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author angelosa <lordkale4@gmail.com>2025-12-01 13:08:05 +0100
committer angelosa <lordkale4@gmail.com>2025-12-01 13:08:12 +0100
commite53a4fc1f8d2922b50417f59313011bb6f5ebed9 (patch)
tree8f012d67401eb6dd9208326a3334507a169d5cb8
parentc5e10711b0fac71ce1921a56cf24cd7317f690ae (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.cpp103
-rw-r--r--src/devices/bus/pc98_cbus/lha201.h10
-rw-r--r--src/devices/bus/pc98_cbus/pc9801_55.cpp21
-rw-r--r--src/devices/bus/pc98_cbus/pc9801_55.h7
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;
};