summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author fulivi <fulivi@users.noreply.github.com>2021-03-07 19:31:39 +0100
committer GitHub <noreply@github.com>2021-03-07 13:31:39 -0500
commit3fe689f03fddb5b921bbec5e631cb3e1ead8f232 (patch)
tree279219061f011860ab8b7b6da467f795c1cddea9
parent61caa1450b534a90fa09f20c084ed45893098725 (diff)
HP9845: added synchronous I/O for RS232 port and HP98046 module (#7695)
* rs232: added device for synchronous I/O * hp9845: implemented external clocking in hp98046 serial module Co-authored-by: ajrhacker <ajrhacker@users.noreply.github.com>
-rw-r--r--scripts/src/bus.lua2
-rw-r--r--src/devices/bus/hp9845_io/98046.cpp138
-rw-r--r--src/devices/bus/hp9845_io/98046.h17
-rw-r--r--src/devices/bus/rs232/rs232.cpp2
-rw-r--r--src/devices/bus/rs232/rs232_sync_io.cpp213
-rw-r--r--src/devices/bus/rs232/rs232_sync_io.h61
-rw-r--r--src/mame/drivers/hp9845.cpp3
7 files changed, 351 insertions, 85 deletions
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index bae08d7d3d1..74f601e7499 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -2631,6 +2631,8 @@ if (BUSES["RS232"]~=null) then
MAME_DIR .. "src/devices/bus/rs232/swtpc8212.h",
MAME_DIR .. "src/devices/bus/rs232/exorterm.cpp",
MAME_DIR .. "src/devices/bus/rs232/exorterm.h",
+ MAME_DIR .. "src/devices/bus/rs232/rs232_sync_io.cpp",
+ MAME_DIR .. "src/devices/bus/rs232/rs232_sync_io.h",
}
end
diff --git a/src/devices/bus/hp9845_io/98046.cpp b/src/devices/bus/hp9845_io/98046.cpp
index 8e977129a76..8b7e601f0f4 100644
--- a/src/devices/bus/hp9845_io/98046.cpp
+++ b/src/devices/bus/hp9845_io/98046.cpp
@@ -55,12 +55,6 @@ namespace {
}
}
-// Timers
-enum {
- TMR_ID_RXC,
- TMR_ID_TXC
-};
-
// device type definition
DEFINE_DEVICE_TYPE(HP98046_IO_CARD, hp98046_io_card_device , "hp98046" , "HP98046 card")
@@ -70,6 +64,8 @@ hp98046_io_card_device::hp98046_io_card_device(const machine_config &mconfig, co
, m_cpu(*this, "cpu")
, m_sio(*this, "sio")
, m_rs232(*this, "rs232")
+ , m_tx_brg(*this , "tx_brg")
+ , m_rx_brg(*this , "rx_brg")
, m_loopback_en(*this, "loop")
{
}
@@ -195,7 +191,16 @@ void hp98046_io_card_device::device_add_mconfig(machine_config &config)
m_rs232->dcd_handler().set(FUNC(hp98046_io_card_device::rs232_dcd_w));
m_rs232->dsr_handler().set(FUNC(hp98046_io_card_device::rs232_dsr_w));
m_rs232->cts_handler().set(FUNC(hp98046_io_card_device::rs232_cts_w));
- config.set_maximum_quantum(attotime::from_hz(5000));
+ m_rs232->rxc_handler().set(FUNC(hp98046_io_card_device::rs232_rxc_w));
+ m_rs232->txc_handler().set(FUNC(hp98046_io_card_device::rs232_txc_w));
+ // There's just one 2.4576 MHz xtal, Tx BRG gets its clock from Rx BRG
+ F4702(config , m_tx_brg , 2.4576_MHz_XTAL);
+ m_tx_brg->s_callback().set([this]() { return m_txc_sel; });
+ m_tx_brg->z_callback().set(FUNC(hp98046_io_card_device::txc_w));
+ F4702(config , m_rx_brg , 2.4576_MHz_XTAL);
+ m_rx_brg->s_callback().set([this]() { return m_rxc_sel; });
+ m_rx_brg->z_callback().set(FUNC(hp98046_io_card_device::rxc_w));
+ config.set_maximum_quantum(attotime::from_hz(307200));
}
static INPUT_PORTS_START(hp98046_port)
@@ -233,9 +238,6 @@ void hp98046_io_card_device::device_start()
{
m_ram = std::make_unique<uint8_t[]>(1024);
save_pointer(NAME(m_ram) , 1024);
-
- m_rxc_timer = timer_alloc(TMR_ID_RXC);
- m_txc_timer = timer_alloc(TMR_ID_TXC);
}
void hp98046_io_card_device::device_reset()
@@ -247,36 +249,6 @@ void hp98046_io_card_device::device_reset()
update_sts();
update_irq();
m_loopback = m_loopback_en->read() != 0;
- // Ensure timers are loaded the 1st time BRGs are configured
- m_rxc_sel = ~0;
- m_txc_sel = ~0;
- m_rxc_timer->reset();
- m_txc_timer->reset();
-}
-
-void hp98046_io_card_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
-{
- switch (id) {
- case TMR_ID_RXC:
- m_rxc = !m_rxc;
- m_sio->rxca_w(m_rxc);
- if (m_loopback && (m_txc_sel == 0 || m_txc_sel == 1)) {
- m_sio->txca_w(m_rxc);
- m_sio->txcb_w(m_rxc);
- m_sio->rxcb_w(m_rxc);
- }
- break;
-
- case TMR_ID_TXC:
- m_txc = !m_txc;
- m_sio->txca_w(m_txc);
- m_sio->txcb_w(m_txc);
- m_sio->rxcb_w(m_txc);
- if (m_loopback && (m_rxc_sel == 0 || m_rxc_sel == 1)) {
- m_sio->rxca_w(m_txc);
- }
- break;
- }
}
void hp98046_io_card_device::cpu_program_map(address_map &map)
@@ -405,7 +377,8 @@ void hp98046_io_card_device::cpu_w(offs_t offset, uint8_t data)
case 3:
// xxxx'x111: write to BRGs
- set_brgs(data);
+ m_rxc_sel = (data >> 4) & 0xf;
+ m_txc_sel = data & 0xf;
break;
}
} else {
@@ -519,6 +492,20 @@ WRITE_LINE_MEMBER(hp98046_io_card_device::rs232_cts_w)
}
}
+WRITE_LINE_MEMBER(hp98046_io_card_device::rs232_rxc_w)
+{
+ if (!m_loopback) {
+ machine().scheduler().synchronize(timer_expired_delegate(FUNC(hp98046_io_card_device::sync_rx_im_w) , this) , state);
+ }
+}
+
+WRITE_LINE_MEMBER(hp98046_io_card_device::rs232_txc_w)
+{
+ if (!m_loopback) {
+ machine().scheduler().synchronize(timer_expired_delegate(FUNC(hp98046_io_card_device::sync_tx_im_w) , this) , state);
+ }
+}
+
bool hp98046_io_card_device::rx_fifo_flag() const
{
return m_rx_fifo.queue_length() >= 16;
@@ -643,43 +630,36 @@ uint8_t hp98046_io_card_device::get_hs_input() const
return res;
}
-// Frequencies of HD4702 BRGs
-// All frequencies are doubled here because the timers expire twice per RxC/TxC period
-static const unsigned brg_freq[] = {
- // Sel: frequency Divisor
- // ============================
- 0, // 0: external clock -
- 0, // 1: external clock -
- 1600, // 2: 50 x16 /3072
- 2400, // 3: 75 x16 /2048
- 4267, // 4: ~134.5 x16 /1152
- 6400, // 5: 200 x16 /768
- 19200, // 6: 600 x16 /256
- 76800, // 7: 2400 x16 /64
- 307200, // 8: 9600 x16 /16
- 153600, // 9: 4800 x16 /32
- 57600, // 10: 1800 x16 / 256/3
- 38400, // 11: 1200 x16 /128
- 76800, // 12: 2400 x16 /64
- 9600, // 13: 300 x16 /512
- 4800, // 14: 150 x16 /1024
- 3491 // 15: ~110 x16 /1408
-};
-
-void hp98046_io_card_device::set_brgs(uint8_t sel)
-{
- LOG_MCU("BRG=%02x\n" , sel);
- uint8_t new_rxc_sel = (sel >> 4) & 0xf;
- uint8_t new_txc_sel = sel & 0xf;
-
- if (new_rxc_sel != m_rxc_sel) {
- m_rxc_sel = new_rxc_sel;
- auto period = attotime::from_hz(brg_freq[ m_rxc_sel ]);
- m_rxc_timer->adjust(period , 0 , period);
- }
- if (new_txc_sel != m_txc_sel) {
- m_txc_sel = new_txc_sel;
- auto period = attotime::from_hz(brg_freq[ m_txc_sel ]);
- m_txc_timer->adjust(period , 0 , period);
+WRITE_LINE_MEMBER(hp98046_io_card_device::rxc_w)
+{
+ if (m_last_rxc != bool(state)) {
+ m_last_rxc = bool(state);
+ m_sio->rxca_w(m_last_rxc);
+ if (m_loopback) {
+ machine().scheduler().synchronize(timer_expired_delegate(FUNC(hp98046_io_card_device::sync_tx_im_w) , this) , state);
+ }
}
}
+
+WRITE_LINE_MEMBER(hp98046_io_card_device::txc_w)
+{
+ if (m_last_txc != bool(state)) {
+ m_last_txc = bool(state);
+ m_sio->txca_w(m_last_txc);
+ m_sio->txcb_w(m_last_txc);
+ m_sio->rxcb_w(m_last_txc);
+ if (m_loopback) {
+ machine().scheduler().synchronize(timer_expired_delegate(FUNC(hp98046_io_card_device::sync_rx_im_w) , this) , state);
+ }
+ }
+}
+
+TIMER_CALLBACK_MEMBER(hp98046_io_card_device::sync_rx_im_w)
+{
+ m_rx_brg->im_w(param);
+}
+
+TIMER_CALLBACK_MEMBER(hp98046_io_card_device::sync_tx_im_w)
+{
+ m_tx_brg->im_w(param);
+}
diff --git a/src/devices/bus/hp9845_io/98046.h b/src/devices/bus/hp9845_io/98046.h
index fb8197de6fb..90debbb8c03 100644
--- a/src/devices/bus/hp9845_io/98046.h
+++ b/src/devices/bus/hp9845_io/98046.h
@@ -17,6 +17,7 @@
#include "cpu/mcs48/mcs48.h"
#include "machine/z80sio.h"
#include "bus/rs232/rs232.h"
+#include "machine/f4702.h"
class hp98046_io_card_device : public device_t, public device_hp9845_io_interface
{
@@ -37,12 +38,13 @@ protected:
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void device_start() override;
virtual void device_reset() override;
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
private:
required_device<i8048_device> m_cpu;
required_device<z80sio_device> m_sio;
required_device<rs232_port_device> m_rs232;
+ required_device<f4702_device> m_tx_brg;
+ required_device<f4702_device> m_rx_brg;
required_ioport m_loopback_en;
std::unique_ptr<uint8_t[]> m_ram;
@@ -64,13 +66,11 @@ private:
bool m_sio_int;
uint8_t m_port_2;
bool m_loopback;
+ bool m_last_rxc;
+ bool m_last_txc;
- emu_timer *m_rxc_timer;
- emu_timer *m_txc_timer;
uint8_t m_rxc_sel;
uint8_t m_txc_sel;
- bool m_rxc;
- bool m_txc;
void cpu_program_map(address_map &map);
void cpu_io_map(address_map &map);
@@ -85,6 +85,8 @@ private:
DECLARE_WRITE_LINE_MEMBER(rs232_dcd_w);
DECLARE_WRITE_LINE_MEMBER(rs232_dsr_w);
DECLARE_WRITE_LINE_MEMBER(rs232_cts_w);
+ DECLARE_WRITE_LINE_MEMBER(rs232_rxc_w);
+ DECLARE_WRITE_LINE_MEMBER(rs232_txc_w);
bool rx_fifo_flag() const;
bool tx_fifo_flag() const;
void update_flg();
@@ -94,7 +96,10 @@ private:
void load_tx_fifo();
void set_r6_r7_pending(bool state);
uint8_t get_hs_input() const;
- void set_brgs(uint8_t sel);
+ DECLARE_WRITE_LINE_MEMBER(rxc_w);
+ DECLARE_WRITE_LINE_MEMBER(txc_w);
+ TIMER_CALLBACK_MEMBER(sync_rx_im_w);
+ TIMER_CALLBACK_MEMBER(sync_tx_im_w);
};
// device type definitions
diff --git a/src/devices/bus/rs232/rs232.cpp b/src/devices/bus/rs232/rs232.cpp
index d55628d64c4..ce3446a85b7 100644
--- a/src/devices/bus/rs232/rs232.cpp
+++ b/src/devices/bus/rs232/rs232.cpp
@@ -171,6 +171,7 @@ device_rs232_port_interface::~device_rs232_port_interface()
#include "swtpc8212.h"
#include "terminal.h"
#include "ie15.h"
+#include "rs232_sync_io.h"
void default_rs232_devices(device_slot_interface &device)
{
@@ -182,6 +183,7 @@ void default_rs232_devices(device_slot_interface &device)
device.option_add("printer", SERIAL_PRINTER);
device.option_add("pty", PSEUDO_TERMINAL);
device.option_add("rs_printer", RADIO_SHACK_SERIAL_PRINTER);
+ device.option_add("rs232_sync_io", RS232_SYNC_IO);
device.option_add("sunkbd", SUN_KBD_ADAPTOR);
device.option_add("swtpc8212", SERIAL_TERMINAL_SWTPC8212);
device.option_add("terminal", SERIAL_TERMINAL);
diff --git a/src/devices/bus/rs232/rs232_sync_io.cpp b/src/devices/bus/rs232/rs232_sync_io.cpp
new file mode 100644
index 00000000000..8977ece64b6
--- /dev/null
+++ b/src/devices/bus/rs232/rs232_sync_io.cpp
@@ -0,0 +1,213 @@
+// license:BSD-3-Clause
+// copyright-holders: F. Ulivi
+/*********************************************************************
+
+ rs232_sync_io.cpp
+
+ Synchronous I/O on RS232 port
+
+ This device provides a bitbanger-based interface to a synchronous
+ RS232 port.
+ It has the following functions:
+ - Provides Tx and/or Rx clock to RS232 port; clocks can be
+ individually turned off when not needed (e.g. Tx clock can
+ disabled when receiving in half-duplex mode)
+ - In the tx direction, it gathers bits from TxD,
+ packs them into bytes LSB to MSB, then sends them out to
+ bitbanger
+ - In the rx direction, it extracts bytes from bitbanger
+ and serializes them to RxD, LSB to MSB.
+ - Supports both full-duplex and half-duplex modes
+ - Generates CTS signal
+
+ There's no kind of synchronization to any higher-level framing:
+ bits are just clocked in/out of the port, packed/unpacked into
+ bytes and exchanged with bitbanger.
+ There's also no automatic stuffing of idle line characters, this
+ function is to be implemented externally if needed.
+
+*********************************************************************/
+
+#include "emu.h"
+#include "rs232_sync_io.h"
+
+// Debugging
+
+#include "logmacro.h"
+//#undef VERBOSE
+//#define VERBOSE LOG_GENERAL
+
+// Bit manipulation
+namespace {
+ template<typename T> constexpr T BIT_MASK(unsigned n)
+ {
+ return (T)1U << n;
+ }
+
+ template<typename T> void BIT_CLR(T& w , unsigned n)
+ {
+ w &= ~BIT_MASK<T>(n);
+ }
+
+ template<typename T> void BIT_SET(T& w , unsigned n)
+ {
+ w |= BIT_MASK<T>(n);
+ }
+}
+
+// Timers
+enum {
+ TMR_ID_CLK
+};
+
+rs232_sync_io_device::rs232_sync_io_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig , RS232_SYNC_IO , tag , owner , clock)
+ , device_rs232_port_interface(mconfig , *this)
+ , m_stream(*this , "stream")
+ , m_rs232_baud(*this , "RS232_BAUD")
+ , m_rts_duplex(*this , "rtsduplex")
+ , m_txc_setting(*this , "txcontrol")
+ , m_rxc_setting(*this , "rxcontrol")
+{
+}
+
+rs232_sync_io_device:: ~rs232_sync_io_device()
+{
+}
+
+WRITE_LINE_MEMBER(rs232_sync_io_device::input_txd)
+{
+ m_txd = state;
+ LOG("TxD %d %u\n" , state , m_tx_counter);
+}
+
+WRITE_LINE_MEMBER(rs232_sync_io_device::input_rts)
+{
+ m_rts = state;
+}
+
+static INPUT_PORTS_START(rs232_sync_io)
+ PORT_RS232_BAUD("RS232_BAUD" , RS232_BAUD_2400 , "Baud rate" , rs232_sync_io_device , update_serial)
+
+ PORT_START("rtsduplex")
+ PORT_CONFNAME(1 , 1 , "RTS controls half-duplex")
+ PORT_CONFSETTING(0 , DEF_STR(Off))
+ PORT_CONFSETTING(1 , DEF_STR(On))
+
+ PORT_START("txcontrol")
+ PORT_CONFNAME(1 , 1 , "TxC generated")
+ PORT_CONFSETTING(0 , "Always")
+ PORT_CONFSETTING(1 , "When Tx is active")
+
+ PORT_START("rxcontrol")
+ PORT_CONFNAME(3 , 1 , "RxC generated")
+ PORT_CONFSETTING(0 , "Always")
+ PORT_CONFSETTING(1 , "When Rx is active")
+ PORT_CONFSETTING(2 , "When a byte is available")
+INPUT_PORTS_END
+
+ioport_constructor rs232_sync_io_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(rs232_sync_io);
+}
+
+void rs232_sync_io_device::device_add_mconfig(machine_config &config)
+{
+ BITBANGER(config , m_stream , 0);
+}
+
+void rs232_sync_io_device::device_start()
+{
+ m_clk_timer = timer_alloc(TMR_ID_CLK);
+}
+
+void rs232_sync_io_device::device_reset()
+{
+ output_dcd(0);
+ output_dsr(0);
+ output_rxd(1);
+ output_cts(1);
+
+ update_serial(0);
+
+ m_clk = false;
+ m_rx_byte = 0xff;
+ m_rx_counter = 0;
+ m_tx_counter = 0;
+ m_tx_enabled = false;
+ m_rx_enabled = false;
+
+ output_txc(1);
+ output_rxc(1);
+}
+
+void rs232_sync_io_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ switch (id) {
+ case TMR_ID_CLK:
+ m_clk = !m_clk;
+ if (m_clk) {
+ output_txc(1);
+ output_rxc(1);
+ if (m_tx_enabled) {
+ // Rising edge: capture TxD
+ m_tx_byte = (m_tx_byte >> 1) & 0x7f;
+ if (m_txd) {
+ BIT_SET(m_tx_byte , 7);
+ }
+ if (++m_tx_counter >= 8) {
+ LOG("Tx %02x @%s\n" , m_tx_byte , machine().time().to_string());
+ m_tx_counter = 0;
+ m_stream->output(m_tx_byte);
+ m_tx_enabled = false;
+ }
+ }
+ } else {
+ if (!m_tx_enabled) {
+ m_tx_enabled = !m_rts || !m_rts_duplex->read();
+ output_cts(!m_tx_enabled);
+ }
+ if (m_tx_enabled || m_txc_setting->read() == 0) {
+ output_txc(0);
+ }
+ if (!m_rx_enabled) {
+ m_rx_enabled = m_rts || !m_rts_duplex->read();
+ if (m_rx_enabled) {
+ if (m_stream->input(&m_rx_byte , 1) == 0) {
+ m_rx_byte = ~0;
+ if (m_rxc_setting->read() == 2) {
+ m_rx_enabled = false;
+ }
+ } else {
+ LOG("Rx %02x @%s\n" , m_rx_byte , machine().time().to_string());
+ }
+ }
+ }
+ if (m_rx_enabled || m_rxc_setting->read() == 0) {
+ output_rxc(0);
+ }
+ if (m_rx_enabled) {
+ // Falling edge: update RxD
+ output_rxd(BIT(m_rx_byte , 0));
+ m_rx_byte >>= 1;
+ if (++m_rx_counter >= 8) {
+ m_rx_counter = 0;
+ m_rx_enabled = false;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+WRITE_LINE_MEMBER(rs232_sync_io_device::update_serial)
+{
+ auto baud_rate = convert_baud(m_rs232_baud->read());
+ auto period = attotime::from_hz(baud_rate * 2);
+ m_clk_timer->adjust(period , 0 , period);
+}
+
+DEFINE_DEVICE_TYPE(RS232_SYNC_IO, rs232_sync_io_device, "rs232_sync_io", "RS232 Synchronous I/O")
diff --git a/src/devices/bus/rs232/rs232_sync_io.h b/src/devices/bus/rs232/rs232_sync_io.h
new file mode 100644
index 00000000000..de43eda5ece
--- /dev/null
+++ b/src/devices/bus/rs232/rs232_sync_io.h
@@ -0,0 +1,61 @@
+// license:BSD-3-Clause
+// copyright-holders: F. Ulivi
+/*********************************************************************
+
+ rs232_sync_io.h
+
+ Synchronous I/O on RS232 port
+
+*********************************************************************/
+
+#ifndef MAME_BUS_RS232_RS232_SYNC_IO_H
+#define MAME_BUS_RS232_RS232_SYNC_IO_H
+
+#pragma once
+
+#include "rs232.h"
+#include "imagedev/bitbngr.h"
+
+class rs232_sync_io_device : public device_t, public device_rs232_port_interface
+{
+public:
+ // construction/destruction
+ rs232_sync_io_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ virtual ~rs232_sync_io_device();
+
+ virtual DECLARE_WRITE_LINE_MEMBER(input_txd) override;
+ virtual DECLARE_WRITE_LINE_MEMBER(input_rts) override;
+
+ DECLARE_WRITE_LINE_MEMBER(update_serial);
+
+protected:
+ // device-level overrides
+ virtual ioport_constructor device_input_ports() const override;
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+
+private:
+ required_device<bitbanger_device> m_stream;
+ required_ioport m_rs232_baud;
+ required_ioport m_rts_duplex;
+ required_ioport m_txc_setting;
+ required_ioport m_rxc_setting;
+
+ emu_timer *m_clk_timer;
+ bool m_clk;
+ bool m_txd;
+ bool m_rts;
+ bool m_tx_enabled;
+ bool m_rx_enabled;
+ uint8_t m_tx_byte;
+ uint8_t m_rx_byte;
+ uint8_t m_tx_counter;
+ uint8_t m_rx_counter;
+};
+
+// device type definitions
+DECLARE_DEVICE_TYPE(RS232_SYNC_IO, rs232_sync_io_device)
+
+#endif // MAME_BUS_RS232_RS232_SYNC_IO_H
diff --git a/src/mame/drivers/hp9845.cpp b/src/mame/drivers/hp9845.cpp
index ed279a0d64c..7976c54cbc9 100644
--- a/src/mame/drivers/hp9845.cpp
+++ b/src/mame/drivers/hp9845.cpp
@@ -3641,11 +3641,14 @@ void hp9845_base_state::ppu_io_map(address_map &map)
void hp9845_base_state::hp9845_base(machine_config &config)
{
HP_5061_3001(config , m_lpu , 5700000);
+ // Clock scaling takes into account the slowdown caused by DRAM refresh
+ m_lpu->set_clock_scale(0.93);
m_lpu->set_addrmap(AS_PROGRAM , &hp9845_base_state::global_mem_map);
m_lpu->set_9845_boot_mode(true);
m_lpu->set_rw_cycles(6 , 6);
m_lpu->set_relative_mode(true);
HP_5061_3001(config , m_ppu , 5700000);
+ m_ppu->set_clock_scale(0.93);
m_ppu->set_addrmap(AS_PROGRAM , &hp9845_base_state::global_mem_map);
m_ppu->set_addrmap(AS_IO , &hp9845_base_state::ppu_io_map);
m_ppu->set_9845_boot_mode(true);