diff --git a/0readme_36.txt b/0readme_36.txt index 307e7846..ece7be4f 100644 --- a/0readme_36.txt +++ b/0readme_36.txt @@ -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 diff --git a/HP2100/hp2100_ms.c b/HP2100/hp2100_ms.c index 5cbcfeef..cf15e20f 100644 --- a/HP2100/hp2100_ms.c +++ b/HP2100/hp2100_ms.c @@ -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 | MTAB_NMO, 1, "REEL", "REEL", &ms_set_reelsize, &ms_show_reelsize, NULL }, - { MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", + { 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 */ + + case 0: + 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) */ diff --git a/I1620/i1620_cd.c b/I1620/i1620_cd.c index 08a8aca1..84169cdc 100644 --- a/I1620/i1620_cd.c +++ b/I1620/i1620_cd.c @@ -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 @@ -266,7 +268,7 @@ switch (op) { /* case on op */ default: /* invalid function */ return STOP_INVFNC; - } + } return sta; } @@ -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; } diff --git a/I1620/i1620_cpu.c b/I1620/i1620_cpu.c index fe91f587..eba47e6e 100644 --- a/I1620/i1620_cpu.c +++ b/I1620/i1620_cpu.c @@ -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 */ diff --git a/I7094/i7094_binloader.c b/I7094/i7094_binloader.c new file mode 100644 index 00000000..6089937e --- /dev/null +++ b/I7094/i7094_binloader.c @@ -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; +} diff --git a/I7094/i7094_cd.c b/I7094/i7094_cd.c index e960efe3..969693be 100644 --- a/I7094/i7094_cd.c +++ b/I7094/i7094_cd.c @@ -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); diff --git a/I7094/i7094_cpu.c b/I7094/i7094_cpu.c index 6a5175cb..9797444a 100644 --- a/I7094/i7094_cpu.c +++ b/I7094/i7094_cpu.c @@ -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 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); } diff --git a/I7094/i7094_sys.c b/I7094/i7094_sys.c index 10c6188c..652e15dc 100644 --- a/I7094/i7094_sys.c +++ b/I7094/i7094_sys.c @@ -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; } diff --git a/Interdata/id16_dboot.c b/Interdata/id16_dboot.c index e2c25a95..06ea5ac1 100644 --- a/Interdata/id16_dboot.c +++ b/Interdata/id16_dboot.c @@ -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, diff --git a/Interdata/id32_dboot.c b/Interdata/id32_dboot.c index 443e8549..28871b25 100644 --- a/Interdata/id32_dboot.c +++ b/Interdata/id32_dboot.c @@ -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, diff --git a/NOVA/eclipse_cpu.c b/NOVA/eclipse_cpu.c index 509297c6..202e37ff 100644 --- a/NOVA/eclipse_cpu.c +++ b/NOVA/eclipse_cpu.c @@ -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]; diff --git a/PDP1/pdp1_cpu.c b/PDP1/pdp1_cpu.c index f995851d..63c71e37 100644 --- a/PDP1/pdp1_cpu.c +++ b/PDP1/pdp1_cpu.c @@ -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; diff --git a/PDP1/pdp1_diag.txt b/PDP1/pdp1_diag.txt new file mode 100644 index 00000000..3b5d6db0 --- /dev/null +++ b/PDP1/pdp1_diag.txt @@ -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: ... diff --git a/PDP1/pdp1_dt.c b/PDP1/pdp1_dt.c index 69c95a88..9a1ff5bc 100644 --- a/PDP1/pdp1_dt.c +++ b/PDP1/pdp1_dt.c @@ -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; diff --git a/PDP1/pdp1_sys.c b/PDP1/pdp1_sys.c index 5ea6c323..d817d5b0 100644 --- a/PDP1/pdp1_sys.c +++ b/PDP1/pdp1_sys.c @@ -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)); diff --git a/PDP11/pdp11_cis.c b/PDP11/pdp11_cis.c index 847e3881..162137b3 100644 --- a/PDP11/pdp11_cis.c +++ b/PDP11/pdp11_cis.c @@ -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); + +/* 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; + } + } /* 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; + } + } /* end for lnts */ + } /* end else fwd */ + } /* end if move */ + for (i = 0; i < R[2]; i++) { + WriteB (R[4], ((R[3] + i) & 0177777) | dsenable); } - fill = A3LNT & 0377; /* do fill, if any */ - for (i = mvlnt; i < A2LNT; i++) { - WriteB (fill, ((A2ADR + i) & 0177777) | dsenable); - } - 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; - } - return; + 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); + +/* 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; + } + } /* 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; + } + } /* 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); } - fill = A3LNT & 0377; /* do fill, if any */ - for (i = mvlnt, j = 0; i < A2LNT; i++, j++) { - WriteB (fill, ((A2ADR + j) & 0177777) | dsenable); - } - 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; - } - return; + 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; +} diff --git a/PDP11/pdp11_cpu.c b/PDP11/pdp11_cpu.c index c80c8795..0bf28d5b 100644 --- a/PDP11/pdp11_cpu.c +++ b/PDP11/pdp11_cpu.c @@ -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; diff --git a/PDP11/pdp11_defs.h b/PDP11/pdp11_defs.h index 48e36c19..85ba923a 100644 --- a/PDP11/pdp11_defs.h +++ b/PDP11/pdp11_defs.h @@ -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 @@ -139,7 +141,7 @@ #define CPUT_F (CPUT_23|CPUT_23P|CPUT_24) /* all F11's */ #define CPUT_J (CPUT_53|CPUT_73|CPUT_73B| \ - CPUT_83|CPUT_84|CPUT_93|CPUT_94) + CPUT_83|CPUT_84|CPUT_93|CPUT_94) #define CPUT_JB (CPUT_73B|CPUT_83|CPUT_84) /* KDJ11B */ #define CPUT_JE (CPUT_93|CPUT_94) /* KDJ11E */ #define CPUT_JU (CPUT_84|CPUT_94) /* KTJ11B UBA */ @@ -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 diff --git a/PDP11/pdp11_dl.c b/PDP11/pdp11_dl.c new file mode 100644 index 00000000..fdfe7f9e --- /dev/null +++ b/PDP11/pdp11_dl.c @@ -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; +} diff --git a/PDP11/pdp11_io.c b/PDP11/pdp11_io.c index ebd3ed06..6a68ac26 100644 --- a/PDP11/pdp11_io.c +++ b/PDP11/pdp11_io.c @@ -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 */ diff --git a/PDP11/pdp11_rf.c b/PDP11/pdp11_rf.c new file mode 100644 index 00000000..52d410eb --- /dev/null +++ b/PDP11/pdp11_rf.c @@ -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 + +#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 */ + rf_cs |= RFCS_NED; +else rf_cs &= ~RFCS_NED; +if (rf_dae & RFDAE_ALLERR) /* update CS */ + rf_cs |= RFCS_FRZ; +else rf_cs &= ~RFCS_FRZ; +if (rf_cs & RFCS_ALLERR) /* update CS */ + 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; +} diff --git a/PDP11/pdp11_stddev.c b/PDP11/pdp11_stddev.c index b082b271..4386218a 100644 --- a/PDP11/pdp11_stddev.c +++ b/PDP11/pdp11_stddev.c @@ -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; diff --git a/PDP11/pdp11_sys.c b/PDP11/pdp11_sys.c index 079a9a02..1324f922 100644 --- a/PDP11/pdp11_sys.c +++ b/PDP11/pdp11_sys.c @@ -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 -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, diff --git a/PDP11/pdp11_tc.c b/PDP11/pdp11_tc.c index bac7fee6..dd1f3c82 100644 --- a/PDP11/pdp11_tc.c +++ b/PDP11/pdp11_tc.c @@ -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; diff --git a/PDP18B/pdp18b_cpu.c b/PDP18B/pdp18b_cpu.c index 8246df99..3cbc50a0 100644 --- a/PDP18B/pdp18b_cpu.c +++ b/PDP18B/pdp18b_cpu.c @@ -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; diff --git a/PDP18B/pdp18b_diag.txt b/PDP18B/pdp18b_diag.txt index ea0dadcd..74fbd1e4 100644 --- a/PDP18B/pdp18b_diag.txt +++ b/PDP18B/pdp18b_diag.txt @@ -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 diff --git a/PDP18B/pdp18b_dt.c b/PDP18B/pdp18b_dt.c index 367ab893..ac29f014 100644 --- a/PDP18B/pdp18b_dt.c +++ b/PDP18B/pdp18b_dt.c @@ -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; diff --git a/PDP18B/pdp18b_fpp.c b/PDP18B/pdp18b_fpp.c index eb6cc5e6..805004fe 100644 --- a/PDP18B/pdp18b_fpp.c +++ b/PDP18B/pdp18b_fpp.c @@ -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; } diff --git a/PDP18B/pdp18b_lp.c b/PDP18B/pdp18b_lp.c index 505878b0..f5a346f3 100644 --- a/PDP18B/pdp18b_lp.c +++ b/PDP18B/pdp18b_lp.c @@ -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; } } diff --git a/PDP18B/pdp18b_stddev.c b/PDP18B/pdp18b_stddev.c index 9f0f33bb..83cc8f84 100644 --- a/PDP18B/pdp18b_stddev.c +++ b/PDP18B/pdp18b_stddev.c @@ -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; diff --git a/PDP18B/pdp18b_sys.c b/PDP18B/pdp18b_sys.c index ee6037c3..b51ac04f 100644 --- a/PDP18B/pdp18b_sys.c +++ b/PDP18B/pdp18b_sys.c @@ -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: @@ -881,7 +887,7 @@ return sp; return = status code */ -#define FMTASC(x) (((x) < 040)? "<%03o>": "%c"), (x) +#define FMTASC(x) (((x) < 040)? "<%03o>": "%c"), (x) #define SIXTOASC(x) (((x) >= 040)? (x): ((x) + 0100)) t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, @@ -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]; diff --git a/PDP8/pdp8_dt.c b/PDP8/pdp8_dt.c index 35293a34..b9abc1de 100644 --- a/PDP8/pdp8_dt.c +++ b/PDP8/pdp8_dt.c @@ -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; diff --git a/PDP8/pdp8_td.c b/PDP8/pdp8_td.c index 0c43f8c9..9f7edbf3 100644 --- a/PDP8/pdp8_td.c +++ b/PDP8/pdp8_td.c @@ -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; diff --git a/PDP8/pdp8_ttx.c b/PDP8/pdp8_ttx.c index 5faefcd2..e12609b8 100644 --- a/PDP8/pdp8_ttx.c +++ b/PDP8/pdp8_ttx.c @@ -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; } diff --git a/descrip.mms b/descrip.mms index 8da57095..46524a48 100644 --- a/descrip.mms +++ b/descrip.mms @@ -374,7 +374,7 @@ PDP11_LIB1 = $(LIB_DIR)PDP11L1-$(ARCH).OLB PDP11_SOURCE1 = $(PDP11_DIR)PDP11_FP.C,$(PDP11_DIR)PDP11_CPU.C,\ $(PDP11_DIR)PDP11_DZ.C,$(PDP11_DIR)PDP11_CIS.C,\ $(PDP11_DIR)PDP11_LP.C,$(PDP11_DIR)PDP11_RK.C,\ - $(PDP11_DIR)PDP11_RL.C,$(PDP11_DIR)PDP11_RP.C,\ + $(PDP11_DIR)PDP11_RL.C,$(PDP11_DIR)PDP11_RP.C,\ $(PDP11_DIR)PDP11_RX.C,$(PDP11_DIR)PDP11_STDDEV.C,\ $(PDP11_DIR)PDP11_SYS.C,$(PDP11_DIR)PDP11_TC.C, \ $(PDP11_DIR)PDP11_CPUMOD.C,$(PDP11_DIR)PDP11_CR.C @@ -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)) diff --git a/makefile b/makefile index c190c9df..99b512d4 100644 --- a/makefile +++ b/makefile @@ -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} diff --git a/scp.c b/scp.c index 8a7ba590..aecbc14d 100644 --- a/scp.c +++ b/scp.c @@ -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: diff --git a/scp.h b/scp.h index c3d150a3..ed7c02aa 100644 --- a/scp.h +++ b/scp.h @@ -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); diff --git a/sim_console.c b/sim_console.c index 714c3095..9704c13e 100644 --- a/sim_console.c +++ b/sim_console.c @@ -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 */ diff --git a/sim_console.h b/sim_console.h index 17e4be69..7a69d7e1 100644 --- a/sim_console.h +++ b/sim_console.h @@ -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); diff --git a/sim_defs.h b/sim_defs.h index 7a234623..7c618861 100644 --- a/sim_defs.h +++ b/sim_defs.h @@ -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 */ diff --git a/sim_ether.c b/sim_ether.c index 774111f2..1010b1f9 100644 --- a/sim_ether.c +++ b/sim_ether.c @@ -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; diff --git a/sim_fio.c b/sim_fio.c index fdeca62f..bb460ff1 100644 --- a/sim_fio.c +++ b/sim_fio.c @@ -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) diff --git a/sim_rev.h b/sim_rev.h index c15c5900..af6079ee 100644 --- a/sim_rev.h +++ b/sim_rev.h @@ -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