diff options
Diffstat (limited to 'src/devices')
-rw-r--r-- | src/devices/bus/centronics/epson_lx810l.cpp | 2 | ||||
-rw-r--r-- | src/devices/bus/m5/slot.cpp | 5 | ||||
-rw-r--r-- | src/devices/bus/m5/slot.h | 2 | ||||
-rw-r--r-- | src/devices/cpu/hphybrid/hphybrid.cpp | 2 | ||||
-rw-r--r-- | src/devices/cpu/m6800/6800ops.inc | 2 | ||||
-rw-r--r-- | src/devices/cpu/z80/z80.cpp | 2 | ||||
-rw-r--r-- | src/devices/machine/hp_taco.cpp | 1982 | ||||
-rw-r--r-- | src/devices/machine/hp_taco.h | 234 | ||||
-rw-r--r-- | src/devices/video/ef9364.cpp | 394 | ||||
-rw-r--r-- | src/devices/video/ef9364.h | 88 | ||||
-rw-r--r-- | src/devices/video/jangou_blitter.cpp | 30 | ||||
-rw-r--r-- | src/devices/video/jangou_blitter.h | 4 | ||||
-rw-r--r-- | src/devices/video/upd7220.cpp | 2 | ||||
-rw-r--r-- | src/devices/video/voodoo.cpp | 10 | ||||
-rw-r--r-- | src/devices/video/voodoo.h | 8 |
15 files changed, 1380 insertions, 1387 deletions
diff --git a/src/devices/bus/centronics/epson_lx810l.cpp b/src/devices/bus/centronics/epson_lx810l.cpp index 77a130b26bf..7185a43ea7e 100644 --- a/src/devices/bus/centronics/epson_lx810l.cpp +++ b/src/devices/bus/centronics/epson_lx810l.cpp @@ -132,7 +132,7 @@ static MACHINE_CONFIG_FRAGMENT( epson_lx810l ) MCFG_UPD7810_CO0(WRITELINE(epson_lx810l_t, co0_w)) MCFG_UPD7810_CO1(WRITELINE(epson_lx810l_t, co1_w)) -// MCFG_DEFAULT_LAYOUT(layout_lx800) +// MCFG_DEFAULT_LAYOUT(layout_lx800) /* video hardware (simulates paper) */ MCFG_SCREEN_ADD("screen", RASTER) diff --git a/src/devices/bus/m5/slot.cpp b/src/devices/bus/m5/slot.cpp index 162d802136e..92bda7e5fbd 100644 --- a/src/devices/bus/m5/slot.cpp +++ b/src/devices/bus/m5/slot.cpp @@ -175,7 +175,6 @@ bool m5_cart_slot_device::call_load() if (m_type == M5_STD || m_type>2) //carts with roms { - UINT32 size = (software_entry() == NULL) ? length() : get_software_region_length("rom"); if (size > 0x5000 && m_type == M5_STD) @@ -190,12 +189,12 @@ bool m5_cart_slot_device::call_load() fread(m_cart->get_rom_base(), size); else memcpy(m_cart->get_rom_base(), get_software_region("rom"), size); - + } if (!M5_STD) if (get_software_region("ram")) m_cart->ram_alloc(get_software_region_length("ram")); - + //printf("Type: %s\n", m5_get_slot(m_type)); } diff --git a/src/devices/bus/m5/slot.h b/src/devices/bus/m5/slot.h index 177977043cf..5f584ea2b82 100644 --- a/src/devices/bus/m5/slot.h +++ b/src/devices/bus/m5/slot.h @@ -18,7 +18,7 @@ enum }; -#define M5_STD 0 +#define M5_STD 0 // ======================> device_m5_cart_interface diff --git a/src/devices/cpu/hphybrid/hphybrid.cpp b/src/devices/cpu/hphybrid/hphybrid.cpp index 71aec796760..14858af369b 100644 --- a/src/devices/cpu/hphybrid/hphybrid.cpp +++ b/src/devices/cpu/hphybrid/hphybrid.cpp @@ -673,7 +673,7 @@ UINT16 hp_hybrid_cpu_device::RM(UINT32 addr) return RIO(CURRENT_PA , addr_wo_bsc - HP_REG_R4_ADDR); case HP_REG_IV_ADDR: - return m_reg_IV; + return m_reg_IV; case HP_REG_PA_ADDR: return CURRENT_PA; diff --git a/src/devices/cpu/m6800/6800ops.inc b/src/devices/cpu/m6800/6800ops.inc index 078529d16ab..d6c3d7634a5 100644 --- a/src/devices/cpu/m6800/6800ops.inc +++ b/src/devices/cpu/m6800/6800ops.inc @@ -2305,4 +2305,4 @@ OP_HANDLER( stx_nsc ) CLR_NZV; SET_NZ8(val); WM(EAD,val); -}
\ No newline at end of file +} diff --git a/src/devices/cpu/z80/z80.cpp b/src/devices/cpu/z80/z80.cpp index e798a1153b2..bafc40e1ea3 100644 --- a/src/devices/cpu/z80/z80.cpp +++ b/src/devices/cpu/z80/z80.cpp @@ -3591,7 +3591,7 @@ void z80_device::execute_set_input(int inputnum, int state) case Z80_INPUT_LINE_WAIT: m_wait_state = state; break; - + default: break; } diff --git a/src/devices/machine/hp_taco.cpp b/src/devices/machine/hp_taco.cpp index 76203d31ee3..eb94faf3b05 100644 --- a/src/devices/machine/hp_taco.cpp +++ b/src/devices/machine/hp_taco.cpp @@ -148,8 +148,8 @@ // Timers enum { - TAPE_TMR_ID, - HOLE_TMR_ID + TAPE_TMR_ID, + HOLE_TMR_ID }; // Constants @@ -178,52 +178,52 @@ enum { // Parts of command register #define CMD_CODE(reg) \ - (((reg) >> 10) & 0x1f) + (((reg) >> 10) & 0x1f) #define DIR_FWD(reg) \ - (BIT(reg , 15)) + (BIT(reg , 15)) #define SPEED_FAST(reg) \ - (BIT(reg , 7)) + (BIT(reg , 7)) #define CMD_OPT(reg) \ - (BIT(reg , 6)) + (BIT(reg , 6)) #define UNKNOWN_B9(reg) \ - (BIT(reg , 9)) + (BIT(reg , 9)) #define DIR_FWD_MASK BIT_MASK(15) // Direction = forward #define SPEED_FAST_MASK BIT_MASK(7) // Speed = fast // Commands enum { - CMD_INDTA_INGAP, // 00: scan for data first then for gap - CMD_UNK_01, // 01: unknown - CMD_FINAL_GAP, // 02: write final gap - CMD_INIT_WRITE, // 03: write words for tape formatting - CMD_STOP, // 04: stop - CMD_UNK_05, // 05: unknown - CMD_SET_TRACK, // 06: set A/B track - CMD_UNK_07, // 07: unknown - CMD_UNK_08, // 08: unknown - CMD_UNK_09, // 09: unknown - CMD_MOVE, // 0a: move tape - CMD_UNK_0b, // 0b: unknown - CMD_INGAP_MOVE, // 0c: scan for gap then move a bit further (used to gain some margin when inverting tape movement) - CMD_UNK_0d, // 0d: unknown - CMD_CLEAR, // 0e: clear errors/unlatch status bits - CMD_UNK_0f, // 0f: unknown - CMD_NOT_INDTA, // 10: scan for end of data - CMD_UNK_11, // 11: unknown - CMD_UNK_12, // 12: unknown - CMD_UNK_13, // 13: unknown - CMD_UNK_14, // 14: unknown - CMD_UNK_15, // 15: unknown - CMD_WRITE_IRG, // 16: write inter-record gap - CMD_UNK_17, // 17: unknown - CMD_SCAN_RECORDS, // 18: scan records (count IRGs) - CMD_RECORD_WRITE, // 19: write record words - CMD_MOVE_INDTA, // 1a: move then scan for data - CMD_UNK_1b, // 1b: unknown (for now it seems harmless to handle it as NOP) - CMD_DELTA_MOVE_HOLE, // 1c: move tape a given distance, intr at end or first hole found (whichever comes first) - CMD_START_READ, // 1d: start record reading - CMD_DELTA_MOVE_IRG, // 1e: move tape a given distance, detect gaps in parallel - CMD_END_READ // 1f: stop reading + CMD_INDTA_INGAP, // 00: scan for data first then for gap + CMD_UNK_01, // 01: unknown + CMD_FINAL_GAP, // 02: write final gap + CMD_INIT_WRITE, // 03: write words for tape formatting + CMD_STOP, // 04: stop + CMD_UNK_05, // 05: unknown + CMD_SET_TRACK, // 06: set A/B track + CMD_UNK_07, // 07: unknown + CMD_UNK_08, // 08: unknown + CMD_UNK_09, // 09: unknown + CMD_MOVE, // 0a: move tape + CMD_UNK_0b, // 0b: unknown + CMD_INGAP_MOVE, // 0c: scan for gap then move a bit further (used to gain some margin when inverting tape movement) + CMD_UNK_0d, // 0d: unknown + CMD_CLEAR, // 0e: clear errors/unlatch status bits + CMD_UNK_0f, // 0f: unknown + CMD_NOT_INDTA, // 10: scan for end of data + CMD_UNK_11, // 11: unknown + CMD_UNK_12, // 12: unknown + CMD_UNK_13, // 13: unknown + CMD_UNK_14, // 14: unknown + CMD_UNK_15, // 15: unknown + CMD_WRITE_IRG, // 16: write inter-record gap + CMD_UNK_17, // 17: unknown + CMD_SCAN_RECORDS, // 18: scan records (count IRGs) + CMD_RECORD_WRITE, // 19: write record words + CMD_MOVE_INDTA, // 1a: move then scan for data + CMD_UNK_1b, // 1b: unknown (for now it seems harmless to handle it as NOP) + CMD_DELTA_MOVE_HOLE, // 1c: move tape a given distance, intr at end or first hole found (whichever comes first) + CMD_START_READ, // 1d: start record reading + CMD_DELTA_MOVE_IRG, // 1e: move tape a given distance, detect gaps in parallel + CMD_END_READ // 1f: stop reading }; // Bits of status register @@ -250,17 +250,17 @@ enum { // O O O O // static const hp_taco_device::tape_pos_t tape_holes[] = { - (hp_taco_device::tape_pos_t)(23.891 * ONE_INCH_POS), // 24 - 0.218 / 2 - (hp_taco_device::tape_pos_t)(24.109 * ONE_INCH_POS), // 24 + 0.218 / 2 - (hp_taco_device::tape_pos_t)(35.891 * ONE_INCH_POS), // 36 - 0.218 / 2 - (hp_taco_device::tape_pos_t)(36.109 * ONE_INCH_POS), // 36 + 0.218 / 2 - (hp_taco_device::tape_pos_t)(47.891 * ONE_INCH_POS), // 48 - 0.218 / 2 - (hp_taco_device::tape_pos_t)(48.109 * ONE_INCH_POS), // 48 + 0.218 / 2 - 72 * ONE_INCH_POS, // 72 - 1752 * ONE_INCH_POS, // 1752 - 1776 * ONE_INCH_POS, // 1776 - 1788 * ONE_INCH_POS, // 1788 - 1800 * ONE_INCH_POS // 1800 + (hp_taco_device::tape_pos_t)(23.891 * ONE_INCH_POS), // 24 - 0.218 / 2 + (hp_taco_device::tape_pos_t)(24.109 * ONE_INCH_POS), // 24 + 0.218 / 2 + (hp_taco_device::tape_pos_t)(35.891 * ONE_INCH_POS), // 36 - 0.218 / 2 + (hp_taco_device::tape_pos_t)(36.109 * ONE_INCH_POS), // 36 + 0.218 / 2 + (hp_taco_device::tape_pos_t)(47.891 * ONE_INCH_POS), // 48 - 0.218 / 2 + (hp_taco_device::tape_pos_t)(48.109 * ONE_INCH_POS), // 48 + 0.218 / 2 + 72 * ONE_INCH_POS, // 72 + 1752 * ONE_INCH_POS, // 1752 + 1776 * ONE_INCH_POS, // 1776 + 1788 * ONE_INCH_POS, // 1788 + 1800 * ONE_INCH_POS // 1800 }; // Device type definition @@ -268,144 +268,144 @@ const device_type HP_TACO = &device_creator<hp_taco_device>; // Constructors hp_taco_device::hp_taco_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname) - : device_t(mconfig, type, name, tag, owner, clock, shortname, __FILE__), - device_image_interface(mconfig , *this), - m_irq_handler(*this), - m_flg_handler(*this), - m_sts_handler(*this), - m_tape_pos(TAPE_INIT_POS), - m_image_dirty(false) + : device_t(mconfig, type, name, tag, owner, clock, shortname, __FILE__), + device_image_interface(mconfig , *this), + m_irq_handler(*this), + m_flg_handler(*this), + m_sts_handler(*this), + m_tape_pos(TAPE_INIT_POS), + m_image_dirty(false) { - clear_state(); + clear_state(); } hp_taco_device::hp_taco_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, HP_TACO, "HP TACO", tag, owner, clock, "TACO", __FILE__), - device_image_interface(mconfig , *this), - m_irq_handler(*this), - m_flg_handler(*this), - m_sts_handler(*this), - m_tape_pos(TAPE_INIT_POS), - m_image_dirty(false) + : device_t(mconfig, HP_TACO, "HP TACO", tag, owner, clock, "TACO", __FILE__), + device_image_interface(mconfig , *this), + m_irq_handler(*this), + m_flg_handler(*this), + m_sts_handler(*this), + m_tape_pos(TAPE_INIT_POS), + m_image_dirty(false) { - clear_state(); + clear_state(); } WRITE16_MEMBER(hp_taco_device::reg_w) { - LOG_0(("wr R%u = %04x\n", 4 + offset , data)); - - // Any I/O activity clears IRQ - irq_w(false); - - switch (offset) { - case 0: - // Data register - m_data_reg = data; - m_data_reg_full = true; - break; - - case 1: - // Command register - start_cmd_exec(data & CMD_REG_MASK); - break; - - case 2: - // Tachometer register - m_tach_reg = data; - break; - - case 3: - // Timing register - m_timing_reg = data; - break; - } + LOG_0(("wr R%u = %04x\n", 4 + offset , data)); + + // Any I/O activity clears IRQ + irq_w(false); + + switch (offset) { + case 0: + // Data register + m_data_reg = data; + m_data_reg_full = true; + break; + + case 1: + // Command register + start_cmd_exec(data & CMD_REG_MASK); + break; + + case 2: + // Tachometer register + m_tach_reg = data; + break; + + case 3: + // Timing register + m_timing_reg = data; + break; + } } READ16_MEMBER(hp_taco_device::reg_r) { - UINT16 res = 0; + UINT16 res = 0; - // Any I/O activity clears IRQ - irq_w(false); + // Any I/O activity clears IRQ + irq_w(false); - switch (offset) { - case 0: - // Data register - res = m_data_reg; - break; + switch (offset) { + case 0: + // Data register + res = m_data_reg; + break; - case 1: - // Command & status register - res = (m_cmd_reg & CMD_REG_MASK) | (m_status_reg & STATUS_REG_MASK); - break; + case 1: + // Command & status register + res = (m_cmd_reg & CMD_REG_MASK) | (m_status_reg & STATUS_REG_MASK); + break; - case 2: - // Tachometer register - res = m_tach_reg; - break; + case 2: + // Tachometer register + res = m_tach_reg; + break; - case 3: - // Checksum register: it clears when read - res = m_checksum_reg; - m_checksum_reg = 0; - break; - } + case 3: + // Checksum register: it clears when read + res = m_checksum_reg; + m_checksum_reg = 0; + break; + } - LOG_0(("rd R%u = %04x\n", 4 + offset , res)); + LOG_0(("rd R%u = %04x\n", 4 + offset , res)); - return res; + return res; } READ_LINE_MEMBER(hp_taco_device::flg_r) { - return m_flg; + return m_flg; } READ_LINE_MEMBER(hp_taco_device::sts_r) { - return m_sts; + return m_sts; } // device_config_complete void hp_taco_device::device_config_complete() { - LOG(("device_config_complete")); + LOG(("device_config_complete")); update_names(); } // device_start void hp_taco_device::device_start() { - LOG(("device_start")); - m_irq_handler.resolve_safe(); - m_flg_handler.resolve_safe(); - m_sts_handler.resolve_safe(); - - save_item(NAME(m_data_reg)); - save_item(NAME(m_data_reg_full)); - save_item(NAME(m_cmd_reg)); - save_item(NAME(m_cmd_state)); - save_item(NAME(m_status_reg)); - save_item(NAME(m_tach_reg)); - save_item(NAME(m_checksum_reg)); - save_item(NAME(m_timing_reg)); - save_item(NAME(m_irq)); - save_item(NAME(m_flg)); - save_item(NAME(m_sts)); - save_item(NAME(m_tape_pos)); - save_item(NAME(m_start_time)); - save_item(NAME(m_tape_fwd)); - save_item(NAME(m_tape_fast)); - save_item(NAME(m_image_dirty)); - save_item(NAME(m_tape_wr)); - 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(("device_start")); + m_irq_handler.resolve_safe(); + m_flg_handler.resolve_safe(); + m_sts_handler.resolve_safe(); + + save_item(NAME(m_data_reg)); + save_item(NAME(m_data_reg_full)); + save_item(NAME(m_cmd_reg)); + save_item(NAME(m_cmd_state)); + save_item(NAME(m_status_reg)); + save_item(NAME(m_tach_reg)); + save_item(NAME(m_checksum_reg)); + save_item(NAME(m_timing_reg)); + save_item(NAME(m_irq)); + save_item(NAME(m_flg)); + save_item(NAME(m_sts)); + save_item(NAME(m_tape_pos)); + save_item(NAME(m_start_time)); + save_item(NAME(m_tape_fwd)); + save_item(NAME(m_tape_fast)); + save_item(NAME(m_image_dirty)); + save_item(NAME(m_tape_wr)); + 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); } // device_stop @@ -416,593 +416,593 @@ void hp_taco_device::device_stop() // device_reset void hp_taco_device::device_reset() { - LOG(("device_reset")); - clear_state(); + LOG(("device_reset")); + clear_state(); - m_irq = false; - m_flg = true; + m_irq = false; + m_flg = true; - m_irq_handler(false); - m_flg_handler(true); - set_error(false); + m_irq_handler(false); + m_flg_handler(true); + set_error(false); } void hp_taco_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { - if (CMD_CODE(m_cmd_reg) != CMD_STOP) { - update_tape_pos(); - } - - switch (id) { - case TAPE_TMR_ID: - LOG_0(("Tape tmr @%g\n" , machine().time().as_double())); - - tape_pos_t length; - - switch (CMD_CODE(m_cmd_reg)) { - case CMD_INDTA_INGAP: - if (m_cmd_state == 0) { - m_cmd_state = 1; - tape_pos_t target = m_tape_pos; - if (next_n_gap(target, 1, MIN_IRG_LENGTH)) { - m_tape_timer->adjust(time_to_target(target)); - } - return; - } - break; - - case CMD_RECORD_WRITE: - if (m_cmd_state == 0) { - if (m_rd_it->second == PREAMBLE_WORD) { - LOG_0(("Got preamble\n")); - m_cmd_state = 1; - // m_rw_pos already at correct position - m_tape_timer->adjust(fetch_next_wr_word()); - break; - } else { - adv_res_t res = adv_it(m_rd_it); - if (res != ADV_NO_MORE_DATA) { - m_tape_timer->adjust(time_to_rd_next_word(m_rw_pos)); - } - // No IRQ - return; - } - } - // Intentional fall-through - case CMD_INIT_WRITE: - write_word(m_rw_pos , m_next_word , length); - pos_offset(m_rw_pos , length); - // Just to be sure.. - m_tape_pos = m_rw_pos; - m_tape_timer->adjust(fetch_next_wr_word()); - break; - - case CMD_STOP: - move_tape_pos(m_tape_fast ? FAST_BRAKE_DIST : SLOW_BRAKE_DIST); - stop_tape(); - break; - - case CMD_INGAP_MOVE: - if (m_cmd_state == 0) { - m_cmd_state = 1; - m_tape_timer->adjust(time_to_tach_pulses()); - return; - } - break; - - case CMD_FINAL_GAP: - case CMD_WRITE_IRG: - write_gap(m_rw_pos , m_tape_pos); - m_hole_timer->reset(); - break; - - case CMD_SCAN_RECORDS: - if (m_cmd_state == 0) { - m_cmd_state = 1; - tape_pos_t target = m_tape_pos; - if (next_n_gap(target, 0x10000U - m_tach_reg, MIN_IRG_LENGTH)) { - LOG_0(("%u gaps @%d\n" , 0x10000U - m_tach_reg, target)); - m_tape_timer->adjust(time_to_target(target)); - } - return; - } else { - m_hole_timer->reset(); - } - break; - - case CMD_MOVE_INDTA: - if (m_cmd_state == 0) { - if (next_data(m_rd_it , m_tape_pos , true)) { - m_cmd_state = 1; - m_tape_timer->adjust(time_to_target(farthest_end(m_rd_it))); - } - // No IRQ - return; - } - // m_cmd_state == 1 -> IRQ & cmd end - break; - - case CMD_DELTA_MOVE_HOLE: - case CMD_DELTA_MOVE_IRG: - // Interrupt at end of movement - m_hole_timer->reset(); - break; - - case CMD_START_READ: - { - bool set_intr = true; - // Just to be sure.. - m_tape_pos = m_rw_pos; - if (m_cmd_state == 0) { - set_intr = false; - if (m_rd_it->second == PREAMBLE_WORD) { - m_cmd_state = 1; - } - LOG_0(("Got preamble\n")); - } else { - m_data_reg = m_rd_it->second; - m_checksum_reg += m_data_reg; - LOG_0(("RD %04x\n" , m_data_reg)); - } - adv_res_t res = adv_it(m_rd_it); - LOG_0(("adv_it %d\n" , res)); - if (res == ADV_NO_MORE_DATA) { - m_rd_it_valid = false; - } else { - if (res == ADV_DISCONT_DATA) { - // Hit a gap, restart preamble search - m_cmd_state = 0; - } - m_tape_timer->adjust(time_to_rd_next_word(m_rw_pos)); - } - if (!set_intr) { - return; - } - } - break; - - case CMD_END_READ: - { - m_tape_pos = m_rw_pos; - // Note: checksum is not updated - m_data_reg = m_rd_it->second; - LOG_0(("Final RD %04x\n" , m_data_reg)); - adv_res_t res = adv_it(m_rd_it); - if (res == ADV_NO_MORE_DATA) { - m_rd_it_valid = false; - } - m_hole_timer->reset(); - } - break; - - default: - // Other commands: just raise irq - break; - } - irq_w(true); - break; - - case HOLE_TMR_ID: - LOG_0(("Hole tmr @%g\n" , machine().time().as_double())); - - BIT_SET(m_status_reg , STATUS_HOLE_BIT); - - switch (CMD_CODE(m_cmd_reg)) { - case CMD_FINAL_GAP: - case CMD_WRITE_IRG: - write_gap(m_rw_pos , m_tape_pos); - m_rw_pos = m_tape_pos; - break; - - case CMD_SCAN_RECORDS: - case CMD_DELTA_MOVE_HOLE: - // Cmds 18 & 1c are terminated at first hole - m_tape_timer->reset(); - irq_w(true); - // No reloading of hole timer - return; - - case CMD_DELTA_MOVE_IRG: - // TODO: update r6 - m_hole_timer->adjust(time_to_next_hole()); - // No IRQ at holes - return; - - case CMD_START_READ: - case CMD_END_READ: - set_error(true); - break; - - default: - // Other cmds: default processing (update tape pos, set IRQ, schedule timer for next hole) - break; - } - - irq_w(true); - m_hole_timer->adjust(time_to_next_hole()); - break; - - default: - break; - } + if (CMD_CODE(m_cmd_reg) != CMD_STOP) { + update_tape_pos(); + } + + switch (id) { + case TAPE_TMR_ID: + LOG_0(("Tape tmr @%g\n" , machine().time().as_double())); + + tape_pos_t length; + + switch (CMD_CODE(m_cmd_reg)) { + case CMD_INDTA_INGAP: + if (m_cmd_state == 0) { + m_cmd_state = 1; + tape_pos_t target = m_tape_pos; + if (next_n_gap(target, 1, MIN_IRG_LENGTH)) { + m_tape_timer->adjust(time_to_target(target)); + } + return; + } + break; + + case CMD_RECORD_WRITE: + if (m_cmd_state == 0) { + if (m_rd_it->second == PREAMBLE_WORD) { + LOG_0(("Got preamble\n")); + m_cmd_state = 1; + // m_rw_pos already at correct position + m_tape_timer->adjust(fetch_next_wr_word()); + break; + } else { + adv_res_t res = adv_it(m_rd_it); + if (res != ADV_NO_MORE_DATA) { + m_tape_timer->adjust(time_to_rd_next_word(m_rw_pos)); + } + // No IRQ + return; + } + } + // Intentional fall-through + case CMD_INIT_WRITE: + write_word(m_rw_pos , m_next_word , length); + pos_offset(m_rw_pos , length); + // Just to be sure.. + m_tape_pos = m_rw_pos; + m_tape_timer->adjust(fetch_next_wr_word()); + break; + + case CMD_STOP: + move_tape_pos(m_tape_fast ? FAST_BRAKE_DIST : SLOW_BRAKE_DIST); + stop_tape(); + break; + + case CMD_INGAP_MOVE: + if (m_cmd_state == 0) { + m_cmd_state = 1; + m_tape_timer->adjust(time_to_tach_pulses()); + return; + } + break; + + case CMD_FINAL_GAP: + case CMD_WRITE_IRG: + write_gap(m_rw_pos , m_tape_pos); + m_hole_timer->reset(); + break; + + case CMD_SCAN_RECORDS: + if (m_cmd_state == 0) { + m_cmd_state = 1; + tape_pos_t target = m_tape_pos; + if (next_n_gap(target, 0x10000U - m_tach_reg, MIN_IRG_LENGTH)) { + LOG_0(("%u gaps @%d\n" , 0x10000U - m_tach_reg, target)); + m_tape_timer->adjust(time_to_target(target)); + } + return; + } else { + m_hole_timer->reset(); + } + break; + + case CMD_MOVE_INDTA: + if (m_cmd_state == 0) { + if (next_data(m_rd_it , m_tape_pos , true)) { + m_cmd_state = 1; + m_tape_timer->adjust(time_to_target(farthest_end(m_rd_it))); + } + // No IRQ + return; + } + // m_cmd_state == 1 -> IRQ & cmd end + break; + + case CMD_DELTA_MOVE_HOLE: + case CMD_DELTA_MOVE_IRG: + // Interrupt at end of movement + m_hole_timer->reset(); + break; + + case CMD_START_READ: + { + bool set_intr = true; + // Just to be sure.. + m_tape_pos = m_rw_pos; + if (m_cmd_state == 0) { + set_intr = false; + if (m_rd_it->second == PREAMBLE_WORD) { + m_cmd_state = 1; + } + LOG_0(("Got preamble\n")); + } else { + m_data_reg = m_rd_it->second; + m_checksum_reg += m_data_reg; + LOG_0(("RD %04x\n" , m_data_reg)); + } + adv_res_t res = adv_it(m_rd_it); + LOG_0(("adv_it %d\n" , res)); + if (res == ADV_NO_MORE_DATA) { + m_rd_it_valid = false; + } else { + if (res == ADV_DISCONT_DATA) { + // Hit a gap, restart preamble search + m_cmd_state = 0; + } + m_tape_timer->adjust(time_to_rd_next_word(m_rw_pos)); + } + if (!set_intr) { + return; + } + } + break; + + case CMD_END_READ: + { + m_tape_pos = m_rw_pos; + // Note: checksum is not updated + m_data_reg = m_rd_it->second; + LOG_0(("Final RD %04x\n" , m_data_reg)); + adv_res_t res = adv_it(m_rd_it); + if (res == ADV_NO_MORE_DATA) { + m_rd_it_valid = false; + } + m_hole_timer->reset(); + } + break; + + default: + // Other commands: just raise irq + break; + } + irq_w(true); + break; + + case HOLE_TMR_ID: + LOG_0(("Hole tmr @%g\n" , machine().time().as_double())); + + BIT_SET(m_status_reg , STATUS_HOLE_BIT); + + switch (CMD_CODE(m_cmd_reg)) { + case CMD_FINAL_GAP: + case CMD_WRITE_IRG: + write_gap(m_rw_pos , m_tape_pos); + m_rw_pos = m_tape_pos; + break; + + case CMD_SCAN_RECORDS: + case CMD_DELTA_MOVE_HOLE: + // Cmds 18 & 1c are terminated at first hole + m_tape_timer->reset(); + irq_w(true); + // No reloading of hole timer + return; + + case CMD_DELTA_MOVE_IRG: + // TODO: update r6 + m_hole_timer->adjust(time_to_next_hole()); + // No IRQ at holes + return; + + case CMD_START_READ: + case CMD_END_READ: + set_error(true); + break; + + default: + // Other cmds: default processing (update tape pos, set IRQ, schedule timer for next hole) + break; + } + + irq_w(true); + m_hole_timer->adjust(time_to_next_hole()); + break; + + default: + break; + } } void hp_taco_device::clear_state(void) { - m_data_reg = 0; - m_data_reg_full = false; - m_cmd_reg = 0; - m_status_reg = 0; - m_tach_reg = 0; - m_checksum_reg = 0; - m_timing_reg = 0; - m_cmd_state = 0; - // m_tape_pos is not reset, tape stays where it is - m_start_time = attotime::never; - m_tape_fwd = false; - m_tape_fast = false; - // m_image_dirty is not touched - m_tape_wr = false; - m_rw_pos = 0; - m_next_word = 0; - m_rd_it_valid = false; - m_gap_detect_start = NULL_TAPE_POS; - - set_tape_present(false); - set_tape_present(is_loaded()); + m_data_reg = 0; + m_data_reg_full = false; + m_cmd_reg = 0; + m_status_reg = 0; + m_tach_reg = 0; + m_checksum_reg = 0; + m_timing_reg = 0; + m_cmd_state = 0; + // m_tape_pos is not reset, tape stays where it is + m_start_time = attotime::never; + m_tape_fwd = false; + m_tape_fast = false; + // m_image_dirty is not touched + m_tape_wr = false; + m_rw_pos = 0; + m_next_word = 0; + m_rd_it_valid = false; + m_gap_detect_start = NULL_TAPE_POS; + + set_tape_present(false); + set_tape_present(is_loaded()); } void hp_taco_device::irq_w(bool state) { - if (state != m_irq) { - m_irq = state; - m_irq_handler(state); - LOG_0(("IRQ = %d\n" , state)); - } + if (state != m_irq) { + m_irq = state; + m_irq_handler(state); + LOG_0(("IRQ = %d\n" , state)); + } } void hp_taco_device::set_error(bool state) { - m_sts = !state; - m_sts_handler(m_sts); - LOG_0(("error = %d\n" , state)); + m_sts = !state; + m_sts_handler(m_sts); + LOG_0(("error = %d\n" , state)); } unsigned hp_taco_device::speed_to_tick_freq(void) const { - return m_tape_fast ? TACH_FREQ_FAST * TAPE_POS_FRACT : TACH_FREQ_SLOW * TAPE_POS_FRACT; + return m_tape_fast ? TACH_FREQ_FAST * TAPE_POS_FRACT : TACH_FREQ_SLOW * TAPE_POS_FRACT; } bool hp_taco_device::pos_offset(tape_pos_t& pos , tape_pos_t offset) const { - if (offset == 0) { - return true; - } - - if (!m_tape_fwd) { - offset = -offset; - } - - pos += offset; - - // In real life tape would unspool.. - if (pos > TAPE_LENGTH) { - pos = TAPE_LENGTH; - return false; - } else if (pos < 0) { - pos = 0; - return false; - } else { - return true; - } + if (offset == 0) { + return true; + } + + if (!m_tape_fwd) { + offset = -offset; + } + + pos += offset; + + // In real life tape would unspool.. + if (pos > TAPE_LENGTH) { + pos = TAPE_LENGTH; + return false; + } else if (pos < 0) { + pos = 0; + return false; + } else { + return true; + } } void hp_taco_device::move_tape_pos(tape_pos_t delta_pos) { - tape_pos_t tape_start_pos = m_tape_pos; - if (!pos_offset(m_tape_pos , delta_pos)) { - LOG(("Tape unspooled!\n")); - } - m_start_time = machine().time(); - LOG_0(("Tape pos = %u\n" , m_tape_pos)); - if (any_hole(tape_start_pos , m_tape_pos)) { - // Crossed one or more holes - BIT_SET(m_status_reg , STATUS_HOLE_BIT); - } + tape_pos_t tape_start_pos = m_tape_pos; + if (!pos_offset(m_tape_pos , delta_pos)) { + LOG(("Tape unspooled!\n")); + } + m_start_time = machine().time(); + LOG_0(("Tape pos = %u\n" , m_tape_pos)); + if (any_hole(tape_start_pos , m_tape_pos)) { + // Crossed one or more holes + BIT_SET(m_status_reg , STATUS_HOLE_BIT); + } } void hp_taco_device::update_tape_pos(void) { - if (m_start_time.is_never()) { - // Tape not moving - return; - } - - attotime delta_time(machine().time() - m_start_time); - LOG_0(("delta_time = %g\n" , delta_time.as_double())); - // How many tachometer ticks has the tape moved? - tape_pos_t delta_tach = (tape_pos_t)(delta_time.as_ticks(speed_to_tick_freq())); - LOG_0(("delta_tach = %u\n" , delta_tach)); - - move_tape_pos(delta_tach); - - // Gap detection - bool gap_detected = false; - if (m_gap_detect_start != NULL_TAPE_POS && abs(m_gap_detect_start - m_tape_pos) >= MIN_IRG_LENGTH) { - tape_pos_t tmp = m_tape_pos; - pos_offset(tmp , -MIN_IRG_LENGTH); - gap_detected = just_gap(tmp , m_tape_pos); - } - if (gap_detected) { - BIT_SET(m_status_reg, STATUS_GAP_BIT); - } else { - BIT_CLR(m_status_reg, STATUS_GAP_BIT); - } + if (m_start_time.is_never()) { + // Tape not moving + return; + } + + attotime delta_time(machine().time() - m_start_time); + LOG_0(("delta_time = %g\n" , delta_time.as_double())); + // How many tachometer ticks has the tape moved? + tape_pos_t delta_tach = (tape_pos_t)(delta_time.as_ticks(speed_to_tick_freq())); + LOG_0(("delta_tach = %u\n" , delta_tach)); + + move_tape_pos(delta_tach); + + // Gap detection + bool gap_detected = false; + if (m_gap_detect_start != NULL_TAPE_POS && abs(m_gap_detect_start - m_tape_pos) >= MIN_IRG_LENGTH) { + tape_pos_t tmp = m_tape_pos; + pos_offset(tmp , -MIN_IRG_LENGTH); + gap_detected = just_gap(tmp , m_tape_pos); + } + if (gap_detected) { + BIT_SET(m_status_reg, STATUS_GAP_BIT); + } else { + BIT_CLR(m_status_reg, STATUS_GAP_BIT); + } } void hp_taco_device::ensure_a_lt_b(tape_pos_t& a , tape_pos_t& b) { - if (a > b) { - // Ensure A always comes before B - tape_pos_t tmp; - tmp = a; - a = b; - b = tmp; - } + if (a > b) { + // Ensure A always comes before B + tape_pos_t tmp; + tmp = a; + a = b; + b = tmp; + } } // Is there any hole in a given section of tape? bool hp_taco_device::any_hole(tape_pos_t tape_pos_a , tape_pos_t tape_pos_b) { - ensure_a_lt_b(tape_pos_a , tape_pos_b); + ensure_a_lt_b(tape_pos_a , tape_pos_b); - for (tape_pos_t hole : tape_holes) { - if (tape_pos_a < hole && tape_pos_b >= hole) { - return true; - } - } + for (tape_pos_t hole : tape_holes) { + if (tape_pos_a < hole && tape_pos_b >= hole) { + return true; + } + } - return false; + return false; } // Position of next hole tape will reach in a given direction hp_taco_device::tape_pos_t hp_taco_device::next_hole(void) const { - if (m_tape_fwd) { - for (tape_pos_t hole : tape_holes) { - if (hole > m_tape_pos) { - LOG_0(("next hole fwd @%u = %u\n" , m_tape_pos , hole)); - return hole; - } - } - // No more holes: will hit end of tape - return TAPE_LENGTH; - } else { - for (int i = (sizeof(tape_holes) / sizeof(tape_holes[ 0 ])) - 1; i >= 0; i--) { - if (tape_holes[ i ] < m_tape_pos) { - LOG_0(("next hole rev @%u = %u\n" , m_tape_pos , tape_holes[ i ])); - return tape_holes[ i ]; - } - } - // No more holes: will hit start of tape - return 0; - } + if (m_tape_fwd) { + for (tape_pos_t hole : tape_holes) { + if (hole > m_tape_pos) { + LOG_0(("next hole fwd @%u = %u\n" , m_tape_pos , hole)); + return hole; + } + } + // No more holes: will hit end of tape + return TAPE_LENGTH; + } else { + for (int i = (sizeof(tape_holes) / sizeof(tape_holes[ 0 ])) - 1; i >= 0; i--) { + if (tape_holes[ i ] < m_tape_pos) { + LOG_0(("next hole rev @%u = %u\n" , m_tape_pos , tape_holes[ i ])); + return tape_holes[ i ]; + } + } + // No more holes: will hit start of tape + return 0; + } } attotime hp_taco_device::time_to_distance(tape_pos_t distance) const { - // +1 for rounding - return attotime::from_ticks(distance + 1 , speed_to_tick_freq()); + // +1 for rounding + return attotime::from_ticks(distance + 1 , speed_to_tick_freq()); } attotime hp_taco_device::time_to_target(tape_pos_t target) const { - return time_to_distance(abs(target - m_tape_pos)); + return time_to_distance(abs(target - m_tape_pos)); } bool hp_taco_device::start_tape_cmd(UINT16 cmd_reg , UINT16 must_be_1 , UINT16 must_be_0) { - m_cmd_reg = cmd_reg; - - UINT16 to_be_tested = (m_cmd_reg & CMD_REG_MASK) | (m_status_reg & STATUS_REG_MASK); - // Bits in STATUS_ERR_MASK must always be 0 - must_be_0 |= STATUS_ERR_MASK; - - // It's not an error if the error state is already set (sts false) - if (((to_be_tested & (must_be_1 | must_be_0)) ^ must_be_1) != 0) { - set_error(true); - return false; - } else { - bool prev_tape_wr = m_tape_wr; - bool prev_tape_fwd = m_tape_fwd; - bool prev_tape_fast = m_tape_fast; - bool not_moving = m_start_time.is_never(); - - m_start_time = machine().time(); - m_tape_wr = (must_be_0 & STATUS_WPR_MASK) != 0; - m_tape_fwd = DIR_FWD(m_cmd_reg); - m_tape_fast = SPEED_FAST(m_cmd_reg); - // TODO: remove? - BIT_CLR(m_status_reg, STATUS_HOLE_BIT); - - if (m_tape_wr) { - // Write command: disable gap detector - m_gap_detect_start = NULL_TAPE_POS; - BIT_CLR(m_status_reg, STATUS_GAP_BIT); - m_image_dirty = true; - } else if (not_moving || prev_tape_wr != m_tape_wr || prev_tape_fwd != m_tape_fwd || prev_tape_fast != m_tape_fast) { - // Tape started right now, switched from writing to reading, direction changed or speed changed: (re)start gap detector - m_gap_detect_start = m_tape_pos; - BIT_CLR(m_status_reg, STATUS_GAP_BIT); - } - return true; - } + m_cmd_reg = cmd_reg; + + UINT16 to_be_tested = (m_cmd_reg & CMD_REG_MASK) | (m_status_reg & STATUS_REG_MASK); + // Bits in STATUS_ERR_MASK must always be 0 + must_be_0 |= STATUS_ERR_MASK; + + // It's not an error if the error state is already set (sts false) + if (((to_be_tested & (must_be_1 | must_be_0)) ^ must_be_1) != 0) { + set_error(true); + return false; + } else { + bool prev_tape_wr = m_tape_wr; + bool prev_tape_fwd = m_tape_fwd; + bool prev_tape_fast = m_tape_fast; + bool not_moving = m_start_time.is_never(); + + m_start_time = machine().time(); + m_tape_wr = (must_be_0 & STATUS_WPR_MASK) != 0; + m_tape_fwd = DIR_FWD(m_cmd_reg); + m_tape_fast = SPEED_FAST(m_cmd_reg); + // TODO: remove? + BIT_CLR(m_status_reg, STATUS_HOLE_BIT); + + if (m_tape_wr) { + // Write command: disable gap detector + m_gap_detect_start = NULL_TAPE_POS; + BIT_CLR(m_status_reg, STATUS_GAP_BIT); + m_image_dirty = true; + } else if (not_moving || prev_tape_wr != m_tape_wr || prev_tape_fwd != m_tape_fwd || prev_tape_fast != m_tape_fast) { + // Tape started right now, switched from writing to reading, direction changed or speed changed: (re)start gap detector + m_gap_detect_start = m_tape_pos; + BIT_CLR(m_status_reg, STATUS_GAP_BIT); + } + return true; + } } void hp_taco_device::stop_tape(void) { - m_start_time = attotime::never; - m_gap_detect_start = NULL_TAPE_POS; + m_start_time = attotime::never; + m_gap_detect_start = NULL_TAPE_POS; } hp_taco_device::tape_track_t& hp_taco_device::current_track(void) { - return m_tracks[ BIT(m_status_reg , STATUS_TRACKB_BIT) ]; + return m_tracks[ BIT(m_status_reg , STATUS_TRACKB_BIT) ]; } // Return physical length of a 16-bit word on tape hp_taco_device::tape_pos_t hp_taco_device::word_length(tape_word_t w) { - unsigned zeros , ones; + unsigned zeros , ones; - // pop count of w - ones = (w & 0x5555) + ((w >> 1) & 0x5555); - ones = (ones & 0x3333) + ((ones >> 2) & 0x3333); - ones = (ones & 0x0f0f) + ((ones >> 4) & 0x0f0f); - ones = (ones & 0x00ff) + ((ones >> 8) & 0x00ff); + // pop count of w + ones = (w & 0x5555) + ((w >> 1) & 0x5555); + ones = (ones & 0x3333) + ((ones >> 2) & 0x3333); + ones = (ones & 0x0f0f) + ((ones >> 4) & 0x0f0f); + ones = (ones & 0x00ff) + ((ones >> 8) & 0x00ff); - zeros = 16 - ones; + zeros = 16 - ones; - return zeros * ZERO_BIT_LEN + (ones + 1) * ONE_BIT_LEN; + return zeros * ZERO_BIT_LEN + (ones + 1) * ONE_BIT_LEN; } hp_taco_device::tape_pos_t hp_taco_device::word_end_pos(const tape_track_t::iterator& it) { - return it->first + word_length(it->second); + return it->first + word_length(it->second); } void hp_taco_device::adjust_it(tape_track_t& track , tape_track_t::iterator& it , tape_pos_t pos) { - if (it != track.begin()) { - it--; - if (word_end_pos(it) <= pos) { - it++; - } - } + if (it != track.begin()) { + it--; + if (word_end_pos(it) <= pos) { + it++; + } + } } // Write a word on current tape track void hp_taco_device::write_word(tape_pos_t start , tape_word_t word , tape_pos_t& length) { - tape_track_t& track = current_track(); - tape_track_t::iterator it_low = track.lower_bound(start); - adjust_it(track , it_low , start); - length = word_length(word); - tape_pos_t end_pos = start + length; - tape_track_t::iterator it_high = track.lower_bound(end_pos); + tape_track_t& track = current_track(); + tape_track_t::iterator it_low = track.lower_bound(start); + adjust_it(track , it_low , start); + length = word_length(word); + tape_pos_t end_pos = start + length; + tape_track_t::iterator it_high = track.lower_bound(end_pos); - track.erase(it_low , it_high); + track.erase(it_low , it_high); - track.insert(it_high , std::make_pair(start, word)); - LOG_0(("WR %04x @ T%u:%u\n" , word , BIT(m_status_reg , STATUS_TRACKB_BIT) , start)); + track.insert(it_high , std::make_pair(start, word)); + LOG_0(("WR %04x @ T%u:%u\n" , word , BIT(m_status_reg , STATUS_TRACKB_BIT) , start)); } // Write a gap on current track void hp_taco_device::write_gap(tape_pos_t a , tape_pos_t b) { - ensure_a_lt_b(a , b); - tape_track_t& track = current_track(); - tape_track_t::iterator it_low = track.lower_bound(a); - adjust_it(track , it_low , a); - tape_track_t::iterator it_high = track.lower_bound(b); + ensure_a_lt_b(a , b); + tape_track_t& track = current_track(); + tape_track_t::iterator it_low = track.lower_bound(a); + adjust_it(track , it_low , a); + tape_track_t::iterator it_high = track.lower_bound(b); - track.erase(it_low, it_high); + track.erase(it_low, it_high); - LOG_0(("GAP on T%u:[%u,%u)\n" , BIT(m_status_reg , STATUS_TRACKB_BIT) , a , b)); + LOG_0(("GAP on T%u:[%u,%u)\n" , BIT(m_status_reg , STATUS_TRACKB_BIT) , a , b)); } bool hp_taco_device::just_gap(tape_pos_t a , tape_pos_t b) { - ensure_a_lt_b(a , b); - tape_track_t& track = current_track(); - tape_track_t::iterator it_low = track.lower_bound(a); - tape_track_t::iterator it_high = track.lower_bound(b); + ensure_a_lt_b(a , b); + tape_track_t& track = current_track(); + tape_track_t::iterator it_low = track.lower_bound(a); + tape_track_t::iterator it_high = track.lower_bound(b); - adjust_it(track, it_low, a); + adjust_it(track, it_low, a); - return it_low == it_high; + return it_low == it_high; } hp_taco_device::tape_pos_t hp_taco_device::farthest_end(const tape_track_t::iterator& it) const { - if (m_tape_fwd) { - return word_end_pos(it); - } else { - return it->first; - } + if (m_tape_fwd) { + return word_end_pos(it); + } else { + return it->first; + } } bool hp_taco_device::next_data(tape_track_t::iterator& it , tape_pos_t pos , bool inclusive) { - tape_track_t& track = current_track(); - it = track.lower_bound(pos); - if (m_tape_fwd) { - if (inclusive) { - adjust_it(track, it, pos); - } - return it != track.end(); - } else { - // Never more than 2 iterations - do { - if (it == track.begin()) { - it = track.end(); - return false; - } - it--; - } while (!inclusive && word_end_pos(it) > pos); - return true; - } + tape_track_t& track = current_track(); + it = track.lower_bound(pos); + if (m_tape_fwd) { + if (inclusive) { + adjust_it(track, it, pos); + } + return it != track.end(); + } else { + // Never more than 2 iterations + do { + if (it == track.begin()) { + it = track.end(); + return false; + } + it--; + } while (!inclusive && word_end_pos(it) > pos); + return true; + } } hp_taco_device::adv_res_t hp_taco_device::adv_it(tape_track_t::iterator& it) { - tape_track_t& track = current_track(); - if (m_tape_fwd) { - tape_pos_t prev_pos = word_end_pos(it); - it++; - if (it == track.end()) { - return ADV_NO_MORE_DATA; - } else { - adv_res_t res = prev_pos == it->first ? ADV_CONT_DATA : ADV_DISCONT_DATA; - return res; - } - } else { - if (it == track.begin()) { - it = track.end(); - return ADV_NO_MORE_DATA; - } else { - tape_pos_t prev_pos = it->first; - it--; - return prev_pos == word_end_pos(it) ? ADV_CONT_DATA : ADV_DISCONT_DATA; - } - } + tape_track_t& track = current_track(); + if (m_tape_fwd) { + tape_pos_t prev_pos = word_end_pos(it); + it++; + if (it == track.end()) { + return ADV_NO_MORE_DATA; + } else { + adv_res_t res = prev_pos == it->first ? ADV_CONT_DATA : ADV_DISCONT_DATA; + return res; + } + } else { + if (it == track.begin()) { + it = track.end(); + return ADV_NO_MORE_DATA; + } else { + tape_pos_t prev_pos = it->first; + it--; + return prev_pos == word_end_pos(it) ? ADV_CONT_DATA : ADV_DISCONT_DATA; + } + } } attotime hp_taco_device::fetch_next_wr_word(void) { - if (m_data_reg_full) { - m_next_word = m_data_reg; - m_data_reg_full = false; - LOG_0(("next %04x (DR)\n" , m_next_word)); - } else { - // When data register is empty, write checksum word - m_next_word = m_checksum_reg; - LOG_0(("next %04x (CS)\n" , m_next_word)); - } - // Update checksum with new word - m_checksum_reg += m_next_word; - - return time_to_distance(word_length(m_next_word)); + if (m_data_reg_full) { + m_next_word = m_data_reg; + m_data_reg_full = false; + LOG_0(("next %04x (DR)\n" , m_next_word)); + } else { + // When data register is empty, write checksum word + m_next_word = m_checksum_reg; + LOG_0(("next %04x (CS)\n" , m_next_word)); + } + // Update checksum with new word + m_checksum_reg += m_next_word; + + return time_to_distance(word_length(m_next_word)); } attotime hp_taco_device::time_to_rd_next_word(tape_pos_t& word_rd_pos) { - if (m_rd_it_valid) { - word_rd_pos = farthest_end(m_rd_it); - return time_to_target(word_rd_pos); - } else { - return attotime::never; - } + if (m_rd_it_valid) { + word_rd_pos = farthest_end(m_rd_it); + return time_to_target(word_rd_pos); + } else { + return attotime::never; + } } /** @@ -1017,451 +1017,451 @@ attotime hp_taco_device::time_to_rd_next_word(tape_pos_t& word_rd_pos) */ bool hp_taco_device::next_n_gap(tape_pos_t& pos , tape_track_t::iterator it , unsigned n_gaps , tape_pos_t min_gap) { - tape_track_t& track = current_track(); - bool done = false; - tape_track_t::iterator prev_it; - - if (m_tape_fwd) { - tape_pos_t next_pos; - - while (1) { - if (it == track.end()) { - next_pos = TAPE_LENGTH; - done = true; - } else { - next_pos = it->first; - } - if (((next_pos - pos) >= min_gap && --n_gaps == 0) || done) { - break; - } - adv_res_t adv_res; - do { - prev_it = it; - adv_res = adv_it(it); - } while (adv_res == ADV_CONT_DATA); - pos = word_end_pos(prev_it); - } - } else { - tape_pos_t next_pos; - - while (1) { - if (it == track.end()) { - next_pos = 0; - done = true; - } else { - next_pos = word_end_pos(it); - } - if (((pos - next_pos) >= min_gap && --n_gaps == 0) || done) { - break; - } - adv_res_t adv_res; - do { - prev_it = it; - adv_res = adv_it(it); - } while (adv_res == ADV_CONT_DATA); - pos = prev_it->first; - } - } - - // Set "pos" where minimum gap size is met - pos_offset(pos , min_gap); - - return n_gaps == 0; + tape_track_t& track = current_track(); + bool done = false; + tape_track_t::iterator prev_it; + + if (m_tape_fwd) { + tape_pos_t next_pos; + + while (1) { + if (it == track.end()) { + next_pos = TAPE_LENGTH; + done = true; + } else { + next_pos = it->first; + } + if (((next_pos - pos) >= min_gap && --n_gaps == 0) || done) { + break; + } + adv_res_t adv_res; + do { + prev_it = it; + adv_res = adv_it(it); + } while (adv_res == ADV_CONT_DATA); + pos = word_end_pos(prev_it); + } + } else { + tape_pos_t next_pos; + + while (1) { + if (it == track.end()) { + next_pos = 0; + done = true; + } else { + next_pos = word_end_pos(it); + } + if (((pos - next_pos) >= min_gap && --n_gaps == 0) || done) { + break; + } + adv_res_t adv_res; + do { + prev_it = it; + adv_res = adv_it(it); + } while (adv_res == ADV_CONT_DATA); + pos = prev_it->first; + } + } + + // Set "pos" where minimum gap size is met + pos_offset(pos , min_gap); + + return n_gaps == 0; } bool hp_taco_device::next_n_gap(tape_pos_t& pos , unsigned n_gaps , tape_pos_t min_gap) { - tape_track_t::iterator it; - // First align with next data - next_data(it, pos, true); - // Then scan for n_gaps - return next_n_gap(pos, it, n_gaps, min_gap); + tape_track_t::iterator it; + // First align with next data + next_data(it, pos, true); + // Then scan for n_gaps + return next_n_gap(pos, it, n_gaps, min_gap); } void hp_taco_device::clear_tape(void) { - for (unsigned track_n = 0; track_n < 2; track_n++) { - m_tracks[ track_n ].clear(); - } + for (unsigned track_n = 0; track_n < 2; track_n++) { + m_tracks[ track_n ].clear(); + } } void hp_taco_device::dump_sequence(tape_track_t::const_iterator it_start , unsigned n_words) { - if (n_words) { - UINT32 tmp32; - UINT16 tmp16; - - tmp32 = n_words; - fwrite(&tmp32 , sizeof(tmp32)); - tmp32 = it_start->first; - fwrite(&tmp32 , sizeof(tmp32)); - - for (unsigned i = 0; i < n_words; i++) { - tmp16 = it_start->second; - fwrite(&tmp16 , sizeof(tmp16)); - it_start++; - } - } + if (n_words) { + UINT32 tmp32; + UINT16 tmp16; + + tmp32 = n_words; + fwrite(&tmp32 , sizeof(tmp32)); + tmp32 = it_start->first; + fwrite(&tmp32 , sizeof(tmp32)); + + for (unsigned i = 0; i < n_words; i++) { + tmp16 = it_start->second; + fwrite(&tmp16 , sizeof(tmp16)); + it_start++; + } + } } void hp_taco_device::save_tape(void) { - UINT32 tmp32; - - fseek(0, SEEK_SET); - - tmp32 = FILE_MAGIC; - fwrite(&tmp32 , sizeof(tmp32)); - - for (unsigned track_n = 0; track_n < 2; track_n++) { - const tape_track_t& track = m_tracks[ track_n ]; - tape_pos_t next_pos = (tape_pos_t)-1; - unsigned n_words = 0; - tape_track_t::const_iterator it_start; - for (tape_track_t::const_iterator it = track.cbegin(); it != track.cend(); it++) { - if (it->first != next_pos) { - dump_sequence(it_start , n_words); - it_start = it; - n_words = 0; - } - next_pos = it->first + word_length(it->second); - n_words++; - } - dump_sequence(it_start , n_words); - // End of track - tmp32 = (UINT32)-1; - fwrite(&tmp32 , sizeof(tmp32)); - } + UINT32 tmp32; + + fseek(0, SEEK_SET); + + tmp32 = FILE_MAGIC; + fwrite(&tmp32 , sizeof(tmp32)); + + for (unsigned track_n = 0; track_n < 2; track_n++) { + const tape_track_t& track = m_tracks[ track_n ]; + tape_pos_t next_pos = (tape_pos_t)-1; + unsigned n_words = 0; + tape_track_t::const_iterator it_start; + for (tape_track_t::const_iterator it = track.cbegin(); it != track.cend(); it++) { + if (it->first != next_pos) { + dump_sequence(it_start , n_words); + it_start = it; + n_words = 0; + } + next_pos = it->first + word_length(it->second); + n_words++; + } + dump_sequence(it_start , n_words); + // End of track + tmp32 = (UINT32)-1; + fwrite(&tmp32 , sizeof(tmp32)); + } } bool hp_taco_device::load_track(tape_track_t& track) { - UINT32 tmp32; + UINT32 tmp32; - track.clear(); + track.clear(); - while (1) { - if (fread(&tmp32 , sizeof(tmp32)) != sizeof(tmp32)) { - return false; - } + while (1) { + if (fread(&tmp32 , sizeof(tmp32)) != sizeof(tmp32)) { + return false; + } - if (tmp32 == (UINT32)-1) { - return true; - } + if (tmp32 == (UINT32)-1) { + return true; + } - unsigned n_words = tmp32; + unsigned n_words = tmp32; - if (fread(&tmp32 , sizeof(tmp32)) != sizeof(tmp32)) { - return false; - } + if (fread(&tmp32 , sizeof(tmp32)) != sizeof(tmp32)) { + return false; + } - tape_pos_t pos = (tape_pos_t)tmp32; + tape_pos_t pos = (tape_pos_t)tmp32; - for (unsigned i = 0; i < n_words; i++) { - UINT16 tmp16; + for (unsigned i = 0; i < n_words; i++) { + UINT16 tmp16; - if (fread(&tmp16 , sizeof(tmp16)) != sizeof(tmp16)) { - return false; - } + if (fread(&tmp16 , sizeof(tmp16)) != sizeof(tmp16)) { + return false; + } - track.insert(std::make_pair(pos , tmp16)); - pos += word_length(tmp16); - } - } + track.insert(std::make_pair(pos , tmp16)); + pos += word_length(tmp16); + } + } } bool hp_taco_device::load_tape(void) { - UINT32 magic; - - if (fread(&magic , sizeof(magic)) != sizeof(magic) || - magic != FILE_MAGIC) { - return false; - } - - for (unsigned track_n = 0; track_n < 2; track_n++) { - if (!load_track(m_tracks[ track_n ])) { - LOG(("load_tape failed")); - clear_tape(); - return false; - } - } - - LOG(("load_tape done\n")); - return true; + UINT32 magic; + + if (fread(&magic , sizeof(magic)) != sizeof(magic) || + magic != FILE_MAGIC) { + return false; + } + + for (unsigned track_n = 0; track_n < 2; track_n++) { + if (!load_track(m_tracks[ track_n ])) { + LOG(("load_tape failed")); + clear_tape(); + return false; + } + } + + LOG(("load_tape done\n")); + return true; } void hp_taco_device::set_tape_present(bool present) { - if (present) { - if (is_readonly()) { - BIT_SET(m_status_reg, STATUS_WPR_BIT); - } else { - BIT_CLR(m_status_reg, STATUS_WPR_BIT); - } - // STATUS_CART_OUT_BIT is reset by CMD_CLEAR - } else { - BIT_SET(m_status_reg, STATUS_CART_OUT_BIT); - BIT_SET(m_status_reg, STATUS_WPR_BIT); - } + if (present) { + if (is_readonly()) { + BIT_SET(m_status_reg, STATUS_WPR_BIT); + } else { + BIT_CLR(m_status_reg, STATUS_WPR_BIT); + } + // STATUS_CART_OUT_BIT is reset by CMD_CLEAR + } else { + BIT_SET(m_status_reg, STATUS_CART_OUT_BIT); + BIT_SET(m_status_reg, STATUS_WPR_BIT); + } } attotime hp_taco_device::time_to_next_hole(void) const { - return time_to_target(next_hole()); + return time_to_target(next_hole()); } attotime hp_taco_device::time_to_tach_pulses(void) const { - return time_to_distance((tape_pos_t)(0x10000U - m_tach_reg) * TAPE_POS_FRACT); + return time_to_distance((tape_pos_t)(0x10000U - m_tach_reg) * TAPE_POS_FRACT); } void hp_taco_device::start_cmd_exec(UINT16 new_cmd_reg) { - LOG(("Cmd = %02x\n" , CMD_CODE(new_cmd_reg))); - - update_tape_pos(); - - attotime cmd_duration = attotime::never; - attotime time_to_hole = attotime::never; - - unsigned new_cmd_code = CMD_CODE(new_cmd_reg); - - if (new_cmd_code != CMD_START_READ && - new_cmd_code != CMD_END_READ && - new_cmd_code != CMD_CLEAR) { - m_rd_it_valid = false; - } - - switch (new_cmd_code) { - case CMD_INDTA_INGAP: - // Errors: CART OUT,FAST SPEED - if (start_tape_cmd(new_cmd_reg , 0 , SPEED_FAST_MASK)) { - m_cmd_state = 0; - if (next_data(m_rd_it , m_tape_pos , true)) { - cmd_duration = time_to_target(farthest_end(m_rd_it)); - } - } - break; - - case CMD_FINAL_GAP: - // Errors: WP,CART OUT - if (start_tape_cmd(new_cmd_reg , 0 , STATUS_WPR_MASK)) { - m_rw_pos = m_tape_pos; - cmd_duration = time_to_distance(END_GAP_LENGTH); - time_to_hole = time_to_next_hole(); - } - break; - - case CMD_CLEAR: - set_error(false); - BIT_CLR(m_status_reg, STATUS_HOLE_BIT); - BIT_CLR(m_status_reg, STATUS_CART_OUT_BIT); - BIT_CLR(m_status_reg, STATUS_WPR_BIT); - set_tape_present(is_loaded()); - // This is a special command: it doesn't raise IRQ at completion and it - // doesn't replace current command - return; - - case CMD_NOT_INDTA: - // Errors: CART OUT,FAST SPEED - if (start_tape_cmd(new_cmd_reg , 0 , SPEED_FAST_MASK)) { - tape_pos_t target = m_tape_pos; - if (next_n_gap(target, 1, NO_DATA_GAP)) { - LOG_0(("End of data @%d\n" , target)); - cmd_duration = time_to_target(target); - } - // Holes detected? - } - break; - - case CMD_INIT_WRITE: - // Errors: WP,CART OUT,fast speed,reverse - if (start_tape_cmd(new_cmd_reg , DIR_FWD_MASK , STATUS_WPR_MASK | SPEED_FAST_MASK)) { - m_next_word = PREAMBLE_WORD; - m_rw_pos = m_tape_pos; - cmd_duration = time_to_distance(word_length(m_next_word)); - } - break; - - case CMD_STOP: - if (CMD_CODE(m_cmd_reg) != CMD_STOP) { - if (m_start_time.is_never()) { - // Tape is already stopped - cmd_duration = attotime::from_usec(QUICK_CMD_USEC); - } else { - // Start braking timer - cmd_duration = attotime::from_msec(m_tape_fast ? FAST_BRAKE_MSEC : SLOW_BRAKE_MSEC); - } - m_cmd_reg = new_cmd_reg; - } else { - // TODO: check if ok - return; - } - break; - - case CMD_SET_TRACK: - // Don't know if this command really starts the tape or not (probably it doesn't) - if (start_tape_cmd(new_cmd_reg , 0 , 0)) { - // When b9 is 0, set track A/B - // When b9 is 1, ignore command (in TACO chip it has an unknown purpose) - if (!UNKNOWN_B9(new_cmd_reg)) { - if (CMD_OPT(new_cmd_reg)) { - BIT_SET(m_status_reg, STATUS_TRACKB_BIT); - } else { - BIT_CLR(m_status_reg, STATUS_TRACKB_BIT); - } - } - cmd_duration = attotime::from_usec(QUICK_CMD_USEC); - } - break; - - case CMD_MOVE: - if (start_tape_cmd(new_cmd_reg , 0 , 0)) { - time_to_hole = time_to_next_hole(); - } - break; - - case CMD_INGAP_MOVE: - // Errors: CART OUT,FAST SPEED - if (start_tape_cmd(new_cmd_reg , 0 , SPEED_FAST_MASK)) { - m_cmd_state = 0; - tape_pos_t target = m_tape_pos; - if (next_n_gap(target, 1, MIN_IRG_LENGTH)) { - LOG_0(("IRG @%d\n" , target)); - cmd_duration = time_to_target(target); - } - // Holes detected? - } - break; - - case CMD_WRITE_IRG: - // Errors: WP,CART OUT - if (start_tape_cmd(new_cmd_reg , 0 , STATUS_WPR_MASK)) { - m_rw_pos = m_tape_pos; - cmd_duration = time_to_tach_pulses(); - time_to_hole = time_to_next_hole(); - } - break; - - case CMD_SCAN_RECORDS: - // Errors: CART OUT - if (start_tape_cmd(new_cmd_reg , 0 , 0)) { - m_cmd_state = 0; - if (next_data(m_rd_it , m_tape_pos , true)) { - cmd_duration = time_to_target(farthest_end(m_rd_it)); - } - time_to_hole = time_to_next_hole(); - } - break; - - case CMD_RECORD_WRITE: - // Errors: WP,CART OUT,fast speed,reverse - if (start_tape_cmd(new_cmd_reg , DIR_FWD_MASK , STATUS_WPR_MASK | SPEED_FAST_MASK)) { - // Search for preamble first - m_cmd_state = 0; - m_rd_it_valid = next_data(m_rd_it , m_tape_pos , false); - cmd_duration = time_to_rd_next_word(m_rw_pos); - // Holes detected? - } - break; - - case CMD_MOVE_INDTA: - // Errors: CART OUT,FAST SPEED - if (start_tape_cmd(new_cmd_reg , 0 , SPEED_FAST_MASK)) { - m_cmd_state = 0; - cmd_duration = time_to_tach_pulses(); - // Holes detected? - } - break; - - case CMD_UNK_1b: - if (start_tape_cmd(new_cmd_reg , 0 , 0)) { - // Unknown purpose, but make it a NOP (it's used in "T" test of test ROM) - cmd_duration = attotime::from_usec(QUICK_CMD_USEC); - } - break; - - case CMD_DELTA_MOVE_HOLE: - case CMD_DELTA_MOVE_IRG: - if (start_tape_cmd(new_cmd_reg , 0 , 0)) { - cmd_duration = time_to_tach_pulses(); - time_to_hole = time_to_next_hole(); - } - break; - - case CMD_START_READ: - // Yes, you can read tape backwards: test "C" does that! - // Because of this DIR_FWD_MASK is not in the "must be 1" mask. - if (start_tape_cmd(new_cmd_reg , 0 , SPEED_FAST_MASK)) { - // TODO: check anche m_rw_pos sforato - if (!m_rd_it_valid) { - // Search for preamble first - m_cmd_state = 0; - m_rd_it_valid = next_data(m_rd_it , m_tape_pos , false); - } - - cmd_duration = time_to_rd_next_word(m_rw_pos); - time_to_hole = time_to_next_hole(); - } - break; - - case CMD_END_READ: - // This command only makes sense after CMD_START_READ - if (CMD_CODE(m_cmd_reg) == CMD_START_READ && m_cmd_state == 1 && - start_tape_cmd(new_cmd_reg , 0 , SPEED_FAST_MASK)) { - LOG_0(("END_READ %d\n" , m_rd_it_valid)); - cmd_duration = time_to_rd_next_word(m_rw_pos); - time_to_hole = time_to_next_hole(); - } - break; - - default: - LOG(("Unrecognized command\n")); - break; - } - - m_tape_timer->adjust(cmd_duration); - m_hole_timer->adjust(time_to_hole); + LOG(("Cmd = %02x\n" , CMD_CODE(new_cmd_reg))); + + update_tape_pos(); + + attotime cmd_duration = attotime::never; + attotime time_to_hole = attotime::never; + + unsigned new_cmd_code = CMD_CODE(new_cmd_reg); + + if (new_cmd_code != CMD_START_READ && + new_cmd_code != CMD_END_READ && + new_cmd_code != CMD_CLEAR) { + m_rd_it_valid = false; + } + + switch (new_cmd_code) { + case CMD_INDTA_INGAP: + // Errors: CART OUT,FAST SPEED + if (start_tape_cmd(new_cmd_reg , 0 , SPEED_FAST_MASK)) { + m_cmd_state = 0; + if (next_data(m_rd_it , m_tape_pos , true)) { + cmd_duration = time_to_target(farthest_end(m_rd_it)); + } + } + break; + + case CMD_FINAL_GAP: + // Errors: WP,CART OUT + if (start_tape_cmd(new_cmd_reg , 0 , STATUS_WPR_MASK)) { + m_rw_pos = m_tape_pos; + cmd_duration = time_to_distance(END_GAP_LENGTH); + time_to_hole = time_to_next_hole(); + } + break; + + case CMD_CLEAR: + set_error(false); + BIT_CLR(m_status_reg, STATUS_HOLE_BIT); + BIT_CLR(m_status_reg, STATUS_CART_OUT_BIT); + BIT_CLR(m_status_reg, STATUS_WPR_BIT); + set_tape_present(is_loaded()); + // This is a special command: it doesn't raise IRQ at completion and it + // doesn't replace current command + return; + + case CMD_NOT_INDTA: + // Errors: CART OUT,FAST SPEED + if (start_tape_cmd(new_cmd_reg , 0 , SPEED_FAST_MASK)) { + tape_pos_t target = m_tape_pos; + if (next_n_gap(target, 1, NO_DATA_GAP)) { + LOG_0(("End of data @%d\n" , target)); + cmd_duration = time_to_target(target); + } + // Holes detected? + } + break; + + case CMD_INIT_WRITE: + // Errors: WP,CART OUT,fast speed,reverse + if (start_tape_cmd(new_cmd_reg , DIR_FWD_MASK , STATUS_WPR_MASK | SPEED_FAST_MASK)) { + m_next_word = PREAMBLE_WORD; + m_rw_pos = m_tape_pos; + cmd_duration = time_to_distance(word_length(m_next_word)); + } + break; + + case CMD_STOP: + if (CMD_CODE(m_cmd_reg) != CMD_STOP) { + if (m_start_time.is_never()) { + // Tape is already stopped + cmd_duration = attotime::from_usec(QUICK_CMD_USEC); + } else { + // Start braking timer + cmd_duration = attotime::from_msec(m_tape_fast ? FAST_BRAKE_MSEC : SLOW_BRAKE_MSEC); + } + m_cmd_reg = new_cmd_reg; + } else { + // TODO: check if ok + return; + } + break; + + case CMD_SET_TRACK: + // Don't know if this command really starts the tape or not (probably it doesn't) + if (start_tape_cmd(new_cmd_reg , 0 , 0)) { + // When b9 is 0, set track A/B + // When b9 is 1, ignore command (in TACO chip it has an unknown purpose) + if (!UNKNOWN_B9(new_cmd_reg)) { + if (CMD_OPT(new_cmd_reg)) { + BIT_SET(m_status_reg, STATUS_TRACKB_BIT); + } else { + BIT_CLR(m_status_reg, STATUS_TRACKB_BIT); + } + } + cmd_duration = attotime::from_usec(QUICK_CMD_USEC); + } + break; + + case CMD_MOVE: + if (start_tape_cmd(new_cmd_reg , 0 , 0)) { + time_to_hole = time_to_next_hole(); + } + break; + + case CMD_INGAP_MOVE: + // Errors: CART OUT,FAST SPEED + if (start_tape_cmd(new_cmd_reg , 0 , SPEED_FAST_MASK)) { + m_cmd_state = 0; + tape_pos_t target = m_tape_pos; + if (next_n_gap(target, 1, MIN_IRG_LENGTH)) { + LOG_0(("IRG @%d\n" , target)); + cmd_duration = time_to_target(target); + } + // Holes detected? + } + break; + + case CMD_WRITE_IRG: + // Errors: WP,CART OUT + if (start_tape_cmd(new_cmd_reg , 0 , STATUS_WPR_MASK)) { + m_rw_pos = m_tape_pos; + cmd_duration = time_to_tach_pulses(); + time_to_hole = time_to_next_hole(); + } + break; + + case CMD_SCAN_RECORDS: + // Errors: CART OUT + if (start_tape_cmd(new_cmd_reg , 0 , 0)) { + m_cmd_state = 0; + if (next_data(m_rd_it , m_tape_pos , true)) { + cmd_duration = time_to_target(farthest_end(m_rd_it)); + } + time_to_hole = time_to_next_hole(); + } + break; + + case CMD_RECORD_WRITE: + // Errors: WP,CART OUT,fast speed,reverse + if (start_tape_cmd(new_cmd_reg , DIR_FWD_MASK , STATUS_WPR_MASK | SPEED_FAST_MASK)) { + // Search for preamble first + m_cmd_state = 0; + m_rd_it_valid = next_data(m_rd_it , m_tape_pos , false); + cmd_duration = time_to_rd_next_word(m_rw_pos); + // Holes detected? + } + break; + + case CMD_MOVE_INDTA: + // Errors: CART OUT,FAST SPEED + if (start_tape_cmd(new_cmd_reg , 0 , SPEED_FAST_MASK)) { + m_cmd_state = 0; + cmd_duration = time_to_tach_pulses(); + // Holes detected? + } + break; + + case CMD_UNK_1b: + if (start_tape_cmd(new_cmd_reg , 0 , 0)) { + // Unknown purpose, but make it a NOP (it's used in "T" test of test ROM) + cmd_duration = attotime::from_usec(QUICK_CMD_USEC); + } + break; + + case CMD_DELTA_MOVE_HOLE: + case CMD_DELTA_MOVE_IRG: + if (start_tape_cmd(new_cmd_reg , 0 , 0)) { + cmd_duration = time_to_tach_pulses(); + time_to_hole = time_to_next_hole(); + } + break; + + case CMD_START_READ: + // Yes, you can read tape backwards: test "C" does that! + // Because of this DIR_FWD_MASK is not in the "must be 1" mask. + if (start_tape_cmd(new_cmd_reg , 0 , SPEED_FAST_MASK)) { + // TODO: check anche m_rw_pos sforato + if (!m_rd_it_valid) { + // Search for preamble first + m_cmd_state = 0; + m_rd_it_valid = next_data(m_rd_it , m_tape_pos , false); + } + + cmd_duration = time_to_rd_next_word(m_rw_pos); + time_to_hole = time_to_next_hole(); + } + break; + + case CMD_END_READ: + // This command only makes sense after CMD_START_READ + if (CMD_CODE(m_cmd_reg) == CMD_START_READ && m_cmd_state == 1 && + start_tape_cmd(new_cmd_reg , 0 , SPEED_FAST_MASK)) { + LOG_0(("END_READ %d\n" , m_rd_it_valid)); + cmd_duration = time_to_rd_next_word(m_rw_pos); + time_to_hole = time_to_next_hole(); + } + break; + + default: + LOG(("Unrecognized command\n")); + break; + } + + m_tape_timer->adjust(cmd_duration); + m_hole_timer->adjust(time_to_hole); } bool hp_taco_device::call_load() { - LOG(("call_load %d\n" , has_been_created())); - if (has_been_created()) { - clear_tape(); - save_tape(); - } else if (!load_tape()) { - seterror(IMAGE_ERROR_INVALIDIMAGE , "Wrong format"); - set_tape_present(false); - return IMAGE_INIT_FAIL; - } - - m_image_dirty = false; - - set_tape_present(true); + LOG(("call_load %d\n" , has_been_created())); + if (has_been_created()) { + clear_tape(); + save_tape(); + } else if (!load_tape()) { + seterror(IMAGE_ERROR_INVALIDIMAGE , "Wrong format"); + set_tape_present(false); + return IMAGE_INIT_FAIL; + } + + m_image_dirty = false; + + set_tape_present(true); return IMAGE_INIT_PASS; } bool hp_taco_device::call_create(int format_type, option_resolution *format_options) { - LOG(("call_create %d\n" , has_been_created())); - return call_load(); + LOG(("call_create %d\n" , has_been_created())); + return call_load(); } void hp_taco_device::call_unload() { - LOG(("call_unload dirty=%d\n" , m_image_dirty)); - if (m_image_dirty) { - save_tape(); - m_image_dirty = false; - } - - clear_tape(); - set_tape_present(false); + LOG(("call_unload dirty=%d\n" , m_image_dirty)); + if (m_image_dirty) { + save_tape(); + m_image_dirty = false; + } + + clear_tape(); + set_tape_present(false); } const char *hp_taco_device::file_extensions() const { - return "hti"; + return "hti"; } diff --git a/src/devices/machine/hp_taco.h b/src/devices/machine/hp_taco.h index c8b794c79a2..1695b7ce706 100644 --- a/src/devices/machine/hp_taco.h +++ b/src/devices/machine/hp_taco.h @@ -14,36 +14,36 @@ #include <map> #define MCFG_TACO_IRQ_HANDLER(_devcb) \ - devcb = &hp_taco_device::set_irq_handler(*device , DEVCB_##_devcb); + devcb = &hp_taco_device::set_irq_handler(*device , DEVCB_##_devcb); #define MCFG_TACO_FLG_HANDLER(_devcb) \ - devcb = &hp_taco_device::set_flg_handler(*device , DEVCB_##_devcb); + devcb = &hp_taco_device::set_flg_handler(*device , DEVCB_##_devcb); #define MCFG_TACO_STS_HANDLER(_devcb) \ - devcb = &hp_taco_device::set_sts_handler(*device , DEVCB_##_devcb); + devcb = &hp_taco_device::set_sts_handler(*device , DEVCB_##_devcb); class hp_taco_device : public device_t , - public device_image_interface + public device_image_interface { public: - // construction/destruction - hp_taco_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname); - hp_taco_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + // construction/destruction + hp_taco_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname); + hp_taco_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - // static configuration helpers - template<class _Object> static devcb_base &set_irq_handler(device_t &device, _Object object) { return downcast<hp_taco_device &>(device).m_irq_handler.set_callback(object); } - template<class _Object> static devcb_base &set_flg_handler(device_t &device, _Object object) { return downcast<hp_taco_device &>(device).m_flg_handler.set_callback(object); } - template<class _Object> static devcb_base &set_sts_handler(device_t &device, _Object object) { return downcast<hp_taco_device &>(device).m_sts_handler.set_callback(object); } + // static configuration helpers + template<class _Object> static devcb_base &set_irq_handler(device_t &device, _Object object) { return downcast<hp_taco_device &>(device).m_irq_handler.set_callback(object); } + template<class _Object> static devcb_base &set_flg_handler(device_t &device, _Object object) { return downcast<hp_taco_device &>(device).m_flg_handler.set_callback(object); } + template<class _Object> static devcb_base &set_sts_handler(device_t &device, _Object object) { return downcast<hp_taco_device &>(device).m_sts_handler.set_callback(object); } - // Register read/write - DECLARE_WRITE16_MEMBER(reg_w); - DECLARE_READ16_MEMBER(reg_r); + // Register read/write + DECLARE_WRITE16_MEMBER(reg_w); + DECLARE_READ16_MEMBER(reg_r); - // Flag & status read - DECLARE_READ_LINE_MEMBER(flg_r); - DECLARE_READ_LINE_MEMBER(sts_r); + // Flag & status read + DECLARE_READ_LINE_MEMBER(flg_r); + DECLARE_READ_LINE_MEMBER(sts_r); - // device_image_interface overrides + // device_image_interface overrides virtual bool call_load() override; virtual bool call_create(int format_type, option_resolution *format_options) override; virtual void call_unload() override; @@ -56,111 +56,111 @@ public: virtual const char *file_extensions() const override; virtual const option_guide *create_option_guide() const override { return nullptr; } - // Tape position, 1 unit = 1 inch / (968 * 1024) - typedef INT32 tape_pos_t; + // Tape position, 1 unit = 1 inch / (968 * 1024) + typedef INT32 tape_pos_t; - // Words stored on tape - typedef UINT16 tape_word_t; + // Words stored on tape + typedef UINT16 tape_word_t; protected: - // device-level overrides + // device-level overrides virtual void device_config_complete() override; - virtual void device_start() override; - virtual void device_stop() override; - virtual void device_reset() override; - virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + virtual void device_start() override; + virtual void device_stop() override; + virtual void device_reset() override; + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; private: - // Storage of tracks: mapping from a tape position to word stored there - typedef std::map<tape_pos_t , tape_word_t> tape_track_t; - - devcb_write_line m_irq_handler; - devcb_write_line m_flg_handler; - devcb_write_line m_sts_handler; - - // Registers - UINT16 m_data_reg; - bool m_data_reg_full; - UINT16 m_cmd_reg; - UINT16 m_status_reg; - UINT16 m_tach_reg; - UINT16 m_checksum_reg; - UINT16 m_timing_reg; - - // State - bool m_irq; - bool m_flg; - bool m_sts; - UINT8 m_cmd_state; - - // Tape position & motion - tape_pos_t m_tape_pos; - attotime m_start_time; // Tape moving if != never - bool m_tape_fwd; - bool m_tape_fast; - - // Timers - emu_timer *m_tape_timer; - emu_timer *m_hole_timer; - - // Content of tape tracks - tape_track_t m_tracks[ 2 ]; - bool m_image_dirty; - - // Reading & writing - bool m_tape_wr; - tape_pos_t m_rw_pos; - UINT16 m_next_word; - tape_track_t::iterator m_rd_it; - bool m_rd_it_valid; - - // Gap detection - tape_pos_t m_gap_detect_start; - - typedef enum { - ADV_NO_MORE_DATA, - ADV_CONT_DATA, - ADV_DISCONT_DATA - } adv_res_t; - - void clear_state(void); - void irq_w(bool state); - void set_error(bool state); - unsigned speed_to_tick_freq(void) const; - bool pos_offset(tape_pos_t& pos , tape_pos_t offset) const; - void move_tape_pos(tape_pos_t delta_pos); - void update_tape_pos(void); - static void ensure_a_lt_b(tape_pos_t& a , tape_pos_t& b); - static bool any_hole(tape_pos_t tape_pos_a , tape_pos_t tape_pos_b); - tape_pos_t next_hole(void) const; - attotime time_to_distance(tape_pos_t distance) const; - attotime time_to_target(tape_pos_t target) const; - bool start_tape_cmd(UINT16 cmd_reg , UINT16 must_be_1 , UINT16 must_be_0); - void start_tape(UINT16 cmd_reg); - void stop_tape(void); - tape_track_t& current_track(void); - static tape_pos_t word_length(tape_word_t w); - static tape_pos_t word_end_pos(const tape_track_t::iterator& it); - static void adjust_it(tape_track_t& track , tape_track_t::iterator& it , tape_pos_t pos); - void write_word(tape_pos_t start , tape_word_t word , tape_pos_t& length); - void write_gap(tape_pos_t a , tape_pos_t b); - bool just_gap(tape_pos_t a , tape_pos_t b); - tape_pos_t farthest_end(const tape_track_t::iterator& it) const; - bool next_data(tape_track_t::iterator& it , tape_pos_t pos , bool inclusive); - adv_res_t adv_it(tape_track_t::iterator& it); - attotime fetch_next_wr_word(void); - attotime time_to_rd_next_word(tape_pos_t& word_rd_pos); - bool next_n_gap(tape_pos_t& pos , tape_track_t::iterator it , unsigned n_gaps , tape_pos_t min_gap); - bool next_n_gap(tape_pos_t& pos , unsigned n_gaps , tape_pos_t min_gap); - void clear_tape(void); - void dump_sequence(tape_track_t::const_iterator it_start , unsigned n_words); - void save_tape(void); - bool load_track(tape_track_t& track); - bool load_tape(void); - void set_tape_present(bool present); - attotime time_to_next_hole(void) const; - attotime time_to_tach_pulses(void) const; - void start_cmd_exec(UINT16 new_cmd_reg); + // Storage of tracks: mapping from a tape position to word stored there + typedef std::map<tape_pos_t , tape_word_t> tape_track_t; + + devcb_write_line m_irq_handler; + devcb_write_line m_flg_handler; + devcb_write_line m_sts_handler; + + // Registers + UINT16 m_data_reg; + bool m_data_reg_full; + UINT16 m_cmd_reg; + UINT16 m_status_reg; + UINT16 m_tach_reg; + UINT16 m_checksum_reg; + UINT16 m_timing_reg; + + // State + bool m_irq; + bool m_flg; + bool m_sts; + UINT8 m_cmd_state; + + // Tape position & motion + tape_pos_t m_tape_pos; + attotime m_start_time; // Tape moving if != never + bool m_tape_fwd; + bool m_tape_fast; + + // Timers + emu_timer *m_tape_timer; + emu_timer *m_hole_timer; + + // Content of tape tracks + tape_track_t m_tracks[ 2 ]; + bool m_image_dirty; + + // Reading & writing + bool m_tape_wr; + tape_pos_t m_rw_pos; + UINT16 m_next_word; + tape_track_t::iterator m_rd_it; + bool m_rd_it_valid; + + // Gap detection + tape_pos_t m_gap_detect_start; + + typedef enum { + ADV_NO_MORE_DATA, + ADV_CONT_DATA, + ADV_DISCONT_DATA + } adv_res_t; + + void clear_state(void); + void irq_w(bool state); + void set_error(bool state); + unsigned speed_to_tick_freq(void) const; + bool pos_offset(tape_pos_t& pos , tape_pos_t offset) const; + void move_tape_pos(tape_pos_t delta_pos); + void update_tape_pos(void); + static void ensure_a_lt_b(tape_pos_t& a , tape_pos_t& b); + static bool any_hole(tape_pos_t tape_pos_a , tape_pos_t tape_pos_b); + tape_pos_t next_hole(void) const; + attotime time_to_distance(tape_pos_t distance) const; + attotime time_to_target(tape_pos_t target) const; + bool start_tape_cmd(UINT16 cmd_reg , UINT16 must_be_1 , UINT16 must_be_0); + void start_tape(UINT16 cmd_reg); + void stop_tape(void); + tape_track_t& current_track(void); + static tape_pos_t word_length(tape_word_t w); + static tape_pos_t word_end_pos(const tape_track_t::iterator& it); + static void adjust_it(tape_track_t& track , tape_track_t::iterator& it , tape_pos_t pos); + void write_word(tape_pos_t start , tape_word_t word , tape_pos_t& length); + void write_gap(tape_pos_t a , tape_pos_t b); + bool just_gap(tape_pos_t a , tape_pos_t b); + tape_pos_t farthest_end(const tape_track_t::iterator& it) const; + bool next_data(tape_track_t::iterator& it , tape_pos_t pos , bool inclusive); + adv_res_t adv_it(tape_track_t::iterator& it); + attotime fetch_next_wr_word(void); + attotime time_to_rd_next_word(tape_pos_t& word_rd_pos); + bool next_n_gap(tape_pos_t& pos , tape_track_t::iterator it , unsigned n_gaps , tape_pos_t min_gap); + bool next_n_gap(tape_pos_t& pos , unsigned n_gaps , tape_pos_t min_gap); + void clear_tape(void); + void dump_sequence(tape_track_t::const_iterator it_start , unsigned n_words); + void save_tape(void); + bool load_track(tape_track_t& track); + bool load_tape(void); + void set_tape_present(bool present); + attotime time_to_next_hole(void) const; + attotime time_to_tach_pulses(void) const; + void start_cmd_exec(UINT16 new_cmd_reg); }; // device type definition diff --git a/src/devices/video/ef9364.cpp b/src/devices/video/ef9364.cpp index b850f05d531..5b683b15e09 100644 --- a/src/devices/video/ef9364.cpp +++ b/src/devices/video/ef9364.cpp @@ -31,7 +31,7 @@ const device_type EF9364 = &device_creator<ef9364_device>; // default address map //------------------------------------------------- static ADDRESS_MAP_START( ef9364, AS_0, 8, ef9364_device ) - AM_RANGE(0x00000, ( ( EF9364_TXTPLANE_MAX_SIZE * EF9364_MAX_TXTPLANES ) - 1 ) ) AM_RAM + AM_RANGE(0x00000, ( ( EF9364_TXTPLANE_MAX_SIZE * EF9364_MAX_TXTPLANES ) - 1 ) ) AM_RAM ADDRESS_MAP_END //------------------------------------------------- @@ -41,7 +41,7 @@ ADDRESS_MAP_END const address_space_config *ef9364_device::memory_space_config(address_spacenum spacenum) const { - return (spacenum == AS_0) ? &m_space_config : NULL; + return (spacenum == AS_0) ? &m_space_config : NULL; } //************************************************************************** @@ -57,13 +57,13 @@ const address_space_config *ef9364_device::memory_space_config(address_spacenum //------------------------------------------------- ef9364_device::ef9364_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : - device_t(mconfig, EF9364, "EF9364", tag, owner, clock, "ef9364", __FILE__), - device_memory_interface(mconfig, *this), - device_video_interface(mconfig, *this), - m_space_config("textram", ENDIANNESS_LITTLE, 8, 12, 0, nullptr, *ADDRESS_MAP_NAME(ef9364)), - m_palette(*this) + device_t(mconfig, EF9364, "EF9364", tag, owner, clock, "ef9364", __FILE__), + device_memory_interface(mconfig, *this), + device_video_interface(mconfig, *this), + m_space_config("textram", ENDIANNESS_LITTLE, 8, 12, 0, nullptr, *ADDRESS_MAP_NAME(ef9364)), + m_palette(*this) { - clock_freq = clock; + clock_freq = clock; } //------------------------------------------------- @@ -73,7 +73,7 @@ ef9364_device::ef9364_device(const machine_config &mconfig, const char *tag, dev void ef9364_device::static_set_palette_tag(device_t &device, const char *tag) { - downcast<ef9364_device &>(device).m_palette.set_tag(tag); + downcast<ef9364_device &>(device).m_palette.set_tag(tag); } //------------------------------------------------- @@ -82,10 +82,10 @@ void ef9364_device::static_set_palette_tag(device_t &device, const char *tag) void ef9364_device::static_set_nb_of_pages(device_t &device, int nb_of_pages ) { - if( nb_of_pages > 0 && nb_of_pages <= 8 ) - { - downcast<ef9364_device &>(device).nb_of_pages = nb_of_pages; - } + if( nb_of_pages > 0 && nb_of_pages <= 8 ) + { + downcast<ef9364_device &>(device).nb_of_pages = nb_of_pages; + } } //------------------------------------------------- @@ -95,14 +95,14 @@ void ef9364_device::static_set_nb_of_pages(device_t &device, int nb_of_pages ) void ef9364_device::set_color_entry( int index, UINT8 r, UINT8 g, UINT8 b ) { - if( index < 2 ) - { - palette[index] = rgb_t(r, g, b); - } - else - { - logerror("Invalid EF9364 Palette entry : %02x\n", index); - } + if( index < 2 ) + { + palette[index] = rgb_t(r, g, b); + } + else + { + logerror("Invalid EF9364 Palette entry : %02x\n", index); + } } //------------------------------------------------- @@ -111,26 +111,26 @@ void ef9364_device::set_color_entry( int index, UINT8 r, UINT8 g, UINT8 b ) void ef9364_device::device_start() { - m_textram = &space(0); - m_charset = region(); + m_textram = &space(0); + m_charset = region(); - bitplane_xres = EF9364_NB_OF_COLUMNS*8; - bitplane_yres = EF9364_NB_OF_ROWS*(8+4); + bitplane_xres = EF9364_NB_OF_COLUMNS*8; + bitplane_yres = EF9364_NB_OF_ROWS*(8+4); - vsync_scanline_pos = 250; + vsync_scanline_pos = 250; - // Default palette : Black and white - palette[0] = rgb_t(0, 0, 0); - palette[1] = rgb_t(255, 255, 255); + // Default palette : Black and white + palette[0] = rgb_t(0, 0, 0); + palette[1] = rgb_t(255, 255, 255); - m_screen_out.allocate( bitplane_xres, m_screen->height() ); + m_screen_out.allocate( bitplane_xres, m_screen->height() ); - cursor_cnt = 0; - cursor_state = 0; + cursor_cnt = 0; + cursor_state = 0; - save_item(NAME(m_border)); + save_item(NAME(m_border)); - save_item(NAME(m_screen_out)); + save_item(NAME(m_screen_out)); } //------------------------------------------------- @@ -139,23 +139,23 @@ void ef9364_device::device_start() void ef9364_device::device_reset() { - int i; + int i; - x_curs_pos = 0; - y_curs_pos = 0; + x_curs_pos = 0; + y_curs_pos = 0; - char_latch = 0x00; + char_latch = 0x00; - for(i=0;i<EF9364_NB_OF_COLUMNS * EF9364_NB_OF_ROWS * nb_of_pages;i++) - { - m_textram->write_byte ( i , 0x7F ); - } + for(i=0;i<EF9364_NB_OF_COLUMNS * EF9364_NB_OF_ROWS * nb_of_pages;i++) + { + m_textram->write_byte ( i , 0x7F ); + } - memset(m_border, 0, sizeof(m_border)); + memset(m_border, 0, sizeof(m_border)); - m_screen_out.fill(0); + m_screen_out.fill(0); - set_video_mode(); + set_video_mode(); } //------------------------------------------------- @@ -164,18 +164,18 @@ void ef9364_device::device_reset() void ef9364_device::set_video_mode(void) { - UINT16 new_width = bitplane_xres; + UINT16 new_width = bitplane_xres; - if (m_screen->width() != new_width) - { - rectangle visarea = m_screen->visible_area(); - visarea.max_x = new_width - 1; + if (m_screen->width() != new_width) + { + rectangle visarea = m_screen->visible_area(); + visarea.max_x = new_width - 1; - m_screen->configure(new_width, m_screen->height(), visarea, m_screen->frame_period().attoseconds()); - } + m_screen->configure(new_width, m_screen->height(), visarea, m_screen->frame_period().attoseconds()); + } - //border color - memset(m_border, 0, sizeof(m_border)); + //border color + memset(m_border, 0, sizeof(m_border)); } //------------------------------------------------- @@ -193,41 +193,41 @@ void ef9364_device::draw_border(UINT16 line) UINT32 ef9364_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - int x,y,r; - unsigned char c; - - for( r = 0 ; r < EF9364_NB_OF_ROWS ; r++ ) - { - for( y = 0 ; y < 8 ; y++ ) - { - for( x = 0 ; x < EF9364_NB_OF_COLUMNS * 8 ; x++ ) - { - if( ( ( x >> 3 ) != x_curs_pos ) || ( r != y_curs_pos ) || !cursor_state) - { - c = m_textram->read_byte( ( r * EF9364_NB_OF_COLUMNS ) + ( x>>3 ) ); - - if( m_charset->u8(((c&0x7F)<<3) + y ) & (0x80>>(x&7)) ) - m_screen_out.pix32((r*12)+y, x) = palette[1]; - else - m_screen_out.pix32((r*12)+y, x) = palette[0]; - } - else - { - if(y != 7) - m_screen_out.pix32((r*12)+y, x) = palette[0]; - else - m_screen_out.pix32((r*12)+y, x) = palette[1]; - } - } - } - } - - cursor_cnt = (cursor_cnt + 1) % 13; - if(!cursor_cnt) - cursor_state ^= 1; - - copybitmap(bitmap, m_screen_out, 0, 0, 0, 0, cliprect); - return 0; + int x,y,r; + unsigned char c; + + for( r = 0 ; r < EF9364_NB_OF_ROWS ; r++ ) + { + for( y = 0 ; y < 8 ; y++ ) + { + for( x = 0 ; x < EF9364_NB_OF_COLUMNS * 8 ; x++ ) + { + if( ( ( x >> 3 ) != x_curs_pos ) || ( r != y_curs_pos ) || !cursor_state) + { + c = m_textram->read_byte( ( r * EF9364_NB_OF_COLUMNS ) + ( x>>3 ) ); + + if( m_charset->u8(((c&0x7F)<<3) + y ) & (0x80>>(x&7)) ) + m_screen_out.pix32((r*12)+y, x) = palette[1]; + else + m_screen_out.pix32((r*12)+y, x) = palette[0]; + } + else + { + if(y != 7) + m_screen_out.pix32((r*12)+y, x) = palette[0]; + else + m_screen_out.pix32((r*12)+y, x) = palette[1]; + } + } + } + } + + cursor_cnt = (cursor_cnt + 1) % 13; + if(!cursor_cnt) + cursor_state ^= 1; + + copybitmap(bitmap, m_screen_out, 0, 0, 0, 0, cliprect); + return 0; } //------------------------------------------------- @@ -236,15 +236,15 @@ UINT32 ef9364_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, void ef9364_device::update_scanline(UINT16 scanline) { - if (scanline == vsync_scanline_pos) - { - // vsync - } - - if (scanline == 0) - { - draw_border(0); - } + if (scanline == vsync_scanline_pos) + { + // vsync + } + + if (scanline == 0) + { + draw_border(0); + } } //------------------------------------------------- @@ -253,107 +253,107 @@ void ef9364_device::update_scanline(UINT16 scanline) void ef9364_device::command_w(UINT8 cmd) { - int x,y,i,j; - - switch( cmd&7 ) - { - case 0x0: // Page Erase & Cursor home - for( y=0 ; y < EF9364_NB_OF_ROWS ; y++ ) - { - for( x=0 ; x < EF9364_NB_OF_COLUMNS ; x++ ) - { - m_textram->write_byte ( y * EF9364_NB_OF_COLUMNS + x , 0x7F ); - } - } - x_curs_pos = 0; - y_curs_pos = 0; - break; - - case 0x1: // Erase to end of the line and return cursor - for( ; x_curs_pos < EF9364_NB_OF_COLUMNS ; x_curs_pos++ ) - { - m_textram->write_byte ( y_curs_pos * EF9364_NB_OF_COLUMNS + x_curs_pos , 0x7F ); - } - x_curs_pos = 0; - break; - - case 0x2: // Line feed - y_curs_pos++; - if( y_curs_pos >= EF9364_NB_OF_ROWS ) - { - // Scroll - for( j = 1 ; j < EF9364_NB_OF_ROWS ; j++ ) - { - for( i = 0 ; i < EF9364_NB_OF_COLUMNS ; i++ ) - { - m_textram->write_byte ( (j-1) * EF9364_NB_OF_COLUMNS + i , m_textram->read_byte ( j * EF9364_NB_OF_COLUMNS + i ) ); - } - } - // Erase last line - for( i = 0 ; i < EF9364_NB_OF_COLUMNS ; i++ ) - { - m_textram->write_byte ( ( EF9364_NB_OF_ROWS - 1 ) * EF9364_NB_OF_COLUMNS + i , 0x7F ); - } - - y_curs_pos = EF9364_NB_OF_ROWS - 1; - } - break; - - case 0x3: // Nop - - break; - - case 0x4: // Cursor left - if(x_curs_pos) - x_curs_pos--; - break; - - case 0x5: // Erasure of cursor Line. - for( x = 0 ; x < EF9364_NB_OF_COLUMNS ; x++ ) - { - m_textram->write_byte ( y_curs_pos * EF9364_NB_OF_COLUMNS + x , 0x7F ); - } - break; - - case 0x6: // Cursor up - if(y_curs_pos) - y_curs_pos--; - break; - - case 0x7: // Write char - if(cmd&0x8) - m_textram->write_byte ( y_curs_pos * EF9364_NB_OF_COLUMNS + x_curs_pos , char_latch ); - - x_curs_pos++; - if( x_curs_pos >= EF9364_NB_OF_COLUMNS ) - { - x_curs_pos=0; - y_curs_pos++; - if( y_curs_pos >= EF9364_NB_OF_ROWS ) - { - // Scroll - for( j = 1 ; j < EF9364_NB_OF_ROWS ; j++ ) - { - for( i = 0 ; i < EF9364_NB_OF_COLUMNS ; i++ ) - { - m_textram->write_byte ( (j-1) * EF9364_NB_OF_COLUMNS + i , m_textram->read_byte ( j * EF9364_NB_OF_COLUMNS + i ) ); - } - } - // Erase last line - for( i = 0 ; i < EF9364_NB_OF_COLUMNS ; i++ ) - { - m_textram->write_byte ( ( EF9364_NB_OF_ROWS - 1 ) * EF9364_NB_OF_COLUMNS + i , 0x7F ); - } - - y_curs_pos = EF9364_NB_OF_ROWS - 1; - } - } - break; - - } + int x,y,i,j; + + switch( cmd&7 ) + { + case 0x0: // Page Erase & Cursor home + for( y=0 ; y < EF9364_NB_OF_ROWS ; y++ ) + { + for( x=0 ; x < EF9364_NB_OF_COLUMNS ; x++ ) + { + m_textram->write_byte ( y * EF9364_NB_OF_COLUMNS + x , 0x7F ); + } + } + x_curs_pos = 0; + y_curs_pos = 0; + break; + + case 0x1: // Erase to end of the line and return cursor + for( ; x_curs_pos < EF9364_NB_OF_COLUMNS ; x_curs_pos++ ) + { + m_textram->write_byte ( y_curs_pos * EF9364_NB_OF_COLUMNS + x_curs_pos , 0x7F ); + } + x_curs_pos = 0; + break; + + case 0x2: // Line feed + y_curs_pos++; + if( y_curs_pos >= EF9364_NB_OF_ROWS ) + { + // Scroll + for( j = 1 ; j < EF9364_NB_OF_ROWS ; j++ ) + { + for( i = 0 ; i < EF9364_NB_OF_COLUMNS ; i++ ) + { + m_textram->write_byte ( (j-1) * EF9364_NB_OF_COLUMNS + i , m_textram->read_byte ( j * EF9364_NB_OF_COLUMNS + i ) ); + } + } + // Erase last line + for( i = 0 ; i < EF9364_NB_OF_COLUMNS ; i++ ) + { + m_textram->write_byte ( ( EF9364_NB_OF_ROWS - 1 ) * EF9364_NB_OF_COLUMNS + i , 0x7F ); + } + + y_curs_pos = EF9364_NB_OF_ROWS - 1; + } + break; + + case 0x3: // Nop + + break; + + case 0x4: // Cursor left + if(x_curs_pos) + x_curs_pos--; + break; + + case 0x5: // Erasure of cursor Line. + for( x = 0 ; x < EF9364_NB_OF_COLUMNS ; x++ ) + { + m_textram->write_byte ( y_curs_pos * EF9364_NB_OF_COLUMNS + x , 0x7F ); + } + break; + + case 0x6: // Cursor up + if(y_curs_pos) + y_curs_pos--; + break; + + case 0x7: // Write char + if(cmd&0x8) + m_textram->write_byte ( y_curs_pos * EF9364_NB_OF_COLUMNS + x_curs_pos , char_latch ); + + x_curs_pos++; + if( x_curs_pos >= EF9364_NB_OF_COLUMNS ) + { + x_curs_pos=0; + y_curs_pos++; + if( y_curs_pos >= EF9364_NB_OF_ROWS ) + { + // Scroll + for( j = 1 ; j < EF9364_NB_OF_ROWS ; j++ ) + { + for( i = 0 ; i < EF9364_NB_OF_COLUMNS ; i++ ) + { + m_textram->write_byte ( (j-1) * EF9364_NB_OF_COLUMNS + i , m_textram->read_byte ( j * EF9364_NB_OF_COLUMNS + i ) ); + } + } + // Erase last line + for( i = 0 ; i < EF9364_NB_OF_COLUMNS ; i++ ) + { + m_textram->write_byte ( ( EF9364_NB_OF_ROWS - 1 ) * EF9364_NB_OF_COLUMNS + i , 0x7F ); + } + + y_curs_pos = EF9364_NB_OF_ROWS - 1; + } + } + break; + + } } void ef9364_device::char_latch_w(UINT8 data) { - char_latch = data; + char_latch = data; } diff --git a/src/devices/video/ef9364.h b/src/devices/video/ef9364.h index 1519d817196..4c5f57bb211 100644 --- a/src/devices/video/ef9364.h +++ b/src/devices/video/ef9364.h @@ -20,13 +20,13 @@ #define EF9364_MAX_TXTPLANES 2 #define MCFG_EF9364_PALETTE(_palette_tag) \ - ef9364_device::static_set_palette_tag(*device, "^" _palette_tag); + ef9364_device::static_set_palette_tag(*device, "^" _palette_tag); #define MCFG_EF9364_PAGES_CNT(_pages_number) \ - ef9364_device::static_set_nb_of_pages(*device,_pages_number); + ef9364_device::static_set_nb_of_pages(*device,_pages_number); #define MCFG_EF9364_IRQ_HANDLER(_devcb) \ - devcb = &ef9364_device::set_irq_handler(*device, DEVCB_##_devcb); + devcb = &ef9364_device::set_irq_handler(*device, DEVCB_##_devcb); //************************************************************************** // TYPE DEFINITIONS @@ -35,67 +35,67 @@ // ======================> ef9364_device class ef9364_device : public device_t, - public device_memory_interface, - public device_video_interface + public device_memory_interface, + public device_video_interface { public: - // construction/destruction - ef9364_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + // construction/destruction + ef9364_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - // static configuration - static void static_set_palette_tag(device_t &device, const char *tag); - static void static_set_nb_of_pages(device_t &device, int nb_bitplanes ); + // static configuration + static void static_set_palette_tag(device_t &device, const char *tag); + static void static_set_nb_of_pages(device_t &device, int nb_bitplanes ); - // device interface + // device interface - void update_scanline(UINT16 scanline); - void set_color_entry( int index, UINT8 r, UINT8 g, UINT8 b ); + void update_scanline(UINT16 scanline); + void set_color_entry( int index, UINT8 r, UINT8 g, UINT8 b ); - UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - void char_latch_w(UINT8 data); - void command_w(UINT8 cmd); + UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + void char_latch_w(UINT8 data); + void command_w(UINT8 cmd); protected: - // device-level overrides - virtual void device_start() override; - virtual void device_reset() override; + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; - // device_config_memory_interface overrides - virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const override; + // device_config_memory_interface overrides + virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const override; - // address space configurations - const address_space_config m_space_config; + // address space configurations + const address_space_config m_space_config; - // inline helper + // inline helper private: - void screen_scanning( int force_clear ); - void set_video_mode(void); - void draw_border(UINT16 line); + void screen_scanning( int force_clear ); + void set_video_mode(void); + void draw_border(UINT16 line); - // internal state + // internal state - memory_region *m_charset; - address_space *m_textram; + memory_region *m_charset; + address_space *m_textram; - UINT8 x_curs_pos; - UINT8 y_curs_pos; - UINT8 char_latch; + UINT8 x_curs_pos; + UINT8 y_curs_pos; + UINT8 char_latch; - UINT8 m_border[80]; //border color + UINT8 m_border[80]; //border color - rgb_t palette[2]; - int nb_of_pages; - int bitplane_xres; - int bitplane_yres; - int vsync_scanline_pos; - int cursor_cnt; - int cursor_state; + rgb_t palette[2]; + int nb_of_pages; + int bitplane_xres; + int bitplane_yres; + int vsync_scanline_pos; + int cursor_cnt; + int cursor_state; - UINT32 clock_freq; - bitmap_rgb32 m_screen_out; + UINT32 clock_freq; + bitmap_rgb32 m_screen_out; - required_device<palette_device> m_palette; + required_device<palette_device> m_palette; }; // device type definition diff --git a/src/devices/video/jangou_blitter.cpp b/src/devices/video/jangou_blitter.cpp index e2acdb37ca1..032ed96a4ed 100644 --- a/src/devices/video/jangou_blitter.cpp +++ b/src/devices/video/jangou_blitter.cpp @@ -2,15 +2,15 @@ // copyright-holders:Angelo Salese /*************************************************************************** - Jangou Custom Blitter Chip, codename "???" (name scratched afaik) + Jangou Custom Blitter Chip, codename "???" (name scratched afaik) - device emulation by Angelo Salese, from original jangou.cpp implementation - by Angelo Salese, David Haywood and Phil Bennett. + device emulation by Angelo Salese, from original jangou.cpp implementation + by Angelo Salese, David Haywood and Phil Bennett. + + TODO: + - BLTFLIP mechanism; + - clean-ups; - TODO: - - BLTFLIP mechanism; - - clean-ups; - ***************************************************************************/ #include "emu.h" @@ -51,7 +51,7 @@ void jangou_blitter_device::device_start() if (m_gfxrom == nullptr) fatalerror("JANGOU_BLITTER: \"gfx\" memory base not found"); m_gfxrommask = devregion->bytes()-1; - + save_item(NAME(m_pen_data)); save_item(NAME(m_blit_data)); save_item(NAME(m_blit_buffer)); @@ -84,12 +84,12 @@ UINT8 jangou_blitter_device::gfx_nibble( UINT32 niboffset ) } void jangou_blitter_device::plot_gfx_pixel( UINT8 pix, int x, int y ) -{ +{ if (y < 0 || y >= 256) return; if (x < 0 || x >= 256) return; - + if (x & 1) m_blit_buffer[(y * 256) + (x >> 1)] = (m_blit_buffer[(y * 256) + (x >> 1)] & 0x0f) | ((pix << 4) & 0xf0); else @@ -112,11 +112,11 @@ WRITE8_MEMBER( jangou_blitter_device::process_w ) src |= (m_blit_data[6] & 3) << 16; x = (m_blit_data[2] & 0xff); y = (m_blit_data[3] & 0xff); - + #if 0 if(m_bltflip == true) { - printf("%02x %02x %02x %02x %02x %02x %02x\n", m_blit_data[0], m_blit_data[1], m_blit_data[2],m_blit_data[3], m_blit_data[4], m_blit_data[5],m_blit_data[6]); + printf("%02x %02x %02x %02x %02x %02x %02x\n", m_blit_data[0], m_blit_data[1], m_blit_data[2],m_blit_data[3], m_blit_data[4], m_blit_data[5],m_blit_data[6]); printf("=>"); for(int i=0;i<0x10;i++) printf("%02x ",m_pen_data[i]); @@ -131,7 +131,7 @@ WRITE8_MEMBER( jangou_blitter_device::process_w ) else src -= (w * h) - 1; - + for (ycount = 0; ycount < h; ycount++) { for(xcount = 0; xcount < w; xcount++) @@ -152,9 +152,9 @@ WRITE8_MEMBER( jangou_blitter_device::process_w ) count++; } } - + //UINT32 new_src = src + count; - + // update source and height after blitter operation // TODO: Jangou doesn't agree with this, later HW? #if 0 diff --git a/src/devices/video/jangou_blitter.h b/src/devices/video/jangou_blitter.h index 7a39172e7ca..d5d6e92a55f 100644 --- a/src/devices/video/jangou_blitter.h +++ b/src/devices/video/jangou_blitter.h @@ -43,9 +43,9 @@ public: protected: // device-level overrides - virtual void device_start() override; + virtual void device_start() override; virtual void device_reset() override; - + private: void plot_gfx_pixel( UINT8 pix, int x, int y ); UINT8 gfx_nibble( UINT32 niboffset ); diff --git a/src/devices/video/upd7220.cpp b/src/devices/video/upd7220.cpp index 32d4d2c3c63..070c9e4fbec 100644 --- a/src/devices/video/upd7220.cpp +++ b/src/devices/video/upd7220.cpp @@ -94,7 +94,7 @@ enum #define UPD7220_COMMAND_CCHAR 0x4b #define UPD7220_COMMAND_START 0x6b #define UPD7220_COMMAND_BCTRL 0x0c // & 0xfe -#define UPD7220_COMMAND_05 0x05 +#define UPD7220_COMMAND_05 0x05 #define UPD7220_COMMAND_ZOOM 0x46 #define UPD7220_COMMAND_CURS 0x49 #define UPD7220_COMMAND_PRAM 0x70 // & 0xf0 diff --git a/src/devices/video/voodoo.cpp b/src/devices/video/voodoo.cpp index 7fe0b94a007..025c0fa140f 100644 --- a/src/devices/video/voodoo.cpp +++ b/src/devices/video/voodoo.cpp @@ -960,7 +960,7 @@ TIMER_CALLBACK_MEMBER( voodoo_device::vblank_callback ) /* set a timer for the next off state */ machine().scheduler().timer_set(screen->time_until_pos(0), timer_expired_delegate(FUNC(voodoo_device::vblank_off_callback),this), 0, this); - + /* set internal state and call the client */ fbi.vblank = TRUE; @@ -2877,7 +2877,7 @@ default_case: * *************************************/ INT32 voodoo_device::lfb_direct_w(voodoo_device *vd, offs_t offset, UINT32 data, UINT32 mem_mask) -{ +{ UINT16 *dest; UINT32 destmax; int x, y; @@ -2923,7 +2923,6 @@ INT32 voodoo_device::lfb_direct_w(voodoo_device *vd, offs_t offset, UINT32 data, INT32 voodoo_device::lfb_w(voodoo_device* vd, offs_t offset, UINT32 data, UINT32 mem_mask) { - UINT16 *dest, *depth; UINT32 destmax, depthmax; int sr[2], sg[2], sb[2], sa[2], sw[2]; @@ -3783,7 +3782,6 @@ WRITE32_MEMBER( voodoo_device::voodoo_w ) static UINT32 register_r(voodoo_device *vd, offs_t offset) { - int regnum = offset & 0xff; UINT32 result; @@ -4053,7 +4051,6 @@ static UINT32 lfb_r(voodoo_device *vd, offs_t offset, bool lfb_3d) READ32_MEMBER( voodoo_device::voodoo_r ) { - /* if we have something pending, flush the FIFOs up to the current time */ if (pci.op_pending) flush_fifos(this, machine().time()); @@ -4699,7 +4696,6 @@ WRITE32_MEMBER( voodoo_banshee_device::banshee_agp_w ) WRITE32_MEMBER( voodoo_banshee_device::banshee_w ) { - /* if we have something pending, flush the FIFOs up to the current time */ if (pci.op_pending) flush_fifos(this, machine().time()); @@ -5045,7 +5041,7 @@ void voodoo_device::common_start_voodoo(UINT8 type) pci.fifo.in = pci.fifo.out = 0; pci.stall_state = NOT_STALLED; pci.continue_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(voodoo_device::stall_cpu_callback),this), nullptr); - + /* allocate memory */ tmumem0 = m_tmumem0; tmumem1 = m_tmumem1; diff --git a/src/devices/video/voodoo.h b/src/devices/video/voodoo.h index 1dc1a4a59ec..81951a17087 100644 --- a/src/devices/video/voodoo.h +++ b/src/devices/video/voodoo.h @@ -1777,7 +1777,7 @@ public: const char * m_cputag; devcb_write_line m_vblank; devcb_write_line m_stall; - + TIMER_CALLBACK_MEMBER( vblank_off_callback ); TIMER_CALLBACK_MEMBER( stall_cpu_callback ); TIMER_CALLBACK_MEMBER( vblank_callback ); @@ -1826,11 +1826,9 @@ public: static void raster_generic_2tmu(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid); #define RASTERIZER_HEADER(name) \ - static void raster_##name(void *destbase, INT32 y, const poly_extent *extent, const void *extradata, int threadid); \ - + static void raster_##name(void *destbase, INT32 y, const poly_extent *extent, const void *extradata, int threadid); #define RASTERIZER_ENTRY(fbzcp, alpha, fog, fbz, tex0, tex1) \ - RASTERIZER_HEADER(fbzcp##_##alpha##_##fog##_##fbz##_##tex0##_##tex1) \ - + RASTERIZER_HEADER(fbzcp##_##alpha##_##fog##_##fbz##_##tex0##_##tex1) #include "voodoo_rast.inc" #undef RASTERIZER_ENTRY |