Previous 15994 Revisions Next

r3252 Saturday 13th September, 2008 at 13:22:49 UTC by Fabio Priuli
[CBM] Made the floppy emulation a bit less 1541-centric. No effective progress, just clean-ups.
[src/mess/includes]vc1541.h
[src/mess/machine]c16.c c64.c vc1541.c vc20.c

src/mess/includes/vc1541.h
r3251r3252
99#ifndef VC1541_H_
1010#define VC1541_H_
1111
12typedef struct {
13   int cpunr;
14   int devicenr;
15} VC1541_CONFIG;
16
17
1812/*----------- defined in machine/vc1541.c -----------*/
1913
14/* we currently have preliminary support for 1541 & 1551 only */
15enum {
16type_1541 = 0,
17type_1541ii,
18type_1551,
19type_1570,
20type_1571,
21type_1571cr,
22type_1581,
23type_2031,
24type_2040,
25type_3040,
26type_4040,
27type_1001,
28type_8050,
29type_8250,
30};
31
2032DEVICE_IMAGE_LOAD(vc1541);
2133DEVICE_IMAGE_UNLOAD(vc1541);
2234
23int vc1541_config(int id, int mode, VC1541_CONFIG*config);
24void vc1541_reset(void);
25void vc1541_drive_status(char *text, int size);
35int drive_config(int type, int id, int mode, int cpunr, int devicenr);
36void drive_reset(void);
2637
27typedef struct {
28   int cpunr;
29} C1551_CONFIG;
30
31int c1551_config(int id, int mode, C1551_CONFIG*config);
32#define c1551_reset vc1541_reset
33
34enum
35{
36   DEVINFO_PTR_VC1541_CONFIG = MESS_DEVINFO_PTR_DEV_SPECIFIC
37};
38
3938void vc1541_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info);
4039void c2031_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info);
4140void c1551_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info);
src/mess/machine/vc1541.c
r3251r3252
9696 2 heads
9797
9898 */
99/* 2008-09 FP
100started some work on the floppy emulation code:
101   + made the functions / structs less vc1541-centric   
102   + unified config & reset functions, using type variable
103      to choose the actions to be done
104 
105a limitation is clear: only a single occurrence of emulated drive
106is expected.
107at a later stage, at least drive_config & drive_reset will need
108an index to choose between the drives
99109
110current status:
111   + preliminary vc1541 & c1551 implementation (I still have to
112      investigate how good)
113   + no support for other drive types (even if now I list all
114      the variants supported by Vice in the enum)
115*/
116
117
100118#include <assert.h>
101119#include <stdio.h>
102120
r3251r3252
140158/* G64 or D64 image
141159 implementation as writeback system
142160 */
143typedef enum { TypeVC1541, TypeC1551, Type2031 } CBM_Drive_Emu_type;
144161
145162typedef struct
146163{
147164   int cpunumber;
148   CBM_Drive_Emu_type type;
165   int type;
149166   union {
150167      struct {
151168         int deviceid;
r3251r3252
157174      } ieee488;
158175      struct {
159176         UINT8 cpu_ddr, cpu_port;
160         void *timer;
177         void *irq_timer;
161178      } c1551;
162179   } drive;
163180
r3251r3252
184201   } d64;
185202} CBM_Drive_Emu;
186203
187static CBM_Drive_Emu vc1541_static= { 0 }, *vc1541 = &vc1541_static;
204static CBM_Drive_Emu drive_static= { 0 }, *drive = &drive_static;
188205
206
207/**************************************
208
209   Generic image handling
210
211**************************************/
212
213
189214/* four different frequencies for the 4 different zones on the disk */
190static const double vc1541_times[4]= {
215static const double drive_times[4]= {
191216   13/16e6, 14/16e6, 15/16e6, 16/16e6
192217};
193218
r3251r3252
258283   int data[4];
259284} gcr_helper;
260285
261static void vc1541_sector_start(void)
286static void drive_sector_start(void)
262287{
263288   gcr_helper.count=0;
264289}
265290
266static void vc1541_sector_data(UINT8 data, int *pos)
291static void drive_sector_data(UINT8 data, int *pos)
267292{
268293   gcr_helper.data[gcr_helper.count++]=data;
269294   if (gcr_helper.count==4) {
270295      gcr_double_2_gcr(gcr_helper.data[0], gcr_helper.data[1],
271296                   gcr_helper.data[2], gcr_helper.data[3],
272                   vc1541->head.data+*pos);
297                   drive->head.data+*pos);
273298      *pos=*pos+5;
274299      gcr_helper.count=0;
275300   }
276301}
277302
278static void vc1541_sector_end(int *pos)
303static void drive_sector_end(int *pos)
279304{
280305   assert(gcr_helper.count==0);
281306}
282307
283static void vc1541_sector_to_gcr(int track, int sector)
308static void drive_sector_to_gcr(int track, int sector)
284309{
285310   int i=0, j, offset, chksum=0;
286311
287   if (vc1541->d64.data==NULL) return;
288   vc1541->head.data[i++]=0xff;
289   vc1541->head.data[i++]=0xff;
290   vc1541->head.data[i++]=0xff;
291   vc1541->head.data[i++]=0xff;
292   vc1541->head.data[i++]=0xff;
293   vc1541_sector_start();
312   if (drive->d64.data==NULL) return;
313   drive->head.data[i++]=0xff;
314   drive->head.data[i++]=0xff;
315   drive->head.data[i++]=0xff;
316   drive->head.data[i++]=0xff;
317   drive->head.data[i++]=0xff;
318   drive_sector_start();
294319
295   vc1541_sector_data(8, &i);
320   drive_sector_data(8, &i);
296321   chksum= sector^track
297      ^vc1541->d64.data[D64_TRACK_ID1]^vc1541->d64.data[D64_TRACK_ID2];
298   vc1541_sector_data(chksum, &i);
299   vc1541_sector_data(sector, &i);
300   vc1541_sector_data(track, &i);
301   vc1541_sector_data(vc1541->d64.data[D64_TRACK_ID1], &i);
302   vc1541_sector_data(vc1541->d64.data[D64_TRACK_ID2], &i);
303   vc1541_sector_data(0xf, &i);
304   vc1541_sector_data(0xf, &i);
305   vc1541_sector_end(&i);
322      ^drive->d64.data[D64_TRACK_ID1]^drive->d64.data[D64_TRACK_ID2];
323   drive_sector_data(chksum, &i);
324   drive_sector_data(sector, &i);
325   drive_sector_data(track, &i);
326   drive_sector_data(drive->d64.data[D64_TRACK_ID1], &i);
327   drive_sector_data(drive->d64.data[D64_TRACK_ID2], &i);
328   drive_sector_data(0xf, &i);
329   drive_sector_data(0xf, &i);
330   drive_sector_end(&i);
306331
307332   /* 5 - 10 gcr bytes cap */
308   gcr_double_2_gcr(0, 0, 0, 0, vc1541->head.data+i);i+=5;
309   gcr_double_2_gcr(0, 0, 0, 0, vc1541->head.data+i);i+=5;
310   vc1541->head.data[i++]=0xff;
311   vc1541->head.data[i++]=0xff;
312   vc1541->head.data[i++]=0xff;
313   vc1541->head.data[i++]=0xff;
314   vc1541->head.data[i++]=0xff;
315   vc1541_sector_data(0x7, &i);
333   gcr_double_2_gcr(0, 0, 0, 0, drive->head.data+i);i+=5;
334   gcr_double_2_gcr(0, 0, 0, 0, drive->head.data+i);i+=5;
335   drive->head.data[i++]=0xff;
336   drive->head.data[i++]=0xff;
337   drive->head.data[i++]=0xff;
338   drive->head.data[i++]=0xff;
339   drive->head.data[i++]=0xff;
340   drive_sector_data(0x7, &i);
316341
317342   chksum=0;
318343   for (offset=d64_tracksector2offset(track,sector), j=0; j<256; j++) {
319      chksum^=vc1541->d64.data[offset];
320      vc1541_sector_data(vc1541->d64.data[offset++], &i);
344      chksum^=drive->d64.data[offset];
345      drive_sector_data(drive->d64.data[offset++], &i);
321346   }
322   vc1541_sector_data(chksum, &i);
323   vc1541_sector_data(0, &i); /* padding up */
324   vc1541_sector_data(0, &i);
325   vc1541_sector_end(&i);
326   gcr_double_2_gcr(0, 0, 0, 0, vc1541->head.data+i);i+=5;
327   gcr_double_2_gcr(0, 0, 0, 0, vc1541->head.data+i);i+=5;
347   drive_sector_data(chksum, &i);
348   drive_sector_data(0, &i); /* padding up */
349   drive_sector_data(0, &i);
350   drive_sector_end(&i);
351   gcr_double_2_gcr(0, 0, 0, 0, drive->head.data+i);i+=5;
352   gcr_double_2_gcr(0, 0, 0, 0, drive->head.data+i);i+=5;
328353}
329354
330355
356/**************************************
357
358   VC1541
359
360**************************************/
361
362
331363static ADDRESS_MAP_START( vc1541_map, ADDRESS_SPACE_PROGRAM, 8 )
332364   AM_RANGE(0x0000, 0x07ff) AM_RAM
333365   AM_RANGE(0x1800, 0x180f) AM_READWRITE(via_2_r, via_2_w)  /* 0 and 1 used in vc20 */
334   AM_RANGE(0x1810, 0x189f) AM_READ( SMH_NOP) /* for debugger */
366   AM_RANGE(0x1810, 0x189f) AM_READ(SMH_NOP) /* for debugger */
335367   AM_RANGE(0x1c00, 0x1c0f) AM_READWRITE(via_3_r, via_3_w)
336   AM_RANGE(0x1c10, 0x1c9f) AM_READ( SMH_NOP) /* for debugger */
368   AM_RANGE(0x1c10, 0x1c9f) AM_READ(SMH_NOP) /* for debugger */
337369   AM_RANGE(0xc000, 0xffff) AM_ROM
338370ADDRESS_MAP_END
339371
r3251r3252
358390INPUT_PORTS_END
359391#endif
360392
361static TIMER_CALLBACK(vc1541_timer)
393static TIMER_CALLBACK(drive_timer)
362394{
363   if (vc1541->clock==0) {
364      vc1541->clock=1;
365      vc1541->head.ready=0;
366      vc1541->head.sync=0;
367      if (vc1541->type==TypeVC1541) {
368         cpunum_set_input_line(machine, vc1541->cpunumber, M6502_SET_OVERFLOW, 1);
395   if (drive->clock==0) {
396      drive->clock=1;
397      drive->head.ready=0;
398      drive->head.sync=0;
399      if (drive->type==type_1541) {
400         cpunum_set_input_line(machine, drive->cpunumber, M6502_SET_OVERFLOW, 1);
369401         via_3_ca1_w(machine, 0,1);
370402      }
371403      return;
372404   }
373   if (++(vc1541->d64.pos)>=sizeof(vc1541->head.data)) {
374      if (++(vc1541->d64.sector)>=
375         d64_sectors_per_track[(int)vc1541->track-1]) {
376         vc1541->d64.sector=0;
405   if (++(drive->d64.pos)>=sizeof(drive->head.data)) {
406      if (++(drive->d64.sector)>=
407         d64_sectors_per_track[(int)drive->track-1]) {
408         drive->d64.sector=0;
377409      }
378      vc1541_sector_to_gcr((int)vc1541->track,vc1541->d64.sector);
379      vc1541->d64.pos=0;
410      drive_sector_to_gcr((int)drive->track,drive->d64.sector);
411      drive->d64.pos=0;
380412   }
381   vc1541->head.ready=1;
382   if (vc1541->head.data[vc1541->d64.pos]==0xff) {
383      vc1541->head.ffcount++;
384      if (vc1541->head.ffcount==5) {
385         vc1541->head.sync=1;
413   drive->head.ready=1;
414   if (drive->head.data[drive->d64.pos]==0xff) {
415      drive->head.ffcount++;
416      if (drive->head.ffcount==5) {
417         drive->head.sync=1;
386418      }
387419   } else {
388      vc1541->head.ffcount=0;
389      vc1541->head.sync=0;
420      drive->head.ffcount=0;
421      drive->head.sync=0;
390422   }
391   if (vc1541->type==TypeVC1541) {
392      cpunum_set_input_line(machine, vc1541->cpunumber, M6502_SET_OVERFLOW, 0);
423   if (drive->type==type_1541) {
424      cpunum_set_input_line(machine, drive->cpunumber, M6502_SET_OVERFLOW, 0);
393425      via_3_ca1_w(machine, 0,0);
394426   }
395   vc1541->clock=0;
427   drive->clock=0;
396428}
397429
398430/*
r3251r3252
412444 */
413445static void vc1541_via0_irq (running_machine *machine, int level)
414446{
415   vc1541->via0irq = level;
416   DBG_LOG(2, "vc1541 via0 irq",("level %d %d\n",vc1541->via0irq,vc1541->via1irq));
417   cpunum_set_input_line (machine, vc1541->cpunumber,
418                 M6502_IRQ_LINE, vc1541->via1irq || vc1541->via0irq);
447   drive->via0irq = level;
448   DBG_LOG(2, "vc1541 via0 irq",("level %d %d\n",drive->via0irq,drive->via1irq));
449   cpunum_set_input_line (machine, drive->cpunumber,
450                 M6502_IRQ_LINE, drive->via1irq || drive->via0irq);
419451}
420452
421453static READ8_HANDLER( vc1541_via0_read_portb )
r3251r3252
423455   static int old=-1;
424456   int value = 0x7a;
425457
426   if (!vc1541->drive.serial.serial_data || !serial.data[0])
458   if (!drive->drive.serial.serial_data || !serial.data[0])
427459      value |= 1;
428   if (!vc1541->drive.serial.serial_clock || !serial.clock[0])
460   if (!drive->drive.serial.serial_clock || !serial.clock[0])
429461      value |= 4;
430462   if (!serial.atn[0]) value |= 0x80;
431463
432   switch (vc1541->drive.serial.deviceid)
464   switch (drive->drive.serial.deviceid)
433465   {
434466   case 8:
435467      value &= ~0x60;
r3251r3252
467499                            data&8?"CLOCK":"clock",
468500                            data&2?"DATA":"data"));
469501
470   vc1541->drive.serial.data=data&2?0:1;
471   vc1541->drive.serial.acka=(data&0x10)?1:0;
502   drive->drive.serial.data=data&2?0:1;
503   drive->drive.serial.acka=(data&0x10)?1:0;
472504
473   if ((!(data & 2)) != vc1541->drive.serial.serial_data)
505   if ((!(data & 2)) != drive->drive.serial.serial_data)
474506   {
475      vc1541_serial_data_write (1, vc1541->drive.serial.serial_data = !(data & 2));
507      vc1541_serial_data_write (1, drive->drive.serial.serial_data = !(data & 2));
476508   }
477509
478   if ((!(data & 8)) != vc1541->drive.serial.serial_clock)
510   if ((!(data & 8)) != drive->drive.serial.serial_clock)
479511   {
480      vc1541_serial_clock_write (1, vc1541->drive.serial.serial_clock = !(data & 8));
512      vc1541_serial_clock_write (1, drive->drive.serial.serial_clock = !(data & 8));
481513   }
482   vc1541_serial_atn_write (machine, 1, vc1541->drive.serial.serial_atn = 1);
514   vc1541_serial_atn_write (machine, 1, drive->drive.serial.serial_atn = 1);
483515}
484516
485517/*
r3251r3252
511543 */
512544static void vc1541_via1_irq (running_machine *machine, int level)
513545{
514   vc1541->via1irq = level;
515   DBG_LOG(2, "vc1541 via1 irq",("level %d %d\n",vc1541->via0irq,vc1541->via1irq));
516   cpunum_set_input_line (machine, vc1541->cpunumber,
517                 M6502_IRQ_LINE, vc1541->via1irq || vc1541->via0irq);
546   drive->via1irq = level;
547   DBG_LOG(2, "vc1541 via1 irq",("level %d %d\n",drive->via0irq,drive->via1irq));
548   cpunum_set_input_line (machine, drive->cpunumber,
549                 M6502_IRQ_LINE, drive->via1irq || drive->via0irq);
518550}
519551
520552static READ8_HANDLER( vc1541_via1_read_porta )
521553{
522   int data=vc1541->head.data[vc1541->d64.pos];
554   int data=drive->head.data[drive->d64.pos];
523555   DBG_LOG(2, "vc1541 drive",("port a read %.2x\n", data));
524556   return data;
525557}
r3251r3252
537569   if (WRITEPROTECTED)
538570      value &= ~0x10;
539571#endif
540   if (vc1541->head.sync) {
572   if (drive->head.sync) {
541573      value&=~0x80;
542574   }
543575
r3251r3252
552584      if ((old&3)!=(data&3)) {
553585         switch (old&3) {
554586         case 0:
555            if ((data&3)==1) vc1541->track+=0.5;
556            else if ((data&3)==3) vc1541->track-=0.5;
587            if ((data&3)==1) drive->track+=0.5;
588            else if ((data&3)==3) drive->track-=0.5;
557589            break;
558590         case 1:
559            if ((data&3)==2) vc1541->track+=0.5;
560            else if ((data&3)==0) vc1541->track-=0.5;
591            if ((data&3)==2) drive->track+=0.5;
592            else if ((data&3)==0) drive->track-=0.5;
561593            break;
562594         case 2:
563            if ((data&3)==3) vc1541->track+=0.5;
564            else if ((data&3)==1) vc1541->track-=0.5;
595            if ((data&3)==3) drive->track+=0.5;
596            else if ((data&3)==1) drive->track-=0.5;
565597            break;
566598         case 3:
567            if ((data&3)==0) vc1541->track+=0.5;
568            else if ((data&3)==2) vc1541->track-=0.5;
599            if ((data&3)==0) drive->track+=0.5;
600            else if ((data&3)==2) drive->track-=0.5;
569601            break;
570602         }
571         if (vc1541->track<1) vc1541->track=1.0;
572         if (vc1541->track>35) vc1541->track=35;
603         if (drive->track<1) drive->track=1.0;
604         if (drive->track>35) drive->track=35;
573605      }
574      if ( (vc1541->motor!=(data&4))||(vc1541->frequency!=(data&0x60)) )
606      if ( (drive->motor!=(data&4))||(drive->frequency!=(data&0x60)) )
575607      {
576608         double tme;
577         vc1541->motor = data & 4;
578         vc1541->frequency = data & 0x60;
579         tme=vc1541_times[vc1541->frequency>>5]*8*2;
580         if (vc1541->motor)
609         drive->motor = data & 4;
610         drive->frequency = data & 0x60;
611         tme=drive_times[drive->frequency>>5]*8*2;
612         if (drive->motor)
581613         {
582            if (attotime_to_double(timer_timeelapsed(vc1541->timer)) > 1.0e29)
583               timer_reset(vc1541->timer, attotime_never);
614            if (attotime_to_double(timer_timeelapsed(drive->timer)) > 1.0e29)
615               timer_reset(drive->timer, attotime_never);
584616            else
585               timer_adjust_periodic(vc1541->timer, attotime_zero, 0, double_to_attotime(tme));
617               timer_adjust_periodic(drive->timer, attotime_zero, 0, double_to_attotime(tme));
586618         }
587619         else
588620         {
589            timer_reset(vc1541->timer, attotime_never);
621            timer_reset(drive->timer, attotime_never);
590622         }
591623      }
592624      old=data;
593625   }
594   vc1541->led = data & 8;
626   drive->led = data & 8;
595627}
596628
597629static const struct via6522_interface via2 =
r3251r3252
626658   vc1541_via1_irq
627659};
628660
629DEVICE_IMAGE_LOAD(vc1541)
630{
631   vc1541->d64.data = image_ptr(image);
632   if (!vc1541->d64.data)
633      return INIT_FAIL;
634661
635   logerror("floppy image %s loaded\n", image_filename(image));
636
637   return INIT_PASS;
638}
639
640DEVICE_IMAGE_UNLOAD(vc1541)
641{
642   /* writeback of image data */
643   vc1541->d64.data = NULL;
644}
645
646int vc1541_config (int id, int mode, VC1541_CONFIG *config)
647{
648   via_config (2, &via2);
649   via_config (3, &via3);
650   vc1541->type=TypeVC1541;
651   vc1541->cpunumber = config->cpunr;
652   vc1541->drive.serial.deviceid = config->devicenr;
653   vc1541->timer = timer_alloc(vc1541_timer, NULL);
654   return 0;
655}
656
657void vc1541_reset (void)
658{
659   int i;
660
661   if (vc1541->type==TypeVC1541) {
662      for (i = 0; i < sizeof (serial.atn) / sizeof (serial.atn[0]); i++)
663      {
664         serial.atn[i] = serial.data[i] = serial.clock[i] = 1;
665      }
666   }
667   vc1541->track=1.0;
668   if ((vc1541->type==TypeVC1541)||(vc1541->type==Type2031)) {
669      via_reset ();
670   }
671   if ((vc1541->type==TypeC1551)) {
672      tpi6525_0_reset();
673   }
674}
675
676/* delivers status for displaying */
677void vc1541_drive_status (char *text, int size)
678{
679#if 0
680   if (vc1541->type==TypeVC1541) {
681      snprintf (text, size, "%s %4.1f %s %.2x %s %s %s",
682              vc1541->led ? "LED" : "led",
683              vc1541->track,
684              vc1541->motor ? "MOTOR" : "motor",
685              vc1541->frequency,
686              serial.atn[0]?"ATN":"atn",
687              serial.clock[0]?"CLOCK":"clock",
688              serial.data[0]?"DATA":"data");
689   } else if (vc1541->type==TypeC1551) {
690      snprintf (text, size, "%s %4.1f %s %.2x",
691              vc1541->led ? "LED" : "led",
692              vc1541->track,
693              vc1541->motor ? "MOTOR" : "motor",
694              vc1541->frequency);
695   }
696#else
697   text[0] = 0;
698#endif
699   return;
700}
701
702662void vc1541_serial_reset_write (int which, int level)
703663{
704664}
r3251r3252
733693                            serial.atn[0]?"ATN":"atn"));
734694            via_set_input_ca1 (machine, 2, !level);
735695#if 0
736            value=vc1541->drive.serial.data;
737            if (vc1541->drive.serial.acka!=!level) value=0;
696            value=drive->drive.serial.data;
697            if (drive->drive.serial.acka!=!level) value=0;
738698            if (value!=serial.data[2]) {
739699               serial.data[2]=value;
740700               if (serial.data[0]!=value) {
r3251r3252
816776{
817777}
818778
779
780/**************************************
781
782   C1551
783
784**************************************/
785
819786/*
820787  c1551 irq line
821788  only timing related??? (60 hz?), delivered from c16?
822789 */
823static TIMER_CALLBACK(c1551_timer)
790static TIMER_CALLBACK(c1551_irq_timer)
824791{
825   cpunum_set_input_line(machine, vc1541->cpunumber, M6502_IRQ_LINE, PULSE_LINE);
792   cpunum_set_input_line(machine, drive->cpunumber, M6502_IRQ_LINE, PULSE_LINE);
826793}
827794
828795/*
r3251r3252
839806   static int old=0;
840807   if (offset) {
841808      DBG_LOG(1, "c1551 port",("write %.2x\n",data));
842      vc1541->drive.c1551.cpu_port=data;
809      drive->drive.c1551.cpu_port=data;
843810
844811      if (data!=old) {
845812         DBG_LOG(1, "vc1541 drive",("%.2x\n", data));
846813         if ((old&3)!=(data&3)) {
847814            switch (old&3) {
848815            case 0:
849               if ((data&3)==1) vc1541->track+=0.5;
850               else if ((data&3)==3) vc1541->track-=0.5;
816               if ((data&3)==1) drive->track+=0.5;
817               else if ((data&3)==3) drive->track-=0.5;
851818               break;
852819            case 1:
853               if ((data&3)==2) vc1541->track+=0.5;
854               else if ((data&3)==0) vc1541->track-=0.5;
820               if ((data&3)==2) drive->track+=0.5;
821               else if ((data&3)==0) drive->track-=0.5;
855822               break;
856823            case 2:
857               if ((data&3)==3) vc1541->track+=0.5;
858               else if ((data&3)==1) vc1541->track-=0.5;
824               if ((data&3)==3) drive->track+=0.5;
825               else if ((data&3)==1) drive->track-=0.5;
859826               break;
860827            case 3:
861               if ((data&3)==0) vc1541->track+=0.5;
862               else if ((data&3)==2) vc1541->track-=0.5;
828               if ((data&3)==0) drive->track+=0.5;
829               else if ((data&3)==2) drive->track-=0.5;
863830               break;
864831            }
865            if (vc1541->track<1) vc1541->track=1.0;
866            if (vc1541->track>35) vc1541->track=35;
832            if (drive->track<1) drive->track=1.0;
833            if (drive->track>35) drive->track=35;
867834         }
868         if ( (vc1541->motor!=(data&4))||(vc1541->frequency!=(data&0x60)) ) {
835         if ( (drive->motor!=(data&4))||(drive->frequency!=(data&0x60)) ) {
869836            double tme;
870            vc1541->motor = data & 4;
871            vc1541->frequency = data & 0x60;
872            tme=vc1541_times[vc1541->frequency>>5]*8*2;
873            if (vc1541->motor)
837            drive->motor = data & 4;
838            drive->frequency = data & 0x60;
839            tme=drive_times[drive->frequency>>5]*8*2;
840            if (drive->motor)
874841            {
875               if (attotime_to_double(timer_timeelapsed(vc1541->timer)) > 1.0e29)
876                  timer_reset(vc1541->timer, attotime_never);
842               if (attotime_to_double(timer_timeelapsed(drive->timer)) > 1.0e29)
843                  timer_reset(drive->timer, attotime_never);
877844               else
878                  timer_adjust_periodic(vc1541->timer, attotime_zero, 0, double_to_attotime(tme));
845                  timer_adjust_periodic(drive->timer, attotime_zero, 0, double_to_attotime(tme));
879846            }
880847            else
881848            {
882               timer_reset(vc1541->timer, attotime_never);
849               timer_reset(drive->timer, attotime_never);
883850            }
884851         }
885852         old=data;
886853      }
887      vc1541->led = data & 8;
854      drive->led = data & 8;
888855   } else {
889      vc1541->drive.c1551.cpu_ddr=data;
856      drive->drive.c1551.cpu_ddr=data;
890857      DBG_LOG(1, "c1551 ddr",("write %.2x\n",data));
891858   }
892859}
r3251r3252
901868      if (WRITEPROTECTED)
902869         data &= ~0x10;
903870#endif
904      if (vc1541->head.ready) {
871      if (drive->head.ready) {
905872         data|=0x80;
906         vc1541->head.ready=0;
873         drive->head.ready=0;
907874      }
908      data&=~vc1541->drive.c1551.cpu_ddr;
909      data|=vc1541->drive.c1551.cpu_ddr&vc1541->drive.c1551.cpu_port;
875      data&=~drive->drive.c1551.cpu_ddr;
876      data|=drive->drive.c1551.cpu_ddr&drive->drive.c1551.cpu_port;
910877      DBG_LOG(3, "c1551 port",("read %.2x\n", data));
911878   } else {
912      data=vc1541->drive.c1551.cpu_ddr;
879      data=drive->drive.c1551.cpu_ddr;
913880      DBG_LOG(3, "c1551 ddr",("read %.2x\n", data));
914881   }
915882   return data;
r3251r3252
935902{
936903   int data=0xff;
937904   data&=~0x20;
938   if (vc1541->head.sync) data&=~0x40;
905   if (drive->head.sync) data&=~0x40;
939906   return data;
940907}
941908
942909static int c1551_port_b_r (void)
943910{
944   int data=vc1541->head.data[vc1541->d64.pos];
911   int data=drive->head.data[drive->d64.pos];
945912   DBG_LOG(2, "c1551 drive",("port a read %.2x\n", data));
946913   return data;
947914}
948915
949int c1551_config (int id, int mode, C1551_CONFIG *config)
950{
951   vc1541->cpunumber = config->cpunr;
952   vc1541->type=TypeC1551;
953   vc1541->timer = timer_alloc(vc1541_timer, NULL);
954   tpi6525[0].c.read=c1551_port_c_r;
955   tpi6525[0].b.read=c1551_port_b_r;
956916
957   /* time should be small enough to allow quitting of the irq
958      line before the next interrupt is triggered */
959   vc1541->drive.c1551.timer = timer_alloc(c1551_timer, NULL);
960   timer_adjust_periodic(vc1541->drive.c1551.timer, attotime_zero, 0, ATTOTIME_IN_HZ(60));
961   return 0;
962}
963
964
965917static ADDRESS_MAP_START( c1551_map, ADDRESS_SPACE_PROGRAM, 8 )
966918    AM_RANGE(0x0000, 0x0001) AM_READWRITE(c1551_port_r, c1551_port_w)
967919   AM_RANGE(0x0002, 0x07ff) AM_RAM
r3251r3252
10511003   return c1551x_read_status(Machine, tpi6525);
10521004}
10531005
1006/**************************************
1007
1008   Drive init & reset
1009
1010**************************************/
1011
1012
1013int drive_config (int type, int id, int mode, int cpunr, int devicenr)
1014{
1015   drive->type = type;
1016   drive->cpunumber = cpunr;
1017   drive->drive.serial.deviceid = devicenr;
1018   drive->timer = timer_alloc(drive_timer, NULL);
1019
1020   if ((drive->type == type_1541) || (drive->type == type_2031))
1021   {
1022      via_config (2, &via2);
1023      via_config (3, &via3);
1024   }
1025
1026   if (type == type_1551)
1027   {
1028      tpi6525[0].c.read=c1551_port_c_r;
1029      tpi6525[0].b.read=c1551_port_b_r;
1030
1031      /* time should be small enough to allow quitting of the irq
1032      line before the next interrupt is triggered */
1033      drive->drive.c1551.irq_timer = timer_alloc(c1551_irq_timer, NULL);
1034      timer_adjust_periodic(drive->drive.c1551.irq_timer, attotime_zero, 0, ATTOTIME_IN_HZ(60));
1035   }
1036
1037   return 0;
1038}
1039
1040void drive_reset (void)
1041{
1042   int i;
1043
1044   if (drive->type == type_1541)
1045   {
1046      for (i = 0; i < sizeof (serial.atn) / sizeof (serial.atn[0]); i++)
1047      {
1048         serial.atn[i] = serial.data[i] = serial.clock[i] = 1;
1049      }
1050   }
1051
1052   drive->track = 1.0;
1053
1054   if ((drive->type == type_1541) || (drive->type == type_2031))
1055   {
1056      via_reset ();
1057   }
1058
1059   if ((drive->type == type_1551))
1060   {
1061      tpi6525_0_reset();
1062   }
1063}
1064
1065/**************************************
1066
1067   Machine drivers
1068
1069**************************************/
1070
10541071MACHINE_DRIVER_START( cpu_vc1540 )
10551072   MDRV_CPU_ADD("cpu_vc1540", M6502, 1000000)
10561073   MDRV_CPU_PROGRAM_MAP(vc1541_map, 0)
r3251r3252
10781095   MDRV_IMPORT_FROM(cpu_vc1541)
10791096MACHINE_DRIVER_END
10801097
1098/**************************************
10811099
1100   Device configurations
1101
1102**************************************/
1103
1104DEVICE_IMAGE_LOAD(vc1541)
1105{
1106   drive->d64.data = image_ptr(image);
1107   if (!drive->d64.data)
1108      return INIT_FAIL;
1109
1110   logerror("floppy image %s loaded\n", image_filename(image));
1111
1112   return INIT_PASS;
1113}
1114
1115DEVICE_IMAGE_UNLOAD(vc1541)
1116{
1117   /* writeback of image data */
1118   drive->d64.data = NULL;
1119}
1120
10821121void vc1541_device_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info)
10831122{
10841123   switch(state)
10851124   {
10861125      /* --- the following bits of info are returned as 64-bit signed integers --- */
10871126      case MESS_DEVINFO_INT_TYPE:               info->i = IO_FLOPPY; break;
1088      case MESS_DEVINFO_INT_COUNT:               info->i = 1; break;
1127      case MESS_DEVINFO_INT_COUNT:            info->i = 1; break;
10891128      case MESS_DEVINFO_INT_READABLE:            info->i = 1; break;
1090      case MESS_DEVINFO_INT_WRITEABLE:            info->i = 0; break;
1091      case MESS_DEVINFO_INT_CREATABLE:            info->i = 0; break;
1092      case MESS_DEVINFO_INT_RESET_ON_LOAD:         info->i = 1; break;
1129      case MESS_DEVINFO_INT_WRITEABLE:         info->i = 0; break;
1130      case MESS_DEVINFO_INT_CREATABLE:         info->i = 0; break;
1131      case MESS_DEVINFO_INT_RESET_ON_LOAD:      info->i = 1; break;
10931132
10941133      /* --- the following bits of info are returned as pointers to data or functions --- */
10951134      case MESS_DEVINFO_PTR_LOAD:               info->load = DEVICE_IMAGE_LOAD_NAME(vc1541); break;
10961135      case MESS_DEVINFO_PTR_UNLOAD:            info->unload = DEVICE_IMAGE_UNLOAD_NAME(vc1541); break;
1097      case DEVINFO_PTR_VC1541_CONFIG:         info->f = (genf *) vc1541_config; break;
1136      case MESS_DEVINFO_PTR_DEV_SPECIFIC:         info->f = (genf *) drive_config; break;
10981137
10991138      /* --- the following bits of info are returned as NULL-terminated strings --- */
11001139      case MESS_DEVINFO_STR_FILE_EXTENSIONS:      strcpy(info->s = device_temp_str(), "d64"); break;
r3251r3252
11151154   switch(state)
11161155   {
11171156      /* --- the following bits of info are returned as pointers to data or functions --- */
1118      case DEVINFO_PTR_VC1541_CONFIG:         info->f = (genf *) c1551_config; break;
1157      case MESS_DEVINFO_PTR_DEV_SPECIFIC:         info->f = (genf *) drive_config; break;
11191158
11201159      default: vc1541_device_getinfo(devclass, state, info); break;
11211160   }
src/mess/machine/c16.c
r3251r3252
429429
430430static void c16_common_driver_init (running_machine *machine)
431431{
432   VC1541_CONFIG vc1541= { 1, 8 };
433   C1551_CONFIG config= { 1 };
434432   UINT8 *rom;
435433
436434   /* configure the M7501 port */
r3251r3252
480478   memset(mess_ram + (0xfd40 % mess_ram_size), 0xff, 0x20);
481479   
482480   if (has_c1551)      /* C1551 */
483      c1551_config (0, 0, &config);
481      drive_config (type_1551, 0, 0, 1, 8);
484482
485483   if (has_vc1541)      /* VC1541 */
486      vc1541_config (0, 0, &vc1541);
484      drive_config (type_1541, 0, 0, 1, 8);
487485}
488486
489487void c16_driver_init(running_machine *machine)
r3251r3252
586584   cbm_drive_0_config (SERIAL, 8);
587585   cbm_drive_1_config (SERIAL, 9);
588586
589   if (has_c1551)      /* c1551 */
590      c1551_reset ();
587   if (has_c1551 || has_vc1541)      /* c1551 or vc1541 */
588      drive_reset ();
591589
592   if (has_vc1541)      /* VC1541 */
593      vc1541_reset ();
594
595590   cbm_serial_reset_write (0);
596591}
597592
src/mess/machine/vc20.c
r3251r3252
555555
556556static void vc20_common_driver_init (running_machine *machine)
557557{
558#ifdef VC1541
559   VC1541_CONFIG vc1541= { 1, 8 };
560#endif
561558   vc20_memory_init(machine);
562559
563560   datasette_timer = timer_alloc(vic20_tape_timer, NULL);
564561
565562#ifdef VC1541
566   vc1541_config (0, 0, &vc1541);
563   drive_config (type_1541, 0, 0, 1, 8);
567564#endif
568565   via_config (0, &via0);
569566   via_config (1, &via1);
570
571567}
572568
573569
r3251r3252
602598{
603599   cbm_serial_reset_write (0);
604600#ifdef VC1541
605   vc1541_reset ();
601   drive_reset ();
606602#endif
607603
608604   if (ieee)
src/mess/machine/c64.c
r3251r3252
10461046
10471047DRIVER_INIT( sx64 )
10481048{
1049   VC1541_CONFIG vc1541 = { 1, 8 };
10501049   is_sx64 = 1;
10511050   c64_tape_on = 0;
10521051   c64_pal = 1;
10531052   c64_common_driver_init (machine);
1054   vc1541_config (0, 0, &vc1541);
1053   drive_config (type_1541, 0, 0, 1, 8);
10551054}
10561055
10571056void c64_common_init_machine (running_machine *machine)
10581057{
10591058   if (is_sx64)
1060      vc1541_reset ();
1059      drive_reset ();
10611060
10621061   if (c64_cia1_on)
10631062   {

Previous 15994 Revisions Next


© 1998-2018 The MESS Team