HP9825: printer & beeper added (#4175)
* hp9825: printer added. Whitespace cleanup on hp9825_tape.* * hp9825: added beeper
This commit is contained in:
parent
877906143a
commit
5dba426a7c
@ -14,12 +14,12 @@
|
|||||||
// - Keyboard (SHIFT LOCK & RESET not implemented)
|
// - Keyboard (SHIFT LOCK & RESET not implemented)
|
||||||
// - Display & run light
|
// - Display & run light
|
||||||
// - DC100 tape drive
|
// - DC100 tape drive
|
||||||
|
// - Printer
|
||||||
|
// - Beeper
|
||||||
// What's not yet in:
|
// What's not yet in:
|
||||||
// - Internal & external expansion ROMs
|
// - Internal & external expansion ROMs
|
||||||
// - Configurable RAM size
|
// - Configurable RAM size
|
||||||
// - Printer
|
|
||||||
// - I/O expansion slots: 98034 & 98035 modules from hp9845 emulation can be used here, too
|
// - I/O expansion slots: 98034 & 98035 modules from hp9845 emulation can be used here, too
|
||||||
// - Beeper
|
|
||||||
//
|
//
|
||||||
// 9825A & 9825T can also be emulated. At the moment I haven't all the necessary
|
// 9825A & 9825T can also be emulated. At the moment I haven't all the necessary
|
||||||
// ROM dumps, though.
|
// ROM dumps, though.
|
||||||
@ -28,6 +28,9 @@
|
|||||||
#include "cpu/hphybrid/hphybrid.h"
|
#include "cpu/hphybrid/hphybrid.h"
|
||||||
#include "machine/timer.h"
|
#include "machine/timer.h"
|
||||||
#include "machine/hp9825_tape.h"
|
#include "machine/hp9825_tape.h"
|
||||||
|
#include "imagedev/bitbngr.h"
|
||||||
|
#include "speaker.h"
|
||||||
|
#include "sound/beep.h"
|
||||||
#include "hp9825.lh"
|
#include "hp9825.lh"
|
||||||
|
|
||||||
// CPU clock (generated by a trimmered RC oscillator)
|
// CPU clock (generated by a trimmered RC oscillator)
|
||||||
@ -40,6 +43,15 @@ constexpr unsigned KDP_CLOCK = MAIN_CLOCK / 4;
|
|||||||
constexpr uint8_t KDP_PA = 0;
|
constexpr uint8_t KDP_PA = 0;
|
||||||
constexpr uint8_t TAPE_PA = 1;
|
constexpr uint8_t TAPE_PA = 1;
|
||||||
|
|
||||||
|
// KDP clocks to print 1 line of dots (~33 ms)
|
||||||
|
// This value is semi-guessed.
|
||||||
|
constexpr unsigned KDP_CLOCKS_PER_LINE = 50000;
|
||||||
|
|
||||||
|
// Beeper constants
|
||||||
|
// Values come from R/C values on schematics
|
||||||
|
constexpr unsigned BEEPER_FREQ = 900;
|
||||||
|
constexpr unsigned BEEPER_MS = 40;
|
||||||
|
|
||||||
// Bit manipulation
|
// Bit manipulation
|
||||||
namespace {
|
namespace {
|
||||||
template<typename T> constexpr T BIT_MASK(unsigned n)
|
template<typename T> constexpr T BIT_MASK(unsigned n)
|
||||||
@ -68,6 +80,11 @@ public:
|
|||||||
, m_tape(*this , "tape")
|
, m_tape(*this , "tape")
|
||||||
, m_io_key(*this , "KEY%u" , 0)
|
, m_io_key(*this , "KEY%u" , 0)
|
||||||
, m_shift_key(*this , "KEY_SHIFT")
|
, m_shift_key(*this , "KEY_SHIFT")
|
||||||
|
, m_prt_alpha_out(*this , "prt_alpha")
|
||||||
|
, m_prt_graph_out(*this , "prt_graph")
|
||||||
|
, m_prt_timer(*this , "prt_timer")
|
||||||
|
, m_beeper(*this , "beeper")
|
||||||
|
, m_beep_timer(*this , "beep_timer")
|
||||||
, m_display(*this , "char_%u_%u" , 0U , 0U)
|
, m_display(*this , "char_%u_%u" , 0U , 0U)
|
||||||
, m_run_light(*this , "run_light")
|
, m_run_light(*this , "run_light")
|
||||||
{
|
{
|
||||||
@ -81,6 +98,11 @@ private:
|
|||||||
required_device<hp9825_tape_device> m_tape;
|
required_device<hp9825_tape_device> m_tape;
|
||||||
required_ioport_array<4> m_io_key;
|
required_ioport_array<4> m_io_key;
|
||||||
required_ioport m_shift_key;
|
required_ioport m_shift_key;
|
||||||
|
required_device<bitbanger_device> m_prt_alpha_out;
|
||||||
|
required_device<bitbanger_device> m_prt_graph_out;
|
||||||
|
required_device<timer_device> m_prt_timer;
|
||||||
|
required_device<beep_device> m_beeper;
|
||||||
|
required_device<timer_device> m_beep_timer;
|
||||||
output_finder<32 , 7> m_display;
|
output_finder<32 , 7> m_display;
|
||||||
output_finder<> m_run_light;
|
output_finder<> m_run_light;
|
||||||
|
|
||||||
@ -100,6 +122,10 @@ private:
|
|||||||
uint8_t m_pa;
|
uint8_t m_pa;
|
||||||
uint16_t m_flg_status;
|
uint16_t m_flg_status;
|
||||||
uint16_t m_sts_status;
|
uint16_t m_sts_status;
|
||||||
|
// Printer
|
||||||
|
uint8_t m_printer_mem[ 16 ];
|
||||||
|
uint8_t m_printer_idx;
|
||||||
|
unsigned m_printer_line; // 0: printer idle, 1..10: line being printed
|
||||||
|
|
||||||
virtual void machine_start() override;
|
virtual void machine_start() override;
|
||||||
virtual void machine_reset() override;
|
virtual void machine_reset() override;
|
||||||
@ -111,6 +137,7 @@ private:
|
|||||||
DECLARE_WRITE16_MEMBER(disp_w);
|
DECLARE_WRITE16_MEMBER(disp_w);
|
||||||
DECLARE_READ16_MEMBER(kdp_status_r);
|
DECLARE_READ16_MEMBER(kdp_status_r);
|
||||||
DECLARE_WRITE16_MEMBER(kdp_control_w);
|
DECLARE_WRITE16_MEMBER(kdp_control_w);
|
||||||
|
DECLARE_WRITE16_MEMBER(printer_w);
|
||||||
|
|
||||||
void update_display();
|
void update_display();
|
||||||
TIMER_DEVICE_CALLBACK_MEMBER(cursor_blink);
|
TIMER_DEVICE_CALLBACK_MEMBER(cursor_blink);
|
||||||
@ -125,6 +152,10 @@ private:
|
|||||||
void update_flg_sts();
|
void update_flg_sts();
|
||||||
void set_sts(uint8_t sc , int state);
|
void set_sts(uint8_t sc , int state);
|
||||||
void set_flg(uint8_t sc , int state);
|
void set_flg(uint8_t sc , int state);
|
||||||
|
|
||||||
|
TIMER_DEVICE_CALLBACK_MEMBER(prt_timer);
|
||||||
|
|
||||||
|
TIMER_DEVICE_CALLBACK_MEMBER(beep_timer);
|
||||||
};
|
};
|
||||||
|
|
||||||
void hp9825_state::machine_start()
|
void hp9825_state::machine_start()
|
||||||
@ -158,6 +189,11 @@ void hp9825_state::machine_reset()
|
|||||||
m_pa = 0;
|
m_pa = 0;
|
||||||
m_flg_status = 0;
|
m_flg_status = 0;
|
||||||
m_sts_status = 0;
|
m_sts_status = 0;
|
||||||
|
m_printer_idx = 0;
|
||||||
|
m_printer_line = 0;
|
||||||
|
m_prt_timer->reset();
|
||||||
|
m_beeper->set_state(0);
|
||||||
|
m_beep_timer->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void hp9825_state::cpu_io_map(address_map &map)
|
void hp9825_state::cpu_io_map(address_map &map)
|
||||||
@ -165,6 +201,7 @@ void hp9825_state::cpu_io_map(address_map &map)
|
|||||||
map.unmap_value_low();
|
map.unmap_value_low();
|
||||||
map(HP_MAKE_IOADDR(KDP_PA , 0) , HP_MAKE_IOADDR(KDP_PA , 0)).rw(FUNC(hp9825_state::kb_scancode_r) , FUNC(hp9825_state::disp_w));
|
map(HP_MAKE_IOADDR(KDP_PA , 0) , HP_MAKE_IOADDR(KDP_PA , 0)).rw(FUNC(hp9825_state::kb_scancode_r) , FUNC(hp9825_state::disp_w));
|
||||||
map(HP_MAKE_IOADDR(KDP_PA , 1) , HP_MAKE_IOADDR(KDP_PA , 1)).rw(FUNC(hp9825_state::kdp_status_r) , FUNC(hp9825_state::kdp_control_w));
|
map(HP_MAKE_IOADDR(KDP_PA , 1) , HP_MAKE_IOADDR(KDP_PA , 1)).rw(FUNC(hp9825_state::kdp_status_r) , FUNC(hp9825_state::kdp_control_w));
|
||||||
|
map(HP_MAKE_IOADDR(KDP_PA , 2) , HP_MAKE_IOADDR(KDP_PA , 2)).w(FUNC(hp9825_state::printer_w));
|
||||||
map(HP_MAKE_IOADDR(TAPE_PA , 0) , HP_MAKE_IOADDR(TAPE_PA , 3)).rw(m_tape , FUNC(hp9825_tape_device::tape_r) , FUNC(hp9825_tape_device::tape_w));
|
map(HP_MAKE_IOADDR(TAPE_PA , 0) , HP_MAKE_IOADDR(TAPE_PA , 3)).rw(m_tape , FUNC(hp9825_tape_device::tape_r) , FUNC(hp9825_tape_device::tape_w));
|
||||||
// TODO:
|
// TODO:
|
||||||
}
|
}
|
||||||
@ -202,8 +239,15 @@ WRITE16_MEMBER(hp9825_state::disp_w)
|
|||||||
|
|
||||||
READ16_MEMBER(hp9825_state::kdp_status_r)
|
READ16_MEMBER(hp9825_state::kdp_status_r)
|
||||||
{
|
{
|
||||||
// TODO:
|
uint16_t res = 8;
|
||||||
return 8;
|
if (BIT(m_irl_pending, KDP_PA)) {
|
||||||
|
BIT_SET(res , 4);
|
||||||
|
}
|
||||||
|
if (m_printer_line) {
|
||||||
|
BIT_SET(res , 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE16_MEMBER(hp9825_state::kdp_control_w)
|
WRITE16_MEMBER(hp9825_state::kdp_control_w)
|
||||||
@ -234,11 +278,33 @@ WRITE16_MEMBER(hp9825_state::kdp_control_w)
|
|||||||
} else if (BIT(data , 3)) {
|
} else if (BIT(data , 3)) {
|
||||||
m_run_light = true;
|
m_run_light = true;
|
||||||
}
|
}
|
||||||
|
if (BIT(data , 0) && m_printer_line == 0) {
|
||||||
|
// Start printing
|
||||||
|
// Dump text line to alpha bitbanger
|
||||||
|
for (auto c : m_printer_mem) {
|
||||||
|
m_prt_alpha_out->output(c);
|
||||||
|
}
|
||||||
|
m_prt_alpha_out->output('\n');
|
||||||
|
m_printer_idx = 0;
|
||||||
|
m_printer_line++;
|
||||||
|
m_prt_timer->adjust(attotime::from_ticks(KDP_CLOCKS_PER_LINE , KDP_CLOCK));
|
||||||
|
}
|
||||||
|
if (BIT(data , 2)) {
|
||||||
|
// Start beeper
|
||||||
|
m_beeper->set_state(1);
|
||||||
|
m_beep_timer->adjust(attotime::from_msec(BEEPER_MS));
|
||||||
|
}
|
||||||
if (regen_display) {
|
if (regen_display) {
|
||||||
update_display();
|
update_display();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(hp9825_state::printer_w)
|
||||||
|
{
|
||||||
|
m_printer_mem[ m_printer_idx ] = uint8_t(data);
|
||||||
|
m_printer_idx = (m_printer_idx + 1) & 0xf;
|
||||||
|
}
|
||||||
|
|
||||||
// The character generator was reverse engineered from images of printer & display test patterns.
|
// The character generator was reverse engineered from images of printer & display test patterns.
|
||||||
// It is not guaranteed to be pixel-accurate though it looks quite close to the original.
|
// It is not guaranteed to be pixel-accurate though it looks quite close to the original.
|
||||||
static const uint8_t chargen[ 128 ][ 5 ] = {
|
static const uint8_t chargen[ 128 ][ 5 ] = {
|
||||||
@ -546,6 +612,37 @@ void hp9825_state::set_flg(uint8_t sc , int state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TIMER_DEVICE_CALLBACK_MEMBER(hp9825_state::prt_timer)
|
||||||
|
{
|
||||||
|
if (m_printer_line == 1 || m_printer_line == 9 || m_printer_line == 10) {
|
||||||
|
// Empty lines
|
||||||
|
for (unsigned i = 0; i < 110; i++) {
|
||||||
|
m_prt_graph_out->output(' ');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (unsigned i = 0; i < 16; i++) {
|
||||||
|
for (unsigned col = 0; col < 5; col++) {
|
||||||
|
uint8_t pixels = chargen[ m_printer_mem[ i ] & 0x7f ][ col ];
|
||||||
|
m_prt_graph_out->output(BIT(pixels , m_printer_line - 2) ? '*' : ' ');
|
||||||
|
}
|
||||||
|
m_prt_graph_out->output(' ');
|
||||||
|
m_prt_graph_out->output(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_prt_graph_out->output('\n');
|
||||||
|
m_printer_line++;
|
||||||
|
if (m_printer_line <= 10) {
|
||||||
|
m_prt_timer->adjust(attotime::from_ticks(KDP_CLOCKS_PER_LINE , KDP_CLOCK));
|
||||||
|
} else {
|
||||||
|
m_printer_line = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TIMER_DEVICE_CALLBACK_MEMBER(hp9825_state::beep_timer)
|
||||||
|
{
|
||||||
|
m_beeper->set_state(0);
|
||||||
|
}
|
||||||
|
|
||||||
MACHINE_CONFIG_START(hp9825_state::hp9825b)
|
MACHINE_CONFIG_START(hp9825_state::hp9825b)
|
||||||
HP_09825_67907(config , m_cpu , MAIN_CLOCK);
|
HP_09825_67907(config , m_cpu , MAIN_CLOCK);
|
||||||
// Just guessing... settings borrowed from hp9845
|
// Just guessing... settings borrowed from hp9845
|
||||||
@ -567,6 +664,16 @@ MACHINE_CONFIG_START(hp9825_state::hp9825b)
|
|||||||
m_tape->sts().set([this , sc = TAPE_PA](int state) { set_sts(sc , state); });
|
m_tape->sts().set([this , sc = TAPE_PA](int state) { set_sts(sc , state); });
|
||||||
m_tape->dmar().set(m_cpu , FUNC(hp_09825_67907_cpu_device::dmar_w));
|
m_tape->dmar().set(m_cpu , FUNC(hp_09825_67907_cpu_device::dmar_w));
|
||||||
|
|
||||||
|
// Printer
|
||||||
|
BITBANGER(config , m_prt_alpha_out , 0);
|
||||||
|
BITBANGER(config , m_prt_graph_out , 0);
|
||||||
|
TIMER(config , m_prt_timer , 0).configure_generic(timer_device::expired_delegate(FUNC(hp9825_state::prt_timer) , this));
|
||||||
|
|
||||||
|
// Beeper
|
||||||
|
SPEAKER(config, "mono").front_center();
|
||||||
|
BEEP(config, m_beeper, BEEPER_FREQ).add_route(ALL_OUTPUTS, "mono", 1.00);
|
||||||
|
TIMER(config , m_beep_timer , 0).configure_generic(timer_device::expired_delegate(FUNC(hp9825_state::beep_timer) , this));
|
||||||
|
|
||||||
config.set_default_layout(layout_hp9825);
|
config.set_default_layout(layout_hp9825);
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
@ -42,36 +42,36 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
constexpr double FAST_SPEED = 90.0; // Fast speed: 90 ips
|
constexpr double FAST_SPEED = 90.0; // Fast speed: 90 ips
|
||||||
constexpr double SLOW_SPEED = 22.0; // Slow speed: 22 ips
|
constexpr double SLOW_SPEED = 22.0; // Slow speed: 22 ips
|
||||||
constexpr double MIN_RD_SPEED = 22.0; // Minimum speed to read data off the tape
|
constexpr double MIN_RD_SPEED = 22.0; // Minimum speed to read data off the tape
|
||||||
constexpr double MOVING_THRESHOLD = 2.0; // Tape is moving (from MVG bit POV) when speed > 2.0 ips
|
constexpr double MOVING_THRESHOLD = 2.0; // Tape is moving (from MVG bit POV) when speed > 2.0 ips
|
||||||
constexpr double ACCELERATION = 1200.0; // Acceleration when speed set point is changed: 1200 ips^2
|
constexpr double ACCELERATION = 1200.0; // Acceleration when speed set point is changed: 1200 ips^2
|
||||||
constexpr unsigned TACH_TICKS_PER_INCH = 483; // Tachometer pulses per inch
|
constexpr unsigned TACH_TICKS_PER_INCH = 483; // Tachometer pulses per inch
|
||||||
constexpr double INVERSION_MARGIN = 1e-5; // Margin to ensure speed is away from 0 when motion is inverted (10 µs)
|
constexpr double INVERSION_MARGIN = 1e-5; // Margin to ensure speed is away from 0 when motion is inverted (10 µs)
|
||||||
constexpr hti_format_t::tape_pos_t TACH_TICK_LENGTH = hti_format_t::ONE_INCH_POS / TACH_TICKS_PER_INCH; // Length of each tach tick
|
constexpr hti_format_t::tape_pos_t TACH_TICK_LENGTH = hti_format_t::ONE_INCH_POS / TACH_TICKS_PER_INCH; // Length of each tach tick
|
||||||
|
|
||||||
// Bits in command register
|
// Bits in command register
|
||||||
enum : unsigned {
|
enum : unsigned {
|
||||||
CMD_REG_MOTOR_BIT = 7, // Motor on (0)
|
CMD_REG_MOTOR_BIT = 7, // Motor on (0)
|
||||||
CMD_REG_WR_GATE_BIT = 6, // Write gate (0)
|
CMD_REG_WR_GATE_BIT = 6, // Write gate (0)
|
||||||
CMD_REG_SPEED_BIT = 5, // Tape speed (1 = slow)
|
CMD_REG_SPEED_BIT = 5, // Tape speed (1 = slow)
|
||||||
CMD_REG_DIR_BIT = 4, // Tape direction (1 = fwd)
|
CMD_REG_DIR_BIT = 4, // Tape direction (1 = fwd)
|
||||||
CMD_REG_FLG_SEL_BIT = 3, // FLG selection (0 = tacho pulses, 1 = bit clock)
|
CMD_REG_FLG_SEL_BIT = 3, // FLG selection (0 = tacho pulses, 1 = bit clock)
|
||||||
CMD_REG_THRESHOLD_BIT = 2, // Threshold selection
|
CMD_REG_THRESHOLD_BIT = 2, // Threshold selection
|
||||||
CMD_REG_DMA_EN_BIT = 1, // DMA enable (0)
|
CMD_REG_DMA_EN_BIT = 1, // DMA enable (0)
|
||||||
CMD_REG_TRACK_SEL_BIT = 0 // Track selection (1 = A)
|
CMD_REG_TRACK_SEL_BIT = 0 // Track selection (1 = A)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Bits in status register
|
// Bits in status register
|
||||||
enum : unsigned {
|
enum : unsigned {
|
||||||
STAT_REG_WPR_BIT = 7, // Write protected (1)
|
STAT_REG_WPR_BIT = 7, // Write protected (1)
|
||||||
STAT_REG_DIR_BIT = 6, // Tape direction (1 = rev)
|
STAT_REG_DIR_BIT = 6, // Tape direction (1 = rev)
|
||||||
STAT_REG_MVG_BIT = 5, // Tape moving (1)
|
STAT_REG_MVG_BIT = 5, // Tape moving (1)
|
||||||
STAT_REG_GAP_BIT = 4, // Gap (1) or data (0)
|
STAT_REG_GAP_BIT = 4, // Gap (1) or data (0)
|
||||||
STAT_REG_COUT_BIT = 2, // Cartridge out (1)
|
STAT_REG_COUT_BIT = 2, // Cartridge out (1)
|
||||||
STAT_REG_SVF_BIT = 1, // Servo failure (1)
|
STAT_REG_SVF_BIT = 1, // Servo failure (1)
|
||||||
STAT_REG_EOT_BIT = 0 // End of tape (1)
|
STAT_REG_EOT_BIT = 0 // End of tape (1)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Timers
|
// Timers
|
||||||
@ -100,19 +100,19 @@ hp9825_tape_device::hp9825_tape_device(const machine_config &mconfig, const char
|
|||||||
}
|
}
|
||||||
|
|
||||||
MACHINE_CONFIG_START(hp9825_tape_device::device_add_mconfig)
|
MACHINE_CONFIG_START(hp9825_tape_device::device_add_mconfig)
|
||||||
TTL74123(config , m_short_gap_timer , 0);
|
TTL74123(config , m_short_gap_timer , 0);
|
||||||
m_short_gap_timer->set_connection_type(TTL74123_NOT_GROUNDED_NO_DIODE);
|
m_short_gap_timer->set_connection_type(TTL74123_NOT_GROUNDED_NO_DIODE);
|
||||||
m_short_gap_timer->set_resistor_value(RES_K(37.9));
|
m_short_gap_timer->set_resistor_value(RES_K(37.9));
|
||||||
m_short_gap_timer->set_capacitor_value(CAP_N(10));
|
m_short_gap_timer->set_capacitor_value(CAP_N(10));
|
||||||
m_short_gap_timer->set_a_pin_value(0);
|
m_short_gap_timer->set_a_pin_value(0);
|
||||||
m_short_gap_timer->set_clear_pin_value(1);
|
m_short_gap_timer->set_clear_pin_value(1);
|
||||||
m_short_gap_timer->out_cb().set(FUNC(hp9825_tape_device::short_gap_w));
|
m_short_gap_timer->out_cb().set(FUNC(hp9825_tape_device::short_gap_w));
|
||||||
|
|
||||||
TTL74123(config , m_long_gap_timer , 0);
|
TTL74123(config , m_long_gap_timer , 0);
|
||||||
m_long_gap_timer->set_connection_type(TTL74123_NOT_GROUNDED_NO_DIODE);
|
m_long_gap_timer->set_connection_type(TTL74123_NOT_GROUNDED_NO_DIODE);
|
||||||
m_long_gap_timer->set_resistor_value(RES_K(28.7));
|
m_long_gap_timer->set_resistor_value(RES_K(28.7));
|
||||||
m_long_gap_timer->set_capacitor_value(CAP_U(0.22));
|
m_long_gap_timer->set_capacitor_value(CAP_U(0.22));
|
||||||
m_long_gap_timer->set_clear_pin_value(1);
|
m_long_gap_timer->set_clear_pin_value(1);
|
||||||
m_long_gap_timer->out_cb().set(FUNC(hp9825_tape_device::long_gap_w));
|
m_long_gap_timer->out_cb().set(FUNC(hp9825_tape_device::long_gap_w));
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ void hp9825_tape_device::device_start()
|
|||||||
m_tacho_timer = timer_alloc(TACHO_TMR_ID);
|
m_tacho_timer = timer_alloc(TACHO_TMR_ID);
|
||||||
m_hole_timer = timer_alloc(HOLE_TMR_ID);
|
m_hole_timer = timer_alloc(HOLE_TMR_ID);
|
||||||
m_inv_timer = timer_alloc(INV_TMR_ID);
|
m_inv_timer = timer_alloc(INV_TMR_ID);
|
||||||
|
|
||||||
save_item(NAME(m_cmd_reg));
|
save_item(NAME(m_cmd_reg));
|
||||||
save_item(NAME(m_stat_reg));
|
save_item(NAME(m_stat_reg));
|
||||||
save_item(NAME(m_flg));
|
save_item(NAME(m_flg));
|
||||||
@ -196,7 +196,7 @@ void hp9825_tape_device::clear_state()
|
|||||||
m_sts_handler(true);
|
m_sts_handler(true);
|
||||||
m_dmar_handler(false);
|
m_dmar_handler(false);
|
||||||
m_led_handler(false);
|
m_led_handler(false);
|
||||||
|
|
||||||
m_bit_timer->reset();
|
m_bit_timer->reset();
|
||||||
m_tacho_timer->reset();
|
m_tacho_timer->reset();
|
||||||
m_hole_timer->reset();
|
m_hole_timer->reset();
|
||||||
@ -210,7 +210,7 @@ void hp9825_tape_device::device_timer(emu_timer &timer, device_timer_id id, int
|
|||||||
{
|
{
|
||||||
LOG_TMR("%.6f TMR %d s=%.3f p=%d a=%d\n" , machine().time().as_double() , id , m_speed , m_tape_pos , m_accelerating);
|
LOG_TMR("%.6f TMR %d s=%.3f p=%d a=%d\n" , machine().time().as_double() , id , m_speed , m_tape_pos , m_accelerating);
|
||||||
update_speed_pos();
|
update_speed_pos();
|
||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case BIT_TMR_ID:
|
case BIT_TMR_ID:
|
||||||
m_tape_pos = m_next_bit_pos;
|
m_tape_pos = m_next_bit_pos;
|
||||||
@ -270,7 +270,7 @@ void hp9825_tape_device::device_timer(emu_timer &timer, device_timer_id id, int
|
|||||||
case INV_TMR_ID:
|
case INV_TMR_ID:
|
||||||
// In itself it does nothing (all work is in update_speed_pos)
|
// In itself it does nothing (all work is in update_speed_pos)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -280,7 +280,7 @@ void hp9825_tape_device::device_timer(emu_timer &timer, device_timer_id id, int
|
|||||||
image_init_result hp9825_tape_device::internal_load(bool is_create)
|
image_init_result hp9825_tape_device::internal_load(bool is_create)
|
||||||
{
|
{
|
||||||
LOG("load %d\n" , is_create);
|
LOG("load %d\n" , is_create);
|
||||||
|
|
||||||
device_reset();
|
device_reset();
|
||||||
|
|
||||||
io_generic io;
|
io_generic io;
|
||||||
@ -335,7 +335,7 @@ void hp9825_tape_device::call_unload()
|
|||||||
|
|
||||||
std::string hp9825_tape_device::call_display()
|
std::string hp9825_tape_device::call_display()
|
||||||
{
|
{
|
||||||
// TODO:
|
// TODO:
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,7 +347,7 @@ const char *hp9825_tape_device::file_extensions() const
|
|||||||
READ16_MEMBER(hp9825_tape_device::tape_r)
|
READ16_MEMBER(hp9825_tape_device::tape_r)
|
||||||
{
|
{
|
||||||
uint16_t res = 0;
|
uint16_t res = 0;
|
||||||
|
|
||||||
switch (offset) {
|
switch (offset) {
|
||||||
case 0:
|
case 0:
|
||||||
// R4: read data out
|
// R4: read data out
|
||||||
@ -495,7 +495,7 @@ void hp9825_tape_device::update_sts()
|
|||||||
// m_in_gap
|
// m_in_gap
|
||||||
auto prev_set_point = get_speed_set_point();
|
auto prev_set_point = get_speed_set_point();
|
||||||
auto prev_exception = m_exception;
|
auto prev_exception = m_exception;
|
||||||
|
|
||||||
m_exception =
|
m_exception =
|
||||||
BIT(m_stat_reg , STAT_REG_EOT_BIT) ||
|
BIT(m_stat_reg , STAT_REG_EOT_BIT) ||
|
||||||
BIT(m_stat_reg , STAT_REG_COUT_BIT) ||
|
BIT(m_stat_reg , STAT_REG_COUT_BIT) ||
|
||||||
@ -689,7 +689,7 @@ void hp9825_tape_device::update_speed_pos()
|
|||||||
m_led_handler(false);
|
m_led_handler(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hti_format_t::tape_pos_t delta_pos = (hti_format_t::tape_pos_t)((space_const_a + m_speed * time_const_v) * hti_format_t::ONE_INCH_POS);
|
hti_format_t::tape_pos_t delta_pos = (hti_format_t::tape_pos_t)((space_const_a + m_speed * time_const_v) * hti_format_t::ONE_INCH_POS);
|
||||||
LOG_DBG("dp=%d\n" , delta_pos);
|
LOG_DBG("dp=%d\n" , delta_pos);
|
||||||
if (!hti_format_t::pos_offset(m_tape_pos , true , delta_pos)) {
|
if (!hti_format_t::pos_offset(m_tape_pos , true , delta_pos)) {
|
||||||
@ -731,7 +731,7 @@ void hp9825_tape_device::time_to_distance(hti_format_t::tape_pos_t distance , ht
|
|||||||
target_timer->reset();
|
target_timer->reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
double space = double(distance) / hti_format_t::ONE_INCH_POS;
|
double space = double(distance) / hti_format_t::ONE_INCH_POS;
|
||||||
double set_point = get_speed_set_point();
|
double set_point = get_speed_set_point();
|
||||||
double time_const_a;
|
double time_const_a;
|
||||||
@ -918,7 +918,7 @@ void hp9825_tape_device::rd_bit(bool bit)
|
|||||||
m_in_gap = false;
|
m_in_gap = false;
|
||||||
m_long_gap_timer->a_w(m_in_gap);
|
m_long_gap_timer->a_w(m_in_gap);
|
||||||
update_sts();
|
update_sts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hp9825_tape_device::wr_bit(bool bit)
|
void hp9825_tape_device::wr_bit(bool bit)
|
||||||
|
@ -27,7 +27,7 @@ public:
|
|||||||
virtual void device_start() override;
|
virtual void device_start() override;
|
||||||
virtual void device_reset() override;
|
virtual void device_reset() override;
|
||||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||||
|
|
||||||
// device_image_interface overrides
|
// device_image_interface overrides
|
||||||
virtual image_init_result call_load() override;
|
virtual image_init_result call_load() override;
|
||||||
virtual image_init_result call_create(int format_type, util::option_resolution *format_options) override;
|
virtual image_init_result call_create(int format_type, util::option_resolution *format_options) override;
|
||||||
@ -51,16 +51,16 @@ public:
|
|||||||
|
|
||||||
DECLARE_WRITE_LINE_MEMBER(short_gap_w);
|
DECLARE_WRITE_LINE_MEMBER(short_gap_w);
|
||||||
DECLARE_WRITE_LINE_MEMBER(long_gap_w);
|
DECLARE_WRITE_LINE_MEMBER(long_gap_w);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
devcb_write_line m_flg_handler;
|
devcb_write_line m_flg_handler;
|
||||||
devcb_write_line m_sts_handler;
|
devcb_write_line m_sts_handler;
|
||||||
devcb_write_line m_dmar_handler;
|
devcb_write_line m_dmar_handler;
|
||||||
devcb_write_line m_led_handler;
|
devcb_write_line m_led_handler;
|
||||||
|
|
||||||
required_device<ttl74123_device> m_short_gap_timer; // U43a
|
required_device<ttl74123_device> m_short_gap_timer; // U43a
|
||||||
required_device<ttl74123_device> m_long_gap_timer; // U43b
|
required_device<ttl74123_device> m_long_gap_timer; // U43b
|
||||||
|
|
||||||
// Registers
|
// Registers
|
||||||
uint8_t m_cmd_reg;
|
uint8_t m_cmd_reg;
|
||||||
uint8_t m_stat_reg;
|
uint8_t m_stat_reg;
|
||||||
@ -68,18 +68,18 @@ private:
|
|||||||
// State
|
// State
|
||||||
bool m_flg;
|
bool m_flg;
|
||||||
bool m_sts;
|
bool m_sts;
|
||||||
bool m_data_out; // U38-9
|
bool m_data_out; // U38-9
|
||||||
bool m_data_in; // U13-6
|
bool m_data_in; // U13-6
|
||||||
bool m_exception; // U4-6
|
bool m_exception; // U4-6
|
||||||
bool m_search_complete; // U9-6
|
bool m_search_complete; // U9-6
|
||||||
bool m_dma_req; // U9-9
|
bool m_dma_req; // U9-9
|
||||||
bool m_in_gap; // U39-4
|
bool m_in_gap; // U39-4
|
||||||
bool m_no_go; // U6-3
|
bool m_no_go; // U6-3
|
||||||
bool m_present;
|
bool m_present;
|
||||||
bool m_valid_bits; // U39-5
|
bool m_valid_bits; // U39-5
|
||||||
uint8_t m_trans_cnt; // U42
|
uint8_t m_trans_cnt; // U42
|
||||||
bool m_short_gap_out; // U43-13
|
bool m_short_gap_out; // U43-13
|
||||||
bool m_long_gap_out; // U43-5
|
bool m_long_gap_out; // U43-5
|
||||||
|
|
||||||
// Timers
|
// Timers
|
||||||
emu_timer *m_bit_timer;
|
emu_timer *m_bit_timer;
|
||||||
@ -97,7 +97,7 @@ private:
|
|||||||
hti_format_t::tape_pos_t m_next_tacho_pos;
|
hti_format_t::tape_pos_t m_next_tacho_pos;
|
||||||
hti_format_t::tape_pos_t m_next_hole_pos;
|
hti_format_t::tape_pos_t m_next_hole_pos;
|
||||||
double m_speed;
|
double m_speed;
|
||||||
attotime m_start_time; // Tape moving if != never
|
attotime m_start_time; // Tape moving if != never
|
||||||
bool m_accelerating;
|
bool m_accelerating;
|
||||||
|
|
||||||
// R/W
|
// R/W
|
||||||
@ -111,8 +111,8 @@ private:
|
|||||||
int m_rw_stat;
|
int m_rw_stat;
|
||||||
hti_format_t::track_iterator_t m_rd_it;
|
hti_format_t::track_iterator_t m_rd_it;
|
||||||
bool m_rd_it_valid;
|
bool m_rd_it_valid;
|
||||||
uint32_t m_rw_word; // Need 17 bits because of sync bit
|
uint32_t m_rw_word; // Need 17 bits because of sync bit
|
||||||
unsigned m_bit_idx; // 0 is MSB, 15 is LSB, 16 is sync bit, >16 means "looking for sync"
|
unsigned m_bit_idx; // 0 is MSB, 15 is LSB, 16 is sync bit, >16 means "looking for sync"
|
||||||
hti_format_t::tape_pos_t m_gap_start;
|
hti_format_t::tape_pos_t m_gap_start;
|
||||||
|
|
||||||
void clear_state();
|
void clear_state();
|
||||||
|
Loading…
Reference in New Issue
Block a user