gui_led (num + LED_DF0, (gid->drive_motor ? 1 : 0) | (gid->drive_writing ? 2 : 0), -1);
}
-static void drive_fill_bigbuf (drive * drv,int);
+static void drive_fill_bigbuf(drive *drv, int, int);
void DISK_get_path_text(struct uae_prefs *p, int n, TCHAR *text)
{
drive_settype_id(drv); /* Set DD or HD drive */
update_drive_gui(drv->drvnum, false);
update_disk_statusline(drv->drvnum);
- drive_fill_bigbuf(drv, fake ? -1 : 1);
+ drive_fill_bigbuf(drv, side, fake ? -1 : 1);
return 1;
#endif
}
openwritefile(p, drv, 0);
drive_settype_id(drv); /* Set DD or HD drive */
- drive_fill_bigbuf(drv, 1);
+ drive_fill_bigbuf(drv, side, 1);
drv->mfmpos = uaerand();
drv->mfmpos |= uaerand() << 16;
drv->mfmpos &= 0xffffff;
return dest;
}
-static void decode_pcdos (drive *drv)
+static void decode_pcdos (drive *drv, int tside)
{
int i, len;
- int tr = drv->cyl * 2 + side;
+ int tr = drv->cyl * 2 + tside;
uae_u16 *dstmfmbuf, *mfm2;
uae_u8 secbuf[1000];
uae_u16 crc16;
write_log (_T("pcdos read track %d\n"), tr);
}
-static void decode_amigados (drive *drv)
+static void decode_amigados(drive *drv, int tside)
{
/* Normal AmigaDOS format track */
- int tr = drv->cyl * 2 + side;
+ int tr = drv->cyl * 2 + tside;
int sec;
int dstmfmoffset = 0;
uae_u16 *dstmfmbuf = drv->bigmfmbuf;
*
*/
-static void decode_diskspare (drive *drv)
+static void decode_diskspare(drive *drv, int tside)
{
- int tr = drv->cyl * 2 + side;
+ int tr = drv->cyl * 2 + tside;
int sec;
int dstmfmoffset = 0;
int size = 512 + 8;
write_log (_T("diskspare read track %d\n"), tr);
}
-static void drive_fill_bigbuf (drive * drv, int force)
+static void drive_fill_bigbuf(drive *drv, int tside, int force)
{
- int tr = drv->cyl * 2 + side;
+ int tr = drv->cyl * 2 + tside;
trackid *ti = drv->trackdata + tr;
bool retrytrack;
int rev = -1;
return;
}
- if (!force && drv->buffered_cyl == drv->cyl && drv->buffered_side == side)
+ if (!force && drv->buffered_cyl == drv->cyl && drv->buffered_side == tside)
return;
drv->indexoffset = 0;
drv->multi_revolution = 0;
drv->tracktiming[0] = 0;
drv->skipoffset = -1;
drv->revolutions = 1;
- retrytrack = drv->lastdataacesstrack == drv->cyl * 2 + side;
+ retrytrack = drv->lastdataacesstrack == drv->cyl * 2 + tside;
if (!dskdmaen && !retrytrack)
drv->track_access_done = false;
- //write_log (_T("%d:%d %d\n"), drv->cyl, side, retrytrack);
+ //write_log (_T("%d:%d %d\n"), drv->cyl, tside, retrytrack);
if (drv->writediskfile && drv->writetrackdata[tr].bitlen > 0) {
int i;
if (drv->bridge) {
drv->multi_revolution = 1;
drv->skipoffset = -1;
- drv->bridge->setSurface(side); // force the correct disk side to be selected
+ drv->bridge->setSurface(tside); // force the correct disk side to be selected
drv->tracklen = drv->bridge->maxMFMBitPosition();
drv->tracktiming[0] = drv->bridge->getMFMSpeed(drv->mfmpos % drv->tracklen);
if (force < 0) {
#ifdef CATWEASEL
drv->tracklen = 0;
if (!catweasel_disk_changed (drv->catweasel)) {
- drv->tracklen = catweasel_fillmfm (drv->catweasel, drv->bigmfmbuf, side, drv->ddhd, 0);
+ drv->tracklen = catweasel_fillmfm (drv->catweasel, drv->bigmfmbuf, tside, drv->ddhd, 0);
}
drv->buffered_cyl = -1;
if (!drv->tracklen) {
} else if (ti->type == TRACK_PCDOS) {
- decode_pcdos(drv);
+ decode_pcdos(drv, tside);
} else if (ti->type == TRACK_AMIGADOS) {
- decode_amigados(drv);
+ decode_amigados(drv, tside);
} else if (ti->type == TRACK_DISKSPARE) {
- decode_diskspare(drv);
+ decode_diskspare(drv, tside);
} else if (ti->type == TRACK_NONE) {
if (disk_debug_logging > 2)
write_log (_T("rawtrack %d image offset=%x\n"), tr, ti->offs);
}
- drv->buffered_side = side;
+ drv->buffered_side = tside;
drv->buffered_cyl = drv->cyl;
if (drv->tracklen == 0) {
drv->tracklen = FLOPPY_WRITE_LEN * drv->ddhd * 2 * 8;
#ifdef RETROPLATFORM
rp_disk_image_change(drv->drvnum, name, false);
#endif
- drive_fill_bigbuf(drv, 1);
+ drive_fill_bigbuf(drv, side, 1);
return true;
}
dsklength, dsklength, (adkcon & 0x400) ? dsksync : 0xffff, dskpt, adkcon, intreq, M68K_GETPC);
}
+// fake raw read for draco
+uae_u16 DSKBYTR_fake(int num)
+{
+ drive *drv = &floppy[num];
+ uae_u16 ret;
+ uae_u16 ac = adkcon;
+
+ adkcon |= 0x100;
+ int mfmpos = drv->mfmpos;
+ bool isempty = drive_empty(drv);
+ bool isunformatted = unformatted(drv);
+ int inc = 1;
+ int fword = 0;
+ for (int i = 0; i < 8; i++) {
+ fword <<= 1;
+ if (!isempty) {
+ if (isunformatted)
+ fword |= (uaerand() & 0x1000) ? 1 : 0;
+ else
+ fword |= getonebit(drv, drv->bigmfmbuf, mfmpos, &inc);
+ }
+ mfmpos += inc;
+ mfmpos %= drv->tracklen;
+ }
+ drv->mfmpos = mfmpos;
+ ret = 0x8000 | (fword & 0xff);
+ adkcon = ac;
+ return ret;
+}
+
/* this is very unoptimized. DSKBYTR is used very rarely, so it should not matter. */
uae_u16 DSKBYTR(int hpos)
#ifdef CATWEASEL
if (drv->catweasel) {
word = 0;
- drive_fill_bigbuf (drv, 1);
+ drive_fill_bigbuf (drv, side, 1);
}
#endif
#ifdef FLOPPYBRIDGE
if (drv->bridge && dskdmaen != DSKDMA_WRITE) {
word = 0;
- drive_fill_bigbuf(drv, 1);
+ drive_fill_bigbuf(drv, side, 1);
}
#endif
}
continue;
}
if (drv->diskfile) {
- drive_fill_bigbuf(drv, 0);
+ drive_fill_bigbuf(drv, side, 0);
}
#ifdef FLOPPYBRIDGE
if (drv->bridge) {
- drive_fill_bigbuf(drv, 0);
+ drive_fill_bigbuf(drv, side, 0);
}
#endif
drv->mfmpos %= drv->tracklen;
continue;
pos = drv->mfmpos & ~15;
- drive_fill_bigbuf (drv, 0);
+ drive_fill_bigbuf (drv, side, 0);
if (dskdmaen == DSKDMA_READ) { /* TURBO read */
drv->cyl = cyl;
side = dside;
drv->buffered_cyl = -1;
- drive_fill_bigbuf (drv, -1);
+ drive_fill_bigbuf (drv, side, -1);
decode_buffer (drv, drv->bigmfmbuf, drv->cyl, 11, drv->ddhd, drv->filetype, &drvsec, sectable, 1);
drv->cyl = oldcyl;
side = oldside;
drv->cyl = cyl;
drv->state = motor != 0;
update_drive_gui(i, false);
+ drive_fill_bigbuf(drv, head, 0);
+ // for some reason draco does not like it if data read starts from beginning of gap
+ drv->mfmpos = 8 * 16;
+ while ((drv->bigmfmbuf[drv->mfmpos / 16] == 0xaaaa || drv->bigmfmbuf[drv->mfmpos / 16] == 0x5555) && drv->mfmpos < 2048 && drv->mfmpos < drv->tracklen / 4) {
+ drv->mfmpos += 16;
+ }
}
}
if (z) {
bool ok = false;
drv->num_secs = 21; // max possible
- drive_fill_bigbuf(drv, true);
+ drive_fill_bigbuf(drv, side, true);
int secs = drive_write_pcdos(drv, z, 1);
if (secs >= 8) {
ok = true;
for (int i = 0; i < drv->num_tracks; i++) {
drv->cyl = i / 2;
side = i & 1;
- drive_fill_bigbuf(drv, true);
+ drive_fill_bigbuf(drv, side, true);
drive_write_pcdos(drv, z, 0);
}
}
int cyl;
uae_u8 sector;
uae_u8 head;
+ bool disk_changed;
};
static struct pc_floppy floppy_pc[4];
static void do_floppy_seek(int num, int error)
{
- struct pc_floppy *pcf = &floppy_pc[floppy_num];
+ struct pc_floppy *pcf = &floppy_pc[num];
disk_reserved_reset_disk_change(num);
if (!error) {
struct floppy_reserved fr = { 0 };
- bool valid_floppy = disk_reserved_getinfo(floppy_num, &fr);
+ bool valid_floppy = disk_reserved_getinfo(num, &fr);
if (floppy_seekcyl[num] != pcf->phys_cyl) {
+
+ if (!valid_floppy || !fr.img) {
+ error = 1;
+ goto done;
+ }
+
+ pcf->disk_changed = false;
+
if (floppy_seekcyl[num] > pcf->phys_cyl)
pcf->phys_cyl++;
else if (pcf->phys_cyl > 0)
driveclick_click(fr.num, pcf->phys_cyl);
#endif
#if FLOPPY_DEBUG
- write_log(_T("Floppy%d seeking.. %d\n"), floppy_num, pcf->phys_cyl);
+ write_log(_T("Floppy%d seeking.. %d\n"), num, pcf->phys_cyl);
#endif
if (pcf->phys_cyl - pcf->seek_offset <= 0) {
pcf->phys_cyl = 0;
if (pcf->seek_offset) {
floppy_seekcyl[num] = 0;
#if FLOPPY_DEBUG
- write_log(_T("Floppy%d early track zero\n"), floppy_num);
+ write_log(_T("Floppy%d early track zero\n"), num);
#endif
pcf->seek_offset = 0;
}
pcf->cyl = pcf->phys_cyl;
floppy_seeking[num] = PC_SEEK_DELAY;
- disk_reserved_setinfo(floppy_num, pcf->cyl, pcf->head, 1);
+ disk_reserved_setinfo(num, pcf->cyl, pcf->head, 1);
return;
}
done:
#if FLOPPY_DEBUG
- write_log(_T("Floppy%d seek done err=%d. pcyl=%d cyl=%d h=%d\n"), floppy_num, error, pcf->phys_cyl,pcf->cyl, pcf->head);
+ write_log(_T("Floppy%d seek done err=%d. pcyl=%d cyl=%d h=%d\n"), num, error, pcf->phys_cyl,pcf->cyl, pcf->head);
#endif
floppy_status[0] = 0;
floppy_status[0] |= 0x20; // seek end
return -1;
}
+static void floppy_clear_irq(void)
+{
+ if (floppy_irq) {
+ x86_clearirq(6);
+ floppy_irq = false;
+ }
+}
+
+static bool floppy_valid_format(struct floppy_reserved *fr)
+{
+ if (fr->secs == 11 || fr->secs == 22)
+ return false;
+ return true;
+}
+
static bool floppy_valid_rate(struct floppy_reserved *fr)
{
struct x86_bridge *xb = bridges[0];
// 0xc0 status after reset.
floppy_status[0] = 0xc0;
}
- x86_clearirq(6);
- floppy_irq = false;
+ floppy_clear_irq();
floppy_result[0] = floppy_status[0];
floppy_result[1] = pcf->phys_cyl;
floppy_status[0] = 0;
while (!end && !fr.wrprot) {
int len = 128 << floppy_cmd[5];
uae_u8 buf[512] = { 0 };
- for (int i = 0; i < 512 && i < len; i++) {
- int v = dma_channel_read(2);
- if (v < 0) {
- end = -1;
- break;
- }
- buf[i] = v;
- if (v >= 0x10000) {
- end = 1;
- break;
+ if (floppy_specify_pio) {
+ end = -1;
+ } else {
+ for (int i = 0; i < 512 && i < len; i++) {
+ int v = dma_channel_read(2);
+ if (v < 0) {
+ end = -1;
+ break;
+ }
+ buf[i] = v;
+ if (v >= 0x10000) {
+ end = 1;
+ break;
+ }
}
}
#if FLOPPY_DEBUG
int cyl = pcf->cyl;
bool nodata = false;
if (valid_floppy) {
- if (!floppy_valid_rate(&fr)) {
+ if (!floppy_valid_rate(&fr) || !floppy_valid_format(&fr)) {
nodata = true;
} else if (pcf->head && fr.heads == 1) {
nodata = true;
#if FLOPPY_DEBUG
write_log(_T("Floppy read ID\n"));
#endif
- if (!valid_floppy || !fr.img || !floppy_valid_rate(&fr) || (pcf->head && fr.heads == 1)) {
+ if (!valid_floppy || !fr.img || !floppy_valid_rate(&fr) || (pcf->head && fr.heads == 1) || !floppy_valid_format(&fr)) {
floppy_status[0] |= 0x40; // abnormal termination
floppy_status[1] |= 0x04; // no data
}
static void outfloppy(struct x86_bridge *xb, int portnum, uae_u8 v)
{
+#if FLOPPY_IO_DEBUG
+ write_log(_T("out floppy port %04x %02x\n"), portnum, v);
+#endif
+
switch (portnum)
{
case 0x3f2: // dpc
}
#endif
floppy_dpc = v;
- if (xb->type < 0 && 1) {
+ if (xb->type < 0) {
floppy_dpc |= 8;
}
floppy_num = v & 3;
for (int i = 0; i < 2; i++) {
- disk_reserved_setinfo(0, floppy_pc[i].cyl, floppy_pc[i].head, floppy_selected() == i);
+ disk_reserved_setinfo(i, floppy_pc[i].cyl, floppy_pc[i].head, floppy_selected() == i);
}
break;
case 0x3f5: // data reg
write_log(_T("Unknown FDC %04x write %02x\n"), portnum, v);
break;
}
-#if FLOPPY_IO_DEBUG
- write_log(_T("out floppy port %04x %02x\n"), portnum, v);
-#endif
}
static uae_u8 infloppy(struct x86_bridge *xb, int portnum)
v = floppy_pio_buffer[floppy_pio_cnt++];
if (floppy_pio_cnt >= floppy_pio_len) {
floppy_pio_len = 0;
+ floppy_clear_irq();
+ floppy_delay_hsync = 50;
}
} else if (floppy_cmd_len && floppy_dir) {
int idx = (-floppy_idx) - 1;
floppy_cmd_len = 0;
floppy_dir = 0;
floppy_idx = 0;
+ floppy_clear_irq();
}
}
}
break;
case 0x3f7: // digital input register
- if (xb->type >= TYPE_2286) {
+ if (xb->type >= TYPE_2286 || xb->type < 0) {
+ struct pc_floppy *pcf = &floppy_pc[floppy_num];
struct floppy_reserved fr = { 0 };
bool valid_floppy = disk_reserved_getinfo(floppy_num, &fr);
v = 0x00;
- if (valid_floppy && fr.disk_changed)
- v = 0x80;
- } else if (xb->type < 0) {
- struct floppy_reserved fr = { 0 };
- bool valid_floppy = disk_reserved_getinfo(floppy_num, &fr);
- v = 0x00;
- if (fr.disk_changed)
+ if (valid_floppy && fr.disk_changed && (floppy_dpc >> 4) & (1 << floppy_num)) {
+ pcf->disk_changed = true;
+ }
+ if (pcf->disk_changed) {
v = 0x80;
+ }
}
break;
default:
return v;
}
+uae_u16 floppy_get_raw_data(void)
+{
+ struct floppy_reserved fr = { 0 };
+ bool valid_floppy = disk_reserved_getinfo(floppy_num, &fr);
+ if (valid_floppy) {
+ return DSKBYTR_fake(fr.num);
+ }
+ return 0x8000;
+}
+
static void set_cpu_turbo(struct x86_bridge *xb)
{
cpu_multiplier = (int)currprefs.x86_speed_throttle;