summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
author fulivi <fulivi@users.noreply.github.com>2021-01-12 13:29:30 +0100
committer GitHub <noreply@github.com>2021-01-12 23:29:30 +1100
commitfad7c9e0beb50f6c96da9ea8f93082bc349a25c2 (patch)
tree172a75715375b6627303798660004fd80dd2a75d /src/lib
parentba587a777c41837c8aa9f2a2e8c1fc27b4616623 (diff)
hp2640.cpp: Added tape emulation. (#7625)
* formats/hti_tape.cpp: Added support for Manchester encoded DC100 cassettes. * machine/hp2640_tape.cpp: added emulation of DC100 tape drives. * machine/hp_dc100_tape.cpp: Added unit name display.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/formats/hti_tape.cpp34
-rw-r--r--src/lib/formats/hti_tape.h50
2 files changed, 55 insertions, 29 deletions
diff --git a/src/lib/formats/hti_tape.cpp b/src/lib/formats/hti_tape.cpp
index 29bab6cd51c..7f77e3f99df 100644
--- a/src/lib/formats/hti_tape.cpp
+++ b/src/lib/formats/hti_tape.cpp
@@ -12,7 +12,8 @@
static constexpr uint32_t OLD_FILE_MAGIC = 0x5441434f; // Magic value at start of old-format image file: "TACO"
-static constexpr uint32_t FILE_MAGIC = 0x48544930; // Magic value at start of image file: "HTI0"
+static constexpr uint32_t FILE_MAGIC_DELTA = 0x48544930; // Magic value at start of delta-modulation image file: "HTI0"
+static constexpr uint32_t FILE_MAGIC_MANCHESTER = 0x48544931; // Magic value at start of manchester-modulation image file: "HTI1"
// *** Position of tape holes ***
// At beginning of tape:
@@ -41,7 +42,7 @@ static const hti_format_t::tape_pos_t tape_holes[] = {
};
hti_format_t::hti_format_t()
- : m_bits_per_word(16)
+ : m_img_format(HTI_DELTA_MOD_16_BITS)
{
clear_tape();
}
@@ -52,13 +53,15 @@ bool hti_format_t::load_tape(io_generic *io)
io_generic_read(io, tmp, 0, 4);
auto magic = pick_integer_be(tmp , 0 , 4);
- if (magic != FILE_MAGIC && magic != OLD_FILE_MAGIC) {
+ if (((m_img_format == HTI_DELTA_MOD_16_BITS || m_img_format == HTI_DELTA_MOD_17_BITS) && magic != FILE_MAGIC_DELTA && magic != OLD_FILE_MAGIC) ||
+ (m_img_format == HTI_MANCHESTER_MOD && magic != FILE_MAGIC_MANCHESTER)) {
return false;
}
uint64_t offset = 4;
- for (tape_track_t& track : m_tracks) {
+ for (unsigned i = 0; i < no_of_tracks(); i++) {
+ tape_track_t& track = m_tracks[ i ];
if (!load_track(io , offset , track , magic == OLD_FILE_MAGIC)) {
clear_tape();
return false;
@@ -72,12 +75,13 @@ void hti_format_t::save_tape(io_generic *io)
{
uint8_t tmp[ 4 ];
- place_integer_be(tmp, 0, 4, FILE_MAGIC);
+ place_integer_be(tmp, 0, 4, m_img_format == HTI_MANCHESTER_MOD ? FILE_MAGIC_MANCHESTER : FILE_MAGIC_DELTA);
io_generic_write(io, tmp, 0, 4);
uint64_t offset = 4;
- for (const tape_track_t& track : m_tracks) {
+ for (unsigned i = 0; i < no_of_tracks(); i++) {
+ const tape_track_t& track = m_tracks[ i ];
tape_pos_t next_pos = (tape_pos_t)-1;
unsigned n_words = 0;
tape_track_t::const_iterator it_start;
@@ -105,7 +109,7 @@ void hti_format_t::clear_tape()
}
}
-hti_format_t::tape_pos_t hti_format_t::word_length(tape_word_t w)
+hti_format_t::tape_pos_t hti_format_t::word_length(tape_word_t w) const
{
unsigned zeros , ones;
@@ -117,10 +121,10 @@ hti_format_t::tape_pos_t hti_format_t::word_length(tape_word_t w)
zeros = 16 - ones;
- return zeros * ZERO_BIT_LEN + ones * ONE_BIT_LEN;
+ return zeros * bit_length(false) + ones * bit_length(true);
}
-hti_format_t::tape_pos_t hti_format_t::farthest_end(const track_iterator_t& it , bool forward)
+hti_format_t::tape_pos_t hti_format_t::farthest_end(const track_iterator_t& it , bool forward) const
{
if (forward) {
return word_end_pos(it);
@@ -190,7 +194,7 @@ void hti_format_t::write_word(unsigned track_no , tape_pos_t start , tape_word_t
// as the record expands & contracts when re-written with different content.
// Without this fix, a gap could form in the slack big enough to cause
// false gap detections.
- if (forward && it_high != track.end() && (it_high->first - end_pos) >= (ZERO_BIT_LEN * 16)) {
+ if (forward && it_high != track.end() && (it_high->first - end_pos) >= (bit_length(false) * 16)) {
track.insert(it_high, std::make_pair(end_pos, 0));
it_high--;
}
@@ -414,7 +418,7 @@ bool hti_format_t::load_track(io_generic *io , uint64_t& offset , tape_track_t&
if (!old_format) {
track.insert(std::make_pair(pos , tmp16));
pos += word_length(tmp16);
- } else if (m_bits_per_word == 16) {
+ } else if (m_img_format == HTI_DELTA_MOD_16_BITS) {
// Convert HP9845 & HP85 old format
// Basically, in old format each word had 17 bits (an implicit 1
// was added at the end). In new format we just keep the 16 bits
@@ -429,7 +433,7 @@ bool hti_format_t::load_track(io_generic *io , uint64_t& offset , tape_track_t&
track.insert(std::make_pair(pos, tmp16));
pos += word_length(tmp16);
last_word_end = pos;
- delta_pos -= ONE_BIT_LEN;
+ delta_pos -= DELTA_ONE_BIT_LEN;
} else {
// Convert HP9825 old format
// In moving from old to new format we make the 17th bit at the
@@ -458,7 +462,7 @@ bool hti_format_t::load_track(io_generic *io , uint64_t& offset , tape_track_t&
}
if (bits_in_accum) {
track.insert(std::make_pair(pos, word_accum));
- tape_pos_t shift = (tape_pos_t)(16 - bits_in_accum) * ZERO_BIT_LEN;
+ tape_pos_t shift = (tape_pos_t)(16 - bits_in_accum) * DELTA_ZERO_BIT_LEN;
delta_pos += shift;
last_word_end = pos + word_length(word_accum);
}
@@ -483,12 +487,12 @@ void hti_format_t::dump_sequence(io_generic *io , uint64_t& offset , tape_track_
}
}
-hti_format_t::tape_pos_t hti_format_t::word_end_pos(const track_iterator_t& it)
+hti_format_t::tape_pos_t hti_format_t::word_end_pos(const track_iterator_t& it) const
{
return it->first + word_length(it->second);
}
-void hti_format_t::adjust_it(tape_track_t& track , track_iterator_t& it , tape_pos_t pos)
+void hti_format_t::adjust_it(tape_track_t& track , track_iterator_t& it , tape_pos_t pos) const
{
if (it != track.begin()) {
--it;
diff --git a/src/lib/formats/hti_tape.h b/src/lib/formats/hti_tape.h
index 72eb85d55cc..7725b87fa2a 100644
--- a/src/lib/formats/hti_tape.h
+++ b/src/lib/formats/hti_tape.h
@@ -4,8 +4,8 @@
"HTI" format
- Format of images of DC-100 tape cassettes as used in HP 9825,
- HP 9845 and HP 85 systems.
+ Format of images of DC-100 tape cassettes as used in HP 264x,
+ HP 9825, HP 9845 and HP 85 systems.
*********************************************************************/
#ifndef MAME_FORMATS_HTI_TAPE_H
@@ -34,11 +34,15 @@ public:
// Tape length: 140 ft of usable tape + 72" of punched tape at either end
static constexpr tape_pos_t TAPE_LENGTH = (140 * 12 + 72 * 2) * ONE_INCH_POS;
+ // Length of bits in delta modulation
// Length of 0 bits at slow tape speed: 1/(35200 Hz)
- static constexpr tape_pos_t ZERO_BIT_LEN = 619;
-
+ static constexpr tape_pos_t DELTA_ZERO_BIT_LEN = 619;
// Length of 1 bits at slow tape speed: 1.75 times ZERO_BIT_LEN
- static constexpr tape_pos_t ONE_BIT_LEN = 1083;
+ static constexpr tape_pos_t DELTA_ONE_BIT_LEN = 1083;
+ // Length of bits in Manchester modulation
+ // By "bits" here we mean each of the halves of data bit cells
+ // Zeros & ones have same length
+ static constexpr tape_pos_t MANCHESTER_BIT_LEN = 621;
// Words stored on tape
typedef uint16_t tape_word_t;
@@ -49,20 +53,38 @@ public:
// Iterator to access words on tape
typedef tape_track_t::iterator track_iterator_t;
- // Set no. of bits per word (needed when loading old format)
- void set_bits_per_word(unsigned bits) { m_bits_per_word = bits; }
+ // Set image format
+ enum image_format_t {
+ // Delta modulation, 16 bits per word, 2 tracks per cartridge
+ // HP 9845 & HP 85
+ HTI_DELTA_MOD_16_BITS,
+ // Delta modulation, 17 bits per word, 2 tracks per cartridge
+ // HP 9825
+ HTI_DELTA_MOD_17_BITS,
+ // Manchester modulation, 1 track per cartridge
+ // HP 264x
+ HTI_MANCHESTER_MOD
+ };
+
+ void set_image_format(image_format_t fmt) { m_img_format = fmt; }
+
+ // Return number of tracks
+ unsigned no_of_tracks() const { return m_img_format == HTI_MANCHESTER_MOD ? 1 : 2; }
bool load_tape(io_generic *io);
void save_tape(io_generic *io);
void clear_tape();
// Return physical length of a bit on tape
- static constexpr tape_pos_t bit_length(bool bit) { return bit ? ONE_BIT_LEN : ZERO_BIT_LEN; }
+ tape_pos_t bit_length(bool bit) const
+ {
+ return m_img_format == HTI_MANCHESTER_MOD ? MANCHESTER_BIT_LEN : (bit ? DELTA_ONE_BIT_LEN : DELTA_ZERO_BIT_LEN);
+ }
// Return physical length of a 16-bit word on tape
- static tape_pos_t word_length(tape_word_t w);
+ tape_pos_t word_length(tape_word_t w) const;
- static tape_pos_t farthest_end(const track_iterator_t& it , bool forward);
+ tape_pos_t farthest_end(const track_iterator_t& it , bool forward) const;
static bool pos_offset(tape_pos_t& pos , bool forward , tape_pos_t offset);
@@ -102,14 +124,14 @@ public:
private:
// Content of tape tracks
tape_track_t m_tracks[ 2 ];
- // Bits per word in old format
- unsigned m_bits_per_word;
+ // Image format
+ image_format_t m_img_format;
bool load_track(io_generic *io , uint64_t& offset , tape_track_t& track , bool old_format);
static void dump_sequence(io_generic *io , uint64_t& offset , tape_track_t::const_iterator it_start , unsigned n_words);
- static tape_pos_t word_end_pos(const track_iterator_t& it);
- static void adjust_it(tape_track_t& track , track_iterator_t& it , tape_pos_t pos);
+ tape_pos_t word_end_pos(const track_iterator_t& it) const;
+ void adjust_it(tape_track_t& track , track_iterator_t& it , tape_pos_t pos) const;
static void ensure_a_lt_b(tape_pos_t& a , tape_pos_t& b);
};