wd_fdc: fm support, need to review all timings [O. Galibert]

This commit is contained in:
Olivier Galibert 2012-12-01 10:28:18 +00:00
parent 9d31473f19
commit e28869ccfa
7 changed files with 457 additions and 146 deletions

View File

@ -1,5 +1,16 @@
#include "fdc_pll.h" #include "fdc_pll.h"
astring fdc_pll_t::tts(attotime t)
{
char buf[256];
bool neg = t.seconds < 0;
if(neg)
t = attotime::zero - t;
int nsec = t.attoseconds / ATTOSECONDS_PER_NANOSECOND;
sprintf(buf, "%c%3d.%03d,%03d,%03d", neg ? '-' : ' ', int(t.seconds), nsec/1000000, (nsec/1000)%1000, nsec % 1000);
return buf;
}
void fdc_pll_t::set_clock(attotime _period) void fdc_pll_t::set_clock(attotime _period)
{ {
period = _period; period = _period;

View File

@ -24,6 +24,8 @@ public:
void start_writing(attotime tm); void start_writing(attotime tm);
void commit(floppy_image_device *floppy, attotime tm); void commit(floppy_image_device *floppy, attotime tm);
void stop_writing(floppy_image_device *floppy, attotime tm); void stop_writing(floppy_image_device *floppy, attotime tm);
astring tts(attotime tm);
}; };
#endif #endif

View File

@ -69,7 +69,7 @@ void wd_fdc_t::device_start()
t_cmd = timer_alloc(TM_CMD); t_cmd = timer_alloc(TM_CMD);
t_track = timer_alloc(TM_TRACK); t_track = timer_alloc(TM_TRACK);
t_sector = timer_alloc(TM_SECTOR); t_sector = timer_alloc(TM_SECTOR);
dden = false; dden = disable_mfm;
floppy = 0; floppy = 0;
save_item(NAME(status)); save_item(NAME(status));
@ -148,7 +148,15 @@ void wd_fdc_t::setup_enp_cb(line_cb cb)
void wd_fdc_t::dden_w(bool _dden) void wd_fdc_t::dden_w(bool _dden)
{ {
dden = _dden; if(disable_mfm) {
logerror("%s: Error, this chip does not have a dden line\n", tag());
return;
}
if(dden != _dden) {
dden = _dden;
logerror("%s: select %s\n", tag(), dden ? "fm" : "mfm");
}
} }
astring wd_fdc_t::tts(attotime t) astring wd_fdc_t::tts(attotime t)
@ -333,6 +341,11 @@ void wd_fdc_t::seek_continue()
bool wd_fdc_t::sector_matches() const bool wd_fdc_t::sector_matches() const
{ {
if(0)
logerror("%s: matching %02x %02x %02x %02x - %02x %02x\n", tag(),
cur_live.idbuf[0], cur_live.idbuf[1], cur_live.idbuf[2], cur_live.idbuf[3],
track, sector);
if(cur_live.idbuf[0] != track || cur_live.idbuf[2] != sector) if(cur_live.idbuf[0] != track || cur_live.idbuf[2] != sector)
return false; return false;
if(!side_compare || (command & 2)) if(!side_compare || (command & 2))
@ -357,7 +370,7 @@ void wd_fdc_t::read_sector_start()
status = (status & ~(S_CRC|S_LOST|S_RNF|S_WP|S_DDM)) | S_BUSY; status = (status & ~(S_CRC|S_LOST|S_RNF|S_WP|S_DDM)) | S_BUSY;
drop_drq(); drop_drq();
if(side_control && floppy) if(side_control && floppy)
floppy->ss_w(command & 0x02); floppy->ss_w((command & 0x02) ? 1 : 0);
sub_state = motor_control ? SPINUP : SPINUP_DONE; sub_state = motor_control ? SPINUP : SPINUP_DONE;
status_type_1 = false; status_type_1 = false;
read_sector_continue(); read_sector_continue();
@ -447,7 +460,7 @@ void wd_fdc_t::read_track_start()
status = (status & ~(S_LOST|S_RNF)) | S_BUSY; status = (status & ~(S_LOST|S_RNF)) | S_BUSY;
drop_drq(); drop_drq();
if(side_control && floppy) if(side_control && floppy)
floppy->ss_w(command & 0x02); floppy->ss_w((command & 0x02) ? 1 : 0);
sub_state = motor_control ? SPINUP : SPINUP_DONE; sub_state = motor_control ? SPINUP : SPINUP_DONE;
status_type_1 = false; status_type_1 = false;
read_track_continue(); read_track_continue();
@ -514,7 +527,7 @@ void wd_fdc_t::read_id_start()
status = (status & ~(S_WP|S_DDM|S_LOST|S_RNF)) | S_BUSY; status = (status & ~(S_WP|S_DDM|S_LOST|S_RNF)) | S_BUSY;
drop_drq(); drop_drq();
if(side_control && floppy) if(side_control && floppy)
floppy->ss_w(command & 0x02); floppy->ss_w((command & 0x02) ? 1 : 0);
sub_state = motor_control ? SPINUP : SPINUP_DONE; sub_state = motor_control ? SPINUP : SPINUP_DONE;
status_type_1 = false; status_type_1 = false;
read_id_continue(); read_id_continue();
@ -579,7 +592,7 @@ void wd_fdc_t::write_track_start()
status = (status & ~(S_WP|S_DDM|S_LOST|S_RNF)) | S_BUSY; status = (status & ~(S_WP|S_DDM|S_LOST|S_RNF)) | S_BUSY;
drop_drq(); drop_drq();
if(side_control && floppy) if(side_control && floppy)
floppy->ss_w(command & 0x02); floppy->ss_w((command & 0x02) ? 1 : 0);
sub_state = motor_control ? SPINUP : SPINUP_DONE; sub_state = motor_control ? SPINUP : SPINUP_DONE;
status_type_1 = false; status_type_1 = false;
@ -654,7 +667,7 @@ void wd_fdc_t::write_track_continue()
sprintf(buf, "%02x", format_last_byte); sprintf(buf, "%02x", format_last_byte);
format_description_string += buf; format_description_string += buf;
} }
logerror("wd1772: track description %s\n", format_description_string.cstr()); logerror("%s: track description %s\n", tag(), format_description_string.cstr());
command_end(); command_end();
return; return;
@ -675,7 +688,7 @@ void wd_fdc_t::write_sector_start()
status = (status & ~(S_CRC|S_LOST|S_RNF|S_WP|S_DDM)) | S_BUSY; status = (status & ~(S_CRC|S_LOST|S_RNF|S_WP|S_DDM)) | S_BUSY;
drop_drq(); drop_drq();
if(side_control && floppy) if(side_control && floppy)
floppy->ss_w(command & 0x02); floppy->ss_w((command & 0x02) ? 1 : 0);
sub_state = motor_control ? SPINUP : SPINUP_DONE; sub_state = motor_control ? SPINUP : SPINUP_DONE;
status_type_1 = false; status_type_1 = false;
write_sector_continue(); write_sector_continue();
@ -859,17 +872,17 @@ void wd_fdc_t::do_cmd_w()
cmd_buffer = -1; cmd_buffer = -1;
switch(command & 0xf0) { switch(command & 0xf0) {
case 0x00: logerror("wd1772: restore\n"); last_dir = 1; seek_start(RESTORE); break; case 0x00: logerror("%s: restore\n", tag()); last_dir = 1; seek_start(RESTORE); break;
case 0x10: logerror("wd1772: seek %d\n", data); last_dir = data > track ? 0 : 1; seek_start(SEEK); break; case 0x10: logerror("%s: seek %d\n", tag(), data); last_dir = data > track ? 0 : 1; seek_start(SEEK); break;
case 0x20: case 0x30: logerror("wd1772: step\n"); seek_start(STEP); break; case 0x20: case 0x30: logerror("%s: step\n", tag()); seek_start(STEP); break;
case 0x40: case 0x50: logerror("wd1772: step +\n"); last_dir = 0; seek_start(STEP); break; case 0x40: case 0x50: logerror("%s: step +\n", tag()); last_dir = 0; seek_start(STEP); break;
case 0x60: case 0x70: logerror("wd1772: step -\n"); last_dir = 1; seek_start(STEP); break; case 0x60: case 0x70: logerror("%s: step -\n", tag()); last_dir = 1; seek_start(STEP); break;
case 0x80: case 0x90: logerror("wd1772: read sector%s %d, %d\n", command & 0x10 ? " multiple" : "", track, sector); read_sector_start(); break; case 0x80: case 0x90: logerror("%s: read sector%s %d, %d - %02x\n", tag(), command & 0x10 ? " multiple" : "", track, sector, command); read_sector_start(); break;
case 0xa0: case 0xb0: logerror("wd1772: write sector%s %d, %d\n", command & 0x10 ? " multiple" : "", track, sector); write_sector_start(); break; case 0xa0: case 0xb0: logerror("%s: write sector%s %d, %d\n", tag(), command & 0x10 ? " multiple" : "", track, sector); write_sector_start(); break;
case 0xc0: logerror("wd1772: read id\n"); read_id_start(); break; case 0xc0: logerror("%s: read id\n", tag()); read_id_start(); break;
case 0xd0: logerror("wd1772: interrupt\n"); interrupt_start(); break; case 0xd0: logerror("%s: interrupt\n", tag()); interrupt_start(); break;
case 0xe0: logerror("wd1772: read track %d\n", track); read_track_start(); break; case 0xe0: logerror("%s: read track %d\n", tag(), track); read_track_start(); break;
case 0xf0: logerror("wd1772: write track %d\n", track); write_track_start(); break; case 0xf0: logerror("%s: write track %d\n", tag(), track); write_track_start(); break;
} }
} }
@ -877,8 +890,6 @@ void wd_fdc_t::cmd_w(UINT8 val)
{ {
if (inverted_bus) val ^= 0xff; if (inverted_bus) val ^= 0xff;
logerror("wd1772 cmd: %02x\n", val);
if(intrq && !(intrq_cond & I_IMM)) { if(intrq && !(intrq_cond & I_IMM)) {
intrq = false; intrq = false;
if(!intrq_cb.isnull()) if(!intrq_cb.isnull())
@ -891,7 +902,7 @@ void wd_fdc_t::cmd_w(UINT8 val)
cmd_buffer = val; cmd_buffer = val;
delay_cycles(t_cmd, dden ? 192 : 46); delay_cycles(t_cmd, dden ? 1 : 1);
} }
UINT8 wd_fdc_t::status_r() UINT8 wd_fdc_t::status_r()
@ -952,7 +963,7 @@ void wd_fdc_t::track_w(UINT8 val)
return; return;
track_buffer = val; track_buffer = val;
delay_cycles(t_track, dden ? 64 : 32); delay_cycles(t_track, dden ? 32 : 16);
} }
UINT8 wd_fdc_t::track_r() UINT8 wd_fdc_t::track_r()
@ -978,7 +989,7 @@ void wd_fdc_t::sector_w(UINT8 val)
return; return;
sector_buffer = val; sector_buffer = val;
delay_cycles(t_sector, dden ? 64 : 32); delay_cycles(t_sector, dden ? 32 : 16);
} }
UINT8 wd_fdc_t::sector_r() UINT8 wd_fdc_t::sector_r()
@ -1166,7 +1177,7 @@ void wd_fdc_t::live_start(int state)
cur_live.previous_type = live_info::PT_NONE; cur_live.previous_type = live_info::PT_NONE;
cur_live.data_bit_context = false; cur_live.data_bit_context = false;
cur_live.byte_counter = 0; cur_live.byte_counter = 0;
pll_reset(cur_live.tm); pll_reset(dden, cur_live.tm);
checkpoint_live = cur_live; checkpoint_live = cur_live;
pll_save_checkpoint(); pll_save_checkpoint();
@ -1196,12 +1207,12 @@ void wd_fdc_t::live_sync()
{ {
if(!cur_live.tm.is_never()) { if(!cur_live.tm.is_never()) {
if(cur_live.tm > machine().time()) { if(cur_live.tm > machine().time()) {
// fprintf(stderr, "%s: Rolling back and replaying (%s)\n", ttsn().cstr(), tts(cur_live.tm).cstr()); // fprintf(stderr, "%s: Rolling back and replaying (%s)\n", ttsn().cstr(), tts(cur_live.tm).cstr());
rollback(); rollback();
live_run(machine().time()); live_run(machine().time());
pll_commit(floppy, cur_live.tm); pll_commit(floppy, cur_live.tm);
} else { } else {
// fprintf(stderr, "%s: Committing (%s)\n", ttsn().cstr(), tts(cur_live.tm).cstr()); // fprintf(stderr, "%s: Committing (%s)\n", ttsn().cstr(), tts(cur_live.tm).cstr());
pll_commit(floppy, cur_live.tm); pll_commit(floppy, cur_live.tm);
if(cur_live.next_state != -1) { if(cur_live.next_state != -1) {
cur_live.state = cur_live.next_state; cur_live.state = cur_live.next_state;
@ -1288,6 +1299,19 @@ void wd_fdc_t::live_write_mfm(UINT8 mfm)
// logerror("write %02x %04x %04x\n", mfm, cur_live.crc, raw); // logerror("write %02x %04x %04x\n", mfm, cur_live.crc, raw);
} }
void wd_fdc_t::live_write_fm(UINT8 fm)
{
UINT16 raw = 0xaaaa;
for(int i=0; i<8; i++)
if(fm & (0x80 >> i))
raw |= 0x4000 >> (2*i);
cur_live.data_reg = fm;
cur_live.shift_reg = raw;
cur_live.data_bit_context = fm & 1;
// logerror("write %02x %04x %04x\n", fm, cur_live.crc, raw);
}
void wd_fdc_t::live_run(attotime limit) void wd_fdc_t::live_run(attotime limit)
{ {
if(cur_live.state == IDLE || cur_live.next_state != -1) if(cur_live.state == IDLE || cur_live.next_state != -1)
@ -1328,12 +1352,22 @@ void wd_fdc_t::live_run(attotime limit)
cur_live.bit_counter); cur_live.bit_counter);
#endif #endif
if(cur_live.shift_reg == 0x4489) { if(!dden && cur_live.shift_reg == 0x4489) {
cur_live.crc = 0x443b; cur_live.crc = 0x443b;
cur_live.data_separator_phase = false; cur_live.data_separator_phase = false;
cur_live.bit_counter = 0; cur_live.bit_counter = 0;
cur_live.state = READ_HEADER_BLOCK_HEADER; cur_live.state = READ_HEADER_BLOCK_HEADER;
} }
if(dden && (cur_live.shift_reg == 0xf57e || cur_live.shift_reg == 0xf57e)) {
cur_live.crc = cur_live.shift_reg == 0xf57e ? 0xef21 : 0xff00;
cur_live.data_separator_phase = false;
cur_live.bit_counter = 0;
if(main_state == READ_ID)
cur_live.state = READ_ID_BLOCK_TO_DMA;
else
cur_live.state = READ_ID_BLOCK_TO_LOCAL;
}
break; break;
case READ_HEADER_BLOCK_HEADER: { case READ_HEADER_BLOCK_HEADER: {
@ -1382,6 +1416,7 @@ void wd_fdc_t::live_run(attotime limit)
if(cur_live.bit_counter & 15) if(cur_live.bit_counter & 15)
break; break;
int slot = (cur_live.bit_counter >> 4)-1; int slot = (cur_live.bit_counter >> 4)-1;
// fprintf(stderr, "%s: slot[%d] = %02x crc = %04x\n", tts(cur_live.tm).cstr(), slot, cur_live.data_reg, cur_live.crc);
cur_live.idbuf[slot] = cur_live.data_reg; cur_live.idbuf[slot] = cur_live.data_reg;
if(slot == 5) { if(slot == 5) {
live_delay(IDLE); live_delay(IDLE);
@ -1430,16 +1465,35 @@ void wd_fdc_t::live_run(attotime limit)
(cur_live.shift_reg & 0x0001 ? 0x01 : 0x00), (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
cur_live.bit_counter >> 4, cur_live.bit_counter & 15); cur_live.bit_counter >> 4, cur_live.bit_counter & 15);
#endif #endif
if(cur_live.bit_counter > 43*16) { if(!dden) {
live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED); if(cur_live.bit_counter > 43*16) {
return; live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
} return;
}
if(cur_live.bit_counter >= 28*16 && cur_live.shift_reg == 0x4489) { if(cur_live.bit_counter >= 28*16 && cur_live.shift_reg == 0x4489) {
cur_live.crc = 0x443b; cur_live.crc = 0x443b;
cur_live.data_separator_phase = false; cur_live.data_separator_phase = false;
cur_live.bit_counter = 0; cur_live.bit_counter = 0;
cur_live.state = READ_DATA_BLOCK_HEADER; cur_live.state = READ_DATA_BLOCK_HEADER;
}
} else {
if(cur_live.bit_counter > 23*16) {
live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
return;
}
if(cur_live.bit_counter >= 11*16 && (cur_live.shift_reg == 0xf56a || cur_live.shift_reg == 0xf56b ||
cur_live.shift_reg == 0xf56e || cur_live.shift_reg == 0xf56f)) {
cur_live.crc =
cur_live.shift_reg == 0xf56a ? 0x8fe7 :
cur_live.shift_reg == 0xf56b ? 0x9fc6 :
cur_live.shift_reg == 0xf56e ? 0xafa5 :
0xbf84;
cur_live.data_separator_phase = false;
cur_live.bit_counter = 0;
cur_live.state = READ_SECTOR_DATA;
}
} }
break; break;
@ -1570,29 +1624,77 @@ void wd_fdc_t::live_run(attotime limit)
} else } else
format_last_byte_count++; format_last_byte_count++;
switch(data) { if(dden) {
case 0xf5: switch(data) {
live_write_raw(0x4489); case 0xf7:
cur_live.crc = 0x968b; // Ensures that the crc is cdb4 after writing the byte if(cur_live.previous_type == live_info::PT_CRC_2) {
cur_live.previous_type = live_info::PT_NONE; cur_live.previous_type = live_info::PT_NONE;
break; live_write_fm(0xf7);
case 0xf6: } else {
cur_live.previous_type = live_info::PT_NONE; cur_live.previous_type = live_info::PT_CRC_1;
live_write_raw(0x5224); live_write_fm(cur_live.crc >> 8);
break; }
case 0xf7: break;
if(cur_live.previous_type == live_info::PT_CRC_2) { case 0xf8:
live_write_raw(0xf56a);
cur_live.crc = 0xffff;
cur_live.previous_type = live_info::PT_NONE; cur_live.previous_type = live_info::PT_NONE;
live_write_mfm(0xf7); break;
} else { case 0xf9:
cur_live.previous_type = live_info::PT_CRC_1; live_write_raw(0xf56b);
live_write_mfm(cur_live.crc >> 8); cur_live.crc = 0xffff;
cur_live.previous_type = live_info::PT_NONE;
break;
case 0xfa:
live_write_raw(0xf56e);
cur_live.crc = 0xffff;
cur_live.previous_type = live_info::PT_NONE;
break;
case 0xfb:
live_write_raw(0xf56f);
cur_live.crc = 0xffff;
cur_live.previous_type = live_info::PT_NONE;
break;
case 0xfc:
live_write_raw(0xcf63);
cur_live.previous_type = live_info::PT_NONE;
break;
case 0xfe:
live_write_raw(0xf57e);
cur_live.crc = 0xffff;
cur_live.previous_type = live_info::PT_NONE;
break;
default:
cur_live.previous_type = live_info::PT_NONE;
live_write_fm(data);
break;
}
} else {
switch(data) {
case 0xf5:
live_write_raw(0x4489);
cur_live.crc = 0x968b; // Ensures that the crc is cdb4 after writing the byte
cur_live.previous_type = live_info::PT_NONE;
break;
case 0xf6:
cur_live.previous_type = live_info::PT_NONE;
live_write_raw(0x5224);
break;
case 0xf7:
if(cur_live.previous_type == live_info::PT_CRC_2) {
cur_live.previous_type = live_info::PT_NONE;
live_write_mfm(0xf7);
} else {
cur_live.previous_type = live_info::PT_CRC_1;
live_write_mfm(cur_live.crc >> 8);
}
break;
default:
cur_live.previous_type = live_info::PT_NONE;
live_write_mfm(data);
break;
} }
break;
default:
cur_live.previous_type = live_info::PT_NONE;
live_write_mfm(data);
break;
} }
set_drq(); set_drq();
cur_live.state = WRITE_BYTE; cur_live.state = WRITE_BYTE;
@ -1614,7 +1716,10 @@ void wd_fdc_t::live_run(attotime limit)
case TRACK_DONE: case TRACK_DONE:
if(cur_live.previous_type == live_info::PT_CRC_1) { if(cur_live.previous_type == live_info::PT_CRC_1) {
cur_live.previous_type = live_info::PT_CRC_2; cur_live.previous_type = live_info::PT_CRC_2;
live_write_mfm(cur_live.crc >> 8); if(dden)
live_write_fm(cur_live.crc >> 8);
else
live_write_mfm(cur_live.crc >> 8);
cur_live.state = WRITE_BYTE; cur_live.state = WRITE_BYTE;
cur_live.bit_counter = 16; cur_live.bit_counter = 16;
checkpoint(); checkpoint();
@ -1626,39 +1731,70 @@ void wd_fdc_t::live_run(attotime limit)
cur_live.state = WRITE_BYTE; cur_live.state = WRITE_BYTE;
cur_live.bit_counter = 16; cur_live.bit_counter = 16;
cur_live.byte_counter++; cur_live.byte_counter++;
if(cur_live.byte_counter <= 11)
live_write_mfm(0x00); if(dden) {
else if(cur_live.byte_counter == 12) { if(cur_live.byte_counter < 6)
cur_live.crc = 0xffff; live_write_fm(0x00);
live_write_raw(0x4489); else if(cur_live.byte_counter < 7) {
} else if(cur_live.byte_counter <= 14) cur_live.crc = 0xffff;
live_write_raw(0x4489); live_write_raw(command & 1 ? 0xf56a : 0xf56f);
else if(cur_live.byte_counter == 15) } else if(cur_live.byte_counter < sector_size + 7-1) {
live_write_mfm(command & 1 ? 0xf8 : 0xfb); if(drq) {
else if(cur_live.byte_counter <= sector_size + 16-2) { status |= S_LOST;
if(drq) { data = 0;
status |= S_LOST; }
data = 0; live_write_fm(data);
set_drq();
} else if(cur_live.byte_counter < sector_size + 7) {
if(drq) {
status |= S_LOST;
data = 0;
}
live_write_fm(data);
} else if(cur_live.byte_counter < sector_size + 7+2)
live_write_fm(cur_live.crc >> 8);
else if(cur_live.byte_counter < sector_size + 7+3)
live_write_fm(0xff);
else {
pll_stop_writing(floppy, cur_live.tm);
cur_live.state = IDLE;
return;
} }
live_write_mfm(data);
set_drq(); } else {
} else if(cur_live.byte_counter == sector_size + 16-1) { if(cur_live.byte_counter < 12)
if(drq) { live_write_mfm(0x00);
status |= S_LOST; else if(cur_live.byte_counter < 15)
data = 0; live_write_raw(0x4489);
else if(cur_live.byte_counter < 16) {
cur_live.crc = 0xcdb4;
live_write_mfm(command & 1 ? 0xf8 : 0xfb);
} else if(cur_live.byte_counter < sector_size + 16-1) {
if(drq) {
status |= S_LOST;
data = 0;
}
live_write_mfm(data);
set_drq();
} else if(cur_live.byte_counter < sector_size + 16) {
if(drq) {
status |= S_LOST;
data = 0;
}
live_write_mfm(data);
} else if(cur_live.byte_counter < sector_size + 16+2)
live_write_mfm(cur_live.crc >> 8);
else if(cur_live.byte_counter < sector_size + 16+3)
live_write_mfm(0xff);
else {
pll_stop_writing(floppy, cur_live.tm);
cur_live.state = IDLE;
return;
} }
live_write_mfm(data);
} else if(cur_live.byte_counter <= sector_size + 16+1)
live_write_mfm(cur_live.crc >> 8);
else if(cur_live.byte_counter == sector_size + 16+2)
// Is that correct? It seems required (try ST formatting)
live_write_mfm(0xff);
else {
pll_stop_writing(floppy, cur_live.tm);
cur_live.state = IDLE;
return;
} }
checkpoint(); checkpoint();
break; break;
@ -1693,6 +1829,18 @@ void wd_fdc_t::live_run(attotime limit)
return; return;
} }
break; break;
case 12:
if(dden) {
cur_live.state = WRITE_BYTE;
cur_live.bit_counter = 16;
cur_live.byte_counter = 0;
cur_live.data_bit_context = cur_live.data_reg & 1;
pll_start_writing(cur_live.tm);
if(dden)
live_write_fm(0x00);
}
break;
case 22: case 22:
cur_live.state = WRITE_BYTE; cur_live.state = WRITE_BYTE;
cur_live.bit_counter = 16; cur_live.bit_counter = 16;
@ -1734,7 +1882,7 @@ void wd_fdc_t::drop_drq()
int wd_fdc_t::step_time(int mode) const int wd_fdc_t::step_time(int mode) const
{ {
const static int step_times[4] = { 12000, 24000, 40000, 60000 }; const static int step_times[4] = { 12000, 24000, 40000, 60000 };
return step_times[mode]; return step_times[mode]/10;
} }
int wd_fdc_t::settle_time() const int wd_fdc_t::settle_time() const
@ -1748,10 +1896,10 @@ wd_fdc_analog_t::wd_fdc_analog_t(const machine_config &mconfig, device_type type
clock_ratio = 1; clock_ratio = 1;
} }
void wd_fdc_analog_t::pll_reset(attotime when) void wd_fdc_analog_t::pll_reset(bool fm, attotime when)
{ {
cur_pll.reset(when); cur_pll.reset(when);
cur_pll.set_clock(clocks_to_attotime(4)); cur_pll.set_clock(clocks_to_attotime(fm ? 4 : 2));
} }
void wd_fdc_analog_t::pll_start_writing(attotime tm) void wd_fdc_analog_t::pll_start_writing(attotime tm)
@ -1795,7 +1943,7 @@ wd_fdc_digital_t::wd_fdc_digital_t(const machine_config &mconfig, device_type ty
clock_ratio = 4; clock_ratio = 4;
} }
void wd_fdc_digital_t::pll_reset(attotime when) void wd_fdc_digital_t::pll_reset(bool fm, attotime when)
{ {
cur_pll.reset(when); cur_pll.reset(when);
cur_pll.set_clock(clocks_to_attotime(1)); cur_pll.set_clock(clocks_to_attotime(1));
@ -1993,6 +2141,7 @@ void wd_fdc_digital_t::digital_pll_t::commit(floppy_image_device *floppy, attoti
fd1771_t::fd1771_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1771x, "FD1771", tag, owner, clock) fd1771_t::fd1771_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1771x, "FD1771", tag, owner, clock)
{ {
disable_mfm = true;
inverted_bus = true; inverted_bus = true;
side_control = false; side_control = false;
side_compare = false; side_compare = false;
@ -2003,6 +2152,7 @@ fd1771_t::fd1771_t(const machine_config &mconfig, const char *tag, device_t *own
fd1781_t::fd1781_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1781x, "FD1781", tag, owner, clock) fd1781_t::fd1781_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1781x, "FD1781", tag, owner, clock)
{ {
disable_mfm = false;
inverted_bus = true; inverted_bus = true;
side_control = false; side_control = false;
side_compare = false; side_compare = false;
@ -2013,6 +2163,7 @@ fd1781_t::fd1781_t(const machine_config &mconfig, const char *tag, device_t *own
fd1791_t::fd1791_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1791x, "FD1791", tag, owner, clock) fd1791_t::fd1791_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1791x, "FD1791", tag, owner, clock)
{ {
disable_mfm = false;
inverted_bus = true; inverted_bus = true;
side_control = false; side_control = false;
side_compare = true; side_compare = true;
@ -2023,6 +2174,7 @@ fd1791_t::fd1791_t(const machine_config &mconfig, const char *tag, device_t *own
fd1792_t::fd1792_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1792x, "FD1792", tag, owner, clock) fd1792_t::fd1792_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1792x, "FD1792", tag, owner, clock)
{ {
disable_mfm = true;
inverted_bus = true; inverted_bus = true;
side_control = false; side_control = false;
side_compare = true; side_compare = true;
@ -2033,6 +2185,7 @@ fd1792_t::fd1792_t(const machine_config &mconfig, const char *tag, device_t *own
fd1793_t::fd1793_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1793x, "FD1793", tag, owner, clock) fd1793_t::fd1793_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1793x, "FD1793", tag, owner, clock)
{ {
disable_mfm = false;
inverted_bus = false; inverted_bus = false;
side_control = false; side_control = false;
side_compare = true; side_compare = true;
@ -2043,6 +2196,7 @@ fd1793_t::fd1793_t(const machine_config &mconfig, const char *tag, device_t *own
fd1794_t::fd1794_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1794x, "FD1794", tag, owner, clock) fd1794_t::fd1794_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1794x, "FD1794", tag, owner, clock)
{ {
disable_mfm = true;
inverted_bus = false; inverted_bus = false;
side_control = false; side_control = false;
side_compare = true; side_compare = true;
@ -2053,8 +2207,9 @@ fd1794_t::fd1794_t(const machine_config &mconfig, const char *tag, device_t *own
fd1795_t::fd1795_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1795x, "FD1795", tag, owner, clock) fd1795_t::fd1795_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1795x, "FD1795", tag, owner, clock)
{ {
disable_mfm = false;
inverted_bus = true; inverted_bus = true;
side_control = false; side_control = true;
side_compare = false; side_compare = false;
head_control = true; head_control = true;
motor_control = false; motor_control = false;
@ -2063,8 +2218,9 @@ fd1795_t::fd1795_t(const machine_config &mconfig, const char *tag, device_t *own
fd1797_t::fd1797_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1797x, "FD1797", tag, owner, clock) fd1797_t::fd1797_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1797x, "FD1797", tag, owner, clock)
{ {
disable_mfm = false;
inverted_bus = false; inverted_bus = false;
side_control = false; side_control = true;
side_compare = false; side_compare = false;
head_control = true; head_control = true;
motor_control = false; motor_control = false;
@ -2073,6 +2229,7 @@ fd1797_t::fd1797_t(const machine_config &mconfig, const char *tag, device_t *own
mb8866_t::mb8866_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, MB8866x, "MB8866", tag, owner, clock) mb8866_t::mb8866_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, MB8866x, "MB8866", tag, owner, clock)
{ {
disable_mfm = false;
inverted_bus = true; inverted_bus = true;
side_control = false; side_control = false;
side_compare = true; side_compare = true;
@ -2083,6 +2240,7 @@ mb8866_t::mb8866_t(const machine_config &mconfig, const char *tag, device_t *own
mb8876_t::mb8876_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, MB8876x, "MB8876", tag, owner, clock) mb8876_t::mb8876_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, MB8876x, "MB8876", tag, owner, clock)
{ {
disable_mfm = false;
inverted_bus = true; inverted_bus = true;
side_control = false; side_control = false;
side_compare = true; side_compare = true;
@ -2093,6 +2251,7 @@ mb8876_t::mb8876_t(const machine_config &mconfig, const char *tag, device_t *own
mb8877_t::mb8877_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, MB8877x, "MB8877", tag, owner, clock) mb8877_t::mb8877_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, MB8877x, "MB8877", tag, owner, clock)
{ {
disable_mfm = false;
inverted_bus = false; inverted_bus = false;
side_control = false; side_control = false;
side_compare = true; side_compare = true;
@ -2103,6 +2262,7 @@ mb8877_t::mb8877_t(const machine_config &mconfig, const char *tag, device_t *own
fd1761_t::fd1761_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1761x, "FD1761", tag, owner, clock) fd1761_t::fd1761_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1761x, "FD1761", tag, owner, clock)
{ {
disable_mfm = false;
inverted_bus = true; inverted_bus = true;
side_control = false; side_control = false;
side_compare = true; side_compare = true;
@ -2113,6 +2273,7 @@ fd1761_t::fd1761_t(const machine_config &mconfig, const char *tag, device_t *own
fd1763_t::fd1763_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1763x, "FD1763", tag, owner, clock) fd1763_t::fd1763_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1763x, "FD1763", tag, owner, clock)
{ {
disable_mfm = false;
inverted_bus = false; inverted_bus = false;
side_control = false; side_control = false;
side_compare = true; side_compare = true;
@ -2123,6 +2284,7 @@ fd1763_t::fd1763_t(const machine_config &mconfig, const char *tag, device_t *own
fd1765_t::fd1765_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1765x, "FD1765", tag, owner, clock) fd1765_t::fd1765_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1765x, "FD1765", tag, owner, clock)
{ {
disable_mfm = false;
inverted_bus = true; inverted_bus = true;
side_control = true; side_control = true;
side_compare = false; side_compare = false;
@ -2133,6 +2295,7 @@ fd1765_t::fd1765_t(const machine_config &mconfig, const char *tag, device_t *own
fd1767_t::fd1767_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1767x, "FD1767", tag, owner, clock) fd1767_t::fd1767_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1767x, "FD1767", tag, owner, clock)
{ {
disable_mfm = false;
inverted_bus = false; inverted_bus = false;
side_control = true; side_control = true;
side_compare = false; side_compare = false;
@ -2143,6 +2306,7 @@ fd1767_t::fd1767_t(const machine_config &mconfig, const char *tag, device_t *own
wd2791_t::wd2791_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, WD2791x, "WD2791", tag, owner, clock) wd2791_t::wd2791_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, WD2791x, "WD2791", tag, owner, clock)
{ {
disable_mfm = false;
inverted_bus = true; inverted_bus = true;
side_control = false; side_control = false;
side_compare = true; side_compare = true;
@ -2153,6 +2317,7 @@ wd2791_t::wd2791_t(const machine_config &mconfig, const char *tag, device_t *own
wd2793_t::wd2793_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, WD2793x, "WD2793", tag, owner, clock) wd2793_t::wd2793_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, WD2793x, "WD2793", tag, owner, clock)
{ {
disable_mfm = false;
inverted_bus = false; inverted_bus = false;
side_control = false; side_control = false;
side_compare = true; side_compare = true;
@ -2163,6 +2328,7 @@ wd2793_t::wd2793_t(const machine_config &mconfig, const char *tag, device_t *own
wd2795_t::wd2795_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, WD2795x, "WD2795", tag, owner, clock) wd2795_t::wd2795_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, WD2795x, "WD2795", tag, owner, clock)
{ {
disable_mfm = false;
inverted_bus = true; inverted_bus = true;
side_control = true; side_control = true;
side_compare = false; side_compare = false;
@ -2173,6 +2339,7 @@ wd2795_t::wd2795_t(const machine_config &mconfig, const char *tag, device_t *own
wd2797_t::wd2797_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, WD2797x, "WD2797", tag, owner, clock) wd2797_t::wd2797_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, WD2797x, "WD2797", tag, owner, clock)
{ {
disable_mfm = false;
inverted_bus = false; inverted_bus = false;
side_control = true; side_control = true;
side_compare = false; side_compare = false;
@ -2183,6 +2350,7 @@ wd2797_t::wd2797_t(const machine_config &mconfig, const char *tag, device_t *own
wd1770_t::wd1770_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_digital_t(mconfig, WD1770x, "WD1770", tag, owner, clock) wd1770_t::wd1770_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_digital_t(mconfig, WD1770x, "WD1770", tag, owner, clock)
{ {
disable_mfm = false;
inverted_bus = false; inverted_bus = false;
side_control = false; side_control = false;
side_compare = false; side_compare = false;
@ -2193,6 +2361,7 @@ wd1770_t::wd1770_t(const machine_config &mconfig, const char *tag, device_t *own
wd1772_t::wd1772_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_digital_t(mconfig, WD1772x, "WD1772", tag, owner, clock) wd1772_t::wd1772_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_digital_t(mconfig, WD1772x, "WD1772", tag, owner, clock)
{ {
disable_mfm = false;
inverted_bus = false; inverted_bus = false;
side_control = false; side_control = false;
side_compare = false; side_compare = false;
@ -2214,6 +2383,7 @@ int wd1772_t::settle_time() const
wd1773_t::wd1773_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_digital_t(mconfig, WD1773x, "WD1773", tag, owner, clock) wd1773_t::wd1773_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_digital_t(mconfig, WD1773x, "WD1773", tag, owner, clock)
{ {
disable_mfm = false;
inverted_bus = false; inverted_bus = false;
side_control = false; side_control = false;
side_compare = true; side_compare = true;

View File

@ -156,6 +156,7 @@ public:
protected: protected:
// Chip-specific configuration flags // Chip-specific configuration flags
bool disable_mfm;
bool inverted_bus; bool inverted_bus;
bool side_control; bool side_control;
bool side_compare; bool side_compare;
@ -171,7 +172,7 @@ protected:
virtual int step_time(int mode) const; virtual int step_time(int mode) const;
virtual int settle_time() const; virtual int settle_time() const;
virtual void pll_reset(attotime when) = 0; virtual void pll_reset(bool fm, attotime when) = 0;
virtual void pll_start_writing(attotime tm) = 0; virtual void pll_start_writing(attotime tm) = 0;
virtual void pll_commit(floppy_image_device *floppy, attotime tm) = 0; virtual void pll_commit(floppy_image_device *floppy, attotime tm) = 0;
virtual void pll_stop_writing(floppy_image_device *floppy, attotime tm) = 0; virtual void pll_stop_writing(floppy_image_device *floppy, attotime tm) = 0;
@ -398,6 +399,7 @@ private:
void live_write_raw(UINT16 raw); void live_write_raw(UINT16 raw);
void live_write_mfm(UINT8 mfm); void live_write_mfm(UINT8 mfm);
void live_write_fm(UINT8 fm);
void drop_drq(); void drop_drq();
void set_drq(); void set_drq();
@ -408,7 +410,7 @@ public:
wd_fdc_analog_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); wd_fdc_analog_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
protected: protected:
virtual void pll_reset(attotime when); virtual void pll_reset(bool fm, attotime when);
virtual void pll_start_writing(attotime tm); virtual void pll_start_writing(attotime tm);
virtual void pll_commit(floppy_image_device *floppy, attotime tm); virtual void pll_commit(floppy_image_device *floppy, attotime tm);
virtual void pll_stop_writing(floppy_image_device *floppy, attotime tm); virtual void pll_stop_writing(floppy_image_device *floppy, attotime tm);
@ -426,7 +428,7 @@ public:
wd_fdc_digital_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); wd_fdc_digital_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
protected: protected:
virtual void pll_reset(attotime when); virtual void pll_reset(bool fm, attotime when);
virtual void pll_start_writing(attotime tm); virtual void pll_start_writing(attotime tm);
virtual void pll_commit(floppy_image_device *floppy, attotime tm); virtual void pll_commit(floppy_image_device *floppy, attotime tm);
virtual void pll_stop_writing(floppy_image_device *floppy, attotime tm); virtual void pll_stop_writing(floppy_image_device *floppy, attotime tm);

View File

@ -167,3 +167,115 @@ static FLOPPY_CONSTRUCT(m20_dsk_construct)
LEGACY_FLOPPY_OPTIONS_START( m20 ) LEGACY_FLOPPY_OPTIONS_START( m20 )
LEGACY_FLOPPY_OPTION(m20_dsk, "img", "M20 disk image", m20_dsk_identify, m20_dsk_construct, NULL, NULL) LEGACY_FLOPPY_OPTION(m20_dsk, "img", "M20 disk image", m20_dsk_identify, m20_dsk_construct, NULL, NULL)
LEGACY_FLOPPY_OPTIONS_END LEGACY_FLOPPY_OPTIONS_END
/***************************************************************************
Copyright Olivier Galibert
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name 'MAME' nor the names of its contributors may be
used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
****************************************************************************/
/*********************************************************************
formats/m20_dsk.c
m20 format
*********************************************************************/
#include "emu.h"
#include "formats/m20_dsk.h"
m20_format::m20_format()
{
}
const char *m20_format::name() const
{
return "m20";
}
const char *m20_format::description() const
{
return "M20 disk image";
}
const char *m20_format::extensions() const
{
return "img";
}
bool m20_format::supports_save() const
{
return false;
}
int m20_format::identify(io_generic *io, UINT32 form_factor)
{
if(io_generic_size(io) == 286720)
return 50;
return 0;
}
bool m20_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
{
for(int track = 0; track < 35; track++)
for(int head = 0; head < 2; head ++) {
bool mfm = track || head;
desc_pc_sector sects[16];
UINT8 sectdata[16*256];
io_generic_read(io, sectdata, 16*256*(track*2+head), 16*256);
for(int i=0; i<16; i++) {
int j = i/2 + (i & 1 ? 0 : 8);
sects[i].track = track;
sects[i].head = head;
sects[i].sector = j+1;
sects[i].size = mfm ? 1 : 0;
sects[i].actual_size = mfm ? 256 : 128;
sects[i].data = sectdata + 256*j;
sects[i].deleted = false;
sects[i].bad_crc = false;
}
if(mfm)
build_wd_track_mfm(track, head, image, 100000, 16, sects, 50, 32, 22);
else
build_wd_track_fm(track, head, image, 50000, 16, sects, 24, 16, 11);
}
return true;
}
bool m20_format::save(io_generic *io, floppy_image *image)
{
return false;
}
const floppy_format_type FLOPPY_M20_FORMAT = &floppy_image_format_creator<m20_format>;

View File

@ -15,4 +15,23 @@
LEGACY_FLOPPY_OPTIONS_EXTERN(m20); LEGACY_FLOPPY_OPTIONS_EXTERN(m20);
#include "wd177x_dsk.h"
class m20_format : public floppy_image_format_t {
public:
m20_format();
virtual int identify(io_generic *io, UINT32 form_factor);
virtual bool load(io_generic *io, UINT32 form_factor, floppy_image *image);
virtual bool save(io_generic *io, floppy_image *image);
virtual const char *name() const;
virtual const char *description() const;
virtual const char *extensions() const;
virtual bool supports_save() const;
};
extern const floppy_format_type FLOPPY_M20_FORMAT;
#endif /* M20_DSK_H */ #endif /* M20_DSK_H */

View File

@ -38,7 +38,7 @@ EI1 Vectored interrupt error
#include "cpu/z8000/z8000.h" #include "cpu/z8000/z8000.h"
#include "cpu/i86/i86.h" #include "cpu/i86/i86.h"
#include "video/mc6845.h" #include "video/mc6845.h"
#include "machine/wd17xx.h" #include "machine/wd_fdc.h"
#include "machine/i8251.h" #include "machine/i8251.h"
#include "machine/i8255.h" #include "machine/i8255.h"
#include "machine/pit8253.h" #include "machine/pit8253.h"
@ -58,7 +58,9 @@ public:
m_ttyi8251(*this, "i8251_2"), m_ttyi8251(*this, "i8251_2"),
m_i8255(*this, "ppi8255"), m_i8255(*this, "ppi8255"),
m_i8259(*this, "i8259"), m_i8259(*this, "i8259"),
m_wd177x(*this, "fd1797"), m_fd1797(*this, "fd1797"),
m_floppy0(*this, "fd1797:0:5dd"),
m_floppy1(*this, "fd1797:1:5dd"),
m_p_videoram(*this, "p_videoram"){ } m_p_videoram(*this, "p_videoram"){ }
required_device<z8001_device> m_maincpu; required_device<z8001_device> m_maincpu;
@ -66,10 +68,13 @@ public:
required_device<i8251_device> m_ttyi8251; required_device<i8251_device> m_ttyi8251;
required_device<i8255_device> m_i8255; required_device<i8255_device> m_i8255;
required_device<pic8259_device> m_i8259; required_device<pic8259_device> m_i8259;
required_device<fd1797_device> m_wd177x; required_device<fd1797_t> m_fd1797;
required_device<floppy_image_device> m_floppy0;
required_device<floppy_image_device> m_floppy1;
required_shared_ptr<UINT16> m_p_videoram; required_shared_ptr<UINT16> m_p_videoram;
virtual void machine_start();
virtual void machine_reset(); virtual void machine_reset();
DECLARE_READ16_MEMBER(m20_i8259_r); DECLARE_READ16_MEMBER(m20_i8259_r);
@ -84,20 +89,21 @@ public:
DECLARE_WRITE_LINE_MEMBER(kbd_tx); DECLARE_WRITE_LINE_MEMBER(kbd_tx);
DECLARE_WRITE8_MEMBER(kbd_put); DECLARE_WRITE8_MEMBER(kbd_put);
bool m_port21_sd;
private: private:
bool m_kbrecv_in_progress; bool m_kbrecv_in_progress;
int m_kbrecv_bitcount; int m_kbrecv_bitcount;
UINT16 m_kbrecv_data; UINT16 m_kbrecv_data;
UINT8 m_port21; UINT8 m_port21;
public: public:
DECLARE_DRIVER_INIT(m20); DECLARE_DRIVER_INIT(m20);
virtual void video_start(); virtual void video_start();
UINT32 screen_update_m20(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); UINT32 screen_update_m20(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(kbd_rxrdy_int); DECLARE_WRITE_LINE_MEMBER(kbd_rxrdy_int);
DECLARE_READ_LINE_MEMBER(wd177x_dden_r);
DECLARE_WRITE_LINE_MEMBER(wd177x_intrq_w); DECLARE_FLOPPY_FORMATS( floppy_formats );
void fdc_intrq_w(bool state);
}; };
@ -204,32 +210,27 @@ WRITE16_MEMBER(m20_state::port21_w)
{ {
//printf("port21 write: offset 0x%x, data 0x%x\n", offset, data); //printf("port21 write: offset 0x%x, data 0x%x\n", offset, data);
m_port21 = (m_port21 & 0xf8) | (data & 0x7); m_port21 = (m_port21 & 0xf8) | (data & 0x7);
m_port21_sd = (data & 8) ? 1 : 0;
//printf("port21: sd = %d\n", m_port21_sd);
// floppy drive select // floppy drive select
if (data & 1) { if (data & 1) {
wd17xx_set_drive(m_wd177x, 0); m_floppy0->mon_w(0);
floppy_mon_w(floppy_get_device(machine(), 0) , 0); m_fd1797->set_floppy(m_floppy0);
floppy_drive_set_ready_state(floppy_get_device(machine(), 0), 1, 0);
}
else {
floppy_mon_w(floppy_get_device(machine(), 0) , 1);
floppy_drive_set_ready_state(floppy_get_device(machine(), 0), 0, 0);
} }
else
m_floppy0->mon_w(1);
if (data & 2) { if (data & 2) {
wd17xx_set_drive(m_wd177x, 1); m_floppy1->mon_w(0);
floppy_mon_w(floppy_get_device(machine(), 1) , 0); m_fd1797->set_floppy(m_floppy1);
floppy_drive_set_ready_state(floppy_get_device(machine(), 1), 1, 0);
}
else {
floppy_mon_w(floppy_get_device(machine(), 1) , 1);
floppy_drive_set_ready_state(floppy_get_device(machine(), 1), 0, 0);
} }
else
m_floppy1->mon_w(1);
if(!(data & 3))
m_fd1797->set_floppy(NULL);
// density select 1 - sd, 0 - dd // density select 1 - sd, 0 - dd
wd17xx_dden_w(m_wd177x, m_port21_sd); m_fd1797->dden_w(data & 8);
} }
READ16_MEMBER(m20_state::m20_i8259_r) READ16_MEMBER(m20_state::m20_i8259_r)
@ -313,10 +314,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START(m20_io, AS_IO, 16, m20_state) static ADDRESS_MAP_START(m20_io, AS_IO, 16, m20_state)
ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x00, 0x01) AM_DEVREADWRITE8_LEGACY("fd1797", wd17xx_status_r, wd17xx_command_w, 0x00ff) AM_RANGE(0x00, 0x07) AM_DEVREADWRITE8("fd1797", fd1797_t, read, write, 0x00ff)
AM_RANGE(0x02, 0x03) AM_DEVREADWRITE8_LEGACY("fd1797", wd17xx_track_r, wd17xx_track_w, 0x00ff)
AM_RANGE(0x04, 0x05) AM_DEVREADWRITE8_LEGACY("fd1797", wd17xx_sector_r, wd17xx_sector_w, 0x00ff)
AM_RANGE(0x06, 0x07) AM_DEVREADWRITE8_LEGACY("fd1797", wd17xx_data_r, wd17xx_data_w, 0x00ff)
AM_RANGE(0x20, 0x21) AM_READWRITE(port21_r, port21_w); AM_RANGE(0x20, 0x21) AM_READWRITE(port21_r, port21_w);
@ -368,6 +366,11 @@ static IRQ_CALLBACK( m20_irq_callback )
return pic8259_acknowledge(device->machine().device("i8259")); return pic8259_acknowledge(device->machine().device("i8259"));
} }
void m20_state::machine_start()
{
m_fd1797->setup_intrq_cb(fd1797_t::line_cb(FUNC(m20_state::fdc_intrq_w), this));
}
void m20_state::machine_reset() void m20_state::machine_reset()
{ {
UINT8 *ROM = machine().root_device().memregion("maincpu")->base(); UINT8 *ROM = machine().root_device().memregion("maincpu")->base();
@ -376,12 +379,10 @@ void m20_state::machine_reset()
ROM += 0x10000; // don't know why they load at an offset, but let's go with it ROM += 0x10000; // don't know why they load at an offset, but let's go with it
m_port21 = 0xff; m_port21 = 0xff;
m_port21_sd = 1;
m_maincpu->set_irq_acknowledge_callback(m20_irq_callback); m_maincpu->set_irq_acknowledge_callback(m20_irq_callback);
wd17xx_mr_w(m_wd177x, 0); m_fd1797->reset();
//wd17xx_mr_w(m_wd177x, space, 1);
memcpy(RAM, ROM, 8); // we need only the reset vector memcpy(RAM, ROM, 8); // we need only the reset vector
m_maincpu->reset(); // reset the CPU to ensure it picks up the new vector m_maincpu->reset(); // reset the CPU to ensure it picks up the new vector
@ -416,15 +417,7 @@ WRITE_LINE_MEMBER(m20_state::kbd_rxrdy_int)
pic8259_ir4_w(machine().device("i8259"), state); pic8259_ir4_w(machine().device("i8259"), state);
} }
#if 1 void m20_state::fdc_intrq_w(bool state)
READ_LINE_MEMBER(m20_state::wd177x_dden_r)
{
//printf ("wd177x_dden_r called, returning %d\n", !m_port21_sd);
return !m_port21_sd;
}
#endif
WRITE_LINE_MEMBER(m20_state::wd177x_intrq_w)
{ {
pic8259_ir0_w(machine().device("i8259"), state); pic8259_ir0_w(machine().device("i8259"), state);
} }
@ -455,14 +448,6 @@ static const i8251_interface tty_i8251_intf =
DEVCB_NULL // syndet DEVCB_NULL // syndet
}; };
const wd17xx_interface m20_wd17xx_interface =
{
/*DEVCB_NULL,*/ DEVCB_DRIVER_LINE_MEMBER(m20_state, wd177x_dden_r),
DEVCB_DRIVER_LINE_MEMBER(m20_state, wd177x_intrq_w),
DEVCB_NULL,
{FLOPPY_0, FLOPPY_1, NULL, NULL}
};
static const floppy_interface m20_floppy_interface = static const floppy_interface m20_floppy_interface =
{ {
DEVCB_NULL, DEVCB_NULL,
@ -539,6 +524,14 @@ const struct pic8259_interface pic_intf =
DEVCB_NULL DEVCB_NULL
}; };
static SLOT_INTERFACE_START( m20_floppies )
SLOT_INTERFACE( "5dd", FLOPPY_525_DD )
SLOT_INTERFACE_END
FLOPPY_FORMATS_MEMBER( m20_state::floppy_formats )
FLOPPY_M20_FORMAT
FLOPPY_FORMATS_END
static MACHINE_CONFIG_START( m20, m20_state ) static MACHINE_CONFIG_START( m20, m20_state )
/* basic machine hardware */ /* basic machine hardware */
MCFG_CPU_ADD("maincpu", Z8001, MAIN_CLOCK) MCFG_CPU_ADD("maincpu", Z8001, MAIN_CLOCK)
@ -563,7 +556,9 @@ static MACHINE_CONFIG_START( m20, m20_state )
MCFG_PALETTE_INIT(black_and_white) MCFG_PALETTE_INIT(black_and_white)
/* Devices */ /* Devices */
MCFG_FD1797_ADD("fd1797", m20_wd17xx_interface ) MCFG_FD1797x_ADD("fd1797", 1000000)
MCFG_FLOPPY_DRIVE_ADD("fd1797:0", m20_floppies, "5dd", NULL, m20_state::floppy_formats)
MCFG_FLOPPY_DRIVE_ADD("fd1797:1", m20_floppies, "5dd", NULL, m20_state::floppy_formats)
MCFG_MC6845_ADD("crtc", MC6845, PIXEL_CLOCK/8, mc6845_intf) /* hand tuned to get ~50 fps */ MCFG_MC6845_ADD("crtc", MC6845, PIXEL_CLOCK/8, mc6845_intf) /* hand tuned to get ~50 fps */
MCFG_I8255A_ADD("ppi8255", ppi_interface) MCFG_I8255A_ADD("ppi8255", ppi_interface)
MCFG_I8251_ADD("i8251_1", kbd_i8251_intf) MCFG_I8251_ADD("i8251_1", kbd_i8251_intf)