summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/upd765.cpp
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2019-03-26 11:13:37 +1100
committer Vas Crabb <vas@vastheman.com>2019-03-26 11:13:37 +1100
commit97b67170277437131adf6ed4d60139c172529e4f (patch)
tree7a5cbf608f191075f1612b1af15832c206a3fe2d /src/devices/machine/upd765.cpp
parentb380514764cf857469bae61c11143a19f79a74c5 (diff)
(nw) Clean up the mess on master
This effectively reverts b380514764cf857469bae61c11143a19f79a74c5 and c24473ddff715ecec2e258a6eb38960cf8c8e98e, restoring the state at 598cd5227223c3b04ca31f0dbc1981256d9ea3ff. Before pushing, please check that what you're about to push is sane. Check your local commit log and ensure there isn't anything out-of-place before pushing to mainline. When things like this happen, it wastes everyone's time. I really don't need this in a week when real work™ is busting my balls and I'm behind where I want to be with preparing for MAME release.
Diffstat (limited to 'src/devices/machine/upd765.cpp')
-rw-r--r--src/devices/machine/upd765.cpp139
1 files changed, 75 insertions, 64 deletions
diff --git a/src/devices/machine/upd765.cpp b/src/devices/machine/upd765.cpp
index bfbf277449b..64b844dd222 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")
@@ -166,7 +168,9 @@ upd765_family_device::upd765_family_device(const machine_config &mconfig, device
pc_fdc_interface(mconfig, type, tag, owner, clock),
intrq_cb(*this),
drq_cb(*this),
- hdl_cb(*this)
+ hdl_cb(*this),
+ idx_cb(*this),
+ us_cb(*this)
{
ready_polled = true;
ready_connected = true;
@@ -191,14 +195,19 @@ void upd765_family_device::set_mode(int _mode)
mode = _mode;
}
-void upd765_family_device::device_start()
+void upd765_family_device::device_resolve_objects()
{
- save_item(NAME(motorcfg));
- save_item(NAME(selected_drive));
-
intrq_cb.resolve_safe();
drq_cb.resolve_safe();
hdl_cb.resolve_safe();
+ idx_cb.resolve_safe();
+ us_cb.resolve_safe();
+}
+
+void upd765_family_device::device_start()
+{
+ save_item(NAME(motorcfg));
+ save_item(NAME(selected_drive));
for(int i=0; i != 4; i++) {
char name[2];
@@ -327,6 +336,7 @@ void upd765_family_device::set_ds(int fid)
for(floppy_info &fi : flopi)
if(fi.dev)
fi.dev->ds_w(fid);
+ us_cb(fid);
// record selected drive
selected_drive = fid;
@@ -341,9 +351,11 @@ void upd765_family_device::set_floppy(floppy_image_device *flop)
}
if(flop)
flop->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(&upd765_family_device::index_callback, this));
+ else
+ idx_cb(0);
}
-READ8_MEMBER(upd765_family_device::sra_r)
+uint8_t upd765_family_device::sra_r()
{
uint8_t sra = 0;
int fid = dor & 3;
@@ -366,17 +378,17 @@ READ8_MEMBER(upd765_family_device::sra_r)
return sra;
}
-READ8_MEMBER(upd765_family_device::srb_r)
+uint8_t upd765_family_device::srb_r()
{
return 0;
}
-READ8_MEMBER(upd765_family_device::dor_r)
+uint8_t upd765_family_device::dor_r()
{
return dor;
}
-WRITE8_MEMBER(upd765_family_device::dor_w)
+void upd765_family_device::dor_w(uint8_t data)
{
LOGREGS("dor = %02x\n", data);
uint8_t diff = dor ^ data;
@@ -392,21 +404,16 @@ WRITE8_MEMBER(upd765_family_device::dor_w)
check_irq();
}
-READ8_MEMBER(upd765_family_device::tdr_r)
+uint8_t upd765_family_device::tdr_r()
{
return 0;
}
-WRITE8_MEMBER(upd765_family_device::tdr_w)
-{
-}
-
-READ8_MEMBER(upd765_family_device::msr_r)
+void upd765_family_device::tdr_w(uint8_t data)
{
- return read_msr();
}
-uint8_t upd765_family_device::read_msr()
+uint8_t upd765_family_device::msr_r()
{
uint32_t msr = 0;
switch(main_phase) {
@@ -437,7 +444,7 @@ uint8_t upd765_family_device::read_msr()
}
msr |= get_drive_busy();
- if(data_irq) {
+ if(data_irq && !machine().side_effects_disabled()) {
data_irq = false;
check_irq();
}
@@ -445,7 +452,7 @@ uint8_t upd765_family_device::read_msr()
return msr;
}
-WRITE8_MEMBER(upd765_family_device::dsr_w)
+void upd765_family_device::dsr_w(uint8_t data)
{
LOGREGS("dsr_w %02x (%s)\n", data, machine().describe_context());
if(data & 0x80)
@@ -459,39 +466,43 @@ void upd765_family_device::set_rate(int rate)
cur_rate = rate;
}
-uint8_t upd765_family_device::read_fifo()
+uint8_t upd765_family_device::fifo_r()
{
uint8_t r = 0xff;
switch(main_phase) {
case PHASE_EXEC:
+ if(machine().side_effects_disabled())
+ return fifo[0];
if(internal_drq)
return fifo_pop(false);
- LOGFIFO("read_fifo in phase %d\n", main_phase);
+ LOGFIFO("fifo_r in phase %d\n", main_phase);
break;
case PHASE_RESULT:
r = result[0];
- result_pos--;
- memmove(result, result+1, result_pos);
- if(!result_pos)
- main_phase = PHASE_CMD;
- else if(result_pos == 1) {
- // clear drive busy bit after the first sense interrupt status result byte is read
- for(floppy_info &fi : flopi)
- if((fi.main_state == RECALIBRATE || fi.main_state == SEEK) && fi.sub_state == IDLE && fi.st0_filled == false)
- fi.main_state = IDLE;
- clr_drive_busy();
+ if(!machine().side_effects_disabled()) {
+ result_pos--;
+ memmove(result, result+1, result_pos);
+ if(!result_pos)
+ main_phase = PHASE_CMD;
+ else if(result_pos == 1) {
+ // clear drive busy bit after the first sense interrupt status result byte is read
+ for(floppy_info &fi : flopi)
+ if((fi.main_state == RECALIBRATE || fi.main_state == SEEK) && fi.sub_state == IDLE && fi.st0_filled == false)
+ fi.main_state = IDLE;
+ clr_drive_busy();
+ }
}
break;
default:
- LOGFIFO("read_fifo in phase %d\n", main_phase);
+ LOGFIFO("fifo_r in phase %d\n", main_phase);
break;
}
return r;
}
-void upd765_family_device::write_fifo(uint8_t data)
+void upd765_family_device::fifo_w(uint8_t data)
{
switch(main_phase) {
case PHASE_CMD: {
@@ -517,11 +528,11 @@ void upd765_family_device::write_fifo(uint8_t data)
fifo_push(data, false);
return;
}
- LOGFIFO("write_fifo in phase %d\n", main_phase);
+ LOGFIFO("fifo_w in phase %d\n", main_phase);
break;
default:
- LOGFIFO("write_fifo in phase %d\n", main_phase);
+ LOGFIFO("fifo_w in phase %d\n", main_phase);
break;
}
}
@@ -534,12 +545,7 @@ uint8_t upd765_family_device::do_dir_r()
return 0x00;
}
-READ8_MEMBER(upd765_family_device::dir_r)
-{
- return do_dir_r();
-}
-
-WRITE8_MEMBER(upd765_family_device::ccr_w)
+void upd765_family_device::ccr_w(uint8_t data)
{
dsr = (dsr & 0xfc) | (data & 3);
cur_rate = rates[data & 3];
@@ -641,18 +647,10 @@ void upd765_family_device::fifo_expect(int size, bool write)
enable_transfer();
}
-READ8_MEMBER(upd765_family_device::mdma_r)
-{
- return dma_r();
-}
-
-WRITE8_MEMBER(upd765_family_device::mdma_w)
-{
- dma_w(data);
-}
-
uint8_t upd765_family_device::dma_r()
{
+ if(machine().side_effects_disabled())
+ return fifo[0];
return fifo_pop(false);
}
@@ -1474,7 +1472,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;
@@ -1746,7 +1744,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)
@@ -1758,6 +1765,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],
@@ -1776,11 +1784,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;
@@ -1852,7 +1855,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" : "",
@@ -1920,6 +1923,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;
@@ -1992,7 +2000,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],
@@ -2284,6 +2292,9 @@ void upd765_family_device::read_id_start(floppy_info &fi)
return;
}
+ for(int i=0; i<4; i++)
+ cur_live.idbuf[i] = command[i+2];
+
read_id_continue(fi);
}
@@ -2316,8 +2327,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;
@@ -2443,6 +2453,7 @@ void upd765_family_device::index_callback(floppy_image_device *floppy, int state
if(fi.live)
live_sync();
fi.index = state;
+ idx_cb(state);
if(!state) {
general_continue(fi);
@@ -2955,7 +2966,7 @@ void mcs3201_device::device_start()
m_input_handler.resolve_safe(0);
}
-READ8_MEMBER( mcs3201_device::input_r )
+uint8_t mcs3201_device::input_r()
{
return m_input_handler();
}
@@ -2975,7 +2986,7 @@ void tc8566af_device::device_start()
save_item(NAME(m_cr1));
}
-WRITE8_MEMBER(tc8566af_device::cr1_w)
+void tc8566af_device::cr1_w(uint8_t data)
{
m_cr1 = data;
@@ -2985,7 +2996,7 @@ WRITE8_MEMBER(tc8566af_device::cr1_w)
}
}
-WRITE8_MEMBER(upd72065_device::auxcmd_w)
+void upd72065_device::auxcmd_w(uint8_t data)
{
switch(data) {
case 0x36: // reset