mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00
Hp9845: added 98046 module emulation (#5115)
* hp9845: fixed handling of optional ROMs (nw) * z80sio: massive enhancement to Z80 SIO driven by HP98046 test sw * hp9845: implemented the HP98046 serial I/O module
This commit is contained in:
parent
ecf043eca1
commit
41c456c3a6
@ -3686,6 +3686,8 @@ if (BUSES["HP9845_IO"]~=null) then
|
||||
MAME_DIR .. "src/devices/bus/hp9845_io/98034.h",
|
||||
MAME_DIR .. "src/devices/bus/hp9845_io/98035.cpp",
|
||||
MAME_DIR .. "src/devices/bus/hp9845_io/98035.h",
|
||||
MAME_DIR .. "src/devices/bus/hp9845_io/98046.cpp",
|
||||
MAME_DIR .. "src/devices/bus/hp9845_io/98046.h",
|
||||
MAME_DIR .. "src/devices/bus/hp9845_io/hp9885.cpp",
|
||||
MAME_DIR .. "src/devices/bus/hp9845_io/hp9885.h",
|
||||
}
|
||||
|
684
src/devices/bus/hp9845_io/98046.cpp
Normal file
684
src/devices/bus/hp9845_io/98046.cpp
Normal file
@ -0,0 +1,684 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders: F. Ulivi
|
||||
/*********************************************************************
|
||||
|
||||
98046.cpp
|
||||
|
||||
98046 module (data communications interface)
|
||||
|
||||
Fun fact: I didn't need to dump the fw in 8048 MCU because,
|
||||
in a way, it's already "dumped" in the test sw. Basically, to
|
||||
test the correctness of the ROM content, the HP sw reads out the
|
||||
whole ROM and compares it to the known good image...
|
||||
|
||||
Main reference for this module:
|
||||
HP, 98046B Interface Installation and Service
|
||||
|
||||
Test software:
|
||||
HP, 98046-90449, 98046 Interface Test
|
||||
(see http://www.hpmuseum.net/display_item.php?sw=324)
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "98046.h"
|
||||
|
||||
// Debugging
|
||||
|
||||
#include "logmacro.h"
|
||||
#define LOG_IFS_MASK (LOG_GENERAL << 1)
|
||||
#define LOG_IFS(...) LOGMASKED(LOG_IFS_MASK, __VA_ARGS__)
|
||||
#define LOG_MCU_MASK (LOG_IFS_MASK << 1)
|
||||
#define LOG_MCU(...) LOGMASKED(LOG_MCU_MASK, __VA_ARGS__)
|
||||
#define LOG_CPU_MASK (LOG_MCU_MASK << 1)
|
||||
#define LOG_CPU(...) LOGMASKED(LOG_CPU_MASK, __VA_ARGS__)
|
||||
#define LOG_SIO_MASK (LOG_CPU_MASK << 1)
|
||||
#define LOG_SIO(...) LOGMASKED(LOG_SIO_MASK, __VA_ARGS__)
|
||||
//#undef VERBOSE
|
||||
//#define VERBOSE (LOG_GENERAL | LOG_MCU_MASK | LOG_CPU_MASK | LOG_SIO_MASK)
|
||||
|
||||
// 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_RXC,
|
||||
TMR_ID_TXC
|
||||
};
|
||||
|
||||
// device type definition
|
||||
DEFINE_DEVICE_TYPE(HP98046_IO_CARD, hp98046_io_card_device , "hp98046" , "HP98046 card")
|
||||
|
||||
hp98046_io_card_device::hp98046_io_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: hp9845_io_card_device(mconfig , HP98046_IO_CARD , tag , owner , clock)
|
||||
, m_cpu(*this , "cpu")
|
||||
, m_sio(*this , "sio")
|
||||
, m_rs232(*this , "rs232")
|
||||
, m_loopback_en(*this , "loop")
|
||||
{
|
||||
}
|
||||
|
||||
hp98046_io_card_device::~hp98046_io_card_device()
|
||||
{
|
||||
}
|
||||
|
||||
READ16_MEMBER(hp98046_io_card_device::reg_r)
|
||||
{
|
||||
uint16_t res = 0;
|
||||
|
||||
switch (offset) {
|
||||
case 0:
|
||||
// R4
|
||||
// Read from rxFIFO
|
||||
if (!rx_fifo_flag()) {
|
||||
m_rxfifo_irq = false;
|
||||
update_irq();
|
||||
}
|
||||
res = ~m_rx_fifo.dequeue() & 0x1ff;
|
||||
// Save bit 8 of new word at output of rx FIFO
|
||||
if (!m_rx_fifo.empty()) {
|
||||
m_rx_fifo_out_b8 = BIT(m_rx_fifo.peek() , 8);
|
||||
}
|
||||
update_flg();
|
||||
update_sts();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// R5
|
||||
if (m_rxfifo_overrun) {
|
||||
BIT_SET(res , 15);
|
||||
}
|
||||
BIT_SET(res , 11);
|
||||
if (m_inten) {
|
||||
BIT_SET(res , 7);
|
||||
}
|
||||
if (!m_r6_r7_pending) {
|
||||
BIT_SET(res , 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// R6: not mapped
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// R7: not mapped
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_CPU("rd R%u=%04x\n" , offset + 4 , res);
|
||||
return res;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(hp98046_io_card_device::reg_w)
|
||||
{
|
||||
LOG_CPU("wr R%u=%04x\n" , offset + 4 , data);
|
||||
|
||||
switch (offset) {
|
||||
case 0:
|
||||
// R4
|
||||
// Write to txFIFO
|
||||
m_tx_fifo_in = (data ^ 0x00ff) & 0x1ff;
|
||||
m_tx_fifo_pending = true;
|
||||
load_tx_fifo();
|
||||
space.device().execute().yield();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// R5
|
||||
if (BIT(data , 5)) {
|
||||
// 8048 reset
|
||||
m_cpu->pulse_input_line(INPUT_LINE_RESET , attotime::zero);
|
||||
m_inten = false;
|
||||
} else if (BIT(m_port_2 , 7)) {
|
||||
// When SIORST is active, inten always sets to 0
|
||||
m_inten = false;
|
||||
} else {
|
||||
m_inten = BIT(data , 7);
|
||||
}
|
||||
m_enoutint = BIT(data , 0);
|
||||
update_irq();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// R6
|
||||
case 3:
|
||||
// R7
|
||||
m_r6_r7_select = offset == 3;
|
||||
m_r6_r7 = ~data & 0xff;
|
||||
set_r6_r7_pending(true);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool hp98046_io_card_device::has_dual_sc() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void hp98046_io_card_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
I8048(config , m_cpu , 6_MHz_XTAL);
|
||||
m_cpu->set_addrmap(AS_PROGRAM , &hp98046_io_card_device::cpu_program_map);
|
||||
m_cpu->set_addrmap(AS_IO , &hp98046_io_card_device::cpu_io_map);
|
||||
m_cpu->p1_in_cb().set(FUNC(hp98046_io_card_device::p1_r));
|
||||
m_cpu->p2_out_cb().set(FUNC(hp98046_io_card_device::p2_w));
|
||||
m_cpu->t1_in_cb().set([this] () { return int(!m_sio_int); });
|
||||
// Clock to SIO is actually provided by T0 output of CPU
|
||||
Z80SIO(config , m_sio , 0);
|
||||
m_sio->out_int_callback().set(FUNC(hp98046_io_card_device::sio_int_w));
|
||||
m_sio->out_txda_callback().set(FUNC(hp98046_io_card_device::sio_txd_w));
|
||||
RS232_PORT(config, m_rs232, default_rs232_devices, nullptr);
|
||||
m_rs232->rxd_handler().set(FUNC(hp98046_io_card_device::rs232_rxd_w));
|
||||
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.m_minimum_quantum = attotime::from_hz(5000);
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START(hp98046_port)
|
||||
PORT_START("SC")
|
||||
PORT_CONFNAME(0xf , 4 - HP9845_IO_FIRST_SC , "Select Codes")
|
||||
PORT_CONFSETTING(1 , "2 3")
|
||||
PORT_CONFSETTING(3 , "4 5")
|
||||
PORT_CONFSETTING(5 , "6 7")
|
||||
PORT_CONFSETTING(7 , "8 9")
|
||||
PORT_CONFSETTING(9 , "10 11")
|
||||
PORT_CONFSETTING(11 , "12 13")
|
||||
|
||||
PORT_START("loop")
|
||||
PORT_CONFNAME(1 , 0 , "ESK loopback")
|
||||
PORT_CONFSETTING(0 , DEF_STR(Off))
|
||||
PORT_CONFSETTING(1 , DEF_STR(On))
|
||||
INPUT_PORTS_END
|
||||
|
||||
ioport_constructor hp98046_io_card_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(hp98046_port);
|
||||
}
|
||||
|
||||
ROM_START(hp98046)
|
||||
ROM_REGION(0x400, "cpu" , 0)
|
||||
ROM_LOAD("1820-2431.bin" , 0 , 0x400 , CRC(e6a068d6) SHA1(d19c35b18fae52b841060ed879f860fd2cae3482))
|
||||
ROM_END
|
||||
|
||||
const tiny_rom_entry *hp98046_io_card_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME(hp98046);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
m_port_2 = 0;
|
||||
m_inten = false;
|
||||
m_enoutint = false;
|
||||
update_flg();
|
||||
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)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map(0x000 , 0x3ff).rom();
|
||||
map(0x400 , 0x7ff).r(FUNC(hp98046_io_card_device::ram_r));
|
||||
}
|
||||
|
||||
void hp98046_io_card_device::cpu_io_map(address_map &map)
|
||||
{
|
||||
map(0 , 0xff).rw(FUNC(hp98046_io_card_device::cpu_r) , FUNC(hp98046_io_card_device::cpu_w));
|
||||
}
|
||||
|
||||
READ8_MEMBER(hp98046_io_card_device::ram_r)
|
||||
{
|
||||
return m_ram[ offset ];
|
||||
}
|
||||
|
||||
READ8_MEMBER(hp98046_io_card_device::cpu_r)
|
||||
{
|
||||
if (BIT(m_port_2 , 2)) {
|
||||
return m_ram[ (offset & 0xff) | (uint16_t(m_port_2 & 3) << 8) ];
|
||||
} else if (BIT(offset , 2)) {
|
||||
uint8_t res = ~0;
|
||||
|
||||
switch (offset & 3) {
|
||||
case 0:
|
||||
// xxxx'x100: read from tx FIFO
|
||||
res = uint8_t(m_tx_fifo.dequeue());
|
||||
load_tx_fifo();
|
||||
update_flg();
|
||||
update_irq();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// xxxx'x101: read HS
|
||||
res = get_hs_input();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// xxxx'x110: clear FIFOs
|
||||
m_tx_fifo.clear();
|
||||
m_rx_fifo.clear();
|
||||
load_tx_fifo();
|
||||
update_flg();
|
||||
update_sts();
|
||||
update_irq();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// xxxx'x111: read r6/r7
|
||||
res = m_r6_r7;
|
||||
set_r6_r7_pending(false);
|
||||
break;
|
||||
}
|
||||
LOG_MCU("CPU R @%02x=%02x\n" , offset , res);
|
||||
return res;
|
||||
} else {
|
||||
uint8_t res = m_sio->cd_ba_r(offset & 3);
|
||||
LOG_SIO("SIO R @%u=%02x\n" , offset & 3 , res);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(hp98046_io_card_device::cpu_w)
|
||||
{
|
||||
if (BIT(m_port_2 , 2)) {
|
||||
m_ram[ (offset & 0xff) | (uint16_t(m_port_2 & 3) << 8) ] = data;
|
||||
} else if (BIT(offset , 2)) {
|
||||
LOG_MCU("CPU W @%02x=%02x\n" , offset , data);
|
||||
switch (offset & 3) {
|
||||
case 0:
|
||||
// xxxx'x100: write to rx FIFO
|
||||
if (BIT(offset , 6)) {
|
||||
if (m_rx_fifo.full()) {
|
||||
m_rxfifo_overrun = true;
|
||||
}
|
||||
uint16_t w = data;
|
||||
if (BIT(offset , 7)) {
|
||||
BIT_SET(w , 8);
|
||||
}
|
||||
// If enqueuing first word, store bit 8
|
||||
if (m_rx_fifo.empty()) {
|
||||
m_rx_fifo_out_b8 = BIT(w , 8);
|
||||
}
|
||||
m_rx_fifo.enqueue(w);
|
||||
}
|
||||
if (rx_fifo_flag()) {
|
||||
m_rxfifo_irq = true;
|
||||
} else {
|
||||
// Logic of A1U21A 'LS109 JK FF (J=A3 K/=A4)
|
||||
switch (offset & 0x18) {
|
||||
case 0x00:
|
||||
m_rxfifo_irq = false;
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
m_rxfifo_irq = !m_rxfifo_irq;
|
||||
break;
|
||||
|
||||
case 0x10:
|
||||
break;
|
||||
|
||||
case 0x18:
|
||||
m_rxfifo_irq = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
update_flg();
|
||||
update_sts();
|
||||
update_irq();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// xxxx'x101: write HS
|
||||
m_hs_out = data;
|
||||
update_hs_out();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// xxxx'x110: clear rx FIFO overrun
|
||||
m_rxfifo_overrun = false;
|
||||
update_sts();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// xxxx'x111: write to BRGs
|
||||
set_brgs(data);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
LOG_SIO("%.6f SIO W @%u=%02x\n" , machine().time().as_double() , offset & 3 , data);
|
||||
m_sio->cd_ba_w(offset & 3 , data);
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER(hp98046_io_card_device::p1_r)
|
||||
{
|
||||
uint8_t res = 0;
|
||||
// b7: b8 of word @ txFIFO head
|
||||
if (BIT(m_tx_fifo.peek() , 8)) {
|
||||
BIT_SET(res , 7);
|
||||
}
|
||||
// b6: rxFIFO overrun
|
||||
if (!m_rxfifo_overrun) {
|
||||
BIT_SET(res , 6);
|
||||
}
|
||||
// b5: rxFIFO not empty
|
||||
if (!m_rx_fifo.empty()) {
|
||||
BIT_SET(res , 5);
|
||||
}
|
||||
// b4: R6(0)/R7(1)
|
||||
if (m_r6_r7_select) {
|
||||
BIT_SET(res , 4);
|
||||
}
|
||||
// b3: tx FIFO flag
|
||||
if (tx_fifo_flag()) {
|
||||
BIT_SET(res , 3);
|
||||
}
|
||||
// b2: tx FIFO not empty
|
||||
if (!m_tx_fifo.empty()) {
|
||||
BIT_SET(res , 2);
|
||||
}
|
||||
// b1: rx FIFO flag
|
||||
if (rx_fifo_flag()) {
|
||||
BIT_SET(res , 1);
|
||||
}
|
||||
// b0: rx FIFO not full
|
||||
if (!m_rx_fifo.full()) {
|
||||
BIT_SET(res , 0);
|
||||
}
|
||||
//LOG("p1=%02x\n" , res);
|
||||
return res;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(hp98046_io_card_device::p2_w)
|
||||
{
|
||||
LOG_MCU("p2=%02x\n" , data);
|
||||
uint8_t diff = data ^ m_port_2;
|
||||
m_port_2 = data;
|
||||
if (BIT(diff , 7)) {
|
||||
if (BIT(m_port_2 , 7)) {
|
||||
m_sio->reset();
|
||||
set_r6_r7_pending(true);
|
||||
}
|
||||
update_hs_out();
|
||||
}
|
||||
if (BIT(diff , 6)) {
|
||||
update_flg();
|
||||
}
|
||||
if (BIT(diff , 5)) {
|
||||
update_sts();
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp98046_io_card_device::sio_int_w)
|
||||
{
|
||||
if (m_sio_int != state) {
|
||||
LOG_SIO("SIO int=%d\n" , state);
|
||||
}
|
||||
m_sio_int = state;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp98046_io_card_device::sio_txd_w)
|
||||
{
|
||||
m_sio->rxb_w(state);
|
||||
if (m_loopback) {
|
||||
m_sio->rxa_w(state);
|
||||
} else {
|
||||
m_rs232->write_txd(state);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp98046_io_card_device::rs232_rxd_w)
|
||||
{
|
||||
if (!m_loopback) {
|
||||
m_sio->rxa_w(state);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp98046_io_card_device::rs232_dcd_w)
|
||||
{
|
||||
if (!m_loopback) {
|
||||
m_sio->dcda_w(state);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp98046_io_card_device::rs232_dsr_w)
|
||||
{
|
||||
if (!m_loopback) {
|
||||
m_sio->dcdb_w(state);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp98046_io_card_device::rs232_cts_w)
|
||||
{
|
||||
if (!m_loopback) {
|
||||
m_sio->ctsa_w(state);
|
||||
}
|
||||
}
|
||||
|
||||
bool hp98046_io_card_device::rx_fifo_flag() const
|
||||
{
|
||||
return m_rx_fifo.queue_length() >= 16;
|
||||
}
|
||||
|
||||
bool hp98046_io_card_device::tx_fifo_flag() const
|
||||
{
|
||||
return m_tx_fifo.queue_length() >= 16;
|
||||
}
|
||||
|
||||
void hp98046_io_card_device::update_flg()
|
||||
{
|
||||
bool flg_e = !m_r6_r7_pending && !m_tx_fifo.full() && BIT(m_port_2 , 6);
|
||||
bool flg_o = !m_r6_r7_pending && !m_rx_fifo.empty();
|
||||
|
||||
LOG_IFS("FLG e/o=%d/%d\n" , flg_e , flg_o);
|
||||
flg_w(flg_e);
|
||||
flg_nextsc_w(flg_o);
|
||||
}
|
||||
|
||||
void hp98046_io_card_device::update_sts()
|
||||
{
|
||||
bool sts_e = !BIT(m_port_2 , 5);
|
||||
bool sts_o = !m_rxfifo_overrun && m_rx_fifo_out_b8;
|
||||
|
||||
LOG_IFS("STS e/o=%d/%d\n" , sts_e , sts_o);
|
||||
sts_w(sts_e);
|
||||
sts_nextsc_w(sts_o);
|
||||
}
|
||||
|
||||
void hp98046_io_card_device::update_irq()
|
||||
{
|
||||
bool irq = m_inten && !m_r6_r7_pending && (m_rxfifo_irq || (m_enoutint && !tx_fifo_flag()));
|
||||
bool irq_e = irq && !m_rxfifo_irq;
|
||||
bool irq_o = irq && m_rxfifo_irq;
|
||||
|
||||
LOG_IFS("IRQ e/o=%d/%d\n" , irq_e , irq_o);
|
||||
irq_w(irq_e);
|
||||
irq_nextsc_w(irq_o);
|
||||
}
|
||||
|
||||
void hp98046_io_card_device::update_hs_out()
|
||||
{
|
||||
if (BIT(m_port_2 , 7)) {
|
||||
m_actual_hs_out = ~0;
|
||||
} else {
|
||||
m_actual_hs_out = m_hs_out;
|
||||
}
|
||||
if (m_loopback) {
|
||||
m_sio->ctsa_w(BIT(m_actual_hs_out , 4));
|
||||
m_sio->dcda_w(BIT(m_actual_hs_out , 3));
|
||||
m_sio->ctsb_w(BIT(m_actual_hs_out , 2));
|
||||
m_sio->dcdb_w(BIT(m_actual_hs_out , 1));
|
||||
} else {
|
||||
m_rs232->write_dtr(BIT(m_actual_hs_out , 5));
|
||||
m_rs232->write_rts(BIT(m_actual_hs_out , 4));
|
||||
// b3 (A2J1-13) not mapped
|
||||
// b2 (A2J1-15) not mapped (Data Rate Select)
|
||||
// b1 (A2J1-30) not mapped (Secondary RTS)
|
||||
// b0 (A2J1-24) not mapped
|
||||
}
|
||||
}
|
||||
|
||||
void hp98046_io_card_device::load_tx_fifo()
|
||||
{
|
||||
if (m_tx_fifo_pending && !m_tx_fifo.full()) {
|
||||
m_tx_fifo.enqueue(m_tx_fifo_in);
|
||||
m_tx_fifo_pending = false;
|
||||
update_flg();
|
||||
update_irq();
|
||||
}
|
||||
}
|
||||
|
||||
void hp98046_io_card_device::set_r6_r7_pending(bool state)
|
||||
{
|
||||
m_r6_r7_pending = state || BIT(m_port_2 , 7);
|
||||
m_cpu->set_input_line(MCS48_INPUT_IRQ , m_r6_r7_pending ? ASSERT_LINE : CLEAR_LINE);
|
||||
update_flg();
|
||||
update_irq();
|
||||
}
|
||||
|
||||
uint8_t hp98046_io_card_device::get_hs_input() const
|
||||
{
|
||||
uint8_t res = 0xc1;
|
||||
if (m_loopback) {
|
||||
// DTR looped back into RI
|
||||
if (BIT(m_actual_hs_out , 5)) {
|
||||
BIT_SET(res , 5);
|
||||
}
|
||||
// RTS looped back into CTS
|
||||
if (BIT(m_actual_hs_out , 4)) {
|
||||
BIT_SET(res , 4);
|
||||
}
|
||||
// A2J1-13 looped back into DCD
|
||||
if (BIT(m_actual_hs_out , 3)) {
|
||||
BIT_SET(res , 3);
|
||||
}
|
||||
// DRS looped back into SCD
|
||||
if (BIT(m_actual_hs_out , 2)) {
|
||||
BIT_SET(res , 2);
|
||||
}
|
||||
// SRTS looped back into DSR
|
||||
if (BIT(m_actual_hs_out , 1)) {
|
||||
BIT_SET(res , 1);
|
||||
}
|
||||
} else {
|
||||
if (m_rs232->ri_r()) {
|
||||
BIT_SET(res , 5);
|
||||
}
|
||||
if (m_rs232->cts_r()) {
|
||||
BIT_SET(res , 4);
|
||||
}
|
||||
if (m_rs232->dcd_r()) {
|
||||
BIT_SET(res , 3);
|
||||
}
|
||||
// SCD always 1
|
||||
BIT_SET(res , 2);
|
||||
if (m_rs232->dsr_r()) {
|
||||
BIT_SET(res , 1);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
103
src/devices/bus/hp9845_io/98046.h
Normal file
103
src/devices/bus/hp9845_io/98046.h
Normal file
@ -0,0 +1,103 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders: F. Ulivi
|
||||
/*********************************************************************
|
||||
|
||||
98046.h
|
||||
|
||||
98046 module (data communications interface)
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef MAME_BUS_HP9845_IO_98046_H
|
||||
#define MAME_BUS_HP9845_IO_98046_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hp9845_io.h"
|
||||
#include "cpu/mcs48/mcs48.h"
|
||||
#include "machine/z80sio.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
|
||||
class hp98046_io_card_device : public hp9845_io_card_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
hp98046_io_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
virtual ~hp98046_io_card_device();
|
||||
|
||||
virtual DECLARE_READ16_MEMBER(reg_r) override;
|
||||
virtual DECLARE_WRITE16_MEMBER(reg_w) override;
|
||||
|
||||
virtual bool has_dual_sc() const override;
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual ioport_constructor device_input_ports() const override;
|
||||
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_ioport m_loopback_en;
|
||||
|
||||
std::unique_ptr<uint8_t[]> m_ram;
|
||||
util::fifo<uint16_t , 32> m_tx_fifo; // A1U7
|
||||
util::fifo<uint16_t , 32> m_rx_fifo; // A1U11
|
||||
bool m_rx_fifo_out_b8; // Bit 8 of rx FIFO output
|
||||
|
||||
uint16_t m_tx_fifo_in; // A1U1 & A1U9-8
|
||||
bool m_tx_fifo_pending; // A1U18-7
|
||||
uint8_t m_r6_r7; // A1U2
|
||||
bool m_r6_r7_pending; // A1U18-9
|
||||
bool m_r6_r7_select; // A1U18-13
|
||||
bool m_rxfifo_overrun; // A1U21-9
|
||||
bool m_rxfifo_irq; // A1U21-6
|
||||
bool m_inten; // A1U15-2
|
||||
bool m_enoutint; // A1U15-6
|
||||
uint8_t m_hs_out; // A2U4
|
||||
uint8_t m_actual_hs_out; // A2U4 output
|
||||
bool m_sio_int;
|
||||
uint8_t m_port_2;
|
||||
bool m_loopback;
|
||||
|
||||
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);
|
||||
DECLARE_READ8_MEMBER(ram_r);
|
||||
DECLARE_READ8_MEMBER(cpu_r);
|
||||
DECLARE_WRITE8_MEMBER(cpu_w);
|
||||
DECLARE_READ8_MEMBER(p1_r);
|
||||
DECLARE_WRITE8_MEMBER(p2_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(sio_int_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(sio_txd_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(rs232_rxd_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(rs232_dcd_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(rs232_dsr_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(rs232_cts_w);
|
||||
bool rx_fifo_flag() const;
|
||||
bool tx_fifo_flag() const;
|
||||
void update_flg();
|
||||
void update_sts();
|
||||
void update_irq();
|
||||
void update_hs_out();
|
||||
void load_tx_fifo();
|
||||
void set_r6_r7_pending(bool state);
|
||||
uint8_t get_hs_input() const;
|
||||
void set_brgs(uint8_t sel);
|
||||
};
|
||||
|
||||
// device type definitions
|
||||
DECLARE_DEVICE_TYPE(HP98046_IO_CARD, hp98046_io_card_device)
|
||||
|
||||
#endif // MAME_BUS_HP9845_IO_98046_H
|
@ -13,6 +13,7 @@
|
||||
#include "98032.h"
|
||||
#include "98035.h"
|
||||
#include "98034.h"
|
||||
#include "98046.h"
|
||||
|
||||
// device type definition
|
||||
DEFINE_DEVICE_TYPE(HP9845_IO_SLOT, hp9845_io_slot_device, "hp98x5_io_slot", "HP98x5 I/O Slot")
|
||||
@ -26,12 +27,16 @@ hp9845_io_slot_device::hp9845_io_slot_device(const machine_config &mconfig, cons
|
||||
m_irq_cb_func(*this),
|
||||
m_sts_cb_func(*this),
|
||||
m_flg_cb_func(*this),
|
||||
m_irq_nextsc_cb_func(*this),
|
||||
m_sts_nextsc_cb_func(*this),
|
||||
m_flg_nextsc_cb_func(*this),
|
||||
m_dmar_cb_func(*this)
|
||||
{
|
||||
option_reset();
|
||||
option_add("98032_gpio" , HP98032_IO_CARD);
|
||||
option_add("98034_hpib" , HP98034_IO_CARD);
|
||||
option_add("98035_rtc" , HP98035_IO_CARD);
|
||||
option_add("98046" , HP98046_IO_CARD);
|
||||
set_default_option(nullptr);
|
||||
set_fixed(false);
|
||||
}
|
||||
@ -45,6 +50,9 @@ void hp9845_io_slot_device::device_start()
|
||||
m_irq_cb_func.resolve_safe();
|
||||
m_sts_cb_func.resolve_safe();
|
||||
m_flg_cb_func.resolve_safe();
|
||||
m_irq_nextsc_cb_func.resolve_safe();
|
||||
m_sts_nextsc_cb_func.resolve_safe();
|
||||
m_flg_nextsc_cb_func.resolve_safe();
|
||||
m_dmar_cb_func.resolve_safe();
|
||||
|
||||
hp9845_io_card_device *card = dynamic_cast<hp9845_io_card_device*>(get_card_device());
|
||||
@ -69,6 +77,21 @@ WRITE_LINE_MEMBER(hp9845_io_slot_device::flg_w)
|
||||
m_flg_cb_func(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp9845_io_slot_device::irq_nextsc_w)
|
||||
{
|
||||
m_irq_nextsc_cb_func(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp9845_io_slot_device::sts_nextsc_w)
|
||||
{
|
||||
m_sts_nextsc_cb_func(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp9845_io_slot_device::flg_nextsc_w)
|
||||
{
|
||||
m_flg_nextsc_cb_func(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp9845_io_slot_device::dmar_w)
|
||||
{
|
||||
m_dmar_cb_func(state);
|
||||
@ -87,6 +110,17 @@ int hp9845_io_slot_device::get_rw_handlers(read16_delegate& rhandler , write16_d
|
||||
}
|
||||
}
|
||||
|
||||
bool hp9845_io_slot_device::has_dual_sc() const
|
||||
{
|
||||
hp9845_io_card_device *card = dynamic_cast<hp9845_io_card_device*>(get_card_device());
|
||||
|
||||
if (card != nullptr) {
|
||||
return card->has_dual_sc();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// +---------------------+
|
||||
// |hp9845_io_card_device|
|
||||
// +---------------------+
|
||||
@ -100,6 +134,11 @@ uint8_t hp9845_io_card_device::get_sc(void)
|
||||
return m_select_code_port->read() + HP9845_IO_FIRST_SC;
|
||||
}
|
||||
|
||||
bool hp9845_io_card_device::has_dual_sc() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
hp9845_io_card_device::hp9845_io_card_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, type, tag, owner, clock),
|
||||
device_slot_card_interface(mconfig, *this),
|
||||
@ -133,6 +172,27 @@ WRITE_LINE_MEMBER(hp9845_io_card_device::flg_w)
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp9845_io_card_device::irq_nextsc_w)
|
||||
{
|
||||
if (m_slot_dev) {
|
||||
m_slot_dev->irq_nextsc_w(state);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp9845_io_card_device::sts_nextsc_w)
|
||||
{
|
||||
if (m_slot_dev) {
|
||||
m_slot_dev->sts_nextsc_w(state);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp9845_io_card_device::flg_nextsc_w)
|
||||
{
|
||||
if (m_slot_dev) {
|
||||
m_slot_dev->flg_nextsc_w(state);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp9845_io_card_device::dmar_w)
|
||||
{
|
||||
if (m_slot_dev) {
|
||||
|
@ -46,22 +46,33 @@ public:
|
||||
auto irq() { return m_irq_cb_func.bind(); }
|
||||
auto sts() { return m_sts_cb_func.bind(); }
|
||||
auto flg() { return m_flg_cb_func.bind(); }
|
||||
auto irq_nextsc() { return m_irq_nextsc_cb_func.bind(); }
|
||||
auto sts_nextsc() { return m_sts_nextsc_cb_func.bind(); }
|
||||
auto flg_nextsc() { return m_flg_nextsc_cb_func.bind(); }
|
||||
auto dmar() { return m_dmar_cb_func.bind(); }
|
||||
|
||||
// irq/sts/flg/dmar signal handlers for card devices
|
||||
DECLARE_WRITE_LINE_MEMBER(irq_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(sts_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(flg_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(irq_nextsc_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(sts_nextsc_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(flg_nextsc_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(dmar_w);
|
||||
|
||||
// getter for r/w handlers
|
||||
// return value is SC (negative if no card is attached to slot)
|
||||
int get_rw_handlers(read16_delegate& rhandler , write16_delegate& whandler);
|
||||
|
||||
bool has_dual_sc() const;
|
||||
|
||||
private:
|
||||
devcb_write_line m_irq_cb_func;
|
||||
devcb_write_line m_sts_cb_func;
|
||||
devcb_write_line m_flg_cb_func;
|
||||
devcb_write_line m_irq_nextsc_cb_func;
|
||||
devcb_write_line m_sts_nextsc_cb_func;
|
||||
devcb_write_line m_flg_nextsc_cb_func;
|
||||
devcb_write_line m_dmar_cb_func;
|
||||
};
|
||||
|
||||
@ -77,6 +88,8 @@ public:
|
||||
// SC getter
|
||||
uint8_t get_sc(void);
|
||||
|
||||
virtual bool has_dual_sc() const;
|
||||
|
||||
protected:
|
||||
// construction/destruction
|
||||
hp9845_io_card_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
@ -89,6 +102,9 @@ protected:
|
||||
DECLARE_WRITE_LINE_MEMBER(irq_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(sts_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(flg_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(irq_nextsc_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(sts_nextsc_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(flg_nextsc_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(dmar_w);
|
||||
};
|
||||
|
||||
|
@ -41,6 +41,10 @@ hp_optrom_slot_device::hp_optrom_slot_device(const machine_config &mconfig, cons
|
||||
m_base_addr(0),
|
||||
m_end_addr(0)
|
||||
{
|
||||
option_reset();
|
||||
option_add_internal("rom", HP_OPTROM_CART);
|
||||
set_default_option(nullptr);
|
||||
set_fixed(false);
|
||||
}
|
||||
|
||||
hp_optrom_slot_device::~hp_optrom_slot_device()
|
||||
@ -125,8 +129,3 @@ std::string hp_optrom_slot_device::get_default_card_software(get_default_card_so
|
||||
{
|
||||
return software_get_default_slot("rom");
|
||||
}
|
||||
|
||||
void hp_optrom_slot_devices(device_slot_interface &device)
|
||||
{
|
||||
device.option_add_internal("rom", HP_OPTROM_CART);
|
||||
}
|
||||
|
@ -70,6 +70,4 @@ protected:
|
||||
DECLARE_DEVICE_TYPE(HP_OPTROM_SLOT, hp_optrom_slot_device)
|
||||
DECLARE_DEVICE_TYPE(HP_OPTROM_CART, hp_optrom_cart_device)
|
||||
|
||||
void hp_optrom_slot_devices(device_slot_interface &device);
|
||||
|
||||
#endif // MAME_BUS_HP_OPTROMS_HP_OPTROM_H
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -167,8 +167,19 @@ protected:
|
||||
enum : uint8_t
|
||||
{
|
||||
TX_FLAG_CRC = 1U << 0, // include in checksum calculation
|
||||
TX_FLAG_FRAMING = 1U << 1, // tranmitting framing bits
|
||||
TX_FLAG_SPECIAL = 1U << 2 // transmitting checksum or abort sequence
|
||||
TX_FLAG_FRAMING = 1U << 1, // transmitting framing bits
|
||||
TX_FLAG_ABORT_TX= 1U << 2, // transmitting abort sequence
|
||||
TX_FLAG_CRC_TX = 1U << 3, // transmitting CRC value
|
||||
TX_FLAG_DATA_TX = 1U << 4 // transmitting frame data
|
||||
};
|
||||
|
||||
// Sync/SDLC FSM states
|
||||
enum
|
||||
{
|
||||
SYNC_FSM_HUNT = 0, // Hunt for start sync/flag
|
||||
SYNC_FSM_EVICT = 1, // Evict flag from sync SR
|
||||
SYNC_FSM_1ST_CHAR = 2, // Receiving 1st character
|
||||
SYNC_FSM_IN_FRAME = 3 // Inside a frame
|
||||
};
|
||||
|
||||
z80sio_channel(
|
||||
@ -191,7 +202,6 @@ protected:
|
||||
int get_clock_mode();
|
||||
int get_rx_word_length();
|
||||
int get_tx_word_length() const;
|
||||
int get_tx_word_length(uint8_t data) const;
|
||||
|
||||
// receiver state
|
||||
int m_rx_fifo_depth;
|
||||
@ -200,26 +210,37 @@ protected:
|
||||
|
||||
int m_rx_clock; // receive clock line state
|
||||
int m_rx_count; // clocks until next sample
|
||||
bool m_dlyd_rxd; // delayed RxD
|
||||
int m_rx_bit; // receive data bit (0 = start bit, 1 = LSB, etc.)
|
||||
int m_rx_bit_limit; // bits to assemble for next character (sync/SDLC)
|
||||
int m_rx_sync_fsm; // Sync/SDLC FSM state
|
||||
uint8_t m_rx_one_cnt; // SDLC: counter to delete stuffed zeros
|
||||
uint16_t m_rx_sr; // receive shift register
|
||||
uint8_t m_rx_sync_sr; // rx sync SR
|
||||
uint8_t m_rx_crc_delay; // rx CRC delay SR
|
||||
uint16_t m_rx_crc; // rx CRC accumulator
|
||||
bool m_rx_crc_en; // rx CRC enabled
|
||||
bool m_rx_parity; // accumulated parity
|
||||
|
||||
int m_rx_first; // first character received
|
||||
int m_rx_break; // receive break condition
|
||||
|
||||
int m_rxd;
|
||||
int m_sh; // sync hunt
|
||||
|
||||
// transmitter state
|
||||
uint8_t m_tx_data;
|
||||
|
||||
int m_tx_clock; // transmit clock line state
|
||||
int m_tx_count; // clocks until next bit transition
|
||||
int m_tx_bits; // remaining bits in shift register
|
||||
int m_tx_parity; // parity bit position or zero if disabled
|
||||
uint16_t m_tx_sr; // transmit shift register
|
||||
bool m_tx_phase; // phase of bit clock
|
||||
bool m_tx_parity; // accumulated parity
|
||||
bool m_tx_in_pkt; // In active part of packet (sync mode)
|
||||
bool m_tx_forced_sync; // Force sync/flag
|
||||
uint32_t m_tx_sr; // transmit shift register
|
||||
uint16_t m_tx_crc; // calculated transmit checksum
|
||||
uint8_t m_tx_hist; // transmit history (for bitstuffing)
|
||||
uint8_t m_tx_flags; // internal transmit control flags
|
||||
uint8_t m_tx_delay; // 2-bit tx delay (4 half-bits)
|
||||
uint8_t m_all_sent_delay; // SR for all-sent delay
|
||||
|
||||
int m_txd;
|
||||
int m_dtr; // data terminal ready
|
||||
@ -247,17 +268,24 @@ private:
|
||||
bool transmit_allowed() const;
|
||||
|
||||
void receive_enabled();
|
||||
void enter_hunt_mode();
|
||||
void sync_receive();
|
||||
void sdlc_receive();
|
||||
void receive_data();
|
||||
void queue_received(uint16_t data, uint32_t error);
|
||||
void advance_rx_fifo();
|
||||
uint8_t get_special_rx_mask() const;
|
||||
|
||||
bool is_tx_idle() const;
|
||||
void transmit_enable();
|
||||
void transmit_complete();
|
||||
void async_tx_setup();
|
||||
void sync_tx_sr_empty();
|
||||
void tx_setup(uint16_t data, int bits, int parity, bool framing, bool special);
|
||||
void tx_setup(uint16_t data, int bits, bool framing, bool crc_tx, bool abort_tx);
|
||||
void tx_setup_idle();
|
||||
bool get_tx_empty() const;
|
||||
void set_tx_empty(bool prev_state, bool new_state);
|
||||
void update_crc(uint16_t& crc , bool bit);
|
||||
|
||||
void reset_ext_status();
|
||||
void read_ext();
|
||||
|
@ -479,6 +479,10 @@ void hp9845_base_state::device_reset()
|
||||
if ((sc = m_io_slot[i]->get_rw_handlers(rhandler , whandler)) >= 0) {
|
||||
logerror("Install R/W handlers for slot %u @ SC = %d\n", i, sc);
|
||||
m_ppu->space(AS_IO).install_readwrite_handler(sc * 4 , sc * 4 + 3 , rhandler , whandler);
|
||||
if (m_io_slot[ i ]->has_dual_sc()) {
|
||||
logerror("Installing dual SC\n");
|
||||
m_ppu->space(AS_IO).install_readwrite_handler(sc * 4 + 4 , sc * 4 + 7 , rhandler , whandler);
|
||||
}
|
||||
}
|
||||
m_slot_sc[ i ] = sc;
|
||||
}
|
||||
@ -668,6 +672,27 @@ void hp9845_base_state::set_flg_slot(unsigned slot , int state)
|
||||
m_io_sys->set_flg(uint8_t(sc) , state);
|
||||
}
|
||||
|
||||
void hp9845_base_state::set_irq_nextsc_slot(unsigned slot , int state)
|
||||
{
|
||||
int sc = m_slot_sc[ slot ];
|
||||
assert(sc >= 0);
|
||||
m_io_sys->set_irq(uint8_t(sc + 1) , state);
|
||||
}
|
||||
|
||||
void hp9845_base_state::set_sts_nextsc_slot(unsigned slot , int state)
|
||||
{
|
||||
int sc = m_slot_sc[ slot ];
|
||||
assert(sc >= 0);
|
||||
m_io_sys->set_sts(uint8_t(sc + 1) , state);
|
||||
}
|
||||
|
||||
void hp9845_base_state::set_flg_nextsc_slot(unsigned slot , int state)
|
||||
{
|
||||
int sc = m_slot_sc[ slot ];
|
||||
assert(sc >= 0);
|
||||
m_io_sys->set_flg(uint8_t(sc + 1) , state);
|
||||
}
|
||||
|
||||
void hp9845_base_state::set_dmar_slot(unsigned slot , int state)
|
||||
{
|
||||
int sc = m_slot_sc[ slot ];
|
||||
@ -3692,6 +3717,9 @@ void hp9845_base_state::hp9845_base(machine_config &config)
|
||||
tmp.irq().set([this , slot](int state) { set_irq_slot(slot , state); });
|
||||
tmp.sts().set([this , slot](int state) { set_sts_slot(slot , state); });
|
||||
tmp.flg().set([this , slot](int state) { set_flg_slot(slot , state); });
|
||||
tmp.irq_nextsc().set([this , slot](int state) { set_irq_nextsc_slot(slot , state); });
|
||||
tmp.sts_nextsc().set([this , slot](int state) { set_sts_nextsc_slot(slot , state); });
|
||||
tmp.flg_nextsc().set([this , slot](int state) { set_flg_nextsc_slot(slot , state); });
|
||||
tmp.dmar().set([this , slot](int state) { set_dmar_slot(slot , state); });
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,9 @@ protected:
|
||||
void set_irq_slot(unsigned slot , int state);
|
||||
void set_sts_slot(unsigned slot , int state);
|
||||
void set_flg_slot(unsigned slot , int state);
|
||||
void set_irq_nextsc_slot(unsigned slot , int state);
|
||||
void set_sts_nextsc_slot(unsigned slot , int state);
|
||||
void set_flg_nextsc_slot(unsigned slot , int state);
|
||||
void set_dmar_slot(unsigned slot , int state);
|
||||
|
||||
// Character generator
|
||||
|
Loading…
Reference in New Issue
Block a user