diff --git a/src/disc.c b/src/disc.c index 57b7ed343..372a88cd7 100644 --- a/src/disc.c +++ b/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() diff --git a/src/disc.h b/src/disc.h index c5784672b..5525c2635 100644 --- a/src/disc.h +++ b/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); diff --git a/src/disc_86f.c b/src/disc_86f.c index 2ff13e267..187e8a711 100644 --- a/src/disc_86f.c +++ b/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) diff --git a/src/fdc.c b/src/fdc.c index 3725efc17..42d710b6d 100644 --- a/src/fdc.c +++ b/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; diff --git a/src/mem.c b/src/mem.c index 18507f95b..d83ed8386 100644 --- a/src/mem.c +++ b/src/mem.c @@ -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); diff --git a/src/sound_sb.c b/src/sound_sb.c index 34ca8b4d7..75493d315 100644 --- a/src/sound_sb.c +++ b/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", diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index dc4013c1c..232604e14 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -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);