Skip to content

Commit 6218b23

Browse files
authored
bus/qbus/dvk_kmd.cpp: Added the DVK KMD intelligent floppy controller. (#14226)
1 parent 843121f commit 6218b23

File tree

5 files changed

+425
-0
lines changed

5 files changed

+425
-0
lines changed

scripts/src/bus.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4923,6 +4923,8 @@ if (BUSES["QBUS"]~=null) then
49234923
MAME_DIR .. "src/devices/bus/qbus/dsd4432.h",
49244924
MAME_DIR .. "src/devices/bus/qbus/dvk_kgd.cpp",
49254925
MAME_DIR .. "src/devices/bus/qbus/dvk_kgd.h",
4926+
MAME_DIR .. "src/devices/bus/qbus/dvk_kmd.cpp",
4927+
MAME_DIR .. "src/devices/bus/qbus/dvk_kmd.h",
49264928
MAME_DIR .. "src/devices/bus/qbus/dvk_mx.cpp",
49274929
MAME_DIR .. "src/devices/bus/qbus/dvk_mx.h",
49284930
MAME_DIR .. "src/devices/bus/qbus/pc11.cpp",

src/devices/bus/qbus/dvk_kmd.cpp

Lines changed: 320 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
// license:BSD-3-Clause
2+
// copyright-holders:Sergey Svishchev
3+
/***************************************************************************
4+
5+
DVK KMD floppy controller (decimal 3.057.136, device driver MY.SYS)
6+
7+
https://emuverse.ru/downloads/computers/DVK/docs/KMD/KMD_MY_RU1_.djvu
8+
9+
22-bit bus capable, uses DMA. CSR 172140, vector 170.
10+
11+
Firmware 091 supports only ISO track format (without index mark) and
12+
double-sided disks.
13+
14+
Firmware 092 also supports PC track format (with index mark) and
15+
single-sided disks, fixes bugs and adds 4 new commands.
16+
17+
Bootstrap for systems without ROM 279:
18+
19+
172140/000040 37 <newline>
20+
172142/xxxxxx 0 "^"
21+
172140/000000 40 "G"
22+
23+
Commands:
24+
25+
0 read
26+
1 write
27+
2 read dd
28+
3 write dd
29+
4 read track
30+
5 read id
31+
6 format iso
32+
7 seek
33+
8 set
34+
9 read error state
35+
A*
36+
B* format & write
37+
C* format ibm
38+
D* block move
39+
E* run user code
40+
F boot
41+
42+
***************************************************************************/
43+
44+
#include "emu.h"
45+
#include "dvk_kmd.h"
46+
47+
#define LOG_DBG (1U << 1)
48+
49+
//#define VERBOSE (LOG_GENERAL)
50+
//#define LOG_OUTPUT_FUNC osd_printf_info
51+
52+
#include "logmacro.h"
53+
54+
#define LOGDBG(format, ...) LOGMASKED(LOG_DBG, "%11.6f at %s: " format, machine().time().as_double(), machine().describe_context(), __VA_ARGS__)
55+
56+
57+
//**************************************************************************
58+
// DEVICE DEFINITIONS
59+
//**************************************************************************
60+
61+
DEFINE_DEVICE_TYPE(DVK_KMD, dvk_kmd_device, "dvk_kmd", "DVK KMD floppy controller")
62+
63+
ROM_START(dvk_kmd)
64+
ROM_REGION(0x2000, "maincpu", 0)
65+
ROM_DEFAULT_BIOS("092")
66+
ROM_SYSTEM_BIOS(0, "091", "mask 091")
67+
ROMX_LOAD("091.dat", 0x0000, 0x2000, CRC(3bd0effc) SHA1(4a3e4567dc46cb306d37fbe71839bc46e232bac8), ROM_BIOS(0))
68+
ROM_SYSTEM_BIOS(1, "092", "mask 092")
69+
ROMX_LOAD("092.dat", 0x0000, 0x2000, CRC(eb4e1de1) SHA1(6bc020054934a5562e763a18f915b8d612ccc70c), ROM_BIOS(1))
70+
ROM_END
71+
72+
73+
//**************************************************************************
74+
// LIVE DEVICE
75+
//**************************************************************************
76+
77+
//-------------------------------------------------
78+
// dvk_kmd_device - constructor
79+
//-------------------------------------------------
80+
81+
dvk_kmd_device::dvk_kmd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
82+
: device_t(mconfig, DVK_KMD, tag, owner, clock)
83+
, device_qbus_card_interface(mconfig, *this)
84+
, device_z80daisy_interface(mconfig, *this)
85+
, m_maincpu(*this, "maincpu")
86+
, m_fdc(*this, "fdc")
87+
, m_installed(false)
88+
{
89+
}
90+
91+
void dvk_kmd_device::floppy_formats(format_registration &fr)
92+
{
93+
fr.add_mfm_containers();
94+
fr.add(FLOPPY_BK0010_FORMAT);
95+
}
96+
97+
static void kmd_floppies(device_slot_interface &device)
98+
{
99+
device.option_add("525qd", FLOPPY_525_QD);
100+
}
101+
102+
void dvk_kmd_device::kmd_mem(address_map &map)
103+
{
104+
// FIXME: add trap
105+
map(0000000, 0017777).rom().region("maincpu", 0);
106+
map(0020000, 0023777).ram();
107+
map(0040000, 0077777).rw(FUNC(dvk_kmd_device::dma_read), FUNC(dvk_kmd_device::dma_write));
108+
map(0177100, 0177103).rw(FUNC(dvk_kmd_device::local_read), FUNC(dvk_kmd_device::local_write));
109+
map(0177130, 0177133).rw(m_fdc, FUNC(k1801vp128_device::read), FUNC(k1801vp128_device::write));
110+
map(0177716, 0177717).lr16(NAME([] (offs_t offset) { return 010000 | 1; })).nopw();
111+
map(0177760, 0177761).noprw(); // RAM chip base address register
112+
}
113+
114+
const tiny_rom_entry *dvk_kmd_device::device_rom_region() const
115+
{
116+
return ROM_NAME(dvk_kmd);
117+
}
118+
119+
void dvk_kmd_device::device_add_mconfig(machine_config &config)
120+
{
121+
K1801VM1(config, m_maincpu, XTAL(8'000'000) / 2);
122+
m_maincpu->set_addrmap(AS_PROGRAM, &dvk_kmd_device::kmd_mem);
123+
124+
K1801VP128(config, m_fdc, XTAL(4'000'000));
125+
m_fdc->ds_in_callback().set(
126+
[] (uint16_t data)
127+
{
128+
switch (data & 15)
129+
{
130+
case 1: return 0;
131+
case 2: return 1;
132+
case 4: return 2;
133+
case 8: return 3;
134+
default: return -1;
135+
}
136+
});
137+
FLOPPY_CONNECTOR(config, "fdc:0", kmd_floppies, "525qd", dvk_kmd_device::floppy_formats);
138+
FLOPPY_CONNECTOR(config, "fdc:1", kmd_floppies, "525qd", dvk_kmd_device::floppy_formats);
139+
FLOPPY_CONNECTOR(config, "fdc:2", kmd_floppies, "525qd", dvk_kmd_device::floppy_formats);
140+
FLOPPY_CONNECTOR(config, "fdc:3", kmd_floppies, "525qd", dvk_kmd_device::floppy_formats);
141+
}
142+
143+
144+
//-------------------------------------------------
145+
// device_start - device-specific startup
146+
//-------------------------------------------------
147+
148+
void dvk_kmd_device::device_start()
149+
{
150+
// save state
151+
save_item(NAME(m_installed));
152+
save_item(NAME(m_cr));
153+
save_item(NAME(m_dr));
154+
155+
m_installed = false;
156+
}
157+
158+
159+
//-------------------------------------------------
160+
// device_reset - device-specific reset
161+
//-------------------------------------------------
162+
163+
void dvk_kmd_device::device_reset()
164+
{
165+
if (!m_installed)
166+
{
167+
m_bus->install_device(0172140, 0172143,
168+
read16sm_delegate(*this, FUNC(dvk_kmd_device::read)),
169+
write16sm_delegate(*this, FUNC(dvk_kmd_device::write)));
170+
m_installed = true;
171+
}
172+
m_cr = m_dr = m_go = 0;
173+
m_rxrdy = CLEAR_LINE;
174+
}
175+
176+
void dvk_kmd_device::init_w()
177+
{
178+
m_maincpu->pulse_input_line(t11_device::CP2_LINE, m_maincpu->minimum_quantum_time());
179+
}
180+
181+
182+
//-------------------------------------------------
183+
// read - register read
184+
//-------------------------------------------------
185+
186+
uint16_t dvk_kmd_device::read(offs_t offset)
187+
{
188+
uint16_t data = 0;
189+
190+
switch (offset)
191+
{
192+
case 0:
193+
data = m_cr & KMDCSR_RD;
194+
break;
195+
196+
case 1:
197+
data = m_dr;
198+
break;
199+
}
200+
201+
return data;
202+
}
203+
204+
205+
//-------------------------------------------------
206+
// write - register write
207+
//-------------------------------------------------
208+
209+
void dvk_kmd_device::write(offs_t offset, uint16_t data)
210+
{
211+
LOGDBG("host W %06o <- %06o [cr %06o go %06o]\n", 0172140 + (offset << 1), data, m_cr, m_go);
212+
213+
switch (offset)
214+
{
215+
case 0:
216+
if ((data & CSR_IE) == 0)
217+
{
218+
clear_virq(m_bus->birq4_w, 1, 1, m_rxrdy);
219+
}
220+
m_cr = ((m_cr & ~KMDCSR_WR) | (data & KMDCSR_WR));
221+
if (data & KMDCSR_GO)
222+
{
223+
m_go = m_cr;
224+
m_cr &= ~KMDCSR_DONE;
225+
}
226+
break;
227+
228+
case 1:
229+
m_dr = data;
230+
m_cr &= ~KMDCSR_TR;
231+
clear_virq(m_bus->birq4_w, m_cr, CSR_IE, m_rxrdy);
232+
break;
233+
}
234+
}
235+
236+
237+
int dvk_kmd_device::z80daisy_irq_state()
238+
{
239+
if (m_rxrdy == ASSERT_LINE)
240+
return Z80_DAISY_INT;
241+
else
242+
return 0;
243+
}
244+
245+
int dvk_kmd_device::z80daisy_irq_ack()
246+
{
247+
int vec = -1;
248+
249+
if (m_rxrdy == ASSERT_LINE)
250+
{
251+
m_rxrdy = CLEAR_LINE;
252+
vec = 0170;
253+
}
254+
255+
return vec;
256+
}
257+
258+
259+
//**************************************************************************
260+
// local bus
261+
//**************************************************************************
262+
263+
uint16_t dvk_kmd_device::local_read(offs_t offset)
264+
{
265+
uint16_t data = 0;
266+
267+
switch (offset)
268+
{
269+
case 0:
270+
data = m_cr;
271+
break;
272+
273+
case 1:
274+
data = m_dr;
275+
break;
276+
}
277+
278+
return data;
279+
}
280+
281+
void dvk_kmd_device::local_write(offs_t offset, uint16_t data)
282+
{
283+
LOGDBG("locl W %06o <- %06o [cr %06o go %06o]\n", 0177100 + (offset << 1), data, m_cr, m_go);
284+
285+
switch (offset)
286+
{
287+
case 0:
288+
if ((data & KMDCSR_DONE) && !(m_cr & KMDCSR_DONE))
289+
{
290+
if (m_go & CSR_IE) LOGDBG("raising irq %s\n", "");
291+
raise_virq(m_bus->birq4_w, m_cr, CSR_IE, m_rxrdy);
292+
}
293+
else if (!(data & KMDCSR_DONE) && (m_cr & KMDCSR_DONE))
294+
{
295+
if (m_go & CSR_IE) LOGDBG("clearing irq %s\n", "");
296+
clear_virq(m_bus->birq4_w, m_cr, CSR_IE, m_rxrdy);
297+
}
298+
m_cr = ((m_cr & ~KMDCSR_L_WR) | (data & KMDCSR_L_WR));
299+
break;
300+
301+
case 1:
302+
m_dr = data;
303+
break;
304+
}
305+
}
306+
307+
// FIXME add DMA protocol (CPU halt etc.); HALT mode howto?
308+
uint16_t dvk_kmd_device::dma_read(offs_t offset)
309+
{
310+
LOGDBG("dma R %06o=%06o\n", offset, (offset << 1) | ((m_dr & 3) << 14));
311+
312+
return m_bus->read((offset << 1) | ((m_dr & 3) << 14));
313+
}
314+
315+
void dvk_kmd_device::dma_write(offs_t offset, uint16_t data)
316+
{
317+
LOGDBG("dma W %06o=%06o <- %06o\n", offset, (offset << 1) | ((m_dr & 3) << 14), data);
318+
319+
m_bus->write((offset << 1) | ((m_dr & 3) << 14), data);
320+
}

0 commit comments

Comments
 (0)