void wd33c9x_base_device::update_irq() { if (m_regs[AUXILIARY_STATUS] & AUXILIARY_STATUS_INT) { m_regs[AUXILIARY_STATUS] &= ~AUXILIARY_STATUS_INT; LOGMASKED(LOG_LINES, "%s: Clearing IRQ\n", shortname()); m_irq_cb(CLEAR_LINE); } if (!irq_fifo_empty()) { m_regs[SCSI_STATUS] = irq_fifo_pop(); m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_INT; const uint8_t cc = (m_regs[COMMAND] & COMMAND_CC); if (cc == COMMAND_CC_SELECT_TRANSFER || cc == COMMAND_CC_SELECT_ATN_TRANSFER) { switch (m_regs[SCSI_STATUS]) { case SCSI_STATUS_DISCONNECT: if (!(m_regs[CONTROL] & CONTROL_IDI)) { return; } break; case SCSI_STATUS_SELECT_TRANSFER_SUCCESS: if ((m_regs[CONTROL] & CONTROL_EDI) && m_mode != MODE_D) { return; } break; } } LOGMASKED(LOG_LINES, "%s: Asserting IRQ - SCSI Status (%02x)\n", shortname(), m_regs[SCSI_STATUS]); m_irq_cb(ASSERT_LINE); } }
/* should be called after any change to int_state or enabled_ints. */ void tms9901_device::field_interrupts() { int current_ints; // m_int_state: inverted state of lines INT1*-INT15*. Bits are set by set_single_int only. current_ints = m_int_state; if (m_clock_register != 0) { // if timer is enabled, INT3 pin is overridden by timer if (m_timer_int_pending) { LOGMASKED(LOG_INT, "INT3 (timer) asserted\n"); current_ints |= INT3; } else { LOGMASKED(LOG_INT, "INT3 (timer) cleared\n"); current_ints &= ~INT3; } } // enabled_ints: enabled interrupts // Remove all settings from pins that are set as outputs (INT7*-INT15* share the same pins as P15-P7) current_ints &= m_enabled_ints & (~m_pio_direction_mirror); // Check whether we have a new state. For systems that use level-triggered // interrupts it should not do any harm if the line is re-asserted // but we may as well avoid this. if (current_ints == m_old_int_state) return; m_old_int_state = current_ints; if (current_ints != 0) { // find which interrupt tripped us: // the number of the first (i.e. least significant) non-zero bit among // the 16 first bits // we simply look for the first bit set to 1 in current_ints... int level = 0; while ((current_ints & 1)==0) { current_ints >>= 1; /* try next bit */ level++; } LOGMASKED(LOG_INT, "Triggering interrupt, level %d\n", level); m_int_pending = true; if (!m_interrupt.isnull()) m_interrupt(level, 1, 0xff); // the offset carries the IC0-3 level }
uint8_t m68340_cpu_device::int_ack(offs_t offset) { uint8_t pit_iarb = pit_arbitrate(offset); uint8_t scu_iarb = m_serial->arbitrate(offset); uint8_t t1_iarb = m_timer[0]->arbitrate(offset); uint8_t t2_iarb = m_timer[1]->arbitrate(offset); uint8_t iarb = std::max({pit_iarb, scu_iarb, t1_iarb, t2_iarb}); LOGMASKED(LOG_IPL, "Level %d interrupt arbitration: PIT = %X, SCU = %X, T1 = %X, T2 = %X\n", offset, pit_iarb, scu_iarb, t1_iarb, t2_iarb); int response = 0; uint8_t vector = 0x18; // Spurious interrupt // Valid IARB levels are F (high) to 1 (low) and should be unique among modules using the same interrupt level if (iarb != 0) { if (iarb == scu_iarb) { vector = m_serial->irq_vector(); LOGMASKED(LOG_IPL, "SCU acknowledged interrupt with vector %02X\n", vector); response++; } if (iarb == t1_iarb) { vector = m_timer[0]->irq_vector(); LOGMASKED(LOG_IPL, "T1 acknowledged interrupt with vector %02X\n", vector); response++; } if (iarb == t2_iarb) { vector = m_timer[1]->irq_vector(); LOGMASKED(LOG_IPL, "T2 acknowledged interrupt with vector %02X\n", vector); response++; } if (iarb == pit_iarb) { vector = pit_iack(); LOGMASKED(LOG_IPL, "PIT acknowledged interrupt with vector %02X\n", vector); response++; } } if (response == 0) logerror("Spurious interrupt (level %d)\n", offset); else if (response > 1) logerror("%d modules responded to interrupt (level %d, IARB = %X)\n", response, offset, iarb); return vector; }
void i8155_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { if (m_count_extra) { m_count_extra = false; return; } // count down by twos m_counter -= 2; if (m_counter == 1) { LOGMASKED(LOG_TIMER, "Timer count half finished\n"); // reload the even half of the count m_counter = m_count_loaded & 0x3ffe; // square wave modes produce a low output in the second half of the counting period if ((get_timer_mode() & TIMER_MODE_TC_PULSE) == 0) timer_output(0); } else if (m_counter == 2) { if ((get_timer_mode() & TIMER_MODE_TC_PULSE) != 0) { // pulse low on TC being reached timer_output(0); } // set timer flag m_status |= STATUS_TIMER; } else if (m_counter == 0) { timer_output(1); if ((get_timer_mode() & TIMER_MODE_AUTO_RELOAD) == 0 || (m_command & COMMAND_TM_MASK) == COMMAND_TM_STOP_AFTER_TC) { // stop timer timer_stop_count(); LOGMASKED(LOG_TIMER, "Timer stopped\n"); } else { // automatically reload the counter timer_reload_count(); } } }
void aic6250_device::offset_cntrl_w(u8 data) { LOGMASKED(LOG_REG, "offset_cntrl_w 0x%02x\n", data); if (VERBOSE & LOG_CONFIG) { if (data & R04W_OFFSET) { double divisor = 4.0 + ((data & R04W_SYNC_XFER_RATE) >> 4); LOGMASKED(LOG_CONFIG, "synchronous offset %d speed %.3f\n", data & R04W_OFFSET, clock() / divisor); } else
bool wd33c9x_base_device::set_command_length(const uint8_t cc) { const bool eaf = ((m_regs[OWN_ID] & OWN_ID_EAF) != 0); bool ret; if (eaf && (cc == COMMAND_CC_SELECT_TRANSFER || cc == COMMAND_CC_SELECT_ATN_TRANSFER)) { m_command_length &= OWN_ID_CDB_SIZE; ret = true; } else if (eaf && cc == COMMAND_CC_WAIT_SELECT_RECEIVE_DATA) { m_command_length = 6; m_regs[COMMAND_PHASE] = COMMAND_PHASE_CP_BYTES_1; irq_fifo_push(SCSI_STATUS_NEED_COMMAND_SIZE); update_irq(); ret = false; } else { switch (m_regs[CDB_1] >> 5) { default: case 0: m_command_length = 6; break; case 1: m_command_length = 10; break; case 5: m_command_length = 12; break; } ret = true; } LOGMASKED(LOG_COMMANDS, "%s: SCSI Command Length %d bytes\n", shortname(), m_command_length); return ret; }
void wd33c9x_base_device::set_drq() { if (!m_drq_state) { LOGMASKED(LOG_LINES, "%s: Asserting DRQ\n", shortname()); m_drq_state = true; m_drq_cb(ASSERT_LINE); } }
void wd33c9x_base_device::clear_drq() { if (m_drq_state) { LOGMASKED(LOG_LINES, "%s: Clearing DRQ\n", shortname()); m_drq_state = false; m_drq_cb(CLEAR_LINE); } }
inline void i8155_device::timer_output(int to) { if (to == m_to) return; m_to = to; m_out_to_cb(to); LOGMASKED(LOG_TIMER, "Timer output: %u\n", to); }
uint8_t a2bus_echoii_device::read_c0nx(uint8_t offset) { // offset is completely ignored on the echoii (but not so on the echo+), so the same register maps to the entire space. uint8_t retval = 0xff; // pull-up resistor pack on the tms5220 bus // upon the falling edge of /DEVREAD, the active part of the read... if (m_readlatch_flag == false) // /RS was low, so we need to return a value from the tms5220 { retval = 0x1f | m_tms->status_r(machine().dummy_space(), 0, 0xff); LOGMASKED(LOG_READ,"Returning status of speech chip, which is %02x\n", retval); } else LOGMASKED(LOG_READ,"chip status read on odd cycle, returning pull-up value of %02x\n", retval); // upon the rising edge of /DEVREAD, i.e. after the read has finished (so no updating retval after this) m_readlatch_flag = (!m_readlatch_flag); // latch inverts itself upon each read... m_tms->rsq_w(m_readlatch_flag); // update the /RS pin return retval; }
inline void i8155_device::timer_reload_count() { m_count_loaded = m_count_length; // valid counts range from 2 to 3FFF if ((m_count_length & 0x3fff) < 2) { timer_stop_count(); return; } // begin the odd half of the count, with one extra cycle if count is odd m_counter = (m_count_loaded & 0x3ffe) | 1; m_count_extra = BIT(m_count_loaded, 0); // set up our timer m_timer->adjust(attotime::zero, 0, clocks_to_attotime(1)); timer_output(1); switch (get_timer_mode()) { case 0: // puts out LOW during second half of count LOGMASKED(LOG_TIMER, "Timer loaded with %d (Mode: LOW)\n", m_count_loaded & 0x3fff); break; case TIMER_MODE_AUTO_RELOAD: // square wave, i.e. the period of the square wave equals the count length programmed with automatic reload at terminal count LOGMASKED(LOG_TIMER, "Timer loaded with %d (Mode: Square wave)\n", m_count_loaded & 0x3fff); break; case TIMER_MODE_TC_PULSE: // single pulse upon TC being reached LOGMASKED(LOG_TIMER, "Timer loaded with %d (Mode: Single pulse)\n", m_count_loaded & 0x3fff); break; case TIMER_MODE_TC_PULSE | TIMER_MODE_AUTO_RELOAD: // automatic reload, i.e. single pulse every time TC is reached LOGMASKED(LOG_TIMER, "Timer loaded with %d (Mode: Automatic reload)\n", m_count_loaded & 0x3fff); break; } }
uint8_t ps2_keyboard_controller_device::status_r() { u8 const data = m_mcu->upi41_master_r(machine().dummy_space(), 1U); LOGMASKED(LOG_STATUS, "status_r 0x%02x%s%s%s%s%s%s%s%s (%s)\n", data, BIT(data, 7) ? " PER" : "", BIT(data, 6) ? " GTO" : "", BIT(data, 5) ? " AUX_OBF" : "", BIT(data, 4) ? " INH" : "", BIT(data, 3) ? " CMD" : "", BIT(data, 2) ? " SYS" : "", BIT(data, 1) ? " IBF" : "", BIT(data, 0) ? " OBF" : "", machine().describe_context()); return data; }
void peribox_device::lcp_join(int slot, int state) { LOGMASKED(LOG_INT, "propagating LCP from slot %d to SGCPU: %d\n", slot, state); if (state==ASSERT_LINE) m_lcp_flag |= (1 << slot); else m_lcp_flag &= ~(1 << slot); // Not propagated to console if (!m_ioport_connected) m_slot1_lcp((m_lcp_flag != 0)? ASSERT_LINE : CLEAR_LINE); }
/* The INTA*, INTB*, and READY* lines are connected to each PEB card and are pulled up when inactive. If any card asserts the line (pulling down), the line state goes down. So we must keep a record which cards pull down the line. (We're doing a kind of wired-AND here.) */ void peribox_device::inta_join(int slot, int state) { LOGMASKED(LOG_INT, "propagating INTA from slot %d to console: %d\n", slot, state); if (state==ASSERT_LINE) m_inta_flag |= (1 << slot); else m_inta_flag &= ~(1 << slot); if (m_ioport_connected) set_extint((m_inta_flag != 0)? ASSERT_LINE : CLEAR_LINE); else m_slot1_inta((m_inta_flag != 0)? ASSERT_LINE : CLEAR_LINE); }
/* When any device pulls down READY, READY goes down. */ void peribox_device::ready_join(int slot, int state) { LOGMASKED(LOG_READY, "Incoming READY=%d from slot %d\n", state, slot); // We store the inverse state if (state==CLEAR_LINE) m_ready_flag |= (1 << slot); else m_ready_flag &= ~(1 << slot); if (m_ioport_connected) set_ready((m_ready_flag != 0)? CLEAR_LINE : ASSERT_LINE); else m_slot1_ready((m_ready_flag != 0)? CLEAR_LINE : ASSERT_LINE); }
void peribox_device::device_start() { // Resolve the callback lines to the console m_slot1_inta.resolve(); m_slot1_intb.resolve(); m_slot1_lcp.resolve(); m_slot1_ready.resolve(); m_ioport_connected = (m_slot1_inta.isnull()); // TODO: init LOGMASKED(LOG_CONFIG, "AMA/B/C address prefix set to %05x\n", m_address_prefix); for (int i=2; i < 9; i++) { LOGMASKED(LOG_CONFIG, "Slot %d = %s\n", i, (m_slot[i] != nullptr)? m_slot[i]->card_name() : "empty"); } save_item(NAME(m_inta_flag)); save_item(NAME(m_intb_flag)); save_item(NAME(m_lcp_flag)); save_item(NAME(m_ready_flag)); save_item(NAME(m_msast)); save_item(NAME(m_memen)); }
void a2bus_echoii_device::write_c0nx(uint8_t offset, uint8_t data) { // offset is completely ignored on the echoii (but not so on the echo+), so the same register maps to the entire space. if (m_writelatch_flag == false) logerror("Data in echoii latch (%02x) was clobbered with new write (%02x) before being read by speech chip!\n", m_writelatch_data, data); else LOGMASKED(LOG_WRITE,"Data written to latch of %02x\n", data); m_writelatch_data = data; m_writelatch_flag = false; // /DEVWRITE clears the latch on its falling edge m_tms->wsq_w(m_writelatch_flag); m_tms->data_w(machine().dummy_space(), 0, m_writelatch_data); }
void wd33c9x_base_device::load_transfer_count() { if (m_regs[COMMAND] & COMMAND_SBT) { m_transfer_count = 1; } else { m_transfer_count = ( (uint32_t(m_regs[TRANSFER_COUNT_MSB]) << 16) | (uint32_t(m_regs[TRANSFER_COUNT]) << 8) | (uint32_t(m_regs[TRANSFER_COUNT_LSB]) << 0) ); if (m_transfer_count == 0) { m_transfer_count = 1; } } LOGMASKED(LOG_COMMANDS, "%s: Transfer Count %d bytes\n", shortname(), m_transfer_count); }
void m68340_cpu_device::update_ipl() { uint8_t new_ipl = std::max({ pit_irq_level(), m_serial->irq_level(), m_timer[0]->irq_level(), m_timer[1]->irq_level() }); if (m_ipl != new_ipl) { if (m_ipl != 0) set_input_line(m_ipl, CLEAR_LINE); LOGMASKED(LOG_IPL, "Changing interrupt level from %d to %d\n", m_ipl, new_ipl); m_ipl = new_ipl; if (m_ipl != 0) set_input_line(m_ipl, ASSERT_LINE); } }
void aic6250_device::int_msk_reg_0_w(u8 data) { LOGMASKED(LOG_REG, "int_msk_reg_0_w 0x%02x\n", data); /* * Writing a zero to Bits 0 and 1 of this register will reset the selected * or reselected interrupt status in Status Register 1 (Register 08), * causing the interrupt status to be lost. */ if (!(data & R03W_EN_SELECT_INT)) m_status_reg_1 &= ~R08R_SELECTED; if (!(data & R03W_EN_RESEL_INT)) m_status_reg_1 &= ~R08R_RESELECTED; /* * This bit will be reset to 0 when the Enable Command Done interrupt bit (Reg 03, Bit 3) is set to zero. */ if (!(data & R03W_EN_CMD_DONE_INT)) m_status_reg_1 &= ~R08R_CMD_DONE; if ((m_int_msk_reg_0 ^ data) & R03W_ARB_SEL_START) { if (data & R03W_ARB_SEL_START) { if (m_state != IDLE) fatalerror("attempted to start selection while not idle\n"); m_state = ARB_BUS_FREE; m_state_timer->adjust(attotime::zero); } else { if (m_state == IDLE) fatalerror("attempted to abort selection while idle\n"); m_state = IDLE; } } m_int_msk_reg_0 = data; int_check(); }
INPUT_PORTS_END /**************************************************************************** CRU handling *****************************************************************************/ #define CRU_CONTROL_BASE 0x1ee0 #define CRU_SSTEP_BASE 0x13c0 void geneve_state::cruwrite(offs_t offset, uint8_t data) { int addroff = offset << 1; // Single step // 13c0 - 13fe: 0001 0011 11xx xxx0 if ((addroff & 0xffc0) == CRU_SSTEP_BASE) { int bit = (addroff & 0x003e)>>1; LOGMASKED(LOG_WARN, "Single step not implemented; bit %d set to %d\n", bit, data); return; }
void at_kbc_device_base::command_w(uint8_t data) { if (VERBOSE & LOG_COMMAND) { switch (data) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: LOGMASKED(LOG_COMMAND, "read controller ram indirect 0x%02x (%s)\n", data & 0x3f, machine().describe_context()); break; case 0x20: LOGMASKED(LOG_COMMAND, "read command byte (%s)\n", machine().describe_context()); break; case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: LOGMASKED(LOG_COMMAND, "read controller ram offset 0x%02x (%s)\n", data & 0x3f, machine().describe_context()); break; case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: LOGMASKED(LOG_COMMAND, "write controller ram indirect 0x%02x (%s)\n", data & 0x3f, machine().describe_context()); break; case 0x60: LOGMASKED(LOG_COMMAND, "write command byte (%s)\n", machine().describe_context()); break; case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f: case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: LOGMASKED(LOG_COMMAND, "write controller ram offset 0x%02x (%s)\n", data & 0x3f, machine().describe_context()); break; case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f: LOGMASKED(LOG_COMMAND, "write output port 0x%1x (%s)\n", data & 0xf, machine().describe_context()); break; case 0xa1: LOGMASKED(LOG_COMMAND, "get version number (%s)\n", machine().describe_context()); break; case 0xa4: LOGMASKED(LOG_COMMAND, "test password installed (%s)\n", machine().describe_context()); break; case 0xa5: LOGMASKED(LOG_COMMAND, "load security (%s)\n", machine().describe_context()); break; case 0xa6: LOGMASKED(LOG_COMMAND, "enable security (%s)\n", machine().describe_context()); break; case 0xa7: LOGMASKED(LOG_COMMAND, "disable auxiliary interface (%s)\n", machine().describe_context()); break; case 0xa8: LOGMASKED(LOG_COMMAND, "enable auxiliary interface (%s)\n", machine().describe_context()); break; case 0xa9: LOGMASKED(LOG_COMMAND, "auxiliary interface test (%s)\n", machine().describe_context()); break; case 0xaa: LOGMASKED(LOG_COMMAND, "controller self-test (%s)\n", machine().describe_context()); break; case 0xab: LOGMASKED(LOG_COMMAND, "keyboard interface test (%s)\n", machine().describe_context()); break; case 0xac: LOGMASKED(LOG_COMMAND, "diagnostic dump (%s)\n", machine().describe_context()); break; case 0xad: LOGMASKED(LOG_COMMAND, "disable keyboard interface (%s)\n", machine().describe_context()); break; case 0xae: LOGMASKED(LOG_COMMAND, "enable keyboard interface (%s)\n", machine().describe_context()); break; case 0xaf: LOGMASKED(LOG_COMMAND, "get version (%s)\n", machine().describe_context()); break; case 0xc0: LOGMASKED(LOG_COMMAND, "read input port (%s)\n", machine().describe_context()); break; case 0xc1: LOGMASKED(LOG_COMMAND, "poll input port low (%s)\n", machine().describe_context()); break; case 0xc2: LOGMASKED(LOG_COMMAND, "poll input port high (%s)\n", machine().describe_context()); break; case 0xd0: LOGMASKED(LOG_COMMAND, "read output port (%s)\n", machine().describe_context()); break; case 0xd1: LOGMASKED(LOG_COMMAND, "write output port (%s)\n", machine().describe_context()); break; case 0xd2: LOGMASKED(LOG_COMMAND, "write keyboard output buffer (%s)\n", machine().describe_context()); break; case 0xd3: LOGMASKED(LOG_COMMAND, "write auxiliary output buffer (%s)\n", machine().describe_context()); break; case 0xd4: LOGMASKED(LOG_COMMAND, "write auxiliary device (%s)\n", machine().describe_context()); break; case 0xe0: LOGMASKED(LOG_COMMAND, "read test inputs (%s)\n", machine().describe_context()); break; case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: LOGMASKED(LOG_COMMAND, "pulse output port 0x%1x (%s)\n", data & 0xf, machine().describe_context()); break; default: LOGMASKED(LOG_COMMAND, "unknown command 0x%02x (%s)\n", data, machine().describe_context()); break; } } else LOG("command_w 0x%02x (%s)\n", data, machine().describe_context()); machine().scheduler().synchronize(timer_expired_delegate(FUNC(at_kbc_device_base::write_command), this), unsigned(data)); }
void i8155_device::register_w(int offset, uint8_t data) { switch (offset & 0x07) { case REGISTER_COMMAND: m_command = data; LOGMASKED(LOG_PORT, "Port A Mode: %s\n", (data & COMMAND_PA) ? "output" : "input"); LOGMASKED(LOG_PORT, "Port B Mode: %s\n", (data & COMMAND_PB) ? "output" : "input"); LOGMASKED(LOG_PORT, "Port A Interrupt: %s\n", (data & COMMAND_IEA) ? "enabled" : "disabled"); LOGMASKED(LOG_PORT, "Port B Interrupt: %s\n", (data & COMMAND_IEB) ? "enabled" : "disabled"); switch (data & COMMAND_PC_MASK) { case COMMAND_PC_ALT_1: LOGMASKED(LOG_PORT, "Port C Mode: Alt 1\n"); break; case COMMAND_PC_ALT_2: LOGMASKED(LOG_PORT, "Port C Mode: Alt 2\n"); break; case COMMAND_PC_ALT_3: LOGMASKED(LOG_PORT, "Port C Mode: Alt 3\n"); break; case COMMAND_PC_ALT_4: LOGMASKED(LOG_PORT, "Port C Mode: Alt 4\n"); break; } switch (data & COMMAND_TM_MASK) { case COMMAND_TM_NOP: // do not affect counter operation break; case COMMAND_TM_STOP: // NOP if timer has not started, stop counting if the timer is running LOGMASKED(LOG_PORT, "Timer Command: Stop\n"); timer_stop_count(); break; case COMMAND_TM_STOP_AFTER_TC: // stop immediately after present TC is reached (NOP if timer has not started) LOGMASKED(LOG_PORT, "Timer Command: Stop after TC\n"); break; case COMMAND_TM_START: LOGMASKED(LOG_PORT, "Timer Command: Start\n"); if (m_timer->enabled()) { // if timer is running, start the new mode and CNT length immediately after present TC is reached } else { // load mode and CNT length and start immediately after loading (if timer is not running) timer_reload_count(); } break; } break; case REGISTER_PORT_A: write_port(PORT_A, data); break; case REGISTER_PORT_B: write_port(PORT_B, data); break; case REGISTER_PORT_C: write_port(PORT_C, data & 0x3f); break; case REGISTER_TIMER_LOW: m_count_length = (m_count_length & 0xff00) | data; break; case REGISTER_TIMER_HIGH: m_count_length = (data << 8) | (m_count_length & 0xff); break; } }
void hx5102_device::update_readyff_input() { LOGMASKED(LOG_READY, "MON=%d, MSP=%d, WAIT=%d, INT*=%d, DRQ*=%d, DCS=%d\n", m_motor_on, m_mspeed_on, m_wait, !m_pending_int, !m_pending_drq, m_dcs); m_readyff->d_w(m_motor_on && m_mspeed_on && m_wait && !m_pending_int && !m_pending_drq && m_dcs); }
void wd33c9x_base_device::step(bool timeout) { if (++m_step_count > 1) { return; } const uint8_t cc = (m_regs[COMMAND] & COMMAND_CC); const bool sat = (cc == COMMAND_CC_SELECT_TRANSFER || cc == COMMAND_CC_SELECT_ATN_TRANSFER); uint32_t cycles = 0; do { const uint32_t ctrl = scsi_bus->ctrl_r(); const uint32_t data = scsi_bus->data_r(); m_step_count = 1; LOGMASKED(LOG_STEP, "%s: step - PHASE:%s BSY:%x SEL:%x REQ:%x ACK:%x ATN:%x RST:%x DATA:%x (%d.%d) %s\n", shortname(), phase_strings[ctrl & S_PHASE_MASK], (ctrl & S_BSY) ? 1 : 0, (ctrl & S_SEL) ? 1 : 0, (ctrl & S_REQ) ? 1 : 0, (ctrl & S_ACK) ? 1 : 0, (ctrl & S_ATN) ? 1 : 0, (ctrl & S_RST) ? 1 : 0, data, m_scsi_state & STATE_MASK, m_scsi_state >> SUB_SHIFT, (timeout) ? "timeout" : "change" ); if (m_mode == MODE_I) { if (ctrl & S_BSY) { if (ctrl & S_REQ) { uint8_t xfr_phase = (ctrl & S_PHASE_MASK); switch (m_scsi_state) { case DISC_SEL_ARBITRATION: m_xfr_phase = xfr_phase; break; case INIT_XFR_WAIT_REQ: break; default: if (m_xfr_phase != xfr_phase) { fatalerror("%s: Unexpected phase change during state.\n", shortname()); } break; } } } else { LOGMASKED(LOG_STATE, "%s: Target disconnected\n", shortname()); if (sat) { switch (m_regs[COMMAND_PHASE]) { case COMMAND_PHASE_DISCONNECT_MESSAGE: set_scsi_state(FINISHED); m_regs[COMMAND_PHASE] = COMMAND_PHASE_DISCONNECTED; break; case COMMAND_PHASE_COMMAND_COMPLETE: if (m_regs[CONTROL] & CONTROL_EDI) { set_scsi_state(FINISHED); irq_fifo_push(SCSI_STATUS_SELECT_TRANSFER_SUCCESS); } break; default: fatalerror("%s: Unhandled command phase during Select-and-Transfer disconnect.\n", shortname()); break; } } else { set_scsi_state(FINISHED); irq_fifo_push(SCSI_STATUS_DISCONNECT); } m_mode = MODE_D; scsi_bus->ctrl_w(scsi_refid, 0, S_ALL); scsi_bus->ctrl_wait(scsi_refid, S_SEL|S_BSY|S_RST, S_ALL); continue; } } switch (m_scsi_state & SUB_MASK ? m_scsi_state & SUB_MASK : m_scsi_state & STATE_MASK) { case IDLE: break; case FINISHED: set_scsi_state(IDLE); m_regs[AUXILIARY_STATUS] &= ~(AUXILIARY_STATUS_CIP | AUXILIARY_STATUS_BSY); update_irq(); break; case ARB_WAIT_BUS_FREE << SUB_SHIFT: if (timeout) { if (!(ctrl & (S_BSY | S_SEL))) { set_scsi_state_sub(ARB_CHECK_FREE); } cycles = 1; } break; case ARB_CHECK_FREE << SUB_SHIFT: if (timeout) { uint8_t next_state; if (ctrl & (S_BSY | S_SEL)) { next_state = ARB_WAIT_BUS_FREE; cycles = 1; } else { scsi_bus->data_w(scsi_refid, 1 << scsi_id); scsi_bus->ctrl_w(scsi_refid, S_BSY, S_BSY); next_state = ARB_EXAMINE_BUS; cycles = 1; } set_scsi_state_sub(next_state); } break; case ARB_EXAMINE_BUS << SUB_SHIFT: if (timeout) { if (ctrl & S_SEL) { scsi_bus->ctrl_w(scsi_refid, 0, S_BSY); scsi_bus->data_w(scsi_refid, 0); set_scsi_state_sub(ARB_WAIT_BUS_FREE); } else { int win; for (win = 7; win >=0 && !(data & (1 << win)); win--) {}; if (win == scsi_id) { scsi_bus->ctrl_w(scsi_refid, S_SEL, S_SEL); set_scsi_state_sub(ARB_ASSERT_SEL); } else { scsi_bus->data_w(scsi_refid, 0); scsi_bus->ctrl_w(scsi_refid, 0, S_ALL); } } cycles = 1; } break; case ARB_ASSERT_SEL << SUB_SHIFT: if (timeout) { scsi_bus->data_w(scsi_refid, (1 << scsi_id) | (1 << (m_regs[DESTINATION_ID] & DESTINATION_ID_DI))); set_scsi_state_sub(ARB_SET_DEST); cycles = 1; } break; case ARB_SET_DEST << SUB_SHIFT: if (timeout) { scsi_bus->ctrl_w(scsi_refid, (cc == COMMAND_CC_SELECT_ATN || cc == COMMAND_CC_SELECT_ATN_TRANSFER) ? S_ATN : 0, S_ATN | S_BSY); set_scsi_state_sub(ARB_RELEASE_BUSY); cycles = 1; } break; case ARB_RELEASE_BUSY << SUB_SHIFT: if (timeout) { if (ctrl & S_BSY) { set_scsi_state_sub(ARB_DESKEW_WAIT); if (cc == COMMAND_CC_RESELECT) { scsi_bus->ctrl_w(scsi_refid, S_BSY, S_BSY); } cycles = 1; } else { set_scsi_state_sub(ARB_TIMEOUT_BUSY); cycles = 1; } } break; case ARB_DESKEW_WAIT << SUB_SHIFT: if (timeout) { scsi_bus->data_w(scsi_refid, 0); scsi_bus->ctrl_w(scsi_refid, 0, S_SEL); m_mode = (cc == COMMAND_CC_RESELECT) ? MODE_T : MODE_I; set_scsi_state_sub(0); ++m_step_count; } break; case ARB_TIMEOUT_BUSY << SUB_SHIFT: if (timeout) { scsi_bus->data_w(scsi_refid, 0); set_scsi_state_sub(ARB_TIMEOUT_ABORT); cycles = 1000; } else if (ctrl & S_BSY) { set_scsi_state_sub(ARB_DESKEW_WAIT); if (cc == COMMAND_CC_RESELECT) { scsi_bus->ctrl_w(scsi_refid, S_BSY, S_BSY); } cycles = 1; } break; case ARB_TIMEOUT_ABORT << SUB_SHIFT: if (timeout) { if (ctrl & S_BSY) { set_scsi_state_sub(ARB_DESKEW_WAIT); if (cc == COMMAND_CC_RESELECT) { scsi_bus->ctrl_w(scsi_refid, S_BSY, S_BSY); } cycles = 1; } else { scsi_bus->ctrl_w(scsi_refid, 0, S_ALL); scsi_bus->ctrl_wait(scsi_refid, S_SEL|S_BSY|S_RST, S_ALL); m_regs[AUXILIARY_STATUS] &= ~(AUXILIARY_STATUS_CIP | AUXILIARY_STATUS_BSY); m_mode = MODE_D; set_scsi_state(IDLE); irq_fifo_push(SCSI_STATUS_SELECTION_TIMEOUT); update_irq(); } } break; case SEND_WAIT_SETTLE << SUB_SHIFT: if (timeout) { set_scsi_state_sub(SEND_WAIT_REQ_0); ++m_step_count; } break; case SEND_WAIT_REQ_0 << SUB_SHIFT: if (!(ctrl & S_REQ)) { set_scsi_state_sub(0); scsi_bus->data_w(scsi_refid, 0); scsi_bus->ctrl_w(scsi_refid, 0, S_ACK); if (sat) { switch (m_xfr_phase) { case S_PHASE_COMMAND: ++m_regs[COMMAND_PHASE]; break; } } ++m_step_count; } break; case RECV_WAIT_REQ_1 << SUB_SHIFT: if (ctrl & S_REQ) { set_scsi_state_sub(RECV_WAIT_SETTLE); cycles = 1; } break; case RECV_WAIT_SETTLE << SUB_SHIFT: if (timeout) { if (sat) { switch (m_xfr_phase) { case S_PHASE_DATA_IN: data_fifo_push(data); if ((m_regs[CONTROL] & CONTROL_DM) != CONTROL_DM_POLLED) { set_drq(); } else { decrement_transfer_count(); m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_DBR; } break; case S_PHASE_STATUS: m_regs[TARGET_LUN] = data; m_regs[COMMAND_PHASE] = COMMAND_PHASE_STATUS_RECEIVED; break; case S_PHASE_MSG_IN: data_fifo_push(data); break; default: fatalerror("%s: Unexpected phase in RECV_WAIT_SETTLE.\n", shortname()); break; } } else { data_fifo_push(data); if (m_xfr_phase == S_PHASE_DATA_IN && (m_regs[CONTROL] & CONTROL_DM) != CONTROL_DM_POLLED) { set_drq(); } else { decrement_transfer_count(); m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_DBR; } } set_scsi_state_sub(RECV_WAIT_REQ_0); scsi_bus->ctrl_w(scsi_refid, S_ACK, S_ACK); ++m_step_count; } break; case RECV_WAIT_REQ_0 << SUB_SHIFT: if (!(ctrl & S_REQ)) { set_scsi_state_sub(0); ++m_step_count; } break; case DISC_SEL_ARBITRATION: scsi_bus->ctrl_wait(scsi_refid, S_REQ, S_REQ); if (cc == COMMAND_CC_SELECT || cc == COMMAND_CC_SELECT_ATN) { set_scsi_state(FINISHED); irq_fifo_push(SCSI_STATUS_SELECT_SUCCESS); if (ctrl & S_REQ) { irq_fifo_push(SCSI_STATUS_REQ | m_xfr_phase); } } else { set_scsi_state(INIT_XFR); m_regs[COMMAND_PHASE] = COMMAND_PHASE_SELECTED; } ++m_step_count; break; case INIT_XFR: if (ctrl & S_REQ) { switch (m_xfr_phase) { case S_PHASE_DATA_OUT: if ((m_regs[CONTROL] & CONTROL_DM) != CONTROL_DM_POLLED) { while (!data_fifo_full() && m_transfer_count > 0) { set_drq(); } } if (!data_fifo_empty()) { set_scsi_state(INIT_XFR_WAIT_REQ); cycles = send_byte(); } else if ((m_regs[CONTROL] & CONTROL_DM) == CONTROL_DM_POLLED) { m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_DBR; } break; case S_PHASE_COMMAND: if (!data_fifo_empty()) { uint32_t mask; if (sat) { mask = 0; } else { m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_DBR; mask = (m_transfer_count == 0 && m_data_fifo_size == 1) ? S_ATN : 0; } set_scsi_state(INIT_XFR_WAIT_REQ); cycles = send_byte(0, mask); } else if (!sat) { m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_DBR; } break; case S_PHASE_MSG_OUT: if (sat) { data_fifo_push(get_msg_out()); } if (!data_fifo_empty()) { uint32_t mask; if (sat) { mask = S_ATN; } else { m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_DBR; mask = (m_transfer_count == 0 && m_data_fifo_size == 1) ? S_ATN : 0; } set_scsi_state(INIT_XFR_WAIT_REQ); cycles = send_byte(0, mask); } else if (!sat) { m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_DBR; } break; case S_PHASE_DATA_IN: case S_PHASE_STATUS: case S_PHASE_MSG_IN: if (!data_fifo_full()) { // if it's the last message byte, ACK remains asserted, terminate with function_complete() //state = (m_xfr_phase == S_PHASE_MSG_IN && (!dma_command || tcounter == 1)) ? INIT_XFR_RECV_BYTE_NACK : INIT_XFR_RECV_BYTE_ACK; scsi_bus->ctrl_wait(scsi_refid, S_REQ, S_REQ); set_scsi_state((RECV_WAIT_REQ_1 << SUB_SHIFT) | INIT_XFR_RECV_BYTE_ACK); if (ctrl & S_REQ) { ++m_step_count; } } break; default: fatalerror("%s: Invalid phase during INIT_XFR.\n", shortname()); break; } } break; case INIT_XFR_WAIT_REQ: if (ctrl & S_REQ) { uint16_t next_state = m_scsi_state; const uint8_t xfr_phase = (ctrl & S_PHASE_MASK); switch ((m_xfr_phase << 3) | xfr_phase) { case ((S_PHASE_MSG_OUT << 3) | S_PHASE_MSG_OUT): case ((S_PHASE_COMMAND << 3) | S_PHASE_COMMAND): case ((S_PHASE_MSG_IN << 3) | S_PHASE_MSG_IN): next_state = INIT_XFR; break; case ((S_PHASE_DATA_IN << 3) | S_PHASE_DATA_IN): case ((S_PHASE_DATA_OUT << 3) | S_PHASE_DATA_OUT): if (sat || cc == COMMAND_CC_TRANSFER_INFO) { if (m_transfer_count > 0 || (m_xfr_phase == S_PHASE_DATA_OUT && !data_fifo_empty())) { next_state = INIT_XFR; } else { next_state = FINISHED; uint8_t scsi_status; if (sat) { m_regs[COMMAND_PHASE] = COMMAND_PHASE_TRANSFER_COUNT; scsi_status = SCSI_STATUS_UNEXPECTED_PHASE; } else { scsi_status = SCSI_STATUS_TRANSFER_SUCCESS; } irq_fifo_push(scsi_status | m_xfr_phase); } } else { fatalerror("%s: Unhandled command in data phase.\n", shortname()); next_state = FINISHED; } break; case ((S_PHASE_MSG_OUT << 3) | S_PHASE_COMMAND): case ((S_PHASE_COMMAND << 3) | S_PHASE_DATA_OUT): case ((S_PHASE_COMMAND << 3) | S_PHASE_DATA_IN): case ((S_PHASE_COMMAND << 3) | S_PHASE_STATUS): case ((S_PHASE_COMMAND << 3) | S_PHASE_MSG_IN): case ((S_PHASE_DATA_OUT << 3) | S_PHASE_STATUS): case ((S_PHASE_DATA_IN << 3) | S_PHASE_STATUS): case ((S_PHASE_STATUS << 3) | S_PHASE_MSG_IN): if (!(m_xfr_phase & 1) && !data_fifo_empty()) { fatalerror("%s: Data FIFO is not empty on phase transition.\n", shortname()); } if (sat) { switch (xfr_phase) { case S_PHASE_MSG_OUT: next_state = INIT_XFR; break; case S_PHASE_COMMAND: next_state = INIT_XFR; m_regs[COMMAND_PHASE] = COMMAND_PHASE_CP_BYTES_0; LOGMASKED(LOG_COMMANDS, "%s: Sending Command:", shortname()); for (uint8_t i = 0; i < m_command_length; ++i) { const uint8_t command_byte = m_regs[CDB_1 + i]; LOGMASKED(LOG_COMMANDS, " %02x", command_byte); data_fifo_push(command_byte); } LOGMASKED(LOG_COMMANDS, " (%d)\n", m_transfer_count); break; case S_PHASE_DATA_OUT: case S_PHASE_DATA_IN: next_state = INIT_XFR; break; case S_PHASE_STATUS: next_state = INIT_XFR; m_regs[COMMAND_PHASE] = COMMAND_PHASE_RECEIVE_STATUS; break; case S_PHASE_MSG_IN: next_state = INIT_XFR; break; default: fatalerror("%s: Unhandled phase in Select-w/Atn-and-Transfer.\n", shortname()); next_state = FINISHED; break; } } else if (cc == COMMAND_CC_TRANSFER_INFO) { next_state = FINISHED; irq_fifo_push(SCSI_STATUS_TRANSFER_SUCCESS | xfr_phase); } else { fatalerror("%s: Unhandled command in data phase.\n", shortname()); next_state = FINISHED; } break; default: fatalerror("%s: Unhandled phase transition in INIT_XFR_WAIT_REQ.\n", shortname()); next_state = FINISHED; break; } if (next_state != m_scsi_state) { set_scsi_state(next_state); ++m_step_count; m_xfr_phase = xfr_phase; } } break; case INIT_XFR_RECV_BYTE_ACK: if (sat && m_xfr_phase == S_PHASE_MSG_IN) { const uint8_t msg = data_fifo_pop(); if (m_regs[COMMAND_PHASE] <= COMMAND_PHASE_CP_BYTES_C) { switch (msg) { case SM_SAVE_DATA_PTR: set_scsi_state(FINISHED); irq_fifo_push(SCSI_STATUS_SAVE_DATA_POINTERS); m_regs[COMMAND_PHASE] = COMMAND_PHASE_SAVE_DATA_POINTER; break; case SM_DISCONNECT: m_regs[COMMAND_PHASE] = COMMAND_PHASE_DISCONNECT_MESSAGE; break; default: fatalerror("%s: Unhandled MSG_IN.\n", shortname()); break; } } else if (m_regs[COMMAND_PHASE] < COMMAND_PHASE_COMMAND_COMPLETE) { switch (msg) { case SM_COMMAND_COMPLETE: set_scsi_state(FINISHED); irq_fifo_push(SCSI_STATUS_SELECT_TRANSFER_SUCCESS); m_regs[COMMAND_PHASE] = COMMAND_PHASE_COMMAND_COMPLETE; break; default: fatalerror("%s: Unhandled MSG_IN.\n", shortname()); break; } } } else { set_scsi_state(INIT_XFR_WAIT_REQ); } scsi_bus->ctrl_w(scsi_refid, 0, S_ACK); ++m_step_count; break; default: fatalerror("%s: Unhandled state in step.\n", shortname()); break; } timeout = false; } while (--m_step_count); if (cycles) { delay(cycles); } }
void wd33c9x_base_device::start_command() { const uint8_t cc = m_regs[COMMAND] & COMMAND_CC; // Command In Progress // The CIP flag being set only means that the WD33C9x is // *interpreting* the contents of the Command Register. // It shouldn't actually be set. //m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_CIP; if (cc > COMMAND_CC_DISCONNECT && cc != COMMAND_CC_SET_IDI) { m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_BSY; } switch (cc) { case COMMAND_CC_RESET: LOGMASKED(LOG_COMMANDS, "%s: Reset Command\n", shortname()); scsi_bus->ctrl_w(scsi_refid, 0, S_ALL); scsi_bus->ctrl_wait(scsi_refid, S_SEL|S_BSY|S_RST, S_ALL); m_regs[OWN_ID] = m_command_length; memset(&m_regs[CONTROL], 0, SOURCE_ID - CONTROL); m_regs[COMMAND] = 0; m_regs[AUXILIARY_STATUS] &= ~AUXILIARY_STATUS_DBR; m_mode = MODE_D; data_fifo_reset(); irq_fifo_reset(); update_irq(); set_scsi_state(FINISHED); irq_fifo_push((m_regs[OWN_ID] & OWN_ID_EAF) ? SCSI_STATUS_RESET_EAF : SCSI_STATUS_RESET); scsi_id = (m_regs[OWN_ID] & OWN_ID_SCSI_ID); break; case COMMAND_CC_ABORT: LOGMASKED(LOG_COMMANDS, "%s: Abort Command\n", shortname()); set_scsi_state(FINISHED); // FIXME irq_fifo_push((m_regs[OWN_ID] & OWN_ID_EAF) ? SCSI_STATUS_RESET_EAF : SCSI_STATUS_RESET); break; case COMMAND_CC_ASSERT_ATN: LOGMASKED(LOG_COMMANDS, "%s: Assert ATN Command\n", shortname()); if (m_mode != MODE_I) { fatalerror("%s: ASSERT_ATN command only valid in the Initiator state.", shortname()); } scsi_bus->ctrl_w(scsi_refid, S_ATN, S_ATN); return; case COMMAND_CC_NEGATE_ACK: LOGMASKED(LOG_COMMANDS, "%s: Negate ACK Command\n", shortname()); // FIXME - This is causing problems, so ignore for now. //if (m_mode != MODE_I) { // fatalerror("NEGATE_ACK command only valid in the Initiator state."); //} scsi_bus->ctrl_w(scsi_refid, 0, S_ACK); return; case COMMAND_CC_DISCONNECT: LOGMASKED(LOG_COMMANDS, "%s: Disconnect Command\n", shortname()); scsi_bus->ctrl_w(scsi_refid, 0, S_ALL); scsi_bus->ctrl_wait(scsi_refid, S_SEL|S_BSY|S_RST, S_ALL); m_mode = MODE_D; set_scsi_state(IDLE); m_regs[AUXILIARY_STATUS] &= ~(AUXILIARY_STATUS_CIP | AUXILIARY_STATUS_BSY); break; case COMMAND_CC_SELECT: case COMMAND_CC_SELECT_ATN: LOGMASKED(LOG_COMMANDS, "%s: %s Command\n", shortname(), select_strings[cc - COMMAND_CC_SELECT_ATN]); if (m_mode != MODE_D) { fatalerror("Select commands only valid in the Disconnected state."); } set_scsi_state((ARB_WAIT_BUS_FREE << SUB_SHIFT) | DISC_SEL_ARBITRATION); break; case COMMAND_CC_SELECT_TRANSFER: case COMMAND_CC_SELECT_ATN_TRANSFER: LOGMASKED(LOG_COMMANDS, "%s: %s Command\n", shortname(), select_strings[cc - COMMAND_CC_SELECT_ATN]); if (m_mode == MODE_D) { set_scsi_state((ARB_WAIT_BUS_FREE << SUB_SHIFT) | DISC_SEL_ARBITRATION); m_regs[COMMAND_PHASE] = COMMAND_PHASE_ZERO; } else if (m_mode == MODE_I) { set_scsi_state(INIT_XFR); } else { fatalerror("%s: Select-and-Transfer commands only valid in the Disconnected and Initiator states.", shortname()); } set_command_length(cc); load_transfer_count(); break; case COMMAND_CC_TRANSFER_INFO: LOGMASKED(LOG_COMMANDS, "%s: Transfer Info Command\n", shortname()); if (m_mode != MODE_I) { fatalerror("%s: TRANSFER_INFO command only valid in the Initiator state.", shortname()); } m_regs[AUXILIARY_STATUS] &= ~AUXILIARY_STATUS_DBR; set_scsi_state(INIT_XFR); set_command_length(COMMAND_CC_TRANSFER_INFO); load_transfer_count(); m_xfr_phase = (scsi_bus->ctrl_r() & S_PHASE_MASK); step(false); return; default: fatalerror("%s: Unimplemented command: 0x%02x", shortname(), cc); break; } delay(1); }
void wd33c9x_base_device::set_scsi_state(uint16_t state) { LOGMASKED(LOG_STEP, "%s: SCSI state change: %x to %x\n", shortname(), m_scsi_state, state); m_scsi_state = state; }