3b2: CONTTY line configuration

Adds modem control line speed configuration to prevent FIFO overflow.
This commit is contained in:
Seth Morabito 2017-12-16 16:06:06 -08:00
parent 52990b3bc2
commit 7bb02e7530
4 changed files with 70 additions and 49 deletions

View file

@ -333,6 +333,9 @@ extern DEVICE dmac_dev;
/* global symbols from the CSR */
extern uint16 csr_data;
/* global symbols from the timer */
extern int32 tmxr_poll;
/* global symbols from the IU */
extern t_bool iu_increment_a;
extern t_bool iu_increment_b;

View file

@ -178,8 +178,8 @@ REG contty_reg[] = {
};
UNIT contty_unit[2] = {
{ UDATA(&iu_svc_contty, UNIT_IDLE|UNIT_ATTABLE, 0) },
{ UDATA(&iu_svc_contty_xmt, UNIT_DIS, 0), SERIAL_OUT_WAIT }
{ UDATA(&iu_svc_contty_rcv, UNIT_ATTABLE, 0) },
{ UDATA(&iu_svc_contty_xmt, TT_MODE_8B, 0), SERIAL_OUT_WAIT }
};
UNIT *contty_rcv_unit = &contty_unit[0];
@ -259,7 +259,7 @@ void increment_modep_b()
}
void iu_txrdy_a_irq() {
if ((iu_state.imr & ISTS_TAI) &&
if ((iu_state.imr & IMR_TXRA) &&
(iu_console.conf & TX_EN) &&
(iu_console.stat & STS_TXR)) {
csr_data |= CSRUART;
@ -267,7 +267,7 @@ void iu_txrdy_a_irq() {
}
void iu_txrdy_b_irq() {
if ((iu_state.imr & ISTS_TBI) &&
if ((iu_state.imr & IMR_TXRB) &&
(iu_contty.conf & TX_EN) &&
(iu_contty.stat & STS_TXR)) {
csr_data |= CSRUART;
@ -300,6 +300,10 @@ t_stat contty_reset(DEVICE *dtpr)
(TMLN *)calloc(1, sizeof(*contty_ldsc));
}
memset(&iu_state, 0, sizeof(IU_STATE));
memset(&iu_contty, 0, sizeof(IU_PORT));
tmxr_set_config_line(&contty_ldsc[0], "115200-8N1");
/* Start the CONTTY polling loop */
if (!sim_is_active(contty_rcv_unit)) {
sim_activate(contty_rcv_unit, contty_rcv_unit->wait);
@ -321,7 +325,7 @@ t_stat iu_svc_tti(UNIT *uptr)
{
int32 temp;
sim_clock_coschedule_tmr_abs(uptr, TMR_CLK, 2);
sim_clock_coschedule(uptr, tmxr_poll);
/* TODO:
@ -347,7 +351,7 @@ t_stat iu_svc_tti(UNIT *uptr)
}
iu_console.stat |= STS_RXR;
iu_state.istat |= ISTS_RAI;
if (iu_state.imr & 0x02) {
if (iu_state.imr & IMR_RXRA) {
csr_data |= CSRUART;
}
}
@ -362,7 +366,7 @@ t_stat iu_svc_tto(UNIT *uptr)
return SCPE_OK;
}
t_stat iu_svc_contty(UNIT *uptr)
t_stat iu_svc_contty_rcv(UNIT *uptr)
{
int32 temp, ln;
@ -373,9 +377,9 @@ t_stat iu_svc_contty(UNIT *uptr)
ln = tmxr_poll_conn(&contty_desc);
if (ln >= 0) {
contty_ldsc[ln].rcve = 1;
/* Set DCR */
/* Set DCD */
iu_state.inprt &= ~(IU_DCDB);
iu_state.ipcr = IU_DCDB;
iu_state.ipcr |= IU_DCDB;
/* Cause an interrupt */
csr_data |= CSRUART;
}
@ -384,11 +388,7 @@ t_stat iu_svc_contty(UNIT *uptr)
if (contty_ldsc[0].conn) {
temp = tmxr_getc_ln(&contty_ldsc[0]);
if (temp & SCPE_BREAK) {
sim_debug(EXECUTE_MSG, &contty_dev,
"*** BREAK RECEIVED ON CONTTY!\n");
}
if (temp) {
if (temp && !(temp & SCPE_BREAK)) {
if (iu_contty.conf & RX_EN) {
if ((iu_contty.stat & STS_FFL) == 0) {
iu_contty.rxbuf[iu_contty.w_p] = (temp & 0xff);
@ -399,14 +399,16 @@ t_stat iu_svc_contty(UNIT *uptr)
}
iu_contty.stat |= STS_RXR;
iu_state.istat |= ISTS_RBI;
if (iu_state.imr & 0x02) {
if (iu_state.imr & IMR_RXRB) {
csr_data |= CSRUART;
}
}
}
}
return sim_clock_coschedule_tmr(uptr, TMR_CLK, 2);
tmxr_clock_coschedule(uptr, tmxr_poll);
return SCPE_OK;
}
t_stat iu_svc_contty_xmt(UNIT *uptr)
@ -420,7 +422,7 @@ t_stat iu_svc_timer(UNIT *uptr)
{
iu_state.istat |= ISTS_CRI;
if (iu_state.imr & 0x08) {
if (iu_state.imr & IMR_CTR) {
csr_data |= CSRUART;
}
@ -498,8 +500,14 @@ uint32 iu_read(uint32 pa, size_t size)
case RHRB:
data = iu_contty.rxbuf[iu_contty.r_p];
iu_contty.r_p = (iu_contty.r_p + 1) % IU_BUF_SIZE;
/* If the FIFO is not empty, we must cause another interrupt
* to continue reading */
if (iu_contty.r_p == iu_contty.w_p) {
iu_contty.stat &= ~(STS_RXR|STS_FFL);
iu_state.istat &= ~ISTS_RBI;
} else {
csr_data |= CSRUART;
}
break;
case INPRT:
data = iu_state.inprt;
@ -534,29 +542,30 @@ void iu_write(uint32 pa, uint32 val, size_t size)
{
uint8 reg;
uint8 modep;
uint8 bval = (uint8) val;
reg = (uint8) (pa - IUBASE);
switch (reg) {
case MR12A:
modep = iu_console.modep;
iu_console.mode[modep] = val & 0xff;
iu_console.mode[modep] = bval;
iu_increment_a = TRUE;
break;
case CSRA:
/* Set baud rate - not implemented */
break;
case CRA: /* Command A */
iu_w_cmd(PORT_A, (uint8) val);
iu_w_cmd(PORT_A, bval);
break;
case THRA: /* TX/RX Buf A */
/* Loopback mode */
if ((iu_console.mode[1] & 0xc0) == 0x80) {
iu_console.txbuf = (uint8) val;
iu_console.txbuf = bval;
/* This is also a Receive */
if ((iu_console.stat & STS_FFL) == 0) {
iu_console.rxbuf[iu_console.w_p] = (uint8) val;
iu_console.rxbuf[iu_console.w_p] = bval;
iu_console.w_p = (iu_console.w_p + 1) % IU_BUF_SIZE;
if (iu_console.w_p == iu_console.r_p) {
iu_console.stat |= STS_FFL;
@ -565,16 +574,19 @@ void iu_write(uint32 pa, uint32 val, size_t size)
iu_console.stat |= STS_RXR;
iu_state.istat |= ISTS_RAI;
if (iu_state.imr & IMR_RXRA) {
csr_data |= CSRUART;
}
} else {
iu_tx(PORT_A, (uint8) val);
iu_tx(PORT_A, bval);
}
csr_data &= ~CSRUART;
break;
case ACR: /* Auxiliary Control Register */
iu_state.acr = (uint8) val;
iu_state.acr = bval;
break;
case IMR:
iu_state.imr = (uint8) val;
iu_state.imr = bval;
csr_data &= ~CSRUART;
/* Possibly cause an interrupt */
iu_txrdy_a_irq();
@ -584,32 +596,32 @@ void iu_write(uint32 pa, uint32 val, size_t size)
/* Clear out high byte */
iu_timer_state.c_set &= 0x00ff;
/* Set high byte */
iu_timer_state.c_set |= (val & 0xff) << 8;
iu_timer_state.c_set |= ((uint16) bval << 8);
break;
case CTLR: /* Counter/Timer Lower Preset Value */
/* Clear out low byte */
iu_timer_state.c_set &= 0xff00;
/* Set low byte */
iu_timer_state.c_set |= (val & 0xff);
iu_timer_state.c_set |= bval;
break;
case MR12B:
modep = iu_contty.modep;
iu_contty.mode[modep] = val & 0xff;
iu_contty.mode[modep] = bval;
iu_increment_b = TRUE;
break;
case CRB: /* Command B */
iu_w_cmd(PORT_B, (uint8) val);
iu_w_cmd(PORT_B, bval);
break;
case CSRB:
break;
case THRB: /* TX/RX Buf B */
/* Loopback mode */
if ((iu_contty.mode[1] & 0xc0) == 0x80) {
iu_contty.txbuf = (uint8) val;
iu_contty.txbuf = bval;
/* This is also a Receive */
if ((iu_contty.stat & STS_FFL) == 0) {
iu_contty.rxbuf[iu_contty.w_p] = (uint8) val;
iu_contty.rxbuf[iu_contty.w_p] = bval;
iu_contty.w_p = (iu_contty.w_p + 1) % IU_BUF_SIZE;
if (iu_contty.w_p == iu_contty.r_p) {
iu_contty.stat |= STS_FFL;
@ -618,31 +630,25 @@ void iu_write(uint32 pa, uint32 val, size_t size)
iu_contty.stat |= STS_RXR;
iu_state.istat |= ISTS_RBI;
if (iu_state.imr & IMR_RXRB) {
csr_data |= CSRUART;
}
} else {
iu_tx(PORT_B, (uint8) val);
iu_tx(PORT_B, bval);
}
break;
case OPCR:
sim_debug(EXECUTE_MSG, &contty_dev,
">>> OPCR written: %02x\n",
(uint8) val);
iu_state.opcr = (uint8) val;
iu_state.opcr = bval;
break;
case SOPR:
sim_debug(EXECUTE_MSG, &contty_dev,
">>> SOPR written: %02x\n",
(uint8) val);
/* Bit 2 of the IU output register is used as a soft power
* switch. When set, the machine will power down
* immediately. */
if (val & IU_KILLPWR) {
if (bval & IU_KILLPWR) {
stop_reason = STOP_POWER;
}
break;
case ROPR:
sim_debug(EXECUTE_MSG, &contty_dev,
">>> ROPR written: %02x\n",
(uint8) val);
break;
default:
break;

View file

@ -113,6 +113,13 @@
#define UM_MASK 0x70
#define UM_SHIFT 4
/* IMR bits */
#define IMR_TXRA 0x01
#define IMR_RXRA 0x02
#define IMR_CTR 0x08
#define IMR_TXRB 0x10
#define IMR_RXRB 0x20
/* Power-off bit */
#define IU_KILLPWR 0x04
@ -150,6 +157,8 @@ extern DEVICE iu_timer_dev;
#define IU_DCDA 0x01
#define IU_DCDB 0x02
#define IU_DTRA 0x01
#define IU_DTRB 0x02
typedef struct iu_port {
uint8 stat; /* Port Status */
@ -189,7 +198,7 @@ t_stat contty_reset(DEVICE *dptr);
t_stat iu_timer_reset(DEVICE *dptr);
t_stat iu_svc_tti(UNIT *uptr);
t_stat iu_svc_tto(UNIT *uptr);
t_stat iu_svc_contty(UNIT *uptr);
t_stat iu_svc_contty_rcv(UNIT *uptr);
t_stat iu_svc_contty_xmt(UNIT *uptr);
t_stat iu_svc_timer(UNIT *uptr);
uint32 iu_read(uint32 pa, size_t size);

View file

@ -59,6 +59,8 @@ uint32 *NVRAM = NULL;
extern DEVICE cpu_dev;
int32 tmxr_poll = 0;
/* CSR */
uint16 csr_data;
@ -486,7 +488,7 @@ t_stat timer0_svc(UNIT *uptr)
t_stat timer1_svc(UNIT *uptr)
{
struct timer_ctr *ctr;
int32 ticks;
int32 ticks, t;
ctr = (struct timer_ctr *)uptr->tmr;
@ -501,8 +503,9 @@ t_stat timer1_svc(UNIT *uptr)
ticks = TPS_CLK;
}
sim_rtcn_calb(ticks, TMR_CLK);
t = sim_rtcn_calb(ticks, TMR_CLK);
sim_activate_after(uptr, (uint32) (1000000 / ticks));
tmxr_poll = t;
return SCPE_OK;
}