1
0
mirror of https://github.com/simh/simh.git synced 2026-01-25 11:46:37 +00:00

Notes For V3.7-0

1. New Features

1.1 3.7-0

1.1.1 SCP

- Added SET THROTTLE and SET NOTHROTTLE commands to regulate simulator
  execution rate and host resource utilization.
- Added idle support (based on work by Mark Pizzolato).
- Added -e to control error processing in nested DO commands (from
  Dave Bryan).

1.1.2 HP2100

- Added Double Integer instructions, 1000-F CPU, and Floating Point
  Processor (from Dave Bryan).
- Added 2114 and 2115 CPUs, 12607B and 12578A DMA controllers, and
  21xx binary loader protection (from Dave Bryan).

1.1.3 Interdata

- Added SET IDLE and SET NOIDLE commands to idle the simulator in wait
  state.

1.1.4 PDP-11

- Added SET IDLE and SET NOIDLE commands to idle the simulator in wait
  state (WAIT instruction executed).
- Added TA11/TU60 cassette support.

1.1.5 PDP-8

- Added SET IDLE and SET NOIDLE commands to idle the simulator in wait
  state (keyboard poll loop or jump-to-self).
- Added TA8E/TU60 cassette support.

1.1.6 PDP-1

- Added support for 16-channel sequence break system.
- Added support for PDP-1D extended features and timesharing clock.
- Added support for Type 630 data communications subsystem.

1.1.6 PDP-4/7/9/15

- Added SET IDLE and SET NOIDLE commands to idle the simulator in wait
  state (keyboard poll loop or jump-to-self).

1.1.7 VAX, VAX780

- Added SET IDLE and SET NOIDLE commands to idle the simulator in wait
  state (more than 200 cycles at IPL's 0, 1, or 3 in kernel mode).

1.1.8 PDP-10

- Added SET IDLE and SET NOIDLE commands to idle the simulator in wait
  state (operating system dependent).
- Added CD20 (CD11) support.

2. Bugs Fixed

Please see the revision history on http://simh.trailing-edge.com or
in the source module sim_rev.h.
This commit is contained in:
Bob Supnik
2007-02-03 14:59:00 -08:00
committed by Mark Pizzolato
parent 15919a2dd7
commit 53d02f7fa7
161 changed files with 18604 additions and 6903 deletions

125
PDP1/pdp1_clk.c Normal file
View File

@@ -0,0 +1,125 @@
/* pdp1_clk.c: PDP-1D clock simulator
Copyright (c) 2006, 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
bused in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
clk PDP-1D clock
Note that the clock is run at 1/8 of real speed (125Hz instead of 1Khz), to
provide for eventual implementation of idling.
*/
#include "pdp1_defs.h"
#define CLK_HWRE_TPS 1000 /* hardware freq */
#define CLK_TPS 125 /* sim freq */
#define CLK_CNTS (CLK_HWRE_TPS / CLK_TPS) /* counts per tick */
#define CLK_C1MIN (1000 * 60) /* counts per min */
#define CLK_C32MS 32 /* counts per 32ms */
int32 clk32ms_sbs = 0; /* 32ms SBS level */
int32 clk1min_sbs = 0; /* 1min SBS level */
int32 clk_cntr = 0;
int32 tmxr_poll = 5000;
extern int32 stop_inst;
t_stat clk_svc (UNIT *uptr);
t_stat clk_reset (DEVICE *dptr);
/* CLK data structures
clk_dev CLK device descriptor
clk_unit CLK unit
clk_reg CLK register list
*/
UNIT clk_unit = {
UDATA (&clk_svc, 0, 0), 5000
};
REG clk_reg[] = {
{ ORDATA (CNTR, clk_cntr, 16) },
{ DRDATA (SBS32LVL, clk32ms_sbs, 4), REG_HRO },
{ DRDATA (SBS1MLVL, clk1min_sbs, 4), REG_HRO },
{ NULL }
};
MTAB clk_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "SBS32MSLVL", "SBS32MSLVL",
&dev_set_sbs, &dev_show_sbs, (void *) &clk32ms_sbs },
{ MTAB_XTD|MTAB_VDV, 0, "SBS1MINLVL", "SBS1MINLVL",
&dev_set_sbs, &dev_show_sbs, (void *) &clk1min_sbs },
{ 0 }
};
DEVICE clk_dev = {
"CLK", &clk_unit, clk_reg, clk_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &clk_reset,
NULL, NULL, NULL,
NULL, DEV_DISABLE | DEV_DIS
};
/* Clock IOT routine */
int32 clk (int32 inst, int32 dev, int32 dat)
{
int32 used, incr;
if (clk_dev.flags & DEV_DIS) /* disabled? */
return (stop_inst << IOT_V_REASON) | dat; /* illegal inst */
used = tmxr_poll - (sim_is_active (&clk_unit) - 1);
incr = (used * CLK_CNTS) / tmxr_poll;
return clk_cntr + incr;
}
/* Unit service, generate appropriate interrupts */
t_stat clk_svc (UNIT *uptr)
{
if (clk_dev.flags & DEV_DIS) return SCPE_OK; /* disabled? */
tmxr_poll = sim_rtcn_calb (CLK_TPS, TMR_CLK); /* calibrate clock */
sim_activate (&clk_unit, tmxr_poll); /* reactivate unit */
clk_cntr = clk_cntr + CLK_CNTS; /* incr counter */
if ((clk_cntr % CLK_C32MS) == 0) /* 32ms interval? */
dev_req_int (clk32ms_sbs); /* req intr */
if (clk_cntr >= CLK_C1MIN) { /* 1min interval? */
dev_req_int (clk1min_sbs); /* req intr */
clk_cntr = 0; /* reset counter */
}
return SCPE_OK;
}
/* Reset routine */
t_stat clk_reset (DEVICE *dptr)
{
if (clk_dev.flags & DEV_DIS) sim_cancel (&clk_unit); /* disabled? */
else {
tmxr_poll = sim_rtcn_init (clk_unit.wait, TMR_CLK);
sim_activate_abs (&clk_unit, tmxr_poll); /* activate unit */
}
clk_cntr = 0; /* clear counter */
return SCPE_OK;
}

File diff suppressed because it is too large Load Diff

431
PDP1/pdp1_dcs.c Normal file
View File

@@ -0,0 +1,431 @@
/* pdp1_dcs.c: PDP-1D terminal multiplexor simulator
Copyright (c) 2006, 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.
dcs Type 630 data communications subsystem
This module implements up to 32 individual serial interfaces.
*/
#include "pdp1_defs.h"
#include "sim_sock.h"
#include "sim_tmxr.h"
#define DCS_LINES 32 /* lines */
#define DCS_LINE_MASK (DCS_LINES - 1)
#define DCSL_WAIT 1000 /* output wait */
#define DCS_NUMLIN dcs_desc.lines
int32 dcs_sbs = 0; /* SBS level */
uint32 dcs_send = 0; /* line for send */
uint32 dcs_scan = 0; /* line for scanner */
uint8 dcs_flg[DCS_LINES]; /* line flags */
uint8 dcs_buf[DCS_LINES]; /* line bufffers */
extern int32 iosta, stop_inst;
extern int32 tmxr_poll;
TMLN dcs_ldsc[DCS_LINES] = { 0 }; /* line descriptors */
TMXR dcs_desc = { DCS_LINES, 0, 0, dcs_ldsc }; /* mux descriptor */
t_stat dcsi_svc (UNIT *uptr);
t_stat dcso_svc (UNIT *uptr);
t_stat dcs_reset (DEVICE *dptr);
t_stat dcs_attach (UNIT *uptr, char *cptr);
t_stat dcs_detach (UNIT *uptr);
t_stat dcs_summ (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat dcs_show (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat dcs_vlines (UNIT *uptr, int32 val, char *cptr, void *desc);
void dcs_reset_ln (int32 ln);
void dcs_scan_next (t_bool unlk);
/* DCS data structures
dcs_dev DCS device descriptor
dcs_unit DCS unit descriptor
dcs_reg DCS register list
dcs_mod DCS modifiers list
*/
REG dcs_nlreg = { DRDATA (NLINES, DCS_NUMLIN, 6), PV_LEFT };
UNIT dcs_unit = { UDATA (&dcsi_svc, UNIT_ATTABLE, 0) };
REG dcs_reg[] = {
{ BRDATA (BUF, dcs_buf, 8, 8, DCS_LINES) },
{ BRDATA (FLAGS, dcs_flg, 8, 1, DCS_LINES) },
{ FLDATA (SCNF, iosta, IOS_V_DCS) },
{ ORDATA (SCAN, dcs_scan, 5) },
{ ORDATA (SEND, dcs_send, 5) },
{ DRDATA (SBSLVL, dcs_sbs, 4), REG_HRO },
{ NULL }
};
MTAB dcs_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "SBSLVL", "SBSLVL",
&dev_set_sbs, &dev_show_sbs, (void *) &dcs_sbs },
{ MTAB_XTD | MTAB_VDV | MTAB_VAL, 0, "lines", "LINES",
&dcs_vlines, NULL, &dcs_nlreg },
{ MTAB_XTD | MTAB_VDV, 1, NULL, "DISCONNECT",
&tmxr_dscln, NULL, &dcs_desc },
{ UNIT_ATT, UNIT_ATT, "connections", NULL, NULL, &dcs_summ },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL,
NULL, &dcs_show, NULL },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL,
NULL, &dcs_show, NULL },
{ 0 }
};
DEVICE dcs_dev = {
"DCS", &dcs_unit, dcs_reg, dcs_mod,
1, 10, 31, 1, 8, 8,
&tmxr_ex, &tmxr_dep, &dcs_reset,
NULL, &dcs_attach, &dcs_detach,
NULL, DEV_NET | DEV_DISABLE | DEV_DIS
};
/* DCSL data structures
dcsl_dev DCSL device descriptor
dcsl_unit DCSL unit descriptor
dcsl_reg DCSL register list
dcsl_mod DCSL modifiers list
*/
UNIT dcsl_unit[] = {
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
{ UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT }
};
MTAB dcsl_mod[] = {
{ TT_MODE, TT_MODE_UC, "UC", "UC", NULL },
{ TT_MODE, TT_MODE_7B, "7b", "7B", NULL },
{ TT_MODE, TT_MODE_8B, "8b", "8B", NULL },
{ TT_MODE, TT_MODE_7P, "7p", "7P", NULL },
{ MTAB_XTD|MTAB_VUN, 0, NULL, "DISCONNECT",
&tmxr_dscln, NULL, &dcs_desc },
{ MTAB_XTD|MTAB_VUN|MTAB_NC, 0, "LOG", "LOG",
&tmxr_set_log, &tmxr_show_log, &dcs_desc },
{ MTAB_XTD|MTAB_VUN|MTAB_NC, 0, NULL, "NOLOG",
&tmxr_set_nolog, NULL, &dcs_desc },
{ 0 }
};
REG dcsl_reg[] = {
{ URDATA (TIME, dcsl_unit[0].wait, 10, 24, 0,
DCS_LINES, REG_NZ + PV_LEFT) },
{ NULL }
};
DEVICE dcsl_dev = {
"DCSL", dcsl_unit, dcsl_reg, dcsl_mod,
DCS_LINES, 10, 31, 1, 8, 8,
NULL, NULL, &dcs_reset,
NULL, NULL, NULL,
NULL, DEV_DIS
};
/* DCS IOT routine */
int32 dcs (int32 inst, int32 dev, int32 dat)
{
int32 pls = (inst >> 6) & 077;
if (dcs_dev.flags & DEV_DIS) /* disabled? */
return (stop_inst << IOT_V_REASON) | dat; /* illegal inst */
if (pls & 020) dat = 0; /* pulse 20? clr IO */
switch (pls & 057) { /* case IR<6,8:11> */
case 000: /* RCH */
dat |= dcs_buf[dcs_scan]; /* return line buf */
dcs_flg[dcs_scan] = 0; /* clr line flag */
break;
case 001: /* RRC */
dat |= dcs_scan; /* return line num */
break;
case 010: /* RCC */
dat |= dcs_buf[dcs_scan]; /* return line buf */
dcs_flg[dcs_scan] = 0; /* clr line flag */
/* fall through */
case 011: /* RSC */
dcs_scan_next (TRUE); /* unlock scanner */
break;
case 040: /* TCB */
dcs_buf[dcs_send] = dat & 0377; /* load buffer */
dcs_flg[dcs_send] = 0; /* clr line flag */
sim_activate (&dcsl_unit[dcs_send], dcsl_unit[dcs_send].wait);
break;
case 041: /* SSB */
dcs_send = dat & DCS_LINE_MASK; /* load line num */
break;
case 050: /* TCC */
dcs_buf[dcs_scan] = dat & 0377; /* load buffer */
dcs_flg[dcs_scan] = 0; /* clr line flag */
sim_activate (&dcsl_unit[dcs_scan], dcsl_unit[dcs_scan].wait);
dcs_scan_next (TRUE); /* unlock scanner */
break;
default:
return (stop_inst << IOT_V_REASON) | dat; /* illegal inst */
} /* end case */
return dat;
}
/* Unit service - receive side
Poll all active lines for input
Poll for new connections
*/
t_stat dcsi_svc (UNIT *uptr)
{
int32 ln, c, out;
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_OK; /* attached? */
if (dcs_dev.flags & DEV_DIS) return SCPE_OK;
sim_activate (uptr, tmxr_poll); /* continue poll */
ln = tmxr_poll_conn (&dcs_desc); /* look for connect */
if (ln >= 0) { /* got one? */
dcs_ldsc[ln].rcve = 1; /* set rcv enable */
}
tmxr_poll_rx (&dcs_desc); /* poll for input */
for (ln = 0; ln < DCS_NUMLIN; ln++) { /* loop thru lines */
if (dcs_ldsc[ln].conn) { /* connected? */
if (c = tmxr_getc_ln (&dcs_ldsc[ln])) { /* get char */
if (c & SCPE_BREAK) c = 0; /* break? */
else c = sim_tt_inpcvt (c, TT_GET_MODE (dcsl_unit[ln].flags)|TTUF_KSR);
dcs_buf[ln] = c; /* save char */
dcs_flg[ln] = 1; /* set line flag */
dcs_scan_next (FALSE); /* kick scanner */
out = sim_tt_outcvt (c & 0177, TT_GET_MODE (dcsl_unit[ln].flags));
if (out >= 0) {
tmxr_putc_ln (&dcs_ldsc[ln], out); /* echo char */
tmxr_poll_tx (&dcs_desc); /* poll xmt */
}
}
}
else dcs_ldsc[ln].rcve = 0; /* disconnected */
} /* end for */
return SCPE_OK;
}
/* Unit service - transmit side */
t_stat dcso_svc (UNIT *uptr)
{
int32 c;
uint32 ln = uptr - dcsl_unit; /* line # */
if (dcs_dev.flags & DEV_DIS) return SCPE_OK;
if (dcs_ldsc[ln].conn) { /* connected? */
if (dcs_ldsc[ln].xmte) { /* xmt enabled? */
c = sim_tt_outcvt (dcs_buf[ln] & 0177, TT_GET_MODE (uptr->flags));
if (c >= 0) tmxr_putc_ln (&dcs_ldsc[ln], c); /* output char */
tmxr_poll_tx (&dcs_desc); /* poll xmt */
}
else { /* buf full */
tmxr_poll_tx (&dcs_desc); /* poll xmt */
sim_activate (uptr, uptr->wait); /* reschedule */
return SCPE_OK;
}
}
dcs_flg[ln] = 1; /* set line flag */
dcs_scan_next (FALSE); /* kick scanner */
return SCPE_OK;
}
/* Kick scanner */
void dcs_scan_next (t_bool unlk)
{
int32 i;
if (unlk) iosta &= ~IOS_DCS; /* unlock? */
else if (iosta & IOS_DCS) return; /* no, locked? */
for (i = 0; i < DCS_LINES; i++) { /* scan flags */
dcs_scan = (dcs_scan + 1) & DCS_LINE_MASK; /* next flag */
if (dcs_flg[dcs_scan] != 0) { /* flag set? */
iosta |= IOS_DCS; /* lock scanner */
dev_req_int (dcs_sbs); /* request intr */
return;
}
}
return;
}
/* Reset routine */
t_stat dcs_reset (DEVICE *dptr)
{
int32 i;
if (dcs_dev.flags & DEV_DIS) /* master disabled? */
dcsl_dev.flags = dcsl_dev.flags | DEV_DIS; /* disable lines */
else dcsl_dev.flags = dcsl_dev.flags & ~DEV_DIS;
if (dcs_unit.flags & UNIT_ATT) /* master att? */
sim_activate_abs (&dcs_unit, tmxr_poll); /* activate */
else sim_cancel (&dcs_unit); /* else stop */
for (i = 0; i < DCS_LINES; i++) dcs_reset_ln (i); /* reset lines */
dcs_send = 0;
dcs_scan = 0;
iosta &= ~IOS_DCS; /* clr intr req */
return SCPE_OK;
}
/* Attach master unit */
t_stat dcs_attach (UNIT *uptr, char *cptr)
{
t_stat r;
r = tmxr_attach (&dcs_desc, uptr, cptr); /* attach */
if (r != SCPE_OK) return r; /* error */
sim_activate_abs (uptr, tmxr_poll); /* start poll */
return SCPE_OK;
}
/* Detach master unit */
t_stat dcs_detach (UNIT *uptr)
{
int32 i;
t_stat r;
r = tmxr_detach (&dcs_desc, uptr); /* detach */
for (i = 0; i < DCS_LINES; i++) dcs_ldsc[i].rcve = 0; /* disable rcv */
sim_cancel (uptr); /* stop poll */
return r;
}
/* Show summary processor */
t_stat dcs_summ (FILE *st, UNIT *uptr, int32 val, void *desc)
{
int32 i, t;
for (i = t = 0; i < DCS_LINES; i++) t = t + (dcs_ldsc[i].conn != 0);
if (t == 1) fprintf (st, "1 connection");
else fprintf (st, "%d connections", t);
return SCPE_OK;
}
/* SHOW CONN/STAT processor */
t_stat dcs_show (FILE *st, UNIT *uptr, int32 val, void *desc)
{
int32 i, t;
for (i = t = 0; i < DCS_LINES; i++) t = t + (dcs_ldsc[i].conn != 0);
if (t) {
for (i = 0; i < DCS_LINES; i++) {
if (dcs_ldsc[i].conn) {
if (val) tmxr_fconns (st, &dcs_ldsc[i], i);
else tmxr_fstats (st, &dcs_ldsc[i], i);
}
}
}
else fprintf (st, "all disconnected\n");
return SCPE_OK;
}
/* Change number of lines */
t_stat dcs_vlines (UNIT *uptr, int32 val, char *cptr, void *desc)
{
int32 newln, i, t;
t_stat r;
if (cptr == NULL) return SCPE_ARG;
newln = get_uint (cptr, 10, DCS_LINES, &r);
if ((r != SCPE_OK) || (newln == DCS_NUMLIN)) return r;
if (newln == 0) return SCPE_ARG;
if (newln < DCS_LINES) {
for (i = newln, t = 0; i < DCS_NUMLIN; i++) t = t | dcs_ldsc[i].conn;
if (t && !get_yn ("This will disconnect users; proceed [N]?", FALSE))
return SCPE_OK;
for (i = newln; i < DCS_NUMLIN; i++) {
if (dcs_ldsc[i].conn) {
tmxr_linemsg (&dcs_ldsc[i], "\r\nOperator disconnected line\r\n");
tmxr_reset_ln (&dcs_ldsc[i]); /* reset line */
}
dcsl_unit[i].flags = dcsl_unit[i].flags | UNIT_DIS;
dcs_reset_ln (i);
}
}
else {
for (i = DCS_NUMLIN; i < newln; i++) {
dcsl_unit[i].flags = dcsl_unit[i].flags & ~UNIT_DIS;
dcs_reset_ln (i);
}
}
DCS_NUMLIN = newln;
return SCPE_OK;
}
/* Reset an individual line */
void dcs_reset_ln (int32 ln)
{
sim_cancel (&dcsl_unit[ln]);
dcs_buf[ln] = 0;
dcs_flg[ln] = 0;
return;
}

View File

@@ -1,6 +1,6 @@
/* pdp1_defs.h: 18b PDP simulator definitions
Copyright (c) 1993-2005, Robert M. Supnik
Copyright (c) 1993-2006, 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"),
@@ -23,6 +23,7 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
21-Dec-06 RMS Added 16-channel sequence break support
22-Jul-05 RMS Fixed definition of CPLS_DPY
08-Feb-04 PLB Added support for display
08-Dec-03 RMS Added support for parallel drum
@@ -61,6 +62,7 @@
#define STOP_IND 5 /* nested indirects */
#define STOP_WAIT 6 /* IO wait hang */
#define STOP_DTOFF 7 /* DECtape off reel */
#define ERR_RMV 10 /* restrict mode viol */
/* Memory */
@@ -72,6 +74,7 @@
/* Architectural constants */
#define SIGN 0400000 /* sign */
#define DMASK 0777777 /* data mask */
#define DAMASK 0007777 /* direct addr */
#define EPCMASK (AMASK & ~DAMASK) /* extended addr */
@@ -83,6 +86,37 @@
#define OP_JMP 0600000 /* JMP */
#define GEN_CPLS(x) (((x) ^ ((x) << 1)) & IO_WAIT) /* completion pulse? */
/* Program flags/sense switches */
#define PF_V_L 7
#define PF_V_RNG 6
#define PF_L (1u << PF_V_L)
#define PF_RNG (1u << PF_V_RNG)
#define PF_SS_1 0040
#define PF_SS_2 0020
#define PF_SS_3 0010
#define PF_SS_4 0004
#define PF_SS_5 0002
#define PF_SS_6 0001
#define PF_VR_ALL 0377
#define PF_SS_ALL 0077
/* Restict mode */
#define RTB_IOT 0400000
#define RTB_ILL 0200000
#define RTB_HLT 0100000
#define RTB_DBK 0040000
#define RTB_CHR 0020000
#define RTB_MB_MASK 0017777
#define RM45_V_BNK 14
#define RM45_M_BNK 003
#define RM48_V_BNK 12
#define RM48_M_BNK 017
#define RN45_SIZE 4
/* IOT subroutine return codes */
#define IOT_V_SKP 18 /* skip */
@@ -100,8 +134,9 @@
#define IOS_V_PTP 13 /* paper tape punch */
#define IOS_V_DRM 12 /* drum */
#define IOS_V_SQB 11 /* sequence break */
#define IOS_V_PNT 2 /* print done */
#define IOS_V_SPC 1 /* space done */
#define IOS_V_PNT 3 /* print done */
#define IOS_V_SPC 2 /* space done */
#define IOS_V_DCS 1 /* data comm sys */
#define IOS_V_DRP 0 /* parallel drum busy */
#define IOS_LPN (1 << IOS_V_LPN)
@@ -113,6 +148,7 @@
#define IOS_SQB (1 << IOS_V_SQB)
#define IOS_PNT (1 << IOS_V_PNT)
#define IOS_SPC (1 << IOS_V_SPC)
#define IOS_DCS (1 << IOS_V_DCS)
#define IOS_DRP (1 << IOS_V_DRP)
/* Completion pulses */
@@ -128,7 +164,7 @@
#define CPLS_LPT (1 << CPLS_V_LPT)
#define CPLS_DPY (1 << CPLS_V_DPY)
/* Sequence break flags */
/* One channel sequence break */
#define SB_V_IP 0 /* in progress */
#define SB_V_RQ 1 /* request */
@@ -138,4 +174,21 @@
#define SB_RQ (1 << SB_V_RQ)
#define SB_ON (1 << SB_V_ON)
/* 16 channel sequence break */
#define SBS_LVLS 16 /* num levels */
#define SBS_LVL_MASK (SBS_LVLS - 1)
#define SBS_LVL_RMV 14 /* restrict level */
#define SBS_MASK(x) (1u << (SBS_LVLS - 1 - (x))) /* level to mask */
/* Timers */
#define TMR_CLK 0
/* Device routines */
t_stat dev_req_int (int32 lvl);
t_stat dev_set_sbs (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat dev_show_sbs (FILE *st, UNIT *uptr, int32 val, void *desc);
#endif

View File

@@ -1,6 +1,6 @@
/* pdp1_drm.c: PDP-1 drum simulator
Copyright (c) 1993-2005, Robert M Supnik
Copyright (c) 1993-2006, 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"),
@@ -26,6 +26,7 @@
drp Type 23 parallel drum
drm Type 24 serial drum
21-Dec-06 RMS Added 16-chan SBS support
08-Dec-03 RMS Added parallel drum support
Fixed bug in DBL/DCN decoding
26-Oct-03 RMS Cleaned up buffer copy code
@@ -71,7 +72,7 @@
((double) DRM_NUMWDT)))
extern int32 M[];
extern int32 iosta, sbs;
extern int32 iosta;
extern int32 stop_inst;
extern UNIT cpu_unit;
@@ -82,6 +83,7 @@ uint32 drm_ma = 0; /* memory address */
uint32 drm_err = 0; /* error flag */
uint32 drm_wlk = 0; /* write lock */
int32 drm_time = 4; /* inter-word time */
int32 drm_sbs = 0; /* SBS level */
int32 drm_stopioe = 1; /* stop on error */
/* Parallel drum variables */
@@ -123,12 +125,19 @@ REG drm_reg[] = {
{ FLDATA (ERR, drm_err, 0) },
{ ORDATA (WLK, drm_wlk, 32) },
{ DRDATA (TIME, drm_time, 24), REG_NZ + PV_LEFT },
{ DRDATA (SBSLVL, drm_sbs, 4), REG_HRO },
{ FLDATA (STOP_IOE, drm_stopioe, 0) },
{ NULL }
};
MTAB drm_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "APILVL", "APILVL",
&dev_set_sbs, &dev_show_sbs, (void *) &drm_sbs },
{ 0 }
};
DEVICE drm_dev = {
"DRM", &drm_unit, drm_reg, NULL,
"DRM", &drm_unit, drm_reg, drm_mod,
1, 8, 20, 1, 8, 18,
NULL, NULL, &drm_reset,
NULL, NULL, NULL,
@@ -159,6 +168,7 @@ REG drp_reg[] = {
{ FLDATA (ERR, drp_err, 0) },
{ DRDATA (TIME, drp_time, 24), REG_NZ + PV_LEFT },
{ FLDATA (STOP_IOE, drp_stopioe, 0) },
{ DRDATA (SBSLVL, drm_sbs, 4), REG_HRO },
{ NULL }
};
@@ -266,7 +276,7 @@ uint32 *fbuf = uptr->filebuf;
if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */
drm_err = 1; /* set error */
iosta = iosta | IOS_DRM; /* set done */
sbs = sbs | SB_RQ; /* req intr */
dev_req_int (drm_sbs); /* req intr */
return IORETURN (drm_stopioe, SCPE_UNATT);
}
@@ -287,7 +297,7 @@ for (i = 0; i < DRM_NUMWDS; i++, da++) { /* do transfer */
}
drm_da = (drm_da + 1) & DRM_SMASK; /* incr dev addr */
iosta = iosta | IOS_DRM; /* set done */
sbs = sbs | SB_RQ; /* req intr */
dev_req_int (drm_sbs); /* req intr */
return SCPE_OK;
}
@@ -314,7 +324,7 @@ uint32 *fbuf = uptr->filebuf;
if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */
drp_err = 1; /* set error */
iosta = iosta & ~IOS_DRP; /* clear busy */
if (uptr->FUNC) sbs = sbs | SB_RQ; /* req intr */
if (uptr->FUNC) dev_req_int (drm_sbs); /* req intr */
return IORETURN (drp_stopioe, SCPE_UNATT);
}
@@ -330,7 +340,7 @@ if (uptr->FUNC == DRP_RW) { /* read/write? */
} /* end for */
} /* end if */
iosta = iosta & ~IOS_DRP; /* clear busy */
if (uptr->FUNC) sbs = sbs | SB_RQ; /* req intr */
if (uptr->FUNC) dev_req_int (drm_sbs); /* req intr */
return SCPE_OK;
}

View File

@@ -25,6 +25,7 @@
dt Type 550/555 DECtape
21-Dec-06 RMS Added 16-channel SBS support
23-Jun-06 RMS Fixed conflict in ATTACH switches
Revised header format
16-Aug-05 RMS Fixed C++ declaration and cast problems
@@ -179,7 +180,7 @@
#define DTA_RW 077
#define DTA_GETUNIT(x) map_unit[(((x) >> DTA_V_UNIT) & DTA_M_UNIT)]
#define DT_UPDINT if (dtsb & (DTB_DTF | DTB_BEF | DTB_ERF)) \
sbs = sbs | SB_RQ;
dev_req_int (dt_sbs);
#define DTA_GETMOT(x) (((x) >> DTA_V_MOT) & DTA_M_MOT)
#define DTA_GETFNC(x) (((x) >> DTA_V_FNC) & DTA_M_FNC)
@@ -247,7 +248,6 @@
#define ABS(x) (((x) < 0)? (-(x)): (x))
extern int32 M[];
extern int32 sbs;
extern int32 stop_inst;
extern UNIT cpu_unit;
extern int32 sim_switches;
@@ -257,6 +257,7 @@ extern FILE *sim_deb;
int32 dtsa = 0; /* status A */
int32 dtsb = 0; /* status B */
int32 dtdb = 0; /* data buffer */
int32 dt_sbs = 0; /* SBS level */
int32 dt_ltime = 12; /* interline time */
int32 dt_dctime = 40000; /* decel time */
int32 dt_substate = 0;
@@ -326,10 +327,13 @@ REG dt_reg[] = {
{ URDATA (LASTT, dt_unit[0].LASTT, 10, 32, 0,
DT_NUMDR, REG_HRO) },
{ FLDATA (STOP_OFFR, dt_stopoffr, 0) },
{ DRDATA (SBSLVL, dt_sbs, 4), REG_HRO },
{ NULL }
};
MTAB dt_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "SBSLVL", "SBSLVL",
&dev_set_sbs, &dev_show_sbs, (void *) &dt_sbs },
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
{ UNIT_8FMT + UNIT_11FMT, 0, "18b", NULL, NULL },

View File

@@ -1,6 +1,6 @@
/* pdp1_lp.c: PDP-1 line printer simulator
Copyright (c) 1993-2005, Robert M. Supnik
Copyright (c) 1993-2006, 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"),
@@ -25,6 +25,7 @@
lpt Type 62 line printer for the PDP-1
21-Dec-06 RMS Added 16-channel SBS support
07-Sep-03 RMS Changed ioc to ios
23-Jul-03 RMS Fixed bugs in instruction decoding, overprinting
Revised to detect I/O wait hang
@@ -43,6 +44,7 @@ int32 lpt_spc = 0; /* print (0) vs spc */
int32 lpt_ovrpr = 0; /* overprint */
int32 lpt_stopioe = 0; /* stop on error */
int32 lpt_bptr = 0; /* buffer ptr */
int32 lpt_sbs = 0; /* SBS level */
char lpt_buf[LPT_BSIZE + 1] = { 0 };
static const unsigned char lpt_trans[64] = {
' ','1','2','3','4','5','6','7','8','9','\'','~','#','V','^','<',
@@ -51,7 +53,7 @@ static const unsigned char lpt_trans[64] = {
'_','A','B','C','D','E','F','G','H','I','*','.','+',']','|','['
};
extern int32 ios, cpls, sbs, iosta;
extern int32 ios, cpls, iosta;
extern int32 stop_inst;
t_stat lpt_svc (UNIT *uptr);
@@ -80,11 +82,18 @@ REG lpt_reg[] = {
{ DRDATA (TIME, lpt_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, lpt_stopioe, 0) },
{ BRDATA (LBUF, lpt_buf, 8, 8, LPT_BSIZE) },
{ DRDATA (SBSLVL, lpt_sbs, 4), REG_HRO },
{ NULL }
};
MTAB lpt_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "SBSLVL", "SBSLVL",
&dev_set_sbs, &dev_show_sbs, (void *) &lpt_sbs },
{ 0 }
};
DEVICE lpt_dev = {
"LPT", &lpt_unit, lpt_reg, NULL,
"LPT", &lpt_unit, lpt_reg, lpt_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &lpt_reset,
NULL, NULL, NULL,
@@ -151,7 +160,7 @@ if (cpls & CPLS_LPT) { /* completion pulse? */
ios = 1; /* restart */
cpls = cpls & ~CPLS_LPT; /* clr pulse pending */
}
sbs = sbs | SB_RQ; /* req seq break */
dev_req_int (lpt_sbs); /* req interrupt */
if (lpt_spc) { /* space? */
iosta = iosta | IOS_SPC; /* set flag */
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */

View File

@@ -1,6 +1,6 @@
/* pdp1_stddev.c: PDP-1 standard devices
Copyright (c) 1993-2005, Robert M. Supnik
Copyright (c) 1993-2006, 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"),
@@ -28,6 +28,7 @@
tti keyboard
tto teleprinter
21-Dec-06 RMS Added 16-channel sequence break support
29-Oct-03 RMS Added PTR FIODEC-to-ASCII translation (from Phil Budne)
07-Sep-03 RMS Changed ioc to ios
30-Aug-03 RMS Revised PTR to conform to Maintenance Manual;
@@ -58,8 +59,6 @@
#define BOTH (1 << (UC_V + 1)) /* both cases */
#define CW (1 << (UC_V + 2)) /* char waiting */
#define TT_WIDTH 077
#define TTI 0
#define TTO 1
#define UNIT_V_ASCII (UNIT_V_UF + 0) /* ASCII/binary mode */
#define UNIT_ASCII (1 << UNIT_V_ASCII)
#define PTR_LEADER 20 /* ASCII leader chars */
@@ -70,12 +69,16 @@ int32 ptr_stopioe = 0;
int32 ptr_uc = 0; /* upper/lower case */
int32 ptr_hold = 0; /* holding buffer */
int32 ptr_leader = PTR_LEADER; /* leader count */
int32 ptr_sbs = 0; /* SBS level */
int32 ptp_stopioe = 0;
int32 ptp_sbs = 0; /* SBS level */
int32 tti_hold = 0; /* tti hold buf */
int32 tti_sbs = 0; /* SBS level */
int32 tty_buf = 0; /* tty buffer */
int32 tty_uc = 0; /* tty uc/lc */
int32 tto_sbs = 0;
extern int32 sbs, ios, ioh, cpls, iosta;
extern int32 ios, ioh, cpls, iosta;
extern int32 PF, IO, PC, TA;
extern int32 M[];
@@ -154,10 +157,13 @@ REG ptr_reg[] = {
{ DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
{ DRDATA (LEADER, ptr_leader, 6), REG_HRO },
{ FLDATA (STOP_IOE, ptr_stopioe, 0) },
{ DRDATA (SBSLVL, ptr_sbs, 4), REG_HRO },
{ NULL }
};
MTAB ptr_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "SBSLVL", "SBSLVL",
&dev_set_sbs, &dev_show_sbs, (void *) &ptr_sbs },
{ UNIT_ASCII, UNIT_ASCII, "ASCII", "ASCII", NULL },
{ UNIT_ASCII, 0, "FIODEC", "FIODEC", NULL },
{ 0 }
@@ -189,46 +195,87 @@ REG ptp_reg[] = {
{ DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, ptp_stopioe, 0) },
{ DRDATA (SBSLVL, ptp_sbs, 4), REG_HRO },
{ NULL }
};
MTAB ptp_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "SBSLVL", "SBSLVL",
&dev_set_sbs, &dev_show_sbs, (void *) &ptp_sbs },
{ 0 }
};
DEVICE ptp_dev = {
"PTP", &ptp_unit, ptp_reg, NULL,
"PTP", &ptp_unit, ptp_reg, ptp_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &ptp_reset,
NULL, NULL, NULL,
NULL, 0
};
/* TTY data structures
/* TTI data structures
tty_dev TTY device descriptor
tty_unit TTY unit
tty_reg TTY register list
tti_dev TTI device descriptor
tti_unit TTI unit
tti_reg TTI register list
*/
UNIT tty_unit[] = {
{ UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT },
{ UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT * 10 }
};
UNIT tti_unit = { UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT };
REG tty_reg[] = {
REG tti_reg[] = {
{ ORDATA (BUF, tty_buf, 6) },
{ FLDATA (UC, tty_uc, UC_V) },
{ FLDATA (RPLS, cpls, CPLS_V_TTO) },
{ ORDATA (HOLD, tti_hold, 9), REG_HRO },
{ FLDATA (KDONE, iosta, IOS_V_TTI) },
{ DRDATA (KPOS, tty_unit[TTI].pos, T_ADDR_W), PV_LEFT },
{ DRDATA (KTIME, tty_unit[TTI].wait, 24), REG_NZ + PV_LEFT },
{ FLDATA (TDONE, iosta, IOS_V_TTO) },
{ DRDATA (TPOS, tty_unit[TTO].pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TTIME, tty_unit[TTO].wait, 24), PV_LEFT },
{ FLDATA (DONE, iosta, IOS_V_TTI) },
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
{ DRDATA (SBSLVL, tti_sbs, 4), REG_HRO },
{ NULL }
};
DEVICE tty_dev = {
"TTY", tty_unit, tty_reg, NULL,
2, 10, 31, 1, 8, 8,
MTAB tti_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "SBSLVL", "SBSLVL",
&dev_set_sbs, &dev_show_sbs, (void *) &tti_sbs },
{ 0 }
};
DEVICE tti_dev = {
"TTI", &tti_unit, tti_reg, tti_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tty_reset,
NULL, NULL, NULL,
NULL, 0
};
/* TTO data structures
tto_dev TTO device descriptor
tto_unit TTO unit
tto_reg TTO register list
*/
UNIT tto_unit = { UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT * 10 };
REG tto_reg[] = {
{ ORDATA (BUF, tty_buf, 6) },
{ FLDATA (UC, tty_uc, UC_V) },
{ FLDATA (RPLS, cpls, CPLS_V_TTO) },
{ FLDATA (DONE, iosta, IOS_V_TTO) },
{ DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
{ DRDATA (SBSLVL, tto_sbs, 4), REG_HRO },
{ NULL }
};
MTAB tto_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "SBSLVL", "SBSLVL",
&dev_set_sbs, &dev_show_sbs, (void *) &tto_sbs },
{ 0 }
};
DEVICE tto_dev = {
"TTO", &tto_unit, tto_reg, tto_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tty_reset,
NULL, NULL, NULL,
NULL, 0
@@ -309,7 +356,7 @@ if (ptr_state == 0) { /* done? */
}
else { /* no, interrupt */
iosta = iosta | IOS_PTR; /* set flag */
sbs = sbs | SB_RQ; /* req seq break */
dev_req_int (ptr_sbs); /* req interrupt */
}
}
else sim_activate (uptr, uptr->wait); /* get next char */
@@ -443,7 +490,7 @@ if (cpls & CPLS_PTP) { /* completion pulse? */
cpls = cpls & ~CPLS_PTP;
}
iosta = iosta | IOS_PTP; /* set flag */
sbs = sbs | SB_RQ; /* req seq break */
dev_req_int (ptp_sbs); /* req interrupt */
if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */
return IORETURN (ptp_stopioe, SCPE_UNATT);
if (putc (uptr->buf, uptr->fileref) == EOF) { /* I/O error? */
@@ -485,7 +532,7 @@ if (GEN_CPLS (inst)) { /* comp pulse? */
cpls = cpls | CPLS_TTO;
}
else cpls = cpls & ~CPLS_TTO;
sim_activate (&tty_unit[TTO], tty_unit[TTO].wait); /* activate unit */
sim_activate (&tto_unit, tto_unit.wait); /* activate unit */
return dat;
}
@@ -518,8 +565,8 @@ else {
}
}
iosta = iosta | IOS_TTI; /* set flag */
sbs = sbs | SB_RQ; /* req seq break */
PF = PF | 040; /* set prog flag 1 */
dev_req_int (tti_sbs); /* req interrupt */
PF = PF | PF_SS_1; /* set prog flag 1 */
uptr->pos = uptr->pos + 1;
return SCPE_OK;
}
@@ -543,7 +590,7 @@ if (cpls & CPLS_TTO) { /* completion pulse? */
cpls = cpls & ~CPLS_TTO;
}
iosta = iosta | IOS_TTO; /* set flag */
sbs = sbs | SB_RQ; /* req seq break */
dev_req_int (tto_sbs); /* req interrupt */
uptr->pos = uptr->pos + 1;
if (c == '\r') { /* cr? add lf */
sim_putchar ('\n');
@@ -561,7 +608,7 @@ tty_uc = 0; /* clear case */
tti_hold = 0; /* clear hold buf */
cpls = cpls & ~CPLS_TTO;
iosta = (iosta & ~IOS_TTI) | IOS_TTO; /* clear flag */
sim_activate (&tty_unit[TTI], tty_unit[TTI].wait); /* activate keyboard */
sim_cancel (&tty_unit[TTO]); /* stop printer */
sim_activate (&tti_unit, tti_unit.wait); /* activate keyboard */
sim_cancel (&tto_unit); /* stop printer */
return SCPE_OK;
}

View File

@@ -1,6 +1,6 @@
/* pdp1_sys.c: PDP-1 simulator interface
Copyright (c) 1993-2004, Robert M. Supnik
Copyright (c) 1993-2007, 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"),
@@ -23,6 +23,8 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
03-Jan-07 RMS Fixed bugs in block loader, char input
21-Dec-06 RMS Added 16-channel sequence break support, PDP-1D support
06-Apr-04 RMS Fixed bug in binary loader (found by Mark Crispin)
08-Feb-04 PLB Merged display support
08-Dec-03 RMS Added parallel drum support, drum mnemonics
@@ -46,13 +48,16 @@
#include <ctype.h>
extern DEVICE cpu_dev;
extern DEVICE clk_dev;
extern DEVICE ptr_dev;
extern DEVICE ptp_dev;
extern DEVICE tty_dev;
extern DEVICE tti_dev;
extern DEVICE tto_dev;
extern DEVICE lpt_dev;
extern DEVICE dt_dev;
extern DEVICE drm_dev;
extern DEVICE drp_dev;
extern DEVICE dcs_dev, dcsl_dev;
extern DEVICE dpy_dev;
extern UNIT cpu_unit;
extern REG cpu_reg[];
@@ -80,13 +85,17 @@ int32 sim_emax = 1;
DEVICE *sim_devices[] = {
&cpu_dev,
&clk_dev,
&ptr_dev,
&ptp_dev,
&tty_dev,
&tti_dev,
&tto_dev,
&lpt_dev,
&dt_dev,
&drm_dev,
&drp_dev,
&dcs_dev,
&dcsl_dev,
/* &dpy_dev, */
NULL
};
@@ -152,13 +161,13 @@ for (;;) {
if ((val = pdp1_getw (inf)) < 0) return SCPE_FMT;
if ((val & 0760000) != OP_DIO) return SCPE_FMT;
csum = csum + val;
if (csum > 0777777) csum = (csum + 1) & 0777777;
count = (val & DAMASK) - start + 1; /* block count */
if (csum > DMASK) csum = (csum + 1) & DMASK;
count = (val & DAMASK) - start; /* block count */
if (count <= 0) return SCPE_FMT;
while (count--) { /* loop on data */
if ((val = pdp1_getw (inf)) < 0) return SCPE_FMT;
csum = csum + val;
if (csum > 0777777) csum = (csum + 1) & 0777777;
if (csum > DMASK) csum = (csum + 1) & DMASK;
M[fld | start] = val;
start = (start + 1) & DAMASK;
}
@@ -196,7 +205,7 @@ return SCPE_OK;
/* Symbol tables */
#define I_V_FL 18 /* inst class */
#define I_M_FL 07 /* class mask */
#define I_M_FL 017 /* class mask */
#define I_V_NPN 0 /* no operand */
#define I_V_IOT 1 /* IOT */
#define I_V_LAW 2 /* LAW */
@@ -205,6 +214,7 @@ return SCPE_OK;
#define I_V_OPR 5 /* OPR */
#define I_V_SKP 6 /* skip */
#define I_V_SHF 7 /* shift */
#define I_V_SPC 8 /* special */
#define I_NPN (I_V_NPN << I_V_FL) /* no operand */
#define I_IOT (I_V_IOT << I_V_FL) /* IOT */
#define I_LAW (I_V_LAW << I_V_FL) /* LAW */
@@ -213,10 +223,12 @@ return SCPE_OK;
#define I_OPR (I_V_OPR << I_V_FL) /* OPR */
#define I_SKP (I_V_SKP << I_V_FL) /* skip */
#define I_SHF (I_V_SHF << I_V_FL) /* shift */
#define I_SPC (I_V_SPC << I_V_FL)
static const int32 masks[] = {
0777777, 0763777, 0760000, 0760000,
0770000, 0760017, 0760077, 0777000
0777777, 0760077, 0760000, 0760000,
0770000, 0760017, 0760077, 0777000,
0760003
};
static const char *opcode[] = {
@@ -224,22 +236,30 @@ static const char *opcode[] = {
"LAC", "LIO", "DAC", "DAP",
"DIP", "DIO", "DZM", "ADD",
"SUB", "IDX", "ISP", "SAD",
"SAS", "MUL", "DIV", "JMP", "JSP",
"SAS", "MUL", "DIV", "JMP",
"JSP", "LCH", "DCH", "TAD",
"CAL", "JDA", /* mem ref no ind */
"LAW",
"IOH", "RPA", "RPB", "RRB", /* I/O instructions */
"PPA", "PPB", "TYO", "TYI",
"DPY",
"DSC", "ASC", "ISC", "CAC",
"LSM", "ESM", "CBS",
"LEM", "EEM", "CKS",
"MSE", "MLC", "MRD", "MWR", "MRS",
"DIA", "DBA", "DWC", "DRA", "DCL",
"DRD", "DWR", "DBL", "DCN",
"DTD", "DSE", "DSP",
"LRG", "ERG", "LRM", "ERM",
"RNM", "RSM", "RCK", "CTB",
"RCH", "RCC", "TCC", "TCB",
"RRC", "SSB", "RSC",
"SKP", "SKP I", "CLO",
"SFT", "LAW", "OPR",
"SKP", "SKP I", "CLO", /* base as NPNs */
"SFT", "SPC", "OPR",
"RAL", "RIL", "RCL", /* shifts */
"SAL", "SIL", "SCL",
@@ -268,12 +288,24 @@ static const char *opcode[] = {
"STF1", "STF2", "STF3",
"STF4", "STF5", "STF6", "STF7",
"SZA", "SPA", "SMA", /* encode only */
"SZO", "SPI", "I",
"FF1", "FF2", "FF3", /* specials */
"SZA", "SPA", "SMA", /* uprog skips */
"SZO", "SPI", "SNI",
"I", /* encode only */
"LIA", "LAI", "SWP", /* uprog opers */
"LAP", "CLA", "HLT",
"CMA", "LAT", "CLI",
NULL, NULL, /* decode only */
NULL
"CMI",
"CML", "CLL", "SZL", /* uprog specials */
"SCF", "SCI", "SCM",
"IDA", "IDC", "IFI",
"IIF",
NULL, NULL, NULL, /* decode only */
NULL,
};
static const int32 opc_val[] = {
@@ -281,22 +313,30 @@ static const int32 opc_val[] = {
0200000+I_MRF, 0220000+I_MRF, 0240000+I_MRF, 0260000+I_MRF,
0300000+I_MRF, 0320000+I_MRF, 0340000+I_MRF, 0400000+I_MRF,
0420000+I_MRF, 0440000+I_MRF, 0460000+I_MRF, 0500000+I_MRF,
0520000+I_MRF, 0540000+I_MRF, 0560000+I_MRF, 0600000+I_MRF, 0620000+I_MRF,
0520000+I_MRF, 0540000+I_MRF, 0560000+I_MRF, 0600000+I_MRF,
0620000+I_MRF, 0120000+I_MRF, 0140000+I_MRF, 0360000+I_MRF,
0160000+I_MRI, 0170000+I_MRI,
0700000+I_LAW,
0730000+I_NPN, 0720001+I_IOT, 0720002+I_IOT, 0720030+I_IOT,
0720005+I_IOT, 0720006+I_IOT, 0720003+I_IOT, 0720004+I_IOT,
0720007+I_IOT,
0720050+I_IOT, 0720051+I_IOT, 0720052+I_IOT, 0720053+I_NPN,
0720054+I_NPN, 0720055+I_NPN, 0720056+I_NPN,
0720074+I_NPN, 0724074+I_NPN, 0720033+I_NPN,
0720301+I_NPN, 0720401+I_NPN, 0720501+I_NPN, 0720601+I_NPN, 0720701+I_NPN,
0720061+I_NPN, 0722061+I_NPN, 0720062+I_NPN, 0722062+I_NPN, 0720063+I_NPN,
0720161+I_NPN, 0721161+I_NPN, 0720162+I_NPN, 0721162+I_NPN,
0720163+I_NPN, 0720164+I_NPN, 0721164+I_NPN,
0720010+I_NPN, 0720011+I_NPN, 0720064+I_NPN, 0720065+I_NPN,
0720066+I_IOT, 0720067+I_NPN, 0720032+I_NPN, 0720035+I_NPN,
0720022+I_NPN, 0721022+I_NPN, 0725022+I_NPN, 0724022+I_NPN,
0720122+I_NPN, 0724122+I_NPN, 0721122+I_NPN,
0640000+I_NPN, 0650000+I_NPN, 0651600+I_NPN,
0660000+I_NPN, 0700000+I_LAW, 0760000+I_NPN,
0660000+I_NPN, 0740000+I_NPN, 0760000+I_NPN,
0661000+I_SHF, 0662000+I_SHF, 0663000+I_SHF,
0665000+I_SHF, 0666000+I_SHF, 0667000+I_SHF,
@@ -325,12 +365,23 @@ static const int32 opc_val[] = {
0760011+I_OPR, 0760012+I_OPR, 0760013+I_OPR,
0760014+I_OPR, 0760015+I_OPR, 0760016+I_OPR, 0760017+I_OPR,
0640100+I_SKP, 0640200+I_SKP, 0640400+I_SKP, /* encode only */
0641000+I_SKP, 0642000+I_SKP, 0010000+I_SKP,
0740001+I_SPC, 0740002+I_SPC, 0740003+I_OPR,
0640100+I_SKP, 0640200+I_SKP, 0640400+I_SKP,
0641000+I_SKP, 0642000+I_SKP, 0644000+I_SKP,
0010000+I_SKP, /* encode only */
0760020+I_OPR, 0760040+I_OPR, 0760060+I_NPN,
0760100+I_OPR, 0760200+I_OPR, 0760400+I_OPR,
0761000+I_OPR, 0762000+I_OPR, 0764000+I_OPR,
0770000+I_OPR,
0640000+I_SKP, 0760000+I_OPR, /* decode only */
0740004+I_SPC, 0740010+I_SPC, 0740020+I_SPC,
0740040+I_SPC, 0740100+I_SPC, 0740200+I_SPC,
0740400+I_SPC, 0741000+I_SPC, 0742000+I_SPC,
0744000+I_SPC,
0640000+I_SKP, 0740000+I_SPC, 0760000+I_OPR, /* decode only */
-1
};
@@ -406,7 +457,7 @@ disp = inst & 007777;
ma = (addr & EPCMASK) | disp;
for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
j = (opc_val[i] >> I_V_FL) & I_M_FL; /* get class */
if ((opc_val[i] & 0777777) == (inst & masks[j])) { /* match? */
if ((opc_val[i] & DMASK) == (inst & masks[j])) { /* match? */
switch (j) { /* case on class */
@@ -433,7 +484,7 @@ for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
break;
case I_V_OPR: /* operates */
sp = fprint_opr (of, inst & 007700, j, 0);
sp = fprint_opr (of, inst & 017760, j, 0);
if (opcode[i]) fprintf (of, (sp? " %s": "%s"), opcode[i]);
break;
@@ -443,6 +494,12 @@ for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
if (inst & IA) fprintf (of, sp? " I": "I");
break;
case I_V_SPC: /* specials */
sp = fprint_opr (of, inst & 007774, j, 0);
if (opcode[i]) sp = fprintf (of, (sp? " %s": "%s"), opcode[i]);
if (inst & IA) fprintf (of, sp? " I": "I");
break;
case I_V_SHF: /* shifts */
fprintf (of, "%s %-d", opcode[i], sc_map[inst & 0777]);
break;
@@ -475,7 +532,7 @@ else if (*cptr == '-') {
*sign = -1;
cptr++;
}
return get_uint (cptr, 8, 0777777, status);
return get_uint (cptr, 8, DMASK, status);
}
/* Symbolic input
@@ -508,16 +565,16 @@ if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */
}
if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* sixbit string? */
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
val[0] = (ASCTOSIX (cptr[0] & 077) << 12) |
(ASCTOSIX (cptr[1] & 077) << 6) |
ASCTOSIX (cptr[2] & 077);
val[0] = ((ASCTOSIX (cptr[0]) & 077) << 12) |
((ASCTOSIX (cptr[1]) & 077) << 6) |
(ASCTOSIX (cptr[2]) & 077);
return SCPE_OK;
}
cptr = get_glyph (cptr, gbuf, 0); /* get opcode */
for (i = 0; (opcode[i] != NULL) && (strcmp (opcode[i], gbuf) != 0) ; i++) ;
if (opcode[i] == NULL) return SCPE_ARG;
val[0] = opc_val[i] & 0777777; /* get value */
val[0] = opc_val[i] & DMASK; /* get value */
j = (opc_val[i] >> I_V_FL) & I_M_FL; /* get class */
switch (j) { /* case on class */
@@ -545,13 +602,14 @@ switch (j) { /* case on class */
val[0] = val[0] | sc_enc[d];
break;
case I_V_NPN: case I_V_IOT: case I_V_OPR: case I_V_SKP:
case I_V_NPN: case I_V_IOT:
case I_V_OPR: case I_V_SKP: case I_V_SPC:
for (cptr = get_glyph (cptr, gbuf, 0); gbuf[0] != 0;
cptr = get_glyph (cptr, gbuf, 0)) {
for (i = 0; (opcode[i] != NULL) &&
(strcmp (opcode[i], gbuf) != 0); i++) ;
if (opcode[i] != NULL) {
k = opc_val[i] & 0777777;
k = opc_val[i] & DMASK;
if ((k != IA) && (((k ^ val[0]) & 0760000) != 0))
return SCPE_ARG;
val[0] = val[0] | k;