Notes For V3.0-2

RESTRICTION: The FP15 and XVM features of the PDP-15 are only partially
debugged.  Do NOT enable these features for normal operations.

1. New Features in 3.0-2

1.1 PDP-1

- The LOAD command takes an optional argument specifying the memory field
  to be loaded.
- The PTR BOOT command takes its starting memory field from the TA (address
  switch) register.

2. Bugs Fixed in 3.0-2

2.1 SCP and libraries

- Fixed end of file problem in dep, idep.
- Fixed handling of trailing spaces in dep, idep.

2.2 PDP-1

- Fixed system hang if continue after PTR error.
- Fixed PTR to start/stop on successive rpa instructions.

2.3 PDP 18b family

- Fixed priorities in PDP-15 API (differs from PDP-9).
- Fixed sign handling in PDP-15 EAE unsigned mul/div (differs from PDP-9).
- Fixed bug in CAF, clears API subsystem.

2.4 1401

- Fixed tape read end-of-record handling based on real 1401.
- Added diagnostic read (space forward).

2.5 1620

- Fixed bug in immediate index add (found by Michael Short).

3. New Features in 3.0 vs prior releases

3.1 SCP and Libraries

- Added ASSIGN/DEASSIGN (logical name) commands.
- Changed RESTORE to unconditionally detach files.
- Added E11 and TPC format support to magtape library.
- Fixed bug in SHOW CONNECTIONS.
- Added USE_ADDR64 support

3.2 All magtapes

- Magtapes support SIMH format, E11 format, and TPC format (read only).
- SET <tape_unit> FORMAT=format sets the specified tape unit's format.
- SHOW <tape_unit> FORMAT displays the specified tape unit's format.
- Tape format can also be set as part of the ATTACH command, using
  the -F switch.

3.3 VAX

- VAX can be compiled without USE_INT64.
- If compiled with USE_INT64 and USE_ADDR64, RQ and TQ controllers support
  files > 2GB.
- VAX ROM has speed control (SET ROM DELAY/NODELAY).

3.4 PDP-1

- Added block loader format support to LOAD.
- Changed BOOT PTR to allow loading of all of the first bank of memory.

3.5 PDP-18b Family

- Added PDP-4 EAE support.
- Added PDP-15 FP15 support.
- Added PDP-15 XVM support.
- Added PDP-15 "re-entrancy ECO".
- Added PDP-7, PDP-9, PDP-15 hardware RIM loader support in BOOT PTR.

4. Bugs Fixed in 3.0 vs prior releases

4.1 VAX

- Fixed CVTfi bug: integer overflow not set if exponent out of range
- Fixed EMODx bugs:
  o First and second operands reversed
  o Separated fraction received wrong exponent
  o Overflow calculation on separated integer incorrect
  o Fraction not set to zero if exponent out of range
- Fixed interval timer and ROM access to pass power-up self-test even on very
  fast host processors (fixes from Mark Pizzolato).
- Fixed bug in user disk size (found by Chaskiel M Grundman).

4.2 1401

- Fixed mnemonic, instruction lengths, and reverse scan length check bug for MCS.
- Fixed MCE bug, BS off by 1 if zero suppress.
- Fixed chaining bug, D lost if return to SCP.
- Fixed H branch, branch occurs after continue.
- Added check for invalid 8 character MCW, LCA.
- Fixed magtape load-mode end of record response.
- Revised fetch to model hardware more closely.

4.3 Nova

- Fixed DSK variable size interaction with restore.
- Fixed bug in DSK set size routine.

4.4 PDP-1

- Fixed DT variable size interaction with restore.
- Updated CPU, line printer, standard devices to detect indefinite I/O wait.
- Fixed incorrect logical, missing activate, break in drum simulator.
- Fixed bugs in instruction decoding, overprinting for line printer.

4.5 PDP-11

- Fixed DT variable size interaction with restore.
- Fixed bug in MMR1 update (found by Tim Stark).
- Added XQ features and fixed bugs:
  o Corrected XQ interrupts on IE state transition (code by Tom Evans).
  o Added XQ interrupt clear on soft reset.
  o Removed XQ interrupt when setting XL or RL (multiple people).
  o Added SET/SHOW XQ STATS.
  o Added SHOW XQ FILTERS.
  o Added ability to split received packet into multiple buffers.
  o Added explicit runt and giant packet processing.
- Fixed bug in user disk size (found by Chaskiel M Grundman).

4.6 PDP-18B

- Fixed DT, RF variable size interaction with restore.
- Fixed MT bug in MTTR.
- Fixed bug in PDP-4 line printer overprinting.
- Fixed bug in PDP-15 memory protect/skip interaction.
- Fixed bug in RF set size routine.
- Increased PTP TIME for PDP-15 operating systems.

4.7 PDP-8

- Fixed DT, DF, RF, RX variable size interaction with restore.
- Fixed MT bug in SKTR.
- Fixed bug in DF, RF set size routine.

4.8 HP2100

- Fixed bug in DP (13210A controller only), DQ read status.
- Fixed bug in DP, DQ seek complete.
- Fixed DR drum sizes.
- Fixed DR variable capacity interaction with SAVE/RESTORE.

4.9 GRI

- Fixed bug in SC queue pointer management.

4.10 PDP-10

- Fixed bug in RP read header.

4.11 Ibm1130

- Fixed bugs found by APL 1130.

4.12 Altairz80

- Fixed bug in real-time clock on Windows host.
This commit is contained in:
Bob Supnik 2003-09-15 18:00:00 -07:00 committed by Mark Pizzolato
parent f9564b81b9
commit b2101ecdd4
21 changed files with 554 additions and 216 deletions

View file

@ -1,71 +1,43 @@
Notes For V3.0-1 Notes For V3.0-2
RESTRICTION: The FP15 and XVM features of the PDP-15 are only partially RESTRICTION: The FP15 and XVM features of the PDP-15 are only partially
debugged. Do NOT enable these features for normal operations. debugged. Do NOT enable these features for normal operations.
1. New Features in 3.0-1 1. New Features in 3.0-2
1.1 PDP-1 1.1 PDP-1
- Added block loader format support to LOAD. - The LOAD command takes an optional argument specifying the memory field
- Changed BOOT PTR to allow loading of all of the first bank of memory. to be loaded.
- The PTR BOOT command takes its starting memory field from the TA (address
switch) register.
1.2 PDP-18b Family 2. Bugs Fixed in 3.0-2
- Added PDP-4 EAE support. 2.1 SCP and libraries
- Added PDP-15 FP15 support.
- Added PDP-15 XVM support.
- Added PDP-15 "re-entrancy ECO".
- Added PDP-7, PDP-9, PDP-15 hardware RIM loader support in BOOT PTR.
2. Bugs Fixed in 3.0-1 - Fixed end of file problem in dep, idep.
- Fixed handling of trailing spaces in dep, idep.
2.1 PDP-11/VAX
- Fixed bug in user disk size (found by Chaskiel M Grundman).
2.2 PDP-1 2.2 PDP-1
- Updated CPU, line printer, standard devices to detect indefinite I/O wait. - Fixed system hang if continue after PTR error.
- Fixed incorrect logical, missing activate, break in drum simulator. - Fixed PTR to start/stop on successive rpa instructions.
- Fixed bugs in instruction decoding, overprinting for line printer.
2.3 PDP-10 2.3 PDP 18b family
- Fixed bug in RP read header. - Fixed priorities in PDP-15 API (differs from PDP-9).
- Fixed sign handling in PDP-15 EAE unsigned mul/div (differs from PDP-9).
- Fixed bug in CAF, clears API subsystem.
2.4 PDP-18b Family 2.4 1401
- Fixed bug in PDP-4 line printer overprinting. - Fixed tape read end-of-record handling based on real 1401.
- Fixed bug in PDP-15 memory protect/skip interaction. - Added diagnostic read (space forward).
- Fixed bug in RF set size routine.
- Increased PTP TIME for PDP-15 operating systems.
2.5 PDP-8 2.5 1620
- Fixed bug in DF, RF set size routine.
2.6 Nova
- Fixed bug in DSK set size routine.
2.7 1401
- Revised fetch to model hardware more closely.
2.8 Ibm1130
- Fixed bugs found by APL 1130.
2.9 Altairz80
- Fixed bug in real-time clock on Windows host.
2.10 HP2100
-- Fixed DR drum sizes.
-- Fixed DR variable capacity interaction with SAVE/RESTORE.
- Fixed bug in immediate index add (found by Michael Short).
3. New Features in 3.0 vs prior releases 3. New Features in 3.0 vs prior releases
@ -92,6 +64,19 @@ debugged. Do NOT enable these features for normal operations.
files > 2GB. files > 2GB.
- VAX ROM has speed control (SET ROM DELAY/NODELAY). - VAX ROM has speed control (SET ROM DELAY/NODELAY).
3.4 PDP-1
- Added block loader format support to LOAD.
- Changed BOOT PTR to allow loading of all of the first bank of memory.
3.5 PDP-18b Family
- Added PDP-4 EAE support.
- Added PDP-15 FP15 support.
- Added PDP-15 XVM support.
- Added PDP-15 "re-entrancy ECO".
- Added PDP-7, PDP-9, PDP-15 hardware RIM loader support in BOOT PTR.
4. Bugs Fixed in 3.0 vs prior releases 4. Bugs Fixed in 3.0 vs prior releases
4.1 VAX 4.1 VAX
@ -104,6 +89,7 @@ debugged. Do NOT enable these features for normal operations.
o Fraction not set to zero if exponent out of range o Fraction not set to zero if exponent out of range
- Fixed interval timer and ROM access to pass power-up self-test even on very - Fixed interval timer and ROM access to pass power-up self-test even on very
fast host processors (fixes from Mark Pizzolato). fast host processors (fixes from Mark Pizzolato).
- Fixed bug in user disk size (found by Chaskiel M Grundman).
4.2 1401 4.2 1401
@ -113,14 +99,19 @@ debugged. Do NOT enable these features for normal operations.
- Fixed H branch, branch occurs after continue. - Fixed H branch, branch occurs after continue.
- Added check for invalid 8 character MCW, LCA. - Added check for invalid 8 character MCW, LCA.
- Fixed magtape load-mode end of record response. - Fixed magtape load-mode end of record response.
- Revised fetch to model hardware more closely.
4.3 Nova 4.3 Nova
- Fixed DSK variable size interaction with restore. - Fixed DSK variable size interaction with restore.
- Fixed bug in DSK set size routine.
4.4 PDP-1 4.4 PDP-1
- Fixed DT variable size interaction with restore. - Fixed DT variable size interaction with restore.
- Updated CPU, line printer, standard devices to detect indefinite I/O wait.
- Fixed incorrect logical, missing activate, break in drum simulator.
- Fixed bugs in instruction decoding, overprinting for line printer.
4.5 PDP-11 4.5 PDP-11
@ -134,22 +125,42 @@ debugged. Do NOT enable these features for normal operations.
o Added SHOW XQ FILTERS. o Added SHOW XQ FILTERS.
o Added ability to split received packet into multiple buffers. o Added ability to split received packet into multiple buffers.
o Added explicit runt and giant packet processing. o Added explicit runt and giant packet processing.
- Fixed bug in user disk size (found by Chaskiel M Grundman).
4.6 PDP-18B 4.6 PDP-18B
- Fixed DT, RF variable size interaction with restore. - Fixed DT, RF variable size interaction with restore.
- Fixed MT bug in MTTR. - Fixed MT bug in MTTR.
- Fixed bug in PDP-4 line printer overprinting.
- Fixed bug in PDP-15 memory protect/skip interaction.
- Fixed bug in RF set size routine.
- Increased PTP TIME for PDP-15 operating systems.
4.7 PDP-8 4.7 PDP-8
- Fixed DT, DF, RF, RX variable size interaction with restore. - Fixed DT, DF, RF, RX variable size interaction with restore.
- Fixed MT bug in SKTR. - Fixed MT bug in SKTR.
- Fixed bug in DF, RF set size routine.
4.8 HP2100 4.8 HP2100
- Fixed bug in DP (13210A controller only), DQ read status. - Fixed bug in DP (13210A controller only), DQ read status.
- Fixed bug in DP, DQ seek complete. - Fixed bug in DP, DQ seek complete.
- Fixed DR drum sizes.
- Fixed DR variable capacity interaction with SAVE/RESTORE.
4.9 GRI 4.9 GRI
- Fixed bug in SC queue pointer management. - Fixed bug in SC queue pointer management.
4.10 PDP-10
- Fixed bug in RP read header.
4.11 Ibm1130
- Fixed bugs found by APL 1130.
4.12 Altairz80
- Fixed bug in real-time clock on Windows host.

View file

@ -256,7 +256,7 @@ DEVICE cpu_dev = {
/* Tables */ /* Tables */
/* Opcode table - length, dispatch, and option flags. This table is also /* Opcode table - length, dispatch, and option flags. This table is
used by the symbolic input routine to validate instruction lengths */ used by the symbolic input routine to validate instruction lengths */
const int32 op_table[64] = { const int32 op_table[64] = {
@ -563,8 +563,7 @@ PP (IS);
if (flags & NOWM) goto CHECK_LENGTH; /* I-7: SWM? done */ if (flags & NOWM) goto CHECK_LENGTH; /* I-7: SWM? done */
if ((t = M[IS]) & WM) goto CHECK_LENGTH; /* WM? 7 char inst */ if ((t = M[IS]) & WM) goto CHECK_LENGTH; /* WM? 7 char inst */
D = t; /* last char is D */ D = t; /* last char is D */
for (;;) { /* I-8: repeats until WM */ while (((t = M[IS]) & WM) == 0) { /* I-8: repeats until WM */
if ((t = M[IS]) & WM) break; /* WM? done */
D = t; /* last char is D */ D = t; /* last char is D */
PP (IS); } PP (IS); }
@ -711,9 +710,9 @@ case OP_B: /* branch */
/* Other branch instructions A check B check /* Other branch instructions A check B check
BWZ branch if (d<0>: B char WM) if branch here BWZ branch if (d<0>: B char WM) if branch fetch
(d<1>: B char zone = d zone) (d<1>: B char zone = d zone)
BBE branch if B char & d non-zero if branch here BBE branch if B char & d non-zero if branch fetch
Instruction lengths: Instruction lengths:
1 chained 1 chained

View file

@ -180,6 +180,7 @@
#define BCD_DOLLAR 053 #define BCD_DOLLAR 053
#define BCD_ASTER 054 #define BCD_ASTER 054
#define BCD_AMPER 060 #define BCD_AMPER 060
#define BCD_A 061
#define BCD_B 062 #define BCD_B 062
#define BCD_C 063 #define BCD_C 063
#define BCD_E 065 #define BCD_E 065

View file

@ -25,6 +25,9 @@
mt 7-track magtape mt 7-track magtape
16-Aug-03 RMS End-of-record on load read works like move read
(verified on real 1401)
Added diagnostic read (space forward)
25-Apr-03 RMS Revised for extended file support 25-Apr-03 RMS Revised for extended file support
28-Mar-03 RMS Added multiformat support 28-Mar-03 RMS Added multiformat support
15-Mar-03 RMS Fixed end-of-record on load read yet again 15-Mar-03 RMS Fixed end-of-record on load read yet again
@ -143,6 +146,12 @@ t_stat st;
if ((uptr = get_unit (unit)) == NULL) return STOP_INVMTU; /* valid unit? */ if ((uptr = get_unit (unit)) == NULL) return STOP_INVMTU; /* valid unit? */
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT; /* attached? */ if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT; /* attached? */
switch (mod) { /* case on modifier */ switch (mod) { /* case on modifier */
case BCD_A: /* diagnostic read */
ind[IN_END] = 0; /* clear end of file */
st = sim_tape_sprecf (uptr, &tbc); /* space fwd */
break;
case BCD_B: /* backspace */ case BCD_B: /* backspace */
ind[IN_END] = 0; /* clear end of file */ ind[IN_END] = 0; /* clear end of file */
st = sim_tape_sprecr (uptr, &tbc); /* space rev */ st = sim_tape_sprecr (uptr, &tbc); /* space rev */
@ -222,9 +231,10 @@ case BCD_R: /* read */
if (ADDR_ERR (BS)) { /* check next BS */ if (ADDR_ERR (BS)) { /* check next BS */
BS = BA | (BS % MAXMEMSIZE); BS = BA | (BS % MAXMEMSIZE);
return STOP_WRAP; } } return STOP_WRAP; } }
if (M[BS] != (BCD_GRPMRK + WM)) { /* not GM+WM at end? */ /* if (M[BS] != (BCD_GRPMRK + WM)) { /* not GM+WM at end? */
if (flag == MD_WM) M[BS] = BCD_GRPMRK; /* LCA: clear WM */ /* if (flag == MD_WM) M[BS] = BCD_GRPMRK; /* LCA: clear WM */
else M[BS] = (M[BS] & WM) | BCD_GRPMRK; } /* MCW: save WM */ /* else M[BS] = (M[BS] & WM) | BCD_GRPMRK; } /* MCW: save WM */
M[BS] = (M[BS] & WM) | BCD_GRPMRK; /* write GM, save WM */
BS++; /* adv BS */ BS++; /* adv BS */
if (ADDR_ERR (BS)) { /* check final BS */ if (ADDR_ERR (BS)) { /* check final BS */
BS = BA | (BS % MAXMEMSIZE); BS = BA | (BS % MAXMEMSIZE);

View file

@ -26,6 +26,7 @@
This CPU module incorporates code and comments from the 1620 simulator by This CPU module incorporates code and comments from the 1620 simulator by
Geoff Kuenning, with his permission. Geoff Kuenning, with his permission.
21-Aug-03 RMS Fixed bug in immediate index add (found by Michael Short)
25-Apr-03 RMS Changed t_addr to uint32 throughout 25-Apr-03 RMS Changed t_addr to uint32 throughout
18-Oct-02 RMS Fixed bugs in invalid result testing (found by Hans Pufal) 18-Oct-02 RMS Fixed bugs in invalid result testing (found by Hans Pufal)
@ -137,7 +138,7 @@ t_stat xmt_index (uint32 d, uint32 s);
t_stat xmt_divd (uint32 d, uint32 s); t_stat xmt_divd (uint32 d, uint32 s);
t_stat xmt_tns (uint32 d, uint32 s); t_stat xmt_tns (uint32 d, uint32 s);
t_stat xmt_tnf (uint32 d, uint32 s); t_stat xmt_tnf (uint32 d, uint32 s);
t_stat add_field (uint32 d, uint32 s, t_bool sub, t_bool sto, int32 *sta); t_stat add_field (uint32 d, uint32 s, t_bool sub, t_bool sto, uint32 skp, int32 *sta);
uint32 add_one_digit (uint32 dst, uint32 src, uint32 *cry); uint32 add_one_digit (uint32 dst, uint32 src, uint32 *cry);
t_stat mul_field (uint32 mpc, uint32 mpy); t_stat mul_field (uint32 mpc, uint32 mpy);
t_stat mul_one_digit (uint32 mpyd, uint32 mpcp, uint32 prop, uint32 last); t_stat mul_one_digit (uint32 mpyd, uint32 mpcp, uint32 prop, uint32 last);
@ -612,21 +613,21 @@ case OP_BNI:
case OP_A: case OP_A:
case OP_AM: case OP_AM:
reason = add_field (PAR, QAR, FALSE, TRUE, &sta); /* add, store */ reason = add_field (PAR, QAR, FALSE, TRUE, 0, &sta); /* add, store */
if (sta == ADD_CARRY) ind[IN_OVF] = 1; /* cout => ovflo */ if (sta == ADD_CARRY) ind[IN_OVF] = 1; /* cout => ovflo */
if (ar_stop && ind[IN_OVF]) reason = STOP_OVERFL; if (ar_stop && ind[IN_OVF]) reason = STOP_OVERFL;
break; break;
case OP_S: case OP_S:
case OP_SM: case OP_SM:
reason = add_field (PAR, QAR, TRUE, TRUE, &sta); /* sub, store */ reason = add_field (PAR, QAR, TRUE, TRUE, 0, &sta); /* sub, store */
if (sta == ADD_CARRY) ind[IN_OVF] = 1; /* cout => ovflo */ if (sta == ADD_CARRY) ind[IN_OVF] = 1; /* cout => ovflo */
if (ar_stop && ind[IN_OVF]) reason = STOP_OVERFL; if (ar_stop && ind[IN_OVF]) reason = STOP_OVERFL;
break; break;
case OP_C: case OP_C:
case OP_CM: case OP_CM:
reason = add_field (PAR, QAR, TRUE, FALSE, &sta); /* sub, nostore */ reason = add_field (PAR, QAR, TRUE, FALSE, 0, &sta); /* sub, nostore */
if (sta == ADD_CARRY) ind[IN_OVF] = 1; /* cout => ovflo */ if (sta == ADD_CARRY) ind[IN_OVF] = 1; /* cout => ovflo */
if (ar_stop && ind[IN_OVF]) reason = STOP_OVERFL; if (ar_stop && ind[IN_OVF]) reason = STOP_OVERFL;
break; break;
@ -720,8 +721,8 @@ case OP_MA:
case OP_BLX: case OP_BLX:
case OP_BLXM: case OP_BLXM:
idx = get_idx (ADDR_A (saved_PC, I_QL - 1)); /* get index */ idx = get_idx (ADDR_A (saved_PC, I_QL - 1)); /* get index */
if (idx < 0) { /* invalid? */ if (idx < 0) { /* disabled? */
reason = STOP_INVIDX; /* stop for now */ reason = STOP_INVIDX; /* stop */
break; } break; }
xmt_index (GET_IDXADDR (idx), QAR); /* copy Q to idx */ xmt_index (GET_IDXADDR (idx), QAR); /* copy Q to idx */
BRANCH (PAR); /* branch to P */ BRANCH (PAR); /* branch to P */
@ -731,8 +732,8 @@ case OP_BLXM:
case OP_BSX: case OP_BSX:
idx = get_idx (ADDR_A (saved_PC, I_QL - 1)); /* get index */ idx = get_idx (ADDR_A (saved_PC, I_QL - 1)); /* get index */
if (idx < 0) { /* invalid? */ if (idx < 0) { /* disabled? */
reason = STOP_INVIDX; /* stop for now */ reason = STOP_INVIDX; /* stop */
break; } break; }
xmt_index (QAR, GET_IDXADDR (idx)); /* copy idx to Q */ xmt_index (QAR, GET_IDXADDR (idx)); /* copy idx to Q */
BRANCH (PAR); /* branch to P */ BRANCH (PAR); /* branch to P */
@ -741,12 +742,21 @@ case OP_BSX:
/* Branch and modify index - P,Q are valid, Q not indexed */ /* Branch and modify index - P,Q are valid, Q not indexed */
case OP_BX: case OP_BX:
idx = get_idx (ADDR_A (saved_PC, I_QL - 1)); /* get index */
if (idx < 0) { /* disabled? */
reason = STOP_INVIDX; /* stop */
break; }
reason = add_field (GET_IDXADDR (idx), QAR, FALSE, TRUE, 0, &sta);
if (ar_stop && ind[IN_OVF]) reason = STOP_OVERFL;
BRANCH (PAR); /* branch to P */
break;
case OP_BXM: case OP_BXM:
idx = get_idx (ADDR_A (saved_PC, I_QL - 1)); /* get index */ idx = get_idx (ADDR_A (saved_PC, I_QL - 1)); /* get index */
if (idx < 0) { /* invalid? */ if (idx < 0) { /* disabled? */
reason = STOP_INVIDX; /* stop for now */ reason = STOP_INVIDX; /* stop */
break; } break; }
reason = add_field (GET_IDXADDR (idx), QAR, FALSE, TRUE, &sta); reason = add_field (GET_IDXADDR (idx), QAR, FALSE, TRUE, 3, &sta);
if (ar_stop && ind[IN_OVF]) reason = STOP_OVERFL; if (ar_stop && ind[IN_OVF]) reason = STOP_OVERFL;
BRANCH (PAR); /* branch to P */ BRANCH (PAR); /* branch to P */
break; break;
@ -754,12 +764,22 @@ case OP_BXM:
/* Branch conditionally and modify index - P,Q are valid, Q not indexed */ /* Branch conditionally and modify index - P,Q are valid, Q not indexed */
case OP_BCX: case OP_BCX:
idx = get_idx (ADDR_A (saved_PC, I_QL - 1)); /* get index */
if (idx < 0) { /* disabled? */
reason = STOP_INVIDX; /* stop */
break; }
reason = add_field (GET_IDXADDR (idx), QAR, FALSE, TRUE, 0, &sta);
if (ar_stop && ind[IN_OVF]) reason = STOP_OVERFL;
if ((ind[IN_EZ] == 0) && (sta == ADD_NOCRY)) { /* ~z, ~c, ~sign chg? */
BRANCH (PAR); } /* branch */
break;
case OP_BCXM: case OP_BCXM:
idx = get_idx (ADDR_A (saved_PC, I_QL - 1)); /* get index */ idx = get_idx (ADDR_A (saved_PC, I_QL - 1)); /* get index */
if (idx < 0) { /* invalid? */ if (idx < 0) { /* disabled? */
reason = STOP_INVIDX; /* stop for now */ reason = STOP_INVIDX; /* stop */
break; } break; }
reason = add_field (GET_IDXADDR (idx), QAR, FALSE, TRUE, &sta); reason = add_field (GET_IDXADDR (idx), QAR, FALSE, TRUE, 3, &sta);
if (ar_stop && ind[IN_OVF]) reason = STOP_OVERFL; if (ar_stop && ind[IN_OVF]) reason = STOP_OVERFL;
if ((ind[IN_EZ] == 0) && (sta == ADD_NOCRY)) { /* ~z, ~c, ~sign chg? */ if ((ind[IN_EZ] == 0) && (sta == ADD_NOCRY)) { /* ~z, ~c, ~sign chg? */
BRANCH (PAR); } /* branch */ BRANCH (PAR); } /* branch */
@ -1145,6 +1165,7 @@ return SCPE_OK;
s = source field low (Q) s = source field low (Q)
sub = TRUE if subtracting sub = TRUE if subtracting
sto = TRUE if storing sto = TRUE if storing
skp = number of source field flags, beyond sign, to ignore
Output: Output:
return = status return = status
sta = ADD_NOCRY: no carry out, no sign change sta = ADD_NOCRY: no carry out, no sign change
@ -1155,7 +1176,7 @@ return SCPE_OK;
is retained." is retained."
*/ */
t_stat add_field (uint32 d, uint32 s, t_bool sub, t_bool sto, int32 *sta) t_stat add_field (uint32 d, uint32 s, t_bool sub, t_bool sto, uint32 skp, int32 *sta)
{ {
uint32 cry, src, dst, res, comp, dp, dsv; uint32 cry, src, dst, res, comp, dp, dsv;
uint32 src_f = 0, cnt = 0, dst_f; uint32 src_f = 0, cnt = 0, dst_f;
@ -1180,7 +1201,7 @@ do { dst = M[d] & DIGIT; /* get dst digit */
if (src_f) src = 0; /* src done? src = 0 */ if (src_f) src = 0; /* src done? src = 0 */
else { else {
src = M[s] & DIGIT; /* get src digit */ src = M[s] & DIGIT; /* get src digit */
src_f = M[s] & FLAG; /* get src flag */ if (cnt >= skp) src_f = M[s] & FLAG; /* get src flag */
MM (s); } /* decr src addr */ MM (s); } /* decr src addr */
if (BAD_DIGIT (dst) || BAD_DIGIT (src)) /* bad digit? */ if (BAD_DIGIT (dst) || BAD_DIGIT (src)) /* bad digit? */
return STOP_INVDIG; return STOP_INVDIG;

View file

@ -25,6 +25,8 @@
cpu PDP-1 central processor cpu PDP-1 central processor
07-Sep-03 RMS Added additional explanation on I/O simulation
01-Sep-03 RMS Added address switches for hardware readin
23-Jul-03 RMS Revised to detect I/O wait hang 23-Jul-03 RMS Revised to detect I/O wait hang
05-Dec-02 RMS Added drum support 05-Dec-02 RMS Added drum support
06-Oct-02 RMS Revised for V2.10 06-Oct-02 RMS Revised for V2.10
@ -49,7 +51,7 @@
IOSTA I/O status register IOSTA I/O status register
SBS<0:2> sequence break flip flops SBS<0:2> sequence break flip flops
IOH I/O halt flip flop IOH I/O halt flip flop
IOC I/O completion flip flop IOS I/O syncronizer (completion) flip flop
EXTM extend mode EXTM extend mode
PF<1:6> program flags PF<1:6> program flags
SS<1:6> sense switches SS<1:6> sense switches
@ -234,12 +236,13 @@ int32 PC = 0; /* PC */
int32 OV = 0; /* overflow */ int32 OV = 0; /* overflow */
int32 SS = 0; /* sense switches */ int32 SS = 0; /* sense switches */
int32 PF = 0; /* program flags */ int32 PF = 0; /* program flags */
int32 TA = 0; /* address switches */
int32 TW = 0; /* test word */ int32 TW = 0; /* test word */
int32 iosta = 0; /* status reg */ int32 iosta = 0; /* status reg */
int32 sbs = 0; /* sequence break */ int32 sbs = 0; /* sequence break */
int32 sbs_init = 0; /* seq break startup */ int32 sbs_init = 0; /* seq break startup */
int32 ioh = 0; /* I/O halt */ int32 ioh = 0; /* I/O halt */
int32 ioc = 0; /* I/O completion */ int32 ios = 0; /* I/O syncronizer */
int32 cpls = 0; /* pending completions */ int32 cpls = 0; /* pending completions */
int32 extm = 0; /* ext mem mode */ int32 extm = 0; /* ext mem mode */
int32 extm_init = 0; /* ext mem startup */ int32 extm_init = 0; /* ext mem startup */
@ -319,6 +322,7 @@ REG cpu_reg[] = {
{ FLDATA (OV, OV, 0) }, { FLDATA (OV, OV, 0) },
{ ORDATA (PF, PF, 6) }, { ORDATA (PF, PF, 6) },
{ ORDATA (SS, SS, 6) }, { ORDATA (SS, SS, 6) },
{ ORDATA (TA, TA, ASIZE) },
{ ORDATA (TW, TW, 18) }, { ORDATA (TW, TW, 18) },
{ FLDATA (EXTM, extm, 0) }, { FLDATA (EXTM, extm, 0) },
{ ORDATA (IOSTA, iosta, 18), REG_RO }, { ORDATA (IOSTA, iosta, 18), REG_RO },
@ -326,7 +330,7 @@ REG cpu_reg[] = {
{ FLDATA (SBRQ, sbs, SB_V_RQ) }, { FLDATA (SBRQ, sbs, SB_V_RQ) },
{ FLDATA (SBIP, sbs, SB_V_IP) }, { FLDATA (SBIP, sbs, SB_V_IP) },
{ FLDATA (IOH, ioh, 0) }, { FLDATA (IOH, ioh, 0) },
{ FLDATA (IOC, ioc, 0) }, { FLDATA (IOS, ios, 0) },
{ BRDATA (PCQ, pcq, 8, ASIZE, PCQ_SIZE), REG_RO+REG_CIRC }, { BRDATA (PCQ, pcq, 8, ASIZE, PCQ_SIZE), REG_RO+REG_CIRC },
{ ORDATA (PCQP, pcq_p, 6), REG_HRO }, { ORDATA (PCQP, pcq_p, 6), REG_HRO },
{ FLDATA (STOP_INST, stop_inst, 0) }, { FLDATA (STOP_INST, stop_inst, 0) },
@ -705,12 +709,31 @@ case 033:
break; } /* end switch shifts */ break; } /* end switch shifts */
break; break;
/* IOT */ /* IOT - The simulator behaves functionally like a real PDP-1 but does not
use the same mechanisms or state bits. In particular,
- If an IOT does not specify IO_WAIT, the IOT will be executed, and the
I/O halt flag (IOH) will not be disturbed. On the real PDP-1, IOH is
stored in IHS, IOH is cleared, the IOT is executed, and then IOH is
restored from IHS. Because IHS is not otherwise used, it is not
explicitly simulated.
- If an IOT does specify IO_WAIT, then IOH specifies whether an I/O halt
(wait) is already in progress.
> If already set, I/O wait is in progress. The simulator looks for
a completion pulse (IOS). If there is a pulse, IOH is cleared. If
not, the IOT is fetched again. In either case, execution of the
IOT is skipped.
> If not set, I/O wait must start. IOH is set, the PC is backed up,
and the IOT is executed.
On a real PDP-1, IOC is the I/O command enable and enables the IOT
pulses. In the simulator, the enabling of IOT pulses is done through
code flow, and IOC is not explicitly simulated.
*/
case 035: case 035:
if (IR & IO_WAIT) { /* wait? */ if (IR & IO_WAIT) { /* wait? */
if (ioh) { /* I/O halt? */ if (ioh) { /* I/O halt? */
if (ioc) ioh = 0; /* comp pulse? done */ if (ios) ioh = 0; /* comp pulse? done */
else { /* wait more */ else { /* wait more */
PC = DECR_ADDR (PC); /* re-execute */ PC = DECR_ADDR (PC); /* re-execute */
if (cpls == 0) { /* any pending pulses? */ if (cpls == 0) { /* any pending pulses? */
@ -784,7 +807,7 @@ t_stat cpu_reset (DEVICE *dptr)
{ {
sbs = sbs_init; sbs = sbs_init;
extm = extm_init; extm = extm_init;
ioh = ioc = cpls = 0; ioh = ios = cpls = 0;
OV = 0; OV = 0;
PF = 0; PF = 0;
pcq_r = find_reg ("PCQ", NULL, dptr); pcq_r = find_reg ("PCQ", NULL, dptr);

View file

@ -1,7 +1,7 @@
To: Users To: Users
From: Bob Supnik From: Bob Supnik
Subj: PDP-1 Simulator Usage Subj: PDP-1 Simulator Usage
Date: 15-Jul-2003 Date: 15-Sep-2003
COPYRIGHT NOTICE COPYRIGHT NOTICE
@ -71,15 +71,25 @@ The PDP-1 simulator implements the following unique stop conditions:
- an unimplemented instruction is decoded, and register - an unimplemented instruction is decoded, and register
STOP_INST is set STOP_INST is set
- more than INDMAX indirect addresses are detected during - more than IND_MAX indirect addresses are detected during
memory reference address decoding memory reference address decoding
- more than XCTMAX nested executes are detected during - more than XCT_MAX nested executes are detected during
instruction execution instruction execution
- I/O wait, and no I/O operations outstanding (i.e, no I/O - I/O wait, and no I/O operations outstanding (i.e, no I/O
completion will ever occur) completion will ever occur)
The PDP-1 loader supports RIM format tapes. The DUMP command is not The PDP-1 loader supports RIM format tapes and BLK format tapes. If
implemented. the file to be loaded has an extension of .BIN, or switch -B is specified,
the file is assumed to be BLK format; otherwise, it defaults to RIM
format. LOAD takes an optional argument which specifies the starting
address of the field to be loaded:
LOAD lisp.rim -- load RIM format file lisp.rim
LOAD ddt.rim 70000 -- load RIM format file ddt.rim into
the field starting at 70000
LOAD -B macro.blk -- load BLK format file macro.blk
The DUMP command is not implemented.
2.1 CPU 2.1 CPU
@ -114,6 +124,7 @@ control registers for the interrupt system.
OV 1 overflow flag OV 1 overflow flag
PF 6 program flags<1:6> PF 6 program flags<1:6>
SS 6 sense switches<1:6> SS 6 sense switches<1:6>
TA 16 address switches
TW 18 test word (front panel switches) TW 18 test word (front panel switches)
EXTM 1 extend mode EXTM 1 extend mode
IOSTA 18 IO status register IOSTA 18 IO status register
@ -121,12 +132,14 @@ control registers for the interrupt system.
SBRQ 1 sequence break request SBRQ 1 sequence break request
SBIP 1 sequence break in progress SBIP 1 sequence break in progress
IOH 1 I/O halt in progress IOH 1 I/O halt in progress
IOC 1 I/O continue IOS 1 I/O synchronizer (completion)
PCQ[0:63] 16 PC prior to last jump or interrupt; PCQ[0:63] 16 PC prior to last jump or interrupt;
most recent PC change first most recent PC change first
STOP_INST 1 stop on undefined instruction STOP_INST 1 stop on undefined instruction
SBS_INIT 1 initial state of sequence break enable SBS_INIT 1 initial state of sequence break enable
EXTM_INIT 1 initial state of extend mode EXTM_INIT 1 initial state of extend mode
XCT_MAX 8 maximum XCT chain
IND_MAX 8 maximum nested indirect addresses
WRU 8 interrupt character WRU 8 interrupt character
2.2 Programmed I/O Devices 2.2 Programmed I/O Devices
@ -138,7 +151,9 @@ register specifies the number of the next data item to be read. Thus,
by changing POS, the user can backspace or advance the reader. by changing POS, the user can backspace or advance the reader.
The paper tape reader supports the BOOT command. BOOT PTR copies the The paper tape reader supports the BOOT command. BOOT PTR copies the
RIM loader into memory and starts it running. RIM loader into memory and starts it running. BOOT PTR loads into the
field selected by TA<0:3> (the high order four bits of the address
switches).
The paper tape reader implements these registers: The paper tape reader implements these registers:
@ -192,11 +207,11 @@ Error handling is as follows:
2.2.3 Console Typewriter (TTY) 2.2.3 Console Typewriter (TTY)
The Typewriter is a half-duplex electric typewriter (originally a The Typewriter is a half-duplex electric typewriter (originally a
Friden Flexowriter, later an IBM Sorobon B). It has only a single Friden Flexowriter, later a Sorobon-modified IBM B). It has only a
buffer and a single carriage state but distinct input and output single buffer and a single carriage state but distinct input and
done and interrupt flags. The typewriter input (TTY unit 0) polls output done and interrupt flags. The typewriter input (TTY unit 0)
the console keyboard for input. The typewriter output (TTY unit 1) polls the console keyboard for input. The typewriter output (TTY
writes to the simulator console window. unit 1) writes to the simulator console window.
The typewriter implements these registers: The typewriter implements these registers:
@ -246,8 +261,8 @@ Error handling is as follows:
2.3 Type 550/555 Microtape (DECtape) (DT) 2.3 Type 550/555 Microtape (DECtape) (DT)
The PDP-1 used the Type 550 Microtape (later renamed DECtape), a programmed The PDP-1 uses the Type 550 Microtape (later renamed DECtape), a programmed
I/O controller. PDP-1 DECtape format had 4 18b words in its block headers I/O controller. PDP-1 DECtape format has 4 18b words in its block headers
and trailers. and trailers.
DECtapes drives are numbered 1-8; in the simulator, drive 8 is unit 0. DECtapes drives are numbered 1-8; in the simulator, drive 8 is unit 0.
@ -388,7 +403,7 @@ where immediate is in the range 0 to 07777.
2.6 Character Sets 2.6 Character Sets
The PDP-1's console was a Frieden Flexowriter; its character encoding The PDP-1's first console was a Frieden Flexowriter; its character encoding
was known as FIODEC. The PDP-1's line printer used a modified Hollerith was known as FIODEC. The PDP-1's line printer used a modified Hollerith
character set. The following table provides equivalences between ASCII character set. The following table provides equivalences between ASCII
characters and the PDP-1's I/O devices. In the console table, UC stands characters and the PDP-1's I/O devices. In the console table, UC stands

View file

@ -25,6 +25,7 @@
lpt Type 62 line printer for the PDP-1 lpt Type 62 line printer for the PDP-1
07-Sep-03 RMS Changed ioc to ios
23-Jul-03 RMS Fixed bugs in instruction decoding, overprinting 23-Jul-03 RMS Fixed bugs in instruction decoding, overprinting
Revised to detect I/O wait hang Revised to detect I/O wait hang
25-Apr-03 RMS Revised for extended file support 25-Apr-03 RMS Revised for extended file support
@ -49,7 +50,7 @@ static const unsigned char lpt_trans[64] = {
'@','J','K','L','M','N','O','P','Q','R','$','=','-',')','-','(', '@','J','K','L','M','N','O','P','Q','R','$','=','-',')','-','(',
'_','A','B','C','D','E','F','G','H','I','*','.','+',']','|','[' }; '_','A','B','C','D','E','F','G','H','I','*','.','+',']','|','[' };
extern int32 ioc, cpls, sbs, iosta; extern int32 ios, cpls, sbs, iosta;
extern int32 stop_inst; extern int32 stop_inst;
t_stat lpt_svc (UNIT *uptr); t_stat lpt_svc (UNIT *uptr);
@ -110,7 +111,7 @@ else if ((inst & 07000) == 00000) { /* print */
lpt_spc = 0; } /* state = print */ lpt_spc = 0; } /* state = print */
else return (stop_inst << IOT_V_REASON) | dat; /* not implemented */ else return (stop_inst << IOT_V_REASON) | dat; /* not implemented */
if (GEN_CPLS (inst)) { /* comp pulse? */ if (GEN_CPLS (inst)) { /* comp pulse? */
ioc = 0; /* clear flop */ ios = 0; /* clear flop */
cpls = cpls | CPLS_LPT; } /* request completion */ cpls = cpls | CPLS_LPT; } /* request completion */
else cpls = cpls & ~CPLS_LPT; else cpls = cpls & ~CPLS_LPT;
sim_activate (&lpt_unit, lpt_unit.wait); /* activate */ sim_activate (&lpt_unit, lpt_unit.wait); /* activate */
@ -137,7 +138,7 @@ static const char *lpt_cc[] = {
"\f" }; "\f" };
if (cpls & CPLS_LPT) { /* completion pulse? */ if (cpls & CPLS_LPT) { /* completion pulse? */
ioc = 1; /* restart */ ios = 1; /* restart */
cpls = cpls & ~CPLS_LPT; } /* clr pulse pending */ cpls = cpls & ~CPLS_LPT; } /* clr pulse pending */
sbs = sbs | SB_RQ; /* req seq break */ sbs = sbs | SB_RQ; /* req seq break */
if (lpt_spc) { /* space? */ if (lpt_spc) { /* space? */

View file

@ -28,6 +28,9 @@
tti keyboard tti keyboard
tto teleprinter tto teleprinter
07-Sep-03 RMS Changed ioc to ios
30-Aug-03 RMS Revised PTR to conform to Maintenance Manual;
added deadlock prevention on errors
23-Jul-03 RMS Revised to detect I/O wait hang 23-Jul-03 RMS Revised to detect I/O wait hang
25-Apr-03 RMS Revised for extended file support 25-Apr-03 RMS Revised for extended file support
22-Dec-02 RMS Added break support 22-Dec-02 RMS Added break support
@ -54,13 +57,15 @@
#define TTO 1 #define TTO 1
int32 ptr_state = 0; int32 ptr_state = 0;
int32 ptr_wait = 0;
int32 ptr_stopioe = 0; int32 ptr_stopioe = 0;
int32 ptp_stopioe = 0; int32 ptp_stopioe = 0;
int32 tti_hold = 0; /* tti hold buf */ int32 tti_hold = 0; /* tti hold buf */
int32 tty_buf = 0; /* tty buffer */ int32 tty_buf = 0; /* tty buffer */
int32 tty_uc = 0; /* tty uc/lc */ int32 tty_uc = 0; /* tty uc/lc */
extern int32 sbs, ioc, cpls, iosta, PF, IO, PC; extern int32 sbs, ios, ioh, cpls, iosta;
extern int32 PF, IO, PC, TA;
extern int32 M[]; extern int32 M[];
t_stat ptr_svc (UNIT *uptr); t_stat ptr_svc (UNIT *uptr);
@ -126,6 +131,7 @@ REG ptr_reg[] = {
{ FLDATA (DONE, iosta, IOS_V_PTR) }, { FLDATA (DONE, iosta, IOS_V_PTR) },
{ FLDATA (RPLS, cpls, CPLS_V_PTR) }, { FLDATA (RPLS, cpls, CPLS_V_PTR) },
{ ORDATA (STATE, ptr_state, 5), REG_HRO }, { ORDATA (STATE, ptr_state, 5), REG_HRO },
{ FLDATA (WAIT, ptr_wait, 0), REG_HRO },
{ DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT }, { DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, ptr_stopioe, 0) }, { FLDATA (STOP_IOE, ptr_stopioe, 0) },
@ -195,19 +201,36 @@ DEVICE tty_dev = {
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, 0 }; NULL, 0 };
/* Paper tape reader: IOT routine */ /* Paper tape reader: IOT routine. Points to note:
- RPA (but not RPB) complements the reader clutch control. Thus,
if the reader is running, RPA will stop it.
- The status bit indicates data in the reader buffer that has not
been transfered to IO. It is cleared by any RB->IO operation,
including RRB and the completion pulse.
- A reader error on a wait mode operation could hang the simulator.
IOH is set; any retry (without RESET) will be NOP'd. Accordingly,
the PTR service routine clears IOH on any error during a rpa/rpb i.
*/
int32 ptr (int32 inst, int32 dev, int32 dat) int32 ptr (int32 inst, int32 dev, int32 dat)
{ {
iosta = iosta & ~IOS_PTR; /* clear flag */ if (dev == 0030) { /* RRB */
if (dev == 0030) return ptr_unit.buf; /* RRB */ iosta = iosta & ~IOS_PTR; /* clear status */
ptr_state = (dev == 0002)? 18: 0; /* mode = bin/alp */ return ptr_unit.buf; } /* return data */
if (dev == 0002) ptr_state = 18; /* RPB, mode = binary */
else if (sim_is_active (&ptr_unit)) { /* RPA, running? */
sim_cancel (&ptr_unit); /* stop reader */
return dat; }
else ptr_state = 0; /* mode = alpha */
ptr_unit.buf = 0; /* clear buffer */ ptr_unit.buf = 0; /* clear buffer */
if (inst & IO_WAIT) ptr_wait = 1; /* set ptr wait */
else ptr_wait = 0; /* from IR<5> */
if (GEN_CPLS (inst)) { /* comp pulse? */ if (GEN_CPLS (inst)) { /* comp pulse? */
ioc = 0; ios = 0;
cpls = cpls | CPLS_PTR; } cpls = cpls | CPLS_PTR; }
else cpls = cpls & ~CPLS_PTR; else cpls = cpls & ~CPLS_PTR;
sim_activate (&ptr_unit, ptr_unit.wait); sim_activate (&ptr_unit, ptr_unit.wait); /* start reader */
return dat; return dat;
} }
@ -217,11 +240,14 @@ t_stat ptr_svc (UNIT *uptr)
{ {
int32 temp; int32 temp;
if ((ptr_unit.flags & UNIT_ATT) == 0) /* attached? */ if ((ptr_unit.flags & UNIT_ATT) == 0) { /* attached? */
return IORETURN (ptr_stopioe, SCPE_UNATT); if (ptr_wait) ptr_wait = ioh = 0; /* if wait, clr ioh */
if ((cpls & CPLS_PTR) || ptr_stopioe) return SCPE_UNATT;
return SCPE_OK; }
if ((temp = getc (ptr_unit.fileref)) == EOF) { /* end of file? */ if ((temp = getc (ptr_unit.fileref)) == EOF) { /* end of file? */
if (ptr_wait) ptr_wait = ioh = 0; /* if wait, clr ioh */
if (feof (ptr_unit.fileref)) { if (feof (ptr_unit.fileref)) {
if (ptr_stopioe) printf ("PTR end of file\n"); if ((cpls & CPLS_PTR) || ptr_stopioe) printf ("PTR end of file\n");
else return SCPE_OK; } else return SCPE_OK; }
else perror ("PTR I/O error"); else perror ("PTR I/O error");
clearerr (ptr_unit.fileref); clearerr (ptr_unit.fileref);
@ -233,11 +259,13 @@ else if (temp & 0200) { /* binary */
ptr_unit.buf = ptr_unit.buf | ((temp & 077) << ptr_state); } ptr_unit.buf = ptr_unit.buf | ((temp & 077) << ptr_state); }
if (ptr_state == 0) { /* done? */ if (ptr_state == 0) { /* done? */
if (cpls & CPLS_PTR) { /* completion pulse? */ if (cpls & CPLS_PTR) { /* completion pulse? */
iosta = iosta & ~IOS_PTR; /* clear flag */
IO = ptr_unit.buf; /* fill IO */ IO = ptr_unit.buf; /* fill IO */
ioc = 1; /* restart */ ios = 1; /* restart */
cpls = cpls & ~CPLS_PTR; } cpls = cpls & ~CPLS_PTR; }
else { /* no, interrupt */
iosta = iosta | IOS_PTR; /* set flag */ iosta = iosta | IOS_PTR; /* set flag */
sbs = sbs | SB_RQ; } /* req seq break */ sbs = sbs | SB_RQ; } } /* req seq break */
else sim_activate (&ptr_unit, ptr_unit.wait); /* get next char */ else sim_activate (&ptr_unit, ptr_unit.wait); /* get next char */
return SCPE_OK; return SCPE_OK;
} }
@ -247,6 +275,7 @@ return SCPE_OK;
t_stat ptr_reset (DEVICE *dptr) t_stat ptr_reset (DEVICE *dptr)
{ {
ptr_state = 0; /* clear state */ ptr_state = 0; /* clear state */
ptr_wait = 0;
ptr_unit.buf = 0; ptr_unit.buf = 0;
cpls = cpls & ~CPLS_PTR; cpls = cpls & ~CPLS_PTR;
iosta = iosta & ~IOS_PTR; /* clear flag */ iosta = iosta & ~IOS_PTR; /* clear flag */
@ -272,16 +301,17 @@ return word;
t_stat ptr_boot (int32 unitno, DEVICE *dptr) t_stat ptr_boot (int32 unitno, DEVICE *dptr)
{ {
int32 origin, val; int32 origin, val;
int32 fld = TA & EPCMASK;
for (;;) { for (;;) {
if ((val = ptr_getw (&ptr_unit)) < 0) return SCPE_FMT; if ((val = ptr_getw (&ptr_unit)) < 0) return SCPE_FMT;
if (((val & 0760000) == OP_DIO) || /* DIO? */ if (((val & 0760000) == OP_DIO) || /* DIO? */
((val & 0760000) == OP_DAC)) { /* hack - Macro1 err */ ((val & 0760000) == OP_DAC)) { /* hack - Macro1 err */
origin = val & 07777; origin = val & DAMASK;
if ((val = ptr_getw (&ptr_unit)) < 0) return SCPE_FMT; if ((val = ptr_getw (&ptr_unit)) < 0) return SCPE_FMT;
M[origin] = val; } M[fld | origin] = val; }
else if ((val & 0760000) == OP_JMP) { /* JMP? */ else if ((val & 0760000) == OP_JMP) { /* JMP? */
PC = val & 007777; PC = fld | (val & DAMASK);
break; } break; }
else return SCPE_FMT; /* bad instr */ else return SCPE_FMT; /* bad instr */
} }
@ -295,7 +325,7 @@ int32 ptp (int32 inst, int32 dev, int32 dat)
iosta = iosta & ~IOS_PTP; /* clear flag */ iosta = iosta & ~IOS_PTP; /* clear flag */
ptp_unit.buf = (dev == 0006)? ((dat >> 12) | 0200): (dat & 0377); ptp_unit.buf = (dev == 0006)? ((dat >> 12) | 0200): (dat & 0377);
if (GEN_CPLS (inst)) { /* comp pulse? */ if (GEN_CPLS (inst)) { /* comp pulse? */
ioc = 0; ios = 0;
cpls = cpls | CPLS_PTP; } cpls = cpls | CPLS_PTP; }
else cpls = cpls & ~CPLS_PTP; else cpls = cpls & ~CPLS_PTP;
sim_activate (&ptp_unit, ptp_unit.wait); /* start unit */ sim_activate (&ptp_unit, ptp_unit.wait); /* start unit */
@ -307,7 +337,7 @@ return dat;
t_stat ptp_svc (UNIT *uptr) t_stat ptp_svc (UNIT *uptr)
{ {
if (cpls & CPLS_PTP) { /* completion pulse? */ if (cpls & CPLS_PTP) { /* completion pulse? */
ioc = 1; /* restart */ ios = 1; /* restart */
cpls = cpls & ~CPLS_PTP; } cpls = cpls & ~CPLS_PTP; }
iosta = iosta | IOS_PTP; /* set flag */ iosta = iosta | IOS_PTP; /* set flag */
sbs = sbs | SB_RQ; /* req seq break */ sbs = sbs | SB_RQ; /* req seq break */
@ -347,7 +377,7 @@ int32 tto (int32 inst, int32 dev, int32 dat)
iosta = iosta & ~IOS_TTO; /* clear flag */ iosta = iosta & ~IOS_TTO; /* clear flag */
tty_buf = dat & TT_WIDTH; /* load buffer */ tty_buf = dat & TT_WIDTH; /* load buffer */
if (GEN_CPLS (inst)) { /* comp pulse? */ if (GEN_CPLS (inst)) { /* comp pulse? */
ioc = 0; ios = 0;
cpls = cpls | CPLS_TTO; } cpls = cpls | CPLS_TTO; }
else cpls = cpls & ~CPLS_TTO; else cpls = cpls & ~CPLS_TTO;
sim_activate (&tty_unit[TTO], tty_unit[TTO].wait); /* activate unit */ sim_activate (&tty_unit[TTO], tty_unit[TTO].wait); /* activate unit */
@ -390,7 +420,7 @@ t_stat tto_svc (UNIT *uptr)
int32 out; int32 out;
if (cpls & CPLS_TTO) { /* completion pulse? */ if (cpls & CPLS_TTO) { /* completion pulse? */
ioc = 1; /* restart */ ios = 1; /* restart */
cpls = cpls & ~CPLS_TTO; } cpls = cpls & ~CPLS_TTO; }
iosta = iosta | IOS_TTO; /* set flag */ iosta = iosta | IOS_TTO; /* set flag */
sbs = sbs | SB_RQ; /* req seq break */ sbs = sbs | SB_RQ; /* req seq break */

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.
01-Sep-03 RMS Added support for loading in multiple fields
22-Jul-03 RMS Updated for "hardware" RIM loader 22-Jul-03 RMS Updated for "hardware" RIM loader
05-Dec-02 RMS Added drum support 05-Dec-02 RMS Added drum support
21-Nov-02 RMS Changed typewriter to half duplex 21-Nov-02 RMS Changed typewriter to half duplex
@ -105,7 +106,7 @@ for (i = 0; i < 3;) {
return word; return word;
} }
t_stat rim_load (FILE *inf) t_stat rim_load (FILE *inf, int32 fld)
{ {
int32 origin, val; int32 origin, val;
@ -113,18 +114,18 @@ for (;;) {
if ((val = getw (inf)) < 0) return SCPE_FMT; if ((val = getw (inf)) < 0) return SCPE_FMT;
if (((val & 0760000) == OP_DIO) || /* DIO? */ if (((val & 0760000) == OP_DIO) || /* DIO? */
((val & 0760000) == OP_DAC)) { /* hack - Macro1 err */ ((val & 0760000) == OP_DAC)) { /* hack - Macro1 err */
origin = val & 07777; origin = val & DAMASK;
if ((val = getw (inf)) < 0) return SCPE_FMT; if ((val = getw (inf)) < 0) return SCPE_FMT;
M[origin] = val; } M[fld | origin] = val; }
else if ((val & 0760000) == OP_JMP) { /* JMP? */ else if ((val & 0760000) == OP_JMP) { /* JMP? */
PC = val & 007777; PC = fld | (val & DAMASK);
break; } break; }
else return SCPE_FMT; /* bad instr */ else return SCPE_FMT; /* bad instr */
} }
return SCPE_OK; /* done */ return SCPE_OK; /* done */
} }
t_stat blk_load (FILE *inf) t_stat blk_load (FILE *inf, int32 fld)
{ {
int32 val, start, count, csum; int32 val, start, count, csum;
@ -132,22 +133,23 @@ for (;;) {
if ((val = getw (inf)) < 0) return SCPE_FMT; /* get word, EOF? */ if ((val = getw (inf)) < 0) return SCPE_FMT; /* get word, EOF? */
if ((val & 0760000) == OP_DIO) { /* DIO? */ if ((val & 0760000) == OP_DIO) { /* DIO? */
csum = val; /* init checksum */ csum = val; /* init checksum */
start = val & 07777; /* starting addr */ start = val & DAMASK; /* starting addr */
if ((val = getw (inf)) < 0) return SCPE_FMT; if ((val = getw (inf)) < 0) return SCPE_FMT;
if ((val & 0760000) != OP_DIO) return SCPE_FMT; if ((val & 0760000) != OP_DIO) return SCPE_FMT;
csum = csum + val; csum = csum + val;
if (csum > 0777777) csum = (csum + 1) & 0777777; if (csum > 0777777) csum = (csum + 1) & 0777777;
count = (val & 07777) - start + 1; /* block count */ count = (val & DAMASK) - start + 1; /* block count */
if (count <= 0) return SCPE_FMT; if (count <= 0) return SCPE_FMT;
while (count--) { /* loop on data */ while (count--) { /* loop on data */
if ((val = getw (inf)) < 0) return SCPE_FMT; if ((val = getw (inf)) < 0) return SCPE_FMT;
csum = csum + val; csum = csum + val;
if (csum > 0777777) csum = (csum + 1) & 0777777; if (csum > 0777777) csum = (csum + 1) & 0777777;
M[start++] = val; } M[fld | start] = val;
start = (start + 1) & DAMASK; }
if ((val = getw (inf)) < 0) return SCPE_FMT; if ((val = getw (inf)) < 0) return SCPE_FMT;
if (val != csum) return SCPE_CSUM; } if (val != csum) return SCPE_CSUM; }
else if ((val & 0760000) == OP_JMP) { /* JMP? */ else if ((val & 0760000) == OP_JMP) { /* JMP? */
PC = val & 007777; PC = fld | (val & DAMASK);
break; } break; }
else return SCPE_FMT; /* bad instr */ else return SCPE_FMT; /* bad instr */
} }
@ -157,12 +159,18 @@ return SCPE_OK; /* done */
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag) t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
{ {
t_stat sta; t_stat sta;
int32 fld;
if ((*cptr != 0) || (flag != 0)) return SCPE_ARG; if (flag != 0) return SCPE_ARG;
sta = rim_load (fileref); if (cptr) {
fld = get_uint (cptr, 8, AMASK, &sta);
if (sta != SCPE_OK) return sta;
fld = fld & EPCMASK; }
else fld = 0;
sta = rim_load (fileref, fld);
if (sta != SCPE_OK) return sta; if (sta != SCPE_OK) return sta;
if ((sim_switches & SWMASK ('B')) || match_ext (fnam, "BIN")) if ((sim_switches & SWMASK ('B')) || match_ext (fnam, "BIN"))
return blk_load (fileref); return blk_load (fileref, fld);
return SCPE_OK; return SCPE_OK;
} }

View file

@ -1,7 +1,7 @@
To: Users To: Users
From: Bob Supnik From: Bob Supnik
Subj: PDP-11 Simulator Usage Subj: PDP-11 Simulator Usage
Date: 15-Jul-2003 Date: 15-Sep-2003
COPYRIGHT NOTICE COPYRIGHT NOTICE
@ -36,6 +36,10 @@ This memorandum documents the PDP-11 simulator.
1. Simulator Files 1. Simulator Files
To compile the PDP-11, you must define VM_PDP11 as part of the compilation
command line. If you want expanded file support, you must also define USE_INT64
and USE_ADDR64 as part of the compilation command line.
sim/ sim_defs.h sim/ sim_defs.h
sim_ether.h sim_ether.h
sim_rev.h sim_rev.h
@ -277,7 +281,7 @@ disabled and then RY is enabled, RY is assigned the fixed "first instance"
I/O address for floppy disks. I/O address for floppy disks.
Autoconfiguration cannot solve address conflicts between devices with Autoconfiguration cannot solve address conflicts between devices with
overlapping fixed address. For example, with default I/O page addressing, overlapping fixed addresses. For example, with default I/O page addressing,
the PDP-11 can support either a TM11 or a TS11, but not both, since they use the PDP-11 can support either a TM11 or a TS11, but not both, since they use
the same I/O addresses. the same I/O addresses.
@ -683,7 +687,7 @@ Error handling is as follows:
OS I/O error x report error and stop OS I/O error x report error and stop
2.5.2 RK611/RK06,RK07 Cartridge Disk (RL) 2.5.2 RK611/RK06,RK07 Cartridge Disk (HK)
RK611 options include the ability to set units write enabled or write RK611 options include the ability to set units write enabled or write
locked, to set the drive size to RK06, RK07, or autosize, and to write locked, to set the drive size to RK06, RK07, or autosize, and to write

View file

@ -25,6 +25,9 @@
cpu PDP-4/7/9/15 central processor cpu PDP-4/7/9/15 central processor
31-Aug-03 RMS Added instruction history
Fixed PDP-15-specific implementation of API priorities
16-Aug-03 RMS Fixed PDP-15-specific handling of EAE unsigned mul/div
27-Jul-03 RMS Added FP15 support 27-Jul-03 RMS Added FP15 support
Added XVM support Added XVM support
Added EAE option to PDP-4 Added EAE option to PDP-4
@ -274,6 +277,18 @@
#define UNIT_XVM (1 << UNIT_V_XVM) #define UNIT_XVM (1 << UNIT_V_XVM)
#define UNIT_MSIZE (1 << UNIT_V_MSIZE) #define UNIT_MSIZE (1 << UNIT_V_MSIZE)
#define HIST_SIZE 4096
#define HIST_API 0x40000000
#define HIST_PI 0x20000000
#define HIST_M_LVL 0x3F
#define HIST_V_LVL 6
struct InstHistory {
int32 pc;
int32 ir;
int32 ir1;
int32 lac;
int32 mq; };
#define XVM (cpu_unit.flags & UNIT_XVM) #define XVM (cpu_unit.flags & UNIT_XVM)
#define RELOC (cpu_unit.flags & UNIT_RELOC) #define RELOC (cpu_unit.flags & UNIT_RELOC)
#define PROT (cpu_unit.flags & UNIT_PROT) #define PROT (cpu_unit.flags & UNIT_PROT)
@ -338,6 +353,9 @@ int16 pcq[PCQ_SIZE] = { 0 }; /* PC queue */
#endif #endif
int32 pcq_p = 0; /* PC queue ptr */ int32 pcq_p = 0; /* PC queue ptr */
REG *pcq_r = NULL; /* PC queue reg ptr */ REG *pcq_r = NULL; /* PC queue reg ptr */
int32 hst_p = 0; /* history pointer */
int32 hst_lnt = 0; /* history length */
static struct InstHistory hst[HIST_SIZE] = { { 0 } }; /* instruction history */
extern int32 sim_int_char; extern int32 sim_int_char;
extern int32 sim_interval; extern int32 sim_interval;
@ -350,6 +368,10 @@ t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw); t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
t_stat cpu_reset (DEVICE *dptr); t_stat cpu_reset (DEVICE *dptr);
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc); t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat cpu_set_hist (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc);
void cpu_inst_hist (int32 addr, int32 inst);
void cpu_intr_hist (int32 flag, int32 lvl);
int32 upd_iors (void); int32 upd_iors (void);
int32 api_eval (int32 *pend); int32 api_eval (int32 *pend);
t_stat Read (int32 ma, int32 *dat, int32 cyc); t_stat Read (int32 ma, int32 *dat, int32 cyc);
@ -511,6 +533,8 @@ MTAB cpu_mod[] = {
{ UNIT_MSIZE, 114688, NULL, "112K", &cpu_set_size }, { UNIT_MSIZE, 114688, NULL, "112K", &cpu_set_size },
{ UNIT_MSIZE, 131072, NULL, "128K", &cpu_set_size }, { UNIT_MSIZE, 131072, NULL, "128K", &cpu_set_size },
#endif #endif
{ MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "HISTORY", "HISTORY",
&cpu_set_hist, &cpu_show_hist },
{ 0 } }; { 0 } };
DEVICE cpu_dev = { DEVICE cpu_dev = {
@ -564,7 +588,7 @@ if (trap_pending) { /* trap pending? */
Write (0, MB, WR); /* save in 0 */ Write (0, MB, WR); /* save in 0 */
PC = 2; } /* fetch next from 2 */ PC = 2; } /* fetch next from 2 */
#endif #endif
if (ion && !ion_defer && int_pend) { /* interrupt? */ if (int_pend && ion && !ion_defer) { /* interrupt? */
PCQ_ENTRY; /* save old PC */ PCQ_ENTRY; /* save old PC */
MB = Jms_word (usmd); /* save state */ MB = Jms_word (usmd); /* save state */
ion = 0; /* interrupts off */ ion = 0; /* interrupts off */
@ -599,6 +623,7 @@ if (trap_pending) { /* trap pending? */
if (api_int && !ion_defer) { /* API intr? */ if (api_int && !ion_defer) { /* API intr? */
int32 i, lvl = api_int - 1; /* get req level */ int32 i, lvl = api_int - 1; /* get req level */
if (hst_lnt) cpu_intr_hist (HIST_API, lvl); /* record */
api_act = api_act | (API_ML0 >> lvl); /* set level active */ api_act = api_act | (API_ML0 >> lvl); /* set level active */
if (lvl >= API_HLVL) { /* software req? */ if (lvl >= API_HLVL) { /* software req? */
MA = ACH_SWRE + lvl - API_HLVL; /* vec = 40:43 */ MA = ACH_SWRE + lvl - API_HLVL; /* vec = 40:43 */
@ -619,13 +644,16 @@ if (api_int && !ion_defer) { /* API intr? */
xct_count = 0; xct_count = 0;
goto xct_instr; } goto xct_instr; }
if (!(api_enb && api_act) && ion && !ion_defer && int_pend) { if (int_pend && ion && !ion_defer && /* int pending, enabled? */
!(api_enb && (api_act & API_MASKPI))) { /* API off or not masking PI? */
PCQ_ENTRY; /* save old PC */ PCQ_ENTRY; /* save old PC */
if (hst_lnt) cpu_intr_hist (HIST_PI, 0); /* record */
MB = Jms_word (usmd); /* save state */ MB = Jms_word (usmd); /* save state */
ion = 0; /* interrupts off */ ion = 0; /* interrupts off */
#if defined (PDP9) /* PDP-9, */ #if defined (PDP9) /* PDP-9, */
memm = 0; /* extend off */ memm = 0; /* extend off */
#else /* PDP-15 */ #else /* PDP-15 */
ion_defer = 2; /* free instruction */
if (!(cpu_unit.flags & UNIT_NOAPI)) { /* API? */ if (!(cpu_unit.flags & UNIT_NOAPI)) { /* API? */
api_act = api_act | API_ML3; /* set lev 3 active */ api_act = api_act | API_ML3; /* set lev 3 active */
api_int = api_eval (&int_pend); } /* re-evaluate */ api_int = api_eval (&int_pend); } /* re-evaluate */
@ -651,6 +679,7 @@ PC = Incr_addr (PC); /* increment PC */
xct_instr: /* label for XCT */ xct_instr: /* label for XCT */
if (Read (MA, &IR, FE)) continue; /* fetch instruction */ if (Read (MA, &IR, FE)) continue; /* fetch instruction */
if (hst_lnt) cpu_inst_hist (MA, IR); /* history? */
if (ion_defer) ion_defer = ion_defer - 1; /* count down defer */ if (ion_defer) ion_defer = ion_defer - 1; /* count down defer */
if (sim_interval) sim_interval = sim_interval - 1; if (sim_interval) sim_interval = sim_interval - 1;
@ -1014,6 +1043,12 @@ case 033: case 032: /* EAE */
if (IR & 02) LAC = LAC | MQ; /* IR<16>? or MQ */ if (IR & 02) LAC = LAC | MQ; /* IR<16>? or MQ */
if (IR & 01) LAC = LAC | ((-SC) & 077); /* IR<17>? or SC */ if (IR & 01) LAC = LAC | ((-SC) & 077); /* IR<17>? or SC */
break; break;
/* EAE, continued
Multiply uses a shift and add algorithm. The PDP-15, unlike prior
implementations, factors IR<6> (signed multiply) into the calculation
of the result sign. */
case 1: /* multiply */ case 1: /* multiply */
if (Read (PC, &MB, FE)) break; /* get next word */ if (Read (PC, &MB, FE)) break; /* get next word */
@ -1027,20 +1062,19 @@ case 033: case 032: /* EAE */
LAC = LAC >> 1; /* shift AC'MQ right */ LAC = LAC >> 1; /* shift AC'MQ right */
SC = (SC - 1) & 077; } /* decrement SC */ SC = (SC - 1) & 077; } /* decrement SC */
while (SC != 0); /* until SC = 0 */ while (SC != 0); /* until SC = 0 */
#if defined (PDP15)
if ((IR & 0004000) && (eae_ac_sign ^ link_init)) {
#else
if (eae_ac_sign ^ link_init) { /* result negative? */ if (eae_ac_sign ^ link_init) { /* result negative? */
#endif
LAC = LAC ^ DMASK; LAC = LAC ^ DMASK;
MQ = MQ ^ DMASK; } MQ = MQ ^ DMASK; }
break; break;
/* EAE, continued
Divide uses a non-restoring divide. This code duplicates the PDP-7 /* Divide uses a non-restoring divide. Divide uses a subtract and shift
algorithm, except for its use of two's complement arithmetic instead algorithm. The quotient is generated in true form. The PDP-15, unlike
of 1's complement. prior implementations, factors IR<6> (signed multiply) into the calculation
of the result sign.*/
The quotient is generated in one's complement form; therefore, the
quotient is complemented if the input operands had the same sign
(that is, if the quotient is positive). */
case 3: /* divide */ case 3: /* divide */
if (Read (PC, &MB, FE)) break; /* get next word */ if (Read (PC, &MB, FE)) break; /* get next word */
@ -1058,12 +1092,17 @@ case 033: case 032: /* EAE */
t = (LAC >> 18) & 1; /* quotient bit */ t = (LAC >> 18) & 1; /* quotient bit */
if (SC > 1) LAC = /* skip if last */ if (SC > 1) LAC = /* skip if last */
((LAC << 1) | (MQ >> 17)) & LACMASK; ((LAC << 1) | (MQ >> 17)) & LACMASK;
MQ = ((MQ << 1) | t) & DMASK; /* shift in quo bit */ MQ = ((MQ << 1) | (t ^ 1)) & DMASK; /* shift in quo bit */
SC = (SC - 1) & 077; } /* decrement SC */ SC = (SC - 1) & 077; } /* decrement SC */
while (SC != 0); /* until SC = 0 */ while (SC != 0); /* until SC = 0 */
if (t) LAC = (LAC + MB) & LACMASK; if (t) LAC = (LAC + MB) & LACMASK;
if (eae_ac_sign) LAC = LAC ^ DMASK; /* sgn rem = sgn divd */ if (eae_ac_sign) LAC = LAC ^ DMASK; /* sgn rem = sgn divd */
if ((eae_ac_sign ^ link_init) == 0) MQ = MQ ^ DMASK; #if defined (PDP15)
if ((IR & 0004000) && (eae_ac_sign ^ link_init))
#else
if (eae_ac_sign ^ link_init) /* result negative? */
#endif
MQ = MQ ^ DMASK;
break; break;
/* EAE, continued /* EAE, continued
@ -1212,7 +1251,7 @@ case 035: /* index operates */
case 034: /* IOT */ case 034: /* IOT */
#if defined (PDP15) #if defined (PDP15)
if (IR & 0010000) { /* floating point? */ if (IR & 0010000) { /* floating point? */
fp15 (IR); /* process */ reason = fp15 (IR); /* process */
break; } break; }
#endif #endif
if ((api_usmd | usmd) && /* user, not XVM UIOT? */ if ((api_usmd | usmd) && /* user, not XVM UIOT? */
@ -1286,7 +1325,9 @@ case 034: /* IOT */
break; break;
case 033: /* CPU control */ case 033: /* CPU control */
if ((pulse == 001) || (pulse == 041)) PC = Incr_addr (PC); if ((pulse == 001) || (pulse == 041)) PC = Incr_addr (PC);
else if (pulse == 002) reset_all (1); /* CAF - skip CPU */ else if (pulse == 002) { /* CAF */
reset_all (1); /* reset all exc CPU */
api_enb = api_req = api_act = 0; } /* reset API system */
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)) { if (((cpu_unit.flags & UNIT_NOAPI) == 0) && (pulse & 004)) {
int32 t = api_ffo[api_act & 0377]; int32 t = api_ffo[api_act & 0377];
@ -1348,7 +1389,9 @@ case 034: /* IOT */
break; break;
case 033: /* CPU control */ case 033: /* CPU control */
if ((pulse == 001) || (pulse == 041)) PC = Incr_addr (PC); if ((pulse == 001) || (pulse == 041)) PC = Incr_addr (PC);
else if (pulse == 002) reset_all (2); /* CAF - skip CPU, FP15 */ else if (pulse == 002) { /* CAF */
reset_all (2); /* reset all exc CPU, FP15 */
api_enb = api_req = api_act = 0; } /* reset API system */
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)) { if (((cpu_unit.flags & UNIT_NOAPI) == 0) && (pulse & 004)) {
int32 t = api_ffo[api_act & 0377]; int32 t = api_ffo[api_act & 0377];
@ -1881,3 +1924,83 @@ for (i = p = 0; (dptr = sim_devices[i]) != NULL; i++) { /* add devices */
} /* end for i */ } /* end for i */
return FALSE; return FALSE;
} }
/* Set history */
t_stat cpu_set_hist (UNIT *uptr, int32 val, char *cptr, void *desc)
{
int32 i, lnt;
t_stat r;
if (cptr == NULL) {
for (i = 0; i < HIST_SIZE; i++) hst[i].pc = 0;
return SCPE_OK; }
lnt = (int32) get_uint (cptr, 10, HIST_SIZE, &r);
if (r != SCPE_OK) return SCPE_ARG;
hst_lnt = lnt;
return SCPE_OK;
}
/* Show history */
t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc)
{
int32 l, j, k, di;
t_value sim_eval[2];
struct InstHistory *h;
extern t_stat fprint_sym (FILE *ofile, t_addr addr, t_value *val,
UNIT *uptr, int32 sw);
if (hst_lnt == 0) return SCPE_NOFNC; /* enabled? */
di = hst_p + HIST_SIZE - hst_lnt; /* work forward */
for (k = 0; k < hst_lnt; k++) { /* print specified */
h = &hst[(di++) % HIST_SIZE]; /* entry pointer */
if (h->pc == 0) continue; /* filled in? */
if (h->pc & (HIST_API | HIST_PI)) { /* interrupt event? */
if (h->pc & HIST_PI) /* PI? */
fprintf (st, "%06o PI LVL 0-4 =", h->pc & AMASK);
else fprintf (st, "%06o API %d LVL 0-4 =", h->pc & AMASK, h->mq);
for (j = API_HLVL; j >= 0; j--)
fprintf (st, " %02o", (h->ir >> (j * HIST_V_LVL)) & HIST_M_LVL);
}
else { /* instruction */
l = (h->lac >> 18) & 1; /* link */
fprintf (st, "%06o %o %06o %06o ", h->pc, l, h->lac & DMASK, h->mq);
sim_eval[0] = h->ir;
sim_eval[1] = h->ir1;
if ((fprint_sym (st, h->pc, sim_eval, &cpu_unit, SWMASK ('M'))) > 0)
fprintf (st, "(undefined) %06o", h->ir);
} /* end else instruction */
fputc ('\n', st); /* end line */
} /* end for */
return SCPE_OK;
}
/* Record events in history table */
void cpu_inst_hist (int32 addr, int32 inst)
{
hst[hst_p].pc = addr;
hst[hst_p].ir = inst;
if (cpu_ex (&hst[hst_p].ir1, (addr + 1) & AMASK, &cpu_unit, SWMASK ('V')))
hst[hst_p].ir1 = 0;
hst[hst_p].lac = LAC;
hst[hst_p].mq = MQ;
hst_p = (hst_p + 1) % HIST_SIZE;
return;
}
void cpu_intr_hist (int32 flag, int32 lvl)
{
int32 j;
hst[hst_p].pc = PC | flag;
hst[hst_p].ir = 0;
for (j = 0; j < API_HLVL+1; j++) hst[hst_p].ir =
(hst[hst_p].ir << HIST_V_LVL) | (int_hwre[j] & HIST_M_LVL);
hst[hst_p].ir1 = 0;
hst[hst_p].lac = 0;
hst[hst_p].mq = lvl;
hst_p = (hst_p + 1) % HIST_SIZE;
return;
}

View file

@ -45,6 +45,9 @@
Al Kossow and Max Burnet in making documentation and software available. Al Kossow and Max Burnet in making documentation and software available.
*/ */
#ifndef _PDP18B_DEFS_H_
#define _PDP18B_DEFS_H_ 0
#include "sim_defs.h" /* simulator defns */ #include "sim_defs.h" /* simulator defns */
/* Models: only one should be defined /* Models: only one should be defined
@ -52,7 +55,7 @@
model memory CPU options I/O options model memory CPU options I/O options
PDP4 8K Type 18 EAE Type 65 KSR-28 Teletype (Baudot) PDP4 8K Type 18 EAE Type 65 KSR-28 Teletype (Baudot)
integral paper tape reader ??Type 16 mem extension integral paper tape reader
Type 75 paper tape punch Type 75 paper tape punch
integral real time clock integral real time clock
Type 62 line printer (Hollerith) Type 62 line printer (Hollerith)
@ -61,7 +64,7 @@
PDP7 32K Type 177 EAE Type 649 KSR-33 Teletype PDP7 32K Type 177 EAE Type 649 KSR-33 Teletype
Type 148 mem extension Type 444 paper tape reader Type 148 mem extension Type 444 paper tape reader
??KA70A bounds control Type 75 paper tape punch Type 75 paper tape punch
integral real time clock integral real time clock
Type 647B line printer (sixbit) Type 647B line printer (sixbit)
Type 550/555 DECtape Type 550/555 DECtape
@ -106,6 +109,7 @@
#define STOP_API 5 /* invalid API int */ #define STOP_API 5 /* invalid API int */
#define STOP_NONSTD 6 /* non-std dev num */ #define STOP_NONSTD 6 /* non-std dev num */
#define STOP_MME 7 /* mem mgt error */ #define STOP_MME 7 /* mem mgt error */
#define STOP_FPDIS 8 /* fp inst, fpp disabled */
/* Peripheral configuration */ /* Peripheral configuration */
@ -244,7 +248,7 @@ struct pdp18b_dib {
uint32 dev; /* base dev number */ uint32 dev; /* base dev number */
uint32 num; /* number of slots */ uint32 num; /* number of slots */
int32 (*iors)(void); /* IORS responder */ int32 (*iors)(void); /* IORS responder */
int32 (*dsp[DEV_MAXBLK])(int32 IR, int32 dat); int32 (*dsp[DEV_MAXBLK])(int32 pulse, int32 dat);
}; };
typedef struct pdp18b_dib DIB; typedef struct pdp18b_dib DIB;
@ -317,6 +321,12 @@ typedef struct pdp18b_dib DIB;
#define API_ML6 0002 #define API_ML6 0002
#define API_ML7 0001 /* level 7 */ #define API_ML7 0001 /* level 7 */
#if defined (PDP9) /* levels which mask PI */
#define API_MASKPI (API_ML0|API_ML1|API_ML2|API_ML3|API_ML4|API_ML5|API_ML6|API_ML7)
#else
#define API_MASKPI (API_ML0|API_ML1|API_ML2|API_ML3)
#endif
#define API_HLVL 4 /* hwre levels */ #define API_HLVL 4 /* hwre levels */
#define ACH_SWRE 040 /* swre int vec */ #define ACH_SWRE 040 /* swre int vec */
@ -473,3 +483,6 @@ typedef struct pdp18b_dib DIB;
t_stat set_devno (UNIT *uptr, int32 val, char *cptr, void *desc); t_stat set_devno (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat show_devno (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat show_devno (FILE *st, UNIT *uptr, int32 val, void *desc);
#endif

View file

@ -1,7 +1,7 @@
To: Users To: Users
From: Bob Supnik From: Bob Supnik
Subj: 18b PDP Simulator Usage Subj: 18b PDP Simulator Usage
Date: 25-Jul-2003 Date: 25-Aug-2003
COPYRIGHT NOTICE COPYRIGHT NOTICE
@ -150,15 +150,17 @@ The 18b PDP simulators implement several unique stop conditions:
- an unimplemented instruction is decoded, and register - an unimplemented instruction is decoded, and register
STOP_INST is set STOP_INST is set
- more than XCTMAX nested executes are detected during - more than XCT_MAX nested executes are detected during
instruction execution instruction execution
- an FP15 instruction is decoded, the FP15 is disabled,
and register STOP_FPP is set
The PDP-4 and PDP-7 LOAD command supports only "second stage" RIM format The PDP-4 and PDP-7 LOAD command supports only "second stage" RIM format
files (alternating DAC address instructions and data): files (alternating DAC address instructions and data):
LOAD file load PDP-4/PDP-7 RIM format file LOAD file load PDP-4/PDP-7 RIM format file
The PDP-9 and PDP-15 LOAD commands upports hardware RIM format (data only), The PDP-9 and PDP-15 LOAD commands support hardware RIM format (data only),
PDP-4/PDP-7 RIM loader format (for compatability with Macro7), and BIN PDP-4/PDP-7 RIM loader format (for compatability with Macro7), and BIN
loader format: loader format:
@ -238,6 +240,7 @@ control registers for the interrupt system.
all IORS 18 IORS register all IORS 18 IORS register
all ION 1 interrupt enable all ION 1 interrupt enable
all ION_DELAY 2 interrupt enable delay all ION_DELAY 2 interrupt enable delay
15 ION_INH 1 interrupt inhibit
9,15 APIENB 1 API enable 9,15 APIENB 1 API enable
9,15 APIREQ 8 API requesting levels 9,15 APIREQ 8 API requesting levels
9,15 APIACT 8 API active levels 9,15 APIACT 8 API active levels
@ -264,6 +267,7 @@ control registers for the interrupt system.
all PCQ[0:63] addr PC prior to last JMP, JMS, CAL, or all PCQ[0:63] addr PC prior to last JMP, JMS, CAL, or
interrupt; most recent PC change first interrupt; most recent PC change first
all STOP_INST 1 stop on undefined instruction all STOP_INST 1 stop on undefined instruction
all XCT_MAX 8 maximum number of chained XCT's allowed
all WRU 8 interrupt character all WRU 8 interrupt character
"addr" signifies the address width of the system (13b for the PDP-4, 15b for "addr" signifies the address width of the system (13b for the PDP-4, 15b for
@ -291,6 +295,8 @@ The FPP implements these registers:
FMQH 17 FMQ<1:17> FMQH 17 FMQ<1:17>
FMQL 18 FMQ<18:35> FMQL 18 FMQ<18:35>
JEA 18 exception address register JEA 18 exception address register
STOP_FPP 1 stop if FP15 instruction decoded
while FP15 is disabled
2.3 Programmed I/O Devices 2.3 Programmed I/O Devices
@ -308,7 +314,7 @@ recognized vary from system to system:
it running it running
BOOT -H PTR PDP-7: start hardware RIM load at address given BOOT -H PTR PDP-7: start hardware RIM load at address given
by address switches (ASW) by address switches (ASW)
BOOT {-H} PTR PDP-9, PDP-15: start hardware RIM load at addrss BOOT {-H} PTR PDP-9, PDP-15: start hardware RIM load at address
given by address switches (ASW) given by address switches (ASW)
The PDP-4 did not have a hardware read-in mode load capability. The PDP-4 did not have a hardware read-in mode load capability.
@ -398,7 +404,7 @@ implements these registers:
POS 32 number of characters input POS 32 number of characters input
TIME 24 keyboard polling interval TIME 24 keyboard polling interval
If the simulator is compiled under Windows Visual C++, typing ^C to the If the simulator is debugged under Windows Visual C++, typing ^C to the
terminal input causes a fatal run-time error. Use the following command terminal input causes a fatal run-time error. Use the following command
to simulate typing ^C: to simulate typing ^C:
@ -670,7 +676,7 @@ from the attached file:
SET RF 6P six platters (1536K) SET RF 6P six platters (1536K)
SET RF 7P seven platters (1792K) SET RF 7P seven platters (1792K)
SET RF 8P eight platters (2048K) SET RF 8P eight platters (2048K)
SET RF AUTOSIZE autosized on attach SET RF AUTOSIZE autosize on attach
The default is AUTOSIZE. The default is AUTOSIZE.
@ -720,10 +726,10 @@ locked.
Units can also be set ONLINE or OFFLINE. Units can also be set ONLINE or OFFLINE.
The Type 550, TC02, and TC15 support supports PDP-8 format, PDP-11 format, The Type 550, TC02, and TC15 support PDP-8 format, PDP-11 format, and
and 18b format DECtape images. ATTACH tries to determine the tape 18b format DECtape images. ATTACH tries to determine the tape format
format from the DECtape image; the user can force a particular format from the DECtape image; the user can force a particular format with
with switches: switches:
-r PDP-8 format -r PDP-8 format
-s PDP-11 format -s PDP-11 format

View file

@ -132,6 +132,7 @@ typedef struct ufp UFP;
static int32 fir; /* instruction */ static int32 fir; /* instruction */
static int32 jea; /* exc address */ static int32 jea; /* exc address */
static int32 fguard; /* guard bit */ static int32 fguard; /* guard bit */
static int32 stop_fpp = STOP_RSRV; /* stop if fp dis */
static UFP fma; /* FMA */ static UFP fma; /* FMA */
static UFP fmb; /* FMB */ static UFP fmb; /* FMB */
static UFP fmq; /* FMQ - hi,lo only */ static UFP fmq; /* FMQ - hi,lo only */
@ -195,6 +196,7 @@ REG fpp_reg[] = {
{ ORDATA (FMQH, fmq.hi, 17) }, { ORDATA (FMQH, fmq.hi, 17) },
{ ORDATA (FMQL, fmq.lo, 18) }, { ORDATA (FMQL, fmq.lo, 18) },
{ ORDATA (JEA, jea, 18) }, { ORDATA (JEA, jea, 18) },
{ FLDATA (STOP_FPP, stop_fpp, 0) },
{ NULL } }; { NULL } };
DEVICE fpp_dev = { DEVICE fpp_dev = {
@ -218,7 +220,8 @@ t_stat fp15 (int32 ir)
int32 ar, ma, fop, dat; int32 ar, ma, fop, dat;
t_stat sta = FP_OK; t_stat sta = FP_OK;
if (fpp_dev.flags & DEV_DIS) return MM_OK; /* disabled? */ if (fpp_dev.flags & DEV_DIS) /* disabled? */
return (stop_fpp? STOP_FPDIS: SCPE_OK);
fir = ir & 07777; /* save subop + mods */ fir = ir & 07777; /* save subop + mods */
ma = PC; /* fetch next word */ ma = PC; /* fetch next word */
PC = Incr_addr (PC); PC = Incr_addr (PC);
@ -237,33 +240,38 @@ case FOP_TST: /* NOP */
case FOP_SUB: /* subtract */ case FOP_SUB: /* subtract */
if (sta = fp15_opnd (fir, ar, &fmb)) break; /* fetch op to FMB */ if (sta = fp15_opnd (fir, ar, &fmb)) break; /* fetch op to FMB */
if (fir & FI_FP) sta = fp15_fadd (fir, &fma, &fmb, 1); /* fp? */ if (fir & FI_FP) /* fp? */
sta = fp15_fadd (fir, &fma, &fmb, 1); /* yes, fp sub */
else sta = fp15_iadd (fir, &fma, &fmb, 1); /* no, int sub */ else sta = fp15_iadd (fir, &fma, &fmb, 1); /* no, int sub */
break; break;
case FOP_RSUB: /* reverse sub */ case FOP_RSUB: /* reverse sub */
fmb = fma; /* FMB <- FMA */ fmb = fma; /* FMB <- FMA */
if (sta = fp15_opnd (fir, ar, &fma)) break; /* fetch op to FMA */ if (sta = fp15_opnd (fir, ar, &fma)) break; /* fetch op to FMA */
if (fir & FI_FP) sta = fp15_fadd (fir, &fma, &fmb, 1); /* fp? */ if (fir & FI_FP) /* fp? */
sta = fp15_fadd (fir, &fma, &fmb, 1); /* yes, fp sub */
else sta = fp15_iadd (fir, &fma, &fmb, 1); /* no, int sub */ else sta = fp15_iadd (fir, &fma, &fmb, 1); /* no, int sub */
break; break;
case FOP_MUL: /* multiply */ case FOP_MUL: /* multiply */
if (sta = fp15_opnd (fir, ar, &fmb)) break; /* fetch op to FMB */ if (sta = fp15_opnd (fir, ar, &fmb)) break; /* fetch op to FMB */
if (fir & FI_FP) sta = fp15_fmul (fir, &fma, &fmb); /* fp? */ if (fir & FI_FP) /* fp? */
sta = fp15_fmul (fir, &fma, &fmb); /* yes, fp mul */
else sta = fp15_imul (fir, &fma, &fmb); /* no, int mul */ else sta = fp15_imul (fir, &fma, &fmb); /* no, int mul */
break; break;
case FOP_DIV: /* divide */ case FOP_DIV: /* divide */
if (sta = fp15_opnd (fir, ar, &fmb)) break; /* fetch op to FMB */ if (sta = fp15_opnd (fir, ar, &fmb)) break; /* fetch op to FMB */
if (fir & FI_FP) sta = fp15_fdiv (fir, &fma, &fmb); /* fp? */ if (fir & FI_FP) /* fp? */
sta = fp15_fadd (fir, &fma, &fmb, 1); /* yes, fp sub */
else sta = fp15_idiv (fir, &fma, &fmb); /* no, int div */ else sta = fp15_idiv (fir, &fma, &fmb); /* no, int div */
break; break;
case FOP_RDIV: /* reverse divide */ case FOP_RDIV: /* reverse divide */
fmb = fma; /* FMB <- FMA */ fmb = fma; /* FMB <- FMA */
if (sta = fp15_opnd (fir, ar, &fma)) break; /* fetch op to FMA */ if (sta = fp15_opnd (fir, ar, &fma)) break; /* fetch op to FMA */
if (fir & FI_FP) sta = fp15_fdiv (fir, &fma, &fmb); /* fp? */ if (fir & FI_FP) /* fp? */
sta = fp15_fadd (fir, &fma, &fmb, 1); /* yes, fp sub */
else sta = fp15_idiv (fir, &fma, &fmb); /* no, int div */ else sta = fp15_idiv (fir, &fma, &fmb); /* no, int div */
break; break;
@ -271,7 +279,7 @@ case FOP_LD: /* load */
if (sta = fp15_opnd (fir, ar, &fma)) break; /* fetch op to FMA */ if (sta = fp15_opnd (fir, ar, &fma)) break; /* fetch op to FMA */
fp15_asign (fir, &fma); /* modify A sign */ fp15_asign (fir, &fma); /* modify A sign */
if (fir & FI_FP) /* fp? */ if (fir & FI_FP) /* fp? */
sta = fp15_norm (ir, &fma, NULL, 0); /* normalize */ sta = fp15_norm (ir, &fma, NULL, 0); /* norm, no round */
break; break;
case FOP_ST: /* store */ case FOP_ST: /* store */
@ -283,7 +291,7 @@ case FOP_FLT: /* float */
if (sta = fp15_opnd (fir, ar, &fma)) break; /* fetch op to FMA */ if (sta = fp15_opnd (fir, ar, &fma)) break; /* fetch op to FMA */
fma.exp = 35; fma.exp = 35;
fp15_asign (fir, &fma); /* adjust A sign */ fp15_asign (fir, &fma); /* adjust A sign */
sta = fp15_norm (ir, &fma, NULL, 0); /* normalize */ sta = fp15_norm (ir, &fma, NULL, 0); /* norm, no found */
break; break;
case FOP_FIX: /* fix */ case FOP_FIX: /* fix */
@ -295,8 +303,8 @@ case FOP_LFMQ: /* load FMQ */
if (sta = fp15_opnd (fir, ar, &fma)) break; /* fetch op to FMA */ if (sta = fp15_opnd (fir, ar, &fma)) break; /* fetch op to FMA */
dp_swap (&fma, &fmq); /* swap FMA, FMQ */ dp_swap (&fma, &fmq); /* swap FMA, FMQ */
fp15_asign (fir, &fma); /* adjust A sign */ fp15_asign (fir, &fma); /* adjust A sign */
if (fir & FI_FP) /* fp? norm, no rnd */ if (fir & FI_FP) /* fp? */
sta = fp15_norm (ir | FI_NORND, &fma, &fmq, 0); sta = fp15_norm (ir, &fma, &fmq, 0); /* yes, norm, no rnd */
break; break;
case FOP_JEA: /* JEA */ case FOP_JEA: /* JEA */
@ -311,7 +319,8 @@ case FOP_JEA: /* JEA */
case FOP_ADD: /* add */ case FOP_ADD: /* add */
if (sta = fp15_opnd (fir, ar, &fmb)) break; /* fetch op to FMB */ if (sta = fp15_opnd (fir, ar, &fmb)) break; /* fetch op to FMB */
if (fir & FI_FP) sta = fp15_fadd (fir, &fma, &fmb, 0); /* fp? */ if (fir & FI_FP) /* fp? */
sta = fp15_fadd (fir, &fma, &fmb, 0); /* yes, fp add */
else sta = fp15_iadd (fir, &fma, &fmb, 0); /* no, int add */ else sta = fp15_iadd (fir, &fma, &fmb, 0); /* no, int add */
break; break;
@ -331,7 +340,7 @@ default:
fma.exp = fma.exp & DMASK; /* mask exp to 18b */ fma.exp = fma.exp & DMASK; /* mask exp to 18b */
fmb.exp = fmb.exp & DMASK; fmb.exp = fmb.exp & DMASK;
if (sta != FP_OK) return fp15_exc (sta); /* error? */ if (sta != FP_OK) return fp15_exc (sta); /* error? */
return MM_OK; return SCPE_OK;
} }
/* Operand load and store */ /* Operand load and store */
@ -524,7 +533,7 @@ else if (((b->hi | b->lo) != 0) && (ediff <= 35)) { /* b!=0 && ~"small"? */
if (a->exp > 0377777) return FP_OVF; } } if (a->exp > 0377777) return FP_OVF; } }
} /* end if b != 0 */ } /* end if b != 0 */
fp15_asign (ir, a); /* adjust A sign */ fp15_asign (ir, a); /* adjust A sign */
return fp15_norm (ir, a, NULL, 0); /* normalize */ return fp15_norm (ir, a, NULL, 0); /* norm, no round */
} }
/* Floating multiply - overflow/underflow detected in normalize */ /* Floating multiply - overflow/underflow detected in normalize */
@ -587,8 +596,6 @@ return FP_OK;
void dp_add (UFP *a, UFP *b) void dp_add (UFP *a, UFP *b)
{ {
int32 a_hi_orig = a->hi;
a->lo = (a->lo + b->lo) & UFP_FL_MASK; /* add low */ a->lo = (a->lo + b->lo) & UFP_FL_MASK; /* add low */
a->hi = a->hi + b->hi + (a->lo < b->lo); /* add hi + carry */ a->hi = a->hi + b->hi + (a->lo < b->lo); /* add hi + carry */
return; return;
@ -755,9 +762,9 @@ ma = (jea & JEA_EAMASK) + sta - 1; /* JEA address */
PCQ_ENTRY; /* record branch */ PCQ_ENTRY; /* record branch */
PC = Incr_addr (PC); /* PC+1 for "JMS" */ PC = Incr_addr (PC); /* PC+1 for "JMS" */
mb = Jms_word (usmd); /* form JMS word */ mb = Jms_word (usmd); /* form JMS word */
if (Write (ma, mb, WR)) return MM_ERR; /* store */ if (Write (ma, mb, WR)) return SCPE_OK; /* store */
PC = (jea + 1) & IAMASK; /* new PC */ PC = (jea + 1) & IAMASK; /* new PC */
return MM_OK; return SCPE_OK;
} }
/* Reset routine */ /* Reset routine */

View file

@ -169,7 +169,8 @@ const char *sim_stop_messages[] = {
"Nested XCT's", "Nested XCT's",
"Invalid API interrupt", "Invalid API interrupt",
"Non-standard device number", "Non-standard device number",
"Memory management error" }; "Memory management error",
"FP15 instruction disabled" };
/* Binary loaders */ /* Binary loaders */

26
scp.c
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.
01-Sep-03 RMS Fixed end-of-file problem in dep, idep
Fixed error on trailing spaces in dep, idep
15-Jul-03 RMS Removed unnecessary test in reset_all 15-Jul-03 RMS Removed unnecessary test in reset_all
15-Jun-03 RMS Added register flag REG_VMIO 15-Jun-03 RMS Added register flag REG_VMIO
25-Apr-03 RMS Added extended address support (V3.0) 25-Apr-03 RMS Added extended address support (V3.0)
@ -58,7 +60,7 @@
02-May-02 RMS Added VT emulation interface, changed {NO}LOG to SET {NO}LOG 02-May-02 RMS Added VT emulation interface, changed {NO}LOG to SET {NO}LOG
22-Apr-02 RMS Fixed laptop sleep problem in clock calibration, added 22-Apr-02 RMS Fixed laptop sleep problem in clock calibration, added
magtape record length error (found by Jonathan Engdahl) magtape record length error (found by Jonathan Engdahl)
26-Feb-02 RMS Fixed initialization bugs in do_cmd, get_avail 26-Feb-02 RMS Fixed initialization bugs in do_cmd, get_aval
(found by Brian Knittel) (found by Brian Knittel)
10-Feb-02 RMS Fixed problem in clock calibration 10-Feb-02 RMS Fixed problem in clock calibration
06-Jan-02 RMS Moved device enable/disable to simulators 06-Jan-02 RMS Moved device enable/disable to simulators
@ -2177,9 +2179,10 @@ if (uptr->flags & UNIT_DIS) return SCPE_UDIS; /* disabled? */
mask = (t_addr) width_mask[dptr->awidth]; mask = (t_addr) width_mask[dptr->awidth];
if ((low > mask) || (high > mask) || (low > high)) return SCPE_ARG; if ((low > mask) || (high > mask) || (low > high)) return SCPE_ARG;
for (i = low; i <= high; i = i + (dptr->aincr)) { for (i = low; i <= high; i = i + (dptr->aincr)) {
if ((flag & EX_E) || schptr) { /* examine or search? */
reason = get_aval (i, dptr, uptr); /* get data */ reason = get_aval (i, dptr, uptr); /* get data */
if (reason != SCPE_OK) return reason; /* return if error */ if (reason != SCPE_OK) return reason; /* return if error */
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;
@ -2630,9 +2633,11 @@ t_value get_uint (char *cptr, uint32 radix, t_value max, t_stat *status)
t_value val; t_value val;
char *tptr; char *tptr;
*status = SCPE_OK;
val = strtotv (cptr, &tptr, radix); val = strtotv (cptr, &tptr, radix);
if ((cptr == tptr) || (val > max) || (*tptr != 0)) *status = SCPE_ARG; if ((cptr == tptr) || (val > max)) *status = SCPE_ARG;
else *status = SCPE_OK; else { while (isspace (*tptr)) tptr++;
if (*tptr != 0) *status = SCPE_ARG; }
return val; return val;
} }
@ -2654,20 +2659,23 @@ char *get_range (char *cptr, t_addr *lo, t_addr *hi, uint32 rdx,
t_addr max, char term) t_addr max, char term)
{ {
char *tptr; char *tptr;
t_addr hb;
*lo = *hi = hb = 0;
if (max && strncmp (cptr, "ALL", strlen ("ALL")) == 0) { /* ALL? */ if (max && strncmp (cptr, "ALL", strlen ("ALL")) == 0) { /* ALL? */
tptr = cptr + strlen ("ALL"); tptr = cptr + strlen ("ALL");
*lo = 0;
*hi = max; } *hi = max; }
else { *lo = (t_addr) strtotv (cptr, &tptr, rdx); /* get low */ else { *lo = (t_addr) strtotv (cptr, &tptr, rdx); /* get low */
if (cptr == tptr) return NULL; /* error? */ if (cptr == tptr) return NULL; /* error? */
if ((*tptr == '-') || (*tptr == ':') || (*tptr == '/')) { if ((*tptr == '-') || (*tptr == ':')) { /* range? */
if (*tptr == '/') hb = *lo; /* relative? */
cptr = tptr + 1; cptr = tptr + 1;
*hi = hb + (t_addr) strtotv (cptr, &tptr, rdx); /* get high */ *hi = (t_addr) strtotv (cptr, &tptr, rdx); /* get high */
if (cptr == tptr) return NULL; if (cptr == tptr) return NULL;
if (*lo > *hi) return NULL; } if (*lo > *hi) return NULL; }
else if (*tptr == '/') { /* relative? */
cptr = tptr + 1;
*hi = (t_addr) strtotv (cptr, &tptr, rdx); /* get high */
if ((cptr == tptr) || (*hi == 0)) return NULL;
*hi = *lo + *hi - 1; }
else *hi = *lo; } else *hi = *lo; }
if (term && (*tptr++ != term)) return NULL; if (term && (*tptr++ != term)) return NULL;
return tptr; return tptr;

View file

@ -29,12 +29,35 @@
#define SIM_MAJOR 3 #define SIM_MAJOR 3
#define SIM_MINOR 0 #define SIM_MINOR 0
#define SIM_PATCH 1 #define SIM_PATCH 2
/* V3.0 revision history /* V3.0 revision history
patch date module(s) and fix(es) patch date module(s) and fix(es)
2 tbd scp.c:
-- fixed end-of-file problem in dep, idep
-- fixed error on trailing spaces in dep, idep
pdp1_stddev.c
-- fixed system hang if continue after PTR error
-- added PTR start/stop functionality
-- added address switch functionality to PTR BOOT
pdp1_sys.c: added multibank capability to LOAD
pdp18b_cpu.c:
-- fixed priorities in PDP-15 API (PI between 3 and 4)
-- fixed sign handling in PDP-15 unsigned mul/div
-- fixed bug in CAF, must clear API subsystem
i1401_mt.c:
-- fixed tape read end-of-record handling based on real 1401
-- added diagnostic read (space forward)
i1620_cpu.c
-- fixed bug in immediate index add (found by Michael Short)
1 27-Jul-03 pdp1_cpu.c: updated to detect indefinite I/O wait 1 27-Jul-03 pdp1_cpu.c: updated to detect indefinite I/O wait
pdp1_drm.c: fixed incorrect logical, missing activate, break pdp1_drm.c: fixed incorrect logical, missing activate, break

View file

@ -1,7 +1,7 @@
To: Users To: Users
From: Bob Supnik From: Bob Supnik
Subj: Simulator Usage, V3.1 Subj: Simulator Usage, V3.0-2
Date: 15-Jul-2003 Date: 15-Sep-2003
COPYRIGHT NOTICE COPYRIGHT NOTICE
@ -66,8 +66,8 @@ The simulators recognize or require a few compile-time #defines:
of the compilation command line (i.e., PDP4 for the PDP-4, PDP7 of the compilation command line (i.e., PDP4 for the PDP-4, PDP7
for the PDP-7, PDP9 for the PDP-9, PDP15 for the PDP-15). for the PDP-7, PDP9 for the PDP-9, PDP15 for the PDP-15).
- The PDP-10 and VAX simulators use 64b integer variables, requiring - The PDP-10 simulator uses 64b integer variables, requiring that
that USE_INT64 be defined as part of the compilation command line. USE_INT64 be defined as part of the compilation command line.
Since 64b integer declarations vary, sim_defs.h has conditional Since 64b integer declarations vary, sim_defs.h has conditional
declarations for Windows (_int64) and Digital UNIX (long). The declarations for Windows (_int64) and Digital UNIX (long). The
default is GNU C (long long). If your compiler uses a different default is GNU C (long long). If your compiler uses a different
@ -83,6 +83,11 @@ The simulators recognize or require a few compile-time #defines:
of the compilation command line. At present, Ethernet support is of the compilation command line. At present, Ethernet support is
available only on Windows, Linux, NetBSD, and OpenBSD. available only on Windows, Linux, NetBSD, and OpenBSD.
- The PDP-11 and VAX simulators optionally support disks and serial
devices files greater than 2GB. To include large device support,
both USE_INT64 and USE_ADDR64 must be defined as part of the
compilation command line.
To start the simulator, simply type its name. (On version of VMS To start the simulator, simply type its name. (On version of VMS
prior to 6.2, the simulators must then be defined as foreign commands prior to 6.2, the simulators must then be defined as foreign commands
in order to be be started by name.) The simulator recognizes one in order to be be started by name.) The simulator recognizes one
@ -271,7 +276,7 @@ loader format:
sim> load <filename> {implementation options}(cr) sim> load <filename> {implementation options}(cr)
The number of formats supported is implementation specific. Options The types of formats supported are implementation specific. Options
(such as load within range) are also implementation specific. (such as load within range) are also implementation specific.
The DUMP command (abbreviation DU) dumps memory in binary paper- The DUMP command (abbreviation DU) dumps memory in binary paper-
@ -279,7 +284,7 @@ tape loader format:
sim> dump <filename> {implementation options}(cr) sim> dump <filename> {implementation options}(cr)
The number of formats supported is implementation specific. Options The types of formats supported are implementation specific. Options
(such as dump within range) are also implementation specific. (such as dump within range) are also implementation specific.
3.2 Saving and Restoring State 3.2 Saving and Restoring State
@ -422,8 +427,11 @@ by commas:
register the specified register register the specified register
register[sub1-sub2] the specified register array locations, register[sub1-sub2] the specified register array locations,
start at location sub1 up to and including starting at location sub1 up to and
location sub2 including location sub2
register[sub1/length] the specified register array locations,
starting at location sub1 up to but
not including sub1+length
register[ALL] all locations in the specified register register[ALL] all locations in the specified register
array array
register1-register2 all the registers starting at register1 register1-register2 all the registers starting at register1
@ -599,7 +607,7 @@ The SHOW <unit> command shows the status of the named simulated unit.
SHOW <unit> <parameter> shows the value of the named parameter, if SHOW <unit> <parameter> shows the value of the named parameter, if
it can display a value. it can display a value.
3.10 Altering the Simulated Configuration 3.10 Altering The Simulated Configuration
In most simulators, the SET <device> DISABLED command removes the In most simulators, the SET <device> DISABLED command removes the
specified device from the configuration. A DISABLED device is specified device from the configuration. A DISABLED device is
@ -783,7 +791,7 @@ The debug status of each simulated CPU and device is as follows:
system PDP-8 PDP-11 Nova PDP-1 18b PDP system PDP-8 PDP-11 Nova PDP-1 18b PDP
device device
CPU y y y y y CPU y y y y y
FPU - y - - - FPU - y - - h
EIS/CIS - h - - - EIS/CIS - h - - -
console y y y y y console y y y y y
paper tape y y y h y paper tape y y y h y
@ -849,6 +857,8 @@ Rev 3.0, May, 03
Added logical name support Added logical name support
Added multiple tape format support Added multiple tape format support
Added 64b address support Added 64b address support
Added PDP-4 EAE support
Added PDP-15 FP15 and XVM support
Rev 2.10, Nov, 02 Rev 2.10, Nov, 02
Added Telnet console capability, removed VT emulation Added Telnet console capability, removed VT emulation

View file

@ -1,4 +1,4 @@
SIMH FAQ, 15-Apr-2003 SIMH FAQ, 15-Sep-2003
1 General 1 General
@ -52,6 +52,13 @@ SIMH FAQ, 15-Apr-2003
4.8 How can I import files into a simulated VMS environment? 4.8 How can I import files into a simulated VMS environment?
4.9 How can I export files from a simulated VMS environment? 4.9 How can I export files from a simulated VMS environment?
--------------------------------------------------------------------------------
5 PDP-11
5.1 When installing RSTS/E from simulated magtape, the installation process
hangs with no error message; why?
================================================================================ ================================================================================
1. General Questions 1. General Questions
================================================================================ ================================================================================
@ -199,7 +206,7 @@ the source kit.
2.2 How do I install SIMH with Ethernet support on Windows? 2.2 How do I install SIMH with Ethernet support on Windows?
The pre-compiled binaries contain Ethernet support. Before running these Separate pre-compiled binaries contain Ethernet support. Before running these
binaries, you must download download and install the WinPCAP AutoInstaller from binaries, you must download download and install the WinPCAP AutoInstaller from
http://winpcap.polito.it http://winpcap.polito.it
@ -244,10 +251,10 @@ UNZIP can be found on the VMS freeware CDs, or from www.info-zip.org
MMK can be found on the VMS freeware CDs, or from www.madgoat.com MMK can be found on the VMS freeware CDs, or from www.madgoat.com
MMS can be licensed from HP/Compaq/Digital. MMS can be licensed from HP/Compaq/Digital.
Note that the VAX and PDP-10 emulators cannot be built and used on VAX/VMS, Note that the PDP-10 emulator cannot be built and used on VAX/VMS, because
since the DEC C compiler for that operating system does not support 64-bit the DEC C compiler for VAX/VMS does not support 64-bit integers. DEC C on
integers. DEC C on Alpha VMS has the required 64-bit capability to build on Alpha VMS has the required 64-bit capability to build and run all of the
and run all of the emulators. emulators.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -263,10 +270,10 @@ and run all of the emulators.
sim> set rq1 cdrom sim> set rq1 cdrom
sim> att rq1 /dev/cdrom_drive sim> att rq1 /dev/cdrom_drive
- On Windows, there a quite a few products that can do this. The two most - On Windows, there are quite a few products that can do this. The two most
common products are detailed below. Make sure to disable any antivirus common products are detailed below. Make sure to disable any antivirus
software before proceeding. Antivirus software tends to interfere with software before proceeding. Antivirus software tends to interfere with
the smooth flow of data from the CD, and will occasionally transform the the smooth flow of data from the CD and will occasionally transform the
data in strange and unexpected ways to 'protect' you. data in strange and unexpected ways to 'protect' you.
1) Roxio EZ-CD Creator 5.x 1) Roxio EZ-CD Creator 5.x
@ -589,3 +596,11 @@ Ethernet Adapter 0 (774440)
from that image to the host file system. from that image to the host file system.
- Text files can be printed to the simulated line printer, as described above. - Text files can be printed to the simulated line printer, as described above.
================================================================================
5 PDP-11
================================================================================
5.1 When installing RSTS/E from simulated magtape, the installation process
hangs with no error message; why?
- RSTS/E installation from magnetic tape requires that the tape be write locked.

View file

@ -1,7 +1,7 @@
To: Users To: Users
From: Bob Supnik From: Bob Supnik
Subj: Sample Software Packages Subj: Sample Software Packages
Date: 15-Jun-2003 Date: 15-Sep-2003
This memorandum documents the sample software packages available to run This memorandum documents the sample software packages available to run
with the SIMH simulators. Many of these packages are available under with the SIMH simulators. Many of these packages are available under
@ -292,7 +292,9 @@ To boot and run RDOS for the Eclipse:
R R
list/e list/e
4. PDP-1 LISP 4. PDP-1
4.1 PDP-1 LISP
PDP-1 LISP is an interactive interpreter for the Lisp language. It can PDP-1 LISP is an interactive interpreter for the Lisp language. It can
execute both interactive commands and stored programs. The startup execute both interactive commands and stored programs. The startup
@ -301,6 +303,13 @@ with the program for details. My thanks to Peter Deutsch, who wrote the
program, to Gordon Greene, who typed it in from a printed listing, and program, to Gordon Greene, who typed it in from a printed listing, and
to Paul McJones, who helped with the final debug process. to Paul McJones, who helped with the final debug process.
4.2 PDP-1 DDT
PDP-1 DDT is an interactive debugging tool for the PDP-1. It provides
symbolic debugging capabilities for PDP-1 programs. The documentation
included with the program provides information on loading and operating
DDT. My thanks to Derek Peschel, who transcribed and debugged DDT.
5. PDP-7 SIM8 5. PDP-7 SIM8
PDP-7 SIM8 is a PDP-8 simulator for the PDP-7. It implements an 8K PDP-7 SIM8 is a PDP-8 simulator for the PDP-7. It implements an 8K