1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /**********************************************************************
4 
5     CMD FD-2000/FD-4000 disk drive emulation
6 
7 **********************************************************************/
8 
9 /*
10 
11     TODO:
12 
13     - IEC
14     - VIA
15     - DP8473/PC8477A command extensions to upd765
16     - D1M/D2M/D4M image format (http://ist.uwaterloo.ca/~schepers/formats/D2M-DNP.TXT)
17 
18 */
19 
20 #include "emu.h"
21 #include "fd2000.h"
22 
23 
24 
25 //**************************************************************************
26 //  MACROS / CONSTANTS
27 //**************************************************************************
28 
29 #define G65SC02PI2_TAG  "m6502"
30 #define R65C02P4_TAG    "m6502"
31 #define G65SC22P2_TAG   "m6522"
32 #define DP8473V_TAG     "dp8473"
33 #define PC8477AV1_TAG   "pc8477av1"
34 #define DS1216E_TAG     "ds1216e"
35 
36 
37 
38 //**************************************************************************
39 //  DEVICE DEFINITIONS
40 //**************************************************************************
41 
42 DEFINE_DEVICE_TYPE(FD2000, fd2000_device, "fd2000", "FD-2000 Disk Drive")
43 DEFINE_DEVICE_TYPE(FD4000, fd4000_device, "fd4000", "FD-4000 Disk Drive")
44 
45 
46 //-------------------------------------------------
47 //  ROM( fd2000 )
48 //-------------------------------------------------
49 
ROM_START(fd2000)50 ROM_START( fd2000 )
51 	ROM_REGION( 0x8000, G65SC02PI2_TAG, 0 )
52 	ROM_DEFAULT_BIOS( "v140" )
53 	ROM_SYSTEM_BIOS( 0, "v134", "Version 1.34" )
54 	ROMX_LOAD( "cmd fd-2000 dos v1.34 fd-350026.bin", 0x0000, 0x8000, CRC(859a5edc) SHA1(487fa82a7977e5208d5088f3580f34e8c89560d1), ROM_BIOS(0) )
55 	ROM_SYSTEM_BIOS( 1, "v140", "Version 1.40" )
56 	ROMX_LOAD( "cmd fd-2000 dos v1.40 cs 33cc6f.bin", 0x0000, 0x8000, CRC(4e6ca15c) SHA1(0c61ba58269baf2b8aadf3bbc4648c7a5a6d2128), ROM_BIOS(1) )
57 ROM_END
58 
59 
60 //-------------------------------------------------
61 //  ROM( fd4000 )
62 //-------------------------------------------------
63 
64 ROM_START( fd4000 )
65 	ROM_REGION( 0x8000, R65C02P4_TAG, 0 )
66 	ROM_DEFAULT_BIOS( "v140" )
67 	ROM_SYSTEM_BIOS( 0, "v134", "Version 1.34" )
68 	ROMX_LOAD( "cmd fd-4000 dos v1.34 fd-350022.bin", 0x0000, 0x8000, CRC(1f4820c1) SHA1(7a2966662e7840fd9377549727ccba62e4349c6f), ROM_BIOS(0) )
69 	ROM_SYSTEM_BIOS( 1, "v140", "Version 1.40" )
70 	ROMX_LOAD( "cmd fd-4000 dos v1.40 fd-350022.bin", 0x0000, 0x8000, CRC(b563ef10) SHA1(d936d76fd8b50ce4c65f885703653d7c1bd7d3c9), ROM_BIOS(1) )
71 ROM_END
72 
73 
74 //-------------------------------------------------
75 //  rom_region - device-specific ROM region
76 //-------------------------------------------------
77 
78 const tiny_rom_entry *fd2000_device::device_rom_region() const
79 {
80 	return ROM_NAME( fd2000 );
81 }
82 
device_rom_region() const83 const tiny_rom_entry *fd4000_device::device_rom_region() const
84 {
85 	return ROM_NAME( fd4000 );
86 }
87 
88 //-------------------------------------------------
89 //  ADDRESS_MAP( fd2000_mem )
90 //-------------------------------------------------
91 
fd2000_mem(address_map & map)92 void fd2000_device::fd2000_mem(address_map &map)
93 {
94 	map(0x0000, 0x3fff).ram();
95 	map(0x4000, 0x400f).mirror(0xbf0).m(G65SC22P2_TAG, FUNC(via6522_device::map));
96 	map(0x4e00, 0x4e07).mirror(0x1f8).m(DP8473V_TAG, FUNC(dp8473_device::map));
97 	map(0x5000, 0x7fff).ram();
98 	map(0x8000, 0xffff).rom().region(G65SC02PI2_TAG, 0);
99 }
100 
101 
102 //-------------------------------------------------
103 //  ADDRESS_MAP( fd4000_mem )
104 //-------------------------------------------------
105 
fd4000_mem(address_map & map)106 void fd4000_device::fd4000_mem(address_map &map)
107 {
108 	map(0x0000, 0x3fff).ram();
109 	map(0x4000, 0x400f).mirror(0xbf0).m(G65SC22P2_TAG, FUNC(via6522_device::map));
110 	map(0x4e00, 0x4e07).mirror(0x1f8).m(PC8477AV1_TAG, FUNC(pc8477a_device::map));
111 	map(0x5000, 0x7fff).ram();
112 	map(0x8000, 0xffff).rom().region(R65C02P4_TAG, 0);
113 }
114 
115 
via_pa_r()116 uint8_t fd2000_device::via_pa_r()
117 {
118 	/*
119 
120 	    bit     description
121 
122 	    0
123 	    1
124 	    2
125 	    3
126 	    4
127 	    5
128 	    6
129 	    7
130 
131 	*/
132 
133 	return 0;
134 }
135 
via_pa_w(uint8_t data)136 void fd2000_device::via_pa_w(uint8_t data)
137 {
138 	/*
139 
140 	    bit     description
141 
142 	    0
143 	    1
144 	    2
145 	    3
146 	    4
147 	    5       FAST DIR
148 	    6
149 	    7
150 
151 	*/
152 }
153 
via_pb_r()154 uint8_t fd2000_device::via_pb_r()
155 {
156 	/*
157 
158 	    bit     description
159 
160 	    0
161 	    1
162 	    2
163 	    3
164 	    4
165 	    5
166 	    6
167 	    7       FDC INTRQ
168 
169 	*/
170 
171 	uint8_t data = 0;
172 
173 	// FDC interrupt
174 	data |= m_fdc->get_irq() << 7;
175 
176 	return data;
177 }
178 
via_pb_w(uint8_t data)179 void fd2000_device::via_pb_w(uint8_t data)
180 {
181 	/*
182 
183 	    bit     description
184 
185 	    0
186 	    1
187 	    2
188 	    3
189 	    4
190 	    5       LED
191 	    6       LED
192 	    7
193 
194 	*/
195 }
196 
fd2000_floppies(device_slot_interface & device)197 static void fd2000_floppies(device_slot_interface &device)
198 {
199 	device.option_add("35hd", FLOPPY_35_HD); // TEAC FD-235HF
200 }
201 
fd4000_floppies(device_slot_interface & device)202 static void fd4000_floppies(device_slot_interface &device)
203 {
204 	device.option_add("35ed", FLOPPY_35_ED); // TEAC FD-235J
205 }
206 /*
207 FLOPPY_FORMATS_MEMBER( fd2000_device::floppy_formats )
208     FLOPPY_D81_FORMAT
209     FLOPPY_D2M_FORMAT
210 FLOPPY_FORMATS_END
211 */
212 
213 
214 //-------------------------------------------------
215 //  device_add_mconfig - add device configuration
216 //-------------------------------------------------
217 
add_common_devices(machine_config & config)218 void fd2000_device::add_common_devices(machine_config &config)
219 {
220 	M65C02(config, m_maincpu, 24_MHz_XTAL / 12);
221 
222 	via6522_device &via(VIA6522(config, G65SC22P2_TAG, 24_MHz_XTAL / 12));
223 	via.readpa_handler().set(FUNC(fd2000_device::via_pa_r));
224 	via.readpb_handler().set(FUNC(fd2000_device::via_pb_r));
225 	via.writepa_handler().set(FUNC(fd2000_device::via_pa_w));
226 	via.writepb_handler().set(FUNC(fd2000_device::via_pb_w));
227 }
228 
device_add_mconfig(machine_config & config)229 void fd2000_device::device_add_mconfig(machine_config &config)
230 {
231 	add_common_devices(config);
232 	m_maincpu->set_addrmap(AS_PROGRAM, &fd2000_device::fd2000_mem);
233 	DP8473(config, m_fdc, 24_MHz_XTAL);
234 	FLOPPY_CONNECTOR(config, DP8473V_TAG":0", fd2000_floppies, "35hd", floppy_image_device::default_floppy_formats, true);//fd2000_device::floppy_formats);
235 }
236 
device_add_mconfig(machine_config & config)237 void fd4000_device::device_add_mconfig(machine_config &config)
238 {
239 	add_common_devices(config);
240 	m_maincpu->set_addrmap(AS_PROGRAM, &fd4000_device::fd4000_mem);
241 	PC8477A(config, m_fdc, 24_MHz_XTAL);
242 	FLOPPY_CONNECTOR(config, PC8477AV1_TAG":0", fd4000_floppies, "35ed", floppy_image_device::default_floppy_formats, true);//fd2000_device::floppy_formats);
243 }
244 
245 
246 //**************************************************************************
247 //  LIVE DEVICE
248 //**************************************************************************
249 
250 //-------------------------------------------------
251 //  fd2000_device - constructor
252 //-------------------------------------------------
253 
fd2000_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)254 fd2000_device::fd2000_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
255 	: fd2000_device(mconfig, FD2000, tag, owner, clock)
256 {
257 }
258 
fd2000_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)259 fd2000_device::fd2000_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
260 	: device_t(mconfig, type, tag, owner, clock)
261 	, device_cbm_iec_interface(mconfig, *this)
262 	, m_maincpu(*this, G65SC02PI2_TAG)
263 	, m_fdc(*this, DP8473V_TAG)
264 	, m_floppy0(*this, DP8473V_TAG":0")
265 {
266 }
267 
268 
269 //-------------------------------------------------
270 //  fd4000_device - constructor
271 //-------------------------------------------------
272 
fd4000_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)273 fd4000_device::fd4000_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
274 	: fd2000_device(mconfig, FD4000, tag, owner, clock)
275 {
276 	m_maincpu.set_tag(*this, R65C02P4_TAG);
277 	m_fdc.set_tag(*this, PC8477AV1_TAG);
278 	m_floppy0.set_tag(*this, PC8477AV1_TAG":0");
279 }
280 
281 
282 //-------------------------------------------------
283 //  device_start - device-specific startup
284 //-------------------------------------------------
285 
device_start()286 void fd2000_device::device_start()
287 {
288 }
289 
290 
291 //-------------------------------------------------
292 //  device_reset - device-specific reset
293 //-------------------------------------------------
294 
device_reset()295 void fd2000_device::device_reset()
296 {
297 }
298 
299 
300 //-------------------------------------------------
301 //  cbm_iec_srq -
302 //-------------------------------------------------
303 
cbm_iec_srq(int state)304 void fd2000_device::cbm_iec_srq(int state)
305 {
306 }
307 
308 
309 //-------------------------------------------------
310 //  cbm_iec_atn -
311 //-------------------------------------------------
312 
cbm_iec_atn(int state)313 void fd2000_device::cbm_iec_atn(int state)
314 {
315 }
316 
317 
318 //-------------------------------------------------
319 //  cbm_iec_data -
320 //-------------------------------------------------
321 
cbm_iec_data(int state)322 void fd2000_device::cbm_iec_data(int state)
323 {
324 }
325 
326 
327 //-------------------------------------------------
328 //  cbm_iec_reset -
329 //-------------------------------------------------
330 
cbm_iec_reset(int state)331 void fd2000_device::cbm_iec_reset(int state)
332 {
333 	if (!state)
334 	{
335 		device_reset();
336 	}
337 }
338