3b2: Fix for erratic CONTTY behavior

This commit is contained in:
Seth Morabito 2018-08-22 17:13:48 -07:00
parent cf57f0d638
commit 3f7e473b79
6 changed files with 62 additions and 24 deletions

View file

@ -50,6 +50,13 @@ noret __libc_longjmp (jmp_buf buf, int val);
#define longjmp __libc_longjmp
#endif
#ifndef MAX
#define MAX(x,y) ((x) > (y) ? (x) : (y))
#endif
#ifndef MIN
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#endif
/* -t flag: Translate a virtual address */
#define EX_T_FLAG 1 << 19
/* -v flag for examine routine */

View file

@ -55,8 +55,8 @@ DEVICE dmac_dev = {
dmac_dma_handler device_dma_handlers[] = {
{DMA_ID_CHAN, IDBASE+ID_DATA_REG, &id_drq, dmac_generic_dma, id_after_dma},
{DMA_IF_CHAN, IFBASE+IF_DATA_REG, &if_state.drq, dmac_generic_dma, if_after_dma},
{DMA_IUA_CHAN, IUBASE+IUA_DATA_REG, &iu_console.drq, iu_dma, NULL},
{DMA_IUB_CHAN, IUBASE+IUB_DATA_REG, &iu_contty.drq, iu_dma, NULL},
{DMA_IUA_CHAN, IUBASE+IUA_DATA_REG, &iu_console.drq, iu_dma_console, NULL},
{DMA_IUB_CHAN, IUBASE+IUB_DATA_REG, &iu_contty.drq, iu_dma_contty, NULL},
{0, 0, NULL, NULL, NULL }
};

View file

@ -36,13 +36,6 @@ static SIM_INLINE void if_clear_irq();
static SIM_INLINE void if_cancel_pending_irq();
static SIM_INLINE uint32 if_buf_offset();
#ifndef MAX
#define MAX(x,y) ((x) > (y) ? (x) : (y))
#endif
#ifndef MIN
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#endif
/*
* Disk Format:
* ------------

View file

@ -426,7 +426,7 @@ t_stat iu_svc_tto(UNIT *uptr)
{
/* If there's more DMA to do, do it */
if (iu_console.dma && ((dma_state.mask >> DMA_IUA_CHAN) & 0x1) == 0) {
iu_dma(DMA_IUA_CHAN, IUBASE+IUA_DATA_REG);
iu_dma_console(DMA_IUA_CHAN, IUBASE+IUA_DATA_REG);
} else {
/* The buffer is now empty, we've transmitted, so set TXR */
iu_console.stat |= STS_TXR;
@ -492,9 +492,9 @@ t_stat iu_svc_contty_xmt(UNIT *uptr)
tmxr_poll_tx(&contty_desc);
/* If there's more DMA to do, do it */
if (chan->wcount_c >= 0) {
/* More DMA to do */
iu_dma(DMA_IUB_CHAN, IUBASE+IUB_DATA_REG);
iu_dma_contty(DMA_IUB_CHAN, IUBASE+IUB_DATA_REG);
} else {
/* The buffer is now empty, we've transmitted, so set TXR */
iu_contty.stat |= STS_TXR;
@ -911,14 +911,14 @@ static SIM_INLINE void iu_w_cmd(uint8 portno, uint8 cmd)
/*
* Initiate DMA transfer or continue one already in progress.
*/
void iu_dma(uint8 channel, uint32 service_address)
void iu_dma_console(uint8 channel, uint32 service_address)
{
uint8 data;
uint32 addr;
t_stat status = SCPE_OK;
dma_channel *chan = &dma_state.channels[channel];
UNIT *uptr = (channel == DMA_IUA_CHAN) ? &tto_unit : contty_xmt_unit;
IU_PORT *port = (channel == DMA_IUA_CHAN) ? &iu_console : &iu_contty;
UNIT *uptr = &tto_unit;
IU_PORT *port = &iu_console;
/* Immediate acknowledge of DMA */
port->drq = FALSE;
@ -936,9 +936,6 @@ void iu_dma(uint8 channel, uint32 service_address)
if (status == SCPE_OK) {
chan->ptr++;
chan->wcount_c--;
} else if (status == SCPE_LOST) {
chan->ptr = 0;
chan->wcount_c = -1;
}
sim_activate_abs(uptr, uptr->wait);
@ -956,3 +953,48 @@ void iu_dma(uint8 channel, uint32 service_address)
dma_state.status |= (1 << channel);
csr_data |= CSRDMA;
}
void iu_dma_contty(uint8 channel, uint32 service_address)
{
uint8 data;
uint32 addr;
t_stat status = SCPE_OK;
dma_channel *chan = &dma_state.channels[channel];
UNIT *uptr = contty_xmt_unit;
IU_PORT *port = &iu_contty;
uint32 wait = 0x7fffffff;
/* Immediate acknowledge of DMA */
port->drq = FALSE;
if (!port->dma) {
/* Set DMA transfer type */
port->dma = 1u << ((dma_state.mode >> 2) & 0xf);
}
if (port->dma == DMA_READ) {
addr = dma_address(channel, chan->ptr, TRUE);
chan->addr_c = chan->addr + chan->ptr + 1;
data = pread_b(addr);
status = iu_tx(channel - 2, data);
if (status == SCPE_OK) {
wait = MIN(wait, contty_ldsc[0].txdeltausecs);
chan->ptr++;
chan->wcount_c--;
}
tmxr_activate_after(uptr, wait);
if (chan->wcount_c >= 0) {
/* Return early so we don't finish DMA */
return;
}
}
/* Done with DMA */
port->dma = DMA_NONE;
dma_state.mask |= (1 << channel);
dma_state.status |= (1 << channel);
csr_data |= CSRDMA;
}

View file

@ -210,6 +210,7 @@ void iua_drq_handled();
void iub_drq_handled();
void iu_txrdy_a_irq();
void iu_txrdy_b_irq();
void iu_dma(uint8 channel, uint32 service_address);
void iu_dma_console(uint8 channel, uint32 service_address);
void iu_dma_contty(uint8 channel, uint32 service_address);
#endif

View file

@ -74,11 +74,6 @@ extern UNIT cio_unit;
*
*/
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
#define PPQESIZE 12
#define DELAY_ASYNC 25
#define DELAY_DLM 100