hp9845: Changed cmd 1c on TACO

This commit is contained in:
fulivi 2016-03-17 16:49:51 +01:00
parent 241b732ea7
commit 0b8eec6c45

View File

@ -16,7 +16,7 @@
// So, my main source of information was the careful study of HP software, especially the 9845 system test ROM (09845-66520).
// The second half of this ROM holds a comprehensive set of tape drive tests.
// The main shortcomings of my approach are:
// * I could indentify only those TACO commands that are actually used by the software. I managed
// * I could identify only those TACO commands that are actually used by the software. I managed
// to identify 17 out of 32 possible commands. The purpose of the rest of commands is anyone's guess.
// * I could only guess the behavior of TACO chips in corner cases (especially behavior in various error/abnormal
// conditions)
@ -51,7 +51,7 @@
// 9 RW ? Drive ON according to [1], the actual use seems to be selection of gap length
// 8 RW ? Size of gaps according to [1], N/U in my opinion
// 7 RW Speed of tape (1 = 90 ips, 0 = 22 ips)
// 6 RW Option bit for various commands
// 6 RW Option bit for various commands. Most of them use it to select read threshold (0 = low, 1 = high).
// 5 R Current track (1 = B)
// 4 R Gap detected (1)
// 3 R Write protection (1)
@ -128,7 +128,6 @@
// * Some code cleanup
// * Handling of tape holes seems to be wrong: test "C" of test ROM only works partially
// * Find out what is read from register R6
// * Handle device_image_interface::call_display to show state of tape
// * Find more info on TACO chips (does anyone with a working 9845 or access to internal HP docs want to
// help me here, please?)
//
@ -172,7 +171,8 @@ enum {
#define SLOW_BRAKE_DIST 197883 // Braking distance at slow speed (~0.2 in)
#define PREAMBLE_WORD 0 // Value of preamble word
#define END_GAP_LENGTH (6 * ONE_INCH_POS) // Length of final gap: 6"
#define MIN_IRG_LENGTH ((tape_pos_t)(0.2 * ONE_INCH_POS)) // Minimum length of IRGs: 0.2" (from 9825, not sure about value in TACO)
#define SHORT_GAP_LENGTH ((tape_pos_t)(0.066 * ONE_INCH_POS)) // Minimum length of short gaps: 0.066" ([1], pg 8-10)
#define LONG_GAP_LENGTH ((tape_pos_t)(1.5 * ONE_INCH_POS)) // Minimum length long gaps: 1.5" ([1], pg 8-10)
#define NULL_TAPE_POS ((tape_pos_t)-1) // Special value for invalid/unknown tape position
#define NO_DATA_GAP (17 * ONE_BIT_LEN) // Minimum gap size to detect end of data: length of longest word (0xffff)
#define FILE_MAGIC 0x4f434154 // Magic value at start of image file: "TACO"
@ -193,38 +193,38 @@ enum {
// 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_MOVE_INGAP, // 1c: move tape a given distance then scan for gap (as cmd 0c but in reverse order)
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
@ -444,7 +444,7 @@ void hp_taco_device::device_timer(emu_timer &timer, device_timer_id id, int para
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)) {
if (next_n_gap(target, 1, SHORT_GAP_LENGTH)) {
m_tape_timer->adjust(time_to_target(target));
}
return;
@ -500,7 +500,7 @@ void hp_taco_device::device_timer(emu_timer &timer, device_timer_id id, int para
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)) {
if (next_n_gap(target, 0x10000U - m_tach_reg, SHORT_GAP_LENGTH)) {
LOG_0(("%u gaps @%d\n" , 0x10000U - m_tach_reg, target));
m_tape_timer->adjust(time_to_target(target));
}
@ -522,7 +522,19 @@ void hp_taco_device::device_timer(emu_timer &timer, device_timer_id id, int para
// m_cmd_state == 1 -> IRQ & cmd end
break;
case CMD_DELTA_MOVE_HOLE:
case CMD_MOVE_INGAP:
if (m_cmd_state == 0) {
m_cmd_state = 1;
tape_pos_t target = m_tape_pos;
if (next_n_gap(target, 1, SHORT_GAP_LENGTH)) {
LOG_0(("GAP @%d\n" , target));
m_tape_timer->adjust(time_to_target(target));
}
// No IRQ
return;
}
break;
case CMD_DELTA_MOVE_IRG:
// Interrupt at end of movement
m_hole_timer->reset();
@ -596,13 +608,13 @@ void hp_taco_device::device_timer(emu_timer &timer, device_timer_id id, int para
break;
case CMD_SCAN_RECORDS:
case CMD_DELTA_MOVE_HOLE:
// Cmds 18 & 1c are terminated at first hole
// Cmds 18 is terminated at first hole
m_tape_timer->reset();
irq_w(true);
// No reloading of hole timer
return;
case CMD_MOVE_INGAP:
case CMD_DELTA_MOVE_IRG:
// TODO: update r6
m_hole_timer->adjust(time_to_next_hole());
@ -735,9 +747,9 @@ void hp_taco_device::update_tape_pos(void)
}
// 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) {
if (m_gap_detect_start != NULL_TAPE_POS && abs(m_gap_detect_start - m_tape_pos) >= SHORT_GAP_LENGTH) {
tape_pos_t tmp = m_tape_pos;
pos_offset(tmp , -MIN_IRG_LENGTH);
pos_offset(tmp , -SHORT_GAP_LENGTH);
gap_detected = just_gap(tmp , m_tape_pos);
}
if (gap_detected) {
@ -1336,7 +1348,7 @@ void hp_taco_device::start_cmd_exec(UINT16 new_cmd_reg)
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)) {
if (next_n_gap(target, 1, SHORT_GAP_LENGTH)) {
LOG_0(("IRG @%d\n" , target));
cmd_duration = time_to_target(target);
}
@ -1391,9 +1403,11 @@ void hp_taco_device::start_cmd_exec(UINT16 new_cmd_reg)
}
break;
case CMD_DELTA_MOVE_HOLE:
case CMD_MOVE_INGAP:
// Apparently cmd 1c uses b9 for some unknown purpose (to set the gap length?)
case CMD_DELTA_MOVE_IRG:
if (start_tape_cmd(new_cmd_reg , 0 , 0)) {
m_cmd_state = 0;
cmd_duration = time_to_tach_pulses();
time_to_hole = time_to_next_hole();
}