summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/1ma6.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/1ma6.cpp')
-rw-r--r--src/devices/machine/1ma6.cpp676
1 files changed, 188 insertions, 488 deletions
diff --git a/src/devices/machine/1ma6.cpp b/src/devices/machine/1ma6.cpp
index 771fd0d9b1f..479c7b9d6d3 100644
--- a/src/devices/machine/1ma6.cpp
+++ b/src/devices/machine/1ma6.cpp
@@ -29,8 +29,14 @@
#include "1ma6.h"
// Debugging
-#define VERBOSE 0
#include "logmacro.h"
+#define LOG_DBG_MASK (LOG_GENERAL << 1)
+#define LOG_DBG(...) LOGMASKED(LOG_DBG_MASK, __VA_ARGS__)
+#define LOG_RW_MASK (LOG_DBG_MASK << 1)
+#define LOG_RW(...) LOGMASKED(LOG_RW_MASK, __VA_ARGS__)
+#undef VERBOSE
+//#define VERBOSE (LOG_GENERAL | LOG_DBG_MASK | LOG_RW_MASK)
+#define VERBOSE 0
// Device type definition
DEFINE_DEVICE_TYPE(HP_1MA6, hp_1ma6_device, "hp_1ma6", "HP 1MA6")
@@ -63,19 +69,14 @@ namespace {
}
// **** Constants ****
+constexpr double FAST_SPEED = 60.0; // Fast speed: 60 ips
+constexpr double SLOW_SPEED = 10.0; // Slow speed: 10 ips
+constexpr double MOVING_THRESHOLD = 2.0; // Tape is moving when speed > 2.0 ips
+constexpr double ACCELERATION = 1200.0; // Acceleration when speed set point is changed: 1200 ips^2
// One tachometer tick every 1/32 of inch
-static constexpr hti_format_t::tape_pos_t TACH_TICK_LEN = hti_format_t::ONE_INCH_POS / 32;
-static constexpr hti_format_t::tape_pos_t TAPE_INIT_POS = hti_format_t::ONE_INCH_POS * 80;
-// Slow tape speed (10 ips)
-static constexpr unsigned TACH_FREQ_SLOW = hti_format_t::ONE_INCH_POS * 10;
-// Fast tape speed (60 ips)
-static constexpr unsigned TACH_FREQ_FAST = hti_format_t::ONE_INCH_POS * 60;
+constexpr hti_format_t::tape_pos_t TACH_TICK_LEN = hti_format_t::ONE_INCH_POS / 32;
// Minimum gap size (totally made up)
-static constexpr hti_format_t::tape_pos_t MIN_GAP_SIZE = TACH_TICK_LEN;
-// Braking distance at fast speed: 1.5 in (this value assumes the deceleration is 1200 in/s^2, the same as in TACO)
-static constexpr hti_format_t::tape_pos_t FAST_BRAKE_DIST = hti_format_t::ONE_INCH_POS * 1.5;
-// Braking distance at slow speed: 1/24 in
-static constexpr hti_format_t::tape_pos_t SLOW_BRAKE_DIST = hti_format_t::ONE_INCH_POS / 24;
+constexpr hti_format_t::tape_pos_t MIN_GAP_SIZE = TACH_TICK_LEN;
// Bits in control register
enum control_bits : unsigned
@@ -110,10 +111,8 @@ enum {
};
hp_1ma6_device::hp_1ma6_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig , HP_1MA6 , tag , owner , clock),
- device_image_interface(mconfig , *this),
- m_image(),
- m_image_dirty(false)
+ : device_t(mconfig , HP_1MA6 , tag , owner , clock)
+ , m_tape(*this , "drive")
{
clear_state();
}
@@ -141,7 +140,7 @@ READ8_MEMBER(hp_1ma6_device::reg_r)
switch (offset) {
case 0:
// Status register
- update_tape_pos();
+ m_tape->update_speed_pos();
if (m_cmd_state == CMD_IDLE) {
BIT_SET(m_status_reg , STS_READY_BIT);
} else if (m_cmd_state == CMD_STOPPING ||
@@ -151,24 +150,15 @@ READ8_MEMBER(hp_1ma6_device::reg_r)
}
if ((m_control_reg & (BIT_MASK(CTL_WRITE_SYNC_BIT) |
BIT_MASK(CTL_WRITE_GAP_BIT))) != 0 &&
- (!m_cartridge_in || !is_readonly())) {
+ (m_tape->cart_out_r() || !m_tape->wpr_r())) {
BIT_SET(m_status_reg , STS_WRITE_EN_BIT);
} else {
BIT_CLR(m_status_reg , STS_WRITE_EN_BIT);
}
// Gap detection
- if (m_cmd_state == CMD_IDLE) {
+ if (m_cmd_state == CMD_IDLE ||
+ m_tape->gap_reached(MIN_GAP_SIZE)) {
BIT_SET(m_status_reg , STS_GAP_BIT);
- } else if (m_gap_detect_start != hti_format_t::NULL_TAPE_POS) {
- if (abs(m_gap_detect_start - m_tape_pos) >= MIN_GAP_SIZE) {
- auto tmp = m_tape_pos;
- hti_format_t::pos_offset(tmp , is_moving_fwd() , -MIN_GAP_SIZE);
- if (m_image.just_gap(current_track() , tmp , m_tape_pos)) {
- BIT_SET(m_status_reg , STS_GAP_BIT);
- }
- } else {
- BIT_SET(m_status_reg , STS_GAP_BIT);
- }
}
res = m_status_reg;
@@ -177,7 +167,7 @@ READ8_MEMBER(hp_1ma6_device::reg_r)
BIT_CLR(m_status_reg , STS_GAP_BIT);
BIT_CLR(m_status_reg , STS_TACH_BIT);
BIT_CLR(m_status_reg , STS_READY_BIT);
- if (m_cartridge_in) {
+ if (!m_tape->cart_out_r()) {
BIT_SET(m_status_reg , STS_CASSETTE_IN_BIT);
}
break;
@@ -191,143 +181,137 @@ READ8_MEMBER(hp_1ma6_device::reg_r)
return res;
}
-void hp_1ma6_device::device_start()
+WRITE_LINE_MEMBER(hp_1ma6_device::cart_out_w)
{
- save_item(NAME(m_data_reg));
- save_item(NAME(m_status_reg));
- save_item(NAME(m_control_reg));
- save_item(NAME(m_tape_pos));
- save_item(NAME(m_prev_pos));
- save_item(NAME(m_start_time));
- save_item(NAME(m_image_dirty));
- save_item(NAME(m_rw_pos));
- save_item(NAME(m_next_word));
- save_item(NAME(m_rd_it_valid));
- save_item(NAME(m_gap_detect_start));
-
- m_tape_timer = timer_alloc(TAPE_TMR_ID);
- m_hole_timer = timer_alloc(HOLE_TMR_ID);
+ LOG_DBG("cart_out_w %d\n" , state);
+ if (state) {
+ // STS_CASSETTE_IN_BIT is set by reading status register
+ BIT_CLR(m_status_reg , STS_CASSETTE_IN_BIT);
+ }
}
-void hp_1ma6_device::device_reset()
+WRITE_LINE_MEMBER(hp_1ma6_device::hole_w)
{
- clear_state();
+ if (state) {
+ LOG_DBG("hole_w\n");
+ BIT_SET(m_status_reg , STS_HOLE_BIT);
+ }
+}
- m_tape_timer->reset();
- m_hole_timer->reset();
+WRITE_LINE_MEMBER(hp_1ma6_device::tacho_tick_w)
+{
+ if (state) {
+ LOG_DBG("tacho_tick_w\n");
+ BIT_SET(m_status_reg , STS_TACH_BIT);
+ }
}
-void hp_1ma6_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+WRITE_LINE_MEMBER(hp_1ma6_device::motion_w)
{
- update_tape_pos();
-
- switch (id) {
- case TAPE_TMR_ID:
- {
- LOG("TMR %.6f %d %d\n" , machine().time().as_double() , m_tape_pos , m_cmd_state);
- attotime cmd_duration = attotime::never;
- switch (m_cmd_state) {
- case CMD_STOPPING:
+ if (state) {
+ LOG_DBG("motion_w @%.6f st=%d\n" , machine().time().as_double() , m_cmd_state);
+ switch (m_cmd_state) {
+ case CMD_STOPPING:
+ if (!m_tape->is_moving()) {
m_cmd_state = CMD_IDLE;
- stop_tape();
- break;
-
- case CMD_RD_WAIT_SYNC:
- m_tape_pos = m_rw_pos;
- LOG("RD WS @ %d = %04x\n" , m_tape_pos , m_rd_it->second);
- if (m_rd_it->second != 0xffff) {
- // Sync achieved
- m_cmd_state = CMD_RD_MSB;
- }
- cmd_duration = advance_rd_state();
- break;
-
- case CMD_RD_MSB:
- m_tape_pos = m_rw_pos;
- m_next_word = m_rd_it->second;
- LOG("RD T%u @ %d = %04x\n" , current_track() , m_rw_pos , m_next_word);
- m_data_reg = (uint8_t)(m_next_word >> 8);
- BIT_SET(m_status_reg , STS_READY_BIT);
- // Time to reach LSB: half the length of a 0 word
- // Actually it varies basing on MSB content
- cmd_duration = time_to_distance(hti_format_t::word_length(0) / 2);
- m_cmd_state = CMD_RD_LSB;
- break;
-
- case CMD_RD_LSB:
- m_data_reg = (uint8_t)m_next_word;
- BIT_SET(m_status_reg , STS_READY_BIT);
- m_cmd_state = CMD_RD_MSB;
- cmd_duration = advance_rd_state();
- break;
-
- case CMD_WR_SYNC:
- m_tape_pos = m_rw_pos;
- if (m_rd_it->second != 0xffff) {
- // Got preamble
- m_next_word = (hti_format_t::tape_word_t)m_data_reg << 8;
- BIT_SET(m_status_reg , STS_READY_BIT);
- m_cmd_state = CMD_WR_LSB;
- cmd_duration = time_to_distance(hti_format_t::word_length(0) / 2);
- } else {
- cmd_duration = advance_rd_state();
- }
- break;
-
- case CMD_WR_MSB:
- // **** FWD ****
- // | m_rw_pos --> m_next_word
- // | m_tape_pos --> (start of next word)
- // V
- //
- // **** REV ****
- // ^ m_tape_pos --> m_next_word
- // | m_rw_pos --> (start of previous word)
- // |
- {
- auto length = hti_format_t::word_length(m_next_word);
- if (!is_moving_fwd()) {
- hti_format_t::pos_offset(m_rw_pos , false , length);
+ }
+ break;
+
+ case CMD_STARTING:
+ {
+ hp_dc100_tape_device::tape_op_t op = hp_dc100_tape_device::OP_IDLE;
+
+ switch (m_control_reg & (BIT_MASK(CTL_FAST_BIT) |
+ BIT_MASK(CTL_WRITE_DATA_BIT) |
+ BIT_MASK(CTL_WRITE_SYNC_BIT) |
+ BIT_MASK(CTL_WRITE_GAP_BIT))) {
+ case 0:
+ if (m_tape->is_above_threshold()) {
+ // Start RD
+ m_cmd_state = CMD_RD_WAIT_SYNC;
+ op = hp_dc100_tape_device::OP_READ;
}
- LOG("WR T%u @ %d = %04x\n" , current_track() , m_rw_pos , m_next_word);
- if (m_cartridge_in) {
- m_image.write_word(current_track() , m_rw_pos , m_next_word , length , is_moving_fwd());
- m_image_dirty = true;
+ break;
+
+ case BIT_MASK(CTL_FAST_BIT):
+ case BIT_MASK(CTL_WRITE_GAP_BIT):
+ case BIT_MASK(CTL_WRITE_GAP_BIT) | BIT_MASK(CTL_WRITE_DATA_BIT):
+ // Start simple movement
+ m_cmd_state = CMD_FAST_FWD_REV;
+ break;
+
+ case BIT_MASK(CTL_WRITE_DATA_BIT):
+ if (m_tape->is_above_threshold()) {
+ // Start re-writing
+ m_cmd_state = CMD_WR_WAIT_SYNC;
+ // Need to achieve sync first (hence RD op)
+ op = hp_dc100_tape_device::OP_READ;
}
- if (is_moving_fwd()) {
- hti_format_t::pos_offset(m_rw_pos , true , length);
+ break;
+
+ case BIT_MASK(CTL_WRITE_SYNC_BIT):
+ if (m_tape->is_above_threshold()) {
+ // Start WR
+ load_wr_word();
+ m_cmd_state = CMD_WR_PREAMBLE;
+ op = hp_dc100_tape_device::OP_WRITE;
}
- m_tape_pos = m_rw_pos;
+ break;
- m_next_word = (hti_format_t::tape_word_t)m_data_reg << 8;
- BIT_SET(m_status_reg , STS_READY_BIT);
- m_cmd_state = CMD_WR_LSB;
- cmd_duration = time_to_distance(hti_format_t::word_length(0) / 2);
- }
- break;
-
- case CMD_WR_LSB:
- {
- m_next_word = (m_next_word & 0xff00) | m_data_reg;
- BIT_SET(m_status_reg , STS_READY_BIT);
- m_cmd_state = CMD_WR_MSB;
- auto length = hti_format_t::word_length(m_next_word);
- auto tmp = m_rw_pos;
- hti_format_t::pos_offset(tmp , is_moving_fwd() , length);
- cmd_duration = time_to_target(tmp);
- }
- break;
+ case BIT_MASK(CTL_WRITE_SYNC_BIT) | BIT_MASK(CTL_WRITE_GAP_BIT):
+ if (m_tape->is_above_threshold()) {
+ // Start erasing (gap writing)
+ m_cmd_state = CMD_WR_GAP;
+ op = hp_dc100_tape_device::OP_ERASE;
+ }
+ break;
- default:
- break;
+ default:
+ break;
+ }
+ m_tape->set_op(op);
}
- m_tape_timer->adjust(cmd_duration);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+WRITE_LINE_MEMBER(hp_1ma6_device::rd_bit_w)
+{
+ LOG_RW("RD bit %d (st=%d,sr=%02x,i=%u)\n" , state , m_cmd_state , m_data_sr , m_bit_idx);
+ switch (m_cmd_state) {
+ case CMD_RD_WAIT_SYNC:
+ if (state) {
+ // Got sync (bit is 1)
+ LOG_RW("RD synced\n");
+ m_cmd_state = CMD_RD;
+ m_bit_idx = 7;
+ m_data_sr = 0;
}
break;
- case HOLE_TMR_ID:
- BIT_SET(m_status_reg , STS_HOLE_BIT);
- m_hole_timer->adjust(time_to_next_hole());
+ case CMD_RD:
+ if (state) {
+ BIT_SET(m_data_sr , m_bit_idx);
+ }
+ if (m_bit_idx) {
+ m_bit_idx--;
+ } else {
+ LOG_RW("RD byte %02x\n" , m_data_sr);
+ m_data_reg = m_data_sr;
+ m_bit_idx = 7;
+ m_data_sr = 0;
+ BIT_SET(m_status_reg , STS_READY_BIT);
+ }
+ break;
+
+ case CMD_WR_WAIT_SYNC:
+ m_cmd_state = CMD_WR_PREAMBLE;
+ load_wr_word();
+ m_tape->set_op(hp_dc100_tape_device::OP_WRITE);
break;
default:
@@ -335,74 +319,50 @@ void hp_1ma6_device::device_timer(emu_timer &timer, device_timer_id id, int para
}
}
-image_init_result hp_1ma6_device::call_load()
+READ_LINE_MEMBER(hp_1ma6_device::wr_bit_r)
{
- LOG("call_load\n");
- return internal_load(false);
+ bool bit = m_cmd_state == CMD_WR_PREAMBLE ? false : BIT(m_data_sr , m_bit_idx);
+ if (m_bit_idx) {
+ m_bit_idx--;
+ } else {
+ if (m_cmd_state == CMD_WR) {
+ load_wr_word();
+ }
+ m_cmd_state = CMD_WR;
+ m_bit_idx = 7;
+ }
+ LOG_RW("WR bit %d (sr=%02x,i=%u)\n" , bit , m_data_sr , m_bit_idx);
+ return bit;
}
-image_init_result hp_1ma6_device::call_create(int format_type, util::option_resolution *format_options)
+void hp_1ma6_device::device_add_mconfig(machine_config &config)
{
- LOG("call_create\n");
- return internal_load(true);
+ HP_DC100_TAPE(config , m_tape , 0);
+ m_tape->set_acceleration(ACCELERATION);
+ m_tape->set_set_points(SLOW_SPEED , FAST_SPEED);
+ m_tape->set_tick_size(TACH_TICK_LEN);
+ m_tape->set_bits_per_word(16);
+ m_tape->set_go_threshold(MOVING_THRESHOLD);
+ m_tape->cart_out().set(FUNC(hp_1ma6_device::cart_out_w));
+ m_tape->hole().set(FUNC(hp_1ma6_device::hole_w));
+ m_tape->tacho_tick().set(FUNC(hp_1ma6_device::tacho_tick_w));
+ m_tape->motion_event().set(FUNC(hp_1ma6_device::motion_w));
+ m_tape->rd_bit().set(FUNC(hp_1ma6_device::rd_bit_w));
+ m_tape->wr_bit().set(FUNC(hp_1ma6_device::wr_bit_r));
}
-void hp_1ma6_device::call_unload()
-{
- LOG("call_unload dirty=%d\n" , m_image_dirty);
-
- device_reset();
-
- if (m_image_dirty) {
- io_generic io;
- io.file = (device_image_interface *)this;
- io.procs = &image_ioprocs;
- io.filler = 0;
- m_image.save_tape(&io);
- m_image_dirty = false;
- }
-
- m_image.clear_tape();
- set_cartridge_in(false);
-}
-
-std::string hp_1ma6_device::call_display()
+void hp_1ma6_device::device_start()
{
- std::string buffer;
- // Mostly lifted from cassette_image_device::call_display ;)
- // See also hp_taco_device::call_display
-
- // Do not show anything if image not loaded or tape not moving
- if (!exists() || m_start_time.is_never()) {
- return buffer;
- }
-
- char track = BIT(m_control_reg , CTL_TRACK_NO_BIT) ? 'B' : 'A';
- char r_w = m_cmd_state == CMD_WR_SYNC ||
- m_cmd_state == CMD_WR_MSB ||
- m_cmd_state == CMD_WR_LSB ||
- m_cmd_state == CMD_WR_GAP ? 'W' : 'R';
- char m1;
- char m2;
-
- if (is_moving_fwd()) {
- m1 = '>';
- m2 = BIT(m_control_reg , CTL_FAST_BIT) ? '>' : ' ';
- } else {
- m1 = '<';
- m2 = BIT(m_control_reg , CTL_FAST_BIT) ? '<' : ' ';
- }
-
- int pos_in = current_tape_pos() / hti_format_t::ONE_INCH_POS;
-
- buffer = string_format("%c %c %c%c [%04d/1824]" , track , r_w , m1 , m2 , pos_in);
-
- return buffer;
+ save_item(NAME(m_data_reg));
+ save_item(NAME(m_status_reg));
+ save_item(NAME(m_control_reg));
+ save_item(NAME(m_bit_idx));
+ save_item(NAME(m_data_sr));
}
-const char *hp_1ma6_device::file_extensions() const
+void hp_1ma6_device::device_reset()
{
- return "hti";
+ clear_state();
}
void hp_1ma6_device::clear_state()
@@ -410,300 +370,40 @@ void hp_1ma6_device::clear_state()
m_data_reg = 0;
m_status_reg = 0;
m_control_reg = 0;
- m_tape_pos = TAPE_INIT_POS;
- m_prev_pos = TAPE_INIT_POS;
- m_start_time = attotime::never;
- m_rw_pos = hti_format_t::NULL_TAPE_POS;
- m_next_word = 0;
- m_rd_it_valid = false;
- m_gap_detect_start = hti_format_t::NULL_TAPE_POS;
+ m_bit_idx = 0;
+ m_data_sr = 0;
m_cmd_state = CMD_IDLE;
- set_cartridge_in(false);
- set_cartridge_in(is_loaded());
-}
-
-unsigned hp_1ma6_device::current_track() const
-{
- return BIT(m_control_reg , CTL_TRACK_NO_BIT);
-}
-
-unsigned hp_1ma6_device::speed_to_tick_freq(void) const
-{
- unsigned freq = BIT(m_control_reg , CTL_FAST_BIT) ? TACH_FREQ_FAST : TACH_FREQ_SLOW;
-
- if (m_cmd_state == CMD_STOPPING) {
- // Braking
- freq /= 2;
- }
-
- return freq;
-}
-
-attotime hp_1ma6_device::time_to_distance(hti_format_t::tape_pos_t distance) const
-{
- // +1 for rounding
- return attotime::from_ticks(distance + 1 , speed_to_tick_freq());
-}
-
-attotime hp_1ma6_device::time_to_target(hti_format_t::tape_pos_t target) const
-{
- return time_to_distance(abs(target - m_tape_pos));
-}
-
-attotime hp_1ma6_device::time_to_next_hole(void) const
-{
- auto pos = hti_format_t::next_hole(m_tape_pos , is_moving_fwd());
-
- if (pos == hti_format_t::NULL_TAPE_POS) {
- return attotime::never;
- } else {
- return time_to_target(pos);
- }
-}
-
-attotime hp_1ma6_device::time_to_rd_next_word(hti_format_t::tape_pos_t& word_rd_pos) const
-{
- if (m_rd_it_valid) {
- word_rd_pos = hti_format_t::farthest_end(m_rd_it , is_moving_fwd());
- return time_to_target(word_rd_pos);
- } else {
- return attotime::never;
- }
}
-hti_format_t::tape_pos_t hp_1ma6_device::current_tape_pos() const
+void hp_1ma6_device::load_wr_word()
{
- if (m_start_time.is_never()) {
- // Tape not moving
- return m_tape_pos;
- }
-
- attotime delta_time(machine().time() - m_start_time);
- hti_format_t::tape_pos_t delta_tach = (hti_format_t::tape_pos_t)(delta_time.as_ticks(speed_to_tick_freq()));
-
- auto tape_pos = m_tape_pos;
- if (!hti_format_t::pos_offset(tape_pos , is_moving_fwd() , delta_tach)) {
- LOG("Tape unspooled!\n");
- }
-
- return tape_pos;
-}
-
-void hp_1ma6_device::update_tape_pos()
-{
- if (m_start_time.is_never()) {
- // Tape not moving
- return;
- }
-
- m_tape_pos = current_tape_pos();
- m_start_time = machine().time();
-
- // Tachometer ticks
- if ((m_prev_pos / TACH_TICK_LEN) != (m_tape_pos / TACH_TICK_LEN)) {
- BIT_SET(m_status_reg , STS_TACH_BIT);
- }
- m_prev_pos = m_tape_pos;
-}
-
-bool hp_1ma6_device::is_reading() const
-{
- return m_cmd_state >= CMD_RD_WAIT_SYNC &&
- m_cmd_state <= CMD_RD_LSB;
-}
-
-bool hp_1ma6_device::is_writing() const
-{
- return m_cmd_state >= CMD_WR_SYNC &&
- m_cmd_state <= CMD_WR_GAP;
-}
-
-bool hp_1ma6_device::is_moving_fwd() const
-{
- return BIT(m_control_reg , CTL_DIR_FWD_BIT);
-}
-
-void hp_1ma6_device::set_cartridge_in(bool in)
-{
- m_cartridge_in = in;
- if (!m_cartridge_in) {
- BIT_CLR(m_status_reg , STS_CASSETTE_IN_BIT);
- }
-}
-
-void hp_1ma6_device::start_tape()
-{
- m_start_time = machine().time();
- m_prev_pos = m_tape_pos;
- if (!is_writing()) {
- m_gap_detect_start = m_tape_pos;
- } else {
- m_gap_detect_start = hti_format_t::NULL_TAPE_POS;
- }
- m_hole_timer->adjust(time_to_next_hole());
-}
-
-void hp_1ma6_device::stop_tape()
-{
- m_start_time = attotime::never;
- m_gap_detect_start = hti_format_t::NULL_TAPE_POS;
- m_hole_timer->reset();
- m_tape_timer->reset();
-}
-
-attotime hp_1ma6_device::advance_rd_state()
-{
- auto res = m_image.adv_it(current_track() , is_moving_fwd() , m_rd_it);
- if (res == hti_format_t::ADV_NO_MORE_DATA) {
- m_rd_it_valid = false;
- } else if (res == hti_format_t::ADV_DISCONT_DATA && is_reading()) {
- // Discontinuous data: move back to sync search (probably..)
- m_cmd_state = CMD_RD_WAIT_SYNC;
- }
- return time_to_rd_next_word(m_rw_pos);
+ m_bit_idx = 7;
+ m_data_sr = m_data_reg;
+ LOG_RW("WR byte %02x\n" , m_data_sr);
+ BIT_SET(m_status_reg , STS_READY_BIT);
}
void hp_1ma6_device::start_cmd_exec(uint8_t new_ctl_reg)
{
- if (new_ctl_reg == m_control_reg) {
- return;
- }
-
- cmd_state_t new_state;
-
- if (!BIT(new_ctl_reg , CTL_POWER_UP_BIT)) {
- new_state = CMD_IDLE;
- } else if (!BIT(new_ctl_reg , CTL_MOTOR_ON_BIT)) {
- new_state = CMD_STOPPING;
- } else switch (new_ctl_reg & (BIT_MASK(CTL_FAST_BIT) |
- BIT_MASK(CTL_WRITE_DATA_BIT) |
- BIT_MASK(CTL_WRITE_SYNC_BIT) |
- BIT_MASK(CTL_WRITE_GAP_BIT))) {
- case 0:
- new_state = CMD_RD_WAIT_SYNC;
- break;
-
- case BIT_MASK(CTL_FAST_BIT):
- case BIT_MASK(CTL_WRITE_GAP_BIT):
- case BIT_MASK(CTL_WRITE_GAP_BIT) | BIT_MASK(CTL_WRITE_DATA_BIT):
- new_state = CMD_FAST_FWD_REV;
- break;
-
- case BIT_MASK(CTL_WRITE_DATA_BIT):
- new_state = CMD_WR_SYNC;
- break;
-
- case BIT_MASK(CTL_WRITE_SYNC_BIT):
- new_state = CMD_WR_MSB;
- break;
-
- case BIT_MASK(CTL_WRITE_SYNC_BIT) | BIT_MASK(CTL_WRITE_GAP_BIT):
- new_state = CMD_WR_GAP;
- break;
-
- default:
- LOG("Unknown command %02x\n" , new_ctl_reg);
- return;
- }
-
- update_tape_pos();
- LOG("State %d -> %d pos = %d\n" , m_cmd_state , new_state , m_tape_pos);
-
- if (m_cmd_state == CMD_WR_GAP) {
- // Finish gap writing
- LOG("T%u: Gap from %d to %d\n" , current_track() , m_rw_pos , m_tape_pos);
- if (m_cartridge_in) {
- m_image.write_gap(current_track() , m_rw_pos , m_tape_pos);
- m_image_dirty = true;
- }
- }
-
- uint8_t saved_dir_speed = m_control_reg & (BIT_MASK(CTL_DIR_FWD_BIT) | BIT_MASK(CTL_FAST_BIT));
-
m_control_reg = new_ctl_reg;
- attotime cmd_duration = attotime::never;
-
- switch (new_state) {
- case CMD_IDLE:
- m_cmd_state = CMD_IDLE;
- stop_tape();
- break;
-
- case CMD_STOPPING:
- if (m_cmd_state != CMD_IDLE &&
- m_cmd_state != CMD_STOPPING) {
- m_cmd_state = CMD_STOPPING;
- // Keep speed & direction from before the STOP command
- m_control_reg = (m_control_reg & ~(BIT_MASK(CTL_DIR_FWD_BIT) | BIT_MASK(CTL_FAST_BIT))) | saved_dir_speed;
- cmd_duration = time_to_distance(BIT(m_control_reg , CTL_FAST_BIT) ? FAST_BRAKE_DIST : SLOW_BRAKE_DIST);
- }
- break;
-
- case CMD_RD_WAIT_SYNC:
- m_cmd_state = CMD_RD_WAIT_SYNC;
- start_tape();
- m_rd_it_valid = m_image.next_data(current_track() , m_tape_pos , is_moving_fwd() , false , m_rd_it);
- cmd_duration = time_to_rd_next_word(m_rw_pos);
- // TODO: ??
- BIT_CLR(m_status_reg , STS_READY_BIT);
- break;
-
- case CMD_WR_SYNC:
- m_cmd_state = CMD_WR_SYNC;
- start_tape();
- m_rd_it_valid = m_image.next_data(current_track() , m_tape_pos , is_moving_fwd() , false , m_rd_it);
- cmd_duration = time_to_rd_next_word(m_rw_pos);
- BIT_SET(m_status_reg , STS_READY_BIT);
- break;
-
- case CMD_WR_MSB:
- m_cmd_state = CMD_WR_MSB;
- start_tape();
- m_rw_pos = m_tape_pos;
- // SYNC word: MSB = 00, LSB = data register
- m_next_word = (hti_format_t::tape_word_t)m_data_reg;
- BIT_SET(m_status_reg , STS_READY_BIT);
- cmd_duration = time_to_distance(hti_format_t::word_length(m_next_word));
- break;
-
- case CMD_WR_GAP:
- m_cmd_state = CMD_WR_GAP;
- start_tape();
- m_rw_pos = m_tape_pos;
- break;
-
- case CMD_FAST_FWD_REV:
- m_cmd_state = CMD_FAST_FWD_REV;
- start_tape();
- break;
-
- default:
- break;
+ if (!BIT(new_ctl_reg , CTL_POWER_UP_BIT) ||
+ !BIT(new_ctl_reg , CTL_MOTOR_ON_BIT)) {
+ m_cmd_state = CMD_STOPPING;
+ } else {
+ m_cmd_state = CMD_STARTING;
}
- m_tape_timer->adjust(cmd_duration);
-}
+ m_tape->set_op(hp_dc100_tape_device::OP_IDLE);
+ m_tape->set_track_no(BIT(m_control_reg , CTL_TRACK_NO_BIT));
-image_init_result hp_1ma6_device::internal_load(bool is_create)
-{
- device_reset();
-
- io_generic io;
- io.file = (device_image_interface *)this;
- io.procs = &image_ioprocs;
- io.filler = 0;
- if (is_create) {
- m_image.clear_tape();
- m_image.save_tape(&io);
- } else if (!m_image.load_tape(&io)) {
- seterror(IMAGE_ERROR_INVALIDIMAGE , "Wrong format");
- set_cartridge_in(false);
- return image_init_result::FAIL;
+ hp_dc100_tape_device::tape_speed_t new_speed = hp_dc100_tape_device::SP_STOP;
+ if (BIT(new_ctl_reg , CTL_POWER_UP_BIT) &&
+ BIT(new_ctl_reg , CTL_MOTOR_ON_BIT)) {
+ new_speed = BIT(new_ctl_reg , CTL_FAST_BIT) ? hp_dc100_tape_device::SP_FAST :
+ hp_dc100_tape_device::SP_SLOW;
}
- m_image_dirty = false;
- set_cartridge_in(true);
-
- return image_init_result::PASS;
+ m_tape->set_speed_setpoint(new_speed , BIT(new_ctl_reg , CTL_DIR_FWD_BIT));
+ motion_w(1);
}