Previous 15994 Revisions Next

r6733 Thursday 24th December, 2009 at 11:43:17 UTC by Miodrag Milanović
C16/C65/PET/CBMB/PRIMO removed simulated floppy
[src/mess]mess.mak
[src/mess/drivers]c16.c c65.c pet.c primo.c
[src/mess/includes]cbmdrive.h vc1541.h
[src/mess/machine]c16.c c65.c cbmb.c cbmdrive.c cbmieeeb.c pet.c primo.c vc1541.c vc20.c

src/mess/includes/vc1541.h
r6732r6733
1/*****************************************************************************
2 *
3 * includes/vc1541.h
4 *
5 * Commodore VC1541 floppy disk drive
6 *
7 ****************************************************************************/
8
9#ifndef VC1541_H_
10#define VC1541_H_
11
12/*----------- defined in machine/vc1541.c -----------*/
13
14/* we currently have preliminary support for 1541 & 1551 only */
15enum {
16   type_1541 = 0,
17   type_1541ii,
18   type_1551,
19   type_1570,
20   type_1571,
21   type_1571cr,
22   type_1581,
23   type_2031,
24   type_2040,
25   type_3040,
26   type_4040,
27   type_1001,
28   type_8050,
29   type_8250,
30};
31
32enum {
33   format_d64 = 0,         /* 1541 image, 35 tracks */
34   format_d64_err,         /* 1541 image, 35 tracks + error table */
35   format_d64_40t,         /* 1541 image, 40 tracks */
36   format_d64_40t_err,      /* 1541 image, 40 tracks + error table */
37   format_d67,            /* 2040 image, 35 tracks DOS1 format */
38   format_d71,            /* 1571 image, 70 tracks */
39   format_d71_err,         /* 1571 image, 70 tracks + error table */
40   format_d81,            /* 1581 image, 80 tracks */
41   format_d80,            /* 8050 image, 77 tracks */
42   format_d82,            /* 8250 image, 154 tracks (read as 77?) */
43   format_g64,            /* 1541 image in GCR format */
44};
45
46
47void cbm_drive_config(running_machine *machine, int type, int id, int mode, const char *cputag, int devicenr);
48void c1551_config(running_machine *machine, const char *cputag);
49void cbm_drive_reset(running_machine *machine);
50void c1551_drive_reset(void);
51
52void vc1541_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info);
53void c1551_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info);
54void c1571_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info);
55void c1581_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info);
56/* the ones below are still not used in any drivers */
57void c2031_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info);
58void c2040_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info);
59void c8050_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info);
60void c8250_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info);
61
62
63MACHINE_DRIVER_EXTERN( cpu_vc1540 );
64MACHINE_DRIVER_EXTERN( cpu_vc1541 );
65MACHINE_DRIVER_EXTERN( cpu_c1571 );
66MACHINE_DRIVER_EXTERN( cpu_c1571cr );
67MACHINE_DRIVER_EXTERN( cpu_c1581 );
68MACHINE_DRIVER_EXTERN( cpu_c2031 );
69MACHINE_DRIVER_EXTERN( cpu_c1551 );
70
71// currently not used (hacked drive firmware with more RAM)
72MACHINE_DRIVER_EXTERN( cpu_dolphin );
73
74
75/* IEC interface for c16 with c1551 */
76
77/* To be passed directly to the drivers */
78WRITE8_DEVICE_HANDLER( c1551x_write_data );
79READ8_DEVICE_HANDLER( c1551x_read_data );
80WRITE8_DEVICE_HANDLER( c1551x_write_handshake );
81READ8_DEVICE_HANDLER( c1551x_read_handshake );
82READ8_DEVICE_HANDLER( c1551x_read_status );
83
84
85/* Floppy drive ROMs */
86
87/****************************************************************************
88
89Info from zimmers.net
90
911551 Parts
92
93Location       Part Number     Description
94U4             318008-01       23128 ROM DOS 2.6 C000-FFFF
95U5                             6116 2K x 8 Static RAM
96U6                             HD61J215P 42 pin Gate Array
97U7             251829-01       64H157 20 pin Gate Array
98U2                             6510T CPU
99U3                             6525A TPI
100U11            251853-01       R/W Hybrid
101
102Interface Cartridge:
103U2                             6523 Tri-Port Interface
104U1             251641-03       82S100 PLA
105
106****************************************************************************/
107
108#define C1551_ROM( cpu )   \
109   ROM_REGION( 0x10000, cpu, 0 )   \
110   ROM_LOAD( "318008-01.u4", 0xc000, 0x4000, CRC(6d16d024) SHA1(fae3c788ad9a6cc2dbdfbcf6c0264b2ca921d55e) )
111
112
113
114/****************************************************************************
115
116Info from zimmers.net
117
1181540/1541/1541A/SX-64 Parts
119
120Location       Part Number    Description
121                              2016 2K x 8 bit Static RAM (short board)
122UA2-UB3                       2114 (4) 1K x 4 bit Static RAM (long board)
123               325302-01      2364-130 ROM DOS 2.6 C000-DFFF
124               325303-01      2364-131 ROM DOS 2.6 (1540) E000-FFFF
125               901229-01      2364-173 ROM DOS 2.6 (1541) E000-FFFF
126               901229-03      2364-197 ROM DOS 2.6 rev. 1 E000-FFFF
127               901229-05      2364     ROM DOS 2.6 rev. 2 E000-FFFF
128               325572-01      64H105 40 pin Gate Array (short board)
129                              6502 CPU
130                              6522 (2) VIA
131drive                         Alps DFB111M25A
132drive                         Alps FDM2111-B2
133drive                         Newtronics D500
134
1351541B/1541C Parts
136
137Location       Part Number    Description
138UA3                           2016 2K x 8 bit Static RAM
139UA2            251968-01      23128 ROM DOS 2.6 rev. 3 C000-FFFF
140UA2            251968-01      27128 EPROM DOS 2.6 rev. 3 C000-FFFF
141UC4            251828-02      64H156 42 pin Gate Array
142UC5            251829-01      64H157 20 pin Gate Array
143UC2                           6502 CPU
144UC1, UC3                      6522 (2) CIA
145UD1          * 251853-01      R/W Hybrid
146UD1          * 251853-02      R/W Hybrid
147drive                         Newtronics D500
148  * Not interchangeable.
149
1501541-II Parts
151
152Location       Part Number    Description
153U5                            2016-15 2K x 8 bit Static RAM
154U12                           SONY CX20185 R/W Amp.
155U4             251968-03      16K ROM DOS 2.6 rev. 4 C000-FFFF
156U10            251828-01      64H156 40 pin Gate Array
157U3                            6502A CPU
158U6, U8                        6522 (2) CIA
159drive                         Chinon FZ-501M REV A
160drive                         Digital System DS-50F
161drive                         Newtronics D500
162drive                         Safronic DS-50F
163
164
165
166Note: according to additional docs at zimmers.net, ROMs in these drive
167were interchangeable: you could burn later revisions on EEPROM and put
168them in older drives and they would work perfectly.
169
170****************************************************************************/
171
172// I'm not 100% sure about UA2/UB3 locations used below for ROM names
173// I need a picture to confirm these, since the part listing above is not really clear (without a pic of the board)
174#define VC1540_ROM( cpu )   \
175   ROM_REGION( 0x10000, cpu, 0 )   \
176   ROM_LOAD( "325302-01.ua2", 0xc000, 0x2000, CRC(29ae9752) SHA1(8e0547430135ba462525c224e76356bd3d430f11) )   \
177   ROM_LOAD( "325303-01.ub3", 0xe000, 0x2000, CRC(10b39158) SHA1(56dfe79b26f50af4e83fd9604857756d196516b9) )
178
179/*
180    rev. 01 - It is believed to be the first revision of the 1541 firmware. The service manual says that this ROM
181        is for North America and Japan only.
182    rev. 02 - Second version of the 1541 firmware. The service manual says that this ROM was not available in North
183        America (Japan only?).
184    rev. 03 - It is said to be the first version that is usable in Europe (in the service manual?).
185    rev. 05 - From an old-style 1541 with short board.
186    rev. 06AA - From an old-style 1541 with short board.
187*/
188#define VC1541_ROM( cpu )   \
189   ROM_REGION( 0x10000, cpu, 0 )   \
190   ROM_SYSTEM_BIOS( 0, "rev1", "VC-1541 rev. 01" )   \
191   ROMX_LOAD( "325302-01.ua2", 0xc000, 0x2000, CRC(29ae9752) SHA1(8e0547430135ba462525c224e76356bd3d430f11), ROM_BIOS(1) )   \
192   ROMX_LOAD( "901229-01.ub3", 0xe000, 0x2000, CRC(9a48d3f0) SHA1(7a1054c6156b51c25410caec0f609efb079d3a77), ROM_BIOS(1) )   \
193   ROM_SYSTEM_BIOS( 1, "rev2", "VC-1541 rev. 02" )   \
194   ROMX_LOAD( "325302-01.ua2", 0xc000, 0x2000, CRC(29ae9752) SHA1(8e0547430135ba462525c224e76356bd3d430f11), ROM_BIOS(2) )   \
195   ROMX_LOAD( "901229-02.ub3", 0xe000, 0x2000, CRC(b29bab75) SHA1(91321142e226168b1139c30c83896933f317d000), ROM_BIOS(2) )   \
196   ROM_SYSTEM_BIOS( 2, "rev3", "VC-1541 rev. 03" )   \
197   ROMX_LOAD( "325302-01.ua2", 0xc000, 0x2000, CRC(29ae9752) SHA1(8e0547430135ba462525c224e76356bd3d430f11), ROM_BIOS(3) )   \
198   ROMX_LOAD( "901229-03.ub3", 0xe000, 0x2000, CRC(9126e74a) SHA1(03d17bd745066f1ead801c5183ac1d3af7809744), ROM_BIOS(3) )   \
199   ROM_SYSTEM_BIOS( 3, "rev5", "VC-1541 rev. 05" )   \
200   ROMX_LOAD( "325302-01.ua2", 0xc000, 0x2000, CRC(29ae9752) SHA1(8e0547430135ba462525c224e76356bd3d430f11), ROM_BIOS(4) )   \
201   ROMX_LOAD( "901229-05.ub3", 0xe000, 0x2000, CRC(361c9f37) SHA1(f5d60777440829e46dc91285e662ba072acd2d8b), ROM_BIOS(4) )   \
202   ROM_SYSTEM_BIOS( 4, "rev6aa", "VC-1541 rev. 06AA" )   \
203   ROMX_LOAD( "325302-01.ua2", 0xc000, 0x2000, CRC(29ae9752) SHA1(8e0547430135ba462525c224e76356bd3d430f11), ROM_BIOS(5) )   \
204   ROMX_LOAD( "901229-06aa.ub3", 0xe000, 0x2000, CRC(3a235039) SHA1(c7f94f4f51d6de4cdc21ecbb7e57bb209f0530c0), ROM_BIOS(5) )   \
205   ROM_SYSTEM_BIOS( 5, "rev1c", "VC-1541C rev. 01" )   \
206   ROMX_LOAD( "251968-01.ua2", 0xc000, 0x4000, CRC(1b3ca08d) SHA1(8e893932de8cce244117fcea4c46b7c39c6a7765), ROM_BIOS(6) )   \
207   ROM_SYSTEM_BIOS( 6, "rev2c", "VC-1541C rev. 02" )   \
208   ROMX_LOAD( "251968-02.ua2", 0xc000, 0x4000, CRC(2d862d20) SHA1(38a7a489c7bbc8661cf63476bf1eb07b38b1c704), ROM_BIOS(7) )   \
209   ROM_SYSTEM_BIOS( 7, "rev3ii", "VC-1541-II" )   \
210   ROMX_LOAD( "251968-03.u4", 0xc000, 0x4000, CRC(899fa3c5) SHA1(d3b78c3dbac55f5199f33f3fe0036439811f7fb3), ROM_BIOS(8) )   \
211   ROM_SYSTEM_BIOS( 8, "reviin", "VC-1541-II (with Newtronics D500)" )   \
212   ROMX_LOAD( "355640-01.u4", 0xc000, 0x4000, CRC(57224cde) SHA1(ab16f56989b27d89babe5f89c5a8cb3da71a82f0), ROM_BIOS(9) )   \
213
214
215
216// currently not used (hacked drive firmware with more RAM)
217#define DOLPHIN_ROM( cpu )   \
218   ROM_REGION( 0x10000, cpu, 0 )   \
219   ROM_LOAD( "c1541.rom", 0xa000, 0x6000, CRC(bd8e42b2) SHA1(d6aff55fc70876fa72be45c666b6f42b92689b4d) )
220
221
222
223/****************************************************************************
224
225Info from zimmers.net
226
2271570 Parts
228
229Location       Part Number    Description
230               315090-01      32K ROM DOS 3.0
231drive                         Alps
232
2331571 Parts
234
235Location       Part Number    Description
236U11                           WD1770 FDC
237U11                           WD1772 FDC
238U3                            2016-20 2K x 8 bit Static RAM
239U1                            6502A CPU
240U4, U9                        65C22A (2) CIA
241U20                           6526A CIA
242U20                           8520 CIA
243U6             251828-01      64H156 40 pin Gate Array
244U5             251829-01      64H157 20 pin Gate Array
245U7             251853-01      R/W Hybrid
246U2             310654-03      23256 ROM DOS 3.0
247U2             310654-05      32K ROM DOS 3.0 rev.
248drive                         Alps
249drive                         Newtronics D502
250
251C128D Parts
252
253Location       Part Number    Description
254U103                          2016-20 2K x 8 bit Static RAM
255U108           252308-01      MC2871A R/W Amp.
256U107           252371-01      MOS5710 FDC and Gate Array
257U101                          6502A CPU
258U104, U106                    65C22 (2) CIA
259U105           251828-01      64H156 40 pin Gate Array
260U102           318047-01      23256 ROM DOS 3.1
261drive                         Newtronics D502
262
263
264****************************************************************************/
265
266// no locations available for this, I need a picture of the board
267// currently, we add 1570 to 1571, to preserve the firmware.
268// this will be used later, when proper drives will be added to each system
269#define C1570_ROM( cpu ) \
270   ROM_REGION( 0x10000, cpu, 0) \
271   ROM_LOAD( "315090-01.bin", 0x8000, 0x8000, CRC(5a0c7937) SHA1(5fc06dc82ff6840f183bd43a4d9b8a16956b2f56) )
272
273
274#define C1571_ROM( cpu ) \
275   ROM_REGION( 0x10000, cpu, 0 ) \
276   ROM_SYSTEM_BIOS( 0, "rev5", "1571 rev. 05" )   \
277   ROMX_LOAD( "310654-05.u2", 0x8000, 0x8000, CRC(5755bae3) SHA1(f1be619c106641a685f6609e4d43d6fc9eac1e70), ROM_BIOS(1) )   \
278   ROM_SYSTEM_BIOS( 1, "rev3", "1571 rev. 03" )   \
279   ROMX_LOAD( "310654-03.u2", 0x8000, 0x8000, CRC(3889b8b8) SHA1(e649ef4419d65829d2afd65e07d31f3ce147d6eb), ROM_BIOS(2) )   \
280   /* This should not be here... */   \
281   ROM_SYSTEM_BIOS( 2, "1570", "1570" )   \
282   ROMX_LOAD( "315090-01.bin", 0x8000, 0x8000, CRC(5a0c7937) SHA1(5fc06dc82ff6840f183bd43a4d9b8a16956b2f56), ROM_BIOS(3) )
283
284
285#define C1571CR_ROM( cpu ) \
286   ROM_REGION( 0x10000, cpu, 0) \
287   ROM_LOAD( "318047-01.u102", 0x8000, 0x8000, CRC(f24efcc4) SHA1(14ee7a0fb7e1c59c51fbf781f944387037daa3ee) )
288
289
290// no locations available for this, I need a picture of the board
291/*
292    rev. 01 - First revision of 1581 firmware
293    rev. 02 - Second revision of 1581 firmware
294    beta - Probably a beta version
295    1563 - This comes from a prototype unit of the so-called c128d/81 (a c128d with built-in 1581 drive).
296        Despite the label, is a 1581 firmaware
297*/
298#define C1581_ROM( cpu ) \
299   ROM_REGION( 0x10000, cpu, 0 ) \
300   ROM_SYSTEM_BIOS( 0, "rev2", "1581 rev. 02" )   \
301   ROMX_LOAD( "318045-02.bin", 0x8000, 0x8000, CRC(a9011b84) SHA1(01228eae6f066bd9b7b2b6a7fa3f667e41dad393), ROM_BIOS(1) )   \
302   ROM_SYSTEM_BIOS( 1, "rev1", "1581 rev. 01" )   \
303   ROMX_LOAD( "318045-01.bin", 0x8000, 0x8000, CRC(113af078) SHA1(3fc088349ab83e8f5948b7670c866a3c954e6164), ROM_BIOS(2) )   \
304   ROM_SYSTEM_BIOS( 2, "beta", "1581 beta?" )   \
305   ROMX_LOAD( "1581-beta.bin", 0x8000, 0x8000, CRC(ecc223cd) SHA1(a331d0d46ead1f0275b4ca594f87c6694d9d9594), ROM_BIOS(3) )   \
306   ROM_SYSTEM_BIOS( 3, "1563", "1563 (from C128D/81)" )   \
307   ROMX_LOAD( "1563.bin", 0x8000, 0x8000, CRC(1d184687) SHA1(2c5111a9c15be7b7955f6c8775fea25ec10c0ca0), ROM_BIOS(4) )
308
309
310
311/* Older drive - currently these are only added as documentation (no driver uses them yet) */
312/* They all use IEEE-448 connector */
313
314/****************************************************************************
315
316Info from zimmers.net
317
3182031 Parts
319
320Location       Part Number    Description
321UB2                           2016 2K x 8 bit static RAM (HP)
322U3B-U3E                       2114 (4) 1K x 4 bit static RAM (LP)
323               901484-03      2364-107 ROM DOS 2.6 C000-DFFF
324               901484-05      2364-123 ROM DOS 2.6 E000-FFFF
325                              6502 CPU
326                              6522 (2) VIA
327drive                         Alps DFB111M25A (LP)
328drive                         Alps FDM2111-B2 (LP)
329drive                         Shugart 390 (HP)
330
331****************************************************************************/
332
333// I'm not 100% sure about U3B/U3E locations used below for ROM names
334// I need a picture to confirm these, since the part listing above is not really clear (without a pic of the board)
335#define C2031_ROM( cpu )   \
336   ROM_REGION( 0x10000, cpu, 0 )   \
337   ROM_LOAD( "901484-03.u3b", 0xc000, 0x2000, CRC(ee4b893b) SHA1(54d608f7f07860f24186749f21c96724dd48bc50) )      \
338   ROM_LOAD( "901484-05.u3e", 0xe000, 0x2000, CRC(6a629054) SHA1(ec6b75ecfdd4744e5d57979ef6af990444c11ae1) )
339
340
341
342/****************************************************************************
343
344Info from zimmers.net
345
346SFD-1001 Parts
347
348Location       Part Number    Description
3497G, 9G                        2116 (2) 2K x 8 static RAM
350
351DOS:
3521J             901887-01      2364 ROM DOS 2.7 C000-DFFF
3533J             901887-02      2364 ROM DOS 2.7 E000-FFFF
3543J             901888-01      2364 ROM DOS 2.7 E000-FFFF
3552H                            6502 CPU
3564J, 6J                        6532 (2) RIOT
357
358Controller:
3595C             901467-01      6316-017 ROM GCR
3601E                            6502 CPU
3615E                            6522 VIA
3623E             251232         adapter board
363drive                         Matsushita JU-570-2
364
365Adapter Board:
366U2             251257-02A     2716 EPROM controller
367U1                            6530 RIOT (ROM disabled)
368
369
370Notes: The DOS 2.7 ROM in SFD-1001 is the same as in 8250 drives. Differences:
371
372CBM 8050 - dual 5" 1/4 floppy drive, disks are written on one side
373        with double density
374CBM 8250 / 8250LP - dual 5.25" 1/4 floppy drive, disks are written
375        on both sides. it reads 8050-disks, LP version has smaller case
376SFD-1001 - single 5" 1/4 floppy drive, same as CBM 8250LP, but only
377        one drive and 1541-case
378
379****************************************************************************/
380
381#define SFD1001_ROM( cpu )   \
382   ROM_REGION( 0x10800, cpu, 0 )   \
383   ROM_LOAD( "901887-01.1j", 0xc000, 0x2000, CRC(0073b8b2) )      \
384   ROM_LOAD( "901888-01.3j", 0xe000, 0x2000, CRC(de9b6132) )      \
385   ROM_LOAD( "251257-02a.u2", 0x10000, 0x800, CRC(b51150de) )   /* Floppy Disc Controller */
386
387
388#define C8250_ROM( cpu )   \
389   ROM_REGION( 0x10000, cpu, 0 )
390
391// still to be sorted out
392
393/****************************************************************************
394
395Info from zimmers.net
396
3972040/3040/4040 Parts
398
399Location       Part Number    Description
400UC4-UF5                       2114 (8) 1K x 4 bit static RAM
401
402DOS:
403UL1            901468-06      2332-020 ROM DOS 1 E000-EFFF
404UH1            901468-07      2332-021 ROM DOS 1 F000-FFFF
405UJ1            901468-11      2332 ROM DOS 2 D000-DFFF
406UL1            901468-12      2332 ROM DOS 2 E000-EFFF
407UH1            901468-13      2332 ROM DOS 2 F000-FFFF
408UJ1            901468-14      2332-191 ROM DOS 2 rev. D000-DFFF
409UL1            901468-15      2332-192 ROM DOS 2 rev. E000-EFFF
410UH1            901468-16      2332-193 ROM DOS 2 rev. F000-FFFF
411UN1                           6502 CPU
412UC1, UE1                      6532 (2) RIOT
413
414Controller:
415UH3                           6504 CPU
416UM3                           6522 VIA
417UK3            901466-02      6530-028 RIOT DOS 1
418UK3            901466-04      6530-034 RIOT DOS 2
419UK6            901467-01      6316-017 ROM GCR
420drive                         Shugart 390
421
422****************************************************************************/
423
424#define C4040_ROM( cpu )   \
425   ROM_REGION( 0x10000, cpu, 0 )
426
427// still to be sorted out
428
429
430/****************************************************************************
431
432Info from zimmers.net
433
4349060/9090 Parts
435
436Location  Part Number   Description
4375A-5H                   2114 (8) 1K x 4 bit Static RAM
438
439DOS:
4407C        300516-002  * 2564 EPROM DOS 3.0 C000-DFFF (rev. B)
4417D        300517-002  * 2564 EPROM DOS 3.0 E000-FFFF (rev. B)
4427C        300516-001  + 2764 EPROM DOS 3.0 C000-DFFF (rev. B)
4437D        300517-001  + 2764 EPROM DOS 3.0 E000-FFFF (rev. B)
4447C        300516      * 2564 EPROM DOS 3.0 rev. C000-DFFF (rev. C)
4457D        300517      * 2564 EPROM DOS 3.0 rev. E000-FFFF (rev. C)
4467C        300516      + 2764 EPROM DOS 3.0 rev. C000-DFFF (rev. C)
4477D        300517      + 2764 EPROM DOS 3.0 rev. E000-FFFF (rev. C)
4487E                      6502 CPU
4497F, 7G                  6532 (2) RIOT
450 * 2564 are used on PCB 300012-001
451 + 2764 are used on PCB 230012-002
452
453Controller:
4544C        300515        2716 EPROM DOS 3.0 (rev. A)
4554C        300515-001    2716 EPROM DOS 3.0 (rev. B)
4564A                      6502 CPU
4574B                      6522 VIA
4584D                      6810 128 x 8 bit Static RAM
459
460Winchester Controller:
4619D                      Am2910 12 bit Bit/Slice Controller
462drive                   Tandon TM602S (9060)
463drive                   Tandon TM603S (9090)
464
465
466Note: The Commodore D9060 and D9090 can use the same firmware. The
467difference between these units is that the jumper J14 on the DOS board
468is open in the D9060, and closed in the D9090 to select a 4-head vs.
4696-head drive. The jumper J13 seems to be unused.
470
471****************************************************************************/
472
473#define D9090_ROM( cpu )   \
474   ROM_REGION( 0x10800, cpu, 0 )   \
475   ROM_SYSTEM_BIOS( 0, "reva", "D9090 rev. A" )   \
476   ROMX_LOAD( "300516-revb.7c", 0xc000, 0x2000, CRC(2d758a14), ROM_BIOS(1) )   /* No Rev A available for this! */   \
477   ROMX_LOAD( "300517-reva.7d", 0xe000, 0x2000, CRC(566df630), ROM_BIOS(1) )   \
478   ROMX_LOAD( "300515-reva.4c", 0x10000, 0x800, CRC(99e096f7), ROM_BIOS(1) )   /* Floppy Disc Controller Rev. A - label "300515 Rev A" */   \
479   ROM_SYSTEM_BIOS( 1, "revb", "D9090 rev. B" )   \
480   ROMX_LOAD( "300516-revb.7c", 0xc000, 0x2000, CRC(2d758a14), ROM_BIOS(2) )   \
481   ROMX_LOAD( "300517-revb.7d", 0xe000, 0x2000, CRC(f0382bc3), ROM_BIOS(2) )   \
482   ROMX_LOAD( "300515-revb.4c", 0x10000, 0x800, CRC(49adf4fb), ROM_BIOS(2) )   /* Floppy Disc Controller Rev. B - label "300515 Rev B" or "300515-001" */   \
483   ROM_SYSTEM_BIOS( 2, "revc", "D9090 rev. C" )   \
484   ROMX_LOAD( "300516-revc.7c", 0xc000, 0x2000, CRC(d6a3e88f), ROM_BIOS(3) )   \
485   ROMX_LOAD( "300517-revc.7d", 0xe000, 0x2000, CRC(2a9ad4ad), ROM_BIOS(3) )   \
486   ROMX_LOAD( "300515-revb.4c", 0x10000, 0x800, CRC(49adf4fb), ROM_BIOS(3) )   /* Floppy Disc Controller Rev. B - label "300515 Rev B" or "300515-001" */
487
488
489/****************************************************************************
490
491    Dual 8" floppy drive. Related to any other drive? What about 8060?
492
493****************************************************************************/
494
495#define C8280_ROM( cpu )   \
496   ROM_REGION( 0x10800, cpu, 0 )   \
497   ROM_LOAD( "300542-001.bin", 0xc000, 0x2000, CRC(3c6eee1e) )      \
498   ROM_LOAD( "300543-001.bin", 0xe000, 0x2000, CRC(f58e665e) )      \
499   ROM_LOAD( "300541-001.bin", 0x10000, 0x800, CRC(cb07b2db) )   /* GCR encoding/decoding tables? */
500
501
502
503#if 0
504   ROM_LOAD("dos2040",  0x?000, 0x2000, CRC(d04c1fbb))
505
506   ROM_LOAD("dos3040",  0x?000, 0x3000, CRC(f4967a7f))
507
508   ROM_LOAD("dos4040",  0x?000, 0x3000, CRC(40e0ebaa))
509
510   ROM_LOAD("dos1001",  0xc000, 0x4000, CRC(87e6a94e))
511
512   /* dolphin vc1541 */
513   ROM_LOAD("c1541.rom",  0xa000, 0x6000, CRC(bd8e42b2))
514
515   /* modified drive 0x2000-0x3ffe ram, 0x3fff 6529 */
516   ROM_LOAD("1581rom5.bin",  0x8000, 0x8000, CRC(e08801d7))
517
518   ROM_LOAD("",  0xc000, 0x4000, CRC())
519#endif
520
521#endif /* VC1541_H_ */
src/mess/includes/cbmdrive.h
r6732r6733
1/*****************************************************************************
2 *
3 * includes/cbmdrive.h
4 *
5 * commodore cbm floppy drives vc1541 c1551
6 * synthetic simulation
7 *
8 * contains state machines and file system accesses
9 *
10 ****************************************************************************/
11
12#ifndef CBMDRIVE_H_
13#define CBMDRIVE_H_
14
15
16#define IEC 1
17#define SERIAL 2
18#define IEEE 3
19
20
21/*----------- defined in machine/cbmdrive.c -----------*/
22
23/* data for one drive */
24typedef struct
25{
26   int interface;
27   unsigned char cmdbuffer[32];
28   int cmdpos;
29#define OPEN 1
30#define READING 2
31#define WRITING 3
32   int state;                     /*0 nothing */
33   unsigned char *buffer;
34   int size;
35   int pos;
36   union
37   {
38      struct
39      {
40         int handshakein, handshakeout;
41         int datain, dataout;
42         int status;
43         int state;
44      }
45      iec;
46      struct
47      {
48         int device;
49         int data, clock, atn;
50         int state, value;
51         int forme;               /* i am selected */
52         int last;               /* last byte to be sent */
53         int broadcast;            /* sent to all */
54         attotime time;
55      }
56      serial;
57      struct
58      {
59         int device;
60         int state;
61         UINT8 data;
62      } ieee;
63   }
64   i;
65#define D64_IMAGE 1
66   int drive;
67   unsigned char *image;      /*d64 image */
68
69   char filename[20];
70}
71CBM_Drive;
72
73extern CBM_Drive cbm_drive[2];
74
75
76typedef struct
77{
78   int count;
79   CBM_Drive *drives[4];
80   /* whole + computer + drives */
81   int /*reset, request[6], */ data[6], clock[6], atn[6];
82}
83CBM_Serial;
84
85extern CBM_Serial cbm_serial;
86
87
88void cbm_drive_open_helper(void);
89void c1551_state(running_machine *machine, CBM_Drive * drive);
90void vc1541_state(running_machine *machine, CBM_Drive * drive);
91void c2031_state(running_machine *machine, CBM_Drive *drive);
92
93void cbm_drive_0_config(int interface, int serialnr);
94void cbm_drive_1_config(int interface, int serialnr);
95
96
97/* IEC interface for c16 with c1551 */
98
99/* To be passed directly to the drivers */
100WRITE8_DEVICE_HANDLER( c1551_0_write_data );
101READ8_DEVICE_HANDLER( c1551_0_read_data );
102WRITE8_DEVICE_HANDLER( c1551_0_write_handshake );
103READ8_DEVICE_HANDLER( c1551_0_read_handshake );
104READ8_DEVICE_HANDLER( c1551_0_read_status );
105
106WRITE8_DEVICE_HANDLER( c1551_1_write_data );
107READ8_DEVICE_HANDLER( c1551_1_read_data );
108WRITE8_DEVICE_HANDLER( c1551_1_write_handshake );
109READ8_DEVICE_HANDLER( c1551_1_read_handshake );
110READ8_DEVICE_HANDLER( c1551_1_read_status );
111
112
113MACHINE_DRIVER_EXTERN( simulated_drive );
114
115void cbmfloppy_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info);
116
117
118#endif /* CBMDRIVE_H_ */
src/mess/machine/vc1541.c
r6732r6733
1/***************************************************************************
2
3       commodore vc1541 floppy disk drive
4
5***************************************************************************/
6
7/*
8 vc1540
9  higher serial bus timing than the vc1541, to fast for c64
10 vc1541
11  (also build in in sx64)
12  used with commodore vc20, c64, c16, c128
13  floppy disk drive 5 1/4 inch, single sided, double density,
14   40 tracks (tone head to big to use 80 tracks?)
15  gcr encoding
16
17  computer M6502, 2x VIA6522, 2 KByte RAM, 16 KByte ROM
18  1 Commodore serial bus (2 connectors)
19
20 vc1541 ieee488 hardware modification
21  additional ieee488 connection, modified rom
22
23 vc1541 II
24  ?
25
26 dolphin drives
27  vc1541 clone?
28  additional 8 KByte RAM at 0x8000 (complete track buffer ?)
29  24 KByte rom
30
31 c1551
32  used with commodore c16
33  m6510t? processor (4 MHz???),
34  (m6510t internal 4 MHz clock?, 8 port pins?)
35  VIA6522 ?, CIA6526 ?,
36  2 KByte RAM, 16 KByte ROM
37  connector commodore C16 expansion cartridge
38  parallel protocoll
39
40 1750
41  single sided 1751
42 1751
43  (also build in in c128d series)
44  used with c128 (vic20,c16,c64 possible?)
45  double sided
46  can read some other disk formats (mfm encoded?)
47  modified commodore serial bus (with quick serial transmission)
48  (m6510?, cia6526?)
490000-00FF      Zero page work area, job queue, variables
500100-01FF      GCR overflow area and stack (1571 mode BAM side 1)
510200-02FF      Command buffer, parser, tables, variables
520300-07FF      5 data buffers, 0-4 one of which is used for BAM
531800-1BFF      65C22A, serial, controller ports
541C00-1FFF      65C22A, controller ports
558000-FFE5      32K byte ROM, DOS and controller routines
56FFE6-FFFF      JMP table, user command vectors
57
58 1581
59  3 1/2 inch, double sided, double density, 80 tracks
60  used with c128 (vic20,c16,c64 possible?)
61  only mfm encoding?
620000-00FF       Zero page work area, job queue, variables
630100-01FF       Stack, variables, vectors
640200-02FF       Command buffer, tables, variables
650300-09FF       Data buffers (0-6)
660A00-0AFF       BAM for tracks 0-39
670B00-0BFF       BAM for tracks 40-79
680C00-1FFF       Track cache buffer
694000-5FFF       8520A CIA
706000-7FFF       WD177X FDC
718000-FEFF       32K byte ROM, DOS and controller routines
72FF00-FFFF       Jump table, vectors
73
74 2031/4031
75 ieee488 interface
76 1541 with ieee488 bus instead of serial bus
77  $1800 via6522 used for ieee488 interface?
78  maybe like in pet series?
79   port a data in/out?
80   port b ce port, ddr 31
81
82 2040/3040
83 ieee488 interface
84 2 drives
85
86 2041
87 ieee488 interface
88
89 4040
90 ieee488 interface
91 2 drives
92
93 sfd1001
94 ieee488 interface
95 5 1/4 inch high density
96 2 heads
97
98 */
99/* 2008-09 FP
100Started some work on the floppy emulation code:
101    + made the functions / structs less vc1541-centric & d64-centric
102    + unified config & reset functions, using type variable
103        to choose the actions to be done
104    + moved GCR encoding at loading time (wip untested code)
105
106A limitation is clear: only a single occurrence of emulated drive
107is expected.
108At a later stage, at least drive_config & drive_reset will need
109an index to choose between the drives
110In the end, we could also split the floppy drives emulation from the
111disk image handling...
112
113Current status:
114    + preliminary vc1541 & c1551 implementation (quite slow, especially
115        if you turn on logging)
116    + no support for other drive types (even if now I list all
117        the variants supported by Vice in the enum)
118    + communications between the drive CPU and the computer CPU have
119        to be checked, debugged and improved: somehow it works, but no
120        sync bit is set (encoding bug? timers-related bug?) and the drive
121        keeps reading beyond the end of the track (synchronization
122        problems?)
123    + all but .g64 images should be correctly encoded at loading time
124        (I actually have doubts about some .d82 details)
125    + error maps are not still used, even if their presence is
126        acknowledged
127    + floppy drives should become devices and use ROMREGION_LOADBYNAME
128        for their ROMs (not the current defines)
129    + all available drive dumps are included for each systems using it
130        (vc1541 = sx64, vip64, c16v, plus4v; vc1571 = c128d; vc1571cr = c128dcr;
131        vc1581 = c128d81; vc1540 = vc20v, vic20plv; c2031 = vc20i (only dumps added);
132        c1551 = c16c, plus4c). this is only a temporary workaround to document
133        available dumps. correct revisions will be used with each systems when
134        emulation works (or 'default' bios will be used for most common
135        configurations, when machines were compatible with more than a single
136        drive model)
137*/
138/*
139Informations on the fileformats (which the code is based on)
140
141D64 - http://ist.uwaterloo.ca/~schepers/formats/D64.TXT
142D71 - http://ist.uwaterloo.ca/~schepers/formats/D71.TXT
143D81 - http://ist.uwaterloo.ca/~schepers/formats/D81.TXT
144D80 & D82 - http://ist.uwaterloo.ca/~schepers/formats/D80-D82.TXT
145G64 & GCR - http://ist.uwaterloo.ca/~schepers/formats/G64.TXT
146GCR - http://www.baltissen.org/newhtm/1541c.htm
147
148Other info sources:
149    http://sta.c64.org/cbm1541mem.html
150
151*/
152
153
154#include "driver.h"
155#include "image.h"
156#include "cpu/m6502/m6502.h"
157#include "machine/6525tpi.h"
158#include "machine/6522via.h"
159#include "includes/cbmserb.h"
160
161#include "includes/vc1541.h"
162
163
164#define VERBOSE_LEVEL 0
165#define DBG_LOG( MACHINE, N, M, A ) \
166   do { \
167      if(VERBOSE_LEVEL >= N) \
168      { \
169         if( M ) \
170            logerror("%11.6f: %-24s", attotime_to_double(timer_get_time(MACHINE)), (char*) M ); \
171         logerror A; \
172      } \
173   } while (0)
174
175#define XTAL_16_MHz   16000000
176
177
178/*
179 * only for testing at the moment
180 */
181
182#define WRITEPROTECTED 0
183
184
185/*******************************************
186
187    Structures
188
189*******************************************/
190
191/* Legacy code. At a later stage, we should convert everything to devices.
192However, fixing the C64 / Floppy drive communications is a priority over
193cleaning up of this part */
194
195
196/* 0 summarized, 1 computer, 2 vc1541 */
197static struct
198{
199   int atn[3], data[3], clock[3];
200}
201serial;
202
203typedef struct
204{
205   int sync;            // active after > 9 '1's
206   int ones_count;
207   int ready;            // needed for 1551
208   UINT8 *data;         // entire d64 image encoded at loading time
209} GCR_data;
210
211typedef struct
212{
213   const char *cputag;
214   int type;
215
216   int led, motor, frequency;
217
218   double track;
219   int clock;
220   int start_pos, pos;      // start_pos = start of half track ; pos = position from the beginning of the current half-track!
221
222   void *timer;
223
224   GCR_data gcr;
225
226   /* vc1541 specific */
227   struct {
228      int deviceid;
229      int serial_atn, serial_clock, serial_data;
230      int acka, data;
231   } vc1541_serial;
232
233   int via0irq, via1irq;
234
235} _vc1541_drive_emu_t;
236
237typedef struct
238{
239   const char *cputag;
240   int type;
241
242   int led, motor, frequency;
243
244   double track;
245   int clock;
246   int start_pos, pos;      // start_pos = start of half track ; pos = position from the beginning of the current half-track!
247
248   void *timer;
249
250   GCR_data gcr;
251
252   /* c1551 specific */
253   UINT8 cpu_ddr, cpu_port;
254   void *irq_timer;
255
256} _c1551_drive_emu_t;
257
258static _vc1541_drive_emu_t vc1541_drive;
259static _c1551_drive_emu_t c1551_drive;
260
261
262/*******************************************
263
264    Format specific code
265
266*******************************************/
267
268
269/* Are there other formats to support which could require more tracks? */
270#define IMAGE_MAX_TRACKS 154
271
272#define D64_MAX_TRACKS 35
273#define D64_40T_MAX_TRACKS 40
274
275static const int d64_sectors_per_track[] =
276{
277   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
278   19, 19, 19, 19, 19, 19, 19,
279   18, 18, 18, 18, 18, 18,
280   17, 17, 17, 17, 17,
281   17, 17, 17, 17, 17,      /* only for 40 tracks d64 */
282   17, 17            /* in principle the drive could read 42 tracks */
283};
284
285#define D71_MAX_TRACKS 70
286
287static const int d71_sectors_per_track[] =
288{
289   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
290   19, 19, 19, 19, 19, 19, 19,
291   18, 18, 18, 18, 18, 18,
292   17, 17, 17, 17, 17,
293   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
294   19, 19, 19, 19, 19, 19, 19,
295   18, 18, 18, 18, 18, 18,
296   17, 17, 17, 17, 17
297};
298
299#define D81_MAX_TRACKS 80
300
301/* Each track in a d81 file has 40 sectors, so no need of a sectors_per_track table */
302
303#define D80_MAX_TRACKS 77
304
305static const int d80_sectors_per_track[] =
306{
307   29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
308   29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
309   27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
310   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
311   23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23
312};
313
314
315/* Still have to investigate if these are read as 154 or as 77 in the drive... */
316/* For now we assume it's 154, but I'm not sure */
317#define D82_MAX_TRACKS 154
318
319static const int d82_sectors_per_track[] =
320{
321   29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
322   29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
323   27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
324   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
325   23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
326   29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
327   29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
328   27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
329   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
330   23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23
331};
332
333
334static const int max_tracks_per_format[] =
335{
336   D64_MAX_TRACKS,
337   D64_MAX_TRACKS,
338   D64_40T_MAX_TRACKS,
339   D64_40T_MAX_TRACKS,
340   D64_MAX_TRACKS,
341   D71_MAX_TRACKS,
342   D71_MAX_TRACKS,
343   D81_MAX_TRACKS,
344   D80_MAX_TRACKS,
345   D82_MAX_TRACKS,
346   0      /* Still to add support for .g64 */
347};
348
349static int image_offset[IMAGE_MAX_TRACKS];
350static int gcr_offset[IMAGE_MAX_TRACKS];
351
352/*******************************************
353
354    Offset initialization
355
356*******************************************/
357
358/* This is twice useful: with length = 256, it allows to determine the starting offset of each
359track in the .d64 image; with length = 368, it allows to determine the starting offset of each
360track in the GCR encoded image  */
361static void offset_init( int format, int *offset_list, int length )
362{
363   int i;
364
365   /* Track # starts from 1, hence Track k will start at image_offset[k-1] */
366   offset_list[0] = 0;
367
368   switch (format)
369   {
370      case format_d64:
371      case format_d64_err:
372      case format_d67:
373         for (i = 1; i < D64_MAX_TRACKS; i++)
374            offset_list[i] = offset_list[i - 1] + d64_sectors_per_track[i - 1] * length;
375         break;
376
377      case format_d64_40t:
378      case format_d64_40t_err:
379         for (i = 1; i < D64_40T_MAX_TRACKS; i++)
380            offset_list[i] = offset_list[i - 1] + d64_sectors_per_track[i - 1] * length;
381         break;
382
383      case format_d71:
384      case format_d71_err:
385         for (i = 1; i < D71_MAX_TRACKS; i++)
386            offset_list[i] = offset_list[i - 1] + d71_sectors_per_track[i - 1] * length;
387         break;
388
389      case format_d81:
390         for (i = 1; i < D81_MAX_TRACKS; i++)
391            offset_list[i] = offset_list[i - 1] + 40 * length;
392         break;
393
394      case format_d80:
395         for (i = 1; i < D80_MAX_TRACKS; i++)
396            offset_list[i] = offset_list[i - 1] + d80_sectors_per_track[i - 1] * length;
397         break;
398
399      case format_d82:
400         for (i = 1; i < D82_MAX_TRACKS; i++)
401            offset_list[i] = offset_list[i - 1] + d82_sectors_per_track[i - 1] * length;
402         break;
403
404      default:
405         /* Still have to work on g64 images */
406         logerror("Unsupported format\n");
407         break;
408   }
409}
410
411
412/*******************************************
413
414    Generic image handling
415
416*******************************************/
417
418
419/* This calculates starting offset (from the beginning of the image file) of a sector */
420/* Since sectors are always 256 bytes large, this works no matter the file format! */
421static int image_tracksector2offset( int track, int sector )
422{
423   return image_offset[track - 1] + sector * 256;
424}
425
426#ifdef UNUSED_FUNCTION
427// WARNING: this would work with a d64 image... it has to be adapted to work with GCR image we store at loading time
428static void image_offset2tracksector( int offset )
429{
430    int track = 0, sector = 0, helper, i = 0;
431
432    helper = offset;
433
434    do
435    {
436        helper -= (d64_sectors_per_track[++i] * 256);
437    } while (helper > 0);
438
439    track = i;
440
441    sector = (offset - image_offset[track]) / 256;
442
443    logerror("We are reading at offset %d, which is in track %d and sector %d \n", offset, track, sector);
444}
445#endif
446
447
448/* These functions return the Disk ID stored in the disk BAM */
449/* It is not necessarily the one some copy protection checks, and
450   indeed, in these cases a g64 image is needed (which stores the
451   Disk ID as coded in the GCR data) */
452
453static int disk_id1( int format )
454{
455   int id1 = 0;
456
457   switch (format)
458   {
459      case format_d64:
460      case format_d64_err:
461      case format_d64_40t:
462      case format_d64_40t_err:
463      case format_d67:
464      case format_d71:
465      case format_d71_err:
466         id1 = image_tracksector2offset(18, 0) + 0xa2;
467         break;
468
469      case format_d81:
470         id1 = image_tracksector2offset(40, 0) + 0x16;
471         break;
472
473      case format_d80:
474      case format_d82:
475         id1 = image_tracksector2offset(39, 0) + 0x18;
476         break;
477
478      default:
479         /* Still have to work on g64 images */
480         logerror("Unsupported format\n");
481         break;
482   }
483
484   return id1;
485}
486
487
488static int disk_id2( int format )
489{
490   int id2 = 0;
491
492   switch (format)
493   {
494      case format_d64:
495      case format_d64_err:
496      case format_d64_40t:
497      case format_d64_40t_err:
498      case format_d67:
499      case format_d71:
500      case format_d71_err:
501         id2 = image_tracksector2offset(18, 0) + 0xa3;
502         break;
503
504      case format_d81:
505         id2 = image_tracksector2offset(40, 0) + 0x17;
506         break;
507
508      case format_d80:
509      case format_d82:
510         id2 = image_tracksector2offset(39, 0) + 0x19;
511         break;
512
513      default:
514         /* Still have to work on g64 images */
515         logerror("Unsupported format\n");
516         break;
517   }
518
519   return id2;
520}
521
522
523/* Four different frequencies for the 4 different zones on the disk */
524/* These work for 1541 drives, are the same for other drives? */
525static const double drive_times[4]=
526{
527   XTAL_16_MHz / 13, XTAL_16_MHz / 14, XTAL_16_MHz / 15, XTAL_16_MHz / 16
528};
529
530
531/* Commodore GCR format */
532/*
533Original    Encoded
5344 bits      5 bits
535
5360000    ->  01010 = 0x0a
5370001    ->  01011 = 0x0b
5380010    ->  10010 = 0x12
5390011    ->  10011 = 0x13
5400100    ->  01110 = 0x0e
5410101    ->  01111 = 0x0f
5420110    ->  10110 = 0x16
5430111    ->  10111 = 0x17
5441000    ->  01001 = 0x09
5451001    ->  11001 = 0x19
5461010    ->  11010 = 0x1a
5471011    ->  11011 = 0x1b
5481100    ->  01101 = 0x0d
5491101    ->  11101 = 0x1d
5501110    ->  11110 = 0x1e
5511111    ->  10101 = 0x15
552
553We use the encoded values in bytes because we use them to encode
554groups of 4 bytes into groups of 5 bytes, below.
555*/
556
557static const int bin_2_gcr[] =
558{
559   0x0a, 0x0b, 0x12, 0x13, 0x0e, 0x0f, 0x16, 0x17,
560   0x09, 0x19, 0x1a, 0x1b, 0x0d, 0x1d, 0x1e, 0x15
561};
562
563
564/* This could be of use if we ever implement saving in .d64 format, to convert back GCR -> d64 */
565#if 0
566static const int gcr_2_bin[] =
567{
568    -1, -1,   -1,   -1,
569    -1, -1,   -1,   -1,
570    -1, 0x08, 0x00, 0x01,
571    -1, 0x0c, 0x04, 0x05,
572    -1, -1,   0x02, 0x03,
573    -1, 0x0f, 0x06, 0x07,
574    -1, 0x09, 0x0a, 0x0b,
575    -1, 0x0d, 0x0e, -1
576};
577#endif
578
579
580/* gcr_double_2_gcr takes 4 bytes (a, b, c, d) and shuffles their nibbles to obtain 5 bytes in dest */
581/* The result is basically res = (enc(a) << 15) | (enc(b) << 10) | (enc(c) << 5) | enc(d)
582 * with res being 5 bytes long and enc(x) being the GCR encode of x.
583 * In fact, we store the result as five separate bytes in the dest argument
584 */
585static void gcr_double_2_gcr( UINT8 a, UINT8 b, UINT8 c, UINT8 d, UINT8 *dest )
586{
587   UINT8 gcr[8];
588
589   /* Encode each nibble to 5 bits */
590   gcr[0] = bin_2_gcr[a >> 4];
591   gcr[1] = bin_2_gcr[a & 0x0f];
592   gcr[2] = bin_2_gcr[b >> 4];
593   gcr[3] = bin_2_gcr[b & 0x0f];
594   gcr[4] = bin_2_gcr[c >> 4];
595   gcr[5] = bin_2_gcr[c & 0x0f];
596   gcr[6] = bin_2_gcr[d >> 4];
597   gcr[7] = bin_2_gcr[d & 0x0f];
598
599   /* Re-order the encoded data to only keep the 5 lower bits of each byte */
600   dest[0] = (gcr[0] << 3) | (gcr[1] >> 2);
601   dest[1] = (gcr[1] << 6) | (gcr[2] << 1) | (gcr[3] >> 4);
602   dest[2] = (gcr[3] << 4) | (gcr[4] >> 1);
603   dest[3] = (gcr[4] << 7) | (gcr[5] << 2) | (gcr[6] >> 3);
604   dest[4] = (gcr[6] << 5) | gcr[7];
605}
606
607/* FIXME: temp workaround */
608static void filling_byte( UINT8 a, UINT8 *dest )
609{
610   dest[0] = a;
611}
612
613
614/**************************************
615
616    Drive timers (aka floppy reading)
617
618**************************************/
619
620static TIMER_CALLBACK( vc1541_drive_timer )
621{
622   const device_config *via_1 = devtag_get_device(machine, "_1541_via_1");
623
624   if (vc1541_drive.clock == 0)
625   {
626      vc1541_drive.gcr.ready = 0;
627      // why put sync back to 0 here?!? it would break the sync count, isn't it?
628      // or is it the way the serial port reads the sync count?!?
629      vc1541_drive.gcr.sync = 0;
630
631      cputag_set_input_line(machine, vc1541_drive.cputag, M6502_SET_OVERFLOW, 1);
632      via_ca1_w(via_1, 0, 1);
633
634      vc1541_drive.clock = 1;
635      return;
636   }
637
638   // this code has 2 effects: move on the pos on the data and reset it to 0 at the end of the track!
639   // size of the track is: (# sectors in the track) * (size of sector GCR endoded)
640   // Here, size of sector is 368 because of our choices in the loading: 9 bytes of header gap & 14 bytes of sector gap
641   // We will need to set the size at loading time when adding support for G64 images
642   if (++(vc1541_drive.pos) >= (d64_sectors_per_track[(int)vc1541_drive.track - 1] * 368))
643      vc1541_drive.pos = 0;
644   // should we check if there is a change of track? to reset the pos in that case as well?
645
646   vc1541_drive.gcr.ready = 1;
647
648   // notice that if there is a sequence of more than 40 1s it correctly does not reset the sync
649   // counter until a 0 is found
650   if (vc1541_drive.gcr.data[vc1541_drive.pos] == 0xff)
651   {
652      vc1541_drive.gcr.ones_count++;
653
654//      if (vc1541_drive.gcr.ones_count == 2) // 9 ones should already mark it as a sync, even if CBM chose to use 40 of them
655      if (vc1541_drive.gcr.ones_count == 5)
656         vc1541_drive.gcr.sync = 1;
657   }
658   else
659   {
660      vc1541_drive.gcr.ones_count = 0;
661      vc1541_drive.gcr.sync = 0;
662   }
663
664   cputag_set_input_line(machine, vc1541_drive.cputag, M6502_SET_OVERFLOW, 0);
665   via_ca1_w(via_1, 0, 0);
666
667   vc1541_drive.clock = 0;
668}
669
670static TIMER_CALLBACK( c1551_drive_timer )
671{
672   if (c1551_drive.clock == 0)
673   {
674      c1551_drive.gcr.ready = 0;
675      // why put sync back to 0 here?!? it would break the sync count, isn't it?
676      // or is it the way the serial port reads the sync count?!?
677      c1551_drive.gcr.sync = 0;
678
679      c1551_drive.clock = 1;
680      return;
681   }
682
683   // this code has 2 effects: move on the pos on the data and reset it to 0 at the end of the track!
684   // size of the track is: (# sectors in the track) * (size of sector GCR endoded)
685   // Here, size of sector is 368 because of our choices in the loading: 9 bytes of header gap & 14 bytes of sector gap
686   // We will need to set the size at loading time when adding support for G64 images
687   if (++(c1551_drive.pos) >= (d64_sectors_per_track[(int)c1551_drive.track - 1] * 368))
688      c1551_drive.pos = 0;
689   // should we check if there is a change of track? to reset the pos in that case as well?
690
691   c1551_drive.gcr.ready = 1;
692
693   // notice that if there is a sequence of more than 40 1s it correctly does not reset the sync
694   // counter until a 0 is found
695   if (c1551_drive.gcr.data[c1551_drive.pos] == 0xff)
696   {
697      c1551_drive.gcr.ones_count++;
698
699//      if (c1551_drive.gcr.ones_count == 2) // 9 ones should already mark it as a sync, even if CBM chose to use 40 of them
700      if (c1551_drive.gcr.ones_count == 5)
701         c1551_drive.gcr.sync = 1;
702   }
703   else
704   {
705      c1551_drive.gcr.ones_count = 0;
706      c1551_drive.gcr.sync = 0;
707   }
708
709   c1551_drive.clock = 0;
710}
711
712
713/**************************************
714
715    VC1541 Serial Bus Device Interface
716
717**************************************/
718
719/* 2009-05 FP - Note: I could use directly these functions as DEVICE_HANDLERs for
720the serial bus device, but these are also used in the VIA interface above, so I
721prefer to keep the handlers separated at this stage. Further work on the serial
722bus emulation should allow to remove the duplicated code. */
723
724static void vc1541_serial_reset_write( running_machine *machine, int which, int level )
725{
726}
727
728static UINT8 vc1541_serial_atn_read( running_machine *machine, int which )
729{
730/* there is no more cpu_getactivecpu! */
731#ifdef CPU_SYNC
732      if (cpu_getactivecpu()==0) cpu_sync();
733#endif
734   return serial.atn[0];
735}
736
737static void vc1541_serial_atn_write( running_machine *machine, int which, int level )
738{
739   const device_config *via_0 = devtag_get_device(machine, "_1541_via_0");
740#if 0
741   int value;
742#endif
743   if (serial.atn[1 + which] != level)
744   {
745/* there is no more cpu_getactivecpu! */
746#ifdef CPU_SYNC
747      if (cpu_getactivecpu()==0) cpu_sync();
748#endif
749      serial.atn[1 + which] = level;
750      if (serial.atn[0] != level)
751      {
752         serial.atn[0] = serial.atn[1] && serial.atn[2];
753         if (serial.atn[0] == level)
754         {
755         #if 0
756            DBG_LOG(machine, 1, "vc1541",("%d:%.4x atn %s\n",
757                            cpu_getactivecpu (),
758                            activecpu_get_pc(),
759                            serial.atn[0]?"ATN":"atn"));
760         #endif
761            via_ca1_w (via_0, 0, !level);
762#if 0
763            value = vc1541_drive.vc1541_serial.data;
764            if (vc1541_drive.vc1541_serial.acka != !level)
765               value = 0;
766            if (value != serial.data[2])
767            {
768               serial.data[2] = value;
769               if (serial.data[0] != value)
770               {
771                  serial.data[0] = serial.data[1] && serial.data[2];
772               }
773            }
774#endif
775         }
776      }
777   }
778}
779
780static UINT8 vc1541_serial_data_read( running_machine *machine, int which )
781{
782/* there is no more cpu_getactivecpu! */
783#ifdef CPU_SYNC
784      if (cpu_getactivecpu()==0) cpu_sync();
785#endif
786   return serial.data[0];
787}
788
789static void vc1541_serial_data_write( running_machine *machine, int which, int level )
790{
791   if (serial.data[1 + which] != level)
792   {
793/* there is no more cpu_getactivecpu! */
794#ifdef CPU_SYNC
795      if (cpu_getactivecpu()==0) cpu_sync();
796#endif
797      serial.data[1 + which] = level;
798      if (serial.data[0] != level)
799      {
800         serial.data[0] = serial.data[1] && serial.data[2];
801         #if 0
802         if (serial.data[0] == level)
803         {
804            DBG_LOG(machine, 1, "vc1541",("%d:%.4x data %s\n",
805                            cpu_getactivecpu (),
806                            activecpu_get_pc(),
807                            serial.data[0]?"DATA":"data"));
808         }
809         #endif
810      }
811   }
812}
813
814static UINT8 vc1541_serial_clock_read( running_machine *machine, int which )
815{
816/* there is no more cpu_getactivecpu! */
817#ifdef CPU_SYNC
818      if (cpu_getactivecpu()==0) cpu_sync();
819#endif
820   return serial.clock[0];
821}
822
823static void vc1541_serial_clock_write( running_machine *machine, int which, int level )
824{
825   if (serial.clock[1 + which] != level)
826   {
827/* there is no more cpu_getactivecpu! */
828#ifdef CPU_SYNC
829      if (cpu_getactivecpu()==0) cpu_sync();
830#endif
831      serial.clock[1 + which] = level;
832      if (serial.clock[0] != level)
833      {
834         serial.clock[0] = serial.clock[1] && serial.clock[2];
835         if (serial.clock[0] == level)
836         {
837/*              DBG_LOG(machine, 1, "vc1541",("%d:%.4x clock %s\n",
838                                     cpu_getactivecpu (),
839                                     activecpu_get_pc(),
840                                     serial.clock[0]?"CLOCK":"clock"));*/
841         }
842      }
843   }
844}
845
846static UINT8 vc1541_serial_request_read( running_machine *machine, int which )
847{
848   return 1;
849}
850
851static void vc1541_serial_request_write( running_machine *machine, int which, int level )
852{
853}
854
855
856/* 2009-05 FP - TODO: better implementation of the DEVICE_HANDLERs below. Right now they are
857redundant (see also my Note above)  */
858static READ8_DEVICE_HANDLER( emu_drive_atn_read )
859{
860   return vc1541_serial_atn_read(device->machine, 0);
861}
862
863static READ8_DEVICE_HANDLER( emu_drive_clock_read )
864{
865   return vc1541_serial_clock_read(device->machine, 0);
866}
867
868static READ8_DEVICE_HANDLER( emu_drive_data_read )
869{
870   return vc1541_serial_data_read(device->machine, 0);
871}
872
873static READ8_DEVICE_HANDLER( emu_drive_request_read )
874{
875   return vc1541_serial_request_read(device->machine, 0);
876}
877
878static WRITE8_DEVICE_HANDLER( emu_drive_atn_write )
879{
880   vc1541_serial_atn_write(device->machine, 0, data);
881}
882
883static WRITE8_DEVICE_HANDLER( emu_drive_clock_write )
884{
885   vc1541_serial_clock_write(device->machine, 0, data);
886}
887
888static WRITE8_DEVICE_HANDLER( emu_drive_data_write )
889{
890   vc1541_serial_data_write(device->machine, 0, data);
891}
892
893static WRITE8_DEVICE_HANDLER( emu_drive_request_write )
894{
895   vc1541_serial_request_write(device->machine, 0, data);
896}
897
898static WRITE8_DEVICE_HANDLER( emu_drive_reset_write )
899{
900   vc1541_serial_reset_write(device->machine, 0, data);
901}
902
903
904static const cbm_serial_bus_interface cbm_emu_drive_interface =
905{
906   DEVCB_HANDLER(emu_drive_atn_read),
907   DEVCB_HANDLER(emu_drive_clock_read),
908   DEVCB_HANDLER(emu_drive_data_read),
909   DEVCB_HANDLER(emu_drive_request_read),
910   DEVCB_HANDLER(emu_drive_atn_write),
911   DEVCB_HANDLER(emu_drive_clock_write),
912   DEVCB_HANDLER(emu_drive_data_write),
913   DEVCB_HANDLER(emu_drive_request_write),
914
915   DEVCB_HANDLER(emu_drive_reset_write)
916};
917
918
919
920/**************************************************************************
921 *  VIA 6522 at 0x1800
922 *
923 *  0x1800  port B
924 *      bit 0 : data in (inverted: 0 = Low, 1 = High)
925 *      bit 1 : data out (inverted: 0 = Low, 1 = High)
926 *      bit 2 : clock in (inverted: 0 = Low, 1 = High)
927 *      bit 3 : clock out (inverted: 0 = Low, 1 = High)
928 *      bit 4 : atna out (inverted: 0 = Low, 1 = High)
929 *      bit 5 : device id 1
930 *      bit 6 : device id 2
931 *              device ID number is set by a jumper:
932 *              00 = 8 (default), 01 = 9, 10 = 10, 11 = 11
933 *      bit 7 : atn in (inverted: 0 = Low, 1 = High)
934 *  0x1801  port A - Read to acknowledge interrupt generated by ATN IN going high.
935 *  0x1802  port B data direction register.
936 *          if a bit here is 0, then the corresponding bit of portB can only be read
937 *          if a bit here is 1, then the corresponding bit of portB can be read and written
938 *          default value 0x1a
939 *  0x1803  port A data direction register.
940 *          default value 0xff
941 *  0x1804  timer 1 counter (low)
942 *  0x1805  timer 1 counter (high) / Timer one counter
943 *          Read low byte or write high byte to start timer or restart timer upon underflow.
944 *  0x1806  timer 1 latch (low)
945 *  0x1807  timer 1 latch (high)
946 *          read/write starting value of timer from/to here.
947 *  0x1808  timer 2 counter (low)
948 *  0x1809  timer 2 counter (high)
949 *  0x180a  shift register
950 *  0x180b  auxiliary control register. bit 6: 0 = Stop timer; 1 = Start timer.
951 *  0x180c  peripheral control register
952 *  0x180d  interrupt flag register. bit 1: 1 = ATN IN went high, bit 6: 1 = Timer underflow occurred.
953 *  0x180e  interrupt enable register.
954 *          bit 1: write -  1 = Enable interrupts generated by ATN IN going high
955 *          bit 7: read - interrupt has been generated.
956 *          bit 7: write - Fill bit: bits 0-6, that are set to 1, get their values from this bit; bits 0-6, that are set to 0, are left unchanged
957 *
958 * also ca1 (books says cb2)
959 * irq to m6502 irq connected (or with second via irq)
960 *
961 **************************************************************************/
962
963static void vc1541_via0_irq( const device_config *device, int level )
964{
965   vc1541_drive.via0irq = level;
966   DBG_LOG(device->machine, 2, "vc1541 via0 irq", ("level %d %d\n", vc1541_drive.via0irq, vc1541_drive.via1irq));
967
968   cputag_set_input_line(device->machine, vc1541_drive.cputag, M6502_IRQ_LINE, vc1541_drive.via1irq || vc1541_drive.via0irq);
969}
970
971static READ8_DEVICE_HANDLER( vc1541_via0_read_portb )
972{
973   int value = 0x7a;
974
975   if (!vc1541_drive.vc1541_serial.serial_data || !serial.data[0])
976      value |= 0x01;
977
978   if (!vc1541_drive.vc1541_serial.serial_clock || !serial.clock[0])
979      value |= 0x04;
980
981   if (!serial.atn[0])
982      value |= 0x80;
983
984   switch (vc1541_drive.vc1541_serial.deviceid)
985   {
986      case 8:
987         value &= ~0x60;
988         break;
989      case 9:
990         value &= ~0x40;
991         break;
992      case 10:
993         value &= ~0x20;
994         break;
995      case 11:
996         break;
997   }
998
999   return value;
1000}
1001
1002static WRITE8_DEVICE_HANDLER( vc1541_via0_write_portb )
1003{
1004   DBG_LOG(device->machine, 2, "vc1541 serial write", ("%s %s %s\n",
1005                            data & 0x10 ? "ATN"   : "atn",
1006                            data & 0x08 ? "CLOCK" : "clock",
1007                            data & 0x02 ? "DATA"  : "data"));
1008
1009   vc1541_drive.vc1541_serial.data = data & 0x02 ? 0 : 1;
1010   vc1541_drive.vc1541_serial.acka = data & 0x10 ? 1 : 0;
1011
1012   if ((!(data & 0x02)) != vc1541_drive.vc1541_serial.serial_data)
1013   {
1014      vc1541_serial_data_write(device->machine, 1, vc1541_drive.vc1541_serial.serial_data = !(data & 0x02));
1015   }
1016
1017   if ((!(data & 0x08)) != vc1541_drive.vc1541_serial.serial_clock)
1018   {
1019      vc1541_serial_clock_write(device->machine, 1, vc1541_drive.vc1541_serial.serial_clock = !(data & 0x08));
1020   }
1021
1022   vc1541_serial_atn_write(device->machine, 1, vc1541_drive.vc1541_serial.serial_atn = 1);
1023}
1024
1025static const via6522_interface vc1541_via0 =
1026{
1027   DEVCB_NULL,                           /*via0_read_porta, */
1028   DEVCB_HANDLER(vc1541_via0_read_portb),
1029   DEVCB_NULL,                           /*via0_read_ca1, */
1030   DEVCB_NULL,                           /*via0_read_cb1, */
1031   DEVCB_NULL,                           /*via0_read_ca2, */
1032   DEVCB_NULL,                           /*via0_read_cb2, */
1033   DEVCB_NULL,                           /*via0_write_porta, */
1034   DEVCB_HANDLER(vc1541_via0_write_portb),
1035   DEVCB_NULL,                                /*via0_write_ca1, */
1036   DEVCB_NULL,                                /*via0_write_cb1, */
1037   DEVCB_NULL,                           /*via0_write_ca2, */
1038   DEVCB_NULL,                           /*via0_write_cb2, */
1039   DEVCB_LINE(vc1541_via0_irq)
1040};
1041
1042
1043/**************************************************************************
1044 *  VIA 6522 at 0x1c00
1045 *
1046 *  0x1c00  port B - Disk controller i/o control line
1047 *      bit 0 : step head motor output 1
1048 *      bit 1 : step head motor output 2
1049 *      bit 2 : motor on output (0 = Off, 1 = On) - 300 revolutions per minute
1050 *      bit 3 : LED control output (0 = Off, 1 = On)
1051 *      bit 4 : write protect sense (0 = protected, 1 = unprotected)
1052 *      bit 5 : density select 0
1053 *      bit 6 : density select 1
1054 *          data density (track dependend): 00 = lowest (faster time), 11 = highest (slower timer)
1055 *      bit 7 : sync signal (more then nine 1 bits) detect
1056 *  0x1c01  Port A - byte in gcr format from or to floppy
1057 *  0x1c02  Port B data direction register + LED output - default 0x6f
1058 *  0x1c03  Port A data direction register - 0x00 read from disk, 0xff write to disk
1059 *  0x1c04  Timer 1 counter (low)
1060 *  0x1c05  Timer 1 counter (high)
1061 *          Read low byte or write high byte to start timer or restart timer upon underflow.
1062 *  0x1c06  Timer 1 latch (low)
1063 *  0x1c07  Timer 1 latch (high)
1064 *          read/write starting value of timer from/to here.
1065 *  0x1c08  Timer 2 latch (low)
1066 *  0x1c09  Timer 2 latch (high)
1067 *  0x1c0a  Shift register
1068 *  0x1c0b  Auxiliary control register. bit 6: 0 = Stop timer; 1 = Start timer.
1069 *  0x1c0c  Peripheral control register
1070 *  0x1c0d  Interrupt flag register. bit 6: 1 = Timer underflow occurred.
1071 *  0x1c0e  Interrupt enable register
1072 *          bit 6: write -  1 = Enable interrupts generated by timer underflow
1073 *          bit 7: read - interrupt has been generated.
1074 *          bit 7: write - Fill bit: bits 0-6, that are set to 1, get their values from this bit; bits 0-6, that are set to 0, are left unchanged
1075 *
1076 * ca1 byte ready input (also m6502 set overflow input)
1077 * ca2 set overflow enable for 6502
1078 * ca3 read/write
1079 *
1080 * irq to m6502 irq connected
1081 *
1082 **************************************************************************/
1083
1084
1085static void vc1541_via1_irq( const device_config *device, int level )
1086{
1087   vc1541_drive.via1irq = level;
1088   DBG_LOG(device->machine, 2, "vc1541 via1 irq", ("level %d %d\n", vc1541_drive.via0irq, vc1541_drive.via1irq));
1089
1090   cputag_set_input_line(device->machine, vc1541_drive.cputag, M6502_IRQ_LINE, vc1541_drive.via1irq || vc1541_drive.via0irq);
1091}
1092
1093static READ8_DEVICE_HANDLER( vc1541_via1_read_porta )
1094{
1095   UINT8 data = vc1541_drive.gcr.data[vc1541_drive.start_pos + vc1541_drive.pos];
1096
1097//  logerror("Data read: Track %.1f Pos %d\n", vc1541_drive.track, vc1541_drive.pos);
1098
1099   DBG_LOG(device->machine, 2, "vc1541 drive", ("port a read %.2x\n", data));
1100   return data;
1101}
1102
1103static WRITE8_DEVICE_HANDLER( vc1541_via1_write_porta )
1104{
1105   DBG_LOG(device->machine, 1, "vc1541 drive", ("port a write %.2x\n", data));
1106}
1107
1108static  READ8_DEVICE_HANDLER( vc1541_via1_read_portb )
1109{
1110   UINT8 value = 0xff;
1111
1112#if 0
1113   if (WRITEPROTECTED)
1114      value &= ~0x10;
1115#endif
1116
1117   if (vc1541_drive.gcr.sync)
1118   {
1119      value &= ~0x80;
1120   }
1121
1122   return value;
1123}
1124
1125static int old = 0;
1126
1127static WRITE8_DEVICE_HANDLER( vc1541_via1_write_portb )
1128{
1129   if (data != old)
1130   {
1131      DBG_LOG(device->machine, 1, "vc1541 drive",("%.2x\n", data));
1132
1133   /*  decrease value (%00-%11-%10-%01-%00...) to move head downwards; */
1134   /*  increase value (%00-%01-%10-%11-%00...) to move head upwards.   */
1135      if ((old & 0x03) != (data & 0x03))
1136      {
1137         switch (old & 0x03)
1138         {
1139         case 0:
1140            if ((data & 0x03) == 1)
1141               vc1541_drive.track += 0.5;
1142            else if ((data & 0x03) == 3)
1143               vc1541_drive.track -= 0.5;
1144            break;
1145
1146         case 1:
1147            if ((data & 0x03) == 2)
1148               vc1541_drive.track += 0.5;
1149            else if ((data & 0x03) == 0)
1150               vc1541_drive.track -= 0.5;
1151            break;
1152
1153         case 2:
1154            if ((data & 0x03) == 3)
1155               vc1541_drive.track += 0.5;
1156            else if ((data & 0x03) == 1)
1157               vc1541_drive.track -= 0.5;
1158            break;
1159
1160         case 3:
1161            if ((data & 0x03) == 0)
1162               vc1541_drive.track += 0.5;
1163            else if ((data & 0x03) == 2)
1164               vc1541_drive.track -= 0.5;
1165            break;
1166         }
1167
1168         /* If we have reached the first or last track, we cannot proceed further! */
1169         if (vc1541_drive.track < 1)
1170            vc1541_drive.track = 1.0;
1171         if (vc1541_drive.track > 35)
1172            vc1541_drive.track = 35.0;
1173
1174         logerror("Track #: %.1f\n", vc1541_drive.track);
1175
1176         /* We now adjust the vc1541_drive.pos according to the new track */
1177         /* This seems a simple way to deal with half tracks */
1178         vc1541_drive.pos = 0;
1179         vc1541_drive.start_pos = gcr_offset[(int)vc1541_drive.track - 1]            // starting point of Track #
1180            + (int)(2 * (vc1541_drive.track - (int)vc1541_drive.track)) * 184 / 2;   // half track if needed (again, 184 comes from out loading choices)
1181      }
1182
1183      if ((vc1541_drive.motor != (data & 0x04)) || (vc1541_drive.frequency != (data & 0x60)))
1184      {
1185         double tme;
1186         vc1541_drive.motor = data & 0x04;
1187         vc1541_drive.frequency = data & 0x60;
1188         tme = drive_times[vc1541_drive.frequency >> 5];
1189
1190         if (vc1541_drive.motor)
1191         {
1192            if (attotime_to_double(timer_timeelapsed(vc1541_drive.timer)) > 1.0e29)
1193            {
1194               timer_reset(vc1541_drive.timer, attotime_never);
1195            }
1196            else
1197            {
1198               timer_adjust_periodic(vc1541_drive.timer, attotime_zero, 0, ATTOTIME_IN_HZ(tme));
1199               logerror("Freq changed: %f\n", tme);
1200            }
1201         }
1202         else
1203         {
1204            timer_reset(vc1541_drive.timer, attotime_never);
1205            logerror("Motor turned off\n");
1206         }
1207      }
1208      old = data;
1209   }
1210
1211   vc1541_drive.led = data & 0x08;
1212}
1213
1214static const via6522_interface vc1541_via1 =
1215{
1216   DEVCB_HANDLER(vc1541_via1_read_porta),
1217   DEVCB_HANDLER(vc1541_via1_read_portb),
1218   DEVCB_NULL,                           /*via3_read_ca1, */
1219   DEVCB_NULL,                           /*via3_read_cb1, */
1220   DEVCB_NULL,                           /*via3_read_ca2, */
1221   DEVCB_NULL,                           /*via3_read_cb2, */
1222   DEVCB_HANDLER(vc1541_via1_write_porta),
1223   DEVCB_HANDLER(vc1541_via1_write_portb),
1224   DEVCB_NULL,                           /*via3_write_ca1, */
1225   DEVCB_NULL,                           /*via3_write_cb1, */
1226   DEVCB_NULL,                           /*via3_write_ca2, */
1227   DEVCB_NULL,                           /*via3_write_cb2, */
1228   DEVCB_LINE(vc1541_via1_irq)
1229};
1230
1231
1232/**************************************
1233
1234    1541 / 1541B / 1541C / 1541II /
1235        2031 (same as 1541 but IEEE)
1236
1237**************************************/
1238
1239static ADDRESS_MAP_START( _1541_map, ADDRESS_SPACE_PROGRAM, 8 )
1240   AM_RANGE(0x0000, 0x07ff) AM_RAM
1241   AM_RANGE(0x1800, 0x180f) AM_DEVREADWRITE("_1541_via_0", via_r, via_w)   /* 0 and 1 used in vc20 */   // IEC Bus
1242   AM_RANGE(0x1c00, 0x1c0f) AM_DEVREADWRITE("_1541_via_1", via_r, via_w)      // Drive
1243   AM_RANGE(0xc000, 0xffff) AM_ROM
1244ADDRESS_MAP_END
1245
1246
1247static ADDRESS_MAP_START( dolphin_map, ADDRESS_SPACE_PROGRAM, 8 )
1248   AM_RANGE(0x0000, 0x07ff) AM_RAM
1249   AM_RANGE(0x1800, 0x180f) AM_DEVREADWRITE("_1541_via_0", via_r, via_w)   /* 0 and 1 used in vc20 */
1250   AM_RANGE(0x1c00, 0x1c0f) AM_DEVREADWRITE("_1541_via_1", via_r, via_w)
1251   AM_RANGE(0x8000, 0x9fff) AM_RAM
1252   AM_RANGE(0xa000, 0xffff) AM_ROM
1253ADDRESS_MAP_END
1254
1255/**************************************
1256
1257    1570 / 1571 / 1571CR
1258
1259**************************************/
1260
1261static ADDRESS_MAP_START( _1571_map, ADDRESS_SPACE_PROGRAM, 8 )
1262   AM_RANGE(0x0000, 0x07ff) AM_RAM
1263   AM_RANGE(0x1800, 0x180f) AM_DEVREADWRITE("_1541_via_0", via_r, via_w)  /* 0 and 1 used in vc20 */
1264   AM_RANGE(0x1c00, 0x1c0f) AM_DEVREADWRITE("_1541_via_1", via_r, via_w)
1265//  AM_RANGE(0x2000, 0x2003) // WD17xx
1266//  AM_RANGE(0x4000, 0x400f) // CIA
1267   AM_RANGE(0x8000, 0xffff) AM_ROM
1268ADDRESS_MAP_END
1269
1270// for the C128DCR Drive
1271/*
1272David Gahris provided info about differences between 128DCR and stand-alone 1571s
1273
1274* There is no 6526 or 8521 in the drive section of the 128DCR.  I believe the
1275  5710 handles fast serial because the 5710 is a Commodore custom chip and
1276  128 fast serial is a Commodore custom protocol.  [Ed's note: Commodore lists
1277  NTE229, ECG229, SK3246A/229, and 121-Z9021 as substitutes of the 5710.]
1278
1279* There is no 177x or heat-shrink-wrapped daughterboard in the drive section
1280  of the 128DCR.  I believe the Motorola plastic quad flat-pack chip handles
1281  MFM because I am pretty sure that I have seen this chip in IBM PC drive
1282  mechanisms.
1283
1284* The 1571cr ROM works great in 1541 mode but not at all in 1571 mode in a
1285  standalone 1571.
1286
1287* Olaf Seibert informed me that the 1571cr ROM contains a string to the
1288  effect of "5710 (c) 1986 by c. hauck"
1289*/
1290static ADDRESS_MAP_START( _1571cr_map, ADDRESS_SPACE_PROGRAM, 8 )
1291   AM_RANGE(0x0000, 0x07ff) AM_RAM
1292   AM_RANGE(0x1800, 0x180f) AM_DEVREADWRITE("_1541_via_0", via_r, via_w)  /* 0 and 1 used in vc20 */
1293   AM_RANGE(0x1c00, 0x1c0f) AM_DEVREADWRITE("_1541_via_1", via_r, via_w)
1294//  AM_RANGE(0x2000, 0x2005) // 5710 FDC
1295//  AM_RANGE(0x400c, 0x400f) // 5710 CIA Serial Port
1296//  AM_RANGE(0x4010, 0x4017) // 5710 FDC2
1297//  AM_RANGE(0x6000, 0x7fff) // RAM shadows
1298   AM_RANGE(0x8000, 0xffff) AM_ROM
1299ADDRESS_MAP_END
1300
1301
1302/**************************************
1303
1304    1581
1305
1306**************************************/
1307
1308static ADDRESS_MAP_START( _1581_map, ADDRESS_SPACE_PROGRAM, 8 )
1309//  AM_RANGE(0x4000, 0x400f) // CIA
1310//  AM_RANGE(0x6000, 0x6003) // WD17xx
1311   AM_RANGE(0x8000, 0xffff) AM_ROM
1312ADDRESS_MAP_END
1313
1314
1315/**************************************
1316
1317    1001 / 8050 / 8250
1318
1319http://www.zimmers.net/anonftp/pub/cbm/firmware/drives/old/8050/d/8250.notes
1320
1321**************************************/
1322
1323static ADDRESS_MAP_START( sfd1001_map, ADDRESS_SPACE_PROGRAM, 8 )
1324//  AM_RANGE(0x0200, 0x021f) // RIOT1
1325//  AM_RANGE(0x0280, 0x029f) // RIOT2
1326   AM_RANGE(0xc000, 0xffff) AM_ROM
1327ADDRESS_MAP_END
1328
1329
1330/**************************************
1331
1332    2040 / 3040 / 4040
1333
1334http://www.zimmers.net/anonftp/pub/cbm/schematics/drives/old/4040/memorymap.txt
1335
1336**************************************/
1337
1338static ADDRESS_MAP_START( _4040_map, ADDRESS_SPACE_PROGRAM, 8 )
1339ADDRESS_MAP_END
1340
1341
1342/**************************************
1343
1344    1551
1345
1346**************************************/
1347
1348/*
1349  c1551 irq line
1350  only timing related??? (60 Hz?), delivered from c16?
1351 */
1352static TIMER_CALLBACK(c1551_irq_timer)
1353{
1354   cputag_set_input_line(machine, c1551_drive.cputag, M6502_IRQ_LINE, ASSERT_LINE);
1355}
1356
1357/*
1358  ddr 0x6f (p0 .. p5? in pinout)
1359  0,1: output stepper motor
1360  2 output motor (rotation) (300 revolutions per minute)
1361  3 output led ?
1362  4 input disk not write protected ?
1363  5,6: output frequency select
1364  7: input byte ready
1365 */
1366
1367static WRITE8_HANDLER( c1551_port_w )
1368{
1369   if (offset)
1370   {
1371      DBG_LOG(space->machine, 1, "c1551 port",("write %.2x\n", data));
1372      c1551_drive.cpu_port = data;
1373
1374      if (data != old)
1375      {
1376         DBG_LOG(space->machine, 1, "c1551 drive",("%.2x\n", data));
1377
1378         if ((old & 0x03) != (data & 0x03))
1379         {
1380            switch (old & 0x03)
1381            {
1382            case 0:
1383               if ((data & 0x03) == 1)
1384                  c1551_drive.track += 0.5;
1385               else if ((data & 0x03) == 3)
1386                  c1551_drive.track -= 0.5;
1387               break;
1388
1389            case 1:
1390               if ((data & 0x03) == 2)
1391                  c1551_drive.track += 0.5;
1392               else if ((data & 0x03) == 0)
1393                  c1551_drive.track -= 0.5;
1394               break;
1395
1396            case 2:
1397               if ((data & 0x03) == 3)
1398                  c1551_drive.track += 0.5;
1399               else if ((data & 0x03) == 1)
1400                  c1551_drive.track -= 0.5;
1401               break;
1402
1403            case 3:
1404               if ((data & 0x03) == 0)
1405                  c1551_drive.track += 0.5;
1406               else if ((data & 0x03) == 2)
1407                  c1551_drive.track -= 0.5;
1408               break;
1409            }
1410
1411            /* If we have reached the first or last track, we cannot proceed further! */
1412            if (c1551_drive.track < 1)
1413               c1551_drive.track = 1.0;
1414            if (c1551_drive.track > 35)
1415               c1551_drive.track = 35.0;
1416
1417         logerror("Track #: %.1f\n", c1551_drive.track);
1418
1419         /* We now adjust the c1551_drive.pos according to the new track */
1420         /* This seems a simple way to deal with half tracks */
1421         c1551_drive.pos = 0;
1422         c1551_drive.start_pos = gcr_offset[(int)c1551_drive.track - 1]            // starting point of Track #
1423            + (int)(2 * (c1551_drive.track - (int)c1551_drive.track)) * 184 / 2;   // half track if needed (again, 184 comes from out loading choices)
1424         }
1425
1426         if ((c1551_drive.motor != (data & 0x04)) || (c1551_drive.frequency != (data & 0x60)))
1427         {
1428            double tme;
1429            c1551_drive.motor = data & 0x04;
1430            c1551_drive.frequency = data & 0x60;
1431
1432            tme = drive_times[c1551_drive.frequency >> 5];
1433            if (c1551_drive.motor)
1434            {
1435               if (attotime_to_double(timer_timeelapsed(c1551_drive.timer)) > 1.0e29)
1436                  timer_reset(c1551_drive.timer, attotime_never);
1437               else
1438                  timer_adjust_periodic(c1551_drive.timer, attotime_zero, 0, ATTOTIME_IN_HZ(tme));
1439            }
1440            else
1441            {
1442               timer_reset(c1551_drive.timer, attotime_never);
1443            }
1444         }
1445         old = data;
1446      }
1447      c1551_drive.led = data & 0x08;
1448   }
1449   else
1450   {
1451      c1551_drive.cpu_ddr = data;
1452      DBG_LOG(space->machine, 1, "c1551 ddr", ("write %.2x\n", data));
1453   }
1454}
1455
1456static READ8_HANDLER( c1551_port_r )
1457{
1458   int data;
1459
1460   if (offset)
1461   {
1462      data = 0x7f;
1463#if 0
1464      if (WRITEPROTECTED)
1465         data &= ~0x10;
1466#endif
1467      if (c1551_drive.gcr.ready)
1468      {
1469         data |= 0x80;
1470         c1551_drive.gcr.ready = 0;
1471      }
1472
1473      data &= ~c1551_drive.cpu_ddr;
1474      data |= c1551_drive.cpu_ddr & c1551_drive.cpu_port;
1475      DBG_LOG(space->machine, 3, "c1551 port",("read %.2x\n", data));
1476   }
1477   else
1478   {
1479      data = c1551_drive.cpu_ddr;
1480      DBG_LOG(space->machine, 3, "c1551 ddr",("read %.2x\n", data));
1481   }
1482   return data;
1483}
1484
1485
1486static ADDRESS_MAP_START( _1551_map, ADDRESS_SPACE_PROGRAM, 8 )
1487   AM_RANGE(0x0000, 0x0001) AM_READWRITE(c1551_port_r, c1551_port_w)
1488   AM_RANGE(0x0002, 0x07ff) AM_RAM
1489   AM_RANGE(0x4000, 0x4007) AM_DEVREADWRITE("c1551_tpi", tpi6525_r, tpi6525_w)
1490   AM_RANGE(0xc000, 0xffff) AM_ROM
1491ADDRESS_MAP_END
1492
1493
1494/******************** Handlers for the C1551 TPI ********************/
1495
1496/*
1497   tia6523
1498   port a
1499    c16 communication in/out
1500   port b
1501    drive data in/out
1502   port c ddr (0x1f)
1503    0 output status out
1504    1 output status out
1505    2 output
1506    3 output handshake out
1507    4 output
1508    5 input drive number 9
1509    6 input sync 0 active
1510    7 input handshake in
1511 */
1512static READ8_DEVICE_HANDLER( c1551_port_c_r )
1513{
1514   int data = 0xff;
1515
1516   data &= ~0x20;
1517
1518   if (c1551_drive.gcr.sync)
1519      data &= ~0x40;
1520
1521   return data;
1522}
1523
1524static READ8_DEVICE_HANDLER( c1551_port_b_r )
1525{
1526   UINT8 data = c1551_drive.gcr.data[c1551_drive.start_pos + c1551_drive.pos];
1527
1528   DBG_LOG(device->machine, 2, "c1551 drive",("port a read %.2x\n", data));
1529   return data;
1530}
1531
1532static const tpi6525_interface c1551_tpi_intf =
1533{
1534   NULL,
1535   c1551_port_b_r,
1536   c1551_port_c_r,
1537   NULL,
1538   NULL,
1539   NULL,
1540   NULL,
1541   NULL,
1542   NULL
1543};
1544
1545
1546/******************** Handlers for the C16 TPI ********************/
1547
1548WRITE8_DEVICE_HANDLER( c1551x_write_data )
1549{
1550//  DBG_LOG(device->machine, 1, "c1551 cpu", ("%d write data %.2x\n", cpu_getactivecpu (), data));
1551#ifdef CPU_SYNC
1552   cpu_sync();
1553#endif
1554   const device_config *tpi_0 = devtag_get_device(device->machine, "c1551_tpi");
1555
1556   tpi6525_porta_w(tpi_0, 0, data);
1557}
1558
1559READ8_DEVICE_HANDLER( c1551x_read_data )
1560{
1561   UINT8 data = 0xff;
1562   const device_config *tpi_0 = devtag_get_device(device->machine, "c1551_tpi");
1563
1564#ifdef CPU_SYNC
1565   cpu_sync ();
1566#endif
1567
1568   data = tpi6525_porta_r(tpi_0, 0);
1569//  DBG_LOG(device->machine, 2, "c1551 cpu",("%d read data %.2x\n", cpu_getactivecpu (), data));
1570   return data;
1571}
1572
1573WRITE8_DEVICE_HANDLER( c1551x_write_handshake )
1574{
1575   const device_config *tpi_0 = devtag_get_device(device->machine, "c1551_tpi");
1576//  DBG_LOG(device->machine, 1, "c1551 cpu",("%d write handshake %.2x\n", cpu_getactivecpu (), data));
1577#ifdef CPU_SYNC
1578   cpu_sync();
1579#endif
1580
1581   tpi6525_portc_w(tpi_0, 0, data & 0x40 ? 0xff : 0x7f);
1582}
1583
1584READ8_DEVICE_HANDLER( c1551x_read_handshake )
1585{
1586   const device_config *tpi_0 = devtag_get_device(device->machine, "c1551_tpi");
1587   UINT8 data = 0xff;
1588#ifdef CPU_SYNC
1589   cpu_sync();
1590#endif
1591
1592   data = tpi6525_portc_r(tpi_0, 0) & 0x08 ? 0x80 : 0x00;
1593//  DBG_LOG(device->machine, 2, "c1551 cpu",("%d read handshake %.2x\n", cpu_getactivecpu (), data));
1594   return data;
1595}
1596
1597READ8_DEVICE_HANDLER( c1551x_read_status )
1598{
1599   const device_config *tpi_0 = devtag_get_device(device->machine, "c1551_tpi");
1600   UINT8 data = 0xff;
1601#ifdef CPU_SYNC
1602   cpu_sync();
1603#endif
1604
1605   data = tpi6525_portc_r(tpi_0, 0) & 0x03;
1606//  DBG_LOG(device->machine, 1, "c1551 cpu",("%d read status %.2x\n", cpu_getactivecpu (), data));
1607
1608   return data;
1609}
1610
1611
1612
1613/**************************************
1614
1615    Machine drivers
1616
1617**************************************/
1618
1619
1620MACHINE_DRIVER_START( cpu_vc1540 )
1621   MDRV_CPU_ADD("cpu_vc1540", M6502, XTAL_16_MHz / 16)
1622   MDRV_CPU_PROGRAM_MAP(_1541_map)
1623
1624   MDRV_VIA6522_ADD("_1541_via_0", 0, vc1541_via0)
1625   MDRV_VIA6522_ADD("_1541_via_1", 0, vc1541_via1)
1626
1627   MDRV_CBM_SERBUS_ADD("serial_bus", cbm_emu_drive_interface)
1628MACHINE_DRIVER_END
1629
1630MACHINE_DRIVER_START( cpu_vc1541 )
1631   MDRV_IMPORT_FROM(cpu_vc1540)
1632MACHINE_DRIVER_END
1633
1634MACHINE_DRIVER_START( cpu_c1571 )
1635   MDRV_CPU_ADD("cpu_vc1571", M6502, XTAL_16_MHz / 16)
1636   MDRV_CPU_PROGRAM_MAP(_1571_map)
1637
1638   MDRV_VIA6522_ADD("_1541_via_0", 0, vc1541_via0)
1639   MDRV_VIA6522_ADD("_1541_via_1", 0, vc1541_via1)
1640
1641   MDRV_CBM_SERBUS_ADD("serial_bus", cbm_emu_drive_interface)
1642MACHINE_DRIVER_END
1643
1644MACHINE_DRIVER_START( cpu_c1571cr )
1645   MDRV_CPU_ADD("cpu_vc1571", M6502, XTAL_16_MHz / 16)
1646   MDRV_CPU_PROGRAM_MAP(_1571cr_map)
1647
1648   MDRV_VIA6522_ADD("_1541_via_0", 0, vc1541_via0)
1649   MDRV_VIA6522_ADD("_1541_via_1", 0, vc1541_via1)
1650
1651   MDRV_CBM_SERBUS_ADD("serial_bus", cbm_emu_drive_interface)
1652MACHINE_DRIVER_END
1653
1654MACHINE_DRIVER_START( cpu_c1581 )
1655   MDRV_IMPORT_FROM(cpu_c1571)      // obviously incorrect: we need proper 1581 memory map and emulation!
1656MACHINE_DRIVER_END
1657
1658MACHINE_DRIVER_START( cpu_c2031 )
1659   MDRV_IMPORT_FROM(cpu_vc1540)   // not sure the memory map is exactly the vc1541 one!
1660MACHINE_DRIVER_END
1661
1662MACHINE_DRIVER_START( cpu_dolphin )
1663   MDRV_CPU_ADD("cpu_dolphin", M6502, XTAL_16_MHz / 16)
1664   MDRV_CPU_PROGRAM_MAP(dolphin_map)
1665MACHINE_DRIVER_END
1666
1667MACHINE_DRIVER_START( cpu_c1551 )
1668   MDRV_CPU_ADD("cpu_c1551", M6510T, 2000000)
1669   MDRV_CPU_PROGRAM_MAP(_1551_map)
1670
1671   /* tpi */
1672   MDRV_TPI6525_ADD("c1551_tpi", c1551_tpi_intf)
1673
1674   MDRV_CBM_SERBUS_ADD("serial_bus", cbm_emu_drive_interface)   // in the current code, serial bus device is tied to the floppy drive
1675                                                // and c16 reads/writes to serial bus in m7501_port_r/w!
1676MACHINE_DRIVER_END
1677
1678
1679
1680/**************************************
1681
1682    Drive init & reset
1683
1684**************************************/
1685
1686void cbm_drive_config( running_machine *machine, int type, int id, int mode, const char *cputag, int devicenr )
1687{
1688   vc1541_drive.type = type;
1689   vc1541_drive.cputag = cputag;
1690   vc1541_drive.vc1541_serial.deviceid = devicenr;
1691   vc1541_drive.timer = timer_alloc(machine, vc1541_drive_timer, NULL);
1692   vc1541_drive.gcr.data = (UINT8*)auto_alloc_array(machine, UINT8, 0x500000);
1693}
1694
1695void c1551_config( running_machine *machine, const char *cputag )
1696{
1697   c1551_drive.type = type_1551;
1698   c1551_drive.cputag = cputag;
1699   c1551_drive.timer = timer_alloc(machine, c1551_drive_timer, NULL);
1700   c1551_drive.gcr.data = (UINT8*)auto_alloc_array(machine, UINT8, 0x500000);
1701
1702   /* time should be small enough to allow quitting of the irq
1703    line before the next interrupt is triggered */
1704   c1551_drive.irq_timer = timer_alloc(machine, c1551_irq_timer, NULL);
1705   timer_adjust_periodic(c1551_drive.irq_timer, attotime_zero, 0, ATTOTIME_IN_HZ(60));
1706}
1707
1708void cbm_drive_reset( running_machine* machine )
1709{
1710   int i;
1711
1712   if (vc1541_drive.type == type_1541)
1713   {
1714      for (i = 0; i < ARRAY_LENGTH(serial.atn); i++)
1715      {
1716         serial.atn[i] = serial.data[i] = serial.clock[i] = 1;
1717      }
1718   }
1719
1720   /* Create offset map for GCR encoded images: it speeds up finding position where to read data from */
1721   switch (vc1541_drive.type)
1722   {
1723      case type_1541:
1724      case type_1541ii:
1725         offset_init(format_d64_40t, gcr_offset, 368);   // offset map is the same for both 35 and 40 track discs
1726         break;
1727
1728      case type_1570:
1729      case type_1571:
1730      case type_1571cr:
1731         offset_init(format_d71, gcr_offset, 368);
1732         break;
1733
1734      case type_1581:
1735         offset_init(format_d81, gcr_offset, 368);
1736         break;
1737
1738      default:
1739         logerror("GCR offset map not created\n");
1740   }
1741
1742   vc1541_drive.gcr.sync = 0;
1743   vc1541_drive.gcr.ones_count = 0;
1744   vc1541_drive.gcr.ready = 0;
1745
1746   vc1541_drive.track = 1.0;
1747   vc1541_drive.start_pos = 0;
1748   vc1541_drive.pos = 0;
1749   vc1541_drive.led = 0;
1750   vc1541_drive.motor = 0;
1751   vc1541_drive.frequency = 0;
1752   vc1541_drive.clock = 0;
1753
1754   vc1541_drive.vc1541_serial.acka = 0;
1755   vc1541_drive.vc1541_serial.data = 0;
1756
1757}
1758
1759void c1551_drive_reset( void )
1760{
1761   offset_init(format_d64_40t, gcr_offset, 368);   // offset map is the same for both 35 and 40 track discs
1762
1763   c1551_drive.gcr.sync = 0;
1764   c1551_drive.gcr.ones_count = 0;
1765   c1551_drive.gcr.ready = 0;
1766
1767   c1551_drive.track = 1.0;
1768   c1551_drive.start_pos = 0;
1769   c1551_drive.pos = 0;
1770   c1551_drive.led = 0;
1771   c1551_drive.motor = 0;
1772   c1551_drive.frequency = 0;
1773   c1551_drive.clock = 0;
1774}
1775
1776
1777
1778/**************************************
1779
1780    Device configurations
1781
1782**************************************/
1783
1784/* Floppy loading clean-up, part 1: with cbm_floppy_image_loading we can finally split c1551 from vc1541
1785   Both struct have a GCR_data gcr component where we store the floppy data, but remaining parts are finally separated!
1786   Later, everything should be changed to use devices for the drives...      */
1787static void cbm_floppy_image_loading( int format, int id1, int id2, UINT8 *copy, GCR_data gcr )
1788{
1789   UINT8 sector_checksum;
1790   int i = 0, j, k, l, pos;
1791
1792   for (k = 1; k <= max_tracks_per_format[format]; k++)
1793   {
1794/*      logerror("decoding track %d offset %d %d %d %d %d\n", k,
1795                        image_tracksector2offset(k, 0) / (16*16*16*16),
1796                        (image_tracksector2offset(k, 0) % (16*16*16*16)) / (16*16*16),
1797                        (image_tracksector2offset(k, 0) % (16*16*16)) / (16*16),
1798                        (image_tracksector2offset(k, 0) % (16*16)) / 16,
1799                        image_tracksector2offset(k, 0) % 16);
1800*/
1801
1802      for (l = 0; l < d64_sectors_per_track[k - 1]; l++)
1803      {
1804         // here we convert the sector data to gcr directly!
1805         // IMPORTANT: we shall implement errors in reading sectors!
1806         // these can modify e.g. header info $01 & $05
1807
1808         // first we set the position at which sector data starts in the image
1809         pos = image_tracksector2offset(k, l);
1810
1811         /*
1812                1. Header sync       FF FF FF FF FF (40 'on' bits, not GCR encoded)
1813                2. Header info       52 54 B5 29 4B 7A 5E 95 55 55 (10 GCR bytes)
1814                3. Header gap        55 55 55 55 55 55 55 55 55 (9 bytes, never read)
1815                4. Data sync         FF FF FF FF FF (40 'on' bits, not GCR encoded)
1816                5. Data block        55...4A (325 GCR bytes)
1817                6. Inter-sector gap  55 55 55 55...55 55 (4 to 19 bytes, never read)
1818            */
1819
1820         /* Header sync */
1821         for (j = 0; j < 5; j++)
1822            filling_byte(0xff, gcr.data + i + j);
1823         i += 5;
1824
1825         /* Header info */
1826         /* These are 8 bytes unencoded, which become 10 bytes encoded */
1827         // $00 - header block ID ($08)                      // this byte can be modified by error code 20 -> 0xff
1828         // $01 - header block checksum (EOR of $02-$05)     // this byte can be modified by error code 27 -> ^ 0xff
1829         // $02 - Sector# of data block
1830         // $03 - Track# of data block
1831         gcr_double_2_gcr(0x08, l ^ k ^ id2 ^ id1, l, k, gcr.data + i);
1832         i += 5;
1833
1834         // $04 - Format ID byte #2
1835         // $05 - Format ID byte #1
1836         // $06 - $0F ("off" byte)
1837         // $07 - $0F ("off" byte)
1838         gcr_double_2_gcr(id2, id1, 0x0f, 0x0f, gcr.data + i);
1839         i += 5;
1840
1841         /* Header gap */
1842         for (j = 0; j < 9; j++)
1843            filling_byte(0x55, gcr.data + i + j);
1844         i += 9;
1845
1846         /* Data sync */
1847         for (j = 0; j < 5; j++)
1848            filling_byte(0xff, gcr.data + i + j);
1849         i += 5;
1850
1851         /* Data block */
1852         // we first need to calculate the checksum of the 256 bytes of the sector
1853         sector_checksum = copy[pos];
1854         for (j = 1; j < 256; j++)
1855            sector_checksum ^= copy[pos + j];
1856
1857         /*
1858                $00      - data block ID ($07)
1859                $01-100  - 256 bytes sector data
1860                $101     - data block checksum (EOR of $01-100)
1861                $102-103 - $00 ("off" bytes, to make the sector size a multiple of 5)
1862            */
1863         gcr_double_2_gcr(0x07, copy[pos], copy[pos + 1],
1864                        copy[pos + 2], gcr.data + i);
1865         i += 5;
1866
1867         for (j = 1; j < 64; j++)
1868         {
1869            gcr_double_2_gcr(copy[pos + 4 * j - 1], copy[pos + 4 * j],
1870                           copy[pos + 4 * j + 1], copy[pos + 4 * j + 2], gcr.data + i);
1871            i += 5;
1872         }
1873
1874         gcr_double_2_gcr(copy[pos + 255], sector_checksum, 0x00, 0x00, gcr.data + i);
1875         i += 5;
1876
1877         /* Inter-sector gap */
1878         // "In tests that the author conducted on a real 1541 disk, gap sizes of 8  to  19 bytes were seen."
1879         // Here we put 14 as an average...
1880         for (j = 0; j < 14; j++)
1881            filling_byte(0x55, gcr.data + i + j);
1882         i += 14;
1883      }
1884   }
1885
1886}
1887
1888static DEVICE_IMAGE_LOAD( _1541 )
1889{
1890   UINT8 format_id_1, format_id_2;
1891   int format = 0, filesize;
1892   UINT8 *temp_copy = NULL;
1893   const char *filetype;
1894
1895   filesize = image_length(image);
1896   filetype = image_filetype(image);
1897
1898   /* Find out which type of image we are loading */
1899   if (!mame_stricmp (filetype, "d64"))
1900   {
1901      switch (filesize)
1902      {
1903         case 0x2ab00:
1904            format = format_d64;
1905            break;
1906         case (0x2ab00 + 0x2ab):
1907            format = format_d64_err;
1908            break;
1909         case 0x30000:
1910            format = format_d64_40t;
1911            break;
1912         case (0x30000 + 0x300):
1913            format = format_d64_40t_err;
1914            break;
1915         default:
1916            logerror("The image you're trying to load has not the regular size of a .d64 image: \n");
1917            logerror("Image %s size %d\n", image_filename(image), filesize);
1918            return INIT_FAIL;
1919      }
1920   }
1921   // these are not supported yet!
1922   else if (!mame_stricmp (filetype, "d71"))
1923   {
1924      switch (filesize)
1925      {
1926         case 0x55600:
1927            format = format_d71;
1928            break;
1929         case (0x55600 + 0x556):
1930            format = format_d71_err;
1931            break;
1932         default:
1933            logerror("The image you're trying to load has not the regular size of a .d71 image: \n");
1934            logerror("Image %s size %d\n", image_filename(image), filesize);
1935            return INIT_FAIL;
1936      }
1937   }
1938   else if (!mame_stricmp (filetype, "d67"))
1939      format = format_d67;
1940   else if (!mame_stricmp (filetype, "d81"))
1941      format = format_d81;
1942   else if (!mame_stricmp (filetype, "d80"))
1943      format = format_d80;
1944   else if (!mame_stricmp (filetype, "d82"))
1945      format = format_d82;
1946   else
1947   {
1948      /* Still have to work on g64 images */
1949      logerror("Unsupported format\n");
1950      return INIT_FAIL;
1951   }
1952
1953   /* Set up track / sector map according to the format of the image */
1954   offset_init(format, image_offset, 256);
1955
1956   /* Claim memory */
1957   temp_copy = auto_alloc_array(image->machine, UINT8, filesize);
1958
1959   if ((image_fread( image, temp_copy, filesize ) != filesize) || !filesize)
1960      return INIT_FAIL;
1961
1962   /* Start GCR encoding */
1963   format_id_1 = temp_copy[disk_id1(format)];   // can be modified by error code 29 -> ^ 0xff
1964   format_id_2 = temp_copy[disk_id2(format)];
1965
1966   /* Disk is encoded and stored in xxx_drive.gcr.data */
1967   cbm_floppy_image_loading( format, format_id_1, format_id_2, temp_copy, vc1541_drive.gcr );
1968
1969   logerror("Floppy image %s successfully loaded\n", image_filename(image));
1970   return INIT_PASS;
1971}
1972
1973static DEVICE_IMAGE_LOAD( _1551 )
1974{
1975   UINT8 format_id_1, format_id_2;
1976   int format = 0, filesize;
1977   UINT8 *temp_copy = NULL;
1978   const char *filetype;
1979
1980   filesize = image_length(image);
1981   filetype = image_filetype(image);
1982
1983   /* Find out which type of image we are loading */
1984   if (!mame_stricmp (filetype, "d64"))
1985   {
1986      switch (filesize)
1987      {
1988         case 0x2ab00:
1989            format = format_d64;
1990            break;
1991         case (0x2ab00 + 0x2ab):
1992            format = format_d64_err;
1993            break;
1994         case 0x30000:
1995            format = format_d64_40t;
1996            break;
1997         case (0x30000 + 0x300):
1998            format = format_d64_40t_err;
1999            break;
2000         default:
2001            logerror("The image you're trying to load has not the regular size of a .d64 image: \n");
2002            logerror("Image %s size %d\n", image_filename(image), filesize);
2003            return INIT_FAIL;
2004      }
2005   }
2006   else
2007   {
2008      logerror("Unsupported format\n");
2009      return INIT_FAIL;
2010   }
2011
2012   /* Set up track / sector map according to the format of the image */
2013   offset_init(format, image_offset, 256);
2014
2015   /* Claim memory */
2016   temp_copy = auto_alloc_array(image->machine, UINT8, filesize);
2017
2018   if ((image_fread( image, temp_copy, filesize ) != filesize) || !filesize)
2019      return INIT_FAIL;
2020
2021   /* Start GCR encoding */
2022   format_id_1 = temp_copy[disk_id1(format)];   // can be modified by error code 29 -> ^ 0xff
2023   format_id_2 = temp_copy[disk_id2(format)];
2024
2025   /* Disk is encoded and stored in xxx_drive.gcr.data */
2026   cbm_floppy_image_loading( format, format_id_1, format_id_2, temp_copy, c1551_drive.gcr );
2027
2028   logerror("Floppy image %s successfully loaded\n", image_filename(image));
2029   return INIT_PASS;
2030}
2031
2032static DEVICE_IMAGE_UNLOAD( _1541 )
2033{
2034}
2035
2036void vc1541_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info)
2037{
2038   switch(state)
2039   {
2040      /* --- the following bits of info are returned as 64-bit signed integers --- */
2041      case MESS_DEVINFO_INT_TYPE:               info->i = IO_FLOPPY; break;
2042      case MESS_DEVINFO_INT_COUNT:            info->i = 1; break;
2043      case MESS_DEVINFO_INT_READABLE:            info->i = 1; break;
2044      case MESS_DEVINFO_INT_WRITEABLE:         info->i = 0; break;
2045      case MESS_DEVINFO_INT_CREATABLE:         info->i = 0; break;
2046      case MESS_DEVINFO_INT_RESET_ON_LOAD:      info->i = 1; break;
2047
2048      /* --- the following bits of info are returned as pointers to data or functions --- */
2049      case MESS_DEVINFO_PTR_LOAD:               info->load = DEVICE_IMAGE_LOAD_NAME(_1541); break;
2050      case MESS_DEVINFO_PTR_UNLOAD:            info->unload = DEVICE_IMAGE_UNLOAD_NAME(_1541); break;
2051      case MESS_DEVINFO_PTR_DEV_SPECIFIC:         info->f = (genf *) cbm_drive_config; break;
2052
2053      /* --- the following bits of info are returned as NULL-terminated strings --- */
2054      case MESS_DEVINFO_STR_FILE_EXTENSIONS:      strcpy(info->s = device_temp_str(), "d64"); break;
2055   }
2056}
2057
2058
2059void c2031_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info)
2060{
2061   vc1541_device_getinfo(devclass, state, info);
2062}
2063
2064
2065void c1551_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info)
2066{
2067   switch(state)
2068   {
2069      /* --- the following bits of info are returned as pointers to data or functions --- */
2070      case MESS_DEVINFO_PTR_LOAD:               info->load = DEVICE_IMAGE_LOAD_NAME(_1551); break;
2071      case MESS_DEVINFO_PTR_DEV_SPECIFIC:            info->f = (genf *) c1551_config; break;
2072
2073      default:                           vc1541_device_getinfo(devclass, state, info);
2074   }
2075}
2076
2077
2078void c1571_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info)
2079{
2080   switch(state)
2081   {
2082      /* --- the following bits of info are returned as NULL-terminated strings --- */
2083      case MESS_DEVINFO_STR_FILE_EXTENSIONS:      strcpy(info->s = device_temp_str(), "d71"); break;
2084
2085      default:                           vc1541_device_getinfo(devclass, state, info);
2086   }
2087}
2088
2089void c1581_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info)
2090{
2091   switch(state)
2092   {
2093      /* --- the following bits of info are returned as NULL-terminated strings --- */
2094      case MESS_DEVINFO_STR_FILE_EXTENSIONS:      strcpy(info->s = device_temp_str(), "d81"); break;
2095
2096      default:                           vc1541_device_getinfo(devclass, state, info);
2097   }
2098}
2099
2100void c8050_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info)
2101{
2102   switch(state)
2103   {
2104      /* --- the following bits of info are returned as NULL-terminated strings --- */
2105      case MESS_DEVINFO_STR_FILE_EXTENSIONS:      strcpy(info->s = device_temp_str(), "d80"); break;
2106
2107      default:                           vc1541_device_getinfo(devclass, state, info);
2108   }
2109}
2110
2111void c8250_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info)
2112{
2113   switch(state)
2114   {
2115      /* --- the following bits of info are returned as NULL-terminated strings --- */
2116      case MESS_DEVINFO_STR_FILE_EXTENSIONS:      strcpy(info->s = device_temp_str(), "d82"); break;
2117
2118      default:                           vc1541_device_getinfo(devclass, state, info);
2119   }
2120}
2121
2122void c2040_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info)
2123{
2124   switch(state)
2125   {
2126      /* --- the following bits of info are returned as NULL-terminated strings --- */
2127      case MESS_DEVINFO_STR_FILE_EXTENSIONS:      strcpy(info->s = device_temp_str(), "d67"); break;
2128
2129      default:                           vc1541_device_getinfo(devclass, state, info);
2130   }
2131}
src/mess/machine/cbmdrive.c
r6732r6733
1/***************************************************************
2
3    CBM Floppy Drive Simulation
4
5    This code incercepts commands from the CBM machine and
6    send/return the appropriate data to/from the disk image
7
8    This code will be eventually replaced by proper emulation
9    (see vc1541.c)
10
11***************************************************************/
12
13#include <ctype.h>
14#include "driver.h"
15
16#include "includes/cbmserb.h"
17#include "includes/cbmieeeb.h"
18
19#include "includes/cbmdrive.h"
20
21#define VERBOSE_LEVEL 0
22#define DBG_LOG( MACHINE, N, M, A ) \
23   do { \
24      if(VERBOSE_LEVEL >= N) \
25      { \
26         if( M ) \
27            logerror("%11.6f: %-24s", attotime_to_double(timer_get_time(MACHINE)), (char*) M ); \
28         logerror A; \
29      } \
30   } while (0)
31
32/***********************************************
33
34    D64 images handling
35
36***********************************************/
37
38/* tracks 1 to 35
39 * sectors number from 0
40 * each sector holds 256 data bytes
41 * directory and Bitmap Allocation Memory in track 18
42 * sector 0:
43 * 0: track# of directory begin (this linkage of sector often used)
44 * 1: sector# of directory begin
45 *
46 * BAM entries (one per track)
47 * offset 0: # of free sectors
48 * offset 1: sector 0 (lsb) free to sector 7
49 * offset 2: sector 8 to 15
50 * offset 3: sector 16 to whatever the number to sectors in track is
51 *
52 * directory sector:
53 * 0,1: track sector of next directory sector
54 * 2, 34, 66, ... : 8 directory entries
55 *
56 * directory entry:
57 * 0: file type
58 * (0x = scratched/splat, 8x = alive, Cx = locked
59 * where x: 0=DEL, 1=SEQ, 2=PRG, 3=USR, 4=REL)
60 * 1,2: track and sector of file
61 * 3..18: file name padded with a0
62 * 19,20: REL files side sector
63 * 21: REL files record length
64 * 28,29: number of blocks in file
65 * ended with illegal track and sector numbers
66 */
67
68#define D64_MAX_TRACKS 35
69
70static const int d64_sectors_per_track[] =
71{
72   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
73   19, 19, 19, 19, 19, 19, 19,
74   18, 18, 18, 18, 18, 18,
75   17, 17, 17, 17, 17
76};
77
78static int d64_offset[D64_MAX_TRACKS];         /* offset of begin of track in d64 file */
79
80/* must be called before other functions */
81void cbm_drive_open_helper( void )
82{
83   int i;
84
85   d64_offset[0] = 0;
86   for (i = 1; i < D64_MAX_TRACKS; i++)
87      d64_offset[i] = d64_offset[i - 1] + d64_sectors_per_track[i - 1] * 256;
88}
89
90/* calculates offset to beginning of d64 file for sector beginning */
91static int d64_tracksector2offset( int track, int sector )
92{
93   return d64_offset[track - 1] + sector * 256;
94}
95
96static int cbm_compareNames( unsigned char *left, unsigned char *right )
97{
98   int i;
99
100   for (i = 0; i < 16; i++)
101   {
102      if ((left[i] == '*') || (right[i] == '*'))
103         return 1;
104      if (left[i] == right[i])
105         continue;
106      if ((left[i] == 0xa0) && (right[i] == 0))
107         return 1;
108      if ((right[i] == 0xa0) && (left[i] == 0))
109         return 1;
110      return 0;
111   }
112   return 1;
113}
114
115/* searches program with given name in directory
116 * delivers -1 if not found
117 * or pos in image of directory node */
118static int d64_find( CBM_Drive * drive, unsigned char *name )
119{
120   int pos, track, sector, i;
121
122   pos = d64_tracksector2offset(18, 0);
123   track = drive->image[pos];
124   sector = drive->image[pos + 1];
125
126   while ((track >= 1) && (track <= 35))
127   {
128      pos = d64_tracksector2offset(track, sector);
129      for (i = 2; i < 256; i += 32)
130      {
131         if (drive->image[pos + i] & 0x80)
132         {
133            if (mame_stricmp((char *) name, (char *) "*") == 0)
134               return pos + i;
135            if (cbm_compareNames(name, drive->image + pos + i + 3))
136               return pos + i;
137         }
138      }
139      track = drive->image[pos];
140      sector = drive->image[pos + 1];
141   }
142   return -1;
143}
144
145/* reads file into buffer */
146static void d64_readprg( running_machine *machine, CBM_Drive * drive, int pos )
147{
148   int i;
149
150   for (i = 0; i < 16; i++)
151      drive->filename[i] = toupper(drive->image[pos + i + 3]);
152
153   drive->filename[i] = 0;
154
155   pos = d64_tracksector2offset(drive->image[pos + 1], drive->image[pos + 2]);
156
157   i = pos;
158   drive->size = 0;
159   while (drive->image[i] != 0)
160   {
161      drive->size += 254;
162      i = d64_tracksector2offset(drive->image[i], drive->image[i + 1]);
163   }
164   drive->size += drive->image[i + 1];
165
166   DBG_LOG(machine, 3, "d64 readprg", ("size %d\n", drive->size));
167
168   drive->buffer = (UINT8*)realloc(drive->buffer, drive->size);
169   if (!drive->buffer)
170      fatalerror("out of memory %s %d\n", __FILE__, __LINE__);
171
172   drive->size--;
173
174   DBG_LOG(machine, 3, "d64 readprg", ("track: %d sector: %d\n",
175                        drive->image[pos + 1],
176                        drive->image[pos + 2]));
177
178   for (i = 0; i < drive->size; i += 254)
179   {
180      if (i + 254 < drive->size)
181      {                        /* not last sector */
182         memcpy(drive->buffer + i, drive->image + pos + 2, 254);
183         pos = d64_tracksector2offset(drive->image[pos + 0],
184                             drive->image[pos + 1]);
185         DBG_LOG(machine, 3, "d64 readprg", ("track: %d sector: %d\n",
186                              drive->image[pos],
187                              drive->image[pos + 1]));
188      }
189      else
190      {
191         memcpy(drive->buffer + i, drive->image + pos + 2, drive->size - i);
192      }
193   }
194}
195
196/* reads sector into buffer */
197static void d64_read_sector( CBM_Drive * drive, int track, int sector )
198{
199   int pos;
200
201   snprintf(drive->filename, sizeof (drive->filename),
202           "track %d sector %d", track, sector);
203
204   pos = d64_tracksector2offset (track, sector);
205
206   drive->buffer = (UINT8*)realloc(drive->buffer,256);
207   if (!drive->buffer)
208      fatalerror("out of memory %s %d\n", __FILE__, __LINE__);
209
210   logerror("d64 read track %d sector %d\n", track, sector);
211
212   memcpy(drive->buffer, drive->image + pos, 256);
213   drive->size = 256;
214   drive->pos = 0;
215}
216
217/* reads directory into buffer */
218static void d64_read_directory( CBM_Drive * drive )
219{
220   int pos, track, sector, i, j, blocksfree, addr = 0x0101/*0x1001*/;
221
222   drive->buffer = (UINT8*)realloc(drive->buffer, 8 * 18 * 25);
223   if (!drive->buffer)
224      fatalerror("out of memory %s %d\n", __FILE__, __LINE__);
225
226   drive->size = 0;
227
228   pos = d64_tracksector2offset(18, 0);
229   track = drive->image[pos];
230   sector = drive->image[pos + 1];
231
232   blocksfree = 0;
233   for (j = 1, i = 4; j <= 35; j++, i += 4)
234   {
235      blocksfree += drive->image[pos + i];
236   }
237   drive->buffer[drive->size++] = addr & 0xff;
238   drive->buffer[drive->size++] = addr >> 8;
239   addr += 29;
240   drive->buffer[drive->size++] = addr & 0xff;
241   drive->buffer[drive->size++] = addr >> 8;
242   drive->buffer[drive->size++] = 0;
243   drive->buffer[drive->size++] = 0;
244   drive->buffer[drive->size++] = '\"';
245   for (j = 0; j < 16; j++)
246      drive->buffer[drive->size++] = drive->image[pos + 0x90 + j];
247/*memcpy(drive->buffer+drive->size,drive->image+pos+0x90, 16);drive->size+=16; */
248   drive->buffer[drive->size++] = '\"';
249   drive->buffer[drive->size++] = ' ';
250   drive->buffer[drive->size++] = drive->image[pos + 162];
251   drive->buffer[drive->size++] = drive->image[pos + 163];
252   drive->buffer[drive->size++] = ' ';
253   drive->buffer[drive->size++] = drive->image[pos + 165];
254   drive->buffer[drive->size++] = drive->image[pos + 166];
255   drive->buffer[drive->size++] = 0;
256
257   while ((track >= 1) && (track <= 35))
258   {
259      pos = d64_tracksector2offset(track, sector);
260      for (i = 2; i < 256; i += 32)
261      {
262         if (drive->image[pos + i] & 0x80)
263         {
264            int len, blocks = drive->image[pos + i + 28]
265            + 256 * drive->image[pos + i + 29];
266            char dummy[10];
267
268            sprintf(dummy, "%d", blocks);
269            len = strlen (dummy);
270            addr += 29 - len;
271            drive->buffer[drive->size++] = addr & 0xff;
272            drive->buffer[drive->size++] = addr >> 8;
273            drive->buffer[drive->size++] = drive->image[pos + i + 28];
274            drive->buffer[drive->size++] = drive->image[pos + i + 29];
275            for (j = 4; j > len; j--)
276               drive->buffer[drive->size++] = ' ';
277            drive->buffer[drive->size++] = '\"';
278            for (j = 0; j < 16; j++)
279               drive->buffer[drive->size++] = drive->image[pos + i + 3 + j];
280            drive->buffer[drive->size++] = '\"';
281            drive->buffer[drive->size++] = ' ';
282            switch (drive->image[pos + i] & 0x3f)
283            {
284            case 0:
285               drive->buffer[drive->size++] = 'D';
286               drive->buffer[drive->size++] = 'E';
287               drive->buffer[drive->size++] = 'L';
288               break;
289            case 1:
290               drive->buffer[drive->size++] = 'S';
291               drive->buffer[drive->size++] = 'E';
292               drive->buffer[drive->size++] = 'Q';
293               break;
294            case 2:
295               drive->buffer[drive->size++] = 'P';
296               drive->buffer[drive->size++] = 'R';
297               drive->buffer[drive->size++] = 'G';
298               break;
299            case 3:
300               drive->buffer[drive->size++] = 'U';
301               drive->buffer[drive->size++] = 'S';
302               drive->buffer[drive->size++] = 'R';
303               break;
304            case 4:
305               drive->buffer[drive->size++] = 'R';
306               drive->buffer[drive->size++] = 'E';
307               drive->buffer[drive->size++] = 'L';
308               break;
309            }
310            drive->buffer[drive->size++] = 0;
311         }
312      }
313      track = drive->image[pos];
314      sector = drive->image[pos + 1];
315   }
316   addr += 14;
317   drive->buffer[drive->size++] = addr & 0xff;
318   drive->buffer[drive->size++] = addr >> 8;
319   drive->buffer[drive->size++] = blocksfree & 0xff;
320   drive->buffer[drive->size++] = blocksfree >> 8;
321   memcpy(drive->buffer + drive->size, "BLOCKS FREE", 11);
322   drive->size += 11;
323   drive->buffer[drive->size++] = 0;
324
325   strcpy(drive->filename, "$");
326}
327
328static int d64_command( running_machine *machine, CBM_Drive * drive, unsigned char *name )
329{
330   int pos;
331
332   /* name eventuell mit 0xa0 auffuellen */
333
334   if (mame_stricmp((char *) name, (char *) "$") == 0)
335   {
336      d64_read_directory(drive);
337   }
338   else
339   {
340      if ((pos = d64_find (drive, name)) == -1)
341      {
342         return 1;
343      }
344      d64_readprg(machine, drive, pos);
345   }
346   return 0;
347}
348
349/**
350  7.1 Serial bus
351
352   CBM Serial Bus Control Codes
353
354    20  Talk
355    3F  Untalk
356    40  Listen
357    5F  Unlisten
358    60  Open Channel
359    70  -
360    80  -
361    90  -
362    A0  -
363    B0  -
364    C0  -
365    D0  -
366    E0  Close
367    F0  Open
368
369
370
371     How the C1541 is called by the C64:
372
373        read (drive 8)
374        /28 /f0 filename /3f
375        /48 /60 read data /5f
376        /28 /e0 /3f
377
378        write (drive 8)
379        /28 /f0 filename /3f
380        /28 /60 send data /3f
381        /28 /e0 /3f
382
383     I used '/' to denote bytes sent under Attention (ATN low).
384
385    28 == LISTEN command + device number 8
386    f0 == secondary addres for OPEN file on channel 0
387
388  Note that there's no acknowledge bit, but timeout/EOI handshake for each
389  byte. Check the C64 Kernel for exact description...
390
391 computer master
392
393 c16 called
394 dload
395  20 f0 30 3a name 3f
396  40 60 listening 5f
397  20 e0 3f
398
399 load
400  20 f0 name 3f
401 */
402static void cbm_command( running_machine *machine, CBM_Drive * drive )
403{
404   unsigned char name[20], type = 'P', mode = 0;
405   int channel, head, track, sector;
406   int j, i, rc;
407
408   if ((drive->cmdpos == 4)
409      && ((drive->cmdbuffer[0] & 0xf0) == 0x20)
410      && ((drive->cmdbuffer[1] & 0xf0) == 0xf0)
411      && (drive->cmdbuffer[2] == '#')
412      && (drive->cmdbuffer[3] == 0x3f))
413   {
414      logerror("floppy direct access channel %d opened\n",
415                (unsigned) drive->cmdbuffer[1] & 0xf);
416   }
417   else if ((drive->cmdpos >= 4)
418          && (((unsigned) drive->cmdbuffer[0] & 0xf0) == 0x20)
419          && (((unsigned) drive->cmdbuffer[1] & 0xf0) == 0xf0)
420          && (drive->cmdbuffer[drive->cmdpos - 1] == 0x3f))
421   {
422      if (drive->cmdbuffer[3] == ':')
423         j = 4;
424      else
425         j = 2;
426
427      for (i = 0; (j < sizeof (name)) && (drive->cmdbuffer[j] != 0x3f)
428          && (drive->cmdbuffer[j] != ',');
429          i++, j++)
430         name[i] = drive->cmdbuffer[j];
431      name[i] = 0;
432
433      if (drive->cmdbuffer[j] == ',')
434      {
435         j++;
436         if (j < drive->cmdpos)
437         {
438            type = drive->cmdbuffer[j];
439            j++;
440            if ((j < drive->cmdpos) && (drive->cmdbuffer[j] == 'j'))
441            {
442               j++;
443               if (j < drive->cmdpos)
444                  mode = drive->cmdbuffer[j];
445            }
446         }
447      }
448      rc = 1;
449      if (drive->drive == D64_IMAGE)
450      {
451         if ((type == 'P') || (type == 'S'))
452            rc = d64_command (machine, drive, name);
453      }
454      if (!rc)
455      {
456         drive->state = OPEN;
457         drive->pos = 0;
458      }
459      DBG_LOG(machine, 1, "cbm_open", ("%s %s type:%c %c\n", name,
460                         rc ? "failed" : "success", type, mode ? mode : ' '));
461   }
462   else if ((drive->cmdpos == 1) && (drive->cmdbuffer[0] == 0x5f))
463   {
464      drive->state = OPEN;
465   }
466   else if ((drive->cmdpos == 3) && ((drive->cmdbuffer[0] & 0xf0) == 0x20)
467          && ((drive->cmdbuffer[1] & 0xf0) == 0xe0)
468          && (drive->cmdbuffer[2] == 0x3f))
469   {
470/*    if (drive->buffer) free(drive->buffer);drive->buffer=0; */
471      drive->state = 0;
472   }
473   else if ((drive->cmdpos == 2) && ((drive->cmdbuffer[0] & 0xf0) == 0x40)
474          && ((drive->cmdbuffer[1] & 0xf0) == 0x60))
475   {
476      if (drive->state == OPEN)
477      {
478         drive->state = READING;
479      }
480   }
481   else if ((drive->cmdpos == 2) && ((drive->cmdbuffer[0] & 0xf0) == 0x20)
482          && ((drive->cmdbuffer[1] & 0xf0) == 0x60))
483   {
484      drive->state = WRITING;
485   }
486   else if ((drive->cmdpos == 1) && (drive->cmdbuffer[0] == 0x3f))
487   {
488      drive->state = OPEN;
489   }
490   else if ((drive->drive == D64_IMAGE)
491          && (4 == sscanf ((char *) drive->cmdbuffer, "U1: %d %d %d %d\x0d",
492                       &channel, &head, &track, &sector)))
493   {
494      d64_read_sector (drive, track, sector);
495      drive->state = OPEN;
496   }
497   else
498   {
499
500      logerror("unknown floppycommand(size:%d):", drive->cmdpos);
501      for (i = 0; i < drive->cmdpos; i++)
502         logerror("%.2x", drive->cmdbuffer[i]);
503      logerror(" ");
504      for (i = 0; i < drive->cmdpos; i++)
505         logerror("%c", drive->cmdbuffer[i]);
506      logerror("\n");
507
508      drive->state = 0;
509   }
510   drive->cmdpos = 0;
511}
512
513
514/***********************************************
515
516    Drive state update
517
518***********************************************/
519
520
521 /*
522  * 0x55 begin of command
523  *
524  * frame
525  * selector
526  * 0x81 device id
527  * 0x82 command
528  * 0x83 data
529  * 0x84 read byte
530  * handshake low
531  *
532  * byte (like in serial bus!)
533  *
534  * floppy drive delivers
535  * status 3 for file not found
536  * or filedata ended with status 3
537  */
538void c1551_state( running_machine *machine, CBM_Drive * drive )
539{
540   static int oldstate;
541
542   oldstate = drive->i.iec.state;
543
544   switch (drive->i.iec.state)
545   {
546   case -1:                     /* currently neccessary for correct init */
547      if (drive->i.iec.handshakein)
548      {
549         drive->i.iec.state++;
550      }
551      break;
552   case 0:
553      if (drive->i.iec.datain == 0x55)
554      {
555         drive->i.iec.status = 0;
556         drive->i.iec.state++;
557      }
558      break;
559   case 1:
560      if (drive->i.iec.datain != 0x55)
561      {
562         drive->i.iec.state = 10;
563      }
564      break;
565   case 10:
566      if (drive->i.iec.datain != 0)
567      {
568         drive->i.iec.handshakeout = 0;
569         if (drive->i.iec.datain == 0x84)
570         {
571            drive->i.iec.state = 20;
572            if (drive->pos + 1 == drive->size)
573               drive->i.iec.status = 3;
574         }
575         else if (drive->i.iec.datain == 0x83)
576         {
577            drive->i.iec.state = 40;
578         }
579         else
580         {
581            drive->i.iec.status = 0;
582            drive->i.iec.state++;
583         }
584      }
585      break;
586   case 11:
587      if (!drive->i.iec.handshakein)
588      {
589         drive->i.iec.state++;
590         DBG_LOG(machine, 1,"c1551",("taken data %.2x\n",drive->i.iec.datain));
591         if (drive->cmdpos < sizeof (drive->cmdbuffer))
592            drive->cmdbuffer[drive->cmdpos++] = drive->i.iec.datain;
593         if ((drive->i.iec.datain == 0x3f) || (drive->i.iec.datain == 0x5f))
594         {
595            cbm_command (machine, drive);
596            drive->i.iec.state = 30;
597         }
598         else if (((drive->i.iec.datain & 0xf0) == 0x60))
599         {
600            cbm_command (machine, drive);
601            if (drive->state == READING)
602            {
603            }
604            else if (drive->state == WRITING)
605            {
606            }
607            else
608               drive->i.iec.status = 3;
609         }
610         drive->i.iec.handshakeout = 1;
611      }
612      break;
613   case 12:
614      if (drive->i.iec.datain == 0)
615      {
616         drive->i.iec.state++;
617      }
618      break;
619   case 13:
620      if (drive->i.iec.handshakein)
621      {
622         drive->i.iec.state = 10;
623      }
624      break;
625
626   case 20:                     /* reading data */
627      if (!drive->i.iec.handshakein)
628      {
629         drive->i.iec.handshakeout = 1;
630         if (drive->state == READING)
631            drive->i.iec.dataout = drive->buffer[drive->pos++];
632         drive->i.iec.state++;
633      }
634      break;
635   case 21:                     /* reading data */
636      if (drive->i.iec.handshakein)
637      {
638         drive->i.iec.handshakeout = 0;
639         drive->i.iec.state++;
640      }
641      break;
642   case 22:
643      if (drive->i.iec.datain == 0)
644      {
645         drive->i.iec.state++;
646      }
647      break;
648   case 23:
649      if (!drive->i.iec.handshakein)
650      {
651         drive->i.iec.handshakeout = 1;
652         if (drive->state == READING)
653            drive->i.iec.state = 10;
654         else
655            drive->i.iec.state = 0;
656      }
657      break;
658
659   case 30:                     /* end of command */
660      if (drive->i.iec.datain == 0)
661      {
662         drive->i.iec.state++;
663      }
664      break;
665   case 31:
666      if (drive->i.iec.handshakein)
667      {
668         drive->i.iec.state = 0;
669      }
670      break;
671
672   case 40:                     /* simple write */
673      if (!drive->i.iec.handshakein)
674      {
675         drive->i.iec.state++;
676         if ((drive->state == 0) || (drive->state == OPEN))
677         {
678            DBG_LOG(machine, 1, "c1551", ("taken data %.2x\n",
679                             drive->i.iec.datain));
680            if (drive->cmdpos < sizeof (drive->cmdbuffer))
681               drive->cmdbuffer[drive->cmdpos++] = drive->i.iec.datain;
682         }
683         else if (drive->state == WRITING)
684         {
685            DBG_LOG(machine, 1, "c1551", ("written data %.2x\n", drive->i.iec.datain));
686         }
687         drive->i.iec.handshakeout = 1;
688      }
689      break;
690   case 41:
691      if (drive->i.iec.datain == 0)
692      {
693         drive->i.iec.state++;
694      }
695      break;
696   case 42:
697      if (drive->i.iec.handshakein)
698      {
699         drive->i.iec.state = 10;
700      }
701      break;
702   }
703
704   if (oldstate != drive->i.iec.state)
705      if (VERBOSE_LEVEL >= 1) logerror("state %d->%d %d\n", oldstate, drive->i.iec.state, drive->state);
706}
707
708static int vc1541_time_greater( running_machine *machine, CBM_Drive * drive, attotime threshold )
709{
710   return attotime_compare(
711      attotime_sub(timer_get_time(machine), drive->i.serial.time),
712      threshold) > 0;
713}
714
715void vc1541_state( running_machine *machine, CBM_Drive * drive )
716{
717   int oldstate = drive->i.serial.state;
718
719   switch (drive->i.serial.state)
720   {
721   case 0:
722      if (!cbm_serial.atn[0] && !cbm_serial.clock[0])
723      {
724         drive->i.serial.data = 0;
725         drive->i.serial.state = 2;
726         break;
727      }
728      if (!cbm_serial.clock[0] && drive->i.serial.forme)
729      {
730         drive->i.serial.data = 0;
731         drive->i.serial.state++;
732         break;
733      }
734      break;
735   case 1:
736      if (!cbm_serial.atn[0])
737      {
738         drive->i.serial.state++;
739         break;
740      }
741      if (cbm_serial.clock[0])
742      {
743         drive->i.serial.broadcast = 0;
744         drive->i.serial.data = 1;
745         drive->i.serial.state = 100;
746         drive->i.serial.last = 0;
747         drive->i.serial.value = 0;
748         drive->i.serial.time = timer_get_time(machine);
749         break;
750      }
751      break;
752   case 2:
753      if (cbm_serial.clock[0])
754      {
755         drive->i.serial.broadcast = 1;
756         drive->i.serial.data = 1;
757         drive->i.serial.state = 100;
758         drive->i.serial.last = 0;
759         drive->i.serial.value = 0;
760         drive->i.serial.time = timer_get_time(machine);
761         break;
762      }
763      break;
764      /* bits to byte fitting */
765   case 100:
766      if (!cbm_serial.clock[0])
767      {
768         drive->i.serial.state++;
769         break;
770      }
771      break;
772   case 102:
773   case 104:
774   case 106:
775   case 108:
776   case 110:
777   case 112:
778   case 114:
779      if (!cbm_serial.clock[0])
780         drive->i.serial.state++;
781      break;
782   case 101:
783      if (cbm_serial.clock[0])
784      {
785         drive->i.serial.value |= cbm_serial.data[0] ? 1 : 0;
786         drive->i.serial.state++;
787      }
788      break;
789   case 103:
790      if (cbm_serial.clock[0])
791      {
792         drive->i.serial.value |= cbm_serial.data[0] ? 2 : 0;
793         drive->i.serial.state++;
794      }
795      break;
796   case 105:
797      if (cbm_serial.clock[0])
798      {
799         drive->i.serial.value |= cbm_serial.data[0] ? 4 : 0;
800         drive->i.serial.state++;
801      }
802      break;
803   case 107:
804      if (cbm_serial.clock[0])
805      {
806         drive->i.serial.value |= cbm_serial.data[0] ? 8 : 0;
807         drive->i.serial.state++;
808      }
809      break;
810   case 109:
811      if (cbm_serial.clock[0])
812      {
813         drive->i.serial.value |= cbm_serial.data[0] ? 0x10 : 0;
814         drive->i.serial.state++;
815      }
816      break;
817   case 111:
818      if (cbm_serial.clock[0])
819      {
820         drive->i.serial.value |= cbm_serial.data[0] ? 0x20 : 0;
821         drive->i.serial.state++;
822      }
823      break;
824   case 113:
825      if (cbm_serial.clock[0])
826      {
827         drive->i.serial.value |= cbm_serial.data[0] ? 0x40 : 0;
828         drive->i.serial.state++;
829      }
830      break;
831   case 115:
832      if (cbm_serial.clock[0])
833      {
834         drive->i.serial.value |= cbm_serial.data[0] ? 0x80 : 0;
835         if (drive->i.serial.broadcast
836            && (((drive->i.serial.value & 0xf0) == 0x20)
837               || ((drive->i.serial.value & 0xf0) == 0x40)))
838         {
839            drive->i.serial.forme = (drive->i.serial.value & 0xf)
840               == drive->i.serial.device;
841            if (!drive->i.serial.forme)
842            {
843               drive->i.serial.state = 160;
844               break;
845            }
846         }
847         if (drive->i.serial.forme)
848         {
849            if (drive->cmdpos < sizeof (drive->cmdbuffer))
850               drive->cmdbuffer[drive->cmdpos++] = drive->i.serial.value;
851            DBG_LOG(machine, 1, "serial read", ("%s %s %.2x\n",
852                     drive->i.serial.broadcast ? "broad" : "",
853                     drive->i.serial.last ? "last" : "",
854                                 drive->i.serial.value));
855         }
856         drive->i.serial.state++;
857      }
858      break;
859   case 116:
860      if (!cbm_serial.clock[0])
861      {
862         if (drive->i.serial.last)
863            drive->i.serial.state = 130;
864         else
865            drive->i.serial.state++;
866         if (drive->i.serial.broadcast &&
867            ((drive->i.serial.value == 0x3f) || (drive->i.serial.value == 0x5f)
868             || ((drive->i.serial.value & 0xf0) == 0x60)))
869         {
870            cbm_command(machine, drive);
871         }
872         drive->i.serial.time = timer_get_time(machine);
873         drive->i.serial.data = 0;
874         break;
875      }
876      break;
877   case 117:
878      if (drive->i.serial.forme && ((drive->i.serial.value & 0xf0) == 0x60)
879         && drive->i.serial.broadcast && cbm_serial.atn[0])
880      {
881         if (drive->state == READING)
882         {
883            drive->i.serial.state = 200;
884            break;
885         }
886         else if (drive->state != WRITING)
887         {
888            drive->i.serial.state = 150;
889            break;
890         }
891      }
892      if (((drive->i.serial.value == 0x3f)
893          || (drive->i.serial.value == 0x5f))
894         && drive->i.serial.broadcast && cbm_serial.atn[0])
895      {
896         drive->i.serial.data = 1;
897         drive->i.serial.state = 140;
898         break;
899      }
900      if (cbm_serial.clock[0])
901      {
902         drive->i.serial.time = timer_get_time(machine);
903         drive->i.serial.broadcast = !cbm_serial.atn[0];
904         drive->i.serial.data = 1;
905         drive->i.serial.value = 0;
906         drive->i.serial.state++;
907         break;
908      }
909      break;
910      /* if computer lowers clk not in 200micros (last byte following)
911         * negativ pulse on data by listener */
912   case 118:
913      if (!cbm_serial.clock[0])
914      {
915         drive->i.serial.value = 0;
916         drive->i.serial.state = 101;
917         drive->i.serial.data = 1;
918         break;
919      }
920      if (vc1541_time_greater(machine, drive, ATTOTIME_IN_USEC(200)))
921      {
922         drive->i.serial.data = 0;
923         drive->i.serial.last = 1;
924         drive->i.serial.state++;
925         drive->i.serial.time = timer_get_time(machine);
926         break;
927      }
928      break;
929   case 119:
930      if (vc1541_time_greater(machine, drive, ATTOTIME_IN_USEC(60)))
931      {
932         drive->i.serial.value = 0;
933         drive->i.serial.data = 1;
934         drive->i.serial.state = 100;
935         break;
936      }
937      break;
938
939   case 130:                     /* last byte of talk */
940      if (vc1541_time_greater(machine, drive, ATTOTIME_IN_USEC(60)))
941      {
942         drive->i.serial.data = 1;
943         drive->i.serial.state = 0;
944         break;
945      }
946      break;
947
948   case 131:
949      if (cbm_serial.clock[0])
950      {
951         drive->i.serial.state = 0;
952      }
953      break;
954
955   case 140:                     /* end of talk */
956      if (cbm_serial.clock[0])
957      {
958         drive->i.serial.state = 0;
959      }
960      break;
961
962   case 150:                     /* file not found */
963      if (cbm_serial.atn[0])
964      {
965         drive->i.serial.state++;
966         drive->i.serial.time = timer_get_time(machine);
967         break;
968      }
969      break;
970   case 151:
971      if (vc1541_time_greater(machine, drive, ATTOTIME_IN_USEC(1000)))
972      {
973         drive->i.serial.state++;
974         drive->i.serial.clock = 0;
975         drive->i.serial.time = timer_get_time(machine);
976         break;
977      }
978      break;
979   case 152:
980      if (vc1541_time_greater(machine, drive, ATTOTIME_IN_USEC(50)))
981      {
982         drive->i.serial.state++;
983         drive->i.serial.clock = 1;
984         break;
985      }
986      break;
987   case 153:
988      if (cbm_serial.clock[0])
989      {
990         drive->i.serial.state = 0;
991      }
992      break;
993
994   case 160:                     /* not for me */
995      if (cbm_serial.atn[0])
996      {
997         drive->i.serial.state = 0;
998         drive->i.serial.time = timer_get_time(machine);
999         break;
1000      }
1001      break;
1002
1003   case 200:
1004      if (cbm_serial.clock[0])
1005      {
1006         drive->i.serial.state++;
1007         drive->i.serial.clock = 0;
1008         drive->i.serial.time = timer_get_time(machine);
1009         break;
1010      }
1011      break;
1012   case 201:
1013      if (vc1541_time_greater(machine, drive, ATTOTIME_IN_USEC(80)))
1014      {
1015         drive->i.serial.clock = 1;
1016         drive->i.serial.data = 1;
1017         drive->i.serial.state = 300;
1018         break;
1019      }
1020      break;
1021
1022   case 300:
1023      if (!cbm_serial.atn[0])
1024      {
1025         drive->i.serial.state = 330;
1026         drive->i.serial.data = 1;
1027         drive->i.serial.clock = 1;
1028         break;
1029      }
1030      if (cbm_serial.data[0])
1031      {
1032         drive->i.serial.value = drive->buffer[drive->pos];
1033         drive->i.serial.clock = 0;
1034         drive->i.serial.data = (drive->i.serial.value & 1) ? 1 : 0;
1035         drive->i.serial.state++;
1036         drive->i.serial.time = timer_get_time(machine);
1037         break;
1038      }
1039      break;
1040   case 301:
1041      if (!cbm_serial.atn[0])
1042      {
1043         drive->i.serial.state = 330;
1044         drive->i.serial.data = 1;
1045         drive->i.serial.clock = 1;
1046         break;
1047      }
1048      if (vc1541_time_greater(machine, drive, ATTOTIME_IN_USEC(40)))
1049      {
1050         drive->i.serial.clock = 1;
1051         drive->i.serial.state++;
1052         drive->i.serial.time = timer_get_time(machine);
1053         break;
1054      }
1055      break;
1056   case 303:
1057   case 305:
1058   case 307:
1059   case 309:
1060   case 311:
1061   case 313:
1062   case 315:
1063      if (!cbm_serial.atn[0])
1064      {
1065         drive->i.serial.state = 330;
1066         drive->i.serial.data = 1;
1067         drive->i.serial.clock = 1;
1068         break;
1069      }
1070      if (vc1541_time_greater(machine, drive, ATTOTIME_IN_USEC(20)))
1071      {
1072         drive->i.serial.clock = 1;
1073         drive->i.serial.state++;
1074         drive->i.serial.time = timer_get_time(machine);
1075         break;
1076      }
1077      break;
1078   case 302:
1079      if (!cbm_serial.atn[0])
1080      {
1081         drive->i.serial.state = 330;
1082         drive->i.serial.data = 1;
1083         drive->i.serial.clock = 1;
1084         break;
1085      }
1086      if (vc1541_time_greater(machine, drive, ATTOTIME_IN_USEC(20)))
1087      {
1088         drive->i.serial.data = drive->i.serial.value & 2 ? 1 : 0;
1089         drive->i.serial.clock = 0;
1090         drive->i.serial.state++;
1091         drive->i.serial.time = timer_get_time(machine);
1092         break;
1093      }
1094      break;
1095   case 304:
1096      if (!cbm_serial.atn[0])
1097      {
1098         drive->i.serial.state = 330;
1099         drive->i.serial.data = 1;
1100         drive->i.serial.clock = 1;
1101         break;
1102      }
1103      if (vc1541_time_greater(machine, drive, ATTOTIME_IN_USEC(20)))
1104      {
1105         drive->i.serial.data = drive->i.serial.value & 4 ? 1 : 0;
1106         drive->i.serial.clock = 0;
1107         drive->i.serial.state++;
1108         drive->i.serial.time = timer_get_time(machine);
1109         break;
1110      }
1111      break;
1112   case 306:
1113      if (!cbm_serial.atn[0])
1114      {
1115         drive->i.serial.state = 330;
1116         drive->i.serial.data = 1;
1117         drive->i.serial.clock = 1;
1118         break;
1119      }
1120      if (vc1541_time_greater(machine, drive, ATTOTIME_IN_USEC(20)))
1121      {
1122         drive->i.serial.data = drive->i.serial.value & 8 ? 1 : 0;
1123         drive->i.serial.clock = 0;
1124         drive->i.serial.state++;
1125         drive->i.serial.time = timer_get_time(machine);
1126         break;
1127      }
1128      break;
1129   case 308:
1130      if (!cbm_serial.atn[0])
1131      {
1132         drive->i.serial.state = 330;
1133         drive->i.serial.data = 1;
1134         drive->i.serial.clock = 1;
1135         break;
1136      }
1137      if (vc1541_time_greater(machine, drive, ATTOTIME_IN_USEC(20)))
1138      {
1139         drive->i.serial.data = drive->i.serial.value & 0x10 ? 1 : 0;
1140         drive->i.serial.clock = 0;
1141         drive->i.serial.state++;
1142         drive->i.serial.time = timer_get_time(machine);
1143         break;
1144      }
1145      break;
1146   case 310:
1147      if (!cbm_serial.atn[0])
1148      {
1149         drive->i.serial.state = 330;
1150         drive->i.serial.data = 1;
1151         drive->i.serial.clock = 1;
1152         break;
1153      }
1154      if (vc1541_time_greater(machine, drive, ATTOTIME_IN_USEC(20)))
1155      {
1156         drive->i.serial.data = drive->i.serial.value & 0x20 ? 1 : 0;
1157         drive->i.serial.clock = 0;
1158         drive->i.serial.state++;
1159         drive->i.serial.time = timer_get_time(machine);
1160         break;
1161      }
1162      break;
1163   case 312:
1164      if (!cbm_serial.atn[0])
1165      {
1166         drive->i.serial.state = 330;
1167         drive->i.serial.data = 1;
1168         drive->i.serial.clock = 1;
1169         break;
1170      }
1171      if (vc1541_time_greater(machine, drive, ATTOTIME_IN_USEC(20)))
1172      {
1173         drive->i.serial.data = drive->i.serial.value & 0x40 ? 1 : 0;
1174         drive->i.serial.clock = 0;
1175         drive->i.serial.state++;
1176         drive->i.serial.time = timer_get_time(machine);
1177         break;
1178      }
1179      break;
1180   case 314:
1181      if (!cbm_serial.atn[0])
1182      {
1183         drive->i.serial.state = 330;
1184         drive->i.serial.data = 1;
1185         drive->i.serial.clock = 1;
1186         break;
1187      }
1188      if (vc1541_time_greater(machine, drive, ATTOTIME_IN_USEC(20)))
1189      {
1190         drive->i.serial.data = drive->i.serial.value & 0x80 ? 1 : 0;
1191         drive->i.serial.clock = 0;
1192         drive->i.serial.state++;
1193         drive->i.serial.time = timer_get_time(machine);
1194         break;
1195      }
1196      break;
1197   case 316:
1198      if (!cbm_serial.atn[0])
1199      {
1200         drive->i.serial.state = 330;
1201         drive->i.serial.data = 1;
1202         drive->i.serial.clock = 1;
1203         break;
1204      }
1205      if (vc1541_time_greater(machine, drive, ATTOTIME_IN_USEC(20)))
1206      {
1207         DBG_LOG(machine, 1, "vc1541", ("%.2x written\n", drive->i.serial.value));
1208         drive->i.serial.data = 1;
1209         drive->i.serial.clock = 0;
1210         drive->i.serial.state++;
1211         drive->i.serial.time = timer_get_time(machine);
1212         break;
1213      }
1214      break;
1215   case 317:
1216      if (!cbm_serial.atn[0])
1217      {
1218         drive->i.serial.state = 330;
1219         drive->i.serial.data = 1;
1220         drive->i.serial.clock = 1;
1221         break;
1222      }
1223      if (!cbm_serial.data[0])
1224      {
1225         drive->i.serial.state++;
1226         drive->i.serial.time = timer_get_time(machine);
1227         break;
1228      }
1229      break;
1230   case 318:
1231      if (!cbm_serial.atn[0])
1232      {
1233         drive->i.serial.state = 330;
1234         drive->i.serial.data = 1;
1235         drive->i.serial.clock = 1;
1236         break;
1237      }
1238      if (drive->pos + 1 == drive->size)
1239      {
1240         drive->i.serial.clock = 1;
1241         drive->i.serial.state = 0;
1242         break;
1243      }
1244      if (drive->pos + 2 == drive->size)
1245      {
1246         drive->pos++;
1247         drive->i.serial.state = 320;
1248         break;
1249      }
1250      if (vc1541_time_greater(machine, drive, ATTOTIME_IN_USEC(100)))
1251      {
1252         drive->pos++;
1253         drive->i.serial.clock = 1;
1254         drive->i.serial.state = 300;
1255         break;
1256      }
1257      break;
1258   case 320:
1259      if (!cbm_serial.atn[0])
1260      {
1261         drive->i.serial.state = 330;
1262         drive->i.serial.data = 1;
1263         drive->i.serial.clock = 1;
1264         break;
1265      }
1266      if (vc1541_time_greater(machine, drive, ATTOTIME_IN_USEC(100)))
1267      {
1268         drive->i.serial.clock = 1;
1269         drive->i.serial.state++;
1270         break;
1271      }
1272      break;
1273   case 321:
1274      if (!cbm_serial.atn[0])
1275      {
1276         drive->i.serial.state = 330;
1277         drive->i.serial.data = 1;
1278         drive->i.serial.clock = 1;
1279         break;
1280      }
1281      if (cbm_serial.data[0])
1282      {
1283         drive->i.serial.state++;
1284      }
1285      break;
1286   case 322:
1287      if (!cbm_serial.atn[0])
1288      {
1289         drive->i.serial.state = 330;
1290         drive->i.serial.data = 1;
1291         drive->i.serial.clock = 1;
1292         break;
1293      }
1294      if (!cbm_serial.data[0])
1295      {
1296         drive->i.serial.state++;
1297      }
1298      break;
1299   case 323:
1300      if (!cbm_serial.atn[0])
1301      {
1302         drive->i.serial.state = 330;
1303         drive->i.serial.data = 1;
1304         drive->i.serial.clock = 1;
1305         break;
1306      }
1307      if (cbm_serial.data[0])
1308      {
1309         drive->i.serial.state = 300;
1310      }
1311      break;
1312   case 330:                     /* computer breaks receiving */
1313      drive->i.serial.state = 0;
1314      break;
1315   }
1316
1317   if (oldstate != drive->i.serial.state)
1318      if (VERBOSE_LEVEL >= 1) logerror("%d state %d->%d %d %s %s %s\n",
1319             drive->i.serial.device,
1320             oldstate,
1321             drive->i.serial.state, drive->state,
1322             cbm_serial.atn[0] ? "ATN" : "atn",
1323             cbm_serial.clock[0] ? "CLOCK" : "clock",
1324             cbm_serial.data[0] ? "DATA" : "data");
1325}
1326
1327/* difference between vic20 and pet (first series)
1328   pet lowers atn and wants a reaction on ndac */
1329
1330void c2031_state( running_machine *machine, CBM_Drive *drive )
1331{
1332   const device_config *ieeebus = devtag_get_device(machine, "ieee_bus");
1333   int oldstate = drive->i.ieee.state;
1334   int data;
1335
1336   switch (drive->i.ieee.state)
1337   {
1338   case 0:
1339      if (!cbm_ieee_dav_r(ieeebus, 0))
1340      {
1341         drive->i.ieee.state = 10;
1342      }
1343      else if (!cbm_ieee_atn_r(ieeebus, 0))
1344      {
1345         drive->i.ieee.state = 11;
1346         cbm_ieee_ndac_w(ieeebus, 1, 0);
1347         logerror("arsch\n");
1348      }
1349      break;
1350   case 1:
1351      break;
1352   case 10:
1353      if (cbm_ieee_dav_r(ieeebus, 0))
1354      {
1355         drive->i.ieee.state++;
1356         cbm_ieee_nrfd_w(ieeebus, 1, 1);
1357         cbm_ieee_ndac_w(ieeebus, 1, 0);
1358      }
1359      break;
1360   case 11:
1361      if (!cbm_ieee_dav_r(ieeebus, 0))
1362      {
1363         cbm_ieee_nrfd_w(ieeebus, 1, 0);
1364         data = cbm_ieee_data_r(ieeebus, 0) ^ 0xff;
1365         cbm_ieee_ndac_w(ieeebus, 1, 1);
1366         logerror("byte received %.2x\n",data);
1367         if (!cbm_ieee_atn_r(ieeebus, 0) && ((data & 0x0f) == drive->i.ieee.device))
1368         {
1369            if ((data & 0xf0) == 0x40)
1370               drive->i.ieee.state = 30;
1371            else
1372               drive->i.ieee.state = 20;
1373            if (drive->cmdpos < sizeof (drive->cmdbuffer))
1374               drive->cmdbuffer[drive->cmdpos++] = data;
1375         }
1376         else if ((data&0xf) == 0xf)
1377         {
1378            drive->i.ieee.state--;
1379         }
1380         else
1381         {
1382            drive->i.ieee.state++;
1383         }
1384      }
1385      break;
1386      /* wait until atn is released */
1387   case 12:
1388      if (cbm_ieee_atn_r(ieeebus, 0))
1389      {
1390         drive->i.ieee.state++;
1391         cbm_ieee_nrfd_w(ieeebus, 1, 0);
1392      }
1393      break;
1394   case 13:
1395      if (!cbm_ieee_atn_r(ieeebus, 0))
1396      {
1397         drive->i.ieee.state = 10;
1398/*          cbm_ieee_nrfd_w(ieeebus, 1, 0); */
1399      }
1400      break;
1401
1402      /* receiving rest of command */
1403   case 20:
1404      if (cbm_ieee_dav_r(ieeebus, 0))
1405      {
1406         drive->i.ieee.state++;
1407         cbm_ieee_nrfd_w(ieeebus, 1, 1);
1408         cbm_ieee_ndac_w(ieeebus, 1, 0);
1409      }
1410      break;
1411   case 21:
1412      if (!cbm_ieee_dav_r(ieeebus, 0))
1413      {
1414         cbm_ieee_nrfd_w(ieeebus, 1, 0);
1415         data = cbm_ieee_data_r(ieeebus, 0) ^ 0xff;
1416         logerror("byte received %.2x\n",data);
1417         if (drive->cmdpos < sizeof (drive->cmdbuffer))
1418            drive->cmdbuffer[drive->cmdpos++] = data;
1419         if (!cbm_ieee_atn_r(ieeebus, 0) && ((data & 0xf) == 0xf))
1420         {
1421            cbm_command(machine, drive);
1422            drive->i.ieee.state = 10;
1423         }
1424         else
1425            drive->i.ieee.state = 20;
1426
1427         cbm_ieee_ndac_w(ieeebus, 1, 1);
1428      }
1429      break;
1430
1431      /* read command */
1432   case 30:
1433      if (cbm_ieee_dav_r(ieeebus, 0))
1434      {
1435         drive->i.ieee.state++;
1436         cbm_ieee_nrfd_w(ieeebus, 1, 1);
1437         cbm_ieee_ndac_w(ieeebus, 1, 0);
1438      }
1439      break;
1440   case 31:
1441      if (!cbm_ieee_dav_r(ieeebus, 0))
1442      {
1443         cbm_ieee_nrfd_w(ieeebus, 1, 0);
1444         data = cbm_ieee_data_r(ieeebus, 0) ^ 0xff;
1445         logerror("byte received %.2x\n", data);
1446         if (drive->cmdpos < sizeof (drive->cmdbuffer))
1447            drive->cmdbuffer[drive->cmdpos++] = data;
1448         cbm_command(machine, drive);
1449         if (drive->state == READING)
1450            drive->i.ieee.state++;
1451         else
1452            drive->i.ieee.state = 10;
1453         cbm_ieee_ndac_w(ieeebus, 1, 1);
1454      }
1455      break;
1456   case 32:
1457      if (cbm_ieee_dav_r(ieeebus, 0))
1458      {
1459         cbm_ieee_nrfd_w(ieeebus, 1, 1);
1460         drive->i.ieee.state = 40;
1461      }
1462      break;
1463   case 40:
1464      if (!cbm_ieee_ndac_r(ieeebus, 0))
1465      {
1466         cbm_ieee_data_w(ieeebus, 1, drive->buffer[drive->pos++] ^ 0xff);
1467         if (drive->pos >= drive->size)
1468            cbm_ieee_eoi_w(ieeebus, 1, 0);
1469         cbm_ieee_dav_w(ieeebus, 1, 0);
1470         drive->i.ieee.state++;
1471      }
1472      break;
1473   case 41:
1474      if (!cbm_ieee_nrfd_r(ieeebus, 0))
1475      {
1476         drive->i.ieee.state++;
1477      }
1478      break;
1479   case 42:
1480      if (cbm_ieee_ndac_r(ieeebus, 0))
1481      {
1482         if (cbm_ieee_eoi_r(ieeebus, 0))
1483            drive->i.ieee.state = 40;
1484
1485         else
1486         {
1487            cbm_ieee_data_w(ieeebus, 1, 0xff);
1488            cbm_ieee_ndac_w(ieeebus, 1, 0);
1489            cbm_ieee_nrfd_w(ieeebus, 1, 0);
1490            cbm_ieee_eoi_w(ieeebus, 1, 1);
1491            drive->i.ieee.state = 10;
1492         }
1493         cbm_ieee_dav_w(ieeebus, 1, 1);
1494      }
1495      break;
1496   }
1497
1498   if (oldstate != drive->i.ieee.state)
1499      if (VERBOSE_LEVEL >= 1) logerror("%d state %d->%d %d\n",
1500             drive->i.ieee.device,
1501             oldstate,
1502             drive->i.ieee.state, drive->state
1503             );
1504}
1505
1506
1507/**************************************
1508
1509    C1551 handlers
1510
1511**************************************/
1512
1513
1514static void c1551_write_data( running_machine *machine, CBM_Drive * drive, int data )
1515{
1516   drive->i.iec.datain = data;
1517   c1551_state (machine, drive);
1518}
1519
1520static int c1551_read_data( running_machine *machine, CBM_Drive * drive )
1521{
1522   c1551_state (machine, drive);
1523   return drive->i.iec.dataout;
1524}
1525
1526static void c1551_write_handshake( running_machine *machine, CBM_Drive * drive, int data )
1527{
1528   drive->i.iec.handshakein = data&0x40?1:0;
1529   c1551_state (machine, drive);
1530}
1531
1532static int c1551_read_handshake( running_machine *machine, CBM_Drive * drive )
1533{
1534   c1551_state (machine, drive);
1535   return drive->i.iec.handshakeout?0x80:0;
1536}
1537
1538static int c1551_read_status( running_machine *machine, CBM_Drive * drive )
1539{
1540   c1551_state (machine, drive);
1541   return drive->i.iec.status;
1542}
1543
1544
1545WRITE8_DEVICE_HANDLER( c1551_0_write_data )
1546{
1547   c1551_write_data(device->machine, cbm_drive, data);
1548}
1549
1550READ8_DEVICE_HANDLER( c1551_0_read_data )
1551{
1552   return c1551_read_data(device->machine, cbm_drive);
1553}
1554
1555WRITE8_DEVICE_HANDLER( c1551_0_write_handshake )
1556{
1557   c1551_write_handshake(device->machine, cbm_drive, data);
1558}
1559
1560READ8_DEVICE_HANDLER( c1551_0_read_handshake )
1561{
1562   return c1551_read_handshake(device->machine, cbm_drive);
1563}
1564
1565READ8_DEVICE_HANDLER( c1551_0_read_status )
1566{
1567   return c1551_read_status(device->machine, cbm_drive);
1568}
1569
1570WRITE8_DEVICE_HANDLER( c1551_1_write_data )
1571{
1572   c1551_write_data(device->machine, cbm_drive + 1, data);
1573}
1574
1575READ8_DEVICE_HANDLER( c1551_1_read_data )
1576{
1577   return c1551_read_data(device->machine, cbm_drive + 1);
1578}
1579
1580WRITE8_DEVICE_HANDLER( c1551_1_write_handshake )
1581{
1582   c1551_write_handshake(device->machine, cbm_drive + 1, data);
1583}
1584
1585READ8_DEVICE_HANDLER( c1551_1_read_handshake )
1586{
1587   return c1551_read_handshake(device->machine, cbm_drive + 1);
1588}
1589
1590READ8_DEVICE_HANDLER( c1551_1_read_status )
1591{
1592   return c1551_read_status(device->machine, cbm_drive + 1);
1593}
1594
1595
1596/**************************************
1597
1598    VC1541 Serial Bus Device Interface
1599
1600**************************************/
1601
1602static UINT8 vc1541_atn_read( running_machine *machine, CBM_Drive * drive )
1603{
1604   vc1541_state(machine, drive);
1605   return drive->i.serial.atn;
1606}
1607
1608static UINT8 vc1541_data_read( running_machine *machine, CBM_Drive * drive )
1609{
1610   vc1541_state(machine, drive);
1611   return drive->i.serial.data;
1612}
1613
1614static UINT8 vc1541_clock_read( running_machine *machine, CBM_Drive * drive )
1615{
1616   vc1541_state(machine, drive);
1617   return drive->i.serial.clock;
1618}
1619
1620static void vc1541_data_write( running_machine *machine, CBM_Drive * drive, int level )
1621{
1622   vc1541_state(machine, drive);
1623}
1624
1625static void vc1541_clock_write( running_machine *machine, CBM_Drive * drive, int level )
1626{
1627   vc1541_state(machine, drive);
1628}
1629
1630static void vc1541_atn_write( running_machine *machine, CBM_Drive * drive, int level )
1631{
1632   vc1541_state(machine, drive);
1633}
1634
1635static void drive_reset_write( CBM_Drive * drive, int level )
1636{
1637   if (level == 0)
1638   {
1639      drive->i.serial.data =
1640         drive->i.serial.clock =
1641         drive->i.serial.atn = 1;
1642      drive->i.serial.state = 0;
1643   }
1644}
1645
1646static READ8_DEVICE_HANDLER( sim_drive_atn_read )
1647{
1648   int i;
1649
1650   cbm_serial.atn[0] = cbm_serial.atn[1];
1651   for (i = 0; i < cbm_serial.count; i++)
1652      cbm_serial.atn[0] &= cbm_serial.atn[i + 2] =
1653         vc1541_atn_read(device->machine, cbm_serial.drives[i]);
1654   return cbm_serial.atn[0];
1655}
1656
1657static READ8_DEVICE_HANDLER( sim_drive_clock_read )
1658{
1659   int i;
1660
1661   cbm_serial.clock[0] = cbm_serial.clock[1];
1662   for (i = 0; i < cbm_serial.count; i++)
1663      cbm_serial.clock[0] &= cbm_serial.clock[i + 2] =
1664         vc1541_clock_read(device->machine, cbm_serial.drives[i]);
1665   return cbm_serial.clock[0];
1666}
1667
1668static READ8_DEVICE_HANDLER( sim_drive_data_read )
1669{
1670   int i;
1671
1672   cbm_serial.data[0] = cbm_serial.data[1];
1673   for (i = 0; i < cbm_serial.count; i++)
1674      cbm_serial.data[0] &= cbm_serial.data[i + 2] =
1675         vc1541_data_read(device->machine, cbm_serial.drives[i]);
1676   return cbm_serial.data[0];
1677}
1678
1679static READ8_DEVICE_HANDLER( sim_drive_request_read )
1680{
1681   /* in c16 not connected */
1682   return 1;
1683}
1684
1685static WRITE8_DEVICE_HANDLER( sim_drive_atn_write )
1686{
1687   int i;
1688
1689   cbm_serial.atn[0] =
1690      cbm_serial.atn[1] = data;
1691   /* update line */
1692   for (i = 0; i < cbm_serial.count; i++)
1693      cbm_serial.atn[0] &= cbm_serial.atn[i + 2];
1694   /* inform drives */
1695   for (i = 0; i < cbm_serial.count; i++)
1696      vc1541_atn_write(device->machine, cbm_serial.drives[i], cbm_serial.atn[0]);
1697}
1698
1699static WRITE8_DEVICE_HANDLER( sim_drive_clock_write )
1700{
1701   int i;
1702
1703   cbm_serial.clock[0] =
1704      cbm_serial.clock[1] = data;
1705   /* update line */
1706   for (i = 0; i < cbm_serial.count; i++)
1707      cbm_serial.clock[0] &= cbm_serial.clock[i + 2];
1708   /* inform drives */
1709   for (i = 0; i < cbm_serial.count; i++)
1710      vc1541_clock_write(device->machine, cbm_serial.drives[i], cbm_serial.clock[0]);
1711}
1712
1713static WRITE8_DEVICE_HANDLER( sim_drive_data_write )
1714{
1715   int i;
1716
1717   cbm_serial.data[0] =
1718      cbm_serial.data[1] = data;
1719   /* update line */
1720   for (i = 0; i < cbm_serial.count; i++)
1721      cbm_serial.data[0] &= cbm_serial.data[i + 2];
1722   /* inform drives */
1723   for (i = 0; i < cbm_serial.count; i++)
1724      vc1541_data_write(device->machine, cbm_serial.drives[i], cbm_serial.data[0]);
1725}
1726
1727static WRITE8_DEVICE_HANDLER( sim_drive_request_write )
1728{
1729}
1730
1731static WRITE8_DEVICE_HANDLER( sim_drive_reset_write )
1732{
1733   int i;
1734
1735   for (i = 0; i < cbm_serial.count; i++)
1736      drive_reset_write(cbm_serial.drives[i], data);
1737   /* init bus signals */
1738}
1739
1740static const cbm_serial_bus_interface cbm_sim_drive_interface =
1741{
1742   DEVCB_HANDLER(sim_drive_atn_read),
1743   DEVCB_HANDLER(sim_drive_clock_read),
1744   DEVCB_HANDLER(sim_drive_data_read),
1745   DEVCB_HANDLER(sim_drive_request_read),
1746   DEVCB_HANDLER(sim_drive_atn_write),
1747   DEVCB_HANDLER(sim_drive_clock_write),
1748   DEVCB_HANDLER(sim_drive_data_write),
1749   DEVCB_HANDLER(sim_drive_request_write),
1750
1751   DEVCB_HANDLER(sim_drive_reset_write)
1752};
1753
1754
1755MACHINE_DRIVER_START( simulated_drive )
1756   MDRV_CBM_SERBUS_ADD("serial_bus", cbm_sim_drive_interface)
1757MACHINE_DRIVER_END
1758
1759
1760
1761/***********************************************
1762
1763    Drive handling
1764
1765***********************************************/
1766
1767CBM_Drive cbm_drive[2];
1768
1769CBM_Serial cbm_serial;
1770
1771/* must be called before other functions */
1772static void cbm_drive_open( void )
1773{
1774   int i;
1775
1776   memset(cbm_drive, 0, sizeof(cbm_drive));
1777   memset(&cbm_serial, 0, sizeof(cbm_serial));
1778
1779   cbm_drive_open_helper();
1780
1781   cbm_serial.count = 0;
1782   for (i = 0; i < ARRAY_LENGTH(cbm_serial.atn); i++)
1783
1784   {
1785      cbm_serial.atn[i] =
1786         cbm_serial.data[i] =
1787         cbm_serial.clock[i] = 1;
1788   }
1789}
1790
1791static void cbm_drive_close( void )
1792{
1793   int i;
1794
1795   cbm_serial.count = 0;
1796   for (i = 0; i < ARRAY_LENGTH(cbm_drive); i++)
1797   {
1798      cbm_drive[i].interface = 0;
1799
1800      if( cbm_drive[i].buffer )
1801      {
1802         free(cbm_drive[i].buffer);
1803         cbm_drive[i].buffer = NULL;
1804      }
1805
1806      if (cbm_drive[i].drive == D64_IMAGE)
1807         cbm_drive[i].image = NULL;
1808      cbm_drive[i].drive = 0;
1809   }
1810}
1811
1812
1813
1814static void cbm_drive_config( CBM_Drive * drive, int interface, int serialnr )
1815{
1816   int i;
1817
1818   if (interface == SERIAL)
1819      drive->i.serial.device = serialnr;
1820
1821   if (interface == IEEE)
1822      drive->i.ieee.device = serialnr;
1823
1824   if (drive->interface == interface)
1825      return;
1826
1827   if (drive->interface == SERIAL)
1828   {
1829      for (i = 0; (i < cbm_serial.count) && (cbm_serial.drives[i] != drive); i++);
1830      for (; i + 1 < cbm_serial.count; i++)
1831         cbm_serial.drives[i] = cbm_serial.drives[i + 1];
1832      cbm_serial.count--;
1833   }
1834
1835   drive->interface = interface;
1836
1837   if (drive->interface == IEC)
1838   {
1839      drive->i.iec.handshakein =
1840         drive->i.iec.handshakeout = 0;
1841      drive->i.iec.status = 0;
1842      drive->i.iec.dataout = drive->i.iec.datain = 0xff;
1843      drive->i.iec.state = 0;
1844   }
1845   else if (drive->interface == SERIAL)
1846   {
1847      cbm_serial.drives[cbm_serial.count++] = drive;
1848      drive_reset_write(drive, 0);
1849   }
1850}
1851
1852void cbm_drive_0_config( int interface, int serialnr )
1853{
1854   cbm_drive_config(cbm_drive, interface, serialnr);
1855}
1856
1857void cbm_drive_1_config( int interface, int serialnr )
1858{
1859   cbm_drive_config(cbm_drive + 1, interface, serialnr);
1860}
1861
1862
1863/**************************************
1864
1865    Floppy device configurations
1866
1867**************************************/
1868
1869
1870static DEVICE_START( cbm_drive )
1871{
1872   int id = image_index_in_device(device);
1873   if (id == 0)
1874      cbm_drive_open();   /* boy these C64 drivers are butt ugly */
1875}
1876
1877static DEVICE_STOP( cbm_drive )
1878{
1879   int id = image_index_in_device(device);
1880   if (id == 0)
1881      cbm_drive_close();   /* boy these C64 drivers are butt ugly */
1882}
1883
1884
1885
1886/* open an d64 image */
1887static DEVICE_IMAGE_LOAD( cbm_drive )
1888{
1889   int id = image_index_in_device(image);
1890
1891   cbm_drive[id].drive = 0;
1892   cbm_drive[id].image = NULL;
1893
1894   cbm_drive[id].image = image_ptr(image);
1895   if (!cbm_drive[id].image)
1896      return INIT_FAIL;
1897
1898   cbm_drive[id].drive = D64_IMAGE;
1899   return 0;
1900}
1901
1902static DEVICE_IMAGE_UNLOAD( cbm_drive )
1903{
1904   int id = image_index_in_device(image);
1905
1906   cbm_drive[id].drive = 0;
1907   cbm_drive[id].image = NULL;
1908}
1909
1910
1911void cbmfloppy_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info)
1912{
1913   switch(state)
1914   {
1915      /* --- the following bits of info are returned as 64-bit signed integers --- */
1916      case MESS_DEVINFO_INT_TYPE:                     info->i = IO_FLOPPY; break;
1917      case MESS_DEVINFO_INT_READABLE:                  info->i = 1; break;
1918      case MESS_DEVINFO_INT_WRITEABLE:               info->i = 0; break;
1919      case MESS_DEVINFO_INT_CREATABLE:               info->i = 0; break;
1920      case MESS_DEVINFO_INT_COUNT:                  info->i = 2; break;
1921
1922      /* --- the following bits of info are returned as pointers to data or functions --- */
1923      case MESS_DEVINFO_PTR_START:                  info->start = DEVICE_START_NAME(cbm_drive); break;
1924      case MESS_DEVINFO_PTR_STOP:                     info->stop = DEVICE_STOP_NAME(cbm_drive); break;
1925      case MESS_DEVINFO_PTR_LOAD:                     info->load = DEVICE_IMAGE_LOAD_NAME(cbm_drive); break;
1926      case MESS_DEVINFO_PTR_UNLOAD:                  info->unload = DEVICE_IMAGE_UNLOAD_NAME(cbm_drive); break;
1927
1928      /* --- the following bits of info are returned as NULL-terminated strings --- */
1929      case MESS_DEVINFO_STR_FILE_EXTENSIONS:            strcpy(info->s = device_temp_str(), "d64"); break;
1930   }
1931}
src/mess/machine/c65.c
r6732r6733
1414
1515#include "includes/cbm.h"
1616#include "includes/cbmserb.h"
17#include "includes/cbmdrive.h"
1817
1918#include "includes/c65.h"
2019#include "includes/c64.h"
r6732r6733
10461045   /* clear upper memory */
10471046   memset(messram_get_ptr(devtag_get_device(machine, "messram")) + 128*1024, 0xff, messram_get_size(devtag_get_device(machine, "messram")) -  128*1024);
10481047
1049   cbm_drive_0_config (SERIAL, 10);
1050   cbm_drive_1_config (SERIAL, 11);
1048//removed   cbm_drive_0_config (SERIAL, 10);
1049//removed   cbm_drive_1_config (SERIAL, 11);
10511050   c64_vicaddr = c64_memory;
10521051
10531052   c64mode = 0;
src/mess/machine/cbmb.c
r6732r6733
1414#include "video/vic6567.h"
1515#include "includes/cbmserb.h"
1616#include "includes/cbmieeeb.h"
17#include "includes/cbmdrive.h"
1817
1918#include "includes/cbmb.h"
2019
r6732r6733
344343
345344MACHINE_RESET( cbmb )
346345{
347   cbm_drive_0_config (IEEE8ON ? IEEE : 0, 8);
348   cbm_drive_1_config (IEEE9ON ? IEEE : 0, 9);
346//removed   cbm_drive_0_config (IEEE8ON ? IEEE : 0, 8);
347//removed   cbm_drive_1_config (IEEE9ON ? IEEE : 0, 9);
349348}
350349
351350
src/mess/machine/pet.c
r6732r6733
1313#include "machine/6522via.h"
1414#include "includes/cbmserb.h"
1515#include "includes/cbmieeeb.h"
16#include "includes/cbmdrive.h"
1716
1817#include "includes/pet.h"
1918
r6732r6733
717716      cbm8096_w(cputag_get_address_space(machine,"maincpu",ADDRESS_SPACE_PROGRAM), 0, 0);
718717   }
719718
720   cbm_drive_0_config (input_port_read(machine, "CFG") & 2 ? IEEE : 0, 8);
721   cbm_drive_1_config (input_port_read(machine, "CFG") & 1 ? IEEE : 0, 9);
719//removed   cbm_drive_0_config (input_port_read(machine, "CFG") & 2 ? IEEE : 0, 8);
720//removed   cbm_drive_1_config (input_port_read(machine, "CFG") & 1 ? IEEE : 0, 9);
722721   device_reset(cputag_get_cpu(machine, "maincpu"));
723722}
724723
src/mess/machine/c16.c
r6732r6733
1616#include "machine/6525tpi.h"
1717#include "video/ted7360.h"
1818#include "machine/cbmiec.h"
19#include "includes/vc1541.h"
20#include "includes/cbmdrive.h"
2119
2220#include "includes/c16.h"
2321
r6732r6733
459457
460458   memset(messram_get_ptr(devtag_get_device(machine, "messram")) + (0xfd40 % messram_get_size(devtag_get_device(machine, "messram"))), 0xff, 0x20);
461459
462   if (has_c1551)      /* C1551 */
463      c1551_config(machine, "cpu_c1551");
460//removed   if (has_c1551)      /* C1551 */
461//removed      c1551_config(machine, "cpu_c1551");
464462
465   if (has_vc1541)      /* VC1541 */
466      cbm_drive_config(machine, type_1541, 0, 0, "cpu_vc1540", 8);
463//removed   if (has_vc1541)      /* VC1541 */
464//removed      cbm_drive_config(machine, type_1541, 0, 0, "cpu_vc1540", 8);
467465}
468466
469467static void c16_driver_init( running_machine *machine )
r6732r6733
577575   {
578576      memory_nop_readwrite(space, 0xfec0, 0xfedf, 0, 0);
579577   }
580   if (has_c1551)      /* c1551 */
581   {
582      c1551_drive_reset();
583   }
584   if (has_vc1541)      /* vc1541 */
585   {
586      cbm_drive_reset(machine);
587   }
588   else                        /* simulated drives */
589   {
590      cbm_drive_0_config(SERIAL, 8);
591      cbm_drive_1_config(SERIAL, 9);
592   }
578//removed   if (has_c1551)      /* c1551 */
579//removed   {
580//removed      c1551_drive_reset();
581//removed   }
582//removed   if (has_vc1541)      /* vc1541 */
583//removed   {
584//removed      cbm_drive_reset(machine);
585//removed   }
586//removed   else                        /* simulated drives */
587//removed   {
588//removed      cbm_drive_0_config(SERIAL, 8);
589//removed      cbm_drive_1_config(SERIAL, 9);
590//removed   }
593591}
594592
595593
src/mess/machine/primo.c
r6732r6733
1616/* Components */
1717#include "cpu/z80/z80.h"
1818#include "includes/cbmserb.h"
19#include "includes/cbmdrive.h"
2019#include "sound/speaker.h"
2120
2221/* Devices */
r6732r6733
262261{
263262   primo_common_machine_init(machine);
264263
265   cbm_drive_0_config(SERIAL, 8);
266   cbm_drive_1_config(SERIAL, 9);
264//removed   cbm_drive_0_config(SERIAL, 8);
265//removed   cbm_drive_1_config(SERIAL, 9);
267266}
268267
269268/*******************************************************************************
src/mess/machine/cbmieeeb.c
r6732r6733
356356    IMPLEMENTATION
357357***************************************************************************/
358358
359/* This is needed for c2031_state - It will eventually disappear */
360#include "includes/cbmdrive.h"
361
362
363359#define VERBOSE_LEVEL 0
364360#define DBG_LOG( MACHINE, N, M, A ) \
365361   do { \
r6732r6733
400396
401397//  DBG_LOG(ieeedev->machine, 1, "cbm ieee dav", ("%.4x dev:%d %d\n", activecpu_get_pc(), device, data));
402398   ieeebus->bus[device].dav = data;
403   if (device == 0)
404      c2031_state(ieeedev->machine, cbm_drive);
399//removed   if (device == 0)
400//removed      c2031_state(ieeedev->machine, cbm_drive);
405401}
406402
407403WRITE8_DEVICE_HANDLER( cbm_ieee_dav_write )
r6732r6733
415411
416412//  DBG_LOG(ieeedev->machine, 1, "cbm ieee nrfd", ("%.4x dev:%d %d\n", activecpu_get_pc(), device, data));
417413   ieeebus->bus[device].nrfd = data;
418   if (device == 0)
419      c2031_state(ieeedev->machine, cbm_drive);
414//removed   if (device == 0)
415//removed      c2031_state(ieeedev->machine, cbm_drive);
420416}
421417
422418WRITE8_DEVICE_HANDLER( cbm_ieee_nrfd_write )
r6732r6733
430426
431427//  DBG_LOG(ieeedev->machine, 1, "cbm ieee ndac",("%.4x dev:%d %d\n", activecpu_get_pc(), device, data));
432428   ieeebus->bus[device].ndac = data;
433   if (device == 0)
434      c2031_state(ieeedev->machine, cbm_drive);
429//removed   if (device == 0)
430//removed      c2031_state(ieeedev->machine, cbm_drive);
435431}
436432
437433WRITE8_DEVICE_HANDLER( cbm_ieee_ndac_write )
r6732r6733
445441
446442//  DBG_LOG(ieeedev->machine, 1, "cbm ieee atn",("%.4x dev:%d %d\n", activecpu_get_pc(), device, data));
447443   ieeebus->bus[device].atn = data;
448   if (device == 0)
449      c2031_state(ieeedev->machine, cbm_drive);
444//removed   if (device == 0)
445//removed      c2031_state(ieeedev->machine, cbm_drive);
450446}
451447
452448WRITE8_DEVICE_HANDLER( cbm_ieee_atn_write )
r6732r6733
460456
461457//  DBG_LOG(ieeedev->machine, 1, "cbm ieee eoi", ("%.4x dev:%d %d\n", activecpu_get_pc(), device, data));
462458   ieeebus->bus[device].eoi = data;
463   if (device == 0)
464      c2031_state(ieeedev->machine, cbm_drive);
459//removed   if (device == 0)
460//removed      c2031_state(ieeedev->machine, cbm_drive);
465461}
466462
467463WRITE8_DEVICE_HANDLER( cbm_ieee_eoi_write )
r6732r6733
475471
476472//  DBG_LOG(ieeedev->machine, 1, "cbm ieee data", ("%.4x dev:%d %.2x\n", activecpu_get_pc(), device, data));
477473   ieeebus->bus[device].data = data;
478   if (device == 0)
479      c2031_state(ieeedev->machine, cbm_drive);
474//removed   if (device == 0)
475//removed      c2031_state(ieeedev->machine, cbm_drive);
480476}
481477
482478WRITE8_DEVICE_HANDLER( cbm_ieee_data_write )
src/mess/machine/vc20.c
r6732r6733
2121#include "video/vic6560.h"
2222#include "machine/cbmiec.h"
2323#include "includes/cbmieeeb.h"
24#include "includes/cbmdrive.h"
2524
2625#include "includes/vc20.h"
2726
r6732r6733
635634{
636635   const device_config *via_0 = devtag_get_device(machine, "via6522_0");
637636
638   if (ieee)
637// removed   
638/*   if (ieee)
639639   {
640640      cbm_drive_0_config(IEEE, 8);
641641      cbm_drive_1_config(IEEE, 9);
642642   }
643
643*/
644644   via_ca1_w(via_0, 0, vc20_via0_read_ca1(via_0, 0));
645645
646646   /* Set up memory banks */
src/mess/mess.mak
r6732r6733
696696   $(MESS_FORMATS)/cbm_tap.o    \
697697   $(MESS_MACHINE)/6525tpi.o   \
698698   $(MESS_MACHINE)/cbm.o      \
699   $(MESS_MACHINE)/cbmdrive.o   \
700   $(MESS_MACHINE)/vc1541.o   \
701699   $(MESS_MACHINE)/cbmieeeb.o    \
702700   $(MESS_MACHINE)/cbmserb.o    \
703701   $(MESS_MACHINE)/cbmipt.o      \
src/mess/drivers/c65.c
r6732r6733
6262
6363/* devices config */
6464#include "includes/cbm.h"
65#include "includes/cbmdrive.h"
6665
6766#include "includes/c64.h"
6867#include "includes/c65.h"
r6732r6733
245244   MDRV_CIA6526_ADD("cia_1", CIA6526R1, 3500000, c65_ntsc_cia1)
246245
247246   /* floppy from serial bus */
248   MDRV_IMPORT_FROM(simulated_drive)
247//removed   MDRV_IMPORT_FROM(simulated_drive)
249248
250249   MDRV_IMPORT_FROM(c64_cartslot)
251250
r6732r6733
304303   ROM_LOAD( "910429.bin", 0x20000, 0x20000, CRC(b025805c) SHA1(c3b05665684f74adbe33052a2d10170a1063ee7d) )
305304ROM_END
306305
307
308/*************************************
309 *
310 *  System configuration(s)
311 *
312 *************************************/
313static SYSTEM_CONFIG_START( c65 )
314   // to investigate which carts could work in the c65 expansion port!
315   CONFIG_DEVICE(cbmfloppy_device_getinfo)
316SYSTEM_CONFIG_END
317
318306/***************************************************************************
319307
320308  Game driver(s)
r6732r6733
323311
324312/*    YEAR  NAME    PARENT  COMPAT  MACHINE INPUT   INIT    CONFIG  COMPANY                         FULLNAME                                              FLAGS */
325313
326COMP( 1991, c65,    0,      0,      c65,    c65,    c65,    c65,    "Commodore Electronics, Ltd.",  "Commodore 65 Development System (Prototype, NTSC)", GAME_NOT_WORKING )
327COMP( 1991, c64dx,  c65,    0,      c65pal, c65ger, c65pal, c65,    "Commodore Electronics, Ltd.",  "Commodore 64DX Development System (Prototype, PAL, German)", GAME_NOT_WORKING )
314COMP( 1991, c65,    0,      0,      c65,    c65,    c65,    0,    "Commodore Electronics, Ltd.",  "Commodore 65 Development System (Prototype, NTSC)", GAME_NOT_WORKING )
315COMP( 1991, c64dx,  c65,    0,      c65pal, c65ger, c65pal, 0,    "Commodore Electronics, Ltd.",  "Commodore 64DX Development System (Prototype, PAL, German)", GAME_NOT_WORKING )
src/mess/drivers/pet.c
r6732r6733
393393
394394/* devices config */
395395#include "includes/cbm.h"
396#include "includes/cbmdrive.h"
397396#include "includes/cbmieeeb.h"
398397
399398/*************************************
r6732r6733
11201119   ROM_LOAD("skand.gen.ub3", 0x0000, 0x1000, CRC(da1cd630) SHA1(35f472114ff001259bdbae073ae041b0759e32cb) )   // Actual label was "901640-01 SKAND.GEN."
11211120ROM_END
11221121
1123
1124
1125
1126/*************************************
1127 *
1128 *  System configuration(s)
1129 *
1130 *************************************/
1131
1132static SYSTEM_CONFIG_START( pet )
1133   CONFIG_DEVICE(cbmfloppy_device_getinfo)
1134SYSTEM_CONFIG_END
1135
11361122/***************************************************************************
11371123
11381124  Game driver(s)
r6732r6733
11411127
11421128/* YEAR    NAME      PARENT    COMPAT    MACHINE   INPUT     INIT      CONFIG     COMPANY                             FULLNAME */
11431129
1144COMP(1977, pet2001,  0,        0,        pet2001,  pet,      pet2001,  pet,      "Commodore Business Machines Co.",  "PET 2001", GAME_NO_SOUND)
1145COMP(1979, pet2001n, pet2001,  0,        pet,      pet,      pet,      pet,      "Commodore Business Machines Co.",  "PET 2001-N", GAME_NO_SOUND)
1146COMP(1979, pet2001b, pet2001,  0,        petb,     petb,     pet,      pet,      "Commodore Business Machines Co.",  "PET 2001-B", GAME_NO_SOUND)
1147COMP(1979, cbm30,    pet2001,  0,        pet,      pet,      pet,      pet,      "Commodore Business Machines Co.",  "CBM 30xx", GAME_NO_SOUND)
1148COMP(1979, cbm30b,   pet2001,  0,        petb,     petb,     pet,      pet,      "Commodore Business Machines Co.",  "CBM 30xx (Business keyboard)", GAME_NO_SOUND)
1149COMP(1979, cbm30nor, pet2001,  0,        petb,     petb,     pet,      pet,      "Commodore Business Machines Co.",  "CBM 30xx (Norway, Business keyboard)", GAME_NO_SOUND)
1130COMP(1977, pet2001,  0,        0,        pet2001,  pet,      pet2001,  0,      "Commodore Business Machines Co.",  "PET 2001", GAME_NO_SOUND)
1131COMP(1979, pet2001n, pet2001,  0,        pet,      pet,      pet,      0,      "Commodore Business Machines Co.",  "PET 2001-N", GAME_NO_SOUND)
1132COMP(1979, pet2001b, pet2001,  0,        petb,     petb,     pet,      0,      "Commodore Business Machines Co.",  "PET 2001-B", GAME_NO_SOUND)
1133COMP(1979, cbm30,    pet2001,  0,        pet,      pet,      pet,      0,      "Commodore Business Machines Co.",  "CBM 30xx", GAME_NO_SOUND)
1134COMP(1979, cbm30b,   pet2001,  0,        petb,     petb,     pet,      0,      "Commodore Business Machines Co.",  "CBM 30xx (Business keyboard)", GAME_NO_SOUND)
1135COMP(1979, cbm30nor, pet2001,  0,        petb,     petb,     pet,      0,      "Commodore Business Machines Co.",  "CBM 30xx (Norway, Business keyboard)", GAME_NO_SOUND)
11501136
11511137/* So called, THIN-40 */
1152COMP(1980, pet40on,  pet2001,  0,        pet,      pet,      pet,      pet,      "Commodore Business Machines Co.",  "PET 40xx (Basic 4, no CRTC, Normal keyboard)", GAME_NO_SOUND)
1153COMP(1980, pet40ob,  pet2001,  0,        petb,     petb,     pet,      pet,      "Commodore Business Machines Co.",  "PET 40xx (Basic 4, no CRTC, Business keyboard)", GAME_NO_SOUND)
1154COMP(1980, cbm40o,   pet2001,  0,        pet,      pet,      pet,      pet,      "Commodore Business Machines Co.",  "CBM 40xx (Basic 4, no CRTC, Normal keyboard)", GAME_NO_SOUND)
1155COMP(1980, cbm40ob,  pet2001,  0,        petb,     petb,     pet,      pet,      "Commodore Business Machines Co.",  "CBM 40xx (Basic 4, no CRTC, Business keyboard)", GAME_NO_SOUND)
1138COMP(1980, pet40on,  pet2001,  0,        pet,      pet,      pet,      0,      "Commodore Business Machines Co.",  "PET 40xx (Basic 4, no CRTC, Normal keyboard)", GAME_NO_SOUND)
1139COMP(1980, pet40ob,  pet2001,  0,        petb,     petb,     pet,      0,      "Commodore Business Machines Co.",  "PET 40xx (Basic 4, no CRTC, Business keyboard)", GAME_NO_SOUND)
1140COMP(1980, cbm40o,   pet2001,  0,        pet,      pet,      pet,      0,      "Commodore Business Machines Co.",  "CBM 40xx (Basic 4, no CRTC, Normal keyboard)", GAME_NO_SOUND)
1141COMP(1980, cbm40ob,  pet2001,  0,        petb,     petb,     pet,      0,      "Commodore Business Machines Co.",  "CBM 40xx (Basic 4, no CRTC, Business keyboard)", GAME_NO_SOUND)
11561142
1157COMP(1981, pet80,    0,        0,        pet80,    cbm8096,  pet80,    pet,      "Commodore Business Machines Co.",  "PET 80xx (Basic 4, CRTC 60Hz, 80 columns)", GAME_NO_SOUND)
1158COMP(1981, cbm80,    pet80,    0,        pet80pal, cbm8096,  pet80,    pet,      "Commodore Business Machines Co.",  "CBM 80xx (Basic 4, CRTC 50Hz, 80 columns)", GAME_NO_SOUND)
1159COMP(1981, cbm80ger, pet80,    0,        pet80pal, cbm8096,  pet80,    pet,      "Commodore Business Machines Co.",  "CBM 80xx (Germany, Basic 4, CRTC 50Hz, 80 columns)", GAME_NO_SOUND)
1160COMP(1981, cbm80hun, pet80,    0,        pet80pal, cbm8096,  pet80,    pet,      "Commodore Business Machines Co.",  "CBM 80xx (Hungary, Basic 4, CRTC 50Hz, 80 columns)", GAME_NO_SOUND)
1161COMP(1981, cbm80swe, pet80,    0,        pet80pal, cbm8096,  pet80,    pet,      "Commodore Business Machines Co.",  "CBM 80xx (Sweden, Basic 4, CRTC 50Hz, 80 columns)", GAME_NO_SOUND)
1143COMP(1981, pet80,    0,        0,        pet80,    cbm8096,  pet80,    0,      "Commodore Business Machines Co.",  "PET 80xx (Basic 4, CRTC 60Hz, 80 columns)", GAME_NO_SOUND)
1144COMP(1981, cbm80,    pet80,    0,        pet80pal, cbm8096,  pet80,    0,      "Commodore Business Machines Co.",  "CBM 80xx (Basic 4, CRTC 50Hz, 80 columns)", GAME_NO_SOUND)
1145COMP(1981, cbm80ger, pet80,    0,        pet80pal, cbm8096,  pet80,    0,      "Commodore Business Machines Co.",  "CBM 80xx (Germany, Basic 4, CRTC 50Hz, 80 columns)", GAME_NO_SOUND)
1146COMP(1981, cbm80hun, pet80,    0,        pet80pal, cbm8096,  pet80,    0,      "Commodore Business Machines Co.",  "CBM 80xx (Hungary, Basic 4, CRTC 50Hz, 80 columns)", GAME_NO_SOUND)
1147COMP(1981, cbm80swe, pet80,    0,        pet80pal, cbm8096,  pet80,    0,      "Commodore Business Machines Co.",  "CBM 80xx (Sweden, Basic 4, CRTC 50Hz, 80 columns)", GAME_NO_SOUND)
11621148
11631149/* So called, FAT-40 */
1164COMP(1981, pet40b,   pet80,    0,        pet80,    cbm8096,  pet80,    pet,      "Commodore Business Machines Co.",  "PET 40xx (Basic 4, CRTC 60Hz, 80 columns)", GAME_NO_SOUND)
1165COMP(1981, pet40n,   pet2001,  0,        pet40,    pet,      pet,      pet,     "Commodore Business Machines Co.",  "PET 40xx (Basic 4, CRTC 60Hz, 40 columns)", GAME_NO_SOUND)
1166COMP(1981, cbm40b,   pet80,    0,        pet80pal, cbm8096,  pet80,    pet,      "Commodore Business Machines Co.",  "CBM 40xx (Basic 4, CRTC 50Hz, 80 columns)", GAME_NO_SOUND)
1167COMP(1981, cbm40n,   pet2001,  0,        pet40pal, pet,      pet,      pet,     "Commodore Business Machines Co.",  "CBM 40xx (Basic 4, CRTC 50Hz, 40 columns)", GAME_NO_SOUND)
1150COMP(1981, pet40b,   pet80,    0,        pet80,    cbm8096,  pet80,    0,      "Commodore Business Machines Co.",  "PET 40xx (Basic 4, CRTC 60Hz, 80 columns)", GAME_NO_SOUND)
1151COMP(1981, pet40n,   pet2001,  0,        pet40,    pet,      pet,      0,     "Commodore Business Machines Co.",  "PET 40xx (Basic 4, CRTC 60Hz, 40 columns)", GAME_NO_SOUND)
1152COMP(1981, cbm40b,   pet80,    0,        pet80pal, cbm8096,  pet80,    0,      "Commodore Business Machines Co.",  "CBM 40xx (Basic 4, CRTC 50Hz, 80 columns)", GAME_NO_SOUND)
1153COMP(1981, cbm40n,   pet2001,  0,        pet40pal, pet,      pet,      0,     "Commodore Business Machines Co.",  "CBM 40xx (Basic 4, CRTC 50Hz, 40 columns)", GAME_NO_SOUND)
11681154
1169COMP(1981, superpet, 0,        0,        superpet, superpet, superpet, pet,      "Commodore Business Machines Co.",  "SuperPET (CRTC 50Hz)", GAME_NO_SOUND | GAME_NOT_WORKING)
1170COMP(1981, sp9000,   superpet, 0,        superpet, superpet, superpet, pet,      "Commodore Business Machines Co.",  "CBM SP9000 / MicroMainFrame 9000 (CRTC 50Hz)", GAME_NO_SOUND | GAME_NOT_WORKING)
1171COMP(198?, mmf9000s, superpet, 0,        superpet, superpet, superpet, pet,      "Commodore Business Machines Co.",  "MicroMainFrame 9000 (Sweden, CRTC 50Hz)", GAME_NO_SOUND | GAME_NOT_WORKING)
1155COMP(1981, superpet, 0,        0,        superpet, superpet, superpet, 0,      "Commodore Business Machines Co.",  "SuperPET (CRTC 50Hz)", GAME_NO_SOUND | GAME_NOT_WORKING)
1156COMP(1981, sp9000,   superpet, 0,        superpet, superpet, superpet, 0,      "Commodore Business Machines Co.",  "CBM SP9000 / MicroMainFrame 9000 (CRTC 50Hz)", GAME_NO_SOUND | GAME_NOT_WORKING)
1157COMP(198?, mmf9000s, superpet, 0,        superpet, superpet, superpet, 0,      "Commodore Business Machines Co.",  "MicroMainFrame 9000 (Sweden, CRTC 50Hz)", GAME_NO_SOUND | GAME_NOT_WORKING)
11721158
1173COMP(1984, cbm8296,  pet80,    0,        pet80pal, cbm8096,  pet80,    pet,      "Commodore Business Machines Co.",  "CBM 8296 (Basic 4, CRTC 50Hz, 80 columns)", GAME_NO_SOUND)
1174COMP(1984, cbm8296d, pet80,    0,        pet80pal, cbm8096,  pet80,    pet,      "Commodore Business Machines Co.",  "CBM 8296D", GAME_NO_SOUND)
1159COMP(1984, cbm8296,  pet80,    0,        pet80pal, cbm8096,  pet80,    0,      "Commodore Business Machines Co.",  "CBM 8296 (Basic 4, CRTC 50Hz, 80 columns)", GAME_NO_SOUND)
1160COMP(1984, cbm8296d, pet80,    0,        pet80pal, cbm8096,  pet80,    0,      "Commodore Business Machines Co.",  "CBM 8296D", GAME_NO_SOUND)
src/mess/drivers/c16.c
r6732r6733
122122#include "sound/sid6581.h"
123123
124124#include "machine/6525tpi.h"
125#include "includes/vc1541.h"
126125#include "machine/cbmipt.h"
127126#include "video/ted7360.h"
128127#include "devices/messram.h"
r6732r6733
131130
132131/* devices config */
133132#include "includes/cbm.h"
134#include "includes/cbmdrive.h"
135133#include "machine/cbmiec.h"
136134
137135#include "includes/c16.h"
r6732r6733
369367
370368static const tpi6525_interface c16_tpi6525_tpi_2_intf =
371369{
372   c1551_0_read_data,
373   c1551_0_read_status,
374   c1551_0_read_handshake,
375   c1551_0_write_data,
370   NULL, //removed c1551_0_read_data,
371   NULL, //removed c1551_0_read_status,
372   NULL, //removed c1551_0_read_handshake,
373   NULL, //removed c1551_0_write_data,
376374   NULL,
377   c1551_0_write_handshake,
375   NULL, //removed c1551_0_write_handshake,
378376   NULL,
379377   NULL,
380378   NULL
r6732r6733
382380
383381static const tpi6525_interface c16_tpi6525_tpi_2_c1551_intf =
384382{
385   c1551x_read_data,
386   c1551x_read_status,
387   c1551x_read_handshake,
388   c1551x_write_data,
383   NULL, //removed c1551x_read_data,
384   NULL, //removed c1551x_read_status,
385   NULL, //removed c1551x_read_handshake,
386   NULL, //removed c1551x_write_data,
389387   NULL,
390   c1551x_write_handshake,
388   NULL, //removed c1551x_write_handshake,
391389   NULL,
392390   NULL,
393391   NULL
r6732r6733
395393
396394static const tpi6525_interface c16_tpi6525_tpi_3_intf =
397395{
398   c1551_1_read_data,
399   c1551_1_read_status,
400   c1551_1_read_handshake,
401   c1551_1_write_data,
396   NULL, //removed c1551_1_read_data,
397   NULL, //removed c1551_1_read_status,
398   NULL, //removed c1551_1_read_handshake,
399   NULL, //removed c1551_1_write_data,
402400   NULL,
403   c1551_1_write_handshake,
401   NULL, //removed c1551_1_write_handshake,
404402   NULL,
405403   NULL,
406404   NULL
r6732r6733
491489   /* emulation code currently supports only one drive */
492490   MDRV_DEVICE_REMOVE("tpi6535_tpi_3")
493491
494   MDRV_IMPORT_FROM( cpu_c1551 )
492//removed    MDRV_IMPORT_FROM( cpu_c1551 )
495493#ifdef CPU_SYNC
496494   MDRV_QUANTUM_TIME(HZ(60))
497495#else
r6732r6733
546544   /* emulation code currently supports only one drive */
547545   MDRV_DEVICE_REMOVE("tpi6535_tpi_3")
548546
549   MDRV_IMPORT_FROM( cpu_c1551 )
547//removed   MDRV_IMPORT_FROM( cpu_c1551 )
550548
551549   MDRV_SCREEN_MODIFY("screen")
552550   MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
r6732r6733
601599 *  ROM definition(s)
602600 *
603601 *************************************/
602#define C1551_ROM( cpu )   \
603   ROM_REGION( 0x10000, cpu, 0 )   \
604   ROM_LOAD( "318008-01.u4", 0xc000, 0x4000, CRC(6d16d024) SHA1(fae3c788ad9a6cc2dbdfbcf6c0264b2ca921d55e) )
604605
605606ROM_START( c232 )
606607   ROM_REGION( 0x40000, "maincpu", 0 )
r6732r6733
700701   ROM_LOAD( "317054-01.bin", 0x1c000, 0x4000, CRC(109de2fc) SHA1(0ad7ac2db7da692d972e586ca0dfd747d82c7693) )
701702ROM_END
702703
703
704/*************************************
705 *
706 *  System configuration(s)
707 *
708 *************************************/
709
710
711static SYSTEM_CONFIG_START(c16)
712   CONFIG_DEVICE(cbmfloppy_device_getinfo)
713SYSTEM_CONFIG_END
714
715static SYSTEM_CONFIG_START(c16c)
716   CONFIG_DEVICE(c1551_device_getinfo)
717SYSTEM_CONFIG_END
718
719static SYSTEM_CONFIG_START(plus)
720   CONFIG_DEVICE(cbmfloppy_device_getinfo)
721SYSTEM_CONFIG_END
722
723static SYSTEM_CONFIG_START(plusc)
724   CONFIG_DEVICE(c1551_device_getinfo)
725SYSTEM_CONFIG_END
726
727
728704/***************************************************************************
729705
730706  Game driver(s)
r6732r6733
733709
734710/*    YEAR  NAME  PARENT COMPAT MACHINE INPUT   INIT   CONFIG    COMPANY                             FULLNAME            FLAGS */
735711
736COMP( 1984, c16,     0,     0,  c16,    c16,    c16,    c16,     "Commodore Business Machines Co.",  "Commodore 16 (PAL)", 0)
737COMP( 1984, c16c,    c16,   0,  c16c,   c16,    c16c,   c16c,    "Commodore Business Machines Co.",  "Commodore 16 (PAL, 1551)", 0 )
712COMP( 1984, c16,     0,     0,  c16,    c16,    c16,    0,    "Commodore Business Machines Co.",  "Commodore 16 (PAL)", 0)
713COMP( 1984, c16c,    c16,   0,  c16c,   c16,    c16c,   0,    "Commodore Business Machines Co.",  "Commodore 16 (PAL, 1551)", 0 )
738714COMP( 1984, c16v,    c16,   0,  c16v,   c16,    c16v,   0,    "Commodore Business Machines Co.",  "Commodore 16 (PAL, VC1541)", GAME_NOT_WORKING)
739COMP( 1984, c16hun,  c16,   0,  c16,    c16,    c16,    c16,     "Commodore Business Machines Co.",  "Commodore 16 Novotrade (PAL, Hungary)", 0)
715COMP( 1984, c16hun,  c16,   0,  c16,    c16,    c16,    0,    "Commodore Business Machines Co.",  "Commodore 16 Novotrade (PAL, Hungary)", 0)
740716
741COMP( 1984, c116,    c16,   0,  c16,    c16,    c16,    c16,     "Commodore Business Machines Co.",  "Commodore 116 (PAL)", 0)
742COMP( 1984, c116c,    c16,   0,  c16c,   c16,    c16c,   c16c,    "Commodore Business Machines Co.",  "Commodore 116 (PAL, 1551)", 0 )
717COMP( 1984, c116,    c16,   0,  c16,    c16,    c16,    0,    "Commodore Business Machines Co.",  "Commodore 116 (PAL)", 0)
718COMP( 1984, c116c,    c16,   0,  c16c,   c16,    c16c,   0,    "Commodore Business Machines Co.",  "Commodore 116 (PAL, 1551)", 0 )
743719COMP( 1984, c116v,   c16,   0,  c16v,   c16,    c16v,   0,    "Commodore Business Machines Co.",  "Commodore 116 (PAL, VC1541)", GAME_NOT_WORKING)
744720
745COMP( 1984, plus4,   c16,   0,  plus4,  plus4,  c16,    plus,    "Commodore Business Machines Co.",  "Commodore Plus/4 (NTSC)", 0)
746COMP( 1984, plus4c,  c16,   0,  plus4c, plus4,  c16c,   plusc,   "Commodore Business Machines Co.",  "Commodore Plus/4 (NTSC, 1551)", 0 )
747COMP( 1984, plus4v,  c16,   0,  plus4v, plus4,  c16v,   0,   "Commodore Business Machines Co.",  "Commodore Plus/4 (NTSC, VC1541)", GAME_NOT_WORKING)
721COMP( 1984, plus4,   c16,   0,  plus4,  plus4,  c16,    0,    "Commodore Business Machines Co.",  "Commodore Plus/4 (NTSC)", 0)
722COMP( 1984, plus4c,  c16,   0,  plus4c, plus4,  c16c,   0,    "Commodore Business Machines Co.",  "Commodore Plus/4 (NTSC, 1551)", 0 )
723COMP( 1984, plus4v,  c16,   0,  plus4v, plus4,  c16v,   0,    "Commodore Business Machines Co.",  "Commodore Plus/4 (NTSC, VC1541)", GAME_NOT_WORKING)
748724
749COMP( 1984, c232,    c16,   0,  c16,    c16,    c16,    c16,     "Commodore Business Machines Co.",  "Commodore 232 (Prototype)", 0)
750COMP( 1984, c264,    c16,   0,  c264,   plus4,  c16,    plus,    "Commodore Business Machines Co.",  "Commodore 264 (Prototype)", 0)
751COMP( 1984, c364,    c16,   0,  c364,   plus4,  c16,    plus,    "Commodore Business Machines Co.",  "Commodore V364 (Prototype)", GAME_IMPERFECT_SOUND)
725COMP( 1984, c232,    c16,   0,  c16,    c16,    c16,    0,    "Commodore Business Machines Co.",  "Commodore 232 (Prototype)", 0)
726COMP( 1984, c264,    c16,   0,  c264,   plus4,  c16,    0,    "Commodore Business Machines Co.",  "Commodore 264 (Prototype)", 0)
727COMP( 1984, c364,    c16,   0,  c364,   plus4,  c16,    0,    "Commodore Business Machines Co.",  "Commodore V364 (Prototype)", GAME_IMPERFECT_SOUND)
src/mess/drivers/primo.c
r6732r6733
114114#include "devices/cartslot.h"
115115#include "formats/primoptp.h"
116116
117#include "includes/cbmdrive.h"
118
119117static ADDRESS_MAP_START( primoa_port, ADDRESS_SPACE_IO, 8 )
120118   ADDRESS_MAP_GLOBAL_MASK(0xff)
121119   AM_RANGE( 0x00, 0x3f ) AM_READWRITE( primo_be_1_r, primo_ki_1_w )
r6732r6733
283281   /* floppy from serial bus */
284282   /* for some reason machine/primo.c sets up the serial bus
285283    but no floppy drive has been apparently added... incomplete driver? */
286   MDRV_IMPORT_FROM(simulated_drive)
284//removed   MDRV_IMPORT_FROM(simulated_drive)
287285
288286   /* cartridge */
289287   MDRV_CARTSLOT_ADD("cart1")
r6732r6733
403401   ROM_CART_LOAD("cart1", 0x18000, 0x4000, ROM_FILL_FF | ROM_OPTIONAL)
404402ROM_END
405403
406
407#ifdef UNUSED_FUNCTION
408static void primo_cartslot_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info)
409{
410    switch(state)
411    {
412        case MESS_DEVINFO_STR_DESCRIPTION+0:                    strcpy(info->s = device_temp_str(), "EPROM Expansion Bank #1"); break;
413        case MESS_DEVINFO_STR_DESCRIPTION+1:                    strcpy(info->s = device_temp_str(), "EPROM Expansion Bank #2"); break;
414        case MESS_DEVINFO_STR_DESCRIPTION+2:                    strcpy(info->s = device_temp_str(), "EPROM Expansion Bank #3"); break;
415        case MESS_DEVINFO_STR_DESCRIPTION+3:                    strcpy(info->s = device_temp_str(), "EPROM Expansion Bank #4"); break;
416
417        default:                                        cartslot_device_getinfo(devclass, state, info); break;
418    }
419}
420#endif
421
422404/*     YEAR  NAME      PARENT    COMPAT MACHINE   INPUT  INIT     CONFIG COMPANY  FULLNAME */
423405COMP ( 1984, primoa32, 0,        0,     primoa32, primo, primo32, 0, "Microkey", "Primo A-32" , 0)
424406COMP ( 1984, primoa48, primoa32, 0,     primoa48, primo, primo48, 0, "Microkey", "Primo A-48" , 0)

Previous 15994 Revisions Next


© 1998-2018 The MESS Team