summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/upd765.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/upd765.cpp')
-rw-r--r--src/devices/machine/upd765.cpp98
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;