From 760c720352b6899f4668a8667fe29bed57160b40 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 28 Jul 2024 01:00:58 +0200 Subject: [PATCH] Assorted FDC and PCjr video fixes, fixes #4659. --- src/floppy/fdc.c | 85 ++++++++--------------------------------- src/floppy/fdd_86f.c | 22 ++++++++++- src/include/86box/fdc.h | 2 +- src/machine/m_pcjr.c | 12 +++--- 4 files changed, 43 insertions(+), 78 deletions(-) diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index bce34e327..3fd492bd2 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -561,9 +561,6 @@ static void fdc_rate(fdc_t *fdc, int drive) { fdc_update_rate(fdc, drive); -#if 0 - fdc_log("FDD %c: Setting rate: %i, %i, %i (%i, %i)\n", 0x41 + drive, fdc->drvrate[drive], fdc->rate, fdc_get_densel(fdc, drive), fdc->rwc[drive], fdc->densel_force); -#endif fdc_log("FDD %c: [%i] Setting rate: %i, %i, %i (%i, %i, %i)\n", 0x41 + drive, fdc->enh_mode, fdc->drvrate[drive], fdc->rate, fdc_get_densel(fdc, drive), fdc->rwc[drive], fdc->densel_force, fdc->densel_polarity); fdd_set_densel(fdc_get_densel(fdc, drive)); fdc_log("FDD %c: [%i] Densel: %i\n", 0x41 + drive, fdc->enh_mode, fdc_get_densel(fdc, drive)); @@ -596,17 +593,6 @@ fdc_bad_command(fdc_t *fdc) static void fdc_io_command_phase1(fdc_t *fdc, int out) { -#if 0 - int i; - - pclog_toggle_suppr(); - pclog("%02X ", fdc->processed_cmd); - for (i = 0; i < fdc->pnum; i++) - pclog("%02X ", fdc->params[i]); - pclog("\n"); - pclog_toggle_suppr(); -#endif - fifo_reset(fdc->fifo_p); fdc_rate(fdc, fdc->drive); fdc->head = fdc->params[2]; @@ -1125,9 +1111,6 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->stat = (1 << fdc->drive); if (!(fdc->flags & FDC_FLAG_PCJR)) fdc->stat |= 0x80; -#if 0 - fdc->head = (fdc->params[0] & 4) ? 1 : 0; -#endif fdc->head = 0; /* TODO: See if this is correct. */ fdc->st0 = fdc->params[0] & 0x03; fdc->st0 |= (fdc->params[0] & 4); @@ -1418,7 +1401,6 @@ fdc_read(uint16_t addr, void *priv) default: ret = 0xFF; } - // fdc_log("Read FDC %04X %02X\n", addr, ret); fdc_log("[%04X:%08X] Read FDC %04X %02X [%i:%02X]\n", CS, cpu_state.pc, addr, ret, drive, fdc->dor & (0x10 << drive)); return ret; } @@ -1628,8 +1610,10 @@ fdc_callback(void *priv) if (fdc->sector == fdc->params[5]) { /* Reached end of track, MT bit is clear */ if (!(fdc->command & 0x80)) { - fdc->rw_track++; - fdc->sector = 1; + if (fdc->dma) { + fdc->rw_track++; + fdc->sector = 1; + } if (!(fdc->flags & FDC_FLAG_PCJR) && fdc->dma && (old_sector == 255)) fdc_no_dma_end(fdc, compare); else @@ -1638,10 +1622,12 @@ fdc_callback(void *priv) } /* Reached end of track, MT bit is set, head is 1 */ if (fdd_get_head(real_drive(fdc, fdc->drive)) == 1) { - fdc->rw_track++; - fdc->sector = 1; - fdc->head &= 0xFE; - fdd_set_head(real_drive(fdc, fdc->drive), 0); + if (fdc->dma) { + fdc->rw_track++; + fdc->sector = 1; + fdc->head &= 0xFE; + fdd_set_head(real_drive(fdc, fdc->drive), 0); + } if (!(fdc->flags & FDC_FLAG_PCJR) && fdc->dma && (old_sector == 255)) fdc_no_dma_end(fdc, compare); else @@ -1649,8 +1635,6 @@ fdc_callback(void *priv) return; } if (fdd_get_head(real_drive(fdc, fdc->drive)) == 0) { - fdc->sector = 1; - fdc->head |= 1; fdd_set_head(real_drive(fdc, fdc->drive), 1); if (!fdd_is_double_sided(real_drive(fdc, fdc->drive))) { fdc_noidam(fdc); @@ -1659,6 +1643,8 @@ fdc_callback(void *priv) } } else if (fdc->sector < fdc->params[5]) fdc->sector++; + else if (fdc->params[5] == 0) + fdc->sector++; ui_sb_update_icon(SB_FLOPPY | real_drive(fdc, fdc->drive), 1); switch (fdc->interrupt) { case 5: @@ -1811,7 +1797,6 @@ void fdc_error(fdc_t *fdc, int st5, int st6) { dma_set_drq(fdc->dma_ch, 0); -#if 1 timer_disable(&fdc->timer); fdc_int(fdc, 1); @@ -1823,6 +1808,10 @@ fdc_error(fdc_t *fdc, int st5, int st6) fdc->st0 |= 0x08; fdc->res[5] = st5; fdc->res[6] = st6; + if (fdc->wrong_am) { + fdc->res[6] |= 0x40; + fdc->wrong_am = 0; + } fdc_log("FDC Error: %02X %02X %02X\n", fdc->res[4], fdc->res[5], fdc->res[6]); switch (fdc->interrupt) { case 0x02: @@ -1848,48 +1837,6 @@ fdc_error(fdc_t *fdc, int st5, int st6) } ui_sb_update_icon(SB_FLOPPY | real_drive(fdc, fdc->drive), 0); fdc->paramstogo = 7; -#else - switch (fdc->interrupt) { - case 0x02: - case 0x05: - case 0x06: - case 0x09: - case 0x0C: - case 0x11: - case 0x16: - case 0x19: - case 0x1D: - fdc->error = 1; - fdc->st5 = st5; - fdc->st6 = st6; - fdc->tc = 1; - fdc->stat = 0x10; - fdc_callback(fdc); - break; - default: - timer_disable(&fdc->timer); - - fdc_int(fdc, 1); - if (!(fdc->flags & FDC_FLAG_PS1)) - fdc->fintr = 0; - fdc->stat = 0xD0; - fdc->st0 = fdc->res[4] = 0x40 | (fdd_get_head(real_drive(fdc, fdc->drive)) ? 4 : 0) | fdc->rw_drive; - if (fdc->head && !fdd_is_double_sided(real_drive(fdc, fdc->drive))) - fdc->st0 |= 0x08; - fdc->res[5] = st5; - fdc->res[6] = st6; - fdc_log("FDC Error: %02X %02X %02X\n", fdc->res[4], fdc->res[5], fdc->res[6]); - - fdc->res[7] = 0; - fdc->res[8] = 0; - fdc->res[9] = 0; - fdc->res[10] = 0; - - ui_sb_update_icon(SB_FLOPPY | real_drive(fdc, fdc->drive), 0); - fdc->paramstogo = 7; - break; - } -#endif } void diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index fa1c070f1..35ddbb1dd 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -1298,7 +1298,16 @@ d86f_find_address_mark_fm(int drive, int side, find_t *find, uint16_t req_am, ui find->sync_pos = 0xFFFFFFFF; if (ignore_other_am & 1) { /* Skip mode, let's go back to finding ID. */ - dev->state -= 2; + fdc_set_wrong_am(d86f_fdc); + dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; + dev->error_condition = 0; + dev->state = STATE_IDLE; + if (dev->state == STATE_02_READ_DATA) + fdc_track_finishread(d86f_fdc, dev->error_condition); + else if (dev->state == STATE_11_SCAN_DATA) + fdc_sector_finishcompare(d86f_fdc, (dev->satisfying_bytes == ((128 << ((uint32_t) dev->last_sector.id.n)) - 1)) ? 1 : 0); + else + fdc_sector_finishread(d86f_fdc); } else { /* Not skip mode, process the sector anyway. */ fdc_set_wrong_am(d86f_fdc); @@ -1377,7 +1386,16 @@ d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_am, u find->sync_pos = 0xFFFFFFFF; if (ignore_other_am & 1) { /* Skip mode, let's go back to finding ID. */ - dev->state -= 2; + fdc_set_wrong_am(d86f_fdc); + dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; + dev->error_condition = 0; + dev->state = STATE_IDLE; + if (dev->state == STATE_02_READ_DATA) + fdc_track_finishread(d86f_fdc, dev->error_condition); + else if (dev->state == STATE_11_SCAN_DATA) + fdc_sector_finishcompare(d86f_fdc, (dev->satisfying_bytes == ((128 << ((uint32_t) dev->last_sector.id.n)) - 1)) ? 1 : 0); + else + fdc_sector_finishread(d86f_fdc); } else { /* Not skip mode, process the sector anyway. */ fdc_set_wrong_am(d86f_fdc); diff --git a/src/include/86box/fdc.h b/src/include/86box/fdc.h index e03785df6..ef78239cd 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -120,7 +120,7 @@ typedef struct fdc_t { uint8_t params[15]; uint8_t specify[2]; uint8_t res[11]; - uint8_t eot[4]; + uint16_t eot[4]; uint8_t rwc[4]; uint16_t pcn[4]; diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index 6638402f7..9ac4ff631 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -465,22 +465,22 @@ vid_poll(void *priv) buffer32->line[l][ef_x + 2] = buffer32->line[l][ef_x + 3] = buffer32->line[l + 1][ef_x] = buffer32->line[l + 1][ef_x + 1] = buffer32->line[l + 1][ef_x + 2] = buffer32->line[l + 1][ef_x + 3] = - pcjr->array[((dat >> 12) & pcjr->array[1]) + 16] + 16; + pcjr->array[((dat >> 12) & pcjr->array[1] & 0x0f) + 16] + 16; buffer32->line[l][ef_x + 4] = buffer32->line[l][ef_x + 5] = buffer32->line[l][ef_x + 6] = buffer32->line[l][ef_x + 7] = - buffer32->line[l + 1][(x << 4) + 12] = buffer32->line[l + 1][(x << 4) + 13] = - buffer32->line[l + 1][(x << 4) + 14] = buffer32->line[l + 1][(x << 4) + 15] = - pcjr->array[((dat >> 8) & pcjr->array[1]) + 16] + 16; + buffer32->line[l + 1][ef_x + 4] = buffer32->line[l + 1][ef_x + 5] = + buffer32->line[l + 1][ef_x + 6] = buffer32->line[l + 1][ef_x + 7] = + pcjr->array[((dat >> 8) & pcjr->array[1] & 0x0f) + 16] + 16; buffer32->line[l][ef_x + 8] = buffer32->line[l][ef_x + 9] = buffer32->line[l][ef_x + 10] = buffer32->line[l][ef_x + 11] = buffer32->line[l + 1][ef_x + 8] = buffer32->line[l + 1][ef_x + 9] = buffer32->line[l + 1][ef_x + 10] = buffer32->line[l + 1][ef_x + 11] = - pcjr->array[((dat >> 4) & pcjr->array[1]) + 16] + 16; + pcjr->array[((dat >> 4) & pcjr->array[1] & 0x0f) + 16] + 16; buffer32->line[l][ef_x + 12] = buffer32->line[l][ef_x + 13] = buffer32->line[l][ef_x + 14] = buffer32->line[l][ef_x + 15] = buffer32->line[l + 1][ef_x + 12] = buffer32->line[l + 1][ef_x + 13] = buffer32->line[l + 1][ef_x + 14] = buffer32->line[l + 1][ef_x + 15] = - pcjr->array[(dat & pcjr->array[1]) + 16] + 16; + pcjr->array[(dat & pcjr->array[1] & 0x0f) + 16] + 16; } break; case 0x03: /*640x200x4*/