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
|
#define longjmp __libc_longjmp
|
||||||
#endif
|
#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 */
|
/* -t flag: Translate a virtual address */
|
||||||
#define EX_T_FLAG 1 << 19
|
#define EX_T_FLAG 1 << 19
|
||||||
/* -v flag for examine routine */
|
/* -v flag for examine routine */
|
||||||
|
|
|
@ -55,8 +55,8 @@ DEVICE dmac_dev = {
|
||||||
dmac_dma_handler device_dma_handlers[] = {
|
dmac_dma_handler device_dma_handlers[] = {
|
||||||
{DMA_ID_CHAN, IDBASE+ID_DATA_REG, &id_drq, dmac_generic_dma, id_after_dma},
|
{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_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_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, NULL},
|
{DMA_IUB_CHAN, IUBASE+IUB_DATA_REG, &iu_contty.drq, iu_dma_contty, NULL},
|
||||||
{0, 0, NULL, NULL, 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 void if_cancel_pending_irq();
|
||||||
static SIM_INLINE uint32 if_buf_offset();
|
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:
|
* 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 there's more DMA to do, do it */
|
||||||
if (iu_console.dma && ((dma_state.mask >> DMA_IUA_CHAN) & 0x1) == 0) {
|
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 {
|
} else {
|
||||||
/* The buffer is now empty, we've transmitted, so set TXR */
|
/* The buffer is now empty, we've transmitted, so set TXR */
|
||||||
iu_console.stat |= STS_TXR;
|
iu_console.stat |= STS_TXR;
|
||||||
|
@ -492,9 +492,9 @@ t_stat iu_svc_contty_xmt(UNIT *uptr)
|
||||||
|
|
||||||
tmxr_poll_tx(&contty_desc);
|
tmxr_poll_tx(&contty_desc);
|
||||||
|
|
||||||
|
/* If there's more DMA to do, do it */
|
||||||
if (chan->wcount_c >= 0) {
|
if (chan->wcount_c >= 0) {
|
||||||
/* More DMA to do */
|
iu_dma_contty(DMA_IUB_CHAN, IUBASE+IUB_DATA_REG);
|
||||||
iu_dma(DMA_IUB_CHAN, IUBASE+IUB_DATA_REG);
|
|
||||||
} else {
|
} else {
|
||||||
/* The buffer is now empty, we've transmitted, so set TXR */
|
/* The buffer is now empty, we've transmitted, so set TXR */
|
||||||
iu_contty.stat |= STS_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.
|
* 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;
|
uint8 data;
|
||||||
uint32 addr;
|
uint32 addr;
|
||||||
t_stat status = SCPE_OK;
|
t_stat status = SCPE_OK;
|
||||||
dma_channel *chan = &dma_state.channels[channel];
|
dma_channel *chan = &dma_state.channels[channel];
|
||||||
UNIT *uptr = (channel == DMA_IUA_CHAN) ? &tto_unit : contty_xmt_unit;
|
UNIT *uptr = &tto_unit;
|
||||||
IU_PORT *port = (channel == DMA_IUA_CHAN) ? &iu_console : &iu_contty;
|
IU_PORT *port = &iu_console;
|
||||||
|
|
||||||
/* Immediate acknowledge of DMA */
|
/* Immediate acknowledge of DMA */
|
||||||
port->drq = FALSE;
|
port->drq = FALSE;
|
||||||
|
@ -936,9 +936,6 @@ void iu_dma(uint8 channel, uint32 service_address)
|
||||||
if (status == SCPE_OK) {
|
if (status == SCPE_OK) {
|
||||||
chan->ptr++;
|
chan->ptr++;
|
||||||
chan->wcount_c--;
|
chan->wcount_c--;
|
||||||
} else if (status == SCPE_LOST) {
|
|
||||||
chan->ptr = 0;
|
|
||||||
chan->wcount_c = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sim_activate_abs(uptr, uptr->wait);
|
sim_activate_abs(uptr, uptr->wait);
|
||||||
|
@ -956,3 +953,48 @@ void iu_dma(uint8 channel, uint32 service_address)
|
||||||
dma_state.status |= (1 << channel);
|
dma_state.status |= (1 << channel);
|
||||||
csr_data |= CSRDMA;
|
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 iub_drq_handled();
|
||||||
void iu_txrdy_a_irq();
|
void iu_txrdy_a_irq();
|
||||||
void iu_txrdy_b_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
|
#endif
|
||||||
|
|
|
@ -74,11 +74,6 @@ extern UNIT cio_unit;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef MIN
|
|
||||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PPQESIZE 12
|
#define PPQESIZE 12
|
||||||
#define DELAY_ASYNC 25
|
#define DELAY_ASYNC 25
|
||||||
#define DELAY_DLM 100
|
#define DELAY_DLM 100
|
||||||
|
|
Loading…
Add table
Reference in a new issue