mirror of
https://github.com/holub/mame
synced 2025-04-18 22:49:58 +03:00
mcs51: implement serial input/output as bit stream (#11190)
* fix [MT#05495](https://mametesters.org/view.php?id=5495)
This commit is contained in:
parent
8dbba0b525
commit
743ac098e4
@ -134,9 +134,13 @@
|
||||
#include "mcs51.h"
|
||||
#include "mcs51dasm.h"
|
||||
|
||||
#define VERBOSE 0
|
||||
#define LOG_RX (1U << 1)
|
||||
#define LOG_TX (1U << 2)
|
||||
|
||||
#define VERBOSE (0)
|
||||
|
||||
#include "logmacro.h"
|
||||
|
||||
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
|
||||
|
||||
/***************************************************************************
|
||||
CONSTANTS
|
||||
@ -223,6 +227,22 @@ enum
|
||||
V_PFI = 0x02b /* Power Failure Interrupt */
|
||||
};
|
||||
|
||||
enum serial_state : u8
|
||||
{
|
||||
SIO_IDLE,
|
||||
SIO_START_LE,
|
||||
SIO_START,
|
||||
SIO_DATA0,
|
||||
SIO_DATA1,
|
||||
SIO_DATA2,
|
||||
SIO_DATA3,
|
||||
SIO_DATA4,
|
||||
SIO_DATA5,
|
||||
SIO_DATA6,
|
||||
SIO_DATA7,
|
||||
SIO_DATA8,
|
||||
SIO_STOP,
|
||||
};
|
||||
|
||||
DEFINE_DEVICE_TYPE(I8031, i8031_device, "i8031", "Intel 8031")
|
||||
DEFINE_DEVICE_TYPE(I8032, i8032_device, "i8032", "Intel 8032")
|
||||
@ -281,8 +301,6 @@ mcs51_cpu_device::mcs51_cpu_device(const machine_config &mconfig, device_type ty
|
||||
, m_scratchpad(*this, "scratchpad")
|
||||
, m_port_in_cb(*this)
|
||||
, m_port_out_cb(*this)
|
||||
, m_serial_tx_cb(*this)
|
||||
, m_serial_rx_cb(*this)
|
||||
, m_rtemp(0)
|
||||
{
|
||||
m_ds5002fp.mcon = 0;
|
||||
@ -797,7 +815,7 @@ void mcs51_cpu_device::clear_current_irq()
|
||||
m_cur_irq_prio = 0;
|
||||
else
|
||||
m_cur_irq_prio = -1;
|
||||
LOG(("New: %d %02x\n", m_cur_irq_prio, m_irq_active));
|
||||
LOG("New: %d %02x\n", m_cur_irq_prio, m_irq_active);
|
||||
}
|
||||
|
||||
uint8_t mcs51_cpu_device::r_acc() { return SFR_A(ADDR_ACC); }
|
||||
@ -997,19 +1015,65 @@ void mcs51_cpu_device::do_sub_flags(uint8_t a, uint8_t data, uint8_t c)
|
||||
SET_OV((result1 < -128 || result1 > 127));
|
||||
}
|
||||
|
||||
void mcs51_cpu_device::transmit(bool state)
|
||||
{
|
||||
if (BIT(SFR_A(ADDR_P3), 1) != state)
|
||||
{
|
||||
if (state)
|
||||
SFR_A(ADDR_P3) |= 1U << 1;
|
||||
else
|
||||
SFR_A(ADDR_P3) &= ~(1U << 1);
|
||||
|
||||
m_port_out_cb[3](SFR_A(ADDR_P3));
|
||||
}
|
||||
}
|
||||
|
||||
void mcs51_cpu_device::transmit_receive(int source)
|
||||
{
|
||||
int mode = (GET_SM0<<1) | GET_SM1;
|
||||
|
||||
if (source == 1) /* timer1 */
|
||||
m_uart.smod_div = (m_uart.smod_div + 1) & (2-GET_SMOD);
|
||||
m_uart.smod_div = (m_uart.smod_div + 1) & (1-GET_SMOD);
|
||||
|
||||
switch(mode) {
|
||||
//8 bit shifter ( + start,stop bit ) - baud set by clock freq / 12
|
||||
// 8 bit shifter - rate set by clock freq / 12
|
||||
case 0:
|
||||
m_uart.rx_clk += (source == 0) ? 16 : 0; /* clock / 12 */
|
||||
m_uart.tx_clk += (source == 0) ? 16 : 0; /* clock / 12 */
|
||||
break;
|
||||
if (source == 0)
|
||||
{
|
||||
// TODO: mode 0 serial input is unemulated
|
||||
// FIXME: output timing is highly simplified and incorrect
|
||||
switch (m_uart.txbit)
|
||||
{
|
||||
case SIO_IDLE:
|
||||
break;
|
||||
case SIO_START:
|
||||
SFR_A(ADDR_P3) |= 0x03;
|
||||
m_port_out_cb[3](SFR_A(ADDR_P3));
|
||||
m_uart.txbit = SIO_DATA0;
|
||||
break;
|
||||
case SIO_DATA0: case SIO_DATA1: case SIO_DATA2: case SIO_DATA3:
|
||||
case SIO_DATA4: case SIO_DATA5: case SIO_DATA6: case SIO_DATA7:
|
||||
SFR_A(ADDR_P3) &= ~0x03;
|
||||
if (BIT(m_uart.data_out, m_uart.txbit - SIO_DATA0))
|
||||
SFR_A(ADDR_P3) |= 1U << 0;
|
||||
m_port_out_cb[3](SFR_A(ADDR_P3));
|
||||
|
||||
if (m_uart.txbit == SIO_DATA7)
|
||||
{
|
||||
SET_TI(1);
|
||||
m_uart.txbit = SIO_STOP;
|
||||
}
|
||||
else
|
||||
m_uart.txbit++;
|
||||
break;
|
||||
case SIO_STOP:
|
||||
SFR_A(ADDR_P3) |= 0x03;
|
||||
m_port_out_cb[3](SFR_A(ADDR_P3));
|
||||
m_uart.txbit = SIO_IDLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
//8 bit uart ( + start,stop bit ) - baud set by timer1 or timer2
|
||||
case 1:
|
||||
case 3:
|
||||
@ -1030,39 +1094,139 @@ void mcs51_cpu_device::transmit_receive(int source)
|
||||
m_uart.tx_clk += (source == 0) ? (GET_SMOD ? 6 : 3) : 0; /* clock / 12 */
|
||||
break;
|
||||
}
|
||||
/* transmit ? */
|
||||
|
||||
// transmit
|
||||
if (m_uart.tx_clk >= 16)
|
||||
{
|
||||
m_uart.tx_clk &= 0x0f;
|
||||
if(m_uart.bits_to_send)
|
||||
{
|
||||
m_uart.bits_to_send--;
|
||||
if(m_uart.bits_to_send == 0) {
|
||||
//Call the callback function
|
||||
m_serial_tx_cb(0, m_uart.data_out, 0xff);
|
||||
//Set Interrupt Flag
|
||||
SET_TI(1);
|
||||
}
|
||||
}
|
||||
|
||||
switch (m_uart.txbit)
|
||||
{
|
||||
case SIO_IDLE:
|
||||
transmit(1);
|
||||
break;
|
||||
case SIO_START:
|
||||
LOGMASKED(LOG_TX, "tx start bit (%s)\n", machine().time().to_string());
|
||||
transmit(0);
|
||||
m_uart.txbit = SIO_DATA0;
|
||||
break;
|
||||
case SIO_DATA0: case SIO_DATA1: case SIO_DATA2: case SIO_DATA3:
|
||||
case SIO_DATA4: case SIO_DATA5: case SIO_DATA6: case SIO_DATA7:
|
||||
LOGMASKED(LOG_TX, "tx bit %d data %d (%s)\n", m_uart.txbit - SIO_DATA0, BIT(m_uart.data_out, m_uart.txbit - SIO_DATA0), machine().time().to_string());
|
||||
transmit(BIT(m_uart.data_out, m_uart.txbit - SIO_DATA0));
|
||||
|
||||
// mode 1 has no data8/parity bit
|
||||
if (mode == 1 && m_uart.txbit == SIO_DATA7)
|
||||
m_uart.txbit = SIO_STOP;
|
||||
else
|
||||
m_uart.txbit++;
|
||||
break;
|
||||
case SIO_DATA8: // data8/parity bit
|
||||
LOGMASKED(LOG_TX, "tx bit %d data %d (%s)\n", m_uart.txbit - SIO_DATA0, GET_TB8, machine().time().to_string());
|
||||
transmit(GET_TB8);
|
||||
m_uart.txbit = SIO_STOP;
|
||||
break;
|
||||
case SIO_STOP:
|
||||
LOGMASKED(LOG_TX, "tx stop bit (%s)\n", machine().time().to_string());
|
||||
transmit(1);
|
||||
SET_TI(1);
|
||||
m_uart.txbit = SIO_IDLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* receive */
|
||||
if (m_uart.rx_clk >= 16)
|
||||
|
||||
// receive
|
||||
if (m_uart.rx_clk >= 16 || m_uart.rxbit < SIO_START)
|
||||
{
|
||||
m_uart.rx_clk &= 0x0f;
|
||||
if (m_uart.delay_cycles>0)
|
||||
|
||||
if (GET_REN)
|
||||
{
|
||||
m_uart.delay_cycles--;
|
||||
if (m_uart.delay_cycles == 0)
|
||||
// directly read RXD input
|
||||
bool const data = BIT(m_port_in_cb[3](), 0);
|
||||
|
||||
switch (m_uart.rxbit)
|
||||
{
|
||||
int data = 0;
|
||||
//Call our callball function to retrieve the data
|
||||
data = m_serial_rx_cb(0, 0xff);
|
||||
LOG(("RX Deliver %d\n", data));
|
||||
SET_SBUF(data);
|
||||
//Flag the IRQ
|
||||
SET_RI(1);
|
||||
SET_RB8(1); // HACK force 2nd stop bit
|
||||
case SIO_IDLE:
|
||||
if (data)
|
||||
m_uart.rxbit = SIO_START_LE;
|
||||
break;
|
||||
case SIO_START_LE: // start bit leading edge
|
||||
if (!data)
|
||||
{
|
||||
LOGMASKED(LOG_RX, "rx start leading edge (%s)\n", machine().time().to_string());
|
||||
m_uart.rxbit = SIO_START;
|
||||
m_uart.rx_clk = 8;
|
||||
}
|
||||
break;
|
||||
case SIO_START:
|
||||
if (!data)
|
||||
{
|
||||
LOGMASKED(LOG_RX, "rx start bit (%s)\n", machine().time().to_string());
|
||||
|
||||
m_uart.data_in = 0;
|
||||
m_uart.rxbit = SIO_DATA0;
|
||||
}
|
||||
else
|
||||
// false start bit
|
||||
m_uart.rxbit = SIO_START_LE;
|
||||
break;
|
||||
case SIO_DATA0: case SIO_DATA1: case SIO_DATA2: case SIO_DATA3:
|
||||
case SIO_DATA4: case SIO_DATA5: case SIO_DATA6: case SIO_DATA7:
|
||||
LOGMASKED(LOG_RX, "rx bit %d data %d (%s)\n", m_uart.rxbit - SIO_DATA0, data, machine().time().to_string());
|
||||
if (data)
|
||||
m_uart.data_in |= 1U << (m_uart.rxbit - SIO_DATA0);
|
||||
|
||||
// mode 1 has no data8/parity bit
|
||||
if (mode == 1 && m_uart.rxbit == SIO_DATA7)
|
||||
m_uart.rxbit = SIO_STOP;
|
||||
else
|
||||
m_uart.rxbit++;
|
||||
break;
|
||||
case SIO_DATA8: // data8/parity bit
|
||||
LOGMASKED(LOG_RX, "rx bit %d data %d (%s)\n", m_uart.rxbit - SIO_DATA0, data, machine().time().to_string());
|
||||
m_uart.rxb8 = data;
|
||||
m_uart.rxbit = SIO_STOP;
|
||||
break;
|
||||
case SIO_STOP:
|
||||
if (!GET_RI)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case 1:
|
||||
LOGMASKED(LOG_RX, "rx byte 0x%02x stop %d (%s)\n", m_uart.data_in, data, machine().time().to_string());
|
||||
SET_SBUF(m_uart.data_in);
|
||||
if (!GET_SM2)
|
||||
{
|
||||
// RB8 contains stop bit
|
||||
SET_RB8(data);
|
||||
SET_RI(1);
|
||||
}
|
||||
else if (data)
|
||||
// RI if valid stop bit
|
||||
SET_RI(1);
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
LOGMASKED(LOG_RX, "rx byte 0x%02x RB8 %d stop %d (%s)\n", m_uart.data_in, m_uart.rxb8, data, machine().time().to_string());
|
||||
SET_SBUF(m_uart.data_in);
|
||||
SET_RB8(m_uart.rxb8);
|
||||
|
||||
// no RI if SM2 && !RB8
|
||||
if (!GET_SM2 || GET_RB8)
|
||||
SET_RI(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
LOGMASKED(LOG_RX, "rx overrun discarding data 0x%02x\n", m_uart.data_in);
|
||||
|
||||
// next state depends on stop bit validity
|
||||
if (data)
|
||||
m_uart.rxbit = SIO_START_LE;
|
||||
else
|
||||
m_uart.rxbit = SIO_IDLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1325,56 +1489,6 @@ void mcs51_cpu_device::update_timers(int cycles)
|
||||
}
|
||||
}
|
||||
|
||||
//Set up to transmit data out of serial port
|
||||
//NOTE: Enable Serial Port Interrupt bit is NOT required to send/receive data!
|
||||
|
||||
void mcs51_cpu_device::serial_transmit(uint8_t data)
|
||||
{
|
||||
int mode = (GET_SM0<<1) | GET_SM1;
|
||||
|
||||
//Flag that we're sending data
|
||||
m_uart.data_out = data;
|
||||
LOG(("serial_transmit: %x %x\n", mode, data));
|
||||
switch(mode) {
|
||||
//8 bit shifter ( + start,stop bit ) - baud set by clock freq / 12
|
||||
case 0:
|
||||
m_uart.bits_to_send = 8+2;
|
||||
break;
|
||||
//8 bit uart ( + start,stop bit ) - baud set by timer1 or timer2
|
||||
case 1:
|
||||
m_uart.bits_to_send = 8+2;
|
||||
break;
|
||||
//9 bit uart
|
||||
case 2:
|
||||
case 3:
|
||||
m_uart.bits_to_send = 8+3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mcs51_cpu_device::serial_receive()
|
||||
{
|
||||
int mode = (GET_SM0<<1) | GET_SM1;
|
||||
|
||||
if (GET_REN) {
|
||||
switch(mode) {
|
||||
//8 bit shifter ( + start,stop bit ) - baud set by clock freq / 12
|
||||
case 0:
|
||||
m_uart.delay_cycles = 8+2;
|
||||
break;
|
||||
//8 bit uart ( + start,stop bit ) - baud set by timer1 or timer2
|
||||
case 1:
|
||||
m_uart.delay_cycles = 8+2;
|
||||
break;
|
||||
//9 bit uart
|
||||
case 2:
|
||||
case 3:
|
||||
m_uart.delay_cycles = 8+3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check and update status of serial port */
|
||||
void mcs51_cpu_device::update_serial(int cycles)
|
||||
{
|
||||
@ -1819,10 +1933,10 @@ void mcs51_cpu_device::check_irqs()
|
||||
/* Skip the interrupt request if currently processing interrupt
|
||||
* and the new request does not have a higher priority
|
||||
*/
|
||||
LOG(("Request: %d\n", priority_request));
|
||||
LOG("Request: %d\n", priority_request);
|
||||
if (m_irq_active && (priority_request <= m_cur_irq_prio))
|
||||
{
|
||||
LOG(("higher or equal priority irq (%u) in progress already, skipping ...\n", m_cur_irq_prio));
|
||||
LOG("higher or equal priority irq (%u) in progress already, skipping ...\n", m_cur_irq_prio);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1853,7 +1967,7 @@ void mcs51_cpu_device::check_irqs()
|
||||
m_cur_irq_prio = priority_request;
|
||||
m_irq_active |= (1 << priority_request);
|
||||
|
||||
LOG(("Take: %d %02x\n", m_cur_irq_prio, m_irq_active));
|
||||
LOG("Take: %d %02x\n", m_cur_irq_prio, m_irq_active);
|
||||
|
||||
//Clear any interrupt flags that should be cleared since we're servicing the irq!
|
||||
switch(int_vec) {
|
||||
@ -1994,14 +2108,6 @@ void mcs51_cpu_device::execute_set_input(int irqline, int state)
|
||||
fatalerror("mcs51: Trying to set T2EX_LINE on a non I8052 type cpu.\n");
|
||||
break;
|
||||
|
||||
case MCS51_RX_LINE: /* Serial Port Receive */
|
||||
/* Is the enable flags for this interrupt set? */
|
||||
if (state != CLEAR_LINE)
|
||||
{
|
||||
serial_receive();
|
||||
}
|
||||
break;
|
||||
|
||||
/* Power Fail Interrupt */
|
||||
case DS5002FP_PFI_LINE:
|
||||
if (m_features & FEATURE_DS5002FP)
|
||||
@ -2099,12 +2205,14 @@ void mcs51_cpu_device::sfr_write(size_t offset, uint8_t data)
|
||||
case ADDR_P1: m_port_out_cb[1](data); break;
|
||||
case ADDR_P2: m_port_out_cb[2](data); break;
|
||||
case ADDR_P3: m_port_out_cb[3](data); break;
|
||||
case ADDR_SBUF: serial_transmit(data); break;
|
||||
case ADDR_SBUF:
|
||||
LOGMASKED(LOG_TX, "tx byte 0x%02x\n", data);
|
||||
m_uart.data_out = data;
|
||||
m_uart.txbit = SIO_START;
|
||||
break;
|
||||
case ADDR_PSW: SET_PARITY(); break;
|
||||
case ADDR_ACC: SET_PARITY(); break;
|
||||
case ADDR_IP: update_irq_prio(data, 0); break;
|
||||
/* R_SBUF = data; //This register is used only for "Receiving data coming in!" */
|
||||
|
||||
case ADDR_B:
|
||||
case ADDR_SP:
|
||||
case ADDR_DPL:
|
||||
@ -2117,10 +2225,18 @@ void mcs51_cpu_device::sfr_write(size_t offset, uint8_t data)
|
||||
case ADDR_TL1:
|
||||
case ADDR_TH0:
|
||||
case ADDR_TH1:
|
||||
break;
|
||||
case ADDR_SCON:
|
||||
if (!GET_REN && BIT(data, 4))
|
||||
{
|
||||
LOGMASKED(LOG_RX, "rx enabled SCON 0x%02x\n", data);
|
||||
if (!BIT(data, 6, 2))
|
||||
logerror("mode 0 serial input is not emulated\n");
|
||||
m_uart.rxbit = SIO_IDLE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG(("mcs51 '%s': attemping to write to an invalid/non-implemented SFR address: %x at 0x%04x, data=%x\n", tag(), (uint32_t)offset,PC,data));
|
||||
LOG("attemping to write to an invalid/non-implemented SFR address: %x at 0x%04x, data=%x\n", (uint32_t)offset,PC,data);
|
||||
/* no write in this case according to manual */
|
||||
return;
|
||||
}
|
||||
@ -2162,7 +2278,7 @@ uint8_t mcs51_cpu_device::sfr_read(size_t offset)
|
||||
return m_data.read_byte((size_t) offset | 0x100);
|
||||
/* Illegal or non-implemented sfr */
|
||||
default:
|
||||
LOG(("mcs51 '%s': attemping to read an invalid/non-implemented SFR address: %x at 0x%04x\n", tag(), (uint32_t)offset,PC));
|
||||
LOG("attemping to read an invalid/non-implemented SFR address: %x at 0x%04x\n", (uint32_t)offset,PC);
|
||||
/* according to the manual, the read may return random bits */
|
||||
return 0xff;
|
||||
}
|
||||
@ -2177,8 +2293,6 @@ void mcs51_cpu_device::device_start()
|
||||
|
||||
m_port_in_cb.resolve_all_safe(0xff);
|
||||
m_port_out_cb.resolve_all_safe();
|
||||
m_serial_rx_cb.resolve_safe(0);
|
||||
m_serial_tx_cb.resolve_safe();
|
||||
|
||||
/* Save states */
|
||||
save_item(NAME(m_ppc));
|
||||
@ -2200,11 +2314,10 @@ void mcs51_cpu_device::device_start()
|
||||
save_item(NAME(m_ds5002fp.rnr_delay) );
|
||||
save_item(NAME(m_ds5002fp.range) );
|
||||
save_item(NAME(m_uart.data_out));
|
||||
save_item(NAME(m_uart.bits_to_send));
|
||||
save_item(NAME(m_uart.data_in));
|
||||
save_item(NAME(m_uart.smod_div));
|
||||
save_item(NAME(m_uart.rx_clk));
|
||||
save_item(NAME(m_uart.tx_clk));
|
||||
save_item(NAME(m_uart.delay_cycles));
|
||||
|
||||
state_add( MCS51_PC, "PC", m_pc).formatstr("%04X");
|
||||
state_add( MCS51_SP, "SP", SP).formatstr("%02X");
|
||||
@ -2346,10 +2459,11 @@ void mcs51_cpu_device::device_reset()
|
||||
}
|
||||
|
||||
m_uart.data_out = 0;
|
||||
m_uart.data_in = 0;
|
||||
m_uart.rx_clk = 0;
|
||||
m_uart.tx_clk = 0;
|
||||
m_uart.bits_to_send = 0;
|
||||
m_uart.delay_cycles = 0;
|
||||
m_uart.txbit = SIO_IDLE;
|
||||
m_uart.rxbit = SIO_IDLE;
|
||||
m_uart.smod_div = 0;
|
||||
|
||||
m_recalc_parity = 0;
|
||||
@ -2441,8 +2555,8 @@ uint8_t i80c52_device::sfr_read(size_t offset)
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#define DS5_LOGW(a, d) LOG(("ds5002fp '%s': write to " # a " register at 0x%04x, data=%x\n", tag(), PC, d))
|
||||
#define DS5_LOGR(a, d) LOG(("ds5002fp '%s': read from " # a " register at 0x%04x\n", tag(), PC))
|
||||
#define DS5_LOGW(a, d) LOG("write to " # a " register at 0x%04x, data=%x\n", PC, d)
|
||||
#define DS5_LOGR(a, d) LOG("read from " # a " register at 0x%04x\n", PC)
|
||||
|
||||
uint8_t mcs51_cpu_device::ds5002fp_protected(size_t offset, uint8_t data, uint8_t ta_mask, uint8_t mask)
|
||||
{
|
||||
@ -2467,7 +2581,7 @@ void ds5002fp_device::sfr_write(size_t offset, uint8_t data)
|
||||
if ((data == 0xaa) && (m_ds5002fp.ta_window == 0))
|
||||
{
|
||||
m_ds5002fp.ta_window = 6; /* 4*12 + 2*12 */
|
||||
LOG(("ds5002fp '%s': TA window initiated at 0x%04x\n", tag(), PC));
|
||||
LOG("TA window initiated at 0x%04x\n", PC);
|
||||
}
|
||||
break;
|
||||
case ADDR_MCON: data = ds5002fp_protected(ADDR_MCON, data, 0x0f, 0xf7); DS5_LOGW(MCON, data); break;
|
||||
|
@ -44,8 +44,7 @@ enum
|
||||
{
|
||||
MCS51_INT0_LINE = 0, /* P3.2: External Interrupt 0 */
|
||||
MCS51_INT1_LINE, /* P3.3: External Interrupt 1 */
|
||||
MCS51_RX_LINE, /* P3.0: Serial Port Receive Line */
|
||||
MCS51_T0_LINE, /* P3,4: Timer 0 External Input */
|
||||
MCS51_T0_LINE, /* P3.4: Timer 0 External Input */
|
||||
MCS51_T1_LINE, /* P3.5: Timer 1 External Input */
|
||||
MCS51_T2_LINE, /* P1.0: Timer 2 External Input */
|
||||
MCS51_T2EX_LINE, /* P1.1: Timer 2 Capture Reload Trigger */
|
||||
@ -64,8 +63,6 @@ public:
|
||||
|
||||
template <unsigned N> auto port_in_cb() { return m_port_in_cb[N].bind(); }
|
||||
template <unsigned N> auto port_out_cb() { return m_port_out_cb[N].bind(); }
|
||||
auto serial_rx_cb() { return m_serial_rx_cb.bind(); }
|
||||
auto serial_tx_cb() { return m_serial_tx_cb.bind(); }
|
||||
|
||||
void program_internal(address_map &map);
|
||||
void data_internal(address_map &map);
|
||||
@ -132,12 +129,14 @@ protected:
|
||||
struct mcs51_uart
|
||||
{
|
||||
uint8_t data_out; //Data to send out
|
||||
uint8_t bits_to_send; //How many bits left to send when transmitting out the serial port
|
||||
uint8_t data_in;
|
||||
uint8_t txbit;
|
||||
uint8_t rxbit;
|
||||
bool rxb8;
|
||||
|
||||
int smod_div; /* signal divided by 2^SMOD */
|
||||
int rx_clk; /* rx clock */
|
||||
int tx_clk; /* tx clock */
|
||||
uint8_t delay_cycles; //Gross Hack;
|
||||
} m_uart; /* internal uart */
|
||||
|
||||
/* Internal Ram */
|
||||
@ -148,6 +147,8 @@ protected:
|
||||
virtual void sfr_write(size_t offset, uint8_t data);
|
||||
virtual uint8_t sfr_read(size_t offset);
|
||||
|
||||
void transmit(bool state);
|
||||
|
||||
/* Memory spaces */
|
||||
memory_access<16, 0, 0, ENDIANNESS_LITTLE>::cache m_program;
|
||||
memory_access< 9, 0, 0, ENDIANNESS_LITTLE>::specific m_data;
|
||||
@ -156,10 +157,6 @@ protected:
|
||||
devcb_read8::array<4> m_port_in_cb;
|
||||
devcb_write8::array<4> m_port_out_cb;
|
||||
|
||||
/* Serial Port TX/RX Callbacks */
|
||||
devcb_write8 m_serial_tx_cb; //Call back function when sending data out of serial port
|
||||
devcb_read8 m_serial_rx_cb; //Call back function to retrieve data when receiving serial port data
|
||||
|
||||
/* DS5002FP */
|
||||
struct {
|
||||
uint8_t previous_ta; /* Previous Timed Access value */
|
||||
@ -197,9 +194,7 @@ protected:
|
||||
void update_timer_t1(int cycles);
|
||||
void update_timer_t2(int cycles);
|
||||
void update_timers(int cycles);
|
||||
void serial_transmit(uint8_t data);
|
||||
void serial_receive();
|
||||
void update_serial(int cycles);
|
||||
void update_serial(int source);
|
||||
void update_irq_prio(uint8_t ipl, uint8_t iph);
|
||||
void execute_op(uint8_t op);
|
||||
void check_irqs();
|
||||
|
@ -978,5 +978,5 @@ OPHANDLER( xrl_a_r )
|
||||
//illegal opcodes
|
||||
OPHANDLER( illegal )
|
||||
{
|
||||
LOG(("i8051 '%s': illegal opcode at 0x%03x: %02x\n", tag(), PC-1, r));
|
||||
LOG("illegal opcode at 0x%03x: %02x\n", PC-1, r);
|
||||
}
|
||||
|
@ -232,7 +232,6 @@ ioport_constructor archimedes_keyboard_device::device_input_ports() const
|
||||
|
||||
archimedes_keyboard_device::archimedes_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, ARCHIMEDES_KEYBOARD, tag, owner, clock)
|
||||
, device_serial_interface(mconfig, *this)
|
||||
, m_mcu(*this, "mcu")
|
||||
, m_kout(*this)
|
||||
, m_keyboard(*this, "ROW.%u", 0U)
|
||||
@ -250,10 +249,6 @@ void archimedes_keyboard_device::device_resolve_objects()
|
||||
|
||||
void archimedes_keyboard_device::device_start()
|
||||
{
|
||||
// KART interface
|
||||
set_data_frame(1, 8, PARITY_NONE, STOP_BITS_2);
|
||||
set_rate(31250);
|
||||
|
||||
m_mouse_timer = timer_alloc(FUNC(archimedes_keyboard_device::update_mouse), this);
|
||||
|
||||
save_item(NAME(m_mouse_x));
|
||||
@ -265,6 +260,7 @@ void archimedes_keyboard_device::device_start()
|
||||
save_item(NAME(m_mouse_yref));
|
||||
save_item(NAME(m_mouse_ydir));
|
||||
save_item(NAME(m_mux));
|
||||
save_item(NAME(m_kin));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -282,9 +278,7 @@ void archimedes_keyboard_device::device_reset()
|
||||
m_mouse_yref = 1;
|
||||
m_mouse_ydir = 1;
|
||||
m_mux = 0;
|
||||
|
||||
transmit_register_reset();
|
||||
receive_register_reset();
|
||||
m_kin = false;
|
||||
|
||||
m_mouse_timer->adjust(attotime::from_hz(1000 * 4), 0, attotime::from_hz(1000 * 4));
|
||||
}
|
||||
@ -299,11 +293,9 @@ void archimedes_keyboard_device::device_add_mconfig(machine_config &config)
|
||||
m_mcu->port_in_cb<0>().set([this]() { return m_keyboard[m_mux]->read() & 0xff; });
|
||||
m_mcu->port_in_cb<1>().set([this]() { return (m_keyboard[m_mux]->read() >> 8) & 0xff; });
|
||||
m_mcu->port_in_cb<2>().set(FUNC(archimedes_keyboard_device::mouse_r));
|
||||
m_mcu->port_in_cb<3>().set([this]() { return m_mouse[2]->read() & 0xff; });
|
||||
m_mcu->port_in_cb<3>().set([this]() { return (m_mouse[2]->read() & 0xfe) | m_kin; });
|
||||
m_mcu->port_out_cb<2>().set([this](uint8_t data) { m_mux = data & 0x0f; });
|
||||
m_mcu->port_out_cb<3>().set(FUNC(archimedes_keyboard_device::leds_w));
|
||||
m_mcu->serial_rx_cb().set([this]() { return get_received_char(); });
|
||||
m_mcu->serial_tx_cb().set(FUNC(archimedes_keyboard_device::tx_w));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -321,22 +313,6 @@ const tiny_rom_entry *archimedes_keyboard_device::device_rom_region() const
|
||||
return ROM_NAME( archimedes_keyboard );
|
||||
}
|
||||
|
||||
void archimedes_keyboard_device::tra_complete()
|
||||
{
|
||||
}
|
||||
|
||||
void archimedes_keyboard_device::rcv_complete()
|
||||
{
|
||||
receive_register_extract();
|
||||
m_mcu->set_input_line(MCS51_RX_LINE, ASSERT_LINE);
|
||||
m_mcu->set_input_line(MCS51_RX_LINE, CLEAR_LINE);
|
||||
}
|
||||
|
||||
void archimedes_keyboard_device::tra_callback()
|
||||
{
|
||||
m_kout(transmit_register_get_data_bit());
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(archimedes_keyboard_device::update_mouse)
|
||||
{
|
||||
// Mouse quadrature signals
|
||||
@ -418,10 +394,12 @@ TIMER_CALLBACK_MEMBER(archimedes_keyboard_device::update_mouse)
|
||||
void archimedes_keyboard_device::leds_w(uint8_t data)
|
||||
{
|
||||
// Keyboard LEDs
|
||||
// --- --x- TXD
|
||||
// --- -x-- Caps Lock
|
||||
// --- x--- Scroll Lock
|
||||
// --x ---- Num Lock
|
||||
|
||||
m_kout(BIT(data, 1));
|
||||
for (int i = 0; i < 3; i++)
|
||||
m_leds[i] = BIT(data, 2 + i);
|
||||
}
|
||||
@ -431,8 +409,7 @@ uint8_t archimedes_keyboard_device::mouse_r()
|
||||
return (m_mouse_xref << 4) | (m_mouse_xdir << 5) | (m_mouse_yref << 6) | (m_mouse_ydir << 7);
|
||||
}
|
||||
|
||||
void archimedes_keyboard_device::tx_w(uint8_t data)
|
||||
WRITE_LINE_MEMBER(archimedes_keyboard_device::kin_w)
|
||||
{
|
||||
if (is_transmit_register_empty())
|
||||
transmit_register_setup(data);
|
||||
m_kin = state;
|
||||
}
|
||||
|
@ -13,15 +13,13 @@
|
||||
|
||||
#include "cpu/mcs51/mcs51.h"
|
||||
|
||||
#include "diserial.h"
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> archimedes_keyboard_device
|
||||
|
||||
class archimedes_keyboard_device : public device_t, public device_serial_interface
|
||||
class archimedes_keyboard_device : public device_t
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
@ -29,7 +27,7 @@ public:
|
||||
|
||||
auto kout() { return m_kout.bind(); }
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(kin_w) { rx_w(state); }
|
||||
DECLARE_WRITE_LINE_MEMBER(kin_w);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
@ -42,15 +40,9 @@ protected:
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual ioport_constructor device_input_ports() const override;
|
||||
|
||||
// device_serial_interface overrides
|
||||
virtual void tra_callback() override;
|
||||
virtual void tra_complete() override;
|
||||
virtual void rcv_complete() override;
|
||||
|
||||
TIMER_CALLBACK_MEMBER(update_mouse);
|
||||
|
||||
private:
|
||||
void tx_w(uint8_t data);
|
||||
uint8_t mouse_r();
|
||||
void leds_w(uint8_t data);
|
||||
|
||||
@ -70,6 +62,7 @@ private:
|
||||
int16_t m_mouse_x;
|
||||
int16_t m_mouse_y;
|
||||
uint8_t m_mux;
|
||||
bool m_kin;
|
||||
};
|
||||
|
||||
|
||||
|
@ -175,7 +175,6 @@ qs1000_device::qs1000_device(const machine_config &mconfig, const char *tag, dev
|
||||
m_out_p1_cb(*this),
|
||||
m_out_p2_cb(*this),
|
||||
m_out_p3_cb(*this),
|
||||
//m_serial_w_cb(*this),
|
||||
m_stream(nullptr),
|
||||
m_cpu(*this, "cpu")
|
||||
{
|
||||
@ -207,7 +206,6 @@ void qs1000_device::device_add_mconfig(machine_config &config)
|
||||
m_cpu->port_out_cb<2>().set(FUNC(qs1000_device::p2_w));
|
||||
m_cpu->port_in_cb<3>().set(FUNC(qs1000_device::p3_r));
|
||||
m_cpu->port_out_cb<3>().set(FUNC(qs1000_device::p3_w));
|
||||
m_cpu->serial_rx_cb().set(FUNC(qs1000_device::data_to_i8052));
|
||||
}
|
||||
|
||||
|
||||
@ -241,9 +239,6 @@ void qs1000_device::device_start()
|
||||
m_out_p2_cb.resolve_safe();
|
||||
m_out_p3_cb.resolve_safe();
|
||||
|
||||
//m_serial_w_cb.resolve_safe();
|
||||
|
||||
save_item(NAME(m_serial_data_in));
|
||||
save_item(NAME(m_wave_regs));
|
||||
|
||||
for (int i = 0; i < QS1000_CHANNELS; i++)
|
||||
@ -267,19 +262,6 @@ void qs1000_device::device_start()
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// serial_in - send data to the chip
|
||||
//-------------------------------------------------
|
||||
void qs1000_device::serial_in(uint8_t data)
|
||||
{
|
||||
m_serial_data_in = data;
|
||||
|
||||
// Signal to the CPU that data is available
|
||||
m_cpu->set_input_line(MCS51_RX_LINE, ASSERT_LINE);
|
||||
m_cpu->set_input_line(MCS51_RX_LINE, CLEAR_LINE);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// set_irq - interrupt the internal CPU
|
||||
//-------------------------------------------------
|
||||
@ -290,16 +272,6 @@ void qs1000_device::set_irq(int state)
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// data_to_i8052 - called by the 8052 core to
|
||||
// receive serial data
|
||||
//-------------------------------------------------
|
||||
uint8_t qs1000_device::data_to_i8052()
|
||||
{
|
||||
return m_serial_data_in;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
@ -40,11 +40,9 @@ public:
|
||||
auto p1_out() { return m_out_p1_cb.bind(); }
|
||||
auto p2_out() { return m_out_p2_cb.bind(); }
|
||||
auto p3_out() { return m_out_p3_cb.bind(); }
|
||||
//auto serial_w() { return m_serial_w_cb.bind(); }
|
||||
|
||||
// external
|
||||
i8052_device &cpu() const { return *m_cpu; }
|
||||
void serial_in(uint8_t data);
|
||||
void set_irq(int state);
|
||||
|
||||
void wave_w(offs_t offset, uint8_t data);
|
||||
@ -101,14 +99,11 @@ private:
|
||||
devcb_write8 m_out_p2_cb;
|
||||
devcb_write8 m_out_p3_cb;
|
||||
|
||||
//devcb_write8 m_serial_w_cb;
|
||||
|
||||
// Internal state
|
||||
sound_stream * m_stream;
|
||||
required_device<i8052_device> m_cpu;
|
||||
|
||||
// Wavetable engine
|
||||
uint8_t m_serial_data_in;
|
||||
uint8_t m_wave_regs[18];
|
||||
|
||||
struct qs1000_channel
|
||||
@ -129,8 +124,6 @@ private:
|
||||
};
|
||||
|
||||
qs1000_channel m_channels[QS1000_CHANNELS];
|
||||
|
||||
uint8_t data_to_i8052();
|
||||
};
|
||||
|
||||
|
||||
|
@ -311,6 +311,7 @@ void device_serial_interface::receive_register_extract()
|
||||
data &= ~(0xff<<m_df_word_length);
|
||||
|
||||
m_rcv_byte_received = data;
|
||||
LOGMASKED(LOG_RX, "Receive data 0x%02x\n", m_rcv_byte_received);
|
||||
|
||||
if(m_df_parity == PARITY_NONE)
|
||||
return;
|
||||
@ -436,7 +437,7 @@ u8 device_serial_interface::transmit_register_get_data_bit()
|
||||
bit = (m_tra_register_data>>(m_tra_bit_count-1-m_tra_bit_count_transmitted))&1;
|
||||
|
||||
if (m_tra_bit_count_transmitted < m_df_start_bit_count)
|
||||
LOGMASKED(LOG_TX, "Transmitting start bit as %d (%s)\n", m_tra_bit_count_transmitted, bit, device().machine().time().to_string());
|
||||
LOGMASKED(LOG_TX, "Transmitting start bit %d as %d (%s)\n", m_tra_bit_count_transmitted, bit, device().machine().time().to_string());
|
||||
else
|
||||
LOGMASKED(LOG_TX, "Transmitting bit %d as %d (%s)\n", m_tra_bit_count_transmitted - m_df_start_bit_count, bit, device().machine().time().to_string());
|
||||
m_tra_bit_count_transmitted++;
|
||||
|
@ -133,6 +133,7 @@ Notes:
|
||||
#include "machine/arm_iomd.h"
|
||||
#include "machine/i2cmem.h"
|
||||
#include "sound/qs1000.h"
|
||||
#include "diserial.h"
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
@ -140,11 +141,12 @@ Notes:
|
||||
|
||||
namespace {
|
||||
|
||||
class ssfindo_state : public driver_device
|
||||
class ssfindo_state : public driver_device, public device_serial_interface
|
||||
{
|
||||
public:
|
||||
ssfindo_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, device_serial_interface(mconfig, *this)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_vidc(*this, "vidc")
|
||||
, m_iomd(*this, "iomd")
|
||||
@ -178,6 +180,7 @@ protected:
|
||||
|
||||
bool m_i2cmem_clock = false;
|
||||
|
||||
virtual void tra_callback() override;
|
||||
void sound_w(uint8_t data);
|
||||
|
||||
private:
|
||||
@ -209,6 +212,8 @@ private:
|
||||
uint8_t iolines_r();
|
||||
void iolines_w(uint8_t data);
|
||||
bool m_flash_bank_select = false;
|
||||
|
||||
bool m_txd = true;
|
||||
};
|
||||
|
||||
class tetfight_state : public ssfindo_state
|
||||
@ -371,7 +376,7 @@ uint32_t ssfindo_state::randomized_r()
|
||||
|
||||
void ssfindo_state::sound_w(uint8_t data)
|
||||
{
|
||||
m_qs1000->serial_in(data);
|
||||
transmit_register_setup(data);
|
||||
m_maincpu->spin_until_time(attotime::from_usec(2000)); // give time to the QS1000 CPU to react. TODO: sync things correctly
|
||||
}
|
||||
|
||||
@ -441,11 +446,23 @@ void ssfindo_state::machine_start()
|
||||
save_item(NAME(m_flashN));
|
||||
save_item(NAME(m_i2cmem_clock));
|
||||
save_item(NAME(m_flash_bank_select));
|
||||
|
||||
set_data_frame(1, 8, PARITY_NONE, STOP_BITS_1);
|
||||
set_rate(31250);
|
||||
}
|
||||
|
||||
void ssfindo_state::machine_reset()
|
||||
{
|
||||
// ...
|
||||
receive_register_reset();
|
||||
transmit_register_reset();
|
||||
|
||||
m_txd = true;
|
||||
}
|
||||
|
||||
void ssfindo_state::tra_callback()
|
||||
{
|
||||
m_txd = transmit_register_get_data_bit();
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START( ssfindo )
|
||||
@ -616,6 +633,7 @@ void ssfindo_state::ssfindo(machine_config &config)
|
||||
qs1000_device &qs1000(QS1000(config, "qs1000", 24_MHz_XTAL));
|
||||
qs1000.set_external_rom(true);
|
||||
// qs1000.p1_out().set(FUNC()); // TODO: writes something here
|
||||
qs1000.p3_in().set([this]() { return u8(0xfeU | m_txd); });
|
||||
qs1000.add_route(0, "lspeaker", 0.25);
|
||||
qs1000.add_route(1, "rspeaker", 0.25);
|
||||
}
|
||||
|
@ -153,9 +153,10 @@ private:
|
||||
void eolith_vram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
uint16_t eolith_vram_r(offs_t offset);
|
||||
void sound_p1_w(uint8_t data);
|
||||
void sound_p3_w(uint8_t data);
|
||||
uint8_t qs1000_p1_r();
|
||||
void qs1000_p1_w(uint8_t data);
|
||||
void soundcpu_to_qs1000(uint8_t data);
|
||||
uint8_t qs1000_p3_r();
|
||||
|
||||
uint32_t screen_update_eolith(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
@ -176,6 +177,7 @@ private:
|
||||
int m_coin_counter_bit = 0;
|
||||
std::unique_ptr<uint16_t[]> m_vram;
|
||||
int m_buffer = 0;
|
||||
uint8_t m_sound_txd = 0;
|
||||
};
|
||||
|
||||
|
||||
@ -315,6 +317,11 @@ void eolith_state::sound_p1_w(uint8_t data)
|
||||
m_sndbank->set_entry(data & 0x0f);
|
||||
}
|
||||
|
||||
void eolith_state::sound_p3_w(uint8_t data)
|
||||
{
|
||||
// Sound CPU -> QS1000 CPU serial link
|
||||
m_sound_txd = BIT(data, 1);
|
||||
}
|
||||
|
||||
/*************************************
|
||||
*
|
||||
@ -352,10 +359,9 @@ void eolith_state::qs1000_p1_w(uint8_t data)
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void eolith_state::soundcpu_to_qs1000(uint8_t data)
|
||||
uint8_t eolith_state::qs1000_p3_r()
|
||||
{
|
||||
m_qs1000->serial_in(data);
|
||||
machine().scheduler().perfect_quantum(attotime::from_usec(250));
|
||||
return m_sound_txd;
|
||||
}
|
||||
|
||||
|
||||
@ -693,7 +699,8 @@ void eolith_state::eolith45(machine_config &config)
|
||||
m_soundcpu->set_addrmap(AS_PROGRAM, &eolith_state::sound_prg_map);
|
||||
m_soundcpu->set_addrmap(AS_IO, &eolith_state::sound_io_map);
|
||||
m_soundcpu->port_out_cb<1>().set(FUNC(eolith_state::sound_p1_w));
|
||||
m_soundcpu->serial_tx_cb().set(FUNC(eolith_state::soundcpu_to_qs1000)); // Sound CPU -> QS1000 CPU serial link
|
||||
m_soundcpu->port_out_cb<3>().set(FUNC(eolith_state::sound_p3_w));
|
||||
config.set_perfect_quantum(m_soundcpu); // HACK: ensure serial sync between Sound CPU and QS1000
|
||||
|
||||
EEPROM_93C66_8BIT(config, "eeprom")
|
||||
.erase_time(attotime::from_usec(250))
|
||||
@ -724,6 +731,7 @@ void eolith_state::eolith45(machine_config &config)
|
||||
m_qs1000->set_external_rom(true);
|
||||
m_qs1000->p1_in().set(FUNC(eolith_state::qs1000_p1_r));
|
||||
m_qs1000->p1_out().set(FUNC(eolith_state::qs1000_p1_w));
|
||||
m_qs1000->p3_in().set(FUNC(eolith_state::qs1000_p3_r));
|
||||
m_qs1000->add_route(0, "lspeaker", 1.0);
|
||||
m_qs1000->add_route(1, "rspeaker", 1.0);
|
||||
}
|
||||
|
@ -200,7 +200,6 @@ protected:
|
||||
u8 m_mcu_p1;
|
||||
u8 m_mcu_p2;
|
||||
u8 m_mcu_p3;
|
||||
u8 m_mcu_uart;
|
||||
|
||||
u8 m_ppi_pa;
|
||||
u8 m_ppi_pb;
|
||||
@ -223,7 +222,6 @@ void rtpc_state::machine_start()
|
||||
m_mcu_p1 = 0;
|
||||
m_mcu_p2 = 0;
|
||||
m_mcu_p3 = 0;
|
||||
m_mcu_uart = 0;
|
||||
|
||||
m_ppi_pa = 0;
|
||||
m_ppi_pb = 0;
|
||||
@ -375,6 +373,15 @@ void rtpc_state::mcu_port3_w(u8 data)
|
||||
// 6 o kbd data out
|
||||
// 7 o kbd clock out
|
||||
|
||||
// uart txd -> rxd wrap
|
||||
if (BIT(m_kls_cmd, 5))
|
||||
{
|
||||
if (BIT(data, 1))
|
||||
m_mcu_p3 |= 1;
|
||||
else
|
||||
m_mcu_p3 &= ~1;
|
||||
}
|
||||
|
||||
m_kbd_con->data_write_from_mb(BIT(data, 6));
|
||||
m_kbd_con->clock_write_from_mb(BIT(data, 7));
|
||||
|
||||
@ -578,18 +585,6 @@ void rtpc_state::common(machine_config &config)
|
||||
m_mcu->port_out_cb<2>().set(FUNC(rtpc_state::mcu_port2_w));
|
||||
m_mcu->port_in_cb<3>().set([this]() { return m_mcu_p3 | 0xce; });
|
||||
m_mcu->port_out_cb<3>().set(FUNC(rtpc_state::mcu_port3_w));
|
||||
m_mcu->serial_tx_cb().set(
|
||||
[this](u8 data)
|
||||
{
|
||||
if (BIT(m_kls_cmd, 5))
|
||||
{
|
||||
m_mcu_uart = data;
|
||||
m_mcu->set_input_line(MCS51_RX_LINE, 1);
|
||||
}
|
||||
else
|
||||
LOGMASKED(LOG_KLS, "kls uart tx 0x%02x\n", data);
|
||||
});
|
||||
m_mcu->serial_rx_cb().set([this]() { return m_mcu_uart; });
|
||||
|
||||
TIMER(config, "mcu_timer").configure_periodic(FUNC(rtpc_state::mcu_timer), attotime::from_hz(32768));
|
||||
|
||||
|
@ -14,17 +14,6 @@ BASIC-31 (and variants) as found on the below url, are homebrews.
|
||||
|
||||
https://web.archive.org/web/20110908004037/http://dsaprojects.110mb.com/electronics/8031-ah/8031-bas.html
|
||||
|
||||
|
||||
The driver is working, however there are issues with the cpu serial code.
|
||||
When started, you are supposed to press Space and the system works out
|
||||
the baud rate and boots up.
|
||||
|
||||
However, the way the cpu is written, it actually passes bytes around, so
|
||||
the auto-speed detection doesn't work as intended. Also the cpu interface
|
||||
is horribly outdated and needs to be brought up to date.
|
||||
|
||||
The optional eprom presents the ability to bypass the auto-speed problems.
|
||||
|
||||
Once the system starts, all input must be in uppercase. Read the manual
|
||||
to discover the special features of this Basic.
|
||||
|
||||
@ -36,7 +25,8 @@ Sound: BASIC-31 has sound, and BASIC-52 doesn't. The sound command is PWM.
|
||||
#include "emu.h"
|
||||
#include "cpu/mcs51/mcs51.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "machine/terminal.h"
|
||||
#include "bus/rs232/terminal.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "sound/spkrdev.h"
|
||||
#include "speaker.h"
|
||||
|
||||
@ -49,7 +39,7 @@ public:
|
||||
basic52_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_terminal(*this, "terminal")
|
||||
, m_serial(*this, "serial")
|
||||
, m_speaker(*this, "speaker")
|
||||
{ }
|
||||
|
||||
@ -58,15 +48,15 @@ public:
|
||||
|
||||
private:
|
||||
void machine_start() override;
|
||||
void kbd_put(u8 data);
|
||||
void port1_w(u8 data);
|
||||
uint8_t unk_r();
|
||||
uint8_t from_term();
|
||||
uint8_t port3_r();
|
||||
void port3_w(u8 data);
|
||||
void rx_w(int state);
|
||||
void io_map(address_map &map);
|
||||
void mem_map(address_map &map);
|
||||
uint8_t m_term_data = 0U;
|
||||
uint8_t m_port3 = 0U;
|
||||
required_device<mcs51_cpu_device> m_maincpu;
|
||||
required_device<generic_terminal_device> m_terminal;
|
||||
required_device<rs232_port_device> m_serial;
|
||||
required_device<speaker_sound_device> m_speaker;
|
||||
};
|
||||
|
||||
@ -82,9 +72,6 @@ void basic52_state::io_map(address_map &map)
|
||||
map.unmap_value_high();
|
||||
map(0x0000, 0x7fff).ram();
|
||||
// 8000-9FFF is reserved for a plug-in EPROM containing BASIC programs.
|
||||
// We have used this to preset the baud rate and skip the unreliable auto-detect.
|
||||
map(0x8000, 0x8000).lr8(NAME([] () { return 0x31; })); // we will be manually setting the baud rate
|
||||
map(0x8001, 0x8002).lr8(NAME([] () { return 0xFE; })); // to the fastest possible
|
||||
map(0xa000, 0xa003).rw("ppi8255", FUNC(i8255_device::read), FUNC(i8255_device::write)); // PPI-8255
|
||||
}
|
||||
|
||||
@ -93,14 +80,9 @@ static INPUT_PORTS_START( basic52 )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
uint8_t basic52_state::from_term()
|
||||
uint8_t basic52_state::port3_r()
|
||||
{
|
||||
return m_term_data;
|
||||
}
|
||||
|
||||
uint8_t basic52_state::unk_r()
|
||||
{
|
||||
return m_term_data; // won't boot without this
|
||||
return m_port3;
|
||||
}
|
||||
|
||||
void basic52_state::port1_w(u8 data)
|
||||
@ -108,17 +90,30 @@ void basic52_state::port1_w(u8 data)
|
||||
m_speaker->level_w(BIT(data, 2));
|
||||
}
|
||||
|
||||
|
||||
void basic52_state::kbd_put(u8 data)
|
||||
void basic52_state::port3_w(u8 data)
|
||||
{
|
||||
m_maincpu->set_input_line(MCS51_RX_LINE, ASSERT_LINE);
|
||||
m_maincpu->set_input_line(MCS51_RX_LINE, CLEAR_LINE);
|
||||
m_term_data = data;
|
||||
// preserve RXD
|
||||
m_port3 = (m_port3 & 1) | (data & ~1);
|
||||
|
||||
m_serial->write_txd(BIT(data, 1));
|
||||
}
|
||||
|
||||
void basic52_state::rx_w(int state)
|
||||
{
|
||||
if (state)
|
||||
m_port3 |= 1;
|
||||
else
|
||||
m_port3 &= ~1;
|
||||
}
|
||||
|
||||
void basic52_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_term_data));
|
||||
save_item(NAME(m_port3));
|
||||
}
|
||||
|
||||
static void serial_devices(device_slot_interface &device)
|
||||
{
|
||||
device.option_add("terminal", SERIAL_TERMINAL);
|
||||
}
|
||||
|
||||
void basic52_state::basic31(machine_config &config)
|
||||
@ -128,13 +123,11 @@ void basic52_state::basic31(machine_config &config)
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &basic52_state::mem_map);
|
||||
m_maincpu->set_addrmap(AS_IO, &basic52_state::io_map);
|
||||
m_maincpu->port_out_cb<1>().set(FUNC(basic52_state::port1_w));
|
||||
m_maincpu->port_in_cb<3>().set(FUNC(basic52_state::unk_r));
|
||||
m_maincpu->serial_tx_cb().set(m_terminal, FUNC(generic_terminal_device::write));
|
||||
m_maincpu->serial_rx_cb().set(FUNC(basic52_state::from_term));
|
||||
m_maincpu->port_out_cb<3>().set(FUNC(basic52_state::port3_w));
|
||||
m_maincpu->port_in_cb<3>().set(FUNC(basic52_state::port3_r));
|
||||
|
||||
/* video hardware */
|
||||
GENERIC_TERMINAL(config, m_terminal, 0);
|
||||
m_terminal->set_keyboard_callback(FUNC(basic52_state::kbd_put));
|
||||
RS232_PORT(config, m_serial, serial_devices, "terminal");
|
||||
m_serial->rxd_handler().set(FUNC(basic52_state::rx_w));
|
||||
|
||||
I8255(config, "ppi8255", 0);
|
||||
|
||||
@ -150,9 +143,8 @@ void basic52_state::basic52(machine_config &config)
|
||||
I8052(config.replace(), m_maincpu, XTAL(11'059'200));
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &basic52_state::mem_map);
|
||||
m_maincpu->set_addrmap(AS_IO, &basic52_state::io_map);
|
||||
m_maincpu->port_in_cb<3>().set(FUNC(basic52_state::unk_r));
|
||||
m_maincpu->serial_tx_cb().set(m_terminal, FUNC(generic_terminal_device::write));
|
||||
m_maincpu->serial_rx_cb().set(FUNC(basic52_state::from_term));
|
||||
m_maincpu->port_out_cb<3>().set(FUNC(basic52_state::port3_w));
|
||||
m_maincpu->port_in_cb<3>().set(FUNC(basic52_state::port3_r));
|
||||
}
|
||||
|
||||
/* ROM definition */
|
||||
|
@ -117,10 +117,6 @@ private:
|
||||
|
||||
void unk_ffa9_w(uint8_t data);
|
||||
|
||||
void tx(uint8_t data);
|
||||
uint8_t rx();
|
||||
|
||||
|
||||
uint8_t port0_r();
|
||||
void port0_w(u8 data);
|
||||
uint8_t port1_r();
|
||||
@ -520,28 +516,9 @@ uint32_t leapfrog_iquest_state::screen_update(screen_device &screen, bitmap_rgb3
|
||||
return 0;
|
||||
}
|
||||
|
||||
// never triggered?
|
||||
void leapfrog_iquest_state::tx(uint8_t data)
|
||||
{
|
||||
logerror("%s: transmitting %02x\n", machine().describe_context().c_str(), data);
|
||||
}
|
||||
|
||||
// never triggered?
|
||||
uint8_t leapfrog_iquest_state::rx()
|
||||
{
|
||||
logerror("%s: receiving\n", machine().describe_context().c_str());
|
||||
return machine().rand();
|
||||
}
|
||||
|
||||
|
||||
// doesn't help?
|
||||
WRITE_LINE_MEMBER(leapfrog_iquest_state::rx_line_hack)
|
||||
{
|
||||
/*
|
||||
m_maincpu->set_input_line(MCS51_RX_LINE, ASSERT_LINE);
|
||||
m_maincpu->set_input_line(MCS51_RX_LINE, CLEAR_LINE);
|
||||
*/
|
||||
|
||||
if (0)
|
||||
{
|
||||
// HACK: force past the wait loop if we're treating ff80 - ffff as RAM
|
||||
@ -605,8 +582,6 @@ void leapfrog_iquest_state::leapfrog_base(machine_config &config)
|
||||
I8032(config, m_maincpu, 96000000/10); // unknown clock
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &leapfrog_iquest_state::prog_map);
|
||||
m_maincpu->set_addrmap(AS_IO, &leapfrog_iquest_state::ext_map);
|
||||
m_maincpu->serial_tx_cb().set(FUNC(leapfrog_iquest_state::tx));
|
||||
m_maincpu->serial_rx_cb().set(FUNC(leapfrog_iquest_state::rx));
|
||||
m_maincpu->port_in_cb<0>().set(FUNC(leapfrog_iquest_state::port0_r));
|
||||
m_maincpu->port_out_cb<0>().set(FUNC(leapfrog_iquest_state::port0_w));
|
||||
m_maincpu->port_in_cb<1>().set(FUNC(leapfrog_iquest_state::port1_r));
|
||||
|
@ -234,8 +234,6 @@ private:
|
||||
void write_odd(uint16_t data);
|
||||
uint16_t read_odd();
|
||||
void vsync_int_ctrl(uint16_t data);
|
||||
uint8_t mcu_r(offs_t offset);
|
||||
void mcu_w(offs_t offset, uint8_t data);
|
||||
uint8_t b_read();
|
||||
void b_writ(uint8_t data);
|
||||
void strobe_w(uint8_t data);
|
||||
@ -243,14 +241,13 @@ private:
|
||||
uint8_t kbd_r();
|
||||
uint32_t screen_update_maygayv1(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
DECLARE_WRITE_LINE_MEMBER(screen_vblank_maygayv1);
|
||||
void data_from_i8031(uint8_t data);
|
||||
uint8_t data_to_i8031();
|
||||
uint8_t sound_p1_r();
|
||||
void sound_p1_w(uint8_t data);
|
||||
uint8_t sound_p3_r();
|
||||
void sound_p3_w(uint8_t data);
|
||||
DECLARE_WRITE_LINE_MEMBER(duart_irq_handler);
|
||||
DECLARE_WRITE_LINE_MEMBER(duart_txa);
|
||||
void main_map(address_map &map);
|
||||
void sound_data(address_map &map);
|
||||
void sound_io(address_map &map);
|
||||
void sound_prg(address_map &map);
|
||||
void cpu_space_map(address_map &map);
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
@ -273,7 +270,6 @@ private:
|
||||
int m_vsync_latch_preset = 0;
|
||||
uint8_t m_p1 = 0;
|
||||
uint8_t m_p3 = 0;
|
||||
int m_d68681_val = 0;
|
||||
i82716_t m_i82716;
|
||||
output_finder<8 * 256> m_lamp;
|
||||
};
|
||||
@ -616,59 +612,34 @@ void maygayv1_state::main_map(address_map &map)
|
||||
|
||||
*/
|
||||
|
||||
uint8_t maygayv1_state::mcu_r(offs_t offset)
|
||||
uint8_t maygayv1_state::sound_p1_r()
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
if ( !BIT(m_p3, 4) )
|
||||
return (ioport("REEL")->read()); // Reels???
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
case 3: return m_upd7759->busy_r() ? 0 : 0x08;
|
||||
}
|
||||
return 0;
|
||||
if (!BIT(m_p3, 4))
|
||||
return (ioport("REEL")->read()); // Reels???
|
||||
else
|
||||
return m_p1;
|
||||
}
|
||||
|
||||
void maygayv1_state::mcu_w(offs_t offset, uint8_t data)
|
||||
void maygayv1_state::sound_p1_w(uint8_t data)
|
||||
{
|
||||
logerror("O %x D %x",offset,data);
|
||||
m_p1 = data;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
// Bottom nibble = UPD
|
||||
case 1:
|
||||
m_p1 = data;
|
||||
// m_upd7759->msg_w(data);//?
|
||||
break;
|
||||
case 3:
|
||||
m_upd7759->reset_w (BIT(data, 2));
|
||||
m_upd7759->start_w(BIT(data, 6));
|
||||
|
||||
// if ( !BIT(m_p3, 7) && BIT(data, 7) )
|
||||
// P1 propagates to outputs
|
||||
|
||||
m_p3 = data;
|
||||
break;
|
||||
}
|
||||
m_upd7759->port_w(data);//?
|
||||
}
|
||||
|
||||
|
||||
void maygayv1_state::sound_prg(address_map &map)
|
||||
uint8_t maygayv1_state::sound_p3_r()
|
||||
{
|
||||
map(0x0000, 0xffff).rom();
|
||||
return m_upd7759->busy_r() ? m_p3 : (m_p3 | 0x08);
|
||||
}
|
||||
|
||||
void maygayv1_state::sound_data(address_map &map)
|
||||
void maygayv1_state::sound_p3_w(uint8_t data)
|
||||
{
|
||||
}
|
||||
// preserve RXD
|
||||
m_p3 = (m_p3 & 1) | (m_p3 & ~1);
|
||||
|
||||
void maygayv1_state::sound_io(address_map &map)
|
||||
{
|
||||
map(0x00, 0xff).rw(FUNC(maygayv1_state::mcu_r), FUNC(maygayv1_state::mcu_w));
|
||||
m_duart68681->rx_a_w(BIT(data, 1));
|
||||
m_upd7759->reset_w(BIT(data, 2));
|
||||
m_upd7759->start_w(BIT(data, 6));
|
||||
}
|
||||
|
||||
|
||||
@ -835,18 +806,10 @@ WRITE_LINE_MEMBER(maygayv1_state::duart_irq_handler)
|
||||
|
||||
WRITE_LINE_MEMBER(maygayv1_state::duart_txa)
|
||||
{
|
||||
m_d68681_val = state;
|
||||
m_soundcpu->set_input_line(MCS51_RX_LINE, ASSERT_LINE); // ?
|
||||
}
|
||||
|
||||
uint8_t maygayv1_state::data_to_i8031()
|
||||
{
|
||||
return m_d68681_val;
|
||||
}
|
||||
|
||||
void maygayv1_state::data_from_i8031(uint8_t data)
|
||||
{
|
||||
m_duart68681->rx_a_w(data);
|
||||
if (state)
|
||||
m_p3 |= 1;
|
||||
else
|
||||
m_p3 &= ~1;
|
||||
}
|
||||
|
||||
uint8_t maygayv1_state::b_read()
|
||||
@ -886,11 +849,10 @@ void maygayv1_state::maygayv1(machine_config &config)
|
||||
m_maincpu->set_addrmap(m68000_base_device::AS_CPU_SPACE, &maygayv1_state::cpu_space_map);
|
||||
|
||||
I8052(config, m_soundcpu, SOUND_CLOCK);
|
||||
m_soundcpu->set_addrmap(AS_PROGRAM, &maygayv1_state::sound_prg);
|
||||
m_soundcpu->set_addrmap(AS_DATA, &maygayv1_state::sound_data);
|
||||
m_soundcpu->set_addrmap(AS_IO, &maygayv1_state::sound_io);
|
||||
m_soundcpu->serial_tx_cb().set(FUNC(maygayv1_state::data_from_i8031));
|
||||
m_soundcpu->serial_rx_cb().set(FUNC(maygayv1_state::data_to_i8031));
|
||||
m_soundcpu->port_in_cb<1>().set(FUNC(maygayv1_state::sound_p1_r));
|
||||
m_soundcpu->port_out_cb<1>().set(FUNC(maygayv1_state::sound_p1_w));
|
||||
m_soundcpu->port_in_cb<3>().set(FUNC(maygayv1_state::sound_p3_r));
|
||||
m_soundcpu->port_out_cb<3>().set(FUNC(maygayv1_state::sound_p3_w));
|
||||
|
||||
/* U25 ST 2 9148 EF68B21P */
|
||||
pia6821_device &pia(PIA6821(config, "pia", 0));
|
||||
|
@ -334,8 +334,6 @@ void micro3d_state::micro3d(machine_config &config)
|
||||
m_audiocpu->port_out_cb<1>().set(FUNC(micro3d_state::micro3d_sound_p1_w));
|
||||
m_audiocpu->port_in_cb<3>().set(FUNC(micro3d_state::micro3d_sound_p3_r));
|
||||
m_audiocpu->port_out_cb<3>().set(FUNC(micro3d_state::micro3d_sound_p3_w));
|
||||
m_audiocpu->serial_tx_cb().set(FUNC(micro3d_state::data_from_i8031));
|
||||
m_audiocpu->serial_rx_cb().set(FUNC(micro3d_state::data_to_i8031));
|
||||
|
||||
MC68681(config, m_duart, 3.6864_MHz_XTAL);
|
||||
m_duart->irq_cb().set(FUNC(micro3d_state::duart_irq_handler));
|
||||
|
@ -177,8 +177,6 @@ private:
|
||||
INTERRUPT_GEN_MEMBER(micro3d_vblank);
|
||||
TIMER_CALLBACK_MEMBER(mac_done_callback);
|
||||
void micro3d_upd7759_w(uint8_t data);
|
||||
void data_from_i8031(uint8_t data);
|
||||
uint8_t data_to_i8031();
|
||||
DECLARE_WRITE_LINE_MEMBER(duart_irq_handler);
|
||||
uint8_t duart_input_r();
|
||||
void duart_output_w(uint8_t data);
|
||||
|
@ -39,20 +39,10 @@ WRITE_LINE_MEMBER(micro3d_state::duart_irq_handler)
|
||||
|
||||
WRITE_LINE_MEMBER(micro3d_state::duart_txb)
|
||||
{
|
||||
m_m68681_tx0 = state;
|
||||
m_audiocpu->set_input_line(MCS51_RX_LINE, ASSERT_LINE);
|
||||
// TODO: next line should be behind a timer callback which lasts one audiocpu clock cycle
|
||||
m_audiocpu->set_input_line(MCS51_RX_LINE, CLEAR_LINE);
|
||||
}
|
||||
|
||||
uint8_t micro3d_state::data_to_i8031()
|
||||
{
|
||||
return m_m68681_tx0;
|
||||
}
|
||||
|
||||
void micro3d_state::data_from_i8031(uint8_t data)
|
||||
{
|
||||
m_duart->rx_b_w(data);
|
||||
if (state)
|
||||
m_sound_port_latch[3] |= 1;
|
||||
else
|
||||
m_sound_port_latch[3] &= ~1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -463,8 +453,10 @@ void micro3d_state::micro3d_sound_p1_w(uint8_t data)
|
||||
|
||||
void micro3d_state::micro3d_sound_p3_w(uint8_t data)
|
||||
{
|
||||
m_sound_port_latch[3] = data;
|
||||
// preserve RXD input
|
||||
m_sound_port_latch[3] = (m_sound_port_latch[3] & 1) | (data & ~1);
|
||||
|
||||
m_duart->rx_b_w(BIT(data, 1));
|
||||
m_upd7759->set_rom_bank(BIT(data, 2));
|
||||
m_upd7759->reset_w(!BIT(data, 4));
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ private:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
void ctrl_w(uint8_t data);
|
||||
void mcs51_tx_callback(uint8_t data);
|
||||
void port3_w(uint8_t data);
|
||||
void led_strobe_w(uint8_t data);
|
||||
void lcd_latch_w(uint8_t data);
|
||||
void lcd_control_w(uint8_t data);
|
||||
@ -71,6 +71,8 @@ void piggypas_state::output_digits()
|
||||
m_digits[1] = bitswap<8>((m_digit_latch >> 8) & 0xff, 7,6,4,3,2,1,0,5) & 0x7f;
|
||||
m_digits[2] = bitswap<8>((m_digit_latch >> 16) & 0xff, 7,6,4,3,2,1,0,5) & 0x7f;
|
||||
m_digits[3] = bitswap<8>((m_digit_latch >> 24) & 0xff, 7,6,4,3,2,1,0,5) & 0x7f;
|
||||
|
||||
m_digit_latch = 0;
|
||||
}
|
||||
|
||||
void piggypas_state::ctrl_w(uint8_t data)
|
||||
@ -83,9 +85,15 @@ void piggypas_state::ctrl_w(uint8_t data)
|
||||
m_ctrl = data;
|
||||
}
|
||||
|
||||
void piggypas_state::mcs51_tx_callback(uint8_t data)
|
||||
void piggypas_state::port3_w(uint8_t data)
|
||||
{
|
||||
m_digit_latch = (m_digit_latch >> 8) | (u32(data) << 24);
|
||||
if (!BIT(data, 1))
|
||||
{
|
||||
m_digit_latch >>= 1;
|
||||
|
||||
if (BIT(data, 0))
|
||||
m_digit_latch |= (1U << 31);
|
||||
}
|
||||
}
|
||||
|
||||
void piggypas_state::led_strobe_w(uint8_t data)
|
||||
@ -197,7 +205,7 @@ void piggypas_state::piggypas(machine_config &config)
|
||||
m_maincpu->set_addrmap(AS_IO, &piggypas_state::piggypas_io);
|
||||
m_maincpu->port_out_cb<1>().set(FUNC(piggypas_state::led_strobe_w));
|
||||
m_maincpu->port_in_cb<3>().set_ioport("IN2");
|
||||
m_maincpu->serial_tx_cb().set(FUNC(piggypas_state::mcs51_tx_callback));
|
||||
m_maincpu->port_out_cb<3>().set(FUNC(piggypas_state::port3_w));
|
||||
// m_maincpu->set_vblank_int("screen", FUNC(piggypas_state::irq0_line_hold));
|
||||
|
||||
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); // DS1220AD
|
||||
@ -235,7 +243,6 @@ void piggypas_state::fidlstix(machine_config &config)
|
||||
piggypas(config);
|
||||
|
||||
m_maincpu->set_addrmap(AS_IO, &piggypas_state::fidlstix_io);
|
||||
m_maincpu->serial_tx_cb().set_nop();
|
||||
m_maincpu->port_in_cb<1>().set(m_hd44780, FUNC(hd44780_device::db_r));
|
||||
m_maincpu->port_out_cb<1>().set(FUNC(piggypas_state::lcd_latch_w));
|
||||
m_maincpu->port_out_cb<3>().set(FUNC(piggypas_state::lcd_control_w));
|
||||
|
@ -195,21 +195,21 @@ void cdi_state::machine_reset()
|
||||
|
||||
void quizard_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_mcu_rx_from_cpu));
|
||||
save_item(NAME(m_mcu_initial_byte));
|
||||
save_item(NAME(m_boot_press));
|
||||
|
||||
m_boot_timer = timer_alloc(FUNC(quizard_state::boot_press_tick), this);
|
||||
|
||||
set_data_frame(1, 8, PARITY_NONE, STOP_BITS_1);
|
||||
set_rate(9600);
|
||||
}
|
||||
|
||||
void quizard_state::machine_reset()
|
||||
{
|
||||
cdi_state::machine_reset();
|
||||
|
||||
m_mcu_rx_from_cpu = 0x00;
|
||||
m_mcu_initial_byte = true;
|
||||
m_boot_press = false;
|
||||
m_boot_timer->adjust(attotime::from_seconds(13), 1);
|
||||
m_mcu_p3 = 0x04;
|
||||
}
|
||||
|
||||
|
||||
@ -288,16 +288,8 @@ void quizard_state::mcu_rtsn_from_cpu(int state)
|
||||
void quizard_state::mcu_rx_from_cpu(uint8_t data)
|
||||
{
|
||||
LOGMASKED(LOG_UART, "MCU receiving %02x from CPU\n", data);
|
||||
if (m_mcu_initial_byte)
|
||||
{
|
||||
m_mcu_initial_byte = false;
|
||||
return;
|
||||
}
|
||||
|
||||
m_mcu_rx_from_cpu = data;
|
||||
|
||||
m_mcu->set_input_line(MCS51_RX_LINE, ASSERT_LINE);
|
||||
m_mcu->set_input_line(MCS51_RX_LINE, CLEAR_LINE);
|
||||
transmit_register_setup(data);
|
||||
}
|
||||
|
||||
uint8_t quizard_state::mcu_p0_r()
|
||||
@ -325,8 +317,8 @@ uint8_t quizard_state::mcu_p2_r()
|
||||
|
||||
uint8_t quizard_state::mcu_p3_r()
|
||||
{
|
||||
LOGMASKED(LOG_QUIZARD_READS, "%s: MCU Port 3 Read (%02x)\n", machine().describe_context(), 0x04);
|
||||
return 0x04;
|
||||
LOGMASKED(LOG_QUIZARD_READS, "%s: MCU Port 3 Read (%02x)\n", machine().describe_context(), m_mcu_p3);
|
||||
return m_mcu_p3;
|
||||
}
|
||||
|
||||
void quizard_state::mcu_p0_w(uint8_t data)
|
||||
@ -347,22 +339,10 @@ void quizard_state::mcu_p2_w(uint8_t data)
|
||||
void quizard_state::mcu_p3_w(uint8_t data)
|
||||
{
|
||||
LOGMASKED(LOG_QUIZARD_WRITES, "%s: MCU Port 3 Write (%02x)\n", machine().describe_context(), data);
|
||||
rx_w(BIT(data, 1));
|
||||
m_maincpu->uart_ctsn(BIT(data, 6));
|
||||
}
|
||||
|
||||
void quizard_state::mcu_tx(uint8_t data)
|
||||
{
|
||||
LOGMASKED(LOG_QUIZARD_OTHER, "%s: MCU transmitting %02x\n", machine().describe_context(), data);
|
||||
m_maincpu->uart_rx(data);
|
||||
}
|
||||
|
||||
uint8_t quizard_state::mcu_rx()
|
||||
{
|
||||
uint8_t data = m_mcu_rx_from_cpu;
|
||||
LOGMASKED(LOG_QUIZARD_OTHER, "%s: MCU receiving %02x\n", machine().describe_context(), data);
|
||||
return data;
|
||||
}
|
||||
|
||||
/*************************
|
||||
* DVC cartridge *
|
||||
*************************/
|
||||
@ -601,7 +581,7 @@ void quizard_state::quizard(machine_config &config)
|
||||
m_maincpu->uart_rtsn_callback().set(FUNC(quizard_state::mcu_rtsn_from_cpu));
|
||||
m_maincpu->uart_tx_callback().set(FUNC(quizard_state::mcu_rx_from_cpu));
|
||||
|
||||
I8751(config, m_mcu, 8000000);
|
||||
I8751(config, m_mcu, 11.0592_MHz_XTAL);
|
||||
m_mcu->port_in_cb<0>().set(FUNC(quizard_state::mcu_p0_r));
|
||||
m_mcu->port_in_cb<1>().set(FUNC(quizard_state::mcu_p1_r));
|
||||
m_mcu->port_in_cb<2>().set(FUNC(quizard_state::mcu_p2_r));
|
||||
@ -610,12 +590,27 @@ void quizard_state::quizard(machine_config &config)
|
||||
m_mcu->port_out_cb<1>().set(FUNC(quizard_state::mcu_p1_w));
|
||||
m_mcu->port_out_cb<2>().set(FUNC(quizard_state::mcu_p2_w));
|
||||
m_mcu->port_out_cb<3>().set(FUNC(quizard_state::mcu_p3_w));
|
||||
m_mcu->serial_tx_cb().set(FUNC(quizard_state::mcu_tx));
|
||||
m_mcu->serial_rx_cb().set(FUNC(quizard_state::mcu_rx));
|
||||
|
||||
m_slave_hle->read_mousebtn().set(FUNC(quizard_state::mcu_button_press));
|
||||
}
|
||||
|
||||
void quizard_state::tra_callback()
|
||||
{
|
||||
if (transmit_register_get_data_bit())
|
||||
m_mcu_p3 |= 1;
|
||||
else
|
||||
m_mcu_p3 &= ~1;
|
||||
}
|
||||
|
||||
void quizard_state::rcv_complete()
|
||||
{
|
||||
receive_register_extract();
|
||||
|
||||
const uint8_t data = get_received_char();
|
||||
LOGMASKED(LOG_QUIZARD_OTHER, "%s: MCU transmitting %02x\n", machine().describe_context(), data);
|
||||
m_maincpu->uart_rx(data);
|
||||
}
|
||||
|
||||
/*************************
|
||||
* Rom Load *
|
||||
*************************/
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "mcd212.h"
|
||||
#include "cpu/mcs51/mcs51.h"
|
||||
#include "cpu/m6805/m68hc05.h"
|
||||
#include "diserial.h"
|
||||
#include "screen.h"
|
||||
|
||||
/*----------- driver state -----------*/
|
||||
@ -81,11 +82,12 @@ private:
|
||||
required_device_array<dmadac_sound_device, 2> m_dmadac;
|
||||
};
|
||||
|
||||
class quizard_state : public cdi_state
|
||||
class quizard_state : public cdi_state, public device_serial_interface
|
||||
{
|
||||
public:
|
||||
quizard_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: cdi_state(mconfig, type, tag)
|
||||
, device_serial_interface(mconfig, *this)
|
||||
, m_mcu(*this, "mcu")
|
||||
, m_inputs(*this, "P%u", 0U)
|
||||
{ }
|
||||
@ -96,6 +98,9 @@ private:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
virtual void tra_callback() override;
|
||||
virtual void rcv_complete() override;
|
||||
|
||||
TIMER_CALLBACK_MEMBER(boot_press_tick);
|
||||
|
||||
uint8_t mcu_p0_r();
|
||||
@ -106,8 +111,6 @@ private:
|
||||
void mcu_p1_w(uint8_t data);
|
||||
void mcu_p2_w(uint8_t data);
|
||||
void mcu_p3_w(uint8_t data);
|
||||
void mcu_tx(uint8_t data);
|
||||
uint8_t mcu_rx();
|
||||
|
||||
void mcu_rx_from_cpu(uint8_t data);
|
||||
void mcu_rtsn_from_cpu(int state);
|
||||
@ -117,10 +120,9 @@ private:
|
||||
required_device<i8751_device> m_mcu;
|
||||
required_ioport_array<3> m_inputs;
|
||||
|
||||
uint8_t m_mcu_rx_from_cpu = 0U;
|
||||
bool m_mcu_initial_byte = false;
|
||||
bool m_boot_press = false;
|
||||
emu_timer *m_boot_timer = nullptr;
|
||||
uint8_t m_mcu_p3 = 0x04;
|
||||
};
|
||||
|
||||
// Quizard 2 language values:
|
||||
|
@ -156,6 +156,8 @@ private:
|
||||
uint8_t port1_r();
|
||||
uint8_t port3_r();
|
||||
|
||||
void serial_rxd(int state);
|
||||
|
||||
void dev_ctrl_reg_w(offs_t offset, uint8_t data);
|
||||
uint8_t dev_keyb_ser_r(offs_t offset);
|
||||
|
||||
@ -243,9 +245,16 @@ void minitel_state::port3_w(uint8_t data)
|
||||
|
||||
m_serport->write_txd( !!(data & PORT_3_SER_TXD) );
|
||||
|
||||
port3 = data;
|
||||
port3 = (port3 & PORT_3_SER_RXD) | (data & ~PORT_3_SER_RXD);
|
||||
}
|
||||
|
||||
void minitel_state::serial_rxd(int state)
|
||||
{
|
||||
if (state)
|
||||
port3 |= PORT_3_SER_RXD;
|
||||
else
|
||||
port3 &= ~PORT_3_SER_RXD;
|
||||
}
|
||||
|
||||
|
||||
void minitel_state::update_modem_state()
|
||||
@ -532,7 +541,7 @@ void minitel_state::minitel2(machine_config &config)
|
||||
m_modem->set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(m_modem));
|
||||
|
||||
RS232_PORT(config, m_serport, default_rs232_devices, nullptr);
|
||||
m_serport->rxd_handler().set_inputline(m_maincpu, MCS51_RX_LINE);
|
||||
m_serport->rxd_handler().set(FUNC(minitel_state::serial_rxd));
|
||||
m_serport->set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(m_serport));
|
||||
|
||||
lineconnected = 0;
|
||||
|
@ -235,7 +235,6 @@ void mephisto_state::mephisto(machine_config &config)
|
||||
soundcpu.port_in_cb<1>().set(FUNC(mephisto_state::ay8910_read));
|
||||
soundcpu.port_out_cb<1>().set(FUNC(mephisto_state::ay8910_write));
|
||||
soundcpu.port_out_cb<3>().set(FUNC(mephisto_state::t0_t1_w));
|
||||
soundcpu.serial_rx_cb().set_constant(0); // from MUART
|
||||
|
||||
/* Sound */
|
||||
genpin_audio(config);
|
||||
|
@ -10,8 +10,6 @@
|
||||
#include "video/scn2674.h"
|
||||
#include "emupal.h"
|
||||
|
||||
#include "diserial.h"
|
||||
|
||||
|
||||
class pcdx_video_device : public device_t, public device_gfx_interface
|
||||
{
|
||||
@ -78,12 +76,12 @@ private:
|
||||
SCN2674_DRAW_CHARACTER_MEMBER(display_pixels);
|
||||
};
|
||||
|
||||
class pcx_video_device : public pcdx_video_device,
|
||||
public device_serial_interface
|
||||
class pcx_video_device : public pcdx_video_device
|
||||
{
|
||||
public:
|
||||
pcx_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
auto txd_handler() { return m_txd_handler.bind(); }
|
||||
void rx_w(int state);
|
||||
|
||||
virtual void map(address_map &map) override;
|
||||
uint8_t term_r(offs_t offset);
|
||||
@ -103,18 +101,15 @@ protected:
|
||||
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
|
||||
void tra_callback() override;
|
||||
void rcv_complete() override;
|
||||
|
||||
private:
|
||||
required_device<scn2672_device> m_crtc;
|
||||
|
||||
required_region_ptr<uint8_t> m_charrom;
|
||||
devcb_write_line m_txd_handler;
|
||||
uint8_t m_term_key, m_term_char, m_term_stat, m_p1;
|
||||
uint8_t m_term_key, m_term_char, m_term_stat, m_p1, m_p3;
|
||||
|
||||
uint8_t rx_callback();
|
||||
void tx_callback(uint8_t data);
|
||||
uint8_t p3_r();
|
||||
void p3_w(uint8_t data);
|
||||
|
||||
SCN2672_DRAW_CHARACTER_MEMBER(display_pixels);
|
||||
};
|
||||
|
@ -34,7 +34,6 @@ pcd_video_device::pcd_video_device(const machine_config &mconfig, const char *ta
|
||||
|
||||
pcx_video_device::pcx_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
pcdx_video_device(mconfig, PCX_VIDEO, tag, owner, clock),
|
||||
device_serial_interface(mconfig, *this),
|
||||
m_crtc(*this, "crtc"),
|
||||
m_charrom(*this, "char"),
|
||||
m_txd_handler(*this)
|
||||
@ -152,8 +151,8 @@ void pcx_video_device::device_add_mconfig(machine_config &config)
|
||||
gfx.set_addrmap(AS_PROGRAM, &pcx_video_device::pcx_vid_map);
|
||||
gfx.set_addrmap(AS_IO, &pcx_video_device::pcx_vid_io);
|
||||
gfx.port_out_cb<1>().set(FUNC(pcx_video_device::p1_w));
|
||||
gfx.serial_tx_cb().set(FUNC(pcx_video_device::tx_callback));
|
||||
gfx.serial_rx_cb().set(FUNC(pcx_video_device::rx_callback));
|
||||
gfx.port_in_cb<3>().set(FUNC(pcx_video_device::p3_r));
|
||||
gfx.port_out_cb<3>().set(FUNC(pcx_video_device::p3_w));
|
||||
|
||||
// video hardware
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
@ -422,9 +421,6 @@ void pcx_video_device::device_start()
|
||||
m_maincpu->space(AS_IO).install_readwrite_handler(0xfb00, 0xfb01, read8smo_delegate(*this, FUNC(pcdx_video_device::detect_r)), write8smo_delegate(*this, FUNC(pcdx_video_device::detect_w)), 0x00ff);
|
||||
m_txd_handler.resolve_safe();
|
||||
|
||||
set_data_frame(1, 8, PARITY_NONE, STOP_BITS_1);
|
||||
set_rate(600);
|
||||
|
||||
decode_gfx(gfx_pcx);
|
||||
}
|
||||
|
||||
@ -432,8 +428,6 @@ void pcx_video_device::device_reset()
|
||||
{
|
||||
m_term_key = 0;
|
||||
m_term_stat = 0;
|
||||
transmit_register_reset();
|
||||
receive_register_reset();
|
||||
|
||||
m_txd_handler(1);
|
||||
}
|
||||
@ -443,24 +437,23 @@ void pcx_video_device::map(address_map &map)
|
||||
map(0x0, 0xf).rw(FUNC(pcx_video_device::term_r), FUNC(pcx_video_device::term_w));
|
||||
}
|
||||
|
||||
uint8_t pcx_video_device::rx_callback()
|
||||
void pcx_video_device::rx_w(int state)
|
||||
{
|
||||
return get_received_char();
|
||||
if (state)
|
||||
m_p3 |= 1;
|
||||
else
|
||||
m_p3 &= ~1;
|
||||
}
|
||||
|
||||
void pcx_video_device::tx_callback(uint8_t data)
|
||||
uint8_t pcx_video_device::p3_r()
|
||||
{
|
||||
transmit_register_setup(data);
|
||||
return m_p3;
|
||||
}
|
||||
|
||||
void pcx_video_device::tra_callback()
|
||||
void pcx_video_device::p3_w(uint8_t data)
|
||||
{
|
||||
m_txd_handler(transmit_register_get_data_bit());
|
||||
}
|
||||
// preserve RXD
|
||||
m_p3 = (m_p3 & 1) | (data & ~1);
|
||||
|
||||
void pcx_video_device::rcv_complete()
|
||||
{
|
||||
receive_register_extract();
|
||||
m_mcu->set_input_line(MCS51_RX_LINE, ASSERT_LINE);
|
||||
m_mcu->set_input_line(MCS51_RX_LINE, CLEAR_LINE);
|
||||
m_txd_handler(BIT(data, 1));
|
||||
}
|
||||
|
@ -64,7 +64,8 @@ Current status:
|
||||
#include "emu.h"
|
||||
#include "cpu/mcs51/mcs51.h"
|
||||
#include "sound/tms5220.h"
|
||||
#include "machine/terminal.h"
|
||||
#include "bus/rs232/terminal.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "speaker.h"
|
||||
|
||||
|
||||
@ -76,7 +77,7 @@ public:
|
||||
pes_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_terminal(*this, "terminal")
|
||||
, m_serial(*this, "serial")
|
||||
, m_speech(*this, "tms5220")
|
||||
{ }
|
||||
|
||||
@ -84,34 +85,25 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
u8 m_term_data = 0U;
|
||||
u8 m_port3 = 0U;
|
||||
virtual void machine_reset() override;
|
||||
void port3_w(u8 data);
|
||||
u8 port3_r();
|
||||
void kbd_put(u8 data);
|
||||
void rx_w(int state);
|
||||
void io_map(address_map &map);
|
||||
void prg_map(address_map &map);
|
||||
required_device<i80c31_device> m_maincpu;
|
||||
required_device<generic_terminal_device> m_terminal;
|
||||
required_device<rs232_port_device> m_serial;
|
||||
required_device<tms5220_device> m_speech;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Devices */
|
||||
void pes_state::kbd_put(u8 data)
|
||||
{
|
||||
m_maincpu->set_input_line(MCS51_RX_LINE, ASSERT_LINE);
|
||||
m_maincpu->set_input_line(MCS51_RX_LINE, CLEAR_LINE);
|
||||
m_term_data = data;
|
||||
}
|
||||
|
||||
|
||||
/* Port Handlers */
|
||||
void pes_state::port3_w(u8 data)
|
||||
{
|
||||
m_port3 = data;
|
||||
// preserve RXD
|
||||
m_port3 = (m_port3 & 0x01) | (data & ~0x01);
|
||||
#if 0
|
||||
logerror("port3 write: control data written: %02X; ", data);
|
||||
logerror("RXD: %d; ", BIT(data,0));
|
||||
@ -123,7 +115,7 @@ void pes_state::port3_w(u8 data)
|
||||
logerror("WR: %d; ", BIT(data,6));
|
||||
logerror("RD: %d;\n", BIT(data,7));
|
||||
#endif
|
||||
// todo: poke serial handler here somehow?
|
||||
m_serial->write_txd(BIT(data, 1));
|
||||
}
|
||||
|
||||
u8 pes_state::port3_r()
|
||||
@ -136,6 +128,14 @@ u8 pes_state::port3_r()
|
||||
return data;
|
||||
}
|
||||
|
||||
void pes_state::rx_w(int state)
|
||||
{
|
||||
if (state)
|
||||
m_port3 |= 1;
|
||||
else
|
||||
m_port3 &= ~1;
|
||||
}
|
||||
|
||||
|
||||
/* Reset */
|
||||
void pes_state::machine_reset()
|
||||
@ -171,6 +171,11 @@ INPUT_PORTS_END
|
||||
Machine Drivers
|
||||
******************************************************************************/
|
||||
|
||||
static void serial_devices(device_slot_interface &device)
|
||||
{
|
||||
device.option_add("terminal", SERIAL_TERMINAL);
|
||||
}
|
||||
|
||||
void pes_state::pes(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
@ -181,16 +186,14 @@ void pes_state::pes(machine_config &config)
|
||||
m_maincpu->port_out_cb<1>().set(m_speech, FUNC(tms5220_device::data_w));
|
||||
m_maincpu->port_in_cb<3>().set(FUNC(pes_state::port3_r));
|
||||
m_maincpu->port_out_cb<3>().set(FUNC(pes_state::port3_w));
|
||||
m_maincpu->serial_tx_cb().set(m_terminal, FUNC(generic_terminal_device::write));
|
||||
m_maincpu->serial_rx_cb().set([this] () { return m_term_data; });
|
||||
|
||||
/* sound hardware */
|
||||
SPEAKER(config, "mono").front_center();
|
||||
TMS5220C(config, m_speech, 720000); /* 720Khz clock, 9khz sample-rate, adjustable with 10-turn trimpot */
|
||||
m_speech->add_route(ALL_OUTPUTS, "mono", 1.0);
|
||||
|
||||
GENERIC_TERMINAL(config, m_terminal, 0);
|
||||
m_terminal->set_keyboard_callback(FUNC(pes_state::kbd_put));
|
||||
RS232_PORT(config, m_serial, serial_devices, "terminal");
|
||||
m_serial->rxd_handler().set(FUNC(pes_state::rx_w));
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -52,7 +52,6 @@ private:
|
||||
void scan_load_w(u8 data);
|
||||
u8 scan_shift_r();
|
||||
void lcd_control_w(u8 data);
|
||||
void serial_tx_w(u8 data) { logerror("Serial TX: %02X\n", data); }
|
||||
|
||||
void prog_map(address_map &map);
|
||||
void ext_map(address_map &map);
|
||||
@ -163,7 +162,6 @@ void sk101bl_state::sk101bl(machine_config &config)
|
||||
m_maincpu->port_in_cb<1>().set(FUNC(sk101bl_state::p1_r));
|
||||
m_maincpu->port_out_cb<1>().set(FUNC(sk101bl_state::p1_w));
|
||||
m_maincpu->port_out_cb<3>().set("alarm", FUNC(speaker_sound_device::level_w)).bit(3);
|
||||
m_maincpu->serial_tx_cb().set(FUNC(sk101bl_state::serial_tx_w));
|
||||
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD));
|
||||
screen.set_refresh_hz(50);
|
||||
|
@ -71,9 +71,11 @@ private:
|
||||
u8 dma_r(offs_t offset);
|
||||
u8 key_r(offs_t offset);
|
||||
u8 port1_r();
|
||||
u8 port3_r();
|
||||
void store_w(u8 data);
|
||||
void port1_w(u8 data);
|
||||
void port3_w(u8 data);
|
||||
void rx_w(int state);
|
||||
I8275_DRAW_CHARACTER_MEMBER(crtc_update_row);
|
||||
|
||||
void io_map(address_map &map);
|
||||
@ -94,6 +96,8 @@ private:
|
||||
required_device<ttl7474_device> m_7474;
|
||||
required_device<rs232_port_device> m_rs232;
|
||||
required_device<centronics_device> m_centronics;
|
||||
|
||||
u8 m_port3;
|
||||
};
|
||||
|
||||
void trs80dt1_state::machine_reset()
|
||||
@ -103,6 +107,7 @@ void trs80dt1_state::machine_reset()
|
||||
// line is active low in the real chip
|
||||
m_nvram->recall(1);
|
||||
m_nvram->recall(0);
|
||||
m_port3 = 0;
|
||||
}
|
||||
|
||||
u8 trs80dt1_state::dma_r(offs_t offset)
|
||||
@ -158,6 +163,21 @@ void trs80dt1_state::port3_w(u8 data)
|
||||
{
|
||||
m_rs232->write_txd(BIT(data, 1));
|
||||
m_buzzer->set_state(BIT(data, 4));
|
||||
|
||||
m_port3 = (m_port3 & 1) | (data & ~1);
|
||||
}
|
||||
|
||||
u8 trs80dt1_state::port3_r()
|
||||
{
|
||||
return m_port3;
|
||||
}
|
||||
|
||||
void trs80dt1_state::rx_w(int state)
|
||||
{
|
||||
if (state)
|
||||
m_port3 |= 1;
|
||||
else
|
||||
m_port3 &= ~1;
|
||||
}
|
||||
|
||||
void trs80dt1_state::prg_map(address_map &map)
|
||||
@ -341,6 +361,7 @@ void trs80dt1_state::trs80dt1(machine_config &config)
|
||||
m_maincpu->port_out_cb<1>().set(FUNC(trs80dt1_state::port1_w));
|
||||
m_maincpu->port_in_cb<1>().set(FUNC(trs80dt1_state::port1_r));
|
||||
m_maincpu->port_out_cb<3>().set(FUNC(trs80dt1_state::port3_w));
|
||||
m_maincpu->port_in_cb<3>().set(FUNC(trs80dt1_state::port3_r));
|
||||
|
||||
/* video hardware */
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
@ -373,7 +394,7 @@ void trs80dt1_state::trs80dt1(machine_config &config)
|
||||
BEEP(config, m_buzzer, 2000).add_route(ALL_OUTPUTS, "mono", 0.50);
|
||||
|
||||
RS232_PORT(config, m_rs232, default_rs232_devices, nullptr);
|
||||
m_rs232->rxd_handler().set_inputline("maincpu", MCS51_RX_LINE);
|
||||
m_rs232->rxd_handler().set(FUNC(trs80dt1_state::rx_w));
|
||||
|
||||
/* printer */
|
||||
CENTRONICS(config, m_centronics, centronics_devices, "printer");
|
||||
|
@ -44,7 +44,6 @@ Notes:
|
||||
|
||||
TODO:
|
||||
|
||||
- rewrite the mcs51.c serial I/O to replace this horrible, horrible hack
|
||||
- dip switches
|
||||
|
||||
*/
|
||||
@ -119,9 +118,8 @@ void wangpc_keyboard_device::device_add_mconfig(machine_config &config)
|
||||
m_maincpu->port_in_cb<1>().set(FUNC(wangpc_keyboard_device::kb_p1_r));
|
||||
m_maincpu->port_out_cb<1>().set(FUNC(wangpc_keyboard_device::kb_p1_w));
|
||||
m_maincpu->port_out_cb<2>().set(FUNC(wangpc_keyboard_device::kb_p2_w));
|
||||
m_maincpu->port_in_cb<3>().set(FUNC(wangpc_keyboard_device::kb_p3_r));
|
||||
m_maincpu->port_out_cb<3>().set(FUNC(wangpc_keyboard_device::kb_p3_w));
|
||||
m_maincpu->serial_tx_cb().set(FUNC(wangpc_keyboard_device::mcs51_tx_callback));
|
||||
m_maincpu->serial_rx_cb().set(FUNC(wangpc_keyboard_device::mcs51_rx_callback));
|
||||
|
||||
// sound hardware
|
||||
SPEAKER(config, "mono").front_center();
|
||||
@ -369,7 +367,6 @@ ioport_constructor wangpc_keyboard_device::device_input_ports() const
|
||||
|
||||
wangpc_keyboard_device::wangpc_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, WANGPC_KEYBOARD, tag, owner, clock),
|
||||
device_serial_interface(mconfig, *this),
|
||||
m_maincpu(*this, I8051_TAG),
|
||||
m_y(*this, "Y%u", 0),
|
||||
m_txd_handler(*this),
|
||||
@ -389,11 +386,6 @@ void wangpc_keyboard_device::device_start()
|
||||
m_txd_handler.resolve_safe();
|
||||
m_leds.resolve();
|
||||
|
||||
set_data_frame(1, 8, PARITY_NONE, STOP_BITS_2);
|
||||
|
||||
set_rcv_rate(62500);
|
||||
set_tra_rate(62500);
|
||||
|
||||
save_item(NAME(m_keylatch));
|
||||
save_item(NAME(m_rxd));
|
||||
}
|
||||
@ -405,63 +397,10 @@ void wangpc_keyboard_device::device_start()
|
||||
|
||||
void wangpc_keyboard_device::device_reset()
|
||||
{
|
||||
receive_register_reset();
|
||||
transmit_register_reset();
|
||||
|
||||
m_txd_handler(1);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// tra_callback -
|
||||
//-------------------------------------------------
|
||||
|
||||
void wangpc_keyboard_device::tra_callback()
|
||||
{
|
||||
int bit = transmit_register_get_data_bit();
|
||||
|
||||
if (LOG) logerror("KB '%s' Transmit Bit %u\n", tag(), bit);
|
||||
|
||||
m_txd_handler(bit);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// tra_complete -
|
||||
//-------------------------------------------------
|
||||
|
||||
void wangpc_keyboard_device::tra_complete()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// rcv_callback -
|
||||
//-------------------------------------------------
|
||||
|
||||
void wangpc_keyboard_device::rcv_callback()
|
||||
{
|
||||
if (LOG) logerror("KB '%s' Receive Bit %u\n", tag(), m_rxd);
|
||||
|
||||
receive_register_update_bit(m_rxd);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// rcv_complete -
|
||||
//-------------------------------------------------
|
||||
|
||||
void wangpc_keyboard_device::rcv_complete()
|
||||
{
|
||||
receive_register_extract();
|
||||
|
||||
if (LOG) logerror("KB '%s' Receive Data %02x\n", tag(), get_received_char());
|
||||
|
||||
m_maincpu->set_input_line(MCS51_RX_LINE, ASSERT_LINE);
|
||||
m_maincpu->set_input_line(MCS51_RX_LINE, CLEAR_LINE);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// write_rxd -
|
||||
//-------------------------------------------------
|
||||
@ -469,32 +408,6 @@ void wangpc_keyboard_device::rcv_complete()
|
||||
WRITE_LINE_MEMBER(wangpc_keyboard_device::write_rxd)
|
||||
{
|
||||
m_rxd = state;
|
||||
|
||||
device_serial_interface::rx_w(state);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// mcs51_rx_callback -
|
||||
//-------------------------------------------------
|
||||
|
||||
uint8_t wangpc_keyboard_device::mcs51_rx_callback()
|
||||
{
|
||||
if (LOG) logerror("KB '%s' CPU Receive Data %02x\n", tag(), get_received_char());
|
||||
|
||||
return get_received_char();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// mcs51_tx_callback -
|
||||
//-------------------------------------------------
|
||||
|
||||
void wangpc_keyboard_device::mcs51_tx_callback(uint8_t data)
|
||||
{
|
||||
if (LOG) logerror("KB '%s' CPU Transmit Data %02x\n", tag(), data);
|
||||
|
||||
transmit_register_setup(data);
|
||||
}
|
||||
|
||||
|
||||
@ -565,6 +478,16 @@ void wangpc_keyboard_device::kb_p2_w(uint8_t data)
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// kb_p3_r -
|
||||
//-------------------------------------------------
|
||||
|
||||
uint8_t wangpc_keyboard_device::kb_p3_r()
|
||||
{
|
||||
return m_rxd;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// kb_p3_w -
|
||||
//-------------------------------------------------
|
||||
@ -587,4 +510,5 @@ void wangpc_keyboard_device::kb_p3_w(uint8_t data)
|
||||
*/
|
||||
|
||||
//if (LOG) logerror("P3 %02x\n", data);
|
||||
m_txd_handler(BIT(data, 1));
|
||||
}
|
||||
|
@ -15,8 +15,6 @@
|
||||
|
||||
#include "sound/sn76496.h"
|
||||
|
||||
#include "diserial.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
@ -24,7 +22,7 @@
|
||||
|
||||
// ======================> wangpc_keyboard_device
|
||||
|
||||
class wangpc_keyboard_device : public device_t, public device_serial_interface
|
||||
class wangpc_keyboard_device : public device_t
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
@ -46,12 +44,6 @@ protected:
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual ioport_constructor device_input_ports() const override;
|
||||
|
||||
// device_serial_interface overrides
|
||||
virtual void tra_callback() override;
|
||||
virtual void tra_complete() override;
|
||||
virtual void rcv_callback() override;
|
||||
virtual void rcv_complete() override;
|
||||
|
||||
private:
|
||||
required_device<i8051_device> m_maincpu;
|
||||
required_ioport_array<16> m_y;
|
||||
@ -61,12 +53,10 @@ private:
|
||||
uint8_t m_keylatch;
|
||||
int m_rxd;
|
||||
|
||||
uint8_t mcs51_rx_callback();
|
||||
void mcs51_tx_callback(uint8_t data);
|
||||
|
||||
uint8_t kb_p1_r();
|
||||
void kb_p1_w(uint8_t data);
|
||||
void kb_p2_w(uint8_t data);
|
||||
uint8_t kb_p3_r();
|
||||
void kb_p3_w(uint8_t data);
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user