Better implementation of FDC 'not found' errors - can now distinguish missing
address mark (eg disc not present or track not formatted), sector not found, wrong cylinder and bad cylinder.
This commit is contained in:
parent
2e3444697f
commit
38f19f7c9f
6 changed files with 106 additions and 26 deletions
|
|
@ -143,7 +143,7 @@ void disc_poll()
|
||||||
{
|
{
|
||||||
disc_notfound--;
|
disc_notfound--;
|
||||||
if (!disc_notfound)
|
if (!disc_notfound)
|
||||||
fdc_notfound();
|
fdc_notfound(FDC_STATUS_AM_NOT_FOUND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ void fdc_callback();
|
||||||
int fdc_data(uint8_t dat);
|
int fdc_data(uint8_t dat);
|
||||||
void fdc_spindown();
|
void fdc_spindown();
|
||||||
void fdc_finishread();
|
void fdc_finishread();
|
||||||
void fdc_notfound();
|
void fdc_notfound(int reason);
|
||||||
void fdc_datacrcerror();
|
void fdc_datacrcerror();
|
||||||
void fdc_headercrcerror();
|
void fdc_headercrcerror();
|
||||||
void fdc_writeprotect();
|
void fdc_writeprotect();
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
#include "disc.h"
|
#include "disc.h"
|
||||||
#include "disc_fdi.h"
|
#include "disc_fdi.h"
|
||||||
|
#include "fdc.h"
|
||||||
#include "fdi2raw.h"
|
#include "fdi2raw.h"
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
|
|
@ -314,7 +315,7 @@ void fdi_poll()
|
||||||
if (fdi_revs == 3)
|
if (fdi_revs == 3)
|
||||||
{
|
{
|
||||||
// pclog("Not found!\n");
|
// pclog("Not found!\n");
|
||||||
fdc_notfound();
|
fdc_notfound(FDC_STATUS_NOT_FOUND);
|
||||||
fdi_inread = fdi_inreadaddr = 0;
|
fdi_inread = fdi_inreadaddr = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,8 @@ static uint8_t disc_sector_fill;
|
||||||
static int cur_sector, cur_byte;
|
static int cur_sector, cur_byte;
|
||||||
static int index_count;
|
static int index_count;
|
||||||
|
|
||||||
|
static int disc_sector_status;
|
||||||
|
|
||||||
void disc_sector_reset(int drive, int side)
|
void disc_sector_reset(int drive, int side)
|
||||||
{
|
{
|
||||||
disc_sector_count[drive][side] = 0;
|
disc_sector_count[drive][side] = 0;
|
||||||
|
|
@ -90,6 +92,8 @@ void disc_sector_readsector(int drive, int sector, int track, int side, int rate
|
||||||
disc_sector_sector = sector;
|
disc_sector_sector = sector;
|
||||||
disc_sector_n = sector_size;
|
disc_sector_n = sector_size;
|
||||||
index_count = 0;
|
index_count = 0;
|
||||||
|
|
||||||
|
disc_sector_status = FDC_STATUS_AM_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
void disc_sector_writesector(int drive, int sector, int track, int side, int rate, int sector_size)
|
void disc_sector_writesector(int drive, int sector, int track, int side, int rate, int sector_size)
|
||||||
|
|
@ -103,6 +107,8 @@ void disc_sector_writesector(int drive, int sector, int track, int side, int rat
|
||||||
disc_sector_sector = sector;
|
disc_sector_sector = sector;
|
||||||
disc_sector_n = sector_size;
|
disc_sector_n = sector_size;
|
||||||
index_count = 0;
|
index_count = 0;
|
||||||
|
|
||||||
|
disc_sector_status = FDC_STATUS_AM_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
void disc_sector_readaddress(int drive, int track, int side, int rate)
|
void disc_sector_readaddress(int drive, int track, int side, int rate)
|
||||||
|
|
@ -114,6 +120,8 @@ void disc_sector_readaddress(int drive, int track, int side, int rate)
|
||||||
disc_sector_side = side;
|
disc_sector_side = side;
|
||||||
disc_sector_drive = drive;
|
disc_sector_drive = drive;
|
||||||
index_count = 0;
|
index_count = 0;
|
||||||
|
|
||||||
|
disc_sector_status = FDC_STATUS_AM_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
void disc_sector_format(int drive, int track, int side, int rate, uint8_t fill)
|
void disc_sector_format(int drive, int track, int side, int rate, uint8_t fill)
|
||||||
|
|
@ -179,7 +187,7 @@ void disc_sector_poll()
|
||||||
if (index_count > 1)
|
if (index_count > 1)
|
||||||
{
|
{
|
||||||
// pclog("Find sector not found\n");
|
// pclog("Find sector not found\n");
|
||||||
fdc_notfound();
|
fdc_notfound(disc_sector_status);
|
||||||
disc_sector_state = STATE_IDLE;
|
disc_sector_state = STATE_IDLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -187,10 +195,11 @@ void disc_sector_poll()
|
||||||
disc_sector_side != s->h,
|
disc_sector_side != s->h,
|
||||||
disc_sector_sector != s->r,
|
disc_sector_sector != s->r,
|
||||||
fdc_get_bitcell_period() != get_bitcell_period());*/
|
fdc_get_bitcell_period() != get_bitcell_period());*/
|
||||||
if (cur_byte || disc_sector_track != s->c ||
|
if (!cur_byte && fdc_get_bitcell_period() == get_bitcell_period() &&
|
||||||
disc_sector_side != s->h ||
|
fdd_can_read_medium(disc_sector_drive ^ fdd_swap))
|
||||||
disc_sector_sector != s->r ||
|
disc_sector_status = FDC_STATUS_NOT_FOUND; /*Disc readable, assume address marker found*/
|
||||||
disc_sector_n != s->n ||
|
|
||||||
|
if (cur_byte ||
|
||||||
fdc_get_bitcell_period() != get_bitcell_period() ||
|
fdc_get_bitcell_period() != get_bitcell_period() ||
|
||||||
!fdd_can_read_medium(disc_sector_drive ^ fdd_swap) ||
|
!fdd_can_read_medium(disc_sector_drive ^ fdd_swap) ||
|
||||||
disc_intersector_delay)
|
disc_intersector_delay)
|
||||||
|
|
@ -198,6 +207,16 @@ void disc_sector_poll()
|
||||||
advance_byte();
|
advance_byte();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (disc_sector_track != s->c ||
|
||||||
|
disc_sector_side != s->h ||
|
||||||
|
disc_sector_sector != s->r ||
|
||||||
|
disc_sector_n != s->n)
|
||||||
|
{
|
||||||
|
if (disc_sector_track != s->c)
|
||||||
|
disc_sector_status = (disc_sector_track == 0xff) ? FDC_STATUS_BAD_CYLINDER : FDC_STATUS_WRONG_CYLINDER;
|
||||||
|
advance_byte();
|
||||||
|
break;
|
||||||
|
}
|
||||||
disc_sector_state = STATE_READ_SECTOR;
|
disc_sector_state = STATE_READ_SECTOR;
|
||||||
case STATE_READ_SECTOR:
|
case STATE_READ_SECTOR:
|
||||||
// pclog("STATE_READ_SECTOR: cur_byte=%i %i\n", cur_byte, disc_intersector_delay);
|
// pclog("STATE_READ_SECTOR: cur_byte=%i %i\n", cur_byte, disc_intersector_delay);
|
||||||
|
|
@ -218,10 +237,14 @@ void disc_sector_poll()
|
||||||
if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap)))
|
if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap)))
|
||||||
{
|
{
|
||||||
// pclog("Medium is of a density not supported by the drive\n");
|
// pclog("Medium is of a density not supported by the drive\n");
|
||||||
fdc_notfound();
|
fdc_notfound(FDC_STATUS_AM_NOT_FOUND);
|
||||||
disc_sector_state = STATE_IDLE;
|
disc_sector_state = STATE_IDLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (!cur_byte && fdc_get_bitcell_period() == get_bitcell_period() &&
|
||||||
|
fdd_can_read_medium(disc_sector_drive ^ fdd_swap))
|
||||||
|
disc_sector_status = FDC_STATUS_NOT_FOUND; /*Disc readable, assume address marker found*/
|
||||||
|
|
||||||
if (cur_byte || !index_count || fdc_get_bitcell_period() != get_bitcell_period() ||
|
if (cur_byte || !index_count || fdc_get_bitcell_period() != get_bitcell_period() ||
|
||||||
disc_intersector_delay)
|
disc_intersector_delay)
|
||||||
{
|
{
|
||||||
|
|
@ -244,14 +267,14 @@ void disc_sector_poll()
|
||||||
if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap)))
|
if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap)))
|
||||||
{
|
{
|
||||||
// pclog("Medium is of a density not supported by the drive\n");
|
// pclog("Medium is of a density not supported by the drive\n");
|
||||||
fdc_notfound();
|
fdc_notfound(FDC_STATUS_AM_NOT_FOUND);
|
||||||
disc_sector_state = STATE_IDLE;
|
disc_sector_state = STATE_IDLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (index_count)
|
if (index_count)
|
||||||
{
|
{
|
||||||
// pclog("Find next sector hit end of track\n");
|
// pclog("Find next sector hit end of track\n");
|
||||||
fdc_notfound();
|
fdc_notfound(disc_sector_status);
|
||||||
disc_sector_state = STATE_IDLE;
|
disc_sector_state = STATE_IDLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -277,10 +300,15 @@ void disc_sector_poll()
|
||||||
if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap)))
|
if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap)))
|
||||||
{
|
{
|
||||||
// pclog("Medium is of a density not supported by the drive\n");
|
// pclog("Medium is of a density not supported by the drive\n");
|
||||||
fdc_notfound();
|
fdc_notfound(FDC_STATUS_AM_NOT_FOUND);
|
||||||
disc_sector_state = STATE_IDLE;
|
disc_sector_state = STATE_IDLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!cur_byte && fdc_get_bitcell_period() == get_bitcell_period() &&
|
||||||
|
fdd_can_read_medium(disc_sector_drive ^ fdd_swap))
|
||||||
|
disc_sector_status = FDC_STATUS_NOT_FOUND; /*Disc readable, assume address marker found*/
|
||||||
|
|
||||||
if (writeprot[disc_sector_drive])
|
if (writeprot[disc_sector_drive])
|
||||||
{
|
{
|
||||||
fdc_writeprotect();
|
fdc_writeprotect();
|
||||||
|
|
@ -290,20 +318,27 @@ void disc_sector_poll()
|
||||||
if (index_count > 1)
|
if (index_count > 1)
|
||||||
{
|
{
|
||||||
// pclog("Write find sector not found\n");
|
// pclog("Write find sector not found\n");
|
||||||
fdc_notfound();
|
fdc_notfound(disc_sector_status);
|
||||||
disc_sector_state = STATE_IDLE;
|
disc_sector_state = STATE_IDLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (cur_byte || disc_sector_track != s->c ||
|
if (cur_byte ||
|
||||||
disc_sector_side != s->h ||
|
|
||||||
disc_sector_sector != s->r ||
|
|
||||||
disc_sector_n != s->n ||
|
|
||||||
fdc_get_bitcell_period() != get_bitcell_period() ||
|
fdc_get_bitcell_period() != get_bitcell_period() ||
|
||||||
disc_intersector_delay)
|
disc_intersector_delay)
|
||||||
{
|
{
|
||||||
advance_byte();
|
advance_byte();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (disc_sector_track != s->c ||
|
||||||
|
disc_sector_side != s->h ||
|
||||||
|
disc_sector_sector != s->r ||
|
||||||
|
disc_sector_n != s->n)
|
||||||
|
{
|
||||||
|
if (disc_sector_track != s->c)
|
||||||
|
disc_sector_status = (disc_sector_track == 0xff) ? FDC_STATUS_BAD_CYLINDER : FDC_STATUS_WRONG_CYLINDER;
|
||||||
|
advance_byte();
|
||||||
|
break;
|
||||||
|
}
|
||||||
disc_sector_state = STATE_WRITE_SECTOR;
|
disc_sector_state = STATE_WRITE_SECTOR;
|
||||||
case STATE_WRITE_SECTOR:
|
case STATE_WRITE_SECTOR:
|
||||||
data = fdc_getdata(cur_byte == ((128 << s->n) - 1));
|
data = fdc_getdata(cur_byte == ((128 << s->n) - 1));
|
||||||
|
|
@ -323,14 +358,19 @@ void disc_sector_poll()
|
||||||
if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap)))
|
if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap)))
|
||||||
{
|
{
|
||||||
// pclog("Medium is of a density not supported by the drive\n");
|
// pclog("Medium is of a density not supported by the drive\n");
|
||||||
fdc_notfound();
|
fdc_notfound(FDC_STATUS_AM_NOT_FOUND);
|
||||||
disc_sector_state = STATE_IDLE;
|
disc_sector_state = STATE_IDLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!cur_byte && fdc_get_bitcell_period() == get_bitcell_period() &&
|
||||||
|
fdd_can_read_medium(disc_sector_drive ^ fdd_swap))
|
||||||
|
disc_sector_status = FDC_STATUS_NOT_FOUND; /*Disc readable, assume address marker found*/
|
||||||
|
|
||||||
if (index_count)
|
if (index_count)
|
||||||
{
|
{
|
||||||
// pclog("Find next sector hit end of track\n");
|
// pclog("Find next sector hit end of track\n");
|
||||||
fdc_notfound();
|
fdc_notfound(disc_sector_status);
|
||||||
disc_sector_state = STATE_IDLE;
|
disc_sector_state = STATE_IDLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -343,6 +383,7 @@ void disc_sector_poll()
|
||||||
disc_sector_state = STATE_READ_ADDRESS;
|
disc_sector_state = STATE_READ_ADDRESS;
|
||||||
case STATE_READ_ADDRESS:
|
case STATE_READ_ADDRESS:
|
||||||
fdc_sectorid(s->c, s->h, s->r, s->n, 0, 0);
|
fdc_sectorid(s->c, s->h, s->r, s->n, 0, 0);
|
||||||
|
advance_byte();
|
||||||
disc_sector_state = STATE_IDLE;
|
disc_sector_state = STATE_IDLE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -362,13 +403,13 @@ void disc_sector_poll()
|
||||||
if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap)))
|
if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap)))
|
||||||
{
|
{
|
||||||
// pclog("Medium is of a density not supported by the drive\n");
|
// pclog("Medium is of a density not supported by the drive\n");
|
||||||
fdc_notfound();
|
fdc_notfound(FDC_STATUS_NOT_FOUND);
|
||||||
disc_sector_state = STATE_IDLE;
|
disc_sector_state = STATE_IDLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (fdc_get_bitcell_period() != get_bitcell_period())
|
if (fdc_get_bitcell_period() != get_bitcell_period())
|
||||||
{
|
{
|
||||||
fdc_notfound();
|
fdc_notfound(FDC_STATUS_NOT_FOUND);
|
||||||
disc_sector_state = STATE_IDLE;
|
disc_sector_state = STATE_IDLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
36
src/fdc.c
36
src/fdc.c
|
|
@ -5,12 +5,23 @@
|
||||||
#include "disc.h"
|
#include "disc.h"
|
||||||
#include "disc_sector.h"
|
#include "disc_sector.h"
|
||||||
#include "dma.h"
|
#include "dma.h"
|
||||||
|
#include "fdc.h"
|
||||||
#include "fdd.h"
|
#include "fdd.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "pic.h"
|
#include "pic.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "x86.h"
|
#include "x86.h"
|
||||||
|
|
||||||
|
#define ST1_DE (1 << 5)
|
||||||
|
#define ST1_ND (1 << 2)
|
||||||
|
#define ST1_NW (1 << 1)
|
||||||
|
#define ST1_MA (1 << 0)
|
||||||
|
|
||||||
|
#define ST2_DD (1 << 5)
|
||||||
|
#define ST2_WC (1 << 4) /*Wrong cylinder*/
|
||||||
|
#define ST2_BC (1 << 1) /*Bad cylinder*/
|
||||||
|
#define ST2_MD (1 << 0)
|
||||||
|
|
||||||
static int fdc_reset_stat = 0;
|
static int fdc_reset_stat = 0;
|
||||||
/*FDC*/
|
/*FDC*/
|
||||||
typedef struct FDC
|
typedef struct FDC
|
||||||
|
|
@ -790,7 +801,6 @@ uint8_t fdc_read(uint16_t addr, void *priv)
|
||||||
void fdc_callback()
|
void fdc_callback()
|
||||||
{
|
{
|
||||||
int temp;
|
int temp;
|
||||||
int doseek = 0;
|
|
||||||
int drive;
|
int drive;
|
||||||
|
|
||||||
// pclog("fdc_callback %i\n", discint);
|
// pclog("fdc_callback %i\n", discint);
|
||||||
|
|
@ -1187,15 +1197,33 @@ void fdc_finishread()
|
||||||
// rpclog("fdc_finishread\n");
|
// rpclog("fdc_finishread\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void fdc_notfound()
|
void fdc_notfound(int reason)
|
||||||
{
|
{
|
||||||
|
// pclog("fdc_notfound: reason=%i\n", reason);
|
||||||
timer_disable(&fdc.timer);
|
timer_disable(&fdc.timer);
|
||||||
|
|
||||||
fdc_int();
|
fdc_int();
|
||||||
fdc.stat=0xD0;
|
fdc.stat=0xD0;
|
||||||
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
|
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
|
||||||
fdc.res[5]=5;
|
switch (reason)
|
||||||
fdc.res[6]=0;
|
{
|
||||||
|
case FDC_STATUS_AM_NOT_FOUND:
|
||||||
|
fdc.res[5] = ST1_ND | ST1_MA;
|
||||||
|
fdc.res[6] = 0;
|
||||||
|
break;
|
||||||
|
case FDC_STATUS_NOT_FOUND:
|
||||||
|
fdc.res[5] = ST1_ND;
|
||||||
|
fdc.res[6] = 0;
|
||||||
|
break;
|
||||||
|
case FDC_STATUS_WRONG_CYLINDER:
|
||||||
|
fdc.res[5] = ST1_ND;
|
||||||
|
fdc.res[6] = ST2_WC;
|
||||||
|
break;
|
||||||
|
case FDC_STATUS_BAD_CYLINDER:
|
||||||
|
fdc.res[5] = ST1_ND;
|
||||||
|
fdc.res[6] = ST2_WC | ST2_BC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
fdc.res[7] = fdc.rw_track;
|
fdc.res[7] = fdc.rw_track;
|
||||||
fdc.res[8] = fdc.head;
|
fdc.res[8] = fdc.head;
|
||||||
fdc.res[9] = fdc.sector;
|
fdc.res[9] = fdc.sector;
|
||||||
|
|
|
||||||
10
src/fdc.h
10
src/fdc.h
|
|
@ -24,3 +24,13 @@ void fdc_update_boot_drive(int boot_drive);
|
||||||
void fdc_update_densel_polarity(int densel_polarity);
|
void fdc_update_densel_polarity(int densel_polarity);
|
||||||
void fdc_update_densel_force(int densel_force);
|
void fdc_update_densel_force(int densel_force);
|
||||||
void fdc_update_drvrate(int drive, int drvrate);
|
void fdc_update_drvrate(int drive, int drvrate);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FDC_STATUS_AM_NOT_FOUND,
|
||||||
|
FDC_STATUS_NOT_FOUND,
|
||||||
|
FDC_STATUS_WRONG_CYLINDER,
|
||||||
|
FDC_STATUS_BAD_CYLINDER
|
||||||
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue