Annotation of uae/src/disk.c, revision 1.1.1.4

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.3   root       33: #define FLOPPY_SPEED 4
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       root       61:     int tracklen;
                     62:     unsigned long last_cycles;
                     63:     int mfmpos;
1.1.1.2   root       64:     unsigned int num_tracks, num_secs;
1.1.1.3   root       65:     /* dskchange is set to a small number when a disk is removed. At a step
                     66:      * impulse, it is reset if there is a new disk in the drive or counted
                     67:      * down to 1 if the drive contains a disk. DISK_check_change will only
                     68:      * insert a new disk when dskchange is 1, or if the dskchange_time timer
                     69:      * expires. The last condition can happen if AmigaOS isn't running and a
                     70:      * game/demo doesn't use the step motor to check for a new disk.
                     71:      */
                     72:     int dskchange;
                     73:     int dskchange_time;
1.1       root       74: } drive;
                     75: 
                     76: drive floppy[4];
                     77: 
1.1.1.4 ! root       78: static void drive_fill_bigbuf (drive *drv);
1.1       root       79: 
1.1.1.3   root       80: FILE *DISK_validate_filename (const char *fname, int leave_open, int *wrprot)
1.1       root       81: {
1.1.1.4 ! root       82:     FILE *f = zfile_open (fname, "r+b");
1.1.1.3   root       83:     if (f) {
                     84:        if (wrprot)
                     85:            *wrprot = 0;
1.1       root       86:     } else {
1.1.1.3   root       87:        if (wrprot)
                     88:            *wrprot = 1;
1.1.1.4 ! root       89:        f = zfile_open (fname, "rb");
1.1       root       90:     }
1.1.1.3   root       91:     if (!leave_open)
1.1.1.4 ! root       92:        zfile_close (f);
1.1.1.3   root       93:     return f;
                     94: }
                     95: 
1.1.1.4 ! root       96: static int drive_insert (drive *drv, int dnum, const char *fname)
1.1.1.3   root       97: {
                     98:     unsigned char buffer[10];
                     99: 
                    100:     drv->diskfile = DISK_validate_filename (fname, 1, &drv->wrprot);
                    101:     if (drv->diskfile == 0)
                    102:        return 0;
                    103: 
                    104:     strncpy (currprefs.df[dnum], fname, 255);
                    105:     currprefs.df[dnum][255] = 0;
                    106:     strncpy (changed_prefs.df[dnum], fname, 255);
                    107:     changed_prefs.df[dnum][255] = 0;
1.1       root      108:     gui_filename(dnum, fname);
1.1.1.3   root      109: 
1.1.1.4 ! root      110:     fread (buffer, sizeof(char), 8, drv->diskfile);
1.1.1.3   root      111:     if (strncmp((char *)buffer,"UAE--ADF",8) == 0) {
1.1       root      112:        int offs = 160*4+8;
                    113:        int i;
1.1.1.3   root      114: 
                    115:        drv->filetype = ADF_EXT1;
1.1.1.2   root      116:        drv->num_tracks = 160;
                    117:        drv->num_secs = 11;
1.1.1.3   root      118: 
1.1       root      119:        drv->wrprot = 1; /* write to adf_ext1 not implemented */
                    120:        for(i=0; i<160; i++) {
                    121:            fread(buffer, 4, 1, drv->diskfile);
                    122:            drv->trackdata[i].sync = buffer[0]*256 + buffer[1];
                    123:            drv->trackdata[i].len = buffer[2]*256 + buffer[3];
                    124:            drv->trackdata[i].offs = offs;
                    125:            offs += drv->trackdata[i].len;
                    126:        }
                    127:     } else {
1.1.1.2   root      128:        unsigned int i;
1.1.1.3   root      129: 
                    130:        drv->filetype = ADF_NORMAL;
1.1.1.2   root      131: 
1.1.1.4 ! root      132:        fseek (drv->diskfile,0,SEEK_END);
        !           133:        i = ftell (drv->diskfile);
        !           134:        fseek (drv->diskfile,0,SEEK_SET);
1.1.1.3   root      135: 
1.1.1.2   root      136:        /* High-density disk? */
                    137:        if (i >= 160*22*512)
                    138:            drv->num_tracks = i / (512*(drv->num_secs = 22));
                    139:        else
                    140:            drv->num_tracks = i / (512*(drv->num_secs = 11));
1.1.1.3   root      141: 
1.1.1.2   root      142:        if (drv->num_tracks > MAX_TRACKS)
1.1.1.3   root      143:            write_log ("Your diskfile is too big!\n");
1.1.1.2   root      144:        for(i = 0; i < drv->num_tracks; i++) {
                    145:            drv->trackdata[i].len = 512 * drv->num_secs;
1.1       root      146:            drv->trackdata[i].sync = 0;
1.1.1.2   root      147:            drv->trackdata[i].offs = i * 512 * drv->num_secs;
1.1       root      148:        }
                    149:     }
1.1.1.3   root      150:     drv->buffered_side = 2; /* will force read */
                    151:     return 1;
1.1       root      152: }
                    153: 
1.1.1.4 ! root      154: static int drive_empty (drive *drv)
1.1.1.2   root      155: {
1.1.1.3   root      156:     return drv->diskfile == 0;
1.1.1.2   root      157: }
                    158: 
1.1.1.4 ! root      159: static void drive_step (drive *drv)
1.1       root      160: {
1.1.1.3   root      161:     if (!drive_empty(drv))
                    162:        drv->dskchange = 0;
                    163:     else if (drv->dskchange > 1) {
                    164: /*     printf("Stepping...\n");
                    165:        drv->dskchange--;*/
                    166:     }
1.1       root      167:     if (direction) {
1.1.1.3   root      168:        if (drv->cyl) drv->cyl--;
1.1       root      169:     } else {
1.1.1.3   root      170:        if (drv->cyl < drv->num_tracks/2) drv->cyl++;
1.1       root      171:     }
                    172: }
                    173: 
                    174: 
1.1.1.4 ! root      175: static int drive_track0 (drive *drv)
1.1       root      176: {
1.1.1.3   root      177:     return drv->cyl == 0;
1.1       root      178: }
                    179: 
1.1.1.4 ! root      180: static int drive_writeprotected (drive *drv)
1.1       root      181: {
1.1.1.3   root      182:     return drv->wrprot || drv->diskfile == NULL;
1.1       root      183: }
                    184: 
1.1.1.4 ! root      185: static int drive_running (drive *drv)
1.1       root      186: {
1.1.1.3   root      187:     return !drv->motoroff;
1.1       root      188: }
                    189: 
1.1.1.4 ! root      190: static void drive_motor (drive *drv, int off)
1.1       root      191: {
                    192:     if (drv->motoroff && !off) {
                    193:        drv->last_cycles = cycles;
                    194:        drv->mfmpos = 0;
                    195:        eventtab[ev_diskindex].active = 1;
                    196:        if (drv->tracklen)
                    197:            eventtab[ev_diskindex].evtime = FLOPPY_SPEED * drv->tracklen + cycles;
                    198:        else
                    199:            eventtab[ev_diskindex].evtime = cycles + 1000;
                    200:        eventtab[ev_diskindex].oldcycles = cycles;
                    201:     } else if (off)
                    202:        eventtab[ev_diskindex].active = 0;
                    203:     drv->motoroff = off;
1.1.1.4 ! root      204:     events_schedule ();
1.1       root      205: }
                    206: 
                    207: static void drive_fill_bigbuf(drive *drv)
                    208: {
1.1.1.3   root      209:     int tr = drv->cyl*2 + side;
                    210: 
1.1.1.2   root      211:     if (!drv->diskfile) {
                    212:        drv->tracklen = 10;
                    213:        memset (drv->bigmfmbuf,0xaa,drv->tracklen*2);
                    214:        return;
                    215:     }
1.1.1.3   root      216:     if (drv->buffered_cyl == drv->cyl && drv->buffered_side == side)
                    217:        return;
                    218: 
                    219: /*    if (drv->num_tracks <= tr) {
                    220:        write_log ("Access beyond end of floppy image!\n");
                    221:     }*/
1.1       root      222:     
                    223:     if (drv->trackdata[tr].sync == 0) {
                    224:        /* Normal AmigaDOS format track */
1.1.1.2   root      225:        unsigned int sec;
                    226:        drv->tracklen = drv->num_secs*544 + FLOPPY_GAP_LEN;
                    227:        memset(drv->bigmfmbuf,0xaa,FLOPPY_GAP_LEN*2);
                    228: 
                    229:        for (sec = 0; sec < drv->num_secs; sec++) {
1.1.1.3   root      230:            uae_u8 secbuf[544];
1.1       root      231:            int i;
1.1.1.3   root      232:            uae_u16 *mfmbuf = drv->bigmfmbuf + 544*sec + FLOPPY_GAP_LEN;
                    233:            uae_u32 deven,dodd;
                    234:            uae_u32 hck=0,dck=0;
                    235: 
1.1       root      236:            secbuf[0] = secbuf[1] = 0x00;
                    237:            secbuf[2] = secbuf[3] = 0xa1;
                    238:            secbuf[4] = 0xff;
                    239:            secbuf[5] = tr;
                    240:            secbuf[6] = sec;
1.1.1.2   root      241:            secbuf[7] = drv->num_secs-sec;
1.1       root      242: 
                    243:            for(i = 8; i < 24; i++)
                    244:                secbuf[i] = 0;
1.1.1.3   root      245: 
1.1.1.4 ! root      246:            fseek (drv->diskfile,
        !           247:                   drv->trackdata[tr].offs + sec*512,
        !           248:                   SEEK_SET);
        !           249:            fread (&secbuf[32],1,512,drv->diskfile);
1.1.1.3   root      250: 
1.1       root      251:            mfmbuf[0] = mfmbuf[1] = 0xaaaa;
                    252:            mfmbuf[2] = mfmbuf[3] = 0x4489;
1.1.1.3   root      253: 
                    254:            deven = ((secbuf[4] << 24) | (secbuf[5] << 16)
1.1       root      255:                     | (secbuf[6] << 8) | (secbuf[7]));
                    256:            dodd = deven >> 1;
                    257:            deven &= 0x55555555; dodd &= 0x55555555;
1.1.1.3   root      258: 
1.1       root      259:            mfmbuf[4] = dodd >> 16;
                    260:            mfmbuf[5] = dodd;
1.1.1.3   root      261:            mfmbuf[6] = deven>> 16;
1.1       root      262:            mfmbuf[7] = deven;
1.1.1.3   root      263: 
1.1       root      264:            for (i = 8; i < 48; i++)
                    265:                mfmbuf[i] = 0;
                    266:            for (i = 0; i < 512; i += 4){
                    267:                deven = ((secbuf[i+32] << 24) | (secbuf[i+33] << 16)
                    268:                         | (secbuf[i+34] << 8) | (secbuf[i+35]));
                    269:                dodd = deven >> 1;
                    270:                deven &= 0x55555555; dodd &= 0x55555555;
1.1.1.4 ! root      271:                mfmbuf[(i>>1) + 32] = dodd >> 16;
        !           272:                mfmbuf[(i>>1) + 33] = dodd;
        !           273:                mfmbuf[(i>>1) + 256 + 32] = deven >> 16;
        !           274:                mfmbuf[(i>>1) + 256 + 33] = deven;
1.1       root      275:            }
1.1.1.3   root      276: 
1.1       root      277:            for(i = 4; i < 24; i += 2)
                    278:                hck ^= (mfmbuf[i] << 16) | mfmbuf[i+1];
1.1.1.3   root      279: 
1.1       root      280:            deven = dodd = hck; dodd >>= 1;
                    281:            mfmbuf[24] = dodd >> 16; mfmbuf[25] = dodd;
1.1.1.4 ! root      282:            mfmbuf[26] = deven >> 16; mfmbuf[27] = deven;
1.1.1.3   root      283: 
1.1       root      284:            for(i = 32; i < 544; i += 2)
                    285:                dck ^= (mfmbuf[i] << 16) | mfmbuf[i+1];
1.1.1.3   root      286: 
1.1       root      287:            deven = dodd = dck; dodd >>= 1;
                    288:            mfmbuf[28] = dodd >> 16; mfmbuf[29] = dodd;
1.1.1.4 ! root      289:            mfmbuf[30] = deven >> 16; mfmbuf[31] = deven;
1.1       root      290:        }
                    291:     } else {
                    292:        int i;
                    293:        drv->tracklen = drv->trackdata[tr].len/2 + 1;
                    294:        drv->bigmfmbuf[0] = drv->trackdata[tr].sync;
                    295:        fseek(drv->diskfile, drv->trackdata[tr].offs, SEEK_SET);
1.1.1.3   root      296:        fread((char *)(drv->bigmfmbuf + 1), 1, drv->trackdata[tr].len, drv->diskfile);
1.1       root      297:        for (i = 0; i < drv->trackdata[tr].len/2; i++) {
1.1.1.3   root      298:            uae_u16 *mfm = drv->bigmfmbuf + i + 1;
                    299:            uae_u8 *data = (uae_u8 *)mfm;
                    300: 
1.1       root      301:            *mfm = 256 * *data + *(data+1);
                    302:        }
                    303:     }
1.1.1.3   root      304:     drv->buffered_side = side;
                    305:     drv->buffered_cyl = drv->cyl;
1.1       root      306:     drv->last_cycles = cycles;
                    307:     drv->mfmpos = 0;
                    308: }
                    309: 
1.1.1.4 ! root      310: static int drive_get_data (drive *drv, uae_u16 *mfm, uae_u16 *byt)
1.1       root      311: {
                    312:     int offset,mfmpos;
1.1.1.3   root      313: 
                    314:     drive_fill_bigbuf(drv);
1.1       root      315:     offset = (cycles - drv->last_cycles) / FLOPPY_SPEED;
                    316:     mfmpos = (drv->mfmpos + offset) % drv->tracklen;
                    317:     drv->last_cycles += offset*FLOPPY_SPEED;
                    318:     drv->mfmpos = mfmpos;
                    319:     *mfm = drv->bigmfmbuf[mfmpos];
                    320:     return offset > 0;
                    321: }
                    322: 
                    323: #define MFMMASK 0x55555555
1.1.1.4 ! root      324: static __inline__ uae_u32 getmfmlong (uae_u16* mbuf)
1.1       root      325: {
                    326:     return ((*mbuf << 16) | *(mbuf + 1)) & MFMMASK;
                    327: }
                    328: 
1.1.1.4 ! root      329: static void drive_write_data (drive *drv, uae_u16 *mbuf, int length)
1.1       root      330: {
                    331:     int i, secwritten = 0;
1.1.1.3   root      332:     uae_u32 odd, even, chksum, id, dlong;
                    333:     uae_u8* secdata;
                    334:     uae_u8 secbuf[544];
                    335:     uae_u16 *mend = mbuf + length;
                    336: 
1.1.1.4 ! root      337:     if (drive_writeprotected (drv))
1.1.1.3   root      338:        return;
                    339: 
1.1.1.4 ! root      340:     drive_fill_bigbuf (drv);
1.1       root      341:     mend -= (4 + 16 + 8 + 512);
                    342:     while (length > 0) {
                    343:        int trackoffs;
1.1.1.3   root      344: 
1.1       root      345:        do {
                    346:            while (*mbuf++ != 0x4489) {
1.1.1.4 ! root      347:                if (mbuf >= mend)
        !           348:                    return;
1.1       root      349:            }
                    350:        } while (*mbuf++ != 0x4489);
1.1.1.3   root      351: 
1.1.1.4 ! root      352:        odd = getmfmlong (mbuf);
        !           353:        even = getmfmlong (mbuf + 2);
1.1.1.3   root      354:        mbuf += 4;
1.1       root      355:        id = (odd << 1) | even;
1.1.1.3   root      356: 
1.1       root      357:        trackoffs = (id & 0xff00) >> 8;
                    358:        if (trackoffs > 10) {
1.1.1.4 ! root      359:            printf ("Disk write: weird sector number %d\n", trackoffs);
1.1       root      360:            continue;
                    361:        }
                    362:        chksum = odd ^ even;
1.1.1.4 ! root      363:        for (i = 0; i < 4; i++) {
1.1       root      364:            odd = getmfmlong(mbuf);
                    365:            even = getmfmlong(mbuf+8);
                    366:            mbuf += 2;
1.1.1.3   root      367: 
1.1       root      368:            dlong = (odd << 1) | even;
1.1.1.4 ! root      369:            if (dlong)
        !           370:                secwritten = -200;
1.1       root      371:            chksum ^= odd ^ even;
                    372:        }  /* could check here if the label is nonstandard */
                    373:        mbuf += 8;
1.1.1.4 ! root      374:        odd = getmfmlong (mbuf); even = getmfmlong (mbuf+2); mbuf += 4;
        !           375:        if (((odd << 1) | even) != chksum
        !           376:            || ((id & 0x00ff0000) >> 16) != drv->cyl*2 + side)
        !           377:        {
1.1.1.3   root      378:            write_log ("Disk write: checksum error on sector header\n");
1.1       root      379:            continue;
                    380:        }
                    381:        odd = getmfmlong(mbuf); even = getmfmlong(mbuf+2); mbuf += 4;
                    382:        chksum = (odd << 1) | even;
                    383:        secdata = secbuf + 32;
                    384:        for (i=0; i<128; i++) {
                    385:            odd = getmfmlong(mbuf); even = getmfmlong(mbuf+256); mbuf += 2;
                    386:            dlong = (odd << 1) | even;
                    387:            *secdata++ = dlong >> 24; *secdata++ = (dlong >> 16) & 0xff;
                    388:            *secdata++ = dlong >> 8; *secdata++ = dlong;
                    389:            chksum ^= odd ^ even;
                    390:        }
                    391:        mbuf += 256;
                    392:        if (chksum) {
1.1.1.3   root      393:            write_log ("Disk write: data checksum error\n");
1.1       root      394:            continue;
                    395:        }
                    396:        secwritten++;
1.1.1.4 ! root      397:        fseek (drv->diskfile,
        !           398:               drv->trackdata[drv->cyl*2 + side].offs + trackoffs*512,
        !           399:               SEEK_SET);
        !           400:        fwrite (secbuf+32, sizeof (uae_u8), 512, drv->diskfile);
1.1       root      401:     }
1.1.1.3   root      402:     drv->buffered_side = 2; /* will force read */
                    403: 
                    404:     if (secwritten == 0)
                    405:        write_log ("Disk write in unsupported format\n");
1.1       root      406:     if (secwritten < 0)
1.1.1.3   root      407:        write_log ("Disk write: sector labels ignored\n");
1.1       root      408: }
                    409: 
                    410: 
1.1.1.4 ! root      411: static void drive_eject (drive *drv)
1.1       root      412: {
1.1.1.4 ! root      413:     if (! drive_empty (drv))
        !           414:        zfile_close (drv->diskfile);
1.1.1.3   root      415: 
                    416:     drv->dskchange = 4;
                    417:     drv->dskchange_time = 20;
                    418: /*    printf("setting changed bit %d\n", drv-floppy);*/
1.1       root      419:     drv->diskfile = 0;
                    420: }
                    421: 
1.1.1.3   root      422: /* We use this function if we have no Kickstart ROM.
1.1       root      423:  * No error checking - we trust our luck. */
1.1.1.3   root      424: void DISK_ersatz_read (int tr, int sec, uaecptr dest)
1.1       root      425: {
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: 
1.1.1.4 ! root      431: void disk_eject (int num)
1.1       root      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.4 ! root      438: void disk_insert (int num, const char *name)
1.1       root      439: {
                    440:     /* just to be sure */
1.1.1.4 ! root      441:     drive_eject (floppy + num);
        !           442:     drive_insert (floppy + num, num, name);
1.1       root      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.1.4 ! root      471: int disk_empty (int num)
1.1       root      472: {
1.1.1.4 ! root      473:     return drive_empty (floppy + num);
1.1       root      474: }
                    475: 
1.1.1.4 ! root      476: void DISK_init (void)
1.1       root      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.4 ! 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))) {
1.1.1.4 ! root      506:                    drive_step (floppy + dr);
1.1       root      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.4 ! root      527: uae_u8 DISK_status (void)
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.4 ! 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.4 ! 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.4 ! 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.4 ! 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: 
1.1.1.4 ! root      629: void DISK_InitWrite (void)
1.1       root      630: {
                    631:     mfmwrite = mfmwrbuffer;
                    632: }
                    633: 
1.1.1.4 ! root      634: void DISK_WriteData (int length)
1.1       root      635: {
                    636:     int dr;
1.1.1.4 ! root      637:     for (dr = 0; dr < 4; dr++){
1.1       root      638:        if (!(selected & (1<<dr))) {
                    639:            drive_write_data(floppy + dr, mfmwrbuffer, length);
                    640:        }
                    641:     }
                    642: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.