diff options
Diffstat (limited to 'src/devices/machine/hp_taco.cpp')
-rw-r--r-- | src/devices/machine/hp_taco.cpp | 216 |
1 files changed, 103 insertions, 113 deletions
diff --git a/src/devices/machine/hp_taco.cpp b/src/devices/machine/hp_taco.cpp index 02cbfa2199d..8896edf0fc2 100644 --- a/src/devices/machine/hp_taco.cpp +++ b/src/devices/machine/hp_taco.cpp @@ -141,16 +141,18 @@ #include "hp_taco.h" // Debugging -#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__) #define LOG_REG_MASK (LOG_RW_MASK << 1) + +#define LOG_DBG(...) LOGMASKED(LOG_DBG_MASK, __VA_ARGS__) +#define LOG_RW(...) LOGMASKED(LOG_RW_MASK, __VA_ARGS__) #define LOG_REG(...) LOGMASKED(LOG_REG_MASK, __VA_ARGS__) -#undef VERBOSE + //#define VERBOSE (LOG_GENERAL | LOG_DBG_MASK | LOG_RW_MASK | LOG_REG_MASK) #define VERBOSE (LOG_GENERAL) +#include "logmacro.h" // Bit manipulation namespace { @@ -159,24 +161,17 @@ namespace { return (T)1U << n; } - template<typename T> void BIT_CLR(T& w , unsigned n) + template<typename T> void BIT_CLR(T& w, unsigned n) { w &= ~BIT_MASK<T>(n); } - template<typename T> void BIT_SET(T& w , unsigned n) + template<typename T> void BIT_SET(T& w, unsigned n) { w |= BIT_MASK<T>(n); } } -// Timers -enum { - GAP_TMR_ID, - EVD_TMR_ID, - ERROR_TMR_ID -}; - // **** Constants **** constexpr unsigned TACH_FREQ_FAST = 87196; // Tachometer pulse frequency for fast speed (90.08 ips) constexpr unsigned TACH_FREQ_SLOW = 21276; // Tachometer pulse frequency for slow speed (21.98 ips) @@ -281,7 +276,7 @@ DEFINE_DEVICE_TYPE(HP_TACO, hp_taco_device, "hp_taco", "HP TACO") // Constructors hp_taco_device::hp_taco_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock) - , m_tape(*this , "drive") + , m_tape(*this, "drive") , m_irq_handler(*this) , m_flg_handler(*this) , m_sts_handler(*this) @@ -300,7 +295,7 @@ void hp_taco_device::set_name(const std::string& name) void hp_taco_device::reg_w(offs_t offset, uint16_t data) { - LOG_REG("wr R%u = %04x\n", 4 + offset , data); + LOG_REG("wr R%u = %04x\n", 4 + offset, data); // Any I/O activity clears IRQ irq_w(false); @@ -344,9 +339,9 @@ uint16_t hp_taco_device::reg_r(offs_t offset) case 1: // Command & status register if (m_tape->gap_reached(SHORT_GAP_LENGTH)) { - BIT_SET(m_status_reg , CMD_ST_GAP); + BIT_SET(m_status_reg, CMD_ST_GAP); } else { - BIT_CLR(m_status_reg , CMD_ST_GAP); + BIT_CLR(m_status_reg, CMD_ST_GAP); } res = (m_cmd_reg & CMD_REG_MASK) | (m_status_reg & STATUS_REG_MASK); break; @@ -363,7 +358,7 @@ uint16_t hp_taco_device::reg_r(offs_t offset) break; } - LOG_REG("rd R%u = %04x\n", 4 + offset , res); + LOG_REG("rd R%u = %04x\n", 4 + offset, res); return res; } @@ -380,10 +375,10 @@ READ_LINE_MEMBER(hp_taco_device::sts_r) WRITE_LINE_MEMBER(hp_taco_device::cart_out_w) { - LOG_DBG("cart_out_w %d\n" , state); + LOG_DBG("cart_out_w %d\n", state); set_tape_present(!state); if (state && m_cmd_state != CMD_IDLE) { - set_error(true , false); + set_error(true, false); m_cmd_state = CMD_IDLE; } } @@ -393,10 +388,10 @@ WRITE_LINE_MEMBER(hp_taco_device::hole_w) if (state) { LOG_DBG("hole_w\n"); if (m_cmd_state != CMD_IDLE && m_cmd_state != CMD_STOPPING && - (!is_double_hole_cmd(m_cmd_reg) || BIT(m_status_reg , CMD_ST_HOLE))) { - set_error(true , false); + (!is_double_hole_cmd(m_cmd_reg) || BIT(m_status_reg, CMD_ST_HOLE))) { + set_error(true, false); } - BIT_SET(m_status_reg , CMD_ST_HOLE); + BIT_SET(m_status_reg, CMD_ST_HOLE); } } @@ -427,7 +422,7 @@ WRITE_LINE_MEMBER(hp_taco_device::tacho_tick_w) if (m_cmd_state == CMD_PH2) { m_tach_reg++; if (m_tach_reg == 0) { - if (!BIT(m_cmd_reg , CMD_ST_G0)) { + if (!BIT(m_cmd_reg, CMD_ST_G0)) { irq_w(true); } send_stop(); @@ -465,7 +460,7 @@ WRITE_LINE_MEMBER(hp_taco_device::motion_w) WRITE_LINE_MEMBER(hp_taco_device::rd_bit_w) { - LOG_RW("RD bit %d (st=%d,w=%04x,i=%u)\n" , state , m_cmd_state , m_working_reg , m_bit_idx); + LOG_RW("RD bit %d (st=%d,w=%04x,i=%u)\n", state, m_cmd_state, m_working_reg, m_bit_idx); if (m_cmd_state != CMD_IDLE) { switch (get_cmd(m_cmd_reg)) { case CMD_RD_6UPD: @@ -479,7 +474,7 @@ WRITE_LINE_MEMBER(hp_taco_device::rd_bit_w) // Synchronized LOG_RW("RD synced!\n"); m_cmd_state = CMD_PH2; - m_bit_idx = BIT(m_cmd_reg , CMD_ST_G0) ? 17 : 15; + m_bit_idx = BIT(m_cmd_reg, CMD_ST_G0) ? 17 : 15; m_working_reg = 0; } } else if (m_cmd_state == CMD_PH2) { @@ -489,15 +484,15 @@ WRITE_LINE_MEMBER(hp_taco_device::rd_bit_w) break; } else if (m_bit_idx != 16 && state) { // Skip 17th bit when reading in 9825 format - BIT_SET(m_working_reg , m_bit_idx); + BIT_SET(m_working_reg, m_bit_idx); } if (adv_bit_idx()) { m_data_reg = m_working_reg; m_working_reg = 0; - if (!BIT(m_cmd_reg , CMD_ST_G2)) { + if (!BIT(m_cmd_reg, CMD_ST_G2)) { update_checksum(m_data_reg); } - LOG_RW("RD word %04x csum=%04x\n" , m_data_reg , m_checksum_reg); + LOG_RW("RD word %04x csum=%04x\n", m_data_reg, m_checksum_reg); irq_w(true); } } @@ -529,7 +524,7 @@ READ_LINE_MEMBER(hp_taco_device::wr_bit_r) // HP9825 format: 17th bit bit = true; } else { - bit = BIT(m_working_reg , m_bit_idx); + bit = BIT(m_working_reg, m_bit_idx); } if (adv_bit_idx()) { m_working_reg = m_data_reg; @@ -537,20 +532,20 @@ READ_LINE_MEMBER(hp_taco_device::wr_bit_r) if ((get_cmd(m_cmd_reg) & ~BIT_MASK<uint8_t>(0)) != CMD_WR_CSUM) { update_checksum(m_data_reg); } - LOG_RW("WR word %04x csum=%04x\n" , m_working_reg , m_checksum_reg); + LOG_RW("WR word %04x csum=%04x\n", m_working_reg, m_checksum_reg); m_data_reg = m_checksum_reg; irq_w(true); } } - LOG_RW("WR bit %d (w=%04x,i=%u)\n" , bit , m_working_reg , m_bit_idx); + LOG_RW("WR bit %d (w=%04x,i=%u)\n", bit, m_working_reg, m_bit_idx); return bit; } void hp_taco_device::device_add_mconfig(machine_config &config) { - HP_DC100_TAPE(config , m_tape , 0); + HP_DC100_TAPE(config, m_tape, 0); m_tape->set_acceleration(ACCELERATION); - m_tape->set_set_points(SLOW_SPEED , FAST_SPEED); + m_tape->set_set_points(SLOW_SPEED, FAST_SPEED); m_tape->set_tick_size(TACH_TICK_LEN); m_tape->set_image_format(hti_format_t::HTI_DELTA_MOD_16_BITS); m_tape->set_go_threshold(MOVING_THRESHOLD); @@ -583,9 +578,9 @@ void hp_taco_device::device_start() save_item(NAME(m_working_reg)); save_item(NAME(m_bit_idx)); - m_gap_timer = timer_alloc(GAP_TMR_ID); - m_evd_timer = timer_alloc(EVD_TMR_ID); - m_error_timer = timer_alloc(ERROR_TMR_ID); + m_gap_timer = timer_alloc(FUNC(hp_taco_device::gap_timer_tick), this); + m_evd_timer = timer_alloc(FUNC(hp_taco_device::evd_timer_tick), this); + m_error_timer = timer_alloc(FUNC(hp_taco_device::error_timer_tick), this); } void hp_taco_device::device_reset() @@ -600,69 +595,51 @@ void hp_taco_device::device_reset() m_irq_handler(false); m_flg_handler(true); m_sts_handler(true); - set_error(false , false); + set_error(false, false); m_gap_timer->reset(); m_evd_timer->reset(); m_error_timer->reset(); } -void hp_taco_device::device_timer(emu_timer &timer, device_timer_id id, int param) +TIMER_CALLBACK_MEMBER(hp_taco_device::gap_timer_tick) { - switch (id) { - case GAP_TMR_ID: - m_tape->update_speed_pos(); - LOG_DBG("Gap tmr @%g pos=%d cmd %02x st %d\n" , machine().time().as_double() , m_tape->get_pos() , get_cmd(m_cmd_reg) , m_cmd_state); - - switch (get_cmd(m_cmd_reg)) { - case CMD_INT_ON_GAP: - if (m_cmd_state == CMD_PH1) { - irq_and_end(); - } - break; - - case CMD_STOP_IN_GAP: - case CMD_STOP_IN_GAP1: - if (m_cmd_state == CMD_PH1) { - // Count 256 ticks - m_tach_reg = 0xff00; - m_cmd_state = CMD_PH2; - } - break; - - case CMD_INT_N_GAP: - if (m_cmd_state == CMD_PH1) { - m_tach_reg++; - if (m_tach_reg == 0) { - irq_and_end(); - } else { - set_gap_timer(); - } - } - break; + m_tape->update_speed_pos(); + LOG_DBG("Gap tmr @%g pos=%d cmd %02x st %d\n", machine().time().as_double(), m_tape->get_pos(), get_cmd(m_cmd_reg), m_cmd_state); - case CMD_RD_6UPD: - case CMD_RD_9825_6UPD: - case CMD_RD_CSUM_6UPD: - case CMD_RD_9825_CSUM6: - // Gap in read error - set_error(false , true); - break; + switch (get_cmd(m_cmd_reg)) { + case CMD_INT_ON_GAP: + if (m_cmd_state == CMD_PH1) { + irq_and_end(); + } + break; - default: - break; + case CMD_STOP_IN_GAP: + case CMD_STOP_IN_GAP1: + if (m_cmd_state == CMD_PH1) { + // Count 256 ticks + m_tach_reg = 0xff00; + m_cmd_state = CMD_PH2; } break; - case EVD_TMR_ID: - m_tape->update_speed_pos(); - LOG_DBG("EVD tmr @%g pos=%d cmd %02x st %d\n" , machine().time().as_double() , m_tape->get_pos() , get_cmd(m_cmd_reg) , m_cmd_state); - set_error(true , false); + case CMD_INT_N_GAP: + if (m_cmd_state == CMD_PH1) { + m_tach_reg++; + if (m_tach_reg == 0) { + irq_and_end(); + } else { + set_gap_timer(); + } + } break; - case ERROR_TMR_ID: - LOG_DBG("Error tmr\n"); - irq_w(true); + case CMD_RD_6UPD: + case CMD_RD_9825_6UPD: + case CMD_RD_CSUM_6UPD: + case CMD_RD_9825_CSUM6: + // Gap in read error + set_error(false, true); break; default: @@ -670,6 +647,19 @@ void hp_taco_device::device_timer(emu_timer &timer, device_timer_id id, int para } } +TIMER_CALLBACK_MEMBER(hp_taco_device::evd_timer_tick) +{ + m_tape->update_speed_pos(); + LOG_DBG("EVD tmr @%g pos=%d cmd %02x st %d\n", machine().time().as_double(), m_tape->get_pos(), get_cmd(m_cmd_reg), m_cmd_state); + set_error(true, false); +} + +TIMER_CALLBACK_MEMBER(hp_taco_device::error_timer_tick) +{ + LOG_DBG("Error tmr\n"); + irq_w(true); +} + void hp_taco_device::clear_state() { m_data_reg = 0; @@ -691,7 +681,7 @@ void hp_taco_device::irq_w(bool state) if (state != m_irq) { m_irq = state; m_irq_handler(state); - LOG_DBG("IRQ = %d\n" , state); + LOG_DBG("IRQ = %d\n", state); } } @@ -700,13 +690,13 @@ void hp_taco_device::sts_w(bool state) if (state != m_sts) { m_sts = state; m_sts_handler(state); - LOG_DBG("STS = %d\n" , state); + LOG_DBG("STS = %d\n", state); } } -void hp_taco_device::set_error(bool error , bool gap_in_read) +void hp_taco_device::set_error(bool error, bool gap_in_read) { - LOG_DBG("Error %d %d\n" , error , gap_in_read); + LOG_DBG("Error %d %d\n", error, gap_in_read); m_error = error; m_gap_in_read = gap_in_read; @@ -718,7 +708,7 @@ void hp_taco_device::set_error(bool error , bool gap_in_read) m_cmd_state = CMD_IDLE; } sts_w(false); - m_error_timer->adjust(attotime::zero , 0 , clocks_to_attotime(ERROR_IRQ_PERIOD)); + m_error_timer->adjust(attotime::zero, 0, clocks_to_attotime(ERROR_IRQ_PERIOD)); if (m_error) { send_stop(); } @@ -729,17 +719,17 @@ void hp_taco_device::set_error(bool error , bool gap_in_read) hti_format_t::tape_pos_t hp_taco_device::min_gap_size() const { - return BIT(m_cmd_reg , CMD_ST_FGAP) ? LONG_GAP_LENGTH : SHORT_GAP_LENGTH; + return BIT(m_cmd_reg, CMD_ST_FGAP) ? LONG_GAP_LENGTH : SHORT_GAP_LENGTH; } void hp_taco_device::set_gap_timer() { - m_tape->time_to_next_gap(min_gap_size() , true , m_gap_timer); + m_tape->time_to_next_gap(min_gap_size(), true, m_gap_timer); } void hp_taco_device::set_evd_timer() { - m_tape->time_to_next_gap(EVD_GAP_LENGTH , false , m_evd_timer); + m_tape->time_to_next_gap(EVD_GAP_LENGTH, false, m_evd_timer); } void hp_taco_device::set_tape_present(bool present) @@ -761,18 +751,18 @@ void hp_taco_device::send_go() { hp_dc100_tape_device::tape_speed_t speed; - if (BIT(m_cmd_reg , CMD_ST_FST)) { + if (BIT(m_cmd_reg, CMD_ST_FST)) { speed = hp_dc100_tape_device::SP_FAST; } else { speed = hp_dc100_tape_device::SP_SLOW; } - m_tape->set_speed_setpoint(speed , BIT(m_cmd_reg , CMD_ST_FWD)); + m_tape->set_speed_setpoint(speed, BIT(m_cmd_reg, CMD_ST_FWD)); } void hp_taco_device::send_stop() { m_tape->set_op(hp_dc100_tape_device::OP_IDLE); - if (m_tape->set_speed_setpoint(hp_dc100_tape_device::SP_STOP , false)) { + if (m_tape->set_speed_setpoint(hp_dc100_tape_device::SP_STOP, false)) { m_cmd_state = CMD_STOPPING; } } @@ -800,7 +790,7 @@ void hp_taco_device::start_rd() if (m_tape->get_op() != hp_dc100_tape_device::OP_READ) { m_tape->set_op(hp_dc100_tape_device::OP_READ); // TODO: check - m_tape->time_to_next_gap(GIR_GAP_LENGTH , true , m_gap_timer); + m_tape->time_to_next_gap(GIR_GAP_LENGTH, true, m_gap_timer); set_evd_timer(); } } @@ -817,7 +807,7 @@ bool hp_taco_device::adv_bit_idx() if (m_bit_idx) { m_bit_idx--; } else { - m_bit_idx = BIT(m_cmd_reg , CMD_ST_G0) ? 16 : 15; + m_bit_idx = BIT(m_cmd_reg, CMD_ST_G0) ? 16 : 15; } return m_bit_idx == 15; } @@ -942,7 +932,7 @@ void hp_taco_device::cmd_fsm() } } if (prev_state != m_cmd_state) { - LOG_DBG("FSM st %d->%d\n" , prev_state , m_cmd_state); + LOG_DBG("FSM st %d->%d\n", prev_state, m_cmd_state); } } @@ -955,17 +945,17 @@ uint8_t hp_taco_device::get_cmd(uint16_t cmd_reg) bool hp_taco_device::is_cmd_rd_wr(uint16_t cmd_reg) { - return BIT(cmd_reg , CMD_ST_G1); + return BIT(cmd_reg, CMD_ST_G1); } bool hp_taco_device::is_cmd_rd(uint16_t cmd_reg) { - return is_cmd_rd_wr(cmd_reg) && BIT(cmd_reg , CMD_ST_G3); + return is_cmd_rd_wr(cmd_reg) && BIT(cmd_reg, CMD_ST_G3); } bool hp_taco_device::is_cmd_wr(uint16_t cmd_reg) { - return is_cmd_rd_wr(cmd_reg) && !BIT(cmd_reg , CMD_ST_G3); + return is_cmd_rd_wr(cmd_reg) && !BIT(cmd_reg, CMD_ST_G3); } bool hp_taco_device::is_double_hole_cmd(uint16_t cmd_reg) @@ -975,7 +965,7 @@ bool hp_taco_device::is_double_hole_cmd(uint16_t cmd_reg) void hp_taco_device::start_cmd_exec(uint16_t new_cmd_reg) { - LOG_DBG("New cmd %02x D=%d S=%d @ %g cmd %02x st %d\n" , get_cmd(new_cmd_reg) , BIT(new_cmd_reg , CMD_ST_FWD) , BIT(new_cmd_reg , CMD_ST_FST) , machine().time().as_double() , get_cmd(m_cmd_reg) , m_cmd_state); + LOG_DBG("New cmd %02x D=%d S=%d @ %g cmd %02x st %d\n", get_cmd(new_cmd_reg), BIT(new_cmd_reg, CMD_ST_FWD), BIT(new_cmd_reg, CMD_ST_FST), machine().time().as_double(), get_cmd(m_cmd_reg), m_cmd_state); m_tape->update_speed_pos(); @@ -983,7 +973,7 @@ void hp_taco_device::start_cmd_exec(uint16_t new_cmd_reg) if (new_cmd_code == CMD_CLEAR_ST) { // Clear status - set_error(false , false); + set_error(false, false); sts_w(true); if (!m_tape->cart_out_r()) { BIT_CLR(m_status_reg, CMD_ST_CART_OUT); @@ -998,7 +988,7 @@ void hp_taco_device::start_cmd_exec(uint16_t new_cmd_reg) hp_dc100_tape_device::tape_op_t op = hp_dc100_tape_device::OP_IDLE; if (m_gap_in_read) { - set_error(false , false); + set_error(false, false); } m_cmd_state = CMD_PH0; @@ -1048,11 +1038,11 @@ void hp_taco_device::start_cmd_exec(uint16_t new_cmd_reg) case CMD_SET_TRACK: // 1. Set A/B track - if (BIT(new_cmd_reg , CMD_ST_MOD)) { - BIT_SET(m_status_reg , CMD_ST_TRB); + if (BIT(new_cmd_reg, CMD_ST_MOD)) { + BIT_SET(m_status_reg, CMD_ST_TRB); m_tape->set_track_no(1); } else { - BIT_CLR(m_status_reg , CMD_ST_TRB); + BIT_CLR(m_status_reg, CMD_ST_TRB); m_tape->set_track_no(0); } start_tape = false; @@ -1128,16 +1118,16 @@ void hp_taco_device::start_cmd_exec(uint16_t new_cmd_reg) break; default: - LOG("Unrecognized command %x\n" , new_cmd_code); + LOG("Unrecognized command %x\n", new_cmd_code); start_tape = false; break; } if (start_tape) { if (m_error || - (BIT(m_status_reg , CMD_ST_HOLE) && !is_double_hole_cmd(new_cmd_reg)) || - BIT(m_status_reg , CMD_ST_CART_OUT)) { - set_error(true , false); + (BIT(m_status_reg, CMD_ST_HOLE) && !is_double_hole_cmd(new_cmd_reg)) || + BIT(m_status_reg, CMD_ST_CART_OUT)) { + set_error(true, false); return; } else { send_go(); |