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