summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Olivier Galibert <galibert@pobox.com>2012-11-16 09:16:15 +0000
committer Olivier Galibert <galibert@pobox.com>2012-11-16 09:16:15 +0000
commitefe49873d4c0d2a7237ca60ab38925fd2a789eb3 (patch)
treef2799835ff1aa7fd3d158a3b27aa9b25046ef567
parent2aa1e82537e60b7e221865e4afdc1f8163b5cea2 (diff)
(mess) upd765: Add read fm sector support [O. Galibert]
-rw-r--r--src/emu/imagedev/floppy.c33
-rw-r--r--src/emu/imagedev/floppy.h13
-rw-r--r--src/lib/formats/imd_dsk.c8
-rw-r--r--src/mess/drivers/apc.c6
-rw-r--r--src/mess/machine/upd765.c85
-rw-r--r--src/mess/machine/upd765.h3
6 files changed, 135 insertions, 13 deletions
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<floppy_525_dd>;
const device_type FLOPPY_525_QD = &device_creator<floppy_525_qd>;
const device_type FLOPPY_525_HD = &device_creator<floppy_525_hd>;
const device_type FLOPPY_8_SSSD = &device_creator<floppy_8_sssd>;
+const device_type FLOPPY_8_DSDD = &device_creator<floppy_8_dsdd>;
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; j<size; j++) fm_w(track_data, tpos, 8, img[pos]);
pos++;
diff --git a/src/mess/drivers/apc.c b/src/mess/drivers/apc.c
index a811011393e..3d79f0d1644 100644
--- a/src/mess/drivers/apc.c
+++ b/src/mess/drivers/apc.c
@@ -613,7 +613,7 @@ static const floppy_format_type apc_floppy_formats[] = {
};
static SLOT_INTERFACE_START( apc_floppies )
- SLOT_INTERFACE( "8sd", FLOPPY_8_SSSD ) // TODO: Ok?
+ SLOT_INTERFACE( "8", FLOPPY_8_DSDD )
SLOT_INTERFACE_END
PALETTE_INIT_MEMBER(apc_state,apc)
@@ -641,8 +641,8 @@ static MACHINE_CONFIG_START( apc, apc_state )
MCFG_I8237_ADD("8237dma", MAIN_CLOCK, dma8237_config)
MCFG_UPD765A_ADD("upd765", true, true)
- MCFG_FLOPPY_DRIVE_ADD("upd765:0", apc_floppies, "8sd", 0, apc_floppy_formats)
- MCFG_FLOPPY_DRIVE_ADD("upd765:1", apc_floppies, "8sd", 0, apc_floppy_formats)
+ MCFG_FLOPPY_DRIVE_ADD("upd765:0", apc_floppies, "8", 0, apc_floppy_formats)
+ MCFG_FLOPPY_DRIVE_ADD("upd765:1", apc_floppies, "8", 0, apc_floppy_formats)
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
diff --git a/src/mess/machine/upd765.c b/src/mess/machine/upd765.c
index 8ad0c985d12..e8aab6962fd 100644
--- a/src/mess/machine/upd765.c
+++ b/src/mess/machine/upd765.c
@@ -195,7 +195,7 @@ void upd765_family_device::ready_w(bool _ready)
bool upd765_family_device::get_ready(int fid)
{
if(ready_connected)
- return flopi[fid].dev ? flopi[fid].dev->ready_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);