1
0
mirror of https://github.com/simh/simh.git synced 2026-02-03 23:23:55 +00:00

Notes For V3.1-0

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.1-0

1.1 SCP and libraries

- Added simulated Ethernet support for VMS, FreeBSD, Mac OS/X.
- Added status return to tmxr_putc_ln.
- Added sim_putchar_s to handle possible output stalls.

1.2 All DECtapes

- Added "DECtape off reel" error stop.

1.3 All Asynchronous Consoles

- Added support for output congestion stall if using a Telnet connection.

1.4 PDP-1

- Added Type 23 parallel drum support.

1.5 PDP-8

- Added instruction history.
- Added TSC8-75 option support for ETOS.
- Added TD8E DECtape support.

1.6 PDP-18b

- Added instruction history.
- Changed PDP-9, PDP-15 API default to enabled.

1.7 PDP-11

- Added support for 18b only Qbus devices.
- Formalized bus and addressing definitions.
- Added control to enable/disable autoconfiguration.
- Added stub support for second Unibus Ethernet controller.

1.7 Interdata 32b

- Added instruction history.

1.8 Eclipse

- Added floating point support.
- Added programmable interval timer support.

1.9 H316

- Added DMA/DMC support.
- Added fixed head disk support.
- Added moving head disk support.
- Added magtape support.

1.10 IBM 1130 (Brian Knittel)

- Added support for physical card reader, using the Cardread
interface (www.ibm1130.org/sim/downloads).
- Added support for physical printer (flushes output buffer after
each line).

2. Bugs Fixed in 3.1-0

2.1 SCP and libraries

- Fixed numerous bugs in Ethernet library.

2.2 All DECtapes

- Fixed reverse checksum value in 'read all' mode.
- Simplified (and sped up) timing.

2.3 PDP-8

- Fixed bug in RX28 read status (found by Charles Dickman).
- Fixed RX28 double density write.

2.4 PDP-18b

- Fixed autoincrement bug in PDP-4, PDP-7, PDP-9.

2.5 PDP-11/VAX

- Revised RQ MB->LBN conversion for greater accuracy.
- Fixed bug in IO configuration (found by David Hittner).
- Fixed bug with multiple RQ RAUSER drives.
- Fixed bug in second Qbus Ethernet controller interrupts.

2.6 Nova/Eclipse

- Fixed bugs in DKP flag clear, map setup, map usage (Charles Owen).
- Fixed bug in MT, reset completes despite I/O reset (Charles Owen).
- Fixed bug in MT, space operations return word count (Charles Owen).

2.7 IBM 1130 (Brian Knittel)

- Fixed bug in setting carry bit in subtract and subtract double.
- Fixed timing problem in console printer simulation.

2.8 1620

- Fixed bug in branch digit (found by Dave Babcock).

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.
- 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.

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 SCP and Libraries

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

4.2 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.3 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.
- Fixed tape read end-of-record handling based on real 1401.
- Added diagnostic read (space forward).

4.4 Nova

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

4.5 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.
- Fixed system hang if continue after PTR error.
- Fixed PTR to start/stop on successive rpa instructions.

4.6 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.7 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.
- 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.

4.8 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.9 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.10 GRI

- Fixed bug in SC queue pointer management.

4.11 PDP-10

- Fixed bug in RP read header.

4.12 Ibm1130

- Fixed bugs found by APL 1130.

4.13 Altairz80

- Fixed bug in real-time clock on Windows host.

4.14 1620

- Fixed bug in immediate index add (found by Michael Short).
This commit is contained in:
Bob Supnik
2003-12-31 11:49:00 -08:00
committed by Mark Pizzolato
parent b2101ecdd4
commit 1da2d9452d
140 changed files with 17663 additions and 16338 deletions

View File

@@ -1,6 +1,6 @@
/* pdp18b_cpu.c: 18b PDP CPU simulator
Copyright (c) 1993-2003, Robert M Supnik
Copyright (c) 1993-2004, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -25,6 +25,10 @@
cpu PDP-4/7/9/15 central processor
31-Dec-03 RMS Fixed bug in cpu_set_hist
02-Nov-03 RMS Changed PDP-9,-15 default to API
26-Oct-03 RMS Fixed bug in PDP-4,-7,-9 autoincrement addressing
19-Sep-03 RMS Changed instruction history to be dynamically sized
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
@@ -277,9 +281,11 @@
#define UNIT_XVM (1 << UNIT_V_XVM)
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
#define HIST_SIZE 4096
#define HIST_API 0x40000000
#define HIST_PI 0x20000000
#define HIST_PC 0x10000000
#define HIST_MIN 64
#define HIST_MAX 65536
#define HIST_M_LVL 0x3F
#define HIST_V_LVL 6
struct InstHistory {
@@ -303,7 +309,7 @@ struct InstHistory {
#define PROT_DFLT 0
#define ASW_DFLT 017763
#else
#define API_DFLT UNIT_NOAPI /* for now */
#define API_DFLT 0
#define PROT_DFLT UNIT_PROT
#define ASW_DFLT 017720
#endif
@@ -355,7 +361,7 @@ int32 pcq_p = 0; /* PC queue 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 */
struct InstHistory *hst = NULL; /* instruction history */
extern int32 sim_int_char;
extern int32 sim_interval;
@@ -1510,7 +1516,7 @@ t_stat Ia (int32 ma, int32 *ea, t_bool jmp)
int32 t;
t_stat sta = MM_OK;
if ((ma & B_DAMASK) == 010) { /* autoindex? */
if ((ma & B_DAMASK & ~07) == 010) { /* autoindex? */
Read (ma, &t, DF); /* add 1 before use */
t = (t + 1) & DMASK;
sta = Write (ma, t, DF); }
@@ -1588,7 +1594,7 @@ t_stat Ia (int32 ma, int32 *ea, t_bool jmp)
int32 t;
t_stat sta = MM_OK;
if ((ma & B_DAMASK) == 010) { /* autoindex? */
if ((ma & B_DAMASK & ~07) == 010) { /* autoindex? */
ma = ma & 017; /* always in bank 0 */
Read (ma, &t, DF); /* +1 before use */
t = (t + 1) & DMASK;
@@ -1799,7 +1805,7 @@ t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw)
if (usmd && (sw & SWMASK ('V'))) {
if (XVM) addr = RelocXVM (addr, REL_C);
else if (RELOC) addr = Reloc15 (addr, REL_C);
if (addr < 0) return STOP_MME; }
if ((int32) addr < 0) return STOP_MME; }
#endif
if (addr >= MEMSIZE) return SCPE_NXM;
if (vptr != NULL) *vptr = M[addr] & DMASK;
@@ -1814,7 +1820,7 @@ t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw)
if (usmd && (sw & SWMASK ('V'))) {
if (XVM) addr = RelocXVM (addr, REL_C);
else if (RELOC) addr = Reloc15 (addr, REL_C);
if (addr < 0) return STOP_MME; }
if ((int32) addr < 0) return STOP_MME; }
#endif
if (addr >= MEMSIZE) return SCPE_NXM;
M[addr] = val & DMASK;
@@ -1933,11 +1939,20 @@ int32 i, lnt;
t_stat r;
if (cptr == NULL) {
for (i = 0; i < HIST_SIZE; i++) hst[i].pc = 0;
for (i = 0; i < hst_lnt; i++) hst[i].pc = 0;
hst_p = 0;
return SCPE_OK; }
lnt = (int32) get_uint (cptr, 10, HIST_SIZE, &r);
if (r != SCPE_OK) return SCPE_ARG;
hst_lnt = lnt;
lnt = (int32) get_uint (cptr, 10, HIST_MAX, &r);
if ((r != SCPE_OK) || (lnt && (lnt < HIST_MIN))) return SCPE_ARG;
hst_p = 0;
if (hst_lnt) {
free (hst);
hst_lnt = 0;
hst = NULL; }
if (lnt) {
hst = calloc (sizeof (struct InstHistory), lnt);
if (hst == NULL) return SCPE_MEM;
hst_lnt = lnt; }
return SCPE_OK;
}
@@ -1952,25 +1967,26 @@ 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 */
fprintf (st, "PC L AC MQ IR\n\n");
di = hst_p; /* 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? */
h = &hst[(di++) % hst_lnt]; /* entry pointer */
if (h->pc & HIST_PC) { /* instruction? */
l = (h->lac >> 18) & 1; /* link */
fprintf (st, "%06o %o %06o %06o ", h->pc & AMASK, l, h->lac & DMASK, h->mq);
sim_eval[0] = h->ir;
sim_eval[1] = h->ir1;
if ((fprint_sym (st, h->pc & AMASK, sim_eval, &cpu_unit, SWMASK ('M'))) > 0)
fprintf (st, "(undefined) %06o", h->ir);
} /* end else instruction */
else 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);
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 */
else continue; /* invalid */
fputc ('\n', st); /* end line */
} /* end for */
return SCPE_OK;
@@ -1980,13 +1996,17 @@ return SCPE_OK;
void cpu_inst_hist (int32 addr, int32 inst)
{
hst[hst_p].pc = addr;
t_value word;
hst[hst_p].pc = addr | HIST_PC;
hst[hst_p].ir = inst;
if (cpu_ex (&hst[hst_p].ir1, (addr + 1) & AMASK, &cpu_unit, SWMASK ('V')))
if (cpu_ex (&word, (addr + 1) & AMASK, &cpu_unit, SWMASK ('V')))
hst[hst_p].ir1 = 0;
else hst[hst_p].ir1 = word;
hst[hst_p].lac = LAC;
hst[hst_p].mq = MQ;
hst_p = (hst_p + 1) % HIST_SIZE;
hst_p = (hst_p + 1);
if (hst_p >= hst_lnt) hst_p = 0;
return;
}
@@ -2001,6 +2021,7 @@ for (j = 0; j < API_HLVL+1; j++) hst[hst_p].ir =
hst[hst_p].ir1 = 0;
hst[hst_p].lac = 0;
hst[hst_p].mq = lvl;
hst_p = (hst_p + 1) % HIST_SIZE;
hst_p = (hst_p + 1);
if (hst_p >= hst_lnt) hst_p = 0;
return;
}

View File

@@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
18-Oct-03 RMS Added DECtape off reel message
18-Jul-03 RMS Added FP15 support
Added XVM support
Added EAE option for PDP-4
@@ -110,6 +111,7 @@
#define STOP_NONSTD 6 /* non-std dev num */
#define STOP_MME 7 /* mem mgt error */
#define STOP_FPDIS 8 /* fp inst, fpp disabled */
#define STOP_DTOFF 9 /* DECtape off reel */
/* Peripheral configuration */

View File

@@ -154,6 +154,7 @@ The 18b PDP simulators implement several unique stop conditions:
instruction execution
- an FP15 instruction is decoded, the FP15 is disabled,
and register STOP_FPP is set
- a simulated DECtape runs off the end of its real
The PDP-4 and PDP-7 LOAD command supports only "second stage" RIM format
files (alternating DAC address instructions and data):
@@ -273,6 +274,16 @@ control registers for the interrupt system.
"addr" signifies the address width of the system (13b for the PDP-4, 15b for
the PDP-7 and PDP-9, 17b for the PDP-15).
The CPU can maintain a history of the most recently executed instructions.
This is controlled by the SET CPU HISTORY and SHOW CPU HISTORY commands:
SET CPU HISTORY clear history buffer
SET CPU HISTORY=0 disable history
SET CPU HISTORY=n enable history, display length = n
SHOW CPU HISTORY print CPU history
The maximum length for the history is 65536 entries.
2.2 Floating Point Processor (FPP)
The PDP-15 features an optional floating point processor, the FP15 (FPP).
@@ -756,7 +767,6 @@ The DECtape controller implements these registers:
9,15 CA 18 current address (memory location 30)
9,15 WC 18 word count (memory location 31)
all LTIME 31 time between lines
all ACTIME 31 time to accelerate to full speed
all DCTIME 31 time to decelerate to a full stop
all SUBSTATE 2 read/write command substate
all POS[0:7] 32 position, in lines, units 0-7
@@ -767,8 +777,9 @@ among the DECtape parameters, or the DECtape simulator will fail to
operate correctly.
- LTIME must be at least 6
- ACTIME must be less than DCTIME, and both need to be at
least 100 times LTIME
- DCTIME needs to be at least 100 times LTIME
Acceleration time is set to 75% of deceleration time.
2.9 TC59/TU10 Magnetic Tape (MT)

View File

@@ -25,6 +25,7 @@
drm (PDP-4,PDP-7) Type 24 serial drum
26-Oct-03 RMS Cleaned up buffer copy code
05-Dec-02 RMS Updated from Type 24 documentation
22-Nov-02 RMS Added PDP-4 support
05-Feb-02 RMS Added DIB, device number support
@@ -165,6 +166,7 @@ t_stat drm_svc (UNIT *uptr)
{
int32 i;
uint32 da;
int32 *fbuf = uptr->filebuf;
if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */
drm_err = 1; /* set error */
@@ -173,13 +175,13 @@ if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */
da = drm_da * DRM_NUMWDS; /* compute dev addr */
for (i = 0; i < DRM_NUMWDS; i++, da++) { /* do transfer */
if (uptr->FUNC == DRM_READ) {
if (MEM_ADDR_OK (drm_ma)) /* read, check nxm */
M[drm_ma] = *(((int32 *) uptr->filebuf) + da); }
else {
if (uptr->FUNC == DRM_READ) { /* read? */
if (MEM_ADDR_OK (drm_ma)) /* if !nxm */
M[drm_ma] = fbuf[da]; } /* read word */
else { /* write */
if ((drm_wlk >> (drm_da >> 4)) & 1) drm_err = 1;
else {
*(((int32 *) uptr->filebuf) + da) = M[drm_ma];
else { /* not locked */
fbuf[da] = M[drm_ma]; /* write word */
if (da >= uptr->hwmark) uptr->hwmark = da + 1; } }
drm_ma = (drm_ma + 1) & 0177777; } /* incr mem addr */
drm_da = (drm_da + 1) & DRM_SMASK; /* incr dev addr */

View File

@@ -27,6 +27,10 @@
(PDP-9) TC02/TU55 DECtape
(PDP-15) TC15/TU56 DECtape
26-Oct-03 RMS Cleaned up buffer copy code
18-Oct-03 RMS Fixed reverse checksum in read all
Added DECtape off reel message
Simplified timing
25-Apr-03 RMS Revised for extended file support
14-Mar-03 RMS Fixed variable size interaction with save/restore
17-Oct-02 RMS Fixed bug in end of reel logic
@@ -56,13 +60,16 @@
When a 16b or 12b DECtape file is read in, it is converted to 18b/36b format.
DECtape motion is measured in 3b lines. Time between lines is 33.33us.
Tape density is nominally 300 lines per inch. The format of a DECtape is
Tape density is nominally 300 lines per inch. The format of a DECtape (as
taken from the TD8E formatter) is:
reverse end zone 36000 lines ~ 10 feet
reverse end zone 8192 reverse end zone codes ~ 10 feet
reverse buffer 200 interblock codes
block 0
:
block n
forward end zone 36000 lines ~ 10 feet
forward buffer 200 interblock codes
forward end zone 8192 forward end zone codes ~ 10 feet
A block consists of five 18b header words, a tape-specific number of data
words, and five 18b trailer words. All systems except the PDP-8 use a
@@ -79,9 +86,9 @@
header word 0 0
header word 1 block number (for forward reads)
header words 2,3 0
header word 4 0
header word 4 checksum (for reverse reads)
:
trailer word 4 checksum
trailer word 4 checksum (for forward reads)
trailer words 3,2 0
trailer word 1 block number (for reverse reads)
trailer word 0 0
@@ -112,13 +119,15 @@
/* System independent DECtape constants */
#define DT_EZLIN 36000 /* end zone length */
#define DT_HTLIN 30 /* header/trailer lines */
#define DT_BLKLN 6 /* blk no line in h/t */
#define DT_CSMLN 24 /* checksum line in h/t */
#define DT_HTWRD (DT_HTLIN / DT_WSIZE) /* header/trailer words */
#define DT_BLKWD (DT_BLKLN / DT_WSIZE) /* blk no word in h/t */
#define DT_CSMWD (DT_CSMLN / DT_WSIZE) /* checksum word in h/t */
#define DT_LPERMC 6 /* lines per mark track */
#define DT_BLKWD 1 /* blk no word in h/t */
#define DT_CSMWD 4 /* checksum word in h/t */
#define DT_HTWRD 5 /* header/trailer words */
#define DT_EZLIN (8192 * DT_LPERMC) /* end zone length */
#define DT_BFLIN (200 * DT_LPERMC) /* buffer length */
#define DT_BLKLN (DT_BLKWD * DT_LPERMC) /* blk no line in h/t */
#define DT_CSMLN (DT_CSMWD * DT_LPERMC) /* csum line in h/t */
#define DT_HTLIN (DT_HTWRD * DT_LPERMC) /* header/trailer lines */
/* 16b, 18b, 36b DECtape constants */
@@ -317,8 +326,7 @@ int32 dtsa = 0; /* status A */
int32 dtsb = 0; /* status B */
int32 dtdb = 0; /* data buffer */
int32 dt_ltime = 12; /* interline time */
int32 dt_actime = 54000; /* accel time */
int32 dt_dctime = 72000; /* decel time */
int32 dt_dctime = 40000; /* decel time */
int32 dt_substate = 0;
int32 dt_log = 0;
int32 dt_logblk = 0;
@@ -390,7 +398,6 @@ REG dt_reg[] = {
{ ORDATA (CA, M[DT_CA], 18) },
#endif
{ DRDATA (LTIME, dt_ltime, 31), REG_NZ },
{ DRDATA (ACTIME, dt_actime, 31), REG_NZ },
{ DRDATA (DCTIME, dt_dctime, 31), REG_NZ },
{ ORDATA (SUBSTATE, dt_substate, 2) },
{ ORDATA (LOG, dt_log, 4), REG_HIDDEN },
@@ -579,7 +586,7 @@ if ((prev_mving | new_mving) == 0) return; /* stop to stop */
if (new_mving & ~prev_mving) { /* start? */
if (dt_setpos (uptr)) return; /* update pos */
sim_cancel (uptr); /* stop current */
sim_activate (uptr, dt_actime); /* schedule accel */
sim_activate (uptr, dt_dctime - (dt_dctime >> 2)); /* sched accel */
DTS_SETSTA (DTS_ACCF | new_dir, 0); /* state = accel */
DTS_SET2ND (DTS_ATSF | new_dir, new_fnc); /* next = fnc */
return; }
@@ -605,7 +612,7 @@ if (prev_dir ^ new_dir) { /* dir chg? */
if (prev_mot < DTS_ACCF) { /* not accel/at speed? */
if (dt_setpos (uptr)) return; /* update pos */
sim_cancel (uptr); /* cancel cur */
sim_activate (uptr, dt_actime); /* schedule accel */
sim_activate (uptr, dt_dctime - (dt_dctime >> 2)); /* sched accel */
DTS_SETSTA (DTS_ACCF | new_dir, 0); /* state = accel */
DTS_SET2ND (DTS_ATSF | new_dir, new_fnc); /* next = fnc */
return; }
@@ -744,11 +751,13 @@ case DTS_STOP: /* stop */
delta = 0;
break;
case DTS_DECF: /* slowing */
ulin = ut / (uint32) dt_ltime; udelt = dt_dctime / dt_ltime;
ulin = ut / (uint32) dt_ltime;
udelt = dt_dctime / dt_ltime;
delta = ((ulin * udelt * 2) - (ulin * ulin)) / (2 * udelt);
break;
case DTS_ACCF: /* accelerating */
ulin = ut / (uint32) dt_ltime; udelt = dt_actime / dt_ltime;
ulin = ut / (uint32) dt_ltime;
udelt = (dt_dctime - (dt_dctime >> 2)) / dt_ltime;
delta = (ulin * ulin) / (2 * udelt);
break;
case DTS_ATSF: /* at speed */
@@ -777,7 +786,7 @@ t_stat dt_svc (UNIT *uptr)
int32 mot = DTS_GETMOT (uptr->STATE);
int32 dir = mot & DTS_DIR;
int32 fnc = DTS_GETFNC (uptr->STATE);
int32 *bptr = uptr->filebuf;
int32 *fbuf = uptr->filebuf;
int32 unum = uptr - dt_dev.units;
int32 blk, wrd, ma, relpos;
uint32 ba;
@@ -791,10 +800,10 @@ uint32 ba;
switch (mot) {
case DTS_DECF: case DTS_DECR: /* decelerating */
if (dt_setpos (uptr)) return SCPE_OK; /* update pos */
if (dt_setpos (uptr)) return STOP_DTOFF; /* update pos */
uptr->STATE = DTS_NXTSTA (uptr->STATE); /* advance state */
if (uptr->STATE) /* not stopped? */
sim_activate (uptr, dt_actime); /* must be reversing */
sim_activate (uptr, dt_dctime - (dt_dctime >> 2)); /* reversing */
return SCPE_OK;
case DTS_ACCF: case DTS_ACCR: /* accelerating */
dt_newfnc (uptr, DTS_NXTSTA (uptr->STATE)); /* adv state, sched */
@@ -812,7 +821,7 @@ default: /* other */
Off reel - detach unit (it must be deselected)
*/
if (dt_setpos (uptr)) return SCPE_OK; /* update pos */
if (dt_setpos (uptr)) return STOP_DTOFF; /* update pos */
if (DT_QEZ (uptr)) { /* in end zone? */
dt_seterr (uptr, DTB_END); /* end zone error */
return SCPE_OK; }
@@ -872,7 +881,7 @@ case FNC_READ: /* read */
M[DT_CA] = (M[DT_CA] + 1) & DMASK;
ma = M[DT_CA] & AMASK; /* mem addr */
ba = (blk * DTU_BSIZE (uptr)) + wrd; /* buffer ptr */
dtdb = bptr[ba]; /* get tape word */
dtdb = fbuf[ba]; /* get tape word */
if (dir) dtdb = dt_comobv (dtdb); /* rev? comp obv */
if (MEM_ADDR_OK (ma)) M[ma] = dtdb; /* mem addr legal? */
if (M[DT_WC] == 0) dt_substate = DTO_WCO; /* wc ovf? */
@@ -924,7 +933,7 @@ case FNC_WRIT: /* write */
ba = (blk * DTU_BSIZE (uptr)) + wrd; /* buffer ptr */
dtdb = dt_substate? 0: M[ma]; /* get word */
if (dir) dtdb = dt_comobv (dtdb); /* rev? comp obv */
bptr[ba] = dtdb; /* write word */
fbuf[ba] = dtdb; /* write word */
if (ba >= uptr->hwmark) uptr->hwmark = ba + 1;
if (M[DT_WC] == 0) dt_substate = DTO_WCO;
if (wrd != (dir? 0: DTU_BSIZE (uptr) - 1)) /* not last? */
@@ -960,7 +969,7 @@ case FNC_RALL:
(relpos < (DTU_LPERB (uptr) - DT_HTLIN))) {
wrd = DT_LIN2WD (uptr->pos, uptr);
ba = (blk * DTU_BSIZE (uptr)) + wrd;
dtdb = bptr[ba]; } /* get tape word */
dtdb = fbuf[ba]; } /* get tape word */
else dtdb = dt_gethdr (uptr, blk, relpos); /* get hdr */
if (dir) dtdb = dt_comobv (dtdb); /* rev? comp obv */
sim_activate (uptr, DT_WSIZE * dt_ltime);
@@ -996,7 +1005,7 @@ case FNC_WALL:
if (dir) dtdb = dt_comobv (dtdb);
wrd = DT_LIN2WD (uptr->pos, uptr);
ba = (blk * DTU_BSIZE (uptr)) + wrd;
bptr[ba] = dtdb; /* write word */
fbuf[ba] = dtdb; /* write word */
if (ba >= uptr->hwmark) uptr->hwmark = ba + 1; }
/* /* ignore hdr */
sim_activate (uptr, DT_WSIZE * dt_ltime);
@@ -1034,7 +1043,7 @@ case FNC_READ: case FNC_RALL:
(relpos < (DTU_LPERB (uptr) - DT_HTLIN))) {
wrd = DT_LIN2WD (uptr->pos, uptr);
ba = (blk * DTU_BSIZE (uptr)) + wrd;
dtdb = bptr[ba]; /* get tape word */
dtdb = fbuf[ba]; /* get tape word */
dtsb = dtsb | DTB_DTF; } /* set flag */
else {
ma = (2 * DT_HTWRD) + DTU_BSIZE (uptr) - DT_CSMWD - 1;
@@ -1063,8 +1072,8 @@ case FNC_WRIT: case FNC_WALL:
(relpos < (DTU_LPERB (uptr) - DT_HTLIN))) {
wrd = DT_LIN2WD (uptr->pos, uptr);
ba = (blk * DTU_BSIZE (uptr)) + wrd;
if (dir) bptr[ba] = dt_comobv (dtdb); /* get data word */
else bptr[ba] = dtdb;
if (dir) fbuf[ba] = dt_comobv (dtdb); /* get data word */
else fbuf[ba] = dtdb;
if (ba >= uptr->hwmark) uptr->hwmark = ba + 1;
if (wrd == (dir? 0: DTU_BSIZE (uptr) - 1))
dtsb = dtsb | DTB_BEF; /* end block */
@@ -1133,20 +1142,20 @@ return dat;
int32 dt_csum (UNIT *uptr, int32 blk)
{
int32 *bptr = uptr->filebuf;
int32 *fbuf = uptr->filebuf;
int32 ba = blk * DTU_BSIZE (uptr);
int32 i, csum, wrd;
#if defined (TC02) /* TC02/TC15 */
csum = 077; /* init csum */
for (i = 0; i < DTU_BSIZE (uptr); i++) { /* loop thru buf */
wrd = bptr[ba + i] ^ DMASK; /* get ~word */
wrd = fbuf[ba + i] ^ DMASK; /* get ~word */
csum = csum ^ (wrd >> 12) ^ (wrd >> 6) ^ wrd; }
return (csum & 077);
#else /* Type 550 */
csum = DMASK;
csum = 0777777;
for (i = 0; i < DTU_BSIZE (uptr); i++) { /* loop thru buf */
wrd = bptr[ba + i]; /* get word */
wrd = fbuf[ba + i]; /* get word */
csum = csum + wrd; /* 1's comp add */
if (csum > DMASK) csum = (csum + 1) & DMASK; }
return (csum ^ DMASK); /* 1's comp res */
@@ -1160,15 +1169,15 @@ int32 dt_gethdr (UNIT *uptr, int32 blk, int32 relpos)
int32 wrd = relpos / DT_WSIZE;
if (wrd == DT_BLKWD) return blk; /* fwd blknum */
if (wrd == DT_CSMWD) return 077; /* rev csum */
#if defined (TC02) /* TC02/TC15 */
if (wrd == (2 * DT_HTWRD + DTU_BSIZE (uptr) - DT_CSMWD - 1)) /* fwd csum */
if (wrd == ((2 * DT_HTWRD) + DTU_BSIZE (uptr) - DT_CSMWD - 1)) /* fwd csum */
return (dt_csum (uptr, blk) << 12);
#else
if (wrd == DT_CSMWD) return DMASK; /* rev csum */
if (wrd == (2 * DT_HTWRD + DTU_BSIZE (uptr) - DT_CSMWD - 1)) /* fwd csum */
if (wrd == ((2 * DT_HTWRD) + DTU_BSIZE (uptr) - DT_CSMWD - 1)) /* fwd csum */
return (dt_csum (uptr, blk));
#endif /* Type 550 */
if (wrd == (2 * DT_HTWRD + DTU_BSIZE (uptr) - DT_BLKWD - 1)) /* rev blkno */
if (wrd == ((2 * DT_HTWRD) + DTU_BSIZE (uptr) - DT_BLKWD - 1)) /* rev blkno */
return dt_comobv (blk);
return 0; /* all others */
}
@@ -1223,7 +1232,7 @@ t_stat dt_attach (UNIT *uptr, char *cptr)
{
uint16 pdp8b[D8_NBSIZE];
uint16 pdp11b[D18_BSIZE];
uint32 ba, sz, k, *bptr;
uint32 ba, sz, k, *fbuf;
int32 u = uptr - dt_dev.units;
t_stat r;
@@ -1246,7 +1255,7 @@ uptr->filebuf = calloc (uptr->capac, sizeof (int32));
if (uptr->filebuf == NULL) { /* can't alloc? */
detach_unit (uptr);
return SCPE_MEM; }
bptr = uptr->filebuf; /* file buffer */
fbuf = uptr->filebuf; /* file buffer */
printf ("%s%d: ", sim_dname (&dt_dev), u);
if (uptr->flags & UNIT_8FMT) printf ("12b format");
else if (uptr->flags & UNIT_11FMT) printf ("16b format");
@@ -1258,9 +1267,9 @@ if (uptr->flags & UNIT_8FMT) { /* 12b? */
if (k == 0) break;
for ( ; k < D8_NBSIZE; k++) pdp8b[k] = 0;
for (k = 0; k < D8_NBSIZE; k = k + 3) { /* loop thru blk */
bptr[ba] = ((uint32) (pdp8b[k] & 07777) << 6) |
fbuf[ba] = ((uint32) (pdp8b[k] & 07777) << 6) |
((uint32) (pdp8b[k + 1] >> 6) & 077);
bptr[ba + 1] = ((uint32) (pdp8b[k + 1] & 077) << 12) |
fbuf[ba + 1] = ((uint32) (pdp8b[k + 1] & 077) << 12) |
(pdp8b[k + 2] & 07777);
ba = ba + 2; } /* end blk loop */
} /* end file loop */
@@ -1271,7 +1280,7 @@ else if (uptr->flags & UNIT_11FMT) { /* 16b? */
if (k == 0) break;
for ( ; k < D18_BSIZE; k++) pdp11b[k] = 0;
for (k = 0; k < D18_BSIZE; k++)
bptr[ba++] = pdp11b[k]; }
fbuf[ba++] = pdp11b[k]; }
uptr->hwmark = ba; } /* end elif */
else uptr->hwmark = fxread (uptr->filebuf, sizeof (int32),
uptr->capac, uptr->fileref);
@@ -1294,7 +1303,7 @@ t_stat dt_detach (UNIT* uptr)
{
uint16 pdp8b[D8_NBSIZE];
uint16 pdp11b[D18_BSIZE];
uint32 ba, k, *bptr;
uint32 ba, k, *fbuf;
int32 u = uptr - dt_dev.units;
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK;
@@ -1304,17 +1313,17 @@ if (sim_is_active (uptr)) {
dtsb = dtsb | DTB_ERF | DTB_SEL | DTB_DTF;
DT_UPDINT; }
uptr->STATE = uptr->pos = 0; }
bptr = uptr->filebuf; /* file buffer */
fbuf = uptr->filebuf; /* file buffer */
if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
printf ("%s%d: writing buffer to file\n", sim_dname (&dt_dev), u);
rewind (uptr->fileref); /* start of file */
if (uptr->flags & UNIT_8FMT) { /* 12b? */
for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */
for (k = 0; k < D8_NBSIZE; k = k + 3) { /* loop blk */
pdp8b[k] = (bptr[ba] >> 6) & 07777;
pdp8b[k + 1] = ((bptr[ba] & 077) << 6) |
((bptr[ba + 1] >> 12) & 077);
pdp8b[k + 2] = bptr[ba + 1] & 07777;
pdp8b[k] = (fbuf[ba] >> 6) & 07777;
pdp8b[k + 1] = ((fbuf[ba] & 077) << 6) |
((fbuf[ba + 1] >> 12) & 077);
pdp8b[k + 2] = fbuf[ba + 1] & 07777;
ba = ba + 2; } /* end loop blk */
fxwrite (pdp8b, sizeof (int16), D8_NBSIZE, uptr->fileref);
if (ferror (uptr->fileref)) break; } /* end loop file */
@@ -1322,7 +1331,7 @@ if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
else if (uptr->flags & UNIT_11FMT) { /* 16b? */
for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */
for (k = 0; k < D18_BSIZE; k++) /* loop blk */
pdp11b[k] = bptr[ba++] & 0177777;
pdp11b[k] = fbuf[ba++] & 0177777;
fxwrite (pdp11b, sizeof (int16), D18_BSIZE, uptr->fileref);
if (ferror (uptr->fileref)) break; } /* end loop file */
} /* end if 16b */

View File

@@ -25,6 +25,8 @@
rb RB09 fixed head disk
26-Oct-03 RMS Cleaned up buffer copy code
The RB09 is a head-per-track disk. It uses the single cycle data break
facility. To minimize overhead, the entire RB09 is buffered in memory.
@@ -219,6 +221,7 @@ return r;
t_stat rb_svc (UNIT *uptr)
{
int32 t, sw;
int32 *fbuf = uptr->filebuf;
if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */
rb_updsta (RBS_NRY | RBS_DON); /* set nxd, done */
@@ -230,11 +233,11 @@ do { if (rb_sta & RBS_WR) { /* write? */
if ((rb_wlk >> sw) & 1) { /* write locked? */
rb_updsta (RBS_ILA | RBS_DON);
break; }
else {
*(((int32 *) uptr->filebuf) + rb_da) = M[rb_ma];
else { /* not locked */
fbuf[rb_da] = M[rb_ma]; /* write word */
if (((t_addr) rb_da) >= uptr->hwmark) uptr->hwmark = rb_da + 1; } }
else if (MEM_ADDR_OK (rb_ma)) /* read, valid addr? */
M[rb_ma] = *(((int32 *) uptr->filebuf) + rb_da);
M[rb_ma] = fbuf[rb_da]; /* read word */
rb_wc = (rb_wc + 1) & 0177777; /* incr word count */
rb_ma = (rb_ma + 1) & AMASK; /* incr mem addr */
rb_da = rb_da + 1; /* incr disk addr */

View File

@@ -26,6 +26,7 @@
rf (PDP-9) RF09/RF09
(PDP-15) RF15/RS09
26-Oct-03 RMS Cleaned up buffer copy code
26-Jul-03 RMS Fixed bug in set size routine
14-Mar-03 RMS Fixed variable platter interaction with save/restore
03-Mar-03 RMS Fixed autosizing
@@ -239,6 +240,7 @@ return dat;
t_stat rf_svc (UNIT *uptr)
{
int32 f, pa, d, t;
int32 *fbuf = uptr->filebuf;
if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */
rf_updsta (RFS_NED | RFS_DON); /* set nxd, done */
@@ -251,9 +253,8 @@ do { if ((uint32) rf_da >= uptr->capac) { /* disk overflow? */
M[RF_WC] = (M[RF_WC] + 1) & DMASK; /* incr word count */
pa = M[RF_CA] = (M[RF_CA] + 1) & AMASK; /* incr mem addr */
if ((f == FN_READ) && MEM_ADDR_OK (pa)) /* read? */
M[pa] = *(((int32 *) uptr->filebuf) + rf_da);
if ((f == FN_WCHK) && /* write check? */
(M[pa] != *(((int32 *) uptr->filebuf) + rf_da))) {
M[pa] = fbuf[rf_da];
if ((f == FN_WCHK) && (M[pa] != fbuf[rf_da])) { /* write check? */
rf_updsta (RFS_WCE); /* flag error */
break; }
if (f == FN_WRITE) { /* write? */
@@ -262,8 +263,8 @@ do { if ((uint32) rf_da >= uptr->capac) { /* disk overflow? */
if ((rf_wlk[d] >> t) & 1) { /* write locked? */
rf_updsta (RFS_WLO);
break; }
else {
*(((int32 *) uptr->filebuf) + rf_da) = M[pa];
else { /* not locked */
fbuf[rf_da] = M[pa]; /* write word */
if (((uint32) rf_da) >= uptr->hwmark) uptr->hwmark = rf_da + 1; } }
rf_da = rf_da + 1; /* incr disk addr */
}

View File

@@ -29,6 +29,7 @@
tto teleprinter
clk clock
29-Dec-03 RMS Added console backpressure support
26-Jul-03 RMS Increased PTP, TTO timeouts for PDP-15 operating systems
Added hardware read-in mode support for PDP-7/9/15
25-Apr-03 RMS Revised for extended file support
@@ -839,40 +840,40 @@ t_stat tti_svc (UNIT *uptr)
#if defined (KSR28) /* Baudot... */
int32 c;
sim_activate (&tti_unit, tti_unit.wait); /* continue poll */
sim_activate (uptr, uptr->wait); /* continue poll */
if (tti_state & TTI_2ND) { /* char waiting? */
tti_unit.buf = tti_state & TTI_MASK; /* return char */
uptr->buf = tti_state & TTI_MASK; /* return char */
tti_state = tti_state & ~TTI_2ND; } /* not waiting */
else { if ((c = sim_poll_kbd ()) < SCPE_KFLAG) return c;
c = tti_trans[c & 0177]; /* translate char */
if (c == 0) return SCPE_OK; /* untranslatable? */
if (((c & TTI_FIGURES) == (tti_state & TTI_FIGURES)) ||
(c & TTI_BOTH)) tti_unit.buf = c & TTI_MASK;
(c & TTI_BOTH)) uptr->buf = c & TTI_MASK;
else {
tti_unit.buf = (c & TTI_FIGURES)?
uptr->buf = (c & TTI_FIGURES)?
BAUDOT_FIGURES: BAUDOT_LETTERS;
tti_state = c | TTI_2ND; } } /* set 2nd waiting */
#else /* ASCII... */
int32 c, out;
sim_activate (&tti_unit, tti_unit.wait); /* continue poll */
sim_activate (uptr, uptr->wait); /* continue poll */
if ((c = sim_poll_kbd ()) < SCPE_KFLAG) return c; /* no char or error? */
out = c & 0177; /* mask echo to 7b */
if (c & SCPE_BREAK) c = 0; /* break? */
else if (tti_unit.flags & UNIT_KSR) { /* KSR? */
else if (uptr->flags & UNIT_KSR) { /* KSR? */
if (islower (out)) out = toupper (out); /* convert to UC */
c = out | 0200; } /* set TTY bit */
else c = c & ((tti_unit.flags & UNIT_8B)? 0377: 0177); /* no, 7b/8b */
if ((tti_unit.flags & UNIT_HDX) && out && /* half duplex and */
else c = c & ((uptr->flags & UNIT_8B)? 0377: 0177); /* no, 7b/8b */
if ((uptr->flags & UNIT_HDX) && out && /* half duplex and */
(!(tto_unit.flags & UNIT_KSR) || /* 7b/8b or */
((out >= 007) && (out <= 0137)))) { /* in range? */
sim_putchar (out); /* echo */
tto_unit.pos = tto_unit.pos + 1; }
tti_unit.buf = c; /* got char */
uptr->buf = c; /* got char */
#endif
tti_unit.pos = tti_unit.pos + 1;
uptr->pos = uptr->pos + 1;
SET_INT (TTI); /* set flag */
return SCPE_OK;
}
@@ -926,24 +927,27 @@ t_stat tto_svc (UNIT *uptr)
int32 c;
t_stat r;
SET_INT (TTO); /* set flag */
#if defined (KSR28) /* Baudot... */
if (tto_unit.buf == BAUDOT_FIGURES) { /* set figures? */
if (uptr->buf == BAUDOT_FIGURES) /* set figures? */
tto_state = TTO_FIGURES;
return SCPE_OK; }
if (tto_unit.buf == BAUDOT_LETTERS) { /* set letters? */
else if (uptr->buf == BAUDOT_LETTERS) /* set letters? */
tto_state = 0;
return SCPE_OK; }
c = tto_trans[tto_unit.buf + tto_state]; /* translate */
else { c = tto_trans[uptr->buf + tto_state]; /* translate */
#else
if (tto_unit.flags & UNIT_KSR) { /* KSR? */
c = tto_unit.buf & 0177;
if (islower (c)) c = toupper (c);
if ((c < 007) || (c > 0137)) return SCPE_OK; }
else c = tto_unit.buf & ((tto_unit.flags & UNIT_8B)? 0377: 0177);
c = uptr->buf & 0177; /* assume 7b or KSR */
if (!(uptr->flags & UNIT_KSR) || /* 7b/8b or */
((c >= 007) && (c <= 0137))) { /* in range? */
if ((uptr->flags & UNIT_KSR) && islower (c)) /* KSR? */
c = toupper (c);
else if (tto_unit.flags & UNIT_8B) c = uptr->buf;
#endif
if ((r = sim_putchar (c)) != SCPE_OK) return r;
tto_unit.pos = tto_unit.pos + 1;
if ((r = sim_putchar_s (c)) != SCPE_OK) { /* output; error? */
sim_activate (uptr, uptr->wait); /* retry? */
return ((r == SCPE_STALL)? SCPE_OK: r); } }
SET_INT (TTO); /* set flag */
uptr->pos = uptr->pos + 1;
return SCPE_OK;
}

View File

@@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
18-Oct-03 RMS Added DECtape off reel message
30-Jul-03 RMS Fixed FPM class mask
18-Jul-03 RMS Added FP15 support
02-Mar-03 RMS Split loaders apart for greater flexibility
@@ -170,7 +171,8 @@ const char *sim_stop_messages[] = {
"Invalid API interrupt",
"Non-standard device number",
"Memory management error",
"FP15 instruction disabled" };
"FP15 instruction disabled",
"DECtape off reel" };
/* Binary loaders */