diff --git a/src/emu/imagedev/floppy.c b/src/emu/imagedev/floppy.c index 592fc74141b..c1c9131cfc8 100644 --- a/src/emu/imagedev/floppy.c +++ b/src/emu/imagedev/floppy.c @@ -23,6 +23,7 @@ const device_type FLOPPY_525_DD = &device_creator; const device_type FLOPPY_525_QD = &device_creator; const device_type FLOPPY_525_HD = &device_creator; const device_type FLOPPY_8_SSSD = &device_creator; +const device_type FLOPPY_8_DSDD = &device_creator; floppy_connector::floppy_connector(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, FLOPPY_CONNECTOR, "Floppy drive connector abstraction", tag, owner, clock), @@ -174,6 +175,7 @@ void floppy_image_device::commit_image() void floppy_image_device::device_start() { rpm = 0; + motor_always_on = false; setup_characteristics(); idx = 0; @@ -194,6 +196,8 @@ void floppy_image_device::device_reset() revolution_start_time = attotime::never; revolution_count = 0; mon = 1; + if(motor_always_on) + mon_w(0); } void floppy_image_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) @@ -1032,7 +1036,8 @@ void floppy_8_sssd::setup_characteristics() form_factor = floppy_image::FF_8; tracks = 77; sides = 1; - set_rpm(300); + motor_always_on = true; + set_rpm(360); } void floppy_8_sssd::handled_variants(UINT32 *variants, int &var_count) const @@ -1040,3 +1045,29 @@ void floppy_8_sssd::handled_variants(UINT32 *variants, int &var_count) const var_count = 0; variants[var_count++] = floppy_image::SSSD; } + +floppy_8_dsdd::floppy_8_dsdd(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + floppy_image_device(mconfig, FLOPPY_8_DSDD, "8\" double density double sided floppy drive", tag, owner, clock) +{ +} + +floppy_8_dsdd::~floppy_8_dsdd() +{ +} + +void floppy_8_dsdd::setup_characteristics() +{ + form_factor = floppy_image::FF_8; + tracks = 77; + sides = 2; + motor_always_on = true; + set_rpm(360); +} + +void floppy_8_dsdd::handled_variants(UINT32 *variants, int &var_count) const +{ + var_count = 0; + variants[var_count++] = floppy_image::SSSD; + variants[var_count++] = floppy_image::SSDD; + variants[var_count++] = floppy_image::DSDD; +} diff --git a/src/emu/imagedev/floppy.h b/src/emu/imagedev/floppy.h index a1459479fa1..62023eb68a2 100644 --- a/src/emu/imagedev/floppy.h +++ b/src/emu/imagedev/floppy.h @@ -110,6 +110,7 @@ protected: int tracks; /* addressable tracks */ int sides; /* number of heads */ UINT32 form_factor; /* 3"5, 5"25, etc */ + bool motor_always_on; /* state of input lines */ int dir; /* direction */ @@ -282,6 +283,17 @@ protected: virtual void setup_characteristics(); }; +class floppy_8_dsdd : public floppy_image_device { +public: + floppy_8_dsdd(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual ~floppy_8_dsdd(); + virtual void handled_variants(UINT32 *variants, int &var_count) const; + virtual void device_config_complete() { m_shortname = "floppy_8_dsdd"; } + virtual const char *image_interface() const { return "floppy_8"; } +protected: + virtual void setup_characteristics(); +}; + class floppy_connector: public device_t, public device_slot_interface { @@ -314,5 +326,6 @@ extern const device_type FLOPPY_525_DD; extern const device_type FLOPPY_525_QD; extern const device_type FLOPPY_525_HD; extern const device_type FLOPPY_8_SSSD; +extern const device_type FLOPPY_8_DSDD; #endif /* FLOPPY_H */ diff --git a/src/lib/formats/imd_dsk.c b/src/lib/formats/imd_dsk.c index 79b9f2663c6..15cbd672dd5 100644 --- a/src/lib/formats/imd_dsk.c +++ b/src/lib/formats/imd_dsk.c @@ -475,9 +475,9 @@ bool imd_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) int cpos; UINT16 crc; // sync and IDAM and gap 2 - for(int j=0; j< 6; j++) fm_w(track_data, tpos, 8, 0xff); + for(int j=0; j< 6; j++) fm_w(track_data, tpos, 8, 0x00); cpos = tpos; - raw_w(track_data, tpos, 8, 0xf57e); + raw_w(track_data, tpos, 16, 0xf57e); fm_w (track_data, tpos, 8, tnum ? tnum[i] : track); fm_w (track_data, tpos, 8, hnum ? hnum[i] : head); fm_w (track_data, tpos, 8, snum[i]); @@ -491,9 +491,9 @@ bool imd_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) else { // sync, DAM, data and gap 3 - for(int j=0; j< 6; j++) fm_w(track_data, tpos, 8, 0xff); + for(int j=0; j< 6; j++) fm_w(track_data, tpos, 8, 0x00); cpos = tpos; - raw_w(track_data, tpos, 8, stype == 3 || stype == 4 || stype == 7 || stype == 8 ? 0xf56a : 0xf56f); + raw_w(track_data, tpos, 16, stype == 3 || stype == 4 || stype == 7 || stype == 8 ? 0xf56a : 0xf56f); if(stype == 2 || stype == 4 || stype == 6 || stype == 8) { for(int j=0; jready_r() : false; + return flopi[fid].dev ? !flopi[fid].dev->ready_r() : false; return external_ready; } @@ -438,8 +438,11 @@ void upd765_family_device::disable_transfer() void upd765_family_device::fifo_push(UINT8 data, bool internal) { if(fifo_pos == 16) { - if(internal) + if(internal) { + if(!(st1 & ST1_OR)) + logerror("%s: Fifo overrun\n", tag()); st1 |= ST1_OR; + } return; } fifo[fifo_pos++] = data; @@ -456,8 +459,11 @@ void upd765_family_device::fifo_push(UINT8 data, bool internal) UINT8 upd765_family_device::fifo_pop(bool internal) { if(!fifo_pos) { - if(internal) + if(internal) { + if(!(st1 & ST1_OR)) + logerror("%s: Fifo underrun\n", tag()); st1 |= ST1_OR; + } return 0; } UINT8 r = fifo[0]; @@ -668,6 +674,30 @@ void upd765_family_device::live_run(attotime limit) break; } + case SEARCH_ADDRESS_MARK_HEADER_FM: + if(read_one_bit(limit)) + return; +#if 0 + fprintf(stderr, "%s: shift = %04x data=%02x c=%d\n", tts(cur_live.tm).cstr(), 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) | + (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) | + (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) | + (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) | + (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) | + (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00), + cur_live.bit_counter); +#endif + + if(cur_live.shift_reg == 0xf57e) { + cur_live.crc = 0xef21; + cur_live.data_separator_phase = false; + cur_live.bit_counter = 0; + cur_live.state = READ_ID_BLOCK; + } + break; + case READ_ID_BLOCK: { if(read_one_bit(limit)) return; @@ -757,6 +787,34 @@ void upd765_family_device::live_run(attotime limit) cur_live.state = IDLE; return; + case SEARCH_ADDRESS_MARK_DATA_FM: + if(read_one_bit(limit)) + return; +#if 0 + fprintf(stderr, "%s: shift = %04x data=%02x c=%d.%x\n", tts(cur_live.tm).cstr(), 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) | + (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) | + (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) | + (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) | + (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) | + (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00), + cur_live.bit_counter >> 4, cur_live.bit_counter & 15); +#endif + 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 == 0xf56f)) { + cur_live.crc = cur_live.shift_reg == 0xf56a ? 0x8fe7 : 0xbf84; + cur_live.data_separator_phase = false; + cur_live.bit_counter = 0; + cur_live.state = READ_SECTOR_DATA; + } + break; + case READ_SECTOR_DATA: { if(read_one_bit(limit)) return; @@ -1331,7 +1389,7 @@ void upd765_family_device::read_data_continue(floppy_info &fi) case SEEK_DONE: fi.counter = 0; fi.sub_state = SCAN_ID; - live_start(fi, SEARCH_ADDRESS_MARK_HEADER); + live_start(fi, command[0] & 0x40 ? SEARCH_ADDRESS_MARK_HEADER : SEARCH_ADDRESS_MARK_HEADER_FM); return; case SCAN_ID: @@ -1364,7 +1422,7 @@ void upd765_family_device::read_data_continue(floppy_info &fi) sector_size = calc_sector_size(cur_live.idbuf[3]); fifo_expect(sector_size, false); fi.sub_state = SECTOR_READ; - live_start(fi, SEARCH_ADDRESS_MARK_DATA); + live_start(fi, command[0] & 0x40 ? SEARCH_ADDRESS_MARK_DATA : SEARCH_ADDRESS_MARK_DATA_FM); return; case SCAN_ID_FAILED: @@ -2019,6 +2077,23 @@ void upd765_family_device::live_write_mfm(UINT8 mfm) // logerror("write %02x %04x %04x\n", mfm, cur_live.crc, raw); } +void upd765_family_device::live_write_fm(UINT8 fm) +{ + bool context = cur_live.data_bit_context; + UINT16 raw = 0; + for(int i=0; i<8; i++) { + bool bit = fm & (0x80 >> i); + raw |= 0x8000 >> (2*i); + if(bit) + raw |= 0x4000 >> (2*i); + context = bit; + } + cur_live.data_reg = fm; + cur_live.shift_reg = raw; + cur_live.data_bit_context = context; + // logerror("write %02x %04x %04x\n", fm, cur_live.crc, raw); +} + bool upd765_family_device::sector_matches() const { return diff --git a/src/mess/machine/upd765.h b/src/mess/machine/upd765.h index 7c0b813a5d3..2953d843bbc 100644 --- a/src/mess/machine/upd765.h +++ b/src/mess/machine/upd765.h @@ -208,10 +208,12 @@ protected: // Live states SEARCH_ADDRESS_MARK_HEADER, + SEARCH_ADDRESS_MARK_HEADER_FM, READ_HEADER_BLOCK_HEADER, READ_DATA_BLOCK_HEADER, READ_ID_BLOCK, SEARCH_ADDRESS_MARK_DATA, + SEARCH_ADDRESS_MARK_DATA_FM, SEARCH_ADDRESS_MARK_DATA_FAILED, READ_SECTOR_DATA, READ_SECTOR_DATA_BYTE, @@ -374,6 +376,7 @@ protected: void live_sync(); void live_run(attotime limit = attotime::never); void live_write_raw(UINT16 raw); + void live_write_fm(UINT8 fm); void live_write_mfm(UINT8 mfm); bool read_one_bit(attotime limit);