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:
committed by
Mark Pizzolato
parent
b2101ecdd4
commit
1da2d9452d
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user