hp_taco: added support for writing hp9825-format tapes (#8860)

This commit is contained in:
fulivi 2021-11-22 14:00:36 +01:00 committed by GitHub
parent 8417bda8e2
commit 73b6d39404
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 28 deletions

View File

@ -28,8 +28,8 @@
// according to flow charts in [1]
// - Handling of error conditions, R/W bits, tachometer ticks and gaps according to [1]
// What's not in:
// - Commands that are not used at all by the software I analyzed, especially those that
// write tapes in HP9825 format. They could be added easily, though.
// - Commands that are not used at all by the software I analyzed. They could be added easily,
// though.
// - Accurate execution times of commands
// - Handling of FLG signal: the emulated chip always reports itself as ready for writing.
// - Read threshold is ignored. Real tapes could be read with either a low or high threshold.
@ -243,7 +243,7 @@ enum cmd_t : uint8_t {
CMD_ERASE = 0b000100, // Erase tape
CMD_WR_REVERSAL = 0b000101, // Write flux reversal (*)
CMD_WR = 0b000110, // Write
CMD_WR_9825 = 0b000111, // Write 9825 (*)
CMD_WR_9825 = 0b000111, // Write 9825
CMD_STOP = 0b001000, // Stop
CMD_STOP_INT = 0b001001, // Stop & interrupt
CMD_SET_TRACK = 0b001100, // Set track
@ -262,10 +262,10 @@ enum cmd_t : uint8_t {
CMD_WR_GAP_N_TACH = 0b101100, // Write gap of N tach
CMD_INT_N_GAP = 0b110000, // Interrupt on N gap
CMD_WR_SYNC = 0b110010, // Write synchronous
CMD_WR_SYNC_9825 = 0b110011, // Write synchronous 9825 (*)
CMD_WR_SYNC_9825 = 0b110011, // Write synchronous 9825
CMD_INT_N_TACH_22 = 0b110100, // Interrupt on N tach after 22 ips
CMD_WR_CSUM = 0b110110, // Write checksum
CMD_WR_CSUM_9825 = 0b110111, // Write checksum 9825 (*)
CMD_WR_CSUM_9825 = 0b110111, // Write checksum 9825
CMD_INT_STOP_N_TACH = 0b111000, // Interrupt and stop on N tach
CMD_INT_STOP_N_TACH1= 0b111001, // Interrupt and stop on N tach (int when stopped)
CMD_RD_6UPD = 0b111010, // Read 6% update
@ -479,35 +479,34 @@ WRITE_LINE_MEMBER(hp_taco_device::rd_bit_w)
// Synchronized
LOG_RW("RD synced!\n");
m_cmd_state = CMD_PH2;
m_bit_idx = BIT(m_cmd_reg , CMD_ST_G0) ? 16 : 15;
m_bit_idx = BIT(m_cmd_reg , CMD_ST_G0) ? 17 : 15;
m_working_reg = 0;
}
} else if (m_cmd_state == CMD_PH2) {
if (m_bit_idx == 16) {
if (m_bit_idx == 17) {
// 9825 format: skip first 17th bit after preamble
m_bit_idx = 15;
break;
} else if (m_bit_idx != 16 && state) {
// Skip 17th bit when reading in 9825 format
m_bit_idx--;
} else {
if (state) {
BIT_SET(m_working_reg , m_bit_idx);
}
if (m_bit_idx) {
m_bit_idx--;
} else {
m_data_reg = m_working_reg;
m_bit_idx = BIT(m_cmd_reg , CMD_ST_G0) ? 16 : 15;
m_working_reg = 0;
if (!BIT(m_cmd_reg , CMD_ST_G2)) {
update_checksum(m_data_reg);
}
LOG_RW("RD word %04x csum=%04x\n" , m_data_reg , m_checksum_reg);
irq_w(true);
BIT_SET(m_working_reg , m_bit_idx);
}
if (adv_bit_idx()) {
m_data_reg = m_working_reg;
m_working_reg = 0;
if (!BIT(m_cmd_reg , CMD_ST_G2)) {
update_checksum(m_data_reg);
}
LOG_RW("RD word %04x csum=%04x\n" , m_data_reg , m_checksum_reg);
irq_w(true);
}
}
break;
case CMD_WR_SYNC:
case CMD_WR_SYNC_9825:
case CMD_WR_CSUM:
case CMD_WR_CSUM_9825:
if (m_cmd_state == CMD_PH1) {
LOG_RW("WR synced\n");
m_cmd_state = CMD_PH2;
@ -526,13 +525,16 @@ READ_LINE_MEMBER(hp_taco_device::wr_bit_r)
{
bool bit = false;
if (is_cmd_wr(m_cmd_reg) && m_cmd_state == CMD_PH2) {
bit = BIT(m_working_reg , m_bit_idx);
if (m_bit_idx) {
m_bit_idx--;
if (m_bit_idx == 16) {
// HP9825 format: 17th bit
bit = true;
} else {
m_bit_idx = 15;
bit = BIT(m_working_reg , m_bit_idx);
}
if (adv_bit_idx()) {
m_working_reg = m_data_reg;
if (get_cmd(m_cmd_reg) != CMD_WR_CSUM) {
// Bit 0 selects HP9825 mode: it is to be ignored here
if ((get_cmd(m_cmd_reg) & ~BIT_MASK<uint8_t>(0)) != CMD_WR_CSUM) {
update_checksum(m_data_reg);
}
LOG_RW("WR word %04x csum=%04x\n" , m_working_reg , m_checksum_reg);
@ -810,6 +812,16 @@ void hp_taco_device::start_wr()
m_evd_timer->reset();
}
bool hp_taco_device::adv_bit_idx()
{
if (m_bit_idx) {
m_bit_idx--;
} else {
m_bit_idx = BIT(m_cmd_reg , CMD_ST_G0) ? 16 : 15;
}
return m_bit_idx == 15;
}
void hp_taco_device::update_checksum(uint16_t data)
{
// Update checksum with data
@ -846,6 +858,7 @@ void hp_taco_device::cmd_fsm()
break;
case CMD_WR:
case CMD_WR_9825:
if (m_cmd_state == CMD_PH0 && is_at_slow_speed()) {
m_cmd_state = CMD_PH2;
m_bit_idx = 15;
@ -887,7 +900,9 @@ void hp_taco_device::cmd_fsm()
break;
case CMD_WR_SYNC:
case CMD_WR_SYNC_9825:
case CMD_WR_CSUM:
case CMD_WR_CSUM_9825:
if (m_cmd_state == CMD_PH0 && is_at_slow_speed()) {
m_cmd_state = CMD_PH1;
start_rd();
@ -1003,8 +1018,11 @@ void hp_taco_device::start_cmd_exec(uint16_t new_cmd_reg)
break;
case CMD_WR:
case CMD_WR_9825:
case CMD_WR_SYNC:
case CMD_WR_SYNC_9825:
case CMD_WR_CSUM:
case CMD_WR_CSUM_9825:
// 1. Wait for tape to reach 22 ips
// 2. Wait for data to begin (not for CMD_WR)
// 3. Write words on tape

View File

@ -110,6 +110,7 @@ private:
bool is_at_slow_speed() const;
void start_rd();
void start_wr();
bool adv_bit_idx();
void update_checksum(uint16_t data);
void cmd_fsm();
static uint8_t get_cmd(uint16_t cmd_reg);