|
|
1.1.1.2 root 1: /*
1.1 root 2: * UAE - The Un*x Amiga Emulator
1.1.1.2 root 3: *
1.1 root 4: * Floppy disk emulation
5: *
1.1.1.4 root 6: * Copyright 1995 Bernd Schmidt, Hannu Rummukainen
1.1 root 7: */
8:
1.1.1.2 root 9: #include <stdio.h>
10:
1.1 root 11: #include "sysconfig.h"
12: #include "sysdeps.h"
13:
14: #include "config.h"
15: #include "options.h"
1.1.1.3 root 16: #include "threaddep/penguin.h"
1.1 root 17: #include "memory.h"
18: #include "events.h"
19: #include "custom.h"
20: #include "ersatz.h"
21: #include "disk.h"
22: #include "gui.h"
23: #include "zfile.h"
1.1.1.2 root 24: #include "autoconf.h"
25: #include "readcpu.h"
26: #include "newcpu.h"
27: #include "xwin.h"
28: #include "osemu.h"
29: #include "execlib.h"
30:
1.1.1.3 root 31: #define FLOPPY_GAP_LEN 360
1.1 root 32:
1.1.1.6 ! root 33: #define FLOPPY_SPEED 50
1.1 root 34:
1.1.1.3 root 35: uae_u16* mfmwrite;
36: static uae_u16 mfmwrbuffer[16384]; /* space for maximum disk DMA transfer */
1.1 root 37:
38: static int side, direction, step;
1.1.1.3 root 39: static uae_u8 selected = 15;
1.1 root 40: static int dskready;
41:
42: typedef struct {
1.1.1.3 root 43: uae_u16 sync;
44: uae_u16 len;
45: uae_u32 offs;
1.1 root 46: } trackid;
47:
1.1.1.2 root 48: #define MAX_TRACKS 328
49:
1.1 root 50: typedef enum { ADF_NORMAL, ADF_EXT1 } drive_filetype;
51: typedef struct {
52: FILE *diskfile;
53: drive_filetype filetype;
1.1.1.2 root 54: trackid trackdata[MAX_TRACKS];
1.1.1.3 root 55: unsigned int buffered_cyl, buffered_side;
56: unsigned int cyl;
57: int side;
1.1 root 58: int motoroff;
59: int wrprot;
1.1.1.3 root 60: uae_u16 bigmfmbuf[0x4000];
1.1.1.6 ! root 61: int mfmbufpos;
1.1 root 62: int tracklen;
63: unsigned long last_cycles;
64: int mfmpos;
1.1.1.2 root 65: unsigned int num_tracks, num_secs;
1.1.1.3 root 66: /* dskchange is set to a small number when a disk is removed. At a step
67: * impulse, it is reset if there is a new disk in the drive or counted
68: * down to 1 if the drive contains a disk. DISK_check_change will only
69: * insert a new disk when dskchange is 1, or if the dskchange_time timer
70: * expires. The last condition can happen if AmigaOS isn't running and a
71: * game/demo doesn't use the step motor to check for a new disk.
72: */
73: int dskchange;
74: int dskchange_time;
1.1 root 75: } drive;
76:
77: drive floppy[4];
78:
1.1.1.4 root 79: static void drive_fill_bigbuf (drive *drv);
1.1 root 80:
1.1.1.3 root 81: FILE *DISK_validate_filename (const char *fname, int leave_open, int *wrprot)
1.1 root 82: {
1.1.1.4 root 83: FILE *f = zfile_open (fname, "r+b");
1.1.1.3 root 84: if (f) {
85: if (wrprot)
86: *wrprot = 0;
1.1 root 87: } else {
1.1.1.3 root 88: if (wrprot)
89: *wrprot = 1;
1.1.1.4 root 90: f = zfile_open (fname, "rb");
1.1 root 91: }
1.1.1.3 root 92: if (!leave_open)
1.1.1.4 root 93: zfile_close (f);
1.1.1.3 root 94: return f;
95: }
96:
1.1.1.4 root 97: static int drive_insert (drive *drv, int dnum, const char *fname)
1.1.1.3 root 98: {
99: unsigned char buffer[10];
100:
101: drv->diskfile = DISK_validate_filename (fname, 1, &drv->wrprot);
1.1.1.6 ! root 102: if (drv->diskfile == 0) {
! 103: drv->tracklen = 2000;
1.1.1.3 root 104: return 0;
1.1.1.6 ! root 105: }
1.1.1.3 root 106: strncpy (currprefs.df[dnum], fname, 255);
107: currprefs.df[dnum][255] = 0;
108: strncpy (changed_prefs.df[dnum], fname, 255);
109: changed_prefs.df[dnum][255] = 0;
1.1 root 110: gui_filename(dnum, fname);
1.1.1.3 root 111:
1.1.1.4 root 112: fread (buffer, sizeof(char), 8, drv->diskfile);
1.1.1.3 root 113: if (strncmp((char *)buffer,"UAE--ADF",8) == 0) {
1.1 root 114: int offs = 160*4+8;
115: int i;
1.1.1.3 root 116:
117: drv->filetype = ADF_EXT1;
1.1.1.2 root 118: drv->num_tracks = 160;
119: drv->num_secs = 11;
1.1.1.3 root 120:
1.1 root 121: drv->wrprot = 1; /* write to adf_ext1 not implemented */
122: for(i=0; i<160; i++) {
123: fread(buffer, 4, 1, drv->diskfile);
124: drv->trackdata[i].sync = buffer[0]*256 + buffer[1];
125: drv->trackdata[i].len = buffer[2]*256 + buffer[3];
126: drv->trackdata[i].offs = offs;
127: offs += drv->trackdata[i].len;
128: }
129: } else {
1.1.1.2 root 130: unsigned int i;
1.1.1.3 root 131:
132: drv->filetype = ADF_NORMAL;
1.1.1.2 root 133:
1.1.1.4 root 134: fseek (drv->diskfile,0,SEEK_END);
135: i = ftell (drv->diskfile);
136: fseek (drv->diskfile,0,SEEK_SET);
1.1.1.3 root 137:
1.1.1.2 root 138: /* High-density disk? */
139: if (i >= 160*22*512)
140: drv->num_tracks = i / (512*(drv->num_secs = 22));
141: else
142: drv->num_tracks = i / (512*(drv->num_secs = 11));
1.1.1.3 root 143:
1.1.1.2 root 144: if (drv->num_tracks > MAX_TRACKS)
1.1.1.3 root 145: write_log ("Your diskfile is too big!\n");
1.1.1.2 root 146: for(i = 0; i < drv->num_tracks; i++) {
147: drv->trackdata[i].len = 512 * drv->num_secs;
1.1 root 148: drv->trackdata[i].sync = 0;
1.1.1.2 root 149: drv->trackdata[i].offs = i * 512 * drv->num_secs;
1.1 root 150: }
151: }
1.1.1.3 root 152: drv->buffered_side = 2; /* will force read */
1.1.1.6 ! root 153: drive_fill_bigbuf (drv);
1.1.1.3 root 154: return 1;
1.1 root 155: }
156:
1.1.1.4 root 157: static int drive_empty (drive *drv)
1.1.1.2 root 158: {
1.1.1.3 root 159: return drv->diskfile == 0;
1.1.1.2 root 160: }
161:
1.1.1.4 root 162: static void drive_step (drive *drv)
1.1 root 163: {
1.1.1.3 root 164: if (!drive_empty(drv))
165: drv->dskchange = 0;
166: else if (drv->dskchange > 1) {
167: /* printf("Stepping...\n");
168: drv->dskchange--;*/
169: }
1.1 root 170: if (direction) {
1.1.1.3 root 171: if (drv->cyl) drv->cyl--;
1.1 root 172: } else {
1.1.1.3 root 173: if (drv->cyl < drv->num_tracks/2) drv->cyl++;
1.1 root 174: }
175: }
176:
177:
1.1.1.4 root 178: static int drive_track0 (drive *drv)
1.1 root 179: {
1.1.1.3 root 180: return drv->cyl == 0;
1.1 root 181: }
182:
1.1.1.4 root 183: static int drive_writeprotected (drive *drv)
1.1 root 184: {
1.1.1.3 root 185: return drv->wrprot || drv->diskfile == NULL;
1.1 root 186: }
187:
1.1.1.4 root 188: static int drive_running (drive *drv)
1.1 root 189: {
1.1.1.3 root 190: return !drv->motoroff;
1.1 root 191: }
192:
1.1.1.4 root 193: static void drive_motor (drive *drv, int off)
1.1 root 194: {
195: if (drv->motoroff && !off) {
196: drv->last_cycles = cycles;
197: drv->mfmpos = 0;
198: eventtab[ev_diskindex].active = 1;
199: if (drv->tracklen)
200: eventtab[ev_diskindex].evtime = FLOPPY_SPEED * drv->tracklen + cycles;
201: else
202: eventtab[ev_diskindex].evtime = cycles + 1000;
203: eventtab[ev_diskindex].oldcycles = cycles;
204: } else if (off)
205: eventtab[ev_diskindex].active = 0;
206: drv->motoroff = off;
1.1.1.4 root 207: events_schedule ();
1.1 root 208: }
209:
210: static void drive_fill_bigbuf(drive *drv)
211: {
1.1.1.3 root 212: int tr = drv->cyl*2 + side;
213:
1.1.1.2 root 214: if (!drv->diskfile) {
1.1.1.6 ! root 215: drv->tracklen = 2000;
1.1.1.2 root 216: memset (drv->bigmfmbuf,0xaa,drv->tracklen*2);
217: return;
218: }
1.1.1.3 root 219: if (drv->buffered_cyl == drv->cyl && drv->buffered_side == side)
220: return;
221:
222: /* if (drv->num_tracks <= tr) {
223: write_log ("Access beyond end of floppy image!\n");
224: }*/
1.1 root 225:
226: if (drv->trackdata[tr].sync == 0) {
227: /* Normal AmigaDOS format track */
1.1.1.2 root 228: unsigned int sec;
229: drv->tracklen = drv->num_secs*544 + FLOPPY_GAP_LEN;
1.1.1.6 ! root 230: memset (drv->bigmfmbuf,0xaa,FLOPPY_GAP_LEN*2);
1.1.1.2 root 231:
232: for (sec = 0; sec < drv->num_secs; sec++) {
1.1.1.3 root 233: uae_u8 secbuf[544];
1.1 root 234: int i;
1.1.1.3 root 235: uae_u16 *mfmbuf = drv->bigmfmbuf + 544*sec + FLOPPY_GAP_LEN;
236: uae_u32 deven,dodd;
237: uae_u32 hck=0,dck=0;
238:
1.1 root 239: secbuf[0] = secbuf[1] = 0x00;
240: secbuf[2] = secbuf[3] = 0xa1;
241: secbuf[4] = 0xff;
242: secbuf[5] = tr;
243: secbuf[6] = sec;
1.1.1.2 root 244: secbuf[7] = drv->num_secs-sec;
1.1 root 245:
246: for(i = 8; i < 24; i++)
247: secbuf[i] = 0;
1.1.1.3 root 248:
1.1.1.4 root 249: fseek (drv->diskfile,
250: drv->trackdata[tr].offs + sec*512,
251: SEEK_SET);
252: fread (&secbuf[32],1,512,drv->diskfile);
1.1.1.3 root 253:
1.1 root 254: mfmbuf[0] = mfmbuf[1] = 0xaaaa;
255: mfmbuf[2] = mfmbuf[3] = 0x4489;
1.1.1.3 root 256:
257: deven = ((secbuf[4] << 24) | (secbuf[5] << 16)
1.1 root 258: | (secbuf[6] << 8) | (secbuf[7]));
259: dodd = deven >> 1;
260: deven &= 0x55555555; dodd &= 0x55555555;
1.1.1.3 root 261:
1.1 root 262: mfmbuf[4] = dodd >> 16;
263: mfmbuf[5] = dodd;
1.1.1.3 root 264: mfmbuf[6] = deven>> 16;
1.1 root 265: mfmbuf[7] = deven;
1.1.1.3 root 266:
1.1 root 267: for (i = 8; i < 48; i++)
1.1.1.6 ! root 268: mfmbuf[i] = 0xaaaa;
1.1 root 269: for (i = 0; i < 512; i += 4){
270: deven = ((secbuf[i+32] << 24) | (secbuf[i+33] << 16)
271: | (secbuf[i+34] << 8) | (secbuf[i+35]));
272: dodd = deven >> 1;
273: deven &= 0x55555555; dodd &= 0x55555555;
1.1.1.4 root 274: mfmbuf[(i>>1) + 32] = dodd >> 16;
275: mfmbuf[(i>>1) + 33] = dodd;
276: mfmbuf[(i>>1) + 256 + 32] = deven >> 16;
277: mfmbuf[(i>>1) + 256 + 33] = deven;
1.1 root 278: }
1.1.1.3 root 279:
1.1 root 280: for(i = 4; i < 24; i += 2)
281: hck ^= (mfmbuf[i] << 16) | mfmbuf[i+1];
1.1.1.3 root 282:
1.1 root 283: deven = dodd = hck; dodd >>= 1;
284: mfmbuf[24] = dodd >> 16; mfmbuf[25] = dodd;
1.1.1.4 root 285: mfmbuf[26] = deven >> 16; mfmbuf[27] = deven;
1.1.1.3 root 286:
1.1 root 287: for(i = 32; i < 544; i += 2)
288: dck ^= (mfmbuf[i] << 16) | mfmbuf[i+1];
1.1.1.3 root 289:
1.1 root 290: deven = dodd = dck; dodd >>= 1;
291: mfmbuf[28] = dodd >> 16; mfmbuf[29] = dodd;
1.1.1.4 root 292: mfmbuf[30] = deven >> 16; mfmbuf[31] = deven;
1.1 root 293: }
294: } else {
295: int i;
296: drv->tracklen = drv->trackdata[tr].len/2 + 1;
297: drv->bigmfmbuf[0] = drv->trackdata[tr].sync;
298: fseek(drv->diskfile, drv->trackdata[tr].offs, SEEK_SET);
1.1.1.3 root 299: fread((char *)(drv->bigmfmbuf + 1), 1, drv->trackdata[tr].len, drv->diskfile);
1.1 root 300: for (i = 0; i < drv->trackdata[tr].len/2; i++) {
1.1.1.3 root 301: uae_u16 *mfm = drv->bigmfmbuf + i + 1;
302: uae_u8 *data = (uae_u8 *)mfm;
303:
1.1 root 304: *mfm = 256 * *data + *(data+1);
305: }
306: }
1.1.1.3 root 307: drv->buffered_side = side;
308: drv->buffered_cyl = drv->cyl;
1.1 root 309: drv->last_cycles = cycles;
310: drv->mfmpos = 0;
311: }
312:
1.1.1.6 ! root 313: /* Perform DMA for the time interval since the last call. */
! 314: static int drive_update_reads (drive *drv, uaecptr *ptr, int *length, int *syncfound, int sync)
1.1 root 315: {
1.1.1.6 ! root 316: unsigned long maxbytes = (cycles - drv->last_cycles) * 2 / FLOPPY_SPEED;
! 317: unsigned long maxcount = maxbytes >> 1;
! 318: drv->last_cycles += maxcount * FLOPPY_SPEED;
1.1.1.3 root 319:
320: drive_fill_bigbuf(drv);
1.1.1.6 ! root 321:
! 322: if (! ptr) {
! 323: if (! drv->motoroff)
! 324: drv->mfmpos += maxcount;
! 325: drv->mfmpos %= drv->tracklen;
! 326: } else {
! 327: while (maxcount-- > 0 && *length > 0) {
! 328: unsigned int word;
! 329: if (drv->mfmpos > drv->tracklen) {
! 330: write_log ("Bug in disk code - mfmpos too large\n");
! 331: drv->mfmpos = 0;
! 332: }
! 333: word = drv->bigmfmbuf[drv->mfmpos];
! 334: if (*syncfound) {
! 335: put_word (*ptr, word);
! 336: (*ptr) += 2;
! 337: (*length)--;
! 338: }
! 339: if (word == sync)
! 340: *syncfound = 1;
! 341: if (! drv->motoroff)
! 342: drv->mfmpos++;
! 343: if (drv->mfmpos > drv->tracklen)
! 344: drv->mfmpos = 0;
! 345: }
! 346: }
! 347: return ! drv->motoroff && maxbytes >= 1;
! 348: }
! 349:
! 350: /* We assume that drive_update_reads has already been called. */
! 351: static void drive_get_data (drive *drv, uae_u16 *mfm, uae_u16 *byt)
! 352: {
! 353: *mfm = drv->bigmfmbuf[drv->mfmpos];
! 354: if (cycles - drv->last_cycles > (FLOPPY_SPEED / 2))
! 355: *byt = *mfm & 0xff;
! 356: else
! 357: *byt = (*mfm >> 8) & 0xff;
1.1 root 358: }
359:
360: #define MFMMASK 0x55555555
1.1.1.6 ! root 361: STATIC_INLINE uae_u32 getmfmlong (uae_u16* mbuf)
1.1 root 362: {
363: return ((*mbuf << 16) | *(mbuf + 1)) & MFMMASK;
364: }
365:
1.1.1.4 root 366: static void drive_write_data (drive *drv, uae_u16 *mbuf, int length)
1.1 root 367: {
368: int i, secwritten = 0;
1.1.1.3 root 369: uae_u32 odd, even, chksum, id, dlong;
370: uae_u8* secdata;
371: uae_u8 secbuf[544];
372: uae_u16 *mend = mbuf + length;
373:
1.1.1.4 root 374: if (drive_writeprotected (drv))
1.1.1.3 root 375: return;
376:
1.1.1.4 root 377: drive_fill_bigbuf (drv);
1.1 root 378: mend -= (4 + 16 + 8 + 512);
379: while (length > 0) {
380: int trackoffs;
1.1.1.3 root 381:
1.1 root 382: do {
383: while (*mbuf++ != 0x4489) {
1.1.1.4 root 384: if (mbuf >= mend)
385: return;
1.1 root 386: }
387: } while (*mbuf++ != 0x4489);
1.1.1.3 root 388:
1.1.1.4 root 389: odd = getmfmlong (mbuf);
390: even = getmfmlong (mbuf + 2);
1.1.1.3 root 391: mbuf += 4;
1.1 root 392: id = (odd << 1) | even;
1.1.1.3 root 393:
1.1 root 394: trackoffs = (id & 0xff00) >> 8;
395: if (trackoffs > 10) {
1.1.1.5 root 396: write_log ("Disk write: weird sector number %d\n", trackoffs);
1.1 root 397: continue;
398: }
399: chksum = odd ^ even;
1.1.1.4 root 400: for (i = 0; i < 4; i++) {
1.1 root 401: odd = getmfmlong(mbuf);
402: even = getmfmlong(mbuf+8);
403: mbuf += 2;
1.1.1.3 root 404:
1.1 root 405: dlong = (odd << 1) | even;
1.1.1.4 root 406: if (dlong)
407: secwritten = -200;
1.1 root 408: chksum ^= odd ^ even;
409: } /* could check here if the label is nonstandard */
410: mbuf += 8;
1.1.1.4 root 411: odd = getmfmlong (mbuf); even = getmfmlong (mbuf+2); mbuf += 4;
412: if (((odd << 1) | even) != chksum
413: || ((id & 0x00ff0000) >> 16) != drv->cyl*2 + side)
414: {
1.1.1.3 root 415: write_log ("Disk write: checksum error on sector header\n");
1.1 root 416: continue;
417: }
418: odd = getmfmlong(mbuf); even = getmfmlong(mbuf+2); mbuf += 4;
419: chksum = (odd << 1) | even;
420: secdata = secbuf + 32;
421: for (i=0; i<128; i++) {
422: odd = getmfmlong(mbuf); even = getmfmlong(mbuf+256); mbuf += 2;
423: dlong = (odd << 1) | even;
424: *secdata++ = dlong >> 24; *secdata++ = (dlong >> 16) & 0xff;
425: *secdata++ = dlong >> 8; *secdata++ = dlong;
426: chksum ^= odd ^ even;
427: }
428: mbuf += 256;
429: if (chksum) {
1.1.1.3 root 430: write_log ("Disk write: data checksum error\n");
1.1 root 431: continue;
432: }
433: secwritten++;
1.1.1.4 root 434: fseek (drv->diskfile,
435: drv->trackdata[drv->cyl*2 + side].offs + trackoffs*512,
436: SEEK_SET);
437: fwrite (secbuf+32, sizeof (uae_u8), 512, drv->diskfile);
1.1 root 438: }
1.1.1.3 root 439: drv->buffered_side = 2; /* will force read */
440:
441: if (secwritten == 0)
442: write_log ("Disk write in unsupported format\n");
1.1 root 443: if (secwritten < 0)
1.1.1.3 root 444: write_log ("Disk write: sector labels ignored\n");
1.1 root 445: }
446:
447:
1.1.1.4 root 448: static void drive_eject (drive *drv)
1.1 root 449: {
1.1.1.4 root 450: if (! drive_empty (drv))
451: zfile_close (drv->diskfile);
1.1.1.3 root 452:
453: drv->dskchange = 4;
454: drv->dskchange_time = 20;
455: /* printf("setting changed bit %d\n", drv-floppy);*/
1.1 root 456: drv->diskfile = 0;
457: }
458:
1.1.1.3 root 459: /* We use this function if we have no Kickstart ROM.
1.1 root 460: * No error checking - we trust our luck. */
1.1.1.3 root 461: void DISK_ersatz_read (int tr, int sec, uaecptr dest)
1.1 root 462: {
1.1.1.3 root 463: uae_u8 *dptr = get_real_address(dest);
464: fseek (floppy[0].diskfile, floppy[0].trackdata[tr].offs + sec*512, SEEK_SET);
465: fread (dptr, 1, 512, floppy[0].diskfile);
1.1 root 466: }
467:
1.1.1.4 root 468: void disk_eject (int num)
1.1 root 469: {
470: gui_filename(num, "");
471: drive_eject(floppy + num);
1.1.1.3 root 472: *currprefs.df[num] = *changed_prefs.df[num] = 0;
1.1 root 473: }
474:
1.1.1.4 root 475: void disk_insert (int num, const char *name)
1.1 root 476: {
477: /* just to be sure */
1.1.1.4 root 478: drive_eject (floppy + num);
479: drive_insert (floppy + num, num, name);
1.1 root 480: }
481:
1.1.1.3 root 482: void DISK_check_change (void)
483: {
484: int i;
485: static int count = 0;
486: count++;
487:
488: for (i = 0; i < 4; i++) {
489: if (strcmp (currprefs.df[i], changed_prefs.df[i]) != 0) {
490: if (currprefs.df[i][0] != '\0') {
491: drive_eject(floppy + i);
492: currprefs.df[i][0] = '\0';
493: gui_filename(i, "");
494: } else if (floppy[i].dskchange == 1) {
495: /* In theory, it should work without the dskchange test.
496: * In practice, it doesn't. */
497: drive_insert (floppy + i, i, changed_prefs.df[i]);
498: } else if (floppy[i].dskchange > 1 && floppy[i].dskchange_time > 0) {
499: /* Force the dskchange bit to go to 1 after a given timeout */
500: if (--floppy[i].dskchange_time == 0) {
501: floppy[i].dskchange = 1;
502: }
503: }
504: }
505: }
506: }
507:
1.1.1.4 root 508: int disk_empty (int num)
1.1 root 509: {
1.1.1.4 root 510: return drive_empty (floppy + num);
1.1 root 511: }
512:
1.1.1.4 root 513: void DISK_init (void)
1.1 root 514: {
1.1.1.3 root 515: int i;
516: for (i = 0; i < 4; i++)
517: if (!drive_insert (floppy+i, i, currprefs.df[i]))
518: disk_eject (i);
519:
520: if (disk_empty (0))
521: write_log ("No disk in drive 0.\n");
1.1 root 522: }
523:
524: static int ledstate[] = { 0,0,0,0 };
525:
1.1.1.4 root 526: void DISK_select (uae_u8 data)
1.1 root 527: {
528: int step_pulse;
529: int dr;
1.1.1.3 root 530:
531: if (selected != ((data >> 3) & 15))
1.1 root 532: dskready = 0;
533: selected = (data >> 3) & 15;
1.1.1.3 root 534: side = 1 - ((data >> 2) & 1);
535:
1.1 root 536: direction = (data >> 1) & 1;
537: step_pulse = data & 1;
538: if (step != step_pulse) {
539: step = step_pulse;
540: if (step == 0){
541: for (dr = 0; dr < 4; dr++){
542: if (!(selected & (1 << dr))) {
1.1.1.4 root 543: drive_step (floppy + dr);
1.1 root 544: }
545: }
546: }
547: }
548: for (dr = 0; dr < 4; dr++){
549: if (!(selected & (1<<dr))) {
550: drive_motor(floppy + dr, data >> 7);
551: }
552: }
553: for (dr = 0; dr < 4; dr++) {
554: int state = (!(selected & (1<<dr))) | !floppy[dr].motoroff;
1.1.1.3 root 555: if (state == ledstate[dr])
556: continue;
557: gui_led (dr + 1, state);
1.1 root 558: ledstate[dr] = state;
1.1.1.3 root 559: gui_ledstate &= ~(1 << (dr + 1));
560: gui_ledstate |= state << (dr + 1);
1.1 root 561: }
562: }
563:
1.1.1.4 root 564: uae_u8 DISK_status (void)
1.1 root 565: {
1.1.1.3 root 566: uae_u8 st = 0x3c;
1.1 root 567: int dr;
1.1.1.3 root 568:
1.1 root 569: for (dr = 0; dr < 4; dr++){
1.1.1.3 root 570: drive *drv = floppy + dr;
1.1 root 571: if (!(selected & (1 << dr))) {
1.1.1.3 root 572: if (drive_running(drv)){
1.1 root 573: if (dskready) st &= ~0x20;
574: dskready = 1;
575: } else {
576: st &= ~0x20; /* report drive ID */
577: }
1.1.1.3 root 578:
579: if (drive_track0 (drv)) { st &= ~0x10; }
580: if (drive_writeprotected (drv)) { st &= ~8; }
581: if (drv->dskchange) {
582: /*printf("changed bit set: %d\n",dr); */
583: st &= ~0x4;
584: if (drv->dskchange > 1)
585: drv->dskchange--;
586: }
1.1 root 587: }
588: }
589: return st;
590: }
591:
1.1.1.6 ! root 592: void DISK_GetData (uae_u16 *mfm, uae_u16 *byt)
1.1 root 593: {
594: int dr;
595: for (dr = 0; dr < 4; dr++){
596: if (!(selected & (1<<dr))) {
1.1.1.6 ! root 597: drive_get_data (floppy + dr, mfm, byt);
1.1 root 598: }
599: }
600: }
601:
1.1.1.6 ! root 602: #if 0
1.1.1.4 root 603: int DISK_PrepareReadMFM (int length, uae_u16 sync, int use_sync)
1.1 root 604: {
605: int dr;
1.1.1.3 root 606:
1.1 root 607: mfm_read_length = 0;
1.1.1.3 root 608:
1.1 root 609: for (dr = 0; dr < 4; dr++) {
610: if (!(selected & (1<<dr))) {
611: int time = 0;
1.1.1.3 root 612: uae_u16 *mfmp = mfm_read_buffer;
1.1 root 613: drive *drv = floppy + dr;
614: int offset,mfmpos;
615:
1.1.1.4 root 616: drive_fill_bigbuf (drv);
1.1.1.2 root 617:
1.1 root 618: offset = (cycles - drv->last_cycles) / FLOPPY_SPEED;
619: mfmpos = (drv->mfmpos + offset) % drv->tracklen;
620: drv->last_cycles += offset*FLOPPY_SPEED;
621: drv->mfmpos = mfmpos;
622: mfmpos++; mfmpos %= drv->tracklen;
623: while (drv->bigmfmbuf[mfmpos] != sync && mfmpos != drv->mfmpos && use_sync)
624: mfmpos = (mfmpos + 1) % drv->tracklen, time++;
1.1.1.2 root 625:
1.1 root 626: if (drv->bigmfmbuf[mfmpos] != sync && use_sync) {
1.1.1.3 root 627: write_log ("warning: sync not found on disk read\n");
1.1 root 628: return 0;
629: } else
630: mfmpos++;
1.1.1.2 root 631:
1.1 root 632: mfm_read_length = length;
633:
634: while (length--) {
635: *mfmp++ = drv->bigmfmbuf[mfmpos];
636: mfmpos = (mfmpos + 1) % drv->tracklen;
637: time++;
638: }
639:
640: return time*FLOPPY_SPEED;
641: }
642: }
1.1.1.3 root 643: return 0;
1.1 root 644: }
645:
1.1.1.4 root 646: int DISK_ReadMFM (uaecptr target)
1.1 root 647: {
648: int i;
1.1.1.3 root 649: uae_u8 *mfmp = get_real_address(target);
650:
1.1 root 651: if (!chipmem_bank.check(target, mfm_read_length * 2)) {
1.1.1.3 root 652: write_log ("warning: Bad disk DMA read pointer\n");
1.1 root 653: return 0;
654: }
655:
656: for (i = 0; i < mfm_read_length; i++) {
657: *mfmp++ = mfm_read_buffer[i] >> 8;
658: *mfmp++ = mfm_read_buffer[i];
659: }
660: return 1;
661: }
1.1.1.6 ! root 662: #endif
1.1 root 663:
1.1.1.4 root 664: void DISK_InitWrite (void)
1.1 root 665: {
666: mfmwrite = mfmwrbuffer;
667: }
668:
1.1.1.6 ! root 669: int DISK_update_reads (uaecptr *ptr, int *length, int *syncfound, int sync)
! 670: {
! 671: int dr;
! 672: for (dr = 0; dr < 4; dr++) {
! 673: if (!(selected & (1<<dr))) {
! 674: return drive_update_reads (floppy + dr, ptr, length, syncfound, sync);
! 675: }
! 676: }
! 677: return 0;
! 678: }
! 679:
1.1.1.4 root 680: void DISK_WriteData (int length)
1.1 root 681: {
682: int dr;
1.1.1.6 ! root 683: for (dr = 0; dr < 4; dr++) {
1.1 root 684: if (!(selected & (1<<dr))) {
685: drive_write_data(floppy + dr, mfmwrbuffer, length);
686: }
687: }
688: }
1.1.1.6 ! root 689:
! 690: void DISK_search_sync (int cycle_limit, unsigned int sync)
! 691: {
! 692: int dr;
! 693: for (dr = 0; dr < 4; dr++) {
! 694: if (!(selected & (1 << dr))) {
! 695: drive *drv = floppy + dr;
! 696: unsigned long offs = drv->mfmpos;
! 697: unsigned long missing = FLOPPY_SPEED - (cycles - drv->last_cycles);
! 698: unsigned long count = 0;
! 699: if (missing == 0) {
! 700: write_log ("bug in disk code: missing == 0\n");
! 701: return;
! 702: }
! 703:
! 704: while (missing < cycle_limit) {
! 705: count += missing;
! 706: cycle_limit -= missing;
! 707: missing = FLOPPY_SPEED;
! 708: if (drv->bigmfmbuf[offs] == sync) {
! 709: eventtab[ev_disksync].active = 1;
! 710: eventtab[ev_disksync].oldcycles = cycles;
! 711: eventtab[ev_disksync].evtime = cycles + count;
! 712: events_schedule ();
! 713: }
! 714: offs++;
! 715: }
! 716: }
! 717: }
! 718: }
! 719:
! 720: /* Called when DMA gets restarted, so that we don't do DMA for the
! 721: parts of the track that went past us while DMA was off. */
! 722: void DISK_reset_cycles (void)
! 723: {
! 724: int dr;
! 725: for (dr = 0; dr < 4; dr++) {
! 726: drive *drv = floppy + dr;
! 727: unsigned long count = (cycles - drv->last_cycles) / FLOPPY_SPEED;
! 728: drv->mfmpos += count;
! 729: drv->mfmpos %= drv->tracklen;
! 730: drv->last_cycles += count * FLOPPY_SPEED;
! 731: }
! 732: }
! 733:
! 734: void DISK_StartRead ()
! 735: {
! 736: DISK_reset_cycles ();
! 737: }
! 738:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.