mirror of
https://github.com/holub/mame
synced 2025-10-05 08:41:31 +03:00
upd765: implement scan data and read track [Carl]
fail command when drive not ready and check ready before command (verified on real hardware) stop polling when first byte of command sent (verified) (mess) x68k: experiment with fdc drive control (nw)
This commit is contained in:
parent
b1a96bf2cc
commit
c779d7a67f
@ -274,7 +274,7 @@ void hd63450_device::set_timer(int channel, attotime tm)
|
||||
|
||||
TIMER_CALLBACK_MEMBER(hd63450_device::dma_transfer_timer)
|
||||
{
|
||||
if((m_reg[param].ocr & 3) == 2)
|
||||
if(((m_reg[param].ocr & 3) == 2) && !m_drq_state[param])
|
||||
return;
|
||||
single_transfer(param);
|
||||
}
|
||||
@ -467,7 +467,7 @@ void hd63450_device::single_transfer(int x)
|
||||
m_reg[x].mtc = space.read_word(m_reg[x].bar+4);
|
||||
return;
|
||||
}
|
||||
m_timer[x]->adjust(attotime::zero);
|
||||
m_timer[x]->adjust(attotime::never);
|
||||
m_in_progress[x] = 0;
|
||||
m_reg[x].csr |= 0xe0; // channel operation complete, block transfer complete
|
||||
m_reg[x].csr &= ~0x08; // channel no longer active
|
||||
@ -491,7 +491,13 @@ WRITE_LINE_MEMBER(hd63450_device::drq0_w)
|
||||
m_drq_state[0] = state;
|
||||
|
||||
if((m_reg[0].ocr & 2) && (state && !ostate))
|
||||
{
|
||||
// in cycle steal mode drq is supposed to be edge triggered
|
||||
single_transfer(0);
|
||||
m_timer[0]->adjust(m_our_clock[0], 0, m_our_clock[0]);
|
||||
}
|
||||
else if(!state)
|
||||
m_timer[0]->adjust(attotime::never);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hd63450_device::drq1_w)
|
||||
@ -500,7 +506,12 @@ WRITE_LINE_MEMBER(hd63450_device::drq1_w)
|
||||
m_drq_state[1] = state;
|
||||
|
||||
if((m_reg[1].ocr & 2) && (state && !ostate))
|
||||
{
|
||||
single_transfer(1);
|
||||
m_timer[1]->adjust(m_our_clock[1], 1, m_our_clock[1]);
|
||||
}
|
||||
else if(!state)
|
||||
m_timer[1]->adjust(attotime::never);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hd63450_device::drq2_w)
|
||||
@ -509,7 +520,12 @@ WRITE_LINE_MEMBER(hd63450_device::drq2_w)
|
||||
m_drq_state[2] = state;
|
||||
|
||||
if((m_reg[2].ocr & 2) && (state && !ostate))
|
||||
{
|
||||
single_transfer(2);
|
||||
m_timer[0]->adjust(m_our_clock[2], 2, m_our_clock[2]);
|
||||
}
|
||||
else if(!state)
|
||||
m_timer[2]->adjust(attotime::never);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hd63450_device::drq3_w)
|
||||
@ -518,7 +534,12 @@ WRITE_LINE_MEMBER(hd63450_device::drq3_w)
|
||||
m_drq_state[3] = state;
|
||||
|
||||
if((m_reg[3].ocr & 2) && (state && !ostate))
|
||||
{
|
||||
single_transfer(3);
|
||||
m_timer[0]->adjust(m_our_clock[3], 3, m_our_clock[3]);
|
||||
}
|
||||
else if(!state)
|
||||
m_timer[3]->adjust(attotime::never);
|
||||
}
|
||||
|
||||
int hd63450_device::get_vector(int channel)
|
||||
|
@ -116,7 +116,6 @@ upd765_family_device::upd765_family_device(const machine_config &mconfig, device
|
||||
ready_connected = true;
|
||||
select_connected = true;
|
||||
external_ready = false;
|
||||
no_poll_irq = false;
|
||||
dor_reset = 0x00;
|
||||
mode = MODE_AT;
|
||||
}
|
||||
@ -845,7 +844,10 @@ void upd765_family_device::live_run(attotime limit)
|
||||
int slot = (cur_live.bit_counter >> 4)-1;
|
||||
if(slot < sector_size) {
|
||||
// Sector data
|
||||
live_delay(READ_SECTOR_DATA_BYTE);
|
||||
if(cur_live.fi->main_state == SCAN_DATA)
|
||||
live_delay(SCAN_SECTOR_DATA_BYTE);
|
||||
else
|
||||
live_delay(READ_SECTOR_DATA_BYTE);
|
||||
return;
|
||||
|
||||
} else if(slot < sector_size+2) {
|
||||
@ -865,6 +867,38 @@ void upd765_family_device::live_run(attotime limit)
|
||||
checkpoint();
|
||||
break;
|
||||
|
||||
case SCAN_SECTOR_DATA_BYTE:
|
||||
if(!scan_done) // TODO: handle stp, x68000 sets it to 0xff (as it would dtl)?
|
||||
{
|
||||
int slot = (cur_live.bit_counter >> 4)-1;
|
||||
UINT8 data = fifo_pop(true);
|
||||
if(!slot)
|
||||
st2 = (st2 & ~(ST2_SN)) | ST2_SH;
|
||||
|
||||
if(data != cur_live.data_reg)
|
||||
{
|
||||
st2 = (st2 & ~(ST2_SH)) | ST2_SN;
|
||||
if((data < cur_live.data_reg) && ((command[0] & 0x1f) == 0x19)) // low
|
||||
st2 &= ~ST2_SN;
|
||||
|
||||
if((data > cur_live.data_reg) && ((command[0] & 0x1f) == 0x1d)) // high
|
||||
st2 &= ~ST2_SN;
|
||||
}
|
||||
if((slot == sector_size) && !(st2 & ST2_SN))
|
||||
{
|
||||
scan_done = true;
|
||||
tc_done = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fifo_pos)
|
||||
fifo_pop(true);
|
||||
}
|
||||
cur_live.state = READ_SECTOR_DATA;
|
||||
checkpoint();
|
||||
break;
|
||||
|
||||
case WRITE_SECTOR_SKIP_GAP2:
|
||||
cur_live.bit_counter = 0;
|
||||
cur_live.byte_counter = 0;
|
||||
@ -1150,6 +1184,9 @@ int upd765_family_device::check_command()
|
||||
case 0x0f:
|
||||
return command_pos == 3 ? C_SEEK : C_INCOMPLETE;
|
||||
|
||||
case 0x11:
|
||||
return command_pos == 9 ? C_SCAN_EQUAL : C_INCOMPLETE;
|
||||
|
||||
case 0x12:
|
||||
return command_pos == 2 ? C_PERPENDICULAR : C_INCOMPLETE;
|
||||
|
||||
@ -1159,6 +1196,12 @@ int upd765_family_device::check_command()
|
||||
case 0x14:
|
||||
return C_LOCK;
|
||||
|
||||
case 0x19:
|
||||
return command_pos == 9 ? C_SCAN_LOW : C_INCOMPLETE;
|
||||
|
||||
case 0x1d:
|
||||
return command_pos == 9 ? C_SCAN_HIGH : C_INCOMPLETE;
|
||||
|
||||
default:
|
||||
return C_INVALID;
|
||||
}
|
||||
@ -1228,6 +1271,12 @@ void upd765_family_device::start_command(int cmd)
|
||||
read_track_start(flopi[command[1] & 3]);
|
||||
break;
|
||||
|
||||
case C_SCAN_EQUAL:
|
||||
case C_SCAN_LOW:
|
||||
case C_SCAN_HIGH:
|
||||
scan_start(flopi[command[1] & 3]);
|
||||
break;
|
||||
|
||||
case C_RECALIBRATE:
|
||||
recalibrate_start(flopi[command[1] & 3]);
|
||||
main_phase = PHASE_CMD;
|
||||
@ -1448,10 +1497,67 @@ void upd765_family_device::read_data_start(floppy_info &fi)
|
||||
fi.st0 = command[1] & 7;
|
||||
st1 = ST1_MA;
|
||||
st2 = 0x00;
|
||||
hdl_cb(1);
|
||||
fi.ready = get_ready(command[1] & 3);
|
||||
|
||||
if(!fi.ready)
|
||||
{
|
||||
fi.st0 |= ST0_NR | ST0_FAIL;
|
||||
fi.sub_state = COMMAND_DONE;
|
||||
st1 = 0;
|
||||
st2 = 0;
|
||||
read_data_continue(fi);
|
||||
return;
|
||||
}
|
||||
|
||||
if(fi.dev)
|
||||
fi.dev->ss_w(command[1] & 4 ? 1 : 0);
|
||||
read_data_continue(fi);
|
||||
}
|
||||
|
||||
void upd765_family_device::scan_start(floppy_info &fi)
|
||||
{
|
||||
fi.main_state = SCAN_DATA;
|
||||
fi.sub_state = HEAD_LOAD_DONE;
|
||||
mfm = command[0] & 0x40;
|
||||
|
||||
logerror("%s: command scan%s data%s%s%s%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x stp=%02x rate=%d\n",
|
||||
tag(),
|
||||
command[0] & 0x08 ? " deleted" : "",
|
||||
command[0] & 0x80 ? " mt" : "",
|
||||
command[0] & 0x40 ? " mfm" : "",
|
||||
command[0] & 0x20 ? " sk" : "",
|
||||
fifocfg & 0x40 ? " seek" : "",
|
||||
command[0],
|
||||
command[1],
|
||||
command[2],
|
||||
command[3],
|
||||
command[4],
|
||||
128 << (command[5] & 7),
|
||||
command[6],
|
||||
command[7],
|
||||
command[8],
|
||||
cur_rate);
|
||||
|
||||
fi.st0 = command[1] & 7;
|
||||
st1 = ST1_MA;
|
||||
st2 = 0x00;
|
||||
scan_done = false;
|
||||
hdl_cb(1);
|
||||
fi.ready = get_ready(command[1] & 3);
|
||||
|
||||
if(!fi.ready)
|
||||
{
|
||||
fi.st0 |= ST0_NR | ST0_FAIL;
|
||||
fi.sub_state = COMMAND_DONE;
|
||||
st1 = 0;
|
||||
st2 = 0;
|
||||
read_data_continue(fi);
|
||||
return;
|
||||
}
|
||||
|
||||
if(fi.dev)
|
||||
fi.dev->ss_w(command[1] & 4 ? 1 : 0);
|
||||
read_data_continue(fi);
|
||||
}
|
||||
|
||||
@ -1529,7 +1635,10 @@ void upd765_family_device::read_data_continue(floppy_info &fi)
|
||||
cur_live.idbuf[2],
|
||||
cur_live.idbuf[3]);
|
||||
sector_size = calc_sector_size(cur_live.idbuf[3]);
|
||||
fifo_expect(sector_size, false);
|
||||
if(fi.main_state == SCAN_DATA)
|
||||
fifo_expect(sector_size, true);
|
||||
else
|
||||
fifo_expect(sector_size, false);
|
||||
fi.sub_state = SECTOR_READ;
|
||||
live_start(fi, SEARCH_ADDRESS_MARK_DATA);
|
||||
return;
|
||||
@ -1628,8 +1737,19 @@ void upd765_family_device::write_data_start(floppy_info &fi)
|
||||
fi.st0 = command[1] & 7;
|
||||
st1 = ST1_MA;
|
||||
st2 = 0x00;
|
||||
|
||||
hdl_cb(1);
|
||||
fi.ready = get_ready(command[1] & 3);
|
||||
|
||||
if(!fi.ready)
|
||||
{
|
||||
fi.st0 |= ST0_NR | ST0_FAIL;
|
||||
fi.sub_state = COMMAND_DONE;
|
||||
st1 = 0;
|
||||
st2 = 0;
|
||||
write_data_continue(fi);
|
||||
return;
|
||||
}
|
||||
|
||||
write_data_continue(fi);
|
||||
}
|
||||
|
||||
@ -1721,6 +1841,7 @@ void upd765_family_device::read_track_start(floppy_info &fi)
|
||||
fi.main_state = READ_TRACK;
|
||||
fi.sub_state = HEAD_LOAD_DONE;
|
||||
mfm = command[0] & 0x40;
|
||||
sectors_read = 0;
|
||||
|
||||
logerror("%s: command read track%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n",
|
||||
tag(),
|
||||
@ -1735,10 +1856,24 @@ void upd765_family_device::read_track_start(floppy_info &fi)
|
||||
command[7],
|
||||
command[8],
|
||||
cur_rate);
|
||||
fi.st0 = command[1] & 7;
|
||||
st1 = ST1_MA;
|
||||
st2 = 0x00;
|
||||
hdl_cb(1);
|
||||
fi.ready = get_ready(command[1] & 3);
|
||||
|
||||
if(!fi.ready)
|
||||
{
|
||||
fi.st0 |= ST0_NR | ST0_FAIL;
|
||||
fi.sub_state = COMMAND_DONE;
|
||||
st1 = 0;
|
||||
st2 = 0;
|
||||
read_track_continue(fi);
|
||||
return;
|
||||
}
|
||||
|
||||
if(fi.dev)
|
||||
fi.dev->ss_w(command[1] & 4 ? 1 : 0);
|
||||
hdl_cb(1);
|
||||
read_track_continue(fi);
|
||||
}
|
||||
|
||||
@ -1751,6 +1886,7 @@ void upd765_family_device::read_track_continue(floppy_info &fi)
|
||||
fi.sub_state = SEEK_DONE;
|
||||
break;
|
||||
}
|
||||
fi.st0 |= ST0_SE;
|
||||
if(fi.dev) {
|
||||
fi.dev->dir_w(fi.pcn > command[2] ? 1 : 0);
|
||||
fi.dev->stp_w(0);
|
||||
@ -1783,16 +1919,34 @@ void upd765_family_device::read_track_continue(floppy_info &fi)
|
||||
|
||||
case SEEK_DONE:
|
||||
fi.counter = 0;
|
||||
fi.sub_state = WAIT_INDEX;
|
||||
return;
|
||||
|
||||
case WAIT_INDEX:
|
||||
return;
|
||||
|
||||
case WAIT_INDEX_DONE:
|
||||
logerror("%s: index found, reading track\n", tag());
|
||||
fi.sub_state = SCAN_ID;
|
||||
live_start(fi, SEARCH_ADDRESS_MARK_HEADER);
|
||||
return;
|
||||
|
||||
case SCAN_ID:
|
||||
if(cur_live.crc) {
|
||||
fprintf(stderr, "Header CRC error\n");
|
||||
live_start(fi, SEARCH_ADDRESS_MARK_HEADER);
|
||||
return;
|
||||
st1 |= ST1_DE;
|
||||
}
|
||||
st1 &= ~ST1_MA;
|
||||
logerror("%s: reading sector %02x %02x %02x %02x\n",
|
||||
tag(),
|
||||
cur_live.idbuf[0],
|
||||
cur_live.idbuf[1],
|
||||
cur_live.idbuf[2],
|
||||
cur_live.idbuf[3]);
|
||||
if(!sector_matches())
|
||||
st1 |= ST1_ND;
|
||||
else
|
||||
st1 &= ~ST1_ND;
|
||||
|
||||
sector_size = calc_sector_size(cur_live.idbuf[3]);
|
||||
fifo_expect(sector_size, false);
|
||||
fi.sub_state = SECTOR_READ;
|
||||
@ -1800,30 +1954,49 @@ void upd765_family_device::read_track_continue(floppy_info &fi)
|
||||
return;
|
||||
|
||||
case SCAN_ID_FAILED:
|
||||
fprintf(stderr, "RNF\n");
|
||||
// command_end(fi, true, 1);
|
||||
return;
|
||||
fi.st0 |= ST0_FAIL;
|
||||
st1 |= ST1_ND;
|
||||
fi.sub_state = COMMAND_DONE;
|
||||
break;
|
||||
|
||||
case SECTOR_READ:
|
||||
if(cur_live.crc) {
|
||||
fprintf(stderr, "CRC error\n");
|
||||
}
|
||||
if(command[4] < command[6]) {
|
||||
command[4]++;
|
||||
fi.sub_state = HEAD_LOAD_DONE;
|
||||
case SECTOR_READ: {
|
||||
if(st2 & ST2_MD) {
|
||||
fi.st0 |= ST0_FAIL;
|
||||
fi.sub_state = COMMAND_DONE;
|
||||
break;
|
||||
}
|
||||
if(cur_live.crc) {
|
||||
st1 |= ST1_DE;
|
||||
st2 |= ST2_CM;
|
||||
}
|
||||
bool done = tc_done;
|
||||
sectors_read++;
|
||||
if(sectors_read == command[6]) {
|
||||
if(!tc_done) {
|
||||
fi.st0 |= ST0_FAIL;
|
||||
st1 |= ST1_EN;
|
||||
}
|
||||
done = true;
|
||||
}
|
||||
if(!done) {
|
||||
fi.sub_state = WAIT_INDEX_DONE;
|
||||
break;
|
||||
}
|
||||
fi.sub_state = COMMAND_DONE;
|
||||
break;
|
||||
}
|
||||
|
||||
case COMMAND_DONE:
|
||||
main_phase = PHASE_RESULT;
|
||||
result[0] = 0x40 | (fi.dev->ss_r() << 2) | fi.id;
|
||||
result[1] = 0;
|
||||
result[2] = 0;
|
||||
result[0] = fi.st0;
|
||||
result[1] = st1;
|
||||
result[2] = st2;
|
||||
result[3] = command[2];
|
||||
result[4] = command[3];
|
||||
result[5] = command[4];
|
||||
result[6] = command[5];
|
||||
result_pos = 7;
|
||||
// command_end(fi, true, 0);
|
||||
command_end(fi, true);
|
||||
return;
|
||||
|
||||
default:
|
||||
@ -1849,11 +2022,22 @@ void upd765_family_device::format_track_start(floppy_info &fi)
|
||||
command[0] & 0x40 ? "mfm" : "fm",
|
||||
command[1], command[2], command[3], command[4], command[5]);
|
||||
|
||||
hdl_cb(1);
|
||||
fi.ready = get_ready(command[1] & 3);
|
||||
|
||||
if(!fi.ready)
|
||||
{
|
||||
fi.st0 = (command[1] & 7) | ST0_NR | ST0_FAIL;
|
||||
fi.sub_state = TRACK_DONE;
|
||||
format_track_continue(fi);
|
||||
return;
|
||||
}
|
||||
fi.st0 = command[1] & 7;
|
||||
|
||||
if(fi.dev)
|
||||
fi.dev->ss_w(command[1] & 4 ? 1 : 0);
|
||||
sector_size = calc_sector_size(command[2]);
|
||||
|
||||
hdl_cb(1);
|
||||
format_track_continue(fi);
|
||||
}
|
||||
|
||||
@ -1877,7 +2061,7 @@ void upd765_family_device::format_track_continue(floppy_info &fi)
|
||||
|
||||
case TRACK_DONE:
|
||||
main_phase = PHASE_RESULT;
|
||||
result[0] = (fi.dev->ss_r() << 2) | fi.id;
|
||||
result[0] = fi.st0;
|
||||
result[1] = 0;
|
||||
result[2] = 0;
|
||||
result[3] = 0;
|
||||
@ -1917,6 +2101,16 @@ void upd765_family_device::read_id_start(floppy_info &fi)
|
||||
cur_live.idbuf[i] = 0x00;
|
||||
|
||||
hdl_cb(1);
|
||||
fi.ready = get_ready(command[1] & 3);
|
||||
|
||||
if(!fi.ready)
|
||||
{
|
||||
fi.st0 |= ST0_NR | ST0_FAIL;
|
||||
fi.sub_state = COMMAND_DONE;
|
||||
read_id_continue(fi);
|
||||
return;
|
||||
}
|
||||
|
||||
read_id_continue(fi);
|
||||
}
|
||||
|
||||
@ -2022,7 +2216,7 @@ void upd765_family_device::device_timer(emu_timer &timer, device_timer_id id, in
|
||||
|
||||
void upd765_family_device::run_drive_ready_polling()
|
||||
{
|
||||
if(main_phase != PHASE_CMD || (fifocfg & FIF_POLL))
|
||||
if(main_phase != PHASE_CMD || (fifocfg & FIF_POLL) || command_pos)
|
||||
return;
|
||||
|
||||
for(int fid=0; fid<4; fid++) {
|
||||
@ -2033,8 +2227,7 @@ void upd765_family_device::run_drive_ready_polling()
|
||||
if(!flopi[fid].st0_filled) {
|
||||
flopi[fid].st0 = ST0_ABRT | fid;
|
||||
flopi[fid].st0_filled = true;
|
||||
if(!no_poll_irq)
|
||||
other_irq = true;
|
||||
other_irq = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2114,6 +2307,7 @@ void upd765_family_device::general_continue(floppy_info &fi)
|
||||
break;
|
||||
|
||||
case READ_DATA:
|
||||
case SCAN_DATA:
|
||||
read_data_continue(fi);
|
||||
break;
|
||||
|
||||
@ -2241,7 +2435,6 @@ i8272a_device::i8272a_device(const machine_config &mconfig, const char *tag, dev
|
||||
upd72065_device::upd72065_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, UPD72065, "UPD72065", tag, owner, clock, "upd72065", __FILE__)
|
||||
{
|
||||
dor_reset = 0x0c;
|
||||
no_poll_irq = true;
|
||||
}
|
||||
|
||||
smc37c78_device::smc37c78_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, SMC37C78, "SMC37C78", tag, owner, clock, "smc37c78", __FILE__)
|
||||
|
@ -207,6 +207,7 @@ protected:
|
||||
READ_TRACK,
|
||||
FORMAT_TRACK,
|
||||
READ_ID,
|
||||
SCAN_DATA,
|
||||
|
||||
// Sub-states
|
||||
COMMAND_DONE,
|
||||
@ -241,6 +242,7 @@ protected:
|
||||
SEARCH_ADDRESS_MARK_DATA_FAILED,
|
||||
READ_SECTOR_DATA,
|
||||
READ_SECTOR_DATA_BYTE,
|
||||
SCAN_SECTOR_DATA_BYTE,
|
||||
|
||||
WRITE_SECTOR_SKIP_GAP2,
|
||||
WRITE_SECTOR_SKIP_GAP2_BYTE,
|
||||
@ -305,17 +307,17 @@ protected:
|
||||
|
||||
bool ready_connected, ready_polled, select_connected;
|
||||
|
||||
bool external_ready, no_poll_irq;
|
||||
bool external_ready;
|
||||
|
||||
int mode;
|
||||
int main_phase;
|
||||
|
||||
live_info cur_live, checkpoint_live;
|
||||
devcb_write_line intrq_cb, drq_cb, hdl_cb;
|
||||
bool cur_irq, other_irq, data_irq, drq, internal_drq, tc, tc_done, locked, mfm;
|
||||
bool cur_irq, other_irq, data_irq, drq, internal_drq, tc, tc_done, locked, mfm, scan_done;
|
||||
floppy_info flopi[4];
|
||||
|
||||
int fifo_pos, fifo_expected, command_pos, result_pos;
|
||||
int fifo_pos, fifo_expected, command_pos, result_pos, sectors_read;
|
||||
bool fifo_write;
|
||||
UINT8 dor, dsr, msr, fifo[16], command[16], result[16];
|
||||
UINT8 st1, st2, st3;
|
||||
@ -345,6 +347,9 @@ protected:
|
||||
C_SENSE_INTERRUPT_STATUS,
|
||||
C_SPECIFY,
|
||||
C_WRITE_DATA,
|
||||
C_SCAN_EQUAL,
|
||||
C_SCAN_LOW,
|
||||
C_SCAN_HIGH,
|
||||
|
||||
C_INVALID,
|
||||
C_INCOMPLETE,
|
||||
@ -387,6 +392,8 @@ protected:
|
||||
void read_id_start(floppy_info &fi);
|
||||
void read_id_continue(floppy_info &fi);
|
||||
|
||||
void scan_start(floppy_info &fi);
|
||||
|
||||
void general_continue(floppy_info &fi);
|
||||
void index_callback(floppy_image_device *floppy, int state);
|
||||
bool sector_matches() const;
|
||||
|
@ -174,8 +174,8 @@ void x68k_state::device_timer(emu_timer &timer, device_timer_id id, int param, v
|
||||
x68k_crtc_vblank_irq(ptr, param);
|
||||
break;
|
||||
case TIMER_X68K_FDC_TC:
|
||||
m_fdc.fdc->tc_w(ASSERT_LINE);
|
||||
m_fdc.fdc->tc_w(CLEAR_LINE);
|
||||
m_upd72065->tc_w(ASSERT_LINE);
|
||||
m_upd72065->tc_w(CLEAR_LINE);
|
||||
break;
|
||||
case TIMER_X68K_ADPCM:
|
||||
m_hd63450->drq3_w(1);
|
||||
@ -629,53 +629,38 @@ WRITE16_MEMBER(x68k_state::x68k_fdc_w)
|
||||
x = data & 0x0f;
|
||||
for(drive=0;drive<4;drive++)
|
||||
{
|
||||
if(m_fdc.selected_drive & (1 << drive))
|
||||
if(m_fdc.control_drives & (1 << drive))
|
||||
{
|
||||
if(!(x & (1 << drive))) // functions take place on 1->0 transitions of drive bits only
|
||||
{
|
||||
m_fdc.led_ctrl[drive] = data & 0x80; // blinking drive LED if no disk inserted
|
||||
m_fdc.led_eject[drive] = data & 0x40; // eject button LED (on when set to 0)
|
||||
output_set_indexed_value("eject_drv",drive,(data & 0x40) ? 1 : 0);
|
||||
if(data & 0x20) // ejects disk
|
||||
{
|
||||
m_fdc.floppy[drive]->mon_w(true);
|
||||
if((data & 0x60) == 0x20) // ejects disk
|
||||
m_fdc.floppy[drive]->unload();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_fdc.selected_drive = data & 0x0f;
|
||||
m_fdc.control_drives = data & 0x0f;
|
||||
logerror("FDC: signal control set to %02x\n",data);
|
||||
break;
|
||||
case 0x01: {
|
||||
static const int rates[4] = { 500000, 300000, 250000, 125000 };
|
||||
m_fdc.fdc->set_rate(rates[(data >> 4) & 3]);
|
||||
m_fdc.motor[data & 0x03] = data & 0x80;
|
||||
m_fdc.floppy[data & 0x03]->mon_w(!BIT(data, 7));
|
||||
if(data & 0x80)
|
||||
{
|
||||
for(drive=0;drive<4;drive++) // enable motor for this drive
|
||||
{
|
||||
if(drive == (data & 0x03))
|
||||
{
|
||||
m_fdc.floppy[drive]->mon_w(false);
|
||||
output_set_indexed_value("access_drv",drive,0);
|
||||
}
|
||||
else
|
||||
output_set_indexed_value("access_drv",drive,1);
|
||||
}
|
||||
}
|
||||
else // BIOS code suggests that setting bit 7 of this port to 0 disables the motor of all floppy drives
|
||||
{
|
||||
for(drive=0;drive<4;drive++)
|
||||
{
|
||||
m_fdc.floppy[drive]->mon_w(true);
|
||||
output_set_indexed_value("access_drv",drive,1);
|
||||
}
|
||||
}
|
||||
logerror("FDC: Drive #%i: Drive selection set to %02x\n",data & 0x03,data);
|
||||
x = data & 3;
|
||||
m_upd72065->set_floppy(m_fdc.floppy[x]);
|
||||
m_upd72065->set_rate((data & 0x10) ? 300000 : 500000);
|
||||
m_fdc.motor = data & 0x80;
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
if(m_fdc.floppy[i]->exists())
|
||||
m_fdc.floppy[i]->mon_w(!BIT(data, 7));
|
||||
|
||||
output_set_indexed_value("access_drv",x,0);
|
||||
if(x != m_fdc.select_drive)
|
||||
output_set_indexed_value("access_drv",m_fdc.select_drive,1);
|
||||
m_fdc.select_drive = x;
|
||||
logerror("FDC: Drive #%i: Drive selection set to %02x\n",x,data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -690,7 +675,7 @@ READ16_MEMBER(x68k_state::x68k_fdc_r)
|
||||
ret = 0x00;
|
||||
for(x=0;x<4;x++)
|
||||
{
|
||||
if(m_fdc.selected_drive & (1 << x))
|
||||
if(m_fdc.control_drives & (1 << x))
|
||||
{
|
||||
ret = 0x00;
|
||||
if(m_fdc.floppy[x]->exists())
|
||||
@ -722,16 +707,6 @@ WRITE_LINE_MEMBER( x68k_state::fdc_irq )
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER(x68k_state::fdc_read_byte)
|
||||
{
|
||||
return m_fdc.fdc->dma_r();
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(x68k_state::fdc_write_byte)
|
||||
{
|
||||
return m_fdc.fdc->dma_w(data);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(x68k_state::x68k_fm_w)
|
||||
{
|
||||
switch(offset)
|
||||
@ -756,7 +731,14 @@ WRITE8_MEMBER(x68k_state::x68k_ct_w)
|
||||
// CT1 and CT2 bits from YM2151 port 0x1b
|
||||
// CT1 - ADPCM clock - 0 = 8MHz, 1 = 4MHz
|
||||
// CT2 - 1 = Set ready state of FDC
|
||||
m_fdc.fdc->ready_w(data & 0x01);
|
||||
if(data & 1)
|
||||
{
|
||||
m_upd72065->set_ready_line_connected(0);
|
||||
m_upd72065->ready_w(0);
|
||||
}
|
||||
else
|
||||
m_upd72065->set_ready_line_connected(1);
|
||||
|
||||
m_adpcm.clock = data & 0x02;
|
||||
x68k_set_adpcm();
|
||||
m_okim6258->set_clock(data & 0x02 ? 4000000 : 8000000);
|
||||
@ -1459,8 +1441,9 @@ static INPUT_PORTS_START( x68000 )
|
||||
|
||||
INPUT_PORTS_END
|
||||
|
||||
void x68k_state::floppy_load_unload()
|
||||
void x68k_state::floppy_load_unload(bool load, floppy_image_device *dev)
|
||||
{
|
||||
dev->mon_w(m_fdc.motor && !load);
|
||||
if(m_ioc.irqstatus & 0x02)
|
||||
{
|
||||
m_current_vector[1] = 0x61;
|
||||
@ -1473,13 +1456,13 @@ void x68k_state::floppy_load_unload()
|
||||
|
||||
int x68k_state::floppy_load(floppy_image_device *dev)
|
||||
{
|
||||
floppy_load_unload();
|
||||
floppy_load_unload(true, dev);
|
||||
return IMAGE_INIT_PASS;
|
||||
}
|
||||
|
||||
void x68k_state::floppy_unload(floppy_image_device *dev)
|
||||
{
|
||||
floppy_load_unload();
|
||||
floppy_load_unload(false, dev);
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(x68k_state::x68k_net_irq)
|
||||
@ -1564,6 +1547,7 @@ MACHINE_RESET_MEMBER(x68k_state,x68000)
|
||||
output_set_indexed_value("ctrl_drv",drive,1);
|
||||
output_set_indexed_value("access_drv",drive,1);
|
||||
}
|
||||
m_fdc.select_drive = 0;
|
||||
|
||||
// reset CPU
|
||||
m_maincpu->reset();
|
||||
@ -1584,20 +1568,18 @@ MACHINE_START_MEMBER(x68k_state,x68000)
|
||||
// start LED timer
|
||||
m_led_timer->adjust(attotime::zero, 0, attotime::from_msec(400));
|
||||
|
||||
// check for disks
|
||||
m_fdc.fdc = machine().device<upd72065_device>("upd72065");
|
||||
|
||||
for(int drive=0;drive<4;drive++)
|
||||
{
|
||||
char devname[16];
|
||||
sprintf(devname, "%d", drive);
|
||||
floppy_image_device *floppy = m_fdc.fdc->subdevice<floppy_connector>(devname)->get_device();
|
||||
floppy_image_device *floppy = m_upd72065->subdevice<floppy_connector>(devname)->get_device();
|
||||
m_fdc.floppy[drive] = floppy;
|
||||
if(floppy) {
|
||||
floppy->setup_load_cb(floppy_image_device::load_cb(FUNC(x68k_state::floppy_load), this));
|
||||
floppy->setup_unload_cb(floppy_image_device::unload_cb(FUNC(x68k_state::floppy_unload), this));
|
||||
}
|
||||
}
|
||||
m_fdc.motor = 0;
|
||||
}
|
||||
|
||||
DRIVER_INIT_MEMBER(x68k_state,x68000)
|
||||
@ -1696,12 +1678,12 @@ static MACHINE_CONFIG_START( x68000, x68k_state )
|
||||
|
||||
MCFG_DEVICE_ADD("hd63450", HD63450, 0)
|
||||
MCFG_HD63450_CPU("maincpu") // CPU - 68000
|
||||
MCFG_HD63450_CLOCKS(attotime::from_usec(32), attotime::from_nsec(450), attotime::from_usec(4), attotime::from_hz(15625/2))
|
||||
MCFG_HD63450_BURST_CLOCKS(attotime::from_usec(32), attotime::from_nsec(450), attotime::from_nsec(50), attotime::from_nsec(50))
|
||||
MCFG_HD63450_CLOCKS(attotime::from_usec(2), attotime::from_nsec(450), attotime::from_usec(4), attotime::from_hz(15625/2))
|
||||
MCFG_HD63450_BURST_CLOCKS(attotime::from_usec(2), attotime::from_nsec(450), attotime::from_nsec(50), attotime::from_nsec(50))
|
||||
MCFG_HD63450_DMA_END_CB(WRITE8(x68k_state, dma_end))
|
||||
MCFG_HD63450_DMA_ERROR_CB(WRITE8(x68k_state, dma_error))
|
||||
MCFG_HD63450_DMA_READ_0_CB(READ8(x68k_state, fdc_read_byte))
|
||||
MCFG_HD63450_DMA_WRITE_0_CB(WRITE8(x68k_state, fdc_write_byte))
|
||||
MCFG_HD63450_DMA_READ_0_CB(DEVREAD8("upd72065", upd72065_device, mdma_r))
|
||||
MCFG_HD63450_DMA_WRITE_0_CB(DEVWRITE8("upd72065", upd72065_device, mdma_w))
|
||||
|
||||
MCFG_DEVICE_ADD("scc", SCC8530, 5000000)
|
||||
|
||||
@ -1741,7 +1723,7 @@ static MACHINE_CONFIG_START( x68000, x68k_state )
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.50)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.50)
|
||||
|
||||
MCFG_UPD72065_ADD("upd72065", true, true)
|
||||
MCFG_UPD72065_ADD("upd72065", true, false)
|
||||
MCFG_UPD765_INTRQ_CALLBACK(WRITELINE(x68k_state, fdc_irq))
|
||||
MCFG_UPD765_DRQ_CALLBACK(DEVWRITELINE("hd63450", hd63450_device, drq0_w))
|
||||
MCFG_FLOPPY_DRIVE_ADD("upd72065:0", x68k_floppies, "525hd", x68k_state::floppy_formats)
|
||||
|
@ -61,6 +61,7 @@ public:
|
||||
m_ym2151(*this, "ym2151"),
|
||||
m_ppi(*this, "ppi8255"),
|
||||
m_screen(*this, "screen"),
|
||||
m_upd72065(*this, "upd72065"),
|
||||
m_options(*this, "options"),
|
||||
m_mouse1(*this, "mouse1"),
|
||||
m_mouse2(*this, "mouse2"),
|
||||
@ -91,6 +92,7 @@ public:
|
||||
required_device<ym2151_device> m_ym2151;
|
||||
required_device<i8255_device> m_ppi;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<upd72065_device> m_upd72065;
|
||||
|
||||
required_ioport m_options;
|
||||
required_ioport m_mouse1;
|
||||
@ -112,7 +114,7 @@ public:
|
||||
bitmap_ind16 *m_pcgbitmap;
|
||||
bitmap_ind16 *m_gfxbitmap;
|
||||
|
||||
void floppy_load_unload();
|
||||
void floppy_load_unload(bool load, floppy_image_device *dev);
|
||||
int floppy_load(floppy_image_device *dev);
|
||||
void floppy_unload(floppy_image_device *dev);
|
||||
DECLARE_FLOPPY_FORMATS( floppy_formats );
|
||||
@ -127,13 +129,13 @@ public:
|
||||
} m_sysport;
|
||||
struct
|
||||
{
|
||||
upd72065_device *fdc;
|
||||
floppy_image_device *floppy[4];
|
||||
int led_ctrl[4];
|
||||
int led_eject[4];
|
||||
int eject[4];
|
||||
int motor[4];
|
||||
int selected_drive;
|
||||
int motor;
|
||||
int control_drives;
|
||||
int select_drive;
|
||||
} m_fdc;
|
||||
struct
|
||||
{
|
||||
@ -283,8 +285,6 @@ public:
|
||||
void dma_irq(int channel);
|
||||
DECLARE_WRITE8_MEMBER(dma_end);
|
||||
DECLARE_WRITE8_MEMBER(dma_error);
|
||||
DECLARE_READ8_MEMBER(fdc_read_byte);
|
||||
DECLARE_WRITE8_MEMBER(fdc_write_byte);
|
||||
|
||||
int x68k_read_mouse();
|
||||
void x68k_set_adpcm();
|
||||
|
@ -733,7 +733,7 @@ void x68k_state::x68k_draw_text(bitmap_rgb32 &bitmap, int xscr, int yscr, rectan
|
||||
+ (((m_tvram[loc+0x20000] >> bit) & 0x01) ? 4 : 0)
|
||||
+ (((m_tvram[loc+0x30000] >> bit) & 0x01) ? 8 : 0);
|
||||
// Colour 0 is displayable if the text layer is at the priority level 2
|
||||
if((colour && (m_pcgpalette->pen(colour) & 0xffffff)) || ((m_video.reg[1] & 0x0c00) == 0x0800))
|
||||
if((m_pcgpalette->pen(colour) & 0xffffff) || ((m_video.reg[1] & 0x0c00) == 0x0800))
|
||||
bitmap.pix32(line, pixel) = m_pcgpalette->pen(colour);
|
||||
bit--;
|
||||
if(bit < 0)
|
||||
|
Loading…
Reference in New Issue
Block a user