mirror of
https://github.com/rcornwell/sims.git
synced 2026-01-13 23:35:30 +00:00
KA10: Updated KL10 to start to work correctly. Tops10 now working.
This commit is contained in:
parent
65dd4f6d2c
commit
42721f499e
328
PDP10/kl10_fe.c
328
PDP10/kl10_fe.c
@ -104,8 +104,8 @@
|
||||
#define SEC_RTM 05400
|
||||
#define SEC_CMDMSK 07400
|
||||
#define DTE_MON 00000001 /* Save in unit1 STATUS */
|
||||
#define SEC_CLK 00000001 /* Clock enabled */
|
||||
#define DTE_ACK_CTY 00000002 /* Send CTY Ack */
|
||||
#define SEC_CLK 00000002 /* Clock enabled */
|
||||
#define ITS_ON 00000004 /* ITS Is alive */
|
||||
|
||||
/* Primary or Queued protocol addresses */
|
||||
#define PRI_CMTW_0 0
|
||||
@ -157,6 +157,20 @@
|
||||
#define PRI_EMCLK 007 /* Clock */
|
||||
#define PRI_EMFED 010 /* Front end device */
|
||||
|
||||
#if KL_ITS
|
||||
/* ITS Timesharing protocol locations */
|
||||
#define ITS_DTEVER 0400 /* Protocol version and number of devices */
|
||||
#define ITS_DTECHK 0401 /* Increment at 60Hz. Ten setom 2 times per second */
|
||||
#define ITS_DTEINP 0402 /* Input from 10 to 11. Line #, Count */
|
||||
#define ITS_DTEOUT 0403 /* Output from 10 to 11 Line #, Count */
|
||||
#define ITS_DTELSP 0404 /* Line # to set speed of */
|
||||
#define ITS_DTELPR 0405 /* Parameter */
|
||||
#define ITS_DTEOST 0406 /* Line # to start output on */
|
||||
#define ITS_DTETYI 0410 /* Received char (Line #, char) */
|
||||
#define ITS_DTEODN 0411 /* Output done (Line #, buffer size) */
|
||||
#define ITS_DTEHNG 0412 /* Hangup/dialup */
|
||||
#endif
|
||||
|
||||
#define TMR_RTC 2
|
||||
|
||||
extern int32 tmxr_poll;
|
||||
@ -164,6 +178,9 @@ t_stat dte_devio(uint32 dev, uint64 *data);
|
||||
int dte_devirq(uint32 dev, int addr);
|
||||
void dte_second(UNIT *uptr);
|
||||
void dte_primary(UNIT *uptr);
|
||||
#if KL_ITS
|
||||
void dte_its(UNIT *uptr);
|
||||
#endif
|
||||
void dte_transfer(UNIT *uptr);
|
||||
void dte_function(UNIT *uptr);
|
||||
int dte_start(UNIT *uptr);
|
||||
@ -178,6 +195,11 @@ t_stat dte_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cpt
|
||||
const char *dte_description (DEVICE *dptr);
|
||||
extern uint64 SW; /* Switch register */
|
||||
|
||||
#if KL_ITS
|
||||
#define QITS (cpu_unit[0].flags & UNIT_ITSPAGE)
|
||||
#else
|
||||
#define QITS 0
|
||||
#endif
|
||||
|
||||
#define STATUS u3
|
||||
#define CNT u4
|
||||
@ -319,6 +341,7 @@ DEVICE lpt_dev = {
|
||||
#if (NUM_DEVS_TTY > 0)
|
||||
|
||||
struct _buffer tty_out[NUM_LINES_TTY], tty_in[NUM_LINES_TTY];
|
||||
struct _buffer tty_done, tty_hang;
|
||||
TMLN tty_ldsc[NUM_LINES_TTY] = { 0 }; /* Line descriptors */
|
||||
TMXR tty_desc = { NUM_LINES_TTY, 0, 0, tty_ldsc };
|
||||
int tty_connect[NUM_LINES_TTY];;
|
||||
@ -479,6 +502,14 @@ void dte_second(UNIT *uptr) {
|
||||
#endif
|
||||
/* read command */
|
||||
word = M[SEC_DTCMD + base];
|
||||
#if KL_ITS
|
||||
if (word == 0 && QITS && (uptr->STATUS & ITS_ON) != 0) {
|
||||
dte_its(uptr);
|
||||
uptr->STATUS |= DTE_10DB;
|
||||
uptr->STATUS &= ~DTE_11DB;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/* Do it */
|
||||
sim_debug(DEBUG_DETAIL, &dte_dev, "CTY secondary %012llo\n", word);
|
||||
switch(word & SEC_CMDMSK) {
|
||||
@ -564,11 +595,142 @@ enter_pri:
|
||||
break;
|
||||
}
|
||||
/* Acknowledge command */
|
||||
M[SEC_DTCMD + base] = 0;
|
||||
M[SEC_DTFLG + base] = FMASK;
|
||||
uptr->STATUS |= DTE_10DB;
|
||||
uptr->STATUS &= ~DTE_11DB;
|
||||
}
|
||||
|
||||
#if KL_ITS
|
||||
void dte_its(UNIT *uptr) {
|
||||
uint64 word;
|
||||
char ch;
|
||||
uint16 data;
|
||||
int cnt;
|
||||
int ln;
|
||||
t_stat r;
|
||||
|
||||
/* Check for output Start */
|
||||
word = M[ITS_DTEOST];
|
||||
if ((word & SMASK) == 0) {
|
||||
if (((tty_done.in_ptr + 1) & 0xff) != tty_done.out_ptr) {
|
||||
tty_done.buff[tty_done.in_ptr] = (char)(word & 0xff);
|
||||
tty_done.in_ptr = (tty_done.in_ptr + 1) & 0xff;
|
||||
M[ITS_DTEOST] = FMASK;
|
||||
sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS DTEOST = %012llo\n", word);
|
||||
}
|
||||
}
|
||||
/* Check for input Start */
|
||||
word = M[ITS_DTEINP];
|
||||
if ((word & SMASK) == 0) {
|
||||
M[ITS_DTEINP] = FMASK;
|
||||
sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS DTEINP = %012llo\n", word);
|
||||
}
|
||||
/* Check for output Start */
|
||||
word = M[ITS_DTEOUT];
|
||||
if ((word & SMASK) == 0) {
|
||||
cnt = word & 017777;
|
||||
ln = ((word >> 18) & 077) - 1;
|
||||
sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS DTEOUT = %012llo\n", word);
|
||||
while (cnt > 0) {
|
||||
if (ln < 0) {
|
||||
if (!Mem_read_byte(0, &data))
|
||||
return;
|
||||
ch = (data >> 8) & 0177;
|
||||
sim_debug(DEBUG_DETAIL, &dte_dev, "CTY type %x\n", ch);
|
||||
ch = sim_tt_outcvt( ch, TT_GET_MODE(uptr->flags));
|
||||
if ((r = sim_putchar_s (ch)) != SCPE_OK) /* Output errors */
|
||||
return;
|
||||
cnt--;
|
||||
if (cnt) {
|
||||
ch = data & 0177;
|
||||
sim_debug(DEBUG_DETAIL, &dte_dev, "CTY type %x\n", ch);
|
||||
ch = sim_tt_outcvt( ch, TT_GET_MODE(uptr->flags));
|
||||
if ((r = sim_putchar_s (ch)) != SCPE_OK) /* Output errors */
|
||||
return;
|
||||
cnt--;
|
||||
}
|
||||
} else {
|
||||
if (!Mem_read_byte(0, &data))
|
||||
return;
|
||||
ch = (data >> 8) & 0177;
|
||||
if (((tty_out[ln].in_ptr + 1) & 0xff) == tty_out[ln].out_ptr)
|
||||
return;
|
||||
sim_debug(DEBUG_DETAIL, &dte_dev, "TTY queue %x %d\n", ch, ln);
|
||||
tty_out[ln].buff[tty_out[ln].in_ptr] = ch;
|
||||
tty_out[ln].in_ptr = (tty_out[ln].in_ptr + 1) & 0xff;
|
||||
cnt--;
|
||||
if (cnt) {
|
||||
ch = data & 0177;
|
||||
if (((tty_out[ln].in_ptr + 1) & 0xff) == tty_out[ln].out_ptr)
|
||||
return;
|
||||
sim_debug(DEBUG_DETAIL, &dte_dev, "TTY queue %x %d\n", ch, ln);
|
||||
tty_out[ln].buff[tty_out[ln].in_ptr] = ch;
|
||||
tty_out[ln].in_ptr = (tty_out[ln].in_ptr + 1) & 0xff;
|
||||
cnt--;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If on CTY Queue output done response */
|
||||
if (ln < 0) {
|
||||
if (((tty_done.in_ptr + 1) & 0xff) != tty_done.out_ptr) {
|
||||
tty_done.buff[tty_done.in_ptr] = (char)(0 & 0xff);
|
||||
tty_done.in_ptr = (tty_done.in_ptr + 1) & 0xff;
|
||||
}
|
||||
}
|
||||
M[ITS_DTEOUT] = FMASK;
|
||||
uptr->STATUS |= DTE_11DN;
|
||||
if (uptr->STATUS & DTE_PIE)
|
||||
set_interrupt(DTE_DEVNUM, uptr->STATUS);
|
||||
sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS DTEOUT = %012llo\n", word);
|
||||
}
|
||||
/* Check for line speed */
|
||||
word = M[ITS_DTELSP];
|
||||
if ((word & SMASK) == 0) {
|
||||
M[ITS_DTELSP] = FMASK;
|
||||
sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS DTELSP = %012llo %012llo\n", word, M[ITS_DTELPR]);
|
||||
}
|
||||
#if 0
|
||||
/* Check for input */
|
||||
word = M[ITS_DTETYI];
|
||||
if ((word & SMASK) != 0) {
|
||||
int l = uptr->CNT;
|
||||
do {
|
||||
if (tty_connect[l]) {
|
||||
// if ((ch = dte_unit[1].CHHOLD) != 0) {
|
||||
// word = ch;
|
||||
// dte_unit[1].CHHOLD = 0;
|
||||
// M[ITS_DTETYI] = word;
|
||||
// /* Tell 10 something is ready */
|
||||
// uptr->STATUS |= DTE_10DB;
|
||||
// if (uptr->STATUS & DTE_PIE)
|
||||
// set_interrupt(DTE_DEVNUM, uptr->STATUS);
|
||||
// }
|
||||
sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS DTETYI = %012llo\n", word);
|
||||
}
|
||||
#endif
|
||||
/* Check for output done */
|
||||
word = M[ITS_DTEODN];
|
||||
if ((word & SMASK) != 0) {
|
||||
if (tty_done.in_ptr != tty_done.out_ptr) {
|
||||
ln = tty_done.buff[tty_done.out_ptr];
|
||||
tty_done.out_ptr = (tty_done.out_ptr + 1) & 0xff;
|
||||
word = M[ITS_DTEODN] = (((uint64)ln) << 18)|1;
|
||||
sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS DTEODN = %012llo\n", word);
|
||||
/* Tell 10 something is ready */
|
||||
uptr->STATUS |= DTE_10DB;
|
||||
if (uptr->STATUS & DTE_PIE)
|
||||
set_interrupt(DTE_DEVNUM, uptr->STATUS);
|
||||
}
|
||||
}
|
||||
/* Check for hangup */
|
||||
word = M[ITS_DTEHNG];
|
||||
if ((word & SMASK) == 0) {
|
||||
sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS DTEHNG = %012llo\n", word);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Handle primary protocol */
|
||||
void dte_primary(UNIT *uptr) {
|
||||
uint64 word, iword;
|
||||
@ -1049,10 +1211,12 @@ t_stat dtei_svc (UNIT *uptr)
|
||||
uint16 data1;
|
||||
|
||||
#if KI_22BIT
|
||||
#if KL_ITS
|
||||
if ((cpu_unit[0].flags & UNIT_ITSPAGE) == 0)
|
||||
#endif
|
||||
base = eb_ptr;
|
||||
#endif
|
||||
|
||||
sim_clock_coschedule (uptr, 1000);
|
||||
sim_activate (uptr, 1000);
|
||||
if ((uptr->STATUS & DTE_SEC) == 0) {
|
||||
dte_function(uptr); /* Process queue */
|
||||
dte_start(optr);
|
||||
@ -1067,6 +1231,24 @@ t_stat dtei_svc (UNIT *uptr)
|
||||
uptr->CHHOLD = ch;
|
||||
}
|
||||
sim_debug(DEBUG_DETAIL, &dte_dev, "CTY char %x\n", ch);
|
||||
#if KL_ITS
|
||||
if (QITS && (optr->STATUS & ITS_ON) != 0) {
|
||||
uint64 word = M[ITS_DTETYI];
|
||||
if ((word & SMASK) != 0) {
|
||||
if (ch != 0) {
|
||||
word = ch;
|
||||
uptr->CHHOLD = 0;
|
||||
M[ITS_DTETYI] = word;
|
||||
/* Tell 10 something is ready */
|
||||
optr->STATUS |= DTE_10DB;
|
||||
if (optr->STATUS & DTE_PIE)
|
||||
set_interrupt(DTE_DEVNUM, optr->STATUS);
|
||||
sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS DTETYI = %012llo\n", word);
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
#endif
|
||||
if (optr->STATUS & DTE_SEC) {
|
||||
if (optr->STATUS & DTE_MON && M[SEC_DTMTI + base] == 0) {
|
||||
sim_debug(DEBUG_DETAIL, &dte_dev, "CTY char %x\n", ch & 0177);
|
||||
@ -1078,6 +1260,10 @@ t_stat dtei_svc (UNIT *uptr)
|
||||
uptr->CHHOLD = 0;
|
||||
}
|
||||
} else {
|
||||
#if KL_ITS
|
||||
if (QITS)
|
||||
return SCPE_OK;
|
||||
#endif
|
||||
data1 = (PRI_EMCTY << 8) | ch;
|
||||
if (dte_queue(uptr, PRI_EMLNC, PRI_EMCTY, 1, &data1) != 0)
|
||||
uptr->CHHOLD = 0;
|
||||
@ -1091,7 +1277,6 @@ dtertc_srv(UNIT * uptr)
|
||||
int32 t;
|
||||
UNIT *optr = &dte_unit[0];
|
||||
|
||||
t = sim_rtcn_calb (rtc_tps, TMR_RTC);
|
||||
sim_activate_after(uptr, 1000000/rtc_tps);
|
||||
if (uptr->STATUS & SEC_CLK) {
|
||||
rtc_tick++;
|
||||
@ -1111,6 +1296,22 @@ dtertc_srv(UNIT * uptr)
|
||||
rtc_tick, rtc_wait, optr->STATUS);
|
||||
}
|
||||
}
|
||||
#if KL_ITS
|
||||
if (QITS) {
|
||||
uint64 word;
|
||||
|
||||
word = (M[ITS_DTECHK] + 1) & FMASK;
|
||||
if (word == 0) {
|
||||
optr->STATUS |= ITS_ON;
|
||||
sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS ON\n");
|
||||
} else if (word >= (15 * 60)) {
|
||||
optr->STATUS &= ~ITS_ON;
|
||||
word = 15 * 60;
|
||||
sim_debug(DEBUG_DETAIL, &dte_dev, "CTY ITS OFF\n");
|
||||
}
|
||||
M[ITS_DTECHK] = word;
|
||||
}
|
||||
#endif
|
||||
if ((optr->STATUS & DTE_SEC) == 0) {
|
||||
int addr = 0144 + eb_ptr;
|
||||
uint64 word;
|
||||
@ -1409,9 +1610,7 @@ const char *lpt_description (DEVICE *dptr)
|
||||
t_stat ttyi_svc (UNIT *uptr)
|
||||
{
|
||||
int32 ln;
|
||||
int n = 0;
|
||||
TMLN *lp;
|
||||
uint16 data1[32];
|
||||
int flg;
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
|
||||
@ -1419,68 +1618,45 @@ t_stat ttyi_svc (UNIT *uptr)
|
||||
|
||||
sim_clock_coschedule(uptr, tmxr_poll); /* continue poll */
|
||||
|
||||
/* Check if room in queue for at least one packet */
|
||||
if (((dte_out_res + 1) & 0x1f) == dte_out_ptr) {
|
||||
sim_debug(DEBUG_DATA, &dte_dev, "DTE: func out full %d %d\n",
|
||||
dte_out_res, dte_out_ptr);
|
||||
return SCPE_OK;
|
||||
/* If we have room see if any new lines */
|
||||
if (((tty_hang.in_ptr + 1) & 0xff) != tty_hang.out_ptr) {
|
||||
ln = tmxr_poll_conn (&tty_desc); /* look for connect */
|
||||
if (ln >= 0) { /* got one? rcv enb*/
|
||||
tty_hang.buff[tty_hang.in_ptr] = ln + 1;
|
||||
tty_hang.in_ptr = (tty_hang.in_ptr + 1) & 0xff;
|
||||
tty_connect[ln] = 1;
|
||||
sim_debug(DEBUG_DETAIL, &tty_dev, "TTY line connect %d\n", ln);
|
||||
}
|
||||
}
|
||||
|
||||
ln = tmxr_poll_conn (&tty_desc); /* look for connect */
|
||||
if (ln >= 0) { /* got one? rcv enb*/
|
||||
tty_ldsc[ln].rcve = 1;
|
||||
tty_ldsc[ln].xmte = 1;
|
||||
data1[0] = ((ln + 1) << 8) | (ln + 1);
|
||||
tty_connect[ln] = 1;
|
||||
(void)dte_queue(&dte_unit[0], PRI_EMDSC, PRI_EMDLS, 1, data1);
|
||||
// data1[0] = (ln + 1) << 8;
|
||||
// /* Send out any data we got */
|
||||
// (void)dte_queue(&dte_unit[0], PRI_EMACK, PRI_EMDLS, 1, data1);
|
||||
sim_debug(DEBUG_DETAIL, &tty_dev, "TTY line connect %d\n", ln);
|
||||
}
|
||||
tmxr_poll_tx(&tty_desc);
|
||||
tmxr_poll_rx(&tty_desc);
|
||||
|
||||
/* Check if room in queue for at least one packet */
|
||||
if (((dte_out_res + 1) & 0x1f) == dte_out_ptr) {
|
||||
sim_debug(DEBUG_DATA, &dte_dev, "DTE: func out full %d %d\n",
|
||||
dte_out_res, dte_out_ptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
ln = uptr->CNT;
|
||||
do {
|
||||
flg = 0;
|
||||
lp = &tty_ldsc[ln];
|
||||
/* Check to see if any pending data for this line */
|
||||
if (lp->rcve && tmxr_input_pending_ln(lp) > 0) {
|
||||
int32 ch = tmxr_getc_ln (lp);
|
||||
sim_debug(DEBUG_DETAIL, &tty_dev, "TTY recieve %d: %02x\n", ln, ch);
|
||||
if ((ch & SCPE_BREAK) == 0) { /* break? */
|
||||
ch = sim_tt_inpcvt (ch, TT_GET_MODE(tty_unit[0].flags) | TTUF_KSR);
|
||||
data1[n++] = ((ln + 1) << 8) | ch;
|
||||
}
|
||||
flg = 1;
|
||||
}
|
||||
if (++ln >= tty_desc.lines)
|
||||
ln = 0;
|
||||
} while (flg && n < 32);
|
||||
uptr->CNT = ln;
|
||||
|
||||
/* Send out any data we got */
|
||||
if (n > 0)
|
||||
(void)dte_queue(&dte_unit[0], PRI_EMLNC, PRI_EMDLS, n, data1);
|
||||
|
||||
/* Look for lines that have been disconnected */
|
||||
/* Scan each line for input */
|
||||
for (ln = 0; ln < tty_desc.lines; ln++) {
|
||||
if (tty_connect[ln] == 1 && tty_ldsc[ln].conn == 0) {
|
||||
data1[0] = (ln + 1) << 8;
|
||||
if (dte_queue(&dte_unit[0], PRI_EMHUD, PRI_EMDLS, 1, data1) != 0) {
|
||||
/* Check if disconnect */
|
||||
lp = &tty_ldsc[ln];
|
||||
flg = 1;
|
||||
/* Spool up as much as we have room for */
|
||||
while (flg && ((tty_out[ln].in_ptr + 1) & 0xff) != tty_out[ln].out_ptr) {
|
||||
int32 ch = tmxr_getc_ln(lp);
|
||||
if ((ch & TMXR_VALID) != 0) {
|
||||
ch = sim_tt_inpcvt (ch, TT_GET_MODE(tty_unit[0].flags) | TTUF_KSR);
|
||||
tty_in[ln].buff[tty_in[ln].in_ptr] = ch & 0377;
|
||||
tty_in[ln].in_ptr = (tty_in[ln].in_ptr + 1) & 0xff;
|
||||
sim_debug(DEBUG_DETAIL, &tty_dev, "TTY recieve %d: %02x\n", ln, ch);
|
||||
} else
|
||||
flg = 0;
|
||||
}
|
||||
/* Look for lines that have been disconnected */
|
||||
if (tty_connect[ln] == 1 && lp->conn == 0) {
|
||||
if (((tty_hang.in_ptr + 1) & 0xff) != tty_hang.out_ptr) {
|
||||
tty_hang.buff[tty_hang.in_ptr] = ln + 1;
|
||||
tty_hang.in_ptr = (tty_hang.in_ptr + 1) & 0xff;
|
||||
tty_connect[ln] = 0;
|
||||
sim_debug(DEBUG_DETAIL, &tty_dev, "TTY line disconnect %d\n", ln);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
@ -1503,14 +1679,10 @@ t_stat ttyo_svc (UNIT *uptr)
|
||||
lp = &tty_ldsc[ln];
|
||||
if (lp->conn == 0)
|
||||
continue;
|
||||
if (((tty_done.in_ptr + 1) & 0xff) == tty_done.out_ptr)
|
||||
return SCPE_OK;
|
||||
if (tty_out[ln].out_ptr == tty_out[ln].in_ptr)
|
||||
continue;
|
||||
/* Check if room in queue for at least one packet */
|
||||
if (((dte_out_res + 1) & 0x1f) == dte_out_ptr) {
|
||||
sim_debug(DEBUG_DATA, &dte_dev, "DTE: func out full %d %d\n",
|
||||
dte_out_res, dte_out_ptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
while (tty_out[ln].out_ptr != tty_out[ln].in_ptr) {
|
||||
int32 ch = tty_out[ln].buff[tty_out[ln].out_ptr];
|
||||
ch = sim_tt_outcvt(ch, TT_GET_MODE (tty_unit[0].flags) | TTUF_KSR);
|
||||
@ -1521,20 +1693,20 @@ t_stat ttyo_svc (UNIT *uptr)
|
||||
else if (r == SCPE_LOST) {
|
||||
tty_out[ln].out_ptr = tty_out[ln].in_ptr = 0;
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
data1[n++] = (ln + 1) << 8;
|
||||
/* Send out any data we got */
|
||||
if (n > 32) {
|
||||
(void)dte_queue(&dte_unit[0], PRI_EMACK, PRI_EMDLS, n, data1);
|
||||
n = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Send out any data we got */
|
||||
if (n > 0)
|
||||
(void)dte_queue(&dte_unit[0], PRI_EMACK, PRI_EMDLS, n, data1);
|
||||
|
||||
tty_done.buff[tty_done.in_ptr] = ln + 1;
|
||||
tty_done.in_ptr = (tty_done.in_ptr + 1) & 0xff;
|
||||
#if KL_ITS
|
||||
/* Tell 10 we have something for it */
|
||||
if (QITS) {
|
||||
dte_unit[0].STATUS |= DTE_10DB;
|
||||
if (dte_unit[0].STATUS & DTE_PIE)
|
||||
set_interrupt(DTE_DEVNUM, dte_unit[0].STATUS);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
120
PDP10/kx10_cpu.c
120
PDP10/kx10_cpu.c
@ -1206,8 +1206,10 @@ t_stat dev_pag(uint32 dev, uint64 *data) {
|
||||
|
||||
case CONO:
|
||||
eb_ptr = (*data & 017777) << 9;
|
||||
for (i = 0; i < 512; i++)
|
||||
for (i = 0; i < 512; i++) {
|
||||
e_tlb[i] = 0;
|
||||
u_tlb[i] = 0;
|
||||
}
|
||||
for (;i < 546; i++)
|
||||
u_tlb[i] = 0;
|
||||
page_enable = (*data & 020000) != 0;
|
||||
@ -1224,17 +1226,17 @@ t_stat dev_pag(uint32 dev, uint64 *data) {
|
||||
|
||||
page &= ~7;
|
||||
/* Map the page */
|
||||
for(i = 0; i < 8; i++)
|
||||
for(i = 0; i < 8; i++) {
|
||||
u_tlb[page+i] = 0;
|
||||
for(i = 0; i < 8; i++)
|
||||
e_tlb[page+i] = 0;
|
||||
}
|
||||
/* If not user do exec mappping */
|
||||
if (/*!uf && !t20_page &&*/ (page & 0740) == 0340) {
|
||||
/* Pages 340-377 via UBT */
|
||||
page += 01000 - 0340;
|
||||
upmp = 1;
|
||||
for(i = 0; i < 8; i++)
|
||||
u_tlb[page+i] = 0;
|
||||
for(i = 0; i < 8; i++)
|
||||
u_tlb[page+i] = 0;
|
||||
}
|
||||
} else {
|
||||
res = *data;
|
||||
@ -1257,8 +1259,10 @@ t_stat dev_pag(uint32 dev, uint64 *data) {
|
||||
}
|
||||
if (res & BIT2) {
|
||||
ub_ptr = (res & 017777) << 9;
|
||||
for (i = 0; i < 512; i++)
|
||||
for (i = 0; i < 512; i++) {
|
||||
u_tlb[i] = 0;
|
||||
e_tlb[i] = 0;
|
||||
}
|
||||
for (;i < 546; i++)
|
||||
u_tlb[i] = 0;
|
||||
}
|
||||
@ -1290,6 +1294,7 @@ t_stat dev_pag(uint32 dev, uint64 *data) {
|
||||
*/
|
||||
t_stat dev_cca(uint32 dev, uint64 *data) {
|
||||
irq_flags |= 020;
|
||||
*data = 0;
|
||||
check_apr_irq();
|
||||
return SCPE_OK;
|
||||
}
|
||||
@ -1618,8 +1623,8 @@ t_stat dev_pag(uint32 dev, uint64 *data) {
|
||||
e_tlb[i] = u_tlb[i] = 0;
|
||||
for (;i < 546; i++)
|
||||
u_tlb[i] = 0;
|
||||
user_addr_cmp = (res & 00020000000000LL) != 0;
|
||||
small_user = (res & 00040000000000LL) != 0;
|
||||
user_addr_cmp = (res & BIT4) != 0;
|
||||
small_user = (res & BIT3) != 0;
|
||||
fm_sel = (uint8)(res >> 29) & 060;
|
||||
}
|
||||
pag_reload = 0;
|
||||
@ -1634,9 +1639,9 @@ t_stat dev_pag(uint32 dev, uint64 *data) {
|
||||
res |= 020000;
|
||||
res |= ((uint64)(ub_ptr)) << 9;
|
||||
if (user_addr_cmp)
|
||||
res |= 00020000000000LL;
|
||||
res |= BIT4;
|
||||
if (small_user)
|
||||
res |= 00040000000000LL;
|
||||
res |= BIT3;
|
||||
res |= ((uint64)(fm_sel)) << 29;
|
||||
*data = res;
|
||||
sim_debug(DEBUG_DATAIO, &cpu_dev, "DATAI PAG %012llo\n", *data);
|
||||
@ -1933,9 +1938,19 @@ load_tlb(int uf, int page, int upmp, int wr, int trap, int flag)
|
||||
data &= RMASK;
|
||||
pg = 0;
|
||||
switch(data >> 16) {
|
||||
case 0: break; /* No access */
|
||||
case 0:
|
||||
fault_data = 033LL << 30 |((uf)?SMASK:0);
|
||||
page_fault = 1;
|
||||
return 0; /* No access */
|
||||
case 1: /* Read Only */
|
||||
case 2: pg = RSIGN; break; /* R/W First */
|
||||
case 2: /* R/W First */
|
||||
if (wr) {
|
||||
fault_data = 024LL << 30 |((uf)?SMASK:0);
|
||||
page_fault = 1;
|
||||
return 0;
|
||||
}
|
||||
pg = RSIGN;
|
||||
break;
|
||||
case 3: pg = RSIGN|0100000; break; /* R/W */
|
||||
}
|
||||
pg |= (data & 017777) << 1;
|
||||
@ -2257,8 +2272,16 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context, int fetch
|
||||
/* If not valid, go refill it */
|
||||
if (data == 0) {
|
||||
data = load_tlb(uf, page, upmp, wr, 1, flag);
|
||||
if (data == 0 && page_fault)
|
||||
if (data == 0 && page_fault) {
|
||||
fault_data |= ((uint64)addr);
|
||||
#if KL_ITS
|
||||
if (QITS && (xct_flag & 020) != 0) {
|
||||
PC = (PC + 1) & AMASK;
|
||||
page_fault = 0;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
*loc = ((data & 017777) << 9) + (addr & 0777);
|
||||
|
||||
@ -2283,23 +2306,33 @@ fprintf(stderr, "Page fault %06o a=%o wr=%o w=%o %06o\n\r", addr, (data & RSIGN)
|
||||
} else {
|
||||
e_tlb[page] = 0;
|
||||
}
|
||||
if (data & 0400000LL) /* A */
|
||||
fault_data |= 00100000000000LL; /* BIT2 */
|
||||
if (data & 0200000LL) /* P */
|
||||
fault_data |= 00004000000000LL; /* BIT6 */
|
||||
if (data & 0100000LL) /* W */
|
||||
fault_data |= 00040000000000LL; /* BIT3 */
|
||||
if (data & 0040000LL) /* S */
|
||||
fault_data |= 00020000000000LL; /* BIT4 */
|
||||
if (wr) /* T */
|
||||
fault_data |= 00010000000000LL; /* BIT5 */
|
||||
if (data & 0020000LL) /* C */
|
||||
fault_data |= 00002000000000LL; /* BIT7 */
|
||||
fault_data |= BIT7; /* BIT7 */
|
||||
if (data & 0200000LL) /* P */
|
||||
fault_data |= BIT6; /* BIT6 */
|
||||
#if KL_ITS
|
||||
if (QITS && (xct_flag & 020) != 0)
|
||||
PC = (PC + 1) & AMASK;
|
||||
else
|
||||
if (QITS) {
|
||||
if ((xct_flag & 020) != 0) {
|
||||
PC = (PC + 1) & AMASK;
|
||||
page_fault = 0;
|
||||
} else if ((data & RSIGN) == 0) {
|
||||
fault_data = ((uint64)addr) | 033LL << 30 |((uf)?SMASK:0);
|
||||
page_fault = 1;
|
||||
} else {// if (wr & ((data & 0100000) == 0)) {
|
||||
fault_data = ((uint64)addr) | 024LL << 30 |((uf)?SMASK:0);
|
||||
page_fault = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (wr) /* T */
|
||||
fault_data |= BIT5; /* BIT5 */
|
||||
if (data & 0040000LL) /* S */
|
||||
fault_data |= BIT4; /* BIT4 */
|
||||
if (data & 0100000LL) /* W */
|
||||
fault_data |= BIT3; /* BIT3 */
|
||||
if (data & 0400000LL) /* A */
|
||||
fault_data |= BIT2; /* BIT2 */
|
||||
page_fault = 1;
|
||||
return 0;
|
||||
}
|
||||
@ -4255,7 +4288,7 @@ unasign:
|
||||
brk_flags = 017 & (MB >> 23);
|
||||
AB = (AB + 1) & RMASK;
|
||||
MB = M[AB]; /* WD 2 */
|
||||
fault_data = MB;
|
||||
FM[(6<<4)|0] = MB;
|
||||
AB = (AB + 1) & RMASK;
|
||||
MB = M[AB]; /* WD 3 */
|
||||
dbr1 = MB;
|
||||
@ -4279,7 +4312,7 @@ unasign:
|
||||
MB |= ((uint64)brk_flags) << 23;
|
||||
M[AB] = MB; /* WD 1 */
|
||||
AB = (AB + 1) & RMASK;
|
||||
MB = fault_data;
|
||||
MB = FM[(6<<4)|0];
|
||||
M[AB] = MB; /* WD 2 */
|
||||
AB = (AB + 1) & RMASK;
|
||||
MB = dbr1;
|
||||
@ -6718,7 +6751,6 @@ xjrstf:
|
||||
goto xjrstf;
|
||||
/* Fall through */
|
||||
|
||||
|
||||
case 002: /* JRSTF */
|
||||
BR = AR >> 23; /* Move into position */
|
||||
jrstf:
|
||||
@ -6932,8 +6964,8 @@ jrstf:
|
||||
if (!page_enable || AB < 020) {
|
||||
AR = AB; /* direct map */
|
||||
if (flag1) /* U */
|
||||
AR |= SMASK; /* BIT8 */
|
||||
AR |= BIT8|BIT2|00040000000000LL; /* BIT3 */
|
||||
AR |= SMASK; /* BIT0 */
|
||||
AR |= BIT2|BIT3|BIT4|BIT8;
|
||||
set_reg(AC, AR);
|
||||
break;
|
||||
}
|
||||
@ -6952,16 +6984,16 @@ jrstf:
|
||||
if (BR & 0400000LL) { /* A */
|
||||
AR = ((AR & 017777LL) << 9) + (AB & 0777);
|
||||
if (flag1) /* U */
|
||||
AR |= SMASK; /* BIT8 */
|
||||
AR |= 00100000000000LL; /* BIT2 */
|
||||
AR |= SMASK; /* BIT0 */
|
||||
AR |= BIT2; /* BIT2 */
|
||||
if (BR & 0200000LL) /* P */
|
||||
AR |= 00004000000000LL; /* BIT6 */
|
||||
AR |= BIT6; /* BIT6 */
|
||||
if (BR & 0100000LL) /* W */
|
||||
AR |= 00040000000000LL; /* BIT3 */
|
||||
AR |= BIT3; /* BIT3 */
|
||||
if (BR & 0040000LL) /* S */
|
||||
AR |= 00020000000000LL; /* BIT4 */
|
||||
AR |= BIT4; /* BIT4 */
|
||||
if (BR & 0020000LL) /* C */
|
||||
AR |= 00002000000000LL; /* BIT7 */
|
||||
AR |= BIT7; /* BIT7 */
|
||||
} else
|
||||
AR = (f & 01740) ? 0 : 0377777LL;
|
||||
AR |= BIT8;
|
||||
@ -7730,6 +7762,12 @@ test_op:
|
||||
goto muuo;
|
||||
} else {
|
||||
int d = ((IR & 077) << 1) | ((AC & 010) != 0);
|
||||
#if KL
|
||||
if (d == 3) {
|
||||
irq_flags |= 020;
|
||||
goto last;
|
||||
}
|
||||
#endif
|
||||
fetch_opr:
|
||||
switch(AC & 07) {
|
||||
case 0: /* 00 BLKI */
|
||||
@ -7864,6 +7902,12 @@ last:
|
||||
}
|
||||
fprintf(stderr, "Page fault %06o %012llo %06o\n\r", PC, fault_data, FLAGS << 5);
|
||||
BYF5 = 0;
|
||||
#if KL_ITS
|
||||
if (QITS) {
|
||||
AB = eb_ptr + 0500;
|
||||
FM[(6<<4)|0] = fault_data;
|
||||
} else
|
||||
#endif
|
||||
AB = ub_ptr + 0500;
|
||||
MB = fault_data;
|
||||
Mem_write_nopage();
|
||||
|
||||
@ -174,6 +174,9 @@ extern DEBTAB crd_debug[];
|
||||
#define BIT1 00200000000000LL
|
||||
#define BIT2 00100000000000LL
|
||||
#define BIT3 00040000000000LL
|
||||
#define BIT4 00020000000000LL
|
||||
#define BIT5 00010000000000LL
|
||||
#define BIT6 00004000000000LL
|
||||
#define BIT7 00002000000000LL
|
||||
#define BIT8 00001000000000LL
|
||||
#define BIT9 00000400000000LL
|
||||
@ -405,6 +408,7 @@ extern DEVICE pmp_dev;
|
||||
extern DEVICE dk_dev;
|
||||
extern DEVICE pd_dev;
|
||||
extern DEVICE dpy_dev;
|
||||
extern DEVICE iii_dev;
|
||||
extern DEVICE imx_dev;
|
||||
extern DEVICE imp_dev;
|
||||
extern DEVICE ch10_dev;
|
||||
@ -514,7 +518,7 @@ int auxcpu_write (int addr, t_uint64);
|
||||
#define NUM_DEVS_DK 0
|
||||
#define NUM_DEVS_DP 0
|
||||
#define NUM_DEVS_TTY 1
|
||||
#define NUM_LINES_TTY 16
|
||||
#define NUM_LINES_TTY 40
|
||||
#else
|
||||
#define NUM_DEVS_RC 1
|
||||
#define NUM_DEVS_DT 1
|
||||
@ -527,6 +531,7 @@ int auxcpu_write (int addr, t_uint64);
|
||||
#define NUM_DEVS_TU 1
|
||||
#define NUM_DEVS_PMP WAITS
|
||||
#define NUM_DEVS_DKB WAITS
|
||||
#define NUM_DEVS_III 0
|
||||
#define NUM_DEVS_PD ITS | KL_ITS
|
||||
#define NUM_DEVS_IMX ITS
|
||||
#define NUM_DEVS_STK ITS
|
||||
|
||||
@ -42,11 +42,8 @@
|
||||
sim_load binary loader
|
||||
*/
|
||||
|
||||
#if KLB
|
||||
char sim_name[] = "KL-10B";
|
||||
#endif
|
||||
#if KLA
|
||||
char sim_name[] = "KL-10A";
|
||||
#if KL
|
||||
char sim_name[] = "KL-10";
|
||||
#endif
|
||||
#if KI
|
||||
char sim_name[] = "KI-10";
|
||||
@ -162,6 +159,9 @@ DEVICE *sim_devices[] = {
|
||||
&wcnsls_dev,
|
||||
#endif
|
||||
#endif
|
||||
#if (NUM_DEVS_III > 0)
|
||||
&iii_dev,
|
||||
#endif
|
||||
#if NUM_DEVS_IMP > 0
|
||||
&imp_dev,
|
||||
#endif
|
||||
@ -203,7 +203,8 @@ DEVICE *sim_devices[] = {
|
||||
const char *sim_stop_messages[] = {
|
||||
"Unknown error",
|
||||
"HALT instruction",
|
||||
"Breakpoint"
|
||||
"Breakpoint",
|
||||
"Invalid access"
|
||||
};
|
||||
|
||||
/* Simulator debug controls */
|
||||
@ -556,6 +557,7 @@ t_stat load_sav (FILE *fileref)
|
||||
wc = (int32)(data >> 18);
|
||||
pa = (uint32) (data & RMASK);
|
||||
if (wc == (OP_JRST << 9)) {
|
||||
printf("Start addr=%06o\n", pa);
|
||||
PC = pa;
|
||||
return SCPE_OK;
|
||||
}
|
||||
@ -673,12 +675,16 @@ for (i = 0; i < ndir; i = i + 2) { /* loop thru dir */
|
||||
if (get_word(fileref, &pagbuf[k]))
|
||||
return SCPE_FMT;
|
||||
}
|
||||
// wc = sim_fread (pagbuf, sizeof (uint64), PAG_SIZE, fileref);
|
||||
// if (wc < PAG_SIZE)
|
||||
// return SCPE_FMT;
|
||||
fpage++;
|
||||
}
|
||||
ma = mpage << PAG_V_PN; /* mem addr */
|
||||
for (k = 0; k < PAG_SIZE; k++, ma++) { /* copy buf to mem */
|
||||
if (ma > MEMSIZE)
|
||||
return SCPE_NXM;
|
||||
fprintf(stderr, "M %06o %012llo\n", ma, pagbuf[k]);
|
||||
M[ma] = fpage? (pagbuf[k] & FMASK): 0;
|
||||
} /* end copy */
|
||||
} /* end rpt */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user