|
|
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.1.7 ! root 32: /* writable track length with normal 2us bitcell/300RPM motor */
! 33: #define FLOPPY_WRITE_LEN 6250
! 34: /* (cycles/bitcell) << 8, normal = ((2us/280ns)<<8) = ~1830 */
! 35: #define NORMAL_FLOPPY_SPEED 1830
! 36:
! 37: static int floppy_speed = NORMAL_FLOPPY_SPEED;
! 38:
! 39: #undef DISK_DEBUG
! 40:
! 41: /* UAE-1ADF (ADF_EXT2)
! 42: * W reserved
! 43: * W number of tracks (default 2*80=160)
! 44: *
! 45: * W reserved
! 46: * W type, 0=normal AmigaDOS track, 1 = raw MFM
! 47: * L available space for track in bytes
! 48: * L track length in bits
! 49: */
1.1 root 50:
1.1.1.7 ! root 51: static int side, direction, step, writing;
1.1.1.3 root 52: static uae_u8 selected = 15;
1.1 root 53: static int dskready;
54:
1.1.1.7 ! root 55: static uae_u8 *writebuffer[544 * 11];
! 56:
! 57: typedef enum { TRACK_AMIGADOS, TRACK_RAW, TRACK_RAW1 } image_tracktype;
1.1 root 58: typedef struct {
1.1.1.3 root 59: uae_u16 len;
60: uae_u32 offs;
1.1.1.7 ! root 61: int bitlen;
! 62: unsigned int sync;
! 63: image_tracktype type;
1.1 root 64: } trackid;
65:
1.1.1.2 root 66: #define MAX_TRACKS 328
67:
1.1.1.7 ! root 68: typedef enum { ADF_NORMAL, ADF_EXT1, ADF_EXT2 } drive_filetype;
1.1 root 69: typedef struct {
70: FILE *diskfile;
71: drive_filetype filetype;
1.1.1.2 root 72: trackid trackdata[MAX_TRACKS];
1.1.1.7 ! root 73: int buffered_cyl, buffered_side;
! 74: int cyl;
1.1 root 75: int motoroff;
1.1.1.7 ! root 76: int state;
! 77: int disabled;
1.1 root 78: int wrprot;
1.1.1.3 root 79: uae_u16 bigmfmbuf[0x4000];
1.1 root 80: int mfmpos;
1.1.1.7 ! root 81: int mfmpos_hsync;
! 82: int tracklen;
! 83: int trackspeed;
! 84: int dmalen;
! 85: int num_tracks, num_secs;
1.1.1.3 root 86: /* dskchange is set to a small number when a disk is removed. At a step
87: * impulse, it is reset if there is a new disk in the drive or counted
88: * down to 1 if the drive contains a disk. DISK_check_change will only
89: * insert a new disk when dskchange is 1, or if the dskchange_time timer
90: * expires. The last condition can happen if AmigaOS isn't running and a
91: * game/demo doesn't use the step motor to check for a new disk.
92: */
93: int dskchange;
94: int dskchange_time;
1.1 root 95: } drive;
96:
97: drive floppy[4];
98:
1.1.1.7 ! root 99: /* code for track display */
! 100: static void update_drive_gui (drive * drv)
! 101: {
! 102: int num;
! 103: #if 0
! 104: num = drv - &floppy[0];
! 105: if (drv->state == gui_data.drive_motor[num]
! 106: && drv->cyl == gui_data.drive_track[num]
! 107: && ((writing && gui_data.drive_writing[num])
! 108: || (!writing && !gui_data.drive_writing[num]))) {
! 109: return;
! 110: }
! 111: gui_data.drive_motor[num] = drv->state;
! 112: gui_data.drive_track[num] = drv->cyl;
! 113: if (!gui_data.drive_writing[num])
! 114: gui_data.drive_writing[num] = writing;
! 115: gui_led (num + 1, gui_data.drive_motor[num]);
! 116: #endif
! 117: }
! 118:
! 119: static void drive_fill_bigbuf (drive * drv);
1.1 root 120:
1.1.1.3 root 121: FILE *DISK_validate_filename (const char *fname, int leave_open, int *wrprot)
1.1 root 122: {
1.1.1.4 root 123: FILE *f = zfile_open (fname, "r+b");
1.1.1.3 root 124: if (f) {
125: if (wrprot)
126: *wrprot = 0;
1.1 root 127: } else {
1.1.1.3 root 128: if (wrprot)
129: *wrprot = 1;
1.1.1.4 root 130: f = zfile_open (fname, "rb");
1.1 root 131: }
1.1.1.3 root 132: if (!leave_open)
1.1.1.4 root 133: zfile_close (f);
1.1.1.3 root 134: return f;
135: }
136:
1.1.1.7 ! root 137: static int drive_insert (drive * drv, int dnum, const char *fname)
1.1.1.3 root 138: {
1.1.1.7 ! root 139: unsigned char buffer[2 + 2 + 4 + 4];
! 140: trackid *tid;
1.1.1.3 root 141:
142: drv->diskfile = DISK_validate_filename (fname, 1, &drv->wrprot);
1.1.1.6 root 143: if (drv->diskfile == 0) {
1.1.1.7 ! root 144: drv->tracklen = FLOPPY_WRITE_LEN * 2 * 8;
! 145: drv->trackspeed = floppy_speed;
1.1.1.3 root 146: return 0;
1.1.1.6 root 147: }
1.1.1.3 root 148: strncpy (currprefs.df[dnum], fname, 255);
149: currprefs.df[dnum][255] = 0;
150: strncpy (changed_prefs.df[dnum], fname, 255);
151: changed_prefs.df[dnum][255] = 0;
1.1.1.7 ! root 152: gui_filename (dnum, fname);
1.1.1.3 root 153:
1.1.1.7 ! root 154: fread (buffer, sizeof (char), 8, drv->diskfile);
! 155: if (strncmp ((char *) buffer, "UAE-1ADF", 8) == 0) {
! 156: int offs;
! 157: int i;
! 158:
! 159: fread (buffer, 1, 4, drv->diskfile);
! 160: drv->num_tracks = buffer[2] * 256 + buffer[3];
! 161: drv->filetype = ADF_EXT2;
! 162: drv->num_secs = 11;
! 163: offs = 8 + drv->num_tracks * (2 + 2 + 4 + 4);
! 164:
! 165: for (i = 0; i < drv->num_tracks; i++) {
! 166: tid = &drv->trackdata[i];
! 167: fread (buffer, 2 + 2 + 4 + 4, 1, drv->diskfile);
! 168: tid->type = buffer[2] * 256 + buffer[3];
! 169: tid->len = buffer[5] * 65536 + buffer[6] * 256 + buffer[7];
! 170: tid->bitlen = buffer[9] * 65536 + buffer[10] * 256 + buffer[11];
! 171: tid->offs = offs;
! 172: if (tid->type == TRACK_AMIGADOS) {
! 173: if (tid->len > 20000)
! 174: drv->num_secs = 22;
! 175: }
! 176: offs += tid->len;
! 177: }
! 178: } else if (strncmp ((char *) buffer, "UAE--ADF", 8) == 0) {
! 179: int offs = 160 * 4 + 8;
1.1 root 180: int i;
1.1.1.3 root 181:
182: drv->filetype = ADF_EXT1;
1.1.1.2 root 183: drv->num_tracks = 160;
184: drv->num_secs = 11;
1.1.1.3 root 185:
1.1.1.7 ! root 186: drv->wrprot = 1; /* write to adf_ext1 not implemented */
! 187: for (i = 0; i < 160; i++) {
! 188: tid = &drv->trackdata[i];
! 189: fread (buffer, 4, 1, drv->diskfile);
! 190: tid->sync = buffer[0] * 256 + buffer[1];
! 191: tid->len = buffer[2] * 256 + buffer[3];
! 192: tid->offs = offs;
! 193: if (tid->sync == 0) {
! 194: tid->type = TRACK_AMIGADOS;
! 195: tid->bitlen = 0;
! 196: } else {
! 197: tid->type = TRACK_RAW1;
! 198: tid->bitlen = tid->len * 8;
! 199: }
! 200: offs += tid->len;
1.1 root 201: }
202: } else {
1.1.1.7 ! root 203: int i;
1.1.1.3 root 204:
205: drv->filetype = ADF_NORMAL;
1.1.1.2 root 206:
1.1.1.7 ! root 207: fseek (drv->diskfile, 0, SEEK_END);
1.1.1.4 root 208: i = ftell (drv->diskfile);
1.1.1.7 ! root 209: fseek (drv->diskfile, 0, SEEK_SET);
1.1.1.3 root 210:
1.1.1.2 root 211: /* High-density disk? */
1.1.1.7 ! root 212: if (i >= 160 * 22 * 512)
! 213: drv->num_tracks = i / (512 * (drv->num_secs = 22));
1.1.1.2 root 214: else
1.1.1.7 ! root 215: drv->num_tracks = i / (512 * (drv->num_secs = 11));
1.1.1.3 root 216:
1.1.1.2 root 217: if (drv->num_tracks > MAX_TRACKS)
1.1.1.3 root 218: write_log ("Your diskfile is too big!\n");
1.1.1.7 ! root 219: for (i = 0; i < drv->num_tracks; i++) {
! 220: tid = &drv->trackdata[i];
! 221: tid->type = TRACK_AMIGADOS;
! 222: tid->len = 512 * drv->num_secs;
! 223: tid->bitlen = 0;
! 224: tid->offs = i * 512 * drv->num_secs;
1.1 root 225: }
226: }
1.1.1.7 ! root 227: drv->buffered_side = 2; /* will force read */
1.1.1.6 root 228: drive_fill_bigbuf (drv);
1.1.1.3 root 229: return 1;
1.1 root 230: }
231:
1.1.1.7 ! root 232: static int drive_empty (drive * drv)
1.1.1.2 root 233: {
1.1.1.3 root 234: return drv->diskfile == 0;
1.1.1.2 root 235: }
236:
1.1.1.7 ! root 237: static void drive_step (drive * drv)
1.1 root 238: {
1.1.1.7 ! root 239: if (!drive_empty (drv))
1.1.1.3 root 240: drv->dskchange = 0;
241: else if (drv->dskchange > 1) {
242: /* printf("Stepping...\n");
243: drv->dskchange--;*/
244: }
1.1 root 245: if (direction) {
1.1.1.7 ! root 246: if (drv->cyl)
! 247: drv->cyl--;
1.1 root 248: } else {
1.1.1.7 ! root 249: if (drv->cyl < 83)
! 250: drv->cyl++;
1.1 root 251: }
252:
1.1.1.7 ! root 253: #if 0 && defined DISK_DEBUG
! 254: write_log ("track %d\n", drv->cyl);
! 255: #endif
! 256: }
1.1 root 257:
1.1.1.7 ! root 258: static int drive_track0 (drive * drv)
1.1 root 259: {
1.1.1.3 root 260: return drv->cyl == 0;
1.1 root 261: }
262:
1.1.1.7 ! root 263: static int drive_writeprotected (drive * drv)
1.1 root 264: {
1.1.1.3 root 265: return drv->wrprot || drv->diskfile == NULL;
1.1 root 266: }
267:
1.1.1.7 ! root 268: static int drive_running (drive * drv)
1.1 root 269: {
1.1.1.3 root 270: return !drv->motoroff;
1.1 root 271: }
272:
1.1.1.7 ! root 273: static void drive_motor (drive * drv, int off)
1.1 root 274: {
275: drv->motoroff = off;
276: }
277:
1.1.1.7 ! root 278: static void read_floppy_data (drive * drv, int track, int offset, unsigned char *dst, int len)
! 279: {
! 280: trackid *ti;
! 281:
! 282: ti = &drv->trackdata[track];
! 283: fseek (drv->diskfile, ti->offs + offset, SEEK_SET);
! 284: fread (dst, 1, len, drv->diskfile);
! 285: }
! 286:
! 287: /* Megalomania does not like zero MFM words... */
! 288: static void mfmcode (uae_u16 * mfm, int words)
! 289: {
! 290: uae_u16 v;
! 291: uae_u32 lv;
! 292: int i;
! 293:
! 294: while (words--) {
! 295: lv = (mfm[0] << 16) | mfm[1];
! 296: v = mfm[0];
! 297: for (i = 30; i >= 16; i -= 2) {
! 298: if (!(lv & (1 << i)) && !(lv & (1 << (i - 2))))
! 299: v |= 1 << (i + 1 - 16);
! 300: }
! 301: *mfm++ = v;
! 302: }
! 303: }
! 304:
! 305: static void drive_fill_bigbuf (drive * drv)
1.1 root 306: {
1.1.1.7 ! root 307: int tr = drv->cyl * 2 + side;
! 308: trackid *ti = drv->trackdata + tr;
1.1.1.3 root 309:
1.1.1.7 ! root 310: if (!drv->diskfile || tr >= drv->num_tracks) {
! 311: drv->tracklen = FLOPPY_WRITE_LEN * 2 * 8;
! 312: drv->trackspeed = floppy_speed;
! 313: memset (drv->bigmfmbuf, 0xaa, FLOPPY_WRITE_LEN * 2);
1.1.1.2 root 314: return;
315: }
1.1.1.3 root 316: if (drv->buffered_cyl == drv->cyl && drv->buffered_side == side)
317: return;
318:
1.1.1.7 ! root 319: if (ti->type == TRACK_AMIGADOS) {
1.1 root 320: /* Normal AmigaDOS format track */
1.1.1.7 ! root 321: int sec;
! 322: drv->tracklen = (drv->num_secs * 544 + FLOPPY_GAP_LEN) * 2 * 8;
! 323: memset (drv->bigmfmbuf, 0xaa, FLOPPY_GAP_LEN * 2);
1.1.1.2 root 324:
325: for (sec = 0; sec < drv->num_secs; sec++) {
1.1.1.3 root 326: uae_u8 secbuf[544];
1.1 root 327: int i;
1.1.1.7 ! root 328: uae_u16 *mfmbuf = drv->bigmfmbuf + 544 * sec + FLOPPY_GAP_LEN;
! 329: uae_u32 deven, dodd;
! 330: uae_u32 hck = 0, dck = 0;
1.1.1.3 root 331:
1.1 root 332: secbuf[0] = secbuf[1] = 0x00;
333: secbuf[2] = secbuf[3] = 0xa1;
334: secbuf[4] = 0xff;
335: secbuf[5] = tr;
336: secbuf[6] = sec;
1.1.1.7 ! root 337: secbuf[7] = drv->num_secs - sec;
1.1 root 338:
1.1.1.7 ! root 339: for (i = 8; i < 24; i++)
1.1 root 340: secbuf[i] = 0;
1.1.1.3 root 341:
1.1.1.7 ! root 342: read_floppy_data (drv, tr, sec * 512, &secbuf[32], 512);
1.1.1.3 root 343:
1.1 root 344: mfmbuf[0] = mfmbuf[1] = 0xaaaa;
345: mfmbuf[2] = mfmbuf[3] = 0x4489;
1.1.1.3 root 346:
347: deven = ((secbuf[4] << 24) | (secbuf[5] << 16)
1.1 root 348: | (secbuf[6] << 8) | (secbuf[7]));
349: dodd = deven >> 1;
1.1.1.7 ! root 350: deven &= 0x55555555;
! 351: dodd &= 0x55555555;
1.1.1.3 root 352:
1.1 root 353: mfmbuf[4] = dodd >> 16;
354: mfmbuf[5] = dodd;
1.1.1.7 ! root 355: mfmbuf[6] = deven >> 16;
1.1 root 356: mfmbuf[7] = deven;
1.1.1.3 root 357:
1.1 root 358: for (i = 8; i < 48; i++)
1.1.1.6 root 359: mfmbuf[i] = 0xaaaa;
1.1.1.7 ! root 360: for (i = 0; i < 512; i += 4) {
! 361: deven = ((secbuf[i + 32] << 24) | (secbuf[i + 33] << 16)
! 362: | (secbuf[i + 34] << 8) | (secbuf[i + 35]));
1.1 root 363: dodd = deven >> 1;
1.1.1.7 ! root 364: deven &= 0x55555555;
! 365: dodd &= 0x55555555;
! 366: mfmbuf[(i >> 1) + 32] = dodd >> 16;
! 367: mfmbuf[(i >> 1) + 33] = dodd;
! 368: mfmbuf[(i >> 1) + 256 + 32] = deven >> 16;
! 369: mfmbuf[(i >> 1) + 256 + 33] = deven;
! 370: }
! 371:
! 372: for (i = 4; i < 24; i += 2)
! 373: hck ^= (mfmbuf[i] << 16) | mfmbuf[i + 1];
! 374:
! 375: deven = dodd = hck;
! 376: dodd >>= 1;
! 377: mfmbuf[24] = dodd >> 16;
! 378: mfmbuf[25] = dodd;
! 379: mfmbuf[26] = deven >> 16;
! 380: mfmbuf[27] = deven;
! 381:
! 382: for (i = 32; i < 544; i += 2)
! 383: dck ^= (mfmbuf[i] << 16) | mfmbuf[i + 1];
! 384:
! 385: deven = dodd = dck;
! 386: dodd >>= 1;
! 387: mfmbuf[28] = dodd >> 16;
! 388: mfmbuf[29] = dodd;
! 389: mfmbuf[30] = deven >> 16;
! 390: mfmbuf[31] = deven;
! 391: mfmcode (mfmbuf + 4, 544 - 4);
1.1 root 392: }
1.1.1.7 ! root 393: #ifdef DISK_DEBUG
! 394: write_log ("amigados read track %d\n", tr);
! 395: #endif
1.1 root 396: } else {
397: int i;
1.1.1.7 ! root 398: int base_offset = ti->type == TRACK_RAW ? 0 : 1;
! 399: drv->tracklen = ti->bitlen + 16 * base_offset;
! 400: read_floppy_data (drv, tr, 0, (char *) (drv->bigmfmbuf + base_offset), (ti->bitlen + 7) / 8);
! 401: drv->bigmfmbuf[0] = ti->sync;
! 402: for (i = base_offset; i < drv->tracklen / 16; i++) {
! 403: uae_u16 *mfm = drv->bigmfmbuf + i;
! 404: uae_u8 *data = (uae_u8 *) mfm;
! 405: *mfm = 256 * *data + *(data + 1);
1.1 root 406: }
1.1.1.7 ! root 407: #if 0 && defined DISK_DEBUG
! 408: write_log ("rawtrack %d\n", tr);
! 409: #endif
1.1 root 410: }
1.1.1.3 root 411: drv->buffered_side = side;
412: drv->buffered_cyl = drv->cyl;
1.1.1.7 ! root 413: drv->trackspeed = floppy_speed * drv->tracklen / (2 * 8 * FLOPPY_WRITE_LEN);
1.1 root 414: }
415:
1.1.1.7 ! root 416: /* Update ADF_EXT2 track header */
! 417: static void diskfile_update (drive * drv, int len, uae_u8 type)
1.1 root 418: {
1.1.1.7 ! root 419: trackid *ti;
! 420: int track;
! 421: uae_u8 buf[2 + 2 + 4 + 4], *zerobuf;
1.1.1.3 root 422:
1.1.1.7 ! root 423: if (drv->filetype != ADF_EXT2)
! 424: return;
1.1.1.6 root 425:
1.1.1.7 ! root 426: track = drv->cyl * 2 + side;
! 427: ti = &drv->trackdata[track];
! 428: ti->bitlen = len;
! 429: fseek (drv->diskfile, 8 + 4 + (2 + 2 + 4 + 4) * track, SEEK_SET);
! 430: memset (buf, 0, sizeof buf);
! 431: ti->type = type;
! 432: buf[3] = ti->type;
! 433: do_put_mem_long ((uae_u32 *) (buf + 4), ti->len);
! 434: do_put_mem_long ((uae_u32 *) (buf + 8), ti->bitlen);
! 435: fwrite (buf, sizeof (buf), 1, drv->diskfile);
! 436: if (ti->len > (len + 7) / 8) {
! 437: zerobuf = malloc (ti->len);
! 438: memset (zerobuf, 0, ti->len);
! 439: fseek (drv->diskfile, ti->offs, SEEK_SET);
! 440: fwrite (zerobuf, 1, ti->len, drv->diskfile);
! 441: free (zerobuf);
! 442: }
! 443: #ifdef DISK_DEBUG
! 444: write_log ("track %d, raw track length %d written (total size %d)\n", track, (ti->bitlen + 7) / 8, ti->len);
! 445: #endif
1.1 root 446: }
447:
448: #define MFMMASK 0x55555555
1.1.1.7 ! root 449: static uae_u32 getmfmlong (uae_u16 * mbuf)
1.1 root 450: {
451: return ((*mbuf << 16) | *(mbuf + 1)) & MFMMASK;
452: }
453:
1.1.1.7 ! root 454: static int drive_write_adf_amigados (drive * drv)
1.1 root 455: {
456: int i, secwritten = 0;
1.1.1.7 ! root 457: int length = 2 * FLOPPY_WRITE_LEN;
1.1.1.3 root 458: uae_u32 odd, even, chksum, id, dlong;
1.1.1.7 ! root 459: uae_u8 *secdata;
1.1.1.3 root 460: uae_u8 secbuf[544];
1.1.1.7 ! root 461: uae_u16 *mbuf = drv->bigmfmbuf;
1.1.1.3 root 462: uae_u16 *mend = mbuf + length;
1.1.1.7 ! root 463: char sectable[11];
1.1.1.3 root 464:
1.1.1.7 ! root 465: memset (sectable, 0, sizeof (sectable));
! 466: memcpy (mbuf + FLOPPY_WRITE_LEN, mbuf, FLOPPY_WRITE_LEN * sizeof (uae_u16));
1.1 root 467: mend -= (4 + 16 + 8 + 512);
1.1.1.7 ! root 468: while (secwritten < 11) {
1.1 root 469: int trackoffs;
1.1.1.3 root 470:
1.1 root 471: do {
472: while (*mbuf++ != 0x4489) {
1.1.1.4 root 473: if (mbuf >= mend)
1.1.1.7 ! root 474: return 1;
1.1 root 475: }
476: } while (*mbuf++ != 0x4489);
1.1.1.3 root 477:
1.1.1.4 root 478: odd = getmfmlong (mbuf);
479: even = getmfmlong (mbuf + 2);
1.1.1.3 root 480: mbuf += 4;
1.1 root 481: id = (odd << 1) | even;
1.1.1.3 root 482:
1.1 root 483: trackoffs = (id & 0xff00) >> 8;
484: if (trackoffs > 10) {
1.1.1.7 ! root 485: if (drv->filetype == ADF_EXT2)
! 486: return 2;
1.1.1.5 root 487: write_log ("Disk write: weird sector number %d\n", trackoffs);
1.1 root 488: continue;
489: }
490: chksum = odd ^ even;
1.1.1.4 root 491: for (i = 0; i < 4; i++) {
1.1.1.7 ! root 492: odd = getmfmlong (mbuf);
! 493: even = getmfmlong (mbuf + 8);
1.1 root 494: mbuf += 2;
1.1.1.3 root 495:
1.1 root 496: dlong = (odd << 1) | even;
1.1.1.7 ! root 497: if (dlong) {
! 498: if (drv->filetype == ADF_EXT2)
! 499: return 6;
1.1.1.4 root 500: secwritten = -200;
1.1.1.7 ! root 501: }
1.1 root 502: chksum ^= odd ^ even;
1.1.1.7 ! root 503: } /* could check here if the label is nonstandard */
1.1 root 504: mbuf += 8;
1.1.1.7 ! root 505: odd = getmfmlong (mbuf);
! 506: even = getmfmlong (mbuf + 2);
! 507: mbuf += 4;
! 508: if (((odd << 1) | even) != chksum || ((id & 0x00ff0000) >> 16) != drv->cyl * 2 + side) {
! 509: if (drv->filetype == ADF_EXT2)
! 510: return 3;
! 511: write_log ("Disk write: checksum error on sector %d header\n", trackoffs);
1.1 root 512: continue;
513: }
1.1.1.7 ! root 514: odd = getmfmlong (mbuf);
! 515: even = getmfmlong (mbuf + 2);
! 516: mbuf += 4;
1.1 root 517: chksum = (odd << 1) | even;
518: secdata = secbuf + 32;
1.1.1.7 ! root 519: for (i = 0; i < 128; i++) {
! 520: odd = getmfmlong (mbuf);
! 521: even = getmfmlong (mbuf + 256);
! 522: mbuf += 2;
1.1 root 523: dlong = (odd << 1) | even;
1.1.1.7 ! root 524: *secdata++ = dlong >> 24;
! 525: *secdata++ = dlong >> 16;
! 526: *secdata++ = dlong >> 8;
! 527: *secdata++ = dlong;
1.1 root 528: chksum ^= odd ^ even;
529: }
530: mbuf += 256;
531: if (chksum) {
1.1.1.7 ! root 532: if (drv->filetype == ADF_EXT2)
! 533: return 4;
! 534: write_log ("Disk write: sector %d, data checksum error\n", trackoffs);
1.1 root 535: continue;
536: }
1.1.1.7 ! root 537: sectable[trackoffs] = 1;
1.1 root 538: secwritten++;
1.1.1.7 ! root 539: memcpy (writebuffer + trackoffs * 512, secbuf + 32, 512);
1.1 root 540: }
1.1.1.7 ! root 541: if (drv->filetype == ADF_EXT2 && (secwritten == 0 || secwritten < 0))
! 542: return 5;
1.1.1.3 root 543: if (secwritten == 0)
544: write_log ("Disk write in unsupported format\n");
1.1 root 545: if (secwritten < 0)
1.1.1.3 root 546: write_log ("Disk write: sector labels ignored\n");
1.1.1.7 ! root 547:
! 548: diskfile_update (drv, 11 * 512 * 8, TRACK_AMIGADOS);
! 549: for (i = 0; i < 11; i++) {
! 550: fseek (drv->diskfile, drv->trackdata[drv->cyl * 2 + side].offs + i * 512, SEEK_SET);
! 551: fwrite (writebuffer + i * 512, sizeof (uae_u8), 512, drv->diskfile);
! 552: }
! 553:
! 554: return 0;
1.1 root 555: }
556:
1.1.1.7 ! root 557: /* write raw track to disk file */
! 558: static int drive_write_ext2 (drive * drv)
! 559: {
! 560: trackid *ti;
! 561: int len, track, i;
1.1 root 562:
1.1.1.7 ! root 563: track = drv->cyl * 2 + side;
! 564: ti = &drv->trackdata[track];
! 565: len = (drv->tracklen + 7) / 8;
! 566: if (len > ti->len) {
! 567: write_log ("disk raw write: image file's track %d is too small (%d < %d)!\n", track, ti->len, len);
! 568: return 0;
! 569: }
! 570: diskfile_update (drv, drv->tracklen, TRACK_RAW);
! 571: for (i = 0; i < drv->trackdata[track].len / 2; i++) {
! 572: uae_u16 *mfm = drv->bigmfmbuf + i;
! 573: uae_u8 *data = (uae_u8 *) mfm;
! 574: *mfm = 256 * *data + *(data + 1);
! 575: }
! 576: fseek (drv->diskfile, ti->offs, SEEK_SET);
! 577: fwrite (drv->bigmfmbuf, 1, len, drv->diskfile);
! 578: return 1;
! 579: }
! 580:
! 581: static void drive_write_data (drive * drv)
1.1 root 582: {
1.1.1.7 ! root 583: int ret;
! 584: if (drive_writeprotected (drv))
! 585: return;
! 586: switch (drv->filetype) {
! 587: case ADF_NORMAL:
! 588: drive_write_adf_amigados (drv);
! 589: break;
! 590: case ADF_EXT1:
! 591: write_log ("writing to ADF_EXT1 not supported\n");
! 592: return;
! 593: case ADF_EXT2:
! 594: ret = drive_write_adf_amigados (drv);
! 595: if (ret) {
! 596: /*write_log("not an amigados track (error %d), writing as raw track\n",ret); */
! 597: drive_write_ext2 (drv);
! 598: }
! 599: break;
! 600: }
! 601: drv->buffered_side = 2; /* will force read */
! 602: }
! 603:
! 604: static void drive_eject (drive * drv)
! 605: {
! 606: if (!drive_empty (drv))
1.1.1.4 root 607: zfile_close (drv->diskfile);
1.1.1.3 root 608:
609: drv->dskchange = 4;
610: drv->dskchange_time = 20;
611: /* printf("setting changed bit %d\n", drv-floppy);*/
1.1 root 612: drv->diskfile = 0;
613: }
614:
1.1.1.3 root 615: /* We use this function if we have no Kickstart ROM.
1.1 root 616: * No error checking - we trust our luck. */
1.1.1.3 root 617: void DISK_ersatz_read (int tr, int sec, uaecptr dest)
1.1 root 618: {
1.1.1.7 ! root 619: uae_u8 *dptr = get_real_address (dest);
! 620: fseek (floppy[0].diskfile, floppy[0].trackdata[tr].offs + sec * 512, SEEK_SET);
1.1.1.3 root 621: fread (dptr, 1, 512, floppy[0].diskfile);
1.1 root 622: }
623:
1.1.1.4 root 624: void disk_eject (int num)
1.1 root 625: {
1.1.1.7 ! root 626: gui_filename (num, "");
! 627: drive_eject (floppy + num);
1.1.1.3 root 628: *currprefs.df[num] = *changed_prefs.df[num] = 0;
1.1 root 629: }
630:
1.1.1.4 root 631: void disk_insert (int num, const char *name)
1.1 root 632: {
633: /* just to be sure */
1.1.1.4 root 634: drive_eject (floppy + num);
635: drive_insert (floppy + num, num, name);
1.1 root 636: }
637:
1.1.1.3 root 638: void DISK_check_change (void)
639: {
640: int i;
641: static int count = 0;
642: count++;
643:
644: for (i = 0; i < 4; i++) {
645: if (strcmp (currprefs.df[i], changed_prefs.df[i]) != 0) {
646: if (currprefs.df[i][0] != '\0') {
1.1.1.7 ! root 647: drive_eject (floppy + i);
1.1.1.3 root 648: currprefs.df[i][0] = '\0';
1.1.1.7 ! root 649: gui_filename (i, "");
1.1.1.3 root 650: } else if (floppy[i].dskchange == 1) {
651: /* In theory, it should work without the dskchange test.
652: * In practice, it doesn't. */
653: drive_insert (floppy + i, i, changed_prefs.df[i]);
654: } else if (floppy[i].dskchange > 1 && floppy[i].dskchange_time > 0) {
655: /* Force the dskchange bit to go to 1 after a given timeout */
656: if (--floppy[i].dskchange_time == 0) {
657: floppy[i].dskchange = 1;
658: }
659: }
660: }
661: }
662: }
663:
1.1.1.4 root 664: int disk_empty (int num)
1.1 root 665: {
1.1.1.4 root 666: return drive_empty (floppy + num);
1.1 root 667: }
668:
1.1.1.4 root 669: void DISK_select (uae_u8 data)
1.1 root 670: {
671: int step_pulse;
672: int dr;
1.1.1.3 root 673:
674: if (selected != ((data >> 3) & 15))
1.1 root 675: dskready = 0;
676: selected = (data >> 3) & 15;
1.1.1.3 root 677: side = 1 - ((data >> 2) & 1);
678:
1.1 root 679: direction = (data >> 1) & 1;
680: step_pulse = data & 1;
681: if (step != step_pulse) {
682: step = step_pulse;
1.1.1.7 ! root 683: if (step == 0) {
! 684: for (dr = 0; dr < 4; dr++) {
1.1 root 685: if (!(selected & (1 << dr))) {
1.1.1.4 root 686: drive_step (floppy + dr);
1.1 root 687: }
688: }
689: }
690: }
1.1.1.7 ! root 691: for (dr = 0; dr < 4; dr++) {
! 692: if (!(selected & (1 << dr))) {
! 693: drive_motor (floppy + dr, data >> 7);
1.1 root 694: }
695: }
696: for (dr = 0; dr < 4; dr++) {
1.1.1.7 ! root 697: floppy[dr].state = (!(selected & (1 << dr))) | !floppy[dr].motoroff;
! 698: update_drive_gui (floppy + dr);
1.1 root 699: }
700: }
701:
1.1.1.4 root 702: uae_u8 DISK_status (void)
1.1 root 703: {
1.1.1.3 root 704: uae_u8 st = 0x3c;
1.1 root 705: int dr;
1.1.1.3 root 706:
1.1.1.7 ! root 707: for (dr = 0; dr < 4; dr++) {
1.1.1.3 root 708: drive *drv = floppy + dr;
1.1 root 709: if (!(selected & (1 << dr))) {
1.1.1.7 ! root 710: if (drive_running (drv)) {
! 711: if (dskready)
! 712: st &= ~0x20;
1.1 root 713: dskready = 1;
1.1.1.7 ! root 714: } else if (!drv->disabled) {
! 715: st &= ~0x20; /* report drive ID */
1.1 root 716: }
1.1.1.3 root 717:
1.1.1.7 ! root 718: if (drive_track0 (drv)) {
! 719: st &= ~0x10;
! 720: }
! 721: if (drive_writeprotected (drv)) {
! 722: st &= ~8;
! 723: }
1.1.1.3 root 724: if (drv->dskchange) {
725: /*printf("changed bit set: %d\n",dr); */
726: st &= ~0x4;
727: if (drv->dskchange > 1)
728: drv->dskchange--;
729: }
1.1 root 730: }
731: }
732: return st;
733: }
734:
1.1.1.7 ! root 735: #define MAX_DISK_WORDS_PER_LINE 50 /* depends on floppy_speed */
! 736:
! 737: #define DISK_INDEXSYNC 1
! 738: #define DISK_WORDSYNC 2
! 739:
! 740: static uae_u16 dskbytr_tab[MAX_DISK_WORDS_PER_LINE * 2 + 1];
! 741: static uae_u8 dskbytr_cycle[MAX_DISK_WORDS_PER_LINE * 2 + 1];
! 742: static uae_u16 dskdatr_tab[MAX_DISK_WORDS_PER_LINE + 1];
! 743: static uae_u8 dskdatr_cycle[MAX_DISK_WORDS_PER_LINE + 1];
! 744: static uae_u32 dma_tab[MAX_DISK_WORDS_PER_LINE + 1];
! 745: static uae_u8 disk_sync[MAXHPOS];
! 746: static int disk_sync_cycle;
! 747: static int indexsync_last_cycle;
! 748: static int dskdmaen, dsklength;
! 749: static uae_u16 dsksync;
! 750: static uae_u32 dskpt;
! 751:
! 752: static void disk_dmafinished (void)
! 753: {
! 754: INTREQ (0x8002);
! 755: dskdmaen = 0;
! 756: }
! 757:
! 758: static void disk_events (int last)
! 759: {
! 760: eventtab[ev_disk].active = 0;
! 761: for (disk_sync_cycle = last; disk_sync_cycle < MAXHPOS; disk_sync_cycle++) {
! 762: if (disk_sync[disk_sync_cycle]) {
! 763: eventtab[ev_disk].oldcycles = cycles;
! 764: eventtab[ev_disk].evtime = cycles + (disk_sync_cycle - last);
! 765: eventtab[ev_disk].active = 1;
! 766: events_schedule ();
! 767: return;
1.1 root 768: }
769: }
770: }
771:
1.1.1.7 ! root 772: extern void cia_diskindex (void);
1.1.1.3 root 773:
1.1.1.7 ! root 774: void DISK_handler (void)
! 775: {
! 776: eventtab[ev_disk].active = 0;
! 777: if (disk_sync[disk_sync_cycle] & DISK_WORDSYNC) {
! 778: INTREQ (0x9000);
! 779: indexsync_last_cycle = disk_sync_cycle + ((floppy_speed + 255) >> 8);
! 780: }
! 781: if (disk_sync[disk_sync_cycle] & DISK_INDEXSYNC) {
! 782: cia_diskindex ();
! 783: }
! 784: disk_sync[disk_sync_cycle] = 0;
! 785: disk_events (disk_sync_cycle);
! 786: }
1.1.1.3 root 787:
1.1.1.7 ! root 788: static int syncfound, dmaon, word, bitoffset;
1.1 root 789:
1.1.1.7 ! root 790: /* Always carried through to the next line. */
! 791: static int disk_hpos;
1.1.1.2 root 792:
1.1.1.7 ! root 793: /* emulate disk write dma for full horizontal line */
! 794: static void disk_doupdate_write (drive * drv)
! 795: {
! 796: int hpos = disk_hpos;
! 797: while (hpos < (MAXHPOS << 8)) {
! 798: drv->mfmpos++;
! 799: drv->mfmpos %= drv->tracklen;
! 800: if (!drv->mfmpos) {
! 801: disk_sync[hpos >> 8] |= DISK_INDEXSYNC;
! 802: disk_events (0);
! 803: }
! 804: if ((dmacon & 0x210) == 0x210 && dskdmaen == 3) {
! 805: bitoffset++;
! 806: bitoffset &= 15;
! 807: if (!bitoffset) {
! 808: drv->bigmfmbuf[drv->mfmpos >> 4] = get_word (dskpt);
! 809: dskpt += 2;
! 810: dsklength--;
! 811: if (dsklength == 0) {
! 812: disk_dmafinished ();
! 813: drive_write_data (drv);
! 814: }
1.1 root 815: }
816: }
1.1.1.7 ! root 817: hpos += drv->trackspeed;
1.1 root 818: }
1.1.1.7 ! root 819: disk_hpos = hpos - (MAXHPOS << 8);
1.1 root 820: }
821:
1.1.1.7 ! root 822: /* get one bit from MFM bit stream */
! 823: static uae_u16 getonebit (uae_u16 * mfmbuf, int mfmpos, uae_u16 word)
1.1 root 824: {
1.1.1.7 ! root 825: uae_u16 *buf;
1.1 root 826:
1.1.1.7 ! root 827: buf = &mfmbuf[mfmpos >> 4];
! 828: word <<= 1;
! 829: word |= (buf[0] & (1 << (15 - (mfmpos & 15)))) ? 1 : 0;
! 830: return word;
1.1 root 831: }
832:
1.1.1.7 ! root 833: /* emulate disk read dma for full horizontal line */
! 834: static void disk_doupdate_read (drive * drv)
! 835: {
! 836: int hpos = disk_hpos;
! 837: int is_sync = 0, dmaon;
! 838: int j = 0, l = 0, k = 0;
! 839:
! 840: while (hpos < (MAXHPOS << 8)) {
! 841: word = getonebit (drv->bigmfmbuf, drv->mfmpos, word);
! 842: drv->mfmpos++;
! 843: drv->mfmpos %= drv->tracklen;
! 844: if (!drv->mfmpos) {
! 845: disk_sync[hpos >> 8] |= DISK_INDEXSYNC;
! 846: is_sync = 1;
! 847: }
! 848: bitoffset++;
! 849: bitoffset &= 15;
! 850: if (bitoffset == 0 && (!(adkcon & 0x400) || syncfound))
! 851: dmaon = 1;
! 852: else
! 853: dmaon = 0;
! 854: if (word == dsksync) {
! 855: if ((adkcon & 0x400) == 0x400 && ! syncfound) {
! 856: syncfound = 1;
! 857: bitoffset = 0;
! 858: }
! 859: disk_sync[hpos >> 8] |= DISK_WORDSYNC;
! 860: is_sync = 1;
! 861: }
! 862: if (dmaon) {
! 863: dma_tab[j++] = word;
! 864: if (j == MAX_DISK_WORDS_PER_LINE - 1) {
! 865: write_log ("Bug: Disk DMA buffer overflow!\n");
! 866: j--;
! 867: }
! 868: }
! 869: if (bitoffset == 0 || bitoffset == 8) {
! 870: dskbytr_tab[k] = (word & 0xff) | 0x8000;
! 871: dskbytr_cycle[k++] = hpos >> 8;
! 872: if (bitoffset == 0) {
! 873: dskdatr_tab[l] = word;
! 874: dskdatr_cycle[l++] = hpos >> 8;
! 875: }
! 876: }
! 877: hpos += drv->trackspeed;
! 878: }
! 879: dma_tab[j] = 0xffffffff;
! 880: if (is_sync)
! 881: disk_events (0);
! 882: dskbytr_cycle[k] = 255;
! 883: dskdatr_cycle[l] = 255;
! 884:
! 885: disk_hpos = hpos - (MAXHPOS << 8);
! 886: }
! 887:
! 888: /* disk DMA fetch happens on real Amiga at the beginning of next horizontal line
! 889: (cycles 9, 11 and 13 according to hardware manual) We transfer all DMA'd
! 890: data at cycle 0. I don't think any program cares about this small difference.
! 891: */
! 892: static void dodmafetch (void)
1.1 root 893: {
1.1.1.7 ! root 894: int i;
! 895:
! 896: i = 0;
! 897: while (dma_tab[i] != 0xffffffff && dskdmaen == 2 && (dmacon & 0x210) == 0x210) {
! 898: put_word (dskpt, dma_tab[i]);
! 899: dskpt += 2;
! 900: dsklength--;
! 901: if (dsklength == 0) {
! 902: disk_dmafinished ();
! 903: break;
! 904: }
! 905: i++;
! 906: }
! 907: dma_tab[0] = 0xffffffff;
1.1 root 908: }
909:
1.1.1.7 ! root 910: static void DISK_start (void)
1.1.1.6 root 911: {
912: int dr;
1.1.1.7 ! root 913:
1.1.1.6 root 914: for (dr = 0; dr < 4; dr++) {
1.1.1.7 ! root 915: drive *drv = &floppy[dr];
! 916: if (!(selected & (1 << dr))) {
! 917: int tr = drv->cyl * 2 + side;
! 918: trackid *ti = drv->trackdata + tr;
! 919:
! 920: drive_fill_bigbuf (drv);
! 921: if (dskdmaen == 3) {
! 922: drv->tracklen = FLOPPY_WRITE_LEN * 8 * 2;
! 923: drv->trackspeed = floppy_speed;
! 924: }
! 925: /* Ugh. A nasty hack. Assume ADF_EXT1 tracks are always read
! 926: from the start. */
! 927: if (ti->type == TRACK_RAW1)
! 928: drv->mfmpos = 0;
! 929: drv->mfmpos %= drv->tracklen;
1.1.1.6 root 930: }
931: }
1.1.1.7 ! root 932: syncfound = 0;
! 933: dmaon = 0;
! 934: word = 0;
! 935: bitoffset = 0;
! 936: dma_tab[0] = 0xffffffff;
1.1.1.6 root 937: }
938:
1.1.1.7 ! root 939: static int linecounter;
! 940:
! 941: void DISK_update (void)
1.1 root 942: {
943: int dr;
1.1.1.7 ! root 944:
1.1.1.6 root 945: for (dr = 0; dr < 4; dr++) {
1.1.1.7 ! root 946: drive *drv = &floppy[dr];
! 947: drv->mfmpos_hsync = drv->mfmpos;
! 948: }
! 949: if (linecounter) {
! 950: linecounter--;
! 951: if (! linecounter)
! 952: disk_dmafinished ();
! 953: return;
! 954: }
! 955:
! 956: dodmafetch ();
! 957: indexsync_last_cycle = -1;
! 958:
! 959: for (dr = 0; dr < 4; dr++) {
! 960: drive *drv = &floppy[dr];
! 961: if (drv->motoroff)
! 962: continue;
! 963: if (selected & (1 << dr)) {
! 964: drv->mfmpos += (MAXHPOS << 8) / drv->trackspeed;
! 965: drv->mfmpos %= drv->tracklen;
! 966: continue;
1.1 root 967: }
1.1.1.7 ! root 968: if (dskdmaen == 3)
! 969: disk_doupdate_write (drv);
! 970: else
! 971: disk_doupdate_read (drv);
! 972: return;
1.1 root 973: }
974: }
1.1.1.6 root 975:
1.1.1.7 ! root 976: void DSKLEN (uae_u16 v, int hpos)
1.1.1.6 root 977: {
1.1.1.7 ! root 978: if (v & 0x8000) {
! 979: dskdmaen = dskdmaen == 1 ? 2 : 1;
! 980: } else {
! 981: /* Megalomania does this */
! 982: #if 0
! 983: if (dskdmaen == 2)
! 984: write_log ("warning: Disk read DMA aborted, %d words left\n", dsklength);
! 985: #endif
! 986: if (dskdmaen == 3)
! 987: write_log ("warning: Disk write DMA aborted, %d words left\n", dsklength);
! 988: dskdmaen = 0;
! 989: }
! 990: dsklength = v & 0x3fff;
! 991: if (dskdmaen <= 1)
! 992: return;
! 993: if (v & 0x4000)
! 994: dskdmaen = 3;
! 995: #ifdef DISK_DEBUG
! 996: {
! 997: int dr;
! 998: for (dr = 0; dr < 4; dr++) {
! 999: drive *drv = &floppy[dr];
! 1000: if (drv->motoroff)
! 1001: continue;
! 1002: if ((selected & (1 << dr)) == 0)
! 1003: break;
! 1004: }
! 1005: if (dr == 4)
! 1006: write_log ("disk DMA started, but no drive ready!\n");
! 1007: else
! 1008: write_log ("disk %s DMA started for %d words (%08.8X) sync=%04.4X track %d\n",
! 1009: dskdmaen == 3 ? "write" : "read", dsklength, dskpt,
! 1010: (adkcon & 0x400) ? dsksync : 0xffff,
! 1011: floppy[dr].cyl * 2 + side);
! 1012: }
! 1013: #endif
! 1014: /* Megalomania does not work if DSKLEN write is delayed to next horizontal line,
! 1015: also it seems some copy protections require this fix */
! 1016: DISK_start ();
1.1.1.6 root 1017:
1.1.1.7 ! root 1018: /* Try to make floppy access from Kickstart faster. */
! 1019: if (dskdmaen != 2)
! 1020: return;
! 1021: {
! 1022: int dr;
! 1023: uaecptr pc = m68k_getpc ();
! 1024: if ((pc & 0xF80000) != 0xF80000)
! 1025: return;
! 1026: for (dr = 0; dr < 4; dr++) {
! 1027: drive *drv = &floppy[dr];
! 1028: if (drv->motoroff)
! 1029: continue;
! 1030: if ((selected & (1 << dr)) == 0) {
! 1031: int pos = drv->mfmpos & ~15;
! 1032: int i;
! 1033:
! 1034: if (adkcon & 0x400) {
! 1035: for (i = 0; i < drv->tracklen; i += 16) {
! 1036: pos += 16;
! 1037: pos %= drv->tracklen;
! 1038: if (drv->bigmfmbuf[pos >> 4] == dsksync)
! 1039: break;
! 1040: }
! 1041: if (i >= drv->tracklen)
! 1042: return;
! 1043: }
! 1044: while (dsklength-- > 0) {
! 1045: put_word (dskpt, drv->bigmfmbuf[pos >> 4]);
! 1046: dskpt += 2;
! 1047: pos += 16;
! 1048: pos %= drv->tracklen;
1.1.1.6 root 1049: }
1.1.1.7 ! root 1050: INTREQ (0x9000);
! 1051: linecounter = 2;
! 1052: dskdmaen = 0;
! 1053: return;
1.1.1.6 root 1054: }
1055: }
1.1.1.7 ! root 1056: }
1.1.1.6 root 1057: }
1058:
1.1.1.7 ! root 1059: /* this unoptimized code should be enough (DSKBYTR and DSKDATR are used very rarely) */
! 1060:
! 1061: uae_u16 DSKBYTR (int hpos)
1.1.1.6 root 1062: {
1.1.1.7 ! root 1063: uae_u16 v;
! 1064: int i;
! 1065:
! 1066: i = 0;
! 1067: while (hpos > dskbytr_cycle[i])
! 1068: i++;
! 1069: v = dskbytr_tab[i];
! 1070: if (indexsync_last_cycle >= 0 && indexsync_last_cycle <= hpos)
! 1071: v |= 0x1000;
! 1072: dskbytr_tab[i] &= ~0x8000;
! 1073: if (dskdmaen && (dmacon & 0x210) == 0x210)
! 1074: v |= 0x4000;
! 1075: if (dskdmaen == 3)
! 1076: v |= 0x2000;
! 1077: return v;
! 1078: }
! 1079:
! 1080: uae_u16 DSKDATR (int hpos)
! 1081: {
! 1082: int i;
! 1083:
! 1084: i = 0;
! 1085: while (hpos > dskdatr_cycle[i])
! 1086: i++;
! 1087: return dskdatr_tab[i];
! 1088: }
! 1089:
! 1090: void DSKSYNC (uae_u16 v)
! 1091: {
! 1092: dsksync = v;
! 1093: }
! 1094:
! 1095: void DSKDAT (uae_u16 v)
! 1096: {
! 1097: static int count = 0;
! 1098: if (count < 5) {
! 1099: count++;
! 1100: write_log ("DSKDAT written. Not good.");
! 1101: if (count == 5)
! 1102: write_log ("(further messages suppressed)");
! 1103:
! 1104: write_log ("\n");
1.1.1.6 root 1105: }
1106: }
1.1.1.7 ! root 1107: void DSKPTH (uae_u16 v)
! 1108: {
! 1109: dskpt = (dskpt & 0xffff) | ((uae_u32) v << 16);
! 1110: }
1.1.1.6 root 1111:
1.1.1.7 ! root 1112: void DSKPTL (uae_u16 v)
1.1.1.6 root 1113: {
1.1.1.7 ! root 1114: dskpt = (dskpt & ~0xffff) | (v);
1.1.1.6 root 1115: }
1116:
1.1.1.7 ! root 1117: void DISK_init (void)
! 1118: {
! 1119: int i;
! 1120:
! 1121: dma_tab[0] = 0xffffffff;
! 1122: dskbytr_cycle[0] = 255;
! 1123: dskdatr_cycle[0] = 255;
! 1124: indexsync_last_cycle = -1;
! 1125:
! 1126: for (i = 0; i < 4; i++)
! 1127: if (!drive_insert (floppy + i, i, currprefs.df[i]))
! 1128: disk_eject (i);
! 1129:
! 1130: if (disk_empty (0))
! 1131: write_log ("No disk in drive 0.\n");
! 1132: }
! 1133:
! 1134: void dumpdisk (void)
! 1135: {
! 1136: int i;
! 1137: for (i = 0; i < 4; i++) {
! 1138: drive *drv = &floppy[i];
! 1139: printf ("Drive %d: motor %s cylinder %2d selected %d\n", i, drv->motoroff ? "off" : " on", drv->cyl, selected & (1 << i));
! 1140: }
! 1141: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.