Timer enable switches are 64-bit;

Floppy reads/writes now correctly finish at gaps;
Sector-based reads/writes no longer cause a delay when signaling finish.
This commit is contained in:
OBattler
2016-08-21 03:42:24 +02:00
parent a924f37f43
commit d860ea79ed
12 changed files with 111 additions and 62 deletions

View File

@@ -37,7 +37,7 @@ int drive_empty[2] = {1, 1};
int disc_changed[2]; int disc_changed[2];
int motorspin; int motorspin;
int motoron; int64_t motoron;
int fdc_indexcount = 52; int fdc_indexcount = 52;

View File

@@ -57,7 +57,7 @@ extern int fdc_ready;
extern int fdc_indexcount;*/ extern int fdc_indexcount;*/
extern int motorspin; extern int motorspin;
extern int motoron; extern int64_t motoron;
extern int swwp; extern int swwp;
extern int disable_write; extern int disable_write;

View File

@@ -319,11 +319,27 @@ int disc_sector_match(int drive)
temp = (disc_sector_track[drive] == last_sector[drive]->c); temp = (disc_sector_track[drive] == last_sector[drive]->c);
temp = temp && (disc_sector_side[drive] == last_sector[drive]->h); temp = temp && (disc_sector_side[drive] == last_sector[drive]->h);
temp = temp && (disc_sector_sector[drive] == last_sector[drive]->r); temp = temp && (disc_sector_sector[drive] == last_sector[drive]->r);
temp = temp && (disc_sector_n[drive] == last_sector[drive]->n);
return temp;
}
uint32_t disc_sector_get_data_len(int drive)
{
if (disc_sector_n[drive]) if (disc_sector_n[drive])
{ {
temp = temp && (disc_sector_n[drive] == last_sector[drive]->n); return (128 << ((uint32_t) disc_sector_n[drive]));
}
else
{
if (fdc_get_dtl() < 128)
{
return fdc_get_dtl();
}
else
{
return (128 << ((uint32_t) disc_sector_n[drive]));
}
} }
return temp;
} }
int disc_sector_can_read_address(int drive) int disc_sector_can_read_address(int drive)
@@ -365,7 +381,7 @@ int disc_sector_read_state(int drive)
return temp; return temp;
} }
int id_pos = 0; int section_pos[2] = {0, 0};
typedef union typedef union
{ {
@@ -385,6 +401,8 @@ void disc_sector_poll()
int b = 0; int b = 0;
int cur_id_pos = 0; int cur_id_pos = 0;
int cur_data_pos = 0;
int cur_gap3_pos = 0;
uint8_t track_byte = 0; uint8_t track_byte = 0;
uint8_t track_index = 0; uint8_t track_index = 0;
@@ -442,7 +460,7 @@ void disc_sector_poll()
// pclog("Index hole hit again, format finished\n"); // pclog("Index hole hit again, format finished\n");
disc_sector_state[drive] = STATE_IDLE; disc_sector_state[drive] = STATE_IDLE;
if (!disable_write) disc_sector_writeback[drive](drive, disc_sector_track[drive]); if (!disable_write) disc_sector_writeback[drive](drive, disc_sector_track[drive]);
fdc_finishread(drive); fdc_sector_finishread(drive);
} }
if ((disc_sector_state[drive] == STATE_FORMAT_FIND) && disc_sector_can_read_address(drive)) if ((disc_sector_state[drive] == STATE_FORMAT_FIND) && disc_sector_can_read_address(drive))
{ {
@@ -455,7 +473,7 @@ void disc_sector_poll()
{ {
case BYTE_ID_SYNC: case BYTE_ID_SYNC:
if (disc_sector_state[drive] != STATE_FORMAT) break; if (disc_sector_state[drive] != STATE_FORMAT) break;
cur_id_pos = cur_track_pos[drive] - id_pos; cur_id_pos = cur_track_pos[drive] - section_pos[drive];
if (cur_id_pos > 3) break; if (cur_id_pos > 3) break;
data = fdc_getdata(0); data = fdc_getdata(0);
if ((data == -1) && (cur_id_pos < 3)) if ((data == -1) && (cur_id_pos < 3))
@@ -477,6 +495,7 @@ void disc_sector_poll()
} }
break; break;
case BYTE_DATA: case BYTE_DATA:
cur_data_pos = cur_track_pos[drive] - section_pos[drive];
if (disc_sector_read_state(drive) && (last_sector[drive] != NULL)) if (disc_sector_read_state(drive) && (last_sector[drive] != NULL))
{ {
if (fdc_data(last_sector[drive]->data[data_counter[drive]])) if (fdc_data(last_sector[drive]->data[data_counter[drive]]))
@@ -492,7 +511,7 @@ void disc_sector_poll()
} }
if ((disc_sector_state[drive] == STATE_WRITE_SECTOR) && (last_sector[drive] != NULL)) if ((disc_sector_state[drive] == STATE_WRITE_SECTOR) && (last_sector[drive] != NULL))
{ {
data = fdc_getdata(cur_byte[drive] == ((128 << ((uint32_t) last_sector[drive]->n)) - 1)); data = fdc_getdata(data_counter[drive] == ((128 << ((uint32_t) last_sector[drive]->n)) - 1));
if (data == -1) if (data == -1)
{ {
/* Data failed to be sent from the FDC, abort. */ /* Data failed to be sent from the FDC, abort. */
@@ -517,23 +536,22 @@ void disc_sector_poll()
else else
{ {
data_counter[drive] %= (128 << ((uint32_t) last_sector[drive]->n)); data_counter[drive] %= (128 << ((uint32_t) last_sector[drive]->n));
if (!data_counter[drive]) }
break;
case BYTE_GAP3:
cur_gap3_pos = cur_track_pos[drive] - section_pos[drive];
if (cur_gap3_pos == (fdc_get_gap() - 1))
{ {
if (disc_sector_read_state(drive) && (last_sector[drive] != NULL)) if (disc_sector_read_state(drive) && (last_sector[drive] != NULL))
{ {
disc_sector_state[drive] = STATE_IDLE; disc_sector_state[drive] = STATE_IDLE;
fdc_finishread(drive); fdc_sector_finishread(drive);
} }
if ((disc_sector_state[drive] == STATE_WRITE_SECTOR) && (last_sector[drive] != NULL)) if ((disc_sector_state[drive] == STATE_WRITE_SECTOR) && (last_sector[drive] != NULL))
{ {
disc_sector_state[drive] = STATE_IDLE; disc_sector_state[drive] = STATE_IDLE;
if (!disable_write) disc_sector_writeback[drive](drive, disc_sector_track[drive]); if (!disable_write) disc_sector_writeback[drive](drive, disc_sector_track[drive]);
fdc_finishread(drive); fdc_sector_finishread(drive);
}
/* if (disc_sector_state[drive] == STATE_FORMAT && (last_sector[drive] != NULL))
{
// pclog("Format: Sector fill finished\n");
} */
} }
} }
break; break;
@@ -573,10 +591,10 @@ void disc_sector_poll()
if (track_byte != old_track_byte) if (track_byte != old_track_byte)
{ {
// if (disc_sector_state[drive] == STATE_FORMAT) pclog("Track byte: %02X, old: %02X\n", track_byte, old_track_byte); // if (disc_sector_state[drive] == STATE_FORMAT) pclog("Track byte: %02X, old: %02X\n", track_byte, old_track_byte);
section_pos[drive] = cur_track_pos[drive];
switch(track_byte) switch(track_byte)
{ {
case BYTE_ID_SYNC: case BYTE_ID_SYNC:
id_pos = cur_track_pos[drive];
if (disc_sector_state[drive] == STATE_FORMAT) if (disc_sector_state[drive] == STATE_FORMAT)
{ {
// pclog("Requesting next sector ID...\n"); // pclog("Requesting next sector ID...\n");
@@ -611,7 +629,7 @@ void disc_sector_poll()
} }
break; break;
case BYTE_DATA: case BYTE_DATA:
data_counter[drive] = 0; // data_counter[drive] = 0;
switch (disc_sector_state[drive]) switch (disc_sector_state[drive])
{ {
case STATE_READ_FIND_SECTOR: case STATE_READ_FIND_SECTOR:

View File

@@ -12,7 +12,7 @@
#include "pic.h" #include "pic.h"
#include "timer.h" #include "timer.h"
extern int motoron; extern int64_t motoron;
static int fdc_reset_stat = 0; static int fdc_reset_stat = 0;
/*FDC*/ /*FDC*/
@@ -101,6 +101,32 @@ void fdc_reset()
int ins; int ins;
int fdc_get_bitcell_period();
double fdc_get_hut()
{
int hut = (fdc.specify[0] & 0xF);
double dusec;
double bcp = ((double) fdc_get_bitcell_period()) / 250.0;
double dhut = (double) hut;
if (fdc_get_bitcell_period() == 3333) bcp = 160.0 / 6.0;
if (hut == 0) dhut = 16.0;
dusec = (double) TIMER_USEC;
return (bcp * dhut * dusec * 1000.0);
}
double fdc_get_hlt()
{
int hlt = (fdc.specify[1] >> 1);
double dusec;
double bcp = ((double) fdc_get_bitcell_period()) / 2000.0;
double dhlt = (double) hlt;
if (fdc_get_bitcell_period() == 3333) bcp = 20.0 / 6.0;
if (hlt == 0) dhlt = 256.0;
dusec = (double) TIMER_USEC;
return (bcp * dhlt * dusec * 1000.0);
}
void fdc_request_next_sector_id() void fdc_request_next_sector_id()
{ {
if (fdc.pcjr || !fdc.dma) if (fdc.pcjr || !fdc.dma)
@@ -619,7 +645,7 @@ bad_command:
disc_drivesel = fdc.drive & 1; disc_drivesel = fdc.drive & 1;
fdc_reset_stat = 0; fdc_reset_stat = 0;
disc_set_drivesel(fdc.drive & 1); disc_set_drivesel(fdc.drive & 1);
switch (discint) switch (discint & 0x1F)
{ {
case 2: /*Read a track*/ case 2: /*Read a track*/
fdc_rate(fdc.drive); fdc_rate(fdc.drive);
@@ -670,7 +696,6 @@ bad_command:
} }
} }
fdc.rw_track = fdc.params[1]; fdc.rw_track = fdc.params[1];
disc_writesector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]); disc_writesector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]);
disctime = 0; disctime = 0;
fdc.written = 0; fdc.written = 0;
@@ -678,7 +703,7 @@ bad_command:
fdc.pos = 0; fdc.pos = 0;
if (fdc.pcjr) if (fdc.pcjr)
fdc.stat = 0xb0; fdc.stat = 0xb0;
// ioc_fiq(IOC_FIQ_DISC_DATA); // ioc_fiq(IOC_FIQ_DISC_DATA);
break; break;
case 6: /*Read data*/ case 6: /*Read data*/
@@ -698,7 +723,6 @@ bad_command:
} }
} }
fdc.rw_track = fdc.params[1]; fdc.rw_track = fdc.params[1];
disc_readsector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]); disc_readsector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]);
disctime = 0; disctime = 0;
readflash = 1; readflash = 1;
@@ -1310,6 +1334,13 @@ void fdc_finishread()
// rpclog("fdc_finishread\n"); // rpclog("fdc_finishread\n");
} }
void fdc_sector_finishread()
{
fdc.inread = 0;
fdc_callback();
// rpclog("fdc_finishread\n");
}
void fdc_notfound() void fdc_notfound()
{ {
disctime = 0; disctime = 0;

View File

@@ -242,9 +242,9 @@ typedef struct PIT
int rereadlatch[3]; int rereadlatch[3];
int gate[3]; int gate[3];
int out[3]; int out[3];
int running[3]; int64_t running[3];
int enabled[3]; int64_t enabled[3];
int newcount[3]; int64_t newcount[3];
int count[3]; int count[3];
int using_timer[3]; int using_timer[3];
int initial[3]; int initial[3];

View File

@@ -16,7 +16,7 @@ typedef struct ad1848_t
int16_t out_l, out_r; int16_t out_l, out_r;
int enable; int64_t enable;
int irq, dma; int irq, dma;

View File

@@ -6,7 +6,7 @@ typedef struct opl_t
int chip_nr[2]; int chip_nr[2];
int64_t timers[2][2]; int64_t timers[2][2];
int timers_enable[2][2]; int64_t timers_enable[2][2];
int16_t filtbuf[2]; int16_t filtbuf[2];

View File

@@ -131,7 +131,7 @@ typedef struct pas16_t
int thit[3]; int thit[3];
int delay[3]; int delay[3];
int rereadlatch[3]; int rereadlatch[3];
int enable[3]; int64_t enable[3];
} pit; } pit;
opl_t opl; opl_t opl;

View File

@@ -26,7 +26,7 @@ typedef struct pssj_t
int irq; int irq;
int64_t timer_count; int64_t timer_count;
int enable; int64_t enable;
int wave_pos; int wave_pos;
int pulse_width; int pulse_width;

View File

@@ -46,7 +46,7 @@ typedef struct sb_dsp_t
uint8_t sb_asp_regs[256]; uint8_t sb_asp_regs[256];
int sbenable, sb_enable_i; int64_t sbenable, sb_enable_i;
int64_t sbcount, sb_count_i; int64_t sbcount, sb_count_i;

View File

@@ -20,12 +20,12 @@ static struct
int present; int present;
void (*callback)(void *priv); void (*callback)(void *priv);
void *priv; void *priv;
int *enable; int64_t *enable;
int64_t *count; int64_t *count;
} timers[TIMERS_MAX]; } timers[TIMERS_MAX];
int timers_present = 0; int timers_present = 0;
int timer_one = 1; int64_t timer_one = 1;
int64_t timer_count = 0, timer_latch = 0; int64_t timer_count = 0, timer_latch = 0;
int64_t timer_start = 0; int64_t timer_start = 0;
@@ -99,7 +99,7 @@ void timer_reset()
// timer_process(); // timer_process();
} }
int timer_add(void (*callback)(void *priv), int64_t *count, int *enable, void *priv) int timer_add(void (*callback)(void *priv), int64_t *count, int64_t *enable, void *priv)
{ {
if (timers_present < TIMERS_MAX) if (timers_present < TIMERS_MAX)
{ {

View File

@@ -46,13 +46,13 @@ extern int64_t timer_start;
void timer_process(); void timer_process();
void timer_update_outstanding(); void timer_update_outstanding();
void timer_reset(); void timer_reset();
int timer_add(void (*callback)(void *priv), int64_t *count, int *enable, void *priv); int timer_add(void (*callback)(void *priv), int64_t *count, int64_t *enable, void *priv);
void timer_set_callback(int timer, void (*callback)(void *priv)); void timer_set_callback(int timer, void (*callback)(void *priv));
#define TIMER_ALWAYS_ENABLED &timer_one #define TIMER_ALWAYS_ENABLED &timer_one
extern int64_t timer_count; extern int64_t timer_count;
extern int timer_one; extern int64_t timer_one;
#define TIMER_SHIFT 6 #define TIMER_SHIFT 6