summaryrefslogtreecommitdiffstats
path: root/src/mame/drivers/hp9825.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/hp9825.cpp')
-rw-r--r--src/mame/drivers/hp9825.cpp77
1 files changed, 71 insertions, 6 deletions
diff --git a/src/mame/drivers/hp9825.cpp b/src/mame/drivers/hp9825.cpp
index 251b256c9bf..b04967f41c1 100644
--- a/src/mame/drivers/hp9825.cpp
+++ b/src/mame/drivers/hp9825.cpp
@@ -13,11 +13,11 @@
// - 12 kw of system ROM
// - Keyboard (SHIFT LOCK & RESET not implemented)
// - Display & run light
+// - DC100 tape drive
// What's not yet in:
// - Internal & external expansion ROMs
// - Configurable RAM size
// - Printer
-// - DC100 tape drive
// - I/O expansion slots: 98034 & 98035 modules from hp9845 emulation can be used here, too
// - Beeper
//
@@ -27,6 +27,7 @@
#include "emu.h"
#include "cpu/hphybrid/hphybrid.h"
#include "machine/timer.h"
+#include "machine/hp9825_tape.h"
#include "hp9825.lh"
// CPU clock (generated by a trimmered RC oscillator)
@@ -35,6 +36,10 @@ constexpr unsigned MAIN_CLOCK = 6000000;
// KDP chip clock
constexpr unsigned KDP_CLOCK = MAIN_CLOCK / 4;
+// Peripheral Addresses (PA)
+constexpr uint8_t KDP_PA = 0;
+constexpr uint8_t TAPE_PA = 1;
+
// Bit manipulation
namespace {
template<typename T> constexpr T BIT_MASK(unsigned n)
@@ -60,6 +65,7 @@ public:
: driver_device(mconfig, type, tag)
, m_cpu(*this , "cpu")
, m_cursor_timer(*this , "cursor_timer")
+ , m_tape(*this , "tape")
, m_io_key(*this , "KEY%u" , 0)
, m_shift_key(*this , "KEY_SHIFT")
, m_display(*this , "char_%u_%u" , 0U , 0U)
@@ -72,6 +78,7 @@ public:
private:
required_device<hp_09825_67907_cpu_device> m_cpu;
required_device<timer_device> m_cursor_timer;
+ required_device<hp9825_tape_device> m_tape;
required_ioport_array<4> m_io_key;
required_ioport m_shift_key;
output_finder<32 , 7> m_display;
@@ -89,6 +96,10 @@ private:
unsigned m_autorepeat_cnt;
uint8_t m_irl_pending;
uint8_t m_irh_pending;
+ // FLG/STS handling
+ uint8_t m_pa;
+ uint16_t m_flg_status;
+ uint16_t m_sts_status;
virtual void machine_start() override;
virtual void machine_reset() override;
@@ -109,6 +120,11 @@ private:
IRQ_CALLBACK_MEMBER(irq_callback);
void update_irq();
void set_irq(uint8_t sc , int state);
+
+ DECLARE_WRITE8_MEMBER(pa_w);
+ void update_flg_sts();
+ void set_sts(uint8_t sc , int state);
+ void set_flg(uint8_t sc , int state);
};
void hp9825_state::machine_start()
@@ -139,13 +155,17 @@ void hp9825_state::machine_reset()
m_irl_pending = 0;
m_irh_pending = 0;
update_irq();
+ m_pa = 0;
+ m_flg_status = 0;
+ m_sts_status = 0;
}
void hp9825_state::cpu_io_map(address_map &map)
{
map.unmap_value_low();
- map(HP_MAKE_IOADDR(0 , 0) , HP_MAKE_IOADDR(0 , 0)).rw(FUNC(hp9825_state::kb_scancode_r) , FUNC(hp9825_state::disp_w));
- map(HP_MAKE_IOADDR(0 , 1) , HP_MAKE_IOADDR(0 , 1)).rw(FUNC(hp9825_state::kdp_status_r) , FUNC(hp9825_state::kdp_control_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(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:
}
@@ -163,7 +183,7 @@ READ16_MEMBER(hp9825_state::kb_scancode_r)
if (m_shift_key->read()) {
BIT_SET(res , 7);
}
- set_irq(0 , false);
+ set_irq(KDP_PA , false);
return res;
}
@@ -417,7 +437,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(hp9825_state::kb_scan)
if (max_seq_len) {
m_scancode = max_seq_idx;
m_key_pressed = true;
- set_irq(0 , true);
+ set_irq(KDP_PA , true);
}
}
@@ -431,7 +451,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(hp9825_state::kb_scan)
}
if (m_autorepeating && BIT(~prev_cnt & m_autorepeat_cnt , 3)) {
// Repeat key every time bit 3 of autorepeat counter goes 0->1
- set_irq(0 , true);
+ set_irq(KDP_PA , true);
}
} else {
m_autorepeating = false;
@@ -488,6 +508,44 @@ void hp9825_state::set_irq(uint8_t sc , int state)
update_irq();
}
+WRITE8_MEMBER(hp9825_state::pa_w)
+{
+ m_pa = data;
+ update_flg_sts();
+}
+
+void hp9825_state::update_flg_sts()
+{
+ bool sts = BIT(m_sts_status , m_pa);
+ bool flg = BIT(m_flg_status , m_pa);
+ m_cpu->status_w(sts);
+ m_cpu->flag_w(flg);
+}
+
+void hp9825_state::set_sts(uint8_t sc , int state)
+{
+ if (state) {
+ BIT_SET(m_sts_status, sc);
+ } else {
+ BIT_CLR(m_sts_status, sc);
+ }
+ if (sc == m_pa) {
+ update_flg_sts();
+ }
+}
+
+void hp9825_state::set_flg(uint8_t sc , int state)
+{
+ if (state) {
+ BIT_SET(m_flg_status, sc);
+ } else {
+ BIT_CLR(m_flg_status, sc);
+ }
+ if (sc == m_pa) {
+ update_flg_sts();
+ }
+}
+
MACHINE_CONFIG_START(hp9825_state::hp9825b)
HP_09825_67907(config , m_cpu , MAIN_CLOCK);
// Just guessing... settings borrowed from hp9845
@@ -496,12 +554,19 @@ MACHINE_CONFIG_START(hp9825_state::hp9825b)
m_cpu->set_addrmap(AS_PROGRAM , &hp9825_state::cpu_mem_map);
m_cpu->set_addrmap(AS_IO , &hp9825_state::cpu_io_map);
m_cpu->set_irq_acknowledge_callback(FUNC(hp9825_state::irq_callback));
+ m_cpu->pa_changed_cb().set(FUNC(hp9825_state::pa_w));
TIMER(config , m_cursor_timer , 0).configure_generic(timer_device::expired_delegate(FUNC(hp9825_state::cursor_blink) , this));
// Keyboard scan timer. A scan of the whole keyboard should take 2^14 KDP clocks.
TIMER(config , "kb_timer" , 0).configure_periodic(timer_device::expired_delegate(FUNC(hp9825_state::kb_scan) , this) , attotime::from_ticks(16384 , KDP_CLOCK));
+ // Tape drive
+ HP9825_TAPE(config , m_tape , 0);
+ m_tape->flg().set([this , sc = TAPE_PA](int state) { set_flg(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));
+
config.set_default_layout(layout_hp9825);
MACHINE_CONFIG_END