Notes For V3.6-0

The save/restore format has been updated to improve its reliability.
As a result, save files prior to release 3.0 are no longer supported.

The text documentation files are obsolete and are no longer included
with the distribution.  Up-to-date PDF documentation files are
available on the SimH web site.

1. New Features

1.1 3.6-0

1.1.1 Most magnetic tapes

- Added support for limiting tape capacity to a particular size in MB

1.1.2 IBM 7090/7094

- First release

1.1.3 VAX-11/780

- Added FLOAD command, loads system file from console floppy disk

1.1.4 VAX, VAX-11/780, and PDP-11

- Added card reader support (from John Dundas)

1.1.5 PDP-11

- Added instruction history

1.2 3.6-1

1.2.1 PDP-11

- Added RF11 support
- Added multiple KL11/DL11 support
- Added upper-case only mode to TTI, TTO

1.2.2

- Added binary loader (courtesy of Dave Pitt)

2. Bugs Fixed

Please see the revision history on http://simh.trailing-edge.com or
in the source module sim_rev.h.
This commit is contained in:
Bob Supnik 2006-07-20 13:36:00 -07:00 committed by Mark Pizzolato
parent dc871fa631
commit 15919a2dd7
44 changed files with 2249 additions and 376 deletions

View file

@ -32,6 +32,18 @@ available on the SimH web site.
- Added instruction history
1.2 3.6-1
1.2.1 PDP-11
- Added RF11 support
- Added multiple KL11/DL11 support
- Added upper-case only mode to TTI, TTO
1.2.2
- Added binary loader (courtesy of Dave Pitt)
2. Bugs Fixed

View file

@ -26,6 +26,8 @@
ms 13181A 7970B 800bpi nine track magnetic tape
13183A 7970E 1600bpi nine track magnetic tape
07-Jul-06 JDB Added CAPACITY as alternate for REEL
Fixed EOT test for unlimited reel size
16-Feb-06 RMS Revised for new EOT test
22-Jul-05 RMS Fixed compiler warning on Solaris (from Doug Glyn)
01-Mar-05 JDB Added SET OFFLINE; rewind/offline now does not detach
@ -304,9 +306,11 @@ MTAB msc_mod[] = {
{ UNIT_OFFLINE, 0, "online", "ONLINE", msc_online },
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL },
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
{ MTAB_XTD|MTAB_VUN, 0, "REEL", "REEL",
{ MTAB_XTD | MTAB_VUN, 0, "CAPACITY", "CAPACITY",
&ms_set_reelsize, &ms_show_reelsize, NULL },
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
{ MTAB_XTD | MTAB_VUN | MTAB_NMO, 1, "REEL", "REEL",
&ms_set_reelsize, &ms_show_reelsize, NULL },
{ MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT",
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "13181A",
&ms_settype, NULL, NULL },
@ -446,7 +450,6 @@ switch (inst) { /* case on opcode */
dat = dat | STA_TBSY;
if (sim_tape_wrp (uptr)) /* write prot? */
dat = dat | STA_WLK;
uptr->capac = (TCAP << uptr->REEL) << ms_ctype;
if (sim_tape_eot (uptr))
dat = dat | STA_EOT;
}
@ -589,7 +592,6 @@ switch (uptr->FNC) { /* case on function */
break;
case FNC_FSF: /* space fwd file */
uptr->capac = (TCAP << uptr->REEL) << ms_ctype;
while ((st = sim_tape_sprecf (uptr, &tbc)) == MTSE_OK) {
if (sim_tape_eot (uptr)) break; /* EOT stops */
}
@ -836,20 +838,29 @@ else fprintf (st, "13181A");
return SCPE_OK;
}
/* Set unit reel size */
/* Set unit reel size
val = 0 -> SET MSCn CAPACITY=n
val = 1 -> SET MSCn REEL=n */
t_stat ms_set_reelsize (UNIT *uptr, int32 val, char *cptr, void *desc)
{
int32 reel;
t_stat status;
if (val == 0) {
status = sim_tape_set_capac (uptr, val, cptr, desc);
if (status == SCPE_OK) uptr->REEL = 0;
return status;
}
if (cptr == NULL) return SCPE_ARG;
reel = (int32) get_uint (cptr, 10, 2400, &status);
if (status != SCPE_OK) return status;
else switch (reel) {
case 0:
uptr->REEL = 0; /* type 0 = unlimited */
uptr->REEL = 0; /* type 0 = unlimited/custom */
break;
case 600:
@ -868,16 +879,23 @@ else switch (reel) {
return SCPE_ARG;
}
uptr->capac = uptr->REEL? (TCAP << uptr->REEL) << ms_ctype: 0;
return SCPE_OK;
}
/* Show unit reel size */
/* Show unit reel size
val = 0 -> SHOW MSC or SHOW MSCn or SHOW MSCn CAPACITY
val = 1 -> SHOW MSCn REEL */
t_stat ms_show_reelsize (FILE *st, UNIT *uptr, int32 val, void *desc)
{
if (uptr->REEL == 0) fputs ("unlimited size", st);
t_stat status = SCPE_OK;
if (uptr->REEL == 0) status = sim_tape_show_capac (st, uptr, val, desc);
else fprintf (st, "%4d foot reel", 300 << uptr->REEL);
return SCPE_OK;
if (val == 1) fputc ('\n', st); /* MTAB_NMO omits \n */
return status;
}
/* 7970B/7970E bootstrap routine (HP 12992D ROM) */

View file

@ -1,6 +1,6 @@
/* i1620_cd.c: IBM 1622 card reader/punch
Copyright (c) 2002-2005, Robert M. Supnik
Copyright (c) 2002-2006, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -26,6 +26,8 @@
cdr 1622 card reader
cdp 1622 card punch
13-Jul-06 RMS Fixed card reader fgets call (from Tom McBride)
Fixed card reader boot sequence (from Tom McBride)
21-Sep-05 RMS Revised translation tables for 7094/1401 compatibility
25-Apr-03 RMS Revised for extended file support
@ -283,8 +285,8 @@ if ((cdr_unit.flags & UNIT_ATT) == 0) { /* attached? */
return SCPE_UNATT;
}
for (i = 0; i < CD_LEN + 1; i++) cdr_buf[i] = ' '; /* clear buffer */
fgets (cdr_buf, CD_LEN, cdr_unit.fileref); /* read card */
for (i = 0; i < CD_LEN + 2; i++) cdr_buf[i] = ' '; /* clear buffer */
fgets (cdr_buf, CD_LEN + 2, cdr_unit.fileref); /* read card */
if (feof (cdr_unit.fileref)) return STOP_NOCD; /* eof? */
if (ferror (cdr_unit.fileref)) { /* error? */
ind[IN_RDCHK] = 1; /* set read check */
@ -317,24 +319,19 @@ return SCPE_OK;
/* Bootstrap routine */
const static uint8 boot_rom[] = {
3, 6, 1, 9, 9, 0, 1, 0, 0, 5, 0, 0, /* RNCD 19901 */
2, 5, 0, 0, 0, 8, 0, 1, 9, 9, 1, 0x10, /* TD 80,-19910 */
3, 1, 1, 9, 9, 0, 0x15, 1, 9, 9, 2, 0, /* TR -19905,19920 */
2, 5, 1, 9, 9, 1, 0x10, 0, 0, 0, 8, 0, /* TD -19910,80 */
4, 9, 1, 9, 9, 1, 0x15, 0, 0, 0, 0, 0 /* BR -19915 */
};
#define BOOT_START 0
#define BOOT_LEN (sizeof (boot_rom) / sizeof (uint8))
t_stat cdr_boot (int32 unitno, DEVICE *dptr)
{
int32 i;
t_stat r;
int32 old_io_stop;
extern int32 saved_PC;
if ((cpu_unit.flags & IF_IA) == 0) return SCPE_NOFNC; /* must have IA */
for (i = 0; i < BOOT_LEN; i++) M[BOOT_START + i] = boot_rom[i];
old_io_stop = io_stop;
io_stop = 1;
r = cdr (OP_RN, 0, 0, 0); /* read card @ 0 */
io_stop = old_io_stop;
if (r != SCPE_OK) return r; /* error? */
saved_PC = BOOT_START;
return SCPE_OK;
}

View file

@ -1,6 +1,6 @@
/* i1620_cpu.c: IBM 1620 CPU simulator
Copyright (c) 2002-2005, Robert M. Supnik
Copyright (c) 2002-2006, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -26,6 +26,7 @@
This CPU module incorporates code and comments from the 1620 simulator by
Geoff Kuenning, with his permission.
28-May-06 RMS Fixed bug in cpu history (found by Peter Schorn)
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
16-Aug-05 RMS Fixed C++ declaration and cast problems
07-Nov-04 RMS Added instruction history
@ -2049,7 +2050,7 @@ for (k = 0; k < lnt; k++) { /* print specified */
if ((fprint_sym (st, h->pc, sim_eval, &cpu_unit, SWMASK ('M'))) > 0) {
fprintf (st, "(undefined)");
for (i = 0; i < INST_LEN; i++)
fprintf (st, "% 02X", h->inst[i]);
fprintf (st, "%02X", h->inst[i]);
}
fputc ('\n', st); /* end line */
} /* end else instruction */

214
I7094/i7094_binloader.c Normal file
View file

@ -0,0 +1,214 @@
/* i7094_binloader.c: IBM 7094 simulator interface
Copyright (c) 2006, David G. Pitts
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of the author shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the author.
*/
/***********************************************************************
*
* binloader.h - IBM 7090 emulator binary loader header.
*
* Changes:
* 10/20/03 DGP Original.
* 12/28/04 DGP Changed for new object formats.
*
***********************************************************************/
#define IBSYSSYM '$' /* Marks end of object file */
#define WORDPERREC 5 /* Object words per record */
#define LOADADDR 0200 /* Default load address */
#define OBJRECLEN 80 /* Object record length */
#define CHARWORD 12 /* Characters per word */
/*
** Object tags
*/
#define IDT_TAG '0' /* 0SSSSSS0LLLLL */
#define ABSENTRY_TAG '1' /* 10000000AAAAA */
#define RELENTRY_TAG '2' /* 20000000RRRRR */
#define ABSEXTRN_TAG '3' /* 3SSSSSS0AAAAA */
#define RELEXTRN_TAG '4' /* 4SSSSSS0RRRRR */
#define ABSGLOBAL_TAG '5' /* 5SSSSSS0AAAAA */
#define RELGLOBAL_TAG '6' /* 6SSSSSS0RRRRR */
#define ABSORG_TAG '7' /* 70000000AAAAA */
#define RELORG_TAG '8' /* 80000000RRRRR */
#define ABSDATA_TAG '9' /* 9AAAAAAAAAAAA */
#define RELADDR_TAG 'A' /* AAAAAAAARRRRR */
#define RELDECR_TAG 'B' /* BARRRRRAAAAAA */
#define RELBOTH_TAG 'C' /* CARRRRRARRRRR */
#define BSS_TAG 'D' /* D0000000PPPPP */
#define ABSXFER_TAG 'E' /* E0000000RRRRR */
#define RELXFER_TAG 'F' /* F0000000RRRRR */
#define EVEN_TAG 'G' /* G0000000RRRRR */
#define FAPCOMMON_TAG 'H' /* H0000000AAAAA */
/* Where:
* SSSSSS - Symbol
* LLLLLL - Length of module
* AAAAAA - Absolute field
* RRRRRR - Relocatable field
* PPPPPP - PC offset field
*/
/***********************************************************************
*
* binloader.c - IBM 7090 emulator binary loader routines for ASM7090
* and LNK7090 object files.
*
* Changes:
* 10/20/03 DGP Original.
* 12/28/04 DGP Changed for new object formats.
* 02/14/05 DGP Detect IBSYSSYM for EOF.
* 06/09/06 DGP Make simh callable.
*
***********************************************************************/
#include "i7094_defs.h"
extern t_uint64 *M;
extern uint32 PC;
t_stat
binloader (FILE *fd, char *file, int loadpt)
{
#ifdef DEBUGLOADER
FILE *lfd;
#endif
int transfer = FALSE;
int loadaddr = LOADADDR;
int curraddr = LOADADDR;
char inbuf[OBJRECLEN+2];
#ifdef DEBUGLOADER
lfd = fopen ("load.log", "w");
fprintf (lfd, "binloader: file = '%s', loadpt = %d\n", file, loadpt);
#endif
if (loadpt > 0)
{
loadaddr = loadpt;
curraddr = loadpt;
}
while (fgets (inbuf, sizeof(inbuf), fd))
{
char *op = inbuf;
int i;
if (*op == IBSYSSYM) /* End of object marker */
break;
for (i = 0; i < WORDPERREC; i++)
{
char otag;
char item[16];
t_uint64 ldata;
otag = *op++;
if (otag == ' ') break;
strncpy (item, op, CHARWORD);
item[CHARWORD] = '\0';
#ifdef WIN32
sscanf (item, "%I64o", &ldata);
#else
sscanf (item, "%llo", &ldata);
#endif
#ifdef DEBUGLOADER
fprintf (lfd, "loadaddr = %05o, curraddr = %05o\n",
loadaddr, curraddr);
fprintf (lfd, " otag = %c, item = %s\n", otag, item);
fprintf (lfd, " ldata = %12.12o\n", ldata);
#endif
switch (otag)
{
case IDT_TAG:
break;
case ABSORG_TAG:
curraddr = loadaddr = (int32) ldata & AMASK;
break;
case RELORG_TAG:
curraddr = (int32) (ldata + loadaddr) & AMASK;
break;
case BSS_TAG:
curraddr = (int32) (curraddr + ldata) & AMASK;
break;
case RELBOTH_TAG:
ldata = ldata + loadaddr + (loadaddr << INST_V_DEC);
goto STORE;
case RELDECR_TAG:
ldata = ldata + (loadaddr << INST_V_DEC);
goto STORE;
case RELADDR_TAG:
ldata = ldata + loadaddr;
case ABSDATA_TAG:
STORE:
#ifdef DEBUGLOADER
fprintf (lfd, " M[%05o] = %12.12o\n", curraddr, ldata);
#endif
M[curraddr] = ldata & DMASK;
curraddr++;
break;
case ABSXFER_TAG:
transfer = TRUE;
case ABSENTRY_TAG:
PC = (uint32) ldata & AMASK;
#ifdef DEBUGLOADER
fprintf (lfd, " PC = %05o\n", PC);
#endif
if (transfer) goto GOSTART;
break;
case RELXFER_TAG:
transfer = TRUE;
case RELENTRY_TAG:
ldata = (ldata + loadaddr) & AMASK;
PC = (uint32) ldata & AMASK;
#ifdef DEBUGLOADER
fprintf (lfd, " PC = %05o\n", PC);
#endif
if (transfer) goto GOSTART;
break;
default: ;
}
op += CHARWORD;
}
}
GOSTART:
#ifdef DEBUGLOADER
fclose (lfd);
#endif
return SCPE_OK;
}

View file

@ -26,6 +26,8 @@
cdr 711 card reader
cdp 721 card punch
13-Jul-06 RMS Fixed problem with 80 column full cards
Cards are represented as ASCII text streams terminated by newlines.
This allows cards to be created and edited as normal files. Two
formats are supported:
@ -204,7 +206,7 @@ return SCPE_OK;
t_stat cdr_svc (UNIT *uptr)
{
uint32 i, col, row, bufw, colbin;
char cdr_cbuf[2 * CD_CHRLNT + 1];
char cdr_cbuf[(2 * CD_CHRLNT) + 2];
t_uint64 dat = 0;
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT; /* not attached? */
@ -213,11 +215,11 @@ switch (cdr_sta) { /* case on state */
case CDS_INIT: /* initial state */
for (i = 0; i < CD_BINLNT; i++) /* clear bin buf */
cdr_bbuf[i] = 0;
for (i = 0; i < ((2 * CD_CHRLNT) + 1); i++) /* clear char buf */
for (i = 0; i < ((2 * CD_CHRLNT) + 2); i++) /* clear char buf */
cdr_cbuf[i] = ' ';
cdr_sta = CDS_DATA; /* data state */
cdr_bptr = 0; /* init buf ptr */
fgets (cdr_cbuf, (uptr->flags & UNIT_CBN)? (2 * CD_CHRLNT): CD_CHRLNT,
fgets (cdr_cbuf, (uptr->flags & UNIT_CBN)? (2 * CD_CHRLNT) + 2: CD_CHRLNT + 2,
uptr->fileref); /* read card */
if (feof (uptr->fileref)) /* eof? */
return ch6_err_disc (CH_A, U_CDR, CHF_EOF); /* set EOF, disc */
@ -412,7 +414,7 @@ return SCPE_OK;
t_stat cdp_card_end (UNIT *uptr)
{
uint32 i, col, row, bufw, colbin;
char *pch, bcd, cdp_cbuf[(2 * CD_CHRLNT) + 1];
char *pch, bcd, cdp_cbuf[(2 * CD_CHRLNT) + 2];
t_uint64 dat;
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT; /* not attached? */
@ -439,7 +441,8 @@ for (col = 0; col < 72; col++) { /* process 72 columns */
for (i = ((2 * CD_CHRLNT) + 1); (i > 0) &&
(cdp_cbuf[i - 1] == ' '); --i) ; /* trim spaces */
cdp_cbuf[i++] = '\n'; /* append nl */
fxwrite (cdp_cbuf, 1, i, uptr->fileref); /* write card */
cdp_cbuf[i++] = 0; /* append nul */
fputs (cdp_cbuf, uptr->fileref); /* write card */
if (ferror (uptr->fileref)) { /* error? */
perror ("CDP I/O error");
clearerr (uptr->fileref);

View file

@ -25,6 +25,8 @@
cpu 7094 central processor
16-Jun-06 RMS Fixed bug in halt IO wait loop
The register state for the 7094 is:
AC<S,Q,P,1:35> accumulator
@ -607,7 +609,7 @@ t_stat reason = SCPE_OK;
t_uint64 IR, SR, t, t1, t2, sr1;
uint32 op, fl, tag, tagi, addr, ea;
uint32 ch, dec, xr, xec_cnt, trp;
uint32 i, sc, s1, s2, spill;
uint32 i, j, sc, s1, s2, spill;
t_bool tracing;
/* Restore register state */
@ -1773,9 +1775,9 @@ while (reason == SCPE_OK) { /* loop until error */
if (r = sim_process_event ()) return r; /* process events */
chtr_pend = chtr_eval (NULL); /* eval chan traps */
while (ch_req) { /* until no ch req */
for (i = 0; i < NUM_CHAN; i++) { /* loop thru channels */
if (ch_req & REQ_CH (i)) { /* channel request? */
if (r = ch_proc (i)) return r;
for (j = 0; i < NUM_CHAN; j++) { /* loop thru channels */
if (ch_req & REQ_CH (j)) { /* channel request? */
if (r = ch_proc (j)) return r;
}
chtr_pend = chtr_eval (NULL);
}

View file

@ -22,6 +22,8 @@
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
08-Jun-06 RMS Added Dave Pitts' binary loader
*/
#include "i7094_defs.h"
@ -126,6 +128,10 @@ return STOP_CHBKPT;
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
{
extern t_stat binloader (FILE *fd, char *file, int loadpt);
if (flag == 0)
return binloader (fileref, cptr, 0);
return SCPE_NOFNC;
}

View file

@ -1,6 +1,6 @@
/* id16_dboot.c: Interdata 16b simulator disk bootstrap
Copyright (c) 2000-2005, Robert M. Supnik
Copyright (c) 2000-2006, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -22,6 +22,8 @@
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
17-Jul-06 RMS Fixed transcription error
*/
#include "id_defs.h"
@ -108,7 +110,8 @@ static uint8 dboot_rom[] = {
0x48, 0x0e, 0x00, 0x10,
0x48, 0x1e, 0x00, 0x12,
0x0b, 0x1c,
0x0f, 0x0a, 0x07, 0xff,
0x0f, 0x0a,
0x07, 0xff,
0x26, 0x11,
0x0e, 0x0f,
0xed, 0x00, 0x00, 0x08,

View file

@ -1,6 +1,6 @@
/* id32_dboot.c: Interdata 32b simulator disk bootstrap
Copyright (c) 2000-2005, Robert M. Supnik
Copyright (c) 2000-2006, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -23,6 +23,7 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
17-Jul-06 RMS Fixed transcription errors (found by Davis Johnson)
17-Feb-03 RMS Fixed for UNIX bootstrap, upper platter bootstrap
*/
@ -80,14 +81,14 @@ static uint8 dboot_rom[] = {
0xd3, 0x7e, 0x00, 0x24,
0xc3, 0x70, 0x00, 0x10,
0x23, 0x3e,
0xce, 0x70, 0x00, 0xe0,
0x21, 0xeb,
0xc3, 0x70, 0x00, 0xe0,
0x21, 0x3b,
0x55, 0xfe, 0x00, 0x00,
0x21, 0x38,
0x58, 0x6e, 0x00, 0x08,
0x10, 0x68,
0x55, 0x6d, 0x03, 0x24,
0x44, 0x3d, 0x01, 0xb2,
0x43, 0x3d, 0x01, 0xb2,
0xca, 0xe0, 0x00, 0x30,
0x27, 0x11,
0x42, 0x3d, 0x01, 0x66,
@ -165,7 +166,7 @@ static uint8 dboot_rom[] = {
0x22, 0x21,
0x98, 0x4a,
0xde, 0x4d, 0x03, 0x2f,
0x0d, 0x3f,
0x9d, 0x3f,
0x22, 0x21,
0xde, 0x4d, 0x03, 0x2b,
0x9d, 0x3f,

View file

@ -28,7 +28,7 @@
cpu Eclipse central processor
06-Feb-06 RMS Fixed bug in DIVS (found by Mark Hittinger)
07-Jun-06 RMS Fixed bug in DIVS (found by Mark Hittinger)
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
25-Aug-05 RMS Fixed DIVS overflow cases
29-Nov-03 CEO Corrected POPJ and Bit operations bugs
@ -1665,7 +1665,7 @@ if ((IR & 0100017) == 0100010) { /* This pattern for all
}
if (IR == 0157710) { /* DIVS: Signed Divide */
if ((AC[0] == 0) ||
((AC[0] == 0100000) && (AC[1] == 0) && (AC[2] = 0177777)))
((AC[0] == 0100000) && (AC[1] == 0) && (AC[2] == 0177777)))
C = 0200000;
else {
sAC2 = AC[2];

View file

@ -1,6 +1,6 @@
/* pdp1_cpu.c: PDP-1 CPU simulator
Copyright (c) 1993-2005, Robert M. Supnik
Copyright (c) 1993-2006, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu PDP-1 central processor
28-Jun-06 RMS Fixed bugs in MUS and DIV
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
16-Aug-05 RMS Fixed C++ declaration and cast problems
09-Nov-04 RMS Added instruction history
@ -631,7 +632,7 @@ while (reason == 0) { /* loop until halted */
else { /* multiply step */
if (IO & 1) AC = AC + M[MA];
if (AC > 0777777) AC = (AC + 1) & 0777777;
if (AC == 0777777) AC = 0;
// if (AC == 0777777) AC = 0;
IO = (IO >> 1) | ((AC & 1) << 17);
AC = AC >> 1;
}
@ -641,12 +642,12 @@ while (reason == 0) { /* loop until halted */
if (cpu_unit.flags & UNIT_MDV) { /* hardware */
sign = AC ^ M[MA]; /* result sign */
signd = AC; /* remainder sign */
v = ABS (M[MA]); /* v = |divr| */
if (ABS (AC) >= v) break; /* overflow? */
if (AC & 0400000) {
AC = AC ^ 0777777; /* AC'IO = |AC'IO| */
IO = IO ^ 0777777;
}
v = ABS (M[MA]); /* v = |divr| */
if (AC >= v) break; /* overflow? */
for (i = t = 0; i < 18; i++) {
if (t) AC = (AC + v) & 0777777;
else AC = (AC - v) & 0777777;

53
PDP1/pdp1_diag.txt Normal file
View file

@ -0,0 +1,53 @@
MAINDEC 1 Instruction Test
sim> att -e ptr digital-1-12-m-rim.bin
sim> boot ptr
HALT instruction, PC: 000002 (JMP 3000)
sim> c
(Test runs until interrupted unless there are errors)
^E
Simulation stopped, PC: 000007 (SZS2 I)
sim> d ss 77
sim> run 32
(Test runs until interrupted unless there are errors)
^E
Simulation stopped, PC: 000032 (SZS1)
sim> d tw 777777
sim> d ss 0
sim> run 7772
Undefined instruction, PC: 000001 (SZS1)
sim> ex ac,io,pf
AC: 000777
IO: 777000
PF: 77
(These are the expected final values for the diagnostic)
MAINDEC 4 Multiply/Divide Test
sim> att -e ptr maindec-4_4-16-68.bin
sim> break 0
sim> boot ptr
Breakpoint, PC: 000000 (JMP 532)
sim> set cpu mdv
sim> c
(Test runs until interrupted unless there are errors)
^E
Simulation stopped, PC: ...
sim> set cpu nomdv
sim> run 1
(Test runs until interrupted unless there are errors)
^E
Simulation stopped, PC: ...

View file

@ -1,6 +1,6 @@
/* pdp1_dt.c: 18b DECtape simulator
Copyright (c) 1993-2005, Robert M Supnik
Copyright (c) 1993-2006, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,8 @@
dt Type 550/555 DECtape
23-Jun-06 RMS Fixed conflict in ATTACH switches
Revised header format
16-Aug-05 RMS Fixed C++ declaration and cast problems
25-Jan-04 RMS Revised for device debug support
09-Jan-04 RMS Changed sim_fsize calling sequence, added STOP_OFFR
@ -60,9 +62,7 @@
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
standard block length of 256 words; the PDP-8 uses a standard block length
of 86 words (x 18b = 129 words x 12b). [A PDP-1/4/7 DECtape has only four 18b
header words; for consistency, the PDP-1/4/7 uses the same format as the PDP-9/15
but skips the missing header words.]
of 86 words (x 18b = 129 words x 12b).
Because a DECtape file only contains data, the simulator cannot support
write timing and mark track and can only do a limited implementation
@ -82,8 +82,7 @@
Write all writes only the data words and dumps the interblock words in the
bit bucket.
The Type 550 controller has a 4b unit select field, for units 1-8; the TC02
has a 3b unit select field, with unit 8 being represented as 0. The code
The Type 550 controller has a 4b unit select field, for units 1-8. The code
assumes that the GETUNIT macro returns a unit number in the range of 0-7,
with 8 represented as 0, and an invalid unit as -1.
*/
@ -769,8 +768,10 @@ switch (fnc) { /* at speed, check fnc *
else {
ma = (2 * DT_HTWRD) + DTU_BSIZE (uptr) - DT_CSMWD - 1;
wrd = relpos / DT_WSIZE; /* hdr start = wd 0 */
#if defined (OLD_TYPE550)
if ((wrd == 0) || /* skip 1st, last */
(wrd == ((2 * DT_HTWRD) + DTU_BSIZE (uptr) - 1))) break;
#endif
if ((fnc == FNC_READ) && /* read, skip if not */
(wrd != DT_CSMWD) && /* fwd, rev cksum */
(wrd != ma)) break;
@ -804,8 +805,10 @@ switch (fnc) { /* at speed, check fnc *
}
else {
wrd = relpos / DT_WSIZE; /* hdr start = wd 0 */
#if defined (OLD_TYPE550)
if ((wrd == 0) || /* skip 1st, last */
(wrd == ((2 * DT_HTWRD) + DTU_BSIZE (uptr) - 1))) break;
#endif
if ((fnc == FNC_WRIT) && /* wr, skip if !csm */
(wrd != ((2 * DT_HTWRD) + DTU_BSIZE (uptr) - DT_CSMWD - 1)))
break;
@ -958,11 +961,11 @@ r = attach_unit (uptr, cptr); /* attach */
if (r != SCPE_OK) return r; /* error? */
if ((sim_switches & SIM_SW_REST) == 0) { /* not from rest? */
uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT); /* default 18b */
if (sim_switches & SWMASK ('R')) /* att 12b? */
if (sim_switches & SWMASK ('T')) /* att 12b? */
uptr->flags = uptr->flags | UNIT_8FMT;
else if (sim_switches & SWMASK ('S')) /* att 16b? */
uptr->flags = uptr->flags | UNIT_11FMT;
else if (!(sim_switches & SWMASK ('T')) && /* autosize? */
else if (!(sim_switches & SWMASK ('A')) && /* autosize? */
(sz = sim_fsize (uptr->fileref))) {
if (sz == D8_FILSIZ)
uptr->flags = uptr->flags | UNIT_8FMT;

View file

@ -388,6 +388,10 @@ if (sw & SWMASK ('A')) { /* ASCII? */
fprintf (of, FMTASC (inst & 0177));
return SCPE_OK;
}
if (sw & SWMASK ('F')) {
fputc (fiodec_to_ascii[inst & 077], of);
return SCPE_OK;
}
if (sw & SWMASK ('C')) { /* character? */
fprintf (of, "%c", SIXTOASC ((inst >> 12) & 077));
fprintf (of, "%c", SIXTOASC ((inst >> 6) & 077));

View file

@ -25,6 +25,8 @@
This module simulates the PDP-11 commercial instruction set (CIS).
30-May-06 RMS Added interrupt tests to character instructions
Added 11/44 stack probe test to MOVCx (only)
22-May-06 RMS Fixed bug in decode table (found by John Dundas)
Fixed bug in ASHP (reported by John Dundas)
Fixed bug in write decimal string with mmgt enabled
@ -91,6 +93,10 @@
#define PACKED 0020 /* packed */
#define NUMERIC 0000 /* numeric */
/* Interrupt test latency */
#define INT_TEST 100
/* Operand type definitions */
#define R0_DESC 1 /* descr in R0:R1 */
@ -99,7 +105,6 @@
#define R4_ARG 4 /* argument in R4 */
#define IN_DESC 5 /* inline descriptor */
#define IN_ARG 6 /* inline argument */
#define IN_DESC_R0 7 /* inline descr to R0:R1 */
#define MAXOPN 4 /* max # operands */
/* Decimal data type definitions */
@ -166,12 +171,12 @@ typedef struct {
static DSTR Dstr0 = { 0, 0, 0, 0, 0 };
extern int32 isenable, dsenable;
extern int32 N, Z, V, C;
extern int32 N, Z, V, C, fpd, ipl;
extern int32 R[8], trap_req;
extern int32 ReadW (int32 addr);
extern void WriteW (int32 data, int32 addr);
extern int32 ReadB (int32 addr);
extern void WriteB (int32 data, int32 addr);
extern int32 sim_interval;
extern uint32 cpu_type;
extern FILE *sim_deb;
int32 ReadDstr (int32 *dscr, DSTR *dec, int32 flag);
void WriteDstr (int32 *dscr, DSTR *dec, int32 flag);
int32 AddDstr (DSTR *src1, DSTR *src2, DSTR *dst, int32 cin);
@ -184,6 +189,16 @@ uint32 NibbleRshift (DSTR *dsrc, int32 sc, uint32 cin);
int32 WordLshift (DSTR *dsrc, int32 sc);
void WordRshift (DSTR *dsrc, int32 sc);
void CreateTable (DSTR *dsrc, DSTR mtable[10]);
t_bool cis_int_test (int32 cycles, int32 oldpc, t_stat *st);
int32 movx_setup (int32 op, int32 *arg);
void movx_cleanup (int32 op);
extern int32 ReadW (int32 addr);
extern void WriteW (int32 data, int32 addr);
extern int32 ReadB (int32 addr);
extern int32 ReadMB (int32 addr);
extern void WriteB (int32 data, int32 addr);
extern int32 calc_ints (int32 nipl, int32 trq);
/* Table of instruction operands */
@ -200,18 +215,18 @@ static int32 opntab[128][MAXOPN] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
R0_DESC, R2_DESC, R4_ARG, 0, /* MOVC */
R0_DESC, R2_DESC, R4_ARG, 0, /* MOVRC */
R0_DESC, R2_DESC, R4_DESC, 0, /* MOVTC */
0, 0, 0, 0, /* MOVC */
0, 0, 0, 0, /* MOVRC */
0, 0, 0, 0, /* MOVTC */
0, 0, 0, 0, /* 033 */
0, 0, 0, 0, 0, 0, 0, 0, /* 034 - 037 */
0, 0, 0, 0, 0, 0, 0, 0,
R4_ARG, 0, 0, 0, /* LOCC */
R4_ARG, 0, 0, 0, /* SKPC */
R4_DESC, 0, 0, 0, /* SCANC */
R4_DESC, 0, 0, 0, /* SPANC */
R0_DESC, R2_DESC, R4_ARG, 0, /* CMPC */
R2_DESC, 0, 0, 0, /* MATC */
0, 0, 0, 0, /* LOCC */
0, 0, 0, 0, /* SKPC */
0, 0, 0, 0, /* SCANC */
0, 0, 0, 0, /* SPANC */
0, 0, 0, 0, /* CMPC */
0, 0, 0, 0, /* MATC */
0, 0, 0, 0, 0, 0, 0, 0, /* 046 - 047 */
R0_DESC, R2_DESC, R4_DESC, 0, /* ADDN */
R0_DESC, R2_DESC, R4_DESC, 0, /* SUBN */
@ -251,12 +266,12 @@ static int32 opntab[128][MAXOPN] = {
0, 0, 0, 0, /* 133 */
0, 0, 0, 0, 0, 0, 0, 0, /* 134 - 137 */
0, 0, 0, 0, 0, 0, 0, 0,
IN_DESC_R0, IN_ARG, 0, 0, /* LOCCI */
IN_DESC_R0, IN_ARG, 0, 0, /* SKPCI */
IN_DESC_R0, IN_DESC, 0, 0, /* SCANCI */
IN_DESC_R0, IN_DESC, 0, 0, /* SPANCI */
IN_DESC, IN_ARG, 0, 0, /* LOCCI */
IN_DESC, IN_ARG, 0, 0, /* SKPCI */
IN_DESC, IN_DESC, 0, 0, /* SCANCI */
IN_DESC, IN_DESC, 0, 0, /* SPANCI */
IN_DESC, IN_DESC, IN_ARG, 0, /* CMPCI */
IN_DESC_R0, IN_DESC, 0, 0, /* MATCI */
IN_DESC, IN_DESC, 0, 0, /* MATCI */
0, 0, 0, 0, 0, 0, 0, 0, /* 146 - 147 */
IN_DESC, IN_DESC, IN_DESC, 0, /* ADDNI */
IN_DESC, IN_DESC, IN_DESC, 0, /* SUBNI */
@ -314,17 +329,20 @@ static unsigned char movbuf[65536];
/* CIS emulator */
void cis11 (int32 IR)
t_stat cis11 (int32 IR)
{
int32 c, i, j, k, t, op, rn, addr;
int32 fill, mask, match, limit, mvlnt, shift;
int32 c, i, j, t, op, rn, addr;
int32 match, limit, mvlnt, shift;
int32 spc, ldivd, ldivr;
int32 arg[6]; /* operands */
int32 old_PC;
uint32 nc, digit, result;
t_stat st;
static DSTR accum, src1, src2, dst;
static DSTR mptable[10];
static DSTR Dstr1 = { 0, 0x10, 0, 0, 0 };
old_PC = (PC - 2) & 0177777; /* original PC */
op = IR & 0177; /* IR <6:0> */
for (i = j = 0; (i < MAXOPN) && opntab[op][i]; i++) { /* parse operands */
switch (opntab[op][i]) { /* case on op type */
@ -355,28 +373,29 @@ for (i = j = 0; (i < MAXOPN) && opntab[op][i]; i++) { /* parse operands */
arg[j++] = ReadW (((addr + 2) & 0177777) | dsenable);
break;
case IN_DESC_R0:
addr = ReadW (PC | isenable);
PC = (PC + 2) & 0177777;
R[0] = ReadW (addr | dsenable);
R[1] = ReadW (((addr + 2) & 0177777) | dsenable);
break;
case IN_ARG:
arg[j++] = ReadW (PC | isenable);
PC = (PC + 2) & 0177777;
break;
default:
return SCPE_IERR;
} /* end case */
} /* end for */
switch (op) { /* case on opcode */
/* MOVC, MOVTC, MOVCI, MOVTCI
Operands:
Operands (MOVC, MOVTC):
R0, R1 = source string descriptor
R2, R3 = dest string descriptor
R4<7:0> = fill character
R5 = translation table address (MOVTC only)
Operands (MOVCI, MOVTCI):
A1LNT, A1ADR = source string descriptor
A2LNT, A2ADR = dest string descriptor
A3LNT<7:0> = fill character
A3ADR = translation table address (MOVTC, MOVTCI only)
A3ADR = translation table address (MOVTCI only)
Condition codes:
NZVC = set from src.lnt - dst.lnt
@ -387,9 +406,6 @@ switch (op) { /* case on opcode */
R4:R5 = unchanged
Notes:
- To avoid overlap problems, the entire source string is
buffered in movbuf. On a modern microprocessor, for most
string sizes, this will be handled in the on chip cache.
- If either the source or destination lengths are zero,
the move loops exit immediately.
- If the source length does not exceed the destination
@ -397,34 +413,66 @@ switch (op) { /* case on opcode */
*/
case 030: case 032: case 0130: case 0132:
mvlnt = (A1LNT < A2LNT)? A1LNT: A2LNT; /* calc move lnt */
for (i = 0; i < mvlnt; i++) {
movbuf[i] = ReadB (((A1ADR + i) & 0177777) | dsenable);
if (!fpd) { /* first time? */
mvlnt = movx_setup (op, arg); /* set up reg */
if (R[1] < R[3]) { /* move backwards? */
R[1] = (R[1] + mvlnt) & 0177777; /* bias addresses */
R[3] = (R[3] + mvlnt) & 0177777;
}
for (i = 0; i < mvlnt; i++) {
t = movbuf[i];
if (op & 2) t = ReadB (((A3ADR + t) & 0177777) | dsenable);
WriteB (t, ((A2ADR + i) & 0177777) | dsenable);
}
fill = A3LNT & 0377; /* do fill, if any */
for (i = mvlnt; i < A2LNT; i++) {
WriteB (fill, ((A2ADR + i) & 0177777) | dsenable);
/* At this point,
R0-R5 = arguments
M[SP] = move length */
if (R[0] && R[2]) { /* move to do? */
if (R[1] < R[3]) { /* backwards? */
for (i = 0; R[0] && R[2]; ) { /* move loop */
t = ReadB (((R[1] - 1) & 0177777) | dsenable);
if (op & 2) t = ReadB (((R[5] + t) & 0177777) | dsenable);
WriteB (t, ((R[3] - 1) & 0177777) | dsenable);
R[0]--;
R[1] = (R[1] - 1) & 0177777;
R[2]--;
R[3] = (R[3] - 1) & 0177777;
if ((++i >= INT_TEST) && R[0] && R[2]) {
if (cis_int_test (i, old_PC, &st)) return st;
i = 0;
}
t = A1LNT - A2LNT; /* src.lnt - dst.lnt */
N = GET_SIGN_W (t); /* set cc's from diff */
Z = GET_Z (t);
V = GET_SIGN_W ((A1LNT ^ A2LNT) & (~A2LNT ^ t));
C = (A1LNT < A2LNT);
if ((op & INLINE) == 0) { /* if reg, set reg */
R[0] = C? 0: t & 0177777;
R[1] = R[2] = R[3] = 0;
R[4] = R[4] & 0377;
} /* end for lnts */
mvlnt = ReadW (SP | dsenable); /* recover mvlnt */
R[3] = (R[3] + mvlnt) & 0177777; /* end of dst str */
} /* end if bkwd */
else { /* forward */
for (i = 0; R[0] && R[2]; ) { /* move loop */
t = ReadB ((R[1] & 0177777) | dsenable);
if (op & 2) t = ReadB (((R[5] + t) & 0177777) | dsenable);
WriteB (t, (R[3] & 0177777) | dsenable);
R[0]--;
R[1] = (R[1] + 1) & 0177777;
R[2]--;
R[3] = (R[3] + 1) & 0177777;
if ((++i >= INT_TEST) && R[0] && R[2]) {
if (cis_int_test (i, old_PC, &st)) return st;
i = 0;
}
return;
} /* end for lnts */
} /* end else fwd */
} /* end if move */
for (i = 0; i < R[2]; i++) {
WriteB (R[4], ((R[3] + i) & 0177777) | dsenable);
}
movx_cleanup (op); /* cleanup */
return SCPE_OK;
/* MOVRC, MOVRCI
Operands:
Operands (MOVC, MOVTC):
R0, R1 = source string descriptor
R2, R3 = dest string descriptor
R4<7:0> = fill character
Operands (MOVCI, MOVTCI):
A1LNT, A1ADR = source string descriptor
A2LNT, A2ADR = dest string descriptor
A3LNT<7:0> = fill character
@ -441,30 +489,58 @@ switch (op) { /* case on opcode */
*/
case 031: case 0131:
mvlnt = (A1LNT < A2LNT)? A1LNT: A2LNT; /* calc move lnt */
addr = A1ADR + A1LNT - mvlnt;
for (i = 0; i < mvlnt; i++) {
movbuf[i] = ReadB (((addr + i) & 0177777) | dsenable);
if (!fpd) { /* first time? */
mvlnt = movx_setup (op, arg); /* set up reg */
R[1] = (R[1] + R[0] - mvlnt) & 0177777; /* eff move start */
R[3] = (R[3] + R[2] - mvlnt) & 0177777;
if (R[1] < R[3]) { /* move backwards? */
R[1] = (R[1] + mvlnt) & 0177777; /* bias addresses */
R[3] = (R[3] + mvlnt) & 0177777;
}
addr = A2ADR + A2LNT - mvlnt;
for (i = 0; i < mvlnt; i++) {
WriteB (movbuf[i], ((addr + i) & 0177777) | dsenable);
}
fill = A3LNT & 0377; /* do fill, if any */
for (i = mvlnt, j = 0; i < A2LNT; i++, j++) {
WriteB (fill, ((A2ADR + j) & 0177777) | dsenable);
/* At this point,
R0-R5 = arguments
M[SP] = move length */
if (R[0] && R[2]) { /* move to do? */
if (R[1] < R[3]) { /* backwards? */
for (i = 0; R[0] && R[2]; ) { /* move loop */
t = ReadB (((R[1] - 1) & 0177777) | dsenable);
WriteB (t, ((R[3] - 1) & 0177777) | dsenable);
R[0]--;
R[1] = (R[1] - 1) & 0177777;
R[2]--;
R[3] = (R[3] - 1) & 0177777;
if ((++i >= INT_TEST) && R[0] && R[2]) {
if (cis_int_test (i, old_PC, &st)) return st;
i = 0;
}
t = A1LNT - A2LNT; /* src.lnt - dst.lnt */
N = GET_SIGN_W (t); /* set cc's from diff */
Z = GET_Z (t);
V = GET_SIGN_W ((A1LNT ^ A2LNT) & (~A2LNT ^ t));
C = (A1LNT < A2LNT);
if ((op & INLINE) == 0) { /* if reg, set reg */
R[0] = C? 0: t & 0177777;
R[1] = R[2] = R[3] = 0;
R[4] = R[4] & 0377;
} /* end for lnts */
} /* end if bkwd */
else { /* forward */
for (i = 0; R[0] && R[2]; ) { /* move loop */
t = ReadB ((R[1] & 0177777) | dsenable);
WriteB (t, (R[3] & 0177777) | dsenable);
R[0]--;
R[1] = (R[1] + 1) & 0177777;
R[2]--;
R[3] = (R[3] + 1) & 0177777;
if ((++i >= INT_TEST) && R[0] && R[2]) {
if (cis_int_test (i, old_PC, &st)) return st;
i = 0;
}
return;
} /* end for lnts */
mvlnt = ReadW (SP | dsenable); /* recover mvlnt */
R[3] = (R[3] - mvlnt) & 0177777; /* start of dst str */
} /* end else fwd */
} /* end if move */
for (i = 0; i < R[2]; i++) {
WriteB (R[4], ((R[3] - R[2] + i) & 0177777) | dsenable);
}
movx_cleanup (op); /* cleanup */
return SCPE_OK;
/* Load descriptors - no operands */
@ -482,13 +558,16 @@ switch (op) { /* case on opcode */
R[j + 1] = ReadW (((addr + 2) & 0177777) | dsenable);
}
if (rn >= limit) R[rn] = (R[rn] + limit) & 0177777;
return;
return SCPE_OK;
/* LOCC, SKPC, LOCCI, SKPCI
Operands:
Operands (LOCC, SKPC):
R0, R1 = source string descriptor
A1LNT<7:0> = match character
R4<7:0> = match character
Operands (LOCCI, SKPCI):
A1LNT, A1ADR = source string descriptor
A2LNT<7:0> = match character
Condition codes:
NZ = set from R0
@ -498,25 +577,47 @@ switch (op) { /* case on opcode */
R0:R1 = substring descriptor where operation terminated
*/
case 040: case 041: case 0140: case 0141:
match = A1LNT & 0377; /* match character */
for ( ; R[0] != 0; R[0]--) { /* loop */
case 0140: case 0141: /* inline */
if (!fpd) { /* FPD clear? */
WriteW (R[4], ((SP - 2) & 0177777) | dsenable);
SP = (SP - 2) & 0177777; /* push R4 */
R[0] = A1LNT; /* args to registers */
R[1] = A1ADR;
R[4] = A2LNT;
} /* fall through */
case 040: case 041: /* register */
fpd = 1; /* set FPD */
R[4] = R[4] & 0377; /* match character */
for (i = 0; R[0] != 0;) { /* loop */
c = ReadB (R[1] | dsenable); /* get char */
if ((c == match) ^ (op & 1)) break; /* = + LOC, != + SKP? */
R[1] = (R[1] + 1) & 0177777;
if ((c == R[4]) ^ (op & 1)) break; /* = + LOC, != + SKP? */
R[0]--; /* decr count, */
R[1] = (R[1] + 1) & 0177777; /* incr addr */
if ((++i >= INT_TEST) && R[0]) { /* test for intr? */
if (cis_int_test (i, old_PC, &st)) return st;
i = 0;
}
}
N = GET_SIGN_W (R[0]);
Z = GET_Z (R[0]);
V = C = 0;
if ((op & INLINE) == 0) R[4] = R[4] & 0377; /* if reg, set reg */
return;
fpd = 0; /* instr done */
if (op & INLINE) { /* inline? */
R[4] = ReadW (SP | dsenable); /* restore R4 */
SP = (SP + 2) & 0177777;
}
return SCPE_OK;
/* SCANC, SPANC, SCANCI, SPANCI
Operands:
Operands (SCANC, SPANC):
R0, R1 = source string descriptor
A1LNT<7:0> = mask
A1ADR = table address
R4<7:0> = mask
R5 = table address
Operands (SCANCI, SPANCI):
A1LNT, A1ADR = source string descriptor
A2LNT<7:0> = match character
A2ADR = table address
Condition codes:
NZ = set from R0
@ -526,23 +627,48 @@ switch (op) { /* case on opcode */
R0:R1 = substring descriptor where operation terminated
*/
case 042: case 043: case 0142: case 0143:
mask = A1LNT & 0377; /* mask character */
for (; R[0] != 0; R[0]--) { /* loop */
case 0142: case 0143: /* inline */
if (!fpd) { /* FPD clear? */
WriteW (R[4], ((SP - 4) & 0177777) | dsenable);
WriteW (R[5], ((SP - 2) & 0177777) | dsenable);
SP = (SP - 4) & 0177777; /* push R4, R5 */
R[0] = A1LNT; /* args to registers */
R[1] = A1ADR;
R[4] = A2LNT;
R[5] = A2ADR;
} /* fall through */
case 042: case 043: /* register */
fpd = 1; /* set FPD */
R[4] = R[4] & 0377; /* match character */
for (i = 0; R[0] != 0;) { /* loop */
t = ReadB (R[1] | dsenable); /* get char as index */
c = ReadB (((A1ADR + t) & 0177777) | dsenable);
if (((c & mask) != 0) ^ (op & 1)) break; /* != + SCN, = + SPN? */
R[1] = (R[1] + 1) & 0177777;
c = ReadB (((R[5] + t) & 0177777) | dsenable);
if (((c & R[4]) != 0) ^ (op & 1)) break; /* != + SCN, = + SPN? */
R[0]--; /* decr count, */
R[1] = (R[1] + 1) & 0177777; /* incr addr */
if ((++i >= INT_TEST) && R[0]) { /* test for intr? */
if (cis_int_test (i, old_PC, &st)) return st;
i = 0;
}
}
N = GET_SIGN_W (R[0]);
Z = GET_Z (R[0]);
V = C = 0;
if ((op & INLINE) == 0) R[4] = R[4] & 0377; /* if reg, set reg */
return;
fpd = 0; /* instr done */
if (op & INLINE) { /* inline? */
R[4] = ReadW (SP | dsenable); /* restore R4, R5 */
R[5] = ReadW (((SP + 2) & 0177777) | dsenable);
SP = (SP + 4) & 0177777;
}
return SCPE_OK;
/* CMPC, CMPCI
Operands:
Operands (CMPC):
R0, R1 = source1 string descriptor
R2, R3 = source2 string descriptor
R4<7:0> = fill character
Operands (CMPCI):
A1LNT, A1ADR = source1 string descriptor
A2LNT, A2ADR = source2 string descriptor
A3LNT<7:0> = fill character
@ -556,36 +682,67 @@ switch (op) { /* case on opcode */
R2:R3 = unmatched source2 substring descriptor
*/
case 044: case 0144:
case 0144: /* inline */
if (!fpd) { /* FPD clear? */
WriteW (R[0], ((SP - 10) & 0177777) | dsenable);
WriteW (R[1], ((SP - 8) & 0177777) | dsenable);
WriteW (R[2], ((SP - 6) & 0177777) | dsenable);
WriteW (R[3], ((SP - 4) & 0177777) | dsenable);
WriteW (R[4], ((SP - 2) & 0177777) | dsenable);
SP = (SP - 10) & 0177777; /* push R0 - R4 */
R[0] = A1LNT; /* args to registers */
R[1] = A1ADR;
R[2] = A2LNT;
R[3] = A2ADR;
R[4] = A3LNT;
} /* fall through */
case 044: /* register */
fpd = 1; /* set FPD */
R[4] = R[4] & 0377; /* mask fill */
c = t = 0;
for (i = 0; i < ((A1LNT > A2LNT)? A1LNT: A2LNT); i++) {
if (i < A1LNT) c = ReadB (((A1ADR + i) & 0177777) | dsenable);
else c = A3LNT & 0377;
if (i < A2LNT) t = ReadB (((A2ADR + i) & 0177777) | dsenable);
else t = A3LNT & 0377;
if (c != t) break;
for (i = 0; (R[0] || R[2]); ) { /* until cnts == 0 */
if (R[0]) c = ReadB (R[1] | dsenable); /* get src1 or fill */
else c = R[4];
if (R[2]) t = ReadB (R[3] | dsenable); /* get src2 or fill */
else t = R[4];
if (c != t) break; /* if diff, done */
if (R[0]) { /* if more src1 */
R[0]--; /* decr count, */
R[1] = (R[1] + 1) & 0177777; /* incr addr */
}
if (R[2]) { /* if more src2 */
R[2]--; /* decr count, */
R[3] = (R[3] + 1) & 0177777; /* incr addr */
}
if ((++i >= INT_TEST) && (R[0] || R[2])) { /* test for intr? */
if (cis_int_test (i, old_PC, &st)) return st;
i = 0;
}
}
j = c - t; /* last chars read */
N = GET_SIGN_B (j); /* set cc's */
Z = GET_Z (j);
V = GET_SIGN_B ((c ^ t) & (~t ^ j));
C = (c < t);
if ((op & INLINE) == 0) { /* if reg, set reg */
j = (i > A1LNT)? A1LNT: i; /* #src1 chars used */
k = (i > A2LNT)? A2LNT: i; /* #src2 chars used */
R[0] = A1LNT - j;
R[1] = (A1ADR + j) & 0177777;
R[2] = A2LNT - k;
R[3] = (A2ADR + k) & 0177777;
R[4] = R[4] & 0377;
fpd = 0; /* instr done */
if (op & INLINE) { /* inline? */
R[0] = ReadW (SP | dsenable); /* restore R0 - R4 */
R[1] = ReadW (((SP + 2) & 0177777) | dsenable);
R[2] = ReadW (((SP + 4) & 0177777) | dsenable);
R[3] = ReadW (((SP + 6) & 0177777) | dsenable);
R[4] = ReadW (((SP + 8) & 0177777) | dsenable);
SP = (SP + 10) & 0177777;
}
return;
return SCPE_OK;
/* MATC, MATCI
Operands:
Operands (MATC):
R0, R1 = source string descriptor
A1LNT, A1ADR = substring descriptor
R2, R3 = substring descriptor
Operands (MATCI):
A1LNT, A1ADR = source1 string descriptor
A2LNT, A2ADR = source2 string descriptor
Condition codes:
NZ = set from R0
@ -606,15 +763,28 @@ switch (op) { /* case on opcode */
is the length of the string (zero), or "no match"
*/
case 0045: case 0145:
for (match = 0; R[0] >= A1LNT; R[0]--) { /* loop thru string */
for (i = 0, match = 1; match && (i < A1LNT); i++) {
case 0145: /* inline */
if (!fpd) { /* FPD clear? */
WriteW (R[2], ((SP - 4) & 0177777) | dsenable);
WriteW (R[3], ((SP - 2) & 0177777) | dsenable);
SP = (SP - 4) & 0177777; /* push R2, R3 */
R[0] = A1LNT; /* args to registers */
R[1] = A1ADR;
R[2] = A2LNT;
R[3] = A2ADR;
} /* fall through */
case 0045: /* register */
fpd = 1;
for (match = 0; R[0] >= R[2]; ) { /* loop thru string */
for (i = 0, match = 1; match && (i < R[2]); i++) {
c = ReadB (((R[1] + i) & 0177777) | dsenable);
t = ReadB (((A1ADR + i) & 0177777) | dsenable);
t = ReadB (((R[3] + i) & 0177777) | dsenable);
match = (c == t); /* end for substring */
}
if (match) break; /* exit if match */
R[1] = (R[1] + 1) & 0177777; /* end for string */
R[0]--; /* on to next char */
R[1] = (R[1] + 1) & 0177777;
if (cis_int_test (i, old_PC, &st)) return st;
}
if (!match) { /* if no match */
R[1] = (R[1] + R[0]) & 0177777;
@ -623,7 +793,13 @@ switch (op) { /* case on opcode */
N = GET_SIGN_W (R[0]);
Z = GET_Z (R[0]);
V = C = 0;
return;
fpd = 0; /* instr done */
if (op & INLINE) { /* inline? */
R[2] = ReadW (SP | dsenable); /* restore R2, R3 */
R[3] = ReadW (((SP + 2) & 0177777) | dsenable);
SP = (SP + 4) & 0177777;
}
return SCPE_OK;
/* ADDN, SUBN, ADDP, SUBP, ADDNI, SUBNI, ADDPI, SUBPI
@ -664,7 +840,7 @@ switch (op) { /* case on opcode */
WriteDstr (A3, &dst, op); /* store result */
if ((op & INLINE) == 0) /* if reg, clr reg */
R[0] = R[1] = R[2] = R[3] = 0;
return;
return SCPE_OK;
/* MULP, MULPI
@ -702,7 +878,7 @@ switch (op) { /* case on opcode */
WriteDstr (A3, &dst, op); /* store result */
if ((op & INLINE) == 0) /* if reg, clr reg */
R[0] = R[1] = R[2] = R[3] = 0;
return;
return SCPE_OK;
/* DIVP, DIVPI
@ -723,7 +899,7 @@ switch (op) { /* case on opcode */
ldivr = ReadDstr (A1, &src1, op); /* get divisor */
if (ldivr == 0) { /* divisor = 0? */
V = C = 1; /* set cc's */
return;
return SCPE_OK;
}
ldivr = LntDstr (&src1, ldivr); /* get exact length */
ldivd = ReadDstr (A2, &src2, op); /* get dividend */
@ -752,7 +928,7 @@ switch (op) { /* case on opcode */
WriteDstr (A3, &dst, op); /* store result */
if ((op & INLINE) == 0) /* if reg, clr reg */
R[0] = R[1] = R[2] = R[3] = 0;
return;
return SCPE_OK;
/* CMPN, CMPP, CMPNI, CMPPI
@ -781,7 +957,7 @@ switch (op) { /* case on opcode */
}
if ((op & INLINE) == 0) /* if reg, clr reg */
R[0] = R[1] = R[2] = R[3] = 0;
return;
return SCPE_OK;
/* ASHN, ASHP, ASHNI, ASHPI
@ -819,7 +995,7 @@ switch (op) { /* case on opcode */
WriteDstr (A2, &src1, op); /* store result */
if ((op & INLINE) == 0) /* if reg, clr reg */
R[0] = R[1] = R[4] = 0;
return;
return SCPE_OK;
/* CVTPN, CVTPNI
@ -840,7 +1016,7 @@ switch (op) { /* case on opcode */
V = C = 0; /* init cc's */
WriteDstr (A2, &src1, NUMERIC); /* write dest */
if ((op & INLINE) == 0) R[0] = R[1] = 0; /* if reg, clr reg */
return;
return SCPE_OK;
/* CVTNP, CVTNPI
@ -861,7 +1037,7 @@ switch (op) { /* case on opcode */
V = C = 0; /* init cc's */
WriteDstr (A2, &src1, PACKED); /* write dest */
if ((op & INLINE) == 0) R[0] = R[1] = 0; /* if reg, clr reg */
return;
return SCPE_OK;
/* CVTNL, CVTPL, CVTNLI, CVTPLI
@ -904,7 +1080,7 @@ switch (op) { /* case on opcode */
R[2] = (result >> 16) & 0177777;
R[3] = result & 0177777;
}
return;
return SCPE_OK;
/* CVTLN, CVTLP, CVTLNI, CVTLPI
@ -937,13 +1113,13 @@ switch (op) { /* case on opcode */
}
V = C = 0;
WriteDstr (A1, &dst, op); /* write result */
return;
return SCPE_OK;
default:
setTRAP (TRAP_ILL);
break;
} /* end case */
return;
return SCPE_OK;
} /* end cis */
/* Get decimal string
@ -1323,3 +1499,87 @@ if (s = sc * 4) {
}
return 0;
}
/* Common setup routine for MOVC class instructions */
int32 movx_setup (int32 op, int32 *arg)
{
int32 mvlnt, t;
if (CPUT (CPUT_44)) { /* 11/44? */
ReadMB (((SP - 0200) & 0177777) | dsenable); /* probe both blocks */
ReadMB (((SP - 0100) & 0177777) | dsenable); /* in 64W stack area */
}
if (op & INLINE) { /* inline */
mvlnt = (A1LNT < A2LNT)? A1LNT: A2LNT;
WriteW (mvlnt, ((SP - 14) & 0177777) | dsenable); /* push move length */
WriteW (R[0], ((SP - 12) & 0177777) | dsenable); /* push R0 - R5 */
WriteW (R[1], ((SP - 10) & 0177777) | dsenable);
WriteW (R[2], ((SP - 8) & 0177777) | dsenable);
WriteW (R[3], ((SP - 6) & 0177777) | dsenable);
WriteW (R[4], ((SP - 4) & 0177777) | dsenable);
WriteW (R[5], ((SP - 2) & 0177777) | dsenable);
SP = (SP - 14) & 0177777;
R[0] = A1LNT; /* args to registers */
R[1] = A1ADR;
R[2] = A2LNT;
R[3] = A2ADR;
R[4] = A3LNT;
R[5] = A3ADR & 0177777;
}
else { /* register */
mvlnt = (R[0] < R[2])? R[0]: R[2];
WriteW (mvlnt, ((SP - 2) & 0177777) | dsenable); /* push move length */
SP = (SP - 2) & 0177777;
}
fpd = 1;
t = R[0] - R[2]; /* src.lnt - dst.lnt */
N = GET_SIGN_W (t); /* set cc's from diff */
Z = GET_Z (t);
V = GET_SIGN_W ((R[0] ^ R[2]) & (~R[2] ^ t));
C = (R[0] < R[2]);
return mvlnt;
}
/* Common cleanup routine for MOVC class instructions */
void movx_cleanup (int32 op)
{
SP = (SP + 2) & 0177777; /* discard mvlnt */
if (op & INLINE) { /* inline? */
R[0] = ReadW (SP | dsenable); /* restore R0 - R5 */
R[1] = ReadW (((SP + 2) & 0177777) | dsenable);
R[2] = ReadW (((SP + 4) & 0177777) | dsenable);
R[3] = ReadW (((SP + 6) & 0177777) | dsenable);
R[4] = ReadW (((SP + 8) & 0177777) | dsenable);
R[5] = ReadW (((SP + 10) & 0177777) | dsenable);
SP = (SP + 12) & 0177777;
}
else R[1] = R[2] = R[3] = 0; /* reg, clear R1 - R3 */
fpd = 0; /* instr done */
return;
}
/* Test for CIS mid-instruction interrupt - stub for now */
t_bool cis_int_test (int32 cycles, int32 oldpc, t_stat *st)
{
while (cycles >= 0) { /* until delay done */
if (sim_interval > cycles) { /* event > delay */
sim_interval = sim_interval - cycles;
break;
}
else { /* event <= delay */
cycles = cycles - sim_interval; /* decr delay */
sim_interval = 0; /* process event */
*st = sim_process_event ();
trap_req = calc_ints (ipl, trap_req); /* recalc int req */
if ((*st != SCPE_OK) || /* bad status or */
trap_req & TRAP_INT) { /* interrupt? */
PC = oldpc; /* back out */
return TRUE;
} /* end if stop */
} /* end else event */
} /* end while delay */
return FALSE;
}

View file

@ -336,7 +336,7 @@ void put_PSW (int32 val, t_bool prot);
void put_PIRQ (int32 val);
extern void fp11 (int32 IR);
extern void cis11 (int32 IR);
extern t_stat cis11 (int32 IR);
extern t_stat fis11 (int32 IR);
extern t_stat build_dib_tab (void);
extern t_stat show_iospace (FILE *st, UNIT *uptr, int32 val, void *desc);
@ -1549,7 +1549,8 @@ while (reason == 0) {
ReadE (PC | isenable); /* read immediate */
PC = (PC + 2) & 0177777;
}
else if (CPUO (OPT_CIS)) cis11 (IR);
else if (CPUO (OPT_CIS)) /* CIS option? */
reason = cis11 (IR);
else setTRAP (TRAP_ILL);
break;

View file

@ -26,6 +26,8 @@
The author gratefully acknowledges the help of Max Burnet, Megan Gentry,
and John Wilson in resolving questions about the PDP-11
06-Jul-06 RMS Added multiple KL11/DL11 support
26-Jun-06 RMS Added RF11 support
24-May-06 RMS Added 11/44 DR support (from CIS diagnostic)
17-May-06 RMS Added CR11/CD11 support (from John Dundas)
30-Sep-04 RMS Added Massbus support
@ -465,6 +467,7 @@ typedef struct {
#define DZ_MUXES 4 /* max # of DZ muxes */
#define DZ_LINES 8 /* lines per DZ mux */
#define VH_MUXES 4 /* max # of VH muxes */
#define TTX_LINES 16 /* max # of KL11/DL11's */
#define MT_MAXFR (1 << 16) /* magtape max rec */
#define AUTO_LNT 34 /* autoconfig ranks */
#define DIB_MAX 100 /* max DIBs */
@ -548,6 +551,8 @@ typedef struct pdp_dib DIB;
#define IOLN_TQ 004
#define IOBA_XU (IOPAGEBASE + 014510) /* DEUNA/DELUA */
#define IOLN_XU 010
#define IOBA_TTIX (IOPAGEBASE + 016500) /* extra KL11/DL11 */
#define IOLN_TTIX (TTX_LINES * 010)
#define IOBA_RP (IOPAGEBASE + 016700) /* RP/RM */
#define IOLN_RP 054
#define IOBA_CR (IOPAGEBASE + 017160) /* CD/CR/CM */
@ -562,6 +567,8 @@ typedef struct pdp_dib DIB;
#define IOLN_RK 020
#define IOBA_HK (IOPAGEBASE + 017440) /* RK611 */
#define IOLN_HK 040
#define IOBA_RF (IOPAGEBASE + 017460) /* RF11 */
#define IOLN_RF 020
#define IOBA_LPT (IOPAGEBASE + 017514) /* LP11 */
#define IOLN_LPT 004
#define IOBA_CTL (IOPAGEBASE + 017520) /* board ctrl */
@ -623,7 +630,8 @@ typedef struct pdp_dib DIB;
#define INT_V_XQ 12
#define INT_V_XU 13
#define INT_V_TU 14
#define INT_V_PIR5 15
#define INT_V_RF 15
#define INT_V_PIR5 16
#define INT_V_TTI 0 /* BR4 */
#define INT_V_TTO 1
@ -633,7 +641,9 @@ typedef struct pdp_dib DIB;
#define INT_V_VHRX 5
#define INT_V_VHTX 6
#define INT_V_CR 7
#define INT_V_PIR4 8
#define INT_V_TTIX 8
#define INT_V_TTOX 9
#define INT_V_PIR4 10
#define INT_V_PIR3 0 /* BR3 */
#define INT_V_PIR2 0 /* BR2 */
@ -659,6 +669,7 @@ typedef struct pdp_dib DIB;
#define INT_XQ (1u << INT_V_XQ)
#define INT_XU (1u << INT_V_XU)
#define INT_TU (1u << INT_V_TU)
#define INT_RF (1u << INT_V_RF)
#define INT_PIR5 (1u << INT_V_PIR5)
#define INT_PTR (1u << INT_V_PTR)
#define INT_PTP (1u << INT_V_PTP)
@ -668,6 +679,8 @@ typedef struct pdp_dib DIB;
#define INT_VHRX (1u << INT_V_VHRX)
#define INT_VHTX (1u << INT_V_VHTX)
#define INT_CR (1u << INT_V_CR)
#define INT_TTIX (1u << INT_V_TTIX)
#define INT_TTOX (1u << INT_V_TTOX)
#define INT_PIR4 (1u << INT_V_PIR4)
#define INT_PIR3 (1u << INT_V_PIR3)
#define INT_PIR2 (1u << INT_V_PIR2)
@ -691,6 +704,7 @@ typedef struct pdp_dib DIB;
#define IPL_XQ 5
#define IPL_XU 5
#define IPL_TU 5
#define IPL_RF 5
#define IPL_PTR 4
#define IPL_PTP 4
#define IPL_TTI 4
@ -699,6 +713,8 @@ typedef struct pdp_dib DIB;
#define IPL_VHRX 4
#define IPL_VHTX 4
#define IPL_CR 4
#define IPL_TTIX 4
#define IPL_TTOX 4
#define IPL_PIR7 7
#define IPL_PIR6 6
@ -723,6 +739,7 @@ typedef struct pdp_dib DIB;
#define VEC_RQ 0154
#define VEC_RL 0160
#define VEC_LPT 0200
#define VEC_RF 0204
#define VEC_HK 0210
#define VEC_RK 0220
#define VEC_DTA 0214
@ -734,6 +751,8 @@ typedef struct pdp_dib DIB;
#define VEC_TQ 0260
#define VEC_RX 0264
#define VEC_RY 0264
#define VEC_TTIX 0300
#define VEC_TTOX 0304
#define VEC_DZRX 0300
#define VEC_DZTX 0304
#define VEC_VHRX 0310

521
PDP11/pdp11_dl.c Normal file
View file

@ -0,0 +1,521 @@
/* pdp11_dl.c: PDP-11 multiple terminal interface simulator
Copyright (c) 1993-2006, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
ttix,ttox DL11 terminal input/output
*/
#if defined (VM_PDP10) /* PDP10 version */
#error "DL11 is not supported on the PDP-10!"
#elif defined (VM_VAX) /* VAX version */
#error "DL11 is not supported on the VAX!"
#else /* PDP-11 version */
#include "pdp11_defs.h"
#endif
#include "sim_sock.h"
#include "sim_tmxr.h"
#define TTX_MASK (TTX_LINES - 1)
#define TTIXCSR_IMP (CSR_DONE + CSR_IE) /* terminal input */
#define TTIXCSR_RW (CSR_IE)
#define TTIXBUF_ERR 0100000
#define TTIXBUF_OVR 0040000
#define TTIXBUF_RBRK 0020000
#define TTOXCSR_IMP (CSR_DONE + CSR_IE) /* terminal output */
#define TTOXCSR_RW (CSR_IE)
extern int32 int_req[IPL_HLVL];
extern int32 tmxr_poll;
uint16 ttix_csr[TTX_LINES] = { 0 }; /* control/status */
uint16 ttix_buf[TTX_LINES] = { 0 };
uint32 ttix_ireq = 0;
uint16 ttox_csr[TTX_LINES] = { 0 }; /* control/status */
uint8 ttox_buf[TTX_LINES] = { 0 };
uint32 ttox_ireq = 0;
TMLN ttx_ldsc[TTX_LINES] = { 0 }; /* line descriptors */
TMXR ttx_desc = { TTX_LINES, 0, 0, ttx_ldsc }; /* mux descriptor */
t_stat ttx_rd (int32 *data, int32 PA, int32 access);
t_stat ttx_wr (int32 data, int32 PA, int32 access);
t_stat ttx_reset (DEVICE *dptr);
t_stat ttix_svc (UNIT *uptr);
t_stat ttox_svc (UNIT *uptr);
t_stat ttx_attach (UNIT *uptr, char *cptr);
t_stat ttx_detach (UNIT *uptr);
t_stat ttx_summ (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat ttx_show (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat ttx_show_vec (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat ttx_set_lines (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat ttx_show_lines (FILE *st, UNIT *uptr, int32 val, void *desc);
void ttx_enbdis (int32 dis);
void ttix_clr_int (uint32 ln);
void ttix_set_int (int32 ln);
int32 ttix_iack (void);
void ttox_clr_int (int32 ln);
void ttox_set_int (int32 ln);
int32 ttox_iack (void);
void ttx_reset_ln (uint32 ln);
/* TTIX data structures
ttix_dev TTIX device descriptor
ttix_unit TTIX unit descriptor
ttix_reg TTIX register list
*/
DIB ttix_dib = {
IOBA_TTIX, IOLN_TTIX, &ttx_rd, &ttx_wr,
2, IVCL (TTIX), VEC_TTIX, { &ttix_iack, &ttox_iack }
};
UNIT ttix_unit = { UDATA (&ttix_svc, 0, 0), KBD_POLL_WAIT };
REG ttix_reg[] = {
{ BRDATA (BUF, ttix_buf, DEV_RDX, 16, TTX_LINES) },
{ BRDATA (CSR, ttix_csr, DEV_RDX, 16, TTX_LINES) },
{ GRDATA (IREQ, ttix_ireq, DEV_RDX, TTX_LINES, 0) },
{ DRDATA (LINES, ttx_desc.lines, 6), REG_HRO },
{ GRDATA (DEVADDR, ttix_dib.ba, DEV_RDX, 32, 0), REG_HRO },
{ GRDATA (DEVVEC, ttix_dib.vec, DEV_RDX, 16, 0), REG_HRO },
{ NULL }
};
MTAB ttix_mod[] = {
{ UNIT_ATT, UNIT_ATT, "summary", NULL, NULL, &ttx_summ },
{ MTAB_XTD | MTAB_VDV, 1, NULL, "DISCONNECT",
&tmxr_dscln, NULL, &ttx_desc },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL,
NULL, &ttx_show, NULL },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL,
NULL, &ttx_show, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
&set_addr, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
&set_vec, &ttx_show_vec, NULL },
{ MTAB_XTD | MTAB_VDV, 0, "lines", "LINES",
&ttx_set_lines, &ttx_show_lines },
{ 0 }
};
DEVICE ttix_dev = {
"TTIX", &ttix_unit, ttix_reg, ttix_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &ttx_reset,
NULL, &ttx_attach, &ttx_detach,
&ttix_dib, DEV_UBUS | DEV_QBUS | DEV_DISABLE | DEV_DIS
};
/* TTOX data structures
ttox_dev TTOX device descriptor
ttox_unit TTOX unit descriptor
ttox_reg TTOX register list
*/
UNIT ttox_unit[] = {
{ UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT },
{ UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT },
{ UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT },
{ UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT },
{ UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT },
{ UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT },
{ UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT },
{ UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT },
{ UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT },
{ UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT },
{ UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT },
{ UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT },
{ UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT },
{ UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT },
{ UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT },
{ UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT }
};
REG ttox_reg[] = {
{ BRDATA (BUF, ttox_buf, DEV_RDX, 8, TTX_LINES) },
{ BRDATA (CSR, ttox_csr, DEV_RDX, 16, TTX_LINES) },
{ GRDATA (IREQ, ttox_ireq, DEV_RDX, TTX_LINES, 0) },
{ URDATA (TIME, ttox_unit[0].wait, 10, 31, 0,
TTX_LINES, PV_LEFT) },
{ NULL }
};
MTAB ttox_mod[] = {
{ TT_MODE, TT_MODE_UC, "UC", "UC", NULL },
{ TT_MODE, TT_MODE_7B, "7b", "7B", NULL },
{ TT_MODE, TT_MODE_8B, "8b", "8B", NULL },
{ TT_MODE, TT_MODE_7P, "7p", "7P", NULL },
{ MTAB_XTD|MTAB_VUN, 0, NULL, "DISCONNECT",
&tmxr_dscln, NULL, &ttx_desc },
{ MTAB_XTD|MTAB_VUN|MTAB_NC, 0, "LOG", "LOG",
&tmxr_set_log, &tmxr_show_log, &ttx_desc },
{ MTAB_XTD|MTAB_VUN|MTAB_NC, 0, NULL, "NOLOG",
&tmxr_set_nolog, NULL, &ttx_desc },
{ 0 }
};
DEVICE ttox_dev = {
"TTOX", ttox_unit, ttox_reg, ttox_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &ttx_reset,
NULL, NULL, NULL,
NULL, DEV_UBUS | DEV_QBUS | DEV_DISABLE | DEV_DIS
};
/* Terminal input routines */
t_stat ttx_rd (int32 *data, int32 PA, int32 access)
{
uint32 ln = ((PA - ttix_dib.ba) >> 3) & TTX_MASK;
switch ((PA >> 1) & 03) { /* decode PA<2:1> */
case 00: /* tti csr */
*data = ttix_csr[ln] & TTIXCSR_IMP;
return SCPE_OK;
case 01: /* tti buf */
ttix_csr[ln] &= ~CSR_DONE;
ttix_clr_int (ln);
*data = ttix_buf[ln];
return SCPE_OK;
case 02: /* tto csr */
*data = ttox_csr[ln] & TTOXCSR_IMP;
return SCPE_OK;
case 03: /* tto buf */
*data = ttox_buf[ln];
return SCPE_OK;
} /* end switch PA */
return SCPE_NXM;
}
t_stat ttx_wr (int32 data, int32 PA, int32 access)
{
uint32 ln = ((PA - ttix_dib.ba) >> 3) & TTX_MASK;
switch ((PA >> 1) & 03) { /* decode PA<2:1> */
case 00: /* tti csr */
if (PA & 1) return SCPE_OK;
if ((data & CSR_IE) == 0)
ttix_clr_int (ln);
else if ((ttix_csr[ln] & (CSR_DONE + CSR_IE)) == CSR_DONE)
ttix_set_int (ln);
ttix_csr[ln] = (uint16) ((ttix_csr[ln] & ~TTIXCSR_RW) | (data & TTIXCSR_RW));
return SCPE_OK;
case 01: /* tti buf */
return SCPE_OK;
case 02: /* tto csr */
if (PA & 1) return SCPE_OK;
if ((data & CSR_IE) == 0)
ttox_clr_int (ln);
else if ((ttox_csr[ln] & (CSR_DONE + CSR_IE)) == CSR_DONE)
ttox_set_int (ln);
ttox_csr[ln] = (uint16) ((ttox_csr[ln] & ~TTOXCSR_RW) | (data & TTOXCSR_RW));
return SCPE_OK;
case 03: /* tto buf */
if ((PA & 1) == 0)
ttox_buf[ln] = data & 0377;
ttox_csr[ln] &= ~CSR_DONE;
ttox_clr_int (ln);
sim_activate (&ttox_unit[ln], ttox_unit[ln].wait);
return SCPE_OK;
} /* end switch PA */
return SCPE_NXM;
}
/* Terminal input service */
t_stat ttix_svc (UNIT *uptr)
{
int32 ln, c, temp;
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_OK; /* attached? */
sim_activate (uptr, tmxr_poll); /* continue poll */
ln = tmxr_poll_conn (&ttx_desc); /* look for connect */
if (ln >= 0) ttx_ldsc[ln].rcve = 1; /* got one? rcv enb */
tmxr_poll_rx (&ttx_desc); /* poll for input */
for (ln = 0; ln < TTX_LINES; ln++) { /* loop thru lines */
if (ttx_ldsc[ln].conn) { /* connected? */
if (temp = tmxr_getc_ln (&ttx_ldsc[ln])) { /* get char */
if (temp & SCPE_BREAK) /* break? */
c = TTIXBUF_ERR|TTIXBUF_RBRK;
else c = sim_tt_inpcvt (temp, TT_GET_MODE (ttox_unit[ln].flags));
if (ttix_csr[ln] & CSR_DONE)
c |= TTIXBUF_ERR|TTIXBUF_OVR;
else {
ttix_csr[ln] |= CSR_DONE;
if (ttix_csr[ln] & CSR_IE) ttix_set_int (ln);
}
ttix_buf[ln] = c;
}
}
}
return SCPE_OK;
}
/* Terminal output service */
t_stat ttox_svc (UNIT *uptr)
{
int32 c;
uint32 ln = uptr - ttox_unit; /* line # */
if (ttx_ldsc[ln].conn) { /* connected? */
if (ttx_ldsc[ln].xmte) { /* tx enabled? */
TMLN *lp = &ttx_ldsc[ln]; /* get line */
c = sim_tt_outcvt (ttox_buf[ln], TT_GET_MODE (ttox_unit[ln].flags));
if (c >= 0) tmxr_putc_ln (lp, c); /* output char */
tmxr_poll_tx (&ttx_desc); /* poll xmt */
}
else {
tmxr_poll_tx (&ttx_desc); /* poll xmt */
sim_activate (uptr, ttox_unit[ln].wait); /* wait */
return SCPE_OK;
}
}
ttox_csr[ln] |= CSR_DONE; /* set done */
if (ttox_csr[ln] & CSR_IE) ttox_set_int (ln);
return SCPE_OK;
}
/* Interrupt routines */
void ttix_clr_int (uint32 ln)
{
ttix_ireq &= ~(1 << ln); /* clr mux rcv int */
if (ttix_ireq == 0) CLR_INT (TTIX); /* all clr? */
else SET_INT (TTIX); /* no, set intr */
return;
}
void ttix_set_int (int32 ln)
{
ttix_ireq |= (1 << ln); /* clr mux rcv int */
SET_INT (TTIX); /* set master intr */
return;
}
int32 ttix_iack (void)
{
int32 ln;
for (ln = 0; ln < TTX_LINES; ln++) { /* find 1st line */
if (ttix_ireq & (1 << ln)) {
ttix_clr_int (ln); /* clear intr */
return (ttix_dib.vec + (ln * 010)); /* return vector */
}
}
return 0;
}
void ttox_clr_int (int32 ln)
{
ttox_ireq &= ~(1 << ln); /* clr mux rcv int */
if (ttox_ireq == 0) CLR_INT (TTOX); /* all clr? */
else SET_INT (TTOX); /* no, set intr */
return;
}
void ttox_set_int (int32 ln)
{
ttox_ireq |= (1 << ln); /* clr mux rcv int */
SET_INT (TTOX); /* set master intr */
return;
}
int32 ttox_iack (void)
{
int32 ln;
for (ln = 0; ln < TTX_LINES; ln++) { /* find 1st line */
if (ttox_ireq & (1 << ln)) {
ttox_clr_int (ln); /* clear intr */
return (ttix_dib.vec + (ln * 010) + 4); /* return vector */
}
}
return 0;
}
/* Reset */
t_stat ttx_reset (DEVICE *dptr)
{
int32 ln;
ttx_enbdis (dptr->flags & DEV_DIS); /* sync enables */
sim_cancel (&ttix_unit); /* assume stop */
if (ttix_unit.flags & UNIT_ATT) /* if attached, */
sim_activate (&ttix_unit, tmxr_poll); /* activate */
for (ln = 0; ln < TTX_LINES; ln++) /* for all lines */
ttx_reset_ln (ln);
return auto_config (ttix_dev.name, ttx_desc.lines); /* auto config */
}
/* Reset individual line */
void ttx_reset_ln (uint32 ln)
{
ttix_buf[ln] = 0; /* clear buf, */
ttix_csr[ln] = CSR_DONE;
ttox_buf[ln] = 0; /* clear buf */
ttox_csr[ln] = CSR_DONE;
sim_cancel (&ttox_unit[ln]); /* deactivate */
ttix_clr_int (ln);
ttox_clr_int (ln);
return;
}
/* Attach master unit */
t_stat ttx_attach (UNIT *uptr, char *cptr)
{
t_stat r;
r = tmxr_attach (&ttx_desc, uptr, cptr); /* attach */
if (r != SCPE_OK) return r; /* error */
sim_activate (uptr, tmxr_poll); /* start poll */
return SCPE_OK;
}
/* Detach master unit */
t_stat ttx_detach (UNIT *uptr)
{
int32 i;
t_stat r;
r = tmxr_detach (&ttx_desc, uptr); /* detach */
for (i = 0; i < TTX_LINES; i++) /* all lines, */
ttx_ldsc[i].rcve = 0; /* disable rcv */
sim_cancel (uptr); /* stop poll */
return r;
}
/* Show summary processor */
t_stat ttx_summ (FILE *st, UNIT *uptr, int32 val, void *desc)
{
int32 i, t;
for (i = t = 0; i < TTX_LINES; i++) t = t + (ttx_ldsc[i].conn != 0);
if (t == 1) fprintf (st, "1 connection");
else fprintf (st, "%d connections", t);
return SCPE_OK;
}
/* SHOW CONN/STAT processor */
t_stat ttx_show (FILE *st, UNIT *uptr, int32 val, void *desc)
{
int32 i, t;
for (i = t = 0; i < TTX_LINES; i++) t = t + (ttx_ldsc[i].conn != 0);
if (t) {
for (i = 0; i < TTX_LINES; i++) {
if (ttx_ldsc[i].conn) {
if (val) tmxr_fconns (st, &ttx_ldsc[i], i);
else tmxr_fstats (st, &ttx_ldsc[i], i);
}
}
}
else fprintf (st, "all disconnected\n");
return SCPE_OK;
}
/* Enable/disable device */
void ttx_enbdis (int32 dis)
{
if (dis) {
ttix_dev.flags = ttox_dev.flags | DEV_DIS;
ttox_dev.flags = ttox_dev.flags | DEV_DIS;
}
else {
ttix_dev.flags = ttix_dev.flags & ~DEV_DIS;
ttox_dev.flags = ttox_dev.flags & ~DEV_DIS;
}
return;
}
/* SHOW VECTOR processor */
t_stat ttx_show_vec (FILE *st, UNIT *uptr, int32 val, void *desc)
{
return show_vec (st, uptr, ttx_desc.lines * 2, desc);
}
/* Change number of lines */
t_stat ttx_set_lines (UNIT *uptr, int32 val, char *cptr, void *desc)
{
int32 newln, i, t;
t_stat r;
if (cptr == NULL) return SCPE_ARG;
newln = get_uint (cptr, 10, TTX_LINES, &r);
if ((r != SCPE_OK) || (newln == ttx_desc.lines)) return r;
if (newln == 0) return SCPE_ARG;
if (newln < ttx_desc.lines) {
for (i = newln, t = 0; i < ttx_desc.lines; i++) t = t | ttx_ldsc[i].conn;
if (t && !get_yn ("This will disconnect users; proceed [N]?", FALSE))
return SCPE_OK;
for (i = newln; i < ttx_desc.lines; i++) {
if (ttx_ldsc[i].conn) {
tmxr_linemsg (&ttx_ldsc[i], "\r\nOperator disconnected line\r\n");
tmxr_reset_ln (&ttx_ldsc[i]); /* reset line */
}
ttox_unit[i].flags |= UNIT_DIS;
ttx_reset_ln (i);
}
}
else {
for (i = ttx_desc.lines; i < newln; i++) {
ttox_unit[i].flags &= ~UNIT_DIS;
ttx_reset_ln (i);
}
}
ttx_desc.lines = newln;
return auto_config (ttix_dev.name, newln); /* auto config */
}
/* Show number of lines */
t_stat ttx_show_lines (FILE *st, UNIT *uptr, int32 val, void *desc)
{
fprintf (st, "lines=%d", ttx_desc.lines);
return SCPE_OK;
}

View file

@ -1,6 +1,6 @@
/* pdp11_io.c: PDP-11 I/O simulator
Copyright (c) 1993-2005, Robert M Supnik
Copyright (c) 1993-2006, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -23,6 +23,7 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
06-Jul-06 RMS Added multiple KL11/DL11 support
15-Oct-05 RMS Fixed bug in autoconfiguration (missing XU)
25-Jul-05 RMS Revised autoconfiguration algorithm and interface
30-Sep-04 RMS Revised Unibus interface
@ -599,7 +600,7 @@ typedef struct {
} AUTO_CON;
AUTO_CON auto_tab[] = {
{ { NULL }, 1, 2, 0, 8, { 0 } }, /* DLV11J - fx CSRs */
{ { "TTIX" }, TTX_LINES, 2, 0, 8, { 0 } }, /* KL11/DL11/DLV11 - fx CSRs */
{ { NULL }, 1, 2, 8, 8 }, /* DJ11 */
{ { NULL }, 1, 2, 16, 8 }, /* DH11 */
{ { NULL }, 1, 2, 8, 8 }, /* DQ11 */

494
PDP11/pdp11_rf.c Normal file
View file

@ -0,0 +1,494 @@
/* pdp11_rf.c: RF11 fixed head disk simulator
Copyright (c) 2006, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
rf RF11 fixed head disk
26-Jun-06 RMS Cloned from RF08 simulator
The RF11 is a head-per-track disk. To minimize overhead, the entire RF11
is buffered in memory.
Two timing parameters are provided:
rf_time Interword timing, must be non-zero
rf_burst Burst mode, if 0, DMA occurs cycle by cycle; otherwise,
DMA occurs in a burst
*/
#include "pdp11_defs.h"
#include <math.h>
#define UNIT_V_AUTO (UNIT_V_UF + 0) /* autosize */
#define UNIT_V_PLAT (UNIT_V_UF + 1) /* #platters - 1 */
#define UNIT_M_PLAT 03
#define UNIT_GETP(x) ((((x) >> UNIT_V_PLAT) & UNIT_M_PLAT) + 1)
#define UNIT_AUTO (1 << UNIT_V_AUTO)
#define UNIT_PLAT (UNIT_M_PLAT << UNIT_V_PLAT)
/* Constants */
#define RF_NUMWD 2048 /* words/track */
#define RF_NUMTR 128 /* tracks/disk */
#define RF_DKSIZE (RF_NUMTR * RF_NUMWD) /* words/disk */
#define RF_NUMDK 8 /* disks/controller */
#define RF_WMASK (RF_NUMWD - 1) /* word mask */
/* Parameters in the unit descriptor */
#define FUNC u4 /* function */
/* Status register */
#define RFCS_ERR (CSR_ERR) /* error */
#define RFCS_FRZ 0040000 /* error freeze */
#define RFCS_WCHK 0020000 /* write check */
#define RFCS_DPAR 0010000 /* data parity (ni) */
#define RFCS_NED 0004000 /* nx disk */
#define RFCS_WLK 0002000 /* write lock */
#define RFCS_MXFR 0001000 /* missed xfer (ni) */
#define RFCS_CLR 0000400 /* clear */
#define RFCS_DONE (CSR_DONE)
#define RFCS_IE (CSR_IE)
#define RFCS_M_MEX 0000003 /* memory extension */
#define RFCS_V_MEX 4
#define RFCS_MEX (RFCS_M_MEX << RFCS_V_MEX)
#define RFCS_MAINT 0000010 /* maint */
#define RFCS_M_FUNC 0000003 /* function */
#define RFNC_NOP 0
#define RFNC_WRITE 1
#define RFNC_READ 2
#define RFNC_WCHK 3
#define RFCS_V_FUNC 1
#define RFCS_FUNC (RFCS_M_FUNC << RFCS_V_FUNC)
#define RFCS_GO 0000001
#define RFCS_ALLERR (RFCS_FRZ|RFCS_WCHK|RFCS_DPAR|RFCS_NED|RFCS_WLK|RFCS_MXFR)
#define RFCS_W (RFCS_IE|RFCS_MEX|RFCS_FUNC)
/* Current memory address */
#define RFCMA_RW 0177776
/* Address extension */
#define RFDAE_ALLERR 0176000
#define RFDAE_NXM 0002000
#define RFDAE_INH 0000400 /* addr inhibit */
#define RFDAE_RLAT 0000200 /* req late */
#define RFDAE_DAE 0000077 /* extension */
#define RFDAE_R 0176677
#define RFDAE_W 0000677
#define GET_FUNC(x) (((x) >> RFCS_V_FUNC) & RFCS_M_FUNC)
#define GET_MEX(x) (((x) & RFCS_MEX) << (16 - RFCS_V_MEX))
#define GET_DEX(x) (((x) & RFDAE_DAE) << 16)
#define GET_POS(x) ((int) fmod (sim_gtime() / ((double) (x)), \
((double) RF_NUMWD)))
extern uint16 *M;
extern int32 int_req[IPL_HLVL];
extern FILE *sim_deb;
uint32 rf_cs = 0; /* status register */
uint32 rf_cma = 0;
uint32 rf_wc = 0;
uint32 rf_da = 0; /* disk address */
uint32 rf_dae = 0;
uint32 rf_dbr = 0;
uint32 rf_maint = 0;
uint32 rf_wlk = 0; /* write lock */
uint32 rf_time = 10; /* inter-word time */
uint32 rf_burst = 1; /* burst mode flag */
uint32 rf_stopioe = 1; /* stop on error */
DEVICE rf_dev;
t_stat rf_rd (int32 *data, int32 PA, int32 access);
t_stat rf_wr (int32 data, int32 PA, int32 access);
int32 rf_inta (void);
t_stat rf_svc (UNIT *uptr);
t_stat rf_reset (DEVICE *dptr);
t_stat rf_boot (int32 unitno, DEVICE *dptr);
t_stat rf_attach (UNIT *uptr, char *cptr);
t_stat rf_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
uint32 update_rfcs (uint32 newcs, uint32 newdae);
/* RF11 data structures
rf_dev RF device descriptor
rf_unit RF unit descriptor
rf_reg RF register list
*/
DIB rf_dib = {
IOBA_RF, IOLN_RF, &rf_rd, &rf_wr,
1, IVCL (RF), VEC_RF, NULL
};
UNIT rf_unit = {
UDATA (&rf_svc, UNIT_FIX+UNIT_ATTABLE+
UNIT_BUFABLE+UNIT_MUSTBUF, RF_DKSIZE)
};
REG rf_reg[] = {
{ ORDATA (RFCS, rf_cs, 16) },
{ ORDATA (RFWC, rf_wc, 16) },
{ ORDATA (RFCMA, rf_cma, 16) },
{ ORDATA (RFDA, rf_da, 16) },
{ ORDATA (RFDAE, rf_dae, 16) },
{ ORDATA (RFDBR, rf_dbr, 16) },
{ ORDATA (RFMR, rf_maint, 16) },
{ ORDATA (RFWLK, rf_wlk, 32) },
{ FLDATA (INT, IREQ (RF), INT_V_RF) },
{ FLDATA (ERR, rf_cs, CSR_V_ERR) },
{ FLDATA (DONE, rf_cs, CSR_V_DONE) },
{ FLDATA (IE, rf_cs, CSR_V_IE) },
{ DRDATA (TIME, rf_time, 24), REG_NZ + PV_LEFT },
{ FLDATA (BURST, rf_burst, 0) },
{ FLDATA (STOP_IOE, rf_stopioe, 0) },
{ ORDATA (DEVADDR, rf_dib.ba, 32), REG_HRO },
{ ORDATA (DEVVEC, rf_dib.vec, 16), REG_HRO },
{ NULL }
};
MTAB rf_mod[] = {
{ UNIT_PLAT, (0 << UNIT_V_PLAT), NULL, "1P", &rf_set_size },
{ UNIT_PLAT, (1 << UNIT_V_PLAT), NULL, "2P", &rf_set_size },
{ UNIT_PLAT, (2 << UNIT_V_PLAT), NULL, "3P", &rf_set_size },
{ UNIT_PLAT, (3 << UNIT_V_PLAT), NULL, "4P", &rf_set_size },
{ UNIT_PLAT, (4 << UNIT_V_PLAT), NULL, "5P", &rf_set_size },
{ UNIT_PLAT, (5 << UNIT_V_PLAT), NULL, "6P", &rf_set_size },
{ UNIT_PLAT, (6 << UNIT_V_PLAT), NULL, "7P", &rf_set_size },
{ UNIT_PLAT, (7 << UNIT_V_PLAT), NULL, "8P", &rf_set_size },
{ UNIT_AUTO, UNIT_AUTO, "autosize", "AUTOSIZE", NULL },
{ MTAB_XTD|MTAB_VDV, 020, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL },
{ 0 }
};
DEVICE rf_dev = {
"RF", &rf_unit, rf_reg, rf_mod,
1, 8, 21, 1, 8, 16,
NULL, NULL, &rf_reset,
&rf_boot, &rf_attach, NULL,
&rf_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG
};
/* I/O dispatch routine, I/O addresses 17777460 - 17777476 */
t_stat rf_rd (int32 *data, int32 PA, int32 access)
{
switch ((PA >> 1) & 07) { /* decode PA<3:1> */
case 0: /* RFCS */
*data = update_rfcs (0, 0); /* update RFCS */
break;
case 1: /* RFWC */
*data = rf_wc;
break;
case 2: /* RFCMA */
*data = rf_cma & RFCMA_RW;
break;
case 3: /* RFDA */
*data = rf_da;
break;
case 4: /* RFDAE */
*data = rf_dae & RFDAE_R;
break;
case 5: /* RFDBR */
*data = rf_dbr;
break;
case 6: /* RFMR */
*data = rf_maint;
break;
case 7: /* RFADS */
*data = GET_POS (rf_time);
break;
} /* end switch */
return SCPE_OK;
}
t_stat rf_wr (int32 data, int32 PA, int32 access)
{
int32 t, fnc;
switch ((PA >> 1) & 07) { /* decode PA<3:1> */
case 0: /* RFCS */
if (access == WRITEB) data = (PA & 1)?
(rf_cs & 0377) | (data << 8): (rf_cs & ~0377) | data;
if (data & RFCS_CLR) rf_reset (&rf_dev); /* clear? */
if ((data & RFCS_IE) == 0) /* int disable? */
CLR_INT (RF); /* clr int request */
else if ((rf_cs & (RFCS_DONE + RFCS_IE)) == RFCS_DONE)
SET_INT (RF); /* set int request */
rf_cs = (rf_cs & ~RFCS_W) | (data & RFCS_W); /* merge */
if ((rf_cs & RFCS_DONE) && (data & RFCS_GO) && /* new function? */
((fnc = GET_FUNC (rf_cs)) != RFNC_NOP)) {
rf_unit.FUNC = fnc; /* save function */
t = (rf_da & RF_WMASK) - GET_POS (rf_time); /* delta to new loc */
if (t < 0) t = t + RF_NUMWD; /* wrap around? */
sim_activate (&rf_unit, t * rf_time); /* schedule op */
rf_cs &= ~(RFCS_WCHK|RFCS_DPAR|RFCS_NED|RFCS_WLK|RFCS_MXFR|RFCS_DONE);
CLR_INT (RF);
if (DEBUG_PRS (rf_dev))
fprintf (sim_deb, ">>RF start: cs = %o, da = %o, ma = %o\n",
update_rfcs (0, 0), GET_DEX (rf_dae) | rf_da, GET_MEX (rf_cs) | rf_cma);
}
break;
case 1: /* RFWC */
if (access == WRITEB) data = (PA & 1)?
(rf_wc & 0377) | (data << 8): (rf_wc & ~0377) | data;
rf_wc = data;
break;
case 2: /* RFCMA */
if (access == WRITEB) data = (PA & 1)?
(rf_cma & 0377) | (data << 8): (rf_cma & ~0377) | data;
rf_cma = data & RFCMA_RW;
break;
case 3: /* RFDA */
if (access == WRITEB) data = (PA & 1)?
(rf_da & 0377) | (data << 8): (rf_da & ~0377) | data;
rf_da = data;
break;
case 4: /* RFDAE */
if (access == WRITEB) data = (PA & 1)?
(rf_dae & 0377) | (data << 8): (rf_dae & ~0377) | data;
rf_dae = (rf_dae & ~RFDAE_W) | (data & RFDAE_W);
break;
case 5: /* RFDBR */
rf_dbr = data;
break;
case 6: /* RFMR */
rf_maint = data;
break;
case 7: /* RFADS */
break; /* read only */
} /* end switch */
update_rfcs (0, 0);
return SCPE_OK;
}
/* Unit service
Note that for reads and writes, memory addresses wrap around in the
current field. This code assumes the entire disk is buffered.
*/
t_stat rf_svc (UNIT *uptr)
{
uint32 ma, da, t;
uint16 dat;
uint16 *fbuf = uptr->filebuf;
if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */
update_rfcs (RFCS_NED|RFCS_DONE, 0); /* nx disk */
return IORETURN (rf_stopioe, SCPE_UNATT);
}
ma = GET_MEX (rf_cs) | rf_cma; /* 18b mem addr */
da = GET_DEX (rf_dae) | rf_da; /* 22b disk addr */
do {
if (da >= rf_unit.capac) { /* disk overflow? */
update_rfcs (RFCS_NED, 0);
break;
}
if (uptr->FUNC == RFNC_READ) { /* read? */
dat = fbuf[da]; /* get disk data */
rf_dbr = dat;
if (Map_WriteW (ma, 2, &dat)) { /* store mem, nxm? */
update_rfcs (0, RFDAE_NXM);
break;
}
}
else if (uptr->FUNC == RFNC_WCHK) { /* write check? */
rf_dbr = fbuf[da]; /* get disk data */
if (Map_ReadW (ma, 2, &dat)) { /* read mem, nxm? */
update_rfcs (0, RFDAE_NXM);
break;
}
if (rf_dbr != dat) { /* miscompare? */
update_rfcs (RFCS_WCHK, 0);
break;
}
}
else { /* write */
t = (da >> 15) & 037;
if ((rf_wlk >> t) & 1) { /* write locked? */
update_rfcs (RFCS_WLK, 0);
break;
}
else { /* not locked */
if (Map_ReadW (ma, 2, &dat)) { /* read mem, nxm? */
update_rfcs (0, RFDAE_NXM);
break;
}
fbuf[da] = dat; /* write word */
rf_dbr = dat;
if (da >= uptr->hwmark) uptr->hwmark = da + 1;
}
}
da = (da + 1) & 017777777; /* incr disk addr */
if ((rf_dae & RFDAE_INH) == 0) /* inhibit clear? */
ma = (ma + 2) & UNIMASK; /* incr mem addr */
rf_wc = (rf_wc + 1) & DMASK; /* incr word count */
} while ((rf_wc != 0) && (rf_burst != 0)); /* brk if wc, no brst */
rf_da = da & DMASK; /* split da */
rf_dae = (rf_dae & ~RFDAE_DAE) | ((rf_da >> 16) && RFDAE_DAE);
rf_cma = ma & DMASK; /* split ma */
rf_cs = (rf_cs & ~RFCS_MEX) | ((ma >> (16 - RFCS_V_MEX)) & RFCS_MEX);
if ((rf_wc != 0) && ((rf_cs & RFCS_ERR) == 0)) /* more to do? */
sim_activate (&rf_unit, rf_time); /* sched next */
else {
update_rfcs (RFCS_DONE, 0);
if (DEBUG_PRS (rf_dev))
fprintf (sim_deb, ">>RF done: cs = %o, dae = %o, da = %o, ma = %o, wc = %o\n",
rf_cs, rf_dae, rf_da, rf_cma, rf_wc);
}
return SCPE_OK;
}
/* Update CS register */
uint32 update_rfcs (uint32 newcs, uint32 newdae)
{
uint32 oldcs = rf_cs;
uint32 da = GET_DEX (rf_dae) | rf_da;
rf_dae |= newdae; /* update DAE */
rf_cs |= newcs; /* update CS */
if (da >= rf_unit.capac) /* update CS<ned> */
rf_cs |= RFCS_NED;
else rf_cs &= ~RFCS_NED;
if (rf_dae & RFDAE_ALLERR) /* update CS<frz> */
rf_cs |= RFCS_FRZ;
else rf_cs &= ~RFCS_FRZ;
if (rf_cs & RFCS_ALLERR) /* update CS<err> */
rf_cs |= RFCS_ERR;
else rf_cs &= ~RFCS_ERR;
if ((rf_cs & RFCS_IE) && /* IE and */
(rf_cs & RFCS_DONE) &&!(oldcs & RFCS_DONE)) /* done 0->1? */
SET_INT (RF);
return rf_cs;
}
/* Reset routine */
t_stat rf_reset (DEVICE *dptr)
{
rf_cs = RFCS_DONE;
rf_da = rf_dae = 0;
rf_dbr = 0;
rf_cma = 0;
rf_wc = 0;
rf_maint = 0;
CLR_INT (RF);
sim_cancel (&rf_unit);
return SCPE_OK;
}
/* Bootstrap routine */
/* Device bootstrap */
#define BOOT_START 02000 /* start */
#define BOOT_ENTRY (BOOT_START + 002) /* entry */
#define BOOT_CSR (BOOT_START + 032) /* CSR */
#define BOOT_LEN (sizeof (boot_rom) / sizeof (uint16))
static const uint16 boot_rom[] = {
0043113, /* "FD" */
0012706, BOOT_START, /* MOV #boot_start, SP */
0012701, 0177472, /* MOV #RFDAE+2, R1 ; csr block */
0005041, /* CLR -(R1) ; clear dae */
0005041, /* CLR -(R1), ; clear da */
0005041, /* CLR -(R1), ; clear cma */
0012741, 0177000, /* MOV #-256.*2, -(R1) ; load wc */
0012741, 0000005, /* MOV #READ+GO, -(R1) ; read & go */
0005002, /* CLR R2 */
0005003, /* CLR R3 */
0012704, BOOT_START+020, /* MOV #START+20, R4 */
0005005, /* CLR R5 */
0105711, /* TSTB (R1) */
0100376, /* BPL .-2 */
0105011, /* CLRB (R1) */
0005007 /* CLR PC */
};
t_stat rf_boot (int32 unitno, DEVICE *dptr)
{
int32 i;
extern int32 saved_PC;
for (i = 0; i < BOOT_LEN; i++) M[(BOOT_START >> 1) + i] = boot_rom[i];
M[BOOT_CSR >> 1] = (rf_dib.ba & DMASK) + 012;
saved_PC = BOOT_ENTRY;
return SCPE_OK;
}
/* Attach routine */
t_stat rf_attach (UNIT *uptr, char *cptr)
{
uint32 sz, p;
uint32 ds_bytes = RF_DKSIZE * sizeof (int16);
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize_name (cptr))) {
p = (sz + ds_bytes - 1) / ds_bytes;
if (p >= RF_NUMDK) p = RF_NUMDK - 1;
uptr->flags = (uptr->flags & ~UNIT_PLAT) |
(p << UNIT_V_PLAT);
}
uptr->capac = UNIT_GETP (uptr->flags) * RF_DKSIZE;
return attach_unit (uptr, cptr);
}
/* Change disk size */
t_stat rf_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (val < 0) return SCPE_IERR;
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
uptr->capac = UNIT_GETP (val) * RF_DKSIZE;
uptr->flags = uptr->flags & ~UNIT_AUTO;
return SCPE_OK;
}

View file

@ -1,6 +1,6 @@
/* pdp11_stddev.c: PDP-11 standard I/O devices simulator
Copyright (c) 1993-2005, Robert M Supnik
Copyright (c) 1993-2006, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -26,6 +26,7 @@
tti,tto DL11 terminal input/output
clk KW11L (and other) line frequency clock
05-Jul-06 RMS Added UC only support for early DOS/RSTS
22-Nov-05 RMS Revised for new terminal processing routines
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
07-Jul-05 RMS Removed extraneous externs
@ -121,6 +122,7 @@ REG tti_reg[] = {
};
MTAB tti_mod[] = {
{ TT_MODE, TT_MODE_UC, "UC", "UC", &tty_set_mode },
{ TT_MODE, TT_MODE_7B, "7b", "7B", &tty_set_mode },
{ TT_MODE, TT_MODE_8B, "8b", "8B", &tty_set_mode },
{ TT_MODE, TT_MODE_7P, "7b", NULL, NULL },
@ -166,6 +168,7 @@ REG tto_reg[] = {
};
MTAB tto_mod[] = {
{ TT_MODE, TT_MODE_UC, "UC", "UC", &tty_set_mode },
{ TT_MODE, TT_MODE_7B, "7b", "7B", &tty_set_mode },
{ TT_MODE, TT_MODE_8B, "8b", "8B", &tty_set_mode },
{ TT_MODE, TT_MODE_7P, "7p", "7P", &tty_set_mode },
@ -440,7 +443,8 @@ else clk_fie = clk_fnxm = 1; /* no, BEVENT */
clk_tps = clk_default; /* set default tps */
clk_csr = CSR_DONE; /* set done */
CLR_INT (CLK);
sim_activate (&clk_unit, clk_unit.wait); /* activate unit */
sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init line clock */
sim_activate_abs (&clk_unit, clk_unit.wait); /* activate unit */
tmr_poll = clk_unit.wait; /* set timer poll */
tmxr_poll = clk_unit.wait; /* set mux poll */
return SCPE_OK;

View file

@ -23,6 +23,9 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
14-Jul-06 RMS Reordered device list
06-Jul-06 RMS Added multiple KL11/DL11 support
26-Jun-06 RMS Added RF11 support
17-May-06 RMS Added CR11/CD11 support (from John Dundas)
16-Aug-05 RMS Fixed C++ declaration and cast problems
22-Jul-05 RMS Fixed missing , in initializer (from Doug Gwyn)
@ -54,23 +57,34 @@
#include "pdp11_defs.h"
#include <ctype.h>
extern DEVICE cpu_dev, sys_dev;
extern DEVICE ptr_dev, ptp_dev;
extern DEVICE tti_dev, tto_dev;
extern DEVICE cpu_dev;
extern DEVICE sys_dev;
extern DEVICE ptr_dev;
extern DEVICE ptp_dev;
extern DEVICE tti_dev;
extern DEVICE tto_dev;
extern DEVICE lpt_dev;
extern DEVICE cr_dev;
extern DEVICE clk_dev, pclk_dev;
extern DEVICE clk_dev;
extern DEVICE pclk_dev;
extern DEVICE ttix_dev;
extern DEVICE ttox_dev;
extern DEVICE dz_dev;
extern DEVICE vh_dev;
extern DEVICE rk_dev, rl_dev;
extern DEVICE hk_dev;
extern DEVICE rx_dev, ry_dev;
extern DEVICE mba_dev[];
extern DEVICE rp_dev, tu_dev;
extern DEVICE rq_dev, rqb_dev, rqc_dev, rqd_dev;
extern DEVICE dt_dev;
extern DEVICE tm_dev, ts_dev;
extern DEVICE rf_dev;
extern DEVICE rk_dev;
extern DEVICE rl_dev;
extern DEVICE hk_dev;
extern DEVICE rx_dev;
extern DEVICE ry_dev;
extern DEVICE mba_dev[];
extern DEVICE rp_dev;
extern DEVICE rq_dev, rqb_dev, rqc_dev, rqd_dev;
extern DEVICE tm_dev;
extern DEVICE tq_dev;
extern DEVICE ts_dev;
extern DEVICE tu_dev;
extern DEVICE xq_dev, xqb_dev;
extern DEVICE xu_dev, xub_dev;
extern UNIT cpu_unit;
@ -99,16 +113,19 @@ DEVICE *sim_devices[] = {
&sys_dev,
&mba_dev[0],
&mba_dev[1],
&clk_dev,
&pclk_dev,
&ptr_dev,
&ptp_dev,
&tti_dev,
&tto_dev,
&cr_dev,
&lpt_dev,
&clk_dev,
&pclk_dev,
&ttix_dev,
&ttox_dev,
&dz_dev,
&vh_dev,
&rf_dev,
&rk_dev,
&rl_dev,
&hk_dev,

View file

@ -25,6 +25,7 @@
tc TC11/TU56 DECtape
23-Jun-06 RMS Fixed switch conflict in ATTACH
10-Feb-06 RMS READ sets extended data bits in TCST (found by Alan Frisbie)
16-Aug-05 RMS Fixed C++ declaration and cast problems
07-Jul-05 RMS Removed extraneous externs
@ -1179,11 +1180,11 @@ r = attach_unit (uptr, cptr); /* attach */
if (r != SCPE_OK) return r; /* fail? */
if ((sim_switches & SIM_SW_REST) == 0) { /* not from rest? */
uptr->flags = (uptr->flags | UNIT_11FMT) & ~UNIT_8FMT; /* default 16b */
if (sim_switches & SWMASK ('R')) /* att 12b? */
if (sim_switches & SWMASK ('T')) /* att 12b? */
uptr->flags = (uptr->flags | UNIT_8FMT) & ~UNIT_11FMT;
else if (sim_switches & SWMASK ('T')) /* att 18b? */
else if (sim_switches & SWMASK ('F')) /* att 18b? */
uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT);
else if (!(sim_switches & SWMASK ('S')) && /* autosize? */
else if (!(sim_switches & SWMASK ('A')) && /* autosize? */
((sz = sim_fsize (uptr->fileref)) > D16_FILSIZ)) {
if (sz <= D8_FILSIZ)
uptr->flags = (uptr->flags | UNIT_8FMT) & ~UNIT_11FMT;

View file

@ -1,6 +1,6 @@
/* pdp18b_cpu.c: 18b PDP CPU simulator
Copyright (c) 1993-2005, Robert M Supnik
Copyright (c) 1993-2006, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu PDP-4/7/9/15 central processor
27-Jun-06 RMS Reset clears AC, L, and MQ
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
16-Aug-05 RMS Fixed C++ declaration and cast problems
22-Jul-05 RMS Removed AAS, error in V1 reference manual
@ -1889,6 +1890,8 @@ return pa;
t_stat cpu_reset (DEVICE *dptr)
{
LAC = 0;
MQ = 0;
SC = 0;
eae_ac_sign = 0;
ion = ion_defer = ion_inh = 0;

View file

@ -1,3 +1,55 @@
18b PDP Diagnostics
1. PDP-4
2. PDP-7
2.1 PDP-7 Instruction Test (Maindec 701)
The diagnostic must be boot loaded, as it jumps dynamically out
of the RIM load process into its own loader.
At start, set SR<1:16> to a non-zero value. The diagnostic
executes four HLT's as part of initial tests and then runs to
completion. Normal HLT is at 2623 (PC = 2624).
sim> att -e ptr digital-7-54-m-rim.bin
sim> boot ptr
HALT instruction, PC: 17670 (AND 17727)
sim> d sr 4 ; any even value between 2 and 377776
sim> run 170
HALT instruction, PC: 00171 (CML CMA)
sim> ex ac,l
AC: 000000
L: 0
sim> c
HALT instruction, PC: 00173 (SPA)
sim> ex ac,l
AC: 777777
L: 1
sim> c
HALT instruction, PC: 00176 (SPA)
sim> ex ac,l
AC: 000000
L: 0
sim> c
HALT instruction, PC: 00201 (LAC 4116)
sim> ex ac,l
AC: 000004
L: 0
sim> c
HALT instruction, PC: 02624 (JMP 201)
3. PDP-9
4. PDP-15
Operating Instructions, PDP-15 diagnostics
MAINDEC-15-D0A1-PH Instruction test 1
@ -14,7 +66,7 @@ Breakpoint: 4437 for one pass
MAINDEC-15-D0AA-PB Index register test
Read in: 17700 (binary tape, doesn't matter)
Read in: 17700 (ignored, binary tape)
Start: 200
Halts: at 214, set BANKM = 0
Runs to: prints END at end of pass

View file

@ -1,6 +1,6 @@
/* pdp18b_dt.c: 18b DECtape simulator
Copyright (c) 1993-2005, Robert M Supnik
Copyright (c) 1993-2006, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -27,6 +27,9 @@
(PDP-9) TC02/TU55 DECtape
(PDP-15) TC15/TU56 DECtape
23-Jun-06 RMS Fixed switch conflict in ATTACH
Revised Type 550 header based on DECTOG formatter
13-Jun-06 RMS Fixed checksum calculation bug in Type 550
16-Aug-05 RMS Fixed C++ declaration and cast problems
25-Jan-04 RMS Revised for device debug support
14-Jan-04 RMS Revised IO device call interface
@ -65,22 +68,23 @@
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 (as
taken from the TD8E formatter) is:
taken from the PDP-7 formatter) is:
reverse end zone 8192 reverse end zone codes ~ 10 feet
reverse end zone 7144 reverse end zone codes ~ 12 feet
reverse buffer 200 interblock codes
block 0
:
block n
forward buffer 200 interblock codes
forward end zone 8192 forward end zone codes ~ 10 feet
forward end zone 7144 forward end zone codes ~ 12 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
standard block length of 256 words; the PDP-8 uses a standard block length
of 86 words (x 18b = 129 words x 12b). [A PDP-4/7 DECtape has only four 18b
header words; for consistency, the PDP-4/7 uses the same format as the PDP-9/15
but skips the missing header words.]
of 86 words (x 18b = 129 words x 12b). PDP-4/7 DECtapes came in two
formats. The first 5 controllers used a 4 word header/trailer (missing
word 0/4). All later serial numbers used the standard header. The later,
standard header/trailer is simulated here.
Because a DECtape file only contains data, the simulator cannot support
write timing and mark track and can only do a limited implementation
@ -848,9 +852,7 @@ int32 mot = DTS_GETMOT (uptr->STATE);
int32 dir = mot & DTS_DIR;
int32 fnc = DTS_GETFNC (uptr->STATE);
int32 *fbuf = (int32 *) uptr->filebuf;
#if defined (TC02)
int32 unum = uptr - dt_dev.units;
#endif
int32 blk, wrd, ma, relpos;
uint32 ba;
@ -925,6 +927,8 @@ switch (fnc) { /* at speed, check fnc *
if (MEM_ADDR_OK (ma)) M[ma] = blk; /* store block # */
if (((dtsa & DTA_MODE) == 0) || (M[DT_WC] == 0))
dtsb = dtsb | DTB_DTF; /* set DTF */
if (DEBUG_PRI (dt_dev, LOG_MS))
fprintf (sim_deb, ">>DT%d: found block %d\n", unum, blk);
break;
/* Read has four subcases
@ -1128,6 +1132,8 @@ switch (fnc) { /* at speed, check fnc *
sim_activate (uptr, DTU_LPERB (uptr) * dt_ltime);/* sched next block */
dtdb = blk; /* store block # */
dtsb = dtsb | DTB_DTF; /* set DTF */
if (DEBUG_PRI (dt_dev, LOG_MS))
fprintf (sim_deb, ">>DT%d: search found block %d\n", unum, blk);
break;
/* Read and read all */
@ -1149,8 +1155,10 @@ switch (fnc) { /* at speed, check fnc *
else {
ma = (2 * DT_HTWRD) + DTU_BSIZE (uptr) - DT_CSMWD - 1;
wrd = relpos / DT_WSIZE; /* hdr start = wd 0 */
#if defined (OLD_TYPE550)
if ((wrd == 0) || /* skip 1st, last */
(wrd == ((2 * DT_HTWRD) + DTU_BSIZE (uptr) - 1))) break;
#endif
if ((fnc == FNC_READ) && /* read, skip if not */
(wrd != DT_CSMWD) && /* fwd, rev cksum */
(wrd != ma)) break;
@ -1184,8 +1192,10 @@ switch (fnc) { /* at speed, check fnc *
}
else {
wrd = relpos / DT_WSIZE; /* hdr start = wd 0 */
#if defined (OLD_TYPE550)
if ((wrd == 0) || /* skip 1st, last */
(wrd == ((2 * DT_HTWRD) + DTU_BSIZE (uptr) - 1))) break;
#endif
if ((fnc == FNC_WRIT) && /* wr, skip if !csm */
(wrd != ((2 * DT_HTWRD) + DTU_BSIZE (uptr) - DT_CSMWD - 1)))
break;
@ -1279,14 +1289,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 == DT_CSMWD) return 077; /* rev csum */
if (wrd == ((2 * DT_HTWRD) + DTU_BSIZE (uptr) - DT_CSMWD - 1)) /* fwd csum */
return (dt_csum (uptr, blk) << 12);
#else
#else /* Type 550 */
if (wrd == DT_CSMWD) return 0777777; /* rev csum */
if (wrd == ((2 * DT_HTWRD) + DTU_BSIZE (uptr) - DT_CSMWD - 1)) /* fwd csum */
return (dt_csum (uptr, blk));
#endif /* Type 550 */
#endif
if (wrd == ((2 * DT_HTWRD) + DTU_BSIZE (uptr) - DT_BLKWD - 1)) /* rev blkno */
return dt_comobv (blk);
return 0; /* all others */
@ -1353,11 +1364,11 @@ r = attach_unit (uptr, cptr); /* attach */
if (r != SCPE_OK) return r; /* error? */
if ((sim_switches & SIM_SW_REST) == 0) { /* not from rest? */
uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT); /* default 18b */
if (sim_switches & SWMASK ('R')) /* att 12b? */
if (sim_switches & SWMASK ('T')) /* att 12b? */
uptr->flags = uptr->flags | UNIT_8FMT;
else if (sim_switches & SWMASK ('S')) /* att 16b? */
uptr->flags = uptr->flags | UNIT_11FMT;
else if (!(sim_switches & SWMASK ('T')) && /* autosize? */
else if (!(sim_switches & SWMASK ('A')) && /* autosize? */
(sz = sim_fsize (uptr->fileref))) {
if (sz == D8_FILSIZ)
uptr->flags = uptr->flags | UNIT_8FMT;

View file

@ -1,6 +1,6 @@
/* pdp18b_fpp.c: FP15 floating point processor simulator
Copyright (c) 2003-2005, Robert M Supnik
Copyright (c) 2003-2006, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
fpp PDP-15 floating point processor
06-Jul-06 RMS Fixed bugs in left shift, multiply
31-Oct-04 RMS Fixed URFST to mask low 9b of fraction
Fixed exception PC setting
10-Apr-04 RMS JEA is 15b not 18b
@ -663,7 +664,8 @@ if (dp_cmp (a,b) >= 0) { /* |a| >= |b|? */
a->hi = (a->hi - b->hi - (a->lo < b->lo)) & UFP_FH_MASK;
a->lo = (a->lo - b->lo) & UFP_FL_MASK; /* a - b */
}
else { a->hi = (b->hi - a->hi - (b->lo < a->lo)) & UFP_FH_MASK;
else {
a->hi = (b->hi - a->hi - (b->lo < a->lo)) & UFP_FH_MASK;
a->lo = (b->lo - a->lo) & UFP_FL_MASK; /* b - a */
a->sign = a->sign ^ 1; /* change a sign */
}
@ -681,7 +683,7 @@ if (a->lo > b->lo) return +1;
return 0;
}
/* Double precision multiply - returns 70b result */
/* Double precision multiply - returns 70b result in a'fmq */
void dp_mul (UFP *a, UFP *b)
{
@ -690,7 +692,11 @@ int32 i;
fmq.hi = a->hi; /* FMQ <- a */
fmq.lo = a->lo;
a->hi = a->lo = 0; /* a <- 0 */
if (((fmq.hi | fmq.lo) == 0) || ((b->hi | b->lo) == 0)) return;
if ((fmq.hi | fmq.lo) == 0) return;
if ((b->hi | b->lo) == 0) {
fmq.hi = fmq.lo = 0;
return;
}
for (i = 0; i < 35; i++) { /* 35 iterations */
if (fmq.lo & 1) dp_add (a, b); /* FMQ<35>? a += b */
dp_rsh_1 (a, &fmq); /* rsh a'FMQ */
@ -702,12 +708,12 @@ return;
void dp_lsh_1 (UFP *a, UFP *b)
{
int32 t = b? b->lo: 0;
int32 t = b? b->hi: 0;
a->hi = (a->hi << 1) | (a->lo >> 17);
a->lo = ((a->lo << 1) | (t >> 16)) & UFP_FL_MASK;
a->hi = (a->hi << 1) | ((a->lo >> 17) & 1);
a->lo = ((a->lo << 1) | ((t >> 16) & 1)) & UFP_FL_MASK;
if (b) {
b->hi = ((b->hi << 1) | (b->lo >> 17)) & UFP_FH_MASK;
b->hi = ((b->hi << 1) | ((b->lo >> 17) & 1)) & UFP_FH_MASK;
b->lo = (b->lo << 1) & UFP_FL_MASK;
}
return;
@ -761,18 +767,23 @@ void fp15_asign (int32 fir, UFP *a)
int32 sgnop = FI_GETSGNOP (fir);
switch (sgnop) { /* modify FMA sign */
case 1:
a->sign = 0;
break;
case 2:
a->sign = 1;
break;
case 3:
a->sign = a->sign ^ 1;
break;
default:
break;
}
return;
}
@ -809,8 +820,8 @@ if (rnd && b && (b->hi & UFP_FH_NORM)) { /* rounding? */
}
}
}
if (a->exp > 0377777) return FP_OVF; /* overflow? */
if (a->exp < -0400000) return FP_UNF; /* underflow? */
if (a->exp > (int32) 0377777) return FP_OVF; /* overflow? */
if (a->exp < (int32) -0400000) return FP_UNF; /* underflow? */
return FP_OK;
}

View file

@ -1,6 +1,6 @@
/* pdp18b_lp.c: 18b PDP's line printer simulator
Copyright (c) 1993-2005, Robert M Supnik
Copyright (c) 1993-2006, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -28,6 +28,7 @@
lp09 (PDP-9,15) LP09 line printer
lp15 (PDP-15) LP15 line printer
11-Jun-06 RMS Made character translation table global scope
14-Jan-04 RMS Revised IO device call interface
23-Jul-03 RMS Fixed overprint bug in Type 62
25-Apr-03 RMS Revised for extended file support
@ -46,6 +47,12 @@
#include "pdp18b_defs.h"
extern int32 int_hwre[API_HLVL+1];
const char fio_to_asc[64] = {
' ','1','2','3','4','5','6','7','8','9','\'','~','#','V','^','<',
'0','/','S','T','U','V','W','X','Y','Z','"',',','>','^','-','?',
'o','J','K','L','M','N','O','P','Q','R','$','=','-',')','-','(',
'_','A','B','C','D','E','F','G','H','I','*','.','+',']','|','['
};
#if defined (TYPE62)
@ -60,12 +67,6 @@ int32 lp62_ovrpr = 0; /* overprint */
int32 lp62_stopioe = 0;
int32 lp62_bp = 0; /* buffer ptr */
char lp62_buf[LP62_BSIZE + 1] = { 0 };
static const char lp62_trans[64] = {
' ','1','2','3','4','5','6','7','8','9','\'','~','#','V','^','<',
'0','/','S','T','U','V','W','X','Y','Z','"',',','>','^','-','?',
'o','J','K','L','M','N','O','P','Q','R','$','=','-',')','-','(',
'_','A','B','C','D','E','F','G','H','I','*','.','+',']','|','['
};
static const char *lp62_cc[] = {
"\n",
"\n\n",
@ -138,9 +139,9 @@ if (pulse & 02) {
if (sb == 000) CLR_INT (LPT); /* LPCF */
if ((sb == 040) && (lp62_bp < BPTR_MAX)) { /* LPLD */
i = lp62_bp * 3; /* cvt to chr ptr */
lp62_buf[i] = lp62_trans[(dat >> 12) & 077];
lp62_buf[i + 1] = lp62_trans[(dat >> 6) & 077];
lp62_buf[i + 2] = lp62_trans[dat & 077];
lp62_buf[i] = fio_to_asc[(dat >> 12) & 077];
lp62_buf[i + 1] = fio_to_asc[(dat >> 6) & 077];
lp62_buf[i + 2] = fio_to_asc[dat & 077];
lp62_bp = (lp62_bp + 1) & BPTR_MASK;
}
}

View file

@ -1,6 +1,6 @@
/* pdp18b_stddev.c: 18b PDP's standard devices
Copyright (c) 1993-2005, Robert M Supnik
Copyright (c) 1993-2006, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -29,6 +29,10 @@
tto teleprinter
clk clock
30-Jun-06 RMS Fixed KSR-28 shift tracking
20-Jun-06 RMS Added KSR ASCII reader support
13-Jun-06 RMS Fixed Baudot letters/figures inversion for PDP-4
Fixed PDP-4/PDP-7 default terminal to be local echo
22-Nov-05 RMS Revised for new terminal processing routines
28-May-04 RMS Removed SET TTI CTRL-C
16-Feb-04 RMS Fixed bug in hardware read-in mode bootstrap
@ -66,6 +70,8 @@
#define UNIT_V_RASCII (UNIT_V_UF + 0) /* reader ASCII */
#define UNIT_RASCII (1 << UNIT_V_RASCII)
#define UNIT_V_KASCII (UNIT_V_UF + 1) /* KSR ASCII */
#define UNIT_KASCII (1 << UNIT_V_KASCII)
#define UNIT_V_PASCII (UNIT_V_UF + 0) /* punch ASCII */
#define UNIT_PASCII (1 << UNIT_V_PASCII)
@ -78,11 +84,41 @@ extern UNIT cpu_unit;
int32 clk_state = 0;
int32 ptr_err = 0, ptr_stopioe = 0, ptr_state = 0;
int32 ptp_err = 0, ptp_stopioe = 0;
int32 tti_state = 0;
int32 tto_state = 0;
int32 tti_2nd = 0; /* 2nd char waiting */
int32 tty_shift = 0; /* KSR28 shift state */
int32 clk_tps = 60; /* ticks/second */
int32 tmxr_poll = 16000; /* term mux poll */
const int32 asc_to_baud[128] = {
000,000,000,000,000,000,000,064, /* bell */
000,000,0110,000,000,0102,000,000, /* lf, cr */
000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,
0104,066,061,045,062,000,053,072, /* space - ' */
076,051,000,000,046,070,047,067, /* ( - / */
055,075,071,060,052,041,065,074, /* 0 - 7 */
054,043,056,057,000,000,000,063, /* 8 - ? */
000,030,023,016,022,020,026,013, /* @ - G */
005,014,032,036,011,007,006,003, /* H - O */
015,035,012,024,001,034,017,031, /* P - W */
027,025,021,000,000,000,000,000, /* X - _ */
000,030,023,016,022,020,026,013, /* ` - g */
005,014,032,036,011,007,006,003, /* h - o */
015,035,012,024,001,034,017,031, /* p - w */
027,025,021,000,000,000,000,000 /* x - DEL */
};
const char baud_to_asc[64] = {
0 ,'T',015,'O',' ','H','N','M',
012,'L','R','G','I','P','C','V',
'E','Z','D','B','S','Y','F','X',
'A','W','J', 0 ,'U','Q','K', 0,
0 ,'5','\r','9',' ','#',',','.',
012,')','4','&','8','0',':',';',
'3','"','$','?','\a','6','!','/',
'-','2','\'',0 ,'7','1','(', 0
};
int32 ptr (int32 dev, int32 pulse, int32 dat);
int32 ptp (int32 dev, int32 pulse, int32 dat);
int32 tti (int32 dev, int32 pulse, int32 dat);
@ -181,6 +217,8 @@ REG ptr_reg[] = {
};
MTAB ptr_mod[] = {
{ UNIT_RASCII, UNIT_RASCII, "even parity ASCII", NULL },
{ UNIT_KASCII, UNIT_KASCII, "forced parity ASCII", NULL },
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", NULL, NULL, &show_devno },
{ 0 }
};
@ -220,6 +258,7 @@ REG ptp_reg[] = {
};
MTAB ptp_mod[] = {
{ UNIT_PASCII, UNIT_PASCII, "7b ASCII", NULL },
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", NULL, NULL, &show_devno },
{ 0 }
};
@ -237,59 +276,35 @@ DEVICE ptp_dev = {
tti_dev TTI device descriptor
tti_unit TTI unit
tti_reg TTI register list
tti_trans ASCII to Baudot table
*/
#if defined (KSR28)
#define TTI_WIDTH 5
#define TTI_FIGURES (1 << TTI_WIDTH)
#define TTI_2ND (1 << (TTI_WIDTH + 1))
#define TTI_BOTH (1 << (TTI_WIDTH + 2))
#define BAUDOT_LETTERS 033
#define BAUDOT_FIGURES 037
#define TTI_BOTH (1 << (TTI_WIDTH + 1))
#define BAUDOT_LETTERS 037
#define BAUDOT_FIGURES 033
static const int32 tti_trans[128] = {
000,000,000,000,000,000,000,064, /* bell */
000,000,0210,000,000,0202,000,000, /* lf, cr */
000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,
0204,066,061,045,062,000,053,072, /* space - ' */
076,051,000,000,046,070,047,067, /* ( - / */
055,075,071,060,052,041,065,074, /* 0 - 7 */
054,043,056,057,000,000,000,063, /* 8 - ? */
000,030,023,016,022,020,026,013, /* @ - G */
005,014,032,036,011,007,006,003, /* H - O */
015,035,012,024,001,034,017,031, /* P - W */
027,025,021,000,000,000,000,000, /* X - _ */
000,030,023,016,022,020,026,013, /* ` - g */
005,014,032,036,011,007,006,003, /* h - o */
015,035,012,024,001,034,017,031, /* p - w */
027,025,021,000,000,000,000,000 /* x - DEL */
};
#else
#define TTI_WIDTH 8
#endif
#define TTI_MASK ((1 << TTI_WIDTH) - 1)
#define UNIT_V_HDX (TTUF_V_UF + 0) /* half duplex */
#define UNIT_HDX (1 << UNIT_V_HDX)
#define TTUF_V_HDX (TTUF_V_UF + 0) /* half duplex */
#define TTUF_HDX (1 << TTUF_V_HDX)
DIB tti_dib = { DEV_TTI, 1, &tti_iors, { &tti } };
#if defined (PDP4) || defined (PDP7)
UNIT tti_unit = { UDATA (&tti_svc, TT_MODE_KSR, 0), KBD_POLL_WAIT };
#else
UNIT tti_unit = { UDATA (&tti_svc, TT_MODE_KSR+UNIT_HDX, 0), KBD_POLL_WAIT };
#endif
UNIT tti_unit = { UDATA (&tti_svc, TT_MODE_KSR+TTUF_HDX, 0), KBD_POLL_WAIT };
REG tti_reg[] = {
{ ORDATA (BUF, tti_unit.buf, TTI_WIDTH) },
#if defined (KSR28)
{ ORDATA (BUF2ND, tti_2nd, TTI_WIDTH), REG_HRO },
#endif
{ FLDATA (INT, int_hwre[API_TTI], INT_V_TTI) },
{ FLDATA (DONE, int_hwre[API_TTI], INT_V_TTI) },
#if defined (KSR28)
{ ORDATA (TTI_STATE, tti_state, (TTI_WIDTH + 3)), REG_HRO },
#endif
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
{ NULL }
@ -301,9 +316,9 @@ MTAB tti_mod[] = {
{ TT_MODE, TT_MODE_7B, "7b", "7B", &tty_set_mode },
{ TT_MODE, TT_MODE_8B, "8b", "8B", &tty_set_mode },
{ TT_MODE, TT_MODE_7P, "7b", NULL, NULL },
{ UNIT_HDX, 0 , "full duplex", "FDX", NULL },
{ UNIT_HDX, UNIT_HDX, "half duplex", "HDX", NULL },
#endif
{ TTUF_HDX, 0 , "full duplex", "FDX", NULL },
{ TTUF_HDX, TTUF_HDX, "half duplex", "HDX", NULL },
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", NULL, NULL, &show_devno, NULL },
{ 0 }
};
@ -321,23 +336,12 @@ DEVICE tti_dev = {
tto_dev TTO device descriptor
tto_unit TTO unit
tto_reg TTO register list
tto_trans Baudot to ASCII table
*/
#if defined (KSR28)
#define TTO_WIDTH 5
#define TTO_FIGURES (1 << TTO_WIDTH)
static const char tto_trans[64] = {
0 ,'T',015,'O',' ','H','N','M',
012,'L','R','G','I','P','C','V',
'E','Z','D','B','S','Y','F','X',
'A','W','J', 0 ,'U','Q','K', 0,
0 ,'5','\r','9',' ','#',',','.',
012,')','4','&','8','0',':',';',
'3','"','$','?','\a','6','!','/',
'-','2','\'',0 ,'7','1','(', 0
};
#else
#define TTO_WIDTH 8
@ -351,11 +355,11 @@ UNIT tto_unit = { UDATA (&tto_svc, TT_MODE_KSR, 0), 1000 };
REG tto_reg[] = {
{ ORDATA (BUF, tto_unit.buf, TTO_WIDTH) },
#if defined (KSR28)
{ FLDATA (SHIFT, tty_shift, 0), REG_HRO },
#endif
{ FLDATA (INT, int_hwre[API_TTO], INT_V_TTO) },
{ FLDATA (DONE, int_hwre[API_TTO], INT_V_TTO) },
#if defined (KSR28)
{ FLDATA (TTO_STATE, tto_state, 0), REG_HRO },
#endif
{ DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
{ NULL }
@ -507,6 +511,8 @@ if (ptr_state == 0) { /* ASCII */
ptr_unit.buf = ptr_unit.buf ^ 0200; /* count bits */
ptr_unit.buf = ptr_unit.buf ^ 0200; /* set even parity */
}
else if (ptr_unit.flags & UNIT_KASCII) /* KSR ASCII? */
ptr_unit.buf = (temp | 0200) & 0377; /* forced parity */
else ptr_unit.buf = temp & 0377;
}
else if (temp & 0200) { /* binary */
@ -550,9 +556,11 @@ t_stat reason;
reason = attach_unit (uptr, cptr);
ptr_err = (ptr_unit.flags & UNIT_ATT)? 0: 1;
ptr_unit.flags = ptr_unit.flags & ~UNIT_RASCII;
ptr_unit.flags = ptr_unit.flags & ~(UNIT_RASCII|UNIT_KASCII);
if (sim_switches & SWMASK ('A'))
ptr_unit.flags = ptr_unit.flags | UNIT_RASCII;
if (sim_switches & SWMASK ('K'))
ptr_unit.flags = ptr_unit.flags | UNIT_KASCII;
return reason;
}
@ -889,23 +897,34 @@ return dat;
t_stat tti_svc (UNIT *uptr)
{
#if defined (KSR28) /* Baudot... */
int32 c;
int32 in, c;
sim_activate (uptr, uptr->wait); /* continue poll */
if (tti_state & TTI_2ND) { /* char waiting? */
uptr->buf = tti_state & TTI_MASK; /* return char */
tti_state = tti_state & ~TTI_2ND; /* not waiting */
if (tti_2nd) { /* char waiting? */
uptr->buf = tti_2nd; /* return char */
tti_2nd = 0; /* not waiting */
}
else {
if ((c = sim_poll_kbd ()) < SCPE_KFLAG) return c;
c = tti_trans[c & 0177]; /* translate char */
if ((in = sim_poll_kbd ()) < SCPE_KFLAG) return in;
c = asc_to_baud[in & 0177]; /* translate char */
if (c == 0) return SCPE_OK; /* untranslatable? */
if (((c & TTI_FIGURES) == (tti_state & TTI_FIGURES)) ||
(c & TTI_BOTH)) uptr->buf = c & TTI_MASK;
else {
uptr->buf = (c & TTI_FIGURES)?
BAUDOT_FIGURES: BAUDOT_LETTERS;
tti_state = c | TTI_2ND; /* set 2nd waiting */
if ((c & TTI_BOTH) || /* case insensitive? */
(((c & TTI_FIGURES)? 1: 0) == tty_shift)) /* right case? */
uptr->buf = c & TTI_MASK;
else { /* send case change */
if (c & TTI_FIGURES) { /* to figures? */
uptr->buf = BAUDOT_FIGURES;
tty_shift = 1;
}
else { /* no, to letters */
uptr->buf = BAUDOT_LETTERS;
tty_shift = 0;
}
tti_2nd = c & TTI_MASK; /* save actual char */
}
if (uptr->flags & TTUF_HDX) { /* half duplex? */
sim_putchar (sim_tt_outcvt (in, TTUF_MODE_UC));
tto_unit.pos = tto_unit.pos + 1;
}
}
@ -917,7 +936,7 @@ 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 c = sim_tt_inpcvt (c, TT_GET_MODE (uptr->flags) | TTUF_KSR);
if ((uptr->flags & UNIT_HDX) && out && /* half duplex and */
if ((uptr->flags & TTUF_HDX) && out && /* half duplex and */
((out = sim_tt_outcvt (out, TT_GET_MODE (uptr->flags))) >= 0)) {
sim_putchar (out); /* echo */
tto_unit.pos = tto_unit.pos + 1;
@ -942,7 +961,8 @@ return (TST_INT (TTI)? IOS_TTI: 0);
t_stat tti_reset (DEVICE *dptr)
{
tti_unit.buf = 0; /* clear buffer */
tti_state = 0; /* clear state */
tti_2nd = 0;
tty_shift = 0; /* clear state */
CLR_INT (TTI); /* clear flag */
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
return SCPE_OK;
@ -972,11 +992,11 @@ t_stat r;
#if defined (KSR28) /* Baudot... */
if (uptr->buf == BAUDOT_FIGURES) /* set figures? */
tto_state = TTO_FIGURES;
tty_shift = 1;
else if (uptr->buf == BAUDOT_LETTERS) /* set letters? */
tto_state = 0;
tty_shift = 0;
else {
c = tto_trans[uptr->buf + tto_state]; /* translate */
c = baud_to_asc[uptr->buf | (tty_shift << 5)]; /* translate */
#else
c = sim_tt_outcvt (uptr->buf, TT_GET_MODE (uptr->flags));
@ -1006,7 +1026,7 @@ return (TST_INT (TTO)? IOS_TTO: 0);
t_stat tto_reset (DEVICE *dptr)
{
tto_unit.buf = 0; /* clear buffer */
tto_state = 0; /* clear state */
tty_shift = 0; /* clear state */
CLR_INT (TTO); /* clear flag */
sim_cancel (&tto_unit); /* deactivate unit */
return SCPE_OK;

View file

@ -1,6 +1,6 @@
/* pdp18b_sys.c: 18b PDP's simulator interface
Copyright (c) 1993-2005, Robert M Supnik
Copyright (c) 1993-2006, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -23,6 +23,8 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
12-Jun-06 RMS Added Fiodec, Baudot display
RMS Generalized LOAD to handle HRI, RIM, or BIN files
22-Jul-05 RMS Removed AAS, error in V1 reference manual
09-Jan-04 RMS Fixed instruction table errors
18-Oct-03 RMS Added DECtape off reel message
@ -96,6 +98,9 @@ extern REG cpu_reg[];
extern int32 M[];
extern int32 memm;
extern int32 PC;
extern const char asc_to_baud[128];
extern const char baud_to_asc[64];
extern const char fio_to_asc[64];
/* SCP data structures and interface routines
@ -231,7 +236,7 @@ for (;;) {
return SCPE_OK; /* done */
}
/* PDP-9/15 RIM format loader
/* PDP-7/9/15 hardware read-in format loader
Tape format (read in address specified externally)
data
@ -240,7 +245,7 @@ return SCPE_OK; /* done */
word to execute (bit 1 of last character set)
*/
t_stat rim_load_915 (FILE *fileref, char *cptr)
t_stat hri_load_7915 (FILE *fileref, char *cptr)
{
int32 bits, origin, val;
char gbuf[CBUFSIZE];
@ -312,35 +317,30 @@ for (;;) { /* block loop */
return SCPE_OK;
}
#if defined (PDP4) || defined (PDP7)
/* PDP-4/PDP-7: RIM format only */
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
{
if (flag != 0) return SCPE_NOFNC;
return rim_load_47 (fileref, cptr);
}
#else
/* PDP-9/PDP-15: all formats */
/* Binary loader, all formats */
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
{
extern int32 sim_switches;
if (flag != 0) return SCPE_NOFNC;
if (sim_switches & SWMASK ('S')) /* PDP-4/7 format? */
if (sim_switches & SWMASK ('S')) /* RIM format? */
return rim_load_47 (fileref, cptr);
if ((sim_switches & SWMASK ('R')) || /* RIM format? */
(match_ext (fnam, "RIM") && !(sim_switches & SWMASK ('B'))))
return rim_load_915 (fileref, cptr);
if (sim_switches & SWMASK ('R')) /* HRI format? */
return hri_load_7915 (fileref, cptr);
if (!(sim_switches & SWMASK ('B')) && /* .rim extension? */
match_ext (fnam, "RIM")) {
int32 val, bits;
do { /* look for HRI flag */
val = getword (fileref, &bits);
} while ((val >= 0) && ((bits & 1) == 0));
rewind (fileref); /* rewind file */
if (val < 0) return rim_load_47 (fileref, cptr); /* eof reached? */
return hri_load_7915 (fileref, cptr); /* no, HRI */
}
return bin_load_915 (fileref, cptr); /* must be BIN */
}
#endif
/* Symbol tables */
#define I_V_FL 18 /* inst class */
@ -869,6 +869,12 @@ for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
return sp;
}
static int32 rar (int32 c)
{
c = c & 077;
return (c >> 1) | (c << 5);
}
/* Symbolic decode
Inputs:
@ -902,6 +908,20 @@ if (sw & SWMASK ('C')) { /* character? */
fprintf (of, "%c", SIXTOASC (inst & 077));
return SCPE_OK;
}
#if defined (PDP4) || defined (PDP7)
if (sw & SWMASK ('F')) { /* FIODEC? */
fprintf (of, "%c", fio_to_asc[(inst >> 12) & 077]);
fprintf (of, "%c", fio_to_asc[(inst >> 6) & 077]);
fprintf (of, "%c", fio_to_asc[inst & 077]);
return SCPE_OK;
}
if (sw & SWMASK ('B')) { /* Baudot? */
fprintf (of, "%c", baud_to_asc[rar (inst >> 12) & 077]);
fprintf (of, "%c", baud_to_asc[rar (inst >> 6) & 077]);
fprintf (of, "%c", baud_to_asc[rar (inst) & 077]);
return SCPE_OK;
}
#endif
#if defined (PDP15)
if (sw & SWMASK ('P')) { /* packed ASCII? */
i = val[1];

View file

@ -25,6 +25,7 @@
dt TC08/TU56 DECtape
23-Jun-06 RMS Fixed switch conflict in ATTACH
07-Jan-06 RMS Fixed unaligned register access bug (found by Doug Carman)
16-Aug-05 RMS Fixed C++ declaration and cast problems
25-Jan-04 RMS Revised for device debug support
@ -1178,11 +1179,11 @@ r = attach_unit (uptr, cptr); /* attach */
if (r != SCPE_OK) return r; /* fail? */
if ((sim_switches & SIM_SW_REST) == 0) { /* not from rest? */
uptr->flags = (uptr->flags | UNIT_8FMT) & ~UNIT_11FMT;
if (sim_switches & SWMASK ('T')) /* att 18b? */
if (sim_switches & SWMASK ('F')) /* att 18b? */
uptr->flags = uptr->flags & ~UNIT_8FMT;
else if (sim_switches & SWMASK ('S')) /* att 16b? */
uptr->flags = (uptr->flags | UNIT_11FMT) & ~UNIT_8FMT;
else if (!(sim_switches & SWMASK ('R')) && /* autosize? */
else if (!(sim_switches & SWMASK ('A')) && /* autosize? */
(sz = sim_fsize (uptr->fileref))) {
if (sz == D11_FILSIZ)
uptr->flags = (uptr->flags | UNIT_11FMT) & ~UNIT_8FMT;

View file

@ -1,6 +1,6 @@
/* pdp8_td.c: PDP-8 simple DECtape controller (TD8E) simulator
Copyright (c) 1993-2005, Robert M Supnik
Copyright (c) 1993-2006, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -28,6 +28,7 @@
td TD8E/TU56 DECtape
23-Jun-06 RMS Fixed switch conflict in ATTACH
16-Aug-05 RMS Fixed C++ declaration and cast problems
09-Jan-04 RMS Changed sim_fsize calling sequence, added STOP_OFFR
@ -758,11 +759,11 @@ r = attach_unit (uptr, cptr); /* attach */
if (r != SCPE_OK) return r; /* fail? */
if ((sim_switches & SIM_SW_REST) == 0) { /* not from rest? */
uptr->flags = (uptr->flags | UNIT_8FMT) & ~UNIT_11FMT;
if (sim_switches & SWMASK ('T')) /* att 18b? */
if (sim_switches & SWMASK ('F')) /* att 18b? */
uptr->flags = uptr->flags & ~UNIT_8FMT;
else if (sim_switches & SWMASK ('S')) /* att 16b? */
uptr->flags = (uptr->flags | UNIT_11FMT) & ~UNIT_8FMT;
else if (!(sim_switches & SWMASK ('R')) && /* autosize? */
else if (!(sim_switches & SWMASK ('A')) && /* autosize? */
(sz = sim_fsize (uptr->fileref))) {
if (sz == D11_FILSIZ)
uptr->flags = (uptr->flags | UNIT_11FMT) & ~UNIT_8FMT;

View file

@ -1,6 +1,6 @@
/* pdp8_ttx.c: PDP-8 additional terminals simulator
Copyright (c) 1993-2005, Robert M Supnik
Copyright (c) 1993-2006, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
ttix,ttox PT08/KL8JA terminal input/output
06-Jul-06 RMS Fixed bug in DETACH routine
22-Nov-05 RMS Revised for new terminal processing routines
29-Jun-05 RMS Added SET TTOXn DISCONNECT
Fixed bug in SET LOG/NOLOG
@ -369,10 +370,9 @@ int32 i;
t_stat r;
r = tmxr_detach (&ttx_desc, uptr); /* detach */
for (i = 0; i < TTX_LINES; i++) { /* all lines, */
for (i = 0; i < TTX_LINES; i++) /* all lines, */
ttx_ldsc[i].rcve = 0; /* disable rcv */
sim_cancel (&ttox_unit[i]); /* stop poll */
}
sim_cancel (uptr); /* stop poll */
return r;
}

View file

@ -385,7 +385,8 @@ PDP11_SOURCE2 = $(PDP11_DIR)PDP11_TM.C,$(PDP11_DIR)PDP11_TS.C,\
$(PDP11_DIR)PDP11_RY.C,$(PDP11_DIR)PDP11_PT.C,\
$(PDP11_DIR)PDP11_HK.C,$(PDP11_DIR)PDP11_XQ.C,\
$(PDP11_DIR)PDP11_VH.C,$(PDP11_DIR)PDP11_RH.C,\
$(PDP11_DIR)PDP11_XU.C,$(PDP11_DIR)PDP11_TU.C
$(PDP11_DIR)PDP11_XU.C,$(PDP11_DIR)PDP11_TU.C,\
$(PDP11_DIR)PDP11_DL.C,$(PDP11_DIR)PDP11_RF.C
PDP11_OPTIONS = /INCL=($(SIMH_DIR),$(PDP11_DIR)$(PCAP_INC))\
/DEF=($(CC_DEFS),"VM_PDP11=1"$(PCAP_DEFS))

View file

@ -83,7 +83,7 @@ PDP11 = ${PDP11D}pdp11_fp.c ${PDP11D}pdp11_cpu.c ${PDP11D}pdp11_dz.c \
${PDP11D}pdp11_ry.c ${PDP11D}pdp11_pt.c ${PDP11D}pdp11_hk.c \
${PDP11D}pdp11_xq.c ${PDP11D}pdp11_xu.c ${PDP11D}pdp11_vh.c \
${PDP11D}pdp11_rh.c ${PDP11D}pdp11_tu.c ${PDP11D}pdp11_cpumod.c \
${PDP11D}pdp11_cr.c
${PDP11D}pdp11_cr.c ${PDP11D}pdp11_rf.c ${PDP11D}pdp11_dl.c
PDP11_OPT = -DVM_PDP11 -I ${PDP11D} ${NETWORK_OPT}
@ -175,7 +175,7 @@ I7094D = I7094/
I7094 = ${I7094D}i7094_cpu.c ${I7094D}i7094_cpu1.c ${I7094D}i7094_io.c \
${I7094D}i7094_cd.c ${I7094D}i7094_clk.c ${I7094D}i7094_com.c \
${I7094D}i7094_drm.c ${I7094D}i7094_dsk.c ${I7094D}i7094_sys.c \
${I7094D}i7094_lp.c ${I7094D}i7094_mt.c
${I7094D}i7094_lp.c ${I7094D}i7094_mt.c ${I7094D}i7094_binloader.c
I7094_OPT = -DUSE_INT64 -I ${I7094D}

16
scp.c
View file

@ -23,6 +23,7 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
14-Jul-06 RMS Added sim_activate_abs
14-Feb-06 RMS Upgraded save file format to V3.5
18-Jan-06 RMS Added fprint_stopped_gen
Added breakpoint spaces
@ -3780,6 +3781,21 @@ sim_interval = sim_clock_queue->time;
return SCPE_OK;
}
/* sim_activate_abs - activate (queue) event even if event already scheduled
Inputs:
uptr = pointer to unit
event_time = relative timeout
Outputs:
reason = result (SCPE_OK if ok)
*/
t_stat sim_activate_abs (UNIT *uptr, int32 event_time)
{
sim_cancel (uptr);
return sim_activate (uptr, event_time);
}
/* sim_cancel - cancel (dequeue) event
Inputs:

2
scp.h
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.
14-Jul-06 RMS Added sim_activate_abs
06-Jan-06 RMS Added fprint_stopped_gen
Changed arg type in sim_brk_test
07-Feb-05 RMS Added ASSERT command
@ -76,6 +77,7 @@ t_stat echo_cmd (int32 flag, char *ptr);
t_stat sim_process_event (void);
t_stat sim_activate (UNIT *uptr, int32 interval);
t_stat sim_activate_abs (UNIT *uptr, int32 interval);
t_stat sim_cancel (UNIT *uptr);
int32 sim_is_active (UNIT *uptr);
double sim_gtime (void);

View file

@ -1,6 +1,6 @@
/* sim_console.c: simulator console I/O library
Copyright (c) 1993-2005, Robert M Supnik
Copyright (c) 1993-2006, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -23,6 +23,8 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
22-Jun-06 RMS Implemented SET/SHOW PCHAR
31-May-06 JDB Fixed bug if SET CONSOLE DEBUG with no argument
22-Nov-05 RMS Added central input/output conversion support
05-Nov-04 RMS Moved SET/SHOW DEBUG under CONSOLE hierarchy
28-Oct-04 JDB Fixed SET CONSOLE to allow comma-separated parameters
@ -111,6 +113,7 @@ static CTAB set_con_tab[] = {
{ "WRU", &sim_set_kmap, KMAP_WRU | KMAP_NZ },
{ "BRK", &sim_set_kmap, KMAP_BRK },
{ "DEL", &sim_set_kmap, KMAP_DEL |KMAP_NZ },
{ "PCHAR", &sim_set_pchar, 0 },
{ "TELNET", &sim_set_telnet, 0 },
{ "NOTELNET", &sim_set_notelnet, 0 },
{ "LOG", &sim_set_logon, 0 },
@ -124,6 +127,7 @@ static SHTAB show_con_tab[] = {
{ "WRU", &sim_show_kmap, KMAP_WRU },
{ "BRK", &sim_show_kmap, KMAP_BRK },
{ "DEL", &sim_show_kmap, KMAP_DEL },
{ "PCHAR", &sim_show_pchar, 0 },
{ "LOG", &sim_show_log, 0 },
{ "TELNET", &sim_show_telnet, 0 },
{ "DEBUG", &sim_show_debug, 0 },
@ -210,13 +214,37 @@ return SCPE_OK;
t_stat sim_show_kmap (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
{
int32 rdx = 8;
if (sim_devices[0]->dradix == 16)
fprintf (st, "%s = %X\n", show_con_tab[flag].name, *(cons_kmap[flag & KMAP_MASK]));
else fprintf (st, "%s = %o\n", show_con_tab[flag].name, *(cons_kmap[flag & KMAP_MASK]));
return SCPE_OK;
}
dptr = sim_devices[0];
/* Set printable characters */
t_stat sim_set_pchar (int32 flag, char *cptr)
{
DEVICE *dptr = sim_devices[0];
uint32 val, rdx;
t_stat r;
if ((cptr == NULL) || (*cptr == 0)) return SCPE_2FARG;
if (dptr->dradix == 16) rdx = 16;
fprintf (st, "%s = ", show_con_tab[flag].name);
fprint_val (st, *(cons_kmap[flag & KMAP_MASK]), rdx, 7, 0);
fprintf (st, "\n");
else rdx = 8;
val = (uint32) get_uint (cptr, rdx, 0xFFFFFFFF, &r);
if ((r != SCPE_OK) ||
((val & 0x00002400) == 0)) return SCPE_ARG;
sim_tt_pchar = val;
return SCPE_OK;
}
/* Show printable characters */
t_stat sim_show_pchar (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
{
if (sim_devices[0]->dradix == 16)
fprintf (st, "pchar mask = %X\n", sim_tt_pchar);
else fprintf (st, "pchar mask = %o\n", sim_tt_pchar);
return SCPE_OK;
}
@ -266,7 +294,7 @@ t_stat sim_set_debon (int32 flag, char *cptr)
{
char *tptr, gbuf[CBUFSIZE];
if (*cptr == 0) return SCPE_2FARG; /* need arg */
if ((cptr == NULL) || (*cptr == 0)) return SCPE_2FARG; /* too few arguments? */
tptr = get_glyph (cptr, gbuf, 0); /* get file name */
if (*tptr != 0) return SCPE_2MARG; /* now eol? */
sim_set_deboff (0, NULL); /* close cur debug */

View file

@ -23,6 +23,7 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
22-Jun-06 RMS Implemented SET/SHOW PCHAR
22-Nov-05 RMS Added central input/output conversion support
05-Nov-04 RMS Moved SET/SHOW DEBUG under CONSOLE hierarchy
28-May-04 RMS Added SET/SHOW CONSOLE
@ -57,11 +58,13 @@ t_stat sim_set_logon (int32 flag, char *cptr);
t_stat sim_set_logoff (int32 flag, char *cptr);
t_stat sim_set_debon (int32 flag, char *cptr);
t_stat sim_set_deboff (int32 flag, char *cptr);
t_stat sim_set_pchar (int32 flag, char *cptr);
t_stat sim_show_console (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
t_stat sim_show_kmap (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
t_stat sim_show_telnet (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
t_stat sim_show_log (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
t_stat sim_show_debug (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
t_stat sim_show_pchar (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
t_stat sim_check_console (int32 sec);
t_stat sim_poll_kbd (void);
t_stat sim_putchar (int32 c);

View file

@ -23,6 +23,7 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
13-Jul-06 RMS Guarantee CBUFSIZE is at least 256
07-Jan-06 RMS Added support for breakpoint spaces
Added REG_FIT flag
16-Aug-05 RMS Fixed C++ declaration and cast problems
@ -160,7 +161,11 @@ typedef uint32 t_addr;
#if !defined (PATH_MAX) /* usually in limits */
#define PATH_MAX 512
#endif
#if (PATH_MAX >= 128)
#define CBUFSIZE (128 + PATH_MAX) /* string buf size */
#else
#define CBUFSIZE 256
#endif
/* Breakpoint spaces definitions */

View file

@ -1,6 +1,6 @@
/* sim_ether.c: OS-dependent network routines
------------------------------------------------------------------------------
Copyright (c) 2002-2005, David T. Hittner
Copyright (c) 2002-2006, David T. Hittner
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -134,6 +134,7 @@
Modification history:
10-Jul-06 RMS Fixed linux conditionalization (from Chaskiel Grundman)
15-Dec-05 DTH Patched eth_host_devices [remove non-ethernet devices]
(from Mark Pizzolato and Galen Tackett, 08-Jun-05)
Patched eth_open [tun fix](from Antal Ritter, 06-Oct-05)
@ -648,7 +649,7 @@ int eth_devices (int max, ETH_LIST* dev)
Return value: 0=Success, -1=Failure */
int pcap_sendpacket(pcap_t* handle, const u_char* msg, int len)
{
#if defined (linux)
#if defined (__linux)
return (send(pcap_fileno(handle), msg, len, 0) == len)? 0 : -1;
#else
return (write(pcap_fileno(handle), msg, len) == len)? 0 : -1;

View file

@ -23,6 +23,7 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
10-Jul-06 RMS Fixed linux conditionalization (from Chaskiel Grundman)
15-May-06 RMS Added sim_fsize_name
21-Apr-06 RMS Added FreeBSD large file support (from Mark Martinec)
19-Nov-05 RMS Added OS/X large file support (from Peter Schorn)
@ -160,7 +161,7 @@ FILE *sim_fopen (const char *file, const char *mode)
#if defined (VMS)
return fopen (file, mode, "ALQ=32", "DEQ=4096",
"MBF=6", "MBC=127", "FOP=cbt,tef", "ROP=rah,wbh", "CTX=stm");
#elif defined (USE_INT64) && defined (USE_ADDR64) && defined (linux)
#elif defined (USE_INT64) && defined (USE_ADDR64) && defined (__linux)
return fopen64 (file, mode);
#else
return fopen (file, mode);
@ -280,7 +281,7 @@ return fsetpos (st, &fileaddr);
/* Linux */
#if defined (linux)
#if defined (__linux)
#define _SIM_IO_FSEEK_EXT_ 1
int sim_fseek (FILE *st, t_addr xpos, int origin)

View file

@ -29,12 +29,72 @@
#define SIM_MAJOR 3
#define SIM_MINOR 6
#define SIM_PATCH 0
#define SIM_PATCH 1
/* V3.6 revision history
patch date module(s) and fix(es)
1 25-Jul-06 sim_console.c:
- implemented SET/SHOW PCHAR
all DECtapes:
- fixed conflict in ATTACH switches
hp2100_ms.c (from Dave Bryan):
- added CAPACITY as alternate for REEL
- fixed EOT test for unlimited reel size
i1620_cd.c (from Tom McBride):
- fixed card reader fgets call
- fixed card reader boot sequence
i7094_cd.c:
- fixed problem with 80 column full cards
i7094_cpu.c:
- fixed bug in halt IO wait loop
i7094_sys.c:
- added binary loader (courtesy of Dave Pitt)
pdp1_cpu.c:
- fixed bugs in MUS and DIV
pdp11_cis.c:
- added interrupt tests to character instructions
- added 11/44 stack probe test to MOVCx (only)
pdp11_dl.c:
- first release
pdp11_rf.c:
- first release
pdp11_stddev.c:
- added UC support to TTI, TTO
pdp18b_cpu.c:
- fixed RESET to clear AC, L, and MQ
pdp18b_dt.c:
- fixed checksum calculation bug for Type 550
pdp18b_fpp.c:
- fixed bugs in left shift, multiply
pdp18b_stddev.c:
- fixed Baudot letters/figures inversion for PDP-4
- fixed letters/figures tracking for PDP-4
- fixed PDP-4/PDP-7 default terminal to be local echo
pdp18b_sys.c:
- added Fiodec, Baudot display
- generalized LOAD to handle HRI, RIM, and BIN files
pdp8_ttx.c:
- fixed bug in DETACH routine
0 15-May-06 scp.c:
- revised save file format to save options, unit capacity