3b2: Fix for erratic CONTTY behavior
This commit is contained in:
parent
cf57f0d638
commit
3f7e473b79
6 changed files with 62 additions and 24 deletions
|
@ -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 */
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
||||
|
|
|
@ -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:
|
||||
* ------------
|
||||
|
|
60
3B2/3b2_iu.c
60
3B2/3b2_iu.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue