86F format handler updated to 86F version 2.0 and bit by bit handling;

FDI stream images are now also handled by the 86F handler;
Both floppy drives' motors now spin separately;
Added Plantronics ColorPlus emulation per patch from PCem forum;
Applied all mainline PCem commits;
Fixed several bugs.
This commit is contained in:
OBattler
2016-11-02 22:39:07 +01:00
parent 9a4e044d91
commit e280faa2d6
87 changed files with 16087 additions and 5675 deletions

136
src/fdc.c
View File

@@ -12,10 +12,25 @@
#include "pic.h"
#include "timer.h"
extern int64_t motoron;
extern int64_t motoron[2];
int ui_writeprot[2] = {0, 0};
int command_has_drivesel[256] = { [0x02] = 1, /* READ TRACK */
[0x04] = 1, /* SENSE DRIVE STATUS */
[0x05] = 1, /* WRITE DATA */
[0x06] = 1, /* READ DATA */
[0x07] = 1, /* RECALIBRATE */
[0x09] = 1, /* WRITE DELETED DATA */
[0x0A] = 1, /* READ ID */
[0x0C] = 1, /* READ DELETED DATA */
[0x0D] = 1, /* FORMAT TRACK */
[0x0F] = 1, /* SEEK, RELATIVE SEEK */
[0x11] = 1, /* SCAN EQUAL */
[0x16] = 1, /* VERIFY */
[0x19] = 1, /* SCAN LOW OR EQUAL */
[0x1D] = 1 }; /* SCAN HIGH OR EQUAL */
static int fdc_reset_stat = 0;
/*FDC*/
typedef struct FDC
@@ -239,7 +254,6 @@ int fdc_get_format_sectors()
void fdc_reset_fifo_buf()
{
int i = 0;
memset(fdc.fifobuf, 0, 16);
fdc.fifobufpos = 0;
}
@@ -346,7 +360,6 @@ void fdc_update_enh_mode(int enh_mode)
int fdc_get_rwc(int drive)
{
return fdc.rwc[drive];
fdc_rate(drive);
}
void fdc_update_rwc(int drive, int rwc)
@@ -525,8 +538,6 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
// pclog("Write FDC %04X %02X %04X:%04X %i %02X %i rate=%i %i\n",addr,val,cs>>4,pc,ins,fdc.st0,ins,fdc.rate, fdc.data_ready);
int drive;
int seek_time;
int temp_drive;
int temp_motoron;
switch (addr&7)
{
@@ -551,8 +562,12 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
discint=-1;
fdc_reset();
}
motoron = val & 0x01;
fdc.drive = 0;
if (!fdd_get_flags(0))
{
val &= 0xfe;
}
motoron[0] = val & 0x01;
// fdc.drive = 0;
/* if (motoron)
output = 3;
else
@@ -577,25 +592,17 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
timer_process();
timer_update_outstanding();
val &= 0x3f; /* Drives 2 and 3 are not emulated, so their motors are always forced off. */
temp_drive = val & 3;
temp_motoron = 0x10 << temp_drive;
temp_motoron = val & temp_motoron;
motoron = 0;
if (temp_motoron && (temp_drive <= 1))
/* We can now simplify this since each motor now spins separately. */
if (!fdd_get_flags(0 ^ fdd_swap))
{
/* Selected drive is drive 0 or 1 and has motor on bit set too, change drive selection. */
fdc.drive = temp_drive;
disc_drivesel = fdc.drive;
disc_set_drivesel(fdc.drive);
motoron = (val & 0xf0) ? 1 : 0;
val &= 0x3f;
val &= 0x2f;
}
else
if (!fdd_get_flags(1 ^ fdd_swap))
{
/* Selected drive is either drive 2 or 3 or has motor on bit clear, turn off the motor. */
motoron = 0;
val &= 0x0f;
val &= 0x1f;
}
motoron[0] = (val & 0x10);
motoron[1] = (val & 0x20);
}
fdc.dor=val;
// printf("DOR now %02X\n",val);
@@ -809,22 +816,15 @@ bad_command:
timer_process();
disctime = 1024 * (1 << TIMER_SHIFT);
timer_update_outstanding();
// fdc.drive = fdc.params[0] & 3;
if (command_has_drivesel[discint & 0x1F])
{
fdc.drive = fdc.params[0] & 3;
}
fdc_reset_stat = 0;
if (fdc.dor & (0x10 << fdc.drive))
{
motoron = 0;
disc_drivesel = fdc.drive;
disc_set_drivesel(fdc.drive);
motoron = 1;
}
else
{
motoron = 0;
}
switch (discint & 0x1F)
{
case 2: /*Read a track*/
fdc_reset_fifo_buf();
fdc_rate(fdc.drive);
fdc.head=fdc.params[2];
fdd_set_head(fdc.drive, (fdc.params[0] & 4) ? 1 : 0);
@@ -877,6 +877,7 @@ bad_command:
case 5: /*Write data*/
case 9: /*Write deleted data*/
fdc_reset_fifo_buf();
fdc_rate(fdc.drive);
fdc.head=fdc.params[2];
fdd_set_head(fdc.drive, (fdc.params[0] & 4) ? 1 : 0);
@@ -900,12 +901,24 @@ bad_command:
fdc.pos = 0;
if (fdc.pcjr)
fdc.stat = 0xb0;
else
{
if (fdc.dma)
{
fdc.stat = 0x90;
}
else
{
fdc.stat = 0xb0;
}
}
// ioc_fiq(IOC_FIQ_DISC_DATA);
break;
case 0x11: /*Scan equal*/
case 0x19: /*Scan low or equal*/
case 0x1D: /*Scan high or equal*/
fdc_reset_fifo_buf();
fdc_rate(fdc.drive);
fdc.head=fdc.params[2];
fdd_set_head(fdc.drive, (fdc.params[0] & 4) ? 1 : 0);
@@ -929,6 +942,17 @@ bad_command:
fdc.pos = 0;
if (fdc.pcjr)
fdc.stat = 0xb0;
else
{
if (fdc.dma)
{
fdc.stat = 0x90;
}
else
{
fdc.stat = 0xb0;
}
}
// ioc_fiq(IOC_FIQ_DISC_DATA);
break;
@@ -936,6 +960,7 @@ bad_command:
if (fdc.params[0] & 0x80) fdc.sc = fdc.params[7];
case 6: /*Read data*/
case 0xC: /*Read deleted data*/
fdc_reset_fifo_buf();
fdc_rate(fdc.drive);
fdc.head=fdc.params[2];
fdd_set_head(fdc.drive, (fdc.params[0] & 4) ? 1 : 0);
@@ -1176,7 +1201,7 @@ void fdc_poll_readwrite_finish(int compare)
fdc.res[6] |= 0x40;
fdc.wrong_am = 0;
}
if (compare)
if (compare == 1)
{
if (!fdc.satisfying_sectors)
{
@@ -1187,6 +1212,18 @@ void fdc_poll_readwrite_finish(int compare)
fdc.res[6] |= 8;
}
}
else if (compare == 2)
{
if (fdc.satisfying_sectors & 1)
{
fdc.res[5] |= 0x20;
}
if (fdc.satisfying_sectors & 2)
{
fdc.res[5] |= 0x20;
fdc.res[6] |= 0x20;
}
}
fdc.res[7]=fdc.rw_track;
fdc.res[8]=fdc.head;
fdc.res[9]=fdc.sector;
@@ -1208,7 +1245,7 @@ void fdc_no_dma_end(int compare)
fdc.res[6] |= 0x40;
fdc.wrong_am = 0;
}
if (compare)
if (compare == 1)
{
if (!fdc.satisfying_sectors)
{
@@ -1219,6 +1256,18 @@ void fdc_no_dma_end(int compare)
fdc.res[6] |= 8;
}
}
else if (compare == 2)
{
if (fdc.satisfying_sectors & 1)
{
fdc.res[5] |= 0x20;
}
if (fdc.satisfying_sectors & 2)
{
fdc.res[5] |= 0x20;
fdc.res[6] |= 0x20;
}
}
fdc.res[7]=fdc.rw_track;
fdc.res[8]=fdc.head;
fdc.res[9]=fdc.sector;
@@ -1259,7 +1308,7 @@ void fdc_callback()
// pclog("Read a track callback, eot=%i\n", fdc.eot[fdc.drive]);
if (!fdc.eot[fdc.drive] || fdc.tc)
{
fdc_poll_readwrite_finish(0);
fdc_poll_readwrite_finish(2);
return;
}
else
@@ -1587,6 +1636,11 @@ void fdc_overrun()
paramstogo=7;
}
int fdc_is_verify()
{
return (fdc.deleted & 2) ? 1 : 0;
}
int fdc_data(uint8_t data)
{
if (fdc.deleted & 2)
@@ -1665,6 +1719,14 @@ void fdc_finishread()
// rpclog("fdc_finishread\n");
}
void fdc_track_finishread(int condition)
{
fdc.satisfying_sectors |= condition;
fdc.inread = 0;
fdc_callback();
// rpclog("fdc_finishread\n");
}
void fdc_sector_finishcompare(int satisfying)
{
fdc.satisfying_sectors++;