diff options
Diffstat (limited to 'src/devices/machine/upd765.cpp')
-rw-r--r-- | src/devices/machine/upd765.cpp | 98 |
1 files changed, 62 insertions, 36 deletions
diff --git a/src/devices/machine/upd765.cpp b/src/devices/machine/upd765.cpp index 6328ec74dab..85aabb49335 100644 --- a/src/devices/machine/upd765.cpp +++ b/src/devices/machine/upd765.cpp @@ -174,6 +174,7 @@ upd765_family_device::upd765_family_device(const machine_config &mconfig, device ready_polled(true), select_connected(true), select_multiplexed(true), + has_dor(true), external_ready(false), recalibrate_steps(77), mode(mode_t::AT), @@ -181,8 +182,7 @@ upd765_family_device::upd765_family_device(const machine_config &mconfig, device drq_cb(*this), hdl_cb(*this), idx_cb(*this), - us_cb(*this), - dor_reset(0x00) + us_cb(*this) { } @@ -245,6 +245,7 @@ void upd765_family_device::device_start() cur_rate = 250000; tc = false; selected_drive = -1; + dor = 0x0c; // reset at upper levels may cause a write to tc ending up with // live_sync, which will crash if the live structure isn't @@ -267,7 +268,8 @@ void upd765_family_device::device_start() void upd765_family_device::device_reset() { - dor = dor_reset; + if(has_dor) + dor = 0x00; locked = false; soft_reset(); } @@ -304,6 +306,14 @@ void upd765_family_device::soft_reset() set_ds(select_multiplexed ? 0 : -1); check_irq(); + if(BIT(dor, 2)) + end_reset(); + else if(ready_polled) + poll_timer->adjust(attotime::never); +} + +void upd765_family_device::end_reset() +{ if(ready_polled) poll_timer->adjust(attotime::from_usec(100), 0, attotime::from_usec(1024)); } @@ -333,6 +343,25 @@ bool upd765_family_device::get_ready(int fid) return !external_ready; } +WRITE_LINE_MEMBER(upd765_family_device::reset_w) +{ + // This implementation is not valid for devices with DOR and possibly other extra registers. + // The working assumption is that no need to manipulate the RESET line directly when software can use DOR instead. + assert(!has_dor); + if(bool(state) == !BIT(dor, 2)) + return; + + LOGREGS("reset = %d\n", state); + if(state) { + dor &= 0xfb; + soft_reset(); + } + else { + dor |= 0x04; + end_reset(); + } +} + void upd765_family_device::set_ds(int fid) { if(selected_drive == fid) @@ -399,11 +428,16 @@ uint8_t upd765_family_device::dor_r() void upd765_family_device::dor_w(uint8_t data) { + assert(has_dor); LOGREGS("dor = %02x\n", data); uint8_t diff = dor ^ data; dor = data; - if(diff & 4) - soft_reset(); + if(BIT(diff, 2)) { + if(BIT(data, 2)) + end_reset(); + else + soft_reset(); + } for(int i=0; i<4; i++) { floppy_info &fi = flopi[i]; @@ -513,6 +547,9 @@ uint8_t upd765_family_device::fifo_r() void upd765_family_device::fifo_w(uint8_t data) { + if(!BIT(dor, 2)) + LOGWARN("%s: fifo_w(%02x) in reset\n", machine().describe_context(), data); + switch(main_phase) { case PHASE_CMD: { command[command_pos++] = data; @@ -780,7 +817,7 @@ void upd765_family_device::live_run(attotime limit) if(read_one_bit(limit)) return; - LOGSHIFT("%s: shift = %04x data=%02x c=%d\n", tts(cur_live.tm), cur_live.shift_reg, + LOGSHIFT("%s: shift = %04x data=%02x c=%d\n", cur_live.tm.to_string(), cur_live.shift_reg, (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | @@ -796,7 +833,7 @@ void upd765_family_device::live_run(attotime limit) cur_live.data_separator_phase = false; cur_live.bit_counter = 0; cur_live.state = READ_HEADER_BLOCK_HEADER; - LOGLIVE("%s: Found A1\n", tts(cur_live.tm)); + LOGLIVE("%s: Found A1\n", cur_live.tm.to_string()); } if(!mfm && cur_live.shift_reg == 0xf57e) { @@ -804,7 +841,7 @@ void upd765_family_device::live_run(attotime limit) cur_live.data_separator_phase = false; cur_live.bit_counter = 0; cur_live.state = READ_ID_BLOCK; - LOGLIVE("%s: Found IDAM\n", tts(cur_live.tm)); + LOGLIVE("%s: Found IDAM\n", cur_live.tm.to_string()); } break; @@ -812,7 +849,7 @@ void upd765_family_device::live_run(attotime limit) if(read_one_bit(limit)) return; - LOGSHIFT("%s: shift = %04x data=%02x counter=%d\n", tts(cur_live.tm), cur_live.shift_reg, + LOGSHIFT("%s: shift = %04x data=%02x counter=%d\n", cur_live.tm.to_string(), cur_live.shift_reg, (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | @@ -832,11 +869,11 @@ void upd765_family_device::live_run(attotime limit) if(cur_live.shift_reg != 0x4489) cur_live.state = SEARCH_ADDRESS_MARK_HEADER; else - LOGLIVE("%s: Found A1\n", tts(cur_live.tm)); + LOGLIVE("%s: Found A1\n", cur_live.tm.to_string()); break; } if(cur_live.data_reg != 0xfe) { - LOGLIVE("%s: No ident byte found after triple-A1, continue search\n", tts(cur_live.tm)); + LOGLIVE("%s: No ident byte found after triple-A1, continue search\n", cur_live.tm.to_string()); cur_live.state = SEARCH_ADDRESS_MARK_HEADER; break; } @@ -854,7 +891,7 @@ void upd765_family_device::live_run(attotime limit) break; int slot = (cur_live.bit_counter >> 4)-1; - LOGLIVE("%s: slot=%d data=%02x crc=%04x\n", tts(cur_live.tm), slot, cur_live.data_reg, cur_live.crc); + LOGLIVE("%s: slot=%d data=%02x crc=%04x\n", cur_live.tm.to_string(), slot, cur_live.data_reg, cur_live.crc); cur_live.idbuf[slot] = cur_live.data_reg; if(slot == 5) { live_delay(IDLE); @@ -867,7 +904,7 @@ void upd765_family_device::live_run(attotime limit) if(read_one_bit(limit)) return; - LOGSHIFT("%s: shift = %04x data=%02x c=%d.%x\n", tts(cur_live.tm), cur_live.shift_reg, + LOGSHIFT("%s: shift = %04x data=%02x c=%d.%x\n", cur_live.tm.to_string(), cur_live.shift_reg, (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | @@ -912,7 +949,7 @@ void upd765_family_device::live_run(attotime limit) if(read_one_bit(limit)) return; - LOGSHIFT("%s: shift = %04x data=%02x counter=%d\n", tts(cur_live.tm), cur_live.shift_reg, + LOGSHIFT("%s: shift = %04x data=%02x counter=%d\n", cur_live.tm.to_string(), cur_live.shift_reg, (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | @@ -1218,7 +1255,7 @@ void upd765_family_device::live_run(attotime limit) break; default: - LOGWARN("%s: Unknown live state %d\n", tts(cur_live.tm), cur_live.state); + LOGWARN("%s: Unknown live state %d\n", cur_live.tm.to_string(), cur_live.state); return; } } @@ -2412,17 +2449,6 @@ bool upd765_family_device::get_irq() const return cur_irq; } -std::string upd765_family_device::tts(attotime t) -{ - const char *sign = ""; - if(t.seconds() < 0) { - t = attotime::zero - t; - sign = "-"; - } - int const nsec = t.attoseconds() / ATTOSECONDS_PER_NANOSECOND; - return util::string_format("%s%04d.%03d,%03d,%03d", sign, int(t.seconds()), nsec/1000000, (nsec/1000)%1000, nsec % 1000); -} - std::string upd765_family_device::results() const { std::ostringstream stream; @@ -2440,7 +2466,7 @@ std::string upd765_family_device::results() const std::string upd765_family_device::ttsn() const { - return tts(machine().time()); + return machine().time().to_string(); } void upd765_family_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) @@ -2623,7 +2649,7 @@ bool upd765_family_device::write_one_bit(const attotime &limit) void upd765_family_device::live_write_raw(uint16_t raw) { - LOGLIVE("%s: write %04x %04x\n", tts(cur_live.tm), raw, cur_live.crc); + LOGLIVE("%s: write %04x %04x\n", cur_live.tm.to_string(), raw, cur_live.crc); cur_live.shift_reg = raw; cur_live.data_bit_context = raw & 1; } @@ -2643,7 +2669,7 @@ void upd765_family_device::live_write_mfm(uint8_t mfm) cur_live.data_reg = mfm; cur_live.shift_reg = raw; cur_live.data_bit_context = context; - LOGLIVE("%s: write %02x %04x %04x\n", tts(cur_live.tm), mfm, cur_live.crc, raw); + LOGLIVE("%s: write %02x %04x %04x\n", cur_live.tm.to_string(), mfm, cur_live.crc, raw); } void upd765_family_device::live_write_fm(uint8_t fm) @@ -2655,7 +2681,7 @@ void upd765_family_device::live_write_fm(uint8_t fm) cur_live.data_reg = fm; cur_live.shift_reg = raw; cur_live.data_bit_context = fm & 1; - LOGLIVE("%s: write %02x %04x %04x\n", tts(cur_live.tm), fm, cur_live.crc, raw); + LOGLIVE("%s: write %02x %04x %04x\n", cur_live.tm.to_string(), fm, cur_live.crc, raw); } bool upd765_family_device::sector_matches() const @@ -2672,17 +2698,17 @@ bool upd765_family_device::sector_matches() const upd765a_device::upd765a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : upd765_family_device(mconfig, UPD765A, tag, owner, clock) { - dor_reset = 0x0c; + has_dor = false; } upd765b_device::upd765b_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : upd765_family_device(mconfig, UPD765B, tag, owner, clock) { - dor_reset = 0x0c; + has_dor = false; } i8272a_device::i8272a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : upd765_family_device(mconfig, I8272A, tag, owner, clock) { - dor_reset = 0x0c; + has_dor = false; } upd72065_device::upd72065_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : upd72065_device(mconfig, UPD72065, tag, owner, clock) @@ -2691,7 +2717,7 @@ upd72065_device::upd72065_device(const machine_config &mconfig, const char *tag, upd72065_device::upd72065_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : upd765_family_device(mconfig, type, tag, owner, clock) { - dor_reset = 0x0c; + has_dor = false; recalibrate_steps = 255; } @@ -2713,7 +2739,7 @@ upd72069_device::upd72069_device(const machine_config &mconfig, const char *tag, i82072_device::i82072_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : upd765_family_device(mconfig, I82072, tag, owner, clock) { - dor_reset = 0x0c; + has_dor = false; recalibrate_steps = 255; } @@ -3089,7 +3115,7 @@ mcs3201_device::mcs3201_device(const machine_config &mconfig, const char *tag, d upd765_family_device(mconfig, MCS3201, tag, owner, clock), m_input_handler(*this) { - dor_reset = 0x0c; + has_dor = true; ready_polled = false; ready_connected = false; select_connected = true; |