--- uae/src/disk.c 2018/04/24 16:44:41 1.1.1.5 +++ uae/src/disk.c 2018/04/24 16:48:34 1.1.1.6 @@ -30,7 +30,7 @@ #define FLOPPY_GAP_LEN 360 -#define FLOPPY_SPEED 4 +#define FLOPPY_SPEED 50 uae_u16* mfmwrite; static uae_u16 mfmwrbuffer[16384]; /* space for maximum disk DMA transfer */ @@ -58,6 +58,7 @@ typedef struct { int motoroff; int wrprot; uae_u16 bigmfmbuf[0x4000]; + int mfmbufpos; int tracklen; unsigned long last_cycles; int mfmpos; @@ -98,9 +99,10 @@ static int drive_insert (drive *drv, int unsigned char buffer[10]; drv->diskfile = DISK_validate_filename (fname, 1, &drv->wrprot); - if (drv->diskfile == 0) + if (drv->diskfile == 0) { + drv->tracklen = 2000; return 0; - + } strncpy (currprefs.df[dnum], fname, 255); currprefs.df[dnum][255] = 0; strncpy (changed_prefs.df[dnum], fname, 255); @@ -148,6 +150,7 @@ static int drive_insert (drive *drv, int } } drv->buffered_side = 2; /* will force read */ + drive_fill_bigbuf (drv); return 1; } @@ -209,7 +212,7 @@ static void drive_fill_bigbuf(drive *drv int tr = drv->cyl*2 + side; if (!drv->diskfile) { - drv->tracklen = 10; + drv->tracklen = 2000; memset (drv->bigmfmbuf,0xaa,drv->tracklen*2); return; } @@ -224,7 +227,7 @@ static void drive_fill_bigbuf(drive *drv /* Normal AmigaDOS format track */ unsigned int sec; drv->tracklen = drv->num_secs*544 + FLOPPY_GAP_LEN; - memset(drv->bigmfmbuf,0xaa,FLOPPY_GAP_LEN*2); + memset (drv->bigmfmbuf,0xaa,FLOPPY_GAP_LEN*2); for (sec = 0; sec < drv->num_secs; sec++) { uae_u8 secbuf[544]; @@ -262,7 +265,7 @@ static void drive_fill_bigbuf(drive *drv mfmbuf[7] = deven; for (i = 8; i < 48; i++) - mfmbuf[i] = 0; + mfmbuf[i] = 0xaaaa; for (i = 0; i < 512; i += 4){ deven = ((secbuf[i+32] << 24) | (secbuf[i+33] << 16) | (secbuf[i+34] << 8) | (secbuf[i+35])); @@ -307,21 +310,55 @@ static void drive_fill_bigbuf(drive *drv drv->mfmpos = 0; } -static int drive_get_data (drive *drv, uae_u16 *mfm, uae_u16 *byt) +/* Perform DMA for the time interval since the last call. */ +static int drive_update_reads (drive *drv, uaecptr *ptr, int *length, int *syncfound, int sync) { - int offset,mfmpos; + unsigned long maxbytes = (cycles - drv->last_cycles) * 2 / FLOPPY_SPEED; + unsigned long maxcount = maxbytes >> 1; + drv->last_cycles += maxcount * FLOPPY_SPEED; drive_fill_bigbuf(drv); - offset = (cycles - drv->last_cycles) / FLOPPY_SPEED; - mfmpos = (drv->mfmpos + offset) % drv->tracklen; - drv->last_cycles += offset*FLOPPY_SPEED; - drv->mfmpos = mfmpos; - *mfm = drv->bigmfmbuf[mfmpos]; - return offset > 0; + + if (! ptr) { + if (! drv->motoroff) + drv->mfmpos += maxcount; + drv->mfmpos %= drv->tracklen; + } else { + while (maxcount-- > 0 && *length > 0) { + unsigned int word; + if (drv->mfmpos > drv->tracklen) { + write_log ("Bug in disk code - mfmpos too large\n"); + drv->mfmpos = 0; + } + word = drv->bigmfmbuf[drv->mfmpos]; + if (*syncfound) { + put_word (*ptr, word); + (*ptr) += 2; + (*length)--; + } + if (word == sync) + *syncfound = 1; + if (! drv->motoroff) + drv->mfmpos++; + if (drv->mfmpos > drv->tracklen) + drv->mfmpos = 0; + } + } + return ! drv->motoroff && maxbytes >= 1; +} + +/* We assume that drive_update_reads has already been called. */ +static void drive_get_data (drive *drv, uae_u16 *mfm, uae_u16 *byt) +{ + *mfm = drv->bigmfmbuf[drv->mfmpos]; + if (cycles - drv->last_cycles > (FLOPPY_SPEED / 2)) + *byt = *mfm & 0xff; + else + *byt = (*mfm >> 8) & 0xff; } #define MFMMASK 0x55555555 -static __inline__ uae_u32 getmfmlong (uae_u16* mbuf) +STATIC_INLINE uae_u32 getmfmlong (uae_u16* mbuf) { return ((*mbuf << 16) | *(mbuf + 1)) & MFMMASK; } @@ -552,20 +589,17 @@ uae_u8 DISK_status (void) return st; } -int DISK_GetData (uae_u16 *mfm, uae_u16 *byt) +void DISK_GetData (uae_u16 *mfm, uae_u16 *byt) { int dr; for (dr = 0; dr < 4; dr++){ if (!(selected & (1<mfmpos; + unsigned long missing = FLOPPY_SPEED - (cycles - drv->last_cycles); + unsigned long count = 0; + if (missing == 0) { + write_log ("bug in disk code: missing == 0\n"); + return; + } + + while (missing < cycle_limit) { + count += missing; + cycle_limit -= missing; + missing = FLOPPY_SPEED; + if (drv->bigmfmbuf[offs] == sync) { + eventtab[ev_disksync].active = 1; + eventtab[ev_disksync].oldcycles = cycles; + eventtab[ev_disksync].evtime = cycles + count; + events_schedule (); + } + offs++; + } + } + } +} + +/* Called when DMA gets restarted, so that we don't do DMA for the + parts of the track that went past us while DMA was off. */ +void DISK_reset_cycles (void) +{ + int dr; + for (dr = 0; dr < 4; dr++) { + drive *drv = floppy + dr; + unsigned long count = (cycles - drv->last_cycles) / FLOPPY_SPEED; + drv->mfmpos += count; + drv->mfmpos %= drv->tracklen; + drv->last_cycles += count * FLOPPY_SPEED; + } +} + +void DISK_StartRead () +{ + DISK_reset_cycles (); +} +