diff options
Diffstat (limited to 'src/devices/machine/upd765.cpp')
-rw-r--r-- | src/devices/machine/upd765.cpp | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/src/devices/machine/upd765.cpp b/src/devices/machine/upd765.cpp index ac5359ae07f..4a55eba7bae 100644 --- a/src/devices/machine/upd765.cpp +++ b/src/devices/machine/upd765.cpp @@ -18,6 +18,7 @@ #define LOG_MATCH (1U << 10) // Sector matching #define LOG_STATE (1U << 11) // State machine #define LOG_LIVE (1U << 12) // Live states +#define LOG_DONE (1U << 13) // Command done #define VERBOSE (LOG_GENERAL | LOG_WARN ) @@ -38,6 +39,7 @@ #define LOGMATCH(...) LOGMASKED(LOG_MATCH, __VA_ARGS__) #define LOGSTATE(...) LOGMASKED(LOG_STATE, __VA_ARGS__) #define LOGLIVE(...) LOGMASKED(LOG_LIVE, __VA_ARGS__) +#define LOGDONE(...) LOGMASKED(LOG_DONE, __VA_ARGS__) DEFINE_DEVICE_TYPE(UPD765A, upd765a_device, "upd765a", "NEC uPD765A FDC") DEFINE_DEVICE_TYPE(UPD765B, upd765b_device, "upd765b", "NEC uPD765B FDC") @@ -1484,7 +1486,7 @@ void upd765_family_device::execute_command(int cmd) void upd765_family_device::command_end(floppy_info &fi, bool data_completion) { - LOGCOMMAND("command done (%s) - %s\n", data_completion ? "data" : "seek", results()); + LOGDONE("command done (%s) - %s\n", data_completion ? "data" : "seek", results()); fi.main_state = fi.sub_state = IDLE; if(data_completion) data_irq = true; @@ -1756,7 +1758,16 @@ void upd765_family_device::read_data_continue(floppy_info &fi) fi.sub_state = COMMAND_DONE; break; } + // MZ: This st1 handling ensures that both HX5102 floppy and the + // Speedlock protection scheme are properly working. + // a) HX5102 requires that the ND flag not be set when no address + // marks could be found on the track at all (particularly due to + // wrong density) + // b) Speedlock requires the ND flag be set when there are valid + // sectors on the track, but the desired sector is missing, also + // when it has no valid address marks st1 &= ~ST1_MA; + st1 |= ST1_ND; if(!sector_matches()) { if(cur_live.idbuf[0] != command[2]) { if(cur_live.idbuf[0] == 0xff) @@ -1768,6 +1779,7 @@ void upd765_family_device::read_data_continue(floppy_info &fi) live_start(fi, SEARCH_ADDRESS_MARK_HEADER); return; } + st1 &= ~ST1_ND; LOGRW("reading sector %02x %02x %02x %02x\n", cur_live.idbuf[0], cur_live.idbuf[1], @@ -1786,11 +1798,6 @@ void upd765_family_device::read_data_continue(floppy_info &fi) case SCAN_ID_FAILED: LOGSTATE("SCAN_ID_FAILED\n"); fi.st0 |= ST0_FAIL; - // MZ: The HX5102 does not correctly detect a FM/MFM mismatch - // when the ND bit is set, because in the firmware the ND bit wins - // against MA, and thus concludes that the format is correct - // but the sector is missing. - // st1 |= ST1_ND; fi.sub_state = COMMAND_DONE; break; @@ -1862,7 +1869,7 @@ void upd765_family_device::write_data_start(floppy_info &fi) fi.main_state = WRITE_DATA; fi.sub_state = HEAD_LOAD; mfm = command[0] & 0x40; - LOGRW("command write%s data%s%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n", + LOGCOMMAND("command write%s data%s%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n", command[0] & 0x08 ? " deleted" : "", command[0] & 0x80 ? " mt" : "", command[0] & 0x40 ? " mfm" : "", @@ -1930,6 +1937,11 @@ void upd765_family_device::write_data_continue(floppy_info &fi) break; } st1 &= ~ST1_MA; + LOGRW("writing sector %02x %02x %02x %02x\n", + cur_live.idbuf[0], + cur_live.idbuf[1], + cur_live.idbuf[2], + cur_live.idbuf[3]); sector_size = calc_sector_size(cur_live.idbuf[3]); fifo_expect(sector_size, true); fi.sub_state = SECTOR_WRITTEN; @@ -2002,7 +2014,7 @@ void upd765_family_device::read_track_start(floppy_info &fi) mfm = command[0] & 0x40; sectors_read = 0; - LOGRW("command read track%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n", + LOGCOMMAND("command read track%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n", command[0] & 0x40 ? " mfm" : "", command[0], command[1], @@ -2326,8 +2338,7 @@ void upd765_family_device::read_id_continue(floppy_info &fi) case SCAN_ID_FAILED: LOGSTATE("SCAN_ID_FAILED\n"); fi.st0 |= ST0_FAIL; - // st1 |= ST1_ND|ST1_MA; - st1 = ST1_MA; + st1 |= ST1_ND|ST1_MA; fi.sub_state = COMMAND_DONE; break; |