Skip to content

Commit 58eaf9a

Browse files
committed
amiga/zorro: Add Zorro III DMA support and the A4091 SCSI Host Adapter
Firmware images provided by The Zone! on EAB. New working software list items ------------------------------- A4091 Install Disk (SetPatch 40.2) [Amiga Hardware Database] A4091 Install Disk (SetPatch 40.14) [Amiga Hardware Database] AI disclosure: gpt-5.6-sol was used as a research and debugging tool.
1 parent 57c909b commit 58eaf9a

9 files changed

Lines changed: 424 additions & 3 deletions

File tree

hash/amiga_hardware.xml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,30 @@ license:CC0-1.0
177177
</part>
178178
</software>
179179

180+
<!-- A4091Setup 40.8, 68040.library 37.30, SetPatch 40.2, Format 40.1, HDToolBox 40.3 -->
181+
<software name="a4091_4002">
182+
<description>A4091 Install Disk (SetPatch 40.2)</description>
183+
<year>1993</year>
184+
<publisher>Commodore</publisher>
185+
<part name="flop1" interface="floppy_3_5">
186+
<dataarea name="flop" size="901120">
187+
<rom name="a4091_4002.adf" size="901120" crc="41debbf7" sha1="6d156a4fecbf9692b310bfaba991d02705ba045d" />
188+
</dataarea>
189+
</part>
190+
</software>
191+
192+
<!-- A4091Setup 40.8, 68040.library 37.30, SetPatch 40.14, Format 40.2, HDToolBox 40.3 -->
193+
<software name="a4091_4014" cloneof="a4091_4002">
194+
<description>A4091 Install Disk (SetPatch 40.14)</description>
195+
<year>1993</year>
196+
<publisher>Commodore</publisher>
197+
<part name="flop1" interface="floppy_3_5">
198+
<dataarea name="flop" size="901120">
199+
<rom name="a4091_4014.adf" size="901120" crc="f962885b" sha1="3387a4f8062d0f61a12ea10d54de20f378e2b2c9" />
200+
</dataarea>
201+
</part>
202+
</software>
203+
180204
<software name="bscscsi13">
181205
<description>bsc SCSI Installation Disk Version 1.3</description>
182206
<year>1992</year>

scripts/src/bus.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,8 @@ if BUSES["AMIGA_ZORRO"] then
586586
MAME_DIR .. "src/devices/bus/amiga/zorro/a2091.h",
587587
MAME_DIR .. "src/devices/bus/amiga/zorro/a2232.cpp",
588588
MAME_DIR .. "src/devices/bus/amiga/zorro/a2232.h",
589+
MAME_DIR .. "src/devices/bus/amiga/zorro/a4091.cpp",
590+
MAME_DIR .. "src/devices/bus/amiga/zorro/a4091.h",
589591
MAME_DIR .. "src/devices/bus/amiga/zorro/adscsi.cpp",
590592
MAME_DIR .. "src/devices/bus/amiga/zorro/adscsi.h",
591593
MAME_DIR .. "src/devices/bus/amiga/zorro/buddha.cpp",
Lines changed: 320 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
// license: GPL-2.0+
2+
// copyright-holders: Dirk Best
3+
/***************************************************************************
4+
5+
Commodore/DKB A4091
6+
7+
Zorro III SCSI host adapter based on the NCR 53C710
8+
9+
Hardware:
10+
- NCR 53C710 SCSI I/O processor
11+
- 50 MHz XTAL
12+
- Internal and external SCSI-2 connectors
13+
- 32 KiB boot ROM
14+
15+
Notes:
16+
- Also sold by DKB in license
17+
18+
TODO:
19+
- Map dip switch ID to actually used ID
20+
21+
***************************************************************************/
22+
23+
#include "emu.h"
24+
#include "a4091.h"
25+
26+
#include "bus/nscsi/devices.h"
27+
#include "machine/53c7xx.h"
28+
#include "machine/nscsi_bus.h"
29+
30+
#define VERBOSE (LOG_GENERAL)
31+
#include "logmacro.h"
32+
33+
34+
namespace bus::amiga::zorro {
35+
36+
37+
class a4091_device : public device_t, public device_zorro3_card_interface
38+
{
39+
public:
40+
a4091_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
41+
42+
protected:
43+
// device_t overrides
44+
virtual void device_start() override ATTR_COLD;
45+
virtual ioport_constructor device_input_ports() const override ATTR_COLD;
46+
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
47+
virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
48+
49+
// device_zorro2_card_interface overrides
50+
virtual void busrst_w(int state) override;
51+
virtual void cfgin_w(int state) override;
52+
53+
private:
54+
static constexpr uint32_t BOARD_SIZE = 0x01000000;
55+
56+
void mmio_map(address_map &map) ATTR_COLD;
57+
58+
uint8_t dips_r();
59+
60+
uint32_t autoconfig_r(offs_t offset, uint32_t mem_mask);
61+
void autoconfig_w(offs_t offset, uint32_t data, uint32_t mem_mask);
62+
void autoconfig_base_address(offs_t address);
63+
64+
uint32_t rom_r(offs_t offset);
65+
uint32_t dma_r(offs_t offset, uint32_t mem_mask);
66+
void dma_w(offs_t offset, uint32_t data, uint32_t mem_mask);
67+
68+
required_device<nscsi_bus_device> m_scsi;
69+
required_device<ncr53c710_device> m_ncr;
70+
required_region_ptr<uint8_t> m_rom;
71+
required_ioport m_dips;
72+
73+
uint32_t m_base_address = 0;
74+
uint32_t m_autoconfig_address = 0;
75+
};
76+
77+
a4091_device::a4091_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
78+
device_t(mconfig, AMIGA_A4091, tag, owner, clock),
79+
device_zorro3_card_interface(mconfig, *this),
80+
m_scsi(*this, "scsi"),
81+
m_ncr(*this, "ncr"),
82+
m_rom(*this, "rom"),
83+
m_dips(*this, "dips")
84+
{
85+
}
86+
87+
88+
//**************************************************************************
89+
// ADDRESS MAPS
90+
//**************************************************************************
91+
92+
void a4091_device::mmio_map(address_map &map)
93+
{
94+
map(0x000000, 0x03ffff).mirror(0x7c0000).r(FUNC(a4091_device::rom_r));
95+
map(0x800000, 0x80003f).mirror(0x07ffc0).rw(m_ncr, FUNC(ncr53c710_device::read), FUNC(ncr53c710_device::write));
96+
map(0x8c0000, 0x8c0003).r(FUNC(a4091_device::dips_r)).umask32(0x000000ff);
97+
}
98+
99+
100+
//**************************************************************************
101+
// INPUT DEFINITIONS
102+
//**************************************************************************
103+
104+
static INPUT_PORTS_START( a4091 )
105+
PORT_START("dips")
106+
PORT_DIPNAME(0x07, 0x07, "SCSI Address") PORT_DIPLOCATION("DIP:1,2,3")
107+
PORT_DIPSETTING(0x00, "0")
108+
PORT_DIPSETTING(0x01, "1")
109+
PORT_DIPSETTING(0x02, "2")
110+
PORT_DIPSETTING(0x03, "3")
111+
PORT_DIPSETTING(0x04, "4")
112+
PORT_DIPSETTING(0x05, "5")
113+
PORT_DIPSETTING(0x06, "6")
114+
PORT_DIPSETTING(0x07, "7")
115+
PORT_DIPNAME(0x08, 0x08, "SCSI Fast Bus") PORT_DIPLOCATION("DIP:4")
116+
PORT_DIPSETTING(0x08, DEF_STR( Off ))
117+
PORT_DIPSETTING(0x00, DEF_STR( On ))
118+
PORT_DIPNAME(0x10, 0x10, "Short/Long Spinup") PORT_DIPLOCATION("DIP:5")
119+
PORT_DIPSETTING(0x10, DEF_STR( Off ))
120+
PORT_DIPSETTING(0x00, DEF_STR( On ))
121+
PORT_DIPNAME(0x20, 0x20, "Synchronous Mode") PORT_DIPLOCATION("DIP:6")
122+
PORT_DIPSETTING(0x20, DEF_STR( Off ))
123+
PORT_DIPSETTING(0x00, DEF_STR( On ))
124+
PORT_DIPNAME(0x40, 0x40, "External SCSI Termination") PORT_DIPLOCATION("DIP:7")
125+
PORT_DIPSETTING(0x40, DEF_STR( Off ))
126+
PORT_DIPSETTING(0x00, DEF_STR( On ))
127+
PORT_DIPNAME(0x80, 0x80, "Logical Unit (LUN) Enable") PORT_DIPLOCATION("DIP:8")
128+
PORT_DIPSETTING(0x80, DEF_STR( Off ))
129+
PORT_DIPSETTING(0x00, DEF_STR( On ))
130+
INPUT_PORTS_END
131+
132+
ioport_constructor a4091_device::device_input_ports() const
133+
{
134+
return INPUT_PORTS_NAME( a4091 );
135+
}
136+
137+
uint8_t a4091_device::dips_r()
138+
{
139+
return m_dips->read();
140+
}
141+
142+
143+
//**************************************************************************
144+
// ZORRO / AUTOCONFIG
145+
//**************************************************************************
146+
147+
void a4091_device::busrst_w(int state)
148+
{
149+
if (state)
150+
return;
151+
152+
int2_w(0);
153+
m_ncr->reset();
154+
155+
if (m_base_address)
156+
zorro3_space().unmap_readwrite(m_base_address, m_base_address + BOARD_SIZE - 1);
157+
158+
m_base_address = 0;
159+
m_autoconfig_address = 0;
160+
}
161+
162+
void a4091_device::cfgin_w(int state)
163+
{
164+
LOG("cfgin_w (%d)\n", state);
165+
166+
if (state)
167+
return;
168+
169+
// the autoconfig nibbles are stored in the boot ROM
170+
zorro3_space().install_readwrite_handler(0xff000000, 0xff00ffff,
171+
read32s_delegate(*this, FUNC(a4091_device::autoconfig_r)),
172+
write32s_delegate(*this, FUNC(a4091_device::autoconfig_w)), 0xffffffff);
173+
}
174+
175+
uint32_t a4091_device::autoconfig_r(offs_t offset, uint32_t mem_mask)
176+
{
177+
uint32_t const data = (uint32_t(m_rom[offset] | 0x0f) << 24) | 0x00ffffff;
178+
179+
if (!machine().side_effects_disabled())
180+
LOG("autoconfig_r: %08x @ %04x [mask = %08x]\n", data, uint32_t(offset << 2), mem_mask);
181+
182+
return data;
183+
}
184+
185+
void a4091_device::autoconfig_w(offs_t offset, uint32_t data, uint32_t mem_mask)
186+
{
187+
uint32_t const reg = offset << 2;
188+
189+
LOG("autoconfig_w: %08x @ %04x [mask = %08x]\n", data, reg, mem_mask);
190+
191+
switch (reg)
192+
{
193+
case 0x44:
194+
if (ACCESSING_BITS_24_31)
195+
m_autoconfig_address = (m_autoconfig_address & 0x00ffffff) | (data & 0xff000000);
196+
if (ACCESSING_BITS_16_23)
197+
m_autoconfig_address = (m_autoconfig_address & 0xff00ffff) | (data & 0x00ff0000);
198+
199+
// a write to the high byte completes the configuration
200+
if (ACCESSING_BITS_24_31)
201+
autoconfig_base_address(m_autoconfig_address);
202+
break;
203+
204+
case 0x48:
205+
if (ACCESSING_BITS_24_31)
206+
m_autoconfig_address = (m_autoconfig_address & 0xff00ffff) | ((data >> 8) & 0x00ff0000);
207+
break;
208+
209+
case 0x4c:
210+
if (ACCESSING_BITS_24_31)
211+
autoconfig_base_address(0);
212+
break;
213+
}
214+
}
215+
216+
void a4091_device::autoconfig_base_address(offs_t address)
217+
{
218+
LOG("Autoconfig address received: 0x%08x\n", uint32_t(address));
219+
220+
// stop responding to default autoconfig
221+
zorro3_space().unmap_readwrite(0xff000000, 0xff00ffff);
222+
223+
m_base_address = address;
224+
225+
// install the board if we have a valid address
226+
if (m_base_address)
227+
zorro3_space().install_device(m_base_address, m_base_address + BOARD_SIZE - 1, *this, &a4091_device::mmio_map);
228+
229+
// we're done
230+
cfgout_w(0);
231+
}
232+
233+
234+
//**************************************************************************
235+
// MACHINE EMULATION
236+
//**************************************************************************
237+
238+
uint32_t a4091_device::rom_r(offs_t offset)
239+
{
240+
// each rom byte is presented as two nibbles on alternate byte lanes
241+
uint8_t const high = m_rom[offset] | 0x0f;
242+
uint8_t const low = (m_rom[offset] << 4) | 0x0f;
243+
244+
return (uint32_t(high) << 24) | 0x00ff0000 | (uint32_t(low) << 8) | 0x000000ff;
245+
}
246+
247+
uint32_t a4091_device::dma_r(offs_t offset, uint32_t mem_mask)
248+
{
249+
return zorro3_dma_r(offset, mem_mask);
250+
}
251+
252+
void a4091_device::dma_w(offs_t offset, uint32_t data, uint32_t mem_mask)
253+
{
254+
zorro3_dma_w(offset, data, mem_mask);
255+
}
256+
257+
void a4091_device::device_start()
258+
{
259+
save_item(NAME(m_base_address));
260+
save_item(NAME(m_autoconfig_address));
261+
}
262+
263+
264+
//**************************************************************************
265+
// MACHINE DEFINITIONS
266+
//**************************************************************************
267+
268+
void a4091_device::device_add_mconfig(machine_config &config)
269+
{
270+
NCR53C710(config, m_ncr, 50_MHz_XTAL);
271+
m_ncr->irq_handler().set([this](int state) { int2_w(state); });
272+
m_ncr->big_lit_handler().set_constant(1);
273+
m_ncr->host_read().set(FUNC(a4091_device::dma_r));
274+
m_ncr->host_write().set(FUNC(a4091_device::dma_w));
275+
276+
NSCSI_BUS(config, m_scsi);
277+
NSCSI_CONNECTOR(config, "scsi:0", default_scsi_devices, "harddisk");
278+
NSCSI_CONNECTOR(config, "scsi:1", default_scsi_devices, nullptr);
279+
NSCSI_CONNECTOR(config, "scsi:2", default_scsi_devices, nullptr);
280+
NSCSI_CONNECTOR(config, "scsi:3", default_scsi_devices, nullptr);
281+
NSCSI_CONNECTOR(config, "scsi:4", default_scsi_devices, nullptr);
282+
NSCSI_CONNECTOR(config, "scsi:5", default_scsi_devices, nullptr);
283+
NSCSI_CONNECTOR(config, "scsi:6", default_scsi_devices, nullptr);
284+
m_scsi->set_external_device(7, m_ncr);
285+
}
286+
287+
288+
//**************************************************************************
289+
// ROM DEFINITIONS
290+
//**************************************************************************
291+
292+
ROM_START( a4091 )
293+
ROM_REGION(0x10000, "rom", 0)
294+
ROM_DEFAULT_BIOS("v4013")
295+
296+
ROM_SYSTEM_BIOS(0, "v404", "v40.4")
297+
ROMX_LOAD("a4091_v404.u206", 0x0000, 0x8000, CRC(9ba7e7dc) SHA1(18985b7ec95239da21a242a4fc42f13496434534), ROM_BIOS(0))
298+
ROM_RELOAD( 0x8000, 0x8000)
299+
ROM_SYSTEM_BIOS(1, "v409", "v40.9")
300+
ROMX_LOAD("a4091_v409.u206", 0x0000, 0x8000, CRC(7e12a120) SHA1(a411d5726801dc443d41428f382ae3d56f44ef27), ROM_BIOS(1))
301+
ROM_RELOAD( 0x8000, 0x8000)
302+
ROM_SYSTEM_BIOS(2, "v4013", "v40.13")
303+
ROMX_LOAD("391592-02_a4091_v4013.u206", 0x0000, 0x8000, CRC(54cb9e85) SHA1(3ce66919f6fd67974923a12d91b730f1ffb4a7ba), ROM_BIOS(2))
304+
ROM_RELOAD( 0x8000, 0x8000)
305+
ROM_END
306+
307+
const tiny_rom_entry *a4091_device::device_rom_region() const
308+
{
309+
return ROM_NAME( a4091 );
310+
}
311+
312+
313+
} // namespace bus::amiga::zorro
314+
315+
316+
//**************************************************************************
317+
// DEVICE DEFINITIONS
318+
//**************************************************************************
319+
320+
DEFINE_DEVICE_TYPE_PRIVATE(AMIGA_A4091, device_zorro3_card_interface, bus::amiga::zorro::a4091_device, "amiga_a4091", "Commodore/DKB A4091 SCSI Host Adapter")
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// license: GPL-2.0+
2+
// copyright-holders: Dirk Best
3+
/***************************************************************************
4+
5+
Commodore/DKB A4091
6+
7+
***************************************************************************/
8+
9+
#ifndef MAME_BUS_AMIGA_ZORRO_A4091_H
10+
#define MAME_BUS_AMIGA_ZORRO_A4091_H
11+
12+
#pragma once
13+
14+
#include "zorro.h"
15+
16+
17+
// device type declaration
18+
DECLARE_DEVICE_TYPE(AMIGA_A4091, device_zorro3_card_interface)
19+
20+
#endif // MAME_BUS_AMIGA_ZORRO_A4091_H

src/devices/bus/amiga/zorro/cards.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "toccata.h"
2626

2727
// zorro3
28+
#include "a4091.h"
2829
#include "cybervision64.h"
2930
#include "dkb3128.h"
3031

@@ -51,6 +52,7 @@ void zorro2_cards(device_slot_interface &device)
5152
void zorro3_cards(device_slot_interface &device)
5253
{
5354
zorro2_cards(device);
55+
device.option_add("a4091", AMIGA_A4091);
5456
device.option_add("cybervision64", AMIGA_CYBERVISION64);
5557
device.option_add("dkb3128", AMIGA_DKB3128);
5658
}

0 commit comments

Comments
 (0)