Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_SRC_1_19910112
-
6-sources/boot.mac
There are 59 other files named boot.mac in the archive. Click here to see a list.
; UPD ID= 4852, SNARK:<6.MONITOR>BOOT.MAC.48, 17-Sep-84 12:07:13 by PURRETTA
;Update copyright notice
; UPD ID= 4773, SNARK:<6.MONITOR>BOOT.MAC.47, 29-Aug-84 16:55:23 by LEACHE
;TCO 6.2207 - Stop output of null directory names on errors
; UPD ID= 4722, SNARK:<6.MONITOR>BOOT.MAC.46, 21-Aug-84 12:21:27 by LEACHE
;TCO 6.2179 - Teach BOOT to load long files
; UPD ID= 4682, SNARK:<6.MONITOR>BOOT.MAC.45, 13-Aug-84 16:55:03 by LEACHE
;TCO 6.2172 Clear channel before touching it in CHNRST
; UPD ID= 4628, SNARK:<6.MONITOR>BOOT.MAC.44, 29-Jul-84 18:41:59 by LEACHE
;Put PFERR code under debug conditional
; UPD ID= 4627, SNARK:<6.MONITOR>BOOT.MAC.43, 29-Jul-84 18:30:11 by LEACHE
;Fix CHNSAV,CHNRST routines
;Add more debugging stuff
; UPD ID= 4415, SNARK:<6.MONITOR>BOOT.MAC.42, 2-Jul-84 10:14:28 by LEACHE
;TCO 6.2105 Teach BOOT to ignore PDV in EXE directory
;Fix bugs in CHNSAV/CHNRST and CHKPG0
;Fix off by 1 bug in DDT preamble code
; UPD ID= 4368, SNARK:<6.MONITOR>BOOT.MAC.41, 20-Jun-84 17:01:36 by LEACHE
;TCO 6.2051 Restart DX20B's after MTBOOT has halted them with channel reset
;Define RP04 composite error bit correctly (was attention active)
;Add real trap handling for debugging
;Fix IOOP(CLEAR) to clear RAE
;TCO 6.2007 Fix pager-clear problem
;TCO 6.2011 Make BOOT unlock the port on dual-ported RP04567's
;Add subdirectory-lookup code
;Add debugging aids and support of new KDDT
;Fix bug in GET logic for MTBOOT relating to old-style (2-pass) loads
; UPD ID= 3835, SNARK:<6.MONITOR>BOOT.MAC.40, 1-Mar-84 13:15:19 by LEACHE
;More of previous - restore previous value of default UBSTR (340)
; UPD ID= 3812, SNARK:<6.MONITOR>BOOT.MAC.39, 29-Feb-84 16:43:53 by LEACHE
;TCO 6.1969
;Make BOOT load resident and swappable monitor in 1 pass
;Make BOOT able to write monitor pages to memory above first 256K
; UPD ID= 3651, SNARK:<6.MONITOR>BOOT.MAC.38, 2-Feb-84 16:55:47 by LEACHE
;Reduce code pages from 5 to 4
; UPD ID= 3639, SNARK:<6.MONITOR>BOOT.MAC.37, 2-Feb-84 11:52:53 by MURPHY
;Put definitions of lower core cells in PROLOG.
;Setup BUTSTA as start address instead of jump to lastpage+777 hack.
; UPD ID= 3605, SNARK:<6.MONITOR>BOOT.MAC.36, 31-Jan-84 14:39:31 by MURPHY
;TCO 6.1525 - Don't use .JBSYM to imply upper limit. POSTLD must know A%VFST.
; UPD ID= 2405, SNARK:<6.MONITOR>BOOT.MAC.35, 3-May-83 15:58:36 by COBB
;TCO 6.1639 - %s and ?s in PRINTX messages...
; UPD ID= 2206, SNARK:<6.MONITOR>BOOT.MAC.34, 8-Apr-83 06:04:10 by WACHS
;Remove TCO 6.1549 since HSC disks can't be PS:
; UPD ID= 2002, SNARK:<6.MONITOR>BOOT.MAC.33, 16-Mar-83 04:11:08 by WACHS
;TCO 6.1549 - Load KLIPA, KLNI microcode
; UPD ID= 1827, SNARK:<6.MONITOR>BOOT.MAC.32, 18-Feb-83 10:59:22 by LEACHE
;Replace error TAPHTE (removed in previous edit)
; UPD ID= 1824, SNARK:<6.MONITOR>BOOT.MAC.31, 18-Feb-83 09:51:41 by LEACHE
;TCO 6.1498 - Increase IO retry count for disks, Add disk status
; UPD ID= 1759, SNARK:<6.MONITOR>BOOT.MAC.30, 4-Feb-83 05:04:29 by WACHS
;TCO 6.1495 - Don't attempt to use KLIPA/KLNI channels
; UPD ID= 1457, SNARK:<6.MONITOR>BOOT.MAC.29, 17-Nov-82 21:01:26 by PAETZOLD
;Add some comments
; UPD ID= 1175, SNARK:<6.MONITOR>BOOT.MAC.28, 13-Sep-82 22:54:12 by MILLER
;Fix up CST mask
; UPD ID= 1174, SNARK:<6.MONITOR>BOOT.MAC.27, 13-Sep-82 21:47:49 by MILLER
;And again
; UPD ID= 1173, SNARK:<6.MONITOR>BOOT.MAC.26, 13-Sep-82 21:17:43 by MILLER
;Once more on the previous edit
; UPD ID= 1155, SNARK:<6.MONITOR>BOOT.MAC.25, 8-Sep-82 12:01:44 by MILLER
;TCO 6.1094. Set CST write bit in all CST entries
; UPD ID= 1076, SNARK:<6.MONITOR>BOOT.MAC.24, 10-Aug-82 19:17:14 by HALL
;TCO 6.1000 - Support the 2080
; Make TYI wait until data is available
; UPD ID= 1069, SNARK:<6.MONITOR>BOOT.MAC.23, 10-Aug-82 08:36:33 by HALL
;TCO 6.1000 - Support the 2080
; Previous edit accidentally deleted a line
; UPD ID= 1067, SNARK:<6.MONITOR>BOOT.MAC.22, 9-Aug-82 17:47:50 by HALL
;TCO 6.1000 - Support the 2080
; Set up P before the first subroutine call near GETCM1
; UPD ID= 1050, SNARK:<6.MONITOR>BOOT.MAC.21, 7-Aug-82 14:13:24 by HALL
;TCO 6.1000 - Support the 2080
; At FNDDEV get the mask right for a physical address
; UPD ID= 1041, SNARK:<6.MONITOR>BOOT.MAC.20, 5-Aug-82 06:37:27 by HALL
;TCO 6.1000 - Support the 2080
; Previous edit failed to update P1 for the KC
; UPD ID= 1039, SNARK:<6.MONITOR>BOOT.MAC.19, 4-Aug-82 14:47:01 by HALL
;TCO 6.1000 - Support the 2080
; Add some console initialization functions
; Remove OPDEFs that are also defined in PROLOG
; UPD ID= 1031, SNARK:<6.MONITOR>BOOT.MAC.18, 3-Aug-82 08:17:23 by HALL
;TCO 6.1000 - Support the 2080
; On the KC, set CST base register to 0
; UPD ID= 1029, SNARK:<6.MONITOR>BOOT.MAC.17, 3-Aug-82 07:20:17 by HALL
;TCO 6.1000 - Support the 2080
; On the KC, map all of memory
; At TOP2, clear left half of P2 before setting bits
; Add support for the console
;Also, fix definition of NCSTPG
; UPD ID= 1024, SNARK:<6.MONITOR>BOOT.MAC.16, 2-Aug-82 07:05:28 by HALL
;TCO 6.1000 - Support the 2080
; Typo in previous edit
; UPD ID= 1023, SNARK:<6.MONITOR>BOOT.MAC.15, 1-Aug-82 10:46:29 by HALL
;TCO 6.1000 - Support the 2080
; Search PROLOG
; Add APR stuff for the KC
; Change some bit numbers to symbol names
; UPD ID= 559, SNARK:<6.MONITOR>BOOT.MAC.14, 31-Mar-82 11:55:06 by LEACHE
;Update edit number for previous edit
; UPD ID= 531, SNARK:<6.MONITOR>BOOT.MAC.13, 18-Mar-82 15:48:22 by MILLER
;TCO 5.1762. Move code at start of FNDDEV to better place
; UPD ID= 86, SNARK:<5.MONITOR>BOOT.MAC.12, 31-Jul-81 09:58:22 by LEACHE
;Improve reporting of "structure not found" errors
; UPD ID= 33, SNARK:<5.MONITOR>BOOT.MAC.11, 15-Jul-81 08:14:26 by LEACHE
;More of previous edit
; UPD ID= 30, SNARK:<5.MONITOR>BOOT.MAC.10, 14-Jul-81 10:56:33 by LEACHE
;Remove all pretense of MTBOOT using a device name
; UPD ID= 2292, SNARK:<5.MONITOR>BOOT.MAC.9, 2-Jul-81 15:29:17 by LEACHE
;Correct debugging example
; UPD ID= 2291, SNARK:<5.MONITOR>BOOT.MAC.8, 2-Jul-81 14:13:56 by LEACHE
;Add /E switch (Load and go to location 141)
;Move KDDT to 500000 when debugging
; UPD ID= 2111, SNARK:<5.MONITOR>BOOT.MAC.7, 31-May-81 11:53:55 by LEACHE
;Shorten assembly error-messages
; UPD ID= 2110, SNARK:<5.MONITOR>BOOT.MAC.6, 31-May-81 11:43:46 by LEACHE
;Make error routine use STRNAM if CURNAM zero
;Force interactive mode on any error
; UPD ID= 2080, SNARK:<5.MONITOR>BOOT.MAC.5, 26-May-81 09:52:01 by LEACHE
;Display pass on swappable load
; UPD ID= 1979, SNARK:<5.MONITOR>BOOT.MAC.4, 12-May-81 13:18:14 by LEACHE
;Fix minor bug in MTBOOT
; UPD ID= 1970, SNARK:<5.MONITOR>BOOT.MAC.3, 10-May-81 10:28:19 by LEACHE
;Minor bug fix
; UPD ID= 1965, SNARK:<5.MONITOR>BOOT.MAC.2, 8-May-81 10:39:34 by LEACHE
;Rewrite error messages & error handling
; UPD ID= 1567, SNARK:<5.MONITOR>BOOT.MAC.14, 19-Feb-81 11:35:20 by LEACHE
;Bump maximum dumpable core to 3 meg
; UPD ID= 1566, SNARK:<5.MONITOR>BOOT.MAC.13, 18-Feb-81 09:30:23 by LEACHE
;Make BOOT complain if the dump file is too small
;Make /D & /S noops for MTBOOT
; UPD ID= 1518, SNARK:<5.MONITOR>BOOT.MAC.12, 4-Feb-81 21:04:23 by ZIMA
;Adjust comments on previous.
; UPD ID= 1517, SNARK:<5.MONITOR>BOOT.MAC.11, 4-Feb-81 17:40:44 by ZIMA
;TCO 5.1257 - Handle uninitialized memory for KS:
; Put BLT of 20-23 under conditional for KL only
; Do DBE scan for low 256K at GOTCOR
; Do DBE scan for high memory at SETEP2
;Fixes problems including trashed ROOT-DIRECTORY on powerfail and SWPPTP
;BUGHLTs on reload.
; UPD ID= 1492, SNARK:<5.MONITOR>BOOT.MAC.10, 26-Jan-81 12:08:55 by LEACHE
;Increase code pages from 3 to 4
; Add /I switch (Information)
; Place following under control of feature test switch FT.RP2:
; (1) symbols from RP20 microcode
; (2) attempt/do not attempt to load DX20B's
; UPD ID= 1369, SNARK:<5.MONITOR>BOOT.MAC.9, 18-Dec-80 11:36:58 by LEACHE
;Fix bug that prevented all directory entries from being written to dump file
; Section-align directory entries for dump file
; Add symbols PHYPAG, PHYADR, NMEG.
; UPD ID= 1270, SNARK:<4.RP20-UTILITIES>BOOT.MAC.6, 13-Nov-80 10:45:09 by WACHS
;Add support for TM78/TU78, fix code for RP07, make the magtape stuff
; table driven
; UPD ID= 1251, SNARK:<5.MONITOR>BOOT.MAC.6, 10-Nov-80 11:44:52 by LEACHE
;Stop BOOT from writing DX20 microcode to dump file. Add diagrams + comments
; Reload DX20 during auto-reload of monitor (currently for disk only)
; Display DX20 "type" during microcode load
; UPD ID= 732, SNARK:<5.MONITOR>BOOT.MAC.5, 5-Jul-80 22:15:17 by ZIMA
;TCO 5.1095 - FIX BOOT TO HANDLE UNINITIALIZED MEMORY INSTEAD OF HANGING.
; UPD ID= 657, SNARK:<5.MONITOR>BOOT.MAC.4, 16-Jun-80 17:22:54 by KONEN
;TCO 5.1063 -
;FIX BOOT TO LOOK AT APR SERIAL NUMBER ON HOME BLOCKS, BEFORE NAME 'PS'
; UPD ID= 553, SNARK:<5.MONITOR>BOOT.MAC.3, 24-May-80 21:27:04 by ZIMA
;TCO 5.1044 - FIX TYPO IN SETZM'ING 20-23.
;TCO 5.1045 - FIX TYPO IN MTBOOT PROMPT.
;TCO 5.1046 - INTERIM FIX FOR KS10 BOOT/MTBOOT HANGING, CLEAR KLINIK
; OUTPUT WORD DURING STARTUP.
; UPD ID= 547, SNARK:<5.MONITOR>BOOT.MAC.2, 21-May-80 16:18:11 by DBELL
;TCO 5.1043 - LOAD DX20 MICROCODE FOR RP20 DISKS
; UPD ID= 230, SNARK:<4.1.MONITOR>BOOT.MAC.63, 30-Jan-80 14:30:34 by ENGEL
;FIX NCSTPG FOR KS
; UPD ID= 229, SNARK:<4.1.MONITOR>BOOT.MAC.62, 30-Jan-80 08:12:35 by ENGEL
; UPD ID= 198, SNARK:<4.1.MONITOR>BOOT.MAC.61, 10-Jan-80 08:34:04 by ENGEL
;ADD <CR><LF> TO ERROR MESSAGES
;<4.MONITOR>BOOT.MAC.60, 18-Oct-79 16:57:29, EDIT BY DBELL
;TCO 4.2534 - DON'T LOAD DX20 MICROCODE IF DUMPING CORE OR AUTO-RELOADING
;<4.MONITOR>BOOT.MAC.59, 11-Oct-79 13:47:20, EDIT BY ENGEL
;MOVE PDL AWAY FROM LODTYP
;<4.MONITOR>BOOT.MAC.58, 5-Oct-79 16:55:50, EDIT BY ENGEL
;CHANGE EDDT TO KDDT IN LINK EXAMPLE
;<4.MONITOR>BOOT.MAC.55, 19-Jul-79 07:48:02, EDIT BY ENGEL
;<4.MONITOR>BOOT.MAC.54, 18-Jul-79 16:49:09, EDIT BY ENGEL
;ADD HELP TEXT TO DEBUGGING BOOT WITH EDDT
;<4.MONITOR>BOOT.MAC.53, 16-Jul-79 10:27:21, EDIT BY ENGEL
;ALLOW SYSTEM TO BOOT WHEN DX20 IS BAD
;<4.MONITOR>BOOT.MAC.52, 6-Jul-79 10:02:15, EDIT BY ENGEL
;<4.MONITOR>BOOT.MAC.51, 5-Jul-79 13:21:23, EDIT BY ENGEL
;FIX NCSTPG
;<4.MONITOR>BOOT.MAC.50, 2-Jul-79 09:04:45, EDIT BY ENGEL
;ADD HINTS FOR HOW TO DEBUG WITH EDDT
;<4.MONITOR>BOOT.MAC.49, 27-Jun-79 15:48:54, Edit by KONEN
;PRINT MTBOOT PROMPT
;<4.MONITOR>BOOT.MAC.48, 25-Jun-79 16:41:08, EDIT BY ENGEL
;DEFEND AGAINST MEMORY PARITY IN LOCATIONS 20-23
;<4.MONITOR>BOOT.MAC.47, 22-Jun-79 14:30:16, EDIT BY ENGEL
;ADD HIGH CORE SAVING AND RUBOUT CHANGES
;<4.MONITOR>BOOT.MAC.46, 10-Jun-79 14:44:37, Edit by MCLEAN
;<4.MONITOR>BOOT.MAC.45, 10-Jun-79 14:33:47, Edit by MCLEAN
;MOVE DECISION ON LOAD TYPE FOR BOOT OF SM FOR MORE ROOM
;<4.MONITOR>BOOT.MAC.44, 4-MAR-79 14:35:04, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.MONITOR>BOOT.MAC.43, 26-JAN-79 22:31:45, EDIT BY MCLEAN
;GET CORRECT NUMBER OF CYLS PER UNIT FOR RP07
;<4.MONITOR>BOOT.MAC.42, 26-JAN-79 22:25:14, EDIT BY MCLEAN
;ADD RP07
;<4.MONITOR>BOOT.MAC.41, 17-JAN-79 14:53:26, EDIT BY DBELL
;PUT IN THE SYMBOL A%VFST FOR THE FIRST ADDRESS OF BOOT, AND FIX
;TSTPAG AND SETLCV TO USE IT.
;<4.MONITOR>BOOT.MAC.40, 16-JAN-79 10:05:44, EDIT BY DBELL
;FIX TSTADR TO USE VFREE CORRECTLY.
;<4.MONITOR>BOOT.MAC.39, 15-JAN-79 10:34:32, EDIT BY DBELL
;TCO 4.2154 - MAKE THE UPPER LIMIT ON LOADING VARY ACCORDING TO .JBSYM,
; AND ADD THE /A SWITCH TO FORCE LOADING OF ALL OF A PROGRAM. CLEAN UP
; THE PAGE DEFINITIONS. EXTEND LOADING RANGE FROM 377 TO BOOT ITSELF.
;<4.MONITOR>BOOT.MAC.37, 7-NOV-78 18:12:26, EDIT BY MCLEAN
;FIX SAVING IF GT 512 K
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
;OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1976, 1984.
;ALL RIGHTS RESERVED.
TITLE BOOT - DISK AND TAPE BOOTSTRAP
SUBTTL L.BOSACK 23-SEP-73 (OLD, OLD ORIGINAL)
SALL
SEARCH MONSYM,MACSYM,PROLOG
BDEBUG==0 ;BOOT'S INTERNAL DEBUG CONDITIONAL
V%WHO==0
V%MAJOR==10
V%MINOR==0
V%EDIT==201
;These definitions reflect that version of the monitor for which
;BOOT's loading behavior was radically changed
M%MAJ==6
M%MIN==0
M%EDT==6070
COMMENT \
EEEEEEEEEEEEEEE DDDDDDDDDDDD DDDDDDDDDDDD TTTTTTTTTTTTTTT
EEEEEEEEEEEEEEE DDDDDDDDDDDD DDDDDDDDDDDD TTTTTTTTTTTTTTT
EEEEEEEEEEEEEEE DDDDDDDDDDDD DDDDDDDDDDDD TTTTTTTTTTTTTTT
EEE DDD DDD DDD DDD TTT
EEE DDD DDD DDD DDD TTT
EEE DDD DDD DDD DDD TTT
EEE DDD DDD DDD DDD TTT
EEE DDD DDD DDD DDD TTT
EEE DDD DDD DDD DDD TTT
EEEEEEEEEEEEEEE DDD DDD DDD DDD TTT
EEEEEEEEEEEEEEE DDD DDD DDD DDD TTT
EEEEEEEEEEEEEEE DDD DDD DDD DDD TTT
EEE DDD DDD DDD DDD TTT
EEE DDD DDD DDD DDD TTT
EEE DDD DDD DDD DDD TTT
EEE DDD DDD DDD DDD TTT
EEE DDD DDD DDD DDD TTT
EEE DDD DDD DDD DDD TTT
EEEEEEEEEEEEEEE DDDDDDDDDDDD DDDDDDDDDDDD TTT
EEEEEEEEEEEEEEE DDDDDDDDDDDD DDDDDDDDDDDD TTT
EEEEEEEEEEEEEEE DDDDDDDDDDDD DDDDDDDDDDDD TTT
Now that I have your attention, here are a few hints on debugging BOOT
with EDDT. The first thing that needs to be done is to create an EXE
file with both BOOT and EDDT in it. This critical step is done with
LINK and would look something like the example below. To assemble BOOT
with proper debugging instructions set BDEBUG non zero.
(if you fail to do this, KDDT's pages will not be placed in the vitrual
map and KDDT will hang once BOOT turns virtual memory on.)
Now for how to link it:
@LINK
*/SET:.LOW.:40000 ;BOOT CODE GOES HERE
*/SET:ERCOD:501000 ;KDDT GOES HERE
*BOOT,KDDT,DXMCA.RMC/G (*BOOT,KDDT,DXMCA.RMC,DXMCE.RMC/G - TO INCLUDE
RP20 MICROCODE)
@SAVE BOOT.EXE
If you get a message like:
?LNKPCL PROGRAM TOO COMPLEX TO LOAD, SAVING AS FILE DSK:005LNK.EXE
simply rename that file to boot.exe - the file is ok.
To test the exe file:
@GET BOOT.EXE
@START 500000
-- you should now get a DDT prompt
ENT=
-- You should now see the value of the symbol displayed (40000)
If either of these tests fail, you blew it and must start over.
The .LOW. psect is BOOT. psect ERCOD is KDDT. The above LINK commands
load KDDT at 500000 and BOOT at 40000. DXMCA.RMC is the TU70 microcode
and needs to be linked even if you have no TU70. DXMCE.RMC is the RP20
microcode; loading it (for debugging) is optional.
Step number two is to get the system to the point where it has typed
"BOOT>" at you (i.e. KLI and friends). assuming you are using directory
<ENGEL> the following is a typical example of how to load the BOOT
being debugged:
BOOT><ENGEL>BOOT.EXE/L
BOOT>/G500000
EDDT
Now you are in EDDT and can access any of BOOT's symbols that occur
before FNDDEV. There are couple of tricky maneuvers to get to FNDDEV.
once at FNDDEV you can use all the symbols after FNDDEV. The following
is an attempt to step you through all of that. But first, a few words
about the general flow of it all.
Boot drops in to wherever you set .LOW. (e.g. 40000). at GOTCOR it
moves itself + N preceding low core pages to high core, while moving an
equivalent number of high core pages to low core. This little goody
causes all the symbols to point to incorrect addresses, for a short
time. The code that moves all this stuff around runs in the ACS. BOOT
also builds maps for the ultimate "CONO PAG," that starts the mapping.
One of these maps is built at SETPTB. There is a conditional there to
build a 256K map and include
EDDT into the mapped boot space). Once boot has mapped itself you can
use all the symbols past FNDDEV and set breakpoints as freely as you
like. What follows is a cookbook approach to getting to FNDDEV.
(When we last saw the computer it had typed EDDT at us. We will continue from
there.)
1. Set a breakpoint at DBG1. This is a JRST 1 to the code that
moves BOOT to high core.
2. Type ENT$G to start BOOT.
3. At the breakpoint set a new breakpoint at DBG2 (i.e. DBG2$b).
This breakpoint is in an AC.
4. Type $P
5. You have hit the second breakpoint. Now set the third. Set this
breakpoint at DBG3 (i.e DBG3$B).
6. Type $P
7. Type three (3) alt X's ($X) to get past the CONO PAG, to FNDDEV.
If the KL goes into limbo after the 1'st $X, KDDT was not mapped
properly - this shouldn't happen unless you've been playing with
the code at SETPTB.
8. You are now at FNDDEV. Get rid of the three breakpoints you set.
This step is very important as you have set a breakpoint in the ACS.
Thus, you have to type $B.
9. From here on it is just like monitor debugging. Good luck.
10. Well, not quite. One of the more annoying things that can happen to
you is the loss of symbols. This may happen twice, depending on how
far into the loading process you monitor BOOT with DDT. The first
occurrence happens when the CLRCOR routine clears page 0, destroying
the symbol-table pointer in .JBSYM (116). The second occurence happens
when BOOT loads in page 0 of the .EXE file, effectively replacing
BOOT's symbol-table pointer with that of the .EXE file. You will
suddenly see a new set of totally inappropriate symbols.
The BDEBUG conditional provides for the generation of code and data
storage to save and restore the symbol table pointer semi-automatically.
After the first occurrence of symbol lossage, do the following:
1. Make note of the current PC. Restart KDDT with:
500000$G
You will again see the DDT herald displayed.
3. Do $: - this clears DDT's symbol table cache. Now you
have BOOT symbols again.
4. Put a breakpoint at the old PC, and do pc$G to get there.
You are ready to debug again.
After the second occurrence of symbol lossage, you must essentially
repeat the above. If you intend to monitor the loaded .EXE file
(with it's own copy of DDT), then make the following changes to
the procedure:
Either:
1. Don't recover BOOT's symbols after the second-occurrence of
lossage.
Or:
1. Before recovering BOOT's symbols after the second occurrence of
lossage, manually move the contents of location 116 to somewhere
in core (E.G. the patch area) or write down the contents. This
is the pointer to the .EXE file BOOT is currently loading.
2. Before BOOT transfers control to the loaded .EXE file (at
DOSTRT), deposit the .EXE file's symbol table pointer in 116.
As soon as EDDT (or even MDDT) is initialized, the symbol table
pointer will be read and DDT will have the correct symbols.
11. Patching. It is sometime convenient to patch BOOT under timesharing,
but the trick is to compensate for all symbols above and including
FNDDEV pointing to the wrong place. This accomplished by PMAPing
the low-core BOOT pages into their usual high-core pages. The BDEBUG
conditional will automatically generate pre/post DDT code that plays
this PMAP game and sets up the DDT location in JOBDAT to point
to the preamble code. Simply GET the .EXE file and enter DDT with the
DDT command. BE SURE TO EXIT DDT WITH ^Z (just like monitor patching).
The BDEBUG conditional also creates the PATCH patching area. This area
can be used to patch either pre-FNDDEV or post FNDDEV code. Patching
is intended to make debugging easier, not to provide a mechanism for
distributing bug fixes to the field.
Always remember that future monitor changes could cause the resident
monitor to overlay both the PATCH area and KDDT.
BOOT's EXE-image map
40 ENT + initialization code
41(773) FNDDEV - high-core code
42(774) high-core code
43(775) high-core code
44(776) high-core code
45(777) high-core code
46 moving code (BOTMOV), DX20A ucode
47 DX20A ucode
50 DX20A ucode
51 DX20A ucode
52 DX20A ucode
53 DX20A ucode
500-513 KDDT+BOOT DDT preamble code (if present)
773(41) high-core code (in position)
774(42) high-core code (in position)
775(43) high-core code (in position)
776(44) high-core code (in position)
777(45) high-core code (in position)
0 ************************* *************************
* * * *
* * * *
* * * *
* * * *
* * * *
LODBAS: ##*#######################*## SL *************************
# * * # *BBBBBBBBBBBBBBBBBBBBBBB*
# * * # *BBBBBBBBBBBBBBBBBBBBBBB*
# * * # *BBBBBBBBBBBBBBBBBBBBBBB*
# +++++++++++++++++++++++++ # *BBBBBBBBBBBBBBBBBBBBBBB*
# + MOVEABLE CODE + # *BBBBBBBBBBBBBBBBBBBBBBB*
# + + # *BBBBBBBBBBBBBBBBBBBBBBB*
# + + # *BBBBBBBBBBBBBBBBBBBBBBB*
LODTOP: ##+#######################+## *************************
MCSPAG: + MOVING CODE + * *
+ + * *
+++++++++++++++++++++++++ * *
+ MICRO CODE + * *
+ + * *
+ + * *
+ + * *
MCEPAG: +++++++++++++++++++++++++ EL * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
TOPBAS: %%*%%%%%%%%%%%%%%%%%%%%%%%*%% *************************
% * * % *MMMMMMMMMMMMMMMMMMMMMMM*
% * * % *MMMMMMMMMMMMMMMMMMMMMMM*
% * * % *MMMMMMMMMMMMMMMMMMMMMMM*
% * * % *MMMMMMMMMMMMMMMMMMMMMMM*
% * * % *MMMMMMMMMMMMMMMMMMMMMMM*
% * * % *MMMMMMMMMMMMMMMMMMMMMMM*
% * * % *MMMMMMMMMMMMMMMMMMMMMMM*
TOPTOP: %%*%%%%%%%%%%%%%%%%%%%%%%%*%% *************************
* CORE > 256K * * *
* (IF PRESENT) * * *
* * * *
* * * *
************************* *************************
LEGEND: BOOT IN PHYSICAL MEMORY MEMORY BEFORE PAGE MOVEMENT
+ = BOOT DROP-IN WINDOW B = PAGES OWNED BY BOOT
# = SOURCE AREA M = MONITOR PAGES
% = TARGET AREA SL = START LOST PAGES
EL = END LOST PAGES
0 ************************* *************************
* * * *
* * * *
* * * *
* * * *
* * * *
LODBAS: ************************* SL *************************
*MMMMMMMMMMMMMMMMMMMMMMM* *???????????????????????*
*MMMMMMMMMMMMMMMMMMMMMMM* *???????????????????????*
*MMMMMMMMMMMMMMMMMMMMMMM* *???????????????????????*
*MMMMMMMMMMMMMMMMMMMMMMM* *???????????????????????*
*MMMMMMMMMMMMMMMMMMMMMMM* *???????????????????????*
*MMMMMMMMMMMMMMMMMMMMMMM* *???????????????????????*
*MMMMMMMMMMMMMMMMMMMMMMM* *???????????????????????*
LODTOP: ************************* *???????????????????????*
MCSPAG: * * *???????????????????????*
* * *???????????????????????*
* * *???????????????????????*
* * *???????????????????????*
* * *???????????????????????*
* * *???????????????????????*
* * *???????????????????????*
MCEPAG: * * EL *************************
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
TOPBAS: ************************* * *
*BBBBBBBBBBBBBBBBBBBBBBB* * *
*BBBBBBBBBBBBBBBBBBBBBBB* * *
*BBBBBBBBBBBBBBBBBBBBBBB* * *
*BBBBBBBBBBBBBBBBBBBBBBB* * *
*BBBBBBBBBBBBBBBBBBBBBBB* * *
*BBBBBBBBBBBBBBBBBBBBBBB* * *
*BBBBBBBBBBBBBBBBBBBBBBB* * *
TOPTOP: ************************* * *
* * * *
* * * *
* * * *
* * * *
* * * *
************************* *************************
LEGEND: MEMORY AFTER PAGE MOVEMENT ADDRESS SPACE OF DUMP
B = PAGES OWNED BY BOOT ? = LOST PAGES (FILE HOLE)
M = MONITOR PAGES SL = START LOST PAGES
EL = END LOST PAGES
\ ;END COMMENT BLOCK
; * * * *
;Temporary
MONACB==0
USRACB==:1 ;USER
IFN KCFLG,<
MONFLG==:FLD(MONACB,EXCAB)+FLD(USRACB,EXPAB)
TRFUNC==:MASKB(0,1)
TRNOP==:FLD (0,TRFUNC) ;IGNORE ERROR
TRMON==:FLD (1,TRFUNC) ;TRAP TO MONITOR
>
; * * * *
;ASSEMBLY PARAMETERS
IFNDEF PORG,<PORG==^D64*^D512> ;PHYSICAL ORIGIN OF CODE
;IFNDEF FTKLIPA,<FTKLIPA==0> ;SUPPORT FOR KLIPA/KLNI
FTKLIPA==0 ;REMOVE KLIPA/KLNI SUPPORT
IFNDEF FT.UDB,<FT.UDB==0> ;USER MODE DEBUG
IFNDEF FT.MTA,<FT.MTA==0> ;MAG TAPE PART 2 IF NONZERO
IFNDEF FT.EXE,<FT.EXE==1> ;LOAD EXE FORMAT FILES
IFNDEF FT.PRT,<FT.PRT==3> ;0 - JUST GLOBALS FOR SWPMON
;1 = STANDALONE PART 1
;2 = PART 2
;3 = STANDALONE PART 1&2
IFN KLFLG,< ;ONLY ALLOW DX20 CODE IF KL10
IFNDEF FT.DX2,<FT.DX2==1> ;DX20/TU7X CODE IF NONZERO
IFNDEF FT.TM8,<FT.TM8==1> ;TM78/TU78 CODE IF NON-0
IFNDEF FT.RP2,<FT.RP2==0> ;RP20 CODE/MICROCODE IF NON-0
> ;END IFN KLFLG
IFE KLFLG,<
IFNDEF FT.DX2,<FT.DX2==0> ;DX20/TU7X CODE IF NONZERO
IFNDEF FT.TM8,<FT.TM8==0> ;TM78/TU78 CODE IF NON ZERO
> ;END IFE KLFLG
;PROCESSOR (ETC.) BITS
AP.RES==1B19 ;IOB RESET (SAME ON KI AND KL)
AP.CLR==1B22
AP.SET==1B23
IFN KLFLG,<
AP.SBE==1B24 ;SBUS error
AP.NXM==1B25 ;NXM
AP.IOP==1B26 ;IO page-fail
AP.MBP==1B27 ;MASS-buss parity error
AP.CAD==1B28 ;Cache-directory parity error
AP.APE==1B29 ;Address-parity error
AP.PFL==1B30 ;Power-fail
AP.SWD==1B31 ;Cache-sweep done
AP.BAD==AP.SBE!AP.IOP!AP.MBP!AP.CAD!AP.APE
>
IFN SMFLG,<
AP.INE==1B25 ;INTERRUPT 8080
AP.NXM==1B27
>
IFN KLFLG!SMFLG,<
AP.RNX==AP.CLR!AP.NXM
>
IFN KLFLG!SMFLG,<
IMMPTR==FLD(IMMCOD,PTRCOD)!PTWR!PTCACH ;IMMEDIATE PAGE POINTER.
;1B2 = IMMEDIATE POINTER
;1B4 = WRITEABLE
;1B6 = CACHEABLE
>
IFN KCFLG,<
IMMPTR==FLD(IMMCOD,PTRCOD)!PTWR ;IMMEDIATE AND WRITABLE
> ;END OF IFN KCFLG
;STATE TABLE DEFINATION
;
STTSIZ==^D29 ;SIZE OF STATE TABLE
RH0==540
ICA==0 ;INITIAL CHANNEL CONTROL WORD ADDRESS IN EPT
.RHRAE==1B24 ;REGISTER ACCESS ERROR
.RHMBR==1B25 ;MASSBUS RESET
.RHCTE==1B26 ;CLEAR TRANSFER ERROR
.RHMBE==1B27 ;MASSBUS ENABLE
.RHCLP==1B28 ;RESET CLP
.RHAIE==1B30 ;ATTENTION INTERRUPT ENABLE
.RHSTP==1B31 ;STOP TRANSFER
.RHDON==1B32 ;DONE
.RHSBR==70B5 ;SBAR
.RHSTR==71B5 ;STCR
.RHIVR==74B5 ;INTERRUPT VECTOR REGISTER
.TMCSR==00B5 ;CONTROL REG.
.TMRDF==71 ;READ FORWARD AND GO
.TMBSF==33 ;BACKSPACE BLOCK
.TMRWF==07 ;REWIND
.TMDSR==01B5 ;DEVICE STATUS REG
.TMERR==02B5 ;ERROR REGISTER
TMSPIP==20000
TMSMOL==10000 ;MEDIUM ON LINE(TELL YOU FORTUNE, 10KCS?)
TMSDRY==200 ;DRIVE/FORMATTER READY
TMSIDB==10 ;PE ID BURST SEEN
.TMATR==04B5 ;ATTENTION SUMMARY REGISTER
.TMFCR==05B5 ;FRAME COUNT REG.
.TMDTR==06B5 ;DRIVE TYPE REG.
.TMTCR==11B5 ;TAPE CONTROL REG.
TMCD8==1400 ;800 BPI
TMCD16==2000 ;1600 BPI
;Definitions for DX20
.DXATP==60 ;DX20 DEVICE TYPE CODE FOR TAPES
.DXBTP==61 ;DX20 DEVICE TYPE CODE FOR RP20 DISKS
.TDSTR==20B5 ;DRIVE STATUS/STATUS INDEX
.TDDEB==1B25 ;DEVICE END
.TDDNR==21B5 ;DRIVE NUMBER, DRIVE MODE, DATA MODE
.TDMOD==1B23!14B27 ;1600 BPI, CORE DUMP MODE
.TDTER==23B5 ;TRACK IN ERROR, FLAGS
.TDE0R==26B5 ;EXTENDED STATUS REG 0
.TDMNR==3B5 ;MAINTENANCE REGISTER
.TDSCB==1B31 ;SINGLE CYCLE THE DX20
.TDSTB==1B33 ;START DX20
.TDSTR==20B5 ;ENDING STATUS
.TDTCR==21B5 ;CONTROL REGISTER
.TDFLR==23B5 ;FLAGS
.TDAYR==24B5 ;ASYNCHRONOUS STATUS
.TDE0R==26B5 ;EXTENDED STATUS REGISTER 0
.TDE1R==27B5 ;EXTENDED STATUS REGISTER 1
.TDIRR==30B5 ;IR REGISTER
.TDPCR==31B5 ;PC REGISTER
.TDICB==1B20 ;ENABLE IR FROM CRAM
.TDCIB==1B21 ;ENABLE CRAM FROM IR
.TDPEB==1B22 ;ENABLE PC LOAD
.TDPIB==1B23 ;ENABLE PC AUTO INCREMENT
.TDIBR==36B5 ;IBUS AND BR REGISTER
.TDERR==2B5 ;Error register
.TDSTS==1B5 ;Status register
.TDATB==1B20 ;ATTENTION
.TDCEB==1B21 ;COMPOSITE ERROR BIT
.TDMPR==1B23 ;MICROPROCESSOR RUNNING BIT
.T8TYP==101 ;TM78 DRIVE TYPE
.T7ICD==1B5 ;INTERRUPT CODE (DATA XFER)
T7.ICD==77 ;MASK FOR ALL INTERRUPT CODES
ICD.DN==1 ;DONE, NO ERRORS
ICD.SR==21 ;SHORT RECORD
ICD.EF==2 ;END OF FILE
ICD.BT==3 ;BOT
.T7FMT==2B5 ;FORMAT
T7.SER==100000 ;SUPPRESS ERROR RECOVERY (REPOSITIONING)
T7.CDP==30000 ;CORE-DUMP
T7.1RC==4 ;READ 1 RECORD
.T7BC==5B5 ;BYTE COUNT
.T7SR==7B5 ;STATUS REGISTER
T7.RDY==100000 ;DRIVE IS READY
.T7ICN==13B5 ;INTERRUPT CODE (NON DATA XFER)
.T7ND0==14B5 ;NON-DATA-XFER COMMAND, DRIVE 0
.T7TMS==21B5 ;TM STATUS
T7.TMR==1B20 ;TM READY
T7.REW==7 ;REWIND
T7.SNS==11 ;SENSE
T7.BSR==23 ;BACKSPACE RECORD
T7.RDF==71 ;READ
LR==1B6 ;LOAD REGISTER
GO==1B35 ;GO BIT IN CONTROL REGISTER
RCLP==1B7 ;RESET CLP (IN DATAO)
STLW==1B10 ;STORE LOGOUT STATUS WORDS (IN DATAO)
; RP04 DEVICE REGISTERS
R4%CSR==00B5 ;Control and status register-1
CR.DVA==4000 ;Device available
R4%DSR==01B5 ;DEVICE STATUS REGISTER
DS.ATA==1B20 ;Attention
DS.ERR==1B21 ;Composite error
DS.PIP==1B22 ;Position in progress
DS.MOL==1B23 ;Media on line
DS.WRL==1B24 ;Write-locked
DS.LST==1B25 ;Last sector transfered
DS.PGM==1B26 ;Programmable
DS.DPR==1B27 ;Drive present
DS.DRY==1B28 ;Drive ready
DS.VV==1B29 ;Volume valid
DS.GUD==DS.MOL!DS.DPR!DS.DRY!DS.VV
DS.MSK==DS.GUD!DS.ATA!DS.ERR!DS.PIP!DS.WRL ;MASK OF STATUS BITS TO CONSIDER
R4%ER1==02B5 ;DEVICE ERROR-REGISTER ONE
R4%ATN==04B5 ;RP04 PSEUDO-ATTENTION REGISTER
R4%DST==05B5 ;DESIRED SECTOR/TRACK REGISTER
R4%DTR==06B5 ;DRIVE TYPE REGISTER
R4%ER2==14B5 ;DEVICE ERROR-REGISTER TWO
R4%DCA==12B5 ;DESIRED CYLINDER REGISTER
R4%ER3==15B5 ;DEVICE ERROR-REGISTER THREE
RH%XFR==40B5 ;RH INITIATE DATA TRANSFER REGISTER
R4%TYP==777B35 ;DEVICE TYPE FIELD IN TYPE REGISTER
.R4TYP==20 ;RP04 DEVICE TYPE CODE
.R5TYP==21 ;RP05 DEVICE TYPE CODE
.R6TYP==22 ;RP06 DEVICE TYPE CODE
.R7TYP==42 ;RP07 DEVICE TYPE CODE
.R3TYP==24 ;RM03 DEVICE TYPE CODE
R4%CSK==02B34 ;RP04 SEEK FUNCTION
R4%CRC==03B34 ;RE-CALIBRATE FUNCTION IN CONTROL REGISTER
R4%CDC==04B34 ;RP04 DRIVE CLEAR FUNCTION
R4%REL==5B34 ;Release port function
R4%RIP==10B34 ;READ-IN PRESET FUNCTION
R4%CPA==11B34 ;PACK ACKNOWLEDGE FUNCTION IN CONTROL REGISTER
R4%CWR==30B34 ;RP04 WRITE FUNCTION
R4%CRD==34B34 ;RP04 READ FUNCTION
RHERR==775120 ;RH10 CONI ERROR BITS
TIMOUT==^D50000 ;COUNT FOR SOJG TIMEOUT
IFE SMFLG,<
MAXCHN==7 ;MAX # OF CHANNELS
>
IFN SMFLG,<
MAXCHN==2 ;MAX # OF CHANNELS
>
MAXDRV==7 ;MAX NUMBER OF DRIVES/CHANNEL
KLPCHN==7 ;KLIPA/KLNI ON CHAN 7 IS A KLIPA
KLPMSK==400003,,0 ;CONI BITS WHICH DEFINE A KLIPA/KLNI
DEFSTR(KLP.VR,T1,^D29,^D8) ;FIELD FOR VERSION NUMBER IN T1
; INDEX BLOCK ADDRESS DEFINITIONS
STGADM==<MASKB 12,35> ;MASK FOR STORAGE ADDRESS
MSKSTR IDXADR,,STGADM ;STORAGE ADDR MASK
; EXE FILE DEFINITIONS
.EXDIR==1776 ;DIRECTORY BLOCK TYPE
.EXEND==1777 ;END BLOCK TYPE
.EXENT==1775 ;ENTRY BLOCK TYPE
.EXPDV==1774 ;PDV block type
; JOB DATA DEFINITIONS
.JBSYM==116 ;SYMBOL TABLE POINTER
; STRUCTURE DEFINITIONS
DEFSTR (DIDIR,A%FP0,17,18) ;DIRECTORY BLOCK TYPE (=.EXDIR)
DEFSTR (DISIZ,A%FP0,35,18) ;SIZE OF DIRECTORY BLOCK
DEFSTR (DIFLG,0,8,9) ;FLAGS
DEFSTR (DI%WRT,0,2,1) ;WRITE ACCESS ALLOWED BIT
DEFSTR (DIFIL,0,35,27) ;FILE PAGE NUMBER
DEFSTR (DIRPT,1,8,9) ;REPEAT COUNT
DEFSTR (DIPRO,1,35,27) ;PROCESS PAGE NUMBER
DEFSTR (VBTYP,0,17,18) ;ENTRY VECTOR BLOCK TYPE (=.EXENT)
DEFSTR (VBSIZ,0,35,18) ;SIZE OF ENTRY VECTOR BLOCK (=.VBSIZ)
DEFSTR (VBCNT,1,35,36) ;ENTRY VECTOR COUNT
DEFSTR (VBADR,2,35,36) ;ADDRESS OF ENTRY VECTOR
DEFSTR (EBTYP,0,17,18) ;BLOCK TYPE CODE FOR END BLOCK (=.EXEND)
DEFSTR (EBSIZ,0,35,18) ;SIZE OF END BLOCK
.DISIZ==2 ;SIZE OF DESCRIPTORS
.EBSIZ==1 ;SIZE OF END BLOCK
.VBSIZ==4 ;SIZE OF ENTRY VECTOR BLOCK
; DEFAULT SIZE AND ADDRESS OF ENTRY VECTOR IN DUMP FILE
EVADR==140 ;DEFAULT STARTING ADDRESS
EVLEN==1 ;DEFAULT LENGTH OF VECTOR
;RH11 EXTERNAL PAGE DEFINITIONS
R0%CS1==1776700 ;CONTROL AND STATUS 1
R0%WC==1776702 ;WORD COUNT REGISTER
R0%BA==1776704 ;UNIBUS ADDRESS REGISTER
R0%DA==1776706 ;DESIRED SECTOR/TRACK ADDRESS REGISTER
R0%CS2==1776710 ;CONTROL AND STATUS 2
R0%DS==1776712 ;DRIVE STATUS REGISTER
R0%ER1==1776714 ;ERROR REGISTER 1
R0%AS==1776716 ;ATTENTION SUMMARY REGISTER
R0%DT==1776726 ;DRIVE TYPE REGISTER
R0%SN==1776730 ;SERIAL NUMBER REGISTER
R0%DC==1776734 ;DESIRED CYLINDER REGISTER
R0%ER2==1776740 ;ERROR REGISTER 2
R0%ER3==1776742 ;ERROR REGISTER 3
;SECOND RH11 DEFINITONS
R1%CS1==3772440 ;CONTROL AND STATUS 1
R1%WC==3772442 ;WORD COUNT REGISTER
R1%BA==3772444 ;UNIBUS ADDRESS REGISTER
R1%DA==3772446 ;DESIRED SECTOR/TRACK ADDRESS REGISTER
R1%CS2==3772450 ;CONTROL AND STATUS 2
R1%DS==3772452 ;DRIVE STATUS REGISTER
R1%ER1==3772454 ;ERROR REGISTER 1
R1%AS==3772456 ;ATTENTION SUMMARY REGISTER
R1%DT==3772466 ;DRIVE TYPE REGISTER
R1%SN==3772470
R1%DC=3772472 ;DESIRED CYLINDER REGISTER
R1%ER2==3772474 ;ERROR REGISTER 2
R1%ER3==3772476 ;ERROR REGISTER 3
;
; DEVICE BIT DEFINITIONS FOR RH11
RH.NED==1B23 ;NON EX DISK
RH1SC==100000 ;SPECIAL CONDITIONS
RH1TRE==040000 ;TRE ERROR
RH1RDY==000200 ;READY
RH1IE==000100 ;INTERRUPT ENABLE
RH1CLR==000040 ;CLEAR CHANNEL
RPPGSZ==2000 ;PAGE SIZE FOR 11 TRANSFER
UNBMP0==1763000 ;ADDRESS OF UNIBUS MAP
UNBMP1==3763000 ;UNIBUS MAP
UNVBIT==40000 ;VALID BIT FOR UNIBUS
UN36B==100000 ;36 BIT TRANSFER MODE
;
; TTY DEFINITIONS
;
CTYIRD=1B27 ;INPUT READY
CTYIWD=32 ;ADDRESS OF INPUT WORD
CTYORD=1B27 ;OUTPUT READY
CTYOWD=33 ;OUTPUT WORD
KLIOWD=35 ;KLINIK OUTPUT WORD
RELWD=31 ;RELOAD WORD
RLFLGS=1B34 ;FLAGS THAT CAUSE RELOADS AND DUMPS
RSFLGS=1B32 ;RESTART FLAG
CTIRDY=00200 ;RECEIVE READY
CTORDY=100000 ;TRANSMIT READY
CTYIST=760010 ;STATUS REGISTER
CTIDAT=760012 ;INPUT BUFFER
CTYLPR=760012 ;LINE PARAMETER REGISTER
CTYTCR=760014 ;TRANSMIT CONTROL
CTODAT=760016 ;OUTPUT DATA BUFFER
CTYCLR=20 ;RESET DZ11
CTYSCE=40 ;ENABLE SCANNER
CTYBUD=17270 ;9600 BAUD 1 STOP BIT
IFN KCFLG,<
KCIOPG==1000 ;VIRTUAL/PHYSICAL ADDRESS OF IO PAGE
;Offsets in the IO page
KCCOMB==:400 ;START OF COMM REGION
KCSTS==400 ;OFFSET FOR KC STATUS WORD
KCPACT==1B35 ;KEEP-ALIVE BIT FOR THE KC
RSSTS==402 ;OFFSET FOR RSP STATUS
.RSKAC==1 ;COMMUNICATIONS ACTIVE IF SET
RSCMDW==420 ;DIAGNOSTIC COMMAND WORD FOR CONSOLE
DCDATA==:MASKB(0,27) ;DATA FOR DIAGNOSTIC COMMAND
DCCODE==:MASKB(28,35) ;CODE FOR DIAGNOSTIC COMMAND
.RSINI==13 ;INIT COMMUNICATIONS WITH THE CONSOLE
.RSCTT==14 ;CONTROL TERMINAL (MASK IN DCDATA)
.RSLNK==40 ;1B22 IN DCDATA INDICATES LINK REMOTE TO HARD COPY
.RSHRD==1 ;1B27 IN DCDATA INDICATES ENABLE HARD COPY
.RSFLO==16 ;FLUSH OUTPUT (LINE NUMBER IN DCDATA)
RSRSPW==422 ;DIAGNOSTIC COMMAND STATUS (1B0 SET WHEN DONE)
.RSRME==1B29 ;REMOTE/APT ENABLED
.RSHCE==1B30 ;HARD COPY TERMINAL ENABLED
ICYSTS==430 ;INPUT STATUS WORD FOR HARD COPY (1B0 SET WHEN DATA PRESENT)
OCYSTS==440 ;OUTPUT STATUS FOR HARD COPY (1B0 SET WHEN DATA PRESENT)
.RSOCT==:MASKB(4,10) ;OUTPUT BYTE COUNT
IDATA==450 ;INPUT DATA BLOCK (4 WORDS)
KCOUTS==:600 ;OUTPUT DATA BLOCK (4 WORDS)
KCCOME==:777 ;END OF COMM REGION
;NOTE:The output data block can be anywhere. This location was picked for
;convenience and could become invalid if the protocol changes.
> ;END IFN KCFLG
;MACRO TO PERFORM IO OPERATIONS - USE IS INDEPENDENT OF WHICH DISK
; MACRO DEFINITION FOR RH20
DEFINE IOOP(OP,OPR)
<IFIDN <OP><CLEAR>,<
CALL IOXCT
CONO .-.,2000
CALL IOXCT
CONO .-.,5610
> ;END IFIDN CLEAR
IFIDN <OP><SKIPNOERR>,<
CALL IOXCT
CONSZ .-.,RHERR ;RH ERROR BITS
> ;END IFIDN SKIPNOERR
IFIDN <OP><XCTOP>,<
CALL IOXCT
DATAO .-.,OPR ;EXECUTE OP
> ;END IFIDN XCTOP
IFIDN <OP><SKIPDONE>,<
CALL IOXCT
CONSO .-.,.RHDON ;SKIP IF DONE
> ;END IFIDN SKIPDONE
> ;END DEFINE IOOP
;AC USAGE
F==0 ;FLAGS
T1=1 ;GP TEMP
T2=2 ; ...
T3=3 ; ...
T4=4 ; ...
Q1=5 ;GENERALLY HOLDS A SINGLE CHARACTER
Q2=6 ;BYTE POINTER TO AN INPUT STRING
Q3=7 ;BYTE POINTER TO AN OUTPUT STRING
P1=10 ;OFTEN PRESERVED
P2=11 ; ..
P3=12 ;A NUMBER
P4=13 ;DESTINATION POINTER (DISK ADDR, BYTE PTR)
P5=14 ;DISK ADDRESS OR PARSER STATE
P6=15 ;DEVICE TYPE INDEX
TM.IDX==0 ;TM02/TM03
DA.IDX==1 ;DX20 FOR TAPES
T8.IDX==2 ;TM78
DB.IDX==3 ;DX20 FOR RP20 DISKS
CX=16 ;RETURN ADDRESS FOR VBOOT ENTRY FROM MONITOR
; NO INTERNAL BOOT CODE MUST USE THIS AC!!!
P=17 ;STACK POINTER
;BIT ALLOCATION IN F
F.WRIT==1B0 ;WRITE FILE IF ON
F.PHYS==1B1 ;PHYSICAL ADDRESSES IF ON, VIRTUAL IF OFF
F.CLR==1B2 ;CLEAR CORE IF ON
F.STRT==1B3 ;START AFTER LOAD IF ON
F.ACT==1B4 ;SOME ACTION REQUEST IF ON
F.BACK==1B5 ;BACKUP SCANNER IF ON
F.OUT==1B6 ;THIS STATE HAS PRODUCED OUTPUT IF ON
F.DUMP==1B7 ;DUMP VS SAVE IF ON
F.EDDT==1B8 ;LOAD AND START AT LOCATION 141
F.ALL==1B9 ;LOAD ALL PAGES FROM 0 TO VFREE
F.NCHL==1B10 ;DON'T USE .JBSYM TO CHANGE PAGE LIMITS
F.INFO==1B11 ;DISPLAY PROGRAM INFORMATION
F.DPER==1B16 ;DUMP ERROR - FILE TOO SMALL
F.IOER==1B17 ;IO ERROR DURING DUMP
;BITS PROVIDED BY KLINIT ON A SPECIAL LOAD CONDITION
F11.LD==1B0 ;DO DEFAULT LOAD
F11.DM==1B1 ;DO DUMP OF CORE
;START LOCATION FOR /E
ELOC==141
NDMPM==^D50 ;MAXIMUM NUMBER OF DUMP PAGE-WRITE FAILURES WE WILL REPORT
;FDB STRUCTURE DEFINITIONS (MOST ARE IN PROLOG)
DEFSTR (FBCTL,.FBCTL,35,36) ;CONTROL BITS FROM FDB
DEFSTR (FBBYV,.FBBYV,35,36) ;POINTER TO PAGE COUNT WORD
;PHYSICAL CORE PARAMETERS
;HOW MANY MEGS CAN WE DUMP?
;NMEG = INTEGRAL MEGS,,FRACTIONAL MEGS (# 1/4 MEGS)
NMEG=3,,0
IFN SMFLG,<NMEG=1,,0>
;NOTE: This number represents 512K because we have no support for NXM on
;the KC yet, and we don't want to try to dump non-existent memory.
IFN KCFLG,<NMEG=0,,2>
NCSTPG==<<<NMEG>&<-1,,0>>*4>_-22+<<NMEG>&<0,,-1>>
;NUMBER OF CST PAGES - THIS DETERMINES THE
; MAXIMUM AMOUNT OF CORE THAT CAN BE DUMPED
;100 IS A SAFE NUMBER FOR ANY SIZE MACHINE.
; 1 CST PAGE = 256K CORE = 1000^D8 PAGES
; 4 CST PAGES = 1 MEG
PHYPAG== <NCSTPG*1000>-1 ;HIGHEST PHYSICAL PAGE WE CAN DUMP
PHYADR== PHYPAG*1000 ;ADDRESS OF HIGHEST PHYSICAL PAGE WE CAN DUMP
;STORAGE ALLOCATION - *NOTE* ADDRESSES USED ARE ALL VIRTUAL!
; THE ORDER OF THESE CANNOT BE CHANGED INDISCRIMINATELY
IFN BDEBUG,<
LOC 74
DDTPRE ;Address of DDT preamble
RELOC
>
;PAGES USED FOR BOOT. ALLOCATION IS DONE UPWARD FROM VORG (HIGHER TO
; LOWER ADDRESSES).
;WHEN DONE, VFREE IS THE LAST FREE PAGE BEFORE BOOT BEGINS.
DEFINE PG(ADDR,SIZE<1>),<
VFREE==VFREE-<SIZE> ;;MOVE FREE PAGE DOWN BY REQUIRED PAGES
ADDR==<VFREE+1>_9 ;;THEN DEFINE DESIRED ADDRESS
>
VORG==777 ;LAST PAGE USED BY BOOT
VFREE==VORG ;INITIALIZE LAST FREE PAGE
PHYORG==VORG+1 ;FIRST PHYSICAL PAGE BEYOND VORG (ASSUMED TO
;BE 1'ST PAGE IN PHYSICAL REGION ABOVE VBOOT'S
;VIRTUAL REGION)
A$CODE==5 ;# Code pages allocated
PG A%CODE,A$CODE ;Code pages
A%CODE==A%CODE ;Get value in listing
PG A%FP0 ;FILE PAGE ZERO WINDOW
A%FP0==A%FP0 ;Get value in listing
PG A%XB ;INDEX BLOCK BUFFER
A%XB==A%XB ;Get value in listing
PG A%SXB ;SUPER INDEX BLOCK BUFFER
A%SXB==A%SXB ;Get value in listing
PG A%CST,NCSTPG ;CORE STATUS TABLE PAGES
A%CST==A%CST ;Get value in listing
PG A%PTB ;PAGE TABLE PAGE
A%PTB==A%PTB ;Get value in listing
PG A%EPT ;EXEC PROCESS TABLE
A%EPT==A%EPT ;Get value in listing
PG A%DPG ;DIRECTORY HEADER PAGE
A%DPG==A%DPG ;Get value in listing
PG A%DIR ;DIRECTORY DATA PAGE
A%DIR==A%DIR ;Get value in listing
A%VFST==<VFREE+1>_9 ;ADDRESS OF FIRST VBOOT PAGE
A%VORG==VORG_9 ;ADDRESS OF LAST VBOOT PAGE
A%DATA==A%CODE ;LOCATION WHERE DATA GOES
VFREE==VFREE ;FORCE VALUE OF VFREE INTO LISTING
A%POST==750000 ;ASSUMED VALUE OF A%VFST IN POSTLD
IF2,<IFL A%VFST-A%POST,<PRINTX %** A%VFST CHANGED, POSTLD MUST BE EDITED **>>
;If the above message occurs, the value of A%VFST in POSTLD must be
;changed to be .LE. the value in this assembly. A%POST above must
;be changed to be the same as the value put in POSTLD so that
;the check here will continue to work.
;Debugging definitions
DBG2==MOVAC+MVCLEN ;Breakpoint in AC for moving code
DBG3==A%CODE+TOP2-ENT-1000 ;This is the location for the final breakpoint
;before VM is turned on
DDTADR==501000 ;DDT load address
DDTPRE==DDTADR-1000 ;DDT preamble code
;O is the relocation value for relocating symbols under timesharing
;(Only useful if older KDDT or user DDT is used)
O==ENT-A%FP0
DEFINE ALLOC(VAR,SIZ)
<VAR=A.DATA
IFNB <SIZ><A.DATA==A.DATA+SIZ>
IFB <SIZ><A.DATA==A.DATA+1>
>
A.DATA==A%DATA ;INITIALIZE COUNTER
;NOTE -- DATA BETWEEN Z.STRT AND Z.END GETS ZEROED ON EACH COMMAND
Z.STRT==A.DATA
ALLOC(ISTRNG) ;INPUT STRING POINTER SAVE VARIABLE
ALLOC(START) ;STARTING ADDRESS
;DO NOT REORDER THE FOLLOWING WITHOUT CHANGING DEFAULT PROCESSING
DEFBEG==A.DATA ;BEGINNING OF DEFAULTED AREA
ALLOC(FILSTR) ;POINTER TO FILE NAME STRING
ALLOC(DIRSTR) ;POINTER TO DIRECTORY STRING
ALLOC(EXTSTR) ;POINTER TO FILE EXTENSION STRING
ALLOC(VERSTR) ;POINTER TO VERSION STRING
ALLOC(SWSTR) ;POINTER TO SWITCH STRING
ALLOC(UBSTR) ;POINTER TO UPPER BOUND STRING
ALLOC(LBSTR) ;POINTER TO LOWER BOUND STRING
ALLOC(DIRTMP) ;POINTER TO SUBDIRECTORY STRING
DEFEND==A.DATA-1 ;END OF DEFAULTED DATA AREA
;END OF DO NOT REORDER
ALLOC(D$FIL,8) ;STRING STORAGE FOR FILE NAME
ALLOC(D$DIR,8) ;STRING STORAGE FOR DIR NAME
ALLOC(D$TMP,8) ;STRING STORAGE FOR SUBDIRECTORY NAME
ALLOC(D$EXT,8) ;STRING STORAGE FOR EXTENSION STRING
ALLOC(D$VER,2) ;STRING STORAGE FOR VERSION STRING
ALLOC(D$SW,2) ;STRING STORAGE FOR SWITCH STRING
ALLOC(D$ISTR,^D25) ;STRING STORAGE FOR INPUT STRING
ALLOC(D$UB,2) ;STRING STORAGE FOR UPPER BOUND STRING
ALLOC(D$LB,2) ;STRING STORAGE FOR LOWER BOUND STRING
ALLOC(VERNUM) ;VERSION NUMBER OF FILE
ALLOC(LWRLIM) ;LOWER PAGE LIMIT FOR GET/SAVE
ALLOC(UPRLIM) ;UPPER PAGE LIMIT FOR GET/SAVE
ALLOC(FNDSTR) ;STRING POINTER TO CURRENT NAME STRING
; DO NOT CHANGE THE ORDER OF THE FOLLOWING TWO WORDS
ALLOC(FNDSTE) ;STRING POINTER TO CURRENT EXT
ALLOC(FNDSTV) ;CURRENT VERSION NUMBER
; ***** NOTE WELL ***** FNDSTE MUST BE FOLLOWED IMMEDIATELY BY
; FNDSTV BECAUSE THEY ARE STORED USING A
; DMOVEM INSTRUCTION IN ROUTINE GETIDX !
;DISK DEPENDENT DATA
;DO NOT REORDER WITHOUT CHANGING SWPMON
ALLOC(MAXUNI) ;LARGEST LOGICAL UNIT IN STR
;END OF DO NOT REORDER
ALLOC(FNDCMD) ;BYTE POINTER TO INITIAL TYPEIN
ALLOC(DEV) ;POINTER/ SIXBIT DEVICE NAME
Z.END==A.DATA-1
; FOLLOWING LOCATIONS NOT CLEARED ON EACH COMMAND
DSKSIZ==^D8 ;Max logical units in a structure
NCHAN==^D8 ;Max physical channels
ALLOC(FILPAG) ;PAGE # READ FROM FILE
ALLOC(STRNAM) ;SIXBIT NAME OF FS OR DEV (I.E. MT:)
ALLOC(CURNAM) ;STR NAME BOOT IS CURRENTLY LOOKING AT
ALLOC(DSKTYP) ;UNIT TYPE FOR DISK STRUCTURES
TAPTYP==DSKTYP ;UNIT TYPE FOR TAPES
ALLOC(NUMCYL) ;NUMBER OF CYLINDERS PER UNIT FOR THIS TYPE
ALLOC(DSKTAB,DSKSIZ) ;LOGICAL/PHYSICAL MAPPING
;Disk format is: flag+chan,,unit
;Tape format is: flag,,cckkuu
; cc = 6bit channel
; kk = 6bit controller
; uu = 6bit unit
ALLOC(IVRTAB,DSKSIZ) ;IVIR contents for each chan of structure
ALLOC(PIATAB,DSKSIZ) ;PI assignment for each chan of structure
ALLOC(CURPAG) ;CURRENTLY MAPPED DIRECTORY PAGE
; ** CAUTION: DO NO INITIALIZE TO 0 **
ALLOC(DIORG) ;HOLDS DISK INDEX ORIGIN
ALLOC(XBNUM) ;-1 FOR SHORT FILE, XB # OF MAPPED XB
; IF THIS FILE IS A LONG FILE
ALLOC(MAXCOR) ;MAX CORE AVAILABLE
IFN FT.MTA,<ALLOC(DIRFLG)> ;NON-ZERO IF EXE DIRECTORY HAS BEEN READ
ALLOC(LODBAS) ;START OF SOURCE AREA (SEE DIAGRAMS)
ALLOC(LODTOP) ;END OF SOURCE AREA
ALLOC(TOPBAS) ;START OF TARGET AREA (SEE DIAGRAMS)
ALLOC(TOPTOP) ;END OF TARGET AREA
ALLOC(LODTYP) ;TYPE OF MONITOR LOAD: 0,DEFAULT - NO OPR COMMAND
ALLOC(MCSPAG) ;STARTING MICROCODE PAGE
; THIS PAGE ALSO CONTAINS THE BOOT MOVING CODE
ALLOC(MCEPAG) ;ENDING MICROCODE PAGE
ALLOC(DXAMCV) ;WORD TO HOLD DXMCA MCODE VERSION
ALLOC(DXBMCV) ;WORD TO HOLD DXMCB MCODE VERSION
ALLOC(NOLDDX) ;NON-ZERO IF WE DON'T LOAD DX20 MICROCODE
ALLOC(DERCNT) ;COUNT OF REPORTED DUMP ERRORS
ALLOC(CHAN) ;Current channel
ALLOC(UNIT) ;Current unit (current controller for tapes)
ALLOC(CYLIND) ;Cylinder # of current DSK transfer
ALLOC(SECTRK) ;Sector and track of current DSK transfer
ALLOC(RHCMD) ;Command for current RH transfer
ALLOC(PASS) ;INDICATES WHICH PASS OF UNIT-SEARCH CODE
IFN BDEBUG,<
ALLOC (EDDBLK,100) ;Reserve breakpoint block for KDDT
ALLOC (MONPDV,1) ;Allocate dummy pointer to PDV
INTERN EDDBLK,MONPDV ;Now, make them global
>
ALLOC(MONLOD) ;0 = LOADING RESIDENT MONITOR
;N = N'TH PASS LOADING SWAPABLE MONITOR
ALLOC(PORTLK) ;0= can't lock this device
;-1 = lock port on this device
ALLOC(PFLAGS) ;PROGRAM FLAGS SAVE-WORD
ALLOC(DEXEPC) ;DUMP.EXE DISK PAGE COUNT
ALLOC(PGCNT) ;IF DUMPING:
; COUNT OF CORE PAGES WRITTEN TO DUMP.EXE
ALLOC(DIRST) ;Working byte-pointer to directory string
ALLOC(ZOOT,5) ;THIS IS TO PUT SOME SPACE BETWEEN THE PDL AND
;LODTYP. WITH ALL THE -N(P) ACCESS I SUSPECT
;A BUG IN SOME OF THEM BUT CAN'T PROVE IT.
; NON-0, PROMPT AND TAKE OPR COMMAND
PDLEN==35 ;PUSH DOWN STACK SIZE
ALLOC(PDL,PDLEN) ;PUSH DOWN STACK
ALLOC (DTCNOW) ;ALLOCATE CONO WORD
ALLOC(APRSER) ;CPU SERIAL NUMBER
ENTFLG==400000 ;ENTRY IN USE FLAG IN DSKTAB
ICCW==20
LCORAD==24 ;LOWEST CORE ADDR DUMPED/LOADED
TIMLOC==23 ;LOCATION OF TIME BASE
N.BKPG==4
N.SCL3==^D148 ;SECTORS PER CYL (RM03)
N.SCL4==^D380 ;SECTORS PER CYL (RP04/RP05/RP06)
N.SCL7==^D1376 ;SECTORS PER CYL RP07
N.CLP3==^D820 ;CYLS PER UNI (RM03)
N.CLP4==^D400 ;CYLS PER UNI (RP04/5)
N.CLP6==^D800 ;CYLS PER UNI (RP06)
N.CLP7==^D629 ;CYLS PER UNI (RP07)
N.STK3==^D30 ;SECTORS PER TRACK (RM03)
N.STK7==^D43 ;SECTORS PER TRACK (RP07)
N.STK4==^D20 ;SECTORS PER TRACK (RP04)
;GLOBALS FOR THE REST OF THE MONITOR
VBSTRT==:A%DIR ;START OF VBOOT PRIVATE AREA
VBEPT==:A%EPT ;WHERE VBOOT EXPECTS EPT TO BE MAPPED
VBEND==:A%VORG ;VBOOT ITSELF
VBDDAT==:DIORG ;START OF VBOOT DISK DATA AREA
;Lower core locations are in PROLOG
IFE FT.PRT,<END> ;END HERE IF SYMBOLS-ONLY ASSEMBLY
;LOCATIONS IN DIR AREA
DIRNUM==A%DIR+2 ;DIR NUMBER
SYMBOT==A%DIR+3 ;BOTTOM OF ST AREA
SYMTOP==A%DIR+4 ;TOP OF ST AREA
HOMNAM==A%FP0+200+0 ;SIXBIT /HOM/
HOMID==A%FP0+200+1 ;PACK ID
HOMSNM==A%FP0+200+3 ;STRUCTURE NAME
HOMLUN==A%FP0+200+4 ;# UNI IN STR,,THIS UNI #
HOMRXB==A%FP0+200+10 ;ROOT INDEX BLOCK
HOMSER==A%FP0+200+164 ;APR SERIAL NUMBER
HOMCOD==A%FP0+200+176 ;FUNNY CODE
CODHOM==707070 ;TYPE CODE FOR HOME BLOCK
; EXEC PROCESS TABLE LOCATIONS
EPTEST==540 ;INDEX TO EXEC SECTION TABLE
EPTATR==421 ;INDEX TO ARITHMETIC TRAP INSTRUCTION
EPTPDO==422 ;INDEX FOR PDL OVERFLOW
EPTSPT==760 ;INDEX TO SPT (ONE WORD TABLE FOR VBOOT)
IFN KCFLG,<
EPTSSP==520 ;SUPER SECTION TABLE POINTER (KL COMPATIBLE MODE)
> ;END OF IFN KCFLG
;UPT DEFINITIONS
IFN KLFLG!SMFLG,<
UPTPFW==500 ;PAGE FAIL ADDRESS
UPTPFN==503 ;INDEX TO PAGE FAIL WORD
UPTPFO==502 ;PAGE FAIL PC WORD
>
IFN KCFLG,<
KCPFOF==456 ;OLD FLAGS WORD
KCPFOP==457 ;OLD PC WORD
KCPFNF==460 ;NEW FLAGS WORD
KCPFNP==461 ;NEW PC WORD
>
; OPDEF FOR STORING VALUES IN PAGER REGISTERS
OPDEF XCTU [XCT 4,0] ;PXCT DEFINITION
;OTHER OPDEFS
OPDEF CLRPT [701100,,0] ;CLEAR PAGING MEMORY
; PAGER REGISTERS
IFN KLFLG,<
CSTMSK==0 ;CST MASK, ANDED WITH CST ENTRY
CSTDTA==1 ;CST DATA, IORED WITH CST ENTRY
CSTADR==2 ;CST BASE ADDRESS
SPTADR==3 ;SPT BASE ADDRESS
> ;END OF IFN KLFLG
;ERROR MESSAGE MACRO
DEFINE $ERROR (CODE,ADDR)
< JRST [MOVEI Q2,CODE
IFB <ADDR>,<JRST ERRTYP>
IFNB <ADDR>,<JRST ADDR>
]
>
IFN FT.PRT&1,<
; ***** MAIN ENTRY POINT AND INITIALIZATION *****
;THE FRONT END AND BOOT:
; 1. ON AN AUTO-RELOAD (ALIAS "SPECIAL" LOAD):
; A. FRONT END SETS IN AC0:
; 1. 1B0 - NO PROMPTING
; 2. 1B1 - DUMP
; 3. B2-B35 - ZERO
; B. FRONT END STARTS BOOT AT ENT+1
;
; 2. ON A DIALOG-LOAD (ALIAS "DEFAULT" LOAD, "MANUAL" LOAD, ETC):
; A. FRONT END DOES NOT TOUCH AC0
; B. FRONT END STARTS BOOT AT ENT
; SET UP RELOCATION CONSTANT IN ACCUMULATOR 16
ENT:
IFN KLFLG!KCFLG,<
;This constitutes BOOT's "entry-vector".
;@SET ENTRY-VECTOR 40000 3 allows I VER to identify
;the version # of BOOT.EXE under timesharing
TDZ F,F ;DIALOGUE LOAD ALWAYS IF STARTED HERE
SKIPA ;SPECIAL LOAD. PRESERVE BITS
BYTE (3)V%WHO(9)V%MAJOR(6)V%MINOR(18)V%EDIT
> ;END IFN KLFLG!KCFLG
;Do I/O reset.
CONO APR,AP.RES ;IOB RESET - CLEAR I/O DEVICES
;Turn off paging and traps. Declare EPT address to be 0.
IFN KLFLG,<
CONI PAG,15 ;GET CURRENT STATE OF PAGER
ANDI 15,PGCLKE!PGCLDE ;CLEAR ALL BUT CACHE STRATEGY BITS
> ;END IFN KLFLG
IFN SMFLG,<
MOVEI 15,PGKLMD ;SM10 REQUIRES KL PAGE FOR TRAPS
> ;END IFN SMFLG
IFN KLFLG!SMFLG,<
CONO PAG,0(15) ;TURN OFF PAGING
> ;END IFN KLFLG!SMFLG
IFN KCFLG,<
MOVSI 15,(PGLTPE) ;LOAD TRAP ENABLE BIT, WHICH TURNS OFF TRAPS
WREBR 15 ;TURN OFF PAGING
> ;END IFN KCFLG
;Figure out where we landed and determine offset for self-relocating code.
MOVSI 17,(<JRST (16)>) ;RETURN INST
JSP 16,17 ;GET CURRENT PC
SUBI 16,.-ENT ;RETURN HERE
;16 NOW CONTAINS RUNTIME ORIGIN OF BOOT
AND F,[F11.DM!F11.LD]-ENT(16) ;SAVE ONLY DEFINED BITS
;Set up the UPT and EPT to be the same page, starting at the end of the
;code. Point to a page fault handler. AC 15 contains control bits used in
;previous CONO PAG/WREBR.
MOVEI T1,PAGTRP-ENT(16) ;THE PAGE FAULT HANDLER
IFN KLFLG!SMFLG,<
MOVEM T1,CODEND-ENT+UPTPFN(16) ;SET UP TEMPORARY EPT/UPT
>
IFN KCFLG,<
MOVEM T1,CODEND-ENT+KCPFNP(16) ;POINT TO TEMPORARY PAGE FAULT HANDLER
MOVEI T1,MONFLG ;NEW FLAGS WORD
MOVEM T1,CODEND-ENT+KCPFNF(16) ;SAVE IT IN THE UPT
>
MOVEI T1,CODEND-ENT(16) ;GET LOCAL ADDRESS OF EPT (END OF CODE)
LSH T1,-11 ;MAKE IT A PAGE NUMBER
IOR 15,T1 ;ADD PAGE NUMBER TO THE CONTROL BITS
IFN KLFLG!SMFLG,<
CONO PAG,0(15) ;MAKE EBR POINT TO THAT PAGE
TDO T1,[1B2+1B18]-ENT(16) ;AND SET UBR AND INHIBIT METER UPDATE
> ;END OF IFN KLFLG!SMFLG
IFN KCFLG,<
WREBR 15 ;DECLARE EPT ADDRESS
TLO T1,(PGLUBR!PGNSAC) ;LOAD UBR, AND INHIBIT ACCOUNTING UPDATES
> ;END OF IFN KCFLG
DATAO PAG,T1 ;MAKE UBR POINT TO ITS PAGE
; DETERMINE HIGHEST PHYSICAL CORE ADDRESS .LE. 256K
;On the KC, we assume all 256K is there. This is guaranteed by the console.
IFN KCFLG,<
MOVEI P1,777000
> ;END OF IFN KCFLG
IFN KLFLG!SMFLG,<
J1: CONO APR,AP.RNX ;ENABLE PAGE-FAIL INTERRUPTS FOR APR AT LEVEL 0
MOVEI P1,777000 ;START AT PAGE 512
FNDCOR: SKIP 20(P1) ;REFERENCE PAGE
TSTCOR: CONSO APR,AP.NXM ;NXM?
JRST GOTCOR-ENT(16) ;NO, NOW HAVE HIGEST ADDR
J2: CONO APR,AP.RNX ;NXM - RESET
SUBI P1,1000 ;TRY NEXT LOWER PAGE
JUMPN P1,FNDCOR-ENT(16) ;LOOP
HALT .-ENT(16) ;INTERLEAVE PROBABLY BAD
> ;END OF IFN KLFLG!SMFLG
; MOVE DISK SEARCH CODE TO TOP OF CORE WHILE MOVING TOP TO BOOTS OLD PLACE
;***NOTA BENE - P MUST REMAIN PRESERVED UNTIL FNDDEV!!
;ARRIVE HERE WITH P1 CONTAINING HIGHEST CORE ADDR .LE. 256K
GOTCOR:
IFN SMFLG,< ;DBE SCAN FOR KS ONLY; -11 DOES KL
MOVEI T1,20 ;WHERE TO START TESTING CORE
DBESCN: MOVE T2,0(T1) ;DO DBE SCAN TO INITIALIZE MEMORY
MOVEM T2,0(T1) ;INCASE OF POWERFAIL (BLT WON'T WORK)
CAIE T1,777(P1) ;LAST WORD? (AOBJN WON'T WORK)
AOJA T1,DBESCN-ENT(16) ;NO, LOOP OVER ALL LOW CORE THERE
> ;END SMFLG CONDITIONAL
;Exchange BOOT code pages with monitor pages at high end of memory
MOVAC==1 ;AC TO LOAD MOVING CODE INTO
HRRI P5,MOVAC ;PUT CODE IN T1
HRLI P5,BOTMOV-ENT(16) ;GET BOOT MOVING CODE
BLT P5,T1+MOVEND-BOTMOV ;MOVE MOVING CODE TO AC'S
HRRZI P2,A%VFST-A%CODE+1000(16) ;WHERE WE START MOVING FROM
;P2 POINTS TO SOURCE AREA (SEE DIAGRAMS)
MOVEM P2,P ;SAVE OLD BASE
HRRZI P3,A%VFST-A%VORG(P1) ;WHERE WE ARE MOVING IT TO
;P3 POINTS TO TARGET AREA (SEE DIAGRAMS)
HRRZI P4,1000+A%VORG-A%VFST ;NUMBER OF WORDS TO MOVE (ROUND PAGES)
DBG1: JRST T1 ;MOVE THE CODE
;Here when code is moved to high end of memory. Paging is still off
;AC contents:
; P1/ address of first word in highest existing page .LE. 777
; P/ Address of first word of first page moved from low end of core
CORMVD: HRRZI 16,A%CODE-1000-A%VORG(P1) ;COMPUTE NEW BASE OF CODE
MOVE P5,P1 ;SAVE ADR OF HIGHEST PHYSICAL PAGE
; CLEAR AND SET UP EXEC PAGE TABLE (EPT)
SUBI P1,A%VORG-A%EPT ;MOVE BASE TO START OF EPT
MOVEI T1,1(P1) ;BUILD BLT POINTER
HRL T1,P1 ; ...
SETZM 0(P1) ;CLR FIRST WORD
BLT T1,777(P1) ;TO END OF EPT
;Prepare to handle traps. Ignore arithmetic overflow. For the KC, trap PDL overflow.
;On the KL, a zero will be executed
IFN KLFLG!SMFLG,<
MOVSI T1,(<JFCL>) ;NO-OP ARITH TRAP INST
> ;END OF IFN KLFLG!SMFLG
IFN KCFLG,<
MOVSI T1,(TRNOP) ;INDICATE IGNORE ERROR
> ;END OF IFN KCFLG
MOVEM T1,EPTATR(P1) ;STORE IN EPT
IFN KCFLG,<
MOVEI T1,PDOVFL
HRLI T1,(TRMON) ;TRAP TO MONITOR IF ERROR OCCURS
MOVEM T1,EPTPDO(P1) ;STORE IN EPT
> ;END OF IFN KCFLG
;POINT TO THE NEXT PAGE FAULT HANDLER
MOVEI T1,PFAIL ;THE NEXT PAGE FAULT HANDLER
IFN KLFLG!SMFLG,<
MOVEM T1,UPTPFN(P1) ;TO THE UPT
>
IFN KCFLG,<
MOVEM T1,KCPFNP(P1)
MOVEI T1,MONFLG ;NEW FLAGS WORD
MOVEM T1,KCPFNF(P1) ;SAVE IT IN THE UPT
> ;END OF IFN KCFLG
;Save page number for combined UPT/EPT
MOVE P2,P1 ;COPY EPT BASE ADR
LSH P2,-9 ;GET PHYS PAGE #
; SET UP EXEC SECTION TABLE AND 1-WORD SPT IN EXEC PAGE TABLE
MOVEI T1,A%PTB-A%EPT(P1) ;GET PHYSICAL ADDRESS OF PAGE TABLE
LSH T1,-^D9 ;CONVERT TO PAGE #
MOVEM T1,EPTSPT(P1) ;SAVE 1-WORD SPT
MOVSI T1,(FLD(SHRCOD,PTRCOD)!PTWR) ;SHARE POINTER, WRITE, SPT INDEX=0
MOVEM T1,EPTEST(P1) ;SAVE SECTION PTR TO PAGE TABLE
IFN KCFLG,<
MOVSI T1,(KLPTR) ;KL COMPATIBLE MODE
MOVEM T1,EPTSSP(P1) ; INTO SUPER SECTION POINTER
> ;END OF IFN KCFLG
; MOVE BASE POINTER TO PAGE TABLE PAGE
ADDI P1,A%PTB-A%EPT ;CHANGE BASE TO PHYS ADDRESS OF A%PTB
; FORM AOBJN POINTER FOR LOOPING THROUGH PAGE TABLE
IFN KLFLG!SMFLG,<
MOVEI T2,A%DIR-A%PTB(P1) ;PHYSICAL ADDRESS IN RH OF T2
LSH T2,-9 ;CONVERT TO # OF DIRECTORY PAGE A%DIR
HRLI T2,-< <VORG-A%DIR_-9>+1 > ;NUMBER OF PAGES TO MAP
; MAP PAGES USED BY VBOOT
MOVEI T1,A%DIR_-9(P1) ;START MAPPING AT DIRECTORY AREA
IFN BDEBUG,<
;EDDT NEEDS TO BE MAPPED WHEN BOOT GOES MAPPED.
;EDDT DOES NOT NORMALLY GET MAPPED INTO BOOT SPACE. IF YOU WANT TO DEBUG WITH
;EDDT AFTER BOOT GETS TO FNDDEV YOU NEED TO ADD THE FOLLOWING INSTRUCTIONS.
;THEY WILL CAUSE ALL OF THE FIRST 512 PHYSICAL PAGES TO APPEAR IN PAGE MAP
;**NOTA BENE - THE PATCH IS FOR SYSTEMS WITH 512K OR MORE ONLY.
HRLZI T2,-1000 ;DO THE WHOLE MAP PAGE
MOVE T1,P1 ;START AT LOCATION ZERO
>
> ;END IFN KLFLG!SMFLG
;On the KC, map the whole section. This will guarantee that the IO
;page is mapped.
IFN KCFLG,<
HRLZI T2,-1000 ;DO THE WHOLE MAP PAGE
MOVE T1,P1 ;START AT LOCATION ZERO
> ;END IFN KCFLG
;HERE WE PUT THE N PAGES OF THE TARGET AREA (SEE DIAGRAMS)
;IN THE PAGE MAP
SETPTB: HRRZ T3,T2 ;GET PHYSICAL ADR OF PAGE
TXO T3,IMMPTR ;FORM AN IMMEDIATE POINTER
MOVEM T3,(T1) ;STORE PAGE TABLE ENTRY
ADDI T1,1 ;POINT TO NEXT PAGE TABLE ENTRY
AOBJN T2,SETPTB-ENT(16) ;GO MAP REMAINING PAGES
; SET UP CST ENTRIES FOR ALL PHYSICAL CORE NOW. KC DOESN'T REQUIRE THIS
;BECAUSE CST BASE REGISTER IS SET TO 0
ADDI P1,A%CST-A%PTB ;CHANGE BASE POINTER TO CST PAGE
IFN KLFLG!SMFLG,<
MOVE T1,P1 ;SET ALL SLOTS
HRLI T1,-<NCSTPG*1000> ;ONE PAGE WORTH
MOVE T3,[1B5+1B18]-ENT(16) ;GET A NON-ZERO CST CODE FIELD & Write bit
SETCST: MOVEM T3,(T1) ;STORE A CST ENTRY
AOBJN T1,SETCST-ENT(16) ;LOOP TILL ALL CST ENTRIES SET UP
>
;Do DATAO PAG to point to the UPT. Make UPT and EPT be the same page.
;For the KL, also set previous AC block to 6 in order to initialize hardware
;tables.
TLO P2,(PGLUBR) ;LOAD UBR
; * * *
;This appears unnecessary.
; * * * *
MOVE P3,P2 ;SAVE PAGER WORD TO STORE LATER
IFN KLFLG!SMFLG,<
HRLI P2,(PGLACB!PGLUBR!FLD(HWRACB,PGPACB)!FLD(MONACB!PGCACB))
> ;END OF IFN SMFLG!KLFLG
IFN KCFLG,<
;* * * *
;May want to select ac blocks here, too
; * * * *
HRLI P2,(PGLUBR)
>
J3: DATAO PAG,P2 ; AND LOAD THE UBR
;Tell the hardware where things are, like the CST, SPT, etc.
IFN SMFLG!KCFLG,<
HRRZI T1,A%EPT-A%CST+EPTSPT(P1) ;GET PHYS ADR OF SPT
WRSPB T1 ;SET UP SPB
WRCSTM [77B5+1B18]-ENT(16) ;CST MASK REGISTER
> ;END IFN SMFLG!KCFLG
IFN SMFLG,<
WRCSB P1 ;SET UP CST BASE REGISTER
>
IFN KCFLG,<
WRCSB [0]-ENT(16) ;IGNORE THE CST
>
IFN SMFLG,<
MOVEI T1,400 ;SET UP HALT STATUS BLOCK
WRHSB T1
>
IFN KLFLG,<
HRRZI T1,A%EPT-A%CST+EPTSPT(P1) ;GET PHYS ADR OF SPT
XCTU [MOVEM T1,SPTADR]-ENT(16) ;STORE SPT BASE ADDRESS IN PAGER AC 3
XCTU [MOVEM P1,CSTADR]-ENT(16) ;STORE CST BASE ADDRESS IN PAGER AC 2
MOVE T1,[77B5+1B18]-ENT(16) ;Get CST mask reg
XCTU [MOVEM T1,CSTMSK]-ENT(16) ;STORE CST MASK VALUE IN PAGER AC 0
> ;END IFN KLFLG
;Do CONO PAG to turn on traps and paging. Use the same address for the EPT
;as for the UPT
IFN KLFLG!SMFLG,<
TRO P2,PGKLMD!PGTPEN ;TRAP EN AND KL PAGING
> ;END IFN KLFLG!SMFLG
IFN KCFLG,<
HRLI P2,(PG20MD!PGENPG!PGLTPE!PGENTP) ;KL PAGING, ENABLE TRAPS
>
IFN KLFLG,<
CONI PAG,T1 ;GET PAGER BITS AGAIN
ANDI T1,PGCLKE!PGCLDE ;PRESERVE CACHE BITS
IOR P2,T1 ;ADD IN CACHE BITS
> ;END IFN KLFLG
IFN KLFLG!SMFLG,<
DMOVE T1,[ CONO PAG,(P2) ;LOAD EBR
JRST FNDDEV ]-ENT(16) ;GO SET UP LOW CORE MAP
>
IFN KCFLG,<
DMOVE T1,[ WREBR P2 ;LOAD EBR
JRST FNDDEV ]-ENT(16) ;GO SET UP LOW CORE MAP
>
TOP2: JRST T1 ;AND TURN THE PAGING ON
LIT
IFGE .-ENT-141,<PRINTX ?NO ROOM FOR INITIAL UPT>
BLOCK 1000-<.-ENT> ;RESERVE REST OF PAGE FOR THE EPT/UPT
BLOCK A.DATA-A%DATA ;MAKE ROOM FOR ALLOCATED VARIABLES
;Here when paging is turned on.
CODE:
PHASE A.DATA
IFN KLFLG,<
FNDDEV: MOVEM F,LODTYP ;SAVE STARTING FLAGS FROM KLINIT
TXNE F,F11.DM ;DUMPING?
SETOM NOLDDX ;YES, DON'T LOAD DX20 MICROCODE
TXNE F,F11.LD ;AUTO-RELOADING?
SETZM NOLDDX ;YES, RELOAD DX20 EVEN IF DUMPING
>
IFN KCFLG,<
;Initialize the console communications region of the IO page
FNDDEV: MOVEI T1,KCIOPG ;GET ADDRESS OF IO PAGE
HRRI T2,KCCOMB+1(T1)
SETZM -1(T2) ;ZERO FIRST WORD
HRLI T2,KCCOMB(T1) ;GET START OF AREA
BLT T2,KCCOME(T1) ;CLEAR COMM REGION
MOVEI T2,KCOUTS(T1) ;GET OUTPUT DATA BLOCK
MAP T2,0(T2) ;GET PHYSICAL ADDRESS
ANDX T2,PHCPNO!PGWD ;25 BITS OF ADDRESS
MOVEM T2,OCYSTS(T1) ;SAVE IT
;Signal the console to initialize communication. Wait for it to complete.
MOVEI T2,.RSINI ;GET FUNCTION CODE TO INITIALIZE
MOVEM T2,RSCMDW(T1) ;STORE COMMAND
SETZM RSRSPW(T1) ;CLEAR RESPONSE WORD
RINGBW CNPRT ;RING BELL AND WAIT A BIT
NOP ;??
SKIPL T2,RSRSPW(T1) ;HAVE RESPONSE YET?
JRST .-1 ;NO
;If the remote line is enabled, link it to the hard copy
TXNN T2,.RSRME ;IS REMOTE LINE ENABLED?
JRST FNDDE1 ;NO. DON'T DO ANYTHING
MOVX T2,FLD(.RSLNK,DCDATA)!FLD(.RSCTT,DCCODE)
MOVEM T2,RSCMDW(T1) ;STORE IN DIAGNOSTIC COMMAND WORD
SETZM RSRSPW(T1) ;CLEAR RESPONSE WORD
RINGBW CNPRT ;RING BELL AND WAIT A BIT
NOP ;??
SKIPL RSRSPW(T1) ;HAVE RESPONSE YET?
JRST .-1 ;NO
FNDDE1:
> ;END IFN KCFLG
IFN SMFLG,<
FNDDEV:
>
;Save some info about the memory ranges that have been affected.
MOVEM P,LODBAS ;SAVE START ADDRESS OF SOURCE AREA (SEE DIAGRAMS)
MOVEI P,<1000+A%VORG-A%VFST>-1(P) ;SAVE END OF SOURCE AREA
MOVEM P,LODTOP ;LAST ADDRESS MOVED
HRRZI P,A%VFST-A%VORG(P5) ;TOP ADDRESS ROUNDED TO PAGES
MOVEM P,TOPBAS ;SAVE START ADDRESS OF TARGET AREA (SEE DIAGRAM)
MOVEI P5,777(P5) ;SET UP TOP OF SAVED FOR THE SAVE
MOVEM P5,TOPTOP ;SAVE END OF TARGET AREA
IFN SMFLG,<
;INTERIM PROTECTION AGAINST CONFUSING THE FRONT END WITH KLINIK OUTPUT
SETZM KLIOWD ;CLEAR THE KLINIK OUTPUT WORD
>
; CODE TO MAP LOW CORE USING KL STYLE PAGING
;* * * *
;Need to work on this when the KC supports NXM. For now, assumes success
; * * * *
MOVEI P1,A%PTB ;GET ADDRESS OF PAGE TABLE PAGE
SETZB P2,P3 ;P2=VIRTUAL, P3=PHYSICAL PAGE #
SETEPT:
IFN KLFLG!SMFLG,<
CONO APR,AP.RNX ;RESET NXM FLAG
> ;END IFN KLFLG!SMFLG
MOVE T1,P3 ;GET PHYSICAL PAGE NUMBER
TXO T1,FLD(IMMCOD,PTRCOD)!PTWR ;IMMEDIATE POINTER, WRITE ACCESS
MOVEM T1,(P1) ;PUT ENTRY INTO PAGE TABLE
MOVE T1,P2 ;GET VIRTUAL PAGE #
LSH T1,^D9 ;CONVERT PAGE # TO ADDRESS
J4: CLRPT 0(T1) ;CLEAR THE ENTRY FIRST
SKIP 20(T1) ;TRY TO REFERENCE VIRTUAL PAGE
TSTMEM:
IFN KLFLG!SMFLG,<
CONSZ APR,AP.NXM ;NXM OCCUR ?
JRST SETEP1 ;YES, TRY NEXT PHYSICAL PAGE
> ;END IFN KLFLG!SMFLG
;Step to next virtual page, and next page slot
ADDI P1,1 ;NO, NEXT PAGE TABLE SLOT
ADDI P2,1 ;NEXT VIRTUAL PAGE #
CAILE P2,VFREE ;MAP JUST UP TO OURSELF
JRST SETEP2 ;IF DONE, GO SET UP DTE20
;Step to next physical page
SETEP1: ADDI P3,1 ;NEXT PHYSICAL PAGE #
CAMG P3,[PHYPAG] ;DONE ALL OF CORE?
JRST SETEPT ;NO, GO DO NEXT PAGE
IFN KCFLG,<
SETEP2:
>
IFN KLFLG,<
SETEP2:
;Defend against memory parity errors in 20-23 (20 is the location
;of our channel-command list [+ 4-word fetch]) caused by the channel
;referencing these locations on a freshly-powered up machine in which
;these locations may "appear" to have parity errors
SETZM 20 ;WIPE OUT PARITY ERRORS
MOVE T1,[20,,21] ;ZERO WHOLE AREA
BLT T1,23 ;DO IT
SETZM DTEFLG ;CLEAR DONE FLAG
SETZM DTEMTI ;INITIALIZE INPUT READY FLAG
MOVSI T1,-DTEN ;SCAN ALL AVAILABLE DTE'S
MOVE T2,[CONSO DTE,DTEPRV] ;LOOK FOR MASTER
MOVE T3,[CONSO DTE,PI0ENB+7] ;LOOK FOR ANY PI ASSIGNMENT
MOVE Q1,[CONO DTE,0] ;PROTOTYPE CONO
SETEP3: XCT T3 ;A PI ASSIGNMENT UP?
JRST [ HRRI Q1,PIENB+PI0ENB ;NO. TRY TO SET IT
XCT Q1
XCT T3 ;NOW SET?
JRST SETEP5 ;NO. NON-EXISTANT DEVICE THEN
TRZ Q1,PI0ENB ;YES. TURN IT OFF
XCT Q1 ;DO IT
JRST .+1] ;AND PROCEED
XCT T2 ;THIS IT
JRST [ MOVEI T1,0(T1) ;YES. GET DTE NUMBER
LSH T1,^D26 ;POSITION FOR CONO
ADD T1,[CONO DTE,0(Q1)] ;PROTOTYPE WORD
MOVEM T1,DTCNOW ;SAVE IT
JRST SETEP4] ;DONE
SETEP5: ADD T2,[4B11] ;NEXT DTE
ADD T3,[4B11]
ADD Q1,[4B11] ;ADJUST ALL I/O INSTRUCTIONS
AOBJN T1,SETEP3 ;NOPE. LOOK AT NEXT
HALT . ;NOT THERE. CAN'T HAPPEN
SETEP4: MOVEI Q1,.DTMMN ;MONITOR MODE ON
MOVEM Q1,DTECMD ; STORE IN COMMAND
J5: MOVEI Q1,TO11DB ;RING THE BELL
XCT DTCNOW ;DO IT
J6: SKIPN DTEFLG ;WAIT FOR COMPLETION
J7: JRST .-1 ; ...
> ;END IFE SMFLG
IFN SMFLG,<
SETEP2:
;MAP AND SCAN THE REST OF MEMORY TO BE SURE IT IS INITIALIZED
DBEPGA=1000 ;USE PAGE ONE FOR MEM SCAN MAPPING
MOVE T4,A%PTB+<DBEPGA/1000> ;PICK UP A MAP SLOT TO USE
MOVEI P3,1000 ;[137]START SCAN AT PAGE 1000
MAPDBE: CONO APR,AP.RNX ;RESET NXM FLAG FOR TESTS
MOVE T1,P3 ;GET PHYSICAL MEMORY PAGE NUMBER
TXO T1,1B2!1B4 ;MAKE IMMEDIATE POINTER, WRITABLE
MOVEM T1,A%PTB+<DBEPGA/1000> ;SET THE POINTER IN THE MAP
CLRPT DBEPGA ;CLEAR THE PAGER
SKIP DBEPGA ;REFERENCE THE PAGE
CONSZ APR,AP.NXM ;NXM RESULT?
JRST MAPDB1 ;YES, DON'T BOTHER WITH THE SCAN
MOVE T1,[-1000,,DBEPGA] ;GET AOBJN POINTER TO PAGE
DBEMSC: MOVE T2,0(T1) ;SCAN PAGE, CLEARING DBE/ECC ERRORS
MOVEM T2,0(T1) ;(BLT DOESN'T WORK)
AOBJN T1,DBEMSC ;LOOP FOR ALL OF PAGE
MAPDB1: ADDI P3,1 ;NEXT PAGE
CAIGE P3,NCSTPG*1000 ;DONE ALL POSSIBLE CORE?
JRST MAPDBE ;NO, DO NEXT PAGE
MOVEM T4,A%PTB+<DBEPGA/1000> ;RESTORE THE OLD MAP SLOT
CLRPT DBEPGA ;AND CLEAR THE PAGER FOR IT AGAIN
HRRZ F,RELWD ;GET RELOAD WORD
MOVEM F,RELWD ;STOP KEEPALIVE IF UNDERWAY
TRNE F,RLFLGS ;CHECK FOR RELOAD FLAGS
MOVE F,[F11.DM!F11.LD]
TRNE F,RSFLGS
MOVE F,[F11.LD]
MOVEM F,LODTYP
> ;END IFN SMFLG
MOVEM P5,MAXCOR ;SAVE MAX CORE AVAILABLE
SETOM CURPAG ;INITIALIZE CURRENTLY IN-CORE DIR PAGE
IFN KLFLG,<
;HERE TO CALCULATE LENGTH OF THE DX20 MICROCODE
MOVEI T1,DXASA ;GET START OF FIRST MICROCODE MODULE
TRO T1,777 ;GET PAGE ADDR + 777
MOVEM T1,MCSPAG ;SAVE STARTING MICROCODE PAGE
; NOTE THAT THIS PAGE BEGINS WITH THE BOOT
; MOVING CODE
MOVEI T1,DXASA ;GET START OF FIRST MICROCODE MODULE
ADDI T1,DXASZ+DXBSZ-1 ;ADD LENGTH OF EACH MICROCODE MODULE
IFN FTKLIPA,< ADDI T1,KLPLEN+NILEN> ;KLIPA, KLNI MICROCODES TOO
TRO T1,777 ;GET PAGE ADDR + 777
MOVEM T1,MCEPAG ;SAVE ENDING MICROCODE PAGE
MOVE T1,DXASA ;GET DXA MCODE VERSION
MOVEM T1,DXAMCV ;SAVE IT
MOVE T1,DXBSA ;GET DXB MCODE VERSION
MOVEM T1,DXBMCV ;SAVE IT
>
;When debugging, handle traps for real
IFN BDEBUG,<
MOVE T1,[JSP T1,TRAP] ;Setup EPT trap locations
MOVEM T1,A%EPT+420
MOVEM T1,A%EPT+421
MOVEM T1,A%EPT+422
MOVEM T1,A%EPT+423
JRST RSTART ;Enter program proper
TRAPPC:
;Here on a trap
TRAP: MOVEM T1,TRAPPC ;Save it here
MOVE P,PDP ;Get us a stack
MOVEI Q2,[ASCIZ/?****TRAP AT /]
CALL OUTSTR ;Output it
MOVE Q2,TRAPPC ;Get flags+PC
CALL OUTOCT ;Output it
MOVEI Q2,[ASCIZ/
/]
CALL OUTSTR
JRST RSTART ;Reenter program
> ;End IFN BDEBUG conditional
;DISPLAY PROGRAM VERSION
RSTART: MOVE P,PDP ;SETUP PDL
CALL CRLF ;...
MOVEI Q2,[ASCIZ/BOOT V/]
CALL OUTSTR ;...
CALL TYPBVR ;OUTPUT BOOT VERSION
GETCM1: SETZM DSKTAB ;MAKE SURE THIS IS ZERO
SETZM MONLOD ;INDICATE FIRST INVOCATION OF VBOOT
IFE FT.MTA,<MOVSI T1,'PS '> ;DISK DEFAULT DEVICE
MOVEM T1,STRNAM ;STORE THE DEFAULT NAME
BLKI APR,T1 ;GET CPU SERIAL NUMBER
IFN KLFLG,< ANDI T1,7777> ;IF KL
IFN KCFLG,<ANDI T1,777777> ;NOTE: T2 IS CLOBBERED!
IFN SMFLG,<ANDI T1,77777> ;IF KS
MOVEM T1,APRSER ;STORE SERIAL NUMBER
;Here to prompt for input
GETCOM: SETZM CX ;INDICATES WE ARE ENTERING VBOOT FROM BOOT
MOVE P,PDP ;SETUP PDL
MOVE T1,[Z.STRT,,Z.STRT+1] ;CLEAR DATA AREA
SETZM Z.STRT
BLT T1,Z.END
SETOM MAXUNI ;THIS MEANS WE HAVE NOT FOUND DEVICE, YET
SKIPE LODTYP ;DIALOGUE LOAD?
JRST GETCO1 ;YES, DON'T PROMPT, DON'T TAKE OPR COMMAND
CALL CRLF ;DO RETURN
IFE FT.MTA, <
MOVEI Q2,[BYTE (7)"B","O","O","T",76,0]
>
IFN FT.MTA, <
MOVEI Q2,[BYTE (7)"M","T","B","O","O","T",76,0]
>
CALL OUTSTR ;OUTPUT PROMPT
GETCO1: CALL GETSTR ;GET COMMAND FROM OPERATOR
MOVEM T1,FNDCMD ;SAVE COMMAND POINTER
SETZ P2, ;WHERE TO FORM STRUCTURE NAME
SKIPN T1,DEV ;DEVICE TYPED?
JRST [ SKIPE DSKTAB ;NO. ALREADY HAVE A DEVICE?
JRST FOUND ;YES. USE IT THEN
JRST DVX1] ;NO. GO FIND THWE DEFAULT
MOVE T2,[POINT 6,P2] ;PTR TO NAME
MOVEI T3,6 ;MAX # CHARS
DEVNAM: ILDB T4,T1 ;GET CHAR
CAIN T4,":" ;END OF NAME?
JRST DEVX ;YES - PUNT
SUBI T4,40 ;CONVERT TO SIXBIT
IDPB T4,T2 ;STORE CHR
SOJG T3,DEVNAM ;LOOP
DEVX: CAMN P2,STRNAM ;SAME STRUCTURE AS LAST TIME?
SKIPN DSKTAB ;YES, FOUND DEVICES YET?
SKIPA ;NO. MUST LOOK THEN
JRST FOUND ;YES, GO DO COMMAND
MOVEM P2,STRNAM
DVX1: MOVE T1,[DSKTAB,,DSKTAB+1] ;SET UP TO CLEAR DSKTAB
SETZM DSKTAB ;CLEAR FIRST WORD OF TABLE
BLT T1,DSKTAB+DSKSIZ-1 ;CLEAR DISK TABLE
SETZM PASS ;INDICATE PASS 1 OF UNIT-SEARCHING CODE
IFN FT.MTA,<SETZM DIRFLG> ;MAKE IT READ DIRECTORY AGAIN
SETZM DSKTYP ;INDICATE UNIT TYPE UNKNOWN
IFN FT.MTA, <
;REMOVE THIS CROCK
;THIS TEST IS INSERTED HERE TO MAKE DEFAULT AND SPECIAL LOADS FROM
; MAG TAPE WORK APPROXIMATELY THE SAME AS FOR DISK, AND TO PROVIDE
; FOR ANY POSSIBLE FUTURE CHANGE TO VBOOT WHEREIN A MAGTAPE DEVICE
; IDENTIFIER OTHER THAN "MT:" WILL BE ACCEPTED, AND ACTED UPON.
; MOVSI T1,'MT ' ;GET MAG TAPE DEVICE NAME
; CAME T1,STRNAM ;CORRECT DEVICE ENTERED ?
; JRST FDSK ;NO, GO ISSUE ERROR MESSAGE
; JRST FTAP ;GO FIND READY TAPE DRIVE
JRST FTAP ;GO FIND READY DRIVE
> ; END OF IFN FT.MTA
IFE FT.MTA, <
JRST FDSK ;GO FIND STRUCTURE
> ; END OF IFE FT.MTA
;SUBROUTINE TO LOCATE UNIT CONTAINING STRUCTURE TO BOOT FROM
;ON A SPECIAL LOAD, WE CAN PASS THROUGH THIS CODE TWICE:
;1. SEARCH FOR A PACK WHOSE APR SERIAL NUMBER MATCHES OUR CPU.
; IF A MATCH IS FOUND, LOAD FROM THAT PACK.
;2. IF #1 FAILS, SEARCH FOR STRUCTURE PS: AND LOAD FROM THAT PACK.
;
; ON THE FIRST PASS, IF WE NOTICE WE HAVE A DX20, WE LOAD AND START IT.
; EVERY CHANNEL AND UNIT ON THE SYSTEM IS CHECKED.
IFE FT.MTA, <
FDSK: SETZM CHAN ;Init the channel #
SETZM UNIT ;Init the unit #
SETZM DIORG ;INITIALIZE DIRECTORY ORIGIN
MAP T1,A%FP0 ;GET PHYS ADDR OF FP0
TLZ T1,777760 ;KEEP JUST THE ADDRESS BITS
TLO T1,(<1B0+1B1+<1000B13>>) ;DATA XFR, LAST CCW, # OF WORDS
MOVEM T1,ICCW ;STORE
FDSK1:
MOVE T1,[1B1+ICCW] ;GET JUMP CCW
MOVE T2,CHAN ;GET CHANNEL NUMBER
LSH T2,2 ;GET CHANNEL*4
MOVEM T1,A%EPT+ICA(T2) ;STORE INITIAL CCW FOR RH20
SETZM UNIT ;START AT UNIT 0
CALL CHKCHN ;THIS CHANNEL EXIST ?
JRST FDSK2 ;YES, GO CHECK ITS UNITS
JRST FDSK4 ;NO, GO TRY NEXT CHANNEL
FDSK2: CALL CHKUNI ;THIS UNIT EXIST ?
JRST GOTDRV ;YES, GO SEE IF AN RP04
FDSK3: AOS T1,UNIT ;Get next unit number
CAIG T1,MAXDRV ;CHECKED ALL DRIVES YET ?
JRST FDSK2 ;NO GO CHECK NEXT DRIVE
FDSK4: AOS T1,CHAN ;Get next channel
CAIG T1,MAXCHN ;CHECKED ALL CHANNELS YET ?
JRST FDSK1 ;NO, GO DO NEXT CHANNEL
JRST FDSK5 ;YES, CHECK FOR ALL UNITS PRESENT
GOTDRV: ANDI T2,R4%TYP ;KEEP JUST THE DEVICE TYPE CODE
IFN FT.DX2,<
PUSH P,T2 ;SAVE THIS AC
SKIPN PASS ;SKIP IF NOT FIRST PASS
CALL LODX20 ;LOAD MICROCODE IF THIS IS A DX20
POP P,T2 ;RESTORE THE AC
>
SKIPG T1,DSKTYP ;DISK TYPE KNOWN YET?
JRST GOTDV3 ;NO - SEE IF ANY OF ALLOWED TYPES
CAMN T2,T1 ;YES - IS THIS UNIT SAME AS DESIRED?
JRST GOTDV0 ;YES - USE IT
CAIN T1,.R4TYP ;IS DESIRED TYPE RP04?
CAIE T2,.R5TYP ;YES - IS THIS UNIT AN RP05?
JRST FDSK3 ;NO TO EITHER QUESTION
IFN SMFLG,<
GOTDV0: MOVEI T1,R4%CPA!GO ;PACK ACK
WRIO T1,@RPCS1(P1) ;DO IT
RDIO T1,@RPDS(P1) ;READ THE DEVICE STATUS REGISTER
> ; END IFN SMFLG
IFE SMFLG,<
GOTDV0: MOVE T1,[R4%CSR!LR!R4%CPA!GO] ;PACK ACKNOWLEDGE, SETS VV BIT
CALL RHWT1 ;GO DO THE DATAO
MOVSI T1,(.TMDSR) ;READ DEVICE STATUS REGISTER
CALL RHRD1 ;GET IT
> ; END IFE SMFLG
TRNN T1,TMSMOL ;IS IT POWERED UP WITH A PACK ON-LINE?
JRST FDSK3 ;NO. FORGET IT
MOVE T1,[A%FP0,,A%FP0+1] ;SET UP FOR BLT
SETZM A%FP0 ;CLEAR FIRST WORD OF DATA PAGE
BLT T1,A%FP0+777 ;ZERO DATA PAGE PRIOR TO READ
CALL RD0 ;GO READ PAGE 0
CALL CHKHOM ;GO CHECK THE HOME BLOCK
JRST GOTDV2 ;NO GOOD, TRY BACKUP HOME BLOCK
GOTDV1: SKIPG T2,DSKTYP ;IS TYPE KNOWN YET?
MOVNS T2,DSKTYP ;NO - MAKE THIS TYPE THE DESIRED TYPE
MOVEI T1,N.CLP4 ;COMPUTE NUMBER OF CYLINDERS PER UNIT
CAIE T2,.R4TYP ;RP04?
MOVEI T1,N.CLP6 ;NO - ASSUME RP06
CAIN T2,.R3TYP ;RM03?
MOVEI T1,N.CLP3 ;YES
CAIN T2,.R7TYP ;RP07?
MOVEI T1,N.CLP7 ;YES
MOVEM T1,NUMCYL ;SAVE RESULT
JRST FDSK3 ;OK, GO CHECK NEXT UNIT
GOTDV2: CALL RD10 ;GO READ BACKUP HOME BLOCK
MOVE T1,[A%FP0,,HOMNAM] ;MOVE DATA TO WHERE THE CHKHOM
BLT T1,HOMCOD ; ROUTINE WANTS IT TO BE
CALL CHKHOM ;GO CHECK THE BACKUP HOME BLOCK
JRST FDSK3 ;ERROR
JRST GOTDV1 ;SETUP TYPE/SIZE IF NEEDED AND GO ON
;HERE IF DESIRED UNIT TYPE IS NOT KNOWN YET. CHECK TYPE AGAINST ALL
;KNOWN DISK TYPE UNITS.
GOTDV3: CAIN T2,.R3TYP ;RM03?
JRST GOTDV4 ;YES
CAIE T2,.R6TYP ;RP06?
CAIN T2,.R4TYP ;OR RP04?
JRST GOTDV4 ;YES - SAVE TYPE NEGATED
CAIN T2,.R7TYP ;RP07?
JRST GOTDV4 ;YES
CAIE T2,.R5TYP ;RP05?
JRST FDSK3 ;NO - TRY FOR NEXT UNIT
MOVEI T2,.R4TYP ;YES - MAKE IT LOOK LIKE RP04
GOTDV4: MOVNM T2,DSKTYP ;SAVE NEGATED TYPE IN CASE HOME BLKS GOOD
JRST GOTDV0 ;AND TRY TO READ HOME BLOCKS
FDSK5: SKIPL T1,MAXUNI ;NO - CHECK FOR FULL DECK
JRST CHKSTR ;HAVE FOUND SOME UNITS
SKIPE DEV ;HAVE WE CHECKED A STRUCTURE NAME?
;STRUCTURE NOT FOUND - CHECK THE CONTEXT
JRST [SKIPE PASS ;PASS 1?
$ERROR(STRNBS) ;NO - NO BOOTABLE STRUCTURE
$ERROR(STRSNF)] ;YES - SPECIFIED OR DEFAULT STRUCTURE NOT FOUND
SETOM DEV ;GO THRU DISKS A SECOND TIME -- FOR STR NAME
SETOM PASS ;INDICATE 2'D PASS
JRST FDSK
CHKSTR: SKIPN DSKTAB(T1) ;ANY ID?
$ERROR (STRNID) ;NO STRUCTURE ID
SOJGE T1,CHKSTR ;YES - LOOP FOR OTHER UNITS
SETZM PORTLK ;ASSUME WE CAN'T DO PORT LOCKING/UNLOCKING
MOVE T1,DSKTYP ;GET DISK TYPE
CAIE T1,.R4TYP ;RP04?
CAIN T1,.R5TYP ;RP05?
SETOM PORTLK ;YES
CAIE T1,.R6TYP ;RP06?
CAIN T1,.R7TYP ;RP07?
SETOM PORTLK ;YES
JRST FOUND ;PASS COMMAND TO VBOOT
> ; END OF IFE FT.MTA
;SUBR TO CHECK IF A CHAN IS PRESENT
;RETURNS: +1 CHANNEL EXISTS
; +2 CHANNEL DOESN'T EXIST
IFE SMFLG, <
CHKCHN: MOVE T1,CHAN ;Get current channel
SETZM IVRTAB(T1) ;Assume it doesn't exist
MOVEI T1,.RHMBR ;RESET
CALL RHCO1 ;DO CONO
MOVEI T1,.RHMBE ;ENABLE
CALL RHCO1
CALL RHCI1 ;DO CONI
TRNN T1,.RHMBE ;BIT COME BACK?
RETSKP ;NO, SKIP RETURN
AND T1,[KLPMSK] ;GET BITS WHICH DEFINE A KLIPA/KLNI
CAME T1,[KLPMSK] ;IS IT A KLIPA OR KLNI?
RET ;RETURN +1, INDICATING CHANNEL EXISTS
IFE FTKLIPA,<
RETSKP ;YES. SAY CHAN DOESN'T EXIST SO UCODE WON'T GET BLOWN
>
IFN FTKLIPA,<
MOVE T2,CHAN ;Get current channel
CAIE T2,KLPCHN ;YES. WHICH?
SKIPA T2,NIPTR ;KLNI
MOVE T2,KLPPTR ;KLIPA
CALL KLPLOD ;LOAD THE CORRECT MICROCODE
RETSKP ;AND RETURN SAYING CHAN DOESN'T EXIST
> ; END IFN FTKLIPA
> ; END IFE SMFLG
IFN SMFLG, <
CHKCHN: CAIG P,MAXCHN1 ;ONLY ONE LEGAL FOR NOW
RET
RETSKP
> ; END IFN SMFLG
;SUBROUTINE TO SEE IF A UNIT EXISTS
;RETURNS: +1 UNIT EXISTS
; DEVICE BITS IN T2
; +2 UNIT DOESN'T EXIST
IFE SMFLG,<
CHKUNI: MOVSI T1,(.TMDTR) ;READ DRIVE TYPE REG
CALL RHRD1 ;...
MOVE T2,T1 ;COPY FOR RETURN
CALL RHCI1 ;SEE IF REG ACC ERR
TRNN T1,.RHRAE ; ...
RET ;ALL IS WELL
MOVEI T1,.RHRAE!.RHMBE ;CLEAR RAE, ENABLE
CALL RHCO1 ;DO CONO
JRST RSKP ;LOSE
RHRD1: TLZ T1,(LR) ;CLEAR LR BIT
RHWT1: TSO T1,UNIT ;INSERT UNIT NUMBER
CALL XIO1 ;SET IOA
DATAO .-.,T1 ;SEND TO DEVICE
CALL XIO1 ;SET IOA
DATAI .-.,T1 ;READ REG
RET
RHCI1: CALL XIO1 ;SET IOA
CONI .-.,T1 ;DO CONI
RET
RHCO1: CALL XIO1 ; SET IOA
CONO .-.,(T1) ;DO CONO
RET
XIO1: HRR F,CHAN ;Get RH #
ADDI F,RH0_-2 ;Produce device code for that RH
IOXCT: DPB F,[POINT 7,@(P),9] ;PLUG IOADDR
RET ;EXECUTE INSTR
> ;END IFE SMFLG
IFN SMFLG,<
CHKUNI: MOVEI T2,RH1CLR ;CHECK FOR NON EXIST DISK
WRIO T2,@RPCS2(P1)
WRIO P2,@RPCS2(P1) ;SELECT DISK
RDIO T2,@RPCS1(P1) ;FORCE ERROR
MOVEI T2,RH.NED ;CHECK FOR ERROR
TIOE T2,@RPCS2(P1) ;CHECK STATUS
RETSKP ;NO -- NO DISK HERE
RDIO T2,@RPDT(P1) ;YES -- GET DRIVE TYPE
RET
> ; END IFN SMFLG
IFN FT.MTA,<
FTAP:
IFN FT.DX2,<
CALL LALLDX ;LOAD MICROCODE INTO ALL DX20S
>;END IFN FT.DX2
SETZM CHAN ;Start at channel zero
SETZM UNIT ; and controller zero
GETTCH: CALL CHKCHN ;DOES THIS CHANNEL EXIST?
JRST GOTTCH ;YES - TRY UNITS
NXTTCH: AOS T1,CHAN ;No, try next channel
CAIG T1,MAXCHN ;No more channels
JRST GETTCH ;NO - TRY THIS ONE
$ERROR (TAPNDR) ;NO READY DRIVE AVAILABLE
GOTTCH: CALL CHKUNI ;GET DEV TYPE IN T2, IF EXTANT
JRST GOTTUN ;EXISTS - GO CHECK TYPE
NXTTUN: AOS T1,UNIT ;Try next controller
CAIG T1,7 ;ANY MORE
JRST GOTTCH ;YES - SEE IF THIS WINS
SETZM UNIT ;No, try next channel, starting at controller 0
JRST NXTTCH ; ...
GOTTUN: ANDI T2,777 ;ISOLATE CONTROLLER TYPE
SETZ P3, ;START AT UNIT 0
IFN FT.DX2,<
MOVEI P6,DA.IDX ;Get device index for DX20A's
CAIN T2,.DXATP ;IS THIS ONE?
JRST GOTDX2 ;YES, PROCESS IT
CAIE T2,.DXBTP ;DX20B?
JRST GOTUN1 ;No
MOVEI P6,DB.IDX ;Get device code for DX20B's
CALL STDX20 ;Restart it
JRST NXTTUN ;Check next unit
>
GOTUN1:
IFN FT.TM8,<
CAIN T2,.T8TYP ;IS IT A TM78?
JRST GOTTM8 ;YES. SEE IF THIS IS THE UNIT
>
MOVEI P6,TM.IDX ;TRY TM02/TM03
CAIL T2,10 ;SEE IF TM02
CAIL T2,17 ; ...
SKIPA ;NOT A TM02
JRST NXTTDR ;ITS A TM02
CAIL T2,50 ;SEE IF A TM03
CAIL T2,57 ; ...
JRST NXTTUN ;NOT A TM03
NXTTDR: MOVSI T1,(.TMTCR!LR) ;PREPARE TO SELECT UNIT
IOR T1,P3 ;INSERT UNIT NUMBER
IFE SMFLG,<
CALL RHWT1 ;INSERT KON, SEND TO CHN
MOVSI T1,(.TMDSR) ;READ DEVICE STATUS
CALL RHRD1 ; ...
> ;END SMFLG
IFN SMFLG,<
WRIO P2,@RPCS2(P1) ;WRITE UNIT
WRIO T1,@RPDC(P1) ;SET SLAVE
RDIO T1,@RPDS(P1) ;READ DRIVE STATUS
> ;END IFN SMFLG
TRNE T1,TMSMOL ;DEVICE READY?
JRST GOTTDR ;YES!!
AOS P3 ;NO - TRY NEXT DRIVE
CAIG P3,7 ;ANY MORE?
JRST NXTTDR ;YES
SETZ P3, ;NO - TRY NEXT KON
JRST NXTTUN ; ...
IFN FT.TM8,<
GOTTM8: MOVEI P6,T8.IDX ;SET FOR TM78
MOVEI T1,T7.SNS_6 ;DO A SENSE ON THIS SLAVE
CALL T78.ND
JUMPE T2,GOTM8A ;TIMED OUT IF 0 - TRY NEXT SLAVE
MOVSI T1,(.T7SR) ;SLAVE IS THERE, SEE IF DRIVE IS OK
CALL RHRD1
TRNN T1,T7.RDY ;IS DRIVE READY?
JRST GOTM8A ;NOPE. TRY NEXT
MOVEI T1,T7.REW_6 ;YES. REWIND IT
CALL T78.ND
JUMPE T2,GOTM8A ;LOSE IF WE TIMED OUT
T78.CK: MOVEI T1,T7.SNS_6 ;DO A SENSE
CALL T78.ND
;THIS IS AN INCREDIBLE *****CROCK****** (CATCH 78) BUT:
; THE ONLY WAY YOU CAN TELL IF A DRIVE IS REWINDING IS TO DO A SENSE
; BUT YOU CAN'T DO A SENSE IF THE DRIVE IS REWINDING - THE CONTROL JUST STACKS IT
; SO IF THE SENSE WE JUST DID TIMES OUT THE DRIVE IS REWINDING!
JUMPE T2,T78.CK ;KEEP ON CHECKING IF WE TIMED OUT
JRST GOTTD1 ;ALL IS COOL. USE THIS SLAVE
GOTM8A: CAIGE P3,3 ;DONE WITH THIS UNIT (TM78)
AOJA P3,GOTTM8 ;NO, TRY NEXT SLAVE ON THIS TM78
SETZ P3, ;YES, RESET SLAVE (UNIT) NUMBER
JRST NXTTUN ;TRY NEXT TM78 ON THIS RH20
;ROUTINE TO DO A NON-DATA FUNCTION ON A TM78/TU78
;ENTER WITH T1=FUNCTION_6, P3=UNIT
T78.ND: PUSH P,T1 ;SAVE FUNCTION
MOVEI T2,200000 ;HOW LONG TO WAIT FOR TM78 TO BECOME READY
T78.N1: MOVSI T1,(.T7TMS) ;READ THE TM78 STATUS REGISTER
CALL RHRD1
TRNN T1,T7.RDY ;IS IT WITH US?
SOJG T2,T78.N1 ;NO, TRY AGAIN
POP P,T1 ;RESTORE REAL FUNCTION
JUMPE T2,R ;RETURN IF WE TIMED OUT
ADDI T1,<(.T7ND0)>_-14(P3) ;POINT AT RIGHT REGISTER FOR THIS DRIVE
ROT T1,-6 ;BITS 0-5=REG, 33-35=FUNCTION
TLO T1,(LR) ;WRITE THE REGISTER
CALL RHWT1 ;DO IT TO IT
MOVEI T2,200000 ;LOOP COUNT
T78.N2: MOVSI T1,(.TMATR) ;WAIT FOR ATTENTION BIT TO COME UP
CALL RHRD1 ;WAIT FOR ATTENTION BIT TO COME UP
TRNN T1,377 ;ATTEN?
SOJG T2,T78.N2 ;NO, TRY AGAIN
JUMPE T2,R ;GO AWAY IF WE TIMED OUT
MOVE T2,T1 ;SAVE FUNCTION
MOVE T1,[.TMATR!LR!377] ;CLEAR THE ATTENTION BIT
CALL RHWT1
EXCH T1,T2 ;RESTORE DATA, SET T2 POSITIVE
RET ;AND GO AWAY
>
IFN FT.DX2,<
;FOUND A DX20, FIND A READY DRIVE
GOTDX2: CALL STDX20 ;START DX20 (MASSBUS RESET HALTS IT)
GTDX2A: MOVE T1,P3 ;GET DRIVE NUMBER
TXO T1,<.TDDNR!LR> ;DRIVE NUMBER REG
CALL RHWT1 ;SELECT THIS DRIVE
MOVE T1,[EXP .TMCSR!LR+.TMRWF]
CALL RHWT1 ;DO REWIND
CALL DX2SWT ;SHORT WAIT
JRST GTDX2B ;FAILED - DRIVE IS NOT READY
MOVX T1,.TDSTR ;GET THE STATUS REGISTER
CALL RHRD1 ; ...
TRNE T3,.TDDEB ;AT LOAD POINT YET?
JRST GOTTD1 ;YES
GTDX2C: CALL DX2LWT ;NO, DO A LONG WAIT
JRST GTDX2B ;ERROR, THIS DRIVE FAILS
MOVX T1,.TDAYR ;GET ASYNCHRONOUS STATUS
CALL RHRD1
TXNN T1,.TDDEB ;DEVICE END?
$ERROR (TAPHTE) ;NO - HARD TAPE ERROR
ANDI T1,377 ;JUST THE DRIVE NUMBER
CAMN T1,P3 ;RIGHT DRIVE?
JRST GOTTD1 ;YES, GOOD DRIVE
MOVX T1,.TDAYR ;NO, CLEAR ASYNCHRONOUS STATUS REG
CALL RHWT1 ; ...
JRST GTDX2C ;AND WAIT SOME MORE
GTDX2B: AOS P3 ;TRY THE NEXT DRIVE
CAIG P3,7 ;MORE DRIVES ON THIS CONTROLLER?
JRST GTDX2A ;YES
JRST NXTTUN ;NO, TO THE NEXT CONTROLLER
;ROUTINE TO LOOK FOR AND LOAD MICROCODE INTO ALL
; DX20S ON THE SYSTEM
;
LALLDX: SETZM CHAN ;Start with channel zero
SETZM UNIT ; and controller zero
LALLD1: CALL CHKCHN ;DOES THIS CHANNEL EXIST?
JRST LALLD3 ;YES, SEE IF ANY DX20S OUT THERE
LALLD2: AOS T1,CHAN ;Look at next channel
CAIG T1,MAXCHN ;LOOKED AT ALL THE CHANNELS?
JRST LALLD1 ;NO, LOOK AT NEXT CHANNEL
RET ;ALL DONE
LALLD3: CALL CHKUNI ;SEE WHAT EXISTS ON THIS CHANNEL
JRST LALLD5 ;SOMETHING THERE, GO SEE IF DX20
LALLD4: AOS T1,UNIT ;Get next controller
CAIG T1,7 ;LOOKED AT ALL CONTROLLERS?
JRST LALLD3 ;NO, LOOK AT NEXT ONE
SETZM UNIT ;Start with controller zero
JRST LALLD2 ;GO LOOK AT NEXT CHANNEL
LALLD5: ANDI T2,777 ;ISOLATE CONTROLLER TYPE
CALL LODX20 ;LOAD MICROCODE IF THIS IS A DX20
JRST LALLD4 ;GO LOOK AT NEXT CONTROLLER
>;END IFN FT.DX2
GOTTDR: MOVE T1,[EXP .TMCSR!LR+.TMRWF]
IFE SMFLG,<
CALL RHWT1 ;DO REWIND
MOVSI T2,10000 ;WAIT COUNT
CALL WTRDY1 ;WAIT FOR READY
>
GOTTD1: SETOM DIORG ;FLAG MAGTAPE
MOVEM P6,TAPTYP ;SAVE TYPE TYPE FOR LATER
SETZM MAXUNI ;HIGHEST NUMBERED UNIT
MOVE T2,CHAN ;GET CHAN
LSH T2,6 ;SHIFT
IOR T2,UNIT ;WITH KONTROLLER
LSH T2,6 ;AGAIN
IOR T2,P3 ;AND SUBUNIT
TLO T2,ENTFLG ;Say entry in use
MOVEM T2,DSKTAB ;STORE
JRST FOUND ;WIN.
WTRDY: MOVSI T2,5 ;TIMEOUT COUNTER
WTRDY1: MOVSI T1,(.TMDSR) ;WAIT FOR DRIVE READY
IFE SMFLG,<
CALL RHRD1 ; ...
> ;END IFE SMFLG
IFN SMFLG,<
WRIO T1,@RPDS(P1)
> ;END IFN SMFLG
TRNE T1,TMSPIP ; ...
SOJG T2,WTRDY1 ;TIMED LOOP
PUSH P,T1 ;SAVE STATUS REG
MOVE T1,[EXP .TMATR!LR+377] ;RESET ALL ATTENTION FLAGS
IFE SMFLG,<
CALL RHWT1 ; ...
> ;END IFE SMFLG
IFN SMFLG,<
WRIO T1,@RPAS(P1) ;WRITE ATTENTION SUMMARY
> ;END SMFLG
POP P,T1 ;RESTORE STATUS REG
SKIPN T2
$ERROR (TAPHTE) ;HARD TAPE ERROR
RET ;WIN
IFN FT.DX2,<
;DX20 WAIT ROUTINES
DX2LWT: SKIPA T2,[10000,,0] ;LONG WAIT
DX2SWT: MOVEI T2,2000 ;SHORT WAIT
DX2WAT: MOVX T1,.TMDSR ;GET THE STATUS REGISTER
CALL RHRD1 ; ...
TXNN T1,.TDATB ;ATTENTION UP?
SOJG T2,DX2WAT ;NO, WAIT
PUSH P,T1 ;SAVE THE STATUS
MOVE T1,[EXP .TMATR!LR+377]
CALL RHWT1 ;TURN OFF ATTENTION
POP P,T1 ;GET BACK THE STATUS
SKIPN T2
$ERROR (TAPHTE) ;HARD TAPE ERROR
TXNN T1,.TDCEB ;ANY ERRORS?
RETSKP ;NO, SKIP RETURN
MOVX T1,<.TMERR!LR> ;YES, CLEAR THE ERROR REGISTER
CALL RHWT1
RET ;AND GIVE AN ERROR RETURN
> ;END IFN FT.DX2
> ;END IFN FT.MTA
IFN FT.DX2,<
;ROUTINE TO CHECK FOR EITHER STYLE OF DX20, AND LOAD THE PROPER
;MICROCODE INTO IT. CALLED WITH DEVICE TYPE IN T2.
EXTERN DXASA,DXASZ ;START ADDRESS AND SIZE OF TAPE MICROCODE
IFN FT.RP2,
<
EXTERN DXESA,DXESZ ;START ADDRESS AND SIZE OF RP20 MICROCODE
>
IFE FT.RP2,
<
DXESA==0 ;PRESUMEABLY, WE HAVE NO RP20 MICROCODE,
DXESZ==1 ; SO DUMMY-UP THESE SYMBOLS
>
DXBSA==DXESA
DXBSZ==DXESZ
COMMENT \
NOTA BENE:
INTERNAL PROGRAM MNEMONICS FOR MICROCODE ARE AS FOLLOWS:
DXA... TU7X MICROCODE
DXB... RP20 MICROCODE
\
LODX20: SKIPE NOLDDX ;ARE WE CONSIDERING LOADING A DX20?
RET ;NO
SETZ P6, ;ASSUME NOT A DX20
CAIE T2,.DXATP ;TAPE STYLE DX20?
JRST NCHK ;NO
;HERE IF WE HAVE A TAPE DX20
;"TEMPORARY" RESTRICTION
MOVEI P6,DA.IDX ;YES, SET UP CODE
MOVE T1,LODTYP ;GET 11-SUPPLIED LOAD FLAGS
TXNE T1,F11.LD ;AUTO-RELOADING?
RET ;YES - DON'T RELOAD ANY TAPE DX20'S
NCHK: CAIN T2,.DXBTP ;DISK STYLE DX20?
MOVEI P6,DB.IDX ;YES, SET UP OTHER CODE
JUMPE P6,R ;RETURN IF NOT A DX20
IFE FT.RP2,
< CAIN P6,DB.IDX ;DX20B?
RET ;YES. WE HAVE NO MICROCODE, SO RETURN.
>
CALL TRYTYP ;TELL HIM WHAT WE ARE TRYING TO DO
MOVEI T1,042562 ;GET MAGIC CODE
; FOR U-CODE CONSISTENCY CHECK (TAPE ONLY)
CAIN P6,DA.IDX ;TAPE MICROCODE?
MOVEM T1,DXASA+11 ;YES, PUT INTO LOCATION 11 OF THE RAM
MOVEI Q1,DXLDFT ;SET FUNCTION TABLE
CALL LDX20 ;LOAD THE RAMS
MOVEI Q1,DXVRFT ;SET VERIFY FUNCTION TABLE
CALL LDX20 ;GO VERIFY THE WORKING MEMORY
CALL STDX20 ;START THE DX20
MOVEI Q2,[ASCIZ \[OK]
\]
CALL OUTSTR ;SAY WE DID IT
RET
;SUBROUTINE TO START THE DX20
STDX20: MOVEI T1,1+.TDICB+.TDPIB+.TDPEB ;SET STARTING ADDRESS
TXO T1,.TDPCR!LR ;INTO THE PC
CALL RHWT1
MOVEI T1,.TDSTB ;START THE DX20
TXO T1,.TDMNR!LR
CALLRET RHWT1
;SUBROUTINE TO TELL HIM WE ARE ATTEMPTING TO START THE DX20
TRYTYP: MOVEI Q2,[ASCIZ\[BOOT: STARTING\]
CALL OUTSTR
CALL TYPDX2 ;TYPE OUT DX20 AND CHANNEL NUMBERS
MOVEI Q2,[ASCIZ \MICROCODE V\]
CALL OUTSTR
MOVE T1,DXAMCV ;ASSUME DX20A
CAIN P6,DB.IDX ;DX20B?
MOVE T1,DXBMCV ;YES
CALL TMCVER ;DISPLAY THE MICROCODE VERSION
MOVEI Q2,[ASCIZ\] \] ;CLOSE THE EXPRESSION
CALL OUTSTR
RET
;LOAD FUNCTION TABLE
DXLDFT: .TDPCR!LR+.TDCIB+.TDPEB ;PC BITS FOR CRAM LOADING
RHWT1 ;CRAM FUNCTION IS WRITE
[ ;WORKING MEMORY FUNCTION
TRO T1,11400 ; SET INSTRUCTION TO MOVI TO BR WITH MA+
CALLRET XI] ; DO THE INSTRUCTION
;VERIFY FUNCTION TABLE
DXVRFT: .TDPCR!LR+.TDICB+.TDPEB ;PC BITS FOR CRAM READING
[ ;CRAM VERIFY FUNCTION
HRRZ T3,T1 ; SAVE THE EXPECTED VALUE
CALL RHRD1 ; GET CRAM CONTENTS
ANDI T1,177777 ; ONLY WANT 16 BITS
CAIN T3,(T1) ; VERIFY MATCH
RET ; MATCH, GOOD RETURN
JRST NOVERC] ; NO MATCH, TYPE ERROR
[ ;WORKING MEMORY FUNCTION
HRRZ T3,T1 ; SAVE THE EXPECTED VALUE
MOVEI T1,043411 ; INSTRUCTION TO MOVE DATA TO BR
CALL XI ; EXECUTE IT
MOVX T1,.TDIBR ; GET THE BR
CALL RHRD1 ; ...
ANDI T1,377 ; ONLY THE BR
CAIN T3,(T1) ; MATCH?
RET ; YES, GOOD RETURN
JRST NOVERW] ; NO, COMPLAIN
;LOAD OR VERIFY DX20 MICRO CODE
;CALL WITH Q1 POINTING TO FUNCTION TABLE AND P6 CONTAINING DX20 TYPE
LDX20: MOVSI T2,-DXASZ ;GET LENGTH OF TAPE MICROCODE
CAIE P6,DA.IDX ;CORRECT?
MOVSI T2,-DXBSZ ;NO, GET LENGTH OF RP20 MICROCODE INSTEAD
LDX20A: CAIE P6,DA.IDX ;TAPE MICROCODE?
SKIPA T1,DXBSA(T2) ;NO, GET CRAM WORD OF RP20 MICROCODE
MOVE T1,DXASA(T2) ;YES, GET CRAM WORD OF TAPE MICROCODE
JUMPL T1,LDX20B ;JUMP IF NO MORE CRAM DATA
HRRZ T1,T2 ;GET THE PC
IOR T1,0(Q1) ;SET DESIRED PC BITS
CALL RHWT1 ;SET THE PC
CAIE P6,DA.IDX ;TAPE MICROCODE?
SKIPA T1,DXBSA(T2) ;NO, GET RP20 CRAM DATA
MOVE T1,DXASA(T2) ;YES, GET CRAM DATA FOR TAPE
ANDI T1,177777 ;JUST THE LOW 16 BITS
TXO T1,.TDIRR!LR ;INTO THE IR
CALL @1(Q1) ;CALL THE PROCESSING ROUTINE
AOBJN T2,LDX20A ;LOOP FOR MORE
LDX20B: AOBJP T2,RSKP ;SKIP THE DELIMITER WORD
MOVEI T1,.TDICB+.TDPEB ;SET PC BACK TO 0
TXO T1,.TDPCR!LR ;PC REGISTER
CALL RHWT1
MOVX T1,.TDIRR ;GET CONTENTS OF LOCATION 0
CALL RHRD1
PUSH P,T1 ;SAVE IT
MOVEI T1,1000 ;SET MEMORY ADDRESS TO 0
CALL XI
MOVEI T1,400
CALL XI
LDX20C: CAIE P6,DA.IDX ;TAPE MICROCODE?
SKIPA T1,DXBSA(T2) ;NO, GET DATA FOR RP20
MOVE T1,DXASA(T2) ;YES, GET DATA FOR TAPE
ANDI T1,377 ;ONLY 8 BITS OF DATA
CALL @2(Q1) ;CALL PROCESSING ROUTINE
AOBJN T2,LDX20C ;LOOP THROUGH THE WHOLE THING
MOVEI T1,.TDPEB+.TDCIB ;BACK TO LOCATION 0 OF THE CRAM
TXO T1,.TDPCR!LR
CALL RHWT1
POP P,T1 ;GET BACK ITS ORIGINAL CONTENTS
ANDI T1,177777 ;ONLY 16 BITS
TXO T1,.TDIRR!LR ;PUT IT BACK INTO THE CRAM
CALLRET RHWT1
;MAKE DX20 EXECUTE INSTRUCTION IN T1
XI: PUSH P,T1 ;SAVE THE INSTRUCTION FOR A MOMENT
MOVEI T1,.TDSCB ;PUT DX20 INTO SINGLE CYCLE
TXO T1,.TDMNR!LR
CALL RHWT1
MOVEI T1,.TDPEB+.TDCIB ;SET PC 0
TXO T1,.TDPCR!LR
CALL RHWT1
POP P,T1 ;GET BACK THE INSTRUCTION
TXO T1,.TDIRR!LR ;PUT INTO CRAM
CALL RHWT1
MOVEI T1,.TDICB+.TDPIB ;TURN ON THE CRAM
TXO T1,.TDPCR!LR
CALL RHWT1
MOVEI T1,.TDSCB+.TDSTB ;CYCLE THE DX20
TXO T1,.TDMNR!LR
CALL RHWT1
MOVX T1,.TDMNR!LR ;TURN SINGLE CYCLE OFF
CALLRET RHWT1 ;AND RETURN
;COMPLAIN ABOUT A VERIFY MISMATCH
NOVERC: MOVEI Q2,[ASCIZ/CRAM VERIFY/]
JRST NOVER
NOVERW: MOVEI Q2,[ASCIZ/WORKING MEMORY VERIFY/]
NOVER: PUSH P,T1 ;SAVE A REGISTER
MOVEI Q1,"?" ;TYPE A QM
CALL TYO
CALL OUTSTR ;OUTPUT DATA
CALL CRLF ;NEXT LINE
MOVEI Q2,[ASCIZ/GOOD /]
CALL OUTSTR ;...
MOVE Q2,T3 ;FIRST WHAT IT SHOULD BE
MOVEI Q1,40 ;GET A SPACE
CALL TYO ;OUTPUT IT
CALL OUTOCT ;OUTPUT OCTAL DATA
MOVEI Q2,[ASCIZ\ BAD\] ;OUTPUT HEADING
CALL OUTSTR ;...
MOVE Q2,(P) ;GET THE BAD DATA
MOVEI Q1,40 ;GET A SPACE
CALL TYO ;OUTPUT IT
CALL OUTOCT ;OUTPUT OCTAL DATA
MOVEI Q2,[ASCIZ\ XOR\] ;OUTPUT HEADING
CALL OUTSTR ;...
POP P,Q2 ;GET THE BAD DATA
XOR Q2,T3 ;GET THE XOR
MOVEI Q1,40 ;GET A SPACE
CALL TYO ;OUTPUT IT
CALL OUTOCT ;OUTPUT THE XOR VALUE IN Q2
RET ;RETURN
;PRINT CHANNEL #, DX20 TYPE AND #
;CALL WITH :
; CHAN, UNIT set up
; P6: DX20 TYPE
TYPDX2: PUSH P,Q2 ;PRESERVE Q2
MOVEI Q2,[ASCIZ \ CHN:\]
CALL OUTSTR ;OUTPUT CHN:
MOVE Q2,CHAN ;GET CHANNEL NUMBER
CALL OUTOCT ;OUTPUT CHANNEL NUMBER
CAIN P6,DA.IDX ;TAPE DX20?
MOVEI Q2,[ASCIZ \ DX20A:\] ;YES
CAIN P6,DB.IDX ;DISK DX20?
MOVEI Q2,[ASCIZ \ DX20B:\] ;YES
CALL OUTSTR ;OUTPUT DX20:
MOVE Q2,UNIT ;GET DX20 NUMBER
CALL OUTOCT ;OUTPUT IT
MOVEI Q1," " ;A SPACE
POP P,Q2 ;RESTORE Q2
CALLRET TYO ;OUTPUT A SPACE AND RETURN
>;END IFN FT.DX2
IFN FTKLIPA,<
EXTERN KLPPTR,NIPTR,KLPVER,NIVER,KLPLEN,NILEN
;LOAD THE KLIPA MICROCODE
;CALL T2/AOBJN WORD TO PICK UP ADDRESS/WORD 1/WORD 2
KLPLOD: CALL XIO1
CONO .-.,400000
MOVE T1,UNIT ;Get unit #
MOVEI F,RH0_-2(T1) ;PRODUCE DEVICE CODE
DPB F,[POINT 7,KLPLD2,9] ;INSERT INTO DATAO'S
DPB F,[POINT 7,KLPLD3,9] ; RATHER THAN CALL XIO1 A FEW THOUSAND TIMES
DPB F,[POINT 7,KLPLD4,9] ; FOR THE SAME DEVICE CODE
DPB F,[POINT 7,KLPLD5,9]
KLPLD1: MOVE T1,(T2) ;PICK UP ADDRESS
KLPLD2: DATAO .-.,T1
KLPLD3: DATAO .-.,1(T2) ;(LH) MICROWORD
TXZ T1,1B13
KLPLD4: DATAO .-.,T1
KLPLD5: DATAO .-.,2(T2) ;(RH) MICROWORD
ADDI T2,2
AOBJN T2,KLPLD1
MOVEI Q2,[ASCIZ\[BOOT: LOADING \]
CALL OUTSTR
MOVEI Q2,[ASCIZ \KLIPA\] ;ASSUME IT'S A KLIPA
CAIE P1,KLPCHN
MOVEI Q2,[ASCIZ \KLNI\] ;BAD GUESS
CALL OUTSTR ;TELL WHAT DEVICE WE'RE LOADING
MOVEI Q2,[ASCIZ \ MICROCODE V\]
CALL OUTSTR
MOVE T1,KLPVER ;ASSUME KLIPA
CAIE P1,KLPCHN
MOVE T1,NIVER ;BAD GUESS
LOAD Q2,KLP.VR ;GET VERSION NUMBER
CALL OUTOCT ;TYPE IT
MOVEI Q2,[ASCIZ\]
\] ;CLOSE THE EXPRESSION
CALL OUTSTR
RET
>
;PAGE FAULT HANDLER
IFN KLFLG!SMFLG,<
PFAIL:
IFN BDEBUG,<JFCL> ;Call to PFERR may be patched here
AOS A%EPT+UPTPFO ;THE PC OF THE FAULT
JRST @<A%EPT+UPTPFO> ;PROCEED
> ;END IFN KLFLG!SMFLG
IFN KCFLG,<
PFAIL: AOS A%EPT+KCPFOP ;THE PC OF THE FAULT
XJRSTF <A%EPT+KCPFOF> ;PROCEED
PDOVFL: JRST 4,.
> ;END IFN KCFLG
IFN BDEBUG,<
PFERR: PUSH P,T1
PUSH P,Q1
PUSH P,Q2
PUSH P,Q3
MOVE T1,A%EPT+UPTPFW ;Get the page-fail word
TXNN T1,1B1 ;Hard page-fail?
CONSZ APR,AP.BAD ;Anything nasty happen?
SKIPA ;Yes
JRST PFERET ;No problem
MOVEI Q2,[ASCIZ/?***Page fail - Address: /]
CALL OUTSTR
MOVE Q2,TSTSLT ;Get the address
CALL OUTOCN ;Output the value
MOVEI Q2,[ASCIZ/ UPTPFW: /]
CALL OUTSTR
MOVE Q2,A%EPT+UPTPFW ;Get the word
CALL OUTOCN ;Output the value
MOVEI Q2,[ASCIZ/ CONI-APR: /]
CALL OUTSTR
CONI APR,Q2 ;Get the value
CALL OUTOCN ;Output it
MOVEI Q2,[ASCIZ/ BLKI-PI: /]
CALL OUTSTR
BLKI PI,Q2 ;Get the value
CALL OUTOCN ;Output it
CALL CRLF ;Output CRLF
SETZM A%EPT+UPTPFW ;Clear the word
CONO APR,AP.CLR+AP.BAD ;Clear the bits
PFERET: POP P,Q3
POP P,Q2
POP P,Q1
POP P,T1
RET
> ;End IFN BDEBUG
; SUBROUTINE TO CHECK STRUCTURE NAME OF PACK ON CURRENT CHANNEL AND UNIT
; RETURNS +1 NO MATCH
; +2 MATCH
; OR ERROR RETURN TO COMMAND PARSER
IFE FT.MTA,<
CHKHOM: MOVE T1,HOMNAM ;CHECK BLOCK NAME
CAME T1,[SIXBIT 'HOM']
RET ;BAD
MOVE T1,HOMCOD ;CHECK BLOCK CODE
CAIE T1,CODHOM ;...
RET ;BAD
SKIPE DEV ;WAS DEVICE STRING TYPED AT CONSOLE
JRST [MOVE T1,HOMSNM ;YES, FORGET LOOKING FOR SERIAL NUMBERS
CAME T1,STRNAM ;CHECK STRUCTURE NAME
RET ;NO MATCH
JRST CHKHM1] ;MATCH, RECORD THIS
MOVE T1,HOMSER ;GET APR SERIAL NUMBER
CAME T1,APRSER ;IS IT A MATCH?
RET ;NO
MOVE T1,HOMSNM ;GET STRUCTURE NAME
SKIPN CURNAM ;IS THIS THE FIRST TIME THRU?
MOVEM T1,CURNAM ;YES, STORE NAME
CAME T1,CURNAM ;ARE THE NAMES THE SAME
RET ;NO
CHKHM1: MOVE T1,HOMLUN ;GET LOGICAL UNIT
SKIPE DSKTAB(T1) ;IS THERE ALREADY AN ENTRY?
$ERROR(STRMTO) ;YES - MORE THAN 1 BOOTABLE STRUCTURE
MOVE T2,UNIT ;Get unit #
HRRZM T2,DSKTAB(T1) ;Store it
MOVE T2,CHAN ;Get channel #
MOVEI T2,ENTFLG(T2) ;GET CHANNEL & ENTRY-IN-USE FLAG
HRLM T2,DSKTAB(T1) ;STORE CHANNEL NUMBER
HLRZ T1,T1 ;GET # UNI IN STR
SOS T1
SKIPGE MAXUNI ;ALREADY SET?
MOVEM T1,MAXUNI ;NO - SET
CAME T1,MAXUNI ;SAME AS OTHERS?
$ERROR (STRHOM) ;BAD HOME BLOCK
MOVE T2,HOMRXB ;GET ROOT XB
SKIPN DIORG ;ALREADY SET?
MOVEM T2,DIORG ;YES - LET IT BE
CAME T2,DIORG ;SAME AS OTHER
$ERROR (STRHOM) ;BAD HOME BLOCK
> ;End IFE FT.MTA
RSKP:
CPOPJ1: AOS (P) ;SKIP RETURN
R:
CPOPJ: RET
;STRING READ FROM CONSOLE
GETSTR: MOVE Q3,[POINT 7,D$ISTR] ;OUTPUT POINTER
MOVE T1,Q3 ;SAVE - THIS IS OUR VALUE
SKIPE T2,LODTYP ;DIALOGUE LOAD? SKIP IF SO.
JRST GETST1 ;NO. GO PROCESS BITS
GET.W: CALL TYI ;READ A CHARACTER
CAIN Q1,"U"-100 ;CONTROL-U?
JRST [ MOVEI Q2,[ASCIZ/XXX/] ;YES - OUTPUT LINE DELETE PROMPT
CALL OUTSTR
JRST GETCOM] ;AND GET ANOTHER LINE
CAIN Q1,177 ;RUBOUT?
JRST [ PUSH P,T1 ;YES = START THE DELETE
LDB Q1,Q3 ;GET THE LAST CHARATER
HRROI T1,-1 ;BACKUP THE BYTE POINTER
CAME Q3,[10700,,D$ISTR-1] ;HAVE WE?
CAMN Q3,[POINT 7,D$ISTR] ;HAVE WE?
JRST [ MOVEI Q1,7 ;YES - RING THE BELL
CALL TYO ;OUTPUT THE BELL
POP P,T1
JRST GET.W] ;GET NEXT CHARACTER
ADJBP T1,Q3
CALL TYO ;OUTPUT THE CHARACTER LAST TYPED
MOVEI Q1,"\" ;AND THE BACK-SLASH
CALL TYO ;TYPE IT
MOVEM T1,Q3 ;RESET BYTE POINTER
POP P,T1
JRST GET.W] ;GET NEXT CHARACTER
CAIL Q1,140 ;LOWER CASE?
SUBI Q1,40 ;YES, MAKE UPPER
CAIN Q1,15 ;EOL?
JRST GET.EL ;YES - FINISH OUT
IDPB Q1,Q3 ;STORE CHARACTER
CAIE Q1,":" ;DEV NAME TERM?
JRST GET.W ;NO - LOOP
MOVEM T1,DEV ;YES - SET FLAG
MOVE T1,Q3 ;NEW COMMAND PTR
JRST GET.W ;LOOP FOR MORE
GET.EL: IDPB Q1,Q3 ;STORE CR
CALL CRLF ;ECHO CRLF
GET.E1: SETZI T2, ;TERMINATING NULL
IDPB T2,Q3 ; STORE
RET ;RETURN
CRLF: MOVEI Q1,15 ;CR WITH PARITY
CALL TYO ;TYPE OUT
MOVEI Q1,12 ;LF
CALLRET TYO
;KLINIT HAS REQUESTED SPECIAL LOAD. PROCESS THE BITS
GETST1: TXZE T2,F11.DM ;WANT DUMP?
JRST [ MOVE T3,[BYTE (7) "/","D",.CHCRT,0]
JRST GETST3]
TXZE T2,F11.LD ;WANT STANDARD LOAD?
JRST [ MOVE T3,[BYTE (7) .CHCRT,0]
JRST GETST3]
GETST3: MOVEM T3,D$ISTR ;STASH THE STRING
MOVEM T2,LODTYP ;STASH REMAINING FLAGS
RET ;AND DONE
IFN FT.UDB,<
;USER MODE CONSOLE DRIVERS
TYO: PUSH P,T1 ;PRESERVE T1
MOVE T1,Q1 ;COPY CHAR
PBOUT ;OUTPUT IT
POP P,T1 ;RESTORE T1
RET
TYI: PUSH P,T1 ;SAVE T1
PBIN ;READ A CHAR
CAIN T1,37 ;EOL?
MOVEI T1,15 ;YES - TURN TO CR
MOVE Q1,T1 ;RETURN IN STANDARD AC
POP P,T1 ;RESTORE T1
RET
> ;END IFN FT.UDB
.DTTYO==10B27 ;FUNCTION CODE FOR TYPE OUT, CHAR IN LOW BITS
.DTMMN==11B27 ;FUNCTION CODE FOR MONITOR MODE ON
;EPT LOCS
DTEFLG=A%EPT+444 ;OPERATION COMPLETE FLAG
DTEF11=A%EPT+450 ;PDP11 TO PDP10 ARGUMENT
DTECMD=A%EPT+451 ;-10 TO -11 COMMAND WORD
DTEOPR=A%EPT+453 ;OPERATION IN PROGRESS FLAG
DTEMTD==A%EPT+455 ;MONITOR OUTPUT DONE WHEN NONZERO
DTEMTI==A%EPT+456 ;0 IF READY FOR ANOTHER CHAR FROM 11
DTEN==4 ;NUMBER OF DTE'S
;DTE20 HARDWARE
DTE==200 ;DEVICE CODE
DTEPRV==1B20 ;PRIVILEGED/RESTRICTED BIT IN CONI
PI0ENB==1B32 ;ENABLE PI 0
PIENB==1B31 ;SET PI ASSIGNMENT
TO11DB==1B22 ;TO 11 DOORBELL
IFE FT.UDB,<
IFN KLFLG,<
;KL10 CONSOLE ROUTINES
;TELETYPE INPUT
TYI: SKIPN DTEMTI ;INPUT READY
JRST TYI ;NO - LOOP
MOVE Q1,DTEF11 ;GET CHAR
CALL TYO ;ECHO IT
MOVE Q1,DTEF11 ;GET CHAR AGAIN
SETZM DTEMTI ;RESET INPUT DONE FLAG
RET
;TELETYPE OUTPUT
TYO: SETZM DTEMTD ;CLEAR OUTPUT DONE FLAG
TRO Q1,.DTTYO ;LIGHT FUNCTION BI
MOVEM Q1,DTECMD ;STORE FOR 11
MOVEI Q1,TO11DB ;RING DOORBELL
XCT DTCNOW ;DO IT
SKIPN DTEMTD ;DONE YET?
JRST .-1 ;NO
RET ;YES
> ; END IFN KLFLG
IFN SMFLG,<
TYI: MOVE Q1,CTYIWD ;CHECK FOR INPUT READY
TRNN Q1,CTYIRD ;CHECK INPUT WORD
JRST .-2 ;NO INPUT YET
SETZM CTYIWD ;CLEAR FLAGS
CONO APR,AP.SET!AP.INE ;INTERRUPT 8080
TYO: PUSH P,T1 ;SAVE A REGISTER
MOVE T1,CTYOWD ;CHECK FOR READY
TRNE T1,CTYORD ;OUTPUT WORD
JRST .-2 ;NOT READY YET
IORI Q1,CTYORD ;INSURE NOT READY FLAG SET
MOVEM Q1,CTYOWD ;OUTPUT WORD
ANDI Q1,177 ;MASK TO USEFUL STUFF
CONO APR,AP.SET!AP.INE ;INTERRUPT 8080
POP P,T1 ;RESTORE
RET
> ; END IFN SMFLG
;TYI - Read terminal input
; CALL TYI
;Returns +1: always,
; Q1/ one character, right-justified
;Reads the character and echoes it
IFN KCFLG,<
TYI:
ADJSP P,4 ;GET SOME STACK SPACE
DMOVEM T1,-3(P) ;SAVE WORK AC'S
DMOVEM T2,-1(P)
MOVEI T1,KCIOPG ;GET ADDRESS OF IO PAGE
SKIPL T2,ICYSTS(T1) ;ANY DATA?
JRST .-1 ;NO. WAIT HERE
LDB T3,[POINT 4,T2,4] ;GET LOCAL COUNT
IDIVI T3,4 ;BYTES IN A WORD
ADDI T3,IDATA(T1) ;POINT TO WORD WE WANT
TXO T3,<POINT 8,0,11> ;POINT TO FIRST BYTE
ADJBP T4,T3 ;POINT TO THE BYTE
LDB T3,T4 ;GET BYTE
SOS T2 ;DECREMENT COUNT OF BYTES REMAINING
ADD T2,[1B4] ;ACCOUNT FOR IT IN LOCAL COUNT
TRNN T2,17 ;ANY LEFT?
SETZM T2 ;NO
MOVEM T2,ICYSTS(T1) ;ALL SET
MOVE Q1,T3 ;COPY THE BYTE TO ECHO IT
CALL TYO ;ECHO IT
MOVE Q1,T3 ;COPY THE BYTE TO RETURN IT
DMOVE T1,-1(P)
DMOVE T3,-3(P)
ADJSP P,-4 ;AND CLEAN UP THE STACK
RET
;TYO - OUTPUT A CHARACTER ON THE TERMINAL
; CALL TYO
;Accepts:
; Q1/ a character, right-justified
;Returns +1: always
TYO: PUSH P,T1
MOVEI T1,KCIOPG ;GET ADDRESS OF IO PAGE
DPB Q1,[POINT 8,KCOUTS(T1),11] ;STASH BYTE
MOVX Q1,1B0+FLD(1,.RSOCT) ;GET MSB (FLAG FOR DATA AVAILABLE)+COUNT
IORM Q1,OCYSTS(T1) ;SAY WE HAVE OUTPUT
SKIPGE OCYSTS(T1) ;OUTPUT DONE YET?
JRST .-1 ;NO
POP P,T1
RET
> ;END IFN KCFLG
> ;END IFE FT.UDB
IFE FT.MTA, <
IFE SMFLG,<
; ROUTINES TO READ PAGES CONTAINING PRIMARY AND SECONDARY HOME BLOCKS
; CHAN and UNIT must be setup
; CALL RD10
; RETURNS +1 IF NO ERRORS, ELSE CAUSES DSKHDE ERROR RETURN
NRETRY==500 ;Number of times to retry.
;Note: the retry count must take into account
;dual ported devices in which the other side
;is keeping the port very active
;Read secondary home block
RD10: SKIPA P4,[.RHSBR!LR!0B27!^D10B35] ;DESIRED SECTOR AND TRACK
;Read primary home block
RD0: MOVE P4,[.RHSBR!LR!0B27!0B35] ;RH20 XFR CONTROL REGISTER
MOVEI T3,NRETRY ;MAX TIMES TO RETRY THIS OPERATION
RD00: MOVE T1,[R4%CSR!LR!R4%CRC!GO] ;RECALIBRATE FUNCTION
CALL RHWT1 ;GO RECALIBRATE DRIVE
RD0A: MOVX T1,R4%DSR ;RP04 DEVICE STATUS REGISTER
CALL RHRD1 ;GET DRIVE STATUS
TXNN T1,DS.DRY ;RECALIBRATE FINISHED ?
JRST RD0A ;NO, GO WAIT TILL DONE
MOVE T1,[R4%CSR!LR!R4%RIP!GO] ;READ-IN PRESET FUNCTION
CALL RHWT1 ;INITIALIZE DRIVE
READX: SETZM ICCW+1 ;CHANNEL HALT COMMAND
MOVE T4,[.RHSTR!LR!RCLP!STLW!R4%CRD!GO] ;RH20 XFR CONTROL REGISTER
MOVNI T1,N.BKPG*1 ;ONE PAGE
DPB T1,[POINT 10,T4,29] ;ADD -BLOCK COUNT
;..
; ROUTINE TO DO A DATAO TO THE RP04
; ACCEPTS IN T4/ DATAO DATA
; P4/ POSITION SELECT WORD
; CHAN and UNIT must be setup
; RETURNS + 1 IF NO ERRORS, ELSE CAUSES DSKHDE ERROR RETURN
DOOP0: MOVE T1,P4 ;GET POSITION SELECT WORD
CALL RHWT1 ;WRITE IT
MOVE T1,T4 ;GET TRANSFER WORD
MOVEI T2,TIMOUT ;GET TIMEOUT COUNT
CALL RHWT1 ;GO DO THE DATAO
DOOP1: CALL RHCI1 ;GO GET CONI BITS
TXNN T1,.RHDON ;OPERATION COMPLETE ?
SOJG T2,DOOP1 ;NO, LOOP TILL DONE
MOVEI T1,.RHRAE!.RHCTE!.RHMBE!.RHDON
CALL RHCO1 ;CLEAR OUT CHANNEL GRACEFULLY
JUMPLE T2,DOOP2 ;OPERATION EVER FINISH ?
MOVX T1,R4%DSR ;YES, SET UP TO GET DEVICE STATUS
CALL RHRD1 ;GO GET DEVICE STATUS
TXNE T1,DS.ERR ;CHECK COMPOSITE ERROR INDICATOR
JRST DOOP2 ;THE CRUMMY DRIVE SCREWED UP
CALL RHCI1 ;GO GET CONI BITS
TXNN T1,RHERR ;ANY ERRORS ?
RET ;ALL DONE, RETURN
DOOP2: MOVEI T1,.RHMBR+.RHMBE+.RHCTE+.RHSTP ;GET MASSBUS RESET AND ENABLE BITS
CALL RHCO1 ;DO CONO TO CHANNEL
MOVEI T1,.RHMBE ;GET MASSBUS ENABLE
CALL RHCO1 ;ENABLE CHANNEL
MOVE T1,[R4%ATN!LR!377] ;RP04 ATTENTION REGISTER
CALL RHWT1 ;CLEAR ATTENTION
SOJG T3,RD00 ;TRY IT ALL OVER AGAIN
RET ;CATCH ERROR LATER
> ;END IFE SMFLG
IFN SMFLG,<
RD10: SKIPA P4,[^D10] ;READ BLOCK 10
RD0: SETZ P4, ;READ BLOCK 0
MOVEI T3,NRETRY ;SET UP RETRY
RD00: MOVEI T1,R4%CRC!GO ;DO A DRIVE CLEAR
WRIO T1,@RPCS1(P1)
MOVEI T1,DS.DRY ;WAIT FOR READY
TION T1,@RPDS(P1)
JRST .-1
MOVEI T1,R4%RIP!GO ;NO DO READIN PRESET
WRIO T1,@RPCS1(P1)
WRIO P4,@RPDA(P1) ;SET DISK ADDRESS
MOVNI T1,RPPGSZ ;SET PAGE SIZE
WRIO T1,@RPWC(P1)
SETZ T1,0 ;SET DEVICE CORE ADDRESS
WRIO T1,@RPBA(P1) ;SET CORE ADDRESS
MOVE T1,ICCW
LSH T1,-9 ;FIND PAGE ADDRESS
ANDI T1,77777
IORI T1,UNVBIT!UN36B ;SET UNIBUS VALID BIT
WRIO T1,@UNBMAP(P1) ;SET MAP
MOVEI T1,R4%CRD!GO ;DO THE READ
WRIO T1,@RPCS1(P1) ;READ
MOVEI T1,DS.DRY ;SET UP READY
MOVEI T2,TIMOUT ;CHECK FOR TIMEOUT
DOOP1: TION T1,@RPCS1(P1) ;WAIT FOR DONE
SOJG T2,DOOP1
RDIO T1,@RPCS1(P1) ;CHECK STATUS
TRNE T1,DS.ERR ;ERROR?
SOJG T3,RD00 ;YES TRY AGAIN
RET ;NO RETURN
> ;END IFN SM10
> ;END IFE FT.MTA
IFN SMFLG,<
;
;R11CHT: THIS IS THE "CHANNEL" TABLE FOR THE RH11'S
; THERE SHOULD BE ONE ENTRY FOR EACH REGISTER OF EACH
; RH11. EACH RH11 IS TO BE CONSIDERED A CHANNEL
; AND THIS TABLE IS USUALLY USED INDEXED.
RH11CH:
RPCS1: R0%CS1 ;STATUS 1
R1%CS1
RPWC: R0%WC ;WORD COUNT
R1%WC
RPBA: R0%BA ;BUS ADDRESS
R1%BA
RPDA: R0%DA ;DISK ADDRESS (SECTOR AND TRACK)
R1%DA
RPCS2: R0%CS2 ;STATUS 2
R1%CS2
RPDS: R0%DS ;DRIVE STATUS
R1%DS
RPER1: R0%ER1 ;ERROR REGISTER 1
R1%ER1
RPAS: R0%AS ;ATTENTION SUMMARY REGISTER
R1%AS
RPDT: R0%DT ;DRIVE TYPE REGISTER
R1%DT
RPDC: R0%DC ;DESIRED CYLINDER
R1%DC
UNBMAP: UNBMP0 ;UNIBUS ADAPTER MAP ADDRESS
UNBMP1
> ;END IFN SM10
; PUSH-DOWN POINTER
PDP: IOWD PDLEN,PDL
;Here when command has been read. Call VBOOT to do the work.
FOUND: MOVE T1,FNDCMD ;POINTER TO CMD
CALL VBOOT1 ;PERFORM COMMAND
VBTRET: JUMPN CX,MRET2 ;RETURN TO MONITOR?
JRST GETCOM ;NO - GO ASK FOR NEXT COMMAND
;ON ERROR, ARRIVE HERE WITH ERROR TYPE IN Q2
ERRTYP: SETZM LODTYP ;FORCE INTERACTIVE MODE ON ERROR
PUSH P,Q2 ;SAVE Q2
CALL CRLF ;OUTPUT CRLF
MOVE Q2,ERRPFX ;GET THE PREFIX
CALL OUTSTR ;OUTPUT IT
MOVE Q2,(P) ;GET ERROR TYPE
MOVE Q2,ERRTAB(Q2) ;GET POINTER TO MESSAGE
CALL OUTSTR ;OUTPUT MESSAGE
;DON'T TRY FOR STRUCTURE/FILENAMES STATUS IF MTBOOT
MOVEI T1,^D35 ;TURN ERROR SYMBOL INTO A BIT
SUB T1,(P)
MOVEI T2,1
LSH T2,(T1)
MOVEM T2,(P) ;SAVE THE BIT
IFE FT.MTA,<
MOVE Q2,[%SNAM] ;DO WE REQUIRE A STRUCTURE NAME?
TDNN Q2,(P) ;...
JRST TFIL ;NO
TSTR: MOVEI Q2,[ASCIZ/: /]
CALL OUTSTR ;TYPE COLON
SKIPN Q2,CURNAM ;GET STRUCTURE NAME FROM CURNAM IF NON-ZERO
MOVE Q2,STRNAM ;GET STRUCTURE NAME
CALL TYPSTR ;TYPE IT
TFIL: MOVE Q2,[%FNAM] ;DO WE REQUIRE A FILE NAME?
TDNE Q2,(P) ;...
CALL TYPFIL ;YES
> ;END FT.MTA CONDITIONAL
TCR: CALL CRLF ;OUTPUT CRLF
MOVE Q2,[%DVSTS] ;WANT DEVICE STATUS?
TDNE Q2,(P) ;...
CALL OUTSTS ;YES
ERRET: JUMPN CX,MRET1 ;RETURN TO MONITOR?
JRST GETCM1 ;NO, TRY FOR NEW COMMAND
MRET2: AOS CX ;RETURN +2
MRET1: MOVE CX-1,PFLAGS ;RETURN +1 - RESTORE FLAGS
XJRSTF CX-1
;VBOOT
;ENTER HERE FOR YOUR FAVORITE BOOTSTRAP FUNCTION
;ARGUMENTS:
; T1 - BYTE POINTER TO COMMAND STRING
;
;CALL
; ;FIRST SETUP MAP FOR PAGES VORG-24 TO VORG + PROGRAM DATA
; ;ALSO SETUP DISK PARAMETERS IN DATA AREA
; EXTERNAL: JSP 16,VBOOT
; INTERNAL: PUSHJ P,VBOOT1
;RETURNS: NO ERROR, NO START: POPJ P, - TO VBTRET
; ERROR: JRST ERRTYP
; START: JRST @START
;
; NOTE THAT VBOOT RUNS IN THE SECTION IT WAS CALLED FROM:
;
; CALLER SECTION
; ------ -------
; BOOT 0
; TOPS20 V4 0
; TOPS20 V5 1
; BOOT MAY BE CALLED FROM SECTIONS 0 - 37
; TO BE CALLED FROM A SECTION LARGER THAN 37 REQUIRES
; A CHANGE IN THE MONITOR'S CALL TO BOOT
VBOOT:: XSFM PFLAGS ;SAVE FLAGS
XMOVEI T4,VBTRET ;VBOOT IS ENTRY VECTOR FOR MONITOR ONLY -
PUSH P,T4 ; SET UP FOR POPJ RETURN TO FOUND: CODE
TLZ CX,777740 ;IN CASE WE WERE CALLED FROM SECTION ZERO,
; TURN OFF ALL PC FLAGS (0-12)
AOS MONLOD ;INDICATE ANOTHER INVOCATION OF VBOOT
VBOOT1: JFCL ;VBOOT1 IS INTERNAL ENTRY VECTOR
SETZM F ;Clear flags
MOVE P6,TAPTYP ;PICK UP THE TAPE TYPE
CALL CHNSAV ;SAVE CHANNEL STATE
MOVEM T1,ISTRNG ;T1 HAS STRING POINTER
CALL PARSE ;PARSE STRING, SETUP ARG BLOCKS
TLNE F,(F.INFO) ;ANY PASIVE FUNCTIONS?
CALL INFO ;YES
TLNN F,(F.ACT) ;ANY ACTIVE FUNCTIONS?
JRST EXIT ;NO - EXIT
IFE FT.MTA,<
CALL FNDIDX ;GET INDEX BLOCK OF DESIRED FILE
> ;END IFE FT.MTA
JUMPGE F,LODRUN ;DUMP DESIRED (B0 OF F)
CALL SAVE ;YES - DO DUMP
RET
LODRUN: MOVE T1,MONLOD ;GET VBOOT INVOCATION COUNT
JUMPE T1,PASS0 ;JUMP IF FIRST INVOCATION
MOVEI Q2,[ASCIZ/[BOOT: LOADING SWAPPABLE MONITOR, PASS /]
CALL OUTSTR
MOVE Q2,MONLOD ;GET INVOCATION COUNT
CALL OUTOCT ;OUTPUT IT
MOVEI Q2,[ASCIZ/] /] ;CLOSE THE EXPRESSION
CALL OUTSTR ;...
JRST GETCAL
PASS0: MOVEI Q2,[ASCIZ/[BOOT: LOADING] /]
CALL OUTSTR
GETCAL: CALL GET ;HERE IF LOAD OR RUN FUNCTIONS
MOVEI Q2,[ASCIZ/[OK]
/]
CALL OUTSTR
IFE SMFLG,<
SETZM DTEMTI ;ZERO INPUT READY FLAG
CALL SETLCV ;SETUP LOW CORE VARS
EXIT: SETZM ICCW ;TEMP
CALL CHNRST ;RESTORE CHANNNEL
> ; END OF IFE SMFLG
IFN SMFLG,<
CALL SETLCV ;SET UP TEMP LOCORE VAR
EXIT:
> ; END OF IFN SMFLG
TXNN F,F.EDDT ;START EDDT?
JRST TSSTRT ;NO
MOVEI T1,ELOC ;GET MONITOR START ADDR FOR EDDT
HRRZM T1,START ;SAVE IT
JRST DOSTRT ;GO DO IT
TSSTRT: TLNE F,(F.STRT) ;SHOULD PROGRAM BE STARTED?
DOSTRT: JRST @START ;YES - GO TO IT
RET ;PRESUMED GOOD RETURN
SETLCV: HRRZI T1,A%VORG ;GET ENDING PAGE ADDRESS
HRLI T1,A%VFST ;GET STARTING PAGE ADDRESS
MOVEM T1,BUTPGS ;SAVE ENDING PAGES IN COMMUNICATION AREA
XMOVEI T1,VBOOT ;SET START ADDRESS
MOVEM T1,BUTSTA
HRRZI T1,A%PTB ;GET ADDRESS OF EPT PAGE
HRLI T1,A%EPT ;GET ADDRESS OF VBOOT EPT PAGE
MOVEM T1,BUTEPT ;SAVE EPT PAGE ADDRESS FOR MONITOR
MOVE T1,MAXCOR ;GET MAX CORE AVAILABLE
MOVEI T1,A%XB-A%VORG(T1) ;GET PHYSICAL ADDRESS OF FIRST PAGE
HRLI T1,-<<A%VORG-A%XB>_-9+1> ;GET # OF PAGES MONITOR MUST MAP
MOVEM T1,BUTPHY ;SAVE MAPPING INFO FOR MONITOR
MOVEI T1,A%XB ;GET FIRS VIRTUAL ADDRESS TO MAP
MOVEM T1,BUTVIR ;SAVE VIRTUAL ADDRESS FROM MONITOR
MOVE Q3,[POINT 7,BUTCMD] ;STORE FILESPEC
MOVEI Q1,"<" ;DIR
IDPB Q1,Q3 ;STORE CHAR
MOVE Q2,DIRSTR ;DIR STRING
CALL CPYSTR ;COPY STRING
MOVEI Q1,">" ;END OF DIR STRING
IDPB Q1,Q3 ;STORE CHAR
MOVE Q2,FILSTR ;FILENAME STRING
CALL CPYSTR ;COPY STRING
MOVEI Q1,"." ;FOR EXT
IDPB Q1,Q3 ;STORE
MOVE Q2,EXTSTR ;EXTENSION
CALL CPYSTR ;COPY STRING
SKIPN VERNUM ;VERSION SPECIFIED?
JRST APPNUL ;NO - EXIT
MOVEI Q1,"." ;YES- PUT VERSION OUT
IDPB Q1,Q3 ;STORE
MOVE Q2,VERSTR ; ...
CALL CPYSTR
JRST APPNUL
CPYSTR: ILDB Q1,Q2 ;GET A CHAR
JUMPE Q1,CPOPJ ;END OF STRING
IDPB Q1,Q3 ;OUTPUT A CHAR
JRST CPYSTR
;THE COMMAND STRING PARSER
PARSE: MOVE T1,[XWD DEFDAT,DEFBEG] ;SETUP BLT POINTER FOR DEFAULTS
BLT T1,DEFEND ;COPY DEFAULTS
TXZ F,F.EDDT ;RESET EDDT FLAG
MOVE Q2,ISTRNG ;GET POINTER TO INPUT STRING
MOVEI P5,ST.0 ;INITIAL STATE
P.NXT: CALL NXTSTA ;SETUP OUTPUTS THEN EVAL NXT STATE
JUMPE P5,P.TRM ;TERMINAL STATE REACHED
CAIN P5,777 ;ERROR STATE
$ERROR (COMERR) ;COMMAND ERROR
IORI P5,STPORG ;NO - RELOCATE STATE TABLE
JRST P.NXT ;GO GET NEXT STATE
P.TRM: MOVE Q2,VERSTR ;TERMINATION - GET VERSION AS #
CALL DECIN ;CONVERT TO BINARY
MOVEM P3,VERNUM ;SAVE VERSION
TXNE F,F.DUMP ;DUMP WANTED?
TXZ F,F.ALL!F.NCHL ;YES, CLEAR THESE FLAGS
MOVE Q2,LBSTR ;GET POINTER TO LOWER BOUND
TXNE F,F.ALL ;WANT TO USE ALL OF CORE?
TDZA P3,P3 ;YES, GET A 0
CALL OCTIN ;NO, READ LOWER BOUND
MOVEM P3,LWRLIM ;SAVE LOWER BOUND
MOVE Q2,UBSTR ;GET POINTER TO UPPER BOUND
TXNE F,F.ALL ;WANT ALL OF CORE?
SKIPA P3,[VFREE] ;YES, GET HIGHEST PAGE BOOT CAN READ
CALL OCTIN ;NO, READ IT
MOVEM P3,UPRLIM ;SAVE UPPER BOUND
MOVE Q2,SWSTR ;GET SWITCH STRING
ILDB T1,Q2 ;GET NEXT CHARACTER
JUMPE T1,P.NOS ;NO SWITCHES - TEST START ADDR AND RETURN
SETZI T2, ;CLEAR SWITCH INDEX
MOVE T3,SWTAB ;GET POINTER TO SWITCHES
P.NXS: ILDB T4,T3 ;GET A LEGAL SWITCH
SKIPN T4 ;ZERO MEANS SWITCH LIST EXHAUSTED
$ERROR (COMUNS) ;UNKNOWN SWITCH
CAME T1,T4 ;TEST IF THIS IS A MATCH
AOJA T2,P.NXS ;NO MATCH - LOOP
XCT SWXTAB(T2) ;EXECUTE APPROPRIATE INSTRUCTION
SKIPE D$UB ;UPPER BOUND SPECIFIED ?
JRST P.SW2 ;YES, USE SPECIFIED VALUE
MOVE T1,[PHYPAG] ;GET HIGHEST PHYSICAL PAGE WE CAN DUMP
TXNE F,F.DUMP ;DUMP REQUESTED ?
MOVEM T1,UPRLIM ;YES, USE DEFAULT UPPER LIMIT FOR DUMP
P.SW2: TLNN F,(F.WRIT) ;WRITING?
JRST P.SA ;NO - CHECK STARTING ADDR
DMOVE T1,DEF.WT ;LOAD BOTH FILENAME DEFAULTS
CAMN T2,FILSTR ;NAME SPECIFIED?
MOVEM T1,FILSTR ;NO - CHANGE DEFAULT
P.SA: CALL OCTIN ;CONVERT STARTING ADDRESS
CALLRET SETSA ;SET STARTING ADDR AND RETURN
SWTAB: POINT 7,.+1 ;POINTER TO SWITCH LIST
ASCIZ 'MLRDSGAIE'
SWXTAB: TLO F,(F.ACT) ;MERGE
TLO F,(F.CLR!F.ACT) ;LOAD
TLO F,(F.CLR!F.STRT!F.ACT) ;RUN
IFE FT.MTA,
< TLO F,(F.WRIT!F.DUMP!F.ACT) ;DUMP
TLO F,(F.WRIT!F.ACT) ;SAVE
>
IFN FT.MTA,
< JFCL ;NOOP FOR DUMP
JFCL ;NOOP FOR SAVE
>
TLO F,(F.STRT) ;GO
TLO F,(F.ALL!F.ACT!F.NCHL) ;ALL
TLO F,(F.INFO) ;DISPLAY PROGRAM INFORMATION
TLO F,(F.CLR!F.ACT!F.EDDT) ;LOAD AND START AT LOCATION ELOC
;THE STATE MACHINE
NXTSTA: MOVSI T4,(<POINT 18,0(P5)>) ;MAKE INPUT BYTE PTR
ILDB P4,T4 ;GET OUTPUT VALUE ADDRESS
ILDB Q3,T4 ;GET OUTPUT DATA ADDRESS
HRLI Q3,(<POINT 7,0>) ; MAKE OUTPUT BYTE PTR
MOVE T2,Q3 ;SAVE FOR LATER (CAREFUL WITH T2)
TLC T4,003300 ;SWITCH TO 9 BIT BYTES
NXT.CH: TLZN F,(F.BACK) ;TEST/CLEAR SCANNER BACKUP
ILDB Q1,Q2 ;GET NEXT CHAR
SKIPN Q1
$ERROR(COMERR) ;COMMAND ERROR
MOVE T3,T4 ;COPY POINTER TO TRANSITION TABLE
NXT.NT: ILDB T1,T3 ;GET NEXT TRANSITION BYTE
ANDI T1,177 ;GET DATA ONLY
JUMPE T1,NXT.EX ;SPECIAL BYTE - PROCESS IT
CAMN Q1,T1 ;TRANSITION CHARACTER?
JRST NXT.EX ;YES - PROCESS
ILDB T1,T3 ;SKIP NEXT STATE
JRST NXT.NT ;AND GET NEXT TRANSITION BYTE
NXT.EX: LDB T1,T3 ;GET FULL TRANSITION BYTE
JUMPE T1,NXT.ST ;END OF TABLE - STORE CHAR
ILDB P5,T3 ;GET NEXT STATE
CAIN P5,ST.6&777 ;ACCUMULATING UPPER AND LOWER BOUNDS?
TXO F,F.NCHL ;YES, DISABLE LIMIT CHANGING LATER
LSH T1,-7 ;GET FLAG BITS IN B34-35
XCT NXXTAB(T1) ;EXECUTE INSTRUCTION CORRESPONDING
TLZN F,(F.OUT) ;HAS STATE PRODUCED OUTPUT?
RET ;NO - EXIT
MOVEM T2,(P4) ;SAVE OUTPUT STRING
APPNUL: SETZ T2, ;APPEND NULL
IDPB T2,Q3 ;...
RET
NXT.ST: IDPB Q1,Q3 ;STORE OUTPUT CHAR
TLO F,(F.OUT) ;INDICATE STATE DID SOMETHING
JRST NXT.CH ;AND PROCESS NEXT CHARACTER
;STATE TABLE FLAG ACTION TABLE
NXXTAB: JFCL ;NO FLAGS
TLO F,(F.BACK) ;(200)SCANNER BACKUP
TLO F,(F.OUT) ;(400)FORCE OUTPUT
;(600)CURRENTLY UNUSED
;THIS BLOCK OF DEFAULT VALUES IS COPIED INTO THE DATA AREA
;STARTING AT DIRSTR ENDING AT DEFEND
DEF.WT: POINT 7,[ASCIZ 'DUMP'] ;DEFAULT FILSTR IF WRITING
DEFDAT:
DEF.FN: POINT 7,[ASCIZ 'MONITR'] ;DEFAULT FILSTR
POINT 7,[ASCIZ 'SYSTEM'] ;DEFAULT DIRSTR
POINT 7,[ASCIZ 'EXE'] ;DEFAULT EXTSTR
ZERO: Z ;DEFAULT VERSTR
Z ;DEFAULT SWSTR
POINT 7,[ASCIZ '340'] ;DEFAULT UBSTR
Z ;DEFAULT LBSTR
POINT 7,D$TMP ;DEFAULT DIRTMP
;NOTE: A LDB ON A BYTE POINTER WITH 0 S FIELD PRODUCES A ZERO BYTE!
IFN <<.&777000>-<<.+STTSIZ>&777000>>,< ;CHECK TO SEE IF STATE PAGE TABLE CROSSES A PAGE
FILLER=<<<.&777000>+1000>-.>&777
BLOCK FILLER ;FORCE STATE TABLE TO PAGE BOUNDARY
>
;STATE TRANSITION TABLES:
; THESE TABLES PARSE A FILESPEC OF THE FORM
; <DIRECTORY>FILE.EXTENSION;VERSION/SWITCHSTARTADDR(LB,UB)
; FORMAT:
; XWD OUTPUT POINTER LOCATION,DATA AREA FOR CHARACTERS OUTPUT FROM THIS STATE
; A STRING OF 9 BIT BYTES CONSISTING OF A CHARACTER+FLAGS WHICH
; WILL CAUSE A STATE TRANSITION FOLLOWED BY THE LOW 9
; BITS OF THE TRANSITION TABLE FOR THE NEXT STATE.
;FLAGS: 200 = BACKUP SCANNER, 400=FORCE OUTPUT EVEN IF NULL
STPORG=.&777000 ;PAGE OFFSET TO STATE TABLES
;STATE 0 - INITIAL P5, MAKES TRANSITION TO NEXT STATE BASED ON FIRST CHARACTER.
ST.0: XWD 0,0 ;NO OUTPUT, NO DATA AREA
BYTE (9)"<",ST.1,"[",ST.1B,".",ST.3,".",ST.4,"/",ST.5,15,0,200,ST.2
;STATE 1 - ACCUMULATE DIRECTORY STRING.
ST.1: XWD DIRSTR,D$DIR ;POINTER=DIRSTR, DATA=D$DIR
BYTE (9)">",ST.2,15,0,0
;STATE 1B - ACCUMULATE DIRECTORY STRING.
ST.1B: XWD DIRSTR,D$DIR ;POINTER=DIRSTR, DATA=D$DIR
BYTE (9)"]",ST.2,15,0,0
;STATE 2 - ACCUMULATE FILE NAME STRING
ST.2: XWD FILSTR,D$FIL ;POINTER=FILSTR,DATA=D$FIL
BYTE (9)".",ST.3,".",ST.4,"/",ST.5,15,0,0
;STATE 3 - ACCUMULATE EXTENSION STRING
ST.3: XWD EXTSTR,D$EXT ;POINTER=EXTSTR,DATA=D$EXT
BYTE (9)"."+400,ST.4,"/"+400,ST.5,15+400,0,0
;STATE 4 - ACCUMULATE VERSION STRING
ST.4: XWD VERSTR,D$VER
BYTE (9)"/",ST.5,15,0,0
;STATE 5 - ACCUMULATE SWITCH STRING
ST.5: XWD SWSTR,D$SW
BYTE (9)15,0,"(",ST.6,0
;STATE 6 - ACCUMULATE LOWER PAGE BOUND STRING
ST.6: XWD LBSTR,D$LB
BYTE (9)")",0,",",ST.7,15,0,0
;STATE 7 ACCUMULATE UPPER BOUND STRING
ST.7: XWD UBSTR,D$UB
BYTE (9)")",0,15,0
IFN <<.-ST.0>-STTSIZ>,<PRINTX ?STATE TABLE SIZE DOES NOT AGREE WITH STTSIZ>
IFN <STPORG-<.&777000>>,<PRINTX ?STATE TABLE MUST FIT ON SINGLE PAGE>
;NUMBER INPUT SUBROUTINES
DECIN: MOVEI T2,^D10 ;SET RADIX DECIMAL
JRST RADIN ;CONVERT
OCTIN: MOVEI T2,^D8 ;OCTAL RADIX
RADIN: SETZI P3, ;ZERO RESULT
RAD.NX: ILDB T1,Q2 ;GET NEXT CHARACTER
JUMPE T1,CPOPJ ;END OF STRING - RETURN OK
CAIG T1,57(T2) ;CHECK TO BE SURE
CAIGE T1,"0" ;THAT IT IS LEGAL
$ERROR (COMINV) ;INVALID NUMERIC VALUE
IMUL P3,T2 ;IS OK - CONVERT
ADDI P3,-60(T1) ;ADD TO RESULT
JRST RAD.NX
;STARTING ADDRESS SETUP/TEST SUBROUTINES
SETSA:
HRRZM P3,START ;NO, STORE START ADDR FROM EXE FILE
SKIPN START ;NON ZERO?
TLZ F,(F.STRT) ;NO - CLEAR F.STRT
RET
;INFO SUBROUTINE
;DISPLAY PROGRAM VERSION
INFO: MOVEI Q2,[ASCIZ/
BOOT VERSION: /] ;OUTPUT TEXT
CALL OUTSTR ;...
CALL TYPBVR ;OUTPUT BOOT VERSION
IFN KLFLG,
<
;DISPLAY MICROCODE VERSION
MOVEI Q2,[ASCIZ/ MICROCODE VERSION: /] ;OUTPUT TEXT
CALL OUTSTR ;...
MOVEI Q2,[ASCIZ/DX20A: /] ;OUTPUT STRING
CALL OUTSTR ;...
MOVE T1,DXAMCV ;GET DXA MCODE VERSION
CALL TMCVER ;GO DISPLAY VERSION INFO
IFN FT.RP2,
< MOVEI Q2,[ASCIZ/ DX20B: /] ;OUTPUT STRING
CALL OUTSTR ;...
MOVE T1,DXBMCV ;GET DXB MCODE VERSION
CALL TMCVER ;GO DISPLAY VERSION INFO
>
IFN FTKLIPA,<
MOVEI Q2,[ASCIZ/KLIPA: /] ;OUTPUT STRING
CALL OUTSTR
MOVE T1,KLPVER ;GET KLIPA MCODE VERSION
MOVEI Q2,[ASCIZ/KLNI: /] ;OUTPUT STRING
CALL OUTSTR
MOVE T1,KLPVER ;GET KLNI MCODE VERSION
>
> ;END IFN KLFLG
INFRET: CALL CRLF ;OUTPUT CRLF
RET
;SUBROUTINE TO DISPLAY MICROCODE VERSION
;CALL WITH MICROCODE VERSION WORD IN T1
DEFSTR(ED.NUM,T1,^D35,^D10) ;FIELD FOR EDIT NUMBER IN T1
DEFSTR(VR.NUM,T1,^D25,^D6) ;FIELD FOR VERSION NUMBER IN T1
TMCVER: PUSH P,T1 ;SAVE VERSION NUMBER
LOAD Q2,VR.NUM ;GET THE VERSION NUMBER
CALL OUTOCT ;DISPLAY IT
MOVEI Q1,"(" ;DISPLAY LEFT PAREN
CALL TYO ;...
POP P,T1 ;RESTORE VERSION NUMBER
LOAD Q2,ED.NUM ;GET EDIT NUMBER
CALL OUTOCT ;DISPLAY IT
MOVEI Q1,")" ;DISPLAY RIGHT PAREN
CALL TYO ;...
RET
;SUBROUTINE TO OUTPUT BOOT VERSION
TYPBVR: MOVEI Q2,V%MAJOR ;OUTPUT MAJOR VERSION
CALL OUTOCT ;...
MOVEI Q1,"." ;OUTPUT A PERIOD
CALL TYO ;...
MOVEI Q2,V%MINOR ;OUTPUT MINOR VERSION
CALL OUTOCT ;...
MOVEI Q1,"(" ;OUTPUT A LEFT PAREN
CALL TYO ;...
MOVEI Q2,V%EDIT ;OUTPUT EDIT NUMBER
CALL OUTOCT ;...
MOVEI Q2,[ASCIZ/)
/] ;OUTPUT RIGHT PAREN + CRLF
CALL OUTSTR ;...
RET
;SUBROUTINE TO OUTPUT ASCIZ STRING
;CALL WITH STRING ADDR IN Q2
OUTSTR: HRLI Q2,(POINT 7,) ;MAKE ADDRESS INTO BYTE POINTER
OUTST1: ILDB Q1,Q2 ;PICK UP A CHARACTER
JUMPE Q1,R ;IF DONE, RETURN
CALL TYO ;OTHERWISE, TYPE IT
JRST OUTST1 ;AND LOOP FOR MORE
;SUBROUTINE TO OUTPUT OCTAL VALUES
;CALL WITH BINARY IN Q2
;ENTRY VECTORS:
; OUTOCN: ;ALLOW LEADING ZEROES
; OUTOCT: ;SUPRESS LEADING ZEROES
OUTOCN: SETOM Q3 ;ALLOW LEADING ZEROES
SKIPA
OUTOCT: SETZM Q3 ;SUPRESS LEADING ZEROES
PUSH P,Q3 ;CREATE A TEMPORARY FLAG
MOVE Q3,[POINT 3,Q2-1,35] ;USE TO FETCH 3-BIT OCTAL VALUE
JUMPN Q2,GETDG1 ;BYPASS LOOP-EXIT CODE FIRST TIME THROUGH
ILDB Q1,Q3 ;HERE IF HE GAVE US A ZERO
JRST OUTASC ;TYPE A "0"
; INSURES WE GET A ZERO EVEN IF SUPPRESSING
GETDIG: TLNN Q3,770000 ;TIME TO LEAVE?
JRST OCTRET ;YES
GETDG1: ILDB Q1,Q3 ;GET A PACKED OCTAL VALUE
SKIPN (P) ;NON-ZERO DIGIT SEEN YET?
JUMPE Q1,GETDIG ;NO, IF THIS DIGIT IS ZERO, TRY AGAIN
SETOM (P) ;INDICATE WE HAVE SEEN A NON-ZERO DIGIT
OUTASC: ADDI Q1,60 ;CONVERT TO ASCII
CALL TYO ;OUTPUT IT
JRST GETDIG ;GET ANOTHER DIGIT
OCTRET: ADJSP P,-1 ;RELEASE TEMPORARY STORAGE FOR FLAG
POPJ P, ;RETURN
OUTSTS: PUSH P,F ;SAV AC'S
MOVEI Q2,[ASCIZ/ Channel-status: /]
CALL OUTSTR ;OUTPUT THE STRING
CALL XIO1 ;SET UP FOR CHANNEL STATUS
CONI .-.,Q2 ;GET THE STATUS
CALL OUTOCN ;OUTPUT THE CHANNEL STATUS
MOVEI Q2,[ASCIZ/ Device-status: /]
CALL OUTSTR ;OUTPUT THE STRING
MOVX T1,R4%DSR ;SET UP FOR DEVICE STATUS
CALL RHRD1 ;READ THE DEVICE REGISTER
MOVE Q2,T1 ;GET THE STATUS
TDZ Q2,[-1,,600000] ;MASK OUT THE JUNK
CALL OUTOCN ;OUTPUT THE STATUS
CALL CRLF ;OUTPUT A CRLF
MOVEI Q2,[ASCIZ/ Device error-registers (1) /]
CALL OUTSTR
MOVX T1,R4%ER1 ;SET UP FOR ERROR REG 1
CALL RHRD1 ;READ IT
MOVE Q2,T1 ;GET THE STATUS
TDZ Q2,[-1,,600000] ;MASK OUT THE JUNK
CALL OUTOCN ;OUTPUT IT
IFE FT.MTA,<
MOVEI Q2,[ASCIZ/ (3) /]
CALL OUTSTR ;OUTPUT THE STRING
MOVX T1,R4%ER3 ;SET UP FOR ERROR REG 3
CALL RHRD1 ;READ IT
MOVE Q2,T1 ;GET THE STATUS
TDZ Q2,[-1,,600000] ;MASK OUT THE JUNK
CALL OUTOCN ;OUTPUT IT
> ;END FT.MTA CONDITIONAL
CALL CRLF ;OUTPUT A CRLF
POP P,F ;RESTORE AC'S
RET ;RETURN
;SUBROUTINE TO TYPE OUT STRUCTURE NAME
;CALL WITH STRUCTURE NAME IN Q2
TYPSTR: MOVE T1,[-6,,0]
SETZM Q1 ;INIT SHIFT AC
TYPST1: LSHC Q1,6 ;SHIFT A SIXBIT CHAR TO Q1
ADDI Q1,40 ;CONVERT TO ASCII
CALL TYO ;TYPE IT
SKIPE Q2 ;EXIT IF Q2 ZERO
AOBJN T1,TYPST1 ;BACK FOR MORE
STRRET: MOVEI Q1,":" ;ADD A COLON
CALL TYO
RET
;SUBROUTINE TO TYPE OUT FILENAME
TYPFIL: MOVEI Q1,"<" ;OUTPUT LEFT ANGLE
CALL TYO
MOVE Q2,DIRSTR ;GET POINTER TO DIRECTORY STRING
CALL OUTSTR
MOVEI Q1,">" ;OUTPUT RIGHT ANGLE
CALL TYO
MOVE Q2,FILSTR ;TYPE FILE NAME
CALL OUTSTR
MOVEI Q1,"." ;OUTPUT PERIOD
CALL TYO
MOVE Q2,EXTSTR ;TYPE FILE EXTENSION
CALL OUTSTR
RET
IFE FT.MTA,<
MAPDIR: MOVEI P4,A%DIR ;GET ADDRESS FOR DIRECTORY HEADER
MOVE P5,A%XB ;GET DISK ADDRESS FOR FIRST PAGE OF DIR
JRST RDPGRT ;READ HEADER PAGE OF DIRECTORY
;MAP THE DIRECTORY INTO VIRTUAL ADDR DIR AND ABOVE
FNDIDX: MOVE P5,DIORG ;GET ADDRESS
MOVEI P4,A%XB ;INDEX BLOCK BUFFER
CALL REDPAG ;READ ROOT-DIR XB
$ERROR (IOER10) ;ERROR READING PAGE
CALL MAPDIR ;MAP IN ROOT DIR HEADER PAGE
MOVE T1,DIRSTR ;Get byte pointer to directory string
MOVEM T1,DIRST ;Keep a working copy here
FND1: MOVE Q1,DIRTMP ;Use this BP for depositing
SETZM @DIRTMP ;Insure trailing nulls for fullword compare
;on first 5 bytes of name
FND2: ILDB T1,DIRST ;Get next character from dir string
CAIN T1,"." ;End of (sub)directory name?
SETZM T1 ;Yes
IDPB T1,Q1 ;Store character
JUMPN T1,FND2 ;End of processing this directory level?
FND3: MOVE T1,DIRTMP ;Yes, get pointer to (sub)directory string
MOVE T2,[POINT 7,[ASCIZ/DIRECTORY/]]
MOVEI T3,0 ;GET HIGHEST VERSION #
CALL GETIDX ;GET INDEX BLOCK OF DIR FILE
CALL MAPDIR ;MAP IN THE DIRECTORY
LDB T1,DIRST ;Look at last char read
JUMPN T1,FND1 ;Get next level directory
MOVE T1,FILSTR ;GET POINTER TO NAME STRING
MOVE T2,EXTSTR ;AND POINTER TO EXTENSION STRING
MOVE T3,VERNUM ;GET DESIRED VERSION #
;FALL INTO GETIDX
;..
> ;END IFE FT.MTA
IFE FT.MTA,<
;HERE TO GET THE INDEX BLOCK FOR THE FILE
GETIDX: MOVEM T1,FNDSTR ;SAVE NAME STRING
DMOVEM T2,FNDSTE ;SAVE EXTENSION STRING POINTER
; AND SAVE VERSION NUMBER
CALL FIND ;RETURN FDB OFFSET IN P1
GX.NE: MOVE Q2,FNDSTE ;COMPARE WITH NEXT EXTENSION
CALL GETPAG ;MAP IN PAGE CONTAINING FDB
; RETURN WITH MAPPED ADDR IN T1
LOAD Q3,FBEXT,(T1) ;GET ADR OF EXT STRING BLOCK
HRLI Q3,(POINT 7,0) ;SET IT UP AS A STRING POINTER
ADDI Q3,1 ;POINT TO STRING
CALL STRCMP ;COMPARE STRINGS
CAIA
JRST GX.NV ;FOUND EXTENSION MATCH - LOOK AT VERSION
CALL GETPAG ;MAP IN PAGE CONTAINING FDB
LOAD P1,FBEXL,(T1) ;STEP TO NEXT FDB IN THIS CHAIN
JUMPN P1,GX.NE ;BACK IF STILL MORE
$ERROR (FILFNF) ;FILE NOT FOUND
GX.NV: CALL GETPAG ;MAP IN PAGE CONTAINING FDB
LOAD T1,FBGEN,(T1) ;GET GENERATION NUMBER
SKIPE FNDSTV ;IS MOST RECENT VER WANTED?
CAMN T1,FNDSTV ;IS IT WHAT WE WANT?
JRST GX.DON ;YES - EXIT
GX.NV1: CALL GETPAG ;MAP IN PAGE CONTAINING THE FDB
LOAD P1,FBGNL,(T1) ;STEP TO FDB OF NEXT GENERATION
SKIPN P1
$ERROR (FILFNF) ;File not found
JRST GX.NV ;TRY AGAIN
GX.DON: CALL GETPAG ;MAP IN PAGE CONTAINING FDB
LOAD T2,FBCTL,(T1) ;GET CONTROL BITS
TXNE T2,FB%DEL!FB%NXF ;DOES IT EXIST?
JRST GX.NV1 ;NO. GO GET ANOTHER THEN
MOVE T4,@FNDSTR ;GET 1'ST 5 CHARS OF FILE NAME
CAME T4,[BYTE (7) "D","U","M","P"] ;IS IT THE DUMP FILE?
JRST NOTDMP ;NO
MOVE T4,@FNDSTE ;GET EXTENSION
CAME T4,[BYTE (7) "E", "X", "E"] ;CORRECT EXTENSION?
JRST NOTDMP ;NO
LOAD T4,FBBYV,(T1) ;YES, GET PAGE COUNT
HRRZM T4,DEXEPC ;REMEMBER IT
NOTDMP: SETOM XBNUM ;INITIALIZE XB NUMBER TO SHORT FILE
LOAD P5,FBADR,(T1) ;GET ADR OF INDEX BLOCK
TXNN T2,FB%LNG ;LONG FILE?
JRST GX.DN1 ;NO, JUST READ IN INDEX BLOCK 0
MOVEI P4,A%SXB ;LONG FILE, READ IN THE SUPER INDEX BLOCK
CALL REDPAG ; INTO A%SXB
$ERROR (IOER2) ;ERROR READING PAGE
LOAD P5,IDXADR,A%SXB+0 ;GET ADR OF FIRST INDEX BLOCK
SKIPN P5 ;IF NO PAGE 0, FORMAT ERROR
$ERROR (FILNEF)
SETZM XBNUM ;MARK THAT INDEX BLOCK 0 IS MAPPED
GX.DN1: MOVEI P4,A%XB ;READ INTO XB AREA
RDPGRT: CALL REDPAG ;READ THE PAGE
$ERROR (IOER3) ;ERROR READING PAGE
RET
; ROUTINE TO MAP A PAGE OF THE DIRECTORY
; ACCEPTS IN P1/ ADDRESS TO MAP
; CALL GETPAG
; RETURNS +1 WITH T1/ MAPPED ADDRESS
GETPAG: HRRZ T1,P1 ;GET ADDRESS DESIRED FROM FILE
LSH T1,-^D9 ;CONVERT ADDRESS TO PAGE NUMBER
MOVE P5,A%XB(T1) ;GET DISK ADDRESS OF FILE PAGE
MOVEI P4,A%DPG ;GET ADDRESS OF DIRECTORY DATA PAGE
CAMN P5,CURPAG ;DESIRED PAGE ALREADY IN CORE ?
JRST GETPG1 ;YES, DO NOT NEED TO READ AGAIN
CALL REDPAG ;NO, READ THE PAGE
$ERROR (IOER4) ;CAN'T READ DIRECTORY PAGE
GETPG1: LDB T1,[POINT 9,P1,35] ;GET LOW ORDER BITS OF ORIGINAL ADDRESS
IORI T1,A%DPG ;ADD ADDRESS OF DIRECTORY DATA PAGE
MOVEM P5,CURPAG ;UPDATE CURRENTLY IN-CORE PAGE
RET ;RETURN
> ;END IFE FT.MTA
IFE FT.MTA,<
;SUBROUTINE TO DO A PRIMARY NAME SEARCH IN A DIRECTORY
; CALL WITH BYTE POINTER TO FILENAME IN FNDSTR
; RETURN WITH OFFSET TO FDB FOR THAT FILE IN P1
FIND: MOVE T1,SYMBOT ;START OF ST AREA
SUB T1,SYMTOP ;GET -LENGTH
MOVE P1,SYMBOT ;BUILD A
ADDI P1,2 ;RELOCATE
HRLI P1,2(T1) ;AOBJN POINTER
FND.NF: MOVE Q2,FNDSTR ;FILE NAME
CALL GETPAG ;MAP IN PAGE CONTAINING S.T. ENTRY
LOAD Q3,SYMET,(T1) ;GET SYMBOL TYPE
SKIPE Q3
$ERROR(FILFNF) ;FILE NOT FOUND
LOAD Q3,SYMVL,(T1) ;GET FIRST FIVE CHARS OF NAME
CAME Q3,@FNDSTR ;IS THIS A MATCH AGAINST STRING?
JRST FND.NM ;NO, NO NEED TO COMPARE NAME STRING
LOAD Q3,SYMAD,(T1) ;GET FDB ADDRESS
PUSH P,P1 ;SAVE POINTER INTO SYMBOL TABLE
MOVE P1,Q3 ;GET ADDRESS OF FDB
CALL GETPAG ;MAP IN PAGE CONTAINING FDB
POP P,P1 ;RESTORE SYMBOL TABLE POINTER
LOAD Q3,FBNAM,(T1) ;GET ADDRESS OF NAME STRING BLOCK
HRLI Q3,(POINT 7,0) ;SET UP STRING POINTER
ADDI Q3,1 ;POINT TO STRING
CALL STRCMP ;COMPARE STRINGS
FND.NM: JRST [ ADD P1,[1,,1] ;NO MATCH, STEP OVER SYMBOL VALUE
AOBJN P1,FND.NF
$ERROR (FILFNF)] ;NO MORE NAMES, ERROR
CALL GETPAG ;MAP IN PAGE CONTAINING S.T. ENTRY
HRRZ P1,(T1) ;GET FIRST FILE FDB
RET
;STRING COMPARE SUBROUTINE
STRCMP: PUSH P,P1 ;SAVE P1
MOVE P1,Q3 ;COPY ADDRESS OF STRING IN FILE
CALL GETPAG ;MAP PAGE CONTAINING STRING BLOCK
POP P,P1 ;RESTORE P1
HRR Q3,T1 ;INSERT MAPPED ADDRESS TO STRING
STRCM1: ILDB T1,Q2 ;GET 1ST BYTE
ILDB T2,Q3 ;GET 2ND BYTE
CAME T1,T2 ;EQUAL?
RET ;NO - LOSE
JUMPN T1,STRCM1 ;YES -END OF STRING?
> ;END IFE FT.MTA
RETSKP ;SKIP RETURN
;IO SUBROUTINES
IFE SMFLG, <
REDPAG: SKIPA T1,[.RHSTR!LR!RCLP!STLW!<-4&1777>B29!R4%CRD!GO] ;RH20 READ DATAO
WRTPAG: MOVE T1,[.RHSTR!LR!<-4&1777>B29!RCLP!STLW!R4%CWR!GO] ;RH20 WRITE DATAO
PUSH P,P2 ;SAVE COUNTER
MOVEI P2,^D15 ;RETRY COUNT
AOS FILPAG ;INCREMENT FILE PAGE #
IFN FT.MTA, <
MOVEI P2,^D100 ;RETRY COUNT FOR MAGTAPE
JRST MRETRY ;YES, GO DO TAPIO
> ; END OF IFN FT.MTA
IFE FT.MTA, <
MOVEM T1,RHCMD ;Save RH command
CALL IOCALC ;Calc channel,unit,cylinder,sector,track
DRETRY: IOOP(CLEAR) ;RESET RH20
CALL LKPORT ;Lock the port
$ERROR(IOER11)
MOVX T1,R4%DCA!LR ;DESIRED CYLINDER REGISTER IN RP04
HRR T1,CYLIND ;GET DESIRED CYLINDER #
CALL RHWT ;TELL RP04 WHICH CYLINDER
MOVE T1,SECTRK ;Get sector and track
TXO T1,R4%DST!LR ;RP04 DESIRED SECTOR AND TRACK REGISTER
CALL RHWT ;GO WRITE SECTOR, TRACK REGISTER
MOVE T1,SECTRK ;Get disk address
TXO T1,.RHSBR!LR ;RH20 BLOCK ADDRESS REGISTER
CALL RHWT ;TELL RP04 WHERE THE DATA IS
MOVE T4,RHCMD ;Get RH command
TSO T4,UNIT ;Insert unit # into command
CALL DOIO ;START IO AND WAIT
JUMPG T1,RWSXIT ;IF NO ERRORS, EXIT SUCCESSFULLY
SOJG P2,DRETRY ;GO RETRY TIL COUNT EXHAUSTED
JRST RWFXIT ;OPERATION FAILED
> ; END OF IFE FT.MTA
IFN FT.MTA,<
MRETRY: CALL TAPIO ;DO IO
JRST RWSXIT ;WIN
SOSG P2 ;DO RETRY?
$ERROR (TAPHTE) ;NO - HARD TAPE ERROR
CALL BSPACE ;YES - BACKSPACE
JRST MRETRY ;LOOP
> ;END IFN FT.MTA
RWSXIT: AOS -1(P) ;SKIP RETURN
RWFXIT:
IFE FT.MTA,<
CALL UKPORT ;UNLOCK THE PORT
>
POP P,P2 ;RESTORE P2
RET ;RETURN
IFE FT.MTA, <
;DISK IO SUBROUTINES - DISK DEPENDENT PARTS.
DOIO: IOOP(CLEAR) ;CLEAR CONTROLLER/UNIT
CALL CKPORT ;Do we still own the port?
JRST IOFAIL ;No, we lost it
MOVSI T1,2 ;DELAY COUNT
IOOP(XCTOP,T4) ;EXECUTE OPERATION
WAIT: IOOP(SKIPDONE) ;SKIP IF DONE
SOJG T1,WAIT ;LOOP
JUMPLE T1,CPOPJ ;RETURN IF TIMEOUT
IOOP(SKIPNOERR) ;SKIP IF NO ERRORS
IOFAIL: SETOI T1, ;IO failed, set flag
RET ;RETURN
> ; END OF IFE FT.MTA
;THIS RANDOM INSTRUCTION FROM PARSE IS HERE TO SAVE SPACE
P.NOS: TLO F,(F.STRT!F.CLR!F.ACT) ;DEFAULT WHEN NO SWITCHES
RET ;RETURN
;ROUTINES TO SAVE AND RESTORE CHANNEL FOR EACH LOGICAL UNIT
;OF STRUCTURE IN USE
;NOTE: On a 2-pass load, incorrectly restoring the channel
; can cause PH2PIM BUGHLT's. Incorrectly restoring the IVR
; can cause IOPGF's.
;For simplicity's sake, we keep IO unit number out of IVR register
CHNSAV: PUSH P,T1 ;SAVE T1
PUSH P,P4 ;Save P4
HRLZI P4,-NCHAN ;Get AOBJN pointer
SAVLP: MOVE T1,DSKTAB(P4) ;Get status of logical unit
TLZN T1,ENTFLG ;In use?
JRST SAVLP1 ;No
IFN FT.MTA,<
LSH T1,6 ;Shift channel # into left half
>
HLRZM T1,CHAN ;Store channel #
CALL XIO1 ;GET DEVICE CODE
CONI .-.,T1 ;GET RH20 PI ASSIGNMENT
ANDI T1,.RHMBE+7 ;KEEP JUST MASBUS ENA + PI
MOVEM T1,PIATAB(P4) ;SAVE IT
MOVX T1,.RHIVR ;INTERRUPT VECTOR REGISTER
CALL RHDIO ;GET ORIGINAL CONTENTS OF IVR
ANDI T1,177777 ;KEEP JUST DATA BITS
HRRM T1,IVRTAB(P4) ;SAVE IT
SAVLP1: AOBJN P4,SAVLP ;DO ALL PHYSICAL UNITS
POP P,P4 ;Restore P4
POP P,T1 ;RESTORE T1
RET
CHNRST: PUSH P,T1 ;SAVE 1
PUSH P,P4 ;Save P4
HRLZI P4,-NCHAN ;Get AOBJN pointer
RSTLP: MOVE T1,DSKTAB(P4) ;Get status of logical unit
TLZN T1,ENTFLG ;In use?
JRST RSTLP1 ;No
IFN FT.MTA,<
LSH T1,6 ;Shift channel # into left half
>
HLRZM T1,CHAN ;Store channel #
HLR F,T1 ;Get RH # in F
ADDI F,RH0_-2 ;Produce device code for that RH
IOOP(CLEAR) ;RESET RH20
MOVX T1,.RHIVR!LR ;INTERRUPT VECTOR REGISTER
HRR T1,IVRTAB(P4) ;GET INITIAL CONTENTS
CALL RHDIO ;RESTORE THEM
MOVE T1,PIATAB(P4) ;GET RH20 PI ASSIGNMENT
CALL IOXCT ;GET DEVICE CODE
CONO .-.,.RHDON!.RHAIE(T1) ;RESTORE ORIGINAL PI ASSIGNMENT
RSTLP1: AOBJN P4,RSTLP ;DO ALL PHYSICAL UNITS
POP P,P4 ;Restore P4
POP P,T1 ;RESTORE 1
RET ;AND DONE
;SUBROUTINES TO GRAB/RELEASE PORT ON DUAL-PORTED RP04567
IFE FT.MTA,<
;LOCK PORT - return +1 failure, +2 success
LKPORT: SKIPN PORTLK ;Can we do it?
RETSKP ;No, wrong device type
ADJSP P,2 ;Make room for 2 AC's
DMOVEM T1,-1(P) ;Save T1-T2
MOVEI T2,TIMOUT ;Timer count
JRST LKPT2 ;Skip channel clear and enter loop
;This loop is coded this way to preserve the channel status
;if our little nest of timeouts actually times out and we branch
;to the ERRTYP code
LKPT1: IOOP(CLEAR) ;No, try clearing channel and unit
;Cover the case where an IO error or popped LAP plug has
;caused Volume-Valid to be cleared
LKPT2: MOVE T1,[R4%CPA!LR!GO] ;Do pack acknowledge and attempt to seize port
CALL RHWT1 ;Send to drive
MOVSI T1,(R4%CSR) ;Get port-status
CALL RHRD1
TXNN T1,CR.DVA ;Drive available?
JRST LKPT3 ;No, try again
MOVSI T1,(R4%DSR) ;Get device status
CALL RHRD1
TXNE T1,DS.PGM ;Programmable?
TXZ T1,DS.ATA ;yes. Ignore attention status then as
; dual-ported drives roll attentions!
ANDI T1,DS.MSK ;Keep only appropriate bits
CAIN T1,DS.GUD ;Drive OK?
JRST LKPTRS ;Yes, return success
LKPT3: SOJG T2,LKPT1 ;Keep trying
JRST LKPTR ;Timeout error, return failure
;UNLOCK PORT - returns +1 always
UKPORT: SKIPN PORTLK ;Can we do it?
RET ;No, wrong device type
ADJSP P,2 ;Make room for 2 AC's
DMOVEM T1,-1(P) ;Save T1-T2
IOOP(CLEAR) ;Clear channel and unit
MOVSI T1,(.TMDSR) ;Get status
CALL RHRD1
TXNN T1,DS.PGM ;Still in AB mode?
JRST LKPTR ;No, so no problem with it being locked
MOVE T1,[R4%CSR!LR!R4%REL!GO] ;Get unlock command
CALL RHWT1 ;Send to drive
JRST LKPTR ;Return
;Restore AC's
LKPTRS: AOS -2(P)
LKPTR: DMOVE T1,-1(P) ;Restore T1-T2
ADJSP P,-2 ;Back up stack pointer
RET
;Routine to check if the dual port is still ours
CKPORT: SKIPN PORTLK ;Dual-ported device?
JRST RSKP ;No, so we always have the port
MOVSI T1,(R4%CSR) ;Get port-status
CALL RHRD1
TXNN T1,CR.DVA ;Drive available?
RET ;No, return failure
MOVSI T1,(.TMDSR) ;Get device status
CALL RHRD1
;If VV is reset, we may have lost+regained port
;if DPR is reset, we have lost port
TXNE T1,DS.VV ;Have we lost Volume Valid?
TXNN T1,DS.DPR ;Is drive present?
RET ;Return failure, port ownership in question
JRST RSKP ;Return success
> ;End IFE FT.MTA
COMMENT \
;This routine can be called from REDPAG/WRTPAG to monitor
;disk addresses
REPORT: PUSH P,Q1
PUSH P,Q2
PUSH P,Q3
MOVEI Q2,[ASCIZ/DSKADR: /]
CALL OUTSTR
MOVE Q2,P5 ;Get the address
CALL OUTOCT ;Output it
MOVEI Q2,[ASCIZ/ CHAN: /]
CALL OUTSTR
MOVE Q2,CHAN
CALL OUTOCT
MOVEI Q2,[ASCIZ/ UNIT: /]
CALL OUTSTR
MOVE Q2,UNIT
CALL OUTOCT
MOVEI Q2,[ASCIZ/ CYL: /]
CALL OUTSTR
MOVE Q2,CYLIND
CALL OUTOCT
MOVEI Q2,[ASCIZ/ SEC-TRK: /]
CALL OUTSTR
MOVE Q2,SECTRK
CALL OUTOCT
CALL CRLF
POP P,Q3
POP P,Q2
POP P,Q1
RET
\ ;End comment
IFE FT.MTA, <
;Calculate sector,cylinder,track addresses
IOCALC:
CALL GETPHY ;GET PHYSICAL ADDR IN T1
$ERROR (MEMMRF) ;BAD ADDRESS
IFN KLFLG, <
;Setup CCW list
JUMPN T1,IOSET1 ;PAGE 0?
MOVSI T1,(EXP 1B0+<LCORAD>B13) ;YES - SKIP FIRST FEW WDS
MOVEM T1,ICCW ;STORE AS FIRST ELEMENT
MOVE T1,[EXP 1B0+1B1+<1000-LCORAD>B13+LCORAD]
MOVEM T1,ICCW+1 ;SECOND AND LAST CCW
JRST IOSETW ;Go set up device-addresses
IOSET1: TLO T1,(EXP 1B0+1B1+<1000>B13) ;BUILD CCW
MOVEM T1,ICCW ;STORE
JRST IOSETW ;Go set up device-addresses
> ; END OF IFN KLFLG
IFE KLFLG, <
MOVEI T3,-1000 ;COUNT
JUMPN T1,IOS.CM ;READ/WRITE PAGE 0?
MOVE T3,[IOWD LCORAD,LCORAD] ;YES - MUST SKIP FIRST FEW WDS
MOVEM T3,2(T2) ;STORE SKIP COMMAND
MOVEI T1,LCORAD ;NEW ADDRESS
MOVEI T3,-<1000-LCORAD> ;NEW COUNT
ADDI T2,1 ;BUMP CCW ADDR
IOS.CM: SOS T1 ;IOWD WANTS ADDR -1
HRL T1,T3 ;INSERT COUNT
MOVEM T1,2(T2) ;STORE COMMAND LIST
SETZM 3(T2) ;0 AT END OF LIST
> ; END OF IFE KLFLG
IOSETW: MOVE T1,P5 ;GET DISK ADDRESS
TLZ T1,777774 ;KEEP JUST THE ADDRESS BITS
MOVE T2,DSKTYP ;FIND TYP
CAIN T2,.R7TYP
JRST [ IDIVI T1,N.SCL7 ;RP07?
JRST IOSETC]
CAIN T2,.R3TYP ;RM03?
JRST [ IDIVI T1,N.SCL3
JRST IOSETC]
IDIVI T1,N.SCL4 ;GET CYLINDER IN T1, SECTOR IN T2
IOSETC: PUSH P,T2 ;Save sector
IDIV T1,NUMCYL ;GET UNIT NUMBER IN T1, CYL IN T2
MOVEM T2,CYLIND ;Save cylinder address
HRRZ P3,DSKTAB(T1) ;GET PHYSICAL UNIT NUMBER
MOVEM P3,UNIT ;Save it here
HLRZ T1,DSKTAB(T1) ;GET CHANNEL #, ENTRY-IN-USE FLAG
TRZ T1,ENTFLG ;KEEP JUST THE CHANNEL NUMBER
MOVEM T1,CHAN ;Save it here
HRRI F,RH0_-2(T1) ;GET IO DEVICE CODE
LSH T1,2 ;GET CHANNEL * 4
MOVE T3,[1B1+ICCW] ;GET JUMP CCW
MOVEM T3,A%EPT+ICA(T1) ;STORE JUMP CCW IN EPT FOR RH20
POP P,T1 ;Restore sector #
MOVE T2,DSKTYP ;GET DISK TYPE AGAIN
CAIN T2,.R7TYP ;RP07?
SKIPA T2,[N.STK7] ;YES
MOVEI T2,N.STK4 ;NO
IDIVI T1,(T2) ;GET TRACK # IN T1, SECTOR IN T2
LSH T1,^D8 ;POSITION THE TRACK # FOR DATAO
IOR T1,T2 ;ADD A PINCH OF SECTOR
MOVEM T1,SECTRK ;Save sector and track
RET ;Return
> ; END OF IFE FT.MTA
IFN FT.MTA,<
;HERE TO SETUP THE CHANNEL FOR TAPE IO
TAPIO: HRR F,CHAN ;Get RH #
ADDI F,RH0_-2 ;Produce device code for that RH
LDB P3,PKON ;GET TM02
LDB T4,PCHAN ;GET CHANNEL NUMBER
CALL XIO1 ;GET DEVICE CODE
CONO .-.,.RHMBE!.RHRAE!.RHCTE!.RHDON ; RESET RH20
CALL @TAPSIO(P6) ;SET CONTROLLER TO START THE IO
MOVE T1,[EXP .TMATR!LR+377] ;CLEAR ATTN
CALL RHWT ;
MOVE T1,[EXP 1B1+ICCW] ;CHANNEL JUMP TO ICCW
LSH T4,2 ;COMPUTE OFFSET INTO EPT
MOVEM T1,A%EPT+ICA(T4) ;STORE
CALL GETPHY ;GET PHYS ADDR
$ERROR (MEMMRF) ;BAD ADDRESS
JUMPN T1,TAPIO1 ;PAGE 0?
MOVSI T1,(EXP 1B0+<LCORAD>B13) ;YES - SKIP FIRST FEW WDS
MOVEM T1,ICCW ;STORE AS FIRST ELEMENT
MOVE T1,[EXP 1B0+1B1+<1000-LCORAD>B13+LCORAD]
MOVEM T1,ICCW+1 ;SECOND AND LAST CCW
JRST TAPIO2 ;GO DO IO
TAPIO1: TLO T1,(EXP 1B0+1B1+<1000>B13) ;BUILD CCW
MOVEM T1,ICCW ;STORE
TAPIO2: MOVE T1,[EXP .RHSTR!LR!RCLP+.TMRDF+1777B29] ;SEND COMMAND
CALL RHWT ; ...
MOVSI T2,1 ;SET WAIT COUNT
TAPWAT: CALL IOXCT ;GET DEVICE CODE
CONI .-.,T1 ;GET DEVICE STATUS
TRNN T1,.RHDON ;DONE ?
SOJG T2,TAPWAT ;NO - LOOP
TRNN T1,775000 ;ERRORS+
JUMPG T2,CPOPJ ; NO - EXIT
JRST CPOPJ1 ;YES - SKIP
BSPACE: CALL IOXCT ;GET IO CODE
CONO .-.,2000 ;RESET THE RH20 BEFORE
CALL IOXCT ; DOING BACKSPACE
CONO .-.,4600 ;...
CALL @STRTMP(P6) ;START THE MICRO PROCESSOR (IF DX20)
CALL @BACKRC(P6) ;BACKSPACE A RECORD
MOVSI T2,5 ;TIMED WAIT
CALL @BKWAIT(P6) ;WAIT FOR BACKSPACE TO FINISH
MOVE T1,[EXP .TMATR!LR+377] ;CLEAR ATTN
CALL RHWT ;
SKIPN T2 ;TIMEOUT?
$ERROR (TAPHTE) ;YES - HARD TAPE ERROR
RET ;NO
PCHAN: POINT 6,DSKTAB,23 ;POINTER TO CHAN NUMBER
PKON: POINT 6,DSKTAB,29 ;POINTER TO KON NUMBER
PUNIT: POINT 6,DSKTAB,35 ;POINT TO TAPE UNIT
> ;END IFN FT.MTA
RHRD: TLZ T1,(LR) ;NO WRITE
RHWT: TSO T1,P3 ;INSERT TM02
RHDIO: CALL IOXCT ;Here to avoid insertion of unit #
DATAO .-.,T1 ;SEND COMMAND
CALL IOXCT
DATAI .-.,T1 ;READ RESULT
RET
IFN FT.MTA,<
;START IO
TAPSIO: TM2SIO
DX2SIO
TM8SIO
;START MICROPROCESSOR
STRTMP: R
STDX20
R
;BACKSPACE RECORD
BACKRC: TM2BSR
TM2BSR
TM8BSR
;WAIT FOR BACKSPACE TO FINISH
BKWAIT: BWAIT
BXWAIT
R ;(WAITED WHEN WE STARTED IT)
TM2SIO: MOVEI T1,TMCD16 ; SET DENSITY
LDB T2,PUNIT ;GET DRIVE NUMBER
IOR T1,T2 ; ...
HRLI T1,(.TMTCR!LR) ;TAPE CONTROL REG
CALLRET RHWT ; ...
DX2SIO: LDB T1,PUNIT ;PICK UP UNIT NUMBER
TRO T1,.TDMOD ;SET THE MODES
TXO T1,.TDDNR!LR ;GOES INTO DRIVE NUMBER REG
CALL RHWT ;LOAD THE REG
MOVX T1,<<-1000*5>&177777> ;SET CORRECT RECORD SIZE
TXO T1,.TMFCR!LR ;GOES INTO BYTE COUNT REG
CALL RHWT ;SET RECORD SIZE
MOVX T1,.TMDSR ;GET THE DEVICE STATUS REG
CALL RHRD ;
TXNN T1,.TDMPR ;MAKE SURE IT IS STILL RUNNING
CALL STDX20 ;IF NOT, START IT
RET
TM8SIO: MOVEI T1,5000 ;SET THE BYTE COUNT REGISTER
HRLI T1,(LR!.T7BC) ;TELL THE HARDWARE HOW MUCH WE'LL READ
CALL RHWT
LDB T1,PUNIT ;SLAVE NUMBER
TRO T1,T7.SER!T7.CDP!T7.1RC ;NO ERROR REPOS, CORE DUMPE, 1 RECORD
HRLI T1,(.T7FMT!LR) ;WRITE THE FORMAT REG
CALLRET RHWT
TM2BSR: MOVE T1,[EXP .TMFCR!LR+177777] ;REPEAT COUNT
CALL RHWT ;
MOVE T1,[EXP .TMCSR!LR+.TMBSF] ;DO BACKSPACE
CALLRET RHWT ;
TM8BSR: MOVEI T1,T7.BSR_6 ;BACK 1 RECORD
PUSH P,P2
MOVE P2,P3
LDB P3,PUNIT ;GET ACS RIGHT
CALL T78.ND ;DO IT AND WAIT TILL DONE
POP P,P2
LDB P3,PKON ;RESTORE ACS
RET
BWAIT: MOVSI T1,(.TMDSR) ;WAIT FOR NO POSN
CALL RHRD ;
TRNE T1,TMSPIP ;DONE YET?
SOJG T2,BWAIT ;NO
RET
BXWAIT: MOVX T1,.TMDSR ;READ THE STATUS REG
CALL RHRD ;
TRNN T1,.TDATB ;ATTENTION UP?
SOJG T2,BXWAIT ;NO, LOOP
RET
IFE FT.DX2,<
DX2SIO:
STDX20:
BXWAIT: RET
>
IFE FT.TM8,<
TM8SIO:
TM8BSR: RET
>
> ; END OF IFE FT.MTA
> ; END OF IFE SMFLG
IFN SMFLG,<
P.NOS: TLO F,(F.STRT!F.CLR!F.ACT)
RET
REDPAG: SKIPA T1,[R4%CRD!GO] ;RH11 READ
WRTPAG: MOVEI T1,R4%CWR!GO ;RH11 WRITE
AOS FILPAG ;INCREMENT FILE PAGE #
PUSH P,TIMLOC ;SAVE A LOW CORE LOCATION
PUSH P,RELWD ;SAVE RELOAD REASON ALSO
PUSH P,P1 ;SAVE A REGISTER
PUSH P,P2 ;SAVE COUNTER
IFN FT.MTA,<
MOVEI P2,^D100 ;RETRY 100
MOVE T4,T1 ;GET COMMAND CODE
MRETRY: CALL TAPIO ;DO TAPE I/O
JRST RWSXIT ;WIN
SKIPN P2 ;DO RETRY?
$ERROR (TAPHTE) ;NO
CALL BSPACE ;YES -- BACKSPACE
JRST MRETRY ;RETRY
> ;END IFN FT.MTA
IFE FT.MTA,<
MOVEI P2,5 ;RETRY COUNTER
DRETRY: PUSH P,T1 ;SAVE RP04 COMMAND
MOVE T1,P5 ;GET DISK ADDRESS
TLZ T1,777774 ;KEEP JUST THE ADDRESS BITS
MOVE T2,DSKTYP ;FIND TYPE
CAIN T2,.R3TYP ;RM03?
JRST [ IDIVI T1,N.SCL3 ;DO RM03 CONVERSION
JRST DRETR3]
IDIVI T1,N.SCL4 ;GET CYL IN T1, SECTOR IN T2
DRETR3: PUSH P,T2 ;SAVE CYL
IDIV T1,NUMCYL ;GET UNIT AND CYL
HLRZ P1,DSKTAB(T1) ;FIND UNIT ADDRESS
TRZ P1,ENTFLG
HRRZ P3,DSKTAB(T1) ;GET PHYSICAL UNIT NUMBER
MOVEI T1,RH1CLR ;CLEAR RH11
WRIO T1,@RPCS2(P1)
WRIO P3,@RPCS2(P1) ;SET UNIT NUMBR
HRRZ T1,T2 ;SET DESIREC CYL
WRIO T1,@RPDC(P1) ;SET DESIRED CYL
POP P,T1 ;RESTORE SECTOR WITHIN CYL
MOVE T2,DSKTYP ;GET TYPE
CAIN T2,.R3TYP ;RM03?
JRST [ IDIVI T1,N.STK3
JRST DRETR4]
IDIVI T1,N.STK4 ;GET TRACK # IN T1, SECTOR IN T2
DRETR4: LSH T1,^D8 ;POSITION IN THE TRACK #
IOR T1,T2 ;ADD THE ECTION
WRIO T1,@RPDA(P1) ;SET DESIRED ADDRESS REG
POP P,T4 ;RESTORE ORIG INSTRUCTION
CALL GETPHY ;GET PHYSICAL ADDR IN 1
$ERROR (MEMMRF) ;BAD ADDRESS
;
; ON THE SM10 LCORAD IS NOT USED SINCE IT IS LEGAL TO TRANSFER
; INTO LOW CORE (SHADOW AC'S) AND IT IS NECESSARY SINCE RH11
; WILL NOT PERMIT THE TRANSFER IN THE MIDDLE OF A BLOCK
;
IOSET1: LSH T1,-^D9 ;SET CORE ADDRESS
IORI T1,UNVBIT!UN36B ;SET UNIBUS VALID BIT
WRIO T1,@UNBMAP(P1) ;SET UNIBUS MAP
SETZ T1,0 ;SET THE UNIBUS ADDRESS TO 0
WRIO T1,@RPBA(P1)
MOVNI T1,RPPGSZ ;SET PAGE SIZE
WRIO T1,@RPWC(P1) ;SET SIZE OF TRANSFER
TRYIT: CALL DOIO ;DO I/O
EXCH T1,T4 ;GET BACK ORIG COMMAND
JUMPG T4,RWSXIT ;IF NO ERROSR , EXIT SUCCESS
SOJG P2,DRETRY ;GO RETRY TIL COUNT EXHAUSTED
JRST RWFXIT ;OP FAILED
> ; END IFE FT.MTA
RWSXIT: AOS -4(P) ;SKIP RETURN
RWFXIT: POP P,P2 ;RESTORE P2
MOVEI T1,RH1IE
WRIO T1,@RPCS1(P1)
POP P,P1 ;RESTORE P1
POP P,RELWD ;RESTORE RELOAD REASON
POP P,TIMLOC ;RESTORE LOW CORE
RET ;RETURN
DOIO: MOVSI T1,2 ;SAVE DELAY COUNT
WRIO T4,@RPCS1(P1) ;DO COMMAND
MOVEI T2,RH1RDY ;WAIT FOR READY
WAIT: TION T2,@RPCS1(P1)
SOJG T1,WAIT ;WAIT FOR DONE
JUMPLE T1,CPOPJ ;RETURN
MOVEI T2,RH1TRE ;CHECK FOR ERROR
TIOE T2,@RPCS1(P1) ;CHECK STATUS
SETOI T1, ;YES SET T1 MINUS AS FLAG
RET ;RETURN
IFN FT.MTA,<
TAPIO: LDB P1,PCHAN ;GET THE CHANNEL
LDB P3,PKON ;GET THE TM02 UNIT NUMBER
WRIO P3,@RPCS2(P1) ;SET CHANNEL
LDB T1,PUNIT ;GET SLAVE UNIT
IORI T1,TMCD16 ;SET 1600BPI
WRIO T1,@RPDC(P1) ;SET IT
CALL GETPHY ;GET PHYSICAL ADDRESS
$ERROR (MEMMRF) ;BAD ADDRESS
IOSET1: LSH T1,-^D9 ;SET CORE ADDRESS
IORI T1,UNVBIT ;SET UNIBUS VALID BIT
WRIO T1,@UNBMAP(P1) ;SET UNIBUS MAP
SETZ T1,0 ;SET THE UNIBUS ADDRESS TO 0
WRIO T1,@RPBA(P1) ;SET BUS ADDRESS
WRIO T1,@RPDA(P1) ;SET FRAME COUNTER TO 0
MOVNI T1,RPPGSZ ;SET PAGE SIZE
WRIO T1,@RPWC(P1) ;SET WORD COUNT REGISTER
CALL DOIO ;DO I/O
JUMPGE T1,CPOPJ ;OK RETURN
RDIO T1,@RPER1(P1) ;READ ERROR REGISTER
TRNN T1,75377
JRST CPOPJ1
JRST CPOPJ
BSPACE: MOVEI T1,40000 ;RESET RH11
WRIO T1,@RPCS1(P1)
MOVEI T1,-1 ;BACKSPACE 1
WRIO T1,@RPDA(P1) ;FRAME COUNT -1 (1 RECORD
PUSH P,T4 ;SAVE PREVIOUS COMMAND
MOVEI T4,.TMBSF ;BACKSPACE
CALL DOIO ;DO BACKSPACE
SKIPA ;WAIT
$ERROR (TAPHTE) ;HARD TAPE ERROR
POP P,T4 ;RESTORE COMMAND
MOVEI T1,TMSPIP ;CHECK FOR PIP
TIOE T1,@RPDS(P1)
JRST .-1
RET
PCHAN: POINT 6,DSKTAB,23 ;POINTER TO CHANNEL NUMBER
PKON: POINT 6,DSKTAB,29 ;POINTER TO TM02 NUMBER
PUNIT: POINT 6,DSKTAB,35 ;POINT TO TAPE UNIT
> ;END IFN FT.MTA
> ;END IFN SMFLG
;SUBROUTINE TO GET THE PHYSICAL ADDRESS CORRESPONDING
;TO THE ADDRESS IN P4 (EITHER PHYS OR VIRT DEPENDING ON F.PHYS)
;RETURN THE RESULT IN T1
;RETURNS NON-SKIP IF THE ADDR PAGE FAULTS OR NXMS
; PAGE TABLE SLOT USED FOR THIS TEST IS FOR THE LAST FREE PAGE BEFORE VBOOT
TSTSLT== <VFREE>+A%PTB ;PAGE TABLE SLOT FOR TESTING
;I.E., THE SLOT IN A%PTB CORRESPONDING TO PAGE
; VFREE
TSTADD==<VFREE>_9 ;ADDRESS OF TEST PAGE
GETPHY: MOVE T1,P4 ;COPY ADDRESS
LSH T1,-9 ;CONVERT ADDRESS TO PAGE NUMBER
TXNE F,F.PHYS ;PHYSICAL ADDRESS FOR ARGUMENT ?
JRST GPY.P0 ;YES, GO TEST FOR EXTANT PAGE
; ARGUMENT IS A VIRTUAL ADDRESS - CONVERT TO PHYSICAL AND TEST
MAP T1,(P4) ;GET PHYSICAL PAGE NUMBER
IFN KLFLG!SMFLG,<
TLNN T1,(1B2) ;IS PAGE ACCESSIBLE ?
RET ;NO, RETURN
> ;END IFN KLFLG!SMFLG
IFN KCFLG,<
TXNN T1,MPHPFF ;HARD FAILURE?
TXNN T1,MPVALD ;NO. VALID MAPPING?
RET ;NO. RETURN
> ;END IFN KCFLG
TLZ T1,777760 ;YES, CLEAR ALL BITS BUT ADDRESS
LSH T1,-^D9 ;CONVERT ADDRESS TO A PAGE #
; HERE WITH A PHYSICAL ADDRESS TO TEST
;NOT ALL PHYSICAL PAGES MAY BE IN THE VIRTUAL MAP, SO FOR TESTING WE
;TEMPORARILY SNEAK THE PHYSICAL ADDRESS INTO A PAGE-TABLE SLOT AND TRY
;TO REFERENCE THE VIRTUAL PAGE ASSOCIATED WITH THAT SLOT.
;* * * *
;Work on this when the KC supports NXM. For now assume success
;The processor will probably hang if we're wrong
; * * * *
GPY.P0: TXO T1,IMMPTR ;FORM IMMEDIATE POINTER (+WRITEABLE+CACHEABLE)
PUSH P,TSTSLT ;SAVE EXISTING PAGE TABLE ENTRY
MOVEM T1,TSTSLT ;MAP PAGE TO BE TESTED
CLRPT TSTADD ;CLEAR PAGER ENTRY FOR TSTADD PAGE
IFN KLFLG!SMFLG,<
CONO APR,AP.RNX ;TURN OFF NXM FLAG
> ;END IFN KLFLG!SMFLG
SKIP TSTADD ;REFERENCE VIRTUAL PAGE
HRRZ T1,TSTSLT ;GET PHYSICAL PAGE #
LSH T1,9 ;CONVERT TO PHYSICAL ADDRESS
POP P,TSTSLT ;RESTORE ORIGINAL MAP ENTRY
CLRPT TSTADD ;The Gene Leache memorial instruction
;Clear pager entry for TSTADD page
IFN KLFLG!SMFLG,<
CONSO APR,AP.NXM ;NXM ON REFERENCE ?
JRST CPOPJ1 ;NO, GIVE GOOD RETURN
CONO APR,AP.RNX ;YES, RESET NXM FLAG
RET ;RETURN BAD
> ;END IFN KLFLG!SMFLG
IFN KCFLG,<
JRST CPOPJ1
>
;SUBROUTINE TO TEST IF A GIVEN VIRTUAL ADDRESS IS LEGAL
;VIZ DOES THE ADDR PAGE FAIL, NXM , OR POINT TO A VBOOT PAGE?
;IF SO, RETURN NON SKIP
;FIRST, SEE IF THE ADDRESS SURVIVES PAGE-FAIL OR NXM TEST
TSTADR: MOVE T1,P4 ;GET ADDR TO TEST
LSH T1,-9 ;CONVERT TO PAGE
CAMG T1,UPRLIM ;BELOW UPPER LIMIT?
CAMGE T1,LWRLIM ;ABOVE LOWER LIMIT?
RET ;NO - BAD
CALL GETPHY ;CONVERT TO PHYSICAL ADDR
RET ;BAD RETURN FROM GETPHY
PUSH P,P4 ;SAVE DEST
PUSH P,F ;SAVE FLAGS
TLZ F,(F.PHYS) ;TEST VIRT ADDR
MOVE T2,T1 ;PHYS ADDR
MOVEI P4,A%VFST ;START OF VBOOT AREA
;OK SO FAR, SEE IF THE PHYSICAL ADDRESS CORRESPONDS TO THE
;PHYSICAL ADDRESS OF ANY VBOOT PAGES - IF SO, GIVE BAD RETURN
TA.NXT: CALL GETPHY ;CONVERT TO PHYS ADDR
$ERROR (MEMMRF) ;IMPOSSIBLE CONDITION
CAMN T1,T2 ;SAME AS TARGET ADDR?
JRST TA.BAD ;YES - FAIL RETURN
ADDI P4,1000 ;NO - TRY NEXT PAGE
CAIG P4,VORG_9 ;CHECKED ALL PAGES?
JRST TA.NXT ;NO - LOOP FOR MORE
AOS -2(P) ;SKIP RETURN (THIS IS PRETTY BAD...)
TA.BAD: POP P,F ;RESTORE FLAGS
POP P,P4 ;RESTORE ADDRESS
RET ;NON-SKIP RETURN
;ERROR MESSAGES
DEFINE ERSTR (SYM,SNAM,FNAM,DVSTS,TEXT),
< SYM==%COUNT
IFG SNAM,<%SNAM=%SNAM!<1B<%COUNT>>> ;;TYPE STRUCTURE NAME
IFG FNAM,<%FNAM=%FNAM!<1B<%COUNT>>> ;;TYPE FILE NAME
IFG DVSTS,<%DVSTS=%DVSTS!<1B<%COUNT>>> ;;TYPE DEVICE STATUS
%COUNT=%COUNT+1
[ASCIZ/TEXT/]
>
ERRPFX: [ASCIZ/ ?BOOT: /]
%COUNT==0 ;RESET COUNTER
%SNAM==0 ;STRUCTURE NAMES
%FNAM==0 ;FILE NAMES
%DVSTS==0 ;DEVICE STATUS
ERRTAB: ERSTR (IOER2,1,1,1,IO error - can't read super-index block)
ERSTR (IOER3,1,1,1,IO error - can't read index block)
ERSTR (IOER4,1,1,1,IO error - can't read directory page)
ERSTR (IOER6,1,1,1,IO error - can't read EXE-directory page)
ERSTR (IOER7,1,1,1,IO error - can't read data page)
ERSTR (IOER8,1,1,1,IO error - can't write data page)
ERSTR (IOER9,1,1,1,IO error - can't write EXE-directory page)
ERSTR (IOER10,1,0,1,IO error - can't read root-directory index block)
ERSTR (IOER11,0,0,1,IO error - Port-seize logic timed out)
ERSTR (TAPHTE,0,0,1,Hard tape error)
ERSTR (FILFNF,1,1,0,File not found)
ERSTR (FILNEF,1,1,0,File not in EXE format)
ERSTR (FILDRP,1,1,0,File's EXE-directory is longer than 1 page)
ERSTR (STRHOM,1,0,0,Bad home block)
ERSTR (STRSNF,1,0,0,Structure not found)
ERSTR (STRNID,1,0,0,No structure ID)
ERSTR (STRNBS,0,0,0,Can't find bootable structure)
ERSTR (STRMTO,0,0,0,More than 1 bootable structure found)
ERSTR (DMPFTS,0,0,0,Dump error - DUMP.EXE is too small: reconfigure with MAKDMP)
ERSTR (COMERR,0,0,0,Command error)
ERSTR (COMUNS,0,0,0,Unknown switch)
ERSTR (COMINV,0,0,0,Invalid numeric value)
ERSTR (MEMMRF,0,0,0,Memory reference failed)
ERSTR (TAPNDR,0,0,0,No ready tape-drive available)
%SNAM==%SNAM ;FORCE INTO LISTING
%FNAM==%FNAM
%DVSTS==%DVSTS
;SUBROUTINE TO CLEAR CORE
CLRCOR: SETOI P4, ;INITIALIZE ADDRESS
IFN SMFLG,<
PUSH P,RELWD ;SAVE RELOAD WORD
>
CLR.NP: ADDI P4,1000 ;NEXT PAGE
TLNE P4,-1 ;DONE 256K?
IFE SMFLG,<
RET
>
IFN SMFLG,<
JRST [ POP P,RELWD
RET]
>
CALL TSTADR ;NO - TEST IF ADDRESS LEGAL
JRST CLR.NP ;NOT LEGAL - TRY NEXT PAGE
MOVE T1,P4 ;COPY ADDRESS
TRZ T1,777 ;CLEAR LOW ORDER BITS
SKIPN T1 ;PAGE ZERO?
MOVEI T1,LCORAD ;YES - START AT LOC LCORAD
CLR.NW: SETZM (T1) ;CLEAR A WORD OF THE PAGE
CAIGE T1,(P4) ;DONE?
AOJA T1,CLR.NW ;NO - LOOP FOR MORE OF THIS PAGE
JRST CLR.NP ;YES - LOOP FOR MORE
IFE FT.EXE, <
;ROUTINE TO GET A FILE FROM DISK TO MEMORY
;THE VIRTUAL ADDRESSES NEEDED BY THE FILE ARE ASSUMED
;TO HAVE BEEN MAPPED BY THE CALLER
GET: SETZM MONFLG ;INDICATE NO SPECIAL ASSUMPTIONS ABOUT FILE
MOVEI P4,A%FP0 ;READ FILE PAGE ZERO
MOVE P5,A%XB ; DISK ADDR FROM XB
CALL REDPAG ;READ THE PAGE
$ERROR (IOER6) ;CAN'T READ DIRECTORY PAGE
HLRZ T1,A%FP0 ;CHECK FORMAT CODE
CAIE T1,1000 ;CODE OK?
$ERROR (FILNEF) ;NO
TLNE F,(F.CLR) ;CLEAR CORE?
CALL CLRCOR ;YES - CALL SUBR
MOVN P1,A%FP0 ;OK - GET COUNT OF PAGES
HRLZS P1 ;BUILD POINTER WORD
HRRI P1,A%FP0+1 ;FIRST DATA WORD
GET.NP: MOVE T1,(P1) ;GET PAGE DESCRIPTOR
MOVE P5,A%XB(T1) ;GET DISK ADDRESS OF PAGE
LDB P4,[POINT 9,T1,17] ;GET MEMORY PAGE ADDR
LSH P4,9 ;CONVERT PAGE NO. TO ADDRESS
CALL TSTADR ;CHECK IF ADDRESS IS LEGAL
JRST GT.NP1 ;NO - SKIP READ
CALL REDPAG ;READ THE PAGE
$ERROR (IOER7) ;CAN'T READ DATA PAGE
GT.NP1: AOBJN P1,GET.NP ;BACK FOR MORE
SKIPG P3,(P1) ;IF POSITIVE, IS IMMED. ADDR
MOVE P3,(P3) ;IF NEG, IS POINTER
CALLRET SETSA ;SET STARTING ADDR AND RETURN
;ROUTINE TO SAVE MEMORY
;ONLY THOSE PAGES WHICH ARE MAPPED ARE SAVED.
SAVE: MOVEI Q2,[ASCIZ/[BOOT: DUMPING] /]
CALL OUTSTR
MOVEI T1,^D50 ;GET REPORT LIMIT FOR DUMP ERRORS
MOVEM T1,DERCNT ;KEEP IT HERE
MOVE T1,[XWD A%FP0,A%FP0+1] ;CLEAR DESCR PAGE
SETZB P2,A%FP0 ; ...
BLT T1,A%FP0+777 ; ...
TLNE F,(F.DUMP) ;DUMP?
TLO F,(F.PHYS) ;YES - USE PHYSICAL ADDRESSES.
SETOI P1, ;INITIALIZE ADDR
SETZM PGCNT ;ZERO COUNT OF DISK PAGES WRITTEN
TXZ F,F.DPER ;RESET DUMP ERROR FLAG
SAV.NP: ADDI P1,1000 ;NEXT PAGE
TLNE P1,-1 ;DONE ALL?
JRST SAV.DN ;YES - WRITE DESCR PAGE
MOVE P4,P1 ;NO - SAVE ADDR FOR WRITE
CALL TSTADR ;IS THIS ADDRESS LEGAL?
JRST SAV.NP ;NO - TRY NEXT PAGE
LSH P4,9 ;MASK LOW ORDER BITS
HLLZS T1,P4 ;SAVE PAGE FOR DESCR
LSH P4,-9 ;RECOVER ADDRESS
TLO T1,520000 ;READ,WRITE,EXECUTE ACCESS
HRRI T1,2(P2) ;FILE PAGE NUMBER
MOVEM T1,A%FP0+1(P2) ;STORE DESCRIPTOR
SKIPN P5,A%XB+2(P2) ;PHYS DISK ADDR - SKIP IF NONE
JRST SV.NP1
CALL WRTPAG ;WRITE THE PAGE
$ERROR(IOER8) ;COULDN'T WRITE IT
SV.NP1: AOJA P2,SAV.NP ;NEXT PAGE
SAV.DN: SKIPE T1,START ;NONZERO START ADDR?
HRLI T1,(<JRST>) ;YES - BUILD SHORT ENTRY
MOVEM T1,A%FP0+1(P2) ;STORE IN DESCR PAGE
TLO P2,1000 ;FINISH DESCRIPTOR BLOCK
MOVEM P2,A%FP0 ;BY STORING TYPE AND COUNT
TLZ F,(F.PHYS) ;CLEAR PHYSICAL ADDRESS REQUEST
MOVEI P4,A%FP0 ;PREPARE FOR FINAL WRITE
MOVE P5,A%XB ; ...
CALL WRTPAG ;WRITE THE DESCR PAGE AND RETURN
$ERROR(IOER9) ;COULDN'T WRITE DIRECTORY PAGE
MOVEI Q2,[ASCIZ/[OK]
/]
CALL OUTSTR
RET
> ; END OF IFE FT.EXE
IFN FT.EXE, <
; EXE BLOCK TYPE DISPATCH TABLE
EXETAB: .EXDIR ,, G.DIR
.EXEND ,, R
.EXENT ,, G.ENT
.EXPDV ,, G.PDV
EXESIZ==.-EXETAB
; ROUTINE TO GET A FILE FROM DISK TO MEMORY. READS EXE FORMAT FILES.
GET: IFN FT.MTA,< ;ONLY FOR MAGTAPE
SKIPE DIRFLG ;EXE DIRECTORY READ YET ?
JRST G.CLR ;YES, DO NOT READ IT AGAIN
SETOM DIRFLG ;NO, INDICATE WE HAVE READ EXE DIR
> ;END OF IFN FT.MTA CONDITIONAL
SETZM FILPAG ;INITIALIZE FILE PAGE #
MOVEI P4,A%FP0 ;READ INTO FILE PAGE 0
MOVE P5,A%XB+0 ;EXE DIRECTORY IS PAGE 0 OF FILE
CALL REDPAG ;READ THE EXE DIRECTORY PAGE
$ERROR (IOER6) ;CAN'T READ DIRECTORY PAGE
G.CLR: ; ** REMOVED NEXT 2 INSTRUCTIONS UNTIL MAP INSTR FIXED **
TXNE F,F.CLR ;CLEAR CORE ?
CALL CLRCOR ;YES, GO ZERO SOME MEMORY
MOVEI P1,A%FP0 ;INITIALIZE EXE DIRECTORY POINTER
G.DSP: HLRZ T1,(P1) ;GET BLOCK TYPE FROM DIRECTORY
MOVSI T2,-EXESIZ ;FORM AOBJN POINTER TO TYPE TABLE
G.DSP1: HLRZ T3,EXETAB(T2) ;GET A KNOWN BLOCK TYPE CODE
CAMN T3,T1 ;FOUND A VALID BLOCK TYPE ?
JRST G.GO ;YES, GO PROCESS THE BLOCK
AOBJN T2,G.DSP1 ;NO, GO CHECK REMAINING VALID CODES
$ERROR (FILNEF) ;BAD FORMAT
G.GO: HRRZ T1,EXETAB(T2) ;GET ADDRESS OF PROCESSING ROUTINE
JRST (T1) ;GO PROCESS BLOCK
; HERE TO PROCESS EXE FILE DIRECTORY BLOCK
G.DIR: HRRZ P2,(P1) ;GET # OF WORDS IN EXE DIRECTORY
SUBI P2,1 ;GET # OF WORDS IN DIRECTORY - 1
ADDI P1,1 ;POINT TO FIRST 2-WORD DESCRIPTOR
G.DIR0: LOAD Q2,DIRPT,(P1) ;GET REPEAT COUNT
ADDI Q2,1 ;GET # OF PAGES TO READ
LOAD P4,DIPRO,(P1) ;GET PROCESS PAGE #
LSH P4,9 ;CONVERT PAGE # TO ADDRESS
LOAD Q1,DIFIL,(P1) ;GET FILE PAGE #
G.DIR1: TXZ F,F.PHYS ;ASSUME VIRTUAL ADDRESS
SKIPG MONLOD ;DON'T DO THIS IF NOT FIRST PASS OF LOAD
CAIG P4,777777 ;IS THIS PAGE BEYOND OUR 1-SECTION
; VIRTUAL SPACE?
JRST G.DIR8 ;NO
TXO F,F.PHYS ;YES, CONSIDER IT PHYSICAL
G.DIR8: JUMPE Q1,G.DIR4 ;ALL ZERO PAGE, HANDLE SPECIALLY
MOVEI T1,TSTADR ;ASSUME THIS IS OUR CHECK ROUTINE
TXNE F,F.PHYS ;ARE WE WRITING TO A PHYSICAL PAGE?
MOVEI T1,GETPHY ;YES, USE THIS ROUTINE
CALL (T1) ;GO SEE IF MEMORY ADDRESS IS LEGAL
JRST G.DIR2 ;NOT LEGAL, GO TRY NEXT PAGE
IFN FT.MTA,< ;DOING MAGTAPE?
CAMGE Q1,FILPAG ;READING PAGE ALREADY PASSED ?
$ERROR (FILNEF) ;YES, CANNOT GO BACKWARDS ON TAPE
CAMLE Q1,FILPAG ;NEED NEXT SEQUENTIAL PAGE IN FILE ?
JRST [ PUSH P,P4 ;NO, SAVE CORE ADDRES
MOVEI P4,A%DIR ;GET A USELESS PAGE FOR DUMMY READ
CALL REDPAG ;READ NEXT SEQUENTIAL PAGE
$ERROR (IOER7) ;ERROR READING PAGE
POP P,P4 ;RESTORE ORIGINAL CORE ADDRESS
JRST G.DIR1 ] ;GO TRY AGAIN
> ;END OF IFN FT.MTA
SKIPGE XBNUM ;Long or short file?
JRST LODPAG ;Short, we always have correct XB
LDB T1,[POINT 18,Q1,26] ;Get index-block # for this file page
CAMN T1,XBNUM ;Correct XB currently loaded?
JRST LODPAG ;Yes
LOAD P5,IDXADR,A%SXB(T1) ;No, get the disk address of the correct one
SKIPG P5 ;Do we have an address?
$ERROR(FILNEF) ;EXE directory data and super-index block
; do not agree
MOVEM T1,XBNUM ;Set up XB # for soon-to-be loaded XB
PUSH P,P4 ;Save P4
PUSH P,F ;Save flags
TXZ F,F.PHYS ;Do virtual read for XB
MOVEI P4,A%XB ;Load XB here
CALL REDPAG ;Load it
$ERROR(IOER3) ;Failed
POP P,F ;Recover F
POP P,P4 ;Recover P4
LODPAG: MOVE T1,Q1 ;Get file page number
ANDI T1,777 ;Keep only section-relative page #
MOVE P5,A%XB(T1) ;GET DISK ADDRESS FROM INDEX BLOCK
CALL REDPAG ;READ A DATA PAGE FROM EXE FILE
$ERROR (IOER7) ;ERROR READING PAGE
JUMPN P4,G.DIR2 ;PAGE ZERO?
SKIPN MONLOD ;PASS ZERO?
CALL CHKPG0 ;YES
G.DIR2: SOJLE Q2,G.DIR3 ;DECREMENT REPEAT COUNT, LOOP IF MORE
ADDI P4,1000 ;NO MORE. POINT TO NEXT PROCESS PAGE
AOJA Q1,G.DIR1 ;GO READ NEXT PAGE OF EXE FILE.
G.DIR3: ADDI P1,.DISIZ ;POINT TO NEXT DESCRIPTOR
SUBI P2,.DISIZ ;DECREMENT DIRECTORY BLOCK WORD COUNT
JUMPE P2,G.DSP ;GO PROCESS NEXT BLOCK IF DONE
JRST G.DIR0 ;GO READ NEXT SET OF PAGES FROM EXE FILE
G.DIR4: MOVEI T1,TSTADR ;ASSUME THIS IS OUR CHECK ROUTINE
TXNE F,F.PHYS ;ARE WE WRITING TO A PHYSICAL PAGE?
MOVEI T1,GETPHY ;YES, USE THIS ROUTINE
CALL (T1) ;GO SEE IF MEMORY ADDRESS IS LEGAL
JRST G.DIR5 ;BAD PAGE, DO NOT CLEAR IT
SETZM (P4) ;CLEAR FIRST WORD OF PAGE
MOVSI T1,(P4) ;GET START ADDRESS FOR BLT
HRRI T1,1(P4) ;GET DESTINATION ADDRESS FOR BLT
BLT T1,777(P4) ;CLEAR PAGE TO ZEROS
G.DIR5: SOJA Q1,G.DIR2 ;GO SEE IF MORE PAGES TO CLEAR
COMMENT %
Used to analyze errors in page selection/rejection logic.
Can get a bit tedious on 2-pass loads
;Routine to report when we couldn't or wouldn't load a page
LODERR: PUSH P,Q1 ;Save the Q's
PUSH P,Q2
PUSH P,Q3
CALL CRLF
MOVE Q2,ERRPFX
CALL OUTSTR
MOVEI Q2,[ASCIZ/Failed to load file page /]
CALL OUTSTR
MOVE Q2,-2(P) ;Get file page from saved copy of Q1
CALL OUTOCT ;Output it
MOVEI Q2,[ASCIZ/ to memory page /]
CALL OUTSTR
MOVE Q2,P4 ;Get process page
LSH Q2,-9 ;Convert to page
CALL OUTOCT ;Output it
CALL CRLF ;Terminate line
POP P,Q3 ;Restore Q's
POP P,Q2
POP P,Q1
RET
% ;End comment
;HERE TO PROCESS ENTRY VECTOR BLOCK
G.ENT: SKIPN 1(P1) ;ENTRY VECTOR SIZE NON-ZERO ?
$ERROR (FILNEF) ;NO, BAD FILE FORMAT
MOVE P3,2(P1) ;YES, GET START ADDRESS
CALL SETSA ;GO SET STARTING ADDRESS
HRRZ T1,(P1) ;GET SIZE OF ENTRY VECTOR BLOCK
ADD P1,T1 ;UPDATE POINTER INTO EXE DIRECTORY
JRST G.DSP ;GO HANDLE NEXT EXE FILE BLOCK
;Here to process PDV block
G.PDV: HRRZ T1,(P1) ;GET SIZE OF PDV BLOCK
ADD P1,T1 ;UPDATE POINTER INTO EXE DIRECTORY
JRST G.DSP ;GO HANDLE NEXT EXE FILE BLOCK
COMMENT %
Routine to read memory page zero of .EXE file and set BOOT parameters
accordingly.
This routine has 2 different behaviors, depending on the version number of
the monitor. In V6 and later monitors, this routine reads data from
the BOOT communications region in the .EXE file and sets various BOOT
parameters.
For older monitors, or non-monitor .EXE files, BOOT behaves as follows:
If .JBSYM is non-zero, BOOT will not load in any pages above the
end of the symbol table, unless specific page-limits are specified in
the command. BOOT uses this feature to load only that portion of the
monitor up to the end of the symbols. MEXEC will then specify a page-range
in order to get the swappable monitor loaded.
% ;End comment
CHKPG0: MOVE T1,BUTCOD ;Get the code
CAME T1,[BTCOD] ;Correct?
JRST CHGLIM ;No, older-style load
LDB T1,[POINT 6,137,11] ;Get the major version
CAILE T1,M%MAJ ;Above the threshold version?
JRST SETLIM ;Yes, do new-style load
CAIE T1,M%MAJ ;At the threshold version?
JRST CHGLIM ;No, older-style load
LDB T1,[POINT 6,137,17] ;Get the minor version
CAILE T1,M%MIN ;The threshold minor version?
JRST SETLIM ;Above it, do new-style load
HRRZ T1,137 ;Get the edit number
CAIGE T1,M%EDT ;The threshold edit?
JRST CHGLIM ;No, older-style load
SETLIM: MOVE T1,BUTLLM ;Get the lower load limit
MOVEM T1,LWRLIM ;Set it
MOVE T1,BUTULM ;Get the upper load limit
MOVEM T1,UPRLIM ;Set it
RET
CHGLIM: TXNN F,F.NCHL ;DON'T WANT TO CHANGE THE LIMITS?
SKIPN T1,.JBSYM ;OR HAVE NO SYMBOL POINTER?
RET ;YES, DO NOTHING
HLRE T2,T1 ;GET NEGATIVE LENGTH
SUB T1,T2 ;COMPUTE ADDRESS RIGHT AFTER SYMBOL TABLE
MOVEI T1,-1(T1) ;BACK OFF TO LAST ADDRESS TO READ
LSH T1,-^D9 ;CONVERT TO PAGE NUMBER
MOVEM T1,UPRLIM ;SET NEW UPPER LIMIT
RET ;DONE
; ROUTINE TO DUMP CORE MEMORY TO A (PREALLOCATED) FILE
COMMENT \
SUPPORTING CHARACTERS:
Q1 STARTING PAGE OF A SET (PROCESS PAGE #)
Q2 NUMBER OF PAGES IN A SET
Q3 EXE DIRECTORY PAGE FIELD POINTER
P1 VIRTUAL ADDRESS ON PAGE TO BE DUMPED
(PG # *1000 +777)
P2 STARTING PAGE OF A SET (FILE PAGE #)
P4 ADDRESS ON PAGE TO BE DUMPED
(PG # *1000 +777)
\
SAVE: MOVEI Q2,[ASCIZ/[BOOT: DUMPING] /]
CALL OUTSTR ;...
MOVEI T1,NDMPM ;GET REPORT LIMIT FOR DUMP ERRORS
MOVEM T1,DERCNT ;KEEP IT HERE
SETZM P2,A%FP0 ;SET UP TO CLEAR EXE DIRECTORY
MOVE T1,[A%FP0,,A%FP0+1] ;PREPARE TO CLEAR EXE DIRECTORY PAGE
BLT T1,A%FP0+777 ;ZERO EXE FILE DIRECTORY PAGE
MOVEI P2,2 ;GET INITIAL FILE PAGE #
SETZB Q1,Q2 ;CLEAR START PAGE #, # OF PAGES IN SET
SETOI P1, ;INITIALIZE FIRST VIRTUAL ADDRESS
TXNE F,F.DUMP ;DUMP REQUESTED ?
TXO F,F.PHYS ;YES, USE PHYSICAL ADDRESSES
MOVEI Q3,A%FP0+1 ;INITIALIZE DIRECTORY ADDRESS
SETZM PGCNT ;ZERO COUNT OF DISK PAGES WRITTEN
TXZ F,F.DPER+F.IOER ;RESET FLAGS
;HERE TO SELECT CANDIDATE FOR NEXT PAGE SAVE
SAV.NP: ADDI P1,1000 ;COMPUTE NEXT VIRTUAL ADDRESS
TXNN F,F.PHYS ;DOING A DUMP OF PHYSICAL PAGES?
TLNN P1,-1 ;NO, END OF VIRTUAL PAGES?
SKIPA P4,P1 ;NO, GET PAGE NUMBER TO BE DUMPED
JRST SAV.DN ;AT END OF VIRTUAL CORE, GO WRITE DIR
CAMLE P1,[PHYADR+777] ;AT END OF PHYSICAL CORE?
JRST SAV.DN ;YES, GO WRITE DIRECTORY
CALL TSTADR ;IS THIS ADDRESS LEGAL ?
;HERE IF PAGE-FAIL, NXM, VBOOT PAGE, OR PAGE OUTSIDE DUMP RANGE
; SPECIFIED BY USER
JRST [ CAML P4,TOPBAS ;ARE WE WHERE BOOT NOW IS?
CAMLE P4,TOPTOP ;ARE WE IN RANGE?
JRST SAV.NS ;NO, GO ON TO NEXT PAGE SET
JRST SAV.NQ] ;PAGE OK, SO WRITE THE SAVED DATA
; TSTADR FAILED BECAUSE IT WAS A VBOOT PAGE -
; GO PLAY MAPPING GAMES
MOVE T1,P2 ;LEGAL PAGE - GET START FILE PAGE # OF SET
ADD T1,Q2 ;COMPUTE CURRENT FILE PAGE #
LDB P4,[POINT 18,T1,26] ;GET INDEX BLOCK #
JUMPE P4,SAV.NQ ;ZERO IS ALWAYS SET UP CORRECTLY
SKIPGE XBNUM ;IF SHORT FILE, THEN CANNOT GO FURTHER
JRST SAV.NS
CAMN P4,XBNUM ;IS THIS PAGE PART OF THE MAPPED XB?
JRST SAV.NQ ;YES, XB IS SET UP ALREADY
;HERE TO GET NEXT INDEX BLOCK FOR DUMP FILE
LOAD P5,IDXADR,A%SXB(P4) ;GET ADR OF NEXT XB
JUMPE P5,SAV.NS ;IF NONE, STEP TO NEXT SET
MOVEM P4,XBNUM ;SAVE THE XB NUMBER OF SOON-TO-BE-MAPPED XB
MOVEI P4,A%XB ;AND GO READ IN NEW XB
PUSH P,F ;SAVE STATE OF FLAGS
TXZ F,F.PHYS ;DO A VIRTUAL READ
CALL REDPAG
$ERROR (IOER3) ;ERROR READING PAGE
POP P,F ;RESTORE FLAGS
;HERE TO CALCULATE INDEX-BLOCK INDEX FOR PAGE TO BE DUMPED
SAV.NQ: MOVE T1,P2 ;YES, GET START FILE PAGE # OF SET
ADD T1,Q2 ;COMPUTE CURRENT FILE PAGE #
IDIVI T1,1000 ;GET ADR WITHIN THIS XB
; XB INDEX NOW IN T2
MOVE P4,P1 ;GET BACK THE PAGE TO BE WRITTEN
;THIS SECTION PLAYS MAPPING GAMES. BOOT LANDED IN LOW CORE AND MOVED ITSELF.
;WHILE MOVING ITSELF TO HIGH CORE IT SAVED THE HIGH CORE DATA IN THE AREA IT
;LANDED IN. NOW WE ARE WRITING A DUMP FILE. THE AREA WHERE BOOT LANDED
;(WHICH NOW HOLDS SAVED HIGH CORE INFORMATION) WILL NOT BE WRITTEN INTO A DUMP
;FILE. INSTEAD THE LOW CORE AREA WILL BE WRITTEN OUT IN IT'S "VIRTUAL" HIGH
;CORE ADDRESS.
;HERE TO SEE IF:
; (1) MICROCODE PAGE - DON'T DUMP IT
; (2) TARGET PAGE - WRITE PAGE SAVED IN SOURCE AREA
CAML P4,LODBAS ;ARE WE IN SOURCE AREA? (SEE DIAGRAMS)
CAMLE P4,LODTOP ;ARE WE IN RANGE?
SKIPA ;NO - CONTINUE NORMALLY
JRST SAV.NS ;YES - SKIP THIS PAGE
IFE SMFLG,<
CAML P4,MCSPAG ;ARE WE IN MICROCODE PAGES
CAMLE P4,MCEPAG ;ARE WE IN RANGE
SKIPA ;NO - CONTINUE NORMALLY
JRST SAV.NS ;YES - SKIP THIS PAGE
>
CAML P4,TOPBAS ;ARE WE WHERE BOOT NOW IS? (TARGET AREA)
CAMLE P4,TOPTOP ;ARE WE IN RANGE?
SKIPA ;NO - CONTINUE NORMALLY
;HERE TO SET POINTERS TO HIGH-CORE PAGES WE RELOCATED TO SOURCE AREA
JRST [ SUB P4,TOPBAS ;YES - COMPUTE PAGE NUMBER WITHIN AREA
ADD P4,LODBAS ;ADDRESS OF WHERE SAVED DATA LIVES
JRST .+1] ;SAVE THE PAGE HERE
;HERE TO WRITE THE MEMORY PAGE TO DISK
AOS T1,PGCNT ;COUNT TOTAL PAGES WRITTEN TO DISK (INCLUDING
; THIS ONE
CAMGE T1,DEXEPC ;IS THERE ROOM FOR THIS PAGE (+ 1 DIR PAGE)?
JRST DMPOK ;YES
TXO F,F.DPER ;NO, SET DUMP ERROR FLAG
JRST SAV.NS ;GO UPDATE DIRECTORY PAGE AND EXIT
DMPOK: LOAD P5,IDXADR,A%XB(T2) ;GET DISK ADDRESS
JUMPE P5,SAV.NS ;NO DISK ADDRESS, START NEW PAGE SET
CALL WRTPAG ;WRITE THE DATA PAGE
CALL DMPERR ;IO ERROR - GO TELL THE USER
AOS Q2 ;COUNT UP THE PAGES WRITTEN
;LIMIT TESTING - SEE IF WE NEED TO START A NEW PAGE SET
LIMTST: CAML P1,[PHYADR+777] ;HAVE WE JUST WRITTEN PHYPAG?
JRST SAV.N1 ;YES, GO FINISH CURRENT PAGE SET
MOVE T1,P1 ;GET ADDR OF PAGE WE JUST DUMPED
ADDI T1,1000 ;INCREMENT FOR PROPER VALUE
; (CONSIDER NEXT PAGE)
TRZ T1,777 ;GET PAGE BOUNDARY
JUMPLE T1,LIM1 ;SKIP THIS TEST FIRST TIME THROUGH
IDIV T1,[1000000] ;SEE IF PAGE FALLS ON A SECTION BOUNDARY
JUMPE T2,SAV.N1 ;IT DOES, SO FORCE A NEW PAGE SET
LIM1: CAIGE Q2,1000 ;REACHED THE END OF A SECTION?
JRST SAV.NP ;NO
;HERE TO START NEW PAGE SET
SAV.NS: JUMPE Q2,SAV.ES ;GO UPDATE START PAGE # IF NULL PAGE SET
CAIGE Q2,1000 ;EARLY QUITTING? (LESS THAN FULL PAGE SET?)
SUBI P1,1000 ;YES MUST RETEST THIS PAGE
SAV.N1: CAILE Q3,A%FP0+777-.DISIZ-.EBSIZ-.VBSIZ+1 ;DIRECTORY TOO BIG ?
$ERROR (FILDRP) ;YES, IT'S GREATER THAN 1 PAGE
MOVEI T1,100 ;GET DI%WRT BIT, STORE IN FLAG WORD
STOR T1,DIFLG,(Q3) ;STORE FLAGS
STOR P2,DIFIL,(Q3) ;STORE STARTING FILE PAGE NUMBER
SOS Q2 ;GET CORRECT REPEAT COUNT
STOR Q2,DIRPT,(Q3) ;STORE REPEAT COUNT
STOR Q1,DIPRO,(Q3) ;STORE PROCESS PAGE #
ADDI Q3,.DISIZ ;POINT TO NEXT DESCRIPTOR
ADDI Q1,0(Q2) ;COUNT UP PROCESS PAGE #
ADDI P2,1(Q2) ;GET CORRECT NEXT FILE PAGE #
SAV.ES: SETZM Q2 ;RESET SIZE OF PAGE SET
TXNN F,F.DPER ;DUMP ERROR OCCURRED?
AOJA Q1,SAV.NP ;NO, GO WRITE NEXT PAGE SET
;YES, FALL THROUGH AND WRITE DIRECTORY PAGE
;HERE TO WRITE DIRECTORY PAGE
SAV.DN: MOVEI T1,.EXDIR ;GET DIRECTORY BLOCK TYPE
STOR T1,DIDIR ;STORE IN EXE DIRECTORY
MOVEI T1,-A%FP0(Q3) ;GET SIZE OF EXE DIRECTORY
STOR T1,DISIZ ;STORE SIZE OF DIRECTORY BLOCK
MOVEI T1,.EXENT ;GET ENTRY VECTOR BLOCK TYPE
STOR T1,VBTYP,(Q3) ;PUT BLOCK TYPE IN ENTRY VECTOR BLOCK
MOVEI T1,.VBSIZ ;GET SIZE OF ENTRY VECTOR BLOCK
STOR T1,VBSIZ,(Q3) ;STORE SIZE OF ENTRY VECTOR BLOCK
MOVEI T1,EVLEN ;GET LENGTH OF ENTRY VECTOR
STOR T1,VBCNT,(Q3) ;STORE LENGTH OF ENTRY VECTOR
MOVEI T1,EVADR ;GET ADDRESS OF ENTRY VECTOR
STOR T1,VBADR,(Q3) ;STORE ADDRESS OF ENTRY VECTOR
ADDI Q3,.VBSIZ ;POINT TO NEXT BLOCK IN EXE DIRECTORY
MOVEI T1,.EXEND ;GET END BLOCK TYPE CODE
STOR T1,EBTYP,(Q3) ;STORE BLOCK TYPE IN END BLOCK
MOVEI T1,.EBSIZ ;GET SIZE OF END BLOCK
STOR T1,EBSIZ,(Q3) ;STORE SIZE OF END BLOCK
TXZ F,F.PHYS ;TURN OFF PHYSICAL ADDRESSES
SKIPG XBNUM ;DO WE HAVE XB 0 MAPPED IN
JRST SAV.D1 ;YES
LOAD P5,IDXADR,A%SXB+0 ;NO, GO MAP IT IN
MOVEI P4,A%XB ;READ INTO XB PAGE
CALL REDPAG
$ERROR (IOER3) ;ERROR READING PAGE
SAV.D1: LOAD P5,IDXADR,A%XB+0 ;WRITE OUT PAGE 0 OF FILE
SKIPN P5 ;COMPLAIN IF NO PAGE ZERO
$ERROR (FILNEF) ;IF NO PAGE 0, COMPLAIN
MOVEI P4,A%FP0 ;GET CORE ADDRESS OF EXE DIRECTORY
CALL WRTPAG ;WRITE DIRECTORY PAGE AND RETURN
$ERROR (IOER9) ;COULDN'T WRITE IT
TXZE F,F.DPER ;DUMP ERROR?
$ERROR (DMPFTS) ;YES - DUMP.EXE TOO SHORT
TXZE F,F.IOER ;DID A WRITE ERROR OCCUR?
JRST ERRET ;YES, GO RETURN
MOVEI Q2,[ASCIZ/[OK]
/]
CALL OUTSTR
RET ;ALL DONE
DMPERR: SOSG DERCNT ;HAVE WE REACHED THE REPORT LIMIT?
POPJ P, ;YES, RETURN
PUSH P,Q1 ;SAVE OUR AC'S
PUSH P,Q2
PUSH P,Q3
TXO F,F.IOER ;INDICATE A WRITE ERROR OCCURRED
MOVE T1,DERCNT ;GET THE LIMIT
CAIN T1,NDMPM-1 ;FIRST TIME THROUGH?
CALL CRLF ;YES
MOVE Q2,ERRPFX ;GET THE ERROR PREFIX
CALL OUTSTR ;OUTPUT IT
MOVEI Q2,[ASCIZ/IO error while dumping page: /]
CALL OUTSTR ;OUTPUT IT
MOVE Q2,P1 ;GET THE PAGE ADDRESS
LSH Q2,-^D9 ;TURN IT INTO A PAGE NUMBER
CALL OUTOCT ;OUTPUT IT
CALL CRLF ;OUTPUT A CRLF
CALL OUTSTS ;OUTPUT CHANNEL/DEVICE STATUS
POP P,Q3 ;RESTORE AC'S
POP P,Q2
POP P,Q1
POPJ P, ;RETURN
> ; END OF IFN FT.EXE
LIT
IFG <A%VORG-.>,<BLOCK <A%VORG-.>>
BLOCK <777-<.&777>>
JRST VBOOT ;MUST BE LAST INSTRUCTION IN LAST PAGE
IFG <.-A%VORG-1000>,<PRINTX ?MAXIMUM CODE SIZE EXCEEDED>
DEPHASE
CODEND:
;This code is executed in the AC's near GOTCOR.
; P2/ address of first word to be moved from low end to high
; P3/ address of first word to be moved from high end to low
; P4/ number of words to move
BOTMOV: MOVE P5,(P3) ;GET NONBOOT WORD
EXCH P5,(P2) ;EXCHANGE WITH BOOT
MOVEM P5,(P3) ;BOOT INTO HIGH CORE
AOS P2 ;NEXT WORD
AOS P3 ;...
SOJG P4,T1 ;DO ALL WORDS
MOVEND: JRST <CORMVD-ENT>+<A%CODE-1000-A%VORG>(P1) ;GO TO MOVED BOOT
MVCLEN==MOVEND-BOTMOV ;Length of moving code (-1)
;PAGE FAULT HANDLER UNTIL AFTER BOOT IS MOVED
PAGTRP:
IFN KLFLG!SMFLG,<
AOS CODEND-ENT+UPTPFO(16) ;THE PC OF THE PAGE FAIL
JRST @CODEND-ENT+UPTPFO(16) ;PROCEED
> ;END OF IFN KLFLG!SMFLG
IFN KCFLG,<
AOS CODEND-ENT+KCPFOP(16) ;THE PC OF THE PAGE FAIL
XJRSTF CODEND-ENT+KCPFOF(16) ;PROCEED
> ;END IFN KCFLG
> ;END IFN FT.PRT&2
;This code interfaces with the V6 KDDT and also allows BOOT's timeshareing
;core image to be mapped to high-core (so that the symbols can be used) and
;unmaps the pages when ^Z is typed to KDDT (again, in user mode).
;BOOT knows nothing about this code, and it is not moved when BOOT moves
;to high core. It should be remembered that future monitor changes might
;cause the resident monitor to overlay this code (and, indeed, KDDT itself).
IFN BDEBUG,<
.PSECT MAPCOD,DDTPRE ;Linked on first page preceding DDT
EXTERN DDTX
MSEC1==:1 ;KDDT wants this
DDTENT: XSFM PCSTOR ;Get PC flags
EXCH T1,PCSTOR ;Get the flags
TXNN T1,1B5 ;User mode?
JRST EXEC ;No
;Here in user mode
MOVE T1,[.FHSLF,,<ENT_-9>+1]
MOVE T2,[.FHSLF,,<A%CODE>_-9]
MOVE T3,[PM%RD!PM%WR!PM%EX!PM%CNT!A$CODE]
PMAP
JRST DDTX ;Enter KDDT in user mode
;Here if in EXEC mode
EXEC: SKIPE EFLAG ;First time through?
JRST EXEC1 ;No
;1'st time through preamble
MOVE T1,116 ;Get pointer to symbol table
MOVEM T1,SYMTAB ;Save symbol table pointer
JRST DDTGO ;Prepare to enter KDDT
;N'th time through preamble
EXEC1: MOVE T1,SYMTAB ;Get symbol table pointer
MOVEM T1,116 ;Restore it
DDTGO: MOVE T1,PCSTOR ;Recover contents of T1
;Very important if he has restarted DDT
SETOM EFLAG ;Indicate we have been through preamble
JRST DDTX ;Enter KDDT in exec mode
;Here after exiting EDDT in user mode with ^Z
;We are guaranteed to get here only in user mode
DDTCZ:: SETOM T1 ;Unmap the pages
MOVE T2,[.FHSLF,,<A%CODE>_-9]
MOVE T3,[PM%RD!PM%WR!PM%EX!PM%CNT!A$CODE]
PMAP
DDTEX: HALTF
JRST DDTENT
;Storage for DDT preamble code
PCSTOR: Z ;Storage for PC flags
EFLAG: Z ;Nonzero means we have been here before
SYMTAB: Z ;Place to save symbol table pointer
Z
Z
LIT
PATCH: BLOCK <777-<.&777>> ;Our patch area
> ;End IFN BDEBUG
IFN FT.PRT&1,<END JRST ENT> ;GIVE START ADR IF ASSEMBLED PT 1