simh v2.6a

This commit is contained in:
Bob Supnik 2001-11-06 20:54:00 -08:00 committed by Mark Pizzolato
parent 4d6dfa4bdb
commit a7b623a1a8
40 changed files with 1793 additions and 901 deletions

View file

@ -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_PC pointer to saved PC register descriptor
sim_emax number of words needed for examine sim_emax number of words needed for examine
sim_devices array of pointers to simulated devices 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_stop_messages array of pointers to stop messages
sim_load binary loader sim_load binary loader
*/ */
@ -43,6 +44,8 @@ int32 sim_emax = 4;
DEVICE *sim_devices[] = { &cpu_dev, &sio_dev, &ptr_dev, DEVICE *sim_devices[] = { &cpu_dev, &sio_dev, &ptr_dev,
&ptp_dev, &dsk_dev, NULL }; &ptp_dev, &dsk_dev, NULL };
UNIT *sim_consoles = NULL;
const char *sim_stop_messages[] = { const char *sim_stop_messages[] = {
"Unknown error", "Unknown error",
"Unknown I/O Instruction", "Unknown I/O Instruction",

View file

@ -28,6 +28,7 @@
cpu Eclipse central processor cpu Eclipse central processor
01-Jun-01 RMS Added second terminal, plotter support
26-Apr-01 RMS Added device enable/disable support 26-Apr-01 RMS Added device enable/disable support
The register state for the Eclipse CPU is basically the same as 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 ptp (int32 pulse, int32 code, int32 AC);
extern int32 tti (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 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 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 lpt (int32 pulse, int32 code, int32 AC);
extern int32 dsk (int32 pulse, int32 code, int32 AC); extern int32 dsk (int32 pulse, int32 code, int32 AC);
extern int32 dkp (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 }, { 0, 0, &nulldev }, { 0, 0, &nulldev },
{ INT_TTI, PI_TTI, &tti }, { INT_TTO, PI_TTO, &tto }, /* 10 - 17 */ { INT_TTI, PI_TTI, &tti }, { INT_TTO, PI_TTO, &tto }, /* 10 - 17 */
{ INT_PTR, PI_PTR, &ptr }, { INT_PTP, PI_PTP, &ptp }, { 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 }, { 0, 0, &nulldev }, { INT_LPT, PI_LPT, &lpt },
{ INT_DSK, PI_DSK, &dsk }, { 0, 0, &nulldev }, /* 20 - 27 */ { INT_DSK, PI_DSK, &dsk }, { 0, 0, &nulldev }, /* 20 - 27 */
{ INT_MTA, PI_MTA, &mta }, { 0, 0, &nulldev }, { 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 },
{ 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 }, { 0, 0, &nulldev }, { 0, 0, &nulldev },
{ 0, 0, &nulldev }, { 0, 0, &nulldev }, { 0, 0, &nulldev }, { 0, 0, &nulldev },

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings 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. 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) 14-Mar-01 RMS Revised load/dump interface (again)
30-Oct-00 RMS Added examine to file support 30-Oct-00 RMS Added examine to file support
15-Oct-00 RMS Added dynamic device number 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_PC pointer to saved PC register descriptor
sim_emax maximum number of words for examine/deposit sim_emax maximum number of words for examine/deposit
sim_devices array of pointers to simulated devices 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_stop_messages array of pointers to stop messages
sim_load binary loader sim_load binary loader
*/ */
@ -67,6 +69,8 @@ DEVICE *sim_devices[] = { &cpu_dev,
&dpd_dev, &dpc_dev, &dpd_dev, &dpc_dev,
NULL }; NULL };
UNIT *sim_consoles = NULL;
const char *sim_stop_messages[] = { const char *sim_stop_messages[] = {
"Unknown error", "Unknown error",
"Unimplemented instruction", "Unimplemented instruction",

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings 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. 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) 14-Mar-01 RMS Revised load/dump interface (again)
30-Oct-00 RMS Added support for examine to file 30-Oct-00 RMS Added support for examine to file
27-Oct-98 RMS V2.4 load interface 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_PC pointer to saved PC register descriptor
sim_emax maximum number of words for examine/deposit sim_emax maximum number of words for examine/deposit
sim_devices array of pointers to simulated devices 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_stop_messages array of pointers to stop messages
sim_load binary loader sim_load binary loader
*/ */
@ -64,6 +66,8 @@ DEVICE *sim_devices[] = { &cpu_dev, &inq_dev,
&cdr_dev, &cdp_dev, &stack_dev, &lpt_dev, &cdr_dev, &cdp_dev, &stack_dev, &lpt_dev,
&mt_dev, NULL }; &mt_dev, NULL };
UNIT *sim_consoles = NULL;
const char *sim_stop_messages[] = { const char *sim_stop_messages[] = {
"Unknown error", "Unknown error",
"Unimplemented instruction", "Unimplemented instruction",

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings 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. 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) 14-Mar-01 RMS Revised load/dump interface (again)
30-Oct-00 RMS Added support for examine to file 30-Oct-00 RMS Added support for examine to file
27-Oct-98 RMS V2.4 load interface 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_PC pointer to saved PC register descriptor
sim_emax number of words for examine sim_emax number of words for examine
sim_devices array of pointers to simulated devices 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_stop_messages array of pointers to stop messages
sim_load binary loader sim_load binary loader
*/ */
@ -58,6 +60,8 @@ DEVICE *sim_devices[] = { &cpu_dev,
&pt_dev, &tt_dev, &pt_dev, &tt_dev,
NULL }; NULL };
UNIT *sim_consoles = NULL;
const char *sim_stop_messages[] = { const char *sim_stop_messages[] = {
"Unknown error", "Unknown error",
"Reserved instruction", "Reserved instruction",

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings 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. 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) 14-Mar-01 RMS Revised load/dump interface (again)
22-Dec-00 RMS Added second terminal support 22-Dec-00 RMS Added second terminal support
10-Dec-00 RMS Added Eclipse support 10-Dec-00 RMS Added Eclipse support
@ -31,7 +32,7 @@
15-Oct-00 RMS Added stack, byte, trap instructions 15-Oct-00 RMS Added stack, byte, trap instructions
14-Apr-99 RMS Changed t_addr to unsigned 14-Apr-99 RMS Changed t_addr to unsigned
27-Oct-98 RMS V2.4 load interface 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" #include "nova_defs.h"
@ -49,6 +50,8 @@ extern DEVICE tti1_dev, tto1_dev;
extern DEVICE clk_dev, lpt_dev; extern DEVICE clk_dev, lpt_dev;
extern DEVICE dkp_dev, dsk_dev; extern DEVICE dkp_dev, dsk_dev;
extern DEVICE mta_dev; extern DEVICE mta_dev;
extern UNIT tti_unit, tto_unit;
extern UNIT tti1_unit, tto1_unit;
extern REG cpu_reg[]; extern REG cpu_reg[];
extern uint16 M[]; extern uint16 M[];
extern int32 saved_PC; extern int32 saved_PC;
@ -59,6 +62,7 @@ extern int32 saved_PC;
sim_PC pointer to saved PC register descriptor sim_PC pointer to saved PC register descriptor
sim_emax number of words needed for examine sim_emax number of words needed for examine
sim_devices array of pointers to simulated devices 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_stop_messages array of pointers to stop messages
sim_load binary loader sim_load binary loader
*/ */
@ -86,6 +90,11 @@ DEVICE *sim_devices[] = {
&dkp_dev, &mta_dev, &dkp_dev, &mta_dev,
NULL }; NULL };
UNIT *sim_consoles[] = {
&tti_unit, &tto_unit,
&tti1_unit, &tto1_unit,
NULL };
const char *sim_stop_messages[] = { const char *sim_stop_messages[] = {
"Unknown error", "Unknown error",
"Unknown I/O instruction", "Unknown I/O instruction",

View file

@ -25,6 +25,8 @@
tti terminal input tti terminal input
tto terminal output tto terminal output
31-May-01 RMS Added multiconsole support
*/ */
#include "nova_defs.h" #include "nova_defs.h"
@ -39,6 +41,7 @@ t_stat tto_reset (DEVICE *dptr);
t_stat ttx_setmod (UNIT *uptr, int32 value); t_stat ttx_setmod (UNIT *uptr, int32 value);
extern t_stat sim_poll_kbd (void); extern t_stat sim_poll_kbd (void);
extern t_stat sim_putchar (int32 out); extern t_stat sim_putchar (int32 out);
static uint8 tto_consout[CONS_SIZE];
/* TTI data structures /* TTI data structures
@ -48,7 +51,7 @@ extern t_stat sim_putchar (int32 out);
ttx_mod TTI/TTO modifiers list 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[] = { REG tti_reg[] = {
{ ORDATA (BUF, tti_unit.buf, 8) }, { ORDATA (BUF, tti_unit.buf, 8) },
@ -59,9 +62,12 @@ REG tti_reg[] = {
{ DRDATA (POS, tti_unit.pos, 31), PV_LEFT }, { DRDATA (POS, tti_unit.pos, 31), PV_LEFT },
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT }, { DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
{ FLDATA (MODE, tti_unit.flags, UNIT_V_DASHER), REG_HRO }, { FLDATA (MODE, tti_unit.flags, UNIT_V_DASHER), REG_HRO },
{ FLDATA (CFLAG, tti_unit.flags, UNIT_V_CONS), REG_HRO },
{ NULL } }; { NULL } };
MTAB ttx_mod[] = { 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, 0, "ANSI", "ANSI", &ttx_setmod },
{ UNIT_DASHER, UNIT_DASHER, "Dasher", "DASHER", &ttx_setmod }, { UNIT_DASHER, UNIT_DASHER, "Dasher", "DASHER", &ttx_setmod },
{ 0 } }; { 0 } };
@ -79,7 +85,7 @@ DEVICE tti_dev = {
tto_reg TTO register list 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[] = { REG tto_reg[] = {
{ ORDATA (BUF, tto_unit.buf, 8) }, { ORDATA (BUF, tto_unit.buf, 8) },
@ -90,6 +96,8 @@ REG tto_reg[] = {
{ DRDATA (POS, tto_unit.pos, 31), PV_LEFT }, { DRDATA (POS, tto_unit.pos, 31), PV_LEFT },
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT }, { DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
{ FLDATA (MODE, tto_unit.flags, UNIT_V_DASHER), REG_HRO }, { 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 } }; { NULL } };
DEVICE tto_dev = { DEVICE tto_dev = {
@ -145,7 +153,8 @@ tti_unit.buf = 0;
dev_busy = dev_busy & ~INT_TTI; /* clear busy */ dev_busy = dev_busy & ~INT_TTI; /* clear busy */
dev_done = dev_done & ~INT_TTI; /* clear done, int */ dev_done = dev_done & ~INT_TTI; /* clear done, int */
int_req = int_req & ~INT_TTI; 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; 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); int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
c = tto_unit.buf & 0177; c = tto_unit.buf & 0177;
if ((tto_unit.flags & UNIT_DASHER) && (c == 031)) c = '\b'; 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; tto_unit.pos = tto_unit.pos + 1;
return SCPE_OK; return SCPE_OK;
} }
@ -195,6 +204,7 @@ dev_busy = dev_busy & ~INT_TTO; /* clear busy */
dev_done = dev_done & ~INT_TTO; /* clear done, int */ dev_done = dev_done & ~INT_TTO; /* clear done, int */
int_req = int_req & ~INT_TTO; int_req = int_req & ~INT_TTO;
sim_cancel (&tto_unit); /* deactivate unit */ sim_cancel (&tto_unit); /* deactivate unit */
tto_unit.filebuf = tto_consout; /* set buf pointer */
return SCPE_OK; return SCPE_OK;
} }

View file

@ -27,6 +27,7 @@
tti1 second terminal input tti1 second terminal input
tto1 second terminal output tto1 second terminal output
31-May-01 RMS Added multiconsole support
26-Apr-01 RMS Added device enable/disable support 26-Apr-01 RMS Added device enable/disable support
*/ */
@ -36,14 +37,13 @@
#define UNIT_DASHER (1 << UNIT_V_DASHER) #define UNIT_DASHER (1 << UNIT_V_DASHER)
extern int32 int_req, dev_busy, dev_done, dev_disable, iot_enb; 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 tti1_svc (UNIT *uptr);
t_stat tto1_svc (UNIT *uptr); t_stat tto1_svc (UNIT *uptr);
t_stat tti1_reset (DEVICE *dptr); t_stat tti1_reset (DEVICE *dptr);
t_stat tto1_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); t_stat ttx1_setmod (UNIT *uptr, int32 value);
extern t_stat sim_poll_kbd (void);
static uint8 tto1_consout[CONS_SIZE];
/* TTI1 data structures /* TTI1 data structures
@ -53,7 +53,7 @@ t_stat ttx1_setmod (UNIT *uptr, int32 value);
ttx1_mod TTI1/TTO1 modifiers list 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[] = { REG tti1_reg[] = {
{ ORDATA (BUF, tti1_unit.buf, 8) }, { ORDATA (BUF, tti1_unit.buf, 8) },
@ -63,12 +63,14 @@ REG tti1_reg[] = {
{ FLDATA (INT, int_req, INT_V_TTI1) }, { FLDATA (INT, int_req, INT_V_TTI1) },
{ DRDATA (POS, tti1_unit.pos, 31), PV_LEFT }, { DRDATA (POS, tti1_unit.pos, 31), PV_LEFT },
{ DRDATA (TIME, tti1_unit.wait, 24), REG_NZ + 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 (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 }, { FLDATA (*DEVENB, iot_enb, INT_V_TTI1), REG_HRO },
{ NULL } }; { NULL } };
MTAB ttx1_mod[] = { 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, 0, "ANSI", "ANSI", &ttx1_setmod },
{ UNIT_DASHER, UNIT_DASHER, "Dasher", "DASHER", &ttx1_setmod }, { UNIT_DASHER, UNIT_DASHER, "Dasher", "DASHER", &ttx1_setmod },
{ 0 } }; { 0 } };
@ -77,7 +79,7 @@ DEVICE tti1_dev = {
"TTI1", &tti1_unit, tti1_reg, ttx1_mod, "TTI1", &tti1_unit, tti1_reg, ttx1_mod,
1, 10, 31, 1, 8, 8, 1, 10, 31, 1, 8, 8,
NULL, NULL, &tti1_reset, NULL, NULL, &tti1_reset,
NULL, &tti1_attach, &tti1_detach }; NULL, NULL, NULL };
/* TTO1 data structures /* TTO1 data structures
@ -86,7 +88,7 @@ DEVICE tti1_dev = {
tto1_reg TTO1 register list 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[] = { REG tto1_reg[] = {
{ ORDATA (BUF, tto1_unit.buf, 8) }, { ORDATA (BUF, tto1_unit.buf, 8) },
@ -96,8 +98,9 @@ REG tto1_reg[] = {
{ FLDATA (INT, int_req, INT_V_TTO1) }, { FLDATA (INT, int_req, INT_V_TTO1) },
{ DRDATA (POS, tto1_unit.pos, 31), PV_LEFT }, { DRDATA (POS, tto1_unit.pos, 31), PV_LEFT },
{ DRDATA (TIME, tto1_unit.wait, 24), 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 }, { 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 }, { FLDATA (*DEVENB, iot_enb, INT_V_TTI1), REG_HRO },
{ NULL } }; { NULL } };
@ -134,16 +137,8 @@ t_stat tti1_svc (UNIT *uptr)
{ {
int32 temp; 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 */ sim_activate (&tti1_unit, tti1_unit.wait); /* continue poll */
if ((temp = getc (tti1_unit.fileref)) == EOF) { /* end of file? */ if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp; /* no char or error? */
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; }
tti1_unit.buf = temp & 0177; tti1_unit.buf = temp & 0177;
if ((tti1_unit.flags & UNIT_DASHER) && (tti1_unit.buf == '\r')) if ((tti1_unit.flags & UNIT_DASHER) && (tti1_unit.buf == '\r'))
tti1_unit.buf = '\n'; /* Dasher: cr -> nl */ tti1_unit.buf = '\n'; /* Dasher: cr -> nl */
@ -162,30 +157,10 @@ tti1_unit.buf = 0;
dev_busy = dev_busy & ~INT_TTI1; /* clear busy */ dev_busy = dev_busy & ~INT_TTI1; /* clear busy */
dev_done = dev_done & ~INT_TTI1; /* clear done, int */ dev_done = dev_done & ~INT_TTI1; /* clear done, int */
int_req = int_req & ~INT_TTI1; 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); sim_activate (&tti1_unit, tti1_unit.wait);
else sim_cancel (&tti1_unit);
return SCPE_OK; 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 */ /* Terminal output: IOT routine */
@ -212,19 +187,14 @@ return 0;
t_stat tto1_svc (UNIT *uptr) t_stat tto1_svc (UNIT *uptr)
{ {
int32 c ; int32 c, temp;
dev_busy = dev_busy & ~INT_TTO1; /* clear busy */ dev_busy = dev_busy & ~INT_TTO1; /* clear busy */
dev_done = dev_done | INT_TTO1; /* set done */ dev_done = dev_done | INT_TTO1; /* set done */
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable); 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; c = tto1_unit.buf & 0177;
if ((tto1_unit.flags & UNIT_DASHER) && (c == 031)) c = '\b'; if ((tto1_unit.flags & UNIT_DASHER) && (c == 031)) c = '\b';
if (putc (c, tto1_unit.fileref) == EOF) { if ((temp = sim_putcons (c, uptr)) != SCPE_OK) return temp;
perror ("TTO1 output error");
clearerr (tto1_unit.fileref);
return SCPE_IOERR; }
tto1_unit.pos = tto1_unit.pos + 1; tto1_unit.pos = tto1_unit.pos + 1;
return SCPE_OK; return SCPE_OK;
} }
@ -238,6 +208,7 @@ dev_busy = dev_busy & ~INT_TTO1; /* clear busy */
dev_done = dev_done & ~INT_TTO1; /* clear done, int */ dev_done = dev_done & ~INT_TTO1; /* clear done, int */
int_req = int_req & ~INT_TTO1; int_req = int_req & ~INT_TTO1;
sim_cancel (&tto1_unit); /* deactivate unit */ sim_cancel (&tto1_unit); /* deactivate unit */
tto1_unit.filebuf = tto1_consout; /* set buf pointer */
return SCPE_OK; return SCPE_OK;
} }

View file

@ -25,6 +25,7 @@
cpu KS10 central processor 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 29-Apr-01 RMS Fixed modifier naming conflict
Fixed XCTR/XCTRI, UMOVE/UMOVEM, BLTUB/BLTBU for ITS Fixed XCTR/XCTRI, UMOVE/UMOVEM, BLTUB/BLTBU for ITS
Added CLRCSH for ITS Added CLRCSH for ITS
@ -115,7 +116,7 @@
#define ILL_ADR_FLAG (1 << VASIZE) #define ILL_ADR_FLAG (1 << VASIZE)
#define save_ibkpt (cpu_unit.u3) #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) #define UNIT_MSIZE (1 << UNIT_V_MSIZE)
d10 *M = NULL; /* memory */ d10 *M = NULL; /* memory */
@ -241,6 +242,7 @@ REG cpu_reg[] = {
{ DRDATA (INDMAX, ind_max, 8), PV_LEFT + REG_NZ }, { DRDATA (INDMAX, ind_max, 8), PV_LEFT + REG_NZ },
{ DRDATA (XCTMAX, xct_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 (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 (BREAK, ibkpt_addr, VASIZE + 1) },
{ ORDATA (WRU, sim_int_char, 8) }, { ORDATA (WRU, sim_int_char, 8) },
{ FLDATA (STOP_ILL, stop_op0, 0) }, { FLDATA (STOP_ILL, stop_op0, 0) },
@ -248,8 +250,9 @@ REG cpu_reg[] = {
{ NULL } }; { NULL } };
MTAB cpu_mod[] = { MTAB cpu_mod[] = {
{ UNIT_ITS, 0, "Standard microcode", "STANDARD", NULL }, { UNIT_ITS+UNIT_T20V41, 0, "Standard microcode", "STANDARD", NULL },
{ UNIT_ITS, UNIT_ITS, "ITS microcode", "ITS", NULL }, { UNIT_ITS+UNIT_T20V41, UNIT_T20V41, "TOPS-20 V4.1", "TOPS20V41", NULL },
{ UNIT_ITS+UNIT_T20V41, UNIT_ITS, "ITS microcode", "ITS", NULL },
{ 0 } }; { 0 } };
DEVICE cpu_dev = { DEVICE cpu_dev = {

View file

@ -22,6 +22,9 @@
Except as contained in this notice, the name of Robert M Supnik shall not 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 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. 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 */ #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_V_ITS (UNIT_V_UF) /* ITS */
#define UNIT_ITS (1 << UNIT_V_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) #define ITS (cpu_unit.flags & UNIT_ITS)
/* Architectural constants */ /* Architectural constants */
@ -590,22 +595,24 @@ typedef int64 d10; /* PDP-10 data (36b) */
/* I/O system definitions, lifted from the PDP-11 simulator /* I/O system definitions, lifted from the PDP-11 simulator
Interrupt assignments, priority is right to left Interrupt assignments, priority is right to left
<7:0> = BR7 <3:0> = BR7
<15:8> = BR6 <7:4> = BR6
<23:16> = BR5 <19:8> = BR5
<30:24> = BR4 <30:20> = BR4
*/ */
#define INT_V_RP 8 /* RH11/RP,RM drives */ #define INT_V_RP 6 /* RH11/RP,RM drives */
#define INT_V_TU 9 /* RH11/TM03/TU45 */ #define INT_V_TU 7 /* RH11/TM03/TU45 */
#define INT_V_DZ 16 /* DZ11 */ #define INT_V_DZ0RX 16 /* DZ11 */
#define INT_V_DZ0TX 17
#define INT_V_PTR 24 /* PC11 */ #define INT_V_PTR 24 /* PC11 */
#define INT_V_PTP 25 #define INT_V_PTP 25
#define INT_V_LP20 26 /* LPT20 */ #define INT_V_LP20 26 /* LPT20 */
#define INT_RP (1u << INT_V_RP) #define INT_RP (1u << INT_V_RP)
#define INT_TU (1u << INT_V_TU) #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_PTR (1u << INT_V_PTR)
#define INT_PTP (1u << INT_V_PTP) #define INT_PTP (1u << INT_V_PTP)
#define INT_LP20 (1u << INT_V_LP20) #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_UB1 INT_RP /* on Unibus 1 */
#define INT_UB3 (0xFFFFFFFFu & ~INT_UB1) /* on Unibus 3 */ #define INT_UB3 (0xFFFFFFFFu & ~INT_UB1) /* on Unibus 3 */
#define INT_IPL7 0x000000FF /* int level masks */ #define INT_IPL7 0x0000000F /* int level masks */
#define INT_IPL6 0x0000FF00 #define INT_IPL6 0x000000F0
#define INT_IPL5 0x00FF0000 #define INT_IPL5 0x000FFF00
#define INT_IPL4 0x3F000000 #define INT_IPL4 0x3FF00000
#define VEC_PTR 0070 /* interrupt vectors */ #define VEC_PTR 0070 /* interrupt vectors */
#define VEC_PTP 0074 #define VEC_PTP 0074
#define VEC_TU 0224 #define VEC_TU 0224
#define VEC_RP 0254 #define VEC_RP 0254
#define VEC_DZ 0340 #define VEC_DZ0RX 0340
#define VEC_DZ0TX 0344
#define VEC_LP20 0754 #define VEC_LP20 0754

View file

@ -25,6 +25,7 @@
uba Unibus adapters uba Unibus adapters
1-Jun-01 RMS Updated DZ11 vectors
12-May-01 RMS Fixed typo 12-May-01 RMS Fixed typo
The KS10 uses the PDP-11 Unibus for its I/O, via adapters. While 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 d10 Read (a10 ea);
extern void pi_eval (); extern void pi_eval ();
extern t_stat dz_rd (int32 *data, int32 addr, int32 access); extern t_stat dz0_rd (int32 *data, int32 addr, int32 access);
extern t_stat dz_wr (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_rd (int32 *data, int32 addr, int32 access);
extern t_stat pt_wr (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); 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, { IO_UBA3+IO_TMBASE, IO_UBA3+IO_TMBASE+033, 0,
&tu_rd, &tu_wr }, /* mag tape */ &tu_rd, &tu_wr }, /* mag tape */
/* { IO_UBA3+IO_DZBASE, IO_UBA3+IO_DZBASE+07, INT_DZ, /* { 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, { IO_UBA3+IO_LPBASE, IO_UBA3+IO_LPBASE+017, 0,
&lp20_rd, &lp20_wr }, /* line printer */ &lp20_rd, &lp20_wr }, /* line printer */
{ IO_UBA3+IO_PTBASE, IO_UBA3+IO_PTBASE+07, INT_PTR, { IO_UBA3+IO_PTBASE, IO_UBA3+IO_PTBASE+07, INT_PTR,
@ -187,17 +188,17 @@ struct iolink iotable[] = {
/* Interrupt request to interrupt action map */ /* Interrupt request to interrupt action map */
int32 (*int_ack[32])() = { /* int ack routines */ 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, 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, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, &lp20_inta, NULL, NULL, NULL, NULL, NULL }; NULL, NULL, &lp20_inta, NULL, NULL, NULL, NULL, NULL };
/* Interrupt request to vector map */ /* Interrupt request to vector map */
int32 int_vec[32] = { /* int req to vector */ 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, 0, 0, 0, 0, 0, 0, 0, 0,
VEC_RP, VEC_TU, 0, 0, 0, 0, 0, 0, VEC_DZ0RX, VEC_DZ0TX, 0, 0, 0, 0, 0, 0,
VEC_DZ, 0, 0, 0, 0, 0, 0, 0,
VEC_PTR, VEC_PTP, VEC_LP20, 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 /* IO 710 (DEC) TIOE - test I/O word, skip if zero

View file

@ -25,6 +25,7 @@
pag KS10 pager 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 03-May-01 RMS Fixed bug in indirect page table pointer processing
29-Apr-01 RMS Added CLRCSH for ITS, fixed LPMR 29-Apr-01 RMS Added CLRCSH for ITS, fixed LPMR
@ -659,6 +660,8 @@ return FALSE;
t_bool wrcstm (a10 ea, int32 prv) t_bool wrcstm (a10 ea, int32 prv)
{ {
cstm = Read (ea, prv); cstm = Read (ea, prv);
if ((cpu_unit.flags & UNIT_T20V41) && (ea == 040127))
cstm = 0770000000000;
return FALSE; return FALSE;
} }

View file

@ -335,21 +335,21 @@ t_stat rp_detach (UNIT *uptr);
*/ */
UNIT rp_unit[] = { 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) }, (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) }, (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) }, (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) }, (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) }, (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) }, (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) }, (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) } }; (RP06_DTYPE << UNIT_V_DTYPE), RP06_SIZE) } };
REG rp_reg[] = { REG rp_reg[] = {

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings 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. 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 29-Apr-01 RMS Fixed format for RDPCST, WRPCST
Added CLRCSH for ITS Added CLRCSH for ITS
03-Apr-01 RMS Added support for loading EXE files 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_PC pointer to saved PC register descriptor
sim_emax number of words for examine sim_emax number of words for examine
sim_devices array of pointers to simulated devices 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_stop_messages array of pointers to stop messages
sim_load binary loader sim_load binary loader
*/ */
@ -69,6 +71,8 @@ DEVICE *sim_devices[] = {
&rp_dev, &tu_dev, &rp_dev, &tu_dev,
NULL }; NULL };
UNIT *sim_consoles = NULL;
const char *sim_stop_messages[] = { const char *sim_stop_messages[] = {
"Unknown error", "Unknown error",
"HALT instruction", "HALT instruction",

View file

@ -416,7 +416,7 @@ case 030: case 032: case 0130: case 0132:
Condition codes: Condition codes:
NZVC = set from src.lnt - dst.lnt NZVC = set from src.lnt - dst.lnt
Registers (MOVC, MOVTC only) Registers (MOVRC only)
R0 = max (0, src.len - dst.len) R0 = max (0, src.len - dst.len)
R1:R3 = 0 R1:R3 = 0
R4:R5 = unchanged R4:R5 = unchanged
@ -735,8 +735,7 @@ case 052: case 072: case 0152: case 0172:
ReadDstr (A2, &src2, op); /* get source2 */ ReadDstr (A2, &src2, op); /* get source2 */
N = Z = V = C = 0; N = Z = V = C = 0;
if (src1.sign != src2.sign) N = src1.sign; if (src1.sign != src2.sign) N = src1.sign;
else { else { t = CmpDstr (&src1, &src2); /* compare strings */
t = CmpDstr (&src1, &src2); /* compare strings */
if (t < 0) N = 1; if (t < 0) N = 1;
else if (t == 0) Z = 1; } else if (t == 0) Z = 1; }
if ((op & INLINE) == 0) /* if reg, clr reg */ if ((op & INLINE) == 0) /* if reg, clr reg */

View file

@ -25,6 +25,7 @@
cpu PDP-11 CPU (J-11 microprocessor) cpu PDP-11 CPU (J-11 microprocessor)
01-Jun-01 RMS Added DZ11 support
23-Apr-01 RMS Added RK611 support 23-Apr-01 RMS Added RK611 support
05-Apr-01 RMS Added TS11/TSV05 support 05-Apr-01 RMS Added TS11/TSV05 support
05-Mar-01 RMS Added clock calibration support 05-Mar-01 RMS Added clock calibration support
@ -325,7 +326,7 @@ struct iolink iotable[] = {
int32 int_vec[32] = { /* int req to vector */ int32 int_vec[32] = { /* int req to vector */
0, 0, 0, VEC_PIRQ, VEC_CLK, VEC_DTA, 0, VEC_PIRQ, 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, 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 }; VEC_LPT, 0, 0, 0, VEC_PIRQ, VEC_PIRQ, VEC_PIRQ, VEC_PIRQ };
int32 (*int_ack[32])() = { /* int ack routines */ int32 (*int_ack[32])() = { /* int ack routines */

View file

@ -26,6 +26,7 @@
The author gratefully acknowledges the help of Max Burnet, Megan Gentry, The author gratefully acknowledges the help of Max Burnet, Megan Gentry,
and John Wilson in resolving questions about the PDP-11 and John Wilson in resolving questions about the PDP-11
01-Jun-01 RMS Added DZ11 support
23-Apr-01 RMS Added RK611 support 23-Apr-01 RMS Added RK611 support
05-Apr-01 RMS Added TS11/TSV05 support 05-Apr-01 RMS Added TS11/TSV05 support
10-Feb-01 RMS Added DECtape support 10-Feb-01 RMS Added DECtape support
@ -240,7 +241,7 @@ typedef struct fpac fpac_t;
<3:0> = BR7, <3> = PIR7 <3:0> = BR7, <3> = PIR7
<7:4> = BR6, <7> = PIR6 <7:4> = BR6, <7> = PIR6
<19:8> = BR5, <15> = PIR5 <19:8> = BR5, <19> = PIR5
<28:20> = BR4, <28> = PIR4 <28:20> = BR4, <28> = PIR4
<29> = PIR3 <29> = PIR3
<30> = PIR2 <30> = PIR2
@ -258,6 +259,8 @@ typedef struct fpac fpac_t;
#define INT_V_RP 12 #define INT_V_RP 12
#define INT_V_TS 13 #define INT_V_TS 13
#define INT_V_HK 14 #define INT_V_HK 14
#define INT_V_DZ0RX 16
#define INT_V_DZ0TX 17
#define INT_V_PIR5 19 #define INT_V_PIR5 19
#define INT_V_TTI 20 #define INT_V_TTI 20
#define INT_V_TTO 21 #define INT_V_TTO 21
@ -280,6 +283,8 @@ typedef struct fpac fpac_t;
#define INT_RP (1u << INT_V_RP) #define INT_RP (1u << INT_V_RP)
#define INT_TS (1u << INT_V_TS) #define INT_TS (1u << INT_V_TS)
#define INT_HK (1u << INT_V_HK) #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_PIR5 (1u << INT_V_PIR5)
#define INT_PTR (1u << INT_V_PTR) #define INT_PTR (1u << INT_V_PTR)
#define INT_PTP (1u << INT_V_PTP) #define INT_PTP (1u << INT_V_PTP)
@ -315,6 +320,8 @@ typedef struct fpac fpac_t;
#define VEC_TS 0224 #define VEC_TS 0224
#define VEC_RP 0254 #define VEC_RP 0254
#define VEC_RX 0264 #define VEC_RX 0264
#define VEC_DZ0RX 0310
#define VEC_DZ0TX 0314
/* CPU and FPU macros */ /* CPU and FPU macros */

View file

@ -27,8 +27,8 @@
20-Apr-98 RMS Fixed bug in MODf integer truncation 20-Apr-98 RMS Fixed bug in MODf integer truncation
17-Apr-98 RMS Fixed bug in STCfi range check 17-Apr-98 RMS Fixed bug in STCfi range check
16-Apr-98 RMS Fixed bugs in STEXP, STCfi, round/pack 16-Apr-98 RMS Fixed bugs in STEXP, STCfi, round/pack
9-Apr-98 RMS Fixed bug in LDEXP 09-Apr-98 RMS Fixed bug in LDEXP
4-Apr-98 RMS Fixed bug in MODf condition codes 04-Apr-98 RMS Fixed bug in MODf condition codes
This module simulates the PDP-11 floating point unit (FP11 series). This module simulates the PDP-11 floating point unit (FP11 series).
It is called from the instruction decoder for opcodes 170000:177777. It is called from the instruction decoder for opcodes 170000:177777.

View file

@ -28,7 +28,7 @@
26-Apr-01 RMS Added device enable/disable support 26-Apr-01 RMS Added device enable/disable support
25-Mar-01 RMS Fixed block fill calculation 25-Mar-01 RMS Fixed block fill calculation
15-Feb-01 RMS Corrected bootstrap string 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 The RK11 is an eight drive cartridge disk subsystem. An RK05 drive
consists of 203 cylinders, each with 2 surfaces containing 12 sectors consists of 203 cylinders, each with 2 surfaces containing 12 sectors

View file

@ -28,9 +28,9 @@
26-Apr-01 RMS Added device enable/disable support 26-Apr-01 RMS Added device enable/disable support
25-Mar-01 RMS Fixed block fill calculation 25-Mar-01 RMS Fixed block fill calculation
15-Feb-01 RMS Corrected bootstrap string 15-Feb-01 RMS Corrected bootstrap string
12-Nov-97 RMS Added bad block table command. 12-Nov-97 RMS Added bad block table command
25-Nov-96 RMS Default units to autosize. 25-Nov-96 RMS Default units to autosize
29-Jun-96 RMS Added unit disable support. 29-Jun-96 RMS Added unit disable support
The RL11 is a four drive cartridge disk subsystem. An RL01 drive The RL11 is a four drive cartridge disk subsystem. An RL01 drive
consists of 256 cylinders, each with 2 surfaces containing 40 sectors consists of 256 cylinders, each with 2 surfaces containing 40 sectors

View file

@ -34,8 +34,8 @@
14-Apr-99 RMS Changed t_addr to unsigned 14-Apr-99 RMS Changed t_addr to unsigned
05-Oct-98 RMS Fixed bug, failing to interrupt on go error 05-Oct-98 RMS Fixed bug, failing to interrupt on go error
04-Oct-98 RMS Changed names to allow coexistence with RH/TU77 04-Oct-98 RMS Changed names to allow coexistence with RH/TU77
12-Nov-97 RMS Added bad block table command. 12-Nov-97 RMS Added bad block table command
10-Aug-97 RMS Fixed bugs in interrupt handling. 10-Aug-97 RMS Fixed bugs in interrupt handling
The "Massbus style" disks consisted of several different large The "Massbus style" disks consisted of several different large
capacity drives interfaced through a reasonably common (but not capacity drives interfaced through a reasonably common (but not

View file

@ -23,16 +23,17 @@
be used in advertising or otherwise to promote the sale, use or other dealings 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. 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 05-Apr-01 RMS Added support for TS11/TSV05
14-Mar-01 RMS Revised load/dump interface (again) 14-Mar-01 RMS Revised load/dump interface (again)
11-Feb-01 RMS Added DECtape support 11-Feb-01 RMS Added DECtape support
30-Oct-00 RMS Added support for examine to file 30-Oct-00 RMS Added support for examine to file
14-Apr-99 RMS Changed t_addr to unsigned 14-Apr-99 RMS Changed t_addr to unsigned
09-Nov-98 RMS Fixed assignments of ROR/ROL (John Wilson). 09-Nov-98 RMS Fixed assignments of ROR/ROL (John Wilson)
27-Oct-98 RMS V2.4 load interface. 27-Oct-98 RMS V2.4 load interface
08-Oct-98 RMS Fixed bug in bad block routine. 08-Oct-98 RMS Fixed bug in bad block routine
30-Mar-98 RMS Fixed bug in floating point display. 30-Mar-98 RMS Fixed bug in floating point display
12-Nov-97 RMS Added bad block table routine. 12-Nov-97 RMS Added bad block table routine
*/ */
#include "pdp11_defs.h" #include "pdp11_defs.h"
@ -58,6 +59,7 @@ extern int32 saved_PC;
sim_PC pointer to saved PC register descriptor sim_PC pointer to saved PC register descriptor
sim_emax number of words for examine sim_emax number of words for examine
sim_devices array of pointers to simulated devices 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_stop_messages array of pointers to stop messages
sim_load binary loader sim_load binary loader
*/ */
@ -79,6 +81,8 @@ DEVICE *sim_devices[] = {
&tm_dev, &ts_dev, &tm_dev, &ts_dev,
NULL }; NULL };
UNIT *sim_consoles = NULL;
const char *sim_stop_messages[] = { const char *sim_stop_messages[] = {
"Unknown error", "Unknown error",
"Red stack trap", "Red stack trap",

View file

@ -25,6 +25,9 @@
cpu PDP-4/7/9/15 central processor 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 26-Apr-01 RMS Added device enable/disable support
25-Jan-01 RMS Added DECtape support 25-Jan-01 RMS Added DECtape support
18-Dec-00 RMS Added PDP-9,-15 memm init register 18-Dec-00 RMS Added PDP-9,-15 memm init register
@ -46,7 +49,7 @@
all IORS I/O status register all IORS I/O status register
PDP-7, PDP-9 EXTM extend mode PDP-7, PDP-9 EXTM extend mode
PDP-15 BANKM bank 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 USMD user mode
PDP-9, PDP-15 BR bounds register PDP-9, PDP-15 BR bounds register
PDP-15 XR index register PDP-15 XR index register
@ -241,22 +244,33 @@
#define save_ibkpt (cpu_unit.u3) #define save_ibkpt (cpu_unit.u3)
#define UNIT_V_NOEAE (UNIT_V_UF) /* EAE absent */ #define UNIT_V_NOEAE (UNIT_V_UF) /* EAE absent */
#define UNIT_NOEAE (1 << UNIT_V_NOEAE) #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) #define UNIT_MSIZE (1 << UNIT_V_MSIZE)
#if defined (PDP4) #if defined (PDP4)
#define EAE_DFLT UNIT_NOEAE #define EAE_DFLT UNIT_NOEAE
#else #else
#define EAE_DFLT 0 #define EAE_DFLT 0
#endif #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 M[MAXMEMSIZE] = { 0 }; /* memory */
int32 saved_LAC = 0; /* link'AC */ int32 saved_LAC = 0; /* link'AC */
int32 saved_MQ = 0; /* MQ */ int32 saved_MQ = 0; /* MQ */
int32 saved_PC = 0; /* PC */ int32 saved_PC = 0; /* PC */
int32 int_req = 0; /* int requests */
int32 iors = 0; /* IORS */ int32 iors = 0; /* IORS */
int32 ion = 0; /* int on */ int32 ion = 0; /* int on */
int32 ion_defer = 0; /* int defer */ 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 */ int32 memm = 0; /* mem mode */
#if defined (PDP15) #if defined (PDP15)
int32 memm_init = 1; /* mem init */ 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_svc (UNIT *uptr);
t_stat cpu_set_size (UNIT *uptr, int32 value); t_stat cpu_set_size (UNIT *uptr, int32 value);
int32 upd_iors (void); 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 /* CPU data structures
@ -298,7 +336,7 @@ extern t_stat sim_activate (UNIT *uptr, int32 delay);
cpu_mod CPU modifier list 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) }; MAXMEMSIZE) };
REG cpu_reg[] = { REG cpu_reg[] = {
@ -320,7 +358,11 @@ REG cpu_reg[] = {
{ FLDATA (TRAPP, trap_pending, 0) }, { FLDATA (TRAPP, trap_pending, 0) },
{ FLDATA (EXTM, memm, 0) }, { FLDATA (EXTM, memm, 0) },
{ FLDATA (EMIRP, emir_pending, 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) }, { ORDATA (BR, BR, ADDRSIZE) },
{ FLDATA (USMD, usmd, 0) }, { FLDATA (USMD, usmd, 0) },
{ FLDATA (USMDBUF, usmdbuf, 0) }, { FLDATA (USMDBUF, usmdbuf, 0) },
@ -332,7 +374,11 @@ REG cpu_reg[] = {
{ FLDATA (EMIRP, emir_pending, 0) }, { FLDATA (EMIRP, emir_pending, 0) },
{ FLDATA (RESTP, rest_pending, 0) }, { FLDATA (RESTP, rest_pending, 0) },
{ FLDATA (PWRFL, int_req, INT_V_PWRFL) }, { 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 (XR, XR, 18) },
{ ORDATA (LR, LR, 18) }, { ORDATA (LR, LR, 18) },
{ ORDATA (BR, BR, ADDRSIZE) }, { ORDATA (BR, BR, ADDRSIZE) },
@ -349,6 +395,7 @@ REG cpu_reg[] = {
{ ORDATA (OLDPC, old_PC, ADDRSIZE), REG_RO }, { ORDATA (OLDPC, old_PC, ADDRSIZE), REG_RO },
{ FLDATA (STOP_INST, stop_inst, 0) }, { FLDATA (STOP_INST, stop_inst, 0) },
{ FLDATA (NOEAE, cpu_unit.flags, UNIT_V_NOEAE), REG_HRO }, { 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 }, { DRDATA (XCT_MAX, xct_max, 8), PV_LEFT + REG_NZ },
{ ORDATA (BREAK, ibkpt_addr, ADDRSIZE + 1) }, { ORDATA (BREAK, ibkpt_addr, ADDRSIZE + 1) },
{ ORDATA (WRU, sim_int_char, 8) }, { ORDATA (WRU, sim_int_char, 8) },
@ -361,6 +408,10 @@ MTAB cpu_mod[] = {
{ UNIT_NOEAE, 0, "EAE", "EAE", NULL }, { UNIT_NOEAE, 0, "EAE", "EAE", NULL },
#else #else
{ UNIT_MSIZE, 4096, NULL, "4K", &cpu_set_size }, { 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 #endif
{ UNIT_MSIZE, 8192, NULL, "8K", &cpu_set_size }, { UNIT_MSIZE, 8192, NULL, "8K", &cpu_set_size },
#if (MAXMEMSIZE > 8192) #if (MAXMEMSIZE > 8192)
@ -391,6 +442,7 @@ t_stat sim_instr (void)
{ {
extern int32 sim_interval; extern int32 sim_interval;
register int32 PC, LAC, MQ; register int32 PC, LAC, MQ;
int32 api_int, api_cycle, skp;
int32 iot_data, device, pulse; int32 iot_data, device, pulse;
t_stat reason; t_stat reason;
extern UNIT clk_unit; extern UNIT clk_unit;
@ -422,94 +474,15 @@ extern int32 mt (int32 pulse, int32 AC);
extern int32 dt75 (int32 pulse, int32 AC); extern int32 dt75 (int32 pulse, int32 AC);
extern int32 dt76 (int32 pulse, int32 AC); extern int32 dt76 (int32 pulse, int32 AC);
#endif #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) | \ #define JMS_WORD(t) (((LAC & 01000000) >> 1) | ((memm & 1) << 16) | \
(((t) & 1) << 15) | ((PC) & 077777)) (((t) & 1) << 15) | ((PC) & 077777))
#define INCR_ADDR(x) (((x) & epcmask) | (((x) + 1) & damask)) #define INCR_ADDR(x) (((x) & epcmask) | (((x) + 1) & damask))
#define SEXT(x) ((int) (((x) & 0400000)? (x) | ~0777777: (x) & 0777777)) #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 /* The following macros implement addressing. They account for autoincrement
addressing, extended addressing, and memory protection, if it exists. addressing, extended addressing, and memory protection, if it exists.
@ -563,7 +536,7 @@ if (PC == ibkpt_addr) { /* breakpoint? */
if (!MEM_ADDR_OK (x)) { \ if (!MEM_ADDR_OK (x)) { \
nexm = prvn = trap_pending = 1; \ nexm = prvn = trap_pending = 1; \
break; } \ break; } \
if ((x) >= BR) { \ if ((x) < BR) { \
prvn = trap_pending = 1; \ prvn = trap_pending = 1; \
break; } } \ break; } } \
if (!MEM_ADDR_OK (x)) nexm = 1 if (!MEM_ADDR_OK (x)) nexm = 1
@ -604,7 +577,7 @@ if (PC == ibkpt_addr) { /* breakpoint? */
if (!MEM_ADDR_OK (x)) { \ if (!MEM_ADDR_OK (x)) { \
nexm = prvn = trap_pending = 1; \ nexm = prvn = trap_pending = 1; \
break; } \ break; } \
if ((x) >= BR) { \ if ((x) < BR) { \
prvn = trap_pending = 1; \ prvn = trap_pending = 1; \
break; } } \ break; } } \
if (!MEM_ADDR_OK (x)) nexm = 1 if (!MEM_ADDR_OK (x)) nexm = 1
@ -613,20 +586,133 @@ if (PC == ibkpt_addr) { /* breakpoint? */
if (!MEM_ADDR_OK (x)) break if (!MEM_ADDR_OK (x)) break
#endif #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 */ /* 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 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 */ if (!ion_defer) usmd = usmdbuf; /* no IOT? load usmd */
#endif #endif
if (ion_defer) ion_defer = ion_defer - 1; /* count down defer */
xct_count = 0; /* track nested XCT's */ 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 */ 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 */ MA = (MA & epcmask) | (IR & damask); /* effective address */
switch ((IR >> 13) & 037) { /* decode IR<0:4> */ switch ((IR >> 13) & 037) { /* decode IR<0:4> */
@ -752,13 +838,13 @@ case 020: /* XCT, dir */
#if defined (PDP9) #if defined (PDP9)
ion_defer = 1; /* defer intr */ ion_defer = 1; /* defer intr */
#endif #endif
IR = M[MA]; /* get instruction */
goto xct_instr; /* go execute */ goto xct_instr; /* go execute */
/* CAL: opcode 00 /* CAL: opcode 00
On the PDP-4 and PDP-7, CAL (I) is exactly the same as JMS (I) 20 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 On the PDP-15, CAL goes to absolute 20, regardless of mode
*/ */
@ -771,6 +857,9 @@ case 001: case 000: /* CAL */
#endif #endif
#if defined (PDP9) || defined (PDP15) #if defined (PDP9) || defined (PDP15)
usmd = 0; /* clear user mode */ 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 #endif
if (IR & 0020000) { INDIRECT; } /* indirect? */ if (IR & 0020000) { INDIRECT; } /* indirect? */
CHECK_ADDR_W (MA); CHECK_ADDR_W (MA);
@ -800,7 +889,7 @@ case 004: /* JMS, dir */
*/ */
case 031: /* JMP, indir */ case 031: /* JMP, indir */
CHECK_AUTO_INC; /* check auto inc */ CHECK_AUTO_INC; /* check auto inc */
#if defined (PDP7) || defined (PDP9) #if defined (PDP7) || defined (PDP9)
if (emir_pending && (((M[MA] >> 16) & 1) == 0)) memm = 0; if (emir_pending && (((M[MA] >> 16) & 1) == 0)) memm = 0;
#endif #endif
@ -825,55 +914,56 @@ case 037: /* OPR, indir */
break; break;
case 036: /* OPR, dir */ case 036: /* OPR, dir */
skp = 0; /* assume no skip */
switch ((IR >> 6) & 017) { /* decode IR<8:11> */ switch ((IR >> 6) & 017) { /* decode IR<8:11> */
case 0: /* nop */ case 0: /* nop */
break; break;
case 1: /* SMA */ case 1: /* SMA */
if ((LAC & 0400000) != 0) PC = INCR_ADDR (PC); if ((LAC & 0400000) != 0) skp = 1;
break; break;
case 2: /* SZA */ case 2: /* SZA */
if ((LAC & 0777777) == 0) PC = INCR_ADDR (PC); if ((LAC & 0777777) == 0) skp = 1;
break; break;
case 3: /* SZA | SMA */ case 3: /* SZA | SMA */
if (((LAC & 0777777) == 0) || ((LAC & 0400000) != 0)) if (((LAC & 0777777) == 0) || ((LAC & 0400000) != 0))
PC = INCR_ADDR (PC); skp = 1;
break; break;
case 4: /* SNL */ case 4: /* SNL */
if (LAC >= 01000000) PC = INCR_ADDR (PC); if (LAC >= 01000000) skp = 1;
break; break;
case 5: /* SNL | SMA */ case 5: /* SNL | SMA */
if (LAC >= 0400000) PC = INCR_ADDR (PC); if (LAC >= 0400000) skp = 1;
break; break;
case 6: /* SNL | SZA */ case 6: /* SNL | SZA */
if ((LAC >= 01000000) || (LAC == 0)) PC = INCR_ADDR (PC); if ((LAC >= 01000000) || (LAC == 0)) skp = 1;
break; break;
case 7: /* SNL | SZA | SMA */ case 7: /* SNL | SZA | SMA */
if ((LAC >= 0400000) || (LAC == 0)) PC = INCR_ADDR (PC); if ((LAC >= 0400000) || (LAC == 0)) skp = 1;
break; break;
case 010: /* SKP */ case 010: /* SKP */
PC = INCR_ADDR (PC); skp = 1;
break; break;
case 011: /* SPA */ case 011: /* SPA */
if ((LAC & 0400000) == 0) PC = INCR_ADDR (PC); if ((LAC & 0400000) == 0) skp = 1;
break; break;
case 012: /* SNA */ case 012: /* SNA */
if ((LAC & 0777777) != 0) PC = INCR_ADDR (PC); if ((LAC & 0777777) != 0) skp = 1;
break; break;
case 013: /* SNA & SPA */ case 013: /* SNA & SPA */
if (((LAC & 0777777) != 0) && ((LAC & 0400000) == 0)) if (((LAC & 0777777) != 0) && ((LAC & 0400000) == 0))
PC = INCR_ADDR (PC); skp = 1;
break; break;
case 014: /* SZL */ case 014: /* SZL */
if (LAC < 01000000) PC = INCR_ADDR (PC); if (LAC < 01000000) skp = 1;
break; break;
case 015: /* SZL & SPA */ case 015: /* SZL & SPA */
if (LAC < 0400000) PC = INCR_ADDR (PC); if (LAC < 0400000) skp = 1;
break; break;
case 016: /* SZL & SNA */ case 016: /* SZL & SNA */
if ((LAC < 01000000) && (LAC != 0)) PC = INCR_ADDR (PC); if ((LAC < 01000000) && (LAC != 0)) skp = 1;
break; break;
case 017: /* SZL & SNA & SPA */ 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 */ break; } /* end switch skips */
/* OPR, continued */ /* OPR, continued */
@ -968,6 +1058,7 @@ case 036: /* OPR, dir */
if (IR & 0000040) { /* HLT */ if (IR & 0000040) { /* HLT */
if (usmd) prvn = trap_pending = 1; if (usmd) prvn = trap_pending = 1;
else reason = STOP_HALT; } else reason = STOP_HALT; }
if (skp && !prvn) PC = INCR_ADDR (PC); /* if skip, inc PC */
break; /* end OPR */ break; /* end OPR */
/* EAE: opcode 64 /* EAE: opcode 64
@ -1169,7 +1260,11 @@ case 035: /* index operates */
703301 undefined TTS TTS TTS 703301 undefined TTS TTS TTS
703341 undefined SKP7 SKP7 SPCO 703341 undefined SKP7 SKP7 SPCO
703302 undefined CAF CAF CAF 703302 undefined CAF CAF CAF
703304 undefined undefined DBK DBK
703344 undefined undefined DBR DBR 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 707701 undefined SEM SEM undefined
707741 undefined undefined undefined SKP15 707741 undefined undefined undefined SKP15
707761 undefined undefined undefined SBA 707761 undefined undefined undefined SBA
@ -1203,10 +1298,11 @@ case 034: /* IOT */
else if (pulse == 042) ion = ion_defer = 1; /* ION */ else if (pulse == 042) ion = ion_defer = 1; /* ION */
else iot_data = clk (pulse, iot_data); else iot_data = clk (pulse, iot_data);
break; break;
#endif
/* PDP-7 system IOT's */ /* PDP-7 system IOT's */
#elif defined (PDP7) #if defined (PDP7)
switch (device) { /* decode IR<6:11> */ switch (device) { /* decode IR<6:11> */
case 0: /* CPU and clock */ case 0: /* CPU and clock */
if (pulse == 002) ion = 0; /* IOF */ if (pulse == 002) ion = 0; /* IOF */
@ -1226,10 +1322,11 @@ case 034: /* IOT */
memm = emir_pending = 1; /* ext on, restore */ memm = emir_pending = 1; /* ext on, restore */
else if (pulse == 004) memm = 0; /* LEM */ else if (pulse == 004) memm = 0; /* LEM */
break; 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 */ ion_defer = 1; /* delay interrupts */
switch (device) { /* decode IR<6:11> */ switch (device) { /* decode IR<6:11> */
case 000: /* CPU and clock */ case 000: /* CPU and clock */
@ -1242,7 +1339,7 @@ case 034: /* IOT */
else if ((pulse == 041) && nexm) PC = INCR_ADDR (PC); else if ((pulse == 041) && nexm) PC = INCR_ADDR (PC);
else if (pulse == 002) prvn = 0; else if (pulse == 002) prvn = 0;
else if (pulse == 042) usmdbuf = 1; 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; else if (pulse == 044) nexm = 0;
break; break;
case 032: /* power fail */ case 032: /* power fail */
@ -1253,7 +1350,26 @@ case 034: /* IOT */
if ((pulse == 001) || (pulse == 041)) PC = INCR_ADDR (PC); if ((pulse == 001) || (pulse == 041)) PC = INCR_ADDR (PC);
else if (pulse == 002) reset_all (0); /* CAF */ 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; 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 */ case 077: /* extended memory */
if ((pulse == 001) && memm) PC = INCR_ADDR (PC); if ((pulse == 001) && memm) PC = INCR_ADDR (PC);
else if (pulse == 002) memm = 1; /* EEM */ else if (pulse == 002) memm = 1; /* EEM */
@ -1261,34 +1377,8 @@ case 034: /* IOT */
memm = emir_pending = 1; /* ext on, restore */ memm = emir_pending = 1; /* ext on, restore */
else if (pulse == 004) memm = 0; /* LEM */ else if (pulse == 004) memm = 0; /* LEM */
break; break;
#endif
/* PDP-15 system IOT's */ #if defined (PDP15)
#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;
case 077: /* bank addressing */ case 077: /* bank addressing */
if ((pulse == 041) || ((pulse == 061) && memm)) if ((pulse == 041) || ((pulse == 061) && memm))
PC = INCR_ADDR (PC); /* SKP15, SBA */ PC = INCR_ADDR (PC); /* SKP15, SBA */
@ -1315,6 +1405,14 @@ case 034: /* IOT */
case 4: /* TTO */ case 4: /* TTO */
iot_data = tto (pulse, iot_data); iot_data = tto (pulse, iot_data);
break; 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) #if defined (DRM)
case 060: /* drum */ case 060: /* drum */
if (dev_enb & INT_DRM) iot_data = drm60 (pulse, iot_data); if (dev_enb & INT_DRM) iot_data = drm60 (pulse, iot_data);
@ -1377,8 +1475,13 @@ case 034: /* IOT */
LAC = LAC | (iot_data & 0777777); LAC = LAC | (iot_data & 0777777);
if (iot_data & IOT_SKP) PC = INCR_ADDR (PC); if (iot_data & IOT_SKP) PC = INCR_ADDR (PC);
if (iot_data >= IOT_REASON) reason = iot_data >> IOT_V_REASON; if (iot_data >= IOT_REASON) reason = iot_data >> IOT_V_REASON;
api_int = api_eval (); /* eval API */
break; /* end case IOT */ break; /* end case IOT */
} /* end switch opcode */ } /* 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 */ } /* end while */
/* Simulation halted */ /* Simulation halted */
@ -1390,20 +1493,21 @@ iors = upd_iors (); /* get IORS */
return reason; return reason;
} }
/* Reset routine */ /* Evaluate API */
t_stat cpu_reset (DEVICE *dptr) int32 api_eval (void)
{ {
SC = 0; int32 i, hi;
eae_ac_sign = 0; static const uint32 api_mask[4] = {
ion = ion_defer = 0; API_L0, API_L1, API_L2, API_L3 };
int_req = int_req & ~INT_PWRFL;
BR = 0; if (api_enb == 0) return 0; /* off? no req */
usmd = usmdbuf = 0; api_req = api_req & ~0360; /* clr req<0:3> */
memm = memm_init; for (i = 0; i < 4; i++) {
nexm = prvn = trap_pending = 0; if (int_req & api_mask[i]) api_req = api_req | (0200 >> i); }
emir_pending = rest_pending = 0; hi = api_ffo[api_req & 0377]; /* find hi req */
return cpu_svc (&cpu_unit); if (hi < api_ffo[api_act & 0377]) return (hi + 1);
return 0;
} }
/* Process IORS instruction */ /* Process IORS instruction */
@ -1441,6 +1545,23 @@ return (ion? IOS_ION: 0) |
std_iors () | lpt_iors (); 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 */ /* Memory examine */
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw)

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings 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. 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 21-Jan-01 RMS Added DECtape support
14-Apr-99 RMS Changed t_addr to unsigned 14-Apr-99 RMS Changed t_addr to unsigned
02-Jan-96 RMS Added fixed head and moving head disks 02-Jan-96 RMS Added fixed head and moving head disks
@ -54,21 +55,23 @@
Type 24 serial drum Type 24 serial drum
PDP9 32K KE09A EAE KSR-33 Teletype PDP9 32K KE09A EAE KSR-33 Teletype
KG09B mem extension PC09A paper tape reader and punch KF09A auto pri intr PC09A paper tape reader and punch
KP09A power detection integral real time clock KG09B mem extension integral real time clock
KX09A mem protection Type 647D/E line printer (sixbit) KP09A power detection Type 647D/E line printer (sixbit)
RF09/RS09 fixed head disk KX09A mem protection RF09/RS09 fixed head disk
TC59 magnetic tape TC59 magnetic tape
TC02/TU55 DECtape TC02/TU55 DECtape
LT09A second Teletype
PDP15 128K KE15 EAE KSR-35 Teletype PDP15 128K KE15 EAE KSR-35 Teletype
KF15 power detection PC15 paper tape reader and punch KA15 auto pri intr PC15 paper tape reader and punch
KM15 mem protection KW15 real time clock KF15 power detection KW15 real time clock
??KT15 mem relocation LP15 line printer KM15 mem protection LP15 line printer
RP15 disk pack ??KT15 mem relocation RP15 disk pack
RF15/RF09 fixed head disk RF15/RF09 fixed head disk
TC59D magnetic tape TC59D magnetic tape
TC15/TU56 DECtape TC15/TU56 DECtape
LT15 second Teletype
??Indicates not implemented. The PDP-4 manual refers to both an EAE ??Indicates not implemented. The PDP-4 manual refers to both an EAE
??and a memory extension control; there is no documentation on either. ??and a memory extension control; there is no documentation on either.
@ -84,6 +87,7 @@
#define STOP_HALT 2 /* HALT */ #define STOP_HALT 2 /* HALT */
#define STOP_IBKPT 3 /* breakpoint */ #define STOP_IBKPT 3 /* breakpoint */
#define STOP_XCT 4 /* nested XCT's */ #define STOP_XCT 4 /* nested XCT's */
#define STOP_API 5 /* invalid API int */
/* Peripheral configuration */ /* Peripheral configuration */
@ -101,6 +105,8 @@
#define RF 0 /* fixed head disk */ #define RF 0 /* fixed head disk */
#define MTA 0 /* magtape */ #define MTA 0 /* magtape */
#define DTA 0 /* DECtape */ #define DTA 0 /* DECtape */
#define TTY1 0 /* second Teletype */
#define BRMASK 0076000 /* bounds mask */
#elif defined (PDP15) #elif defined (PDP15)
#define ADDRSIZE 17 #define ADDRSIZE 17
#define LP15 0 /* ASCII printer */ #define LP15 0 /* ASCII printer */
@ -108,6 +114,8 @@
#define RP 0 /* disk pack */ #define RP 0 /* disk pack */
#define MTA 0 /* magtape */ #define MTA 0 /* magtape */
#define DTA 0 /* DECtape */ #define DTA 0 /* DECtape */
#define TTY1 0 /* second Teletype */
#define BRMASK 0377400 /* bounds mask */
#endif #endif
/* Memory */ /* Memory */
@ -125,6 +133,7 @@
#define LINK (DMASK + 1) /* link */ #define LINK (DMASK + 1) /* link */
#define LACMASK (LINK | DMASK) /* link + data */ #define LACMASK (LINK | DMASK) /* link + data */
#define SIGN 0400000 /* sign bit */ #define SIGN 0400000 /* sign bit */
#define OP_JMS 0100000 /* JMS */
#define OP_JMP 0600000 /* JMP */ #define OP_JMP 0600000 /* JMP */
#define OP_HLT 0740040 /* HLT */ #define OP_HLT 0740040 /* HLT */
@ -144,19 +153,55 @@
If flag based, API is hard to implement; if API based, IORS requires If flag based, API is hard to implement; if API based, IORS requires
extra code for implementation. I've chosen an API based model. 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. Interrupt system, priority is left to right.
<30:28> = priority 0 <30:28> = priority 0
<27:20> = priority 1 <27:20> = priority 1
<19:14> = priority 2 <19:12> = priority 2
<13:10> = priority 3 <11:8> = priority 3
<9:4> = PI only <7:0> = PI only
<3> = priority 4 (software)
<2> = priority 5 (software)
<1> = priority 6 (software)
<0> = priority 7 (software)
*/ */
#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_PWRFL 30 /* powerfail */
#define INT_V_DTA 27 /* DECtape */ #define INT_V_DTA 27 /* DECtape */
#define INT_V_MTA 26 /* magtape */ #define INT_V_MTA 26 /* magtape */
@ -166,14 +211,12 @@
#define INT_V_PTR 19 /* paper tape reader */ #define INT_V_PTR 19 /* paper tape reader */
#define INT_V_LPT 18 /* line printer */ #define INT_V_LPT 18 /* line printer */
#define INT_V_LPTSPC 17 /* line printer spc */ #define INT_V_LPTSPC 17 /* line printer spc */
#define INT_V_CLK 13 /* clock */ #define INT_V_CLK 11 /* clock */
#define INT_V_TTI 9 /* keyboard */ #define INT_V_TTI1 10 /* LT15 keyboard */
#define INT_V_TTO 8 /* terminal */ #define INT_V_TTO1 9 /* LT15 output */
#define INT_V_PTP 7 /* paper tape punch */ #define INT_V_TTI 7 /* console keyboard */
#define INT_V_SW4 3 /* software 4 */ #define INT_V_TTO 6 /* console output */
#define INT_V_SW5 2 /* software 5 */ #define INT_V_PTP 5 /* paper tape punch */
#define INT_V_SW6 1 /* software 6 */
#define INT_V_SW7 0 /* software 7 */
#define INT_PWRFL (1 << INT_V_PWRFL) #define INT_PWRFL (1 << INT_V_PWRFL)
#define INT_DTA (1 << INT_V_DTA) #define INT_DTA (1 << INT_V_DTA)
@ -185,13 +228,24 @@
#define INT_LPT (1 << INT_V_LPT) #define INT_LPT (1 << INT_V_LPT)
#define INT_LPTSPC (1 << INT_V_LPTSPC) #define INT_LPTSPC (1 << INT_V_LPTSPC)
#define INT_CLK (1 << INT_V_CLK) #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_TTI (1 << INT_V_TTI)
#define INT_TTO (1 << INT_V_TTO) #define INT_TTO (1 << INT_V_TTO)
#define INT_PTP (1 << INT_V_PTP) #define INT_PTP (1 << INT_V_PTP)
#define INT_SW4 (1 << INT_V_SW4)
#define INT_SW5 (1 << INT_V_SW5) #define ACH_SWRE 040 /* API channels */
#define INT_SW6 (1 << INT_V_SW6) #define ACH_PWRFL 052
#define INT_SW7 (1 << INT_V_SW7) #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 /* I/O status flags for the IORS instruction

View file

@ -26,6 +26,7 @@
drm (PDP-7) Type 24 serial drum drm (PDP-7) Type 24 serial drum
(PDP-9) RM09 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 26-Apr-01 RMS Added device enable/disable support
14-Apr-99 RMS Changed t_addr to unsigned 14-Apr-99 RMS Changed t_addr to unsigned
*/ */
@ -108,14 +109,13 @@ int32 drm61 (int32 pulse, int32 AC)
{ {
int32 t; int32 t;
if (pulse == 001) return (int_req & INT_DRM)? IOT_SKP + AC: AC; /* DRSF */ if (pulse & 001) { /* DRSF */
if (pulse == 002) { /* DRCF */ if (int_req & INT_DRM) AC = AC | IOT_SKP; }
if (pulse & 002) { /* DRCF */
int_req = int_req & ~INT_DRM; /* clear done */ int_req = int_req & ~INT_DRM; /* clear done */
drm_err = 0; } /* clear error */ drm_err = 0; } /* clear error */
if (pulse == 006) { /* DRSS */ if (pulse & 004) { /* DRSS */
drm_da = AC & DRM_SMASK; /* load sector # */ 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); t = ((drm_da % DRM_NUMSC) * DRM_NUMWDS) - GET_POS (drm_time);
if (t < 0) t = t + DRM_NUMWDT; /* wrap around? */ if (t < 0) t = t + DRM_NUMWDT; /* wrap around? */
sim_activate (&drm_unit, t * drm_time); } /* schedule op */ sim_activate (&drm_unit, t * drm_time); } /* schedule op */
@ -126,8 +126,9 @@ int32 drm62 (int32 pulse, int32 AC)
{ {
int32 t; int32 t;
if (pulse == 001) return (drm_err)? AC: IOT_SKP + AC; /* DRSN */ if (pulse & 001) { /* DRSN */
if (pulse == 004) { /* DRCS */ if (drm_err == 0) AC = AC | IOT_SKP; }
if (pulse & 004) { /* DRCS */
int_req = int_req & ~INT_DRM; /* clear done */ int_req = int_req & ~INT_DRM; /* clear done */
drm_err = 0; /* clear error */ drm_err = 0; /* clear error */
t = ((drm_da % DRM_NUMSC) * DRM_NUMWDS) - GET_POS (drm_time); t = ((drm_da % DRM_NUMSC) * DRM_NUMWDS) - GET_POS (drm_time);

View file

@ -187,7 +187,7 @@ if (pulse == 042) { /* DSCD */
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */ if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */
else rf_sta = 0; else rf_sta = 0;
rf_updsta (0); } rf_updsta (0); }
if (pulse == 0062) { /* DSRS */ if (pulse == 062) { /* DSRS */
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */ if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */
return rf_updsta (0); } return rf_updsta (0); }
return AC; return AC;

View file

@ -29,6 +29,8 @@
tto teleprinter tto teleprinter
clk clock 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 10-Mar-01 RMS Added funny format loader support
05-Mar-01 RMS Added clock calibration support 05-Mar-01 RMS Added clock calibration support
22-Dec-00 RMS Added PDP-9/15 half duplex 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 tti_state = 0;
int32 tto_state = 0; int32 tto_state = 0;
int32 clk_tps = 60; int32 clk_tps = 60;
#if defined (TTY1)
static uint8 tto_consout[CONS_SIZE];
#endif
t_stat clk_svc (UNIT *uptr); t_stat clk_svc (UNIT *uptr);
t_stat ptr_svc (UNIT *uptr); t_stat ptr_svc (UNIT *uptr);
t_stat ptp_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) #define UNIT_HDX (1 << UNIT_V_HDX)
#if defined (PDP4) || defined (PDP7) #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 #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 #endif
REG tti_reg[] = { REG tti_reg[] = {
@ -212,9 +218,16 @@ REG tti_reg[] = {
#endif #endif
{ DRDATA (POS, tti_unit.pos, 31), PV_LEFT }, { DRDATA (POS, tti_unit.pos, 31), PV_LEFT },
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + 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 } }; { NULL } };
MTAB tti_mod[] = { 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) #if !defined (KSR28)
{ UNIT_UC, 0, "lower case", "LC", NULL }, { UNIT_UC, 0, "lower case", "LC", NULL },
{ UNIT_UC, UNIT_UC, "upper case", "UC", 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) #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[] = { REG tto_reg[] = {
{ ORDATA (BUF, tto_unit.buf, TTO_WIDTH) }, { ORDATA (BUF, tto_unit.buf, TTO_WIDTH) },
@ -268,10 +281,25 @@ REG tto_reg[] = {
#endif #endif
{ DRDATA (POS, tto_unit.pos, 31), PV_LEFT }, { DRDATA (POS, tto_unit.pos, 31), PV_LEFT },
{ DRDATA (TIME, tto_unit.wait, 24), 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 } }; { 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 = { DEVICE tto_dev = {
"TTO", &tto_unit, tto_reg, NULL, "TTO", &tto_unit, tto_reg, tto_mod,
1, 10, 31, 1, 8, 8, 1, 10, 31, 1, 8, 8,
NULL, NULL, &tto_reset, NULL, NULL, &tto_reset,
NULL, NULL, NULL }; NULL, NULL, NULL };
@ -280,14 +308,16 @@ DEVICE tto_dev = {
int32 clk (int32 pulse, int32 AC) int32 clk (int32 pulse, int32 AC)
{ {
if (pulse == 001) return (int_req & INT_CLK)? IOT_SKP + AC: AC; /* CLSF */ if (pulse & 001) { /* CLSF */
if (pulse == 004) clk_reset (&clk_dev); /* CLOF */ if (int_req & INT_CLK) AC = AC | IOT_SKP; }
else if (pulse == 044) { /* CLON */ if (pulse & 004) { /* CLON/CLOF */
if (pulse & 040) { /* CLON */
int_req = int_req & ~INT_CLK; /* clear flag */ int_req = int_req & ~INT_CLK; /* clear flag */
clk_state = 1; /* clock on */ clk_state = 1; /* clock on */
if (!sim_is_active (&clk_unit)) /* already on? */ if (!sim_is_active (&clk_unit)) /* already on? */
sim_activate (&clk_unit, /* start */ sim_activate (&clk_unit, /* start, calibr */
sim_rtc_init (clk_unit.wait)); } /* init calibr */ sim_rtc_init (clk_unit.wait)); }
else clk_reset (&clk_dev); } /* CLOF */
return AC; return AC;
} }
@ -335,10 +365,11 @@ return ((int_req & INT_CLK)? IOS_CLK: 0) |
int32 ptr (int32 pulse, int32 AC) 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 */ if (pulse & 002) { /* RRB, RCF */
int_req = int_req & ~INT_PTR; /* clear done */ 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 */ if (pulse & 004) { /* RSA, RSB */
ptr_state = (pulse & 040)? 18: 0; /* set mode */ ptr_state = (pulse & 040)? 18: 0; /* set mode */
int_req = int_req & ~INT_PTR; /* clear done */ int_req = int_req & ~INT_PTR; /* clear done */
@ -587,7 +618,8 @@ return SCPE_ARG;
int32 ptp (int32 pulse, int32 AC) 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 & 002) int_req = int_req & ~INT_PTP; /* PCF */
if (pulse & 004) { /* PSA, PSB, PLS */ if (pulse & 004) { /* PSA, PSB, PLS */
int_req = int_req & ~INT_PTP; /* clear flag */ int_req = int_req & ~INT_PTP; /* clear flag */
@ -648,10 +680,11 @@ return detach_unit (uptr);
int32 tti (int32 pulse, int32 AC) int32 tti (int32 pulse, int32 AC)
{ {
if (pulse == 001) return (int_req & INT_TTI)? IOT_SKP + AC: AC; /* KSF */ if (pulse & 001) { /* KSF */
if (pulse == 002) { /* KRB */ if (int_req & INT_TTI) AC = AC | IOT_SKP; }
if (pulse & 002) { /* KRB */
int_req = int_req & ~INT_TTI; /* clear flag */ 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; 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? */ if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp; /* no char or error? */
temp = temp & 0177; temp = temp & 0177;
if ((tti_unit.flags & UNIT_UC) && islower (temp)) temp = toupper (temp); 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 */ tti_unit.buf = temp | 0200; /* got char */
#endif #endif
int_req = int_req | INT_TTI; /* set flag */ 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_unit.buf = 0; /* clear buffer */
tti_state = 0; /* clear state */ tti_state = 0; /* clear state */
int_req = int_req & ~INT_TTI; /* clear flag */ 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 */ sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
return SCPE_OK; return SCPE_OK;
} }
@ -702,7 +742,8 @@ return SCPE_OK;
int32 tto (int32 pulse, int32 AC) 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 & 002) int_req = int_req & ~INT_TTO; /* clear flag */
if (pulse & 004) { /* load buffer */ if (pulse & 004) { /* load buffer */
sim_activate (&tto_unit, tto_unit.wait); /* activate unit */ sim_activate (&tto_unit, tto_unit.wait); /* activate unit */
@ -728,8 +769,11 @@ out = tto_trans[tto_unit.buf + tto_state]; /* translate */
#else #else
out = tto_unit.buf & 0177; /* ASCII... */ out = tto_unit.buf & 0177; /* ASCII... */
#endif #endif
if ((temp = sim_putchar (out)) != SCPE_OK) return temp; if (!(tto_unit.flags & UNIT_UC) ||
tto_unit.pos = tto_unit.pos + 1; ((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; return SCPE_OK;
} }
@ -741,5 +785,8 @@ tto_unit.buf = 0; /* clear buffer */
tto_state = 0; /* clear state */ tto_state = 0; /* clear state */
int_req = int_req & ~INT_TTO; /* clear flag */ int_req = int_req & ~INT_TTO; /* clear flag */
sim_cancel (&tto_unit); /* deactivate unit */ sim_cancel (&tto_unit); /* deactivate unit */
#if defined (TTY1)
tto_unit.filebuf = tto_consout;
#endif
return SCPE_OK; return SCPE_OK;
} }

View file

@ -23,6 +23,8 @@
be used in advertising or otherwise to promote the sale, use or other dealings 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. 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 12-May-01 RMS Fixed bug in RIM loaders
14-Mar-01 RMS Added extension detection of RIM format tapes 14-Mar-01 RMS Added extension detection of RIM format tapes
21-Jan-01 RMS Added DECtape support 21-Jan-01 RMS Added DECtape support
@ -39,6 +41,7 @@
extern DEVICE cpu_dev; extern DEVICE cpu_dev;
extern DEVICE ptr_dev, ptp_dev; extern DEVICE ptr_dev, ptp_dev;
extern DEVICE tti_dev, tto_dev; extern DEVICE tti_dev, tto_dev;
extern UNIT tti_unit, tto_unit;
extern DEVICE clk_dev; extern DEVICE clk_dev;
extern DEVICE lpt_dev; extern DEVICE lpt_dev;
#if defined (DRM) #if defined (DRM)
@ -56,6 +59,10 @@ extern DEVICE mt_dev;
#if defined (DTA) #if defined (DTA)
extern DEVICE dt_dev; extern DEVICE dt_dev;
#endif #endif
#if defined (TTY1)
extern DEVICE tti1_dev, tto1_dev;
extern UNIT tti1_unit, tto1_unit;
#endif
extern UNIT cpu_unit; extern UNIT cpu_unit;
extern REG cpu_reg[]; extern REG cpu_reg[];
extern int32 M[]; extern int32 M[];
@ -87,7 +94,8 @@ REG *sim_PC = &cpu_reg[0];
int32 sim_emax = 3; int32 sim_emax = 3;
DEVICE *sim_devices[] = { &cpu_dev, 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, &clk_dev, &lpt_dev,
#if defined (DRM) #if defined (DRM)
&drm_dev, &drm_dev,
@ -103,15 +111,28 @@ DEVICE *sim_devices[] = { &cpu_dev,
#endif #endif
#if defined (MTA) #if defined (MTA)
&mt_dev, &mt_dev,
#endif
#if defined (TTY1)
&tti1_dev, &tto1_dev,
#endif #endif
NULL }; 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[] = { const char *sim_stop_messages[] = {
"Unknown error", "Unknown error",
"Undefined instruction", "Undefined instruction",
"HALT instruction", "HALT instruction",
"Breakpoint", "Breakpoint",
"Nested XCT's" }; "Nested XCT's",
"Invalid API interrupt" };
/* Binary loader */ /* Binary loader */
@ -279,7 +300,7 @@ static const char *opcode[] = {
"XCT", "ISZ", "AND", "SAD", "XCT", "ISZ", "AND", "SAD",
"JMP", "JMP",
#if defined (PDP15) /* mem ref ind */ #if defined (PDP9) || defined (PDP15) /* mem ref ind */
"CAL*", "DAC*", "JMS*", "DZM*", /* normal */ "CAL*", "DAC*", "JMS*", "DZM*", /* normal */
"LAC*", "XOR*", "ADD*", "TAD*", "LAC*", "XOR*", "ADD*", "TAD*",
"XCT*", "ISZ*", "AND*", "SAD*", "XCT*", "ISZ*", "AND*", "SAD*",
@ -346,26 +367,34 @@ static const char *opcode[] = {
"MTTR", "MTCR", "MTSF", "MTRC", "MTAF", "MTTR", "MTCR", "MTSF", "MTRC", "MTAF",
"MTRS", "MTGO", "MTCM", "MTLC", "MTRS", "MTGO", "MTCM", "MTLC",
#endif #endif
#if defined (DTA) #if defined (DTA) /* TC02/TC15 */
"DTCA", "DTRA", "DTXA", "DTLA", "DTCA", "DTRA", "DTXA", "DTLA",
"DTEF", "DTRB", "DTDF", "DTEF", "DTRB", "DTDF",
#endif #endif
#if defined (TTY1)
"KSF1", "KRB1",
"TSF1", "TCF1", "TLS1", "TCF1!TLS1",
#endif
#if defined (PDP7) #if defined (PDP7)
"ITON", "TTS", "SKP7", "CAF", "ITON", "TTS", "SKP7", "CAF",
"SEM", "EEM", "EMIR", "LEM", "SEM", "EEM", "EMIR", "LEM",
#elif defined (PDP9) #endif
"PFSF", "TTS", "SKP7", "CAF", #if defined (PDP9)
"DBR", "SEM", "EEM", "LEM", "SKP7", "SEM", "EEM", "LEM",
"MPSK", "MPSNE", "MPCV", "MPEU",
"MPLD", "MPCNE",
"LPDI", "LPEI", "LPDI", "LPEI",
#elif defined (PDP15) #endif
"PFSF", "TTS", "SPCO", "CAF", #if defined (PDP15)
"DBR", "SKP15", "RES", "SPCO", "SKP15", "RES",
"SBA", "DBA", "EBA", "SBA", "DBA", "EBA",
"AAS", "PAX", "PAL", "AAC", "AAS", "PAX", "PAL", "AAC",
"PXA", "AXS", "PXL", "PLA", "PXA", "AXS", "PXL", "PLA",
"PLX", "CLAC","CLX", "CLLR", "AXR", "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 #endif
"IOT", /* general */ "IOT", /* general */
@ -493,22 +522,30 @@ static const int32 opc_val[] = {
0707541+I_NPI, 0707552+I_NPN, 0707544+I_NPI, 0707545+I_NPI, 0707541+I_NPI, 0707552+I_NPN, 0707544+I_NPI, 0707545+I_NPI,
0707561+I_NPI, 0707572+I_NPN, 0707601+I_NPI, 0707561+I_NPI, 0707572+I_NPN, 0707601+I_NPI,
#endif #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) #if defined (PDP7)
0703201+I_NPI, 0703301+I_NPI, 0703341+I_NPI, 0703302+I_NPI, 0703201+I_NPI, 0703301+I_NPI, 0703341+I_NPI, 0703302+I_NPI,
0707701+I_NPI, 0707702+I_NPI, 0707742+I_NPI, 0707704+I_NPI, 0707701+I_NPI, 0707702+I_NPI, 0707742+I_NPI, 0707704+I_NPI,
#elif defined (PDP9) #endif
0700062+I_NPI, 0703301+I_NPI, 0703341+I_NPI, 0703302+I_NPI, #if defined (PDP9)
0703344+I_NPI, 0707701+I_NPI, 0707702+I_NPI, 0707704+I_NPI, 0703341+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,
0706504+I_NPI, 0706604+I_NPI, 0706504+I_NPI, 0706604+I_NPI,
#elif defined (PDP15) #endif
0700062+I_NPI, 0703301+I_NPI, 0703341+I_NPI, 0703302+I_NPI, #if defined (PDP15)
0703344+I_NPI, 0707741+I_NPI, 0707742+I_NPI, 0703341+I_NPI, 0707741+I_NPI, 0707742+I_NPI,
0707761+I_NPI, 0707762+I_NPI, 0707764+I_NPI, 0707761+I_NPI, 0707762+I_NPI, 0707764+I_NPI,
0720000+I_XR9, 0721000+I_XR, 0722000+I_XR, 0723000+I_XR9, 0720000+I_XR9, 0721000+I_XR, 0722000+I_XR, 0723000+I_XR9,
0724000+I_XR, 0725000+I_XR9, 0726000+I_XR, 0730000+I_XR, 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, 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 #endif
0700000+I_IOT, 0700000+I_IOT,
@ -785,6 +822,8 @@ case I_V_MRF: /* mem ref */
#else #else
dmask = 017777; dmask = 017777;
cptr = get_glyph (cptr, gbuf, 0); /* get next field */ cptr = get_glyph (cptr, gbuf, 0); /* get next field */
#endif
#if defined (PDP4) || defined (PDP7)
if (strcmp (gbuf, "I") == 0) { /* indirect? */ if (strcmp (gbuf, "I") == 0) { /* indirect? */
val[0] = val[0] | 020000; val[0] = val[0] | 020000;
cptr = get_glyph (cptr, gbuf, 0); } cptr = get_glyph (cptr, gbuf, 0); }

190
pdp18b_tt1.c Normal file
View 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;
}

View file

@ -28,6 +28,7 @@
tti keyboard tti keyboard
tto teleprinter tto teleprinter
10-Jun-01 RMS Fixed comment
30-Oct-00 RMS Standardized device naming 30-Oct-00 RMS Standardized device naming
*/ */
@ -260,7 +261,7 @@ static const int32 boot_rom[] = {
0327776, /* dio x */ 0327776, /* dio x */
0107776, /* xct x */ 0107776, /* xct x */
0730002, /* rpb + wait */ 0730002, /* rpb + wait */
0760400, /* x, halt / 0760400, /* x, halt */
0607772 /* jmp r */ 0607772 /* jmp r */
}; };

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings 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. 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) 14-Mar-01 RMS Revised load/dump interface (again)
30-Oct-00 RMS Added support for examine to file 30-Oct-00 RMS Added support for examine to file
27-Oct-98 RMS V2.4 load interface 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_PC pointer to saved PC register descriptor
sim_emax number of words for examine sim_emax number of words for examine
sim_devices array of pointers to simulated devices 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_stop_messages array of pointers to stop messages
sim_load binary loader sim_load binary loader
*/ */
@ -64,6 +66,8 @@ DEVICE *sim_devices[] = { &cpu_dev,
&ptr_dev, &ptp_dev, &tti_dev, &tto_dev, &ptr_dev, &ptp_dev, &tti_dev, &tto_dev,
&lpt_dev, NULL }; &lpt_dev, NULL };
UNIT *sim_consoles = NULL;
const char *sim_stop_messages[] = { const char *sim_stop_messages[] = {
"Unknown error", "Unknown error",
"Undefined instruction", "Undefined instruction",
@ -102,7 +106,7 @@ for (;;) {
origin = val & 07777; origin = val & 07777;
if ((val = getword (fileref)) < 0) return SCPE_FMT; if ((val = getword (fileref)) < 0) return SCPE_FMT;
if (MEM_ADDR_OK (origin)) M[origin++] = val; } if (MEM_ADDR_OK (origin)) M[origin++] = val; }
else if ((val & 0770000) == 0600000) { else if ((val & 0770000) == 0600000) { /* JMP? */
PC = val & 007777; PC = val & 007777;
return SCPE_OK; } } return SCPE_OK; } }
return SCPE_FMT; /* error */ return SCPE_FMT; /* error */

View file

@ -25,6 +25,7 @@
cpu central processor cpu central processor
07-Jun-01 RMS Fixed bug in JMS to non-existent memory
25-Apr-01 RMS Added device enable/disable support 25-Apr-01 RMS Added device enable/disable support
18-Mar-01 RMS Added DF32 support 18-Mar-01 RMS Added DF32 support
05-Mar-01 RMS Added clock calibration 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 jump calculations. Data calculations return a full 15b extended
address, jump calculations a 12b field-relative address. 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. Note that MA contains IF'PC.
*/ */
@ -408,12 +413,12 @@ case 007: /* TAD, indir, curr */
case 010: /* ISZ, dir, zero */ case 010: /* ISZ, dir, zero */
ZERO_PAGE; 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; if (MB == 0) PC = (PC + 1) & 07777;
break; break;
case 011: /* ISZ, dir, curr */ case 011: /* ISZ, dir, curr */
CURR_PAGE; 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; if (MB == 0) PC = (PC + 1) & 07777;
break; break;
case 012: /* ISZ, indir, zero */ case 012: /* ISZ, indir, zero */
@ -461,13 +466,17 @@ case 017: /* DCA, indir, curr */
case 020: /* JMS, dir, zero */ case 020: /* JMS, dir, zero */
ZERO_PAGE_J; ZERO_PAGE_J;
CHANGE_FIELD; 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; PC = (MA + 1) & 07777;
break; break;
case 021: /* JMS, dir, curr */ case 021: /* JMS, dir, curr */
CURR_PAGE_J; CURR_PAGE_J;
CHANGE_FIELD; 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; PC = (MA + 1) & 07777;
break; break;
case 022: /* JMS, indir, zero */ case 022: /* JMS, indir, zero */

View file

@ -29,7 +29,7 @@
19-Mar-01 RMS Added disk monitor bootstrap, fixed IOT decoding 19-Mar-01 RMS Added disk monitor bootstrap, fixed IOT decoding
15-Feb-01 RMS Fixed 3 cycle data break sequence 15-Feb-01 RMS Fixed 3 cycle data break sequence
14-Apr-99 RMS Changed t_addr to unsigned 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 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. facility. To minimize overhead, the entire RF08 is buffered in memory.

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings 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. 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 18-Mar-01 RMS Added DF32 support
14-Mar-01 RMS Added extension detection of RIM binary tapes 14-Mar-01 RMS Added extension detection of RIM binary tapes
15-Feb-01 RMS Added DECtape support 15-Feb-01 RMS Added DECtape support
@ -53,6 +54,7 @@ extern int32 sim_switches;
sim_PC pointer to saved PC register descriptor sim_PC pointer to saved PC register descriptor
sim_emax maximum number of words for examine/deposit sim_emax maximum number of words for examine/deposit
sim_devices array of pointers to simulated devices 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_stop_messages array of pointers to stop messages
sim_load binary loader sim_load binary loader
*/ */
@ -73,6 +75,8 @@ DEVICE *sim_devices[] = {
&dt_dev, &mt_dev, &dt_dev, &mt_dev,
NULL }; NULL };
UNIT *sim_consoles = NULL;
const char *sim_stop_messages[] = { const char *sim_stop_messages[] = {
"Unknown error", "Unknown error",
"Unimplemented instruction", "Unimplemented instruction",

374
scp.c
View file

@ -23,6 +23,10 @@
be used in advertising or otherwise to promote the sale, use or other dealings 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. 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 12-May-01 RMS Fixed missing return in disable_cmd
25-Mar-01 RMS Added ENABLE/DISABLE 25-Mar-01 RMS Added ENABLE/DISABLE
14-Mar-01 RMS Revised LOAD/DUMP interface (again) 14-Mar-01 RMS Revised LOAD/DUMP interface (again)
@ -53,7 +57,6 @@
#define SCP 1 /* defining module */ #define SCP 1 /* defining module */
#include "sim_defs.h" #include "sim_defs.h"
#include <limits.h>
#include <signal.h> #include <signal.h>
#include <ctype.h> #include <ctype.h>
#define EX_D 0 /* deposit */ #define EX_D 0 /* deposit */
@ -83,6 +86,7 @@
extern char sim_name[]; extern char sim_name[];
extern DEVICE *sim_devices[]; extern DEVICE *sim_devices[];
extern UNIT *sim_consoles[];
extern REG *sim_PC; extern REG *sim_PC;
extern char *sim_stop_messages[]; extern char *sim_stop_messages[];
extern t_stat sim_instr (void); extern t_stat sim_instr (void);
@ -96,6 +100,7 @@ extern t_stat ttinit (void);
extern t_stat ttrunstate (void); extern t_stat ttrunstate (void);
extern t_stat ttcmdstate (void); extern t_stat ttcmdstate (void);
extern t_stat ttclose (void); extern t_stat ttclose (void);
extern t_stat sim_putchar (int32 out);
extern uint32 sim_os_msec (void); extern uint32 sim_os_msec (void);
UNIT *sim_clock_queue = NULL; UNIT *sim_clock_queue = NULL;
int32 sim_interval = 0; int32 sim_interval = 0;
@ -106,7 +111,8 @@ static uint32 sim_rtime;
static int32 noqueue_time; static int32 noqueue_time;
volatile int32 stop_cpu = 0; volatile int32 stop_cpu = 0;
t_value *sim_eval = NULL; 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]; unsigned char sim_flip[FLIP_SIZE];
#define print_val(a,b,c,d) fprint_val (stdout, (a), (b), (c), (d)) #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_stat get_aval (t_addr addr, DEVICE *dptr, UNIT *uptr);
t_value strtotv (char *inptr, char **endptr, int radix); t_value strtotv (char *inptr, char **endptr, int radix);
t_stat fprint_val (FILE *stream, t_value val, int rdx, int wid, int fmt); 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); char *read_line (char *ptr, int size, FILE *stream);
DEVICE *find_dev (char *ptr); DEVICE *find_dev (char *ptr);
DEVICE *find_unit (char *ptr, int32 *iptr); DEVICE *find_unit (char *ptr, int32 *iptr);
@ -201,7 +209,9 @@ const char *scp_error_messages[] = {
"Console terminal setup error", "Console terminal setup error",
"Subscript out of range", "Subscript out of range",
"Command not allowed", "Command not allowed",
"Unit disabled" "Unit disabled",
"Logging enabled",
"Logging disabled"
}; };
const size_t size_map[] = { sizeof (int8), 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 remove_cmd (int flag, char *ptr);
t_stat enable_cmd (int flag, char *ptr); t_stat enable_cmd (int flag, char *ptr);
t_stat disable_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); t_stat help_cmd (int flag, char *ptr);
static CTAB cmd_table[] = { static CTAB cmd_table[] = {
@ -284,12 +296,14 @@ static CTAB cmd_table[] = {
{ "DISABLE", &disable_cmd, 0 }, { "DISABLE", &disable_cmd, 0 },
{ "ADD", &add_cmd, 0 }, { "ADD", &add_cmd, 0 },
{ "REMOVE", &remove_cmd, 0 }, { "REMOVE", &remove_cmd, 0 },
{ "LOG", &log_cmd, 0 },
{ "NOLOG", &nolog_cmd, 0 },
{ "HELP", &help_cmd, 0 }, { "HELP", &help_cmd, 0 },
{ NULL, NULL, 0 } }; { NULL, NULL, 0 } };
/* Main command loop */ /* 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 */ end_test.i = 1; /* test endian-ness */
sim_end = end_test.c[0]; sim_end = end_test.c[0];
if (sim_emax <= 0) sim_emax = 1; if (sim_emax <= 0) sim_emax = 1;
@ -306,13 +320,14 @@ sim_time = sim_rtime = 0;
noqueue_time = 0; noqueue_time = 0;
sim_clock_queue = NULL; sim_clock_queue = NULL;
sim_is_running = 0; sim_is_running = 0;
sim_log = NULL;
if ((stat = reset_all (0)) != SCPE_OK) { if ((stat = reset_all (0)) != SCPE_OK) {
printf ("Fatal simulator initialization error\n%s\n", printf ("Fatal simulator initialization error\n%s\n",
scp_error_messages[stat - SCPE_BASE]); scp_error_messages[stat - SCPE_BASE]);
return 0; } return 0; }
if ((argc > 1) && (argv[1] != NULL) && if ((argc > 1) && (argv[1] != NULL)) { /* cmd line arg? */
((fpin = fopen (argv[1], "r")) != NULL)) { /* command file? */ if ((fpin = fopen (argv[1], "r")) != NULL) { /* cmd file open? */
do { cptr = read_line (cbuf, CBUFSIZE, fpin); do { cptr = read_line (cbuf, CBUFSIZE, fpin);
if (cptr == NULL) break; /* exit on eof */ if (cptr == NULL) break; /* exit on eof */
if (*cptr == 0) continue; /* ignore blank */ if (*cptr == 0) continue; /* ignore blank */
@ -324,23 +339,28 @@ if ((argc > 1) && (argv[1] != NULL) &&
if (stat >= SCPE_BASE) if (stat >= SCPE_BASE)
printf ("%s\n", scp_error_messages[stat - SCPE_BASE]); printf ("%s\n", scp_error_messages[stat - SCPE_BASE]);
} while (stat != SCPE_EXIT); } /* end if cmd file */ } 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 */ do { printf ("sim> "); /* prompt */
cptr = read_line (cbuf, CBUFSIZE, stdin); /* read command line */ cptr = read_line (cbuf, CBUFSIZE, stdin); /* read command line */
stat = SCPE_UNK; stat = SCPE_UNK;
if (cptr == NULL) continue; /* ignore EOF */ if (cptr == NULL) continue; /* ignore EOF */
if (*cptr == 0) continue; /* ignore blank */ 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 */ cptr = get_glyph (cptr, gbuf, 0); /* get command glyph */
for (i = 0; cmd_table[i].name != NULL; i++) { for (i = 0; cmd_table[i].name != NULL; i++) {
if (MATCH_CMD (gbuf, cmd_table[i].name) == 0) { if (MATCH_CMD (gbuf, cmd_table[i].name) == 0) {
stat = cmd_table[i].action (cmd_table[i].arg, cptr); stat = cmd_table[i].action (cmd_table[i].arg, cptr);
break; } } break; } }
if (stat >= SCPE_BASE) if (stat >= SCPE_BASE) { /* error? */
printf ("%s\n", scp_error_messages[stat - SCPE_BASE]); 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); } while (stat != SCPE_EXIT);
detach_all (0); detach_all (0); /* close files */
ttclose (); nolog_cmd (0, NULL); /* close log */
ttclose (); /* close console */
return 0; return 0;
} }
@ -353,36 +373,45 @@ return SCPE_EXIT;
/* Help command */ /* 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) t_stat help_cmd (int flag, char *cptr)
{ {
printf ("r{eset} {ALL|<device>} reset simulator\n"); fprint_help (stdout);
printf ("e{xamine} <list> examine memory or registers\n"); if (sim_log) fprint_help (sim_log);
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");
return SCPE_OK; return SCPE_OK;
} }
@ -441,13 +470,16 @@ return SCPE_OK;
t_stat show_cmd (int flag, char *cptr) t_stat show_cmd (int flag, char *cptr)
{ {
int32 i; int32 i;
t_stat r;
char gbuf[CBUFSIZE]; char gbuf[CBUFSIZE];
DEVICE *dptr; DEVICE *dptr;
t_stat show_config (int flag);
t_stat show_queue (int flag); t_stat show_config (FILE *st, int flag);
t_stat show_time (int flag); t_stat show_queue (FILE *st, int flag);
t_stat show_modifiers (int flag); t_stat show_time (FILE *st, int flag);
t_stat show_device (DEVICE *dptr, int flag); t_stat show_modifiers (FILE *st, int flag);
t_stat show_device (FILE *st, DEVICE *dptr, int flag);
static CTAB show_table[] = { static CTAB show_table[] = {
{ "CONFIGURATION", &show_config, 0 }, { "CONFIGURATION", &show_config, 0 },
{ "DEVICES", &show_config, 1 }, { "DEVICES", &show_config, 1 },
@ -460,98 +492,106 @@ GET_SWITCHES (cptr, gbuf); /* test for switches */
cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */ cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */
if (*cptr != 0) return SCPE_ARG; /* now eol? */ if (*cptr != 0) return SCPE_ARG; /* now eol? */
for (i = 0; show_table[i].name != NULL; i++) { /* find command */ for (i = 0; show_table[i].name != NULL; i++) { /* find command */
if (MATCH_CMD (gbuf, show_table[i].name) == 0) if (MATCH_CMD (gbuf, show_table[i].name) == 0) {
return show_table[i].action (show_table[i].arg); } 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 */ dptr = find_dev (gbuf); /* locate device */
if (dptr == NULL) return SCPE_ARG; /* not found? */ 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 */ /* Show processors */
t_stat show_device (DEVICE *dptr, int flag) t_stat show_device (FILE *st, DEVICE *dptr, int flag)
{ {
int32 j, ucnt; int32 j, ucnt;
t_addr kval; t_addr kval;
UNIT *uptr; UNIT *uptr;
MTAB *mptr; MTAB *mptr;
printf ("%s", dptr -> name); /* print dev name */ fprintf (st, "%s", dptr -> name); /* print dev name */
if (qdisable (dptr)) { /* disabled? */ if (qdisable (dptr)) { /* disabled? */
printf (", disabled\n"); fprintf (st, ", disabled\n");
return SCPE_OK; } return SCPE_OK; }
for (j = ucnt = 0; j < dptr -> numunits; j++) { /* count units */ for (j = ucnt = 0; j < dptr -> numunits; j++) { /* count units */
uptr = (dptr -> units) + j; uptr = (dptr -> units) + j;
if (!(uptr -> flags & UNIT_DIS)) ucnt++; } if (!(uptr -> flags & UNIT_DIS)) ucnt++; }
if (dptr -> numunits == 0) printf ("\n"); if (dptr -> numunits == 0) fprintf (st, "\n");
else { if (ucnt == 0) printf (", all units disabled\n"); else { if (ucnt == 0) fprintf (st, ", all units disabled\n");
else if (ucnt > 1) printf (", %d units\n", ucnt); else if (ucnt > 1) fprintf (st, ", %d units\n", ucnt);
else if (flag) printf ("\n"); } else if (flag) fprintf (st, "\n"); }
if (flag) return SCPE_OK; /* dev only? */ if (flag) return SCPE_OK; /* dev only? */
for (j = 0; j < dptr -> numunits; j++) { for (j = 0; j < dptr -> numunits; j++) {
uptr = (dptr -> units) + j; uptr = (dptr -> units) + j;
kval = (uptr -> flags & UNIT_BINK)? 1024: 1000; kval = (uptr -> flags & UNIT_BINK)? 1024: 1000;
if (uptr -> flags & UNIT_DIS) continue; 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 -> flags & UNIT_FIX) {
if (uptr -> capac < kval) if (uptr -> capac < kval)
printf (", %d%s", uptr -> capac, fprintf (st, ", %d%s", uptr -> capac,
((dptr -> dwidth / dptr -> aincr) > 8)? "W": "B"); ((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"); } ((dptr -> dwidth / dptr -> aincr) > 8)? "W": "B"); }
if (uptr -> flags & UNIT_ATT) if (uptr -> flags & UNIT_ATT)
printf (", attached to %s", uptr -> filename); fprintf (st, ", attached to %s", uptr -> filename);
else if (uptr -> flags & UNIT_ATTABLE) printf (", not attached"); else if (uptr -> flags & UNIT_ATTABLE)
fprintf (st, ", not attached");
if (dptr -> modifiers != NULL) { if (dptr -> modifiers != NULL) {
for (mptr = dptr -> modifiers; mptr -> mask != 0; mptr++) { for (mptr = dptr -> modifiers; mptr -> mask != 0; mptr++) {
if ((mptr -> pstring != NULL) && if ((mptr -> pstring != NULL) &&
((uptr -> flags & mptr -> mask) == mptr -> match)) ((uptr -> flags & mptr -> mask) == mptr -> match))
printf (", %s", mptr -> pstring); } } fprintf (st, ", %s", mptr -> pstring); } }
printf ("\n"); } fprintf (st, "\n"); }
return SCPE_OK; return SCPE_OK;
} }
t_stat show_config (int flag) t_stat show_config (FILE *st, int flag)
{ {
int32 i; int32 i;
DEVICE *dptr; 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++) for (i = 0; (dptr = sim_devices[i]) != NULL; i++)
show_device (dptr, flag); show_device (st, dptr, flag);
return SCPE_OK; return SCPE_OK;
} }
t_stat show_queue (int flag) t_stat show_queue (FILE *st, int flag)
{ {
DEVICE *dptr; DEVICE *dptr;
UNIT *uptr; UNIT *uptr;
int32 accum; int32 accum;
if (sim_clock_queue == NULL) { 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; } 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; accum = 0;
for (uptr = sim_clock_queue; uptr != NULL; uptr = uptr -> next) { 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) { else if ((dptr = find_dev_from_unit (uptr)) != NULL) {
printf (" %s", dptr -> name); fprintf (st, " %s", dptr -> name);
if (dptr -> numunits > 1) printf (" unit %d", if (dptr -> numunits > 1) fprintf (st, " unit %d",
uptr - dptr -> units); } uptr - dptr -> units); }
else printf (" Unknown"); else fprintf (st, " Unknown");
printf (" at %d\n", accum + uptr -> time); fprintf (st, " at %d\n", accum + uptr -> time);
accum = accum + uptr -> time; } accum = accum + uptr -> time; }
return SCPE_OK; 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; return SCPE_OK;
} }
t_stat show_modifiers (int flag) t_stat show_modifiers (FILE *st, int flag)
{ {
int i, any; int i, any;
DEVICE *dptr; DEVICE *dptr;
@ -561,9 +601,9 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) {
any = 0; any = 0;
for (mptr = dptr -> modifiers; mptr && (mptr -> mask != 0); mptr++) { for (mptr = dptr -> modifiers; mptr && (mptr -> mask != 0); mptr++) {
if (mptr -> mstring) { if (mptr -> mstring) {
if (any++) printf (", %s", mptr -> mstring); if (any++) fprintf (st, ", %s", mptr -> mstring);
else printf ("%s %s", dptr -> name, mptr -> mstring); } } else fprintf (st, "%s %s", dptr -> name, mptr -> mstring); } }
if (any) printf ("\n"); } if (any) fprintf (st, "\n"); }
return SCPE_OK; return SCPE_OK;
} }
@ -668,6 +708,43 @@ uptr -> flags = uptr -> flags | UNIT_DIS; /* disable it */
return SCPE_OK; 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 /* Reset command and routines
re[set] reset all devices 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? */ if (strcmp (buf, sim_name)) { /* name match? */
printf ("Wrong system type: %s\n", buf); printf ("Wrong system type: %s\n", buf);
fclose (rfile); fclose (rfile);
return SCPE_OK; } return SCPE_INCOMP; }
READ_I (sim_time); /* sim time */ READ_I (sim_time); /* sim time */
if (v26) { READ_I (sim_rtime); } /* sim relative 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]; char gbuf[CBUFSIZE];
int32 i, j, step, unitno; int32 i, j, step, unitno;
t_stat r; t_stat r;
t_addr k;
t_value pcval;
DEVICE *dptr; DEVICE *dptr;
UNIT *uptr; UNIT *uptr;
void int_handler (int signal); void int_handler (int signal);
@ -1147,6 +1222,7 @@ if (ttrunstate () != SCPE_OK) { /* set console */
return SCPE_TTYERR; } return SCPE_TTYERR; }
if (step) sim_activate (&step_unit, step); /* set step timer */ if (step) sim_activate (&step_unit, step); /* set step timer */
sim_is_running = 1; /* flag running */ sim_is_running = 1; /* flag running */
sim_chkcons (); /* check console buffer */
r = sim_instr(); r = sim_instr();
sim_is_running = 0; /* flag idle */ sim_is_running = 0; /* flag idle */
@ -1159,11 +1235,26 @@ else { UPDATE_SIM_TIME (noqueue_time); }
#if defined (VMS) #if defined (VMS)
printf ("\n"); printf ("\n");
#endif #endif
if (r >= SCPE_BASE) printf ("\n%s, %s: ", scp_error_messages[r - SCPE_BASE], fprint_stopped (stdout, r); /* print msg */
sim_PC -> name); if (sim_log) fprint_stopped (sim_log, r); /* log if enabled */
else printf ("\n%s, %s: ", sim_stop_messages[r], sim_PC -> name); 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); 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); sim_PC -> flags & REG_FMT);
if (((dptr = sim_devices[0]) != NULL) && (dptr -> examine != NULL)) { if (((dptr = sim_devices[0]) != NULL) && (dptr -> examine != NULL)) {
for (i = 0; i < sim_emax; i++) sim_eval[i] = 0; 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, if (r = dptr -> examine (&sim_eval[i], k, dptr -> units,
SWMASK ('V')) != SCPE_OK) break; } SWMASK ('V')) != SCPE_OK) break; }
if ((r == SCPE_OK) || (i > 0)) { if ((r == SCPE_OK) || (i > 0)) {
printf (" ("); fprintf (stream, " (");
if (fprint_sym (stdout, (t_addr) pcval, sim_eval, NULL, SWMASK('M')) > 0) if (fprint_sym (stream, (t_addr) pcval, sim_eval, NULL, SWMASK('M')) > 0)
fprint_val (stdout, sim_eval[0], dptr -> dradix, fprint_val (stream, sim_eval[0], dptr -> dradix,
dptr -> dwidth, PV_RZRO); dptr -> dwidth, PV_RZRO);
printf (")"); } } fprintf (stream, ")"); } }
printf ("\n"); fprintf (stream, "\n");
return SCPE_OK; return;
} }
/* Run time routines */
/* Unit service for step timeout, originally scheduled by STEP n command /* 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; char gbuf[CBUFSIZE], *gptr, *tptr;
int32 unitno, t; int32 unitno, t;
t_bool log; t_bool exd2f;
t_addr low, high; t_addr low, high;
t_stat reason; t_stat reason;
DEVICE *dptr, *tdptr; 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 */ if (*cptr == 0) return SCPE_ARG; /* err if no args */
ofile = NULL; /* no output file */ ofile = NULL; /* no output file */
log = FALSE; exd2f = FALSE;
sim_switches = 0; /* no switches */ sim_switches = 0; /* no switches */
schptr = NULL; /* no search */ schptr = NULL; /* no search */
stab.logic = SCH_OR; /* default search params */ 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 == 0) return SCPE_ARG; /* error if no arguments */
if (*cptr == '@') { /* output file spec? */ if (*cptr == '@') { /* output file spec? */
if (flag != EX_E) return SCPE_ARG; /* examine only */ if (flag != EX_E) return SCPE_ARG; /* examine only */
if (log) { /* already got one? */ if (exd2f) { /* already got one? */
fclose (ofile); /* one per customer */ fclose (ofile); /* one per customer */
return SCPE_ARG; } return SCPE_ARG; }
cptr = get_glyph_nc (cptr + 1, gbuf, 0); cptr = get_glyph_nc (cptr + 1, gbuf, 0);
ofile = fopen (gbuf, "a"); /* open for append */ ofile = fopen (gbuf, "a"); /* open for append */
if (ofile == NULL) return SCPE_OPENERR; if (ofile == NULL) return SCPE_OPENERR;
log = TRUE; exd2f = TRUE;
continue; } /* look for more */ continue; } /* look for more */
cptr = get_glyph (cptr, gbuf, 0); cptr = get_glyph (cptr, gbuf, 0);
if ((t = get_switches (gbuf)) != 0) { /* try for switches */ 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, reason = exdep_addr_loop (ofile, schptr, flag, cptr, low, high,
dptr, uptr); dptr, uptr);
} /* end for */ } /* end for */
if (log) fclose (ofile); /* close output file */ if (exd2f) fclose (ofile); /* close output file */
return reason; return reason;
} }
@ -1342,7 +1431,9 @@ for (rptr = lowr; rptr <= highr; rptr++) {
if (schptr && !test_search (val, schptr)) continue; if (schptr && !test_search (val, schptr)) continue;
if (flag != EX_D) { if (flag != EX_D) {
reason = ex_reg (ofile, val, flag, rptr, idx); 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) { if (flag != EX_E) {
reason = dep_reg (flag, cptr, rptr, idx); reason = dep_reg (flag, cptr, rptr, idx);
if (reason != SCPE_OK) return reason; } } } 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 (schptr && !test_search (sim_eval[0], schptr)) continue;
if (flag != EX_D) { if (flag != EX_D) {
reason = ex_addr (ofile, flag, i, dptr, uptr); 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) { if (flag != EX_E) {
reason = dep_addr (flag, cptr, i, dptr, uptr, reason); reason = dep_addr (flag, cptr, i, dptr, uptr, reason);
if (reason > SCPE_OK) return 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 (rptr -> flags & REG_RO) return SCPE_RO;
if (flag & EX_I) { if (flag & EX_I) {
cptr = read_line (gbuf, CBUFSIZE, stdin); 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 == NULL) return 1; /* force exit */
if (*cptr == 0) return SCPE_OK; } /* success */ if (*cptr == 0) return SCPE_OK; } /* success */
mask = width_mask[rptr -> width]; mask = width_mask[rptr -> width];
@ -1606,6 +1700,7 @@ char gbuf[CBUFSIZE];
if (dptr == NULL) return SCPE_ARG; if (dptr == NULL) return SCPE_ARG;
if (flag & EX_I) { if (flag & EX_I) {
cptr = read_line (gbuf, CBUFSIZE, stdin); 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 == NULL) return 1; /* force exit */
if (*cptr == 0) return dfltinc; } /* success */ if (*cptr == 0) return dfltinc; } /* success */
mask = width_mask[dptr -> dwidth]; mask = width_mask[dptr -> dwidth];
@ -1661,6 +1756,7 @@ if (cptr == NULL) {
for (tptr = cptr; tptr < (cptr + size); tptr++) /* remove cr */ for (tptr = cptr; tptr < (cptr + size); tptr++) /* remove cr */
if (*tptr == '\n') *tptr = 0; if (*tptr == '\n') *tptr = 0;
while (isspace (*cptr)) cptr++; /* absorb spaces */ while (isspace (*cptr)) cptr++; /* absorb spaces */
if (*cptr == ';') *cptr = 0; /* ignore comment */
return cptr; return cptr;
} }
@ -2267,11 +2363,12 @@ lcnt = count % nelem; /* count in last buf */
if (lcnt) nbuf = nbuf + 1; if (lcnt) nbuf = nbuf + 1;
else lcnt = nelem; else lcnt = nelem;
total = 0; total = 0;
dptr = bptr; /* init output ptr */
for (i = nbuf; i > 0; i--) { for (i = nbuf; i > 0; i--) {
c = fread (sim_flip, size, (i == 1? lcnt: nelem), fptr); c = fread (sim_flip, size, (i == 1? lcnt: nelem), fptr);
if (c == 0) return total; if (c == 0) return total;
total = total + c; 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++; for (k = size - 1; k >= 0; k--) *(dptr + k) = *sptr++;
dptr = dptr + size; } } dptr = dptr + size; } }
return total; return total;
@ -2292,11 +2389,11 @@ lcnt = count % nelem; /* count in last buf */
if (lcnt) nbuf = nbuf + 1; if (lcnt) nbuf = nbuf + 1;
else lcnt = nelem; else lcnt = nelem;
total = 0; total = 0;
sptr = bptr; /* init input ptr */
for (i = nbuf; i > 0; i--) { for (i = nbuf; i > 0; i--) {
c = (i == 1)? lcnt: nelem; c = (i == 1)? lcnt: nelem;
for (j = 0, sptr = bptr, dptr = sim_flip; j < c; j++) { for (j = 0, dptr = sim_flip; j < c; j++) {
for (k = size - 1; k >= 0; k--) for (k = size - 1; k >= 0; k--) *(dptr + k) = *sptr++;
*(dptr + k) = *sptr++;
dptr = dptr + size; } dptr = dptr + size; }
c = fwrite (sim_flip, size, c, fptr); c = fwrite (sim_flip, size, c, fptr);
if (c == 0) return total; if (c == 0) return total;
@ -2354,4 +2451,77 @@ rtc_currdelay = (int32) (((double) rtc_basedelay * (double) rtc_nextintv) /
1000.0); /* next delay */ 1000.0); /* next delay */
return rtc_currdelay; 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;
}

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings 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. 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 05-Mar-01 RMS Added clock calibration support
08-Dec-00 BKR Added OS/2 support 08-Dec-00 BKR Added OS/2 support
18-Aug-98 RMS Added BeOS support 18-Aug-98 RMS Added BeOS support
@ -50,6 +51,7 @@
#undef USE_INT64 /* hack for Windows */ #undef USE_INT64 /* hack for Windows */
#include "sim_defs.h" #include "sim_defs.h"
int32 sim_int_char = 005; /* interrupt character */ int32 sim_int_char = 005; /* interrupt character */
extern FILE *sim_log;
/* VMS routines */ /* VMS routines */
@ -151,6 +153,7 @@ IOSB iosb;
c = out; c = out;
status = sys$qiow (EFN, tty_chan, IO$_WRITELBLK | IO$M_NOFORMAT, status = sys$qiow (EFN, tty_chan, IO$_WRITELBLK | IO$M_NOFORMAT,
&iosb, 0, 0, &c, 1, 0, 0, 0, 0); &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; if ((status != SS$_NORMAL) || (iosb.status != SS$_NORMAL)) return SCPE_TTOERR;
return SCPE_OK; return SCPE_OK;
} }
@ -237,7 +240,9 @@ return c | SCPE_KFLAG;
t_stat sim_putchar (int32 c) 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; return SCPE_OK;
} }
@ -291,7 +296,8 @@ t_stat sim_putchar (int32 c)
{ {
if (c != 0177) { if (c != 0177) {
putch (c); putch (c);
fflush (stdout) ; } fflush (stdout) ;
if (sim_log) fputc (c, sim_log); }
return SCPE_OK; return SCPE_OK;
} }
@ -381,6 +387,7 @@ char c;
c = out; c = out;
write (1, &c, 1); write (1, &c, 1);
if (sim_log) fputc (c, sim_log);
return SCPE_OK; return SCPE_OK;
} }
@ -480,6 +487,7 @@ char c;
c = out; c = out;
write (1, &c, 1); write (1, &c, 1);
if (sim_log) fputc (c, sim_log);
return SCPE_OK; return SCPE_OK;
} }

View file

@ -23,6 +23,8 @@
be used in advertising or otherwise to promote the sale, use or other dealings 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. 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 25-Feb-01 RMS Revisions for V2.6
15-Oct-00 RMS Editorial revisions for V2.5 15-Oct-00 RMS Editorial revisions for V2.5
11-Jul-99 RMS Added unsigned int data types 11-Jul-99 RMS Added unsigned int data types
@ -53,6 +55,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <limits.h>
#ifndef TRUE #ifndef TRUE
#define TRUE 1 #define TRUE 1
@ -90,7 +93,11 @@ typedef int32 t_mtrlnt; /* magtape rec lnt */
#define MTRF(x) ((x) & (1u << 31)) /* record error flg */ #define MTRF(x) ((x) & (1u << 31)) /* record error flg */
#define MTRL(x) ((x) & ((1u << 31) - 1)) /* record length */ #define MTRL(x) ((x) & ((1u << 31) - 1)) /* record length */
#define FLIP_SIZE (1 << 16) /* flip buf size */ #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 /* Simulator status codes
@ -128,6 +135,8 @@ typedef int32 t_mtrlnt; /* magtape rec lnt */
#define SCPE_SUB (SCPE_BASE + 24) /* subscript err */ #define SCPE_SUB (SCPE_BASE + 24) /* subscript err */
#define SCPE_NOFNC (SCPE_BASE + 25) /* func not imp */ #define SCPE_NOFNC (SCPE_BASE + 25) /* func not imp */
#define SCPE_UDIS (SCPE_BASE + 26) /* unit disabled */ #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 */ #define SCPE_KFLAG 01000 /* tti data flag */
/* Print value format codes */ /* Print value format codes */
@ -211,7 +220,9 @@ struct unit {
#define UNIT_BUF 000400 /* buffered */ #define UNIT_BUF 000400 /* buffered */
#define UNIT_DISABLE 001000 /* disable-able */ #define UNIT_DISABLE 001000 /* disable-able */
#define UNIT_DIS 002000 /* disabled */ #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 */ /* 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 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 get_uint (char *cptr, int radix, t_value max, t_stat *status);
EXTERN t_value strtotv (char *cptr, char **endptr, int radix); 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);

806
simh.doc

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
To: Users To: Users
From: Bob Supnik From: Bob Supnik
Subj: Simulator Usage, V2.6 Subj: Simulator Usage, V2.6a
Date: 3-May-01 Date: 15-Jun-01
COPYRIGHT NOTICE 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 -a -b -c -d are treated identically. Verbs, switches, and other
input (except for file names) are case insensitive. 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 3.1 Loading and Saving Programs
The LOAD command (abbreviation LO) loads a file in binary paper-tape 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. 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. 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. 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 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) 6.2.1 Paper Tape Reader (PTR)
The paper tape reader (PTR) reads data from a disk file. The POS 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 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 The active terminal input polls the console keyboard for input. The
options include the ability to set limited Dasher compatibility mode or inactive terminal input cannot receive characters. Terminal input
normal mode: options include the ability to set limited Dasher compatibility mode
or ANSI standard mode:
SET TTI ANSI normal mode SET TTI ANSI normal mode
SET TTI DASHER Dasher mode SET TTI DASHER Dasher mode
SET TTO ANSI normal mode SET TTO ANSI normal mode
SET TTO DASHER Dasher mode SET TTO DASHER Dasher mode
Setting either TTI or TTO changes both devices. In Dasher mode, carriage Setting either TTI (TTI1) or TTO (TTO1) changes both devices. In Dasher
return is changed to newline on input, and ^X is changed to backspace. 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 name size comments
@ -1789,21 +1822,22 @@ The terminal input implements these registers:
POS 31 number of characters input POS 31 number of characters input
TIME 24 keyboard polling interval 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 The active terminal output writes to the simulator window. The inactive
options include the ability to set limited Dasher compatibility mode or terminal output buffers characters. Terminal output options include the
normal mode: the ability to set limited Dasher compatibility mode or ANSI mode:
SET TTI ANSI normal mode SET TTI ANSI normal mode
SET TTI DASHER Dasher mode SET TTI DASHER Dasher mode
SET TTO ANSI normal mode SET TTO ANSI normal mode
SET TTO DASHER Dasher mode SET TTO DASHER Dasher mode
Setting either TTI or TTO changes both devices. In Dasher mode, carriage Setting either TTI (TTI1) or TTO (TTO1) changes both devices. In Dasher
return is changed to newline on input, and ^X is changed to backspace. 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 name size comments
@ -1890,69 +1924,6 @@ Error handling is as follows:
OS I/O error x report error and stop 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) 6.3 Fixed Head Disk (DK)
The fixed head disk controller implements these registers: 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 PDP-9 CPU PDP-9 CPU with 32KW of memory
- KE09A extended arithmetic element (EAE) - KE09A extended arithmetic element (EAE)
- KF09A automatic priority interrupt (API)
- KG09B memory extension - KG09B memory extension
- KP09A power detection - KP09A power detection
- KX09A memory protection - KX09A memory protection
PTR,PTP PC09A paper tape reader/punch PTR,PTP PC09A paper tape reader/punch
TTI,TTO KSR 33 console terminal TTI,TTO KSR 33 console terminal
TTI1,TTO1 LT09A second console terminal
LPT Type 647E line printer LPT Type 647E line printer
CLK integral real-time clock CLK integral real-time clock
RF RF09/RS09 fixed-head disk 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 PDP-15 CPU PDP-15 CPU with 32KW of memory
- KE15 extended arithmetic element (EAE) - KE15 extended arithmetic element (EAE)
- KA15 automatic priority interrupt (API)
- KF15 power detection - KF15 power detection
- KM15 memory protection - KM15 memory protection
PTR,PTP PC15 paper tape reader/punch PTR,PTP PC15 paper tape reader/punch
TTI,TTO KSR 35 console terminal TTI,TTO KSR 35 console terminal
TTI1,TTO1 LT15 second console terminal
LPT LP15 line printer LPT LP15 line printer
CLK integral real-time clock CLK integral real-time clock
RP RP15/RP02 disk pack RP RP15/RP02 disk pack
@ -2569,10 +2544,13 @@ specified, the file is assumed to be BIN format.
8.1 CPU 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 EAE enable EAE
SET CPU NOEAE disable 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 4K set memory size = 4K
SET CPU 8K set memory size = 8K SET CPU 8K set memory size = 8K
SET CPU 12K set memory size = 12K 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 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) 8.2.1 Paper Tape Reader (PTR)
The paper tape reader (PTR) reads data from a disk file. The POS 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 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 The active terminal input polls the console keyboard for input. The
terminal input has one option, UC; when set, it automatically converts inactive terminal input cannot receive characters. The terminal inputs
lower case input to upper case. 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. The PDP-9 and PDP-15 operated the primary terminal (TTI/TTO), by default,
For backward compatibility, on the PDP-9 and PDP-15 the terminal input as half-duplex. For backward compatibility, on the PDP-9 and PDP-15
has a second option, FDX; when set, it operates the terminal input in the first terminal input has a second option, FDX; when set, it operates
full-duplex mode. 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 name size comments
@ -2721,10 +2717,14 @@ The terminal input implements these registers:
POS 31 number of characters input POS 31 number of characters input
TIME 24 keyboard polling interval 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 The active terminal output writes to the simulator window. The inactive
implements these registers: 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 name size comments
@ -4172,9 +4172,12 @@ the file format to try to determine the file type.
12.1 CPU 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 STANDARD Standard microcode
SET CPU TOPS20V41 Standard microcode with TOPS-20 V4.1 bug fix
SET CPU ITS ITS compatible microcode SET CPU ITS ITS compatible microcode
CPU registers include the visible state of the processor as well as the 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) 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 DECtape reset in PDP-8, PDP-11, PDP-9/15
Fixed RIM loader PC handling in PDP-9/15 Fixed RIM loader PC handling in PDP-9/15
Fixed indirect pointers in PDP-10 paging Fixed indirect pointers in PDP-10 paging
Fixed SSC handling in PDP-10 TM02/TU45 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 Rev 2.6, May, 01
Added ENABLE/DISABLE devices Added ENABLE/DISABLE devices

View file

@ -457,9 +457,62 @@ To load and run BASIC:
RUN RUN
1.41421 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. 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 TOPS-20 was a popular alternative derived from the BBN TENEX system.
http://pdp-10.trailing-edge.com. 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] [end simh_swre.txt]