diff options
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 |
commit | fad7c9e0beb50f6c96da9ea8f93082bc349a25c2 (patch) | |
tree | 172a75715375b6627303798660004fd80dd2a75d /src/lib | |
parent | ba587a777c41837c8aa9f2a2e8c1fc27b4616623 (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.cpp | 34 | ||||
-rw-r--r-- | src/lib/formats/hti_tape.h | 50 |
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); }; |