simh v2.6a
This commit is contained in:
parent
4d6dfa4bdb
commit
a7b623a1a8
40 changed files with 1793 additions and 901 deletions
|
@ -30,6 +30,7 @@ extern unsigned int32 get_uint (char *cptr, int32 radix, unsigned int32 max,
|
|||
sim_PC pointer to saved PC register descriptor
|
||||
sim_emax number of words needed for examine
|
||||
sim_devices array of pointers to simulated devices
|
||||
sim_consoles array of pointers to consoles (if more than one)
|
||||
sim_stop_messages array of pointers to stop messages
|
||||
sim_load binary loader
|
||||
*/
|
||||
|
@ -43,6 +44,8 @@ int32 sim_emax = 4;
|
|||
DEVICE *sim_devices[] = { &cpu_dev, &sio_dev, &ptr_dev,
|
||||
&ptp_dev, &dsk_dev, NULL };
|
||||
|
||||
UNIT *sim_consoles = NULL;
|
||||
|
||||
const char *sim_stop_messages[] = {
|
||||
"Unknown error",
|
||||
"Unknown I/O Instruction",
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
cpu Eclipse central processor
|
||||
|
||||
01-Jun-01 RMS Added second terminal, plotter support
|
||||
26-Apr-01 RMS Added device enable/disable support
|
||||
|
||||
The register state for the Eclipse CPU is basically the same as
|
||||
|
@ -436,7 +437,10 @@ extern int32 ptr (int32 pulse, int32 code, int32 AC);
|
|||
extern int32 ptp (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 tti (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 tto (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 tti1 (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 tto1 (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 clk (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 plt (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 lpt (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 dsk (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 dkp (int32 pulse, int32 code, int32 AC);
|
||||
|
@ -455,7 +459,7 @@ struct ndev dev_table[64] = {
|
|||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ INT_TTI, PI_TTI, &tti }, { INT_TTO, PI_TTO, &tto }, /* 10 - 17 */
|
||||
{ INT_PTR, PI_PTR, &ptr }, { INT_PTP, PI_PTP, &ptp },
|
||||
{ INT_CLK, PI_CLK, &clk }, { 0, 0, &nulldev },
|
||||
{ INT_CLK, PI_CLK, &clk }, { INT_PLT, PI_PLT, &plt },
|
||||
{ 0, 0, &nulldev }, { INT_LPT, PI_LPT, &lpt },
|
||||
{ INT_DSK, PI_DSK, &dsk }, { 0, 0, &nulldev }, /* 20 - 27 */
|
||||
{ INT_MTA, PI_MTA, &mta }, { 0, 0, &nulldev },
|
||||
|
@ -469,7 +473,7 @@ struct ndev dev_table[64] = {
|
|||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev }, /* 50 - 57 */
|
||||
{ INT_TTI1, PI_TTI1, &tti1 }, { INT_TTO1, PI_TTO1, &tto1 }, /* 50 - 57 */
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
27-May-01 RMS Added multiconsole support
|
||||
14-Mar-01 RMS Revised load/dump interface (again)
|
||||
30-Oct-00 RMS Added examine to file support
|
||||
15-Oct-00 RMS Added dynamic device number support
|
||||
|
@ -48,6 +49,7 @@ extern uint16 M[];
|
|||
sim_PC pointer to saved PC register descriptor
|
||||
sim_emax maximum number of words for examine/deposit
|
||||
sim_devices array of pointers to simulated devices
|
||||
sim_consoles array of pointers to consoles (if more than one)
|
||||
sim_stop_messages array of pointers to stop messages
|
||||
sim_load binary loader
|
||||
*/
|
||||
|
@ -67,6 +69,8 @@ DEVICE *sim_devices[] = { &cpu_dev,
|
|||
&dpd_dev, &dpc_dev,
|
||||
NULL };
|
||||
|
||||
UNIT *sim_consoles = NULL;
|
||||
|
||||
const char *sim_stop_messages[] = {
|
||||
"Unknown error",
|
||||
"Unimplemented instruction",
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
27-May-01 RMS Added multiconsole support
|
||||
14-Mar-01 RMS Revised load/dump interface (again)
|
||||
30-Oct-00 RMS Added support for examine to file
|
||||
27-Oct-98 RMS V2.4 load interface
|
||||
|
@ -50,6 +51,7 @@ extern int32 store_addr_u (int32 addr);
|
|||
sim_PC pointer to saved PC register descriptor
|
||||
sim_emax maximum number of words for examine/deposit
|
||||
sim_devices array of pointers to simulated devices
|
||||
sim_consoles array of pointers to consoles (if more than one)
|
||||
sim_stop_messages array of pointers to stop messages
|
||||
sim_load binary loader
|
||||
*/
|
||||
|
@ -64,6 +66,8 @@ DEVICE *sim_devices[] = { &cpu_dev, &inq_dev,
|
|||
&cdr_dev, &cdp_dev, &stack_dev, &lpt_dev,
|
||||
&mt_dev, NULL };
|
||||
|
||||
UNIT *sim_consoles = NULL;
|
||||
|
||||
const char *sim_stop_messages[] = {
|
||||
"Unknown error",
|
||||
"Unimplemented instruction",
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
27-May-01 RMS Added multiconsole support
|
||||
14-Mar-01 RMS Revised load/dump interface (again)
|
||||
30-Oct-00 RMS Added support for examine to file
|
||||
27-Oct-98 RMS V2.4 load interface
|
||||
|
@ -44,6 +45,7 @@ extern int32 saved_PC;
|
|||
sim_PC pointer to saved PC register descriptor
|
||||
sim_emax number of words for examine
|
||||
sim_devices array of pointers to simulated devices
|
||||
sim_consoles array of pointers to consoles (if more than one)
|
||||
sim_stop_messages array of pointers to stop messages
|
||||
sim_load binary loader
|
||||
*/
|
||||
|
@ -58,6 +60,8 @@ DEVICE *sim_devices[] = { &cpu_dev,
|
|||
&pt_dev, &tt_dev,
|
||||
NULL };
|
||||
|
||||
UNIT *sim_consoles = NULL;
|
||||
|
||||
const char *sim_stop_messages[] = {
|
||||
"Unknown error",
|
||||
"Reserved instruction",
|
||||
|
|
11
nova_sys.c
11
nova_sys.c
|
@ -23,6 +23,7 @@
|
|||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
31-May-01 RMS Added multiconsole support
|
||||
14-Mar-01 RMS Revised load/dump interface (again)
|
||||
22-Dec-00 RMS Added second terminal support
|
||||
10-Dec-00 RMS Added Eclipse support
|
||||
|
@ -31,7 +32,7 @@
|
|||
15-Oct-00 RMS Added stack, byte, trap instructions
|
||||
14-Apr-99 RMS Changed t_addr to unsigned
|
||||
27-Oct-98 RMS V2.4 load interface
|
||||
24-Sep-97 RMS Fixed bug in device name table (found by Dutch Owen)
|
||||
24-Sep-97 RMS Fixed bug in device name table (found by Charles Owen)
|
||||
*/
|
||||
|
||||
#include "nova_defs.h"
|
||||
|
@ -49,6 +50,8 @@ extern DEVICE tti1_dev, tto1_dev;
|
|||
extern DEVICE clk_dev, lpt_dev;
|
||||
extern DEVICE dkp_dev, dsk_dev;
|
||||
extern DEVICE mta_dev;
|
||||
extern UNIT tti_unit, tto_unit;
|
||||
extern UNIT tti1_unit, tto1_unit;
|
||||
extern REG cpu_reg[];
|
||||
extern uint16 M[];
|
||||
extern int32 saved_PC;
|
||||
|
@ -59,6 +62,7 @@ extern int32 saved_PC;
|
|||
sim_PC pointer to saved PC register descriptor
|
||||
sim_emax number of words needed for examine
|
||||
sim_devices array of pointers to simulated devices
|
||||
sim_consoles array of pointers to consoles (if more than one)
|
||||
sim_stop_messages array of pointers to stop messages
|
||||
sim_load binary loader
|
||||
*/
|
||||
|
@ -86,6 +90,11 @@ DEVICE *sim_devices[] = {
|
|||
&dkp_dev, &mta_dev,
|
||||
NULL };
|
||||
|
||||
UNIT *sim_consoles[] = {
|
||||
&tti_unit, &tto_unit,
|
||||
&tti1_unit, &tto1_unit,
|
||||
NULL };
|
||||
|
||||
const char *sim_stop_messages[] = {
|
||||
"Unknown error",
|
||||
"Unknown I/O instruction",
|
||||
|
|
18
nova_tt.c
18
nova_tt.c
|
@ -25,6 +25,8 @@
|
|||
|
||||
tti terminal input
|
||||
tto terminal output
|
||||
|
||||
31-May-01 RMS Added multiconsole support
|
||||
*/
|
||||
|
||||
#include "nova_defs.h"
|
||||
|
@ -39,6 +41,7 @@ t_stat tto_reset (DEVICE *dptr);
|
|||
t_stat ttx_setmod (UNIT *uptr, int32 value);
|
||||
extern t_stat sim_poll_kbd (void);
|
||||
extern t_stat sim_putchar (int32 out);
|
||||
static uint8 tto_consout[CONS_SIZE];
|
||||
|
||||
/* TTI data structures
|
||||
|
||||
|
@ -48,7 +51,7 @@ extern t_stat sim_putchar (int32 out);
|
|||
ttx_mod TTI/TTO modifiers list
|
||||
*/
|
||||
|
||||
UNIT tti_unit = { UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT };
|
||||
UNIT tti_unit = { UDATA (&tti_svc, UNIT_CONS, 0), KBD_POLL_WAIT };
|
||||
|
||||
REG tti_reg[] = {
|
||||
{ ORDATA (BUF, tti_unit.buf, 8) },
|
||||
|
@ -59,9 +62,12 @@ REG tti_reg[] = {
|
|||
{ DRDATA (POS, tti_unit.pos, 31), PV_LEFT },
|
||||
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||
{ FLDATA (MODE, tti_unit.flags, UNIT_V_DASHER), REG_HRO },
|
||||
{ FLDATA (CFLAG, tti_unit.flags, UNIT_V_CONS), REG_HRO },
|
||||
{ NULL } };
|
||||
|
||||
MTAB ttx_mod[] = {
|
||||
{ UNIT_CONS, 0, "inactive", NULL, NULL },
|
||||
{ UNIT_CONS, UNIT_CONS, "active console", "CONSOLE", &set_console },
|
||||
{ UNIT_DASHER, 0, "ANSI", "ANSI", &ttx_setmod },
|
||||
{ UNIT_DASHER, UNIT_DASHER, "Dasher", "DASHER", &ttx_setmod },
|
||||
{ 0 } };
|
||||
|
@ -79,7 +85,7 @@ DEVICE tti_dev = {
|
|||
tto_reg TTO register list
|
||||
*/
|
||||
|
||||
UNIT tto_unit = { UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT };
|
||||
UNIT tto_unit = { UDATA (&tto_svc, UNIT_CONS, 0), SERIAL_OUT_WAIT };
|
||||
|
||||
REG tto_reg[] = {
|
||||
{ ORDATA (BUF, tto_unit.buf, 8) },
|
||||
|
@ -90,6 +96,8 @@ REG tto_reg[] = {
|
|||
{ DRDATA (POS, tto_unit.pos, 31), PV_LEFT },
|
||||
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
|
||||
{ FLDATA (MODE, tto_unit.flags, UNIT_V_DASHER), REG_HRO },
|
||||
{ BRDATA (CONSOUT, tto_consout, 8, 8, CONS_SIZE), REG_HIDDEN },
|
||||
{ FLDATA (CFLAG, tto_unit.flags, UNIT_V_CONS), REG_HRO },
|
||||
{ NULL } };
|
||||
|
||||
DEVICE tto_dev = {
|
||||
|
@ -145,7 +153,8 @@ tti_unit.buf = 0;
|
|||
dev_busy = dev_busy & ~INT_TTI; /* clear busy */
|
||||
dev_done = dev_done & ~INT_TTI; /* clear done, int */
|
||||
int_req = int_req & ~INT_TTI;
|
||||
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
|
||||
if (tti_unit.flags & UNIT_CONS) /* if active console, */
|
||||
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -181,7 +190,7 @@ dev_done = dev_done | INT_TTO; /* set done */
|
|||
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
|
||||
c = tto_unit.buf & 0177;
|
||||
if ((tto_unit.flags & UNIT_DASHER) && (c == 031)) c = '\b';
|
||||
if ((temp = sim_putchar (c)) != SCPE_OK) return temp;
|
||||
if ((temp = sim_putcons (c, uptr)) != SCPE_OK) return temp;
|
||||
tto_unit.pos = tto_unit.pos + 1;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
@ -195,6 +204,7 @@ dev_busy = dev_busy & ~INT_TTO; /* clear busy */
|
|||
dev_done = dev_done & ~INT_TTO; /* clear done, int */
|
||||
int_req = int_req & ~INT_TTO;
|
||||
sim_cancel (&tto_unit); /* deactivate unit */
|
||||
tto_unit.filebuf = tto_consout; /* set buf pointer */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
|
61
nova_tt1.c
61
nova_tt1.c
|
@ -27,6 +27,7 @@
|
|||
tti1 second terminal input
|
||||
tto1 second terminal output
|
||||
|
||||
31-May-01 RMS Added multiconsole support
|
||||
26-Apr-01 RMS Added device enable/disable support
|
||||
*/
|
||||
|
||||
|
@ -36,14 +37,13 @@
|
|||
#define UNIT_DASHER (1 << UNIT_V_DASHER)
|
||||
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable, iot_enb;
|
||||
int32 tti1_stopioe = 0, tto1_stopioe = 0; /* stop on error */
|
||||
t_stat tti1_svc (UNIT *uptr);
|
||||
t_stat tto1_svc (UNIT *uptr);
|
||||
t_stat tti1_reset (DEVICE *dptr);
|
||||
t_stat tto1_reset (DEVICE *dptr);
|
||||
t_stat tti1_attach (UNIT *uptr, char *ptr);
|
||||
t_stat tti1_detach (UNIT *uptr);
|
||||
t_stat ttx1_setmod (UNIT *uptr, int32 value);
|
||||
extern t_stat sim_poll_kbd (void);
|
||||
static uint8 tto1_consout[CONS_SIZE];
|
||||
|
||||
/* TTI1 data structures
|
||||
|
||||
|
@ -53,7 +53,7 @@ t_stat ttx1_setmod (UNIT *uptr, int32 value);
|
|||
ttx1_mod TTI1/TTO1 modifiers list
|
||||
*/
|
||||
|
||||
UNIT tti1_unit = { UDATA (&tti1_svc, UNIT_SEQ+UNIT_ATTABLE, 0), KBD_POLL_WAIT };
|
||||
UNIT tti1_unit = { UDATA (&tti1_svc, 0, 0), KBD_POLL_WAIT };
|
||||
|
||||
REG tti1_reg[] = {
|
||||
{ ORDATA (BUF, tti1_unit.buf, 8) },
|
||||
|
@ -63,12 +63,14 @@ REG tti1_reg[] = {
|
|||
{ FLDATA (INT, int_req, INT_V_TTI1) },
|
||||
{ DRDATA (POS, tti1_unit.pos, 31), PV_LEFT },
|
||||
{ DRDATA (TIME, tti1_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, tti1_stopioe, 0) },
|
||||
{ FLDATA (MODE, tti1_unit.flags, UNIT_V_DASHER), REG_HRO },
|
||||
{ FLDATA (CFLAG, tti1_unit.flags, UNIT_V_CONS), REG_HRO },
|
||||
{ FLDATA (*DEVENB, iot_enb, INT_V_TTI1), REG_HRO },
|
||||
{ NULL } };
|
||||
|
||||
MTAB ttx1_mod[] = {
|
||||
{ UNIT_CONS, 0, "inactive", NULL, NULL },
|
||||
{ UNIT_CONS, UNIT_CONS, "active console", "CONSOLE", &set_console },
|
||||
{ UNIT_DASHER, 0, "ANSI", "ANSI", &ttx1_setmod },
|
||||
{ UNIT_DASHER, UNIT_DASHER, "Dasher", "DASHER", &ttx1_setmod },
|
||||
{ 0 } };
|
||||
|
@ -77,7 +79,7 @@ DEVICE tti1_dev = {
|
|||
"TTI1", &tti1_unit, tti1_reg, ttx1_mod,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &tti1_reset,
|
||||
NULL, &tti1_attach, &tti1_detach };
|
||||
NULL, NULL, NULL };
|
||||
|
||||
/* TTO1 data structures
|
||||
|
||||
|
@ -86,7 +88,7 @@ DEVICE tti1_dev = {
|
|||
tto1_reg TTO1 register list
|
||||
*/
|
||||
|
||||
UNIT tto1_unit = { UDATA (&tto1_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT };
|
||||
UNIT tto1_unit = { UDATA (&tto1_svc, 0, 0), SERIAL_OUT_WAIT };
|
||||
|
||||
REG tto1_reg[] = {
|
||||
{ ORDATA (BUF, tto1_unit.buf, 8) },
|
||||
|
@ -96,8 +98,9 @@ REG tto1_reg[] = {
|
|||
{ FLDATA (INT, int_req, INT_V_TTO1) },
|
||||
{ DRDATA (POS, tto1_unit.pos, 31), PV_LEFT },
|
||||
{ DRDATA (TIME, tto1_unit.wait, 24), PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, tto1_stopioe, 0) },
|
||||
{ FLDATA (MODE, tto1_unit.flags, UNIT_V_DASHER), REG_HRO },
|
||||
{ BRDATA (CONSOUT, tto1_consout, 8, 8, CONS_SIZE), REG_HIDDEN },
|
||||
{ FLDATA (CFLAG, tto1_unit.flags, UNIT_V_CONS), REG_HRO },
|
||||
{ FLDATA (*DEVENB, iot_enb, INT_V_TTI1), REG_HRO },
|
||||
{ NULL } };
|
||||
|
||||
|
@ -134,16 +137,8 @@ t_stat tti1_svc (UNIT *uptr)
|
|||
{
|
||||
int32 temp;
|
||||
|
||||
if ((tti1_unit.flags & UNIT_ATT) == 0) /* attached? */
|
||||
return IORETURN (tti1_stopioe, SCPE_UNATT);
|
||||
sim_activate (&tti1_unit, tti1_unit.wait); /* continue poll */
|
||||
if ((temp = getc (tti1_unit.fileref)) == EOF) { /* end of file? */
|
||||
if (feof (tti1_unit.fileref)) {
|
||||
if (tti1_stopioe) printf ("TTI1 end of file\n");
|
||||
else return SCPE_OK; }
|
||||
else perror ("TTI1 input error");
|
||||
clearerr (tti1_unit.fileref);
|
||||
return SCPE_IOERR; }
|
||||
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp; /* no char or error? */
|
||||
tti1_unit.buf = temp & 0177;
|
||||
if ((tti1_unit.flags & UNIT_DASHER) && (tti1_unit.buf == '\r'))
|
||||
tti1_unit.buf = '\n'; /* Dasher: cr -> nl */
|
||||
|
@ -162,30 +157,10 @@ tti1_unit.buf = 0;
|
|||
dev_busy = dev_busy & ~INT_TTI1; /* clear busy */
|
||||
dev_done = dev_done & ~INT_TTI1; /* clear done, int */
|
||||
int_req = int_req & ~INT_TTI1;
|
||||
if (tti1_unit.flags & UNIT_ATT) /* attached? */
|
||||
if (tti1_unit.flags & UNIT_CONS) /* active console? */
|
||||
sim_activate (&tti1_unit, tti1_unit.wait);
|
||||
else sim_cancel (&tti1_unit);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Attach routine */
|
||||
|
||||
t_stat tti1_attach (UNIT *uptr, char *cptr)
|
||||
{
|
||||
t_stat reason;
|
||||
|
||||
reason = attach_unit (uptr, cptr);
|
||||
if (reason == SCPE_OK) sim_activate (uptr, uptr -> wait);
|
||||
return reason;
|
||||
}
|
||||
|
||||
/* Detach routine */
|
||||
|
||||
t_stat tti1_detach (UNIT *uptr)
|
||||
{
|
||||
sim_cancel (uptr);
|
||||
return detach_unit (uptr);
|
||||
}
|
||||
|
||||
/* Terminal output: IOT routine */
|
||||
|
||||
|
@ -212,19 +187,14 @@ return 0;
|
|||
|
||||
t_stat tto1_svc (UNIT *uptr)
|
||||
{
|
||||
int32 c ;
|
||||
int32 c, temp;
|
||||
|
||||
dev_busy = dev_busy & ~INT_TTO1; /* clear busy */
|
||||
dev_done = dev_done | INT_TTO1; /* set done */
|
||||
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
|
||||
if ((tto1_unit.flags & UNIT_ATT) == 0) /* attached? */
|
||||
return IORETURN (tto1_stopioe, SCPE_UNATT);
|
||||
c = tto1_unit.buf & 0177;
|
||||
if ((tto1_unit.flags & UNIT_DASHER) && (c == 031)) c = '\b';
|
||||
if (putc (c, tto1_unit.fileref) == EOF) {
|
||||
perror ("TTO1 output error");
|
||||
clearerr (tto1_unit.fileref);
|
||||
return SCPE_IOERR; }
|
||||
if ((temp = sim_putcons (c, uptr)) != SCPE_OK) return temp;
|
||||
tto1_unit.pos = tto1_unit.pos + 1;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
@ -238,6 +208,7 @@ dev_busy = dev_busy & ~INT_TTO1; /* clear busy */
|
|||
dev_done = dev_done & ~INT_TTO1; /* clear done, int */
|
||||
int_req = int_req & ~INT_TTO1;
|
||||
sim_cancel (&tto1_unit); /* deactivate unit */
|
||||
tto1_unit.filebuf = tto1_consout; /* set buf pointer */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
cpu KS10 central processor
|
||||
|
||||
19-May-01 RMS Added workaround for TOPS-20 V4.1 boot bug
|
||||
29-Apr-01 RMS Fixed modifier naming conflict
|
||||
Fixed XCTR/XCTRI, UMOVE/UMOVEM, BLTUB/BLTBU for ITS
|
||||
Added CLRCSH for ITS
|
||||
|
@ -115,7 +116,7 @@
|
|||
|
||||
#define ILL_ADR_FLAG (1 << VASIZE)
|
||||
#define save_ibkpt (cpu_unit.u3)
|
||||
#define UNIT_V_MSIZE (UNIT_V_ITS + 1) /* dummy mask */
|
||||
#define UNIT_V_MSIZE (UNIT_V_T20V41 + 1) /* dummy mask */
|
||||
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
|
||||
|
||||
d10 *M = NULL; /* memory */
|
||||
|
@ -241,6 +242,7 @@ REG cpu_reg[] = {
|
|||
{ DRDATA (INDMAX, ind_max, 8), PV_LEFT + REG_NZ },
|
||||
{ DRDATA (XCTMAX, xct_max, 8), PV_LEFT + REG_NZ },
|
||||
{ FLDATA (ITS, cpu_unit.flags, UNIT_V_ITS), REG_HRO },
|
||||
{ FLDATA (T20V41, cpu_unit.flags, UNIT_V_T20V41), REG_HRO },
|
||||
{ ORDATA (BREAK, ibkpt_addr, VASIZE + 1) },
|
||||
{ ORDATA (WRU, sim_int_char, 8) },
|
||||
{ FLDATA (STOP_ILL, stop_op0, 0) },
|
||||
|
@ -248,8 +250,9 @@ REG cpu_reg[] = {
|
|||
{ NULL } };
|
||||
|
||||
MTAB cpu_mod[] = {
|
||||
{ UNIT_ITS, 0, "Standard microcode", "STANDARD", NULL },
|
||||
{ UNIT_ITS, UNIT_ITS, "ITS microcode", "ITS", NULL },
|
||||
{ UNIT_ITS+UNIT_T20V41, 0, "Standard microcode", "STANDARD", NULL },
|
||||
{ UNIT_ITS+UNIT_T20V41, UNIT_T20V41, "TOPS-20 V4.1", "TOPS20V41", NULL },
|
||||
{ UNIT_ITS+UNIT_T20V41, UNIT_ITS, "ITS microcode", "ITS", NULL },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE cpu_dev = {
|
||||
|
|
34
pdp10_defs.h
34
pdp10_defs.h
|
@ -22,6 +22,9 @@
|
|||
Except as contained in this notice, the name of Robert M Supnik shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
01-Jun-01 RMS Updated DZ11 vector definitions
|
||||
19-May-01 RMS Added workaround for TOPS-20 V4.1 boot bug
|
||||
*/
|
||||
|
||||
#include "sim_defs.h" /* simulator defns */
|
||||
|
@ -103,6 +106,8 @@ typedef int64 d10; /* PDP-10 data (36b) */
|
|||
|
||||
#define UNIT_V_ITS (UNIT_V_UF) /* ITS */
|
||||
#define UNIT_ITS (1 << UNIT_V_ITS)
|
||||
#define UNIT_V_T20V41 (UNIT_V_UF + 1) /* TOPS-20 V4.1 */
|
||||
#define UNIT_T20V41 (1 << UNIT_V_T20V41)
|
||||
#define ITS (cpu_unit.flags & UNIT_ITS)
|
||||
|
||||
/* Architectural constants */
|
||||
|
@ -590,22 +595,24 @@ typedef int64 d10; /* PDP-10 data (36b) */
|
|||
/* I/O system definitions, lifted from the PDP-11 simulator
|
||||
Interrupt assignments, priority is right to left
|
||||
|
||||
<7:0> = BR7
|
||||
<15:8> = BR6
|
||||
<23:16> = BR5
|
||||
<30:24> = BR4
|
||||
<3:0> = BR7
|
||||
<7:4> = BR6
|
||||
<19:8> = BR5
|
||||
<30:20> = BR4
|
||||
*/
|
||||
|
||||
#define INT_V_RP 8 /* RH11/RP,RM drives */
|
||||
#define INT_V_TU 9 /* RH11/TM03/TU45 */
|
||||
#define INT_V_DZ 16 /* DZ11 */
|
||||
#define INT_V_RP 6 /* RH11/RP,RM drives */
|
||||
#define INT_V_TU 7 /* RH11/TM03/TU45 */
|
||||
#define INT_V_DZ0RX 16 /* DZ11 */
|
||||
#define INT_V_DZ0TX 17
|
||||
#define INT_V_PTR 24 /* PC11 */
|
||||
#define INT_V_PTP 25
|
||||
#define INT_V_LP20 26 /* LPT20 */
|
||||
|
||||
#define INT_RP (1u << INT_V_RP)
|
||||
#define INT_TU (1u << INT_V_TU)
|
||||
#define INT_DZ (1u << INT_V_DZ)
|
||||
#define INT_DZ0RX (1u << INT_V_DZ0RX)
|
||||
#define INT_DZ0TX (1u << INT_V_DZ0TX)
|
||||
#define INT_PTR (1u << INT_V_PTR)
|
||||
#define INT_PTP (1u << INT_V_PTP)
|
||||
#define INT_LP20 (1u << INT_V_LP20)
|
||||
|
@ -613,14 +620,15 @@ typedef int64 d10; /* PDP-10 data (36b) */
|
|||
#define INT_UB1 INT_RP /* on Unibus 1 */
|
||||
#define INT_UB3 (0xFFFFFFFFu & ~INT_UB1) /* on Unibus 3 */
|
||||
|
||||
#define INT_IPL7 0x000000FF /* int level masks */
|
||||
#define INT_IPL6 0x0000FF00
|
||||
#define INT_IPL5 0x00FF0000
|
||||
#define INT_IPL4 0x3F000000
|
||||
#define INT_IPL7 0x0000000F /* int level masks */
|
||||
#define INT_IPL6 0x000000F0
|
||||
#define INT_IPL5 0x000FFF00
|
||||
#define INT_IPL4 0x3FF00000
|
||||
|
||||
#define VEC_PTR 0070 /* interrupt vectors */
|
||||
#define VEC_PTP 0074
|
||||
#define VEC_TU 0224
|
||||
#define VEC_RP 0254
|
||||
#define VEC_DZ 0340
|
||||
#define VEC_DZ0RX 0340
|
||||
#define VEC_DZ0TX 0344
|
||||
#define VEC_LP20 0754
|
||||
|
|
13
pdp10_ksio.c
13
pdp10_ksio.c
|
@ -25,6 +25,7 @@
|
|||
|
||||
uba Unibus adapters
|
||||
|
||||
1-Jun-01 RMS Updated DZ11 vectors
|
||||
12-May-01 RMS Fixed typo
|
||||
|
||||
The KS10 uses the PDP-11 Unibus for its I/O, via adapters. While
|
||||
|
@ -94,8 +95,8 @@ extern jmp_buf save_env;
|
|||
|
||||
extern d10 Read (a10 ea);
|
||||
extern void pi_eval ();
|
||||
extern t_stat dz_rd (int32 *data, int32 addr, int32 access);
|
||||
extern t_stat dz_wr (int32 data, int32 addr, int32 access);
|
||||
extern t_stat dz0_rd (int32 *data, int32 addr, int32 access);
|
||||
extern t_stat dz0_wr (int32 data, int32 addr, int32 access);
|
||||
extern t_stat pt_rd (int32 *data, int32 addr, int32 access);
|
||||
extern t_stat pt_wr (int32 data, int32 addr, int32 access);
|
||||
extern t_stat lp20_rd (int32 *data, int32 addr, int32 access);
|
||||
|
@ -162,7 +163,7 @@ struct iolink iotable[] = {
|
|||
{ IO_UBA3+IO_TMBASE, IO_UBA3+IO_TMBASE+033, 0,
|
||||
&tu_rd, &tu_wr }, /* mag tape */
|
||||
/* { IO_UBA3+IO_DZBASE, IO_UBA3+IO_DZBASE+07, INT_DZ,
|
||||
&dz_rd, &dz_wr }, /* terminal mux */
|
||||
&dz0_rd, &dz0_wr }, /* terminal mux */
|
||||
{ IO_UBA3+IO_LPBASE, IO_UBA3+IO_LPBASE+017, 0,
|
||||
&lp20_rd, &lp20_wr }, /* line printer */
|
||||
{ IO_UBA3+IO_PTBASE, IO_UBA3+IO_PTBASE+07, INT_PTR,
|
||||
|
@ -187,17 +188,17 @@ struct iolink iotable[] = {
|
|||
/* Interrupt request to interrupt action map */
|
||||
|
||||
int32 (*int_ack[32])() = { /* int ack routines */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, &rp_inta, &tu_inta,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
&rp_inta, &tu_inta, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, &lp20_inta, NULL, NULL, NULL, NULL, NULL };
|
||||
|
||||
/* Interrupt request to vector map */
|
||||
|
||||
int32 int_vec[32] = { /* int req to vector */
|
||||
0, 0, 0, 0, 0, 0, VEC_RP, VEC_TU,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
VEC_RP, VEC_TU, 0, 0, 0, 0, 0, 0,
|
||||
VEC_DZ, 0, 0, 0, 0, 0, 0, 0,
|
||||
VEC_DZ0RX, VEC_DZ0TX, 0, 0, 0, 0, 0, 0,
|
||||
VEC_PTR, VEC_PTP, VEC_LP20, 0, 0, 0, 0, 0 };
|
||||
|
||||
/* IO 710 (DEC) TIOE - test I/O word, skip if zero
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
pag KS10 pager
|
||||
|
||||
19-May-01 RMS Added workaround for TOPS-20 V4.1 boot bug
|
||||
03-May-01 RMS Fixed bug in indirect page table pointer processing
|
||||
29-Apr-01 RMS Added CLRCSH for ITS, fixed LPMR
|
||||
|
||||
|
@ -659,6 +660,8 @@ return FALSE;
|
|||
t_bool wrcstm (a10 ea, int32 prv)
|
||||
{
|
||||
cstm = Read (ea, prv);
|
||||
if ((cpu_unit.flags & UNIT_T20V41) && (ea == 040127))
|
||||
cstm = 0770000000000;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
16
pdp10_rp.c
16
pdp10_rp.c
|
@ -335,21 +335,21 @@ t_stat rp_detach (UNIT *uptr);
|
|||
*/
|
||||
|
||||
UNIT rp_unit[] = {
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_AUTO+
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
(RP06_DTYPE << UNIT_V_DTYPE), RP06_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_AUTO+
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
(RP06_DTYPE << UNIT_V_DTYPE), RP06_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_AUTO+
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
(RP06_DTYPE << UNIT_V_DTYPE), RP06_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_AUTO+
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
(RP06_DTYPE << UNIT_V_DTYPE), RP06_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_AUTO+
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
(RP06_DTYPE << UNIT_V_DTYPE), RP06_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_AUTO+
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
(RP06_DTYPE << UNIT_V_DTYPE), RP06_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_AUTO+
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
(RP06_DTYPE << UNIT_V_DTYPE), RP06_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_AUTO+
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
(RP06_DTYPE << UNIT_V_DTYPE), RP06_SIZE) } };
|
||||
|
||||
REG rp_reg[] = {
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
27-May-01 RMS Added multiconsole support
|
||||
29-Apr-01 RMS Fixed format for RDPCST, WRPCST
|
||||
Added CLRCSH for ITS
|
||||
03-Apr-01 RMS Added support for loading EXE files
|
||||
|
@ -50,6 +51,7 @@ extern a10 saved_PC;
|
|||
sim_PC pointer to saved PC register descriptor
|
||||
sim_emax number of words for examine
|
||||
sim_devices array of pointers to simulated devices
|
||||
sim_consoles array of pointers to consoles (if more than one)
|
||||
sim_stop_messages array of pointers to stop messages
|
||||
sim_load binary loader
|
||||
*/
|
||||
|
@ -69,6 +71,8 @@ DEVICE *sim_devices[] = {
|
|||
&rp_dev, &tu_dev,
|
||||
NULL };
|
||||
|
||||
UNIT *sim_consoles = NULL;
|
||||
|
||||
const char *sim_stop_messages[] = {
|
||||
"Unknown error",
|
||||
"HALT instruction",
|
||||
|
|
19
pdp11_cis.c
19
pdp11_cis.c
|
@ -138,11 +138,11 @@
|
|||
|
||||
/* Condition code macros */
|
||||
|
||||
#define GET_BIT(ir,n) (((ir) >> n) & 1)
|
||||
#define GET_SIGN_L(ir) GET_BIT((ir), 31)
|
||||
#define GET_SIGN_W(ir) GET_BIT((ir), 15)
|
||||
#define GET_SIGN_B(ir) GET_BIT((ir), 7)
|
||||
#define GET_Z(ir) (ir == 0)
|
||||
#define GET_BIT(ir,n) (((ir) >> n) & 1)
|
||||
#define GET_SIGN_L(ir) GET_BIT((ir), 31)
|
||||
#define GET_SIGN_W(ir) GET_BIT((ir), 15)
|
||||
#define GET_SIGN_B(ir) GET_BIT((ir), 7)
|
||||
#define GET_Z(ir) (ir == 0)
|
||||
|
||||
/* Decimal string structure */
|
||||
|
||||
|
@ -416,7 +416,7 @@ case 030: case 032: case 0130: case 0132:
|
|||
Condition codes:
|
||||
NZVC = set from src.lnt - dst.lnt
|
||||
|
||||
Registers (MOVC, MOVTC only)
|
||||
Registers (MOVRC only)
|
||||
R0 = max (0, src.len - dst.len)
|
||||
R1:R3 = 0
|
||||
R4:R5 = unchanged
|
||||
|
@ -432,7 +432,7 @@ case 031: case 0131:
|
|||
addr = A2ADR + A2LNT - mvlnt;
|
||||
for (i = 0; i < mvlnt; i++) {
|
||||
WriteB (movbuf[i], ((addr + i) & 0177777) | dsenable); }
|
||||
fill = A3LNT & 0377; /* do fill, if any */
|
||||
fill = A3LNT & 0377; /* do fill, if any */
|
||||
for (i = mvlnt, j = 0; i < A2LNT; i++, j++) {
|
||||
WriteB (fill, ((A2ADR + j) & 0177777) | dsenable); }
|
||||
t = A1LNT - A2LNT; /* src.lnt - dst.lnt */
|
||||
|
@ -509,7 +509,7 @@ case 042: case 043: case 0142: case 0143:
|
|||
for (; R[0] != 0; R[0]--) { /* loop */
|
||||
t = ReadB (R[1] | dsenable); /* get char as index */
|
||||
c = ReadB (((A1ADR + t) & 0177777) | dsenable);
|
||||
if (((c & mask) != 0) ^ (op & 1)) break; /* != + SCN, = + SPN? */
|
||||
if (((c & mask) != 0) ^ (op & 1)) break; /* != + SCN, = + SPN? */
|
||||
R[1] = (R[1] + 1) & 0177777; }
|
||||
N = GET_SIGN_W (R[0]);
|
||||
Z = GET_Z (R[0]);
|
||||
|
@ -735,8 +735,7 @@ case 052: case 072: case 0152: case 0172:
|
|||
ReadDstr (A2, &src2, op); /* get source2 */
|
||||
N = Z = V = C = 0;
|
||||
if (src1.sign != src2.sign) N = src1.sign;
|
||||
else {
|
||||
t = CmpDstr (&src1, &src2); /* compare strings */
|
||||
else { t = CmpDstr (&src1, &src2); /* compare strings */
|
||||
if (t < 0) N = 1;
|
||||
else if (t == 0) Z = 1; }
|
||||
if ((op & INLINE) == 0) /* if reg, clr reg */
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
cpu PDP-11 CPU (J-11 microprocessor)
|
||||
|
||||
01-Jun-01 RMS Added DZ11 support
|
||||
23-Apr-01 RMS Added RK611 support
|
||||
05-Apr-01 RMS Added TS11/TSV05 support
|
||||
05-Mar-01 RMS Added clock calibration support
|
||||
|
@ -325,7 +326,7 @@ struct iolink iotable[] = {
|
|||
int32 int_vec[32] = { /* int req to vector */
|
||||
0, 0, 0, VEC_PIRQ, VEC_CLK, VEC_DTA, 0, VEC_PIRQ,
|
||||
VEC_RK, VEC_RL, VEC_RX, VEC_TM, VEC_RP, VEC_TS, VEC_HK, 0,
|
||||
0, 0, 0, VEC_PIRQ, VEC_TTI, VEC_TTO, VEC_PTR, VEC_PTP,
|
||||
VEC_DZ0RX, VEC_DZ0TX, 0, VEC_PIRQ, VEC_TTI, VEC_TTO, VEC_PTR, VEC_PTP,
|
||||
VEC_LPT, 0, 0, 0, VEC_PIRQ, VEC_PIRQ, VEC_PIRQ, VEC_PIRQ };
|
||||
|
||||
int32 (*int_ack[32])() = { /* int ack routines */
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
The author gratefully acknowledges the help of Max Burnet, Megan Gentry,
|
||||
and John Wilson in resolving questions about the PDP-11
|
||||
|
||||
01-Jun-01 RMS Added DZ11 support
|
||||
23-Apr-01 RMS Added RK611 support
|
||||
05-Apr-01 RMS Added TS11/TSV05 support
|
||||
10-Feb-01 RMS Added DECtape support
|
||||
|
@ -240,7 +241,7 @@ typedef struct fpac fpac_t;
|
|||
|
||||
<3:0> = BR7, <3> = PIR7
|
||||
<7:4> = BR6, <7> = PIR6
|
||||
<19:8> = BR5, <15> = PIR5
|
||||
<19:8> = BR5, <19> = PIR5
|
||||
<28:20> = BR4, <28> = PIR4
|
||||
<29> = PIR3
|
||||
<30> = PIR2
|
||||
|
@ -258,6 +259,8 @@ typedef struct fpac fpac_t;
|
|||
#define INT_V_RP 12
|
||||
#define INT_V_TS 13
|
||||
#define INT_V_HK 14
|
||||
#define INT_V_DZ0RX 16
|
||||
#define INT_V_DZ0TX 17
|
||||
#define INT_V_PIR5 19
|
||||
#define INT_V_TTI 20
|
||||
#define INT_V_TTO 21
|
||||
|
@ -280,6 +283,8 @@ typedef struct fpac fpac_t;
|
|||
#define INT_RP (1u << INT_V_RP)
|
||||
#define INT_TS (1u << INT_V_TS)
|
||||
#define INT_HK (1u << INT_V_HK)
|
||||
#define INT_DZ0RX (1u << INT_V_DZ0RX)
|
||||
#define INT_DZ0TX (1u << INT_V_DZ0TX)
|
||||
#define INT_PIR5 (1u << INT_V_PIR5)
|
||||
#define INT_PTR (1u << INT_V_PTR)
|
||||
#define INT_PTP (1u << INT_V_PTP)
|
||||
|
@ -315,6 +320,8 @@ typedef struct fpac fpac_t;
|
|||
#define VEC_TS 0224
|
||||
#define VEC_RP 0254
|
||||
#define VEC_RX 0264
|
||||
#define VEC_DZ0RX 0310
|
||||
#define VEC_DZ0TX 0314
|
||||
|
||||
/* CPU and FPU macros */
|
||||
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
20-Apr-98 RMS Fixed bug in MODf integer truncation
|
||||
17-Apr-98 RMS Fixed bug in STCfi range check
|
||||
16-Apr-98 RMS Fixed bugs in STEXP, STCfi, round/pack
|
||||
9-Apr-98 RMS Fixed bug in LDEXP
|
||||
4-Apr-98 RMS Fixed bug in MODf condition codes
|
||||
09-Apr-98 RMS Fixed bug in LDEXP
|
||||
04-Apr-98 RMS Fixed bug in MODf condition codes
|
||||
|
||||
This module simulates the PDP-11 floating point unit (FP11 series).
|
||||
It is called from the instruction decoder for opcodes 170000:177777.
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
26-Apr-01 RMS Added device enable/disable support
|
||||
25-Mar-01 RMS Fixed block fill calculation
|
||||
15-Feb-01 RMS Corrected bootstrap string
|
||||
29-Jun-96 RMS Added unit disable support.
|
||||
29-Jun-96 RMS Added unit disable support
|
||||
|
||||
The RK11 is an eight drive cartridge disk subsystem. An RK05 drive
|
||||
consists of 203 cylinders, each with 2 surfaces containing 12 sectors
|
||||
|
|
|
@ -28,9 +28,9 @@
|
|||
26-Apr-01 RMS Added device enable/disable support
|
||||
25-Mar-01 RMS Fixed block fill calculation
|
||||
15-Feb-01 RMS Corrected bootstrap string
|
||||
12-Nov-97 RMS Added bad block table command.
|
||||
25-Nov-96 RMS Default units to autosize.
|
||||
29-Jun-96 RMS Added unit disable support.
|
||||
12-Nov-97 RMS Added bad block table command
|
||||
25-Nov-96 RMS Default units to autosize
|
||||
29-Jun-96 RMS Added unit disable support
|
||||
|
||||
The RL11 is a four drive cartridge disk subsystem. An RL01 drive
|
||||
consists of 256 cylinders, each with 2 surfaces containing 40 sectors
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
14-Apr-99 RMS Changed t_addr to unsigned
|
||||
05-Oct-98 RMS Fixed bug, failing to interrupt on go error
|
||||
04-Oct-98 RMS Changed names to allow coexistence with RH/TU77
|
||||
12-Nov-97 RMS Added bad block table command.
|
||||
10-Aug-97 RMS Fixed bugs in interrupt handling.
|
||||
12-Nov-97 RMS Added bad block table command
|
||||
10-Aug-97 RMS Fixed bugs in interrupt handling
|
||||
|
||||
The "Massbus style" disks consisted of several different large
|
||||
capacity drives interfaced through a reasonably common (but not
|
||||
|
|
14
pdp11_sys.c
14
pdp11_sys.c
|
@ -23,16 +23,17 @@
|
|||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
27-May-01 RMS Added multiconsole support
|
||||
05-Apr-01 RMS Added support for TS11/TSV05
|
||||
14-Mar-01 RMS Revised load/dump interface (again)
|
||||
11-Feb-01 RMS Added DECtape support
|
||||
30-Oct-00 RMS Added support for examine to file
|
||||
14-Apr-99 RMS Changed t_addr to unsigned
|
||||
09-Nov-98 RMS Fixed assignments of ROR/ROL (John Wilson).
|
||||
27-Oct-98 RMS V2.4 load interface.
|
||||
08-Oct-98 RMS Fixed bug in bad block routine.
|
||||
30-Mar-98 RMS Fixed bug in floating point display.
|
||||
12-Nov-97 RMS Added bad block table routine.
|
||||
09-Nov-98 RMS Fixed assignments of ROR/ROL (John Wilson)
|
||||
27-Oct-98 RMS V2.4 load interface
|
||||
08-Oct-98 RMS Fixed bug in bad block routine
|
||||
30-Mar-98 RMS Fixed bug in floating point display
|
||||
12-Nov-97 RMS Added bad block table routine
|
||||
*/
|
||||
|
||||
#include "pdp11_defs.h"
|
||||
|
@ -58,6 +59,7 @@ extern int32 saved_PC;
|
|||
sim_PC pointer to saved PC register descriptor
|
||||
sim_emax number of words for examine
|
||||
sim_devices array of pointers to simulated devices
|
||||
sim_consoles array of pointers to consoles (if more than one)
|
||||
sim_stop_messages array of pointers to stop messages
|
||||
sim_load binary loader
|
||||
*/
|
||||
|
@ -79,6 +81,8 @@ DEVICE *sim_devices[] = {
|
|||
&tm_dev, &ts_dev,
|
||||
NULL };
|
||||
|
||||
UNIT *sim_consoles = NULL;
|
||||
|
||||
const char *sim_stop_messages[] = {
|
||||
"Unknown error",
|
||||
"Red stack trap",
|
||||
|
|
443
pdp18b_cpu.c
443
pdp18b_cpu.c
|
@ -25,6 +25,9 @@
|
|||
|
||||
cpu PDP-4/7/9/15 central processor
|
||||
|
||||
27-May-01 RMS Added second Teletype support, fixed bug in API
|
||||
18-May-01 RMS Added PDP-9,-15 API option
|
||||
16-May-01 RMS Fixed bugs in protection checks
|
||||
26-Apr-01 RMS Added device enable/disable support
|
||||
25-Jan-01 RMS Added DECtape support
|
||||
18-Dec-00 RMS Added PDP-9,-15 memm init register
|
||||
|
@ -46,7 +49,7 @@
|
|||
all IORS I/O status register
|
||||
PDP-7, PDP-9 EXTM extend mode
|
||||
PDP-15 BANKM bank mode
|
||||
PDP-7 TRAPM trap mode
|
||||
PDP-7 USMD trap mode
|
||||
PDP-9, PDP-15 USMD user mode
|
||||
PDP-9, PDP-15 BR bounds register
|
||||
PDP-15 XR index register
|
||||
|
@ -241,22 +244,33 @@
|
|||
#define save_ibkpt (cpu_unit.u3)
|
||||
#define UNIT_V_NOEAE (UNIT_V_UF) /* EAE absent */
|
||||
#define UNIT_NOEAE (1 << UNIT_V_NOEAE)
|
||||
#define UNIT_V_MSIZE (UNIT_V_UF+1) /* dummy mask */
|
||||
#define UNIT_V_NOAPI (UNIT_V_UF+1) /* API absent */
|
||||
#define UNIT_NOAPI (1 << UNIT_V_NOAPI)
|
||||
#define UNIT_V_MSIZE (UNIT_V_UF+2) /* dummy mask */
|
||||
|
||||
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
|
||||
#if defined (PDP4)
|
||||
#define EAE_DFLT UNIT_NOEAE
|
||||
#else
|
||||
#define EAE_DFLT 0
|
||||
#endif
|
||||
#if defined (PDP4) || (PDP7)
|
||||
#define API_DFLT UNIT_NOAPI
|
||||
#else
|
||||
#define API_DFLT UNIT_NOAPI /* for now */
|
||||
#endif
|
||||
|
||||
int32 M[MAXMEMSIZE] = { 0 }; /* memory */
|
||||
int32 saved_LAC = 0; /* link'AC */
|
||||
int32 saved_MQ = 0; /* MQ */
|
||||
int32 saved_PC = 0; /* PC */
|
||||
int32 int_req = 0; /* int requests */
|
||||
int32 iors = 0; /* IORS */
|
||||
int32 ion = 0; /* int on */
|
||||
int32 ion_defer = 0; /* int defer */
|
||||
int32 int_req = 0; /* int requests */
|
||||
int32 api_enb = 0; /* API enable */
|
||||
int32 api_req = 0; /* API requests */
|
||||
int32 api_act = 0; /* API active */
|
||||
int32 memm = 0; /* mem mode */
|
||||
#if defined (PDP15)
|
||||
int32 memm_init = 1; /* mem init */
|
||||
|
@ -288,7 +302,31 @@ t_stat cpu_reset (DEVICE *dptr);
|
|||
t_stat cpu_svc (UNIT *uptr);
|
||||
t_stat cpu_set_size (UNIT *uptr, int32 value);
|
||||
int32 upd_iors (void);
|
||||
extern t_stat sim_activate (UNIT *uptr, int32 delay);
|
||||
int32 api_eval (void);
|
||||
|
||||
static const int32 api_ffo[256] = {
|
||||
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
static const int32 api_vec[32] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, ACH_TTO1, ACH_TTI1, ACH_CLK, 0, 0, 0, 0,
|
||||
0, ACH_LPT, ACH_LPT, ACH_PTR, 0, 0, 0, ACH_RP,
|
||||
ACH_RF, ACH_DRM, ACH_MTA, ACH_DTA, 0, 0, ACH_PWRFL, 0 };
|
||||
|
||||
/* CPU data structures
|
||||
|
||||
|
@ -298,7 +336,7 @@ extern t_stat sim_activate (UNIT *uptr, int32 delay);
|
|||
cpu_mod CPU modifier list
|
||||
*/
|
||||
|
||||
UNIT cpu_unit = { UDATA (&cpu_svc, UNIT_FIX + UNIT_BINK + EAE_DFLT,
|
||||
UNIT cpu_unit = { UDATA (&cpu_svc, UNIT_FIX + UNIT_BINK + EAE_DFLT + API_DFLT,
|
||||
MAXMEMSIZE) };
|
||||
|
||||
REG cpu_reg[] = {
|
||||
|
@ -320,7 +358,11 @@ REG cpu_reg[] = {
|
|||
{ FLDATA (TRAPP, trap_pending, 0) },
|
||||
{ FLDATA (EXTM, memm, 0) },
|
||||
{ FLDATA (EMIRP, emir_pending, 0) },
|
||||
#elif defined (PDP9)
|
||||
#endif
|
||||
#if defined (PDP9)
|
||||
{ FLDATA (APIENB, api_enb, 0) },
|
||||
{ ORDATA (APIREQ, api_req, 8) },
|
||||
{ ORDATA (APIACT, api_act, 8) },
|
||||
{ ORDATA (BR, BR, ADDRSIZE) },
|
||||
{ FLDATA (USMD, usmd, 0) },
|
||||
{ FLDATA (USMDBUF, usmdbuf, 0) },
|
||||
|
@ -332,7 +374,11 @@ REG cpu_reg[] = {
|
|||
{ FLDATA (EMIRP, emir_pending, 0) },
|
||||
{ FLDATA (RESTP, rest_pending, 0) },
|
||||
{ FLDATA (PWRFL, int_req, INT_V_PWRFL) },
|
||||
#elif defined (PDP15)
|
||||
#endif
|
||||
#if defined (PDP15)
|
||||
{ FLDATA (APIENB, api_enb, 0) },
|
||||
{ ORDATA (APIREQ, api_req, 8) },
|
||||
{ ORDATA (APIACT, api_act, 8) },
|
||||
{ ORDATA (XR, XR, 18) },
|
||||
{ ORDATA (LR, LR, 18) },
|
||||
{ ORDATA (BR, BR, ADDRSIZE) },
|
||||
|
@ -349,6 +395,7 @@ REG cpu_reg[] = {
|
|||
{ ORDATA (OLDPC, old_PC, ADDRSIZE), REG_RO },
|
||||
{ FLDATA (STOP_INST, stop_inst, 0) },
|
||||
{ FLDATA (NOEAE, cpu_unit.flags, UNIT_V_NOEAE), REG_HRO },
|
||||
{ FLDATA (NOAPI, cpu_unit.flags, UNIT_V_NOAPI), REG_HRO },
|
||||
{ DRDATA (XCT_MAX, xct_max, 8), PV_LEFT + REG_NZ },
|
||||
{ ORDATA (BREAK, ibkpt_addr, ADDRSIZE + 1) },
|
||||
{ ORDATA (WRU, sim_int_char, 8) },
|
||||
|
@ -361,6 +408,10 @@ MTAB cpu_mod[] = {
|
|||
{ UNIT_NOEAE, 0, "EAE", "EAE", NULL },
|
||||
#else
|
||||
{ UNIT_MSIZE, 4096, NULL, "4K", &cpu_set_size },
|
||||
#endif
|
||||
#if defined (PDP9) || defined (PDP15)
|
||||
{ UNIT_NOAPI, UNIT_NOAPI, "no API", "NOAPI", NULL },
|
||||
{ UNIT_NOAPI, 0, "API", "API", NULL },
|
||||
#endif
|
||||
{ UNIT_MSIZE, 8192, NULL, "8K", &cpu_set_size },
|
||||
#if (MAXMEMSIZE > 8192)
|
||||
|
@ -391,6 +442,7 @@ t_stat sim_instr (void)
|
|||
{
|
||||
extern int32 sim_interval;
|
||||
register int32 PC, LAC, MQ;
|
||||
int32 api_int, api_cycle, skp;
|
||||
int32 iot_data, device, pulse;
|
||||
t_stat reason;
|
||||
extern UNIT clk_unit;
|
||||
|
@ -422,94 +474,15 @@ extern int32 mt (int32 pulse, int32 AC);
|
|||
extern int32 dt75 (int32 pulse, int32 AC);
|
||||
extern int32 dt76 (int32 pulse, int32 AC);
|
||||
#endif
|
||||
#if defined (TTY1)
|
||||
extern int32 tti1 (int32 pulse, int32 AC);
|
||||
extern int32 tto1 (int32 pulse, int32 AC);
|
||||
#endif
|
||||
|
||||
#define JMS_WORD(t) (((LAC & 01000000) >> 1) | ((memm & 1) << 16) | \
|
||||
(((t) & 1) << 15) | ((PC) & 077777))
|
||||
#define INCR_ADDR(x) (((x) & epcmask) | (((x) + 1) & damask))
|
||||
#define SEXT(x) ((int) (((x) & 0400000)? (x) | ~0777777: (x) & 0777777))
|
||||
|
||||
/* Restore register state */
|
||||
|
||||
#if defined (PDP15)
|
||||
register int32 epcmask, damask;
|
||||
|
||||
damask = memm? 017777: 07777; /* set dir addr mask */
|
||||
epcmask = ADDRMASK & ~damask; /* extended PC mask */
|
||||
|
||||
#else
|
||||
#define damask 017777 /* direct addr mask */
|
||||
#define epcmask (ADDRMASK & ~damask) /* extended PC mask */
|
||||
#endif
|
||||
|
||||
PC = saved_PC & ADDRMASK; /* load local copies */
|
||||
LAC = saved_LAC & 01777777;
|
||||
MQ = saved_MQ & 0777777;
|
||||
reason = 0;
|
||||
sim_rtc_init (clk_unit.wait); /* init calibration */
|
||||
|
||||
/* Main instruction fetch/decode loop: check trap and interrupt */
|
||||
|
||||
while (reason == 0) { /* loop until halted */
|
||||
register int32 IR, MA, t, xct_count;
|
||||
register int32 link_init, fill;
|
||||
|
||||
if (sim_interval <= 0) { /* check clock queue */
|
||||
if (reason = sim_process_event ()) break; }
|
||||
|
||||
/* Protection traps work like interrupts, with these quirks:
|
||||
|
||||
PDP-7 extend mode forced on, M[0] = PC, PC = 2
|
||||
PDP-9 extend mode ???, M[0/20] = PC, PC = 0/21
|
||||
PDP-15 bank mode unchanged, M[0/20] = PC, PC = 0/21
|
||||
*/
|
||||
|
||||
#if defined (PDP7)
|
||||
if (trap_pending) { /* trap pending? */
|
||||
old_PC = PC; /* save old PC */
|
||||
M[0] = JMS_WORD (1); /* save state */
|
||||
PC = 2; /* fetch next from 2 */
|
||||
ion = 0; /* interrupts off */
|
||||
memm = 1; /* extend on */
|
||||
emir_pending = trap_pending = 0; /* emir, trap off */
|
||||
usmd = 0; } /* protect off */
|
||||
#elif defined (PDP9)
|
||||
if (trap_pending) { /* trap pending? */
|
||||
old_PC = PC; /* save old PC */
|
||||
MA = ion? 0: 020; /* save in 0 or 20 */
|
||||
M[MA] = JMS_WORD (1); /* save state */
|
||||
PC = MA + 1; /* fetch next */
|
||||
ion = 0; /* interrupts off */
|
||||
/*??? memm = 0; /* extend off */
|
||||
emir_pending = rest_pending = trap_pending = 0; /* emir,rest,trap off */
|
||||
usmd = 0; } /* protect off */
|
||||
#elif defined (PDP15)
|
||||
if (trap_pending) { /* trap pending? */
|
||||
old_PC = PC; /* save old PC */
|
||||
MA = ion? 0: 020; /* save in 0 or 20 */
|
||||
M[MA] = JMS_WORD (1); /* save state */
|
||||
PC = MA + 1; /* fetch next */
|
||||
ion = 0; /* interrupts off */
|
||||
emir_pending = rest_pending = trap_pending = 0; /* emir,rest,trap off */
|
||||
usmd = 0; } /* protect off */
|
||||
#endif
|
||||
|
||||
if (ion && !ion_defer && int_req) { /* interrupt? */
|
||||
old_PC = PC; /* save old PC */
|
||||
M[0] = JMS_WORD (usmd); /* save state */
|
||||
PC = 1; /* fetch next from 1 */
|
||||
ion = 0; /* interrupts off */
|
||||
#if !defined (PDP15) /* except PDP-15, */
|
||||
memm = 0; /* extend off */
|
||||
#endif
|
||||
emir_pending = rest_pending = 0; /* emir, restore off */
|
||||
usmd = 0; } /* protect off */
|
||||
|
||||
if (PC == ibkpt_addr) { /* breakpoint? */
|
||||
save_ibkpt = ibkpt_addr; /* save ibkpt */
|
||||
ibkpt_addr = ibkpt_addr | ILL_ADR_FLAG; /* disable */
|
||||
sim_activate (&cpu_unit, 1); /* sched re-enable */
|
||||
reason = STOP_IBKPT; /* stop simulation */
|
||||
break; }
|
||||
|
||||
/* The following macros implement addressing. They account for autoincrement
|
||||
addressing, extended addressing, and memory protection, if it exists.
|
||||
|
@ -563,7 +536,7 @@ if (PC == ibkpt_addr) { /* breakpoint? */
|
|||
if (!MEM_ADDR_OK (x)) { \
|
||||
nexm = prvn = trap_pending = 1; \
|
||||
break; } \
|
||||
if ((x) >= BR) { \
|
||||
if ((x) < BR) { \
|
||||
prvn = trap_pending = 1; \
|
||||
break; } } \
|
||||
if (!MEM_ADDR_OK (x)) nexm = 1
|
||||
|
@ -604,7 +577,7 @@ if (PC == ibkpt_addr) { /* breakpoint? */
|
|||
if (!MEM_ADDR_OK (x)) { \
|
||||
nexm = prvn = trap_pending = 1; \
|
||||
break; } \
|
||||
if ((x) >= BR) { \
|
||||
if ((x) < BR) { \
|
||||
prvn = trap_pending = 1; \
|
||||
break; } } \
|
||||
if (!MEM_ADDR_OK (x)) nexm = 1
|
||||
|
@ -613,20 +586,133 @@ if (PC == ibkpt_addr) { /* breakpoint? */
|
|||
if (!MEM_ADDR_OK (x)) break
|
||||
#endif
|
||||
|
||||
/* Restore register state */
|
||||
|
||||
#if defined (PDP15)
|
||||
register int32 epcmask, damask;
|
||||
|
||||
damask = memm? 017777: 07777; /* set dir addr mask */
|
||||
epcmask = ADDRMASK & ~damask; /* extended PC mask */
|
||||
|
||||
#else
|
||||
#define damask 017777 /* direct addr mask */
|
||||
#define epcmask (ADDRMASK & ~damask) /* extended PC mask */
|
||||
#endif
|
||||
|
||||
PC = saved_PC & ADDRMASK; /* load local copies */
|
||||
LAC = saved_LAC & 01777777;
|
||||
MQ = saved_MQ & 0777777;
|
||||
reason = 0;
|
||||
sim_rtc_init (clk_unit.wait); /* init calibration */
|
||||
if (cpu_unit.flags & UNIT_NOAPI) api_enb = api_req = api_act = 0;
|
||||
api_int = api_eval (); /* eval API */
|
||||
api_cycle = 0; /* not API cycle */
|
||||
|
||||
/* Main instruction fetch/decode loop: check trap and interrupt */
|
||||
|
||||
while (reason == 0) { /* loop until halted */
|
||||
register int32 IR, MA, t, xct_count;
|
||||
register int32 link_init, fill;
|
||||
|
||||
if (sim_interval <= 0) { /* check clock queue */
|
||||
if (reason = sim_process_event ()) break;
|
||||
api_int = api_eval (); } /* eval API */
|
||||
|
||||
/* Protection traps work like interrupts, with these quirks:
|
||||
|
||||
PDP-7 extend mode forced on, M[0] = PC, PC = 2
|
||||
PDP-9 extend mode ???, M[0/20] = PC, PC = 0/21
|
||||
PDP-15 bank mode unchanged, M[0/20] = PC, PC = 0/21
|
||||
*/
|
||||
|
||||
#if defined (PDP7)
|
||||
if (trap_pending) { /* trap pending? */
|
||||
old_PC = PC; /* save old PC */
|
||||
M[0] = JMS_WORD (1); /* save state */
|
||||
PC = 2; /* fetch next from 2 */
|
||||
ion = 0; /* interrupts off */
|
||||
memm = 1; /* extend on */
|
||||
emir_pending = trap_pending = 0; /* emir, trap off */
|
||||
usmd = 0; } /* protect off */
|
||||
#endif
|
||||
#if defined (PDP9) || defined (PDP15)
|
||||
if (trap_pending) { /* trap pending? */
|
||||
old_PC = PC; /* save old PC */
|
||||
MA = ion? 0: 020; /* save in 0 or 20 */
|
||||
M[MA] = JMS_WORD (1); /* save state */
|
||||
PC = MA + 1; /* fetch next */
|
||||
ion = 0; /* interrupts off */
|
||||
emir_pending = rest_pending = trap_pending = 0; /* emir,rest,trap off */
|
||||
usmd = 0; } /* protect off */
|
||||
|
||||
/* PDP-9 and PDP-15 automatic priority interrupt (API) */
|
||||
|
||||
if (api_int && !ion_defer) { /* API intr? */
|
||||
int32 i, lvl = api_int - 1; /* get req level */
|
||||
api_act = api_act | (0200 >> lvl); /* set level active */
|
||||
if (lvl >= 4) { /* software req? */
|
||||
MA = ACH_SWRE + lvl - 4; /* vec = 40:43 */
|
||||
api_req = api_req & ~(0200 >> lvl); } /* remove request */
|
||||
else { MA = 0; /* assume fails */
|
||||
for (i = 31; i >= 0; i--) { /* loop hi to lo */
|
||||
if ((int_req >> i) & 1) { /* int req set? */
|
||||
MA = api_vec[i]; /* get vector */
|
||||
break; } } } /* and stop */
|
||||
if (MA == 0) { /* bad channel? */
|
||||
reason = STOP_API; /* API error */
|
||||
break; }
|
||||
api_int = api_eval (); /* no API int */
|
||||
api_cycle = 1; /* in API cycle */
|
||||
emir_pending = rest_pending = 0; /* emir, restore off */
|
||||
xct_count = 0;
|
||||
goto xct_instr; }
|
||||
|
||||
/* Standard program interrupt */
|
||||
|
||||
if (!(api_enb && api_act) && ion && !ion_defer && int_req) {
|
||||
#else
|
||||
if (ion && !ion_defer && int_req) { /* interrupt? */
|
||||
#endif
|
||||
old_PC = PC; /* save old PC */
|
||||
M[0] = JMS_WORD (usmd); /* save state */
|
||||
PC = 1; /* fetch next from 1 */
|
||||
ion = 0; /* interrupts off */
|
||||
#if !defined (PDP15) /* except PDP-15, */
|
||||
memm = 0; /* extend off */
|
||||
#endif
|
||||
emir_pending = rest_pending = 0; /* emir, restore off */
|
||||
usmd = 0; } /* protect off */
|
||||
|
||||
/* Breakpoint */
|
||||
|
||||
if (PC == ibkpt_addr) { /* breakpoint? */
|
||||
save_ibkpt = ibkpt_addr; /* save ibkpt */
|
||||
ibkpt_addr = ibkpt_addr | ILL_ADR_FLAG; /* disable */
|
||||
sim_activate (&cpu_unit, 1); /* sched re-enable */
|
||||
reason = STOP_IBKPT; /* stop simulation */
|
||||
break; }
|
||||
|
||||
/* Fetch, decode instruction */
|
||||
|
||||
MA = PC; /* fetch at PC */
|
||||
CHECK_ADDR_R (MA); /* validate addr */
|
||||
IR = M[MA]; /* fetch instruction */
|
||||
PC = INCR_ADDR (PC); /* increment PC */
|
||||
#if defined (PDP9) || defined (PDP15)
|
||||
if (usmd) { /* user mode? */
|
||||
if (!MEM_ADDR_OK (PC)) { /* nxm? */
|
||||
nexm = prvn = trap_pending = 1; /* abort fetch */
|
||||
continue; } \
|
||||
if (PC < BR) { /* bounds viol? */
|
||||
prvn = trap_pending = 1; /* abort fetch */
|
||||
continue; } }
|
||||
else if (!MEM_ADDR_OK (PC)) nexm = 1; /* flag nxm */
|
||||
if (!ion_defer) usmd = usmdbuf; /* no IOT? load usmd */
|
||||
#endif
|
||||
if (ion_defer) ion_defer = ion_defer - 1; /* count down defer */
|
||||
xct_count = 0; /* track nested XCT's */
|
||||
sim_interval = sim_interval - 1;
|
||||
MA = PC; /* fetch at PC */
|
||||
PC = INCR_ADDR (PC); /* increment PC */
|
||||
|
||||
xct_instr: /* label for XCT */
|
||||
IR = M[MA]; /* fetch instruction */
|
||||
if (ion_defer) ion_defer = ion_defer - 1; /* count down defer */
|
||||
if (sim_interval) sim_interval = sim_interval - 1;
|
||||
MA = (MA & epcmask) | (IR & damask); /* effective address */
|
||||
switch ((IR >> 13) & 037) { /* decode IR<0:4> */
|
||||
|
||||
|
@ -752,13 +838,13 @@ case 020: /* XCT, dir */
|
|||
#if defined (PDP9)
|
||||
ion_defer = 1; /* defer intr */
|
||||
#endif
|
||||
IR = M[MA]; /* get instruction */
|
||||
goto xct_instr; /* go execute */
|
||||
|
||||
/* CAL: opcode 00
|
||||
|
||||
On the PDP-4 and PDP-7, CAL (I) is exactly the same as JMS (I) 20
|
||||
On the PDP-9, CAL clears user mode
|
||||
On the PDP-9 and PDP-15, CAL clears user mode
|
||||
On the PDP-9 and PDP-15 with API, CAL activates level 4
|
||||
On the PDP-15, CAL goes to absolute 20, regardless of mode
|
||||
*/
|
||||
|
||||
|
@ -771,6 +857,9 @@ case 001: case 000: /* CAL */
|
|||
#endif
|
||||
#if defined (PDP9) || defined (PDP15)
|
||||
usmd = 0; /* clear user mode */
|
||||
if ((cpu_unit.flags & UNIT_NOAPI) == 0) { /* if API, act lvl 4 */
|
||||
api_act = api_act | 010;
|
||||
api_int = api_eval (); }
|
||||
#endif
|
||||
if (IR & 0020000) { INDIRECT; } /* indirect? */
|
||||
CHECK_ADDR_W (MA);
|
||||
|
@ -800,7 +889,7 @@ case 004: /* JMS, dir */
|
|||
*/
|
||||
|
||||
case 031: /* JMP, indir */
|
||||
CHECK_AUTO_INC; /* check auto inc */
|
||||
CHECK_AUTO_INC; /* check auto inc */
|
||||
#if defined (PDP7) || defined (PDP9)
|
||||
if (emir_pending && (((M[MA] >> 16) & 1) == 0)) memm = 0;
|
||||
#endif
|
||||
|
@ -825,55 +914,56 @@ case 037: /* OPR, indir */
|
|||
break;
|
||||
|
||||
case 036: /* OPR, dir */
|
||||
skp = 0; /* assume no skip */
|
||||
switch ((IR >> 6) & 017) { /* decode IR<8:11> */
|
||||
case 0: /* nop */
|
||||
break;
|
||||
case 1: /* SMA */
|
||||
if ((LAC & 0400000) != 0) PC = INCR_ADDR (PC);
|
||||
if ((LAC & 0400000) != 0) skp = 1;
|
||||
break;
|
||||
case 2: /* SZA */
|
||||
if ((LAC & 0777777) == 0) PC = INCR_ADDR (PC);
|
||||
if ((LAC & 0777777) == 0) skp = 1;
|
||||
break;
|
||||
case 3: /* SZA | SMA */
|
||||
if (((LAC & 0777777) == 0) || ((LAC & 0400000) != 0))
|
||||
PC = INCR_ADDR (PC);
|
||||
skp = 1;
|
||||
break;
|
||||
case 4: /* SNL */
|
||||
if (LAC >= 01000000) PC = INCR_ADDR (PC);
|
||||
if (LAC >= 01000000) skp = 1;
|
||||
break;
|
||||
case 5: /* SNL | SMA */
|
||||
if (LAC >= 0400000) PC = INCR_ADDR (PC);
|
||||
if (LAC >= 0400000) skp = 1;
|
||||
break;
|
||||
case 6: /* SNL | SZA */
|
||||
if ((LAC >= 01000000) || (LAC == 0)) PC = INCR_ADDR (PC);
|
||||
if ((LAC >= 01000000) || (LAC == 0)) skp = 1;
|
||||
break;
|
||||
case 7: /* SNL | SZA | SMA */
|
||||
if ((LAC >= 0400000) || (LAC == 0)) PC = INCR_ADDR (PC);
|
||||
if ((LAC >= 0400000) || (LAC == 0)) skp = 1;
|
||||
break;
|
||||
case 010: /* SKP */
|
||||
PC = INCR_ADDR (PC);
|
||||
skp = 1;
|
||||
break;
|
||||
case 011: /* SPA */
|
||||
if ((LAC & 0400000) == 0) PC = INCR_ADDR (PC);
|
||||
if ((LAC & 0400000) == 0) skp = 1;
|
||||
break;
|
||||
case 012: /* SNA */
|
||||
if ((LAC & 0777777) != 0) PC = INCR_ADDR (PC);
|
||||
if ((LAC & 0777777) != 0) skp = 1;
|
||||
break;
|
||||
case 013: /* SNA & SPA */
|
||||
if (((LAC & 0777777) != 0) && ((LAC & 0400000) == 0))
|
||||
PC = INCR_ADDR (PC);
|
||||
skp = 1;
|
||||
break;
|
||||
case 014: /* SZL */
|
||||
if (LAC < 01000000) PC = INCR_ADDR (PC);
|
||||
if (LAC < 01000000) skp = 1;
|
||||
break;
|
||||
case 015: /* SZL & SPA */
|
||||
if (LAC < 0400000) PC = INCR_ADDR (PC);
|
||||
if (LAC < 0400000) skp = 1;
|
||||
break;
|
||||
case 016: /* SZL & SNA */
|
||||
if ((LAC < 01000000) && (LAC != 0)) PC = INCR_ADDR (PC);
|
||||
if ((LAC < 01000000) && (LAC != 0)) skp = 1;
|
||||
break;
|
||||
case 017: /* SZL & SNA & SPA */
|
||||
if ((LAC < 0400000) && (LAC != 0)) PC = INCR_ADDR (PC);
|
||||
if ((LAC < 0400000) && (LAC != 0)) skp = 1;
|
||||
break; } /* end switch skips */
|
||||
|
||||
/* OPR, continued */
|
||||
|
@ -968,6 +1058,7 @@ case 036: /* OPR, dir */
|
|||
if (IR & 0000040) { /* HLT */
|
||||
if (usmd) prvn = trap_pending = 1;
|
||||
else reason = STOP_HALT; }
|
||||
if (skp && !prvn) PC = INCR_ADDR (PC); /* if skip, inc PC */
|
||||
break; /* end OPR */
|
||||
|
||||
/* EAE: opcode 64
|
||||
|
@ -1169,7 +1260,11 @@ case 035: /* index operates */
|
|||
703301 undefined TTS TTS TTS
|
||||
703341 undefined SKP7 SKP7 SPCO
|
||||
703302 undefined CAF CAF CAF
|
||||
703304 undefined undefined DBK DBK
|
||||
703344 undefined undefined DBR DBR
|
||||
705501 undefined undefined SPI SPI
|
||||
705502 undefined undefined RPL RPL
|
||||
705504 undefined undefined ISA ISA
|
||||
707701 undefined SEM SEM undefined
|
||||
707741 undefined undefined undefined SKP15
|
||||
707761 undefined undefined undefined SBA
|
||||
|
@ -1203,10 +1298,11 @@ case 034: /* IOT */
|
|||
else if (pulse == 042) ion = ion_defer = 1; /* ION */
|
||||
else iot_data = clk (pulse, iot_data);
|
||||
break;
|
||||
#endif
|
||||
|
||||
/* PDP-7 system IOT's */
|
||||
|
||||
#elif defined (PDP7)
|
||||
#if defined (PDP7)
|
||||
switch (device) { /* decode IR<6:11> */
|
||||
case 0: /* CPU and clock */
|
||||
if (pulse == 002) ion = 0; /* IOF */
|
||||
|
@ -1226,10 +1322,11 @@ case 034: /* IOT */
|
|||
memm = emir_pending = 1; /* ext on, restore */
|
||||
else if (pulse == 004) memm = 0; /* LEM */
|
||||
break;
|
||||
#endif
|
||||
|
||||
/* PDP-9 system IOT's */
|
||||
/* PDP-9 and PDP-15 system IOT's */
|
||||
|
||||
#elif defined (PDP9)
|
||||
#if defined (PDP9) || defined (PDP15)
|
||||
ion_defer = 1; /* delay interrupts */
|
||||
switch (device) { /* decode IR<6:11> */
|
||||
case 000: /* CPU and clock */
|
||||
|
@ -1242,7 +1339,7 @@ case 034: /* IOT */
|
|||
else if ((pulse == 041) && nexm) PC = INCR_ADDR (PC);
|
||||
else if (pulse == 002) prvn = 0;
|
||||
else if (pulse == 042) usmdbuf = 1;
|
||||
else if (pulse == 004) BR = LAC & 076000;
|
||||
else if (pulse == 004) BR = LAC & BRMASK;
|
||||
else if (pulse == 044) nexm = 0;
|
||||
break;
|
||||
case 032: /* power fail */
|
||||
|
@ -1252,8 +1349,27 @@ case 034: /* IOT */
|
|||
case 033: /* CPU control */
|
||||
if ((pulse == 001) || (pulse == 041)) PC = INCR_ADDR (PC);
|
||||
else if (pulse == 002) reset_all (0); /* CAF */
|
||||
else if (pulse == 044) rest_pending = 1; /* DBR */
|
||||
else if (pulse == 044) rest_pending = 1; /* DBR */
|
||||
if (((cpu_unit.flags & UNIT_NOAPI) == 0) && (pulse & 004)) {
|
||||
int32 t = api_ffo[api_act & 0377];
|
||||
api_act = api_act & ~(0200 >> t); }
|
||||
break;
|
||||
case 055: /* API control */
|
||||
if (cpu_unit.flags & UNIT_NOAPI) reason = stop_inst;
|
||||
else if (pulse == 001) { /* SPI */
|
||||
if (((LAC & SIGN) && api_enb) ||
|
||||
((LAC & 0377) > api_act))
|
||||
iot_data = iot_data | IOT_SKP; }
|
||||
else if (pulse == 002) { /* RPL */
|
||||
iot_data = iot_data | (api_enb << 17) |
|
||||
(api_req << 8) | api_act; }
|
||||
else if (pulse == 004) { /* ISA */
|
||||
api_enb = (iot_data & SIGN)? 1: 0;
|
||||
api_req = api_req | ((LAC >> 8) & 017);
|
||||
api_act = api_act | (LAC & 0377); }
|
||||
break;
|
||||
#endif
|
||||
#if defined (PDP9)
|
||||
case 077: /* extended memory */
|
||||
if ((pulse == 001) && memm) PC = INCR_ADDR (PC);
|
||||
else if (pulse == 002) memm = 1; /* EEM */
|
||||
|
@ -1261,34 +1377,8 @@ case 034: /* IOT */
|
|||
memm = emir_pending = 1; /* ext on, restore */
|
||||
else if (pulse == 004) memm = 0; /* LEM */
|
||||
break;
|
||||
|
||||
/* PDP-15 system IOT's */
|
||||
|
||||
#elif defined (PDP15)
|
||||
ion_defer = 1; /* delay interrupts */
|
||||
switch (device) { /* decode IR<6:11> */
|
||||
case 000: /* CPU and clock */
|
||||
if (pulse == 002) ion = 0; /* IOF */
|
||||
else if (pulse == 042) ion = 1; /* ION */
|
||||
else iot_data = clk (pulse, iot_data);
|
||||
break;
|
||||
case 017: /* mem protection */
|
||||
if ((pulse == 001) && prvn) PC = INCR_ADDR (PC);
|
||||
else if ((pulse == 041) && nexm) PC = INCR_ADDR (PC);
|
||||
else if (pulse == 002) prvn = 0;
|
||||
else if (pulse == 042) usmdbuf = 1;
|
||||
else if (pulse == 004) BR = LAC & 0377400;
|
||||
else if (pulse == 044) nexm = 0;
|
||||
break;
|
||||
case 032: /* power fail */
|
||||
if ((pulse == 001) && (int_req & INT_PWRFL))
|
||||
PC = INCR_ADDR (PC);
|
||||
break;
|
||||
case 033: /* CPU control */
|
||||
if ((pulse == 001) || (pulse == 041)) PC = INCR_ADDR (PC);
|
||||
else if (pulse == 002) reset_all (0); /* CAF */
|
||||
else if (pulse == 044) rest_pending = 1; /* DBR */
|
||||
break;
|
||||
#endif
|
||||
#if defined (PDP15)
|
||||
case 077: /* bank addressing */
|
||||
if ((pulse == 041) || ((pulse == 061) && memm))
|
||||
PC = INCR_ADDR (PC); /* SKP15, SBA */
|
||||
|
@ -1315,6 +1405,14 @@ case 034: /* IOT */
|
|||
case 4: /* TTO */
|
||||
iot_data = tto (pulse, iot_data);
|
||||
break;
|
||||
#if defined (TTY1)
|
||||
case 040: /* TTO1 */
|
||||
iot_data = tto1 (pulse, iot_data);
|
||||
break;
|
||||
case 041: /* TTI1 */
|
||||
iot_data = tti1 (pulse, iot_data);
|
||||
break;
|
||||
#endif
|
||||
#if defined (DRM)
|
||||
case 060: /* drum */
|
||||
if (dev_enb & INT_DRM) iot_data = drm60 (pulse, iot_data);
|
||||
|
@ -1377,8 +1475,13 @@ case 034: /* IOT */
|
|||
LAC = LAC | (iot_data & 0777777);
|
||||
if (iot_data & IOT_SKP) PC = INCR_ADDR (PC);
|
||||
if (iot_data >= IOT_REASON) reason = iot_data >> IOT_V_REASON;
|
||||
api_int = api_eval (); /* eval API */
|
||||
break; /* end case IOT */
|
||||
} /* end switch opcode */
|
||||
if (api_cycle) { /* API cycle? */
|
||||
api_cycle = 0; /* cycle over */
|
||||
usmd = 0; /* exit user mode */
|
||||
trap_pending = prvn = 0; } /* no priv viol */
|
||||
} /* end while */
|
||||
|
||||
/* Simulation halted */
|
||||
|
@ -1390,20 +1493,21 @@ iors = upd_iors (); /* get IORS */
|
|||
return reason;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
/* Evaluate API */
|
||||
|
||||
t_stat cpu_reset (DEVICE *dptr)
|
||||
int32 api_eval (void)
|
||||
{
|
||||
SC = 0;
|
||||
eae_ac_sign = 0;
|
||||
ion = ion_defer = 0;
|
||||
int_req = int_req & ~INT_PWRFL;
|
||||
BR = 0;
|
||||
usmd = usmdbuf = 0;
|
||||
memm = memm_init;
|
||||
nexm = prvn = trap_pending = 0;
|
||||
emir_pending = rest_pending = 0;
|
||||
return cpu_svc (&cpu_unit);
|
||||
int32 i, hi;
|
||||
static const uint32 api_mask[4] = {
|
||||
API_L0, API_L1, API_L2, API_L3 };
|
||||
|
||||
if (api_enb == 0) return 0; /* off? no req */
|
||||
api_req = api_req & ~0360; /* clr req<0:3> */
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (int_req & api_mask[i]) api_req = api_req | (0200 >> i); }
|
||||
hi = api_ffo[api_req & 0377]; /* find hi req */
|
||||
if (hi < api_ffo[api_act & 0377]) return (hi + 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Process IORS instruction */
|
||||
|
@ -1441,6 +1545,23 @@ return (ion? IOS_ION: 0) |
|
|||
std_iors () | lpt_iors ();
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat cpu_reset (DEVICE *dptr)
|
||||
{
|
||||
SC = 0;
|
||||
eae_ac_sign = 0;
|
||||
ion = ion_defer = 0;
|
||||
int_req = int_req & ~INT_PWRFL;
|
||||
api_enb = api_req = api_act = 0;
|
||||
BR = 0;
|
||||
usmd = usmdbuf = 0;
|
||||
memm = memm_init;
|
||||
nexm = prvn = trap_pending = 0;
|
||||
emir_pending = rest_pending = 0;
|
||||
return cpu_svc (&cpu_unit);
|
||||
}
|
||||
|
||||
/* Memory examine */
|
||||
|
||||
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw)
|
||||
|
|
108
pdp18b_defs.h
108
pdp18b_defs.h
|
@ -23,6 +23,7 @@
|
|||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
27-May-01 RMS Added second Teletype support
|
||||
21-Jan-01 RMS Added DECtape support
|
||||
14-Apr-99 RMS Changed t_addr to unsigned
|
||||
02-Jan-96 RMS Added fixed head and moving head disks
|
||||
|
@ -54,21 +55,23 @@
|
|||
Type 24 serial drum
|
||||
|
||||
PDP9 32K KE09A EAE KSR-33 Teletype
|
||||
KG09B mem extension PC09A paper tape reader and punch
|
||||
KP09A power detection integral real time clock
|
||||
KX09A mem protection Type 647D/E line printer (sixbit)
|
||||
RF09/RS09 fixed head disk
|
||||
KF09A auto pri intr PC09A paper tape reader and punch
|
||||
KG09B mem extension integral real time clock
|
||||
KP09A power detection Type 647D/E line printer (sixbit)
|
||||
KX09A mem protection RF09/RS09 fixed head disk
|
||||
TC59 magnetic tape
|
||||
TC02/TU55 DECtape
|
||||
LT09A second Teletype
|
||||
|
||||
PDP15 128K KE15 EAE KSR-35 Teletype
|
||||
KF15 power detection PC15 paper tape reader and punch
|
||||
KM15 mem protection KW15 real time clock
|
||||
??KT15 mem relocation LP15 line printer
|
||||
RP15 disk pack
|
||||
KA15 auto pri intr PC15 paper tape reader and punch
|
||||
KF15 power detection KW15 real time clock
|
||||
KM15 mem protection LP15 line printer
|
||||
??KT15 mem relocation RP15 disk pack
|
||||
RF15/RF09 fixed head disk
|
||||
TC59D magnetic tape
|
||||
TC15/TU56 DECtape
|
||||
LT15 second Teletype
|
||||
|
||||
??Indicates not implemented. The PDP-4 manual refers to both an EAE
|
||||
??and a memory extension control; there is no documentation on either.
|
||||
|
@ -84,6 +87,7 @@
|
|||
#define STOP_HALT 2 /* HALT */
|
||||
#define STOP_IBKPT 3 /* breakpoint */
|
||||
#define STOP_XCT 4 /* nested XCT's */
|
||||
#define STOP_API 5 /* invalid API int */
|
||||
|
||||
/* Peripheral configuration */
|
||||
|
||||
|
@ -101,6 +105,8 @@
|
|||
#define RF 0 /* fixed head disk */
|
||||
#define MTA 0 /* magtape */
|
||||
#define DTA 0 /* DECtape */
|
||||
#define TTY1 0 /* second Teletype */
|
||||
#define BRMASK 0076000 /* bounds mask */
|
||||
#elif defined (PDP15)
|
||||
#define ADDRSIZE 17
|
||||
#define LP15 0 /* ASCII printer */
|
||||
|
@ -108,6 +114,8 @@
|
|||
#define RP 0 /* disk pack */
|
||||
#define MTA 0 /* magtape */
|
||||
#define DTA 0 /* DECtape */
|
||||
#define TTY1 0 /* second Teletype */
|
||||
#define BRMASK 0377400 /* bounds mask */
|
||||
#endif
|
||||
|
||||
/* Memory */
|
||||
|
@ -125,6 +133,7 @@
|
|||
#define LINK (DMASK + 1) /* link */
|
||||
#define LACMASK (LINK | DMASK) /* link + data */
|
||||
#define SIGN 0400000 /* sign bit */
|
||||
#define OP_JMS 0100000 /* JMS */
|
||||
#define OP_JMP 0600000 /* JMP */
|
||||
#define OP_HLT 0740040 /* HLT */
|
||||
|
||||
|
@ -144,19 +153,55 @@
|
|||
If flag based, API is hard to implement; if API based, IORS requires
|
||||
extra code for implementation. I've chosen an API based model.
|
||||
|
||||
API channel Device API priority Notes
|
||||
|
||||
00 software 4 4
|
||||
01 software 5 5
|
||||
02 software 6 6
|
||||
03 software 7 7
|
||||
04 TC02/TC15 1
|
||||
05 TC59D 1
|
||||
06 drum 1 PDP-9 only
|
||||
07 disk 1 PDP-9 only
|
||||
10 paper tape reader 2
|
||||
11 real time clock 3
|
||||
12 power fail 0
|
||||
13 memory parity 0
|
||||
14 display 2
|
||||
15 card reader 2
|
||||
16 line printer 2
|
||||
17 A/D converter 0
|
||||
20 interprocessor buffer 3
|
||||
21 360 link 3 PDP-9 only
|
||||
22 data phone 2 PDP-15 only
|
||||
23 RF09/RF15 1
|
||||
24 RP15 1 PDP-15 only
|
||||
25 plotter 1 PDP-15 only
|
||||
26 -
|
||||
27 -
|
||||
30 -
|
||||
31 -
|
||||
32 -
|
||||
33 -
|
||||
34 LT15 TTO 3 PDP-15 only
|
||||
35 LT15 TTI 3 PDP-15 only
|
||||
36 -
|
||||
37 -
|
||||
|
||||
Interrupt system, priority is left to right.
|
||||
|
||||
<30:28> = priority 0
|
||||
<27:20> = priority 1
|
||||
<19:14> = priority 2
|
||||
<13:10> = priority 3
|
||||
<9:4> = PI only
|
||||
<3> = priority 4 (software)
|
||||
<2> = priority 5 (software)
|
||||
<1> = priority 6 (software)
|
||||
<0> = priority 7 (software)
|
||||
<19:12> = priority 2
|
||||
<11:8> = priority 3
|
||||
<7:0> = PI only
|
||||
*/
|
||||
|
||||
#define API_L0 0xF0000000
|
||||
#define API_L1 0x0FF00000
|
||||
#define API_L2 0x000FF000
|
||||
#define API_L3 0x00000F00
|
||||
|
||||
#define INT_V_PWRFL 30 /* powerfail */
|
||||
#define INT_V_DTA 27 /* DECtape */
|
||||
#define INT_V_MTA 26 /* magtape */
|
||||
|
@ -166,14 +211,12 @@
|
|||
#define INT_V_PTR 19 /* paper tape reader */
|
||||
#define INT_V_LPT 18 /* line printer */
|
||||
#define INT_V_LPTSPC 17 /* line printer spc */
|
||||
#define INT_V_CLK 13 /* clock */
|
||||
#define INT_V_TTI 9 /* keyboard */
|
||||
#define INT_V_TTO 8 /* terminal */
|
||||
#define INT_V_PTP 7 /* paper tape punch */
|
||||
#define INT_V_SW4 3 /* software 4 */
|
||||
#define INT_V_SW5 2 /* software 5 */
|
||||
#define INT_V_SW6 1 /* software 6 */
|
||||
#define INT_V_SW7 0 /* software 7 */
|
||||
#define INT_V_CLK 11 /* clock */
|
||||
#define INT_V_TTI1 10 /* LT15 keyboard */
|
||||
#define INT_V_TTO1 9 /* LT15 output */
|
||||
#define INT_V_TTI 7 /* console keyboard */
|
||||
#define INT_V_TTO 6 /* console output */
|
||||
#define INT_V_PTP 5 /* paper tape punch */
|
||||
|
||||
#define INT_PWRFL (1 << INT_V_PWRFL)
|
||||
#define INT_DTA (1 << INT_V_DTA)
|
||||
|
@ -185,13 +228,24 @@
|
|||
#define INT_LPT (1 << INT_V_LPT)
|
||||
#define INT_LPTSPC (1 << INT_V_LPTSPC)
|
||||
#define INT_CLK (1 << INT_V_CLK)
|
||||
#define INT_TTI1 (1 << INT_V_TTI1)
|
||||
#define INT_TTO1 (1 << INT_V_TTO1)
|
||||
#define INT_TTI (1 << INT_V_TTI)
|
||||
#define INT_TTO (1 << INT_V_TTO)
|
||||
#define INT_PTP (1 << INT_V_PTP)
|
||||
#define INT_SW4 (1 << INT_V_SW4)
|
||||
#define INT_SW5 (1 << INT_V_SW5)
|
||||
#define INT_SW6 (1 << INT_V_SW6)
|
||||
#define INT_SW7 (1 << INT_V_SW7)
|
||||
|
||||
#define ACH_SWRE 040 /* API channels */
|
||||
#define ACH_PWRFL 052
|
||||
#define ACH_DTA 044
|
||||
#define ACH_MTA 045
|
||||
#define ACH_DRM 046
|
||||
#define ACH_RF 063
|
||||
#define ACH_RP 064
|
||||
#define ACH_PTR 050
|
||||
#define ACH_LPT 056
|
||||
#define ACH_CLK 051
|
||||
#define ACH_TTI1 075
|
||||
#define ACH_TTO1 074
|
||||
|
||||
/* I/O status flags for the IORS instruction
|
||||
|
||||
|
|
15
pdp18b_drm.c
15
pdp18b_drm.c
|
@ -26,6 +26,7 @@
|
|||
drm (PDP-7) Type 24 serial drum
|
||||
(PDP-9) RM09 serial drum
|
||||
|
||||
10-Jun-01 RMS Cleaned up IOT decoding to reflect hardware
|
||||
26-Apr-01 RMS Added device enable/disable support
|
||||
14-Apr-99 RMS Changed t_addr to unsigned
|
||||
*/
|
||||
|
@ -108,14 +109,13 @@ int32 drm61 (int32 pulse, int32 AC)
|
|||
{
|
||||
int32 t;
|
||||
|
||||
if (pulse == 001) return (int_req & INT_DRM)? IOT_SKP + AC: AC; /* DRSF */
|
||||
if (pulse == 002) { /* DRCF */
|
||||
if (pulse & 001) { /* DRSF */
|
||||
if (int_req & INT_DRM) AC = AC | IOT_SKP; }
|
||||
if (pulse & 002) { /* DRCF */
|
||||
int_req = int_req & ~INT_DRM; /* clear done */
|
||||
drm_err = 0; } /* clear error */
|
||||
if (pulse == 006) { /* DRSS */
|
||||
if (pulse & 004) { /* DRSS */
|
||||
drm_da = AC & DRM_SMASK; /* load sector # */
|
||||
int_req = int_req & ~INT_DRM; /* clear done */
|
||||
drm_err = 0; /* clear error */
|
||||
t = ((drm_da % DRM_NUMSC) * DRM_NUMWDS) - GET_POS (drm_time);
|
||||
if (t < 0) t = t + DRM_NUMWDT; /* wrap around? */
|
||||
sim_activate (&drm_unit, t * drm_time); } /* schedule op */
|
||||
|
@ -126,8 +126,9 @@ int32 drm62 (int32 pulse, int32 AC)
|
|||
{
|
||||
int32 t;
|
||||
|
||||
if (pulse == 001) return (drm_err)? AC: IOT_SKP + AC; /* DRSN */
|
||||
if (pulse == 004) { /* DRCS */
|
||||
if (pulse & 001) { /* DRSN */
|
||||
if (drm_err == 0) AC = AC | IOT_SKP; }
|
||||
if (pulse & 004) { /* DRCS */
|
||||
int_req = int_req & ~INT_DRM; /* clear done */
|
||||
drm_err = 0; /* clear error */
|
||||
t = ((drm_da % DRM_NUMSC) * DRM_NUMWDS) - GET_POS (drm_time);
|
||||
|
|
|
@ -187,7 +187,7 @@ if (pulse == 042) { /* DSCD */
|
|||
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */
|
||||
else rf_sta = 0;
|
||||
rf_updsta (0); }
|
||||
if (pulse == 0062) { /* DSRS */
|
||||
if (pulse == 062) { /* DSRS */
|
||||
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */
|
||||
return rf_updsta (0); }
|
||||
return AC;
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
tto teleprinter
|
||||
clk clock
|
||||
|
||||
10-Jun-01 RMS Cleaned up IOT decoding to reflect hardware
|
||||
27-May-01 RMS Added multiconsole support
|
||||
10-Mar-01 RMS Added funny format loader support
|
||||
05-Mar-01 RMS Added clock calibration support
|
||||
22-Dec-00 RMS Added PDP-9/15 half duplex support
|
||||
|
@ -50,6 +52,10 @@ int32 ptp_err = 0, ptp_stopioe = 0;
|
|||
int32 tti_state = 0;
|
||||
int32 tto_state = 0;
|
||||
int32 clk_tps = 60;
|
||||
#if defined (TTY1)
|
||||
static uint8 tto_consout[CONS_SIZE];
|
||||
#endif
|
||||
|
||||
t_stat clk_svc (UNIT *uptr);
|
||||
t_stat ptr_svc (UNIT *uptr);
|
||||
t_stat ptp_svc (UNIT *uptr);
|
||||
|
@ -195,9 +201,9 @@ static const int32 tti_trans[128] = {
|
|||
#define UNIT_HDX (1 << UNIT_V_HDX)
|
||||
|
||||
#if defined (PDP4) || defined (PDP7)
|
||||
UNIT tti_unit = { UDATA (&tti_svc, UNIT_UC, 0), KBD_POLL_WAIT };
|
||||
UNIT tti_unit = { UDATA (&tti_svc, UNIT_UC+UNIT_CONS, 0), KBD_POLL_WAIT };
|
||||
#else
|
||||
UNIT tti_unit = { UDATA (&tti_svc, UNIT_UC + UNIT_HDX, 0), KBD_POLL_WAIT };
|
||||
UNIT tti_unit = { UDATA (&tti_svc, UNIT_UC+UNIT_HDX+UNIT_CONS, 0), KBD_POLL_WAIT };
|
||||
#endif
|
||||
|
||||
REG tti_reg[] = {
|
||||
|
@ -212,9 +218,16 @@ REG tti_reg[] = {
|
|||
#endif
|
||||
{ DRDATA (POS, tti_unit.pos, 31), PV_LEFT },
|
||||
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||
#if defined (TTY1)
|
||||
{ FLDATA (CFLAG, tti_unit.flags, UNIT_V_CONS), REG_HRO },
|
||||
#endif
|
||||
{ NULL } };
|
||||
|
||||
MTAB tti_mod[] = {
|
||||
#if defined (TTY1)
|
||||
{ UNIT_CONS, 0, "inactive", NULL, NULL },
|
||||
{ UNIT_CONS, UNIT_CONS, "active console", "CONSOLE", &set_console },
|
||||
#endif
|
||||
#if !defined (KSR28)
|
||||
{ UNIT_UC, 0, "lower case", "LC", NULL },
|
||||
{ UNIT_UC, UNIT_UC, "upper case", "UC", NULL },
|
||||
|
@ -257,7 +270,7 @@ static const char tto_trans[64] = {
|
|||
|
||||
#define TTO_MASK ((1 << TTO_WIDTH) - 1)
|
||||
|
||||
UNIT tto_unit = { UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT };
|
||||
UNIT tto_unit = { UDATA (&tto_svc, UNIT_UC+UNIT_CONS, 0), SERIAL_OUT_WAIT };
|
||||
|
||||
REG tto_reg[] = {
|
||||
{ ORDATA (BUF, tto_unit.buf, TTO_WIDTH) },
|
||||
|
@ -268,10 +281,25 @@ REG tto_reg[] = {
|
|||
#endif
|
||||
{ DRDATA (POS, tto_unit.pos, 31), PV_LEFT },
|
||||
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
|
||||
#if defined (TTY1)
|
||||
{ BRDATA (CONSOUT, tto_consout, 8, 8, CONS_SIZE), REG_HIDDEN },
|
||||
{ FLDATA (CFLAG, tto_unit.flags, UNIT_V_CONS), REG_HRO },
|
||||
#endif
|
||||
{ NULL } };
|
||||
|
||||
MTAB tto_mod[] = {
|
||||
#if defined (TTY1)
|
||||
{ UNIT_CONS, 0, "inactive", NULL, NULL },
|
||||
{ UNIT_CONS, UNIT_CONS, "active console", "CONSOLE", &set_console },
|
||||
#endif
|
||||
#if !defined (KSR28)
|
||||
{ UNIT_UC, 0, "lower case", "LC", NULL },
|
||||
{ UNIT_UC, UNIT_UC, "upper case", "UC", NULL },
|
||||
#endif
|
||||
{ 0 } };
|
||||
|
||||
DEVICE tto_dev = {
|
||||
"TTO", &tto_unit, tto_reg, NULL,
|
||||
"TTO", &tto_unit, tto_reg, tto_mod,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &tto_reset,
|
||||
NULL, NULL, NULL };
|
||||
|
@ -280,14 +308,16 @@ DEVICE tto_dev = {
|
|||
|
||||
int32 clk (int32 pulse, int32 AC)
|
||||
{
|
||||
if (pulse == 001) return (int_req & INT_CLK)? IOT_SKP + AC: AC; /* CLSF */
|
||||
if (pulse == 004) clk_reset (&clk_dev); /* CLOF */
|
||||
else if (pulse == 044) { /* CLON */
|
||||
int_req = int_req & ~INT_CLK; /* clear flag */
|
||||
clk_state = 1; /* clock on */
|
||||
if (!sim_is_active (&clk_unit)) /* already on? */
|
||||
sim_activate (&clk_unit, /* start */
|
||||
sim_rtc_init (clk_unit.wait)); } /* init calibr */
|
||||
if (pulse & 001) { /* CLSF */
|
||||
if (int_req & INT_CLK) AC = AC | IOT_SKP; }
|
||||
if (pulse & 004) { /* CLON/CLOF */
|
||||
if (pulse & 040) { /* CLON */
|
||||
int_req = int_req & ~INT_CLK; /* clear flag */
|
||||
clk_state = 1; /* clock on */
|
||||
if (!sim_is_active (&clk_unit)) /* already on? */
|
||||
sim_activate (&clk_unit, /* start, calibr */
|
||||
sim_rtc_init (clk_unit.wait)); }
|
||||
else clk_reset (&clk_dev); } /* CLOF */
|
||||
return AC;
|
||||
}
|
||||
|
||||
|
@ -335,10 +365,11 @@ return ((int_req & INT_CLK)? IOS_CLK: 0) |
|
|||
|
||||
int32 ptr (int32 pulse, int32 AC)
|
||||
{
|
||||
if (pulse == 001) return (int_req & INT_PTR)? IOT_SKP + AC: AC; /* RSF */
|
||||
if (pulse & 001) { /* RSF */
|
||||
if (int_req & INT_PTR) AC = AC | IOT_SKP; }
|
||||
if (pulse & 002) { /* RRB, RCF */
|
||||
int_req = int_req & ~INT_PTR; /* clear done */
|
||||
AC = ptr_unit.buf; } /* return buffer */
|
||||
AC = AC | ptr_unit.buf; } /* return buffer */
|
||||
if (pulse & 004) { /* RSA, RSB */
|
||||
ptr_state = (pulse & 040)? 18: 0; /* set mode */
|
||||
int_req = int_req & ~INT_PTR; /* clear done */
|
||||
|
@ -587,7 +618,8 @@ return SCPE_ARG;
|
|||
|
||||
int32 ptp (int32 pulse, int32 AC)
|
||||
{
|
||||
if (pulse == 001) return (int_req & INT_PTP)? IOT_SKP + AC: AC; /* PSF */
|
||||
if (pulse & 001) { /* PSF */
|
||||
if (int_req & INT_PTP) AC = AC | IOT_SKP; }
|
||||
if (pulse & 002) int_req = int_req & ~INT_PTP; /* PCF */
|
||||
if (pulse & 004) { /* PSA, PSB, PLS */
|
||||
int_req = int_req & ~INT_PTP; /* clear flag */
|
||||
|
@ -648,10 +680,11 @@ return detach_unit (uptr);
|
|||
|
||||
int32 tti (int32 pulse, int32 AC)
|
||||
{
|
||||
if (pulse == 001) return (int_req & INT_TTI)? IOT_SKP + AC: AC; /* KSF */
|
||||
if (pulse == 002) { /* KRB */
|
||||
if (pulse & 001) { /* KSF */
|
||||
if (int_req & INT_TTI) AC = AC | IOT_SKP; }
|
||||
if (pulse & 002) { /* KRB */
|
||||
int_req = int_req & ~INT_TTI; /* clear flag */
|
||||
return tti_unit.buf & TTI_MASK; } /* return buffer */
|
||||
AC = AC | tti_unit.buf & TTI_MASK; } /* return buffer */
|
||||
return AC;
|
||||
}
|
||||
|
||||
|
@ -679,7 +712,11 @@ else { if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp;
|
|||
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp; /* no char or error? */
|
||||
temp = temp & 0177;
|
||||
if ((tti_unit.flags & UNIT_UC) && islower (temp)) temp = toupper (temp);
|
||||
if (tti_unit.flags & UNIT_HDX) sim_putchar (temp);
|
||||
if ((tti_unit.flags & UNIT_HDX) &&
|
||||
(!(tto_unit.flags & UNIT_UC) ||
|
||||
((temp >= 007) && (temp <= 0137)))) {
|
||||
sim_putcons (temp, uptr);
|
||||
tto_unit.pos = tto_unit.pos + 1; }
|
||||
tti_unit.buf = temp | 0200; /* got char */
|
||||
#endif
|
||||
int_req = int_req | INT_TTI; /* set flag */
|
||||
|
@ -694,6 +731,9 @@ t_stat tti_reset (DEVICE *dptr)
|
|||
tti_unit.buf = 0; /* clear buffer */
|
||||
tti_state = 0; /* clear state */
|
||||
int_req = int_req & ~INT_TTI; /* clear flag */
|
||||
#if defined (TTY1)
|
||||
if (tti_unit.flags & UNIT_CONS) /* if active cons */
|
||||
#endif
|
||||
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
@ -702,7 +742,8 @@ return SCPE_OK;
|
|||
|
||||
int32 tto (int32 pulse, int32 AC)
|
||||
{
|
||||
if (pulse == 001) return (int_req & INT_TTO)? IOT_SKP + AC: AC; /* TSF */
|
||||
if (pulse & 001) { /* TSF */
|
||||
if (int_req & INT_TTO) AC = AC | IOT_SKP; }
|
||||
if (pulse & 002) int_req = int_req & ~INT_TTO; /* clear flag */
|
||||
if (pulse & 004) { /* load buffer */
|
||||
sim_activate (&tto_unit, tto_unit.wait); /* activate unit */
|
||||
|
@ -728,8 +769,11 @@ out = tto_trans[tto_unit.buf + tto_state]; /* translate */
|
|||
#else
|
||||
out = tto_unit.buf & 0177; /* ASCII... */
|
||||
#endif
|
||||
if ((temp = sim_putchar (out)) != SCPE_OK) return temp;
|
||||
tto_unit.pos = tto_unit.pos + 1;
|
||||
if (!(tto_unit.flags & UNIT_UC) ||
|
||||
((out >= 007) && (out <= 0137))) {
|
||||
temp = sim_putcons (out, uptr);
|
||||
if (temp != SCPE_OK) return temp;
|
||||
tto_unit.pos = tto_unit.pos + 1; }
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -741,5 +785,8 @@ tto_unit.buf = 0; /* clear buffer */
|
|||
tto_state = 0; /* clear state */
|
||||
int_req = int_req & ~INT_TTO; /* clear flag */
|
||||
sim_cancel (&tto_unit); /* deactivate unit */
|
||||
#if defined (TTY1)
|
||||
tto_unit.filebuf = tto_consout;
|
||||
#endif
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
|
79
pdp18b_sys.c
79
pdp18b_sys.c
|
@ -23,6 +23,8 @@
|
|||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
27-May-01 RMS Added second Teletype support
|
||||
18-May-01 RMS Added PDP-9,-15 API IOT's
|
||||
12-May-01 RMS Fixed bug in RIM loaders
|
||||
14-Mar-01 RMS Added extension detection of RIM format tapes
|
||||
21-Jan-01 RMS Added DECtape support
|
||||
|
@ -39,6 +41,7 @@
|
|||
extern DEVICE cpu_dev;
|
||||
extern DEVICE ptr_dev, ptp_dev;
|
||||
extern DEVICE tti_dev, tto_dev;
|
||||
extern UNIT tti_unit, tto_unit;
|
||||
extern DEVICE clk_dev;
|
||||
extern DEVICE lpt_dev;
|
||||
#if defined (DRM)
|
||||
|
@ -56,6 +59,10 @@ extern DEVICE mt_dev;
|
|||
#if defined (DTA)
|
||||
extern DEVICE dt_dev;
|
||||
#endif
|
||||
#if defined (TTY1)
|
||||
extern DEVICE tti1_dev, tto1_dev;
|
||||
extern UNIT tti1_unit, tto1_unit;
|
||||
#endif
|
||||
extern UNIT cpu_unit;
|
||||
extern REG cpu_reg[];
|
||||
extern int32 M[];
|
||||
|
@ -87,7 +94,8 @@ REG *sim_PC = &cpu_reg[0];
|
|||
int32 sim_emax = 3;
|
||||
|
||||
DEVICE *sim_devices[] = { &cpu_dev,
|
||||
&ptr_dev, &ptp_dev, &tti_dev, &tto_dev,
|
||||
&ptr_dev, &ptp_dev,
|
||||
&tti_dev, &tto_dev,
|
||||
&clk_dev, &lpt_dev,
|
||||
#if defined (DRM)
|
||||
&drm_dev,
|
||||
|
@ -103,15 +111,28 @@ DEVICE *sim_devices[] = { &cpu_dev,
|
|||
#endif
|
||||
#if defined (MTA)
|
||||
&mt_dev,
|
||||
#endif
|
||||
#if defined (TTY1)
|
||||
&tti1_dev, &tto1_dev,
|
||||
#endif
|
||||
NULL };
|
||||
|
||||
#if defined (TTY1)
|
||||
UNIT *sim_consoles[] = {
|
||||
&tti_unit, &tto_unit,
|
||||
&tti1_unit, &tto1_unit,
|
||||
NULL };
|
||||
#else
|
||||
UNIT *sim_consoles = NULL;
|
||||
#endif
|
||||
|
||||
const char *sim_stop_messages[] = {
|
||||
"Unknown error",
|
||||
"Undefined instruction",
|
||||
"HALT instruction",
|
||||
"Breakpoint",
|
||||
"Nested XCT's" };
|
||||
"Nested XCT's",
|
||||
"Invalid API interrupt" };
|
||||
|
||||
/* Binary loader */
|
||||
|
||||
|
@ -279,7 +300,7 @@ static const char *opcode[] = {
|
|||
"XCT", "ISZ", "AND", "SAD",
|
||||
"JMP",
|
||||
|
||||
#if defined (PDP15) /* mem ref ind */
|
||||
#if defined (PDP9) || defined (PDP15) /* mem ref ind */
|
||||
"CAL*", "DAC*", "JMS*", "DZM*", /* normal */
|
||||
"LAC*", "XOR*", "ADD*", "TAD*",
|
||||
"XCT*", "ISZ*", "AND*", "SAD*",
|
||||
|
@ -346,26 +367,34 @@ static const char *opcode[] = {
|
|||
"MTTR", "MTCR", "MTSF", "MTRC", "MTAF",
|
||||
"MTRS", "MTGO", "MTCM", "MTLC",
|
||||
#endif
|
||||
#if defined (DTA)
|
||||
#if defined (DTA) /* TC02/TC15 */
|
||||
"DTCA", "DTRA", "DTXA", "DTLA",
|
||||
"DTEF", "DTRB", "DTDF",
|
||||
#endif
|
||||
#if defined (TTY1)
|
||||
"KSF1", "KRB1",
|
||||
"TSF1", "TCF1", "TLS1", "TCF1!TLS1",
|
||||
#endif
|
||||
#if defined (PDP7)
|
||||
"ITON", "TTS", "SKP7", "CAF",
|
||||
"SEM", "EEM", "EMIR", "LEM",
|
||||
#elif defined (PDP9)
|
||||
"PFSF", "TTS", "SKP7", "CAF",
|
||||
"DBR", "SEM", "EEM", "LEM",
|
||||
"MPSK", "MPSNE", "MPCV", "MPEU",
|
||||
"MPLD", "MPCNE",
|
||||
#endif
|
||||
#if defined (PDP9)
|
||||
"SKP7", "SEM", "EEM", "LEM",
|
||||
"LPDI", "LPEI",
|
||||
#elif defined (PDP15)
|
||||
"PFSF", "TTS", "SPCO", "CAF",
|
||||
"DBR", "SKP15", "RES",
|
||||
#endif
|
||||
#if defined (PDP15)
|
||||
"SPCO", "SKP15", "RES",
|
||||
"SBA", "DBA", "EBA",
|
||||
"AAS", "PAX", "PAL", "AAC",
|
||||
"PXA", "AXS", "PXL", "PLA",
|
||||
"PLX", "CLAC","CLX", "CLLR", "AXR",
|
||||
#endif
|
||||
#if defined (PDP9) || defined (PDP15)
|
||||
"MPSK", "MPSNE", "MPCV", "MPEU",
|
||||
"MPLD", "MPCNE", "PFSF",
|
||||
"TTS", "CAF", "DBK", "DBR",
|
||||
"SPI", "RPL", "ISA",
|
||||
#endif
|
||||
"IOT", /* general */
|
||||
|
||||
|
@ -493,22 +522,30 @@ static const int32 opc_val[] = {
|
|||
0707541+I_NPI, 0707552+I_NPN, 0707544+I_NPI, 0707545+I_NPI,
|
||||
0707561+I_NPI, 0707572+I_NPN, 0707601+I_NPI,
|
||||
#endif
|
||||
#if defined (TTY1)
|
||||
0704101+I_NPI, 0704112+I_NPN,
|
||||
0704001+I_NPI, 0704002+I_NPI, 0704004+I_NPI, 0704006+I_NPI,
|
||||
#endif
|
||||
#if defined (PDP7)
|
||||
0703201+I_NPI, 0703301+I_NPI, 0703341+I_NPI, 0703302+I_NPI,
|
||||
0707701+I_NPI, 0707702+I_NPI, 0707742+I_NPI, 0707704+I_NPI,
|
||||
#elif defined (PDP9)
|
||||
0700062+I_NPI, 0703301+I_NPI, 0703341+I_NPI, 0703302+I_NPI,
|
||||
0703344+I_NPI, 0707701+I_NPI, 0707702+I_NPI, 0707704+I_NPI,
|
||||
0701701+I_NPI, 0701741+I_NPI, 0701702+I_NPI, 0701742+I_NPI,
|
||||
0701704+I_NPI, 0701644+I_NPI,
|
||||
#endif
|
||||
#if defined (PDP9)
|
||||
0703341+I_NPI, 0707701+I_NPI, 0707702+I_NPI, 0707704+I_NPI,
|
||||
0706504+I_NPI, 0706604+I_NPI,
|
||||
#elif defined (PDP15)
|
||||
0700062+I_NPI, 0703301+I_NPI, 0703341+I_NPI, 0703302+I_NPI,
|
||||
0703344+I_NPI, 0707741+I_NPI, 0707742+I_NPI,
|
||||
#endif
|
||||
#if defined (PDP15)
|
||||
0703341+I_NPI, 0707741+I_NPI, 0707742+I_NPI,
|
||||
0707761+I_NPI, 0707762+I_NPI, 0707764+I_NPI,
|
||||
0720000+I_XR9, 0721000+I_XR, 0722000+I_XR, 0723000+I_XR9,
|
||||
0724000+I_XR, 0725000+I_XR9, 0726000+I_XR, 0730000+I_XR,
|
||||
0731000+I_XR, 0734000+I_XR, 0735000+I_XR, 0736000+I_XR, 0737000+I_XR9,
|
||||
#endif
|
||||
#if defined (PDP9) || defined (PDP15)
|
||||
0701701+I_NPI, 0701741+I_NPI, 0701702+I_NPI, 0701742+I_NPI,
|
||||
0701704+I_NPI, 0701744+I_NPI, 0703201+I_NPI,
|
||||
0703301+I_NPI, 0703302+I_NPI, 0703304+I_NPI, 0703344+I_NPI,
|
||||
0705501+I_NPI, 0705512+I_NPN, 0705504+I_NPI,
|
||||
#endif
|
||||
0700000+I_IOT,
|
||||
|
||||
|
@ -785,6 +822,8 @@ case I_V_MRF: /* mem ref */
|
|||
#else
|
||||
dmask = 017777;
|
||||
cptr = get_glyph (cptr, gbuf, 0); /* get next field */
|
||||
#endif
|
||||
#if defined (PDP4) || defined (PDP7)
|
||||
if (strcmp (gbuf, "I") == 0) { /* indirect? */
|
||||
val[0] = val[0] | 020000;
|
||||
cptr = get_glyph (cptr, gbuf, 0); }
|
||||
|
|
190
pdp18b_tt1.c
Normal file
190
pdp18b_tt1.c
Normal file
|
@ -0,0 +1,190 @@
|
|||
/* pdp18b_tt1.c: 18b PDP's second Teletype
|
||||
|
||||
Copyright (c) 1993-2001, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
tti1 keyboard
|
||||
tto1 teleprinter
|
||||
|
||||
10-Jun-01 RMS Cleaned up IOT decoding to reflect hardware
|
||||
*/
|
||||
|
||||
#include "pdp18b_defs.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#define UNIT_V_UC (UNIT_V_UF + 0) /* UC only */
|
||||
#define UNIT_UC (1 << UNIT_V_UC)
|
||||
|
||||
extern int32 int_req, saved_PC;
|
||||
t_stat tti1_svc (UNIT *uptr);
|
||||
t_stat tto1_svc (UNIT *uptr);
|
||||
t_stat tti1_reset (DEVICE *dptr);
|
||||
t_stat tto1_reset (DEVICE *dptr);
|
||||
extern t_stat sim_poll_kbd (void);
|
||||
extern t_stat sim_putchar (int32 out);
|
||||
static uint8 tto1_consout[CONS_SIZE];
|
||||
|
||||
/* TTI1 data structures
|
||||
|
||||
tti1_dev TTI1 device descriptor
|
||||
tti1_unit TTI1 unit
|
||||
tto1_mod TTI1 modifier list
|
||||
tti1_reg TTI1 register list
|
||||
*/
|
||||
|
||||
UNIT tti1_unit = { UDATA (&tti1_svc, UNIT_UC, 0), KBD_POLL_WAIT };
|
||||
|
||||
REG tti1_reg[] = {
|
||||
{ ORDATA (BUF, tti1_unit.buf, 8) },
|
||||
{ FLDATA (INT, int_req, INT_V_TTI1) },
|
||||
{ FLDATA (DONE, int_req, INT_V_TTI1) },
|
||||
{ FLDATA (UC, tti1_unit.flags, UNIT_V_UC), REG_HRO },
|
||||
{ DRDATA (POS, tti1_unit.pos, 31), PV_LEFT },
|
||||
{ DRDATA (TIME, tti1_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||
{ FLDATA (CFLAG, tti1_unit.flags, UNIT_V_CONS), REG_HRO },
|
||||
{ NULL } };
|
||||
|
||||
MTAB tti1_mod[] = {
|
||||
{ UNIT_CONS, 0, "inactive", NULL, NULL },
|
||||
{ UNIT_CONS, UNIT_CONS, "active console", "CONSOLE", &set_console },
|
||||
{ UNIT_UC, 0, "lower case", "LC", NULL },
|
||||
{ UNIT_UC, UNIT_UC, "upper case", "UC", NULL },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE tti1_dev = {
|
||||
"TTI1", &tti1_unit, tti1_reg, tti1_mod,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &tti1_reset,
|
||||
NULL, NULL, NULL };
|
||||
|
||||
/* TTO1 data structures
|
||||
|
||||
tto1_dev TTO1 device descriptor
|
||||
tto1_unit TTO1 unit
|
||||
tto1_mod TTO1 modifier list
|
||||
tto1_reg TTO1 register list
|
||||
*/
|
||||
|
||||
UNIT tto1_unit = { UDATA (&tto1_svc, UNIT_UC, 0), SERIAL_OUT_WAIT };
|
||||
|
||||
REG tto1_reg[] = {
|
||||
{ ORDATA (BUF, tto1_unit.buf, 8) },
|
||||
{ FLDATA (INT, int_req, INT_V_TTO1) },
|
||||
{ FLDATA (DONE, int_req, INT_V_TTO1) },
|
||||
{ DRDATA (POS, tto1_unit.pos, 31), PV_LEFT },
|
||||
{ DRDATA (TIME, tto1_unit.wait, 24), PV_LEFT },
|
||||
{ BRDATA (CONSOUT, tto1_consout, 8, 8, CONS_SIZE), REG_HIDDEN },
|
||||
{ FLDATA (CFLAG, tto1_unit.flags, UNIT_V_CONS), REG_HRO },
|
||||
{ NULL } };
|
||||
|
||||
MTAB tto1_mod[] = {
|
||||
{ UNIT_CONS, 0, "inactive", NULL, NULL },
|
||||
{ UNIT_CONS, UNIT_CONS, "active console", "CONSOLE", &set_console },
|
||||
{ UNIT_UC, 0, "lower case", "LC", NULL },
|
||||
{ UNIT_UC, UNIT_UC, "upper case", "UC", NULL },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE tto1_dev = {
|
||||
"TTO1", &tto1_unit, tto1_reg, tto1_mod,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &tto1_reset,
|
||||
NULL, NULL, NULL };
|
||||
|
||||
/* Terminal input: IOT routine */
|
||||
|
||||
int32 tti1 (int32 pulse, int32 AC)
|
||||
{
|
||||
if (pulse & 001) { /* KSF1 */
|
||||
if (int_req & INT_TTI1) AC = AC | IOT_SKP; }
|
||||
if (pulse & 002) { /* KRB1 */
|
||||
int_req = int_req & ~INT_TTI1; /* clear flag */
|
||||
AC= AC | tti1_unit.buf; } /* return buffer */
|
||||
return AC;
|
||||
}
|
||||
|
||||
/* Unit service */
|
||||
|
||||
t_stat tti1_svc (UNIT *uptr)
|
||||
{
|
||||
int32 temp;
|
||||
|
||||
sim_activate (&tti1_unit, tti1_unit.wait); /* continue poll */
|
||||
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp; /* no char or error? */
|
||||
temp = temp & 0177;
|
||||
if ((tti1_unit.flags & UNIT_UC) && islower (temp)) temp = toupper (temp);
|
||||
tti1_unit.buf = temp | 0200; /* got char */
|
||||
int_req = int_req | INT_TTI1; /* set flag */
|
||||
tti1_unit.pos = tti1_unit.pos + 1;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat tti1_reset (DEVICE *dptr)
|
||||
{
|
||||
tti1_unit.buf = 0; /* clear buffer */
|
||||
int_req = int_req & ~INT_TTI; /* clear flag */
|
||||
if (tti1_unit.flags & UNIT_CONS) /* if active console */
|
||||
sim_activate (&tti1_unit, tti1_unit.wait); /* activate unit */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Terminal output: IOT routine */
|
||||
|
||||
int32 tto1 (int32 pulse, int32 AC)
|
||||
{
|
||||
if (pulse & 001) { /* TSF */
|
||||
if (int_req & INT_TTO1) AC = AC | IOT_SKP; }
|
||||
if (pulse & 002) int_req = int_req & ~INT_TTO1; /* clear flag */
|
||||
if (pulse & 004) { /* load buffer */
|
||||
sim_activate (&tto1_unit, tto1_unit.wait); /* activate unit */
|
||||
tto1_unit.buf = AC & 0377; } /* load buffer */
|
||||
return AC;
|
||||
}
|
||||
|
||||
/* Unit service */
|
||||
|
||||
t_stat tto1_svc (UNIT *uptr)
|
||||
{
|
||||
int32 out, temp;
|
||||
|
||||
int_req = int_req | INT_TTO1; /* set flag */
|
||||
out = tto1_unit.buf & 0177;
|
||||
if (!(tto1_unit.flags & UNIT_UC) ||
|
||||
((out >= 007) && (out <= 0137))) {
|
||||
temp = sim_putcons (out, uptr);
|
||||
if (temp != SCPE_OK) return temp;
|
||||
tto1_unit.pos = tto1_unit.pos + 1; }
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat tto1_reset (DEVICE *dptr)
|
||||
{
|
||||
tto1_unit.buf = 0; /* clear buffer */
|
||||
int_req = int_req & ~INT_TTO1; /* clear flag */
|
||||
sim_cancel (&tto1_unit); /* deactivate unit */
|
||||
tto1_unit.filebuf = tto1_consout; /* set buf pointer */
|
||||
return SCPE_OK;
|
||||
}
|
|
@ -28,6 +28,7 @@
|
|||
tti keyboard
|
||||
tto teleprinter
|
||||
|
||||
10-Jun-01 RMS Fixed comment
|
||||
30-Oct-00 RMS Standardized device naming
|
||||
*/
|
||||
|
||||
|
@ -260,7 +261,7 @@ static const int32 boot_rom[] = {
|
|||
0327776, /* dio x */
|
||||
0107776, /* xct x */
|
||||
0730002, /* rpb + wait */
|
||||
0760400, /* x, halt /
|
||||
0760400, /* x, halt */
|
||||
0607772 /* jmp r */
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
27-May-01 RMS Added multiconsole support
|
||||
14-Mar-01 RMS Revised load/dump interface (again)
|
||||
30-Oct-00 RMS Added support for examine to file
|
||||
27-Oct-98 RMS V2.4 load interface
|
||||
|
@ -50,6 +51,7 @@ extern int32 sc_map[];
|
|||
sim_PC pointer to saved PC register descriptor
|
||||
sim_emax number of words for examine
|
||||
sim_devices array of pointers to simulated devices
|
||||
sim_consoles array of pointers to consoles (if more than one)
|
||||
sim_stop_messages array of pointers to stop messages
|
||||
sim_load binary loader
|
||||
*/
|
||||
|
@ -64,6 +66,8 @@ DEVICE *sim_devices[] = { &cpu_dev,
|
|||
&ptr_dev, &ptp_dev, &tti_dev, &tto_dev,
|
||||
&lpt_dev, NULL };
|
||||
|
||||
UNIT *sim_consoles = NULL;
|
||||
|
||||
const char *sim_stop_messages[] = {
|
||||
"Unknown error",
|
||||
"Undefined instruction",
|
||||
|
@ -98,11 +102,11 @@ int32 origin, val;
|
|||
if ((*cptr != 0) || (flag != 0)) return SCPE_ARG;
|
||||
for (;;) {
|
||||
if ((val = getword (fileref)) < 0) return SCPE_FMT;
|
||||
if ((val & 0770000) == 0240000) { /* DAC? */
|
||||
if ((val & 0770000) == 0240000) { /* DAC? */
|
||||
origin = val & 07777;
|
||||
if ((val = getword (fileref)) < 0) return SCPE_FMT;
|
||||
if (MEM_ADDR_OK (origin)) M[origin++] = val; }
|
||||
else if ((val & 0770000) == 0600000) {
|
||||
else if ((val & 0770000) == 0600000) { /* JMP? */
|
||||
PC = val & 007777;
|
||||
return SCPE_OK; } }
|
||||
return SCPE_FMT; /* error */
|
||||
|
|
17
pdp8_cpu.c
17
pdp8_cpu.c
|
@ -25,6 +25,7 @@
|
|||
|
||||
cpu central processor
|
||||
|
||||
07-Jun-01 RMS Fixed bug in JMS to non-existent memory
|
||||
25-Apr-01 RMS Added device enable/disable support
|
||||
18-Mar-01 RMS Added DF32 support
|
||||
05-Mar-01 RMS Added clock calibration support
|
||||
|
@ -345,6 +346,10 @@ sim_interval = sim_interval - 1;
|
|||
jump calculations. Data calculations return a full 15b extended
|
||||
address, jump calculations a 12b field-relative address.
|
||||
|
||||
Autoindex calculations always occur within the same field as the
|
||||
instruction fetch. The field must exist; otherwise, the instruction
|
||||
fetched would be 0000, and indirect addressing could not occur.
|
||||
|
||||
Note that MA contains IF'PC.
|
||||
*/
|
||||
|
||||
|
@ -408,12 +413,12 @@ case 007: /* TAD, indir, curr */
|
|||
|
||||
case 010: /* ISZ, dir, zero */
|
||||
ZERO_PAGE;
|
||||
M[MA] = MB = (M[MA] + 1) & 07777;
|
||||
M[MA] = MB = (M[MA] + 1) & 07777; /* field must exist */
|
||||
if (MB == 0) PC = (PC + 1) & 07777;
|
||||
break;
|
||||
case 011: /* ISZ, dir, curr */
|
||||
CURR_PAGE;
|
||||
M[MA] = MB = (M[MA] + 1) & 07777;
|
||||
M[MA] = MB = (M[MA] + 1) & 07777; /* field must exist */
|
||||
if (MB == 0) PC = (PC + 1) & 07777;
|
||||
break;
|
||||
case 012: /* ISZ, indir, zero */
|
||||
|
@ -461,13 +466,17 @@ case 017: /* DCA, indir, curr */
|
|||
case 020: /* JMS, dir, zero */
|
||||
ZERO_PAGE_J;
|
||||
CHANGE_FIELD;
|
||||
M[IF | MA] = old_PC = PC;
|
||||
MA = IF | MA;
|
||||
old_PC = PC;
|
||||
if (MEM_ADDR_OK (MA)) M[MA] = PC;
|
||||
PC = (MA + 1) & 07777;
|
||||
break;
|
||||
case 021: /* JMS, dir, curr */
|
||||
CURR_PAGE_J;
|
||||
CHANGE_FIELD;
|
||||
M[IF | MA] = old_PC = PC;
|
||||
MA = IF | MA;
|
||||
old_PC = PC;
|
||||
if (MEM_ADDR_OK (MA)) M[MA] = PC;
|
||||
PC = (MA + 1) & 07777;
|
||||
break;
|
||||
case 022: /* JMS, indir, zero */
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
19-Mar-01 RMS Added disk monitor bootstrap, fixed IOT decoding
|
||||
15-Feb-01 RMS Fixed 3 cycle data break sequence
|
||||
14-Apr-99 RMS Changed t_addr to unsigned
|
||||
30-Mar-98 RMS Fixed bug in RF bootstrap.
|
||||
30-Mar-98 RMS Fixed bug in RF bootstrap
|
||||
|
||||
The RF08 is a head-per-track disk. It uses the three cycle data break
|
||||
facility. To minimize overhead, the entire RF08 is buffered in memory.
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
27-May-01 RMS Added multiconsole support
|
||||
18-Mar-01 RMS Added DF32 support
|
||||
14-Mar-01 RMS Added extension detection of RIM binary tapes
|
||||
15-Feb-01 RMS Added DECtape support
|
||||
|
@ -53,6 +54,7 @@ extern int32 sim_switches;
|
|||
sim_PC pointer to saved PC register descriptor
|
||||
sim_emax maximum number of words for examine/deposit
|
||||
sim_devices array of pointers to simulated devices
|
||||
sim_consoles array of pointers to consoles (if more than one)
|
||||
sim_stop_messages array of pointers to stop messages
|
||||
sim_load binary loader
|
||||
*/
|
||||
|
@ -73,6 +75,8 @@ DEVICE *sim_devices[] = {
|
|||
&dt_dev, &mt_dev,
|
||||
NULL };
|
||||
|
||||
UNIT *sim_consoles = NULL;
|
||||
|
||||
const char *sim_stop_messages[] = {
|
||||
"Unknown error",
|
||||
"Unimplemented instruction",
|
||||
|
|
380
scp.c
380
scp.c
|
@ -23,6 +23,10 @@
|
|||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
12-Jun-01 RMS Fixed bug in big-endian I/O (found by Dave Conroy)
|
||||
27-May-01 RMS Added multiple console support
|
||||
16-May-01 RMS Added logging
|
||||
15-May-01 RMS Added features from Tim Litt
|
||||
12-May-01 RMS Fixed missing return in disable_cmd
|
||||
25-Mar-01 RMS Added ENABLE/DISABLE
|
||||
14-Mar-01 RMS Revised LOAD/DUMP interface (again)
|
||||
|
@ -53,7 +57,6 @@
|
|||
|
||||
#define SCP 1 /* defining module */
|
||||
#include "sim_defs.h"
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <ctype.h>
|
||||
#define EX_D 0 /* deposit */
|
||||
|
@ -83,6 +86,7 @@
|
|||
|
||||
extern char sim_name[];
|
||||
extern DEVICE *sim_devices[];
|
||||
extern UNIT *sim_consoles[];
|
||||
extern REG *sim_PC;
|
||||
extern char *sim_stop_messages[];
|
||||
extern t_stat sim_instr (void);
|
||||
|
@ -96,6 +100,7 @@ extern t_stat ttinit (void);
|
|||
extern t_stat ttrunstate (void);
|
||||
extern t_stat ttcmdstate (void);
|
||||
extern t_stat ttclose (void);
|
||||
extern t_stat sim_putchar (int32 out);
|
||||
extern uint32 sim_os_msec (void);
|
||||
UNIT *sim_clock_queue = NULL;
|
||||
int32 sim_interval = 0;
|
||||
|
@ -106,7 +111,8 @@ static uint32 sim_rtime;
|
|||
static int32 noqueue_time;
|
||||
volatile int32 stop_cpu = 0;
|
||||
t_value *sim_eval = NULL;
|
||||
int32 sim_end = 1; /* 1 = little, 0 = big */
|
||||
int32 sim_end = 1; /* 1 = little */
|
||||
FILE *sim_log = NULL; /* log file */
|
||||
unsigned char sim_flip[FLIP_SIZE];
|
||||
|
||||
#define print_val(a,b,c,d) fprint_val (stdout, (a), (b), (c), (d))
|
||||
|
@ -153,6 +159,8 @@ void put_rval (REG *rptr, int idx, t_value val);
|
|||
t_stat get_aval (t_addr addr, DEVICE *dptr, UNIT *uptr);
|
||||
t_value strtotv (char *inptr, char **endptr, int radix);
|
||||
t_stat fprint_val (FILE *stream, t_value val, int rdx, int wid, int fmt);
|
||||
void fprint_stopped (FILE *stream, t_stat r);
|
||||
void sim_chkcons (void);
|
||||
char *read_line (char *ptr, int size, FILE *stream);
|
||||
DEVICE *find_dev (char *ptr);
|
||||
DEVICE *find_unit (char *ptr, int32 *iptr);
|
||||
|
@ -201,7 +209,9 @@ const char *scp_error_messages[] = {
|
|||
"Console terminal setup error",
|
||||
"Subscript out of range",
|
||||
"Command not allowed",
|
||||
"Unit disabled"
|
||||
"Unit disabled",
|
||||
"Logging enabled",
|
||||
"Logging disabled"
|
||||
};
|
||||
|
||||
const size_t size_map[] = { sizeof (int8),
|
||||
|
@ -255,6 +265,8 @@ t_stat add_cmd (int flag, char *ptr);
|
|||
t_stat remove_cmd (int flag, char *ptr);
|
||||
t_stat enable_cmd (int flag, char *ptr);
|
||||
t_stat disable_cmd (int flag, char *ptr);
|
||||
t_stat log_cmd (int flag, char *ptr);
|
||||
t_stat nolog_cmd (int flag, char *ptr);
|
||||
t_stat help_cmd (int flag, char *ptr);
|
||||
|
||||
static CTAB cmd_table[] = {
|
||||
|
@ -284,12 +296,14 @@ static CTAB cmd_table[] = {
|
|||
{ "DISABLE", &disable_cmd, 0 },
|
||||
{ "ADD", &add_cmd, 0 },
|
||||
{ "REMOVE", &remove_cmd, 0 },
|
||||
{ "LOG", &log_cmd, 0 },
|
||||
{ "NOLOG", &nolog_cmd, 0 },
|
||||
{ "HELP", &help_cmd, 0 },
|
||||
{ NULL, NULL, 0 } };
|
||||
|
||||
/* Main command loop */
|
||||
|
||||
printf ("\n%s simulator V2.6\n", sim_name);
|
||||
printf ("\n%s simulator V2.6a\n", sim_name);
|
||||
end_test.i = 1; /* test endian-ness */
|
||||
sim_end = end_test.c[0];
|
||||
if (sim_emax <= 0) sim_emax = 1;
|
||||
|
@ -306,13 +320,14 @@ sim_time = sim_rtime = 0;
|
|||
noqueue_time = 0;
|
||||
sim_clock_queue = NULL;
|
||||
sim_is_running = 0;
|
||||
sim_log = NULL;
|
||||
if ((stat = reset_all (0)) != SCPE_OK) {
|
||||
printf ("Fatal simulator initialization error\n%s\n",
|
||||
scp_error_messages[stat - SCPE_BASE]);
|
||||
return 0; }
|
||||
|
||||
if ((argc > 1) && (argv[1] != NULL) &&
|
||||
((fpin = fopen (argv[1], "r")) != NULL)) { /* command file? */
|
||||
if ((argc > 1) && (argv[1] != NULL)) { /* cmd line arg? */
|
||||
if ((fpin = fopen (argv[1], "r")) != NULL) { /* cmd file open? */
|
||||
do { cptr = read_line (cbuf, CBUFSIZE, fpin);
|
||||
if (cptr == NULL) break; /* exit on eof */
|
||||
if (*cptr == 0) continue; /* ignore blank */
|
||||
|
@ -324,23 +339,28 @@ if ((argc > 1) && (argv[1] != NULL) &&
|
|||
if (stat >= SCPE_BASE)
|
||||
printf ("%s\n", scp_error_messages[stat - SCPE_BASE]);
|
||||
} while (stat != SCPE_EXIT); } /* end if cmd file */
|
||||
else printf ("Can't open file \"%s\"\n", argv[1]); } /* end if cmd arg */
|
||||
|
||||
do { printf ("sim> "); /* prompt */
|
||||
cptr = read_line (cbuf, CBUFSIZE, stdin); /* read command line */
|
||||
stat = SCPE_UNK;
|
||||
if (cptr == NULL) continue; /* ignore EOF */
|
||||
if (*cptr == 0) continue; /* ignore blank */
|
||||
if (sim_log) fprintf (sim_log, "sim> %s\n", cbuf); /* log cmd */
|
||||
cptr = get_glyph (cptr, gbuf, 0); /* get command glyph */
|
||||
for (i = 0; cmd_table[i].name != NULL; i++) {
|
||||
if (MATCH_CMD (gbuf, cmd_table[i].name) == 0) {
|
||||
stat = cmd_table[i].action (cmd_table[i].arg, cptr);
|
||||
break; } }
|
||||
if (stat >= SCPE_BASE)
|
||||
if (stat >= SCPE_BASE) { /* error? */
|
||||
printf ("%s\n", scp_error_messages[stat - SCPE_BASE]);
|
||||
if (sim_log) fprintf (sim_log, "%s\n",
|
||||
scp_error_messages[stat - SCPE_BASE]); }
|
||||
} while (stat != SCPE_EXIT);
|
||||
|
||||
detach_all (0);
|
||||
ttclose ();
|
||||
detach_all (0); /* close files */
|
||||
nolog_cmd (0, NULL); /* close log */
|
||||
ttclose (); /* close console */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -353,36 +373,45 @@ return SCPE_EXIT;
|
|||
|
||||
/* Help command */
|
||||
|
||||
void fprint_help (FILE *st)
|
||||
{
|
||||
fprintf (st, "r{eset} {ALL|<device>} reset simulator\n");
|
||||
fprintf (st, "e{xamine} <list> examine memory or registers\n");
|
||||
fprintf (st, "ie{xamine} <list> interactive examine memory or registers\n");
|
||||
fprintf (st, "d{eposit} <list> <val> deposit in memory or registers\n");
|
||||
fprintf (st, "id{eposit} <list> interactive deposit in memory or registers\n");
|
||||
fprintf (st, "l{oad} <file> {<args>} load binary file\n");
|
||||
fprintf (st, "du(mp) <file> {<args>} dump binary file\n");
|
||||
fprintf (st, "ru{n} {new PC} reset and start simulation\n");
|
||||
fprintf (st, "go {new PC} start simulation\n");
|
||||
fprintf (st, "c{ont} continue simulation\n");
|
||||
fprintf (st, "s{tep} {n} simulate n instructions\n");
|
||||
fprintf (st, "b{oot} <device>|<unit> bootstrap device\n");
|
||||
fprintf (st, "at{tach} <unit> <file> attach file to simulated unit\n");
|
||||
fprintf (st, "det{ach} <unit> detach file from simulated unit\n");
|
||||
fprintf (st, "sa{ve} <file> save simulator to file\n");
|
||||
fprintf (st, "rest{ore}|ge{t} <file> restore simulator from file\n");
|
||||
fprintf (st, "exi{t}|q{uit}|by{e} exit from simulation\n");
|
||||
fprintf (st, "set <unit> <val> set unit parameter\n");
|
||||
fprintf (st, "show <device> show device parameters\n");
|
||||
fprintf (st, "sh{ow} c{onfiguration} show configuration\n");
|
||||
fprintf (st, "sh{ow} m{odifiers} show modifiers\n");
|
||||
fprintf (st, "sh{ow} q{ueue} show event queue\n");
|
||||
fprintf (st, "sh{ow} t{ime} show simulated time\n");
|
||||
fprintf (st, "en{able} <device> enable device\n");
|
||||
fprintf (st, "di{sable} <device> disable device\n");
|
||||
fprintf (st, "ad{d} <unit> add unit to configuration\n");
|
||||
fprintf (st, "rem{ove} <unit> remove unit from configuration\n");
|
||||
fprintf (st, "log <file> enable logging to file\n");
|
||||
fprintf (st, "nolog disable logging\n");
|
||||
fprintf (st, "h{elp} type this message\n");
|
||||
return;
|
||||
}
|
||||
|
||||
t_stat help_cmd (int flag, char *cptr)
|
||||
{
|
||||
printf ("r{eset} {ALL|<device>} reset simulator\n");
|
||||
printf ("e{xamine} <list> examine memory or registers\n");
|
||||
printf ("ie{xamine} <list> interactive examine memory or registers\n");
|
||||
printf ("d{eposit} <list> <val> deposit in memory or registers\n");
|
||||
printf ("id{eposit} <list> interactive deposit in memory or registers\n");
|
||||
printf ("l{oad} <file> {<args>} load binary file\n");
|
||||
printf ("du(mp) <file> {<args>} dump binary file\n");
|
||||
printf ("ru{n} {new PC} reset and start simulation\n");
|
||||
printf ("go {new PC} start simulation\n");
|
||||
printf ("c{ont} continue simulation\n");
|
||||
printf ("s{tep} {n} simulate n instructions\n");
|
||||
printf ("b{oot} <device>|<unit> bootstrap device\n");
|
||||
printf ("at{tach} <unit> <file> attach file to simulated unit\n");
|
||||
printf ("det{ach} <unit> detach file from simulated unit\n");
|
||||
printf ("sa{ve} <file> save simulator to file\n");
|
||||
printf ("rest{ore}|ge{t} <file> restore simulator from file\n");
|
||||
printf ("exi{t}|q{uit}|by{e} exit from simulation\n");
|
||||
printf ("set <unit> <val> set unit parameter\n");
|
||||
printf ("show <device> show device parameters\n");
|
||||
printf ("sh{ow} c{onfiguration} show configuration\n");
|
||||
printf ("sh{ow} m{odifiers} show modifiers\n");
|
||||
printf ("sh{ow} q{ueue} show event queue\n");
|
||||
printf ("sh{ow} t{ime} show simulated time\n");
|
||||
printf ("en{able} <device> enable device\n");
|
||||
printf ("di{sable} <device> disable device\n");
|
||||
printf ("ad{d} <unit> add unit to configuration\n");
|
||||
printf ("rem{ove} <unit> remove unit from configuration\n");
|
||||
printf ("h{elp} type this message\n");
|
||||
fprint_help (stdout);
|
||||
if (sim_log) fprint_help (sim_log);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -441,13 +470,16 @@ return SCPE_OK;
|
|||
t_stat show_cmd (int flag, char *cptr)
|
||||
{
|
||||
int32 i;
|
||||
t_stat r;
|
||||
char gbuf[CBUFSIZE];
|
||||
DEVICE *dptr;
|
||||
t_stat show_config (int flag);
|
||||
t_stat show_queue (int flag);
|
||||
t_stat show_time (int flag);
|
||||
t_stat show_modifiers (int flag);
|
||||
t_stat show_device (DEVICE *dptr, int flag);
|
||||
|
||||
t_stat show_config (FILE *st, int flag);
|
||||
t_stat show_queue (FILE *st, int flag);
|
||||
t_stat show_time (FILE *st, int flag);
|
||||
t_stat show_modifiers (FILE *st, int flag);
|
||||
t_stat show_device (FILE *st, DEVICE *dptr, int flag);
|
||||
|
||||
static CTAB show_table[] = {
|
||||
{ "CONFIGURATION", &show_config, 0 },
|
||||
{ "DEVICES", &show_config, 1 },
|
||||
|
@ -460,110 +492,118 @@ GET_SWITCHES (cptr, gbuf); /* test for switches */
|
|||
cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */
|
||||
if (*cptr != 0) return SCPE_ARG; /* now eol? */
|
||||
for (i = 0; show_table[i].name != NULL; i++) { /* find command */
|
||||
if (MATCH_CMD (gbuf, show_table[i].name) == 0)
|
||||
return show_table[i].action (show_table[i].arg); }
|
||||
if (MATCH_CMD (gbuf, show_table[i].name) == 0) {
|
||||
r = show_table[i].action (stdout, show_table[i].arg);
|
||||
if (sim_log)
|
||||
show_table[i].action (sim_log, show_table[i].arg);
|
||||
return r; } }
|
||||
dptr = find_dev (gbuf); /* locate device */
|
||||
if (dptr == NULL) return SCPE_ARG; /* not found? */
|
||||
return show_device (dptr, 0);
|
||||
r = show_device (stdout, dptr, 0);
|
||||
if (sim_log) show_device (sim_log, dptr, 0);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Show processors */
|
||||
|
||||
t_stat show_device (DEVICE *dptr, int flag)
|
||||
t_stat show_device (FILE *st, DEVICE *dptr, int flag)
|
||||
{
|
||||
int32 j, ucnt;
|
||||
t_addr kval;
|
||||
UNIT *uptr;
|
||||
MTAB *mptr;
|
||||
|
||||
printf ("%s", dptr -> name); /* print dev name */
|
||||
fprintf (st, "%s", dptr -> name); /* print dev name */
|
||||
if (qdisable (dptr)) { /* disabled? */
|
||||
printf (", disabled\n");
|
||||
fprintf (st, ", disabled\n");
|
||||
return SCPE_OK; }
|
||||
for (j = ucnt = 0; j < dptr -> numunits; j++) { /* count units */
|
||||
uptr = (dptr -> units) + j;
|
||||
if (!(uptr -> flags & UNIT_DIS)) ucnt++; }
|
||||
if (dptr -> numunits == 0) printf ("\n");
|
||||
else { if (ucnt == 0) printf (", all units disabled\n");
|
||||
else if (ucnt > 1) printf (", %d units\n", ucnt);
|
||||
else if (flag) printf ("\n"); }
|
||||
if (dptr -> numunits == 0) fprintf (st, "\n");
|
||||
else { if (ucnt == 0) fprintf (st, ", all units disabled\n");
|
||||
else if (ucnt > 1) fprintf (st, ", %d units\n", ucnt);
|
||||
else if (flag) fprintf (st, "\n"); }
|
||||
if (flag) return SCPE_OK; /* dev only? */
|
||||
for (j = 0; j < dptr -> numunits; j++) {
|
||||
uptr = (dptr -> units) + j;
|
||||
kval = (uptr -> flags & UNIT_BINK)? 1024: 1000;
|
||||
if (uptr -> flags & UNIT_DIS) continue;
|
||||
if (ucnt > 1) printf (" unit %d", j);
|
||||
if (ucnt > 1) fprintf (st, " unit %d", j);
|
||||
if (uptr -> flags & UNIT_FIX) {
|
||||
if (uptr -> capac < kval)
|
||||
printf (", %d%s", uptr -> capac,
|
||||
fprintf (st, ", %d%s", uptr -> capac,
|
||||
((dptr -> dwidth / dptr -> aincr) > 8)? "W": "B");
|
||||
else printf (", %dK%s", uptr -> capac / kval,
|
||||
else fprintf (st, ", %dK%s", uptr -> capac / kval,
|
||||
((dptr -> dwidth / dptr -> aincr) > 8)? "W": "B"); }
|
||||
if (uptr -> flags & UNIT_ATT)
|
||||
printf (", attached to %s", uptr -> filename);
|
||||
else if (uptr -> flags & UNIT_ATTABLE) printf (", not attached");
|
||||
fprintf (st, ", attached to %s", uptr -> filename);
|
||||
else if (uptr -> flags & UNIT_ATTABLE)
|
||||
fprintf (st, ", not attached");
|
||||
if (dptr -> modifiers != NULL) {
|
||||
for (mptr = dptr -> modifiers; mptr -> mask != 0; mptr++) {
|
||||
if ((mptr -> pstring != NULL) &&
|
||||
((uptr -> flags & mptr -> mask) == mptr -> match))
|
||||
printf (", %s", mptr -> pstring); } }
|
||||
printf ("\n"); }
|
||||
fprintf (st, ", %s", mptr -> pstring); } }
|
||||
fprintf (st, "\n"); }
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat show_config (int flag)
|
||||
t_stat show_config (FILE *st, int flag)
|
||||
{
|
||||
int32 i;
|
||||
DEVICE *dptr;
|
||||
|
||||
printf ("%s simulator configuration\n\n", sim_name);
|
||||
fprintf (st, "%s simulator configuration\n\n", sim_name);
|
||||
for (i = 0; (dptr = sim_devices[i]) != NULL; i++)
|
||||
show_device (dptr, flag);
|
||||
show_device (st, dptr, flag);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat show_queue (int flag)
|
||||
t_stat show_queue (FILE *st, int flag)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
UNIT *uptr;
|
||||
int32 accum;
|
||||
|
||||
if (sim_clock_queue == NULL) {
|
||||
printf ("%s event queue empty, time = %-16.0f\n", sim_name, sim_time);
|
||||
fprintf (st, "%s event queue empty, time = %-16.0f\n",
|
||||
sim_name, sim_time);
|
||||
return SCPE_OK; }
|
||||
printf ("%s event queue status, time = %-16.0f\n", sim_name, sim_time);
|
||||
fprintf (st, "%s event queue status, time = %-16.0f\n",
|
||||
sim_name, sim_time);
|
||||
accum = 0;
|
||||
for (uptr = sim_clock_queue; uptr != NULL; uptr = uptr -> next) {
|
||||
if (uptr == &step_unit) printf (" Step timer");
|
||||
if (uptr == &step_unit) fprintf (st, " Step timer");
|
||||
else if ((dptr = find_dev_from_unit (uptr)) != NULL) {
|
||||
printf (" %s", dptr -> name);
|
||||
if (dptr -> numunits > 1) printf (" unit %d",
|
||||
fprintf (st, " %s", dptr -> name);
|
||||
if (dptr -> numunits > 1) fprintf (st, " unit %d",
|
||||
uptr - dptr -> units); }
|
||||
else printf (" Unknown");
|
||||
printf (" at %d\n", accum + uptr -> time);
|
||||
else fprintf (st, " Unknown");
|
||||
fprintf (st, " at %d\n", accum + uptr -> time);
|
||||
accum = accum + uptr -> time; }
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat show_time (int flag)
|
||||
t_stat show_time (FILE *st, int flag)
|
||||
{
|
||||
printf ("Time: %-16.0f\n", sim_time);
|
||||
fprintf (st, "Time: %-16.0f\n", sim_time);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat show_modifiers (int flag)
|
||||
t_stat show_modifiers (FILE *st, int flag)
|
||||
{
|
||||
int i, any;
|
||||
DEVICE *dptr;
|
||||
MTAB *mptr;
|
||||
|
||||
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) {
|
||||
any = 0;
|
||||
for (mptr = dptr -> modifiers; mptr && (mptr -> mask != 0); mptr++) {
|
||||
if (mptr -> mstring) {
|
||||
if (any++) printf (", %s", mptr -> mstring);
|
||||
else printf ("%s %s", dptr -> name, mptr -> mstring); } }
|
||||
if (any) printf ("\n"); }
|
||||
any = 0;
|
||||
for (mptr = dptr -> modifiers; mptr && (mptr -> mask != 0); mptr++) {
|
||||
if (mptr -> mstring) {
|
||||
if (any++) fprintf (st, ", %s", mptr -> mstring);
|
||||
else fprintf (st, "%s %s", dptr -> name, mptr -> mstring); } }
|
||||
if (any) fprintf (st, "\n"); }
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -668,6 +708,43 @@ uptr -> flags = uptr -> flags | UNIT_DIS; /* disable it */
|
|||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Logging commands
|
||||
|
||||
log filename open log file
|
||||
nolog close log file
|
||||
*/
|
||||
|
||||
t_stat log_cmd (int flag, char *cptr)
|
||||
{
|
||||
char gbuf[CBUFSIZE];
|
||||
|
||||
GET_SWITCHES (cptr, gbuf); /* test for switches */
|
||||
if (*cptr == 0) return (sim_log? SCPE_LOGON: SCPE_LOGOFF);
|
||||
cptr = get_glyph_nc (cptr, gbuf, 0); /* get file name */
|
||||
if (*cptr != 0) return SCPE_ARG; /* end of line? */
|
||||
nolog_cmd (0, NULL); /* close cur log */
|
||||
sim_log = fopen (gbuf, "a"); /* open log */
|
||||
if (sim_log == NULL) return SCPE_OPENERR; /* error? */
|
||||
printf ("Logging to file \"%s\"\n", gbuf); /* start of log */
|
||||
fprintf (sim_log, "Logging to file \"%s\"\n", gbuf);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat nolog_cmd (int flag, char *cptr)
|
||||
{
|
||||
char gbuf[CBUFSIZE];
|
||||
|
||||
if (cptr) {
|
||||
GET_SWITCHES (cptr, gbuf); /* test for switches */
|
||||
if (*cptr != 0) return SCPE_ARG; } /* end of line? */
|
||||
if (sim_log == NULL) return SCPE_OK; /* no log? */
|
||||
printf ("Log file closed\n");
|
||||
fprintf (sim_log, "Log file closed\n"); /* close log */
|
||||
fclose (sim_log);
|
||||
sim_log = NULL;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reset command and routines
|
||||
|
||||
re[set] reset all devices
|
||||
|
@ -991,7 +1068,7 @@ else if (strcmp (buf, save_ver25) == 0) { /* version 2.5? */
|
|||
if (strcmp (buf, sim_name)) { /* name match? */
|
||||
printf ("Wrong system type: %s\n", buf);
|
||||
fclose (rfile);
|
||||
return SCPE_OK; }
|
||||
return SCPE_INCOMP; }
|
||||
READ_I (sim_time); /* sim time */
|
||||
if (v26) { READ_I (sim_rtime); } /* sim relative time */
|
||||
|
||||
|
@ -1095,8 +1172,6 @@ t_stat run_cmd (int flag, char *cptr)
|
|||
char gbuf[CBUFSIZE];
|
||||
int32 i, j, step, unitno;
|
||||
t_stat r;
|
||||
t_addr k;
|
||||
t_value pcval;
|
||||
DEVICE *dptr;
|
||||
UNIT *uptr;
|
||||
void int_handler (int signal);
|
||||
|
@ -1147,6 +1222,7 @@ if (ttrunstate () != SCPE_OK) { /* set console */
|
|||
return SCPE_TTYERR; }
|
||||
if (step) sim_activate (&step_unit, step); /* set step timer */
|
||||
sim_is_running = 1; /* flag running */
|
||||
sim_chkcons (); /* check console buffer */
|
||||
r = sim_instr();
|
||||
|
||||
sim_is_running = 0; /* flag idle */
|
||||
|
@ -1159,11 +1235,26 @@ else { UPDATE_SIM_TIME (noqueue_time); }
|
|||
#if defined (VMS)
|
||||
printf ("\n");
|
||||
#endif
|
||||
if (r >= SCPE_BASE) printf ("\n%s, %s: ", scp_error_messages[r - SCPE_BASE],
|
||||
sim_PC -> name);
|
||||
else printf ("\n%s, %s: ", sim_stop_messages[r], sim_PC -> name);
|
||||
fprint_stopped (stdout, r); /* print msg */
|
||||
if (sim_log) fprint_stopped (sim_log, r); /* log if enabled */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Print stopped message */
|
||||
|
||||
void fprint_stopped (FILE *stream, t_stat v)
|
||||
{
|
||||
int32 i;
|
||||
t_stat r;
|
||||
t_addr k;
|
||||
t_value pcval;
|
||||
DEVICE *dptr;
|
||||
|
||||
if (v >= SCPE_BASE) fprintf (stream, "\n%s, %s: ",
|
||||
scp_error_messages[v - SCPE_BASE], sim_PC -> name);
|
||||
else fprintf (stream, "\n%s, %s: ", sim_stop_messages[v], sim_PC -> name);
|
||||
pcval = get_rval (sim_PC, 0);
|
||||
print_val (pcval, sim_PC -> radix, sim_PC -> width,
|
||||
fprint_val (stream, pcval, sim_PC -> radix, sim_PC -> width,
|
||||
sim_PC -> flags & REG_FMT);
|
||||
if (((dptr = sim_devices[0]) != NULL) && (dptr -> examine != NULL)) {
|
||||
for (i = 0; i < sim_emax; i++) sim_eval[i] = 0;
|
||||
|
@ -1171,16 +1262,14 @@ if (((dptr = sim_devices[0]) != NULL) && (dptr -> examine != NULL)) {
|
|||
if (r = dptr -> examine (&sim_eval[i], k, dptr -> units,
|
||||
SWMASK ('V')) != SCPE_OK) break; }
|
||||
if ((r == SCPE_OK) || (i > 0)) {
|
||||
printf (" (");
|
||||
if (fprint_sym (stdout, (t_addr) pcval, sim_eval, NULL, SWMASK('M')) > 0)
|
||||
fprint_val (stdout, sim_eval[0], dptr -> dradix,
|
||||
fprintf (stream, " (");
|
||||
if (fprint_sym (stream, (t_addr) pcval, sim_eval, NULL, SWMASK('M')) > 0)
|
||||
fprint_val (stream, sim_eval[0], dptr -> dradix,
|
||||
dptr -> dwidth, PV_RZRO);
|
||||
printf (")"); } }
|
||||
printf ("\n");
|
||||
return SCPE_OK;
|
||||
fprintf (stream, ")"); } }
|
||||
fprintf (stream, "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Run time routines */
|
||||
|
||||
/* Unit service for step timeout, originally scheduled by STEP n command
|
||||
|
||||
|
@ -1227,7 +1316,7 @@ t_stat exdep_cmd (int flag, char *cptr)
|
|||
{
|
||||
char gbuf[CBUFSIZE], *gptr, *tptr;
|
||||
int32 unitno, t;
|
||||
t_bool log;
|
||||
t_bool exd2f;
|
||||
t_addr low, high;
|
||||
t_stat reason;
|
||||
DEVICE *dptr, *tdptr;
|
||||
|
@ -1242,7 +1331,7 @@ t_stat exdep_reg_loop (FILE *ofile, SCHTAB *schptr, int flag, char *ptr,
|
|||
|
||||
if (*cptr == 0) return SCPE_ARG; /* err if no args */
|
||||
ofile = NULL; /* no output file */
|
||||
log = FALSE;
|
||||
exd2f = FALSE;
|
||||
sim_switches = 0; /* no switches */
|
||||
schptr = NULL; /* no search */
|
||||
stab.logic = SCH_OR; /* default search params */
|
||||
|
@ -1254,13 +1343,13 @@ for (;;) { /* loop through modifiers */
|
|||
if (*cptr == 0) return SCPE_ARG; /* error if no arguments */
|
||||
if (*cptr == '@') { /* output file spec? */
|
||||
if (flag != EX_E) return SCPE_ARG; /* examine only */
|
||||
if (log) { /* already got one? */
|
||||
if (exd2f) { /* already got one? */
|
||||
fclose (ofile); /* one per customer */
|
||||
return SCPE_ARG; }
|
||||
cptr = get_glyph_nc (cptr + 1, gbuf, 0);
|
||||
ofile = fopen (gbuf, "a"); /* open for append */
|
||||
if (ofile == NULL) return SCPE_OPENERR;
|
||||
log = TRUE;
|
||||
exd2f = TRUE;
|
||||
continue; } /* look for more */
|
||||
cptr = get_glyph (cptr, gbuf, 0);
|
||||
if ((t = get_switches (gbuf)) != 0) { /* try for switches */
|
||||
|
@ -1313,7 +1402,7 @@ for (gptr = gbuf, reason = SCPE_OK;
|
|||
reason = exdep_addr_loop (ofile, schptr, flag, cptr, low, high,
|
||||
dptr, uptr);
|
||||
} /* end for */
|
||||
if (log) fclose (ofile); /* close output file */
|
||||
if (exd2f) fclose (ofile); /* close output file */
|
||||
return reason;
|
||||
}
|
||||
|
||||
|
@ -1342,7 +1431,9 @@ for (rptr = lowr; rptr <= highr; rptr++) {
|
|||
if (schptr && !test_search (val, schptr)) continue;
|
||||
if (flag != EX_D) {
|
||||
reason = ex_reg (ofile, val, flag, rptr, idx);
|
||||
if (reason != SCPE_OK) return reason; }
|
||||
if (reason != SCPE_OK) return reason;
|
||||
if (sim_log && (ofile == stdout))
|
||||
ex_reg (sim_log, val, flag, rptr, idx); }
|
||||
if (flag != EX_E) {
|
||||
reason = dep_reg (flag, cptr, rptr, idx);
|
||||
if (reason != SCPE_OK) return reason; } } }
|
||||
|
@ -1365,7 +1456,9 @@ for (i = low; i <= high; i = i + (dptr -> aincr)) {
|
|||
if (schptr && !test_search (sim_eval[0], schptr)) continue;
|
||||
if (flag != EX_D) {
|
||||
reason = ex_addr (ofile, flag, i, dptr, uptr);
|
||||
if (reason > SCPE_OK) return reason; }
|
||||
if (reason > SCPE_OK) return reason;
|
||||
if (sim_log && (ofile == stdout))
|
||||
ex_addr (sim_log, flag, i, dptr, uptr); }
|
||||
if (flag != EX_E) {
|
||||
reason = dep_addr (flag, cptr, i, dptr, uptr, reason);
|
||||
if (reason > SCPE_OK) return reason; }
|
||||
|
@ -1452,6 +1545,7 @@ if ((cptr == NULL) || (rptr == NULL)) return SCPE_ARG;
|
|||
if (rptr -> flags & REG_RO) return SCPE_RO;
|
||||
if (flag & EX_I) {
|
||||
cptr = read_line (gbuf, CBUFSIZE, stdin);
|
||||
if (sim_log) fprintf (sim_log, (cptr? "%s\n": "\n"), cptr);
|
||||
if (cptr == NULL) return 1; /* force exit */
|
||||
if (*cptr == 0) return SCPE_OK; } /* success */
|
||||
mask = width_mask[rptr -> width];
|
||||
|
@ -1606,6 +1700,7 @@ char gbuf[CBUFSIZE];
|
|||
if (dptr == NULL) return SCPE_ARG;
|
||||
if (flag & EX_I) {
|
||||
cptr = read_line (gbuf, CBUFSIZE, stdin);
|
||||
if (sim_log) fprintf (sim_log, (cptr? "%s\n": "\n"), cptr);
|
||||
if (cptr == NULL) return 1; /* force exit */
|
||||
if (*cptr == 0) return dfltinc; } /* success */
|
||||
mask = width_mask[dptr -> dwidth];
|
||||
|
@ -1661,6 +1756,7 @@ if (cptr == NULL) {
|
|||
for (tptr = cptr; tptr < (cptr + size); tptr++) /* remove cr */
|
||||
if (*tptr == '\n') *tptr = 0;
|
||||
while (isspace (*cptr)) cptr++; /* absorb spaces */
|
||||
if (*cptr == ';') *cptr = 0; /* ignore comment */
|
||||
return cptr;
|
||||
}
|
||||
|
||||
|
@ -2267,11 +2363,12 @@ lcnt = count % nelem; /* count in last buf */
|
|||
if (lcnt) nbuf = nbuf + 1;
|
||||
else lcnt = nelem;
|
||||
total = 0;
|
||||
dptr = bptr; /* init output ptr */
|
||||
for (i = nbuf; i > 0; i--) {
|
||||
c = fread (sim_flip, size, (i == 1? lcnt: nelem), fptr);
|
||||
if (c == 0) return total;
|
||||
total = total + c;
|
||||
for (j = 0, sptr = sim_flip, dptr = bptr; j < c; j++) {
|
||||
for (j = 0, sptr = sim_flip; j < c; j++) {
|
||||
for (k = size - 1; k >= 0; k--) *(dptr + k) = *sptr++;
|
||||
dptr = dptr + size; } }
|
||||
return total;
|
||||
|
@ -2292,11 +2389,11 @@ lcnt = count % nelem; /* count in last buf */
|
|||
if (lcnt) nbuf = nbuf + 1;
|
||||
else lcnt = nelem;
|
||||
total = 0;
|
||||
sptr = bptr; /* init input ptr */
|
||||
for (i = nbuf; i > 0; i--) {
|
||||
c = (i == 1)? lcnt: nelem;
|
||||
for (j = 0, sptr = bptr, dptr = sim_flip; j < c; j++) {
|
||||
for (k = size - 1; k >= 0; k--)
|
||||
*(dptr + k) = *sptr++;
|
||||
for (j = 0, dptr = sim_flip; j < c; j++) {
|
||||
for (k = size - 1; k >= 0; k--) *(dptr + k) = *sptr++;
|
||||
dptr = dptr + size; }
|
||||
c = fwrite (sim_flip, size, c, fptr);
|
||||
if (c == 0) return total;
|
||||
|
@ -2354,4 +2451,77 @@ rtc_currdelay = (int32) (((double) rtc_basedelay * (double) rtc_nextintv) /
|
|||
1000.0); /* next delay */
|
||||
return rtc_currdelay;
|
||||
}
|
||||
|
||||
/* OS independent multiconsole package
|
||||
|
||||
set_console make unit the active console
|
||||
sim_putcons output character in a multiconsole simulator
|
||||
sim_chkcons check for buffered output in a multiconsole simulator
|
||||
*/
|
||||
|
||||
t_stat set_console (UNIT *uptr, int32 flag)
|
||||
{
|
||||
int32 i;
|
||||
DEVICE *idptr, *odptr;
|
||||
UNIT *wuptr, *iuptr = NULL, *ouptr = NULL;
|
||||
|
||||
if (sim_consoles == NULL) return SCPE_NOFNC;
|
||||
for (i = 0; sim_consoles[i] != NULL; i++) {
|
||||
if (uptr == sim_consoles[i]) {
|
||||
iuptr = sim_consoles[i & ~1];
|
||||
ouptr = sim_consoles[i | 1]; } }
|
||||
if ((iuptr == NULL) || (ouptr == NULL)) return SCPE_ARG;
|
||||
idptr = find_dev_from_unit (iuptr);
|
||||
odptr = find_dev_from_unit (ouptr);
|
||||
if ((idptr == NULL) || (odptr == NULL)) return SCPE_ARG;
|
||||
for (i = 0; sim_consoles[i] != NULL; i++) {
|
||||
wuptr = sim_consoles[i];
|
||||
wuptr -> flags = wuptr -> flags & ~UNIT_CONS;
|
||||
if (!(i & 1)) sim_cancel (wuptr); }
|
||||
iuptr -> flags = iuptr -> flags | UNIT_CONS;
|
||||
ouptr -> flags = ouptr -> flags | UNIT_CONS;
|
||||
sim_activate (iuptr, iuptr -> wait);
|
||||
if (idptr == odptr) {
|
||||
printf ("Active console is %s\n", idptr -> name);
|
||||
if (sim_log) fprintf (sim_log, "Active console is %s\n", idptr -> name); }
|
||||
else { printf ("Active console is %s/%s\n", idptr -> name, odptr -> name);
|
||||
if (sim_log) fprintf (sim_log,
|
||||
"Active console is %s/%s\n", idptr -> name, odptr -> name); }
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat sim_putcons (int32 out, UNIT *uptr)
|
||||
{
|
||||
uint8 *consbuf;
|
||||
|
||||
if ((uptr -> flags & UNIT_CONS) || (uptr -> filebuf == NULL))
|
||||
return sim_putchar (out);
|
||||
if (uptr -> u4 < CONS_SIZE) {
|
||||
consbuf = (uint8 *) uptr -> filebuf;
|
||||
consbuf[uptr -> u4] = out; }
|
||||
uptr -> u4 = uptr -> u4 + 1;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
void sim_chkcons (void)
|
||||
{
|
||||
int32 i, j, limit;
|
||||
uint8 *consbuf;
|
||||
UNIT *uptr;
|
||||
|
||||
if (sim_consoles == NULL) return;
|
||||
for (i = 0; sim_consoles[i] != NULL; i++) {
|
||||
uptr = sim_consoles[i];
|
||||
if ((i & 1) && (uptr -> flags & UNIT_CONS) &&
|
||||
(uptr -> filebuf) && (uptr -> u4)) {
|
||||
consbuf = (uint8 *) uptr -> filebuf;
|
||||
limit = (uptr -> u4 < CONS_SIZE)? uptr -> u4: CONS_SIZE;
|
||||
for (j = 0; j < limit; j++) sim_putchar (consbuf[j]);
|
||||
if (uptr -> u4 >= CONS_SIZE) {
|
||||
printf ("\n[Buffered output lost]\n");
|
||||
if (sim_log) fprintf (sim_log, "\n[Buffered output lost]\n"); }
|
||||
uptr -> u4 = 0;
|
||||
return; } }
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
12
scp_tty.c
12
scp_tty.c
|
@ -23,6 +23,7 @@
|
|||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
15-May-01 RMS Added logging support
|
||||
05-Mar-01 RMS Added clock calibration support
|
||||
08-Dec-00 BKR Added OS/2 support
|
||||
18-Aug-98 RMS Added BeOS support
|
||||
|
@ -50,6 +51,7 @@
|
|||
#undef USE_INT64 /* hack for Windows */
|
||||
#include "sim_defs.h"
|
||||
int32 sim_int_char = 005; /* interrupt character */
|
||||
extern FILE *sim_log;
|
||||
|
||||
/* VMS routines */
|
||||
|
||||
|
@ -151,6 +153,7 @@ IOSB iosb;
|
|||
c = out;
|
||||
status = sys$qiow (EFN, tty_chan, IO$_WRITELBLK | IO$M_NOFORMAT,
|
||||
&iosb, 0, 0, &c, 1, 0, 0, 0, 0);
|
||||
if (sim_log) fputc (c, sim_log);
|
||||
if ((status != SS$_NORMAL) || (iosb.status != SS$_NORMAL)) return SCPE_TTOERR;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
@ -237,7 +240,9 @@ return c | SCPE_KFLAG;
|
|||
|
||||
t_stat sim_putchar (int32 c)
|
||||
{
|
||||
if (c != 0177) _putch (c);
|
||||
if (c != 0177) {
|
||||
_putch (c);
|
||||
if (sim_log) fputc (c, sim_log); }
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -291,7 +296,8 @@ t_stat sim_putchar (int32 c)
|
|||
{
|
||||
if (c != 0177) {
|
||||
putch (c);
|
||||
fflush (stdout) ; }
|
||||
fflush (stdout) ;
|
||||
if (sim_log) fputc (c, sim_log); }
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -381,6 +387,7 @@ char c;
|
|||
|
||||
c = out;
|
||||
write (1, &c, 1);
|
||||
if (sim_log) fputc (c, sim_log);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -480,6 +487,7 @@ char c;
|
|||
|
||||
c = out;
|
||||
write (1, &c, 1);
|
||||
if (sim_log) fputc (c, sim_log);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
|
17
sim_defs.h
17
sim_defs.h
|
@ -23,6 +23,8 @@
|
|||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
27-May-01 RMS Added multiple console support
|
||||
15-May-01 RMS Increased string buffer size
|
||||
25-Feb-01 RMS Revisions for V2.6
|
||||
15-Oct-00 RMS Editorial revisions for V2.5
|
||||
11-Jul-99 RMS Added unsigned int data types
|
||||
|
@ -53,6 +55,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
|
@ -90,7 +93,11 @@ typedef int32 t_mtrlnt; /* magtape rec lnt */
|
|||
#define MTRF(x) ((x) & (1u << 31)) /* record error flg */
|
||||
#define MTRL(x) ((x) & ((1u << 31) - 1)) /* record length */
|
||||
#define FLIP_SIZE (1 << 16) /* flip buf size */
|
||||
#define CBUFSIZE 128 /* string buf size */
|
||||
#if !defined (PATH_MAX) /* usually in limits */
|
||||
#define PATH_MAX 512
|
||||
#endif
|
||||
#define CBUFSIZE (128 + PATH_MAX) /* string buf size */
|
||||
#define CONS_SIZE 4096 /* console buffer */
|
||||
|
||||
/* Simulator status codes
|
||||
|
||||
|
@ -128,6 +135,8 @@ typedef int32 t_mtrlnt; /* magtape rec lnt */
|
|||
#define SCPE_SUB (SCPE_BASE + 24) /* subscript err */
|
||||
#define SCPE_NOFNC (SCPE_BASE + 25) /* func not imp */
|
||||
#define SCPE_UDIS (SCPE_BASE + 26) /* unit disabled */
|
||||
#define SCPE_LOGON (SCPE_BASE + 27) /* logging enabled */
|
||||
#define SCPE_LOGOFF (SCPE_BASE + 28) /* logging disabled */
|
||||
#define SCPE_KFLAG 01000 /* tti data flag */
|
||||
|
||||
/* Print value format codes */
|
||||
|
@ -211,7 +220,9 @@ struct unit {
|
|||
#define UNIT_BUF 000400 /* buffered */
|
||||
#define UNIT_DISABLE 001000 /* disable-able */
|
||||
#define UNIT_DIS 002000 /* disabled */
|
||||
#define UNIT_V_UF 11 /* device specific */
|
||||
#define UNIT_CONS 004000 /* active console */
|
||||
#define UNIT_V_CONS 11
|
||||
#define UNIT_V_UF 12 /* device specific */
|
||||
|
||||
/* Register data structure */
|
||||
|
||||
|
@ -310,3 +321,5 @@ EXTERN char *get_glyph (char *iptr, char *optr, char mchar);
|
|||
EXTERN char *get_glyph_nc (char *iptr, char *optr, char mchar);
|
||||
EXTERN t_value get_uint (char *cptr, int radix, t_value max, t_stat *status);
|
||||
EXTERN t_value strtotv (char *cptr, char **endptr, int radix);
|
||||
EXTERN t_stat set_console (UNIT *uptr, int32 flag);
|
||||
EXTERN t_stat sim_putcons (int32 out, UNIT *uptr);
|
||||
|
|
205
simh_doc.txt
205
simh_doc.txt
|
@ -1,7 +1,7 @@
|
|||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: Simulator Usage, V2.6
|
||||
Date: 3-May-01
|
||||
Subj: Simulator Usage, V2.6a
|
||||
Date: 15-Jun-01
|
||||
|
||||
COPYRIGHT NOTICE
|
||||
|
||||
|
@ -161,6 +161,8 @@ Multiple switches may be specified separately or together: -abcd or
|
|||
-a -b -c -d are treated identically. Verbs, switches, and other
|
||||
input (except for file names) are case insensitive.
|
||||
|
||||
Any command beginning with semicolon (;) is considered a comment and ignored.
|
||||
|
||||
3.1 Loading and Saving Programs
|
||||
|
||||
The LOAD command (abbreviation LO) loads a file in binary paper-tape
|
||||
|
@ -419,7 +421,20 @@ specified unit from the configuration. Once removed, a unit cannot be
|
|||
manipulated in any way until it is added back to the configuration.
|
||||
ADD <unit> adds back a unit that had been removed from the configuration.
|
||||
|
||||
3.11 Exiting The Simulator
|
||||
3.11 Logging Console Output
|
||||
|
||||
Output to the console can be logged simultaneously to a file. Logging is
|
||||
enabled by the LOG command:
|
||||
|
||||
sim> LOG <filename> -- log console output to file
|
||||
|
||||
Logging is disabled by the NOLOG command:
|
||||
|
||||
sim> NOLOG -- disable logging
|
||||
|
||||
LOG with no argument displays whether logging is enabled or disabled.
|
||||
|
||||
3.12 Exiting The Simulator
|
||||
|
||||
EXIT (synonyms QUIT and BYE) returns control to the operating system.
|
||||
|
||||
|
@ -1704,6 +1719,22 @@ control registers for the interrupt system.
|
|||
|
||||
6.2 Programmed I/O Devices
|
||||
|
||||
The Nova can have two terminals (TTI/TTO, TTI1/TTO1). At any moment
|
||||
only one terminal is active. It can receive input from the keyboard;
|
||||
it can output to the simulator window. The inactive console cannot
|
||||
receive input from the keyboard and outputs to an internal buffer
|
||||
(maximum 4K characters).
|
||||
|
||||
Control is switched among terminals with a SET TTI{n} CONSOLE or SET
|
||||
TTO{n} CONSOLE command:
|
||||
|
||||
At startup, active console is TTI/TTO
|
||||
SET TTI1 CONSOLE Active console is now TTI1/TTO1
|
||||
SET TTO CONSOLE Active console is now TTI/TTO
|
||||
|
||||
When control is switched to an inactive terminal, any buffered output
|
||||
is printed when simulation resumes.
|
||||
|
||||
6.2.1 Paper Tape Reader (PTR)
|
||||
|
||||
The paper tape reader (PTR) reads data from a disk file. The POS
|
||||
|
@ -1763,21 +1794,23 @@ Error handling is as follows:
|
|||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
6.2.3 Terminal Input (TTI)
|
||||
6.2.3 Terminal Input (TTI, TTI1)
|
||||
|
||||
The terminal input reads from the controling console port. Terminal
|
||||
options include the ability to set limited Dasher compatibility mode or
|
||||
normal mode:
|
||||
The active terminal input polls the console keyboard for input. The
|
||||
inactive terminal input cannot receive characters. Terminal input
|
||||
options include the ability to set limited Dasher compatibility mode
|
||||
or ANSI standard mode:
|
||||
|
||||
SET TTI ANSI normal mode
|
||||
SET TTI DASHER Dasher mode
|
||||
SET TTO ANSI normal mode
|
||||
SET TTO DASHER Dasher mode
|
||||
|
||||
Setting either TTI or TTO changes both devices. In Dasher mode, carriage
|
||||
return is changed to newline on input, and ^X is changed to backspace.
|
||||
Setting either TTI (TTI1) or TTO (TTO1) changes both devices. In Dasher
|
||||
mode, carriage return is changed to newline on input, and ^X is changed
|
||||
to backspace.
|
||||
|
||||
The terminal input implements these registers:
|
||||
The terminal inputs implement these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
|
@ -1789,21 +1822,22 @@ The terminal input implements these registers:
|
|||
POS 31 number of characters input
|
||||
TIME 24 keyboard polling interval
|
||||
|
||||
6.2.4 Terminal Output (TTO)
|
||||
6.2.4 Terminal Output (TTO, TTO1)
|
||||
|
||||
The terminal output writes to the controling console port. Terminal
|
||||
options include the ability to set limited Dasher compatibility mode or
|
||||
normal mode:
|
||||
The active terminal output writes to the simulator window. The inactive
|
||||
terminal output buffers characters. Terminal output options include the
|
||||
the ability to set limited Dasher compatibility mode or ANSI mode:
|
||||
|
||||
SET TTI ANSI normal mode
|
||||
SET TTI DASHER Dasher mode
|
||||
SET TTO ANSI normal mode
|
||||
SET TTO DASHER Dasher mode
|
||||
|
||||
Setting either TTI or TTO changes both devices. In Dasher mode, carriage
|
||||
return is changed to newline on input, and ^X is changed to backspace.
|
||||
Setting either TTI (TTI1) or TTO (TTO1) changes both devices. In Dasher
|
||||
mode, carriage return is changed to newline on input, and ^X is changed
|
||||
to backspace.
|
||||
|
||||
The terminal output implements these registers:
|
||||
The terminal outputs implement these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
|
@ -1890,69 +1924,6 @@ Error handling is as follows:
|
|||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
6.2.8 Second Terminal Input (TTI1)
|
||||
|
||||
The second terminal input (TTI1) reads data from a disk file. When a
|
||||
file is attached, the second terminal input will read characters at
|
||||
the interval specified by the TIME register. Detaching the file, or
|
||||
reaching end of file, stops input. The POS register specifies the
|
||||
number of the next data item to be read. Thus, by changing POS, the
|
||||
user can backspace or advance the input stream.
|
||||
|
||||
The second terminal input implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
BUSY 1 device busy flag
|
||||
DONE 1 device done flag
|
||||
DISABLE 1 interrupt disable flag
|
||||
INT 1 interrupt pending flag
|
||||
POS 31 position in the input file
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape or paper
|
||||
|
||||
end of file 1 report error and stop
|
||||
0 out of tape or paper
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
6.2.9 Second Terminal Output (TTO1)
|
||||
|
||||
The second terminal output (TTO1) writes data to a disk file. The
|
||||
POS register specifies the number of the next data item to be written.
|
||||
Thus, by changing POS, the user can backspace or advance the output
|
||||
stream.
|
||||
|
||||
The second terminal outpout implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
BUSY 1 device busy flag
|
||||
DONE 1 device done flag
|
||||
DISABLE 1 interrupt disable flag
|
||||
INT 1 interrupt pending flag
|
||||
POS 31 position in the output file
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape or paper
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
6.3 Fixed Head Disk (DK)
|
||||
|
||||
The fixed head disk controller implements these registers:
|
||||
|
@ -2528,11 +2499,13 @@ PDP-7 CPU PDP-7 CPU with 32KW of memory
|
|||
|
||||
PDP-9 CPU PDP-9 CPU with 32KW of memory
|
||||
- KE09A extended arithmetic element (EAE)
|
||||
- KF09A automatic priority interrupt (API)
|
||||
- KG09B memory extension
|
||||
- KP09A power detection
|
||||
- KX09A memory protection
|
||||
PTR,PTP PC09A paper tape reader/punch
|
||||
TTI,TTO KSR 33 console terminal
|
||||
TTI1,TTO1 LT09A second console terminal
|
||||
LPT Type 647E line printer
|
||||
CLK integral real-time clock
|
||||
RF RF09/RS09 fixed-head disk
|
||||
|
@ -2541,10 +2514,12 @@ PDP-9 CPU PDP-9 CPU with 32KW of memory
|
|||
|
||||
PDP-15 CPU PDP-15 CPU with 32KW of memory
|
||||
- KE15 extended arithmetic element (EAE)
|
||||
- KA15 automatic priority interrupt (API)
|
||||
- KF15 power detection
|
||||
- KM15 memory protection
|
||||
PTR,PTP PC15 paper tape reader/punch
|
||||
TTI,TTO KSR 35 console terminal
|
||||
TTI1,TTO1 LT15 second console terminal
|
||||
LPT LP15 line printer
|
||||
CLK integral real-time clock
|
||||
RP RP15/RP02 disk pack
|
||||
|
@ -2569,10 +2544,13 @@ specified, the file is assumed to be BIN format.
|
|||
|
||||
8.1 CPU
|
||||
|
||||
The only CPU options are the presence of the EAE and the size of main memory.
|
||||
The CPU options are the presence of the EAE, the presense of the API (for
|
||||
the PDP-9 and PDP-15), and the size of main memory.
|
||||
|
||||
SET CPU EAE enable EAE
|
||||
SET CPU NOEAE disable EAE
|
||||
SET CPU API enable API
|
||||
SET CPU NOAPI disable API
|
||||
SET CPU 4K set memory size = 4K
|
||||
SET CPU 8K set memory size = 8K
|
||||
SET CPU 12K set memory size = 12K
|
||||
|
@ -2638,6 +2616,22 @@ the PDP-7 and PDP-9, 17b for the PDP-15).
|
|||
|
||||
8.2 Programmed I/O Devices
|
||||
|
||||
The PDP-9 and PDP-15 have two terminals (TTI/TTO, TTI1/TTO1). At any
|
||||
moment, only one terminal is active. It can receive input from the
|
||||
keyboard; it can output to the simulator window. The inactive console
|
||||
cannot receive input from the keyboard and outputs to an internal buffer
|
||||
(maximum 4K characters).
|
||||
|
||||
Control is switched among terminals with a SET TTI{n} CONSOLE or SET
|
||||
TTO{n} CONSOLE command:
|
||||
|
||||
At startup, active console is TTI/TTO
|
||||
SET TTI1 CONSOLE Active console is now TTI1/TTO1
|
||||
SET TTO CONSOLE Active console is now TTI/TTO
|
||||
|
||||
When control is switched to an inactive terminal, any buffered output
|
||||
is printed when simulation resumes.
|
||||
|
||||
8.2.1 Paper Tape Reader (PTR)
|
||||
|
||||
The paper tape reader (PTR) reads data from a disk file. The POS
|
||||
|
@ -2700,18 +2694,20 @@ Error handling is as follows:
|
|||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
8.2.3 Terminal Input (TTI)
|
||||
8.2.3 Terminal Input (TTI, TTI1)
|
||||
|
||||
The terminal input (TTI) reads from the controling console port. The
|
||||
terminal input has one option, UC; when set, it automatically converts
|
||||
lower case input to upper case.
|
||||
The active terminal input polls the console keyboard for input. The
|
||||
inactive terminal input cannot receive characters. The terminal inputs
|
||||
have one option, UC; when set, it automatically converts lower case input
|
||||
to upper case.
|
||||
|
||||
The PDP-9 and PDP-15 operated the terminal, by default, as half-duplex.
|
||||
For backward compatibility, on the PDP-9 and PDP-15 the terminal input
|
||||
has a second option, FDX; when set, it operates the terminal input in
|
||||
full-duplex mode.
|
||||
The PDP-9 and PDP-15 operated the primary terminal (TTI/TTO), by default,
|
||||
as half-duplex. For backward compatibility, on the PDP-9 and PDP-15
|
||||
the first terminal input has a second option, FDX; when set, it operates
|
||||
the terminal input in full-duplex mode. The second terminal is always
|
||||
full duplex.
|
||||
|
||||
The terminal input implements these registers:
|
||||
The terminal inputs implement these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
|
@ -2721,10 +2717,14 @@ The terminal input implements these registers:
|
|||
POS 31 number of characters input
|
||||
TIME 24 keyboard polling interval
|
||||
|
||||
8.2.4 Terminal Output (TTO)n backspace or advance these devices.
|
||||
8.2.4 Terminal Output (TTO, TTO1)
|
||||
|
||||
The terminal output (TTO) writes to the controling console port. It
|
||||
implements these registers:
|
||||
The active terminal output writes to the simulator window. The inactive
|
||||
terminal output buffers characters. The terminal outputs have one option,
|
||||
UC; when set, it suppresses lower case output (so that ALTMODE is not
|
||||
echoed as }).
|
||||
|
||||
The terminal outputs implement these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
|
@ -4172,9 +4172,12 @@ the file format to try to determine the file type.
|
|||
|
||||
12.1 CPU
|
||||
|
||||
The only CPU option is the choice of standard or ITS compatible microcode.
|
||||
The CPU options allow the user to specify standard microcode, standard
|
||||
microcode with a bug fix for a boostrap problem in TOPS-20 V4.1, or ITS
|
||||
microcode
|
||||
|
||||
SET CPU STANDARD Standard microcode
|
||||
SET CPU TOPS20V41 Standard microcode with TOPS-20 V4.1 bug fix
|
||||
SET CPU ITS ITS compatible microcode
|
||||
|
||||
CPU registers include the visible state of the processor as well as the
|
||||
|
@ -4663,12 +4666,22 @@ legend: y = runs operating system or sample program
|
|||
|
||||
Revision History (since Rev 1.1)
|
||||
|
||||
Rev 2.6a, Jul, 01
|
||||
Rev 2.6a, Jun, 01
|
||||
Fixed bug (found by Dave Conroy) in big-endian I/O
|
||||
Fixed DECtape reset in PDP-8, PDP-11, PDP-9/15
|
||||
Fixed RIM loader PC handling in PDP-9/15
|
||||
Fixed indirect pointers in PDP-10 paging
|
||||
Fixed SSC handling in PDP-10 TM02/TU45
|
||||
Added FE CTRL-C option for Windoze
|
||||
Fixed JMS to non-existent memory in PDP-8
|
||||
Fixed error handling on command file
|
||||
Increased size of string buffers for long path names
|
||||
Added PDP-9, PDP-15 API option
|
||||
Added PDP-9, PDP-15 second terminal
|
||||
Added PDP-10 option for TOPS-20 V4.1 bug fix
|
||||
Added PDP-10 FE CTRL-C option for Windoze
|
||||
Added console logging
|
||||
Added multiple console support
|
||||
Added comment recognition
|
||||
|
||||
Rev 2.6, May, 01
|
||||
Added ENABLE/DISABLE devices
|
||||
|
|
|
@ -457,9 +457,62 @@ To load and run BASIC:
|
|||
RUN
|
||||
1.41421
|
||||
|
||||
9. PDP-10 TOPS-10 7.03
|
||||
9. PDP-9/PDP-15 Advanced Software System/Keyboard Monitor
|
||||
|
||||
The Advanced Software System was a family of operating systems for the
|
||||
PDP-9 and PDP-15, ranging from a paper-tape basic system, through the
|
||||
DECtape or disk based Keyboard Monitor, through the Foreground/Background
|
||||
Monitor, to DOS-15. To run ADSS/KM from simulated DECtape:
|
||||
|
||||
- On the PDP-9 (only), initialize extend mode to on:
|
||||
|
||||
sim> d extm_init 1
|
||||
|
||||
- Load the paper-tape bootstrap into upper memory:
|
||||
|
||||
sim> load dec-15u.rim 77637
|
||||
|
||||
- Verify that the bootstrap loaded correctly:
|
||||
|
||||
sim> ex pc
|
||||
PC: 077646
|
||||
|
||||
- Mount the Advanced Software System DECtape image on DECtape unit 0:
|
||||
|
||||
sim> attach dt adss15_32k.dtp
|
||||
|
||||
- Run the bootstrap:
|
||||
|
||||
sim> run
|
||||
|
||||
- The DECtape will boot and print out
|
||||
|
||||
KMS9-15 V5B000
|
||||
$
|
||||
|
||||
and is now ready for commands. Recognized commands include:
|
||||
|
||||
D list system device directory
|
||||
I list available commands
|
||||
R list device assignments
|
||||
SCOM list systems communication region
|
||||
|
||||
- To run Focal, assign unused DAT slot 10 and then load Focal
|
||||
|
||||
$A LPA0 10
|
||||
$GLOAD
|
||||
LOADER V5B000
|
||||
>_FOCAL<altmode = control-[>
|
||||
FOCAL V9A
|
||||
*TYPE 2+2,!
|
||||
4.0000
|
||||
*
|
||||
|
||||
10. PDP-10 TOPS-10 7.03, TOPS-20 V4.1
|
||||
|
||||
TOPS-10 was the primary time-shared operating system for the PDP-10.
|
||||
Installation and distribution tapes for TOPS-10 7.03 are available at
|
||||
http://pdp-10.trailing-edge.com.
|
||||
TOPS-20 was a popular alternative derived from the BBN TENEX system.
|
||||
Installation and distribution tapes for TOPS-10 7.03 and TOPS-20 4.1
|
||||
are available at http://pdp-10.trailing-edge.com.
|
||||
|
||||
[end simh_swre.txt]
|
||||
|
|
Loading…
Add table
Reference in a new issue