Reverted floppy disk operation to what it was in build 274, with a slight cleanup;
Sound Blaster 16 and AWE32 IRQ, base address, and DMA configuration is back; The Intel Advanced/ATX now requires version 1.00.06 of the BIOS rather than 1.00.05.
This commit is contained in:
162
src/disc.c
162
src/disc.c
@@ -14,8 +14,7 @@
|
||||
#include "fdd.h"
|
||||
#include "timer.h"
|
||||
|
||||
int disc_poll_time[2][2] = { { 16, 16 }, { 16, 16 } };
|
||||
int disc_poll_enable[2][2] = { { 0, 0 }, { 0, 0 } };
|
||||
int disc_poll_time[2] = { 16, 16 };
|
||||
|
||||
int disc_track[2];
|
||||
int writeprot[2], fwriteprot[2];
|
||||
@@ -42,11 +41,6 @@ int disc_changed[2];
|
||||
int motorspin;
|
||||
int motoron[2];
|
||||
|
||||
int do_poll[2];
|
||||
|
||||
int head_enable[2][2] = { 0, 0 };
|
||||
int head_time[2][2] = { 0, 0 };
|
||||
|
||||
int fdc_indexcount = 52;
|
||||
|
||||
/*void (*fdc_callback)();
|
||||
@@ -192,18 +186,18 @@ double disc_real_period(int drive)
|
||||
return (ddbp * dusec);
|
||||
}
|
||||
|
||||
void disc_poll(int drive, int head)
|
||||
void disc_poll(int drive)
|
||||
{
|
||||
if ((drive > 1) || !motoron[drive])
|
||||
if (drive > 1)
|
||||
{
|
||||
disc_poll_time[drive][head] += (int) (32.0 * TIMER_USEC);
|
||||
disc_poll_time[drive] += (int) (32.0 * TIMER_USEC);
|
||||
return;
|
||||
}
|
||||
|
||||
disc_poll_time[drive][head] += (int) disc_real_period(drive);
|
||||
disc_poll_time[drive] += (int) disc_real_period(drive);
|
||||
|
||||
if (drives[drive].poll)
|
||||
drives[drive].poll(drive, head);
|
||||
drives[drive].poll(drive);
|
||||
|
||||
if (disc_notfound)
|
||||
{
|
||||
@@ -211,35 +205,16 @@ void disc_poll(int drive, int head)
|
||||
if (!disc_notfound)
|
||||
fdc_notfound();
|
||||
}
|
||||
|
||||
/* If both heads are enabled and this is head 1, do not advance to avoid double advancing. */
|
||||
if ((disc_poll_enable[drive][head] && disc_poll_enable[drive][head ^ 1]) && head)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (drives[drive].advance)
|
||||
drives[drive].advance(drive);
|
||||
}
|
||||
|
||||
void disc_poll_00()
|
||||
void disc_poll_0()
|
||||
{
|
||||
disc_poll(0, 0);
|
||||
disc_poll(0);
|
||||
}
|
||||
|
||||
void disc_poll_01()
|
||||
void disc_poll_1()
|
||||
{
|
||||
disc_poll(0, 1);
|
||||
}
|
||||
|
||||
void disc_poll_10()
|
||||
{
|
||||
disc_poll(1, 0);
|
||||
}
|
||||
|
||||
void disc_poll_11()
|
||||
{
|
||||
disc_poll(1, 1);
|
||||
disc_poll(1);
|
||||
}
|
||||
|
||||
int disc_get_bitcell_period(int rate)
|
||||
@@ -295,125 +270,12 @@ void disc_set_rate(int drive, int drvden, int rate)
|
||||
}
|
||||
}
|
||||
|
||||
/* void disc_head_unload_no_callback(int drive, int head)
|
||||
{
|
||||
disc_head_unload(drive, head);
|
||||
head_callback[drive][head] = 0;
|
||||
} */
|
||||
|
||||
void disc_head_load(int drive, int head)
|
||||
{
|
||||
drive ^= fdd_swap;
|
||||
|
||||
// pclog("Head load start (%i, %i) (%i)\n", drive, head, head_time[drive][head]);
|
||||
|
||||
if (head_time[drive][head])
|
||||
{
|
||||
if (!disc_poll_enable[drive][head])
|
||||
{
|
||||
/* If enabling, do nothing and let it enable. */
|
||||
// pclog("Already enabling head (%i, %i)...\n", drive, head);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If disabling, stop the timer so it stays enabled. */
|
||||
// pclog("Currently disabling head (%i, %i)...\n", drive, head);
|
||||
head_time[drive][head] = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (disc_poll_enable[drive][head])
|
||||
{
|
||||
/* If it's already enabled, do nothing. */
|
||||
// pclog("Head (%i, %i) already enabled...\n", drive, head);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enable or disable not in progress, start enabling. */
|
||||
head_time[drive][head] = fdc_get_hlt();
|
||||
|
||||
// pclog("Head load finished (%i, %i) (%i)\n", drive, head, head_time[drive][head]);
|
||||
}
|
||||
|
||||
void disc_head_unload(int drive, int head)
|
||||
{
|
||||
drive ^= fdd_swap;
|
||||
|
||||
// pclog("Head unload start (%i, %i) (%i)\n", drive, head, head_time[drive][head]);
|
||||
|
||||
if (head_time[drive][head])
|
||||
{
|
||||
if (disc_poll_enable[drive][head])
|
||||
{
|
||||
/* If disabling, do nothing and let it disable. */
|
||||
// pclog("Already disabling head (%i, %i)...\n", drive, head);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If enabling, stop the timer so it stays disabled. */
|
||||
// pclog("Currently enabling head (%i, %i)...\n", drive, head);
|
||||
head_time[drive][head] = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!disc_poll_enable[drive][head])
|
||||
{
|
||||
/* If it's already disabled, do nothing. */
|
||||
// pclog("Head (%i, %i) already disabled...\n", drive, head);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enable or disable not in progress, start disabling. */
|
||||
head_time[drive][head] = fdc_get_hut();
|
||||
|
||||
// pclog("Head unload finished (%i, %i) (%i)\n", drive, head, head_time[drive][head]);
|
||||
}
|
||||
|
||||
void disc_head_poll_common(int drive, int head)
|
||||
{
|
||||
disc_poll_enable[drive][head] ^= 1;
|
||||
head_time[drive][head] = 0;
|
||||
// pclog("Head (%i, %i) %s\n", drive, head, disc_poll_enable[drive][head] ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
void disc_head_poll_00()
|
||||
{
|
||||
disc_head_poll_common(0, 0);
|
||||
}
|
||||
|
||||
void disc_head_poll_01()
|
||||
{
|
||||
disc_head_poll_common(0, 1);
|
||||
}
|
||||
|
||||
void disc_head_poll_10()
|
||||
{
|
||||
disc_head_poll_common(1, 0);
|
||||
}
|
||||
|
||||
void disc_head_poll_11()
|
||||
{
|
||||
disc_head_poll_common(1, 1);
|
||||
}
|
||||
|
||||
void disc_reset()
|
||||
{
|
||||
curdrive = 0;
|
||||
disc_period = 32;
|
||||
|
||||
timer_add(disc_poll_00, &(disc_poll_time[0][0]), &(disc_poll_enable[0][0]), NULL);
|
||||
timer_add(disc_poll_01, &(disc_poll_time[0][1]), &(disc_poll_enable[0][1]), NULL);
|
||||
timer_add(disc_poll_10, &(disc_poll_time[1][0]), &(disc_poll_enable[1][0]), NULL);
|
||||
timer_add(disc_poll_11, &(disc_poll_time[1][1]), &(disc_poll_enable[1][1]), NULL);
|
||||
|
||||
timer_add(disc_head_poll_00, &(head_time[0][0]), &(head_time[0][0]), NULL);
|
||||
timer_add(disc_head_poll_01, &(head_time[0][1]), &(head_time[0][1]), NULL);
|
||||
timer_add(disc_head_poll_10, &(head_time[1][0]), &(head_time[1][0]), NULL);
|
||||
timer_add(disc_head_poll_11, &(head_time[1][1]), &(head_time[1][1]), NULL);
|
||||
timer_add(disc_poll_0, &(disc_poll_time[0]), &(motoron[0]), NULL);
|
||||
timer_add(disc_poll_1, &(disc_poll_time[1]), &(motoron[1]), NULL);
|
||||
}
|
||||
|
||||
void disc_init()
|
||||
|
16
src/disc.h
16
src/disc.h
@@ -12,8 +12,7 @@ typedef struct
|
||||
int (*hole)(int drive);
|
||||
double (*byteperiod)(int drive);
|
||||
void (*stop)(int drive);
|
||||
void (*poll)(int drive, int side);
|
||||
void (*advance)(int drive);
|
||||
void (*poll)(int drive);
|
||||
} DRIVE;
|
||||
|
||||
extern DRIVE drives[2];
|
||||
@@ -25,11 +24,9 @@ void disc_new(int drive, char *fn);
|
||||
void disc_close(int drive);
|
||||
void disc_init();
|
||||
void disc_reset();
|
||||
void disc_poll(int drive, int head);
|
||||
void disc_poll_00();
|
||||
void disc_poll_00();
|
||||
void disc_poll_10();
|
||||
void disc_poll_11();
|
||||
void disc_poll(int drive);
|
||||
void disc_poll_0();
|
||||
void disc_poll_1();
|
||||
void disc_seek(int drive, int track);
|
||||
void disc_readsector(int drive, int sector, int track, int side, int density, int sector_size);
|
||||
void disc_writesector(int drive, int sector, int track, int side, int density, int sector_size);
|
||||
@@ -42,7 +39,7 @@ void disc_stop(int drive);
|
||||
int disc_empty(int drive);
|
||||
void disc_set_rate(int drive, int drvden, int rate);
|
||||
extern int disc_time;
|
||||
extern int disc_poll_time[2][2];
|
||||
extern int disc_poll_time[2];
|
||||
|
||||
void fdc_callback();
|
||||
int fdc_data(uint8_t dat);
|
||||
@@ -187,6 +184,3 @@ void null_set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8
|
||||
uint32_t null_index_hole_pos(int drive, int side);
|
||||
|
||||
uint32_t common_get_raw_size(int drive, int side);
|
||||
|
||||
void disc_head_load(int drive, int head);
|
||||
void disc_head_unload(int drive, int head);
|
||||
|
311
src/disc_86f.c
311
src/disc_86f.c
@@ -191,7 +191,7 @@ static struct __attribute__((packed))
|
||||
sector_id_t last_sector;
|
||||
sector_id_t req_sector;
|
||||
uint32_t index_count;
|
||||
uint8_t state[2];
|
||||
uint8_t state;
|
||||
uint8_t fill;
|
||||
uint32_t track_pos;
|
||||
uint32_t datac;
|
||||
@@ -1189,7 +1189,7 @@ void d86f_find_address_mark_fm(int drive, int side, find_t *find, uint16_t req_a
|
||||
find->sync_marks = find->bits_obtained = find->bytes_obtained = 0;
|
||||
find->sync_pos = 0xFFFFFFFF;
|
||||
d86f[drive].preceding_bit[side] = d86f[drive].last_word[side] & 1;
|
||||
d86f[drive].state[side]++;
|
||||
d86f[drive].state++;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1202,14 +1202,14 @@ void d86f_find_address_mark_fm(int drive, int side, find_t *find, uint16_t req_a
|
||||
if (ignore_other_am & 1)
|
||||
{
|
||||
/* Skip mode, let's go back to finding ID. */
|
||||
d86f[drive].state[side] -= 2;
|
||||
d86f[drive].state -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not skip mode, process the sector anyway. */
|
||||
fdc_set_wrong_am();
|
||||
d86f[drive].preceding_bit[side] = d86f[drive].last_word[side] & 1;
|
||||
d86f[drive].state[side]++;
|
||||
d86f[drive].state++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1228,7 +1228,7 @@ void d86f_write_find_address_mark_fm(int drive, int side, find_t *find)
|
||||
d86f[drive].calc_crc.word = 0xFFFF;
|
||||
d86f[drive].preceding_bit[side] = 1;
|
||||
find->sync_marks = 0;
|
||||
d86f[drive].state[side]++;
|
||||
d86f[drive].state++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1262,9 +1262,9 @@ void d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_
|
||||
disc_calccrc(decodefm(drive, d86f[drive].last_word[side]), &(d86f[drive].calc_crc));
|
||||
find->sync_marks = find->bits_obtained = find->bytes_obtained = 0;
|
||||
find->sync_pos = 0xFFFFFFFF;
|
||||
// pclog("AM found (%04X) (%02X)\n", req_am, d86f[drive].state[side]);
|
||||
// pclog("AM found (%04X) (%02X)\n", req_am, d86f[drive].state);
|
||||
d86f[drive].preceding_bit[side] = d86f[drive].last_word[side] & 1;
|
||||
d86f[drive].state[side]++;
|
||||
d86f[drive].state++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1280,14 +1280,14 @@ void d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_
|
||||
if (ignore_other_am & 1)
|
||||
{
|
||||
/* Skip mode, let's go back to finding ID. */
|
||||
d86f[drive].state[side] -= 2;
|
||||
d86f[drive].state -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not skip mode, process the sector anyway. */
|
||||
fdc_set_wrong_am();
|
||||
d86f[drive].preceding_bit[side] = d86f[drive].last_word[side] & 1;
|
||||
d86f[drive].state[side]++;
|
||||
d86f[drive].state++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1317,7 +1317,7 @@ void d86f_write_find_address_mark_mfm(int drive, int side, find_t *find)
|
||||
d86f[drive].calc_crc.word = 0xCDB4;
|
||||
d86f[drive].preceding_bit[side] = 1;
|
||||
find->sync_marks = 0;
|
||||
d86f[drive].state[side]++;
|
||||
d86f[drive].state++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1361,29 +1361,29 @@ void d86f_read_sector_id(int drive, int side, int match)
|
||||
{
|
||||
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = 0;
|
||||
// printf("%04X != %04X (%08X)\n", d86f[drive].track_crc.word, d86f[drive].calc_crc.word, d86f[drive].last_sector.dword);
|
||||
if ((d86f[drive].state[side] != STATE_02_READ_ID) && (d86f[drive].state[side] != STATE_0A_READ_ID))
|
||||
if ((d86f[drive].state != STATE_02_READ_ID) && (d86f[drive].state != STATE_0A_READ_ID))
|
||||
{
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].state[side] = STATE_IDLE;
|
||||
// fdc_finishread();
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_finishread();
|
||||
fdc_headercrcerror();
|
||||
}
|
||||
else if (d86f[drive].state[side] == STATE_0A_READ_ID)
|
||||
else if (d86f[drive].state == STATE_0A_READ_ID)
|
||||
{
|
||||
d86f[drive].state[side]--;
|
||||
d86f[drive].state--;
|
||||
}
|
||||
else
|
||||
{
|
||||
d86f[drive].error_condition |= 1; /* Mark that there was an ID CRC error. */
|
||||
d86f[drive].state[side]++;
|
||||
d86f[drive].state++;
|
||||
}
|
||||
}
|
||||
else if ((d86f[drive].calc_crc.word == d86f[drive].track_crc.word) && (d86f[drive].state[side] == STATE_0A_READ_ID))
|
||||
else if ((d86f[drive].calc_crc.word == d86f[drive].track_crc.word) && (d86f[drive].state == STATE_0A_READ_ID))
|
||||
{
|
||||
/* CRC is valid and this is a read sector ID command. */
|
||||
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = d86f[drive].error_condition = 0;
|
||||
fdc_sectorid(d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n, 0, 0);
|
||||
d86f[drive].state[side] = STATE_IDLE;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1392,13 +1392,13 @@ void d86f_read_sector_id(int drive, int side, int match)
|
||||
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = 0;
|
||||
if ((d86f[drive].last_sector.dword == d86f[drive].req_sector.dword) || !match)
|
||||
{
|
||||
// pclog("ID read (%02X)\n", d86f[drive].state[side]);
|
||||
// pclog("ID read (%02X)\n", d86f[drive].state);
|
||||
d86f_handler[drive].set_sector(drive, side, d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n);
|
||||
d86f[drive].state[side]++;
|
||||
d86f[drive].state++;
|
||||
}
|
||||
else
|
||||
{
|
||||
d86f[drive].state[side]--;
|
||||
d86f[drive].state--;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1474,7 +1474,7 @@ void d86f_read_sector_data(int drive, int side)
|
||||
if (d86f[drive].data_find.bytes_obtained < sector_len)
|
||||
{
|
||||
data = decodefm(drive, d86f[drive].last_word[side]);
|
||||
if (d86f[drive].state[side] == STATE_11_SCAN_DATA)
|
||||
if (d86f[drive].state == STATE_11_SCAN_DATA)
|
||||
{
|
||||
/* Scan/compare command. */
|
||||
recv_data = d86f_get_data(drive, 0);
|
||||
@@ -1484,7 +1484,7 @@ void d86f_read_sector_data(int drive, int side)
|
||||
{
|
||||
if (d86f[drive].data_find.bytes_obtained < d86f_get_data_len(drive))
|
||||
{
|
||||
if (d86f[drive].state[side] != STATE_16_VERIFY_DATA)
|
||||
if (d86f[drive].state != STATE_16_VERIFY_DATA)
|
||||
{
|
||||
fdc_data(data);
|
||||
}
|
||||
@@ -1501,21 +1501,21 @@ void d86f_read_sector_data(int drive, int side)
|
||||
if (d86f[drive].data_find.bytes_obtained == (crc_pos + fdc_get_gap()))
|
||||
{
|
||||
/* We've got the data. */
|
||||
if ((d86f[drive].calc_crc.word != d86f[drive].track_crc.word) && (d86f[drive].state[side] != STATE_02_READ_DATA))
|
||||
if ((d86f[drive].calc_crc.word != d86f[drive].track_crc.word) && (d86f[drive].state != STATE_02_READ_DATA))
|
||||
{
|
||||
// printf("%04X != %04X (%08X)\n", d86f[drive].track_crc.word, d86f[drive].calc_crc.word, d86f[drive].last_sector.dword);
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].state[side] = STATE_IDLE;
|
||||
// fdc_finishread();
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_finishread();
|
||||
fdc_datacrcerror();
|
||||
}
|
||||
else if ((d86f[drive].calc_crc.word != d86f[drive].track_crc.word) && (d86f[drive].state[side] == STATE_02_READ_DATA))
|
||||
else if ((d86f[drive].calc_crc.word != d86f[drive].track_crc.word) && (d86f[drive].state == STATE_02_READ_DATA))
|
||||
{
|
||||
// printf("%04X != %04X (%08X)\n", d86f[drive].track_crc.word, d86f[drive].calc_crc.word, d86f[drive].last_sector.dword);
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].error_condition |= 2; /* Mark that there was a data error. */
|
||||
d86f[drive].state[side] = STATE_IDLE;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_track_finishread(d86f[drive].error_condition);
|
||||
}
|
||||
else
|
||||
@@ -1523,14 +1523,14 @@ void d86f_read_sector_data(int drive, int side)
|
||||
/* CRC is valid. */
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].error_condition = 0;
|
||||
if (d86f[drive].state[side] == STATE_11_SCAN_DATA)
|
||||
if (d86f[drive].state == STATE_11_SCAN_DATA)
|
||||
{
|
||||
d86f[drive].state[side] = STATE_IDLE;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_sector_finishcompare((d86f[drive].satisfying_bytes == ((128 << ((uint32_t) d86f[drive].last_sector.id.n)) - 1)) ? 1 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
d86f[drive].state[side] = STATE_IDLE;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_sector_finishread();
|
||||
}
|
||||
}
|
||||
@@ -1656,7 +1656,7 @@ void d86f_write_sector_data(int drive, int side, int mfm, uint16_t am)
|
||||
/* We've written the data. */
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].state[side] = STATE_IDLE;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f_handler[drive].writeback(drive);
|
||||
fdc_sector_finishread();
|
||||
return;
|
||||
@@ -1674,7 +1674,34 @@ void d86f_advance_bit(int drive, int side)
|
||||
|
||||
if (d86f[drive].track_pos == d86f_handler[drive].index_hole_pos(drive, side)) d86f_handler[drive].read_revolution(drive);
|
||||
|
||||
if ((d86f[drive].track_pos == d86f_handler[drive].index_hole_pos(drive, side)) && (d86f[drive].state[side] != STATE_IDLE)) d86f[drive].index_count++;
|
||||
if ((d86f[drive].track_pos == d86f_handler[drive].index_hole_pos(drive, side)) && (d86f[drive].state != STATE_IDLE)) d86f[drive].index_count++;
|
||||
}
|
||||
|
||||
void d86f_advance_word(int drive, int side)
|
||||
{
|
||||
d86f[drive].track_pos += 16;
|
||||
d86f[drive].track_pos %= d86f_handler[drive].get_raw_size(drive, side);
|
||||
}
|
||||
|
||||
void d86f_spin_to_index(int drive, int side)
|
||||
{
|
||||
d86f_get_bit(drive, side);
|
||||
d86f_get_bit(drive, side ^ 1);
|
||||
|
||||
d86f_advance_bit(drive, side);
|
||||
|
||||
if (d86f[drive].track_pos == d86f_handler[drive].index_hole_pos(drive, side))
|
||||
{
|
||||
if (d86f[drive].state == STATE_0D_SPIN_TO_INDEX)
|
||||
{
|
||||
/* When starting format, reset format state to the beginning. */
|
||||
d86f[drive].preceding_bit[side] = 1;
|
||||
d86f[drive].format_state = FMT_PRETRK_GAP0;
|
||||
}
|
||||
/* This is to make sure both READ TRACK and FORMAT TRACK command don't end prematurely. */
|
||||
d86f[drive].index_count = 0;
|
||||
d86f[drive].state++;
|
||||
}
|
||||
}
|
||||
|
||||
void d86f_write_direct_common(int drive, int side, uint16_t byte, uint8_t type, uint32_t pos)
|
||||
@@ -1775,23 +1802,6 @@ void d86f_format_track(int drive, int side)
|
||||
gap_fill = mfm ? 0x4E : 0xFF;
|
||||
do_write = (d86f[drive].version == D86FVER);
|
||||
|
||||
if (d86f[drive].track_pos == d86f_handler[drive].index_hole_pos(drive, side))
|
||||
{
|
||||
/* Before we return, if the encoding is MFM, we have to make sure the clock bit of the first bit in the track is correct. */
|
||||
if (mfm && do_write)
|
||||
{
|
||||
if (do_write) d86f_write_direct_common(drive, side, gap_fill, 0, 0);
|
||||
}
|
||||
|
||||
d86f[drive].state[side] = STATE_IDLE;
|
||||
d86f_handler[drive].writeback(drive);
|
||||
// pclog("Format finished!\n");
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].datac = 0;
|
||||
fdc_sector_finishread();
|
||||
return;
|
||||
}
|
||||
|
||||
switch(d86f[drive].format_state)
|
||||
{
|
||||
case FMT_POSTTRK_GAP4:
|
||||
@@ -1803,25 +1813,21 @@ void d86f_format_track(int drive, int side)
|
||||
if (do_write) d86f_write_direct(drive, side, gap_fill, 0);
|
||||
break;
|
||||
case FMT_SECTOR_ID_SYNC:
|
||||
if ((d86f[drive].datac > 0) && (d86f[drive].datac <= 4))
|
||||
if (d86f[drive].datac <= 3)
|
||||
{
|
||||
data = fdc_getdata(0);
|
||||
if ((data == -1) && (d86f[drive].datac < 4))
|
||||
if ((data == -1) && (d86f[drive].datac < 3))
|
||||
{
|
||||
data = 0;
|
||||
}
|
||||
d86f[drive].format_sector_id.byte_array[d86f[drive].datac - 1] = data & 0xff;
|
||||
// pclog("format_sector_id[%i] = %i\n", d86f[drive].datac, d86f[drive].format_sector_id.byte_array[d86f[drive].datac - 1]);
|
||||
if (d86f[drive].datac == 4)
|
||||
d86f[drive].format_sector_id.byte_array[d86f[drive].datac] = data & 0xff;
|
||||
// pclog("format_sector_id[%i] = %i\n", d86f[drive].datac, d86f[drive].format_sector_id.byte_array[d86f[drive].datac]);
|
||||
if (d86f[drive].datac == 3)
|
||||
{
|
||||
fdc_stop_id_request();
|
||||
// pclog("Formatting sector: %08X...\n", d86f[drive].format_sector_id.dword);
|
||||
}
|
||||
}
|
||||
else if (d86f[drive].datac == 0)
|
||||
{
|
||||
fdc_request_next_sector_id();
|
||||
}
|
||||
case FMT_PRETRK_SYNC:
|
||||
case FMT_SECTOR_DATA_SYNC:
|
||||
max_len = sync_len;
|
||||
@@ -1847,10 +1853,6 @@ void d86f_format_track(int drive, int side)
|
||||
break;
|
||||
case FMT_SECTOR_IDAM:
|
||||
max_len = am_len;
|
||||
if (!d86f[drive].datac)
|
||||
{
|
||||
d86f[drive].calc_crc.word = 0xffff;
|
||||
}
|
||||
if (mfm)
|
||||
{
|
||||
if (do_write) d86f_write_direct(drive, side, idam_mfm[d86f[drive].datac], 1);
|
||||
@@ -1888,10 +1890,6 @@ void d86f_format_track(int drive, int side)
|
||||
break;
|
||||
case FMT_SECTOR_DATAAM:
|
||||
max_len = am_len;
|
||||
if (!d86f[drive].datac)
|
||||
{
|
||||
d86f[drive].calc_crc.word = 0xffff;
|
||||
}
|
||||
if (mfm)
|
||||
{
|
||||
if (do_write) d86f_write_direct(drive, side, dataam_mfm[d86f[drive].datac], 1);
|
||||
@@ -1916,83 +1914,75 @@ void d86f_format_track(int drive, int side)
|
||||
|
||||
d86f[drive].datac++;
|
||||
|
||||
if (d86f[drive].datac == max_len)
|
||||
d86f_advance_word(drive, side);
|
||||
|
||||
if (d86f[drive].track_pos == d86f_handler[drive].index_hole_pos(drive, side))
|
||||
{
|
||||
/* Before we return, if the encoding is MFM, we have to make sure the clock bit of the first bit in the track is correct. */
|
||||
if (mfm && do_write)
|
||||
{
|
||||
if (do_write) d86f_write_direct_common(drive, side, gap_fill, 0, 0);
|
||||
}
|
||||
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f_handler[drive].writeback(drive);
|
||||
// pclog("Format finished!\n");
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].datac = 0;
|
||||
fdc_sector_finishread();
|
||||
return;
|
||||
}
|
||||
|
||||
if (d86f[drive].datac >= max_len)
|
||||
{
|
||||
d86f[drive].datac = 0;
|
||||
d86f[drive].format_state++;
|
||||
|
||||
if (d86f[drive].format_state == FMT_SECTOR_GAP3)
|
||||
switch (d86f[drive].format_state)
|
||||
{
|
||||
d86f[drive].sector_count++;
|
||||
if (d86f[drive].sector_count < sc)
|
||||
{
|
||||
/* Sector within allotted amount, change state to SECTOR_ID_SYNC. */
|
||||
d86f[drive].format_state = FMT_SECTOR_ID_SYNC;
|
||||
case FMT_SECTOR_ID_SYNC:
|
||||
fdc_request_next_sector_id();
|
||||
}
|
||||
else
|
||||
{
|
||||
d86f[drive].format_state = FMT_POSTTRK_GAP4;
|
||||
d86f[drive].sector_count = 0;
|
||||
}
|
||||
break;
|
||||
case FMT_SECTOR_IDAM:
|
||||
case FMT_SECTOR_DATAAM:
|
||||
d86f[drive].calc_crc.word = 0xffff;
|
||||
break;
|
||||
case FMT_POSTTRK_CHECK:
|
||||
d86f[drive].sector_count++;
|
||||
if (d86f[drive].sector_count < sc)
|
||||
{
|
||||
/* Sector within allotted amount, change state to SECTOR_ID_SYNC. */
|
||||
d86f[drive].format_state = FMT_SECTOR_ID_SYNC;
|
||||
fdc_request_next_sector_id();
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
d86f[drive].format_state = FMT_POSTTRK_GAP4;
|
||||
d86f[drive].sector_count = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void d86f_advance(int drive)
|
||||
{
|
||||
int side;
|
||||
|
||||
side = fdd_get_head(drive);
|
||||
|
||||
d86f_advance_bit(drive, side);
|
||||
}
|
||||
|
||||
void d86f_poll(int drive, int side)
|
||||
void d86f_poll(int drive)
|
||||
{
|
||||
int side = 0;
|
||||
int mfm = 1;
|
||||
|
||||
side = fdd_get_head(drive);
|
||||
mfm = fdc_is_mfm();
|
||||
|
||||
if ((d86f[drive].state[side] == STATE_02_SPIN_TO_INDEX) || (d86f[drive].state[side] == STATE_0D_SPIN_TO_INDEX))
|
||||
{
|
||||
d86f_get_bit(drive, side);
|
||||
|
||||
if (d86f[drive].track_pos == d86f_handler[drive].index_hole_pos(drive, side))
|
||||
{
|
||||
if (d86f[drive].state[side] == STATE_0D_SPIN_TO_INDEX)
|
||||
{
|
||||
/* When starting format, reset format state to the beginning. */
|
||||
d86f[drive].preceding_bit[side] = 1;
|
||||
d86f[drive].format_state = FMT_PRETRK_GAP0;
|
||||
}
|
||||
/* This is to make sure both READ TRACK and FORMAT TRACK command don't end prematurely. */
|
||||
d86f[drive].index_count = 0;
|
||||
d86f[drive].state[side]++;
|
||||
// pclog("Next step will be format proper (%i %i)\n", drive, side);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((d86f[drive].index_count == 2) && (d86f[drive].state[side] != STATE_IDLE) && (d86f[drive].state[side] != STATE_0D_FORMAT_TRACK))
|
||||
{
|
||||
// pclog("[State: %02X] [Side %i] Sector not found (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state[side], side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side));
|
||||
d86f[drive].state[side] = STATE_IDLE;
|
||||
fdc_notfound();
|
||||
}
|
||||
}
|
||||
|
||||
if ((d86f[drive].state[side] & 0xF8) == 0xE8)
|
||||
if ((d86f[drive].state & 0xF8) == 0xE8)
|
||||
{
|
||||
if (!d86f_can_format(drive))
|
||||
{
|
||||
d86f[drive].state[side] = STATE_SECTOR_NOT_FOUND;
|
||||
d86f[drive].state = STATE_SECTOR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
if ((d86f[drive].state[side] != STATE_IDLE) && (d86f[drive].state[side] != STATE_SECTOR_NOT_FOUND) && ((d86f[drive].state[side] & 0xF8) != 0xE8))
|
||||
if ((d86f[drive].state != STATE_IDLE) && (d86f[drive].state != STATE_SECTOR_NOT_FOUND) && ((d86f[drive].state & 0xF8) != 0xE8))
|
||||
{
|
||||
if (!d86f_can_read_address(drive))
|
||||
{
|
||||
@@ -2001,12 +1991,18 @@ void d86f_poll(int drive, int side)
|
||||
if (fdc_is_mfm() != d86f_is_mfm(drive)) pclog("Encoding mismatch\n");
|
||||
if (d86f_get_encoding(drive) > 1) pclog("Image encoding (%s) not FM or MFM\n", (d86f_get_encoding(drive) == 2) ? "M2FM" : "GCR"); */
|
||||
|
||||
d86f[drive].state[side] = STATE_SECTOR_NOT_FOUND;
|
||||
d86f[drive].state = STATE_SECTOR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
switch(d86f[drive].state[side])
|
||||
d86f_get_bit(drive, side ^ 1);
|
||||
|
||||
switch(d86f[drive].state)
|
||||
{
|
||||
case STATE_02_SPIN_TO_INDEX:
|
||||
case STATE_0D_SPIN_TO_INDEX:
|
||||
d86f_spin_to_index(drive, side);
|
||||
return;
|
||||
case STATE_02_FIND_ID:
|
||||
case STATE_05_FIND_ID:
|
||||
case STATE_09_FIND_ID:
|
||||
@@ -2111,15 +2107,42 @@ void d86f_poll(int drive, int side)
|
||||
{
|
||||
d86f_format_track(drive, side);
|
||||
}
|
||||
break;
|
||||
return;
|
||||
case STATE_IDLE:
|
||||
case STATE_SECTOR_NOT_FOUND:
|
||||
default:
|
||||
d86f_get_bit(drive, side);
|
||||
break;
|
||||
}
|
||||
|
||||
d86f_advance_bit(drive, side);
|
||||
|
||||
if ((d86f[drive].index_count == 2) && (d86f[drive].state != STATE_IDLE))
|
||||
{
|
||||
// pclog("[State: %02X] [Side %i] Sector not found (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side));
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_notfound();
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void d86f_poll(int drive)
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
d86f_bit_poll(drive);
|
||||
}
|
||||
}
|
||||
|
||||
void d86f_poll()
|
||||
{
|
||||
int drive = 0;
|
||||
drive = fdc_get_drive();
|
||||
d86f_poll_per_drive(drive);
|
||||
}
|
||||
#endif
|
||||
|
||||
void d86f_reset_index_hole_pos(int drive, int side)
|
||||
{
|
||||
d86f[drive].index_hole_pos[side] = 0;
|
||||
@@ -2524,7 +2547,7 @@ void d86f_seek(int drive, int track)
|
||||
}
|
||||
}
|
||||
|
||||
d86f[drive].state[side] = STATE_IDLE;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
}
|
||||
|
||||
void d86f_write_track(int drive, int side, uint16_t *da0, uint16_t *sa0)
|
||||
@@ -2726,7 +2749,7 @@ void d86f_writeback(int drive)
|
||||
|
||||
void d86f_stop(int drive)
|
||||
{
|
||||
d86f[drive].state[0] = d86f[drive].state[1] = STATE_IDLE;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
}
|
||||
|
||||
int d86f_common_command(int drive, int sector, int track, int side, int rate, int sector_size)
|
||||
@@ -2741,7 +2764,7 @@ int d86f_common_command(int drive, int sector, int track, int side, int rate, in
|
||||
if (fdd_get_head(drive) && (d86f_get_sides(drive) == 1))
|
||||
{
|
||||
fdc_notfound();
|
||||
d86f[drive].state[side] = STATE_IDLE;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f[drive].index_count = 0;
|
||||
return 0;
|
||||
}
|
||||
@@ -2761,11 +2784,11 @@ void d86f_readsector(int drive, int sector, int track, int side, int rate, int s
|
||||
if (!ret) return;
|
||||
|
||||
if (sector == SECTOR_FIRST)
|
||||
d86f[drive].state[side] = STATE_02_SPIN_TO_INDEX;
|
||||
d86f[drive].state = STATE_02_SPIN_TO_INDEX;
|
||||
else if (sector == SECTOR_NEXT)
|
||||
d86f[drive].state[side] = STATE_02_FIND_ID;
|
||||
d86f[drive].state = STATE_02_FIND_ID;
|
||||
else
|
||||
d86f[drive].state[side] = fdc_is_deleted() ? STATE_0C_FIND_ID : (fdc_is_verify() ? STATE_16_FIND_ID : STATE_06_FIND_ID);
|
||||
d86f[drive].state = fdc_is_deleted() ? STATE_0C_FIND_ID : (fdc_is_verify() ? STATE_16_FIND_ID : STATE_06_FIND_ID);
|
||||
}
|
||||
|
||||
void d86f_writesector(int drive, int sector, int track, int side, int rate, int sector_size)
|
||||
@@ -2775,7 +2798,7 @@ void d86f_writesector(int drive, int sector, int track, int side, int rate, int
|
||||
if (writeprot[drive])
|
||||
{
|
||||
fdc_writeprotect();
|
||||
d86f[drive].state[side] = STATE_IDLE;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f[drive].index_count = 0;
|
||||
return;
|
||||
}
|
||||
@@ -2783,7 +2806,7 @@ void d86f_writesector(int drive, int sector, int track, int side, int rate, int
|
||||
ret = d86f_common_command(drive, sector, track, side, rate, sector_size);
|
||||
if (!ret) return;
|
||||
|
||||
d86f[drive].state[side] = fdc_is_deleted() ? STATE_09_FIND_ID : STATE_05_FIND_ID;
|
||||
d86f[drive].state = fdc_is_deleted() ? STATE_09_FIND_ID : STATE_05_FIND_ID;
|
||||
}
|
||||
|
||||
void d86f_comparesector(int drive, int sector, int track, int side, int rate, int sector_size)
|
||||
@@ -2793,16 +2816,16 @@ void d86f_comparesector(int drive, int sector, int track, int side, int rate, in
|
||||
ret = d86f_common_command(drive, sector, track, side, rate, sector_size);
|
||||
if (!ret) return;
|
||||
|
||||
d86f[drive].state[side] = STATE_11_FIND_ID;
|
||||
d86f[drive].state = STATE_11_FIND_ID;
|
||||
}
|
||||
|
||||
void d86f_readaddress(int drive, int track, int side, int rate)
|
||||
{
|
||||
if (fdd_get_head(drive) && (d86f_get_sides(drive) == 1))
|
||||
{
|
||||
// pclog("Trying to access the second side of a single-sided disk\n");
|
||||
pclog("Trying to access the second side of a single-sided disk\n");
|
||||
fdc_notfound();
|
||||
d86f[drive].state[side] = STATE_IDLE;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f[drive].index_count = 0;
|
||||
return;
|
||||
}
|
||||
@@ -2811,7 +2834,7 @@ void d86f_readaddress(int drive, int track, int side, int rate)
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].index_count = d86f[drive].error_condition = d86f[drive].satisfying_bytes = 0;
|
||||
|
||||
d86f[drive].state[side] = STATE_0A_FIND_ID;
|
||||
d86f[drive].state = STATE_0A_FIND_ID;
|
||||
}
|
||||
|
||||
void d86f_add_track(int drive, int track, int side)
|
||||
@@ -2861,7 +2884,7 @@ void d86f_common_format(int drive, int track, int side, int rate, uint8_t fill,
|
||||
if (writeprot[drive])
|
||||
{
|
||||
fdc_writeprotect();
|
||||
d86f[drive].state[side] = STATE_IDLE;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f[drive].index_count = 0;
|
||||
return;
|
||||
}
|
||||
@@ -2869,7 +2892,7 @@ void d86f_common_format(int drive, int track, int side, int rate, uint8_t fill,
|
||||
if ((side && (d86f_get_sides(drive) == 1)) || !(d86f_can_format(drive)))
|
||||
{
|
||||
fdc_notfound();
|
||||
d86f[drive].state[side] = STATE_IDLE;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f[drive].index_count = 0;
|
||||
return;
|
||||
}
|
||||
@@ -2882,7 +2905,7 @@ void d86f_common_format(int drive, int track, int side, int rate, uint8_t fill,
|
||||
{
|
||||
// pclog("Track above 256\n");
|
||||
fdc_writeprotect();
|
||||
d86f[drive].state[side] = STATE_IDLE;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f[drive].index_count = 0;
|
||||
return;
|
||||
}
|
||||
@@ -2929,7 +2952,7 @@ void d86f_common_format(int drive, int track, int side, int rate, uint8_t fill,
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].index_count = d86f[drive].error_condition = d86f[drive].satisfying_bytes = d86f[drive].sector_count = 0;
|
||||
|
||||
d86f[drive].state[side] = STATE_0D_SPIN_TO_INDEX;
|
||||
d86f[drive].state = STATE_0D_SPIN_TO_INDEX;
|
||||
}
|
||||
|
||||
void d86f_proxy_format(int drive, int track, int side, int rate, uint8_t fill)
|
||||
@@ -2953,7 +2976,6 @@ void d86f_common_handlers(int drive)
|
||||
drives[drive].poll = d86f_poll;
|
||||
drives[drive].format = d86f_proxy_format;
|
||||
drives[drive].stop = d86f_stop;
|
||||
drives[drive].advance = d86f_advance;
|
||||
}
|
||||
|
||||
void d86f_load(int drive, char *fn)
|
||||
@@ -3249,8 +3271,7 @@ void d86f_init()
|
||||
|
||||
// crc64speed_init();
|
||||
|
||||
d86f[0].state[0] = d86f[0].state[1] = STATE_IDLE;
|
||||
d86f[1].state[0] = d86f[1].state[1] = STATE_IDLE;
|
||||
d86f[0].state = d86f[1].state = STATE_IDLE;
|
||||
}
|
||||
|
||||
void d86f_close(int drive)
|
||||
|
176
src/fdc.c
176
src/fdc.c
@@ -16,30 +16,26 @@ extern int motoron[2];
|
||||
|
||||
int ui_writeprot[2] = {0, 0};
|
||||
|
||||
/* Bit 0 = Has drive select
|
||||
Bit 1 = Is read/write
|
||||
Bit 2 = Has head select */
|
||||
|
||||
int command_flags[256] = { [0x02] = 7, /* READ TRACK */
|
||||
[0x04] = 7, /* SENSE DRIVE STATUS */
|
||||
[0x05] = 7, /* WRITE DATA */
|
||||
[0x06] = 7, /* READ DATA */
|
||||
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] = 7, /* WRITE DELETED DATA */
|
||||
[0x0A] = 7, /* READ ID */
|
||||
[0x0C] = 7, /* READ DELETED DATA */
|
||||
[0x0D] = 7, /* FORMAT TRACK */
|
||||
[0x0F] = 7, /* SEEK, RELATIVE SEEK */
|
||||
[0x11] = 7, /* SCAN EQUAL */
|
||||
[0x16] = 7, /* VERIFY */
|
||||
[0x19] = 7, /* SCAN LOW OR EQUAL */
|
||||
[0x1D] = 7 }; /* SCAN HIGH OR EQUAL */
|
||||
[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
|
||||
{
|
||||
uint8_t dor,tdr,stat,command,dat,st0;
|
||||
uint8_t dor,stat,command,dat,st0;
|
||||
int head,track[256],sector,drive,lastdrive;
|
||||
int rw_track;
|
||||
int pos;
|
||||
@@ -200,68 +196,31 @@ int fdc_is_mfm()
|
||||
return fdc.mfm ? 1 : 0;
|
||||
}
|
||||
|
||||
double fdc_get_bit_period()
|
||||
{
|
||||
double bcp = 4.0;
|
||||
|
||||
switch(fdc_get_bit_rate())
|
||||
{
|
||||
case 0:
|
||||
bcp = 2.0;
|
||||
break;
|
||||
case 1:
|
||||
bcp = 20.0 / 6.0;
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
bcp = 4.0;
|
||||
break;
|
||||
case 3:
|
||||
bcp = 1.0;
|
||||
break;
|
||||
case 5:
|
||||
bcp = 0.5;
|
||||
break;
|
||||
}
|
||||
if (!fdc_is_mfm())
|
||||
{
|
||||
bcp *= 2.0;
|
||||
}
|
||||
|
||||
return bcp;
|
||||
}
|
||||
|
||||
#if 0
|
||||
double fdc_get_hut()
|
||||
{
|
||||
int hut = (fdc.specify[0] & 0xF);
|
||||
double dusec;
|
||||
double bcp;
|
||||
double dhut;
|
||||
if (!hut)
|
||||
{
|
||||
hut = 0x10;
|
||||
}
|
||||
dhut = (double) hut;
|
||||
bcp = fdc_get_bit_period() * 8.0;
|
||||
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 (dhut * bcp * 1000.0 * dusec);
|
||||
return (bcp * dhut * dusec * 1000.0);
|
||||
}
|
||||
|
||||
double fdc_get_hlt()
|
||||
{
|
||||
int hlt = (fdc.specify[1] >> 1);
|
||||
double dusec;
|
||||
double bcp;
|
||||
double dhlt;
|
||||
if (!hlt)
|
||||
{
|
||||
hlt = 0x80;
|
||||
}
|
||||
dhlt = (double) hlt;
|
||||
bcp = fdc_get_bit_period() * 8.0;
|
||||
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 (dhlt * bcp * 1000.0 * dusec);
|
||||
return (bcp * dhlt * dusec * 1000.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void fdc_request_next_sector_id()
|
||||
{
|
||||
@@ -342,7 +301,9 @@ void fdc_fifo_buf_dummy()
|
||||
static void fdc_int()
|
||||
{
|
||||
if (!fdc.pcjr)
|
||||
{
|
||||
picint(1 << 6);
|
||||
}
|
||||
}
|
||||
|
||||
static void fdc_watchdog_poll(void *p)
|
||||
@@ -580,7 +541,7 @@ 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 seek_time, seek_time_base;
|
||||
|
||||
switch (addr&7)
|
||||
{
|
||||
@@ -652,7 +613,6 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
return;
|
||||
case 3:
|
||||
/* TDR */
|
||||
fdc.tdr = val & 3;
|
||||
if (fdc.enh_mode)
|
||||
{
|
||||
drive = (fdc.dor & 1) ^ fdd_swap;
|
||||
@@ -660,7 +620,6 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
}
|
||||
return;
|
||||
case 4:
|
||||
val &= 0xdf; /* Bit 5 is hardwired to 0. */
|
||||
if (val & 0x80)
|
||||
{
|
||||
timer_process();
|
||||
@@ -861,19 +820,10 @@ bad_command:
|
||||
timer_process();
|
||||
disctime = 1024 * (1 << TIMER_SHIFT);
|
||||
timer_update_outstanding();
|
||||
if (command_flags[discint & 0x1F] & 1)
|
||||
if (command_has_drivesel[discint & 0x1F])
|
||||
{
|
||||
fdc.drive = fdc.params[0] & 3;
|
||||
}
|
||||
if (command_flags[discint & 0x1F] & 4)
|
||||
{
|
||||
fdd_set_head(fdc.drive, (fdc.params[0] & 4) ? 1 : 0);
|
||||
if (command_flags[discint & 0x1F] & 2)
|
||||
{
|
||||
// pclog("Command %02X, loading head...\n", fdc.command);
|
||||
disc_head_load(fdc.drive, fdd_get_head(fdc.drive ^ fdd_swap));
|
||||
}
|
||||
}
|
||||
fdc_reset_stat = 0;
|
||||
switch (discint & 0x1F)
|
||||
{
|
||||
@@ -1038,6 +988,7 @@ bad_command:
|
||||
break;
|
||||
|
||||
case 7: /*Recalibrate*/
|
||||
seek_time_base = fdd_doublestep_40(fdc.drive ^ fdd_swap) ? 10 : 5;
|
||||
fdc.stat = 1 << fdc.drive;
|
||||
disctime = 0;
|
||||
if (((fdc.drive ^ fdd_swap) == 1) && !fdc.drv2en)
|
||||
@@ -1046,7 +997,7 @@ bad_command:
|
||||
{
|
||||
fdc_seek(fdc.drive, -fdc.max_track);
|
||||
}
|
||||
disctime = fdc.max_track * 10 * TIMER_USEC;
|
||||
disctime = fdc.max_track * seek_time_base * TIMER_USEC;
|
||||
break;
|
||||
|
||||
case 0x0d: /*Format*/
|
||||
@@ -1068,6 +1019,7 @@ bad_command:
|
||||
fdc.head = (fdc.params[0] & 4) ? 1 : 0;
|
||||
fdd_set_head(fdc.drive, (fdc.params[0] & 4) ? 1 : 0);
|
||||
disctime = 0;
|
||||
seek_time_base = fdd_doublestep_40(fdc.drive ^ fdd_swap) ? 10 : 5;
|
||||
if (fdc.command & 0x80)
|
||||
{
|
||||
if (!fdc.params[1])
|
||||
@@ -1086,19 +1038,19 @@ bad_command:
|
||||
/* Relative seek outwards. */
|
||||
fdc_seek(fdc.drive, -fdc.params[1]);
|
||||
}
|
||||
disctime = ((int) fdc.params[1]) * 10 * TIMER_USEC;
|
||||
disctime = ((int) fdc.params[1]) * seek_time * TIMER_USEC;
|
||||
}
|
||||
else
|
||||
{
|
||||
disctime = 10 * TIMER_USEC;
|
||||
disctime = seek_time_base * TIMER_USEC;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
seek_time = ((int) (fdc.params[1] - fdc.track[fdc.drive])) * 10 * TIMER_USEC;
|
||||
seek_time = ((int) (fdc.params[1] - fdc.track[fdc.drive])) * seek_time_base * TIMER_USEC;
|
||||
if (!seek_time)
|
||||
{
|
||||
disctime = 10 * TIMER_USEC;
|
||||
disctime = seek_time_base * TIMER_USEC;
|
||||
break;
|
||||
}
|
||||
fdc_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]);
|
||||
@@ -1161,17 +1113,17 @@ uint8_t fdc_read(uint16_t addr, void *priv)
|
||||
presumably implemented outside the FDC on one of the
|
||||
motherboard's support chips.*/
|
||||
if (fdd_is_525(drive))
|
||||
temp = 0x20 | fdc.tdr;
|
||||
temp = 0x20;
|
||||
else if (fdd_is_ed(drive))
|
||||
temp = 0x10 | fdc.tdr;
|
||||
temp = 0x10;
|
||||
else
|
||||
temp = 0x00 | fdc.tdr;
|
||||
temp = 0x00;
|
||||
}
|
||||
else if (!fdc.enh_mode)
|
||||
temp = fdc.tdr;
|
||||
temp = 0x20;
|
||||
else
|
||||
{
|
||||
temp = (fdc.rwc[drive] << 4) | fdc.tdr;
|
||||
temp = fdc.rwc[drive] << 4;
|
||||
}
|
||||
break;
|
||||
case 4: /*Status*/
|
||||
@@ -1242,13 +1194,8 @@ uint8_t fdc_read(uint16_t addr, void *priv)
|
||||
return temp;
|
||||
}
|
||||
|
||||
void fdc_poll_common_finish(int st5, int compare)
|
||||
void fdc_poll_common_finish(int compare, int st5)
|
||||
{
|
||||
fdc.inread = 0;
|
||||
// discint=-2;
|
||||
disctime=0;
|
||||
// pclog("Poll common finish (%02X)...\n", st5);
|
||||
disc_head_unload(fdc.drive, fdd_get_head(fdc.drive ^ fdd_swap));
|
||||
fdc_int();
|
||||
fdc.stat=0xD0;
|
||||
fdc.res[4]=(fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
|
||||
@@ -1291,12 +1238,17 @@ void fdc_poll_common_finish(int st5, int compare)
|
||||
|
||||
void fdc_poll_readwrite_finish(int compare)
|
||||
{
|
||||
fdc_poll_common_finish(0, compare);
|
||||
fdc.inread = 0;
|
||||
discint=-2;
|
||||
|
||||
fdc_poll_common_finish(compare, 0);
|
||||
}
|
||||
|
||||
void fdc_no_dma_end(int compare)
|
||||
{
|
||||
fdc_poll_common_finish(0x80, compare);
|
||||
disctime = 0;
|
||||
|
||||
fdc_poll_common_finish(compare, 0x80);
|
||||
}
|
||||
|
||||
void fdc_callback()
|
||||
@@ -1340,7 +1292,6 @@ void fdc_callback()
|
||||
fdc.inread = 1;
|
||||
return;
|
||||
case 4: /*Sense drive status*/
|
||||
disc_head_unload(fdc.drive, fdd_get_head(fdc.drive ^ fdd_swap));
|
||||
fdc.res[10] = (fdc.params[0] & 7) | 0x28;
|
||||
if (((fdc.drive ^ fdd_swap) != 1) || fdc.drv2en)
|
||||
{
|
||||
@@ -1648,22 +1599,19 @@ void fdc_error(int st5, int st6)
|
||||
{
|
||||
disctime = 0;
|
||||
|
||||
// pclog("Error (%02X, %02X)...\n", st5, st6);
|
||||
disc_head_unload(fdc.drive, fdd_get_head(fdc.drive ^ fdd_swap));
|
||||
// discint=-2;
|
||||
fdc_int();
|
||||
fdc.stat=0xD0;
|
||||
fdc.res[4]=0x40|(fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
|
||||
fdc.res[5]=st5;
|
||||
fdc.res[5]=st5; /*Overrun*/
|
||||
fdc.res[6]=st6;
|
||||
fdc.res[7]=0;
|
||||
fdc.res[8]=0;
|
||||
fdc.res[9]=0;
|
||||
fdc.res[10]=0;
|
||||
paramstogo=7;
|
||||
// rpclog("c82c711_fdc_notfound\n");
|
||||
}
|
||||
|
||||
|
||||
void fdc_overrun()
|
||||
{
|
||||
disc_stop(fdc.drive);
|
||||
@@ -1739,28 +1687,17 @@ int fdc_data(uint8_t data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* void fdc_finishcompare(int satisfying)
|
||||
{
|
||||
fdc.satisfying_sectors++;
|
||||
fdc.inread = 0;
|
||||
// disc_head_unload(fdc.drive, fdd_get_head(fdc.drive ^ fdd_swap));
|
||||
disctime = 200 * TIMER_USEC;
|
||||
// rpclog("fdc_finishread\n");
|
||||
}
|
||||
|
||||
void fdc_finishread()
|
||||
{
|
||||
fdc.inread = 0;
|
||||
// disc_head_unload(fdc.drive, fdd_get_head(fdc.drive ^ fdd_swap));
|
||||
disctime = 200 * TIMER_USEC;
|
||||
// rpclog("fdc_finishread\n");
|
||||
} */
|
||||
}
|
||||
|
||||
void fdc_track_finishread(int condition)
|
||||
{
|
||||
fdc.satisfying_sectors |= condition;
|
||||
fdc.inread = 0;
|
||||
// disc_head_unload(fdc.drive, fdd_get_head(fdc.drive ^ fdd_swap));
|
||||
fdc_callback();
|
||||
// rpclog("fdc_finishread\n");
|
||||
}
|
||||
@@ -1769,7 +1706,6 @@ void fdc_sector_finishcompare(int satisfying)
|
||||
{
|
||||
fdc.satisfying_sectors++;
|
||||
fdc.inread = 0;
|
||||
// disc_head_unload(fdc.drive, fdd_get_head(fdc.drive ^ fdd_swap));
|
||||
fdc_callback();
|
||||
// rpclog("fdc_finishread\n");
|
||||
}
|
||||
@@ -1777,7 +1713,6 @@ void fdc_sector_finishcompare(int satisfying)
|
||||
void fdc_sector_finishread()
|
||||
{
|
||||
fdc.inread = 0;
|
||||
// disc_head_unload(fdc.drive, fdd_get_head(fdc.drive ^ fdd_swap));
|
||||
fdc_callback();
|
||||
// rpclog("fdc_finishread\n");
|
||||
}
|
||||
@@ -1862,10 +1797,7 @@ int fdc_getdata(int last)
|
||||
|
||||
void fdc_sectorid(uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uint8_t crc1, uint8_t crc2)
|
||||
{
|
||||
// pclog("SectorID %i %i %i %i\n", track, side, sector, size);
|
||||
fdc.inread = 0;
|
||||
disc_head_unload(fdc.drive, fdd_get_head(fdc.drive ^ fdd_swap));
|
||||
disctime = 0;
|
||||
// pclog("SectorID %i %i %i %i\n", track, side, sector, size);
|
||||
fdc_int();
|
||||
fdc.stat=0xD0;
|
||||
fdc.res[4]=(fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
|
||||
|
@@ -713,12 +713,12 @@ int loadbios()
|
||||
return 1;
|
||||
|
||||
case ROM_THOR:
|
||||
f = romfopen("roms/thor/1005CN0.BIO", "rb");
|
||||
f = romfopen("roms/thor/1006CN0_.BIO", "rb");
|
||||
if (!f) break;
|
||||
fseek(f, 0x80, SEEK_SET);
|
||||
fread(rom + 0x10000, 0x10000, 1, f);
|
||||
fclose(f);
|
||||
f = romfopen("roms/thor/1005CN0.BI1", "rb");
|
||||
f = romfopen("roms/thor/1006CN0_.BI1", "rb");
|
||||
if (!f) break;
|
||||
fseek(f, 0x80, SEEK_SET);
|
||||
fread(rom, 0x10000, 1, f);
|
||||
|
148
src/sound_sb.c
148
src/sound_sb.c
@@ -444,11 +444,14 @@ void *sb_pro_v2_init()
|
||||
void *sb_16_init()
|
||||
{
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
uint16_t addr = device_get_config_int("addr");
|
||||
memset(sb, 0, sizeof(sb_t));
|
||||
|
||||
opl3_init(&sb->opl);
|
||||
sb_dsp_init(&sb->dsp, SB16);
|
||||
sb_dsp_setaddr(&sb->dsp, 0x0220);
|
||||
sb_dsp_setaddr(&sb->dsp, addr);
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
|
||||
sb_mixer_init(&sb->mixer);
|
||||
io_sethandler(0x0220, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
|
||||
io_sethandler(0x0228, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
|
||||
@@ -482,12 +485,15 @@ int sb_awe32_available()
|
||||
void *sb_awe32_init()
|
||||
{
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
uint16_t addr = device_get_config_int("addr");
|
||||
int onboard_ram = device_get_config_int("onboard_ram");
|
||||
memset(sb, 0, sizeof(sb_t));
|
||||
|
||||
opl3_init(&sb->opl);
|
||||
sb_dsp_init(&sb->dsp, SB16 + 1);
|
||||
sb_dsp_setaddr(&sb->dsp, 0x0220);
|
||||
sb_dsp_setaddr(&sb->dsp, addr);
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
|
||||
sb_mixer_init(&sb->mixer);
|
||||
io_sethandler(0x0220, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
|
||||
io_sethandler(0x0228, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
|
||||
@@ -698,6 +704,75 @@ static device_config_t sb_pro_config[] =
|
||||
|
||||
static device_config_t sb_16_config[] =
|
||||
{
|
||||
{
|
||||
.name = "addr",
|
||||
.description = "Address",
|
||||
.type = CONFIG_BINARY,
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
{
|
||||
{
|
||||
.description = "0x220",
|
||||
.value = 0x220
|
||||
},
|
||||
{
|
||||
.description = "0x240",
|
||||
.value = 0x240
|
||||
},
|
||||
{
|
||||
.description = ""
|
||||
}
|
||||
},
|
||||
.default_int = 0x220
|
||||
},
|
||||
{
|
||||
.name = "irq",
|
||||
.description = "IRQ",
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
{
|
||||
{
|
||||
.description = "IRQ 2",
|
||||
.value = 2
|
||||
},
|
||||
{
|
||||
.description = "IRQ 5",
|
||||
.value = 5
|
||||
},
|
||||
{
|
||||
.description = "IRQ 7",
|
||||
.value = 7
|
||||
},
|
||||
{
|
||||
.description = "IRQ 10",
|
||||
.value = 10
|
||||
},
|
||||
{
|
||||
.description = ""
|
||||
}
|
||||
},
|
||||
.default_int = 5
|
||||
},
|
||||
{
|
||||
.name = "dma",
|
||||
.description = "DMA",
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
{
|
||||
{
|
||||
.description = "DMA 1",
|
||||
.value = 1
|
||||
},
|
||||
{
|
||||
.description = "DMA 3",
|
||||
.value = 3
|
||||
},
|
||||
{
|
||||
.description = ""
|
||||
}
|
||||
},
|
||||
.default_int = 1
|
||||
},
|
||||
{
|
||||
.name = "midi",
|
||||
.description = "MIDI out device",
|
||||
@@ -711,6 +786,75 @@ static device_config_t sb_16_config[] =
|
||||
|
||||
static device_config_t sb_awe32_config[] =
|
||||
{
|
||||
{
|
||||
.name = "addr",
|
||||
.description = "Address",
|
||||
.type = CONFIG_BINARY,
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
{
|
||||
{
|
||||
.description = "0x220",
|
||||
.value = 0x220
|
||||
},
|
||||
{
|
||||
.description = "0x240",
|
||||
.value = 0x240
|
||||
},
|
||||
{
|
||||
.description = ""
|
||||
}
|
||||
},
|
||||
.default_int = 0x220
|
||||
},
|
||||
{
|
||||
.name = "irq",
|
||||
.description = "IRQ",
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
{
|
||||
{
|
||||
.description = "IRQ 2",
|
||||
.value = 2
|
||||
},
|
||||
{
|
||||
.description = "IRQ 5",
|
||||
.value = 5
|
||||
},
|
||||
{
|
||||
.description = "IRQ 7",
|
||||
.value = 7
|
||||
},
|
||||
{
|
||||
.description = "IRQ 10",
|
||||
.value = 10
|
||||
},
|
||||
{
|
||||
.description = ""
|
||||
}
|
||||
},
|
||||
.default_int = 5
|
||||
},
|
||||
{
|
||||
.name = "dma",
|
||||
.description = "DMA",
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
{
|
||||
{
|
||||
.description = "DMA 1",
|
||||
.value = 1
|
||||
},
|
||||
{
|
||||
.description = "DMA 3",
|
||||
.value = 3
|
||||
},
|
||||
{
|
||||
.description = ""
|
||||
}
|
||||
},
|
||||
.default_int = 1
|
||||
},
|
||||
{
|
||||
.name = "midi",
|
||||
.description = "MIDI out device",
|
||||
|
@@ -609,7 +609,7 @@ void sb_dsp_init(sb_dsp_t *dsp, int type)
|
||||
{
|
||||
dsp->sb_type = type;
|
||||
|
||||
dsp->sb_irqnum = 7;
|
||||
dsp->sb_irqnum = 5;
|
||||
dsp->sb_8_dmanum = 1;
|
||||
|
||||
sb_doreset(dsp);
|
||||
|
Reference in New Issue
Block a user