diff --git a/0readme_210.txt b/0readme_210.txt index 194a44b7..2dc98947 100644 --- a/0readme_210.txt +++ b/0readme_210.txt @@ -1,92 +1,37 @@ -Notes For V2.10-2 +Notes For V2.10-3 -1. New Features in 2.10-2 - -The build procedures have changed. There is only one UNIX makefile. -To compile without Ethernet support, simply type - - gmake {target|all} - -To compile with Ethernet support, type - - gmake USE_NETWORK=1 {target|all} - -The Mingw batch files require Mingw release 2 and invoke the Unix -makefile. There are still separate batch files for compilation -with or without Ethernet support. +1. New Features in 2.10-3 1.1 SCP and Libraries -- The EVAL command will evaluate a symbolic type-in and display - it in numeric form. -- The ! command (with no arguments) will launch the host operating - system command shell. The ! command (with an argument) executes - the argument as a host operating system command. (Code from - Mark Pizzolato) -- Telnet sessions now recognize BREAK. How a BREAK is transmitted - dependent on the particular Telnet client. (Code from Mark - Pizzolato) -- The sockets library includes code for active connections as - well as listening connections. -- The RESTORE command will restore saved memory size, if the - simulator supports dynamic memory resizing. +- Added dynamic extension of the breakpoint table. +- Added breakpoint actions. +- Added VMS support for ! (from Mark Pizzolato). -1.2 PDP-1 +1.2 18b PDP's -- The PDP-1 supports the Type 24 serial drum (based on recently - discovered documents). +- Added RB09 fixed head disk for the PDP-9. +- Added LP09 line printer for the PDP-9 and PDP-15. +- Added variable size support and autosizing to the RF15/RF09. -1.3 18b PDP's +1.3 PDP-8 -- The PDP-4 supports the Type 24 serial drum (based on recently - discovered documents). +- Added variable size support and autosizing to the DF32 and RF08. -1.4 PDP-11 +1.4 Nova -- The PDP-11 implements a stub DEUNA/DELUA (XU). The real XU - module will be included in a later release. +- Added variable size support and autosizing to the Novadisk. -1.5 PDP-10 +2. Bugs Fixed in 2.10-3 -- The PDP-10 implements a stub DEUNA/DELUA (XU). The real XU - module will be included in a later release. - -1.6 HP 2100 - -- The IOP microinstruction set is supported for the 21MX as well - as the 2100. -- The HP2100 supports the Access Interprocessor Link (IPL). - -1.7 VAX - -- If the VAX console is attached to a Telnet session, BREAK is - interpreted as console halt. -- The SET/SHOW HISTORY commands enable and display a history of - the most recently executed instructions. (Code from Mark - Pizzolato) - -1.8 Terminals Multiplexors - -- BREAK detection was added to the HP, DEC, and Interdata terminal - multiplexors. - -1.9 Interdata 16b and 32b - -- First release. UNIX is not yet working. - -1.10 SDS 940 - -- First release. - -2. Bugs Fixed in 2.10-2 - -- PDP-11 console must default to 7b for early UNIX compatibility. -- PDP-11/VAX TMSCP emulator was using the wrong packet length for - read/write end packets. -- Telnet IAC+IAC processing was fixed, both for input and output - (found by Mark Pizzolato). -- PDP-11/VAX Ethernet setting flag bits wrong for chained - descriptors (found by Mark Pizzolato). +- 18b PDP RF15/RF09: fixed IOT decoding and address wraparound + logic (found by Hans Pufal). +- 18b PDP RP15: fixed IOT decoding and command initiation. +- HP2100 IPL: changed to full duplex (found by Mike Gemeny). +- HP2100 CPU: fixed last cycle bug in DMA outpout (found by Mike + Gemeny). +- Interdata 16b CPU: fixed bug in SETM, SETMR (found by Mark + Pizzolato). 3. New Features in 2.10 vs prior releases @@ -117,6 +62,19 @@ with or without Ethernet support. to add an additional parameter. - SAVE now saves, and GET now restores, controller and unit flags. - Library sim_ether.c has been added for Ethernet support. +- The EVAL command will evaluate a symbolic type-in and display + it in numeric form. +- The ! command (with no arguments) will launch the host operating + system command shell. The ! command (with an argument) executes + the argument as a host operating system command. (Code from + Mark Pizzolato) +- Telnet sessions now recognize BREAK. How a BREAK is transmitted + dependent on the particular Telnet client. (Code from Mark + Pizzolato) +- The sockets library includes code for active connections as + well as listening connections. +- The RESTORE command will restore saved memory size, if the + simulator supports dynamic memory resizing. 3.2 VAX @@ -137,6 +95,11 @@ with or without Ethernet support. - Examine and deposit switches now work on all devices, not just the CPU. - Device address conflicts are not detected until simulation starts. +- If the VAX console is attached to a Telnet session, BREAK is + interpreted as console halt. +- The SET/SHOW HISTORY commands enable and display a history of + the most recently executed instructions. (Code from Mark + Pizzolato) 3.3 PDP-11 @@ -159,6 +122,8 @@ with or without Ethernet support. configuration, causes all peripherals that are not compatible with the current bus configuration to be disabled. - Device address conflicts are not detected until simulation starts. +- The PDP-11 implements a stub DEUNA/DELUA (XU). The real XU + module will be included in a later release. 3.4 PDP-10 @@ -171,13 +136,22 @@ with or without Ethernet support. - The paper tape now references a common implementation file, dec_pt.h. - Device address conflicts are not detected until simulation starts. +- The PDP-10 implements a stub DEUNA/DELUA (XU). The real XU + module will be included in a later release. 3.5 PDP-1 - DECtape (then known as MicroTape) support has been added. - The line printer and DECtape can be disabled and enabled. +- The PDP-1 supports the Type 24 serial drum (based on recently + discovered documents). -3.6 PDP-8 +3.6 18b PDP's + +- The PDP-4 supports the Type 24 serial drum (based on recently + discovered documents). + +3.7 PDP-8 - The RX28 (double density floppy) has been added as an option to the existing RX8E controller. @@ -186,10 +160,6 @@ with or without Ethernet support. DEVNO=nnn. - Device number conflicts are not detected until simulation starts. -3.7 IBM 1620 - -- The IBM 1620 simulator has been released. - 3.8 AltairZ80 - A hard drive has been added for increased storage. @@ -211,6 +181,9 @@ with or without Ethernet support. - New CPU options (DMS/NODMS) enable/disable the dynamic mapping instructions for the 21MX. - The 12539 timebase generator autocalibrates. +- The IOP microinstruction set is supported for the 21MX as well + as the 2100. +- The HP2100 supports the Access Interprocessor Link (IPL). 3.10 Simulated Magtapes @@ -224,6 +197,11 @@ with or without Ethernet support. - Added support for RT11 image file format (256 x 16b) to DECtapes. +3.12 Terminals Multiplexors + +- BREAK detection was added to the HP, DEC, and Interdata terminal + multiplexors. + 4. Bugs Fixed in 2.10 vs prior releases - TS11/TSV05 was not simulating the XS0_MOT bit, causing failures @@ -242,9 +220,29 @@ with or without Ethernet support. Michael Thompson and Harris Newman, respectively) - PDP-1 typewriter is half duplex, with only one shift state for both input and output (found by Derek Peschel) +- PDP-11 console must default to 7b for early UNIX compatibility. +- PDP-11/VAX TMSCP emulator was using the wrong packet length for + read/write end packets. +- Telnet IAC+IAC processing was fixed, both for input and output + (found by Mark Pizzolato). +- PDP-11/VAX Ethernet setting flag bits wrong for chained + descriptors (found by Mark Pizzolato). 5. General Notes +WARNING: The build procedures have changed. There is only one UNIX +makefile. To compile without Ethernet support, simply type + + gmake {target|all} + +To compile with Ethernet support, type + + gmake USE_NETWORK=1 {target|all} + +The Mingw batch files require Mingw release 2 and invoke the Unix +makefile. There are still separate batch files for compilation +with or without Ethernet support. + WARNING: V2.10 has reorganized and renamed some of the definition files for the PDP-10, PDP-11, and VAX. Be sure to delete all previous source files before you unpack the Zip archive, or diff --git a/HP2100/hp2100_cpu.c b/HP2100/hp2100_cpu.c index 68e4ebdc..ea33b049 100644 --- a/HP2100/hp2100_cpu.c +++ b/HP2100/hp2100_cpu.c @@ -1,6 +1,6 @@ /* hp2100_cpu.c: HP 2100 CPU simulator - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, 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 @@ 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. + 02-Feb-03 RMS Fixed last cycle bug in DMA output (found by Mike Gemeny) 22-Nov-02 RMS Added 21MX IOP support 24-Oct-02 RMS Fixed bugs in IOP and extended instructions Fixed bugs in memory protection and DMS @@ -2349,7 +2350,17 @@ if (IR & I_HC) { clrFLG (DMA0 + ch); } /* HC option */ return dat; } -/* DMA cycle routine */ +/* DMA cycle routine + + The last cycle (word count reaches 0) logic is quite tricky. + Input cases: + - CLC requested: issue CLC + Output cases: + - neither STC nor CLC requested: issue CLF + - CLC requested but not STC: issue CLC,C + - STC requested but not CLC: issue STC,C + - STC and CLC both requested: issue STC,C and CLC,C +*/ void dma_cycle (uint32 ch, uint32 map) { @@ -2369,11 +2380,17 @@ if (dmac[ch].cw3) { /* more to do? */ if (dmac[ch].cw1 & DMA1_STC) /* if STC flag, */ devdisp (dev, ioCTL, I_HC + dev, 0); /* do STC,C dev */ else devdisp (dev, ioFLG, I_HC + dev, 0); } /* else CLF dev */ -else { if (!inp) devdisp (dev, ioFLG, I_HC + dev, 0); /* output? clr flag */ - if (dmac[ch].cw1 & DMA1_CLC) /* CLC at end? */ - devdisp (dev, ioCTL, I_CTL + dev, 0); /* yes */ - else if (!inp && (dmac[ch].cw1 & DMA1_STC)) /* STC && output? */ - devdisp (dev, ioCTL, I_HC + dev, 0); /* STC,C */ +else { if (inp) { /* last cycle, input? */ + if (dmac[ch].cw1 & DMA1_CLC) /* CLC at end? */ + devdisp (dev, ioCTL, I_CTL + dev, 0); /* yes */ + } /* end input */ + else { /* output */ + devdisp (dev, ioFLG, I_HC + dev, 0); /* clear flag */ + if (dmac[ch].cw1 & DMA1_STC) /* if STC flag, */ + devdisp (dev, ioCTL, dev, 0); /* do STC dev */ + if (dmac[ch].cw1 & DMA1_CLC) /* CLC at end? */ + devdisp (dev, ioCTL, I_CTL + dev, 0); /* yes */ + } /* end output */ setFLG (DMA0 + ch); /* set DMA flg */ clrCMD (DMA0 + ch); } /* clr DMA cmd */ return; diff --git a/HP2100/hp2100_doc.txt b/HP2100/hp2100_doc.txt index 58b77bb2..7f942089 100644 --- a/HP2100/hp2100_doc.txt +++ b/HP2100/hp2100_doc.txt @@ -75,7 +75,7 @@ PTR,PTP 12597A paper tape reader/punch TTY 12631C buffered terminal controller LPS 12653A printer controller with 2767 printer 12566B microcircuit interface for diagnostics -LPT 12845A printer controller +LPT 12845A printer controller with 2607 printer CLK 12539A/B/C time base generator MUXL,MUXU,MUXC 12920A terminal multiplexor DP 12557A disk controller with four 2871 drives diff --git a/HP2100/hp2100_ipl.c b/HP2100/hp2100_ipl.c index a1fbfa43..e5c95cb1 100644 --- a/HP2100/hp2100_ipl.c +++ b/HP2100/hp2100_ipl.c @@ -1,6 +1,6 @@ /* hp2100_ipl.c: HP 2000 interprocessor link simulator - Copyright (c) 2002, Robert M Supnik + Copyright (c) 2002-2003, 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"), @@ -24,6 +24,8 @@ in this Software without prior written authorization from Robert M Supnik. ipli, iplo 12556B interprocessor link pair + + 31-Jan-03 RMS Links are full duplex (found by Mike Gemeny) */ #include "hp2100_defs.h" @@ -33,19 +35,22 @@ #define UNIT_V_DIAG (UNIT_V_UF + 0) /* diagnostic mode */ #define UNIT_V_ACTV (UNIT_V_UF + 1) /* making connection */ #define UNIT_V_ESTB (UNIT_V_UF + 2) /* connection established */ +#define UNIT_V_HOLD (UNIT_V_UF + 3) /* character holding */ #define UNIT_DIAG (1 << UNIT_V_DIAG) #define UNIT_ACTV (1 << UNIT_V_ACTV) #define UNIT_ESTB (1 << UNIT_V_ESTB) +#define UNIT_HOLD (1 << UNIT_V_HOLD) +#define IBUF buf /* input buffer */ +#define OBUF wait /* output buffer */ #define DSOCKET u3 /* data socket */ #define LSOCKET u4 /* listening socket */ -#define HOLD wait /* holding byte */ -#define IPL_HOLD 0100000 extern uint32 PC; extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2]; extern FILE *sim_log; int32 ipl_ptime = 400; /* polling interval */ int32 ipl_stopioe = 0; /* stop on error */ +int32 ipl_hold[2] = { 0 }; /* holding character */ DEVICE ipli_dev, iplo_dev; int32 ipliio (int32 inst, int32 IR, int32 dat); @@ -82,12 +87,13 @@ UNIT ipl_unit[] = { #define iplo_unit ipl_unit[1] REG ipli_reg[] = { - { ORDATA (BUF, ipli_unit.buf, 16) }, + { ORDATA (IBUF, ipli_unit.IBUF, 16) }, + { ORDATA (OBUF, ipli_unit.OBUF, 16) }, { FLDATA (CMD, ipli_dib.cmd, 0) }, { FLDATA (CTL, ipli_dib.ctl, 0) }, { FLDATA (FLG, ipli_dib.flg, 0) }, { FLDATA (FBF, ipli_dib.fbf, 0) }, - { ORDATA (HOLD, ipli_unit.HOLD, 16) }, + { ORDATA (HOLD, ipl_hold[0], 8) }, { DRDATA (TIME, ipl_ptime, 24), PV_LEFT }, { FLDATA (STOP_IOE, ipl_stopioe, 0) }, { ORDATA (DEVNO, ipli_dib.devno, 6), REG_HRO }, @@ -117,12 +123,13 @@ DEVICE ipli_dev = { */ REG iplo_reg[] = { - { ORDATA (BUF, iplo_unit.buf, 16) }, + { ORDATA (IBUF, iplo_unit.IBUF, 16) }, + { ORDATA (OBUF, iplo_unit.OBUF, 16) }, { FLDATA (CMD, iplo_dib.cmd, 0) }, { FLDATA (CTL, iplo_dib.ctl, 0) }, { FLDATA (FLG, iplo_dib.flg, 0) }, { FLDATA (FBF, iplo_dib.fbf, 0) }, - { ORDATA (HOLD, iplo_unit.HOLD, 16) }, + { ORDATA (HOLD, ipl_hold[1], 8) }, { DRDATA (TIME, ipl_ptime, 24), PV_LEFT }, { ORDATA (DEVNO, iplo_dib.devno, 6), REG_HRO }, { NULL } }; @@ -164,13 +171,13 @@ case ioSFS: /* skip flag set */ if (FLG (dev) != 0) PC = (PC + 1) & VAMASK; return dat; case ioOTX: /* output */ - uptr->buf = dat; + uptr->OBUF = dat; break; case ioLIX: /* load */ - dat = uptr->buf; /* return val */ + dat = uptr->IBUF; /* return val */ break; case ioMIX: /* merge */ - dat = dat | uptr->buf; /* get return data */ + dat = dat | uptr->IBUF; /* get return data */ break; case ioCTL: /* control clear/set */ if (IR & I_CTL) { /* CLC */ @@ -184,8 +191,8 @@ case ioCTL: /* control clear/set */ if (!ipl_check_conn (uptr)) /* not established? */ return STOP_NOCONN; /* lose */ uptr->flags = uptr->flags | UNIT_ESTB; } - msg[0] = (uptr->buf >> 8) & 0377; - msg[1] = uptr->buf & 0377; + msg[0] = (uptr->OBUF >> 8) & 0377; + msg[1] = uptr->OBUF & 0377; sta = sim_write_sock (uptr->DSOCKET, msg, 2); if (sta == SOCKET_ERROR) { printf ("IPL: socket write error\n"); @@ -193,7 +200,7 @@ case ioCTL: /* control clear/set */ sim_os_sleep (0); } else if (uptr->flags & UNIT_DIAG) { /* diagnostic mode? */ u = (uptr - ipl_unit) ^ 1; /* find other device */ - ipl_unit[u].buf = uptr->buf; /* output to other */ + ipl_unit[u].IBUF = uptr->OBUF; /* output to other */ odev = ipl_dib[u].devno; /* other device no */ setFLG (odev); } /* set other flag */ else return SCPE_UNATT; } /* lose */ @@ -211,23 +218,25 @@ t_stat ipl_svc (UNIT *uptr) int32 u, nb, dev; int8 msg[2]; +u = uptr - ipl_unit; /* get link number */ if ((uptr->flags & UNIT_ATT) == 0) return SCPE_OK; /* not attached? */ sim_activate (uptr, ipl_ptime); /* reactivate */ if ((uptr->flags & UNIT_ESTB) == 0) { /* not established? */ if (!ipl_check_conn (uptr)) return SCPE_OK; /* check for conn */ uptr->flags = uptr->flags | UNIT_ESTB; } -nb = sim_read_sock (uptr->DSOCKET, msg, uptr->HOLD? 1: 2); +nb = sim_read_sock (uptr->DSOCKET, msg, ((uptr->flags & UNIT_HOLD)? 1: 2)); if (nb < 0) { /* connection closed? */ printf ("IPL: socket read error\n"); return SCPE_IOERR; } if (nb == 0) return SCPE_OK; /* no data? */ -if (uptr->HOLD) { /* holdover byte? */ - uptr->buf = ((uptr->HOLD & 0377) << 8) | (((int32) msg[0]) & 0377); - uptr->HOLD = 0; } -else if (nb == 1) uptr->HOLD = (((int32) msg[0]) & 0377) | IPL_HOLD; -else uptr->buf = ((((int32) msg[0]) & 0377) << 8) | +if (uptr->flags & UNIT_HOLD) { /* holdover byte? */ + uptr->IBUF = (ipl_hold[u] << 8) | (((int32) msg[0]) & 0377); + uptr->flags = uptr->flags & ~UNIT_HOLD; } +else if (nb == 1) { + ipl_hold[u] = ((int32) msg[0]) & 0377; + uptr->flags = uptr->flags | UNIT_HOLD; } +else uptr->IBUF = ((((int32) msg[0]) & 0377) << 8) | (((int32) msg[1]) & 0377); -u = uptr - ipl_unit; /* get link number */ dev = ipl_dib[u].devno; /* get device number */ clrCMD (dev); /* clr cmd, set flag */ setFLG (dev); @@ -258,9 +267,10 @@ UNIT *uptr = dptr->units; hp_enbdis_pair (&ipli_dev, &iplo_dev); /* make pair cons */ dibp->cmd = dibp->ctl = 0; /* clear cmd, ctl */ dibp->flg = dibp->fbf = 1; /* set flg, fbf */ -uptr->buf = uptr->HOLD = 0; +uptr->IBUF = uptr->OBUF = 0; /* clr buffers */ if (uptr->flags & UNIT_ATT) sim_activate (uptr, ipl_ptime); else sim_cancel (uptr); /* deactivate unit */ +uptr->flags = uptr->flags & ~UNIT_HOLD; return SCPE_OK; } @@ -305,8 +315,8 @@ else { if (ipa != 0) return SCPE_ARG; uptr->flags = uptr->flags & ~UNIT_ACTV; uptr->LSOCKET = newsock; uptr->DSOCKET = 0; } -uptr->buf = uptr->HOLD = 0; -uptr->flags = (uptr->flags | UNIT_ATT) & ~UNIT_ESTB; /* no more errors */ +uptr->IBUF = uptr->OBUF = 0; +uptr->flags = (uptr->flags | UNIT_ATT) & ~(UNIT_ESTB | UNIT_HOLD); tptr = malloc (strlen (cptr) + 1); /* get string buf */ if (tptr == NULL) { /* no memory? */ ipl_detach (uptr); /* close sockets */ diff --git a/Interdata/id16_cpu.c b/Interdata/id16_cpu.c index dfd4c606..d7c28260 100644 --- a/Interdata/id16_cpu.c +++ b/Interdata/id16_cpu.c @@ -23,6 +23,8 @@ 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. + 07-Feb-03 RMS Fixed bug in SETM, SETMR (found by Mark Pizzolato) + The register state for the Interdata 16b CPU is: R[0:F]<0:15> general registers @@ -1158,7 +1160,7 @@ case 0x53: /* SETM - RXH */ break; } t = (t & ~PSW_MAP) | (map << PSW_V_MAP); /* insert map */ newPSW (t); /* load new PSW */ - CC_GL_16 (rslt); /* set G,L */ + CC_GL_16 (R[r1]); /* set G,L */ break; /* I/O instructions */ diff --git a/Interdata/id32_cpu.c b/Interdata/id32_cpu.c index 3a0b204d..5922d606 100644 --- a/Interdata/id32_cpu.c +++ b/Interdata/id32_cpu.c @@ -1987,6 +1987,8 @@ IOWriteB (addr, val & 0xFF); return SCPE_OK; } +/* Change memory size */ + t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) { uint32 mc = 0; diff --git a/NOVA/nova_cpu.c b/NOVA/nova_cpu.c index e97fe5f2..b61d9216 100644 --- a/NOVA/nova_cpu.c +++ b/NOVA/nova_cpu.c @@ -1,6 +1,6 @@ /* nova_cpu.c: NOVA CPU simulator - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, 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 Nova central processor + 19-Jan-03 RMS Changed CMASK to CDMASK for Apple Dev Kit conflict 03-Oct-02 RMS Added DIB infrastructure 30-Dec-01 RMS Added old PC queue 07-Dec-01 RMS Revised to use breakpoint package @@ -391,21 +392,21 @@ if (IR & I_OPR) { /* operate? */ src = src ^ DMASK; break; case 1: /* NEG */ - src = ((src ^ DMASK) + 1) & CMASK; + src = ((src ^ DMASK) + 1) & CDMASK; break; case 2: /* MOV */ break; case 3: /* INC */ - src = (src + 1) & CMASK; + src = (src + 1) & CDMASK; break; case 4: /* ADC */ - src = ((src ^ DMASK) + AC[dstAC]) & CMASK; + src = ((src ^ DMASK) + AC[dstAC]) & CDMASK; break; case 5: /* SUB */ - src = ((src ^ DMASK) + AC[dstAC] + 1) & CMASK; + src = ((src ^ DMASK) + AC[dstAC] + 1) & CDMASK; break; case 6: /* ADD */ - src = (src + AC[dstAC]) & CMASK; + src = (src + AC[dstAC]) & CDMASK; break; case 7: /* AND */ src = src & (AC[dstAC] | CBIT); @@ -417,10 +418,10 @@ if (IR & I_OPR) { /* operate? */ case 0: /* nop */ break; case 1: /* L */ - src = ((src << 1) | (src >> 16)) & CMASK; + src = ((src << 1) | (src >> 16)) & CDMASK; break; case 2: /* R */ - src = ((src >> 1) | (src << 16)) & CMASK; + src = ((src >> 1) | (src << 16)) & CDMASK; break; case 3: /* S */ src = ((src & 0377) << 8) | ((src >> 8) & 0377) | diff --git a/NOVA/nova_defs.h b/NOVA/nova_defs.h index 15db1b2d..abbc40a7 100644 --- a/NOVA/nova_defs.h +++ b/NOVA/nova_defs.h @@ -1,6 +1,6 @@ /* nova_defs.h: NOVA/Eclipse simulator definitions - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, 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 @@ 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. + 19-Jan-03 RMS Changed CMASK to CDMASK for Apple Dev kit conflict 03-Oct-02 RMS Added device information structure 22-Dec-00 RMS Added Bruce Ray's second terminal support 10-Dec-00 RMS Added Charles Owen's Eclipse support @@ -67,7 +68,7 @@ #define SIGN 0100000 /* sign */ #define DMASK 0177777 /* data mask */ #define CBIT (DMASK + 1) /* carry bit */ -#define CMASK (CBIT | DMASK) /* carry + data */ +#define CDMASK (CBIT | DMASK) /* carry + data */ /* Reserved memory locations */ diff --git a/NOVA/nova_doc.txt b/NOVA/nova_doc.txt index 35667828..c3138c4d 100644 --- a/NOVA/nova_doc.txt +++ b/NOVA/nova_doc.txt @@ -1,14 +1,14 @@ To: Users From: Bob Supnik Subj: Nova Simulator Usage -Date: 15-Nov-2002 +Date: 1-Feb-2003 COPYRIGHT NOTICE The following copyright notice applies to both the SIMH source and binary: - Original code published in 1993-2002, written by Robert M Supnik - Copyright (c) 1993-2002, Robert M Supnik + Original code published in 1993-2003, written by Robert M Supnik + Copyright (c) 1993-2003, 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"), @@ -383,6 +383,22 @@ The second terminal output implements these registers: 2.3 Fixed Head Disk (DK) +Fixed head disk options include the ability to set the number of platters +to a fixed value between 1 and 8, or to autosize the number of platters +from the attached file: + + SET RF 1P one platter (256K) + SET RF 2P two platters (512K) + SET RF 3P three platters (768K) + SET RF 4P four platters (1024K) + SET RF 5P five platters (1280K) + SET RF 6P six platters (1536K) + SET RF 7P seven platters (1792K) + SET RF 8P eight platters (2048K) + SET RF AUTOSIZE autosized on attach + +The default is 8P (maximum size). + The fixed head disk controller implements these registers: name size comments diff --git a/NOVA/nova_dsk.c b/NOVA/nova_dsk.c index d1283521..1c562763 100644 --- a/NOVA/nova_dsk.c +++ b/NOVA/nova_dsk.c @@ -1,6 +1,6 @@ /* nova_dsk.c: 4019 fixed head disk simulator - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, 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"), @@ -40,15 +40,19 @@ #include "nova_defs.h" #include +#define UNIT_V_AUTO (UNIT_V_UF + 0) /* autosize */ +#define UNIT_V_MSIZE (UNIT_V_UF + 1) /* dummy mask */ +#define UNIT_AUTO (1 << UNIT_V_AUTO) +#define UNIT_MSIZE (1 << UNIT_V_MSIZE) + /* Constants */ #define DSK_NUMWD 256 /* words/sector */ #define DSK_NUMSC 8 /* sectors/track */ #define DSK_NUMTR 128 /* tracks/disk */ +#define DSK_DKSIZE (DSK_NUMTR*DSK_NUMSC*DSK_NUMWD) /* words/disk */ +#define DSK_AMASK ((DSK_NUMDK*DSK_NUMTR*DSK_NUMSC) - 1) /* address mask */ #define DSK_NUMDK 8 /* disks/controller */ -#define DSK_SCSIZE (DSK_NUMDK*DSK_NUMTR*DSK_NUMSC) /* sectors/drive */ -#define DSK_AMASK (DSK_SCSIZE - 1) /* address mask */ -#define DSK_SIZE (DSK_SCSIZE * DSK_NUMWD) /* words/drive */ #define GET_DISK(x) (((x) / (DSK_NUMSC * DSK_NUMTR)) & (DSK_NUMDK - 1)) /* Parameters in the unit descriptor */ @@ -94,6 +98,8 @@ int32 dsk (int32 pulse, int32 code, int32 AC); t_stat dsk_svc (UNIT *uptr); t_stat dsk_reset (DEVICE *dptr); t_stat dsk_boot (int32 unitno, DEVICE *dptr); +t_stat dsk_attach (UNIT *uptr, char *cptr); +t_stat dsk_set_size (UNIT *uptr, int32 val, char *cptr, void *desc); /* DSK data structures @@ -106,7 +112,7 @@ DIB dsk_dib = { DEV_DSK, INT_DSK, PI_DSK, &dsk }; UNIT dsk_unit = { UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF, - DSK_SIZE) }; + DSK_NUMDK * DSK_DKSIZE) }; REG dsk_reg[] = { { ORDATA (STAT, dsk_stat, 16) }, @@ -121,11 +127,23 @@ REG dsk_reg[] = { { FLDATA (STOP_IOE, dsk_stopioe, 0) }, { NULL } }; +MTAB dsk_mod[] = { + { UNIT_MSIZE, 262144, NULL, "1P", &dsk_set_size }, + { UNIT_MSIZE, 524288, NULL, "2P", &dsk_set_size }, + { UNIT_MSIZE, 786432, NULL, "3P", &dsk_set_size }, + { UNIT_MSIZE, 1048576, NULL, "4P", &dsk_set_size }, + { UNIT_MSIZE, 1310720, NULL, "5P", &dsk_set_size }, + { UNIT_MSIZE, 1572864, NULL, "6P", &dsk_set_size }, + { UNIT_MSIZE, 1835008, NULL, "7P", &dsk_set_size }, + { UNIT_MSIZE, 2097152, NULL, "8P", &dsk_set_size }, + { UNIT_AUTO, UNIT_AUTO, "autosize", "AUTOSIZE", NULL }, + { 0 } }; + DEVICE dsk_dev = { - "DK", &dsk_unit, dsk_reg, NULL, + "DK", &dsk_unit, dsk_reg, dsk_mod, 1, 8, 21, 1, 8, 16, NULL, NULL, &dsk_reset, - &dsk_boot, NULL, NULL, + &dsk_boot, &dsk_attach, NULL, &dsk_dib, DEV_DISABLE }; /* IOT routine */ @@ -245,3 +263,35 @@ for (i = 0; i < BOOT_LEN; i++) M[BOOT_START + i] = boot_rom[i]; saved_PC = BOOT_START; return SCPE_OK; } + +/* Attach routine */ + +t_stat dsk_attach (UNIT *uptr, char *cptr) +{ +int32 p, d; +int32 ds_bytes = DSK_DKSIZE * sizeof (int16); + +if (uptr->flags & UNIT_AUTO) { + FILE *fp = fopen (cptr, "rb"); + if (fp == NULL) return SCPE_OPENERR; + fseek (fp, 0, SEEK_END); + p = ftell (fp); + d = (p + ds_bytes - 1) / ds_bytes; + if (d == 0) d = 1; + if (d > DSK_NUMDK) d = DSK_NUMDK; + uptr->capac = d * DSK_DKSIZE; + fclose (fp); } +return attach_unit (uptr, cptr); +} + +/* Change disk size */ + +t_stat dsk_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) +{ +if ((val == 0) || (val > (DSK_NUMDK * DSK_DKSIZE))) + return SCPE_IERR; +if (uptr->flags & UNIT_ATT) return SCPE_ALATT; +uptr->capac = val; +uptr->flags = uptr->flags & ~UNIT_AUTO; +return SCPE_OK; +} diff --git a/PDP10/pdp10_rp.c b/PDP10/pdp10_rp.c index f1794119..9b786c01 100644 --- a/PDP10/pdp10_rp.c +++ b/PDP10/pdp10_rp.c @@ -339,7 +339,7 @@ int32 rpiff = 0; /* INTR flip/flop */ int32 rp_stopioe = 1; /* stop on error */ int32 rp_swait = 10; /* seek time */ int32 rp_rwait = 10; /* rotate time */ -int reg_in_drive[32] = { +static int32 reg_in_drive[32] = { 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -972,7 +972,7 @@ return SCPE_OK; t_stat rp_attach (UNIT *uptr, char *cptr) { -int drv, i, p; +int32 drv, i, p; t_stat r; uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size; diff --git a/PDP10/pdp10_tu.c b/PDP10/pdp10_tu.c index fd5ac0c2..2bc26d77 100644 --- a/PDP10/pdp10_tu.c +++ b/PDP10/pdp10_tu.c @@ -1,6 +1,6 @@ /* pdp10_tu.c - PDP-10 RH11/TM03/TU45 magnetic tape simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, 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 @@ tu RH11/TM03/TU45 magtape + 27-Jan-03 RMS Changed to dynamically allocate buffer 21-Nov-02 RMS Fixed bug in bootstrap (reported by Michael Thompson) Fixed bug in read (reported by Harris Newman) 29-Sep-02 RMS Added variable vector support @@ -296,16 +297,17 @@ int32 tuiff = 0; /* INTR flip/flop */ int32 tu_time = 10; /* record latency */ int32 tu_stopioe = 1; /* stop on error */ int32 tu_log = 0; /* debug */ -int reg_in_fmtr[32] = { /* reg in formatter */ +int32 reg_in_fmtr[32] = { /* reg in formatter */ 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; -int reg_in_fmtr1[32] = { /* rmr if write + go */ +int32 reg_in_fmtr1[32] = { /* rmr if write + go */ 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; -int fmt_test[16] = { /* fmt bytes/10 wd */ +int32 fmt_test[16] = { /* fmt bytes/10 wd */ 5, 0, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -int den_test[8] = { /* valid densities */ +int32 den_test[8] = { /* valid densities */ 0, 0, 0, 1, 1, 0, 0, 0 }; +static uint8 *xbuf = NULL; /* xfer buffer */ t_stat tu_rd (int32 *data, int32 PA, int32 access); t_stat tu_wr (int32 data, int32 PA, int32 access); @@ -682,7 +684,6 @@ int32 ba, fc, wc, drv, mpa10, vpn; d10 val, v[4]; t_mtrlnt abc, tbc; static t_mtrlnt bceof = { MTR_TMK }; -static uint8 xbuf[XBUFLNT + 4]; drv = uptr - tu_dev.units; /* get drive # */ pnu = MT_TST_PNU (uptr); /* get pos not upd */ @@ -968,6 +969,8 @@ for (u = 0; u < TU_NUMDR; u++) { /* loop thru units */ MT_CLR_PNU (uptr); /* clear pos flag */ sim_cancel (uptr); /* cancel activity */ uptr->USTAT = 0; } +if (xbuf == NULL) xbuf = calloc (XBUFLNT + 4, sizeof (uint8)); +if (xbuf == NULL) return SCPE_MEM; return SCPE_OK; } diff --git a/PDP11/pdp11_cpu.c b/PDP11/pdp11_cpu.c index 44e00682..4b704180 100644 --- a/PDP11/pdp11_cpu.c +++ b/PDP11/pdp11_cpu.c @@ -25,6 +25,8 @@ cpu PDP-11 CPU (J-11 microprocessor) + 01-Feb-03 RMS Changed R display to follow PSW, added SP display + 19-Jan-03 RMS Changed mode definitions for Apple Dev Kit conflict 05-Jan-03 RMS Added memory size restore support 17-Oct-02 RMS Fixed bug in examine/deposit (found by Hans Pufal) 08-Oct-02 RMS Revised to build dib_tab dynamically @@ -315,6 +317,7 @@ t_stat MMR3_rd (int32 *data, int32 addr, int32 access); t_stat MMR3_wr (int32 data, int32 addr, int32 access); t_stat ubm_rd (int32 *data, int32 addr, int32 access); t_stat ubm_wr (int32 data, int32 addr, int32 access); +void set_r_display (int32 rs, int32 cm); extern t_stat build_dib_tab (int32 ubm); extern t_stat show_iospace (FILE *st, UNIT *uptr, int32 val, void *desc); @@ -369,15 +372,22 @@ REG cpu_reg[] = { { ORDATA (R3, REGFILE[3][0], 16) }, { ORDATA (R4, REGFILE[4][0], 16) }, { ORDATA (R5, REGFILE[5][0], 16) }, + { ORDATA (SP, STACKFILE[MD_KER], 16) }, + { ORDATA (R00, REGFILE[0][0], 16) }, + { ORDATA (R01, REGFILE[1][0], 16) }, + { ORDATA (R02, REGFILE[2][0], 16) }, + { ORDATA (R03, REGFILE[3][0], 16) }, + { ORDATA (R04, REGFILE[4][0], 16) }, + { ORDATA (R05, REGFILE[5][0], 16) }, { ORDATA (R10, REGFILE[0][1], 16) }, { ORDATA (R11, REGFILE[1][1], 16) }, { ORDATA (R12, REGFILE[2][1], 16) }, { ORDATA (R13, REGFILE[3][1], 16) }, { ORDATA (R14, REGFILE[4][1], 16) }, { ORDATA (R15, REGFILE[5][1], 16) }, - { ORDATA (KSP, STACKFILE[KERNEL], 16) }, - { ORDATA (SSP, STACKFILE[SUPER], 16) }, - { ORDATA (USP, STACKFILE[USER], 16) }, + { ORDATA (KSP, STACKFILE[MD_KER], 16) }, + { ORDATA (SSP, STACKFILE[MD_SUP], 16) }, + { ORDATA (USP, STACKFILE[MD_USR], 16) }, { ORDATA (PSW, PSW, 16) }, { GRDATA (CM, PSW, 8, 2, PSW_V_CM) }, { GRDATA (PM, PSW, 8, 2, PSW_V_PM) }, @@ -632,11 +642,11 @@ if (abortval != 0) { trap_req = trap_req | abortval; /* or in trap flag */ if ((trapea > 0) && (stop_vecabort)) reason = STOP_VECABORT; if ((trapea < 0) && (stop_spabort)) reason = STOP_SPABORT; - if (trapea == ~KERNEL) { /* kernel stk abort? */ + if (trapea == ~MD_KER) { /* kernel stk abort? */ setTRAP (TRAP_RED); setCPUERR (CPUE_RED); - STACKFILE[KERNEL] = 4; - if (cm == KERNEL) SP = 4; } } + STACKFILE[MD_KER] = 4; + if (cm == MD_KER) SP = 4; } } /* Main instruction fetch/decode loop @@ -701,8 +711,8 @@ if (trap_req) { /* check traps, ints */ (N << PSW_V_N) | (Z << PSW_V_Z) | (V << PSW_V_V) | (C << PSW_V_C); oldrs = rs; - src = ReadW (trapea | calc_ds (KERNEL)); - src2 = ReadW ((trapea + 2) | calc_ds (KERNEL)); + src = ReadW (trapea | calc_ds (MD_KER)); + src2 = ReadW ((trapea + 2) | calc_ds (MD_KER)); t = (src2 >> PSW_V_CM) & 03; trapea = ~t; /* flag pushes */ WriteW (PSW, ((STACKFILE[t] - 2) & 0177777) | calc_ds (t)); @@ -726,7 +736,7 @@ if (trap_req) { /* check traps, ints */ isenable = calc_is (cm); dsenable = calc_ds (cm); trap_req = calc_ints (ipl, trap_req); - if ((SP < STKLIM) && (cm == KERNEL) && + if ((SP < STKLIM) && (cm == MD_KER) && (trapnum != TRAP_V_RED) && (trapnum != TRAP_V_YEL)) { setTRAP (TRAP_YEL); setCPUERR (CPUE_YEL); } @@ -766,14 +776,14 @@ case 000: break; } switch (IR) { /* decode IR<2:0> */ case 0: /* HALT */ - if ((cm == KERNEL) && ((MAINT & MAINT_HTRAP) == 0)) + if ((cm == MD_KER) && ((MAINT & MAINT_HTRAP) == 0)) reason = STOP_HALT; else { setTRAP (TRAP_PRV); setCPUERR (CPUE_HALT); } break; case 1: /* WAIT */ - if (cm == KERNEL && wait_enable) wait_state = 1; + if (cm == MD_KER && wait_enable) wait_state = 1; break; case 3: /* BPT */ setTRAP (TRAP_BPT); @@ -782,7 +792,7 @@ case 000: setTRAP (TRAP_IOT); break; case 5: /* RESET */ - if (cm == KERNEL) { + if (cm == MD_KER) { reset_all (1); PIRQ = 0; for (i = 0; i < IPL_HLVL; i++) int_req[i] = 0; @@ -800,7 +810,7 @@ case 000: src2 = ReadW (((SP + 2) & 0177777) | dsenable); STACKFILE[cm] = SP = (SP + 4) & 0177777; oldrs = rs; - if (cm == KERNEL) { + if (cm == MD_KER) { cm = (src2 >> PSW_V_CM) & 03; pm = (src2 >> PSW_V_PM) & 03; rs = (src2 >> PSW_V_RS) & 01; @@ -848,7 +858,7 @@ case 000: setTRAP (TRAP_ILL); break; } if (IR < 000240) { /* SPL */ - if (cm == KERNEL) ipl = IR & 07; + if (cm == MD_KER) ipl = IR & 07; trap_req = calc_ints (ipl, trap_req); break; } /* end if SPL */ if (IR < 000260) { /* clear CC */ @@ -925,7 +935,7 @@ case 000: SP = (SP - 2) & 0177777; if (update_MM) MMR1 = calc_MMR1 (0366); WriteW (R[srcspec], SP | dsenable); - if ((SP < STKLIM) && (cm == KERNEL)) { + if ((SP < STKLIM) && (cm == MD_KER)) { setTRAP (TRAP_YEL); setCPUERR (CPUE_YEL); } R[srcspec] = PC; @@ -1066,7 +1076,7 @@ case 000: if ((dstspec == 6) && (cm != pm)) dst = STACKFILE[pm]; else dst = R[dstspec]; } else { - i = ((cm == pm) && (cm == USER))? calc_ds (pm): calc_is (pm); + i = ((cm == pm) && (cm == MD_USR))? calc_ds (pm): calc_is (pm); dst = ReadW ((GeteaW (dstspec) & 0177777) | i); } N = GET_SIGN_W (dst); Z = GET_Z (dst); @@ -1074,7 +1084,7 @@ case 000: SP = (SP - 2) & 0177777; if (update_MM) MMR1 = calc_MMR1 (0366); WriteW (dst, SP | dsenable); - if ((cm == KERNEL) && (SP < STKLIM)) { + if ((cm == MD_KER) && (SP < STKLIM)) { setTRAP (TRAP_YEL); setCPUERR (CPUE_YEL); } break; @@ -1101,7 +1111,7 @@ case 000: /* Opcode 0: SOPs, continued */ case 070: /* CSM */ - if (((MMR3 & MMR3_CSM) == 0) || (cm == KERNEL)) + if (((MMR3 & MMR3_CSM) == 0) || (cm == MD_KER)) setTRAP (TRAP_ILL); else { dst = dstreg? R[dstspec]: ReadW (GeteaW (dstspec)); @@ -1109,12 +1119,12 @@ case 000: (rs << PSW_V_RS) | (ipl << PSW_V_IPL) | (tbit << PSW_V_TBIT); STACKFILE[cm] = SP; - WriteW (PSW, ((SP - 2) & 0177777) | calc_ds (SUPER)); - WriteW (PC, ((SP - 4) & 0177777) | calc_ds (SUPER)); - WriteW (dst, ((SP - 6) & 0177777) | calc_ds (SUPER)); + WriteW (PSW, ((SP - 2) & 0177777) | calc_ds (MD_SUP)); + WriteW (PC, ((SP - 4) & 0177777) | calc_ds (MD_SUP)); + WriteW (dst, ((SP - 6) & 0177777) | calc_ds (MD_SUP)); SP = (SP - 6) & 0177777; pm = cm; - cm = SUPER; + cm = MD_SUP; tbit = 0; isenable = calc_is (cm); dsenable = calc_ds (cm); @@ -1562,7 +1572,7 @@ case 010: case 064: /* MTPS */ dst = dstreg? R[dstspec]: ReadB (GeteaB (dstspec)); - if (cm == KERNEL) { + if (cm == MD_KER) { ipl = (dst >> PSW_V_IPL) & 07; trap_req = calc_ints (ipl, trap_req); } N = (dst >> PSW_V_N) & 01; @@ -1581,7 +1591,7 @@ case 010: SP = (SP - 2) & 0177777; if (update_MM) MMR1 = calc_MMR1 (0366); WriteW (dst, SP | dsenable); - if ((cm == KERNEL) && (SP < STKLIM)) { + if ((cm == MD_KER) && (SP < STKLIM)) { setTRAP (TRAP_YEL); setCPUERR (CPUE_YEL); } break; @@ -1717,6 +1727,7 @@ for (i = 0; i < 6; i++) REGFILE[i][rs] = R[i]; STACKFILE[cm] = SP; saved_PC = PC & 0177777; pcq_r->qptr = pcq_p; /* update pc q ptr */ +set_r_display (rs, cm); return reason; } @@ -1790,14 +1801,14 @@ case 3: /* @(R)+ */ case 4: /* -(R) */ adr = R[reg] = (R[reg] - 2) & 0177777; if (update_MM) MMR1 = calc_MMR1 (0360 | reg); - if ((adr < STKLIM) && (reg == 6) && (cm == KERNEL)) { + if ((adr < STKLIM) && (reg == 6) && (cm == MD_KER)) { setTRAP (TRAP_YEL); setCPUERR (CPUE_YEL); } return (adr | ds); case 5: /* @-(R) */ adr = R[reg] = (R[reg] - 2) & 0177777; if (update_MM) MMR1 = calc_MMR1 (0360 | reg); - if ((adr < STKLIM) && (reg == 6) && (cm == KERNEL)) { + if ((adr < STKLIM) && (reg == 6) && (cm == MD_KER)) { setTRAP (TRAP_YEL); setCPUERR (CPUE_YEL); } adr = ReadW (adr | ds); @@ -1840,14 +1851,14 @@ case 4: /* -(R) */ delta = 1 + (reg >= 6); /* 2 if R6, PC */ adr = R[reg] = (R[reg] - delta) & 0177777; if (update_MM) MMR1 = calc_MMR1 ((((-delta) & 037) << 3) | reg); - if ((adr < STKLIM) && (reg == 6) && (cm == KERNEL)) { + if ((adr < STKLIM) && (reg == 6) && (cm == MD_KER)) { setTRAP (TRAP_YEL); setCPUERR (CPUE_YEL); } return (adr | ds); case 5: /* @-(R) */ adr = R[reg] = (R[reg] - 2) & 0177777; if (update_MM) MMR1 = calc_MMR1 (0360 | reg); - if ((adr < STKLIM) && (reg == 6) && (cm == KERNEL)) { + if ((adr < STKLIM) && (reg == 6) && (cm == MD_KER)) { setTRAP (TRAP_YEL); setCPUERR (CPUE_YEL); } adr = ReadW (adr | ds); @@ -2120,9 +2131,9 @@ int32 relocC (int32 va, int32 sw) int32 mode, dbn, plf, apridx, apr, pa; if (MMR0 & MMR0_MME) { /* if mmgt */ - if (sw & SWMASK ('K')) mode = KERNEL; - else if (sw & SWMASK ('S')) mode = SUPER; - else if (sw & SWMASK ('U')) mode = USER; + if (sw & SWMASK ('K')) mode = MD_KER; + else if (sw & SWMASK ('S')) mode = MD_SUP; + else if (sw & SWMASK ('U')) mode = MD_USR; else if (sw & SWMASK ('P')) mode = (PSW >> PSW_V_PM) & 03; else mode = (PSW >> PSW_V_CM) & 03; va = va | ((sw & SWMASK ('D'))? calc_ds (mode): calc_is (mode)); @@ -2394,6 +2405,7 @@ if (pcq_r) pcq_r->qptr = 0; else return SCPE_IERR; for (i = 0; i < UBM_LNT_LW; i++) ub_map[i] = 0; sim_brk_types = sim_brk_dflt = SWMASK ('E'); +set_r_display (0, MD_KER); return SCPE_OK; } @@ -2476,3 +2488,17 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { return SCPE_OK; } +/* Set R, SP register display addresses */ + +void set_r_display (int32 rs, int32 cm) +{ +extern REG *find_reg (char *cptr, char **optr, DEVICE *dptr); +REG *rptr; +int32 i; + +rptr = find_reg ("R0", NULL, &cpu_dev); +if (rptr == NULL) return; +for (i = 0; i < 6; i++, rptr++) rptr->loc = (void *) ®FILE[i][rs]; +rptr->loc = (void *) &STACKFILE[cm]; +return; +} diff --git a/PDP11/pdp11_defs.h b/PDP11/pdp11_defs.h index 256a908f..6b31c3f0 100644 --- a/PDP11/pdp11_defs.h +++ b/PDP11/pdp11_defs.h @@ -1,6 +1,6 @@ /* pdp11_defs.h: PDP-11 simulator definitions - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, 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 @@ The author gratefully acknowledges the help of Max Burnet, Megan Gentry, and John Wilson in resolving questions about the PDP-11 + 19-Jan-03 RMS Changed mode definitions for Apple Dev Kit conflict 11-Nov-02 RMS Changed log definitions to be VAX compatible 10-Oct-02 RMS Added vector information to DIB Changed DZ11 vector to Unibus standard @@ -71,10 +72,10 @@ /* Protection modes */ -#define KERNEL 0 -#define SUPER 1 -#define UNUSED 2 -#define USER 3 +#define MD_KER 0 +#define MD_SUP 1 +#define MD_UND 2 +#define MD_USR 3 /* I/O access modes */ diff --git a/PDP11/pdp11_doc.txt b/PDP11/pdp11_doc.txt index 1b8b22c3..dfec8fc3 100644 --- a/PDP11/pdp11_doc.txt +++ b/PDP11/pdp11_doc.txt @@ -1,7 +1,7 @@ To: Users From: Bob Supnik Subj: PDP-11 Simulator Usage -Date: 15-Jan-2003 +Date: 1-Feb-2003 COPYRIGHT NOTICE @@ -203,8 +203,10 @@ control registers for the interrupt system. name size comments PC 16 program counter - R0..R5 16 R0..R5, first register set - R10..R15 16 R0..R5, second register set + R0..R5 16 R0..R5, current register set + SP 16 stack pointer, current mode + R00..R05 16 R0..R5, register set 0 + R10..R15 16 R0..R5, register set 1 KSP 16 kernel stack pointer SSP 16 supervisor stack pointer USP 16 user stack pointer diff --git a/PDP11/pdp11_fp.c b/PDP11/pdp11_fp.c index 676fa6d6..50185330 100644 --- a/PDP11/pdp11_fp.c +++ b/PDP11/pdp11_fp.c @@ -1,6 +1,6 @@ /* pdp11_fp.c: PDP-11 floating point simulator (32b version) - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, 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 @@ 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. + 19-Jan-03 RMS Changed mode definitions for Apple Dev Kit conflict 08-Oct-02 RMS Fixed macro definitions 05-Jun-98 RMS Fixed implementation specific shift bugs 20-Apr-98 RMS Fixed bug in MODf integer truncation @@ -516,14 +517,14 @@ case 3: /* @(R)+ */ case 4: /* -(R) */ adr = R[reg] = (R[reg] - len) & 0177777; if (update_MM) MMR1 = (((-len) & 037) << 3) | reg; - if ((adr < STKLIM) && (reg == 6) && (cm == KERNEL)) { + if ((adr < STKLIM) && (reg == 6) && (cm == MD_KER)) { setTRAP (TRAP_YEL); setCPUERR (CPUE_YEL); } return (adr | ds); case 5: /* @-(R) */ adr = R[reg] = (R[reg] - 2) & 0177777; if (update_MM) MMR1 = 0360 | reg; - if ((adr < STKLIM) && (reg == 6) && (cm == KERNEL)) { + if ((adr < STKLIM) && (reg == 6) && (cm == MD_KER)) { setTRAP (TRAP_YEL); setCPUERR (CPUE_YEL); } adr = ReadW (adr | ds); diff --git a/PDP11/pdp11_rp.c b/PDP11/pdp11_rp.c index 4399a108..cdd36a79 100644 --- a/PDP11/pdp11_rp.c +++ b/PDP11/pdp11_rp.c @@ -393,7 +393,7 @@ int32 rpiff = 0; /* INTR flip/flop */ int32 rp_stopioe = 1; /* stop on error */ int32 rp_swait = 10; /* seek time */ int32 rp_rwait = 10; /* rotate time */ -static int reg_in_drive[32] = { +static int32 reg_in_drive[32] = { 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -1060,7 +1060,7 @@ return SCPE_OK; t_stat rp_attach (UNIT *uptr, char *cptr) { -int drv, i, p; +int32 drv, i, p; t_stat r; uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size; diff --git a/PDP18B/pdp18b_cpu.c b/PDP18B/pdp18b_cpu.c index 1e26ff1e..d9dddaa7 100644 --- a/PDP18B/pdp18b_cpu.c +++ b/PDP18B/pdp18b_cpu.c @@ -351,7 +351,7 @@ static const int32 api_ffo[256] = { static const int32 api_vec[API_HLVL][32] = { { ACH_PWRFL }, /* API 0 */ - { ACH_DTA, ACH_MTA, ACH_DRM, ACH_RF, ACH_RP }, /* API 1 */ + { ACH_DTA, ACH_MTA, ACH_DRM, ACH_RF, ACH_RP, ACH_RB }, /* API 1 */ { ACH_PTR, ACH_LPT, ACH_LPT }, /* API 2 */ { ACH_CLK, ACH_TTI1, ACH_TTO1 } }; /* API 3 */ diff --git a/PDP18B/pdp18b_defs.h b/PDP18B/pdp18b_defs.h index 6cc81215..45ccff77 100644 --- a/PDP18B/pdp18b_defs.h +++ b/PDP18B/pdp18b_defs.h @@ -1,6 +1,6 @@ /* pdp18b_defs.h: 18b PDP simulator definitions - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, 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 @@ 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. + 04-Feb-03 RMS Added RB09, LP09 support 22-Nov-02 RMS Added PDP-4 drum support 05-Oct-02 RMS Added DIB structure 25-Jul-02 RMS Added PDP-4 DECtape support @@ -66,7 +67,9 @@ KF09A auto pri intr PC09A paper tape reader and punch KG09B mem extension integral real time clock KP09A power detection Type 647D/E line printer (sixbit) - KX09A mem protection RF09/RS09 fixed head disk + KX09A mem protection LP09 line printer (ASCII) + RF09/RS09 fixed head disk + RB09 fixed head disk TC59 magnetic tape TC02/TU55 DECtape LT09A second Teletype @@ -74,8 +77,9 @@ PDP15 128K KE15 EAE KSR-35 Teletype KA15 auto pri intr PC15 paper tape reader and punch KF15 power detection KW15 real time clock - KM15 mem protection LP15 line printer - ??KT15 mem relocation RP15 disk pack + KM15 mem protection LP09 line printer + ??KT15 mem relocation LP15 line printer + RP15 disk pack RF15/RF09 fixed head disk TC59D magnetic tape TC15/TU56 DECtape @@ -114,6 +118,8 @@ #elif defined (PDP9) #define ADDRSIZE 15 #define TYPE647 0 /* sixbit printer */ +#define LP09 0 /* ASCII printer */ +#define RB 0 /* fixed head disk */ #define RF 0 /* fixed head disk */ #define MTA 0 /* magtape */ #define TC02 0 /* DECtape */ @@ -121,7 +127,8 @@ #define BRMASK 0076000 /* bounds mask */ #elif defined (PDP15) #define ADDRSIZE 17 -#define LP15 0 /* ASCII printer */ +#define LP09 0 /* ASCII printer */ +#define LP15 0 /* DMA printer */ #define RF 0 /* fixed head disk */ #define RP 0 /* disk pack */ #define MTA 0 /* magtape */ @@ -184,6 +191,7 @@ typedef struct pdp18b_dib DIB; #define DEV_RP 063 /* RP15 */ #define DEV_LPT 065 /* line printer */ #define DEV_RF 070 /* RF09 */ +#define DEV_RB 071 /* RB09 */ #define DEV_MT 073 /* magtape */ #define DEV_DTA 075 /* dectape */ @@ -203,7 +211,7 @@ typedef struct pdp18b_dib DIB; 04 TC02/TC15 1 05 TC59D 1 06 drum 1 PDP-9 only - 07 disk 1 PDP-9 only + 07 RB09 1 PDP-9 only 10 paper tape reader 2 11 real time clock 3 12 power fail 0 @@ -250,22 +258,26 @@ typedef struct pdp18b_dib DIB; #define INT_V_DRM 2 /* drum */ #define INT_V_RF 3 /* fixed head disk */ #define INT_V_RP 4 /* disk pack */ +#define INT_V_RB 5 /* RB disk */ #define INT_DTA (1 << INT_V_DTA) #define INT_MTA (1 << INT_V_MTA) #define INT_DRM (1 << INT_V_DRM) #define INT_RF (1 << INT_V_RF) #define INT_RP (1 << INT_V_RP) +#define INT_RB (1 << INT_V_RB) #define API_DTA 1 #define API_MTA 1 #define API_DRM 1 #define API_RF 1 #define API_RP 1 +#define API_RB 1 #define ACH_DTA 044 #define ACH_MTA 045 #define ACH_DRM 046 +#define ACH_RB 047 #define ACH_RF 063 #define ACH_RP 064 @@ -375,6 +387,7 @@ typedef struct pdp18b_dib DIB; #define IOS_PTPERR 0000400 /* punch empty */ #define IOS_MTA 0000100 /* magtape */ #define IOS_LPT 0000010 /* line printer */ +#define IOS_LPT1 0000000 /* not used */ #endif /* Function prototypes */ diff --git a/PDP18B/pdp18b_doc.txt b/PDP18B/pdp18b_doc.txt index 445c62ec..76ce61bf 100644 --- a/PDP18B/pdp18b_doc.txt +++ b/PDP18B/pdp18b_doc.txt @@ -1,14 +1,14 @@ To: Users From: Bob Supnik Subj: 18b PDP Simulator Usage -Date: 15-Nov-2002 +Date: 01-Feb-2003 COPYRIGHT NOTICE The following copyright notice applies to both the SIMH source and binary: - Original code published in 1993-2002, written by Robert M Supnik - Copyright (c) 1993-2002, Robert M Supnik + Original code published in 1993-2003, written by Robert M Supnik + Copyright (c) 1993-2003, 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"), @@ -61,6 +61,7 @@ sim/pdp18b/ pdp18b_defs.h pdp18b_dt.c pdp18b_lp.c pdp18b_mt.c + pdp18b_rb.c pdp18b_rf.c pdp18b_rp.c pdp18b_stddev.c @@ -102,8 +103,10 @@ PDP-9 CPU PDP-9 CPU with 32KW of memory PTR,PTP PC09A paper tape reader/punch TTI,TTO KSR 33 console terminal TTI1,TTO1 LT09A second console terminal + LP9 LP09 line printer LPT Type 647E line printer CLK integral real-time clock + RB RB09 fixed-head disk RF RF09/RS09 fixed-head disk DT TC02/TU55 DECtape MT TC59/TU10 magnetic tape @@ -116,6 +119,7 @@ PDP-15 CPU PDP-15 CPU with 32KW of memory PTR,PTP PC15 paper tape reader/punch TTI,TTO KSR 35 console terminal TTI1,TTO1 LT15 second console terminal + LP9 LP09 line printer LPT LP15 line printer CLK integral real-time clock RP RP15/RP02 disk pack @@ -239,9 +243,8 @@ BOOT -F PTR copies the funny format binary loader into memory and starts it running. The PTR ATTACH command recognizes one switch, -A for ASCII mode. In -ASCII mode, data returned by the read alphabetic command has the high -order bit automatically set to 1. This allows normal text files to be -used as input to the paper tape reader. +ASCII mode, data returned by the read alphabetic command has even parity. +This allows normal text files to be used as input to the paper tape reader. The paper tape reader implements these registers: @@ -337,13 +340,19 @@ implements these registers: POS 32 number of chararacters output TIME 24 time from I/O initiation to interrupt -2.2.5 Line Printer (LPT) +2.2.5 Line Printers (LPT, LP9) -The line printer (LPT) writes data to a disk file. The POS register -specifies the number of the next data item to be written. Thus, -by changing POS, the user can backspace or advance the printer. +The line printers (LPT, LP9) write data to a disk file. The POS +register specifies the number of the next data item to be written. +Thus, by changing POS, the user can backspace or advance the printer. -The PDP-4 uses a Type 62 printer controller, with these registers: +LPT is the "default" line printer for a CPU: Type 62 for the PDP-4, +Type 647 for the PDP-7 and PDP-9, and LP15 for the PDP-15. LP9 is +the LP09 line printer controller for the PDP-9. It may be needed +on the PDP-15 to run certain software packages. LP9 is disabled by +default. + +The Type 62 printer controller implements these registers: name size comments @@ -357,8 +366,7 @@ The PDP-4 uses a Type 62 printer controller, with these registers: STOP_IOE 1 stop on I/O error LBUF[0:119] 8 line buffer -The PDP-7 and PDP-9 use a Type 647 printer controller, with these -registers: +The Type 647 printer controller implements these registers: name size comments @@ -373,7 +381,19 @@ registers: STOP_IOE 1 stop on I/O error LBUF[0:119] 8 line buffer -The PDP-15 uses an LP15 printer controller, with these registers: +The LP09 printer controller implements these registers: + + name size comments + + BUF 7 output character + INT 1 interrupt pending flag + DONE 1 device done flag + ENABLE 1 interrupt enable + ERR 1 error flag + POS 32 position in the output file + TIME 24 time from I/O initiation to interrupt + +The LP15 printer controller implements these registers: name size comments @@ -388,7 +408,7 @@ The PDP-15 uses an LP15 printer controller, with these registers: STOP_IOE 1 stop on I/O error LBUF[0:131] 8 line buffer -For all three models, error handling is as follows: +For all printers, error handling is as follows: error STOP_IOE processed as @@ -519,16 +539,66 @@ Error handling is as follows: Drum data files are buffered in memory; therefore, end of file and OS I/O errors cannot occur. +2.5 RB09 Fixed Head Disk (RB) + +The RB09 was an early fixed-head disk for the PDP-9. It was superceded +by the RF09/RS09. It is disabled by default. + +The RB09 implements these registers: + + name size comments + + STA 18 status + DA 20 current disk address + WC 16 word count + MA 15 memory address + INT 1 interrupt pending flag + WLK 20 write lock switches for track groups, + 10 tracks per group + TIME 24 rotational delay, per word + BURST 1 burst flag + STOP_IOE 1 stop on I/O error + +The RB09 is a data break device. If BURST = 0, word transfers are +scheduled individually; if BURST = 1, the entire transfer occurs in +a single data break. + +Error handling is as follows: + + error STOP_IOE processed as + + not attached 1 report error and stop + 0 disk not ready + +RB09 data files are buffered in memory; therefore, end of file and OS +I/O errors cannot occur. + 2.5 RF09/RF15/RS09 Fixed Head Disk (RF) +RF09/RF15 options include the ability to set the number of platters +to a fixed value between 1 and 8, or to autosize the number of platters +from the attached file: + + SET RF 1P one platter (256K) + SET RF 2P two platters (512K) + SET RF 3P three platters (768K) + SET RF 4P four platters (1024K) + SET RF 5P five platters (1280K) + SET RF 6P six platters (1536K) + SET RF 7P seven platters (1792K) + SET RF 8P eight platters (2048K) + SET RF AUTOSIZE autosized on attach + +The default is AUTOSIZE. + The RF09/RF15 implements these registers: name size comments STA 18 status DA 21 current disk address - MA 18 memory address (in memory) WC 18 word count (in memory) + CA 18 memory address (in memory) BUF 18 data buffer (diagnostic only) INT 1 interrupt pending flag WLK[0:7] 16 write lock switches for disks 0-7 @@ -627,7 +697,7 @@ The magnetic tape controller implements these registers: CMD 18 command STA 18 main status - MA 18 memory address (in memory) + CA 18 memory address (in memory) WC 18 word count (in memory) INT 1 interrupt pending flag STOP_IOE 1 stop on I/O error diff --git a/PDP18B/pdp18b_lp.c b/PDP18B/pdp18b_lp.c index bb23db34..030a41f9 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-2002, Robert M Supnik + Copyright (c) 1993-2003, 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,10 +23,12 @@ 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. - lpt (PDP-4) Type 62 line printer - (PDP-7,9) Type 647 line printer - (PDP-15) LP15 line printer + lp62 (PDP-4) Type 62 line printer + lp647 (PDP-7,9) Type 647 line printer + lp09 (PDP-9,15) LP09 line printer + lp15 (PDP-15) LP15 line printer + 05-Feb-03 RMS Added LP09, fixed conditionalization 05-Oct-02 RMS Added DIB, device number support 30-May-02 RMS Widened POS to 32b 03-Feb-02 RMS Fixed typo (found by Robert Alan Byer) @@ -40,282 +42,188 @@ */ #include "pdp18b_defs.h" - -DEVICE lpt_dev; -int32 lpt65 (int32 pulse, int32 AC); -int32 lpt66 (int32 pulse, int32 AC); -int32 lpt_iors (void); -t_stat lpt_svc (UNIT *uptr); -t_stat lpt_reset (DEVICE *dptr); - extern int32 int_hwre[API_HLVL+1]; -DIB lpt_dib = { DEV_LPT, 2, &lpt_iors, { &lpt65, &lpt66 } }; - -UNIT lpt_unit = { - UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT }; - -MTAB lpt_mod[] = { - { MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_devno, &show_devno }, - { 0 } }; - #if defined (TYPE62) +/* Type 62 line printer */ + +#define LP62_BSIZE 120 /* line size */ #define BPTR_MAX 40 /* pointer max */ -#define LPT_BSIZE 120 /* line size */ #define BPTR_MASK 077 /* buf ptr max */ -int32 lpt_iot = 0, lpt_stopioe = 0, bptr = 0; -char lpt_buf[LPT_BSIZE + 1] = { 0 }; -/* Type 62 LPT data structures - - lpt_dev LPT device descriptor - lpt_unit LPT unit - lpt_reg LPT register list -*/ - -REG lpt_reg[] = { - { ORDATA (BUF, lpt_unit.buf, 8) }, - { FLDATA (INT, int_hwre[API_LPT], INT_V_LPT) }, - { FLDATA (DONE, int_hwre[API_LPT], INT_V_LPT) }, - { FLDATA (SPC, int_hwre[API_LPTSPC], INT_V_LPTSPC) }, - { DRDATA (BPTR, bptr, 6) }, - { ORDATA (STATE, lpt_iot, 6), REG_HRO }, - { DRDATA (POS, lpt_unit.pos, 32), PV_LEFT }, - { DRDATA (TIME, lpt_unit.wait, 24), PV_LEFT }, - { FLDATA (STOP_IOE, lpt_stopioe, 0) }, - { BRDATA (LBUF, lpt_buf, 8, 8, LPT_BSIZE) }, - { ORDATA (DEVNO, lpt_dib.dev, 6), REG_HRO }, - { NULL } }; - -DEVICE lpt_dev = { - "LPT", &lpt_unit, lpt_reg, lpt_mod, - 1, 10, 31, 1, 8, 8, - NULL, NULL, &lpt_reset, - NULL, NULL, NULL, - &lpt_dib, DEV_DISABLE }; - -/* Type 62 line printer: IOT routines */ - -int32 lpt65 (int32 pulse, int32 AC) -{ -int32 i; - -static const char lpt_trans[64] = { +int32 lp62_iot = 0; /* saved state */ +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", + "\n\n\n", + "\n\n\n\n\n\n", + "\n\n\n\n\n\n\n\n\n\n\n", + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", + "\f" }; -if ((pulse & 001) && TST_INT (LPT)) AC = IOT_SKP | AC; /* LPSF */ -if ((pulse & 042) == 002) CLR_INT (LPT); /* LPCF */ -if (((pulse & 042) == 042) && (bptr < BPTR_MAX)) { /* LPLD */ - i = bptr * 3; /* cvt to chr ptr */ - lpt_buf[i] = lpt_trans[(AC >> 12) & 077]; - lpt_buf[i + 1] = lpt_trans[(AC >> 6) & 077]; - lpt_buf[i + 2] = lpt_trans[AC & 077]; - bptr = (bptr + 1) & BPTR_MASK; } -if (pulse & 004) { /* LPSE */ - sim_activate (&lpt_unit, lpt_unit.wait); } /* activate */ +DEVICE lp62_dev; +int32 lp62_65 (int32 pulse, int32 AC); +int32 lp62_66 (int32 pulse, int32 AC); +int32 lp62_iors (void); +t_stat lp62_svc (UNIT *uptr); +t_stat lp62_reset (DEVICE *dptr); + +/* Type 62 LPT data structures + + lp62_dev LPT device descriptor + lp62_unit LPT unit + lp62_reg LPT register list +*/ + +DIB lp62_dib = { DEV_LPT, 2, &lp62_iors, { &lp62_65, &lp62_66 } }; + +UNIT lp62_unit = { + UDATA (&lp62_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT }; + +REG lp62_reg[] = { + { ORDATA (BUF, lp62_unit.buf, 8) }, + { FLDATA (INT, int_hwre[API_LPT], INT_V_LPT) }, + { FLDATA (DONE, int_hwre[API_LPT], INT_V_LPT) }, + { FLDATA (SPC, int_hwre[API_LPTSPC], INT_V_LPTSPC) }, + { DRDATA (BPTR, lp62_bp, 6) }, + { ORDATA (STATE, lp62_iot, 6), REG_HRO }, + { DRDATA (POS, lp62_unit.pos, 32), PV_LEFT }, + { DRDATA (TIME, lp62_unit.wait, 24), PV_LEFT }, + { FLDATA (STOP_IOE, lp62_stopioe, 0) }, + { BRDATA (LBUF, lp62_buf, 8, 8, LP62_BSIZE) }, + { ORDATA (DEVNO, lp62_dib.dev, 6), REG_HRO }, + { NULL } }; + +MTAB lp62_mod[] = { + { MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_devno, &show_devno }, + { 0 } }; + +DEVICE lp62_dev = { + "LPT", &lp62_unit, lp62_reg, lp62_mod, + 1, 10, 31, 1, 8, 8, + NULL, NULL, &lp62_reset, + NULL, NULL, NULL, + &lp62_dib, DEV_DISABLE }; + +/* IOT routines */ + +int32 lp62_65 (int32 pulse, int32 AC) +{ +int32 i; + +if ((pulse & 01) && TST_INT (LPT)) AC = IOT_SKP | AC; /* LPSF */ +if (pulse & 02) { + int32 sb = pulse & 060; /* subopcode */ + 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[(AC >> 12) & 077]; + lp62_buf[i + 1] = lp62_trans[(AC >> 6) & 077]; + lp62_buf[i + 2] = lp62_trans[AC & 077]; + lp62_bp = (lp62_bp + 1) & BPTR_MASK; } + } +if (pulse & 04) /* LPSE */ + sim_activate (&lp62_unit, lp62_unit.wait); /* activate */ return AC; } -int32 lpt66 (int32 pulse, int32 AC) +int32 lp62_66 (int32 pulse, int32 AC) { -if ((pulse & 001) && TST_INT (LPTSPC)) /* LSSF */ +if ((pulse & 01) && TST_INT (LPTSPC)) /* LSSF */ AC = IOT_SKP | AC; -if (pulse & 002) CLR_INT (LPTSPC); /* LSCF */ -if (pulse & 004) { /* LSPR */ - lpt_iot = 020 | (AC & 07); /* space, no print */ - sim_activate (&lpt_unit, lpt_unit.wait); } /* activate */ +if (pulse & 02) CLR_INT (LPTSPC); /* LSCF */ +if (pulse & 04) { /* LSPR */ + lp62_iot = 020 | (AC & 07); /* space, no print */ + sim_activate (&lp62_unit, lp62_unit.wait); } /* activate */ return AC; } /* Unit service, printer is in one of three states - lpt_iot = 0 write buffer to file, set state to - lpt_iot = 10 write cr, then write buffer to file - lpt_iot = 2x space command x, then set state to 0 + lp62_iot = 0 write buffer to file, set state to + lp62_iot = 10 write cr, then write buffer to file + lp62_iot = 2x space command x, then set state to 0 */ -t_stat lpt_svc (UNIT *uptr) +t_stat lp62_svc (UNIT *uptr) { int32 i; -static const char *lpt_cc[] = { - "\n", - "\n\n", - "\n\n\n", - "\n\n\n\n\n\n", - "\n\n\n\n\n\n\n\n\n\n\n", - "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", - "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", - "\f" }; -if (lpt_iot & 020) { /* space? */ +if (lp62_iot & 020) { /* space? */ SET_INT (LPTSPC); /* set flag */ - if ((lpt_unit.flags & UNIT_ATT) == 0) /* attached? */ - return IORETURN (lpt_stopioe, SCPE_UNATT); - fputs (lpt_cc[lpt_iot & 07], lpt_unit.fileref); /* print cctl */ - if (ferror (lpt_unit.fileref)) { /* error? */ + if ((uptr->flags & UNIT_ATT) == 0) /* attached? */ + return IORETURN (lp62_stopioe, SCPE_UNATT); + fputs (lp62_cc[lp62_iot & 07], uptr->fileref); /* print cctl */ + if (ferror (uptr->fileref)) { /* error? */ perror ("LPT I/O error"); - clearerr (lpt_unit.fileref); + clearerr (uptr->fileref); return SCPE_IOERR; } - lpt_iot = 0; } /* clear state */ + lp62_iot = 0; } /* clear state */ else { SET_INT (LPT); /* print */ - if ((lpt_unit.flags & UNIT_ATT) == 0) /* attached? */ - return IORETURN (lpt_stopioe, SCPE_UNATT); - if (lpt_iot & 010) fputc ('\r', lpt_unit.fileref); - fputs (lpt_buf, lpt_unit.fileref); /* print buffer */ - if (ferror (lpt_unit.fileref)) { /* test error */ + if ((uptr->flags & UNIT_ATT) == 0) /* attached? */ + return IORETURN (lp62_stopioe, SCPE_UNATT); + if (lp62_iot & 010) fputc ('\r', uptr->fileref); + fputs (lp62_buf, uptr->fileref); /* print buffer */ + if (ferror (uptr->fileref)) { /* test error */ perror ("LPT I/O error"); - clearerr (lpt_unit.fileref); + clearerr (uptr->fileref); return SCPE_IOERR; } - bptr = 0; - for (i = 0; i <= LPT_BSIZE; i++) lpt_buf[i] = 0; /* clear buffer */ - lpt_iot = 010; } /* set state */ -lpt_unit.pos = ftell (lpt_unit.fileref); /* update position */ + lp62_bp = 0; + for (i = 0; i <= LP62_BSIZE; i++) lp62_buf[i] = 0; /* clear buffer */ + lp62_iot = 010; } /* set state */ +uptr->pos = ftell (uptr->fileref); /* update position */ return SCPE_OK; } /* Reset routine */ -t_stat lpt_reset (DEVICE *dptr) +t_stat lp62_reset (DEVICE *dptr) { int32 i; CLR_INT (LPT); /* clear intrs */ CLR_INT (LPTSPC); -sim_cancel (&lpt_unit); /* deactivate unit */ -bptr = 0; /* clear buffer ptr */ -for (i = 0; i <= LPT_BSIZE; i++) lpt_buf[i] = 0; /* clear buffer */ -lpt_iot = 0; /* clear state */ +sim_cancel (&lp62_unit); /* deactivate unit */ +lp62_bp = 0; /* clear buffer ptr */ +for (i = 0; i <= LP62_BSIZE; i++) lp62_buf[i] = 0; /* clear buffer */ +lp62_iot = 0; /* clear state */ return SCPE_OK; } /* IORS routine */ -int32 lpt_iors (void) +int32 lp62_iors (void) { return (TST_INT (LPT)? IOS_LPT: 0) | (TST_INT (LPTSPC)? IOS_LPT1: 0); } - -#elif defined (TYPE647) -#define LPT_BSIZE 120 /* line size */ -int32 lpt_done = 0, lpt_ie = 1, lpt_err = 0; -int32 lpt_iot = 0, lpt_stopioe = 0, bptr = 0; -char lpt_buf[LPT_BSIZE] = { 0 }; - -t_stat lpt_attach (UNIT *uptr, char *cptr); -t_stat lpt_detach (UNIT *uptr); - -/* Type 647 LPT data structures - - lpt_dev LPT device descriptor - lpt_unit LPT unit - lpt_reg LPT register list -*/ - -REG lpt_reg[] = { - { ORDATA (BUF, lpt_unit.buf, 8) }, - { FLDATA (INT, int_hwre[API_LPT], INT_V_LPT) }, - { FLDATA (DONE, lpt_done, 0) }, -#if defined (PDP9) - { FLDATA (ENABLE, lpt_ie, 0) }, #endif - { FLDATA (ERR, lpt_err, 0) }, - { DRDATA (BPTR, bptr, 7) }, - { ORDATA (SCMD, lpt_iot, 6), REG_HRO }, - { DRDATA (POS, lpt_unit.pos, 32), PV_LEFT }, - { DRDATA (TIME, lpt_unit.wait, 24), PV_LEFT }, - { FLDATA (STOP_IOE, lpt_stopioe, 0) }, - { BRDATA (LBUF, lpt_buf, 8, 8, LPT_BSIZE) }, - { ORDATA (DEVNO, lpt_dib.dev, 6), REG_HRO }, - { NULL } }; - -DEVICE lpt_dev = { - "LPT", &lpt_unit, lpt_reg, lpt_mod, - 1, 10, 31, 1, 8, 8, - NULL, NULL, &lpt_reset, - NULL, &lpt_attach, &lpt_detach, - &lpt_dib, DEV_DISABLE }; -/* Type 647 line printer: IOT routines */ +#if defined (TYPE647) -int32 lpt65 (int32 pulse, int32 AC) -{ -int32 i, subp; +/* Type 647 line printer */ -subp = (pulse >> 4) & 03; /* subcode */ -if ((pulse & 001) && lpt_done) AC = IOT_SKP | AC; /* LPSF */ -if (pulse & 002) { /* pulse 02 */ - lpt_done = 0; /* clear done */ - CLR_INT (LPT); /* clear int req */ - if (subp == 0) { /* LPCB */ - for (i = 0; i < LPT_BSIZE; i++) lpt_buf[i] = 0; - bptr = 0; /* reset buf ptr */ - lpt_done = 1; /* set done */ - if (lpt_ie) SET_INT (LPT); } } /* set int */ -if (pulse & 004) { /* LPDI */ - switch (subp) { /* case on subcode */ - case 0: /* LPDI */ -#if defined (PDP9) - lpt_ie = 0; /* clear int enable */ - CLR_INT (LPT); /* clear int req */ -#endif - break; - case 2: /* LPB3 */ - if (bptr < LPT_BSIZE) { - lpt_buf[bptr] = lpt_buf[bptr] | ((AC >> 12) & 077); - bptr = bptr + 1; } - case 1: /* LPB2 */ - if (bptr < LPT_BSIZE) { - lpt_buf[bptr] = lpt_buf[bptr] | ((AC >> 6) & 077); - bptr = bptr + 1; } - case 3: /* LPB1 */ - if (bptr < LPT_BSIZE) { - lpt_buf[bptr] = lpt_buf[bptr] | (AC & 077); - bptr = bptr + 1; } - lpt_done = 1; /* set done */ - if (lpt_ie) SET_INT (LPT); /* set int */ - break; } /* end case */ - } /* end if pulse 4 */ -return AC; -} +#define LP647_BSIZE 120 /* line size */ -int32 lpt66 (int32 pulse, int32 AC) -{ -if ((pulse & 001) && lpt_err) AC = IOT_SKP | AC; /* LPSE */ -if (pulse & 002) { /* LPCF */ - lpt_done = 0; /* clear done, int */ - CLR_INT (LPT); } -if (pulse & 004) { - int32 subp = (pulse >> 4) & 03; /* get subpulse */ - if (subp < 3) { /* LPLS, LPPB, LPPS */ - lpt_iot = (pulse & 060) | (AC & 07); /* save parameters */ - sim_activate (&lpt_unit, lpt_unit.wait); } /* activate */ -#if defined (PDP9) - else { /* LPEI */ - lpt_ie = 1; /* set int enable */ - if (lpt_done) SET_INT (LPT); } -#endif - } /* end if pulse 4 */ -return AC; -} - -/* Unit service. lpt_iot specifies the action to be taken - - lpt_iot = 0x print only - lpt_iot = 2x space only, x is spacing command - lpt_iot = 4x print then space, x is spacing command -*/ - -t_stat lpt_svc (UNIT *uptr) -{ -int32 i; -char pbuf[LPT_BSIZE + 1]; -static const char *lpt_cc[] = { +int32 lp647_don = 0; /* ready */ +int32 lp647_ie = 1; /* int enable */ +int32 lp647_err = 0; /* error */ +int32 lp647_iot = 0; /* saved state */ +int32 lp647_stopioe = 0; +int32 lp647_bp = 0; /* buffer ptr */ +char lp647_buf[LP647_BSIZE] = { 0 }; +static const char *lp647_cc[] = { "\n", "\n\n", "\n\n\n", @@ -325,79 +233,355 @@ static const char *lpt_cc[] = { "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", "\f" }; -lpt_done = 1; -if (lpt_ie) SET_INT (LPT); /* set flag */ -if ((lpt_unit.flags & UNIT_ATT) == 0) { /* not attached? */ - lpt_err = 1; /* set error */ - return IORETURN (lpt_stopioe, SCPE_UNATT); } -if ((lpt_iot & 020) == 0) { /* print? */ - for (i = 0; i < bptr; i++) /* translate buffer */ - pbuf[i] = lpt_buf[i] | ((lpt_buf[i] >= 040)? 0: 0100); - if ((lpt_iot & 060) == 0) pbuf[bptr++] = '\r'; - for (i = 0; i < LPT_BSIZE; i++) lpt_buf[i] = 0; /* clear buffer */ - fwrite (pbuf, 1, bptr, lpt_unit.fileref); /* print buffer */ - if (ferror (lpt_unit.fileref)) { /* error? */ +DEVICE lp647_dev; +int32 lp647_65 (int32 pulse, int32 AC); +int32 lp647_66 (int32 pulse, int32 AC); +int32 lp647_iors (void); +t_stat lp647_svc (UNIT *uptr); +t_stat lp647_reset (DEVICE *dptr); +t_stat lp647_attach (UNIT *uptr, char *cptr); +t_stat lp647_detach (UNIT *uptr); + +/* Type 647 LPT data structures + + lp647_dev LPT device descriptor + lp647_unit LPT unit + lp647_reg LPT register list +*/ + +DIB lp647_dib = { DEV_LPT, 2, &lp647_iors, { &lp647_65, &lp647_66 } }; + +UNIT lp647_unit = { + UDATA (&lp647_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT }; + +REG lp647_reg[] = { + { ORDATA (BUF, lp647_unit.buf, 8) }, + { FLDATA (INT, int_hwre[API_LPT], INT_V_LPT) }, + { FLDATA (DONE, lp647_don, 0) }, +#if defined (PDP9) + { FLDATA (ENABLE, lp647_ie, 0) }, +#endif + { FLDATA (ERR, lp647_err, 0) }, + { DRDATA (BPTR, lp647_bp, 7) }, + { ORDATA (SCMD, lp647_iot, 6), REG_HRO }, + { DRDATA (POS, lp647_unit.pos, 32), PV_LEFT }, + { DRDATA (TIME, lp647_unit.wait, 24), PV_LEFT }, + { FLDATA (STOP_IOE, lp647_stopioe, 0) }, + { BRDATA (LBUF, lp647_buf, 8, 8, LP647_BSIZE) }, + { ORDATA (DEVNO, lp647_dib.dev, 6), REG_HRO }, + { NULL } }; + +MTAB lp647_mod[] = { + { MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_devno, &show_devno }, + { 0 } }; + +DEVICE lp647_dev = { + "LPT", &lp647_unit, lp647_reg, lp647_mod, + 1, 10, 31, 1, 8, 8, + NULL, NULL, &lp647_reset, + NULL, &lp647_attach, &lp647_detach, + &lp647_dib, DEV_DISABLE }; + +/* IOT routines */ + +int32 lp647_65 (int32 pulse, int32 AC) +{ +int32 i, sb; + +sb = pulse & 060; /* subcode */ +if ((pulse & 01) && lp647_don) AC = IOT_SKP | AC; /* LPSF */ +if (pulse & 02) { /* pulse 02 */ + lp647_don = 0; /* clear done */ + CLR_INT (LPT); /* clear int req */ + if (sb == 000) { /* LPCB */ + for (i = 0; i < LP647_BSIZE; i++) lp647_buf[i] = 0; + lp647_bp = 0; /* reset buf ptr */ + lp647_don = 1; /* set done */ + if (lp647_ie) SET_INT (LPT); } /* set int */ + } +if (pulse & 004) { /* LPDI */ + switch (sb) { /* case on subcode */ + case 000: /* LPDI */ +#if defined (PDP9) + lp647_ie = 0; /* clear int enable */ + CLR_INT (LPT); /* clear int req */ +#endif + break; + case 040: /* LPB3 */ + if (lp647_bp < LP647_BSIZE) { + lp647_buf[lp647_bp] = lp647_buf[lp647_bp] | ((AC >> 12) & 077); + lp647_bp = lp647_bp + 1; } + case 020: /* LPB2 */ + if (lp647_bp < LP647_BSIZE) { + lp647_buf[lp647_bp] = lp647_buf[lp647_bp] | ((AC >> 6) & 077); + lp647_bp = lp647_bp + 1; } + case 060: /* LPB1 */ + if (lp647_bp < LP647_BSIZE) { + lp647_buf[lp647_bp] = lp647_buf[lp647_bp] | (AC & 077); + lp647_bp = lp647_bp + 1; } + lp647_don = 1; /* set done */ + if (lp647_ie) SET_INT (LPT); /* set int */ + break; } /* end case */ + } +return AC; +} + +int32 lp647_66 (int32 pulse, int32 AC) +{ +if ((pulse & 01) && lp647_err) AC = IOT_SKP | AC; /* LPSE */ +if (pulse & 02) { /* LPCF */ + lp647_don = 0; /* clear done, int */ + CLR_INT (LPT); } +if (pulse & 04) { + if ((pulse & 060) < 060) { /* LPLS, LPPB, LPPS */ + lp647_iot = (pulse & 060) | (AC & 07); /* save parameters */ + sim_activate (&lp647_unit, lp647_unit.wait); } /* activate */ +#if defined (PDP9) + else { /* LPEI */ + lp647_ie = 1; /* set int enable */ + if (lp647_don) SET_INT (LPT); } +#endif + } +return AC; +} + +/* Unit service. lp647_iot specifies the action to be taken + + lp647_iot = 0x print only + lp647_iot = 2x space only, x is spacing command + lp647_iot = 4x print then space, x is spacing command +*/ + +t_stat lp647_svc (UNIT *uptr) +{ +int32 i; +char pbuf[LP647_BSIZE + 1]; + +lp647_don = 1; +if (lp647_ie) SET_INT (LPT); /* set flag */ +if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */ + lp647_err = 1; /* set error */ + return IORETURN (lp647_stopioe, SCPE_UNATT); } +if ((lp647_iot & 020) == 0) { /* print? */ + for (i = 0; i < lp647_bp; i++) /* translate buffer */ + pbuf[i] = lp647_buf[i] | ((lp647_buf[i] >= 040)? 0: 0100); + if ((lp647_iot & 060) == 0) pbuf[lp647_bp++] = '\r'; + for (i = 0; i < LP647_BSIZE; i++) lp647_buf[i] = 0; /* clear buffer */ + fwrite (pbuf, 1, lp647_bp, uptr->fileref); /* print buffer */ + if (ferror (uptr->fileref)) { /* error? */ perror ("LPT I/O error"); - clearerr (lpt_unit.fileref); - bptr = 0; + clearerr (uptr->fileref); + lp647_bp = 0; return SCPE_IOERR; } - bptr = 0; } /* clear buffer ptr */ -if (lpt_iot & 060) { /* space? */ - fputs (lpt_cc[lpt_iot & 07], lpt_unit.fileref); /* write cctl */ - if (ferror (lpt_unit.fileref)) { /* error? */ + lp647_bp = 0; } /* clear buffer ptr */ +if (lp647_iot & 060) { /* space? */ + fputs (lp647_cc[lp647_iot & 07], uptr->fileref); /* write cctl */ + if (ferror (uptr->fileref)) { /* error? */ perror ("LPT I/O error"); - clearerr (lpt_unit.fileref); + clearerr (uptr->fileref); return SCPE_IOERR; } } -lpt_unit.pos = ftell (lpt_unit.fileref); /* update position */ +uptr->pos = ftell (uptr->fileref); /* update position */ return SCPE_OK; } /* Reset routine */ -t_stat lpt_reset (DEVICE *dptr) +t_stat lp647_reset (DEVICE *dptr) { int32 i; -lpt_done = 0; /* clear done */ -lpt_err = (lpt_unit.flags & UNIT_ATT)? 0: 1; /* compute error */ -lpt_ie = 1; /* set enable */ +lp647_don = 0; /* clear done */ +lp647_err = (lp647_unit.flags & UNIT_ATT)? 0: 1; /* clr/set error */ +lp647_ie = 1; /* set enable */ CLR_INT (LPT); /* clear int */ -sim_cancel (&lpt_unit); /* deactivate unit */ -bptr = 0; /* clear buffer ptr */ -lpt_iot = 0; /* clear state */ -for (i = 0; i < LPT_BSIZE; i++) lpt_buf[i] = 0; /* clear buffer */ +sim_cancel (&lp647_unit); /* deactivate unit */ +lp647_bp = 0; /* clear buffer ptr */ +lp647_iot = 0; /* clear state */ +for (i = 0; i < LP647_BSIZE; i++) lp647_buf[i] = 0; /* clear buffer */ return SCPE_OK; } /* IORS routine */ -int32 lpt_iors (void) +int32 lp647_iors (void) { -return (lpt_done? IOS_LPT: 0) | (lpt_err? IOS_LPT1: 0); +return (lp647_don? IOS_LPT: 0) | (lp647_err? IOS_LPT1: 0); } /* Attach routine */ -t_stat lpt_attach (UNIT *uptr, char *cptr) +t_stat lp647_attach (UNIT *uptr, char *cptr) { t_stat reason; reason = attach_unit (uptr, cptr); -lpt_err = (lpt_unit.flags & UNIT_ATT)? 0: 1; /* compute error */ +lp647_err = (lp647_unit.flags & UNIT_ATT)? 0: 1; /* clr/set error */ return reason; } /* Detach routine */ -t_stat lpt_detach (UNIT *uptr) +t_stat lp647_detach (UNIT *uptr) { -lpt_err = 1; +lp647_err = 1; return detach_unit (uptr); } - -#elif defined (LP15) -#define LPT_BSIZE 132 /* line size */ +#endif + +#if defined (LP09) + +/* LP09 line printer */ + +#define LP09_BSIZE 132 /* line size */ + +int32 lp09_don = 0; /* ready */ +int32 lp09_err = 0; /* error */ +int32 lp09_ie = 1; /* int enable */ +int32 lp09_stopioe = 0; +DEVICE lp09_dev; + +int32 lp09_66 (int32 pulse, int32 AC); +int32 lp09_iors (void); +t_stat lp09_svc (UNIT *uptr); +t_stat lp09_reset (DEVICE *dptr); +t_stat lp09_attach (UNIT *uptr, char *cptr); +t_stat lp09_detach (UNIT *uptr); + +/* LP09 LPT data structures + + lp09_dev LPT device descriptor + lp09_unit LPT unit + lp09_reg LPT register list +*/ + +DIB lp09_dib = { DEV_LPT, 2, &lp09_iors, { NULL, &lp09_66 } }; + +UNIT lp09_unit = { + UDATA (&lp09_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT }; + +REG lp09_reg[] = { + { ORDATA (BUF, lp09_unit.buf, 7) }, + { FLDATA (INT, int_hwre[API_LPT], INT_V_LPT) }, + { FLDATA (DONE, lp09_don, 0) }, + { FLDATA (ENABLE, lp09_ie, 0) }, + { FLDATA (ERR, lp09_err, 0) }, + { DRDATA (POS, lp09_unit.pos, 32), PV_LEFT }, + { DRDATA (TIME, lp09_unit.wait, 24), PV_LEFT }, + { FLDATA (STOP_IOE, lp09_stopioe, 0) }, + { ORDATA (DEVNO, lp09_dib.dev, 6), REG_HRO }, + { NULL } }; + +MTAB lp09_mod[] = { + { MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_devno, &show_devno }, + { 0 } }; + +DEVICE lp09_dev = { + "LP9", &lp09_unit, lp09_reg, lp09_mod, + 1, 10, 31, 1, 8, 8, + NULL, NULL, &lp09_reset, + NULL, &lp09_attach, &lp09_detach, + &lp09_dib, DEV_DISABLE | DEV_DIS }; + +/* IOT routines */ + +int32 lp09_66 (int32 pulse, int32 AC) +{ +int32 sb = pulse & 060; /* subopcode */ + +if (pulse & 001) { + if ((sb == 000) && lp09_don) AC = IOT_SKP | AC; /* LSDF */ + if ((sb == 020) && lp09_err) AC = IOT_SKP | AC; /* LSEF */ + } +if (pulse & 002) { + if (sb == 000) { /* LSCF */ + lp09_don = 0; /* clear done, int */ + CLR_INT (LPT); } + else if (sb == 020) { /* LPLD */ + lp09_don = 0; /* clear done, int */ + CLR_INT (LPT); + lp09_unit.buf = AC & 0177; /* load char */ + if ((lp09_unit.buf == 015) || (lp09_unit.buf == 014) || + (lp09_unit.buf == 012)) + sim_activate (&lp09_unit, lp09_unit.wait); + else AC = AC | (lp09_svc (&lp09_unit) << IOT_V_REASON); } + } +if (pulse & 004) { + if (sb == 000) { /* LIOF */ + lp09_ie = 0; /* clear int enab */ + CLR_INT (LPT); } /* clear int */ + else if (sb == 040) { /* LION */ + lp09_ie = 1; /* set int enab */ + if (lp09_don) SET_INT (LPT); } /* if done, set int */ + } +return AC; +} + +/* Unit service */ + +t_stat lp09_svc (UNIT *uptr) +{ +int32 c; + +lp09_don = 1; /* set done */ +if (lp09_ie) SET_INT (LPT); /* int enb? req int */ +if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */ + lp09_err = 1; /* set error */ + return IORETURN (lp09_stopioe, SCPE_UNATT); } +c = uptr->buf & 0177; /* get char */ +if ((c == 0) || (c == 0177)) return SCPE_OK; /* skip NULL, DEL */ +if (fputc (c, uptr->fileref) == EOF) { /* print char */ + perror ("LPT I/O error"); + clearerr (uptr->fileref); + return SCPE_IOERR; } +uptr->pos = uptr->pos + 1; /* update position */ +return SCPE_OK; +} + +/* Reset routine */ + +t_stat lp09_reset (DEVICE *dptr) +{ +lp09_don = 0; /* clear done */ +lp09_err = (lp09_unit.flags & UNIT_ATT)? 0: 1; /* compute error */ +lp09_ie = 1; /* set enable */ +CLR_INT (LPT); /* clear int */ +return SCPE_OK; +} + +/* IORS routine */ + +int32 lp09_iors (void) +{ +return (lp09_don? IOS_LPT: 0); +} + +/* Attach routine */ + +t_stat lp09_attach (UNIT *uptr, char *cptr) +{ +t_stat reason; + +reason = attach_unit (uptr, cptr); +lp09_err = (lp09_unit.flags & UNIT_ATT)? 0: 1; /* clr/set error */ +return reason; +} + +/* Detach routine */ + +t_stat lp09_detach (UNIT *uptr) +{ +lp09_err = 1; +return detach_unit (uptr); +} + +#endif + +#if defined (LP15) + +/* LP15 line printer */ + +#define LP15_BSIZE 132 /* line size */ #define LPT_WC 034 /* word count */ #define LPT_CA 035 /* current addr */ @@ -414,76 +598,99 @@ return detach_unit (uptr); #define STA_CLR 0003777 /* always clear */ extern int32 M[]; -int32 lpt_sta = 0, lpt_ie = 1, lpt_stopioe = 0; -int32 mode = 0, lcnt = 0, bptr = 0; -char lpt_buf[LPT_BSIZE] = { 0 }; +int32 lp15_sta = 0; +int32 lp15_ie = 1; +int32 lp15_stopioe = 0; +int32 lp15_mode = 0; +int32 lp15_lc = 0; +int32 lp15_bp = 0; +char lp15_buf[LP15_BSIZE] = { 0 }; -int32 lpt_updsta (int32 new); +DEVICE lp15_dev; +int32 lp15_65 (int32 pulse, int32 AC); +int32 lp15_66 (int32 pulse, int32 AC); +int32 lp15_iors (void); +t_stat lp15_svc (UNIT *uptr); +t_stat lp15_reset (DEVICE *dptr); + +int32 lp15_updsta (int32 new); /* LP15 LPT data structures - lpt_dev LPT device descriptor - lpt_unit LPT unit - lpt_reg LPT register list + lp15_dev LPT device descriptor + lp15_unit LPT unit + lp15_reg LPT register list */ -REG lpt_reg[] = { - { ORDATA (STA, lpt_sta, 18) }, +DIB lp15_dib = { DEV_LPT, 2, &lp15_iors, { &lp15_65, &lp15_66 } }; + +UNIT lp15_unit = { + UDATA (&lp15_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT }; + +REG lp15_reg[] = { + { ORDATA (STA, lp15_sta, 18) }, { ORDATA (CA, M[LPT_CA], 18) }, { FLDATA (INT, int_hwre[API_LPT], INT_V_LPT) }, - { FLDATA (ENABLE, lpt_ie, 0) }, - { DRDATA (LCNT, lcnt, 9) }, - { DRDATA (BPTR, bptr, 8) }, - { FLDATA (MODE, mode, 0) }, - { DRDATA (POS, lpt_unit.pos, 32), PV_LEFT }, - { DRDATA (TIME, lpt_unit.wait, 24), PV_LEFT }, - { FLDATA (STOP_IOE, lpt_stopioe, 0) }, - { BRDATA (LBUF, lpt_buf, 8, 8, LPT_BSIZE) }, - { ORDATA (DEVNO, lpt_dib.dev, 6), REG_HRO }, + { FLDATA (ENABLE, lp15_ie, 0) }, + { DRDATA (LCNT, lp15_lc, 9) }, + { DRDATA (BPTR, lp15_bp, 8) }, + { FLDATA (MODE, lp15_mode, 0) }, + { DRDATA (POS, lp15_unit.pos, 32), PV_LEFT }, + { DRDATA (TIME, lp15_unit.wait, 24), PV_LEFT }, + { FLDATA (STOP_IOE, lp15_stopioe, 0) }, + { BRDATA (LBUF, lp15_buf, 8, 8, LP15_BSIZE) }, + { ORDATA (DEVNO, lp15_dib.dev, 6), REG_HRO }, { NULL } }; -DEVICE lpt_dev = { - "LPT", &lpt_unit, lpt_reg, lpt_mod, +MTAB lp15_mod[] = { + { MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_devno, &show_devno }, + { 0 } }; + +DEVICE lp15_dev = { + "LPT", &lp15_unit, lp15_reg, lp15_mod, 1, 10, 31, 1, 8, 8, - NULL, NULL, &lpt_reset, + NULL, NULL, &lp15_reset, NULL, NULL, NULL, - &lpt_dib, DEV_DISABLE }; + &lp15_dib, DEV_DISABLE }; -/* LP15 line printer: IOT routines */ +/* IOT routines */ -int32 lpt65 (int32 pulse, int32 AC) +int32 lp15_65 (int32 pulse, int32 AC) { -int32 header; +int32 header, sb; -if (pulse == 001) /* LPSF */ - return (lpt_sta & (STA_ERR | STA_DON))? IOT_SKP + AC: AC; -if ((pulse == 021) || (pulse == 041)) { /* LPP1, LPPM */ - header = M[(M[LPT_CA] + 1) & ADDRMASK]; /* get first word */ - M[LPT_CA] = (M[LPT_CA] + 2) & 0777777; - mode = header & 1; /* mode */ - if (pulse == 041) lcnt = 1; /* line count */ - else lcnt = (header >> 9) & 0377; - if (lcnt == 0) lcnt = 256; - bptr = 0; /* reset buf ptr */ - sim_activate (&lpt_unit, lpt_unit.wait); } /* activate */ -if (pulse == 061) lpt_ie = 0; /* LPDI */ -if (pulse == 042) return lpt_updsta (0); /* LPOS, LPRS */ -if (pulse == 044) lpt_ie = 1; /* LPEI */ -lpt_updsta (0); /* update status */ +sb = pulse & 060; /* subopcode */ +if (pulse & 01) { + if ((sb == 000) && (lp15_sta & (STA_ERR | STA_DON))) /* LPSF */ + AC = IOT_SKP | AC; + else if ((sb == 020) || (sb == 040)) { /* LPP1, LPPM */ + sim_activate (&lp15_unit, lp15_unit.wait); /* activate */ + header = M[(M[LPT_CA] + 1) & ADDRMASK]; /* get first word */ + M[LPT_CA] = (M[LPT_CA] + 2) & 0777777; + lp15_mode = header & 1; /* mode */ + if (sb == 040) lp15_lc = 1; /* line count */ + else lp15_lc = (header >> 9) & 0377; + if (lp15_lc == 0) lp15_lc = 256; + lp15_bp = 0; } /* reset buf ptr */ + else if (sb == 060) lp15_ie = 0; /* LPDI */ + } +if ((pulse & 02) && (sb == 040)) AC = AC | lp15_updsta (0); /* LPOS, LPRS */ +if ((pulse & 04) && (sb == 040)) lp15_ie = 1; /* LPEI */ +lp15_updsta (0); /* update status */ return AC; } -int32 lpt66 (int32 pulse, int32 AC) +int32 lp15_66 (int32 pulse, int32 AC) { -if (pulse == 021) lpt_sta = lpt_sta & ~STA_DON; /* LPCD */ -if (pulse == 041) lpt_sta = 0; /* LPCF */ -lpt_updsta (0); /* update status */ +if (pulse == 021) lp15_sta = lp15_sta & ~STA_DON; /* LPCD */ +if (pulse == 041) lp15_sta = 0; /* LPCF */ +lp15_updsta (0); /* update status */ return AC; } /* Unit service */ -t_stat lpt_svc (UNIT *uptr) +t_stat lp15_svc (UNIT *uptr) { int32 i, ccnt, more, w0, w1; char c[5]; @@ -496,15 +703,15 @@ static const char *ctrl[040] = { "\n\n\n\n\n\n\n\n\n\n", NULL, NULL, NULL, NULL, NULL, NULL, "\r", NULL, NULL, NULL, NULL }; -if ((lpt_unit.flags & UNIT_ATT) == 0) { /* not attached? */ - lpt_updsta (STA_DON | STA_ALM); /* set done, err */ - return IORETURN (lpt_stopioe, SCPE_UNATT); } +if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */ + lp15_updsta (STA_DON | STA_ALM); /* set done, err */ + return IORETURN (lp15_stopioe, SCPE_UNATT); } for (more = 1; more != 0; ) { /* loop until ctrl */ w0 = M[(M[LPT_CA] + 1) & ADDRMASK]; /* get first word */ w1 = M[(M[LPT_CA] + 2) & ADDRMASK]; /* get second word */ M[LPT_CA] = (M[LPT_CA] + 2) & 0777777; /* advance mem addr */ - if (mode) { /* unpacked? */ + if (lp15_mode) { /* unpacked? */ c[0] = w0 & 0177; c[1] = w1 & 0177; ccnt = 2; } @@ -517,55 +724,55 @@ for (more = 1; more != 0; ) { /* loop until ctrl */ ccnt = 5; } for (i = 0; i < ccnt; i++) { /* loop through */ if ((c[i] <= 037) && ctrl[c[i]]) { /* control char? */ - fwrite (lpt_buf, 1, bptr, lpt_unit.fileref); - fputs (ctrl[c[i]], lpt_unit.fileref); - if (ferror (lpt_unit.fileref)) { /* error? */ + fwrite (lp15_buf, 1, lp15_bp, uptr->fileref); + fputs (ctrl[c[i]], uptr->fileref); + if (ferror (uptr->fileref)) { /* error? */ perror ("LPT I/O error"); - clearerr (lpt_unit.fileref); - bptr = 0; - lpt_updsta (STA_DON | STA_ALM); + clearerr (uptr->fileref); + lp15_bp = 0; + lp15_updsta (STA_DON | STA_ALM); return SCPE_IOERR; } - lpt_unit.pos = ftell (lpt_unit.fileref); - bptr = more = 0; } + uptr->pos = ftell (uptr->fileref); + lp15_bp = more = 0; } else { - if (bptr < LPT_BSIZE) lpt_buf[bptr++] = c[i]; - else lpt_sta = lpt_sta | STA_OVF; } } } + if (lp15_bp < LP15_BSIZE) lp15_buf[lp15_bp++] = c[i]; + else lp15_sta = lp15_sta | STA_OVF; } } } -lcnt = lcnt - 1; /* decr line count */ -if (lcnt) sim_activate (&lpt_unit, lpt_unit.wait); /* more to do? */ -else lpt_updsta (STA_DON); /* no, set done */ +lp15_lc = lp15_lc - 1; /* decr line count */ +if (lp15_lc) sim_activate (&lp15_unit, uptr->wait); /* more to do? */ +else lp15_updsta (STA_DON); /* no, set done */ return SCPE_OK; } /* Update status */ -int32 lpt_updsta (int32 new) +int32 lp15_updsta (int32 new) { -lpt_sta = (lpt_sta | new) & ~(STA_CLR | STA_ERR | STA_BUSY); -if (lpt_sta & STA_EFLGS) lpt_sta = lpt_sta | STA_ERR; /* update errors */ -if (sim_is_active (&lpt_unit)) lpt_sta = lpt_sta | STA_BUSY; -if (lpt_ie && (lpt_sta & STA_DON)) SET_INT (LPT); +lp15_sta = (lp15_sta | new) & ~(STA_CLR | STA_ERR | STA_BUSY); +if (lp15_sta & STA_EFLGS) lp15_sta = lp15_sta | STA_ERR; /* update errors */ +if (sim_is_active (&lp15_unit)) lp15_sta = lp15_sta | STA_BUSY; +if (lp15_ie && (lp15_sta & STA_DON)) SET_INT (LPT); else CLR_INT (LPT); /* update int */ -return lpt_sta; +return lp15_sta; } /* Reset routine */ -t_stat lpt_reset (DEVICE *dptr) +t_stat lp15_reset (DEVICE *dptr) { -mode = lcnt = bptr = 0; /* clear controls */ -sim_cancel (&lpt_unit); /* deactivate unit */ -lpt_sta = 0; /* clear status */ -lpt_ie = 1; /* enable interrupts */ -lpt_updsta (0); /* update status */ +lp15_mode = lp15_lc = lp15_bp = 0; /* clear controls */ +sim_cancel (&lp15_unit); /* deactivate unit */ +lp15_sta = 0; /* clear status */ +lp15_ie = 1; /* enable interrupts */ +lp15_updsta (0); /* update status */ return SCPE_OK; } /* IORS routine */ -int32 lpt_iors (void) +int32 lp15_iors (void) { -return ((lpt_sta & STA_DON)? IOS_LPT: 0); +return ((lp15_sta & STA_DON)? IOS_LPT: 0); } #endif diff --git a/PDP18B/pdp18b_mt.c b/PDP18B/pdp18b_mt.c index 060c8630..cbec8261 100644 --- a/PDP18B/pdp18b_mt.c +++ b/PDP18B/pdp18b_mt.c @@ -1,6 +1,6 @@ /* pdp18b_mt.c: 18b PDP magnetic tape simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, 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 @@ mt (PDP-9) TC59 magtape (PDP-15) TC59D magtape + 02-Feb-03 RMS Revised IOT decoding 30-Oct-02 RMS Revised BOT handling, added error record handling 05-Oct-02 RMS Added DIB, device number support Revamped error recovery @@ -192,35 +193,44 @@ DEVICE mt_dev = { int32 mt (int32 pulse, int32 AC) { -int32 f; +int32 f, sb; UNIT *uptr; uptr = mt_dev.units + GET_UNIT (mt_cu); /* get unit */ mt_updcsta (uptr, 0); /* update status */ -if (pulse == 001) /* MTTR */ - return (!sim_is_active (uptr))? IOT_SKP + AC: AC; -if (pulse == 021) /* MTCR */ - return (!mt_busy ())? IOT_SKP + AC: AC; -if (pulse == 041) /* MTSF */ - return (mt_sta & (STA_ERR | STA_DON))? IOT_SKP + AC: AC; -if (pulse == 002) return (mt_cu & 0777700); /* MTRC */ -if (pulse == 042) return mt_sta; /* MTRS */ -if ((pulse & 062) == 022) { /* MTAF, MTLC */ - if (!mt_busy ()) mt_cu = mt_sta = 0; /* if not busy, clr */ - mt_sta = mt_sta & ~(STA_ERR | STA_DON); } /* clear flags */ -if ((pulse & 064) == 024) /* MTCM, MTLC */ - mt_cu = (mt_cu & 0770700) | (AC & 0777700); /* load status */ -if (pulse == 004) { /* MTGO */ - f = GET_CMD (mt_cu); /* get function */ - if (mt_busy () || (sim_is_active (uptr)) || - (((f == FN_SPACER) || (f == FN_REWIND)) & (uptr->USTAT & STA_BOT)) || - (((f == FN_WRITE) || (f == FN_WREOF)) && (uptr->flags & UNIT_WPRT)) - || ((uptr->flags & UNIT_ATT) == 0) || (f == FN_NOP)) - mt_sta = mt_sta | STA_ILL; /* illegal op flag */ - else { - if (f == FN_REWIND) uptr->USTAT = STA_REW; /* rewind? */ - else mt_sta = uptr->USTAT = 0; /* no, clear status */ - sim_activate (uptr, mt_time); } } /* start io */ +sb = pulse & 060; /* subop */ +if (pulse & 01) { + if ((sb == 000) && !sim_is_active (uptr)) /* MTTR */ + AC = IOT_SKP | AC; + else if ((sb == 020) && !mt_busy ()) /* MTCR */ + AC = IOT_SKP | AC; + else if ((sb == 040) && (mt_sta & (STA_ERR | STA_DON))) /* MTSF */ + AC = IOT_SKP | AC; + } +if (pulse & 02) { + if (sb == 000) AC = AC | (mt_cu & 0777700); /* MTRC */ + else if (sb == 020) { /* MTAF, MTLC */ + if (!mt_busy ()) mt_cu = mt_sta = 0; /* if not busy, clr */ + mt_sta = mt_sta & ~(STA_ERR | STA_DON); } /* clear flags */ + else if (sb == 040) AC = AC | mt_sta; /* MTRS */ + } +if (pulse & 04) { + if (sb == 000) { /* MTGO */ + f = GET_CMD (mt_cu); /* get function */ + if (mt_busy () || + sim_is_active (uptr) || + (f == FN_NOP) || + (((f == FN_SPACER) || (f == FN_REWIND)) && (uptr->USTAT & STA_BOT)) || + (((f == FN_WRITE) || (f == FN_WREOF)) && (uptr->flags & UNIT_WPRT)) || + ((uptr->flags & UNIT_ATT) == 0)) + mt_sta = mt_sta | STA_ILL; /* illegal op flag */ + else { + if (f == FN_REWIND) uptr->USTAT = STA_REW; /* rewind? */ + else mt_sta = uptr->USTAT = 0; /* no, clear status */ + sim_activate (uptr, mt_time); } } /* start io */ + if (sb == 020) /* MTCM, MTLC */ + mt_cu = (mt_cu & 0770700) | (AC & 0777700); /* load status */ + } mt_updcsta (mt_dev.units + GET_UNIT (mt_cu), 0); /* update status */ return AC; } @@ -340,20 +350,22 @@ case FN_WREOF: case FN_SPACEF: /* space forward */ do { + M[MT_WC] = (M[MT_WC] + 1) & 0777777; /* inc WC */ if (mt_rdlntf (uptr, &tbc, &err)) break; /* read rec lnt, err? */ uptr->pos = uptr->pos + ((tbc + 1) & ~1) + (2 * sizeof (t_mtrlnt)); } - while ((M[MT_WC] = (M[MT_WC] + 1) & 0777777) != 0); + while (M[MT_WC] != 0); break; case FN_SPACER: /* space reverse */ do { + M[MT_WC] = (M[MT_WC] + 1) & 0777777; /* inc WC */ if (pnu) pnu = 0; /* pos not upd? */ else { if (mt_rdlntf (uptr, &tbc, &err)) break; uptr->pos = uptr->pos - ((tbc + 1) & ~1) - (2 * sizeof (t_mtrlnt)); } } - while ((M[MT_WC] = (M[MT_WC] + 1) & 0777777) != 0); + while (M[MT_WC] != 0); break; } /* end case */ mt_updcsta (uptr, STA_DON | (err? STA_PAR: 0)); /* set done */ diff --git a/PDP18B/pdp18b_rb.c b/PDP18B/pdp18b_rb.c new file mode 100644 index 00000000..f25113ab --- /dev/null +++ b/PDP18B/pdp18b_rb.c @@ -0,0 +1,273 @@ +/* pdp18b_rb.c: RB09 fixed head disk simulator + + Copyright (c) 2003, 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. + + rb RB09 fixed head disk + + The RB09 is a head-per-track disk. It uses the single cycle data break + facility. To minimize overhead, the entire RB09 is buffered in memory. + + Two timing parameters are provided: + + rb_time Interword timing. Must be non-zero. + rb_burst Burst mode. If 0, DMA occurs cycle by cycle; otherwise, + DMA occurs in a burst. +*/ + +#include "pdp18b_defs.h" +#include + +/* Constants */ + +#define RB_NUMWD 64 /* words/sector */ +#define RB_NUMSC 80 /* sectors/track */ +#define RB_NUMTR 200 /* tracks/disk */ +#define RB_WLKTR 10 /* tracks/wlock switch */ +#define RB_SIZE (RB_NUMTR * RB_NUMSC * RB_NUMWD) /* words/drive */ + +/* Function/status register */ + +#define RBS_ERR 0400000 /* error */ +#define RBS_PAR 0200000 /* parity error */ +#define RBS_ILA 0100000 /* ill addr error */ +#define RBS_TIM 0040000 /* timing transfer */ +#define RBS_NRY 0020000 /* not ready error */ +#define RBS_DON 0010000 /* done */ +#define RBS_IE 0004000 /* int enable */ +#define RBS_BSY 0002000 /* busy */ +#define RBS_WR 0001000 /* read/write */ +#define RBS_XOR (RBS_IE|RBS_BSY|RBS_WR) /* set by XOR */ +#define RBS_MBZ 0000777 /* always clear */ +#define RBS_EFLGS (RBS_PAR|RBS_ILA|RBS_TIM|RBS_NRY) /* error flags */ + +/* BCD disk address */ + +#define RBA_V_TR 8 +#define RBA_M_TR 0x1FF +#define RBA_V_SC 0 +#define RBA_M_SC 0xFF +#define RBA_GETTR(x) (((x) >> RBA_V_TR) & RBA_M_TR) +#define RBA_GETSC(x) (((x) >> RBA_V_SC) & RBA_M_SC) + +#define GET_POS(x) ((int) fmod (sim_gtime () / ((double) (x)), \ + ((double) (RB_NUMSC * RB_NUMWD)))) + +extern int32 M[]; +extern int32 int_hwre[API_HLVL+1]; +extern UNIT cpu_unit; + +int32 rb_sta = 0; /* status register */ +int32 rb_da = 0; /* disk address */ +int32 rb_ma = 0; /* current addr */ +int32 rb_wc = 0; /* word count */ +int32 rb_wlk = 0; /* write lock */ +int32 rb_time = 10; /* inter-word time */ +int32 rb_burst = 1; /* burst mode flag */ +int32 rb_stopioe = 1; /* stop on error */ + +DEVICE rb_dev; +int32 rb71 (int32 pulse, int32 AC); +t_stat rb_svc (UNIT *uptr); +t_stat rb_reset (DEVICE *dptr); +int32 rb_updsta (int32 new); +int32 rb_make_da (int32 dat); +int32 rb_make_bcd (int32 dat); +int32 rb_set_da (int32 dat, int32 old); +int32 rb_set_bcd (int32 dat); + +/* RB data structures + + rb_dev RF device descriptor + rb_unit RF unit descriptor + rb_reg RF register list +*/ + +DIB rb_dib = { DEV_RB, 1, NULL, { &rb71 } }; + +UNIT rb_unit = + { UDATA (&rb_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF, + RB_SIZE) }; + +REG rb_reg[] = { + { ORDATA (STA, rb_sta, 18) }, + { ORDATA (DA, rb_da, 20) }, + { ORDATA (WC, rb_wc, 16) }, + { ORDATA (MA, rb_ma, ADDRSIZE) }, + { FLDATA (INT, int_hwre[API_RB], INT_V_RB) }, + { ORDATA (WLK, rb_wlk, RB_NUMTR / RB_WLKTR) }, + { DRDATA (TIME, rb_time, 24), PV_LEFT + REG_NZ }, + { FLDATA (BURST, rb_burst, 0) }, + { FLDATA (STOP_IOE, rb_stopioe, 0) }, + { ORDATA (DEVNO, rb_dib.dev, 6), REG_HRO }, + { NULL } }; + +MTAB rb_mod[] = { + { MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_devno, &show_devno }, + { 0 } }; + +DEVICE rb_dev = { + "RB", &rb_unit, rb_reg, rb_mod, + 1, 8, 21, 1, 8, 18, + NULL, NULL, &rb_reset, + NULL, NULL, NULL, + &rb_dib, DEV_DIS | DEV_DISABLE }; + +/* IOT routines */ + +int32 rb71 (int32 pulse, int32 AC) +{ +int32 tow, t, sb = pulse & 060; + +if (pulse & 001) { + if (sb == 000) rb_sta = rb_sta & /* DBCF */ + ~(RBS_ERR | RBS_EFLGS | RBS_DON); + if ((sb == 020) && (rb_sta & (RBS_ERR | RBS_DON))) + AC = AC | IOT_SKP; /* DBSF */ + if (sb == 040) rb_sta = 0; /* DBCS */ + } +if (pulse & 002) { + if (sb == 000) AC = AC | rb_make_da (rb_da); /* DBRD */ + if (sb == 020) AC = AC | rb_sta; /* DBRS */ + if (sb == 040) rb_ma = AC & ADDRMASK; /* DBLM */ + } +if (pulse & 004) { + if (sb == 000) rb_da = rb_set_da (AC, rb_da); /* DBLD */ + if (sb == 020) rb_wc = AC & 0177777; /* DBLW */ + if (sb == 040) { /* DBLS */ + rb_sta = (rb_sta & RBS_XOR) ^ (AC & ~RBS_MBZ); + if (rb_sta & RBS_BSY) { /* busy set? */ + if (!sim_is_active (&rb_unit)) { /* schedule */ + tow = rb_da % (RB_NUMSC * RB_NUMWD); + t = tow - GET_POS (rb_time); + if (t < 0) t = t + (RB_NUMSC * RB_NUMWD); + sim_activate (&rb_unit, t * rb_time); } } + else sim_cancel (&rb_unit); } /* no, stop */ + } +rb_updsta (0); /* update status */ +return AC; +} + +int32 rb_make_da (int32 da) +{ +int32 t = da / (RB_NUMSC * RB_NUMWD); /* bin track */ +int32 s = (da % (RB_NUMSC * RB_NUMWD)) / RB_NUMWD; /* bin sector */ +int32 bcd_t = rb_make_bcd (t); /* bcd track */ +int32 bcd_s = rb_make_bcd (s); /* bcd sector */ +return (bcd_t << RBA_V_TR) | (bcd_s << RBA_V_SC); +} + +int32 rb_set_da (int32 bcda, int32 old_da) +{ +int32 bcd_t = RBA_GETTR (bcda); /* bcd track */ +int32 bcd_s = RBA_GETSC (bcda); /* bcd sector */ +int32 t = rb_set_bcd (bcd_t); /* bin track */ +int32 s = rb_set_bcd (bcd_s); /* bin sector */ + +if ((t >= RB_NUMTR) || (t < 0) || /* invalid? */ + (s >= RB_NUMSC) || (s < 0)) { + rb_updsta (RBS_ILA); /* error */ + return old_da; } /* don't change */ +else return (((t * RB_NUMSC) + s) * RB_NUMWD); /* new da */ +} + +int32 rb_make_bcd (int32 bin) +{ +int32 d, i, r; + +for (r = i = 0; bin != 0; bin = bin / 10) { /* while nz */ + d = bin % 10; /* dec digit */ + r = r | (d << i); /* insert bcd */ + i = i + 4; } +return r; +} + +int32 rb_set_bcd (int32 bcd) +{ +int32 d, i, r; + +for (r = 0, i = 1; bcd != 0; bcd = bcd >> 4) { /* while nz */ + d = bcd & 0xF; /* bcd digit */ + if (d >= 10) return -1; /* invalid? */ + r = r + (d * i); /* insert bin */ + i = i * 10; } +return r; +} + +/* Unit service - disk is buffered in memory */ + +t_stat rb_svc (UNIT *uptr) +{ +int32 t, sw; + +if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */ + rb_updsta (RBS_NRY | RBS_DON); /* set nxd, done */ + return IORETURN (rb_stopioe, SCPE_UNATT); } + +do { if (rb_sta & RBS_WR) { /* write? */ + t = rb_da / (RB_NUMSC * RB_NUMWD); /* track */ + sw = t / RB_WLKTR; /* switch */ + if ((rb_wlk >> sw) & 1) { /* write locked? */ + rb_updsta (RBS_ILA | RBS_DON); + break; } + else { + *(((int32 *) uptr->filebuf) + rb_da) = M[rb_ma]; + if (((t_addr) rb_da) >= uptr->hwmark) uptr->hwmark = rb_da + 1; } } + else if (MEM_ADDR_OK (rb_ma)) /* read, valid addr? */ + M[rb_ma] = *(((int32 *) uptr->filebuf) + rb_da); + rb_wc = (rb_wc + 1) & 0177777; /* incr word count */ + rb_ma = (rb_ma + 1) & ADDRMASK; /* incr mem addr */ + rb_da = rb_da + 1; /* incr disk addr */ + if (rb_da > RB_SIZE) rb_da = 0; /* disk wraparound? */ + } +while ((rb_wc != 0) && (rb_burst != 0)); /* brk if wc, no brst */ + +if ((rb_wc != 0) && ((rb_sta & RBS_ERR) == 0)) /* more to do? */ + sim_activate (&rb_unit, rb_time); /* sched next */ +else rb_updsta (RBS_DON); /* set done */ +return SCPE_OK; +} + +/* Update status */ + +int32 rb_updsta (int32 new) +{ +rb_sta = (rb_sta | new) & ~(RBS_ERR | RBS_MBZ); /* clear err, mbz */ +if (rb_sta & RBS_EFLGS) rb_sta = rb_sta | RBS_ERR; /* error? */ +if (rb_sta & RBS_DON) rb_sta = rb_sta & ~RBS_BSY; /* done? clear busy */ +if ((rb_sta & (RBS_ERR | RBS_DON)) && (rb_sta & RBS_IE)) + SET_INT (RB); /* set or clr intr */ +else CLR_INT (RB); +return rb_sta; +} + +/* Reset routine */ + +t_stat rb_reset (DEVICE *dptr) +{ +rb_sta = rb_da = 0; +rb_wc = rb_ma = 0; +rb_updsta (0); +sim_cancel (&rb_unit); +return SCPE_OK; +} diff --git a/PDP18B/pdp18b_rf.c b/PDP18B/pdp18b_rf.c index 2d180954..ef1d6be8 100644 --- a/PDP18B/pdp18b_rf.c +++ b/PDP18B/pdp18b_rf.c @@ -1,6 +1,6 @@ /* pdp18b_rf.c: fixed head disk simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, 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 @@ rf (PDP-9) RF09/RF09 (PDP-15) RF15/RS09 + 05-Feb-03 RMS Fixed decode bugs, added variable and auto sizing 05-Oct-02 RMS Added DIB, dev number support 06-Jan-02 RMS Revised enable/disable support 25-Nov-01 RMS Revised interrupt structure @@ -48,12 +49,17 @@ #include "pdp18b_defs.h" #include +#define UNIT_V_AUTO (UNIT_V_UF + 0) /* autosize */ +#define UNIT_V_MSIZE (UNIT_V_UF + 1) /* dummy mask */ +#define UNIT_AUTO (1 << UNIT_V_AUTO) +#define UNIT_MSIZE (1 << UNIT_V_MSIZE) + /* 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_SIZE (RF_NUMDK * RF_NUMTR * RF_NUMWD) /* words/drive */ #define RF_WMASK (RF_NUMWD - 1) /* word mask */ #define RF_WC 036 /* word count */ #define RF_CA 037 /* current addr */ @@ -84,7 +90,7 @@ #define RFS_EFLGS (RFS_HDW | RFS_APE | RFS_MXF | RFS_WCE | \ RFS_DPE | RFS_WLO | RFS_NED ) /* error flags */ #define GET_FNC(x) (((x) >> RFS_V_FNC) & RFS_M_FNC) -#define GET_POS(x) ((int) fmod (sim_gtime() / ((double) (x)), \ +#define GET_POS(x) ((int) fmod (sim_gtime () / ((double) (x)), \ ((double) RF_NUMWD))) #define RF_BUSY (sim_is_active (&rf_unit)) @@ -107,6 +113,8 @@ int32 rf_iors (void); t_stat rf_svc (UNIT *uptr); t_stat rf_reset (DEVICE *dptr); int32 rf_updsta (int32 new); +t_stat rf_attach (UNIT *uptr, char *cptr); +t_stat rf_set_size (UNIT *uptr, int32 val, char *cptr, void *desc); /* RF data structures @@ -118,12 +126,12 @@ int32 rf_updsta (int32 new); DIB rf_dib = { DEV_RF, 3, &rf_iors, { &rf70, NULL, &rf72 } }; UNIT rf_unit = - { UDATA (&rf_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF, - RF_SIZE) }; + { UDATA (&rf_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_AUTO, + RF_DKSIZE) }; REG rf_reg[] = { { ORDATA (STA, rf_sta, 18) }, - { ORDATA (DA, rf_da, 21) }, + { ORDATA (DA, rf_da, 22) }, { ORDATA (WC, M[RF_WC], 18) }, { ORDATA (CA, M[RF_CA], 18) }, { ORDATA (BUF, rf_dbuf, 18) }, @@ -136,6 +144,15 @@ REG rf_reg[] = { { NULL } }; MTAB rf_mod[] = { + { UNIT_MSIZE, 262144, NULL, "1P", &rf_set_size }, + { UNIT_MSIZE, 524288, NULL, "2P", &rf_set_size }, + { UNIT_MSIZE, 786432, NULL, "3P", &rf_set_size }, + { UNIT_MSIZE, 1048576, NULL, "4P", &rf_set_size }, + { UNIT_MSIZE, 1310720, NULL, "5P", &rf_set_size }, + { UNIT_MSIZE, 1572864, NULL, "6P", &rf_set_size }, + { UNIT_MSIZE, 1835008, NULL, "7P", &rf_set_size }, + { UNIT_MSIZE, 2097152, NULL, "8P", &rf_set_size }, + { UNIT_AUTO, UNIT_AUTO, "autosize", "AUTOSIZE", NULL }, { MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_devno, &show_devno }, { 0 } }; @@ -143,70 +160,73 @@ DEVICE rf_dev = { "RF", &rf_unit, rf_reg, rf_mod, 1, 8, 21, 1, 8, 18, NULL, NULL, &rf_reset, - NULL, NULL, NULL, + NULL, &rf_attach, NULL, &rf_dib, DEV_DISABLE }; /* IOT routines */ int32 rf70 (int32 pulse, int32 AC) { -int32 t; +int32 t, sb; -if (pulse == 001) /* DSSF */ - return (rf_sta & (RFS_ERR | RFS_DON))? IOT_SKP + AC: AC; -if (pulse == 021) rf_reset (&rf_dev); /* DSCC */ -if ((pulse & 061) == 041) { /* DSCF */ - if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */ - else rf_sta = rf_sta & ~(RFS_FNC | RFS_IE); } /* clear func */ -if (pulse == 002) { /* DRBR */ +sb = pulse & 060; /* subopcode */ +if (pulse & 01) { + if ((sb == 000) && (rf_sta & (RFS_ERR | RFS_DON))) + AC = IOT_SKP | AC; /* DSSF */ + else if (sb == 020) rf_reset (&rf_dev); /* DSCC */ + else if (sb == 040) { /* DSCF */ + if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */ + else rf_sta = rf_sta & ~(RFS_FNC | RFS_IE); } /* clear func */ + } +if (pulse & 02) { if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */ - return AC | rf_dbuf; } -if (pulse == 022) { /* DRAL */ + else if (sb == 000) AC = AC | rf_dbuf; /* DRBR */ + else if (sb == 020) /* DRAL */ + AC = AC | (rf_da & 0777777); + else if (sb == 040) /* DSFX */ + rf_sta = rf_sta ^ (AC & (RFS_FNC | RFS_IE)); /* xor func */ + else if (sb == 060) /* DRAH */ + AC = AC | (rf_da >> 18); + } +if (pulse & 04) { if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */ - return rf_da & 0777777; } -if (pulse == 062) { /* DRAH */ - if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */ - return (rf_da >> 18) | ((rf_sta & RFS_NED)? 010: 0); } -if ((pulse & 062) == 042) { /* DSFX */ - if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */ - else rf_sta = rf_sta ^ (AC & (RFS_FNC | RFS_IE)); } /* xor func */ -if (pulse == 004) { /* DLBR */ - if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */ - else rf_dbuf = AC; } -if (pulse == 024) { /* DLAL */ - if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */ - else rf_da = (rf_da & ~0777777) | AC; } -if (pulse == 064) { /* DLAH */ - if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */ - else rf_da = (rf_da & 0777777) | ((AC & 07) << 18); } -if ((pulse & 064) == 044) { /* DSCN */ - if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */ - else if (GET_FNC (rf_sta) != FN_NOP) { - t = (rf_da & RF_WMASK) - GET_POS (rf_time); /* delta to new */ - if (t < 0) t = t + RF_NUMWD; /* wrap around? */ - sim_activate (&rf_unit, t * rf_time); } } /* schedule op */ + else if (sb == 000) rf_dbuf = AC & 0777777; /* DLBR */ + else if (sb == 020) /* DLAL */ + rf_da = (rf_da & ~0777777) | (AC & 0777777); + else if (sb == 040) { /* DSCN */ + rf_sta = rf_sta & ~RFS_DON; /* clear done */ + if (GET_FNC (rf_sta) != FN_NOP) { + t = (rf_da & RF_WMASK) - GET_POS (rf_time); /* delta to new */ + if (t < 0) t = t + RF_NUMWD; /* wrap around? */ + sim_activate (&rf_unit, t * rf_time); } } /* schedule op */ + else if (sb == 060) { /* DLAH */ + rf_da = (rf_da & 0777777) | ((AC & 017) << 18); + if ((t_addr) rf_da >= rf_unit.capac) /* for sizing */ + rf_updsta (RFS_NED); } + } rf_updsta (0); /* update status */ return AC; } int32 rf72 (int32 pulse, int32 AC) { -if (pulse == 002) return AC | GET_POS (rf_time) | /* DLOK */ - (sim_is_active (&rf_unit)? 0400000: 0); -if (pulse == 042) { /* DSCD */ - if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */ - else rf_sta = 0; - rf_updsta (0); } -if (pulse == 062) { /* DSRS */ - if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */ - return rf_updsta (0); } +int32 sb = pulse & 060; + +if (pulse & 02) { + if (sb == 000) AC = AC | GET_POS (rf_time) | /* DLOK */ + (sim_is_active (&rf_unit)? 0400000: 0); + else if (sb == 040) { /* DSCD */ + if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */ + else rf_sta = 0; + rf_updsta (0); } + else if (sb == 060) { /* DSRS */ + if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */ + AC = AC | rf_updsta (0); } + } return AC; } -/* Unit service - - This code assumes the entire disk is buffered. -*/ +/* Unit service - assumes the entire disk is buffered */ t_stat rf_svc (UNIT *uptr) { @@ -217,7 +237,10 @@ if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */ return IORETURN (rf_stopioe, SCPE_UNATT); } f = GET_FNC (rf_sta); /* get function */ -do { M[RF_WC] = (M[RF_WC] + 1) & 0777777; /* incr word count */ +do { if ((t_addr) rf_da >= uptr->capac) { /* disk overflow? */ + rf_updsta (RFS_NED); /* nx disk error */ + break; } + M[RF_WC] = (M[RF_WC] + 1) & 0777777; /* incr word count */ pa = M[RF_CA] = (M[RF_CA] + 1) & ADDRMASK; /* incr mem addr */ if ((f == FN_READ) && MEM_ADDR_OK (pa)) /* read? */ M[pa] = *(((int32 *) uptr->filebuf) + rf_da); @@ -235,10 +258,7 @@ do { M[RF_WC] = (M[RF_WC] + 1) & 0777777; /* incr word count */ *(((int32 *) uptr->filebuf) + rf_da) = M[pa]; if (((t_addr) rf_da) >= uptr->hwmark) uptr->hwmark = rf_da + 1; } } rf_da = rf_da + 1; /* incr disk addr */ - if (rf_da > RF_SIZE) { /* disk overflow? */ - rf_da = 0; - rf_updsta (RFS_NED); /* nx disk error */ - break; } } + } while ((M[RF_WC] != 0) && (rf_burst != 0)); /* brk if wc, no brst */ if ((M[RF_WC] != 0) && ((rf_sta & RFS_ERR) == 0)) /* more to do? */ @@ -275,3 +295,35 @@ int32 rf_iors (void) { return ((rf_sta & (RFS_ERR | RFS_DON))? IOS_RF: 0); } + +/* Attach routine */ + +t_stat rf_attach (UNIT *uptr, char *cptr) +{ +int32 p, d; +int32 ds_bytes = RF_DKSIZE * sizeof (int32); + +if (uptr->flags & UNIT_AUTO) { + FILE *fp = fopen (cptr, "rb"); + if (fp == NULL) return SCPE_OPENERR; + fseek (fp, 0, SEEK_END); + p = ftell (fp); + d = (p + ds_bytes - 1) / ds_bytes; + if (d == 0) d = 1; + if (d > RF_NUMDK) d = RF_NUMDK; + uptr->capac = d * RF_DKSIZE; + fclose (fp); } +return attach_unit (uptr, cptr); +} + +/* Change disk size */ + +t_stat rf_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) +{ +if ((val == 0) || (val > (RF_NUMDK * RF_DKSIZE))) + return SCPE_IERR; +if (uptr->flags & UNIT_ATT) return SCPE_ALATT; +uptr->capac = val; +uptr->flags = uptr->flags & ~UNIT_AUTO; +return SCPE_OK; +} diff --git a/PDP18B/pdp18b_rp.c b/PDP18B/pdp18b_rp.c index d00fc07a..f8fdd57e 100644 --- a/PDP18B/pdp18b_rp.c +++ b/PDP18B/pdp18b_rp.c @@ -1,6 +1,6 @@ /* pdp18b_rp.c: RP15/RP02 disk pack simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, 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 @@ rp RP15/RP02 disk pack + 06-Feb-03 RMS Revised IOT decoding, fixed bug in initiation 05-Oct-02 RMS Added DIB, device number support 06-Jan-02 RMS Revised enable/disable support 29-Nov-01 RMS Added read only unit support @@ -203,33 +204,41 @@ DEVICE rp_dev = { int32 rp63 (int32 pulse, int32 AC) { +int32 sb = pulse & 060; /* subopcode */ + rp_updsta (0, 0); -if (pulse == 001) /* DPSF */ - return ((rp_sta & (STA_DON | STA_ERR)) || (rp_stb & STB_ATTN))? - IOT_SKP + AC: AC; -if (pulse == 021) /* DPSA */ - return (rp_stb & STB_ATTN)? IOT_SKP + AC: AC; -if (pulse == 041) /* DPSJ */ - return (rp_sta & STA_DON)? IOT_SKP + AC: AC; -if (pulse == 061) /* DPSE */ - return (rp_sta & STA_ERR)? IOT_SKP + AC: AC; -if (pulse == 002) return rp_sta; /* DPOSA */ -if (pulse == 022) return rp_stb; /* DPOSB */ -if (((pulse & 007) == 004) && rp_busy) { /* busy? */ - rp_updsta (0, STB_PGE); - return AC; } -if (pulse == 004) { /* DPLA */ - rp_da = AC; - if (GET_SECT (rp_da) >= RP_NUMSC) rp_updsta (STA_NXS, 0); - if (GET_SURF (rp_da) >= RP_NUMSF) rp_updsta (STA_NXF, 0); - if (GET_CYL (rp_da) >= RP_NUMCY) rp_updsta (STA_NXC, 0); } -if (pulse == 024) { /* DPCS */ - rp_sta = rp_sta & ~(STA_HNF | STA_DON); - rp_stb = rp_stb & ~(STB_FME | STB_WPE | STB_LON | STB_WCE | - STB_TME | STB_PGE | STB_EOP); - rp_updsta (0, 0); } -if (pulse == 044) rp_ma = AC; /* DPCA */ -if (pulse == 064) rp_wc = AC; /* DPWC */ +if (pulse & 01) { + if ((sb == 000) && /* DPSF */ + ((rp_sta & (STA_DON | STA_ERR)) || (rp_stb & STB_ATTN))) + AC = IOT_SKP | AC; + else if ((sb == 020) && (rp_stb & STB_ATTN)) /* DPSA */ + AC = IOT_SKP | AC; + else if ((sb == 040) && (rp_sta & STA_DON)) /* DPSJ */ + AC = IOT_SKP | AC; + else if ((sb == 060) && (rp_sta & STA_ERR)) /* DPSE */ + AC = IOT_SKP | AC; + } +if (pulse & 02) { + if (sb == 000) AC = AC | rp_sta; /* DPOSA */ + else if (sb == 020) AC = AC | rp_stb; /* DPOSB */ + } +if (pulse & 04) { + if (rp_busy) { /* busy? */ + rp_updsta (0, STB_PGE); + return AC; } + else if (sb == 000) { /* DPLA */ + rp_da = AC & 0777777; + if (GET_SECT (rp_da) >= RP_NUMSC) rp_updsta (STA_NXS, 0); + if (GET_SURF (rp_da) >= RP_NUMSF) rp_updsta (STA_NXF, 0); + if (GET_CYL (rp_da) >= RP_NUMCY) rp_updsta (STA_NXC, 0); } + else if (sb == 020) { /* DPCS */ + rp_sta = rp_sta & ~(STA_HNF | STA_DON); + rp_stb = rp_stb & ~(STB_FME | STB_WPE | STB_LON | STB_WCE | + STB_TME | STB_PGE | STB_EOP); + rp_updsta (0, 0); } + else if (sb == 040) rp_ma = AC & 0777777; /* DPCA */ + else if (sb == 060) rp_wc = AC & 0777777; /* DPWC */ + } return AC; } @@ -237,38 +246,45 @@ return AC; int32 rp64 (int32 pulse, int32 AC) { -int32 u, f, c; +int32 u, f, c, sb; UNIT *uptr; -if (pulse == 021) return IOT_SKP + AC; /* DPSN */ -if (pulse == 002) return rp_unit[GET_UNIT (rp_sta)].CYL; /* DPOU */ -if (pulse == 022) return rp_da; /* DPOA */ -if (pulse == 042) return rp_ma; /* DPOC */ -if (pulse == 062) return rp_wc; /* DPOW */ -if ((pulse & 007) != 004) return AC; -if (rp_busy) { /* busy? */ - rp_updsta (0, STB_PGE); - return AC; } -if (pulse == 004) rp_sta = rp_sta & ~STA_RW; /* DPCF */ -if (pulse == 024) rp_sta = rp_sta & (AC | ~STA_RW); /* DPLZ */ -if (pulse == 044) rp_sta = rp_sta | (AC & STA_RW); /* DPLO */ -if (pulse == 064) rp_sta = (rp_sta & ~STA_RW) | (AC & STA_RW); /* DPLF */ -if (rp_sta & STA_GO) { +sb = pulse & 060; +if (pulse & 01) { + if (sb == 020) AC = IOT_SKP | AC; /* DPSN */ + } +if (pulse & 02) { + if (sb == 000) AC = AC | rp_unit[GET_UNIT (rp_sta)].CYL; /* DPOU */ + else if (sb == 020) AC = AC | rp_da; /* DPOA */ + else if (sb == 040) AC = AC | rp_ma; /* DPOC */ + else if (sb == 060) AC = AC | rp_wc; /* DPOW */ + } +if (pulse & 04) { + if (rp_busy) { /* busy? */ + rp_updsta (0, STB_PGE); + return AC; } + if (sb == 000) rp_sta = rp_sta & ~STA_RW; /* DPCF */ + else if (sb == 020) rp_sta = rp_sta & (AC | ~STA_RW); /* DPLZ */ + else if (sb == 040) rp_sta = rp_sta | (AC & STA_RW); /* DPLO */ + else if (sb == 060) /* DPLF */ + rp_sta = (rp_sta & ~STA_RW) | (AC & STA_RW); + rp_sta = rp_sta & ~STA_DON; /* clear done */ u = GET_UNIT (rp_sta); /* get unit num */ uptr = rp_dev.units + u; /* select unit */ - if (sim_is_active (uptr)) return AC; /* can't if busy */ - f = uptr->FUNC = GET_FUNC (rp_sta); /* get function */ - rp_busy = 1; /* set ctrl busy */ - rp_sta = rp_sta & ~(STA_HNF | STA_DON); /* clear flags */ - rp_stb = rp_stb & ~(STB_FME | STB_WPE | STB_LON | STB_WCE | - STB_TME | STB_PGE | STB_EOP | (1 << (STB_V_ATT0 - u))); - if (((uptr->flags & UNIT_ATT) == 0) || (f == FN_IDLE) || - (f == FN_SEEK) || (f == FN_RECAL)) - sim_activate (uptr, RP_MIN); /* short delay */ - else { - c = GET_CYL (rp_da); - c = abs (c - uptr->CYL) * rp_swait; /* seek time */ - sim_activate (uptr, MAX (RP_MIN, c + rp_rwait)); } } + if ((rp_sta & STA_GO) && !sim_is_active (uptr)) { + f = uptr->FUNC = GET_FUNC (rp_sta); /* get function */ + rp_busy = 1; /* set ctrl busy */ + rp_sta = rp_sta & ~(STA_HNF | STA_DON); /* clear flags */ + rp_stb = rp_stb & ~(STB_FME | STB_WPE | STB_LON | STB_WCE | + STB_TME | STB_PGE | STB_EOP | (1 << (STB_V_ATT0 - u))); + if (((uptr->flags & UNIT_ATT) == 0) || (f == FN_IDLE) || + (f == FN_SEEK) || (f == FN_RECAL)) + sim_activate (uptr, RP_MIN); /* short delay */ + else { + c = GET_CYL (rp_da); + c = abs (c - uptr->CYL) * rp_swait; /* seek time */ + sim_activate (uptr, MAX (RP_MIN, c + rp_rwait)); } } + } rp_updsta (0, 0); return AC; } diff --git a/PDP18B/pdp18b_stddev.c b/PDP18B/pdp18b_stddev.c index 0522181f..6ca61c2f 100644 --- a/PDP18B/pdp18b_stddev.c +++ b/PDP18B/pdp18b_stddev.c @@ -433,8 +433,13 @@ if ((temp = getc (ptr_unit.fileref)) == EOF) { /* end of file? */ else perror ("PTR I/O error"); clearerr (ptr_unit.fileref); return SCPE_IOERR; } -if (ptr_state == 0) ptr_unit.buf = (temp | /* alpha */ - ((ptr_unit.flags & UNIT_RASCII)? 0200: 0)) & 0377; +if (ptr_state == 0) { /* ASCII */ + if (ptr_unit.flags & UNIT_RASCII) { /* want parity? */ + ptr_unit.buf = temp = temp & 0177; /* parity off */ + while (temp = temp & (temp - 1)) + ptr_unit.buf = ptr_unit.buf ^ 0200; /* count bits */ + ptr_unit.buf = ptr_unit.buf ^ 0200; } /* set even parity */ + else ptr_unit.buf = temp & 0377; } else if (temp & 0200) { /* binary */ ptr_state = ptr_state - 6; ptr_unit.buf = ptr_unit.buf | ((temp & 077) << ptr_state); } diff --git a/PDP18B/pdp18b_sys.c b/PDP18B/pdp18b_sys.c index d88eba15..70b7b206 100644 --- a/PDP18B/pdp18b_sys.c +++ b/PDP18B/pdp18b_sys.c @@ -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. + 31-Jan-03 RMS Added support for RB09 05-Oct-02 RMS Added variable device number support 25-Jul-02 RMS Added PDP-4 DECtape support 10-Feb-02 RMS Added PDP-7 DECtape IOT's @@ -48,11 +49,25 @@ extern DEVICE ptr_dev, ptp_dev; extern DEVICE tti_dev, tto_dev; extern UNIT tti_unit, tto_unit; extern DEVICE clk_dev; -extern DEVICE lpt_dev; +#if defined (TYPE62) +extern DEVICE lp62_dev; +#endif +#if defined (TYPE647) +extern DEVICE lp647_dev; +#endif +#if defined (LP09) +extern DEVICE lp09_dev; +#endif +#if defined (LP15) +extern DEVICE lp15_dev; +#endif extern DEVICE dt_dev; #if defined (DRM) extern DEVICE drm_dev; #endif +#if defined (RB) +extern DEVICE rb_dev; +#endif #if defined (RF) extern DEVICE rf_dev; #endif @@ -97,12 +112,29 @@ REG *sim_PC = &cpu_reg[0]; int32 sim_emax = 3; DEVICE *sim_devices[] = { &cpu_dev, - &ptr_dev, &ptp_dev, - &tti_dev, &tto_dev, - &clk_dev, &lpt_dev, + &ptr_dev, + &ptp_dev, + &tti_dev, + &tto_dev, + &clk_dev, +#if defined (TYPE62) + &lp62_dev, +#endif +#if defined (TYPE647) + &lp647_dev, +#endif +#if defined (LP09) + &lp09_dev, +#endif +#if defined (LP15) + &lp15_dev, +#endif #if defined (DRM) &drm_dev, #endif +#if defined (RB) + &rb_dev, +#endif #if defined (RF) &rf_dev, #endif @@ -321,15 +353,21 @@ static const char *opcode[] = { "PSF", "PCF", "PSA", "PSB", "PLS", "KSF", "KRB", "KCF", "IORS", "IOOS", "TSF", "TCF", "TPC", "TLS", -#if defined (TYPE62) /* PDP-4 LPT */ +#if defined (TYPE62) /* Type 62 */ "LPSF", "LPCF", "LPLD", "LPSE", "LSSF", "LSCF", "LSPR", -#elif defined (TYPE647) /* PDP-7, PDP-9 LPT */ +#endif +#if defined (TYPE647) /* Type 647 */ "LPSF", "LPCB", "LPCD", "LPCD", "LPCD", "LPL2", "LPLD", "LPL1", "LPEF", "LPCF", "LPCF", "LPCF", "LPCF", "LPPB", "LPLS", "LPPS", -#elif defined (LP15) /* PDP-15 LPT */ +#endif +#if defined (LP09) + "LSDF", "LSEF", "LSCF", "LPLD", + "LIOF", "LION", +#endif +#if defined (LP15) /* LP15 */ "LPSF", "LPPM", "LPP1", "LPDI", "LPRS", "LPOS", "LPEI", "LPCD", "LPCF", #endif @@ -339,6 +377,11 @@ static const char *opcode[] = { "DRLCRD", "DRLCWR", "DRLBLK", "DRCONT", "DRSF", "DRSOK", "DRCF", #endif +#if defined (RB) /* RB09 */ + "DBCF", "DBRD", "DBLD", + "DBSF", "DBRS", "DBLW", + "DBCS", "DBLM", "DBLS", +#endif #if defined (RF) /* RF09 */ "DSSF", "DSCC", "DSCF", "DRBR", "DRAL", "DSFX", "DRAH", @@ -478,12 +521,18 @@ static const int32 opc_val[] = { #if defined (TYPE62) 0706501+I_NPI, 0706502+I_NPI, 0706542+I_NPI, 0706506+I_NPI, 0706601+I_NPI, 0706602+I_NPI, 0706606+I_NPI, -#elif defined (TYPE647) +#endif +#if defined (TYPE647) 0706501+I_NPI, 0706502+I_NPI, 0706522+I_NPI, 0706542+I_NPI, 0706562+I_NPI, 0706526+I_NPI, 0706546+I_NPI, 0706566+I_NPI, 0706601+I_NPI, 0706602+I_NPI, 0706622+I_NPI, 0706642+I_NPI, 0706662+I_NPI, 0706606+I_NPI, 0706626+I_NPI, 0706646+I_NPI, -#elif defined (LP15) +#endif +#if defined (LP09) + 0706601+I_NPI, 0706621+I_NPI, 0706602+I_NPI, 0706622+I_NPI, + 0706604+I_NPI, 0706644+I_NPI, +#endif +#if defined (LP15) 0706501+I_NPI, 0706521+I_NPI, 0706541+I_NPI, 0706561+I_NPI, 0706552+I_NPN, 0706542+I_NPI, 0706544+I_NPI, 0706621+I_NPI, 0706641+I_NPI, #endif @@ -493,6 +542,11 @@ static const int32 opc_val[] = { 0706006+I_NPI, 0706046+I_NPI, 0706106+I_NPI, 0706204+I_NPI, 0706101+I_NPI, 0706201+I_NPI, 0706102+I_NPI, #endif +#if defined (RB) + 0707101+I_NPI, 0707112+I_NPN, 0707104+I_NPI, + 0707121+I_NPI, 0707132+I_NPN, 0707124+I_NPI, + 0707141+I_NPI, 0707142+I_NPI, 0707144+I_NPI, +#endif #if defined (RF) 0707001+I_NPI, 0707021+I_NPI, 0707041+I_NPI, 0707002+I_NPI, 0707022+I_NPI, 0707042+I_NPI, 0707062+I_NPI, diff --git a/PDP8/pdp8_df.c b/PDP8/pdp8_df.c index 3165a717..589c4732 100644 --- a/PDP8/pdp8_df.c +++ b/PDP8/pdp8_df.c @@ -1,6 +1,6 @@ /* pdp8_df.c: DF32 fixed head disk simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, 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 @@ df DF32 fixed head disk + 02-Feb-03 RMS Added variable platter and autosizing support 04-Oct-02 RMS Added DIBs, device number support 28-Nov-01 RMS Added RL8A support 25-Apr-01 RMS Added device enable/disable support @@ -42,12 +43,17 @@ #include "pdp8_defs.h" #include +#define UNIT_V_AUTO (UNIT_V_UF + 0) /* autosize */ +#define UNIT_V_MSIZE (UNIT_V_UF + 1) /* dummy mask */ +#define UNIT_AUTO (1 << UNIT_V_AUTO) +#define UNIT_MSIZE (1 << UNIT_V_MSIZE) + /* Constants */ #define DF_NUMWD 2048 /* words/track */ #define DF_NUMTR 16 /* tracks/disk */ +#define DF_DKSIZE (DF_NUMTR * DF_NUMWD) /* words/disk */ #define DF_NUMDK 4 /* disks/controller */ -#define DF_SIZE (DF_NUMDK * DF_NUMTR * DF_NUMWD) /* words/drive */ #define DF_WC 07750 /* word count */ #define DF_MA 07751 /* mem address */ #define DF_WMASK (DF_NUMWD - 1) /* word mask */ @@ -65,8 +71,9 @@ #define DFS_MEX 00070 /* mem addr extension */ #define DFS_DRL 00004 /* data late error */ #define DFS_WLS 00002 /* write lock error */ +#define DFS_NXD 00002 /* non-existent disk */ #define DFS_PER 00001 /* parity error */ -#define DFS_ERR (DFS_DRL + DFS_WLS + DFS_PER) +#define DFS_ERR (DFS_DRL | DFS_WLS | DFS_PER) #define DFS_V_DEX 6 #define DFS_V_MEX 3 @@ -97,6 +104,8 @@ t_stat df_svc (UNIT *uptr); t_stat pcell_svc (UNIT *uptr); t_stat df_reset (DEVICE *dptr); t_stat df_boot (int32 unitno, DEVICE *dptr); +t_stat df_attach (UNIT *uptr, char *cptr); +t_stat df_set_size (UNIT *uptr, int32 val, char *cptr, void *desc); /* DF32 data structures @@ -110,7 +119,7 @@ DIB df_dib = { DEV_DF, 3, { &df60, &df61, &df62 } }; UNIT df_unit = { UDATA (&df_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF, - DF_SIZE) }; + DF_NUMDK * DF_DKSIZE) }; REG df_reg[] = { { ORDATA (STA, df_sta, 12) }, @@ -127,6 +136,10 @@ REG df_reg[] = { { NULL } }; MTAB df_mod[] = { + { UNIT_MSIZE, 32768, NULL, "1P", &df_set_size }, + { UNIT_MSIZE, 65536, NULL, "2P", &df_set_size }, + { UNIT_MSIZE, 98304, NULL, "3P", &df_set_size }, + { UNIT_MSIZE, 131072, NULL, "4P", &df_set_size }, { MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_dev, &show_dev, NULL }, { 0 } }; @@ -135,7 +148,7 @@ DEVICE df_dev = { "DF", &df_unit, df_reg, df_mod, 1, 8, 17, 1, 8, 12, NULL, NULL, &df_reset, - &df_boot, NULL, NULL, + &df_boot, &df_attach, NULL, &df_dib, DEV_DISABLE }; /* IOT routines */ @@ -220,7 +233,10 @@ if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */ mex = GET_MEX (df_sta); da = GET_DEX (df_sta) | df_da; /* form disk addr */ -do { M[DF_WC] = (M[DF_WC] + 1) & 07777; /* incr word count */ +do { if (da >= uptr->capac) { /* nx disk addr? */ + df_sta = df_sta | DFS_NXD; + break; } + M[DF_WC] = (M[DF_WC] + 1) & 07777; /* incr word count */ M[DF_MA] = (M[DF_MA] + 1) & 07777; /* incr mem addr */ pa = mex | M[DF_MA]; /* add extension */ if (uptr->FUNC == DF_READ) { /* read? */ @@ -235,7 +251,7 @@ do { M[DF_WC] = (M[DF_WC] + 1) & 07777; /* incr word count */ da = (da + 1) & 0377777; } /* incr disk addr */ while ((M[DF_WC] != 0) && (df_burst != 0)); /* brk if wc, no brst */ -if (M[DF_WC] != 0) /* more to do? */ +if ((M[DF_WC] != 0) && ((df_sta & DFS_ERR) == 0)) /* more to do? */ sim_activate (&df_unit, df_time); /* sched next */ else { if (uptr->FUNC != DF_READ) da = (da - 1) & 0377777; df_done = 1; /* done */ @@ -295,3 +311,34 @@ else { for (i = 0; i < OS8_LEN; i++) saved_PC = OS8_START; } return SCPE_OK; } + + +t_stat df_attach (UNIT *uptr, char *cptr) +{ +int32 p, d; +int32 ds_bytes = DF_DKSIZE * sizeof (int16); + +if (uptr->flags & UNIT_AUTO) { + FILE *fp = fopen (cptr, "rb"); + if (fp == NULL) return SCPE_OPENERR; + fseek (fp, 0, SEEK_END); + p = ftell (fp); + d = (p + ds_bytes - 1) / ds_bytes; + if (d == 0) d = 1; + if (d > DF_NUMDK) d = DF_NUMDK; + uptr->capac = d * DF_DKSIZE; + fclose (fp); } +return attach_unit (uptr, cptr); +} + +/* Change disk size */ + +t_stat df_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) +{ +if ((val == 0) || (val > (DF_NUMDK * DF_DKSIZE))) + return SCPE_IERR; +if (uptr->flags & UNIT_ATT) return SCPE_ALATT; +uptr->capac = val; +uptr->flags = uptr->flags & ~UNIT_AUTO; +return SCPE_OK; +} diff --git a/PDP8/pdp8_doc.txt b/PDP8/pdp8_doc.txt index aef8c49f..b4ca45cb 100644 --- a/PDP8/pdp8_doc.txt +++ b/PDP8/pdp8_doc.txt @@ -1,14 +1,14 @@ To: Users From: Bob Supnik Subj: PDP-8 Simulator Usage -Date: 15-Nov-2002 +Date: 1-Feb-2003 COPYRIGHT NOTICE The following copyright notice applies to both the SIMH source and binary: - Original code published in 1993-2002, written by Robert M Supnik - Copyright (c) 1993-2002, Robert M Supnik + Original code published in 1993-2003, written by Robert M Supnik + Copyright (c) 1993-2003, 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"), @@ -76,8 +76,8 @@ TTIX,TTOX KL8JA additional terminals LPT LE8E line printer CLK DK8E line frequency clock (also PDP-8/A compatible) RK RK8E/RK05 cartridge disk controller with four drives -RF RF08/RS08 fixed head disk controller with four platters, or -DF DF32/DS32 fixed head disk controller with four platters +RF RF08/RS08 fixed head disk controller with 1-4 platters, or +DF DF32/DS32 fixed head disk controller with 1-4 platters RL RL8A/RL01 cartridge disk controller with four drives RX RX8E/RX01, RX28/RX02 floppy disk controller with two drives DT TC08/TU56 DECtape controller with eight drives @@ -506,6 +506,18 @@ not both, with default device addressing. 2.5.1 RF08/RS08 Fixed Head Disk (RF) +RF08 options include the ability to set the number of platters to a +fixed value between 1 and 4, or to autosize the number of platters +from the attached file: + + SET RF 1P one platter (256K) + SET RF 2P two platters (512K) + SET RF 3P three platters (768K) + SET RF 4P four platters (1024K) + SET RF AUTOSIZE autosized on attach + +The default is four platters. + The RF08 implements these registers: name size comments @@ -540,6 +552,18 @@ I/O errors cannot occur. 2.5.2 DF32/DS32 Fixed Head Disk (RF) +DF32 options include the ability to set the number of platters to a +fixed value between 1 and 4, or to autosize the number of platters +from the attached file: + + SET DF 1P one platter (32K) + SET DF 2P two platters (64K) + SET DF 3P three platters (98K) + SET DF 4P four platters (128K) + SET DF AUTOSIZE autosized on attach + +The default is four platters. + The DF32 implements these registers: name size comments diff --git a/PDP8/pdp8_rf.c b/PDP8/pdp8_rf.c index f38badfb..fa3f0728 100644 --- a/PDP8/pdp8_rf.c +++ b/PDP8/pdp8_rf.c @@ -1,6 +1,6 @@ /* pdp8_rf.c: RF08 fixed head disk simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, 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 @@ rf RF08 fixed head disk + 02-Feb-03 RMS Added variable platter and autosizing support 04-Oct-02 RMS Added DIB, device number support 28-Nov-01 RMS Added RL8A support 25-Apr-01 RMS Added device enable/disable support @@ -46,12 +47,17 @@ #include "pdp8_defs.h" #include +#define UNIT_V_AUTO (UNIT_V_UF + 0) /* autosize */ +#define UNIT_V_MSIZE (UNIT_V_UF + 1) /* dummy mask */ +#define UNIT_AUTO (1 << UNIT_V_AUTO) +#define UNIT_MSIZE (1 << UNIT_V_MSIZE) + /* 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 4 /* disks/controller */ -#define RF_SIZE (RF_NUMDK * RF_NUMTR * RF_NUMWD) /* words/drive */ #define RF_WC 07750 /* word count */ #define RF_MA 07751 /* mem address */ #define RF_WMASK (RF_NUMWD - 1) /* word mask */ @@ -109,6 +115,8 @@ t_stat rf_svc (UNIT *uptr); t_stat pcell_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); /* RF08 data structures @@ -122,7 +130,7 @@ DIB rf_dib = { DEV_RF, 5, { &rf60, &rf61, &rf62, NULL, &rf64 } }; UNIT rf_unit = { UDATA (&rf_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF, - RF_SIZE) }; + RF_NUMDK * RF_DKSIZE) }; UNIT pcell_unit = { UDATA (&pcell_svc, 0, 0) }; @@ -141,6 +149,11 @@ REG rf_reg[] = { { NULL } }; MTAB rf_mod[] = { + { UNIT_MSIZE, 262144, NULL, "1P", &rf_set_size }, + { UNIT_MSIZE, 524288, NULL, "2P", &rf_set_size }, + { UNIT_MSIZE, 786432, NULL, "3P", &rf_set_size }, + { UNIT_MSIZE, 1048576, NULL, "4P", &rf_set_size }, + { UNIT_AUTO, UNIT_AUTO, "autosize", "AUTOSIZE", NULL }, { MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_dev, &show_dev, NULL }, { 0 } }; @@ -149,7 +162,7 @@ DEVICE rf_dev = { "RF", &rf_unit, rf_reg, rf_mod, 1, 8, 20, 1, 8, 12, NULL, NULL, &rf_reset, - &rf_boot, NULL, NULL, + &rf_boot, &rf_attach, NULL, &rf_dib, DEV_DISABLE | DEV_DIS }; /* IOT routines */ @@ -187,7 +200,7 @@ case 1: /* DCIM */ sim_cancel (&pcell_unit); /* cancel photocell */ return AC; case 2: /* DSAC */ - return ((rf_da & RF_WMASK) == GET_POS (rf_time))? IOT_SKP + AC: AC; + return ((rf_da & RF_WMASK) == GET_POS (rf_time))? IOT_SKP: 0; case 5: /* DIML */ rf_sta = (rf_sta & 07007) | (AC & 0770); /* STA<3:8> <- AC */ if (rf_sta & RFS_PIE) /* photocell int? */ @@ -225,14 +238,25 @@ UPDATE_PCELL; /* update photocell */ switch (pulse) { /* decode IR<9:11> */ case 1: /* DCXA */ rf_da = rf_da & 07777; /* clear DAR<0:7> */ - return AC; + break; case 3: /* DXAL */ - rf_da = (rf_da & 07777) | ((AC & 0377) << 12); /* DAR<0:7> <- AC */ - return 0; /* clear AC */ + rf_da = rf_da & 07777; /* clear DAR<0:7> */ +case 2: /* DXAL w/o clear */ + rf_da = rf_da | ((AC & 0377) << 12); /* DAR<0:7> |= AC */ + AC = AC & ~07777; /* clear AC */ + break; case 5: /* DXAC */ - return ((rf_da >> 12) & 0377); /* AC <- DAR<0:7> */ + AC = AC & ~07777; /* clear AC */ +case 4: /* DXAC w/o clear */ + AC = AC | ((rf_da >> 12) & 0377); /* AC |= DAR<0:7> */ + break; default: - return (stop_inst << IOT_V_REASON) + AC; } /* end switch */ + AC = (stop_inst << IOT_V_REASON) + AC; + break; } /* end switch */ +if ((t_addr) rf_da >= rf_unit.capac) rf_sta = rf_sta | RFS_NXD; +else rf_sta = rf_sta & ~RFS_NXD; +RF_INT_UPDATE; +return AC; } /* Unit service @@ -253,7 +277,10 @@ if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */ return IORETURN (rf_stopioe, SCPE_UNATT); } mex = GET_MEX (rf_sta); -do { M[RF_WC] = (M[RF_WC] + 1) & 07777; /* incr word count */ +do { if ((t_addr) rf_da >= rf_unit.capac) { /* disk overflow? */ + rf_sta = rf_sta | RFS_NXD; + break; } + M[RF_WC] = (M[RF_WC] + 1) & 07777; /* incr word count */ M[RF_MA] = (M[RF_MA] + 1) & 07777; /* incr mem addr */ pa = mex | M[RF_MA]; /* add extension */ if (uptr->FUNC == RF_READ) { /* read? */ @@ -268,7 +295,7 @@ do { M[RF_WC] = (M[RF_WC] + 1) & 07777; /* incr word count */ rf_da = (rf_da + 1) & 03777777; } /* incr disk addr */ while ((M[RF_WC] != 0) && (rf_burst != 0)); /* brk if wc, no brst */ -if (M[RF_WC] != 0) /* more to do? */ +if ((M[RF_WC] != 0) && ((rf_sta & RFS_ERR) == 0)) /* more to do? */ sim_activate (&rf_unit, rf_time); /* sched next */ else { rf_done = 1; /* done */ RF_INT_UPDATE; } /* update int req */ @@ -338,3 +365,35 @@ else { for (i = 0; i < OS8_LEN; i++) saved_PC = OS8_START; } return SCPE_OK; } + +/* Attach routine */ + +t_stat rf_attach (UNIT *uptr, char *cptr) +{ +int32 p, d; +int32 ds_bytes = RF_DKSIZE * sizeof (int16); + +if (uptr->flags & UNIT_AUTO) { + FILE *fp = fopen (cptr, "rb"); + if (fp == NULL) return SCPE_OPENERR; + fseek (fp, 0, SEEK_END); + p = ftell (fp); + d = (p + ds_bytes - 1) / ds_bytes; + if (d == 0) d = 1; + if (d > RF_NUMDK) d = RF_NUMDK; + uptr->capac = d * RF_DKSIZE; + fclose (fp); } +return attach_unit (uptr, cptr); +} + +/* Change disk size */ + +t_stat rf_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) +{ +if ((val == 0) || (val > (RF_NUMDK * RF_DKSIZE))) + return SCPE_IERR; +if (uptr->flags & UNIT_ATT) return SCPE_ALATT; +uptr->capac = val; +uptr->flags = uptr->flags & ~UNIT_AUTO; +return SCPE_OK; +} diff --git a/descrip.mms b/descrip.mms index 0b505ec8..cb92b758 100644 --- a/descrip.mms +++ b/descrip.mms @@ -205,7 +205,7 @@ HP2100_OBJS = $(HP2100_DIR)HP2100_STDDEV.OBJ,$(HP2100_DIR)HP2100_DP.OBJ,\ $(HP2100_DIR)HP2100_LPS.OBJ,$(HP2100_DIR)HP2100_MS.OBJ,\ $(HP2100_DIR)HP2100_MT.OBJ,$(HP2100_DIR)HP2100_MUX.OBJ,\ $(HP2100_DIR)HP2100_CPU.OBJ,$(HP2100_DIR)HP2100_FP.OBJ,\ - $(HP2100_DIR)HP2100_SYS.OBJ,$(HP2100_DIR)HP2100_LPT.OBJ, + $(HP2100_DIR)HP2100_SYS.OBJ,$(HP2100_DIR)HP2100_LPT.OBJ,\ $(HP2100_DIR)HP2100_IPL.OBJ HP2100_OPTIONS = /INCLUDE=($(SIMH_DIR),$(HP2100_DIR)) @@ -336,12 +336,14 @@ PDP18B_SOURCE = $(PDP18B_DIR)PDP18B_DT.C,$(PDP18B_DIR)PDP18B_DRM.C,\ $(PDP18B_DIR)PDP18B_CPU.C,$(PDP18B_DIR)PDP18B_LP.C,\ $(PDP18B_DIR)PDP18B_MT.C,$(PDP18B_DIR)PDP18B_RF.C,\ $(PDP18B_DIR)PDP18B_RP.C,$(PDP18B_DIR)PDP18B_STDDEV.C,\ - $(PDP18B_DIR)PDP18B_SYS.C,$(PDP18B_DIR)PDP18B_TT1.C + $(PDP18B_DIR)PDP18B_SYS.C,$(PDP18B_DIR)PDP18B_TT1.C,\ + $(PDP18B_DIR)PDP18B_RB.C PDP18B_OBJS = $(PDP18B_DIR)PDP18B_DT.OBJ,$(PDP18B_DIR)PDP18B_DRM.OBJ,\ $(PDP18B_DIR)PDP18B_CPU.OBJ,$(PDP18B_DIR)PDP18B_LP.OBJ,\ $(PDP18B_DIR)PDP18B_MT.OBJ,$(PDP18B_DIR)PDP18B_RF.OBJ,\ $(PDP18B_DIR)PDP18B_RP.OBJ,$(PDP18B_DIR)PDP18B_STDDEV.OBJ,\ - $(PDP18B_DIR)PDP18B_SYS.OBJ,$(PDP18B_DIR)PDP18B_TT1.OBJ + $(PDP18B_DIR)PDP18B_SYS.OBJ,$(PDP18B_DIR)PDP18B_TT1.OBJ,\ + $(PDP18B_DIR)PDP18B_RB.OBJ PDP4_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=("PDP4=1") PDP7_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=("PDP7=1") PDP9_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=("PDP9=1") @@ -374,7 +376,7 @@ PDP11_OBJS = $(PDP11_DIR)PDP11_FP.OBJ,$(PDP11_DIR)PDP11_CPU.OBJ,\ $(PDP11_DIR)PDP11_IO.OBJ,$(PDP11_DIR)PDP11_RQ.OBJ,\ $(PDP11_DIR)PDP11_TQ.OBJ,$(PDP11_DIR)PDP11_PCLK.OBJ,\ $(PDP11_DIR)PDP11_RY.OBJ,$(PDP11_DIR)PDP11_PT.OBJ,\ - $(PDP11_DIR)PDP11_HK.OBJ,$(PDP11_DIR)PDP11_XQ.OBJ, + $(PDP11_DIR)PDP11_HK.OBJ,$(PDP11_DIR)PDP11_XQ.OBJ,\ $(PDP11_DIR)PDP11_XU.OBJ PDP11_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP11_DIR)) diff --git a/makefile b/makefile index 380c20ee..388a9aed 100644 --- a/makefile +++ b/makefile @@ -61,7 +61,7 @@ PDP18BD = PDP18B/ PDP18B = ${PDP18BD}pdp18b_dt.c ${PDP18BD}pdp18b_drm.c ${PDP18BD}pdp18b_cpu.c \ ${PDP18BD}pdp18b_lp.c ${PDP18BD}pdp18b_mt.c ${PDP18BD}pdp18b_rf.c \ ${PDP18BD}pdp18b_rp.c ${PDP18BD}pdp18b_stddev.c ${PDP18BD}pdp18b_sys.c \ - ${PDP18BD}pdp18b_tt1.c + ${PDP18BD}pdp18b_rb.c ${PDP18BD}pdp18b_tt1.c PDP4_OPT = -DPDP4 -I ${PDP18BD} PDP7_OPT = -DPDP7 -I ${PDP18BD} PDP9_OPT = -DPDP9 -I ${PDP18BD} diff --git a/scp.c b/scp.c index 35dba2de..9a2da767 100644 --- a/scp.c +++ b/scp.c @@ -23,6 +23,8 @@ 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. + 07-Feb-03 RMS Added VMS support for ! (from Mark Pizzolato) + 01-Feb-03 RMS Added breakpoint table extension, actions 14-Jan-03 RMS Added missing function prototypes 10-Jan-03 RMS Added attach/restore flag, dynamic memory size support, case sensitive SET options @@ -130,7 +132,7 @@ #define RU_BOOT 4 /* boot */ #define SRBSIZ 1024 /* save/restore buffer */ -#define SIM_BRK_INILNT 16384 /* bpt tbl length */ +#define SIM_BRK_INILNT 4096 /* bpt tbl length */ #define SIM_BRK_ALLTYP 0xFFFFFFFF #define SIM_NTIMERS 8 /* # timers */ #define SIM_TMAX 500 /* max timer makeup */ @@ -227,7 +229,7 @@ extern uint32 sim_os_msec (void); /* Prototypes */ t_stat sim_brk_init (void); -t_stat sim_brk_set (t_addr loc, int32 sw, int32 ncnt); +t_stat sim_brk_set (t_addr loc, int32 sw, int32 ncnt, char *act); t_stat sim_brk_clr (t_addr loc, int32 sw); t_stat sim_brk_clrall (int32 sw); t_stat sim_brk_show (FILE *st, t_addr loc, int32 sw); @@ -318,6 +320,7 @@ int32 sim_is_running = 0; uint32 sim_brk_summ = 0; uint32 sim_brk_types = 0; uint32 sim_brk_dflt = 0; +char *sim_brk_act = NULL; BRKTAB *sim_brk_tab = NULL; int32 sim_brk_ent = 0; int32 sim_brk_lnt = 0; @@ -567,12 +570,15 @@ else stat = SCPE_OK; while (stat != SCPE_EXIT) { /* in case exit */ printf ("sim> "); /* prompt */ - if (sim_vm_read != NULL) /* sim routine? */ + if (cptr = sim_brk_act) { /* pending action? */ + printf ("%s\n", sim_brk_act); + sim_brk_act = NULL; } + else if (sim_vm_read != NULL) /* sim routine? */ cptr = (*sim_vm_read) (cbuf, CBUFSIZE, stdin); else cptr = read_line (cbuf, CBUFSIZE, stdin); /* read command line */ if (cptr == NULL) continue; /* ignore EOF */ if (*cptr == 0) continue; /* ignore blank */ - if (sim_log) fprintf (sim_log, "sim> %s\n", cbuf); /* log cmd */ + if (sim_log) fprintf (sim_log, "sim> %s\n", cptr); /* log cmd */ cptr = get_glyph (cptr, gbuf, 0); /* get command glyph */ if (cmdp = find_cmd (gbuf)) /* lookup command */ stat = cmdp->action (cmdp->arg, cptr); /* if found, exec */ @@ -643,9 +649,16 @@ return SCPE_OK; t_stat spawn_cmd (int32 flag, char *cptr) { -if ((cptr == NULL) || (strlen(cptr) == 0)) cptr = getenv("SHELL"); -if ((cptr == NULL) || (strlen(cptr) == 0)) cptr = getenv("ComSpec"); +if ((cptr == NULL) || (strlen (cptr) == 0)) cptr = getenv("SHELL"); +if ((cptr == NULL) || (strlen (cptr) == 0)) cptr = getenv("ComSpec"); +#if defined (VMS) +if ((cptr == NULL) || (strlen (cptr) == 0)) cptr = "SPAWN/INPUT=SYS$COMMAND:"; +#endif system (cptr); +#if defined (VMS) +printf ("\n"); +#endif + return SCPE_OK; } @@ -1177,7 +1190,7 @@ return ssh_break (NULL, cptr, flg); /* call common code */ t_stat ssh_break (FILE *st, char *cptr, int32 flg) { -char gbuf[CBUFSIZE], *tptr, *t1ptr; +char gbuf[CBUFSIZE], *tptr, *t1ptr, *aptr; DEVICE *dptr = sim_devices[0]; UNIT *uptr = dptr->units; t_stat r; @@ -1187,6 +1200,9 @@ int32 cnt; if (*cptr == 0) return SCPE_2FARG; if (sim_brk_types == 0) return SCPE_NOFNC; if ((dptr == NULL) || (uptr == NULL)) return SCPE_IERR; +if (aptr = strchr (cptr, ';')) { /* ;action? */ + if (flg != SSH_ST) return SCPE_ARG; /* only on SET */ + *aptr++ = 0; } /* separate strings */ while (*cptr) { cptr = get_glyph (cptr, gbuf, ','); tptr = get_range (gbuf, &lo, &hi, dptr->aradix, max, 0); @@ -1205,7 +1221,7 @@ while (*cptr) { else return SCPE_ARG; } else { for ( ; lo <= hi; lo = lo + dptr->aincr) { - if (flg == SSH_ST) r = sim_brk_set (lo, sim_switches, cnt); + if (flg == SSH_ST) r = sim_brk_set (lo, sim_switches, cnt, aptr); else if (flg == SSH_CL) r = sim_brk_clr (lo, sim_switches); else if (flg == SSH_SH) r = sim_brk_show (st, lo, sim_switches); else return SCPE_ARG; @@ -1788,6 +1804,7 @@ if ((r = sim_check_console (30)) != SCPE_OK) { /* check console, error? */ return r; } if (step) sim_activate (&step_unit, step); /* set step timer */ sim_is_running = 1; /* flag running */ +sim_brk_act = NULL; /* defang actions */ r = sim_instr(); sim_is_running = 0; /* flag idle */ @@ -3206,7 +3223,7 @@ return sim_rtcn_calb (ticksper, 0); type types of breakpoints set on the address a bit mask representing letters A-Z cnt number of iterations before breakp is taken - action pointer to list of commands to be executed + action pointer command string to be executed when break is taken sim_brk_summ is a summary of the types of breakpoints that are currently set (it @@ -3216,7 +3233,6 @@ return sim_rtcn_calb (ticksper, 0); The package contains the following public routines: sim_brk_init initialize - sim_brk_pchg PC change sim_brk_set set breakpoint sim_brk_clr clear breakpoint sim_brk_clrall clear all breakpoints @@ -3225,17 +3241,17 @@ return sim_rtcn_calb (ticksper, 0); sim_brk_test test for breakpoint sim_brk_npc PC has been changed - Initialize breakpoint system. If simulator has filled in sim_brk_types, - allocate an initial breakpoint table, otherwise, allocate a minimal table. + Initialize breakpoint system. */ t_stat sim_brk_init (void) { -if (sim_brk_types) sim_brk_lnt = SIM_BRK_INILNT; -else sim_brk_lnt = 1; +sim_brk_lnt = SIM_BRK_INILNT; sim_brk_tab = calloc (sim_brk_lnt, sizeof (BRKTAB)); if (sim_brk_tab == NULL) return SCPE_MEM; sim_brk_ent = sim_brk_ins = 0; +sim_brk_pend = FALSE; +sim_brk_act = NULL; return SCPE_OK; } @@ -3266,10 +3282,19 @@ return NULL; BRKTAB *sim_brk_new (t_addr loc) { -BRKTAB *bp; +int32 i, t; +BRKTAB *bp, *newp; if (sim_brk_ins < 0) return NULL; -if (sim_brk_ent >= sim_brk_lnt) return NULL; +if (sim_brk_ent >= sim_brk_lnt) { /* out of space? */ + t = sim_brk_lnt + SIM_BRK_INILNT; /* new size */ + newp = calloc (t, sizeof (BRKTAB)); /* new table */ + if (newp == NULL) return NULL; /* can't extend */ + for (i = 0; i < sim_brk_lnt; i++) /* copy table */ + *(newp + i) = *(sim_brk_tab + i); + free (sim_brk_tab); /* free old table */ + sim_brk_tab = newp; /* new base, lnt */ + sim_brk_lnt = t; } if (sim_brk_ins != sim_brk_ent) { /* move needed? */ for (bp = sim_brk_tab + sim_brk_ent; bp > sim_brk_tab + sim_brk_ins; bp--) @@ -3285,17 +3310,25 @@ return bp; /* Set a breakpoint of type sw */ -t_stat sim_brk_set (t_addr loc, int32 sw, int32 ncnt) +t_stat sim_brk_set (t_addr loc, int32 sw, int32 ncnt, char *act) { BRKTAB *bp; if (sw == 0) sw = sim_brk_dflt; if ((sim_brk_types & sw) == 0) return SCPE_NOFNC; -bp = sim_brk_fnd (loc); -if (!bp) bp = sim_brk_new (loc); -if (!bp) return SCPE_MEM; -bp->typ = sw; -bp->cnt = ncnt; +bp = sim_brk_fnd (loc); /* present? */ +if (!bp) bp = sim_brk_new (loc); /* no, allocate */ +if (!bp) return SCPE_MEM; /* still no? mem err */ +bp->typ = sw; /* set type */ +bp->cnt = ncnt; /* set count */ +if ((bp->act != NULL) && (act != NULL)) { /* replace old action? */ + free (bp->act); /* deallocate */ + bp->act = NULL; } /* now no action */ +if ((act != NULL) && (*act != 0)) { /* new action? */ + char *newp = calloc (CBUFSIZE, sizeof (char)); /* allocate buffer */ + if (newp == NULL) return SCPE_MEM; /* mem err? */ + strncpy (newp, act, CBUFSIZE); /* copy action */ + bp->act = newp; } /* set pointer */ sim_brk_summ = sim_brk_summ | sw; return SCPE_OK; } @@ -3306,14 +3339,15 @@ t_stat sim_brk_clr (t_addr loc, int32 sw) { BRKTAB *bp = sim_brk_fnd (loc); -if (!bp) return SCPE_OK; +if (!bp) return SCPE_OK; /* not there? ok */ if (sw == 0) sw = SIM_BRK_ALLTYP; bp->typ = bp->typ & ~sw; -if (bp->typ) return SCPE_OK; -for ( ; bp < (sim_brk_tab + sim_brk_ent - 1); bp++) +if (bp->typ) return SCPE_OK; /* clear all types? */ +if (bp->act != NULL) free (bp->act); /* deallocate action */ +for ( ; bp < (sim_brk_tab + sim_brk_ent - 1); bp++) /* erase entry */ *bp = *(bp + 1); -sim_brk_ent = sim_brk_ent - 1; -sim_brk_summ = 0; +sim_brk_ent = sim_brk_ent - 1; /* decrement count */ +sim_brk_summ = 0; /* recalc summary */ for (bp = sim_brk_tab; bp < (sim_brk_tab + sim_brk_ent); bp++) sim_brk_summ = sim_brk_summ | bp->typ; return SCPE_OK; @@ -3326,9 +3360,9 @@ t_stat sim_brk_clrall (int32 sw) BRKTAB *bp; if (sw == 0) sw = SIM_BRK_ALLTYP; -if ((sim_brk_summ & ~sw) == 0) sim_brk_ent = sim_brk_summ = 0; -else { for (bp = sim_brk_tab; bp < (sim_brk_tab + sim_brk_ent); bp++) { - if (bp->typ & sw) sim_brk_clr (bp->addr, sw); } } +for (bp = sim_brk_tab; bp < (sim_brk_tab + sim_brk_ent); ) { + if (bp->typ & sw) sim_brk_clr (bp->addr, sw); + else bp++; } return SCPE_OK; } @@ -3352,6 +3386,7 @@ for (i = any = 0; i < 26; i++) { fputc (i + 'A', st); any = 1; } } if (bp->cnt > 0) fprintf (st, " [%d]", bp->cnt); +if (bp->act != NULL) fprintf (st, "; %s", bp->act); fprintf (st, "\n"); return SCPE_OK; } @@ -3374,13 +3409,14 @@ t_bool sim_brk_test (t_addr loc, int32 btyp) { BRKTAB *bp; -if ((bp = sim_brk_fnd (loc)) && - (btyp & bp->typ) && - (!sim_brk_pend || (loc != sim_brk_ploc)) && - (--(bp->cnt) <= 0)) { - bp->cnt = 0; - sim_brk_ploc = loc; - sim_brk_pend = TRUE; +if ((bp = sim_brk_fnd (loc)) && /* entry in table? */ + (btyp & bp->typ) && /* type match? */ + (!sim_brk_pend || (loc != sim_brk_ploc)) && /* new location? */ + (--(bp->cnt) <= 0)) { /* count reach 0? */ + bp->cnt = 0; /* reset count */ + sim_brk_ploc = loc; /* save location */ + sim_brk_act = bp->act; /* set up actions */ + sim_brk_pend = TRUE; /* don't do twice */ return TRUE; } sim_brk_pend = FALSE; return FALSE; diff --git a/sim_rev.h b/sim_rev.h index 196638ff..3ae3280c 100644 --- a/sim_rev.h +++ b/sim_rev.h @@ -29,12 +29,48 @@ #define SIM_MAJOR 2 #define SIM_MINOR 10 -#define SIM_PATCH 2 +#define SIM_PATCH 3 /* V2.10 revision history patch date module(s) and fix(es) + 3 tbd scp.c: + -- added dynamic extension of the breakpoint table + -- added breakpoint actions + + hp2100_cpu.c: fixed last cycle bug in DMA output (found by + Mike Gemeny) + + hp2100_ipl.c: individual links are full duplex (found by + Mike Gemeny) + + pdp11_cpu.c: changed R, SP to track PSW respectively + + pdp18b_defs.h, pdp18b_sys.c: added RB09 fixed head disk, + LP09 printer + + pdp18b_rf.c: + -- fixed IOT decoding (found by Hans Pufal) + -- fixed address overrun logic + -- added variable number of platters and autosizing + + pdp18b_rf.c: + -- fixed IOT decoding + -- fixed bug in command initiation + + pdp18b_rb.c: new RB09 fixed head disk + + pdp18b_lp.c: new LP09 line printer + + pdp8_df.c: added variable number of platters and autosizing + + pdp8_rf.c: added variable number of platters and autosizing + + nova_dsk.c: added variable number of platters and autosizing + + id16_cpu.c: fixed bug in SETM, SETMR (found by Mark Pizzolato) + 2 15-Jan-03 scp.c: -- added dynamic memory size flag and RESTORE support -- added EValuate command diff --git a/simh_doc.txt b/simh_doc.txt index 756bd75b..b665070a 100644 --- a/simh_doc.txt +++ b/simh_doc.txt @@ -1,7 +1,7 @@ To: Users From: Bob Supnik -Subj: Simulator Usage, V2.10-2 -Date: 15-Jan-2003 +Subj: Simulator Usage, V2.10-3 +Date: 15-Feb-2003 COPYRIGHT NOTICE @@ -490,13 +490,15 @@ breakpoints of different types, identified by letter (for example, E for execution, R for read, W for write, etc). At the moment, most simulators support only E (execution) breakpoints. -Associated with a breakpoint is a count. Each time the breakpoint -is sprung, the associated count is decremented. If the count is less -than or equal to 0, the breakpoint occurs; otherwise, it is deferred. +Associated with a breakpoint is a count and, optionally, an action. +Each time the breakpoint is sprung, the associated count is decremented. +If the count is less than or equal to 0, the breakpoint occurs; otherwise, +it is deferred. When the breakpoint occurs, the optional action is +automatically executed A breakpoint is set by the BREAK command: - sim> BREAK {-types} {[count]},{addr range...} + sim> BREAK {-types} {[count]},{addr range...}{;action} If no type is specified, the simulator-specific default breakpoint type (usually E for execution) is used. As with EXAMINE and DEPOSIT, @@ -506,6 +508,9 @@ or a relative range of address/length. Examples of BREAK: sim> break -e 200 -- set E break at 200 sim> break 2000/2[2] -- set E breaks at 2000,2001 with count = 2 + sim> break 100;ex ac -- set E break at 100 with + action EX AC + sim> break 100; -- delete action on break at 100 Currently set breakpoints can be displayed with the SHOW BREAK command: @@ -800,7 +805,9 @@ Rev 2.10, Nov, 02 Added PDP-11/VAX autoconfiguration support Added PDP-10/PDP-11/VAX variable vector support Added PDP-1 DECtape + Added PDP-1, PDP-4 Type 24 serial drum support Added PDP-8 RX28 support + Added PDP-9 RB09 fixed head disk, LP09 line printer Added HP2100 12845A line printer Added HP2100 13183 magtape support Added HP2100 boot ROM support diff --git a/simh_swre.txt b/simh_swre.txt index b5fa8774..8e89ba3d 100644 --- a/simh_swre.txt +++ b/simh_swre.txt @@ -1,7 +1,7 @@ To: Users From: Bob Supnik Subj: Sample Software Packages -Date: 15-Nov-2002 +Date: 15-Feb-2003 This memorandum documents the sample software packages available to run with the SIMH simulators. Many of these packages are available under @@ -10,8 +10,8 @@ software. The following copyright notice applies to both the SIMH source and binary: - Original code published in 1993-2002, written by Robert M Supnik - Copyright (c) 1993-2002, Robert M Supnik + Original code published in 1993-2003, written by Robert M Supnik + Copyright (c) 1993-2003, 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"), @@ -354,6 +354,12 @@ development and execution capabilities. To load and run ADSS/KM-15: sim> ex pc PC: 077646 +- Change the default line printer to be the LP09 rather than the Type + 647 (PDP-9) or LP15 (PDP-15): + + sim> set lpt disa + sim> set lp9 ena + - Mount the Advanced Software System DECtape image on DECtape unit 0: sim> attach dt adss15_32k.dtp @@ -445,6 +451,36 @@ does not support the SIMH sockets library. and is now ready for commands. +6.4 DOS-15 + +DOS-15 was a more polished version of ADSS-15 using the RF15 or RP15 +as its system device. To load and run DOS-15: + +- Load the DOS-15 paper tape bootstrap into upper memory: + + sim> load rfsboot.rim 77637 + +- Mount the DOS-15 RF disk image on the RF15: + + sim> att rf dosv2a_4p.rf + +- Run the bootstrap: + + sim> run + +- The RF disk will boot and print out + +DOS-15 V2A + ENTER DATE (MM/DD/YY) - + + Enter the date (the year must be between 70 and 99). DOS-15 will + print its prompt and is now ready for commands. Recognized commands + include: + + I system information + S system configuration + R system device assignments + 7. IBM 1401