summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices
diff options
context:
space:
mode:
author fulivi <fulivi@users.noreply.github.com>2021-11-22 14:00:36 +0100
committer GitHub <noreply@github.com>2021-11-22 08:00:36 -0500
commit73b6d39404afefa0ec26c9c0f701cfdb20bd977d (patch)
tree161faee5fbabd7bcec2f21171a53428707f0a037 /src/devices
parent8417bda8e25c409835d4fbcc4ea8b57a59375f7d (diff)
hp_taco: added support for writing hp9825-format tapes (#8860)
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/machine/hp_taco.cpp74
-rw-r--r--src/devices/machine/hp_taco.h1
2 files changed, 47 insertions, 28 deletions
diff --git a/src/devices/machine/hp_taco.cpp b/src/devices/machine/hp_taco.cpp
index 5be1a1ebc9a..fc95c72e454 100644
--- a/src/devices/machine/hp_taco.cpp
+++ b/src/devices/machine/hp_taco.cpp
@@ -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
diff --git a/src/devices/machine/hp_taco.h b/src/devices/machine/hp_taco.h
index 243b79e98ba..88ab82f2579 100644
--- a/src/devices/machine/hp_taco.h
+++ b/src/devices/machine/hp_taco.h
@@ -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);