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

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: }

unix.superglobalmegacorp.com

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