summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Robbbert <Robbbert@users.noreply.github.com>2020-04-06 01:37:05 +1000
committer Robbbert <Robbbert@users.noreply.github.com>2020-04-06 01:37:05 +1000
commitb5e08ae5e83f3c58948e82b80fb9b349504a9ef7 (patch)
treea7558259468d2732ae270ec901c90a5186e2c16a
parentf07357d52bd52e1f861bb6d03ec5ea4d8d94e453 (diff)
H8: added support for H8T tapes.
-rw-r--r--scripts/src/formats.lua12
-rw-r--r--scripts/target/mame/mess.lua1
-rw-r--r--src/lib/formats/h8_cas.cpp149
-rw-r--r--src/lib/formats/h8_cas.h19
-rw-r--r--src/mame/drivers/h8.cpp2
5 files changed, 183 insertions, 0 deletions
diff --git a/scripts/src/formats.lua b/scripts/src/formats.lua
index c234f37808b..f168dbe81ca 100644
--- a/scripts/src/formats.lua
+++ b/scripts/src/formats.lua
@@ -931,6 +931,18 @@ end
--------------------------------------------------
--
+--@src/lib/formats/h8_cas.h,FORMATS["H8_CAS"] = true
+--------------------------------------------------
+
+if (FORMATS["H8_CAS"]~=null or _OPTIONS["with-tools"]) then
+ files {
+ MAME_DIR.. "src/lib/formats/h8_cas.cpp",
+ MAME_DIR.. "src/lib/formats/h8_cas.h",
+ }
+end
+
+--------------------------------------------------
+--
--@src/lib/formats/hector_minidisc.h,FORMATS["HECTOR_MINIDISC"] = true
--------------------------------------------------
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index 63389306a8c..ac68c67a185 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -988,6 +988,7 @@ FORMATS["FMTOWNS_DSK"] = true
FORMATS["FSD_DSK"] = true
FORMATS["G64_DSK"] = true
FORMATS["GTP_CAS"] = true
+FORMATS["H8_CAS"] = true
FORMATS["HECTOR_MINIDISC"] = true
FORMATS["HECT_DSK"] = true
FORMATS["HECT_TAP"] = true
diff --git a/src/lib/formats/h8_cas.cpp b/src/lib/formats/h8_cas.cpp
new file mode 100644
index 00000000000..ec92a94b10f
--- /dev/null
+++ b/src/lib/formats/h8_cas.cpp
@@ -0,0 +1,149 @@
+// license:BSD-3-Clause
+// copyright-holders:Robbbert
+/********************************************************************
+
+Support for Heathkit H8 H8T cassette images
+
+
+Standard Kansas City format (300 baud)
+
+We output a leader, followed by the contents of the H8T file.
+
+********************************************************************/
+
+#include <cassert>
+
+#include "h8_cas.h"
+
+#define WAVEENTRY_LOW -32768
+#define WAVEENTRY_HIGH 32767
+
+#define H8_WAV_FREQUENCY 9600
+
+// image size
+static int h8_image_size;
+
+static int h8_put_samples(int16_t *buffer, int sample_pos, int count, int level)
+{
+ if (buffer)
+ {
+ for (int i=0; i<count; i++)
+ buffer[sample_pos + i] = level;
+ }
+
+ return count;
+}
+
+static int h8_output_bit(int16_t *buffer, int sample_pos, bool bit)
+{
+ int samples = 0;
+
+ for (uint8_t i = 0; i < 4; i++)
+ {
+ if (bit)
+ {
+ samples += h8_put_samples(buffer, sample_pos + samples, 2, WAVEENTRY_LOW);
+ samples += h8_put_samples(buffer, sample_pos + samples, 2, WAVEENTRY_HIGH);
+ samples += h8_put_samples(buffer, sample_pos + samples, 2, WAVEENTRY_LOW);
+ samples += h8_put_samples(buffer, sample_pos + samples, 2, WAVEENTRY_HIGH);
+ }
+ else
+ {
+ samples += h8_put_samples(buffer, sample_pos + samples, 4, WAVEENTRY_LOW);
+ samples += h8_put_samples(buffer, sample_pos + samples, 4, WAVEENTRY_HIGH);
+ }
+ }
+
+ return samples;
+}
+
+static int h8_output_byte(int16_t *buffer, int sample_pos, uint8_t byte)
+{
+ int samples = 0;
+ uint8_t i;
+
+ // start bit
+ samples += h8_output_bit (buffer, sample_pos + samples, 0);
+
+ // data bits
+ for (i = 0; i<8; i++)
+ samples += h8_output_bit (buffer, sample_pos + samples, (byte >> i) & 1);
+
+ // stop bits
+ for (i = 0; i<2; i++)
+ samples += h8_output_bit (buffer, sample_pos + samples, 1);
+
+ return samples;
+}
+
+static int h8_handle_cassette(int16_t *buffer, const uint8_t *bytes)
+{
+ uint32_t sample_count = 0;
+ uint32_t byte_count = 0;
+ uint32_t i;
+
+
+ // leader
+ for (i=0; i<2000; i++)
+ sample_count += h8_output_bit(buffer, sample_count, 1);
+
+ // data
+ for (i=byte_count; i<h8_image_size; i++)
+ sample_count += h8_output_byte(buffer, sample_count, bytes[i]);
+
+ return sample_count;
+}
+
+
+/*******************************************************************
+ Generate samples for the tape image
+********************************************************************/
+
+static int h8_cassette_fill_wave(int16_t *buffer, int length, uint8_t *bytes)
+{
+ return h8_handle_cassette(buffer, bytes);
+}
+
+/*******************************************************************
+ Calculate the number of samples needed for this tape image
+********************************************************************/
+
+static int h8_cassette_calculate_size_in_samples(const uint8_t *bytes, int length)
+{
+ h8_image_size = length;
+
+ return h8_handle_cassette(nullptr, bytes);
+}
+
+static const struct CassetteLegacyWaveFiller h8_legacy_fill_wave =
+{
+ h8_cassette_fill_wave, /* fill_wave */
+ -1, /* chunk_size */
+ 0, /* chunk_samples */
+ h8_cassette_calculate_size_in_samples, /* chunk_sample_calc */
+ H8_WAV_FREQUENCY, /* sample_frequency */
+ 0, /* header_samples */
+ 0 /* trailer_samples */
+};
+
+static cassette_image::error h8_cassette_identify(cassette_image *cassette, struct CassetteOptions *opts)
+{
+ return cassette_legacy_identify(cassette, opts, &h8_legacy_fill_wave);
+}
+
+static cassette_image::error h8_cassette_load(cassette_image *cassette)
+{
+ return cassette_legacy_construct(cassette, &h8_legacy_fill_wave);
+}
+
+static const struct CassetteFormat h8_cassette_image_format =
+{
+ "h8t",
+ h8_cassette_identify,
+ h8_cassette_load,
+ nullptr
+};
+
+CASSETTE_FORMATLIST_START(h8_cassette_formats)
+ CASSETTE_FORMAT(h8_cassette_image_format)
+CASSETTE_FORMATLIST_END
diff --git a/src/lib/formats/h8_cas.h b/src/lib/formats/h8_cas.h
new file mode 100644
index 00000000000..8ad9f82006a
--- /dev/null
+++ b/src/lib/formats/h8_cas.h
@@ -0,0 +1,19 @@
+// license:BSD-3-Clause
+// copyright-holders:Robbbert
+/*********************************************************************
+
+ h8_cas.h
+
+ Format code for Heathkit H8 H8T cassette images
+
+*********************************************************************/
+#ifndef MAME_FORMATS_H8_CAS_H
+#define MAME_FORMATS_H8_CAS_H
+
+#pragma once
+
+#include "cassimg.h"
+
+CASSETTE_FORMATLIST_EXTERN(h8_cassette_formats);
+
+#endif // MAME_FORMATS_H8_CAS_H
diff --git a/src/mame/drivers/h8.cpp b/src/mame/drivers/h8.cpp
index 7237a8033ef..3798c8fc3c4 100644
--- a/src/mame/drivers/h8.cpp
+++ b/src/mame/drivers/h8.cpp
@@ -54,6 +54,7 @@ Official test program from pages 4 to 8 of the operator's manual:
#include "sound/beep.h"
#include "speaker.h"
+#include "formats/h8_cas.h"
#include "h8.lh"
@@ -343,6 +344,7 @@ void h8_state::h8(machine_config &config)
cassette_clock.signal_handler().append(m_uart, FUNC(i8251_device::write_rxc));
CASSETTE(config, m_cass);
+ m_cass->set_formats(h8_cassette_formats);
m_cass->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED);
m_cass->add_route(ALL_OUTPUTS, "mono", 0.05);
m_cass->set_interface("h8_cass");