Google
 

Trailing-Edge - PDP-10 Archives - BB-BT99S-BB_1990 - 10,7/boot/boot.mac
Click 10,7/boot/boot.mac to see without markup as text/plain
There are 22 other files named boot.mac in the archive. Click here to see a list.
UNIVER	BTSPRM - PARAMETER FILE FOR DECSYSTEM-10 BOOTSTRAP
SUBTTL	D. MASTROVITO /DPM/JAD	16-OCT-89


;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
; 1980,1981,1982,1983,1984,1985,1986,1987,1988,1989.
;ALL RIGHTS RESERVED.
;
;
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY  OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF THE  SOFTWARE  IS  HEREBY
;TRANSFERRED.
;
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT  NOTICE
;AND  SHOULD  NOT  BE  CONSTRUED  AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY  OF  ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.


	BOOWHO==0		;WHO EDITED
	BOOVER==4		;MAJOR VERSION NUMBER
	BOOMIN==0		;MINOR VERSION NUMBER
	BOOEDT==77		;EDIT NUMBER
	%%BTS==<BYTE(3)BOOWHO(9)BOOVER(6)BOOMIN(18)BOOEDT>
	SUBTTL	REVISION HISTORY


COMMENT `

Version 1

1   05-Feb-80	Add the /REBOOT switch and support for system sleep.
2   15-Jun-80	Change the default filename for /REBOOT from SYSTEM to
		CRASH.
3   05-Jul-80	Change the definitions of APRRST and CLRAPR for the
		KS10 to reflect empirical evidence (i.e. make it work)
4   05-Jul-80	After powerup, the KS10 wants a WREBR 0 before the
		WREBR to set the EBR.  I'm not sure why it's true or
		why it works but it fixes the ?PAR ERR's.
5   07-Feb-81	Add the /EDDT switch to be equivalent to /START:401.

Version 2

6   06-Jun-81	Add conditinal assembly for KL paging.
7   01-Oct-81	Fix typo that caused BOOT to give up on a structure
		if the first HOME block was bad even if the second one
		was OK.
10  01-Oct-81	Make it possible to load the DX20/RP20 microcode with
		BOOT and pass the physical address of the loaded
		microcode to the monitor when it is started.
11  16-Feb-81	Fix a problem with finding 18 bit DF10s.  This fix was
		only installed in maintenance versions since DF10s
		aren't supported with the next field release of BOOT.
		The result is no code change is this source.
12  25-Apr-82	Remove the FTKI10 conditionals and the code that they
		surround.
13  19-Aug-82	More of edit 7.
14  08-Mar-83	Can't boot a KS if one of the drives is dual ported.
		See MCO 10633.
15  08-Jul-83	Fix a typo introduced by edit 6 which causes MUUO EA to
		get printed incorrectly on a trap other than page fail.
16  11-Jul-83	Cause version number to be in .JBVER and the EXE file.
17  22-Nov-83	Be sure to put copyright in a format that is readable
		once the '11 gets the .EXB file
Version 3

20  12-Aug-84	Teach BOOT how to do KL-paging on the KS.  Also, include
		CJA's support for silent switch boot.  (Expanded for KL)
		Process ^R in GETLIN since it fits in all assemblies.

21  26-Sep-84	Remove FTKLP conditionals.  Defend against KLIPAs and KLINIs.

22  31-Oct-84	Merge 702+ and 703 versions together.  Add SAVE. UUO to loader.

23   9-Dec-84	Completely rewrite microcode loader.  Include in it code to
		write .EXB files for KL10s.

24  10-Dec-84	Propagate monitor filespec across monitor/bootstrap reloads
		so typing just optional switches and/or CRLF will reload the
		old monitor instead of DSK:SYSTEM.EXE[1,4].

25  11-Dec-84	Add code to scan the SDL for structures on which to dump.
		Add /FORCE to load from DSKA-DSKZ instead of the SSL or
		dump to DSKA-DSKZ instead of the SDL.  /FORCE is implied if
		either the SSL or SDL is empty on the appropriate operations.

26  13-Dec-84	Preserved ASL entries are now one word per unit.

27  18-Dec-84	Make SSL, ASL, and SDL words contain -LENGTH,,OFFSET to the
		desired preserved data.

30   4-Jan-85	Fix filespec defaulting problems for dump operations.

31  21-Jan-85	Prevent DTE reloads by not clobbering the APR.

32   2-Apr-85	Make BOOT work on a KS10.  Add BTSPRM universal.  Rework
		microcode loader to convert files directly into binary.

33  16-Apr-85	Check validity of data page at the start of COPDAT.

34  22-Apr-85	BOOT hangs on KS10 because KLINIK command word left non-zero
		by the loader's SAVE. UUO, and the KS10 8080 code is irrational

35  24-Apr-85	KS10s don't like XJRST.

36  25-Apr-85	Add system sleep and page replacement support.

37  01-May-85	Fix up some problems with /REBOOT after system sleep.
		BOOT will now reload in place, after checking that enough
		core was reserved for it.
40  19-Jul-85	Don't attempt to save/restore the PI system state.  The
		monitor already does this, and we can lose pending inter-
		rupts if we clear the PI system (causing KAF after taking
		a dump).

41  15-Aug-85	Do Copyrights./LEO

42  15-Nov-85	Forcibly halt internal channel devices when BOOT is started
		(KLNI and KLIPA).  Re-arrange the vector so it is easily
		expanded without causing monitor/BOOT skews.  Preserve
		cache strategy from KLI on the KL, and add a word for
		saving the cache strategy across reloads/CPU restarts.
		Add code from 7.02 MONBTS to save/restore KS UBA mapping
		registers around calls to BOOT.

43  25-Nov-85	Fix bug in EXBDAT which would drop a few words at the end
		of the .EXB file.  Don't create .EXB file for KS BOOT.
		Conditionalize the UCODES entries so we don't ask about KL
		microcodes on a KS, and vice versa.

44   1-Dec-85	More work to get BOOT to work on the KS.  Retrieve code
		from 7.02 MONBTS to save UBA status during R11INI and
		ditto for RH20 status during R12INI.

45  17-Dec-85	Don't default on system sleep dump function.  If can't
		dump for some reason just ask where to dump rather than
		asking if they want to keep the dump.

46  18-Dec-85	Remove the need for BOOTM by teaching BOOT about magtapes.
		(Unsupported) code is under the FTTAPE conditional, which
		is OFF in the distributed version.

47   7-Jan-86	Get version number from the "correct" place in .ULD files.

Start of version 3A

50  19-Jun-86	Remove crocks about loading high segments following low
		segments and just load into the physical pages specified
		by the .EXE directory.

51  18-Nov-86	Save the IA/IVIR registers at R12INI and restore on exit.
		Not restoring the registers can lead to UIL stopcodes if
		the device interrupts and picks up a zeroed EPT index.

Start of version 4

60  18-Nov-86	Turn on FTTAPE conditional so we can get rid of BOOTM for
		the 7.04 release.

61   4-Mar-87	Modify REFMEM to detect memory interleaving errors.  This
		is in preparation for removing similar code in SYSINI so
		the monitor starts up faster.

62   5-Mar-87	Inform the user when the monitor extends into BOOT rather
		than just reporting "memory too complex".

63   6-Mar-87	To aid monitor debugging, report the function code on
		"Illegal function code" errors.

64  16-Mar-87	Rebuild NXMTAB on RESTART or REBOOT functions.  NXMTAB from
		the monitor is incorrect, as it is not a table of non-existant
		pages, but a table of pages the monitor wants to hide from
		itself.

65   6-May-87	Make microcode text more descriptive.  Change KLIPA/CI
		to CI20 and KLNI/NI to NIA20.

66   8-Jun-87	Fix bug in compare logic that prevented us from ever restarting
		a suspended monitor.  Must also throw away tape drivers at
		this time so we use the adjusted size of bootstrap.

67  28-Jul-87	Fix asking/defaulting of questions to avoid hanging in
		automatic dump/reload of monitor.  If we can't do the dump,
		punt it.

70   4-Aug-87	Fix system sleep to mark the suspended system as a dump.
		This way, we won't overwrite it by accident with a useless
		STOPCD dump.  Requires edit 53 to CRSCPY.

71  28-Dec-87	Use a word in the bootstrap vector to store the software
		incarnation level of the host's SCA interface.

72  31-Dec-87	Fix RSTHDW to properly restore the DTE20 status.

73  28-Jan-88	Reserve some words in the preserved area for customer use.

74  28-Mar-88	Accept "TM03" as equivalent to "TM02".

75  29-Mar-88	Mung our version number into something RSX-20F will accept
		in the .EXB file RIB.

76   3-Jun-88	Clear KL address break conditions in strategic places.

77  16-Oct-89	General crash file processing cleanup:
		1. Sprinkle a few more calls to LISTEN.  Check for input
		   on all typeout.
		2. Mark pages in crash file as writable.  This allows
		   one to do a GET SYS:CRASH.EXE command.
		3. Save the last crash filespec in .BTCRS for DAEMON
		   startup.

`
	SUBTTL	MICROCODE STORAGE DEFINITIONS

; THIS MACRO DEFINES THE MICROCODE STORAGE DATA BASE FOR BOOT.  DUMMY
; ENTRIES IN THE MACRO ALLOW UPWARD AND DOWNWARD COMPATIBILTY BETWEEN
; VERSIONS OF THE MONITOR AND BOOT.  AS NEW MICROCODES ARE ADDED, THE
; DUMMY ENTRIES ; SHOULD BE REMOVED.  DUMMY ENTRIES RESERVED FOR DEC
; ARE LABELED 'DEC'.  THOSE FOR CUSTOMERS ARE LABELED 'CST'.  ALSO, WHEN
; ADDING NEW MICROCODES, MAKE SURE THE DESCRIPTIVE TEXT IS PADDED OUT TO
; THE FULL 19 CHARACTERS.  THIS IS USED BY THE MICROCODE LOADER IN BOOT
; AND MAKES FOR A PRETTY DISPLAY.

DEFINE	UCODES,<

;; L,PFX, NAME ,EXT,DESCRIPTIVE TEXT	 , MODE ,MAXIMUM-SIZE
X (FTKL10,TX1,DXMPA ,A8 ,<DX10/TX01 microcode>,.IOASC,<10000/3>)
X (FTKL10,TX2,DXMCA ,ADX,<DX20/TX02 microcode>,.IOASC,<2000+400+^D32+1>)
X (FTKL10,RP2,DXMCD ,ADX,<DX20/RP20 microcode>,.IOASC,<2000+400+^D32+1>)
X (FTKL10,KLP,KLPCOD,ULD,<CI20 microcode     >,.IOASC,<<10000*^D60+^D35>/^D36>)
X (FTKL10,KNI,KNICOD,ULD,<NIA20 microcode    >,.IOASC,<<10000*^D60+^D35>/^D36>)
X (0,UNA,DEUCOD,ULD,<DEUNA/NI microcode >,.IOASC,<<10000*^D60+^D35>/^D36>)
X (0,   ,DUMMY ,DEC,<0>)
X (0,   ,DUMMY ,DEC,<0>)
X (0,   ,DUMMY ,DEC,<0>)
X (0,   ,DUMMY ,DEC,<0>)
X (0,   ,DUMMY ,DEC,<0>)
X (0,   ,DUMMY ,CST,<0>)
X (0,   ,DUMMY ,CST,<0>)

>
DEFINE	X	(L,PFX,NAM,EXT,TXT,MOD,SIZ),<
	IFNB <PFX>,<.BT'PFX==ZZ>
	ZZ==ZZ+2
	IFL ZZZ-<SIZ>,<ZZZ==SIZ>
>

	ZZZ==<ZZ==0>
	UCODES
	UCDNUM==ZZ_-1
	UCDSIZ==ZZZ

	PURGE	ZZ,ZZZ
	SUBTTL	ENTRY VECTOR

; THIS IS THE ACTUAL BOOTSTRAP ENTRY VECTOR.  NOTE THAT THE
; MICROCODE OFFSET DEFINITIONS (FROM THE UCODES MACRO) INDEX
; INTO A STATIC BLOCK INSIDE THE VECTOR RATHER THAN BEING ABSOLUTE
; OFFSETS INTO THE VECTOR ITSELF.  THIS ALLOWS FOR SKEWS BETWEEN
; THE MONITOR AND BOOT WHEN NEW MICROCODES ARE ADDED.

	 .ORG	0

.BTVEC:!			;START OF VECTOR
.BTNAM:! BLOCK	1		;SIXBIT /BOOT/
.BTSIZ:! BLOCK	1		;XWD -SIZE IN PAGES, SIZE IN WORDS
.BTVER:! BLOCK	1		;BOOT VERSION
.BTSTA:! BLOCK	1		;BOOT START ADDRESS
.BTDDT:! BLOCK	1		;DDT START ADDRESS
.BTBPT:! BLOCK	1		;UNSOLICITED BREAKPOINT ADDRESS
.BTSYM:! BLOCK	2		;POINTER TO SYMBOL TABLES
.BTFLG:! BLOCK	1		;FLAGS
.BTFNC:! BLOCK	1		;SUBROUTINE FUNCTION CODE
.BTDAT:! BLOCK	1		;SUBROUTINE OFFSET TO DATA STORAGE
.BTDSP:! BLOCK	1		;SUBROUTINE DISPATCH OFFSET
.BTXPC:! BLOCK	4		;SUBROUTINE XPCW ENTRY POINT
.BTACS:! BLOCK	2		;SUBROUTINE STORAGE FOR CALLER'S ACS 16 AND 17
.BTUCD:! BLOCK	UCDNUM*2	;MICROCODE STORAGE POINTERS (TWO WORD PAIRS)
.BTMSZ:! BLOCK	1		;OFFSET TO SIZE OF MEMORY IN P
.BTNXM:! BLOCK	1		;-LENGTH,,OFFSET TO NXMTAB
.BTCPN:! BLOCK	1		;CPU NUMBER OF CPU INVOKING BOOT
.BTCUS:! BLOCK	4		;4 WORDS FOR CUSTOMER USE
.BTSIN:! BLOCK	1		;SCA SOFTWARE INCARNATION NUMBER
				;*** ADD NEW NON-PRESERVED VARIABLES HERE ***
	.ORG	100		;LEAVE SOME ROOM FOR FUTURE EXPANSION
.BTSVB:!			;BEGINING OF PRESERVED DATA
.BTSAV:! BLOCK	1		;NUMBER OF PRESERVED WORDS
.BTDEV:! BLOCK	1		;DEVICE
.BTFIL:! BLOCK	1		;FILE NAME
.BTEXT:! BLOCK	1		;EXTENSION
.BTPTH:! BLOCK	7		;PATH (PLUS ZERO TERMINATING WORD)
.BTSSL:! BLOCK	1		;-LENGTH,,OFFSET TO SSL
	 BLOCK	^D36		;SYSTEM SEARCH LIST
.BTASL:! BLOCK	1		;-LENGTH,,OFFSET TO ASL
	 BLOCK	^D8		;ACTIVE SWAPPING LIST
.BTSDL:! BLOCK	1		;-LENGTH,,OFFSET TO SDL
	 BLOCK	^D36		;SYSTEM DUMP LIST
.BTSCS:! BLOCK	1		;SAVED CACHE STRATEGY (KL)
.BTPCW:! BLOCK	4		;4 PRESERVED WORDS FOR CUSTOMER USE
.BTCRS:! BLOCK 1+1+1+7		;LAST CRASH FILE SPEC
				;*** ADD NEW PRESERVED VARIABLES HERE ***
.BTSVE:!			;END OF PRESERVED DATA
.BTVCE:!			;END OF VECTOR

.BTVLN==<.BTVCE+777>_-11	;LENGTH OF VECTOR IN PAGES

	 .ORG


	PRGEND
TITLE	BOOT - DECSYSTEM-10 BOOTSTRAP
SUBTTL	G.M. UHLER/GMU/DPM	04-AUG-87


	SEARCH	BTSPRM
	SEARCH	JOBDAT
	SEARCH	UUOSYM

	SALL
	.DIRECTIVE FLBLST

IFNDEF	FTKL10,<FTKL10==-1>
IFNDEF	FTKS10,<FTKS10==0>
IFNDEF	FTTAPE,<FTTAPE==-1>	;INCLUDE BOOTM EMULATION IF NON-ZERO

IF1,<
  IFN FTKL10,<PRINTX [Assembling BOOT for a KL10]>
  IFN FTKS10,<PRINTX [Assembling BOOT for a KS10]>
>

	LOC	.JBVER
	EXP	%%BTS
	RELOC

COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1980,1987. ALL RIGHTS RESERVED.
\;END OF COPYRIGHT MACRO

;THE "\|"s BELOW ARE BECAUSE THE IRPC IN ASCI11 CAN'T DEAL WITH<CR>(!)
DEFINE CPYTXT,<ASCI11	<\|COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1980,1987.\|ALL RIGHTS RESERVED.\|>>
	SUBTTL	MEMORY USAGE


;	SYMBOL	              CONTENTS			ADDRESS
;
;	LOADER	+====================================+	   140
;		|          MICROCODE LOADER          |
;	LOADEN	+------------------------------------+
;		|            UNUSED CORE             |
;	BTSVEC	+------------------------------------+	700000
;		|       ENTRY VECTOR PAGE(S)         |
;		|           (PAGE ALIGNED)           |
;	EPT	+------------------------------------+
;		|       EPT/UPT/SECTION 0 MAP        |
;	DATA	+------------------------------------+
;		|         IMPURE DATA STORAGE        |
;	BOOT	+------------------------------------+
;		|             BOOTSTRAP              |
;	EDDT	+------------------------------------+
;		|              EXEC DDT              |
;	DDTEND	+------------------------------------+
;		|            PATCH SPACE             |
;		+------------------------------------+
;		|            SYMBOL TABLE            |
;		+------------------------------------+
;		|          MICROCODE STORAGE         |
;		+------------------------------------+
;		|            UNUSED CORE             |
;		+====================================+	777777
	SUBTTL	FEATURE TEST NORMALIZATION


;MAKE SURE FEATURE TESTS AREN'T SCREWED

IFE FTTAPE,<			;IF NO TAPE DRIVER CODE
	FTDX10==0		;NO DX10/TU70
	FTTM02==0		;NO TM02/RH10/RH11/RH20
	FTDX20==0		;NO DX20/TU72
	FTTM78==0		;NO TM78
>; END IFE FTTAPE

IFN FTTAPE,<			;IF TAPE DRIVER CODE
  IFN FTKL10,<			;FOR A KL10
    IFNDEF FTDX10,<FTDX10==-1>	;DX10/TU70 BY DEFAULT
    IFNDEF FTTM02,<FTTM02==-1>	;TM02/RH10/RH20 BY DEFAULT
    IFNDEF FTDX20,<FTDX20==-1>	;DX20/TU72 BY DEFAULT
    IFNDEF FTTM78,<FTTM78==-1>	;TM78 BY DEFAULT
  >; END IFN FTKL10
  IFN FTKS10,<		;FOR A KS10
    IFNDEF FTTM02,<FTTM02==-1>	;TM02/RH11 BY DEFAULT
	FTDX10==0		;THE REST STAY OFF
	FTDX20==0		;...
	FTTM78==0
  >; END IFN FTKS10

  IF1,<
    IFN FTDX10,<PRINTX [Including DX10/TX01 driver]>
    IFN FTTM02,<PRINTX [Including TM02 driver]>
    IFN FTDX20,<PRINTX [Including DX20/TX02 driver]>
    IFN FTTM78,<PRINTX [Including TM78 driver]>
  >; END IF1
>; END IFN FTTAPE
	SUBTTL	AC DEFINITIONS


	S=0		;FLAGS
	P=1		;PUSH DOWN POINTER
	T1=2		;FOUR
	T2=T1+1		; TEMPORARY
	T3=T2+1		;  ACS
	T4=T3+1		;   ...
	W=6		;OFFSET INTO THE TYPE TABLE (RH10, RH20, RH11, ETC.)
	M=7		;NUMBER OF BLOCKS TO TRANSFER
	U=10		;PHYSICAL UNIT NUMBER
	P1=11		;FOUR
	P2=P1+1		; PRESERVED
	P3=P2+1		;  ACS
	P4=P3+1		;   ...
	J=15		;INDEX INTO DEVICE CODE TABLE
	F=16		;LOGICAL BLOCK ON UNIT OF FIRST BLOCK TO TRANSFER
	R=17		;RELOCATION REGISTER OR ADDRESS OF START OF TRANSFER
	SUBTTL	FLAG DEFINITIONS


;FLAGS IN S.  NOTE THAT THE FR.XXX FLAGS MUST BE IN THE SAME ORDER
;AS SWTTAB SINCE THE OFFSET INTO SWTTAB IS USED TO SET THE BIT IN S.

FL.RUB==1B0	;CURRENTLY PROCESSING RUBOUT
FL.OVW==1B1	;IGNORE UNPROCESSED DUMPS
FL.WLD==1B2	;DEVICE IS WILD
FL.RIB==1B3	;SKIP 1 BLOCK IN SELBLK SO THAT WE SKIP THE RIB
FL.NOP==1B4	;SCHED 400 IN EFFECT
FL.EXR==1B5	;READING IN AN EXTENDED RIB
FL.IO==1B6	;1 IF DOING OUTPUT, 0 IF DOING INPUT
FL.DEF==1B7	;DON'T DEFAULT ANY ANSWERS IN REDLIN
FL.CMD==1B8	;PARSE COMMANDS FROM COMMAND BUFFER
FL.1CM==1B9	;PARSE JUST NEXT COMMAND FROM COMMAND BUFFER
FL.LDE==1B10	;ERROR BEING PROCESSED WAS FROM LOAD, NOT DUMP
FL.SDT==1B11	;SUCCESSFUL DUMP TAKEN
FL.SSD==1B12	;THIS DUMP IS FOR A SYSTEM SLEEP
FL.DDD==1B13	;DON'T DO DUMP (DEBUGF HAS DF.RAD LIT)
FL.FFL==1B14	;FOUND FILE IN FNDFIL
		;*** BIT 15 FREE
IFN FTTAPE,<
FL.EXS==1B16	;EXTENSION SEEN
FL.REW==1B17	;REWIND IN PROGRESS
>; END IFN FTTAPE

FR.DEV==1B18	;DEVICE SEEN
FR.FIL==1B19	;FILENAME SEEN
FR.EXT==1B20	;EXTENSION SEEN
FR.PTH==1B21	;PATH SEEN

FR.1ST==1B35	;RIGHT-MOST BIT OF SWITCH BITS. SHIFT THIS BIT BY THE
		; OFFSET INTO SWTTAB TO SET THE APPROPRIATE SWITCH BIT
;DEFINE SWITCH BITS

DEFINE	SWBIT(NAM),<
	FR.'NAM==ZZ
	FR.SWT==FR.SWT!FR.'NAM
	ZZ==ZZ_1
>; END SWBIT

ZZ==FR.1ST	;START AT FIRST BIT
FR.SWT==0	;NO BITS SET YET

SWBIT	(STA)	;/START:N SEEN
SWBIT	(DDT)	;/EDDT SEEN
SWBIT	(LOD)	;/LOAD SEEN
SWBIT	(DMP)	;/DUMP SEEN
SWBIT	(RBT)	;/REBOOT SEEN
SWBIT	(FRC)	;/FORCE SEEN
IFN FTTAPE,<
SWBIT	(REW)	;/REWIND SEEN
SWBIT	(SKP)	;/SKIP SEEN
SWBIT	(NOR)	;/NOREWIND SEEN
>; END IFN FTTAPE

IFN FTTAPE,<
FR.TAB==FR.REW!FR.SKP
		;TAPE ACTION BITS
FR.TSB==FR.REW!FR.SKP!FR.NOR
		;TAPE-SPECIFIC BITS
>; END IFN FTTAPE

FR.ALL==FR.DEV!FR.FIL!FR.EXT!FR.SWT
		;ALL PARSE BITS

FX.CLR==FL.RUB!FL.OVW!FL.WLD!FL.SDT!FR.ALL
		;BITS TO CLEAR ON ENTRY TO PARSE
	SUBTTL	PARAMETER DEFINITIONS


;MONITOR PARAMETERS WHICH MUST AGREE WITH COMMON/COMMOD.
;
;HOME BLOCK DEFINITIONS

HOMNAM==0		;SIXBIT/HOM/
HOMSNM==4		;SIXBIT STRUCTURE NAME
HOMLUN==10		;LOGICAL UNIT NUMBER WITHIN FILE STRUCTURE
HOMBSC==14		;BLOCKS PER SUPERCLUSTER
HOMSCU==15		;SUPER CLUSTERS PER UNIT
HOMCNP==16		;BYTE POINTER TO CLUSTER COUNT IN RETRIEVAL PTR
HOMCLP==20		;BYTE POINTER TO CLUSTER ADDRESS IN RET. PTR
HOMBPC==21		;BLOCKS PER CLUSTER
HOMREF==23		;NON-ZERO IF STRUCTURE NEEDS REFRESHING
HOMMFD==46		;LOGICAL BLOCK NUMBER IN STR OF RIB FOR MFD
HOMCOD==176		;CONTAINS UNLIKELY CODE
CODHOM==707070		;THE CODE
HOMSLF==177		;SELF BLOCK POINTER


;RIB DEFINITIONS

RIBFIR==0		;AOBJN POINTER TO FIRST RETRIVAL POINTER IN RIB
RIBPPN==1		;PPN OF FILE
RIBNAM==2		;SIXBIT FILENAME
RIBEXT==3		;SIXBIT EXTENSION
RIBSIZ==5		;SIZE OF FILE IN WORDS
RIBSTS==17		;STATUS BITS
RIPDMP==100000		;THIS FILE CONTAINS AN UNPROCESSED DUMP
RIBXRA==34		;POINTER TO NEXT EXTENDED RIB
RIPNUB==400000		;NEW UNIT POINTER IN RETRIEVAL POINTER
RIBCOD==176		;CONTAINS UNLIKELY CODE
CODRIB==777777		;THE CODE
RIBSLF==177		;SELF BLOCK POINTER


;MICROCODE LOADER DEFINITIONS

EXBBYT==20000		;MAXIMUM NUMBER OF BYTES IN AN EXB FILE RECORD
			;(ABSOLUTE MAXIMUM IS 777777)
EXBMAX==<EXBBYT/4>-<EXBBYT/8> ;CORRESPONDING NUMBER OF PDP-10 WORDS
EXBWDS==EXBBYT/4	;SIZE OF EXB RECORD BUFFER
QWDS==6			;NUMBER OF WORDS IN THE QUESTION BUFFER
IOC==1			;I/O CHANNEL
;SYMBOLIC CHARACTER DEFINITIONS

.CHNUL==000	;NUL
.CHCNC==003	;CONTROL C
.CHCND==004	;CONTROL D
.CHBEL==007	;BELL
.CHCNH==010	;BACKSPACE
.CHTAB==011	;TAB
.CHLFD==012	;LINE-FEED
.CHVTB==013	;VERTICAL TAB
.CHFFD==014	;FORM FEED
.CHCRT==015	;CARRIAGE RETURN
.CHCNR==022	;CONTROL R
.CHCNU==025	;CONTROL U
.CHCNZ==032	;CONTROL Z
.CHESC==033	;ESCAPE
.CHDEL==177	;DELETE


;MISCELANEOUS DEFINITIONS

BOOTSA==20		;PHYSICAL ADDRESS OF BOOT ORIGIN STORED HERE
BOOTWD==22		;RH10/DF10 CHANNEL COMMAND PAIR
SYSDDT==401		;EDDT MONITOR START ADDRESS
LBNHOM==1		;BLOCK ADDRESS OF FIRST HOME BLOCK
LB2HOM==12		;BLOCK ADDRESS OF SECOND HOME BLOCK
LBOBAT==1		;OFFSET OF BAT BLOCK FROM HOME BLOCK
LIMLVL==5		;NUMBER OF SFD'S
MBTCOM==411		;COMMUNICATIONS WORD IN LOW CORE FOR REBOOT
			;REQUESTS.  CONTAINS THE PHYSICAL PAGE NUMBER
			;OF WHERE TO PUT BOOT DURING REBOOT PROCESSING
MAXPGS==<FTKL10&^D8192>!<FTKS10&^D1024>
			;MAXIMUM NUMBER OF PAGES POSSIBLE IN MEMORY
MEMITL==^D4		;NUMBER OF WAYS MEMORY CAN BE INTERLEAVED
NXMLEN==<MAXPGS/^D36>+1	;LENGTH OF NXMTAB
; DEVICE CODES
	APR==0			;PROCESSOR
	PI==4			;PI SYSTEM
	PAG==10			;PAGER
	CCA==14			;CACHE
	DTE0==200		;DTE20

; CONI APR BITS
	LP.SBE==1B24		;S-BUSS ERROR
	LP.NXM==1B25		;NXM
	LP.PAR==1B27		;PARITY ERROR
	LP.CSD==1B31		;CACHE SWEEP DONE

; CONO APR (KS10)
	SP.SSF==1B23		;SET SELECTED FLAGS (BITS 24-31)
	SP.IFE==1B25		;INTERRUPT FRONT END
	SP.NXM==1B27		;NXM
	SP.HMP==1B28		;HARD MEMORY PARITY ERROR

; CONO PI BITS
	PI.CPI==1B23		;CLEAR PI SYSTEM
	PI.OFF==1B27		;TURN PI SYSTEM OFF

; CONO PAG BITS (KL10)
	LG.CSL==1B18		;CACHE STRATEGY LOOK
	LG.CSW==1B19		;CACHE STRATEGY WRITE (LOAD)
	XG.KLP==1B21		;KL PAGING
	XG.TEN==1B22		;TRAP ENABLE
	LG.EPT==17777		;ADDRESS OF EPT (KL10)
	SG.EPT==3777B35		;ADDRESS OF EPT (KS10)

; DATAO PAG BITS (KL10)
	XG.LAB==1B0		;LOAD AC BLOCKS
	LG.LPC==1B1		;LOAD PREV CONTEXT (KL10)
	XG.LUB==1B2		;LOAD USER BASE REGISTER
	LG.IAM==1B18		;INHIBIT STORING ACCOUNTING METER (KL10)

; KS10 I/O INSTRUCTIONS FOR WHICH THERE ARE NO REASONABLE
; KL10 EQUIVALENTS
	OPDEF RDHSB [702300,,0]	;READ HALT STATUS BLOCK ADDRESS
	OPDEF WRHSB [702700,,0]	;WRITE HALT STATUS BLOCK ADDRESS
	OPDEF TIOE  [710000,,0]	;TEST UNIBUS, SKIP EQUAL
	OPDEF TION  [711000,,0]	;TEST UNIBUS, SKIP NOT EQUAL
	OPDEF RDIO  [712000,,0]	;READ I/O
	OPDEF WRIO  [713000,,0]	;WRITE I/O
	OPDEF WRIOB [723000,,0]	;WRITE I/O BYTE
	OPDEF WRCSB [702440,,0]	;WRITE CST BASE REGISTER
; KL10/DTE FUNCTION FLAGS
	DT.MTO==10B27		;CTY OUTPUT
	DT.ESP==11B27		;ENTER SECONDARY PROTOCOL

; KL10/DTE COMMUNICATION WORDS IN THE EPT
	DTEEPW==144		;EXAMINE/PROTECTION WORD
	DTEFLG==444		;COMMAND COMPLETE FLAG
	DTEF11==450		;FROM -11 DATA
	DTECMD==451		;COMMAND WORD
	DTEMTD==455		;OUTPUT DONE FLAG
	DTEMTI==456		;INPUT READY FLAG

; KL10/DTE CONO BITS
	TO11DB==1B22		;TO -11 DOOR BELL
	PILDEN==1B31		;ENABLE LOADING PIA
	PI0ENB==1B32		;PI0 ENABLE
	PIA==7B35		;PIA

; FLAGS FROM KLI PASSED IN AC 0 (S)

	KL.SIL==1B0		;SILENT LOAD
	KL.DMP==1B1		;DUMP


; KS10 RELOAD WORD
	RLWORD==31		;RELOAD WORD
	   AUTOBT==1B32		   ;BOOT SWITCH OR POWER UP CONDITION
	   FORREL==1B34		   ;FORCED RELOAD

; KS10 CTY PARAMETERS
	CTYIWD==32		;INPUT WORD
	CTYOWD==33		;OUTPUT WORD
	   CTYOVL==1B27		   ;OUTPUT VALID FLAG

; KS10 KLINIK LINE PARAMETERS
	KLIIWD==34			;KLINIK INPUT WORD

	KLIOWD==35			;KLINIK OUTPUT WORD
	   KLIOVL==1B27			   ;KLINIK OUTPUT VALID

; INSTRUCTION OPDEFS
	OPDEF	XMOVEI	[SETMI	0,]	;EXTENDED MOVE IMMEDIATE
	OPDEF	XJRST	[JRST	15,]	;JRST AND SWITCH SECTIONS
	OPDEF	APRID	[BLKI	APR,]	;READ PROCESSOR SERIAL NUMBER
	OPDEF	RDERA	[BLKI	PI,]	;READ ERROR ADDRESS REGISTER
	OPDEF	CLRPT	[BLKO	PAG,]	;CLEAR ONE ENTRY IN HARDWARE
	OPDEF	SWPUA	[DATAO	CCA,]	;UNLOAD ALL PAGES, UPDATING
					; CORE AND INVALIDATING CACHE
	OPDEF	PJRST	[JUMPA	17,]	;PUSHJ/POPJ
; PAGE FAIL OFFSETS
	.LMPFW==500			;PAGE FAIL WORD
	.LMPFP==501			;OLD PC WORD
	.LMPFN==502			;NEW PC WORD


; MUUO TRAP OFFSETS
	.UPMUO==424			;LOCATION OF MUUO
	.UPMUP==425			;LOCATION OF MUUO PC
	.UPMUE==426			;MUUO EFFECTIVE ADDRESS
;MISCELANEOUS HARDWARE PARAMETERS

APRRST==<FTKL10&327760>!<FTKS10&221700>
			;CONO BITS TO CLEAR THE WORLD
CLRAPR==<FTKL10&127700>!<FTKS10&021700>
			;CONO BITS TO CLEAR APR ERROR FLAGS
ASNMSK==<IFN FTKL10,<7777>>!<IFN FTKS10,<77777>>
			;MASK OF APR SERIAL NUMBER RETURNED BY APRID
IFN FTKS10,<.EPHSB==424>;KS10 HALT STATUS BLOCK ADDRESS

; KL PAGING PAGE MAP BITS
PM.DCD==1		;DIRECT POINTER
PM.WRT==1B4		;WRITABLE PAGE


;MISCELANEOUS PARAMETERS

PDLLEN==^D36		;SIZE OF PDL
LINBFL==^D16		;SIZE OF COMMAND LINE BUFFER IN WORDS
BLKSIZ==200		;SIZE OF A DISK BLOCK
PAGSIZ==1000		;SIZE OF A PAGE
MAXUNI==^D8		;MAX NUMBER OF UNITS ON A CONTROLLER
P2BLSH==2		;AMOUNT TO LSH A PAGE COUNT TO GET BLOCKS
B2WLSH==^D7		;AMOUNT TO LSH A BLOCK COUNT TO GET WORDS
W2BLSH==-B2WLSH		;AMOUNT TO LSH A WORD COUNT TO GET BLOCKS
P2WLSH==^D9		;AMOUNT TO LSH A PAGE NUMBER TO GET WORDS
W2PLSH==-P2WLSH		;AMOUNT TO LSH A WORD COUNT TO GET PAGES
WATTIM==<FTKL10&50>+<FTKS10&10>
			;TIME TO WAIT FOR OPERATOR RESPONSE IN REDLIN
DATLEN==20		;WORDS OF SUBROUTINE DATA STORAGE
IFN FTTAPE,<
ERRTRY==^D40		;NUMBER OF TIMES TO RETRY ON A TAPE ERROR
>; END IFN FTTAPE

;DEVICE(DRIVE) TYPES

TY.T2L==10		;LOWEST TM02 TYPE
TY.T2H==17		;HIGHEST TM02 TYPE
TY.T3L==50		;LOWEST TM03 TYPE
TY.T3H==57		;HIGHEST TM03 TYPE
TY.DXA==60		;DX20A (TX02 TAPE CONTROLLER)
TY.T78==101		;TM78
;DEFINITIONS FOR BACKUP FORMAT MAGTAPES (STOLEN FROM BACKRS)

IFN FTTAPE,<

;WORDS IN HEADER (FIRST 32. WORDS OF EACH RECORD)

G$TYPE==0	;RECORD TYPE
	T$LBL==1	;LABEL IDENTIFICATION RECORD
	T$BEG==2	;SAVE START
	T$END==3	;SAVE END
	T$FIL==4	;DISK FILE DATA
	T$UFD==5	;UFD RIB
	T$EOV==6	;END OF VOLUME
	T$COM==7	;COMMENT
	T$CON==10	;CONTINUE (SAME DATA AS T$BEG-T$END)
	T$MAX==T$CON	;MAXIMUM RECORD TYPE
G$SEQ==1	;SEQUENCE NUMBER
G$RTNM==2	;RELATIVE TAPE NUMBER
G$FLAG==3	;RECORD DEPENDENT BITS
	GF$EOF==1B0	;LAST RECORD OF FILE
	GF$RPT==1B1	;REPEAT OF LAST RECORD WRITE ERROR
	GF$NCH==1B2	;IGNORE CHECKSUM
	GF$SOF==1B3	;START OF FILE
G$CHK==4	;CHECKSUM
G$SIZ==5	;NUMBER OF DATA WORDS
G$LND==6	;TOTAL LENGTH OF NON-DATA SECTION

;SUB-BLOCK CODES FOR FILE NAME BLOCK IN A T$FIL RECORD

.FCDEV==1	;DEVICE
.FCNAM==2	;FILE NAME
.FCEXT==3	;EXTENSION
.FCDIR==40	;DIRECTORY (PPN), SFD'S ARE 41-45

;RECORD SIZE

MTHLEN==^D32	;LENGTH OF MAGTAPE HEADER RECORD
LNMTBF==PAGSIZ+MTHLEN	;LENGTH OF TAPE BUFFER (HEADER PLUS DATA AREA)

>; END IFN FTTAPE
;DEFINITIONS FOR THE .VBOOT VIRTUAL ADDRESS SPACE.  WITH KL PAGING,
;THE MAP SLOT ASSIGNMENTS ARE ALL DIFFERENT AND WE PUT THE ADDRESS
;SPACE INTO THE LOW SEGMENT TO AVOID CONFLICTS WITH THE RH20 IOWDS.

.VBOOT==700000		;VIRTUAL ADDRESS AT WHICH BOOT RUNS
.VPAG0==302000		;PAGE 0 MAPPED THROUGH THIS VIRUAL ADDRESS
			;PAGE 1 MAPPED THROUGH .VPAG0+PAGSIZ
.VMOVE==304000		;FIRST VIRTUAL ADDRESS USED TO MOVE BOOT TO
			;  HIGH CORE
.VVECT==306000		;VIRTUAL ADDRESS OF OLD BOOT VECTOR
.VZERO==300000		;VIRTUAL ADDRESS USED TO ZERO CORE


;MACRO TO COMPUTE THE MAP SLOT OFFSET FOR A GIVEN VIRTUAL ADDRESS

DEFINE VMAP(SYMBOL,ADDR),<
  SYMBOL==<ADDR/PAGSIZ>
>
    

VMAP(.MBOOT,.VBOOT)	;MAPPED BOOT ORIGIN
VMAP(.MPAG0,.VPAG0)	;MAPPED PHYSICAL PAGE 0
			;MAPPED PHYSICAL PAGE 1 IS AT .VPAG0+PAGSIZ
VMAP(.MMOVE,.VMOVE)	;MAPPED PAGE FOR MOVING BOOT
VMAP(.MZERO,.VZERO)	;MAPPED PAGE FOR ZEROING CORE
VMAP(.MVECT,.VVECT)	;MAPPED BOOT VECTOR OF PREVIOUS BOOT
IFN FTKL10,<

;INTERNAL CHANNEL DEVICE DEPENDENT PARAMETERS

FSTICD==540		;FIRST INTERNAL CHANNEL DEVICE CODE
LSTICD==574		;LAST INTERNAL CHANNEL DEVICE CODE

;CI20/NIA20 DEVICE DEPENDENT PARAMETERS

;CONO BITS
CO.CPT==400000		;CLEAR PORT

;RH10/RH20 DEVICE DEPENDENT PARAMETERS

;CONI BITS
CI.XDN==10		;TRANSFER DONE (RH10/RH20)
CI.122==4000,,0		;22 BIT CHANNEL (RH10/DF10C)
CI.1ER==736320		;DBPE, FXCEP, CHNER, OVR, DRE, ILC, PSFAIL,
			;CBOV, RAE, BUSY (RH10)
CI.1RA==100		;RAE (RH10)
CI.2ER==515000		;DPE, LWCE, DR, RAE, DOE (RH20)
CI.2RA==4000		;RAE (RH20)

;CONO BITS
CO.XDN==10		;CLEAR DONE (RH10/RH20)
CO.XSX==20		;STOP TRANSFER (RH10/RH20)
CO.XMI==2000		;MASSBUS INIT (RH10/RH20)
CO.1RB==47		;CONI BITS TO RESTORE - AIE, PIA (RH10)
CO.1AE==40		;AIE (RH10)
CO.2RB==447		;CONI BITS TO RESTORE - MBE, AIE, PIA (RH20)
CO.2ME==400		;MASSBUS ENABLE (RH20)

;DATAI/DATAO BITS

DO.LDR==004000,,0	;LOAD REGISTER (REGISTER NUMBER IN BITS 0-5)
DO.XCR==004400,,0	;DRIVE CONTROL REGISTER (RH10/RH20)
DO.XSR==010400,,0	;STATUS REGISTER (RH10/RH20)
  DI.XCE==40000		;COMPOSITE ERROR (RH10/RH20)
  DI.XSM==172777	;BIT MASK OF BITS TO CHECK FOR IN INITIALIZATION
  DI.XSB==10700		;LEGAL VALUE IN SR (MOL, DP, DR, VV)
DO.XDS==054000,,0	;BLOCK ADDRESS REGISTER, LR (RH10/RH20)
DO.XDT==060000,,0	;DRIVE TYPE REGISTER (RH10/RH20)
DO.XDC==124000,,0	;DESIRED CYLINDER REGISTER, LR (RH10/RH20)
DO.1CR==404000,,0	;CONTROL REGISTER (RH10)
DO.1IA==440000,,0	;INTERRUPT ADDRESS REGISTER (RH10)
DO.2ST==716200,,0	;STCR, LR, RCLP, STORE (RH20)
  DO.XCL==11		;FUNCTION CODE FOR DRIVE CLEAR (RH10/RH20)
  DO.XRP==21		;FUNCTION CODE FOR READIN PRESET (RH10/RH20)
  DO.XRD==71		;FUNCTION CODE FOR READ (RH10/RH20)
  DO.XWT==61		;FUNCTION CODE FOR WRITE (RH10/RH20)
DO.2IV==740000,,0	;INTERRUPT VECTOR INDEX REGISTER (RH20)
;MISCELANEOUS

RH2TRA==1B0		;CHANNEL COMMAND OPCODE FOR TRANSFER (RH20)
RH2JMP==1B1		;CHANNEL COMMAND OPCODE FOR JUMP (RH20)
R2IOWL==^D66		;NUMBER OF IOWDS TO ALLOCATE FOR THE LARGEST
			;POSSIBLE TRANSFER
R2BCNT==^D15		;MAX NUMBER OF BLOCKS WHICH MAY BE SPECIFIED
			;IN ONE IOWD FOR AN RH20
R2WCNT==R2BCNT*BLKSIZ	;CORRESPONDING WORDCOUNT
R1BCNT==^D127		;MAX NUMBER OF BLOCKS WHICH MAY BE SPECIFIED
			;IN ONE IOWD FOR AN RH10
R1WCNT==R1BCNT*BLKSIZ	;CORRESPONDING WORDCOUNT

>; END IFN FTKL10
IFN FTKS10,<

;RH11 DEVICE DEPENDENT PARAMETERS

;UBA ADDRESSES/BITS

SO.UPR==763000		;UBA PAGING RAM ADDRESS
  SO.VFT==140000	;VALID+FAST XFER
  SO.RBT==100,,277	;BITS TO RESTORE IN CS1 AND UBA SR
SO.USR==763100		;UBA STATUS REGISTER
  SO.UBI==100		;UNIBUS INIT
  SI.UER==740000	;TIME OUT, BMD, BUS PAR, NXD

;DRIVE ADDRESSES/BITS

SO.CS1==776700		;CONTROL STATUS REGISTER 1
  SI.RDY==200		;READY AT END OF XFER
  SI.S1E==140000	;SC, TRE
SO.WC==776702		;WORD COUNT REGISTER
SO.BA==776704		;BUS ADDRESS REGISTER
SO.DA==776706		;DESIRED ADDRESS REGISTER
SO.CS2==776710		;CONTROL STATUS REGISTER 2
SO.DS==776712		;DRIVE STATUS REGISTER
  SO.DSM==172700	;MASK FOR BITS RETURNED
  SO.DSB==10700		;LEGAL VALUE (MOL, DP, DR, VV)
SO.ASR==776716		;ATTENTION SUMMARY REGISTER
SI.DT==776726		;DRIVE TYPE REGISTER
  SI.DSK==20000		;DEVICE IS A DISK
SO.DC==776734		;DESIRED CYLINDER REGISTER

;MISCELLANEOUS

SO.DCL==11		;FUNCTION CODE FOR DRIVE CLEAR
SO.RIP==21		;FUNCTION CODE FOR READIN PRESET
SO.WRT==61		;FUNCTION CODE FOR WRITE
SO.RED==71		;FUNCTION CODE FOR READ

RSBCNT==^D252		;MAX NUMBER OF BLOCKS WHICH MAY BE TRANSFERED
			;AT ONE TIME BY THE RH11

>;END IFN FTKS10
;TM02 DEVICE-DEPENDENT PARAMETERS

IFN FTTM02,<

;PARAMETERS COMMON TO BOTH KL AND KS

;TAPE CNTRL REGISTER BITS
T2.M7T==20		;7-TRACK CORE DUMP

;FUNCTIONS
T2.RWF==7		;REWIND
T2.DCF==11		;DRIVE CLEAR
T2.SFF==31		;SKIP-FORWARD
T2.SBF==33		;SKIP BACKWARD
T2.RDF==71		;READ

IFN FTKL10,<

;REGISTERS
T2.DSR==010000,,0	;STATUS REGISTER
T2.DER==020000,,0	;ERROR
T2.DFC==050000,,0	;FRAME COUNTER
T2.DTC==110000,,0	;TAPE CNTRL
T2.DRH==400000,,0	;RH10 CNTRL REG

T2.DLR==004000,,0	;LOAD REGISTER

;CONI BITS
T2.DON==10		;DONE

;STATUS BITS
T2.SER==40000		;ERROR
T2.SPP==20000		;POSITION IN PROGRESS
T2.SRY==200		;READY
T2.SPE==40		;PHASE ENCODED
T2.SEF==4		;EOF
T2.SBT==2		;BOT

;ERROR REG
T2.NER==102200		;NOT ERRORS IF PE MODE
T2.ERR==176377		;ERROR IF ON
>; END IFN FTKL10
IFN FTKS10,<
TRHBAS==3,,772440	;BASE UBA ADDRESS FOR TAPE RH11

;RH11/TM02 REGISTER OFFSETS

MTCS1==0		;CONTROL REGISTER
MTWC==2			;WORD COUNT REGISTER
MTBA==4			;BUS ADDRESS REGISTER
MTFC==6			;FRAME COUNT REGISTER
MTCS2==10		;STATUS REGISTER
MTDS==12		;DRIVE STATUS REGISTER
MTER==14		;ERROR REG
MTAS==16		;ATTENTION SUMMARY
MTCC==20		;CHARACTER CHECK REGISTER
MTDB==22		;DATA BUFFER
MTMR==24		;MAINT REGISTER
MTDT==26		;DRIVE TYPE
MTSN==30		;SERIAL NUMBER
MTTC==32		;TAPE CONTROL REGISTER

;CONTROL REGISTER BIT ASSIGNMENTS

C1.SC==100000		;(R) SPECIAL CONDITION (ALL ERRORS)
C1.TRE==40000		;(R/W) TRANSFER ERROR
C1.CPE==20000		;(R) CONTROL BUS PARITY ERROR
C1.DVA==4000		;(R) DRIVE AVAILABLE
C1.PSL==2000		;(R/W) PORT SELECT
C1.RDY==200		;(R) READY
C1.IE==100		;(R/W) INTERRUPT ENABLED

;STATUS REGISTER BIT ASSIGNMENTS

C2.DLT==100000		;(R) DATA LATE (OVERRUN)
C2.WCE==40000		;(R) WRITE CHECK ERROR
C2.UPE==20000		;(R/W) UNIBUS PARITY ERROR
C2.NXD==10000		;(R) NON-EXISTANT DRIVE
C2.NXM==4000		;(R) NON-EXISTANT MEMORY
C2.PGE==2000		;(R) PROGRAM ERROR
C2.MXF==1000		;(R/W) MISSED TRANSFER
C2.DPE==400		;(R) DATA BUS PARITY ERROR
C2.OR==200		;(R) OUTPUT READY
C2.IR==100		;(R) INPUT READY
C2.CLR==40		;(W) CONTROLLER CLEAR
C2.PAT==20		;(R/W) PARITY TEST
C2.BAI==10		;(R/W) UNIBUS ADDRESS INCREMENT INHIBIT
;DRIVE STATUS REGISTER

DS.ATA==1B20		;ATTENTION
DS.ERR==1B21		;COMPOSITE ERROR
DS.PIP==1B22		;POSITIONING IN PROGRESS
DS.MOL==1B23		;MEDIUM ON LINE
DS.WRL==1B24		;WRITE LOCKED
DS.EOT==1B25		;END OF TAPE
DS.DPR==1B27		;DRIVE PRESENT
DS.DRY==1B28		;DRIVE READY (NOT GO)
DS.SSC==1B29		;SLAVE STATUS CHANGE
DS.PES==1B30		;PHASE ENCODED STATUS
DS.SDN==1B31		;SHUTDOWN BIT
DS.IDB==1B32		;IDENT BURST (FOR PE)
DS.TM==1B33		;TAPE MARK
DS.BOT==1B34		;BEGINNING OF TAPE
DS.SLA==1B35		;SLAVE ATTENTION
DS.OK==DS.EOT!DS.PES!DS.TM!DS.BOT!DS.SSC!DS.SDN!DS.IDB	;BITS WHICH DON'T MATTER
DS.GUD==DS.MOL!DS.DPR!DS.DRY	;THESE BITS MUST BE ON

;DRIVE ERROR REGISTER

ER.COR==1B20		;CORRECTABLE DATA/ CRC ERROR
ER.UNS==1B21		;UNSAFE
ER.OPI==1B22		;OPERATION INCOMPLETE
ER.DTE==1B23		;DRIVE TIMING ERROR
ER.NEF==1B24		;NON-EXISTANT FUNCTION
ER.CS==1B25		;CORRECTABLE SKEW/ ILLEGAL TAPE MARK
ER.FCE==1B26		;FRAME COUNT ERROR
ER.NSG==1B27		;NON-STANDARD GAP (CRAP IN THE GAP)
ER.LRC==1B28		;LRC ERROR/ FORMAT (PREAMBLE POSTAMBLE) ERROR
ER.INC==1B29		;INCORRECTABLE DATA/ VERTICAL PARITY ERROR
ER.DPA==1B30		;DATA BUS PARITY ERROR
ER.FMT==1B31		;FORMAT ERROR
ER.CPA==1B32		;CBUS PARITY ERROR
ER.RMR==1B33		;REG MODIFICATION REFUSED
ER.ILR==1B34		;ILLEGAL REGISTER ADR
>; END IFN FTKS10
>; END IFN FTTM02
;TX01/DX10 DEVICE-DEPENDENT PARAMETERS

IFN FTDX10,<
;DEVICE DATAO BITS

DO.RES==1B16		;DO LOCAL RESET
DO.LRS==1B17		;LOAD REG SELECT
DO.UC0==4		;MP CTL 0
DO.UC1==5		;MP CTL 1
DU0HLT==1B19		;HALT
DU0CON==1B20		;CONTINUE
DU0EXM==1B22		;EXAMINE
DU0DEP==1B23		;DEPOSIT

UP.SA==200		;MP START ADDRESS
PDC==220		;DEVICE CODE
ICPC==20		;PLACE FOR INITIAL CHL PC

;CHL BITS

CH.COP==1B1+1B3		;DEVICE COMMAND, AUTO ERROR RETRY
CH.GO==1B2		;GO BIT
CH.JMP==1B3		;CHL JMP
CH.STS==1B4		;STORE STATUS
CH.FRC==1B5		;FORCE SENSE BYTES

;DEVICE COMMANDS

TX.NOP==3		;NOOP
TX.FRD==2		;READ FORWARD
TX.FSR==67		;FORWARD SPACE RECORD
TX.BSR==47		;BACK SPACE RECORD
TX.REW==7		;REWIND

;CONI BITS
 
TX.RUN==1B17	;RUN BIT  
TX.ILI==1B25	;INHIBIT LOAD ICPC
TX.UPE==1B26	;MP ERROR
TX.MPE==1B27	;MEM PARITY ERROR
TX.NXM==1B28	;NXM
TX.STA==1B29	;STATUS AVAILABLE
TX.CLR==1B31	;CLEAR
TX.CON==1B32	;CONTINUE

;SENSE BYTE DEFINITIONS

LSNS==^D24	;NUMBER OF SENSE BYTES
SB1==4		;OFFSET INTO CHSNS FOR BYTE 1
SB17TK==1B11	;DRIVE IS 7-TK
;STATUS BITS IN DSR/CSR

DS.UCH==1B6		;UNIT CHECK
DS.UEX==1B7		;UNIT EXCEPTION

CS.SLE==1B11		;SELECTION ERROR
CS.SQE==1B12		;SEQUENCE ERROR
CS.DPE==1B13		;DEVICE PARITY ERROR
CS.LNE==1B14		;LENGTH ERROR
CS.DSF==1B17		;DSR FLAG

CS.NFG==1B18		;SENSE AND/OR STATUS NO GOOD
CS.INC==1B19		;OP INCOMPLETE

CS.STE==1		;ENDING STATUS
CS.STC==2		;CU INITIATED STATUS

;DATA MODES

TX.7TK==3		;7 TRACK CORE DUMP
TX.9TK==0		;9 TRACK CORE DUMP

TX.D72==063		;200 BPI + ODD PARITY
TX.D75==163		;556 BPI + ODD PARITY
TX.D78==263		;800 BPI + ODD PARITY
>; END IFN FTDX10
;TX02/DX20 DEVICE-DEPENDENT PARAMETERS

IFN FTDX20,<
;RH20 CONI/CONO BITS

D2.ATN==1B28		;ATTENTION
D2.CLR==5010		;BITS TO CLEAR ERRORS

;RH20 DATAI/DATAO BITS

D2.SCR==71B5		;RH20 SECONDARY COMMAND REGISTER
	D2.LDR==1B6	;LOAD REGISTER ON DATAO
	D2.RCP==1B7	;RESET COMMAND LIST POINTER
	D2.SCS==1B10	;STORE CHANNEL STATUS
	D2.DTE==1B19	;DISABLE TRANSFER ERROR STOP
	D2.TRA==1B0	;TRANSFER IN CHANNEL COMMAND LIST
	D2.RHJ==1B1	;JUMP WORD IN CHANNEL COMMAND LIST
	D2.HLT==1B1	;HALT CHANNEL WHEN COMBINED WITH D2.TRA

;DX20 DATAO/DATAI BITS

D2.CTR==0B5		;CONTROL REGISTER
	D2.REW==7	;REWIND OPERATION PLUS GO BIT
	D2.SFR==31	;SKIP FORWARD OPERATION PLUS GO BIT
	D2.SBR==33	;SKIP BACKWARD OPERATION PLUS GO BIT
	D2.SNS==45	;SENSE OPERATION PLUS GO BIT
	D2.RDF==71	;READ FORWARD PLUS GO BIT
D2.STR==1B5		;STATUS REGISTER
	D2.CER==1B21	;COMPOSITE ERROR
	D2.RUN==1B23	;MICROPROCESSOR IS RUNNING
D2.ERR==2B5		;ERROR REGISTER
	D2.HER==177B35	;HARD ERRORS
D2.MTR==3B5		;MAINTENANCE REGISTER
	D2.SCY==1B31	;SINGLE CYCLE
	D2.SMP==1B33	;START MICRO PROCESSOR
	D2.RES==1B34	;RESET MICRO PROCESSOR
D2.ASR==4B5		;ATTENTION SUMMARY REGISTER
D2.FCR==5B5		;FRAME COUNT REGISTER
D2.GP0==20B5		;STATUS INDEX/ENDING STATUS REGISTER
	D2.DVE==1B25	;DEVICE END
	D2.UCK==1B26	;UNIT CHECK
	D2.UEX==1B27	;UNIT EXCEPTION
	D2.RST==1B28	;REQUEST STATUS UPDATE
D2.GP1==21B5		;DRIVE NUMBER REGISTER
D2.GP4==24B5		;ASYNCHRONOUS STATUS REGISTER
D2.GP6==26B5		;EXTENDED STATUS REGISTER 0
D2.DR0==30B5		;DIAGNOSTIC REGISTER 0
D2.DR1==31B5		;DIAGNOSTIC REGISTER 1
	D2.IRE==1B20	;INSTRUCTION REGISTER ENABLE
	D2.MSE==1B21	;ENABLE MICRO-STORE LOAD FROM IR
	D2.PCE==1B22	;PC ENABLE
	D2.PCI==1B23	;PC AUTO INCREMENT
D2.DR7==37B5		;DIAGNOSTIC REGISTER 7
	D2.IRP==1B22	;IR PARITY ERROR

D2.DLR==004000,,0	;LOAD REGISTER
D2.DRE==000400,,0	;DISABLE REGISTER ACCESS ERROR STOP

;MISCELLANEOUS DEFINITIONS

D2.7TK==1B31		;DRIVE IS 7 TRACK IN SENSE BYTE 1
D2.SAD==1		;DX20 START ADDRESS
D2.C10==100		;REQUIRED CONTENTS OF CRAM LOCATION 10
D2.C11==042562		;REQUIRED CONTENTS OF CRAM LOCATION 11

;MAGIC ADDRESS AND VALUE

MAGICA==11		;ADDRESS WE MUST STORE MAGIC VALUE IN
MAGICV==42562		;THE MAGIC VALUE
>; END IFN FTDX20
;TM78 DEVICE-DEPENDENT PARAMETERS

IFN FTTM78,<

;DEVICE REGISTERS

T7.ICD==010000,,0	;INTERRUPT CODE
	.T7DCD==1		;DONE
	.T7SCD==21		;SHORT RECORD (OTHERWISE OK)
	.T7EOF==2		;EOF
T7.FMT==020000,,0	;FORMAT REGISTER
T7.ATR==040000,,0	;ATTENTION SUMMARY REGISTER
T7.BCT==050000,,0	;BYTE COUNT REGISTER
T7.NIC==130000,,0	;NON-DATA INTERRUPT CODE
T7.TMS==210000,,0	;STATUS REGISTER
	T7.TMC==40000		;TM CLEAR
	T7.TMR==100000		;TM READY

T7.DLR==004000,,0	;LOAD REGISTER FLAG

.T7DV0==14		;REGISTER FOR DRIVE 0


;FUNCTIONS

T7.FRW==7		;REWIND
T7.FSN==11		;SENSE
T7.FSR==21		;SKIP RECORD
T7.FBR==23		;BACKSPACE RECORD
T7.FRD==71		;READ
>; END IFN FTTM78
	SUBTTL	MACRO DEFINITIONS


; MACRO TO LOAD THE VECTOR
DEFINE	LV	(OFS,DAT),<
	.ORG	BTSVEC+.BT'OFS
	IRP DAT,<DAT>
>

;MACRO DEFINITIONS TO ALLOW ASSEMBLY TO BE PHASED STARTING AT .VBOOT
DEFINE	BLK(LABEL,SIZE),<LABEL:	  BLOCK	SIZE>


;MACRO TO BUILD THE BOOT VERSION STRING
DEFINE	VSTR(VER,EDT),<
ASCIZ/BOOT V'VER'(EDT)

/
	>


;MACRO TO CAUSE A FATAL ERROR TRAP AND RESTART BOOT.

DEFINE	ERROR(TEXT),<
	PUSHJ	P,FATERR
	JUMP	[ASCIZ |TEXT|]
>; END DEFINE ERROR
;MACROS TO HELP IN INSERTING ENTRIES INTO THE PAGE MAP

DEFINE	ONE41(FPAGE,LPAGE),<
	  ZZ==FPAGE
	  XLIST
	  REPEAT <LPAGE-FPAGE+1>,<
	    EXP <PM.DCD>B2+PM.WRT+ZZ
	    ZZ==ZZ+1
	  >
	  LIST
	>


DEFINE	INSLOC(FLOC,LLOC,INSTN),<
	  XLIST
	  REPEAT <LLOC-FLOC+1>,<
	    INSTN
	  >
	  LIST
	>


;MACRO TO CAUSE A PAUSE BETWEEN THE DATAO WHICH LOADS THE PREPARATION
;REGISTER AND THE DATAI WHICH READS THE VALUE FROM THE SPECIFIED
;REGISTER.

	DEFINE	STALL,<
	  IMULI	P,1
	  IFN FTKL10,<
	  XLIST
	  IMULI P,1
	  LIST
	  >
	>
;MACRO TO PUT TEXT IN FORMAT SO IT LOOKS LIKE 11 ASCII WHEN IT GET INTO
;20F FORMAT.  SEE RSXCMN.MAC IF YOU ABSOLUTELY NEED TO KNOW HOW THIS HAPPENS.
;(SIGH, IRPC WON'T DEAL WITH <CR><LF>, SO \| WILL HAVE TO DO)

IFN FTKL10,<
	DEFINE	ASCI11(A),<
	  ...Z1==0
	  ...Z2==0
	  IRPC	A,<
		...Z3==<"'A'">
		IFE ...Z3-"\",<...Z3==15>
		IFE ...Z3-"|",<...Z3==12>
		IFE <...Z2-0>,<...Z1==...Z3>
		IFE <...Z2-1>,<...Z1==<...Z3_^D8>!...Z1>
		IFE <...Z2-2>,<...Z1==<...Z3_^D16>!...Z1>
		IFE <...Z2-3>,<EXP <...Z3_^D24>!...Z1
			       ...Z2==-1>
		...Z2==...Z2+1>
	  IFN	...Z2,<EXP ...Z1>
			>
>;FTKL10

IFN FTKS10,<			;IF A KS10, IT'S ASCIZ AFTER ALL!
	DEFINE	ASCI11(A),<
	  ...Z1==0
	  ...Z2==0
	  IRPC	A,<
		...Z3==<"'A'">
		IFE ...Z3-"\",<...Z3==15>
		IFE ...Z3-"|",<...Z3==12>
		IFE <...Z2-0>,<...Z1==<...Z3>B6>
		IFE <...Z2-1>,<...Z1==<...Z3>B13!...Z1>
		IFE <...Z2-2>,<...Z1==<...Z3>B20!...Z1>
		IFE <...Z2-3>,<...Z1==<...Z3>B20!...Z1>
		IFE <...Z2-4>,<EXP <...Z3>B27!...Z1
			       ...Z2==-1>
		...Z2==...Z2+1>
	  IFN	...Z2,<EXP ...Z1>
			>
>;FTKS10
	SUBTTL	MICROCODE LOADER


	RELOC	0

LOADER:	JFCL			;NO CCL
	RESET			;STOP I/O
	SETOM	USRFLG		;REMEMBER TO DO USER MODE I/O TO THE TTY
	MOVE	P,[IOWD PDLLEN,BTSPDL] ;SET UP A PUSH DOWN LIST
	PUSHJ	P,DELPGS	;KILL USELESS PAGES

GO:
LOADR1:	PUSHJ	P,QINIT		;INIT QUESTION BUFFER
	MOVEI	T1,[ASCIZ/Create binary output files/]
	PUSHJ	P,QTEXT		;STORE IN BUFFER
	PUSHJ	P,QYNT		;APPEND [Y/N] AND TERMINATE BUFFER
	MOVEI	T2,[ASCIZ/No/]	;DEFAULT ANSWER
	PUSHJ	P,ASKYN		;ASK
	  JRST	LOADR1		;CONFUSED USER
	  TDZA	T1,T1		;USER SAID NO
	MOVEI	T1,1		;USER SAID YES
	MOVEM	T1,BINFLG	;SAVE FLAG
	JUMPN	T1,LOADR3	;SKIP DDT QUESTION IF WRITING FILES

LOADR2:	SKIPN	.JBDDT		;DDT LOADED?
	JRST	LOADR3		;NO
	PUSHJ	P,QINIT		;INIT QUESTION BUFFER
	MOVEI	T1,[ASCIZ/Preserve EDDT and symbols/]
	PUSHJ	P,QTEXT		;STORE IN BUFFER
	PUSHJ	P,QYNT		;APPEND [Y/N] AND TERMINATE BUFFER
	MOVEI	T2,[ASCIZ/No/]	;DEFAULT ANSWER
	PUSHJ	P,ASKYN		;ASK
	  JRST	LOADR2		;CAN'T DECIDE
	  PUSHJ	P,DELDDT	;ZAP OLD LOADER+DDT+SYMBOLS

LOADR3:	PUSHJ	P,HIADDR	;FIND HIGHEST ADDRESS IN USE
	MOVEM	T1,UCODSA	;SAVE AS UCODE STARTING ADDRESS
	MOVEM	T1,LOADFF	;SAVE FIRST FREE LOCATION
	MOVSI	U,-UCDNUM	;FOR INDEXING INTO UCODE TABLES

LOADR4:	SKIPN	UCDTXT(U)	;THIS A REAL ENTRY?
	JRST	LOADR5		;NO
	PUSHJ	P,QINIT		;INIT QUESTION BUFFER
	MOVEI	T1,[ASCIZ/Load /]
	PUSHJ	P,QTEXT		;STORE IN BUFFER
	MOVE	T1,UCDTXT(U)	;GET TEXT
	PUSHJ	P,QTEXT		;STORE IN BUFFER
	PUSHJ	P,QYNT		;APPEND [Y/N] AND TERMINATE BUFFER
	MOVEI	T2,[ASCIZ/No/]	;DEFAULT ANSWER
	PUSHJ	P,ASKYN		;ASK
	  JRST	LOADR4		;CONFUSED USER
	  JRST	LOADR5		;DON'T WANT IT
	PUSHJ	P,LODFIL	;LOAD A FILE
	  JRST	LOADR4		;GIVE THE GUY A CHANCE TO FIX THINGS

LOADR5:	AOBJN	U,LOADR4	;LOOP BACK FOR ANOTHER UCODE
	SKIPN	BINFLG		;WRITING BINARY FILES?
	JRST	LOADR6		;NO
	EXIT	1,		;DONE
	JRST	LOADER		;THE FOOL TYPED CONTINUE

LOADR6:	PUSHJ	P,MEMMAP	;DISPLAY MEMORY MAP
	DMOVE	T1,.JBSYM	;GET POINTER TO SYMBOL TABLES
	DMOVEM	T1,BTSVEC+.BTSYM ;SAVE FOR DEBUGGING
	MOVEI	T1,BOOT		;GET START ADDRESS
	HRRM	T1,.JBSA	;STORE IT
IFN FTKL10,<
	PUSHJ	P,EXBFIL	;WRITE AN EXB FILE FOR RSX-20F
>; END IFN FTKL10
	MOVSI	T1,SAVBLT	;WHERE THE FINAL INSTRUCTIONS LIVE
	HRRI	T1,.JBBLT	;AND WHERE THEY'RE MOVING TO
	BLT	T1,.JBBLT+3	;MOVE SAVE. UUO INTO PLACE
	MOVSI	17,SAVCOD	;POINT TO CODE THAT RUNS IN THE ACS
	BLT	17,17		;LOAD THE ACS
	JRST	SAVGO		;DELETE LOADER, DO SAVE, AND EXIT
SUBTTL	FILE LOADERS -- DISPATCH


LODFIL:	SETZM	UCODWD		;CLEAR WORD COUNT
	SETZM	UCODCK		;AND THE CHECKSUM
	SETZM	UCODVR		;AND THE VERSION NUMBER
	MOVSI	T1,UCODBF	;POINT TO START OF TEMP STORAGE
	HRRI	T1,UCODBF+1	;MAKE A BLT POINTER
	SETZM	UCODBF		;CLEAR FIRST WORD
	BLT	T1,UCODBF+UCDSIZ-1 ;CLEAR TEMP STORAGE
	MOVE	T1,UCDNAM(U)	;GET FILE NAME
	HLLZ	T2,UCDEXT(U)	;GET EXTENSION
	MOVE	T3,UCDMOD(U)	;GET I/O MODE
	PUSHJ	P,SETIO		;SET UP FOR I/O
	MOVEI	T1,.FORED	;FILOP FUNCTION
	PUSHJ	P,FILOP		;DO IT
	  JRST	OPNERR		;FAILED
	MOVSI	T1,-FMTLEN	;-LENGTH OF TABLE
	HRRI	T1,FMTTAB	;MAKE AN AOBJN POINTER
LODFI1:	HLLZ	T2,(T1)		;GET AN EXTENSION
	CAME	T2,UCDEXT(U)	;A MATCH?
	AOBJN	T1,LODFI1	;NO
	SKIPL	T1
	HALT	.
	HRRZ	T2,(T1)		;GET DISPATCH ADDRESS
	PUSHJ	P,(T2)		;LOAD FILE
	  JRST	LODFI4		;FAILED
	SKIPE	BINFLG		;WRITING BINARY FILES?
	JRST	LODFI2		;YES
	PUSHJ	P,GETCOR	;ALLOCATE CORE
	  JRST	LODFI4		;FAILED--ALL DONE HERE
	MOVE	T1,UCDPTR(U)	;GET UCODE POINTER INTO VECTOR
	MOVE	T2,UCODWD	;GET WORD COUNT
	AOS	T2		;PLUS ONE FOR THE VERSION WORD
	MOVE	T3,LOADFF	;AND LOAD ADDRESS
	SUBI	T3,BTSVEC	;OFFSET FROM THE START OF THE VECTOR
	DMOVEM	T2,(T1)		;SAVE IN VECTOR
	MOVE	T1,UCODVR	;GET THE VERSION
	MOVEM	T1,@LOADFF	;SAVE
	AOS	LOADFF		;ADVANCE
	MOVSI	T1,UCODBF	;POINT TO TEMP STORAGE
	HRR	T1,LOADFF	;AND TO PERMANENT STORAGE
	MOVE	T2,UCODWD	;GET WORD COUNT
	ADD	T2,LOADFF	;COMPUTE END OF BLT
	BLT	T1,-1(T2)	;COPY
	MOVE	T1,UCODWD	;GET WORD COUNT AGAIN
	ADDM	T1,LOADFF	;UPDATE FIRST FREE LOCATION
	JRST	LODFI3		;FINISH UP
LODFI2:	RELEAS	IOC,		;RELEASE CHANNEL
	PUSHJ	P,WRTBIN	;WRITE OUT BINARY FILE
	  POPJ	P,		;FAILED

LODFI3:	AOS	(P)		;SKIP
LODFI4:	RELEAS	IOC,		;RELEASE CHANNEL
	POPJ	P,		;AND RETURN
FMTTAB:	XWD	'A8 ',A8L	;A8  FORMAT LOADER
	XWD	'ADX',ADX	;ADX FORMAT LOADER
	XWD	'ULD',ULD	;ULD FORMAT LOADER
FMTLEN==.-FMTTAB		;LENGTH OF TABLE


LODER2:	PUSHJ	P,PRCRLF	;START WITH A CRLF
	MOVEI	T1,[ASCIZ/? Input error reading /]
	PUSHJ	P,PRMSG		;TYPE TEXT
	PUSHJ	P,PRFILE	;PRINT FILESPEC
	PUSHJ	P,PRCRLF	;FINISH WITH A CRLF
	JRST	LODFI4		;GO EXIT THROUGH COMMON CLEANUP CODE

FMTERR:	MOVEI	T1,[BYTE (7).CHCRT,.CHLFD,"?"," ",0]
	PUSHJ	P,PRMSG		;START ERROR MESSAGE
	HLLZ	T1,UCDEXT(U)	;GET UCODE EXTENSION
	PUSHJ	P,PRSIX		;PRINT IT
	MOVEI	T1,[ASCIZ / file format error reading /]
	PJRST	FILERR		;PRINT FILESPEC AND RETURN

OPNERR:	MOVEI	T1,[ASCIZ /Open failed for /]
	JRST	IOEERR		;ENTER COMMON CODE
INPERR:	MOVEI	T1,[ASCIZ /Input error reading /]
	JRST	IOEERR		;ENTER COMMON CODE
OUTERR:	MOVEI	T1,[ASCIZ /Output error writing /]
	JRST	IOEERR		;ENTER COMMON CODE
UEFERR:	MOVEI	T1,[ASCIZ /Unexpected EOF reading /]
	JRST	IOEERR		;ENTER COMMON CODE
CHKERR:	MOVEI	T1,[ASCIZ /File data checksum error reading /]
IOEERR:	PUSH	P,T1		;SAVE T1
	MOVEI	T1,[BYTE (7).CHCRT,.CHLFD,"?"," ",0]
	PUSHJ	P,PRMSG		;START ERROR MESSAGE
	POP	P,T1		;GET START OF TEXT
FILERR:	PUSHJ	P,PRMSG		;PRINT TEXT
	PUSHJ	P,PRFILE	;PRINT FILESPEC
	PJRST	PRCRLF		;END WITH A CRLF
SUBTTL	FILE LOADERS -- A8 FORMAT


A8L:	MOVSI	T1,(POINT 7,)	;BYTE POINTER
	PUSHJ	P,SETBUF	;SET UP BUFFERS
	MOVE	T1,[BYTE (12)7402,7402,7402] ;PDP-8 HALT INSTRUCTIONS
	MOVEM	T1,UCODBF	;SAVE IN BUFFER
	MOVE	T1,[UCODBF,,UCODBF+1] ;SET UP BLT
	BLT	T1,UCODBF+<10000/3>-1 ;FILL ENTIRE BUFFER
A8L1:	PUSHJ	P,WCREAD	;GET WORD COUNT IN WC
	JUMPE	T1,A8L3		;ALMOST DONE IF ZERO
	MOVE	T4,T1
	PUSHJ	P,WDREAD	;GET DATA WORD
	PUSH	P,T2
	IDIVI	T1,3
	ADDI	T1,UCODBF	;INDEX INTO BUFFER
	MOVE	T3,T1		;COPY ADDRESS
	IMULI	T2,^D12
	MOVEI	T1,^D36
	SUB	T1,T2
	LSH	T1,^D12
	IORI	T1,^D12_6
	HRLM	T1,T3		;FORM BYTE PNTR
	POP	P,T2		;RESTORE
A8L2:	PUSHJ	P,WDREAD	;GET WORD
	IDPB	T1,T3		;STASH WORD
	SOJG	T4,A8L2		;LOOP THROUGH ALL WORDS
	PUSHJ	P,CHREAD	;READ AND VERIFY CHECKSUM
	JRST	A8L1		;GET NEXT RECORD
A8L3:	MOVEI	T1,<10000/3>	;NUMBER OF PDP-10 WORDS
	MOVEM	T1,UCODWD	;SAVE FOR CORE ALLOCATOR
	LDB	T1,[POINT 12,UCODBF+1,11] ;GET VERSION NUMBER
	DPB	T1,[POINT 9,UCODVR,11] ;SAVE
	JRST	CPOPJ1		;RETURN


;ROUTINE TO READ THE CHECKSUM FROM FILE AND THE CRLF
;CHECK THAT CHECKSUM IS CORRECT
CHREAD:	PUSHJ	P,GET2W		;GET A WORD
	CAIE	T2,.CHCRT	;TERMINATOR BETTER BE CR
	PJRST	FMTERR		;FORMAT ERROR
	ADD	T1,UCODCK	;ADD COMPUTED CHECKSUM
	ANDI	T1,7777		;MASK DOWN
	JUMPN	T1,CHKERR	;JUMP IF CHECKSUM ERROR
	PUSHJ	P,GETBYT	;GET A BYTE
	  PJRST	UEFERR		;UNEXPECTED EOF
	CAIE	T1,.CHLFD	;DOUBLE CHECK CRLF
	PJRST	FMTERR		;FORMAT ERROR
	POPJ	P,		;RETURN
;PDP-8 A8 UTILITIES

GET2W:	PUSH	P,[0]		;INIT ANSWER
	PUSHJ	P,GETA8		;GET FIRST CHAR
	  JRST	GET2X		;EXIT IF NOT DIGIT
	MOVEM	T1,0(P)		;STASH ON PDL
	PUSHJ	P,GETA8		;GET NEXT
	  JRST	GET2X		;MUST BE SINGLE DIGIT
	EXCH	T1,0(P)		;NEW LOW ORDER BYTE
	LSH	T1,6		;MAKE HIGH ORDER BYTE
	IORM	T1,0(P)		;COMBINE
	PUSHJ	P,GETBYT	;GET A BYTE
	  PJRST	UEFERR		;UNEXPECTED EOF
GET2X:	MOVE	T2,T1		;RETURN BREAK CHAR IN T2
	POP	P,T1		;RESTORE WORD TO T1
	POPJ	P,		;RETURN

;GET NEXT FILE CHAR AND RETURN LOW 6 BITS
GETA8:	PUSHJ	P,GETBYT	;GET A BYTE
	  PJRST	UEFERR		;UNEXPECTED EOF
	CAIE	T1,","		;CHECK TERMINATOR
	CAIN	T1,.CHCRT	;CARRIAGE RETURN?
	POPJ	P,		;NON SKIP RETURN
	ANDI	T1,77		;TRIM TO LOW ORDER 6-BIT
	JRST	CPOPJ1		;RETURN

;GET WORD COUNT FFROM FILE

WCCOMM:	PUSHJ	P,SKPCOM	;SKIP COMMENT
WCREAD:	PUSHJ	P,GETBYT	;READ A BYTE
	  PJRST	UEFERR		;UNEXPECTED EOF
	CAIE	T1,"8"		;CHECK VALIDITY
	JRST	WCCOMM		;SKIP COMMENT AND TRY AGAIN
	PUSHJ	P,GETBYT	;GET A BYTE
	  PJRST	UEFERR		;UNEXPECTED EOF
	CAIE	T1," "		;BETTER BE A SPACE
	PJRST	FMTERR		;FORMAT ERROR
	SETZM	UCODCK		;INIT CHECKSUM

WDREAD:	PUSHJ	P,GET2W		;GET 12 BIT NUMBER
	ADDM	T1,UCODCK	;ADD TO CHECKSUM
	CAIE	T2,","		;NEED A COMMA
	PJRST	FMTERR		;FORMAT ERROR
	POPJ	P,		;RETURN (ANSWER IN T1)

;ROUTINE TO SKIP COMMENTS
SKPCOM:	CAIE	T1,";"		;VALID COMMENT CHAR?
	PJRST	FMTERR		;FORMAT ERROR
SKPCM1:	PUSHJ	P,GETBYT	;GET A BYTE
	  PJRST	UEFERR		;UNEXPECTED EOF
	CAIE	T1,.CHLFD	;LINE FEED?
	JRST	SKPCM1		;NO - LOOP
	POPJ	P,		;YES - RETURN
SUBTTL	UCODE FILE PROCESSING -- ADX FORMAT


	CRDAT==UCODBF		;CRAM - 2K*16 BITS
	DRDAT==CRDAT+2000	;DRAM - 1K*8 BITS
	ADXWC==DRDAT+400	;LOAD ADDRESS,,WORD COUNT
	ADXDAT==ADXWC+1		;DATA WORDS

ADX:	MOVSI	T1,(POINT 7,)	;BYTE POINTER
	PUSHJ	P,SETBUF	;SET UP BUFFERS
ADX1:	PUSHJ	P,ADXLIN	;READ A LINE
	JUMPE	T1,ADX4		;DONE?
	MOVNS	T1		;NEGATE WORD COUNT
	HRLZS	T1		;MAKE AN AOBJN POINTER
	SKIPN	T3		;SKIP IF CRAM
	JRST	ADX2		;DRAM
	ROT	T2,-1
	TLZN	T2,400000
	TLOA	T2,442200
	TLO	T2,222200
	ADDI	T2,CRDAT	;FORM LOAD ADDRESS
	JRST	ADX3		;ENTER STORAGE LOOP
ADX2:	IDIVI	T2,4		;COMPUTE STARTING BYTE
	ADD	T2,ADXTAB(T3)	;FORM BYTE POINTER
ADX3:	MOVE	T3,ADXDAT(T1)	;GET A DATA WORD
	IDPB	T3,T2		;STORE
	AOBJN	T1,ADX3		;LOOP THROUGH THIS LINE
	JRST	ADX1		;GO GET ANOTHER LINE
ADX4:	LDB	T1,[POINT 10,CRDAT,17] ;GET EDIT LEVEL
	LDB	T2,[POINT 6,CRDAT,7] ;GET VERSION NUMBER
	LSH	T2,30		;POSITION
	IOR	T1,T2		;FORM STANDARD DEC-10 VERSION NUMBER
	MOVEM	T1,UCODVR	;SAVE
	MOVEI	T1,2000+400	;CRAM + DRAM SIZE
	MOVEM	T1,UCODWD	;SAVE WORD COUNT
	JRST	CPOPJ1		;RETURN

ADXTAB:	POINT	8,DRDAT,	;BYTE 0
	POINT	8,DRDAT,7	;BYTE 1
	POINT	8,DRDAT,15	;BYTE 2
	POINT	8,DRDAT,23	;BYTE 3
;ADXLIN - READS IN A LINE OF DATA WORDS TO BE LOADED INTO CRAM OR
; WORKING MEMORY
;
;	CALL ADXLIN
;
; RETURN+1: ALWAYS
; LINDAT IS THE TALBE WHICH HAS THE CONVERTED DATA WORDS
; T1/ WORD COUNT OF DATA WORDS IN THE TABLE
; T2/ LOAD ADDR
; T3/ 0 FOR WORKING MEMORY, 1 FOR CRAM

ADXLIN:	SETZM	UCODCK		;RESET CHECKSUM
	SETZM	ADXWC		;RESET WORD COUNT
	MOVE	T2,[ADXDAT,,ADXDAT+1] ;INITIALIZE WORK AREA
	SETZM	ADXDAT		;CLEAR FIRST WORD
	BLT	T2,ADXWC+^D32-1	;ZERO LINE BUFFER
	MOVEI	T3,^D32*5	;MAXIMUN NUMBER OF CHARACTERS
	MOVEI	T4,0		;FLAG WORKING MEMORY
	PUSHJ	P,GETBYT	;READ A BYTE
	  PJRST	UEFERR		;UNEXPECTED EOF
	CAIN	T1,";"		;IS IT COMMENT LINE?
	JRST	ADXLI5		;YES, IGNORE IT
	CAIE	T1,"C"		;CRAM LOAD LINE?
	JRST	ADXLI1		;NO, SEE IF WM LOAD LINE
	MOVEI	T4,1		;SET FLAG FOR CRAM
	JRST	ADXLI2		;JUMP AROUND

ADXLI1:	CAIE	T1,"W"		;WM LOAD LINE?
	PJRST	FMTERR		;FORMAT ERROR

ADXLI2:	PUSHJ	P,GETBYT	;GET A BYTE
	  PJRST	UEFERR		;UNEXPECTED EOF
	CAIE	T1," "		;MUST BE BLANK
	PJRST	FMTERR		;FORMAT ERROR
	PUSHJ	P,ADXWRD	;GET NEXT WORD
	  PJRST	FMTERR		;FORMAT ERROR
	MOVEM	T1,ADXWC	;SAVE WORD COUNT FOR THE LINE
	MOVEM	T1,UCODCK	;INITIALIZE CHECKSUM FOR THE LINE
	PUSHJ	P,ADXWRD	;GET NEXT WORD
	  PJRST	FMTERR		;FORMAT ERROR
	ADDM	T1,UCODCK	;UPDATE CHKSUM
	DPB	T1,[POINT 16,ADXWC,19]	;SAVE LOAD ADDR.
	MOVSI	T3,-^D32	;SETUP LOOP INDEX FOR SUBSEQUENT WORDS
ADXLI3:	PUSHJ	P,ADXWRD	;GET NEXT WORD
	  JRST ADXLI4		;LAST WORD, CHECKSUM, READ IN T1
	ADDM	T1,UCODCK	;UPDATE CHECKSUM
	MOVEM	T1,ADXDAT(T3)	;SAVE DATA WORD
	AOBJN	T3,ADXLI3	;LOOP BACK
	PJRST	FMTERR		;FORMAT ERROR

ADXLI4:	MOVEM	T1,ADXDAT(T3)	;SAVE EVEN CHECKSUM
	ADD	T1,UCODCK	;ADD CHECKSUM INTO T1
	TRNE	T1,177777	;CHECKSUM SHOULD BE 0
	PJRST	CHKERR		;CHECKSUM RROR
	LDB	T1,[POINT 16,ADXWC,35]	;WC IN T1
	LDB	T2,[POINT 16,ADXWC,19]	;LOAD ADDR. IN T2
	MOVE	T3,T4		;GET CRAM/WORKING MEMORY FLAG
	POPJ	P,		;NONSKIP RETURN

ADXLI5:	PUSHJ	P,GETBYT	;GET A BYTE
	  PJRST	UEFERR		;UNEXPECTED EOF
	CAIE	T1,.CHLFD	;LINE FEED?
	JRST	ADXLI5		;FLUSH CHARACTER
	JRST	ADXLIN		;ELSE GO PROCESS NEW LINE
;ADXWRD - GET A DATA WORD FROM DATLIN WHICH IS A CHAR. STRING
; CONVERT THE ASCIIZED DATA WORD INTO BINARY
;
;	CALL ADXWRD
;
; RETURN+1: DATA WORD DELIMITED BY CR
; RETURN+2: DATA WORD DELIMITED BY ,
; T1/ CONVERTED DATA WORD

ADXWRD:	SETZ	T2,		;INIT RESULT
ADXWR1:	PUSHJ	P,GETBYT	;GET A BYTE
	  PJRST	UEFERR		;UNEXPECTED EOF
	CAIN	T1,","		;SKIP IF NOT COMMA
	JRST	ADXWR2		;GOT THE DATA WORD
	CAIN	T1,.CHCRT	;SKIP IF NOT CR
	JRST	ADXWR1		;CR, THROW IT AWAY AND LOOK FOR LF
	CAIN	T1,.CHLFD	;LINE FEED?
	JRST	ADXWR3		;GOT LAST DATA WORD IN LINE
	LSH	T2,6		;MAKE ROOM
	CAIE	T1," "		;SKIP IF BLANK
	DPB	T1,[POINT 6,T2,35] ;PUT IN T2, UNASCIIZED THE BYTE
	JRST	ADXWR1		;GET NEXT CHAR.
ADXWR2:	AOS	(P)		;SKIP
ADXWR3:	MOVE	T1,T2		;GET RESULT
	POPJ	P,		;AND RETURN
SUBTTL	UCODE FILE PROCESSING -- ULD FORMAT


; MACRO TO BUILD A BYTE POINTER TO ULD FILE DATA
DEFINE	ULDPNT	(SS,YY,PP),<
	AA==YY*^D60+^D<PP>
	WW==AA/^D36
	XX==AA-<WW*^D36>
	POINT	^D<SS>,UCODBF+WW,XX
	PURGE	AA,WW,XX
>

ULD:	MOVSI	T1,(POINT 7,)	;BYTE POINTER
	PUSHJ	P,SETBUF	;SET UP BUFFERS
ULD1:	PUSHJ	P,GETBYT	;GET A BYTE
	  JRST	ULDEOF		;EOF
	CAIE	T1,"["		;DATA?
	JRST	ULD3		;NO--SKIP REMAINDER OF LINE
	PUSHJ	P,OCTIN		;READ AN OCTAL DOUBLEWORD
	  PJRST	UEFERR		;FORMAT ERROR
	JUMPN	T1,FMTERR	;CHECK FOR FORMAT ERRORS
	CAIL	T2,0
	CAILE	T2,10000-1
	PJRST	FMTERR		;FORMAT ERROR
	MOVE	T3,T2		;SAVE LOW WORD
	MOVE	T1,LSTBYT	;GET LAST BYTE READ
	CAIE	T1,"]"		;END?
	PJRST	FMTERR		;NO--FORMAT ERROR
	PUSHJ	P,GETBYT	;GET A BYTE
	  JRST	ULDEOF		;EOF
	CAIE	T1,"="		;DATA ON THE WAY?
	PJRST	FMTERR		;NO--FORMAT ERROR
	PUSHJ	P,OCTIN		;READ AN OCTAL DOUBLEWORD
	  PJRST	FMTERR		;FORMAT ERROR
	IMULI	T3,^D60		;60 BITS PER ENTRY
	IDIVI	T3,^D36		;36 BITS PER WORD
	MOVNS	T4		;COUNT BITS FROM RIGHT
	ADDI	T4,^D36
	LSH	T4,^D30
	TLO	T4,^D12*100
	ADDI	T4,UCODBF(T3)	;OFFSET TO APPROPRIATE WORD
	MOVEI	T3,^D60/^D12	;NUMBER OF DPB'S TO DO
	ROTC	T1,^D12		;FLUSH NOISE BITS
ULD2:	ROTC	T1,^D12		;GET NEXT 12 BITS
	IDPB	T2,T4
	SOJN	T3,ULD2		;LOOP
	MOVE	T1,LSTBYT	;GET LAST BYTE READ AGAIN

;HERE TO EAT THE REST OF THE LINE
ULD3:	CAIN	T1,.CHLFD	;LINE FEED?
	JRST	ULD1		;YES--GO TRY FOR MORE DATA
	PUSHJ	P,GETBYT	;GET A BYTE
	  JRST	ULDEOF		;EOF
	JRST	ULD3		;FLUSH

;HERE ON EOF
ULDEOF:	LDB	T1,[ULDPNT (03,136,17)] ;MAJOR VERSION
	DPB	T1,[POINT 9,UCODVR,11]
	LDB	T1,[ULDPNT (06,136,23)] ;MINOR VERSION
	DPB	T1,[POINT 6,UCODVR,17]
	LDB	T1,[ULDPNT (10,137,23)] ;EDIT LEVEL
	HRRM	T1,UCODVR
	MOVEI	T1,<<10000*^D60+^D35>/^D36> ;WORD COUNT
	MOVEM	T1,UCODWD	;SAVE
	JRST	CPOPJ1		;RETURN
WRTBIN:	MOVE	T1,UCDNAM(U)	;GET FILE NAME
	MOVSI	T2,'BIN'	;GET EXTENSION
	MOVEI	T3,.IODMP	;DUMP MODE
	PUSHJ	P,SETIO		;SET UP FOR I/O
	MOVE	T1,UCODVR	;GET UCODE VERSION NUMBER
	MOVEM	T1,LEB+.RBVER	;SAVE
	MOVEI	T1,.FOWRT	;FILOP FUNCTION
	PUSHJ	P,FILOP		;DO IT
	  PJRST	OPNERR		;FAILED
	MOVN	T1,UCODWD	;GET -WORD COUNT
	SOS	T1		;ACCOUNT FOR VERSION WORD TOO
	HRLI	T1,UCODVR-1	;POINT TO START OF BUFFER
	MOVSS	T1		;MAKE AN IOWD
	SETZ	T2,		;TERMINATE LIST
	OUT	IOC,T1		;WRITE IT OUT
	SKIPA			;NO PROBLEMS
	PJRST	OUTERR		;REPORT ERROR
	PUSHJ	P,PRLBKT	;START MESSAGE WITH A BRACKET
	MOVEI	T1,[ASCIZ /Microcode version /]
	PUSHJ	P,PRMSG		;PRINT TEXT
	MOVE	T1,UCODVR	;GET VERSION
	PUSHJ	P,PRVRSN	;PRINT IT
	MOVEI	T1,[ASCIZ / written to /]
	PUSHJ	P,PRMSG		;PRINT TEXT
	PUSHJ	P,PRFILE	;PRINT FILESPEC
	PUSHJ	P,PRRBCR	;FINISH WITH A TRAILING BRACKET AND CRLF
	JRST	CPOPJ1		;RETURN
DELPGS:	MOVNI	T2,<<BTSVEC-LOADEN>_-11> ;PAGES TO KILL
	MOVEI	T3,<<LOADEN+PAGSIZ>_-11> ;STARTING PAGE NUMBER
	PUSHJ	P,KILPGS	;DELETE PAGES
	PUSHJ	P,HIPAGE	;GET THE HIGHEST PAGE IN BOOT
	MOVE	T2,T1		;COPY PAGE NUMBER
	ADD	T2,[-1000]	;PAGES TO KILL
	MOVE	T3,T1		;STARTING PAGE NUMBER
	PUSHJ	P,KILPGS	;DELETE PAGES
	POPJ	P,		;RETURN

DELDDT:	PUSHJ	P,HIPAGE	;GET HIGHEST PAGE IN USE
	MOVEI	T2,<<DDT##+PAGSIZ>_-11> ;STARTING PAGE NUMBER
	MOVE	T3,T2		;COPY
	SUBI	T2,(T1)		;PAGES TO KILL
	PUSHJ	P,KILPGS	;DELETE PAGES
	MOVEI	T1,0		;DDT IS GONE
	SETDDT	T1,		;ZERO DDT START ADDRESS
	MOVSI	T1,(JFCL)	;NO-OP
	HLLM	T1,BTSVEC+.BTDDT ;CAN'T ENTER DDT THE NORMAL WAY
	HLLM	T1,BTSVEC+.BTBPT ; OR BY TYPING CONTROL-D
	SETZM	.JBBPT		;ZERO UNSOLICITED BREAKPOINT ADDRESS
	SETZM	.JBSYM		;ZERO SYMBOL TABLE POINTER
	SETZM	.JBUSY		;ZERO UNDEFINED SYMBOL TABLE POINTER
	POPJ	P,		;RETURN

KILPGS:	MOVE	T1,[.PAGCD,,T2]	;SET UP UUO AC
	TLO	T3,(PA.GAF!PA.GDC) ;DELETE PAGES, OK OF NON-EXISTANT
	PAGE.	T1,		;DELETE THEM
	  HALT	.
	POPJ	P,		;RETURN
; COMPUTE THE HIGHEST ADDRESS OR PAGE IN BOOT (AND POSSIBLY DDT)
HIADDR:	TDZA	T3,T3		;ADDR ENTRY POINT
HIPAGE:	MOVEI	T3,1		;PAGE ENTRY POINT
	MOVEI	T1,BTSEND	;HIGHEST ADDRESS
	SKIPN	.JBDDT		;DDT LOADED?
	JRST	HIEXIT		;FINISH UP
	MOVEI	T1,<DDTEND##!<PAGSIZ-1>> ;HIGHEST ADDRESS
	SKIPN	T2,.JBSYM	;SYMBOLS LOADED?
	JRST	HIEXIT		;FINISH UP
	HLRE	T1,T2		;GET -LENGTH OF SYMBOL TABLE
	MOVNS	T1		;MAKE POSITIVE
	ADDI	T1,(T2)		;POINT TO END OF SYMBOL TABLE
HIEXIT:	JUMPE	T3,CPOPJ	;RETURN IF NO CONVERSION NEEDED
	ADDI	T1,PAGSIZ	;ROUND UP
	LSH	T1,-11		;CONVERT TO A PAGE NUMBER
	POPJ	P,		;RETURN

; ROUTINE TO ALLOCATION PAGES FOR MICROCODE STORAGE
GETCOR:	MOVE	T1,[.PAGCD,,T2]	;SET UP UUO TO CREATE NECESSARY PAGES
	MOVN	T2,UCODWD	;GET WORDS NEEDED
	SOS	T2		;PLUS (MINUS) ONE WORD FOR THE VERSION
	SUBI	T2,PAGSIZ	;ROUND UP (DOWN?)
	ASH	T2,W2PLSH	;CONVERT TO -NUMBER OF PAGES NEEDED
	MOVE	T3,LOADFF	;GET FIRST FREE LOCATION
	LSH	T3,W2PLSH	;CONVERT TO A PAGE NUMBER
	TLO	T3,(PA.GDC)	;DON'T CARE IF PAGES ALREADY EXIST
	PAGE.	T1,		;CREATE SOME PAGES
	  CAIA			;FAILED
	JRST	CPOPJ1		;RETURN
	PUSHJ	P,PRCRLF	;START WITH A CRLF
	MOVEI	T1,[ASCIZ/? PAGE. UUO error (/]
	PUSHJ	P,PRMSG		;TYPE TEXT
	POP	P,T1		;GET ERROR CODE
	PUSHJ	P,PROCT		;TYPE IT
	MOVEI	T1,[ASCIZ/) creating pages/]
	PUSHJ	P,PRMSG		;TYPE TEXT
	PJRST	PRCRLF		;END WITH A CRLF AND RETURN
MEMMAP:	MOVEI	T1,MEMTX1	;POINT TO HEADER TEXT
	PUSHJ	P,PRMSG		;TYPE IT
	MOVEI	T4,BTSVEC	;GET START ADDRESS OF BOOT
	PUSHJ	P,PRHWDR	;TYPE IT
	PUSHJ	P,SPACES	;SPACE OVER
	SKIPN	T4,.JBDDT	;GET DDT STARTING ADDRESS (IF ANY)
	MOVE	T4,UCODSA	;GET UCODE STARTING ADDRESS
	HRRZS	P1,T4		;SAVE ADDR
	SUBI	T4,1		;BACK OFF BY ONE FOR BOOTSTRAP END ADDRESS
	PUSHJ	P,PRHWDR	;TYPE ENDING BOOTSTRAP ADDRESS
	PUSHJ	P,SPACES	;SPACE OVER
	MOVEI	T4,-BTSVEC(P1)	;COMPUTE BOOTSTRAP LENGTH
	PUSHJ	P,PRHWDR	;TYPE IT
	PUSHJ	P,SPACES	;SPACE OVER
	MOVE	T1,BTSVEC+.BTVER ;GET OUR VERSION
	PUSHJ	P,PRVRSN	;PRINT IT
	PUSHJ	P,PRCRLF	;END LINE
	SKIPN	.JBDDT		;EDDT LOADED?
	JRST	MEMMA1		;NO
	MOVEI	T1,[ASCIZ/EDDT + symbol table  /]
	PUSHJ	P,PRMSG		;TYPE TEXT
	HRRZ	T4,.JBDDT	;GET START ADDRESS
	MOVE	P1,T4		;COPY
	PUSHJ	P,PRHWDR	;TYPE IT
	PUSHJ	P,SPACES	;SPACE OVER
	MOVE	T2,.JBSYM	;GET POINTER TO SYMBOL TABLE
	HLRE	T4,T2		;GET -VE LENGTH
	MOVNS	T4		;MAKE POSITIVE
	ADDI	T4,-1(T2)	;GET END ADDRESS
	PUSH	P,T4		;SAVE A BIT
	PUSHJ	P,PRHWDR	;TYPE IT
	PUSHJ	P,SPACES	;SPACE OVER
	POP	P,T4		;RESTORE END ADDRESS
	SUBI	T4,(P1)		;COMPUTE LENGTH
	PUSHJ	P,PRHWDR	;TYPE IT
	PUSHJ	P,SPACES	;SPACE OVER
	MOVE	T1,[%%DDT##]	;GET DDT VERSION
	PUSHJ	P,PRVRSN	;PRINT IT
	PUSHJ	P,PRCRLF	;END LINE
MEMMA1:	MOVSI	U,-UCDNUM	;FOR INDEXING INTO UCODE TABLES

MEMMA2:	SKIPE	P1,UCDPTR(U)	;GET STORAGE ADDRESS/COUNT POINTER
	SKIPN	0(P1)		;LENGTH SET?
	JRST	MEMMA3		;UCODE ISN'T INCLUDED
	MOVE	T1,UCDTXT(U)	;GET TEXT
	PUSHJ	P,PRMSG		;TYPE IT
	PUSHJ	P,SPACES	;SPACE OVER
	MOVE	T4,1(P1)	;GET UCODE OFFSET
	ADDI	T4,BTSVEC	;PLUS THE ORIGIN
	PUSHJ	P,PRHWDR	;TYPE IT
	PUSHJ	P,SPACES	;SPACE OVER
	MOVE	T4,0(P1)	;GET UCODE LENGTH
	ADD	T4,1(P1)	;FIND STARTING OFFSET
	ADDI	T4,BTSVEC-1	;AND THE ADDRESS
	PUSHJ	P,PRHWDR	;TYPE IT
	PUSHJ	P,SPACES	;SPACE OVER
	MOVE	T4,0(P1)	;GET LENGTH AGAIN
	PUSHJ	P,PRHWDR	;TYPE IT
	PUSHJ	P,SPACES	;SPACE OVER
	MOVE	T1,1(P1)	;GET UCODE OFFSET
	ADDI	T1,BTSVEC	;PLUS THE ORIGIN
	MOVE	T1,(T1)		;GET UCODE VERSION
	PUSHJ	P,PRVRSN	;PRINT IT
	PUSHJ	P,PRCRLF	;END LINE

MEMMA3:	AOBJN	U,MEMMA2	;LOOP
	MOVEI	T1,MEMTX2	;POINT TO SUMMARY TEXT
	PUSHJ	P,PRMSG		;TYPE IT
	MOVE	T4,LOADFF	;POINT TO LAST WORD+1 USED
	SUBI	T4,BTSVEC	;COMPUTE TOTAL LENGTH
	HRRZM	T4,BTSVEC+.BTSIZ ;SAVE IN VECTOR
	MOVEI	T1,PAGSIZ(T4)	;COPY LENGTH AND ROUND UP A PAGE
	LSH	T1,W2PLSH	;CONVERT TO PAGES
	MOVNS	T1		;NEGATE
	HRLM	T1,BTSVEC+.BTSIZ ;SAVE -SIZE IN PAGES
	PUSHJ	P,PRHWDR	;TYPE IT
	PUSHJ	P,PRCRLF	;TYPE A CRLF
	PJRST	PRCRLF		;ONE MORE AND RETURN
MEMTX1:	ASCIZ	/

     Memory  map      From     To     Size    Version
                     ------  ------  ------  ---------
Bootstrap            /


MEMTX2:	ASCIZ	/
Total size                           /
SPACES:	MOVEI	T1,[ASCIZ /  /]
	PJRST	PRMSG		;SPACE OVER

QINIT:	MOVEI	T1,<QWDS*5>-1	;MAXIMUM CHARACTER COUNT
	MOVEM	T1,QCTR		;SAVE
	MOVEI	T1,QBUF		;POINT TO BUFFER
	HRLI	T1,(POINT 7,)	;MAKE A BYTE POINTER
	MOVEM	T1,QPTR		;SAVE
	POPJ	P,		;RETURN

QTEXT:	HRLI	T1,(POINT 7,)	;MAKE A BYTE POINTER
QTEXT1:	ILDB	T2,T1		;GET A CHARACTER
	JUMPE	T2,CPOPJ	;RETURN IF END OF STRING
	IDPB	T2,QPTR		;PUT A CHARACTER
	JRST	QTEXT1		;LOOP

QYNT:	MOVEI	T1,[ASCIZ\ [Y/N]: \]
	PUSHJ	P,QTEXT		;APPEND TO QUESTION BUFFER
	MOVEI	T1,.CHNUL	;GET A NUL
	IDPB	T1,QPTR		;TERMINATE BUFFER
	MOVEI	T1,QBUF		;POINT TO BUFFER
	POPJ	P,		;AND RETURN
DEFINE	X	(L,PFX,NAM,EXT,TXT,MOD,SIZ),<<SIXBIT /NAM/>>
UCDNAM:	UCODES

DEFINE	X	(L,PFX,NAM,EXT,TXT,MOD,SIZ),<<SIXBIT /EXT/>>
UCDEXT:	UCODES

DEFINE	X	(L,PFX,NAM,EXT,TXT,MOD,SIZ),<
	IFE <L>,<EXP 0>
	IFN <L>,<EXP BTSVEC+.BTUCD+.BT'PFX>
>
UCDPTR:	UCODES

DEFINE	X	(L,PFX,NAM,EXT,TXT,MOD,SIZ),<
	IFE <L>,<EXP 0>
	IFN <L>,<EXP [ASCIZ |TXT|]>
>
UCDTXT:	UCODES

DEFINE	X	(L,PFX,NAM,EXT,TXT,MOD,SIZ),<EXP	MOD>
UCDMOD:	UCODES
	SUBTTL	GENERATE .EXB FILE FOR RSX-20F

IFN FTKL10,<
EXBFIL:	MOVE	T1,['BOOT  ']	;FILE NAME
	MOVSI	T2,'EXB'	;EXTENSION
	MOVEI	T3,.IOIMG	;I/O MODE
	PUSHJ	P,SETIO		;SET UP I/O AND OPEN CHANNEL
	LDB	T1,[POINT 9,.JBVER,11] ;GET MAJOR VERSION
	LSH	T1,11		;MAKE ROOM FOR EDIT LEVEL
	HRRZ	T2,.JBVER	;GET EDIT
	IORI	T1,(T2)		;MERGE
	MOVEM	T1,LEB+.RBVER	;SAVE FOR F11
	MOVEI	T1,.FOWRT	;WRITE FUNCTION
	PUSHJ	P,FILOP		;CREATE THE FILE
	  HALT	.
	MOVSI	T1,(POINT 18,)	;BYTE POINTER FOR BUFFERED MODE
	PUSHJ	P,SETBUF	;SET UP BUFFERS
	MOVEI	T1,BTSVEC	;POINT TO START OF BOOTSTRAP
	MOVEM	T1,EXBPTR	;SAVE
	SETZB	P1,EXBSTA	;INIT BYTE STORAGE AND START ADDRESS FLAG
EXBFI1:	PUSHJ	P,EXBREC	;BUILD A RECORD
	  JRST	EXBFI3		;RAN OUT OF DATA
	MOVE	T1,RECCNT	;GET RECORD BYTE COUNT
	PUSHJ	P,EXBPU2	;WRITE IT OUT
	  HALT	.
EXBFI2:	SOSGE	RECCNT		;COUNT BYTES
	JRST	EXBFI1		;GO DO ANOTHER RECORD
	ILDB	T1,RECPTR	;GET A BYTE
	PUSHJ	P,EXBPUT	;WRITE IT OUT
	  HALT	 .
	JRST	EXBFI2		;LOOP BACK FOR ANOTHER BYTE
EXBFI3:	SKIPL	T1,P1		;ONE MORE BYTE TO OUTPUT?
	JRST	EXBFI4		;NO
	PUSHJ	P,PUTBYT	;WRITE IT OUT
	  HALT	.
EXBFI4:	RELEAS	IOC,		;CLOSE AND RELEASE CHANNEL
	POPJ	P,		;RETURN
; EXB RECORD GENERATOR
EXBREC:	SKIPE	EXBSTA		;HAVE WE WRITTEN THE START ADDRESS YET?
	POPJ	P,		;YES--DONE
	MOVSI	T1,(POINT 8,)	;8-BIT BYTES
	HRRI	T1,RECBUF	;POINT TO RECORD BUFFER
	MOVEM	T1,RECPTR	;SAVE
	SETZM	RECCNT		;RESET BYTE COUNT
	PUSHJ	P,EXBDAT	;GET AOBJN POINTER TO DATA
	  SKIPA	T1,BTSVEC+.BTSTA ;ALL THAT'S LEFT IS THE START ADDRESS
	JRST	EXBRE1		;GOT ONE
	HRLI	T1,-1		;MAKE AN AOBJN POINTER
	MOVNI	T2,5		;FUDGE BYTE COUNT
	MOVEM	T2,RECCNT	; JUST A LITTLE BIT
	SETOM	EXBSTA		;INDICATE WRITING START ADDRESS
EXBRE1:	HRRZM	T1,EXBLDA	;SAVE LOAD ADDRESS
	ADJSP	T1,-1		;COMPENSATE FOR AOBJN LATER ON
	PUSH	P,T1		;SAVE LOAD ADDRESS ON STACK
	MOVEI	T1,EXBLDA	;POINT TO LOAD ADDRESS STORAGE
	TDZA	T3,T3		;PROCESSING BYTE COUNT AND ADDRESS NOW
EXBRE2:	MOVEI	T3,1		;PROCESSING DATA NOW
	LDB	T2,[POINT 8,(T1),35] ;PDP-11 BYTE #0
	IDPB	T2,RECPTR
	LDB	T2,[POINT 8,(T1),27] ;PDP-11 BYTE #1
	IDPB	T2,RECPTR
	LDB	T2,[POINT 8,(T1),19] ;PDP-11 BYTE #2
	IDPB	T2,RECPTR
	LDB	T2,[POINT 8,(T1),11] ;PDP-11 BYTE #3
	IDPB	T2,RECPTR
	JUMPE	T3,EXBRE3	;JUMP IF NOT PROCESSING DATA
	LDB	T2,[POINT 4,(T1),03] ;OVERFLOW HALF-BYTE
	IDPB	T2,RECPTR
	AOSA	EXBPTR		;ADVANCE LOAD ADDRESS WORD
EXBRE3:	POP	P,T1		;GET BACK AOBJN POINTER
	MOVEI	T2,4(T3)	;MUST ACCOUNT FOR ALL BYTES PROCESSED
	ADDM	T2,RECCNT	;ACCUMULATE
	AOBJN	T1,EXBRE2	;GO BACK FOR ANOTHER WORD
	MOVSI	T1,(POINT 8,)	;BYTE POINTER FOR
	HRRI	T1,RECBUF	; READING DATA
	MOVEM	T1,RECPTR	;SAVE IT
	JRST	CPOPJ1		;RETURN
; GENERATE AOBJN POINTER TO EXB DATA
EXBDAT:	MOVEI	T1,0		;INIT WORD COUNT
	MOVE	T2,EXBPTR	;GET STARTING LOAD ADDRESS
EXBDA1:	CAMLE	T2,LOADFF	;END OF BOOTSTRAP?
	POPJ	P,		;YES
	SKIPN	(T2)		;ZERO?
	AOJA	T2,EXBDA1	;YES--COMPRESS ZEROS
	MOVEM	T2,EXBPTR	;UPDATE LOAD ADDRESS
EXBDA2:	CAMG	T2,LOADFF	;END OF BOOTSTRAP?
	SKIPN	(T2)		;NEED TO ZERO COMPRESS?
	JRST	EXBDA3		;YES
	AOS	T2		;ADVANCE POINTER
	CAMLE	T1,[-EXBMAX]	;WILL THIS FILL UP THE RECORD?
	SOJA	T1,EXBDA2	;NO--KEEP COUNTING
EXBDA3:	HRL	T1,EXBPTR	;GET LOAD ADDRESS
	MOVSS	T1		;MAKE AN AOBJN POINTER
	JRST	CPOPJ1		;AND RETURN
; STORE BYTES IN THE EXB FILE
EXBPUT:	ANDI	T1,377		;SMALL MACHINES USE SMALL BYTES
	JUMPL	P1,EXBPU1	;BYTE LEFT OVER FROM BEFORE?
	TLO	T1,400000	;INDICATE INCOMPLETE 16-BIT BYTE
	MOVE	P1,T1		;SAVE BYTE
	JRST	CPOPJ1		;RETURN
EXBPU1:	LSH	T1,10		;SHIFT NEW BYTE TO HIGH BYTE
	IOR	T1,P1		;PUT IN THE LOW BYTE FROM LAST CALL
	MOVEI	P1,0		;RESET OLD BYTE FOR NEXT TIME
EXBPU2:	EXCH	T1,P1		;SAVE NEW BYTE, GET OLD ONE
	JUMPGE	T1,EXBPU3	;JUMP IF NO BYTE LEFT OVER FROM BEFORE
	PUSHJ	P,PUTBYT	;STORE IN FILE
	  HALT	.	
EXBPU3:	MOVE	T1,P1		;GET NEW BYTE BACK
	MOVEI	P1,0		;RESET OLD BYTE FOR NEXT TIME
	PUSHJ	P,PUTBYT	;STORE NEW BYTE IN FILE
	  HALT	.
	JRST	CPOPJ1		;AND RETURN
>; END IFN FTKL10
; SET UP FOR I/O
; CALL:	MOVE	T1, FILE NAME
;	MOVE	T2, EXTENSION
;	MOVE	T3, I/O MODE BITS
;	PUSHJ	P,SETIO

SETIO:	PUSH	P,T1		;SAVE FILE NAME
	PUSH	P,T2		;SAVE EXTENSION
	MOVSI	T1,F.ZBEG	;FIRST CLEAR
	HRRI	T1,F.ZBEG+1	; THE FILE
	SETZM	F.ZBEG		;  STORAGE
	BLT	T1,F.ZEND-1	;   AREA
	MOVSI	T1,<(FO.PRV)>!IOC ;PRIV BIT + CHANNEL NUMBER
	MOVEM	T1,FOP+.FOFNC
	MOVEM	T3,FOP+.FOIOS	;SAVE I/O MODE
	MOVSI	T1,'DSK'	;DEVICE
	MOVEM	T1,FOP+.FODEV
	MOVSI	T1,OBR		;OUTPUT BUFFER RING HEADER
	HRRI	T1,IBR		;INPUT BUFFER RING HEADER
	ANDI	T3,17		;KEEP ONLY THE MODE
	CAIE	T4,.IODMP	;DUMP MODE?
	MOVEM	T1,FOP+.FOBRH	;NO--MUST SAVE RING HEADER POINTERS
	MOVEI	T1,LEB		;POINT TO LOOKUP/ENTER BLOCK
	MOVEM	T1,FOP+.FOLEB
	MOVE	T1,[.FOFMX,,FSP] ;POINT TO RETURNED FILESPEC BLOCK
	MOVEM	T1,FOP+.FOFSP
	MOVEI	T1,.RBMAX	;LENGTH OF LOOKUP/ENTER BLOCK
	MOVEM	T1,LEB+.RBCNT
	MOVE	T1,.JBVER	;SET OUR VERSION NUMBER ON ALL FILES CREATED
	MOVEM	T1,LEB+.RBVER
	POP	P,LEB+.RBEXT	;SAVE EXTENSION
	POP	P,LEB+.RBNAM	;SAVE FILE NAME
	POPJ	P,		;RETURN
SETBUF:	PUSH	P,T1		;SAVE BYTE POINTER
	MOVSI	T1,(BF.IOU)	;BUFFER USE BIT
	HRRI	T1,OBF+.BFHDR	;GET ADDRESS OF NEXT OUTPUT BUFFER
	MOVEM	T1,OBR+.BFADR	;STORE IN OUTPUT BUFFER CONTROL BLOCK
	HLLZ	T1,(P)		;BYTE POINTER
	MOVEM	T1,OBR+.BFPTR	;STORE IN OUTPUT BUFFER CONTROL BLOCK
	MOVSI	T1,201		;NUMBER OF DATA WORDS IN A BUFFER
	HRRI	T1,OBF+.BFHDR	;GET ADDRESS OF NEXT OUTPUT BUFFER
	MOVEM	T1,OBF+.BFHDR	;RING LOOPS ON ITSELF
	MOVSI	T1,(BF.IOU)	;BUFFER USE BIT
	HRRI	T1,IBF+.BFHDR	;GET ADDRESS OF NEXT INPUT BUFFER
	MOVEM	T1,IBR+.BFADR	;STORE IN INPUT BUFFER CONTROL BLOCK
	HLLZ	T1,(P)		;BYTE POINTER
	MOVEM	T1,IBR+.BFPTR	;STORE IN INPUT BUFFER CONTROL BLOCK
	MOVSI	T1,201		;NUMBER OF DATA WORDS IN A BUFFER
	HRRI	T1,IBF+.BFHDR	;GET ADDRESS OF NEXT INPUT BUFFER
	MOVEM	T1,IBF+.BFHDR	;RING LOOPS ON ITSELF
	POP	P,(P)		;TRIM STACK
	POPJ	P,		;RETURN
FILOP:	MOVE	T2,T1		;COPY FUNCTION CODE FOR LATER
	HRRM	T1,FOP+.FOFNC	;COMPLETE FUNCTION WORD
	MOVEI	T1,FOP		;POINT TO ARGUMENT BLOCK
	HRLI	T1,2		;ASSUME I/O CALL (LENGTH=2)
	CAIE	T2,.FORED	;READ?
	CAIN	T2,.FOWRT	;WRITE?
	HRLI	T1,.FOMAX	;USE A FULL ARGUMENT BLOCK
	FILOP.	T1,		;DO SOMETHING
	  POPJ	P,
	CAIE	T2,.FORED	;READ?
	CAIN	T2,.FOWRT	;WRITE?
	SKIPA			;YES TO EITHER
	JRST	CPOPJ1		;ALL DONE
	MOVSI	T1,FSP+.FOFDV	;POINT TO START OF RETURNED FILESPEC
	HRRI	T1,DEV		;WHERE TO PUT IT
	BLT	T1,EXT		;COPY DEVICE, FILE NAME, AND EXTENSION
	MOVSI	T1,FSP+.FOFPP	;POINT TO START OF PATH
	HRRI	T1,PTHBLK	;WHERE TO PUT IT
	BLT	T1,PTHBLK+7-1	;COPY PATH
	JRST	CPOPJ1		;RETURN
GETBYT:	SOSGE	IBR+.BFCTR	;COUNT BYTES
	JRST	GETBY1		;BUFFER EMPTY
	ILDB	T1,IBR+.BFPTR	;GET A BYTE
	MOVEM	T1,LSTBYT	;SAVE AS LAST BYTE
	JRST	CPOPJ1		;AND RETURN
GETBY1:	IN	IOC,		;READ A BUFFER IN
	JRST	GETBYT		;LOOP BACK
	GETSTS	IOC,T1		;GET CHANNEL STATUS
	TRNE	T1,IO.EOF	;END OF FILE?
	POPJ	P,		;YES
	PJRST	INPERR		;ELSE INPUT ERROR

PUTBYT:	SOSGE	OBR+.BFCTR	;COUNT BYTES
	JRST	PUTBY1		;BUFFER FULL
	IDPB	T1,OBR+.BFPTR	;SAVE A BYTE
	JRST	CPOPJ1		;AND RETURN
PUTBY1:	OUT	IOC,		;WRITE BUFFER OUT
	JRST	PUTBYT		;LOOP BACK
	GETSTS	IOC,T1		;GET CHANNEL STATUS
	HALT	.


OCTIN:	PUSH	P,T3		;SAVE T3
	PUSH	P,T4		;SAVE T4
	SETZB	T3,T4		;INIT RESULT
OCTIN1:	PUSHJ	P,GETBYT	;GET A CHARACTER
	  JRST	OCTIN3		;EOF
	CAIL	T1,"0"		;RANGE
	CAILE	T1,"7"		; CHECK
	JRST	OCTIN2		;ALMOST DONE
	LSHC	T3,3		;SHIFT
	ADDI	T4,-"0"(T1)	;INCLUDE DIGIT
	JRST	OCTIN1		;LOOP
OCTIN2:	DMOVE	T1,T3		;GET DOUBLEWORD RESULT
OCTIN3:	POP	P,T4		;RESTORE T4
	POP	P,T3		;RESTORE T3
	JRST	CPOPJ1		;RETURN
SAVBLT:	PHASE	.JBBLT
	SAVE.	0,		;(.JBBLT+0) SAVE PROGRAM
	  HALT	.		;(.JBBLT+1) FAILED
	EXIT			;(.JBBLT+2) RETURN TO MONITOR
	DEPHASE

SAVCOD:	PHASE	0
	XWD	.PAGCD,PAGBLK	;(00) PAGE. UUO AC
SAVGO:!	PAGE.	0,		;(01) DELETE UCODE LOADER
	  HALT	.		;(02) FAILED
	MOVEI	0,SAVBLK	;(03) POINT TO SAVE. UUO ARGUMENT
	JRST	.JBBLT		;(04) DO SAVE AND EXIT
	EXP	0		;(05) FREE
PAGBLK:!EXP	-<LOADPG-1>	;(06) PAGE. UUO ARGUMENT (KEEP PAGE 0)
	EXP	PA.GAF+1	;(07) PAGE. UUO ARGUMENT
SAVBLK:!SIXBIT	/DSK/		;(10) DEVICE
	SIXBIT	/BOOT/		;(11) FILE NAME
	SIXBIT	/EXE/		;(12) EXTENSION
	EXP	0		;(15) MBZ
	EXP	0		;(16) PPN
	EXP	0		;(17) CORE
	DEPHASE
LOADFF:	BLOCK	1		;ADDRESS OF FIRST FREE LOCATION
BINFLG:	BLOCK	1		;BINARY FILE OUTPUT FLAG
UCODSA:	BLOCK	1		;UCODE STARTING ADDRESS
UCODWD:	BLOCK	1		;UCODE WORD COUNT
UCODCK:	BLOCK	1		;UCODE CHECKSUM
UCODVR:	BLOCK	1		;UCODE VERSION NUMBER (TEMPORARY)
UCODBF:	BLOCK	UCDSIZ		;UCODE STORAGE BUFFER (TEMPORARY)
QPTR:	BLOCK	1		;BYTE POINTER TO QUESTION BUFFER
QCTR:	BLOCK	1		;BYTE COUNTER TO QUESTION BUFFER
QBUF:	BLOCK	QWDS		;QUESTION BUFFER
LSTBYT:	BLOCK	1		;SAVE BYTE READ FROM FILE
F.ZBEG:!			;START OF FILE AREA TO CLEAR
FOP:	BLOCK	.FOMAX		;FILOP BLOCK
LEB:	BLOCK	.RBMAX		;LOOKUP/ENTER BLOCK
FSP:	BLOCK	.FOFMX		;RETURNED FILESPEC BLOCK
OBR:	BLOCK	3		;OUTPUT BUFFER RING HEADER
IBR:	BLOCK	3		;INPUT BUFFER RING HEADER
OBF:	BLOCK	203		;OUTUT DISK BLOCK
IBF:	BLOCK	203		;INPUT DISK BLOCK
F.ZEND:!			;END OF FILE AREA TO CLEAR
EXBSTA:	BLOCK	1		;EXB START ADDRESS FLAG
EXBLDA: BLOCK	1		;EXB LOAD ADDRESS
EXBPTR:	BLOCK	1		;EXB CORE IMAGE BYTE POINTER
RECPTR:	BLOCK	1		;EXB RECORD BUFFER BYTE POINTER
RECCNT:	BLOCK	1		;EXB RECORD BYTE COUNT
RECBUF:	BLOCK	EXBWDS		;EXB RECORD BUFFER
LDRLIT:	LIT
LOADEN:!			;END OF THE LOADER
LOADSZ==<LOADEN-LOADER>+.JBDA	;LOADER SIZE IN WORDS
LOADPG==<LOADSZ+PAGSIZ-1>/PAGSIZ ;LOADER SIZE IN PAGES
	SUBTTL	DATA AREAS


;THE DATA AREA MUST BE THE FIRST THING IN THIS PROGRAM THAT GENERATES
;CODE TO INSURE THAT IT STARTS ON A PAGE BOUNDARY.  IN ADDITION,
;THE EPT MUST BE THE FIRST THING IN THE DATA AREA FOLLOWED IMMEDIATELY
;BY THE BLOCKS FOR HOM, RIB, AND BUF, FOR THE SAME REASON.  NOTE
;THAT IF ANY OF THE LAST THREE BLOCKS ARE SPLIT ACROSS A PAGE BOUNDARY
;THE I/O SUBROUTINES WILL NOT (NECESSARILY) WORK.

	RELOC	.VBOOT-.JBDA

BTSVEC:
LV (NAM,<SIXBIT/BOOT/>)		;IDENTIFIER
LV (VER,<%%BTS>)		;BOOT VERSION
LV (STA,<JRST BOOT>)		;BOOT START ADDRESS (FOR DEBUGGING)
LV (DDT,<JRST DDT##>)		;DDT START ADDRESS
LV (BPT,<JSR $0BPT##>)		;DDT ENTRY VIA UNSOLICITED BREAKPOINT
LV (DSP,<SUBR-BTSVEC>)		;SUBROUTINE OFFSET FROM ORIGIN
LV (SAV,<.BTSVE-.BTSVB>)	;NUMBER OF SAVED DATA ITEMS
LV (DAT,<<-DATLEN,,<SUBDAT-BTSVEC>>>) ;-LENGTH,,OFFSET TO DATA FOR SUBR
LV (XPC,<0,0,1B6,0>)		;XPCW ENTRY POINT
LV (SSL,<<-^D36,,.BTSSL+1>>)	;-LENGTH,,OFFSET TO THE SSL
LV (ASL,<<-^D8,,.BTASL+1>>)	;-LENGTH,,OFFSET TO THE ASL
LV (SDL,<<-^D36,,.BTSDL+1>>)	;-LENGTH,,OFFSET TO THE SDL
LV (MSZ,<MEMPSZ-BTSVEC>)	;OFFSET TO MEMORY SIZE IN P
LV (NXM,<<-NXMLEN,,<NXMTAB-BTSVEC>>>)	;-LENGTH,,OFFSET TO NXMTAB

	.ORG	BTSVEC+<.BTVLN*PAGSIZ> ;ROUND UP TO THE NEXT PAGE BOUNDRY

EPTABS:				;UNMAPPED ADDRESS OF EPT
EPTOFS==EPTABS-.VBOOT		;EPT OFFSET FROM BOOT ORIGIN IN WORDS
EPTPAG==EPTOFS/PAGSIZ		;EPT OFFSET FROM BOOT ORIGIN IN PAGES
BLK(EPT,0)			;PUT THIS HERE SO IT STARTS ON A PAGE BOUNDARY
	ONE41	(0,417)		;0-417=PAGES 0-417 IN EXEC MAP
	BLOCK	1		;420=UNUSED ON KL OR KS
	JFCL			;421=ARITHMETIC OVERFLOW TRAP INSTRUCTION
	JRST	TRAP		;422=PDL OVERFLOW TRAP INSTRUCTION
	JRST	TRAP		;423=TRAP 3 TRAP INSTRUCTION
	BLOCK	4		;424-427 MUUO LOCATIONS
	INSLOC	(430,437,<EXP TRAP>) ;430-437=MUUO NEW PC WORDS
	...Z4==.
CPYRIT:!CPYTXT			;PUT THE COPYRIGHT TEXT HERE
	.ORG	...Z4
	BLOCK	40		;440-477=UNUSED
	BLOCK	2		;500-501=PAGE FAIL LOCATIONS ON KL AND KS
	EXP	PFTRAP		;502=NEW PC WORD ON KL AND KS
	EXP	PFTRAP		;503=REAL PAGE FAIL NEW PC WITH KL PAGING
	ONE41	(504,537)	;504-537=PAGES 504-537 IN EXEC MAP
	ONE41	(EPTABS/PAGSIZ,EPTABS/PAGSIZ) ;540=POINTER TO SECTION 0 PAGE TABLE
	ONE41	(541,777)	;541-777=PAGES 541-777 IN EXEC MAP
DATA:!			;START OF IMPURE DATA STORAGE

R.BEG:!			;FIRST ADDRESS OF DATA TO ZERO ON RESTART

BLK(HOM,BLKSIZ)		;HOM BLOCK FOR CURRENT UNIT
BLK(RIB,BLKSIZ)		;RIB BLOCK FOR CURRENT FILE
BLK(BUF,BLKSIZ)		;WORK BUFFER
BLK(SCR,BLKSIZ)		;REBOOT SCRATCH BUFFER

SWTVLV:
BLK(SWTVAL,0)		;START OF BLOCK OF SWITCH VALUES
BLK(STSA,1)		;START ADDRESS GIVEN IN /START
SWTVLL==.-SWTVLV

IFN FTTAPE,<
BLK(TAPIDX,1)		;MAGTAPE UNIT INDEX
BLK(TAPUNI,1)		;MAGTAPE UNIT NUMBER
BLK(TAPDEN,1)		;MAGTAPE DENSITY CODE (1=200 BPI, ..., 5=6250 BPI)
>; END IFN FTTAPE

R.END:!			;LAST ADDRESS TO ZERO ON RESTART

BLK(FILSPC,0)		;FIRST WORD CLEARED EACH TIME THROUGH PARSE
BLK(DEV,1)		;DEVICE NAME
BLK(FILNAM,1)		;FILENAME
BLK(EXT,1)		;EXTENSION
BLK(PTHBLK,7)		;PATH BLOCK
BLK(CPEBR,1)		;ARGUMENT TO CHANGE THE EPT TO IT'S CURRENT VALUE
BLK(CPCLL,1)		;CACHE STRATEGY FROM KLI/MONITOR (KL ONLY)
IFN FTTAPE,<
BLK(NOTAPE,1)		;FLAG NON-ZERO IF MAGTAPE DRIVERS HAVE BEEN DISCARDED
>; END IFN FTTAPE

Z.BEG:!			;FIRST ADDRESS TO ZERO AT INITIALIZATION
BLK(EPTADR,1)		;PHYSICAL ADDRESS OF OUR EPT
BLK(BTBOT,1)		;FIRST PHYSICAL ADDRESS USED BY BOOT
BLK(BTTOP,1)		;FIRST PHYSICAL ADDRESS BEYOND TOP OF BOOT
BLK(SUBREL,1)		;SUBROUTINE RELOCATION
BLK(SUBDAT,DATLEN)	;SUBROUTINE DATA STORAGE
BLK(ERRFLG,1)		;SUBROUTINE ERROR OCCURED IF NON-ZERO
BLK(CPUBR,1)		;ARGUMENT TO RESTORE THE UPT AS IT WAS ON ENTRY
IFN FTKL10,<
BLK(CPDTE,1)		;CONI DTE, ON SUBROUTINE CALLS
>
IFN FTKS10,<
BLK(CPHSB,1)		;RDHSB ON SUBROUTINE CALLS
BLK(CPAPR,1)		;CONI APR, ON SUBROUTINE CALLS
>
BLK(MEMPSZ,1)		;NUMBER OF PAGES IN MEMORY
BLK(TRPADR,1)		;ADDRESS OF WHERE TO GO ON A TRAP
BLK(LUNPOS,1)		;LOGICAL UNIT NUMBER WITHIN STR
BLK(DRVBPC,1)		;BLOCKS/CYLINDER ON THIS UNIT \*** KEEP
BLK(DRVBPT,1)		;BLOCKS/TRACK ON THIS UNIT    /*** TOGETHER
BLK(SDLPOS,1)		;POSITION IN SYSTEM DUMP LIST
BLK(BLKCNT,1)		;NUMBER BLOCKS LEFT IN THIS GROUP
BLK(BLKADR,1)		;CURRENT BLOCK ADDRESS
BLK(BLKNUM,1)		;CURRENT RELATIVE BLOCK NUMBER IN FILE
BLK(SAVFIR,1)		;COPY OF RIBFIR FROM CURRENT RIB
BLK(SAVSIZ,1)		;COPY OF RIBSIZ FROM CURRENT RIB
BLK(SAVEAC,20)		;SAVE AC'S HERE IN BUGDMP
IFN FTKL10,<
BLK(R2IOWD,R2IOWL)	;RH20 IOWDS
>
IFN FTKS10,<
BLK(MAPBLK,40)		;SAVE UBA MAP REGISTERS
>
BLK(USRFLG,1)		;USER MODE FLAG
BLK(CDFLG,1)		;CONTROL-D FLAG
BLK(CDSAV,20)		;SAVED ACS FOR CONTROL-D
BLK(CD112,1)		;SAVED MONITOR LOCATION 112
BLK(CD116,1)		;SAVED MONITOR LOCATION 116
BLK(CD117,1)		;SAVED MONITOR LOCATION 117
BLK(BTSPDL,PDLLEN)	;PUSH DOWN LIST
BLK(CMDPTR,1)		;BYTE POINTER TO COMMAND BUFFER
BLK(CMDBUF,LINBFL)	;COMMAND LINE BUFFER
BLK(BTXPTR,1)		;BYTE POINTER TO BOOTXT
BLK(AUTFLG,1)		;AUTO-BOOT FLAG
BLK(NXMFLG,1)		;NXMTAB VALID FLAG
BLK(NXMTAB,NXMLEN)	;OUR COPY OF NXMTAB

Z.END:!			;LAST ADDRESS TO ZERO AT INITIALIZATION
	SUBTTL	BOOTSTRAP INITIALIZATION

;HERE AFTER BEING LOADED INTO MEMORY.  WE ARE (PROBABLY) RUNNING
;UNPAGED AT THIS POINT SO WE MUST DO SOMETHING ABOUT THAT FIRST.

BOOT:
IFN FTKL10,<
	TDZA	S,S		;NO BITS SPECIFIED
	JFCL			;DON'T TOUCH - 20F SET UP S
				;PRESERVE S UNTIL WE CAN REFERENCE MEMORY
>
	CONO	APR,APRRST	;BLAST THE PROCESSOR
	CONO	PI,PI.CPI!PI.OFF ;BLAST THE PI SYSTEM

REPEAT 0,<
;THIS DOESN'T WORK AND SHOULD NEVER BE REQUIRED SINCE KLI ALREADY DID IT

IFN FTKLP,<
	CONO	PAG,0		;ZAP
	MOVSI	T1,(1B0+0B8+6B11) ;AC BLOCK 6
	JRSTF	@[4000,,.+1]	;MAKE SURE CAN ADDRESS PREVIOUS CONTEXT
	DATAO	PAG,T1		;PREVIOUS CONTEXT ACS
	EXCTUX	<SETZM 2>	;CLEAR CST BASE
>
>;END REPEAT 0

IFN FTKL10,<
	DATAO	APR,[EXP 0]	;CLEAR OLD ADDRESS BREAK
	CONI	PAG,T3		;READ CACHE STRATEGY
	ANDI	T3,LG.CSL!LG.CSW ;ISOLATE CACHE STRATEGY BITS
	MOVEI	T1,XG.TEN!<EPTABS/PAGSIZ>!XG.KLP ;GET BITS TO SET THE EBR
	MOVSI	T4,(XG.LAB!LG.LPC!XG.LUB) ;FLAG BITS TO LOAD THE UBR
	HRRI	T4,LG.IAM!<EPTABS/PAGSIZ> ;AND THE PAGE NUMBER
	CONO	PAG,(T1)	;TURN ON PAGING, MAP US 1 FOR 1
	DATAO	PAG,T4		;SET THE UPT TO THE SAME PAGE
	CONO	DTE0,PILDEN!0	;TURN OFF DTE PIA
>
IFN FTKS10,<
	SETZB	T1,T3		;CLEAR AC, NO CACHE STRATEGY ON KS
	CONO	PAG,(T1)	;TURN OFF PAGING
	WRCSB	T1		;CLEAR CST BASE ADDRESS (REQUIRES UCODE 124)
	MOVEI	T1,XG.TEN!<EPTABS/PAGSIZ>!XG.KLP ;GET BITS TO SET THE EBR
	MOVSI	T4,(XG.LAB!XG.LUB) ;FLAG BITS TO LOAD THE UBR
	HRRI	T4,<EPTABS/PAGSIZ> ;AND THE PAGE NUMBER
	CONO	PAG,(T1)	;TURN ON PAGING, MAP US 1 FOR 1
	DATAO	PAG,T4		;SET THE UPT TO THE SAME PAGE
	MOVEI	T2,.EPHSB	;GET HALT STATUS BLOCK ADDRESS
	WRHSB	T2		;WRITE IT
>
	MOVEM	T1,CPEBR	;STORE BITS TO CHANGE EBR FOR LATER
	MOVEM	T3,CPCLL	;SAVE CACHE STRATEGY FROM KLI
	MOVSI	T2,(<PM.DCD>B2+PM.WRT) ;ACCESSIBLE AND WRITABLE
	MOVEM	T2,EPT+.MPAG0	;MAP PAGE 0
	MOVEM	T2,EPT+.MPAG0+1
	AOS	EPT+.MPAG0+1	;AND PAGE 1
	MOVEI	T2,.VBOOT	;GET STARTING PHYSICAL ADDRESS
	MOVEM	T2,BTBOT	;STORE AS BOTTOM OF BOOT
	HRRZ	T3,.VBOOT+.BTSIZ ;GET +SIZE IN WORDS
	ADD	T2,T3		;GET TOP+1
	MOVEM	T2,BTTOP	;STORE FOR LATER
	MOVEI	T2,EPTABS	;GET PHYSICAL ADDRESS OF OUR EPT
	MOVEM	T2,EPTADR	;STORE FOR LATER
	LSH	T2,W2PLSH	;CONVERT TO PAGE NUMBER
	HRLI	T2,(<PM.DCD>B2+PM.WRT) ;ACCESSIBLE + WRITABLE
	MOVEM	T2,EPT+540	;SETUP SECTION TABLE TO POINT AT SECTION 0 PT
IFN FTKL10,<SETZM EPT+DTEEPW>	;CLEAR EXAMINE/PROTECTION WORD
	MOVE	T2,CHGEBR	;GET INSTRUCTION TO CHANGE THE EBR
	MOVSI	T3,(JRST)	;SETUP JRST TO GET BACK AFTER
	HRRI	T3,MAPPED	;  WE'RE MAPPED
	JRST	T2		;CHANGE THE EBR, COME BACK MAPPED
;HERE WHEN THE .VBOOT ADDRESS SPACE HAS BEEN MAPPED TO DO SOME ONCE
;ONLY INITIALIZATION

MAPPED:	MOVEI	P,BTSPDL	;SETUP A PDL
IFN FTKL10,<
	SETZM	EPT+DTEEPW	;CLEAR DTE EXAMINE/PROTECTION WORD
	SETZM	EPT+DTEMTI	;CLEAR INPUT READY FLAG
	MOVSI	T3,DT.ESP	;BIT TO CAUSE -20F TO ENTER SECONDARY
	HRRI	T3,DTEFLG	;IN THIS WORD
	PUSHJ	P,DODTE		;EXECUTE THE COMMAND
	PUSHJ	P,ZAPICH	;FORCIBLY BLAST INTERNAL CHANNELS
>
	MOVE	T1,[Z.BEG,,Z.BEG+1] ;SET UP BLT
	SETZM	Z.BEG		;CLEAR FIRST WORD
	BLT	T1,Z.END-1	;CLEAR ENTIRE DATA BASE
IFN FTKS10,<
	SETZM	.VPAG0+CTYIWD	;CLEAR INPUT AVAILABLE WORD
	SETZM	.VPAG0+CTYOWD	;AND OUTPUT PRESENT WORD
	SETZM	.VPAG0+KLIIWD	;BE SURE KLINIK LINE COMMANDS
	SETZM	.VPAG0+KLIOWD	;CAN'T MAKE 8080 HANG IF TRASH FROM SAVE.
	HRRZ	S,.VPAG0+RLWORD	;GET FLAGS FROM 8080
	TRNE	S,FORREL	;IF FORCED RELOAD
	TLO	S,(KL.SIL!KL.DMP) ;WE WANT A DUMP/SILENT LOAD
	TRNE	S,AUTOBT	;IF AN AUTO-BOOT
	TLO	S,(KL.SIL)	;JUST LOAD SILENTLY
	HLLZS	S		;KEEP ONLY KL-STYLE FLAGS
>
	MOVEM	S,AUTFLG	;SAVE WHAT WE ARE TOLD
	MOVEI	S,0		;ZERO FLAGS
	PUSHJ	P,SUNXMT	;LOOK AT MEMORY AND SETUP NXMTAB
	MOVEI	T1,VERMSG	;POINT AT VERSION STRING
	PUSHJ	P,PRMSG		;TELL HIM THAT WE'RE HERE
	PUSHJ	P,COPDAT	;COPY DATA FROM OLD BOOT (SSL, ASL, SDL, ETC.)
	PUSHJ	P,FINDHI	;FIND PHYSICAL PAGE # OF TOP OF CORE
	PUSHJ	P,MOVBTS	;RELOCATE BOOT TO TOP OF PHYSICAL CORE
	MOVEI	T1,RESTAR	;GET RESTART ADDRESS
	HRRM	T1,BTSVEC+.BTSTA ;SAVE IT
	SETOM	CDFLG		;NOT A CONTROL-D
	PUSHJ	P,RICD		;ENTER DDT IF DEBUGGING
	SKIPN	T1,AUTFLG	;GET THE FLAGS FROM THE FE
	JRST	RESTAR		;IF NONE, ASK OPR
	PUSHJ	P,DEFSPC	;DEFAULT THE FILE-SPEC
	TLZE	T1,(KL.DMP)	;NEED A DUMP?
	PUSHJ	P,DODUMP	;YES -- DO ONE
	PUSHJ	P,DEFSPC	;RE-DEFAULT FOR LOAD
	MOVE	T1,[BTSVEC+.BTDEV,,DEV] ;SET UP BLT
	SKIPE	BTSVEC+.BTDEV	;HAVE A FILESPEC FROM BEFORE?
	BLT	T1,PTHBLK+6	;COPY IT
	.CREF	KL.SIL		;BIT WE'RE TESTING
	SKIPL	AUTFLG		;A SILENT LOAD?
	PJRST	RESTAR		;NO, ASK OPR
	PJRST	RLDMO2		;YES, DO SO
DEFSPC:	SETZM	R.BEG		;DEFAULT THE WORLD
	MOVE	T2,[R.BEG,,R.BEG+1] ;SET UP BLT
	BLT	T2,R.END-1	;ZERO DATA STORAGE
	MOVE	T2,[FILSPC,,FILSPC+1]
	SETZM	FILSPC
	BLT	T2,PTHBLK+6
	MOVSI	T2,'EXE'	;DEFAULT EXTENSION
	MOVEM	T2,EXT
	MOVE	T2,[XWD 1,4]	;DEFAULT PPN
	MOVEM	T2,PTHBLK
	MOVSI	S,(FL.WLD)	;ANY STRUCTURE
	POPJ	P,		;DONE
; SUBROUTINE ENTRY
SUBR:	MOVSI	17,(JRST (16))	;RETURN INSTRUCTION FOR JSR
	JSR	16		;FIND OUT WHERE WE ARE
	XMOVEI	17,0-.(16)	;OFFSET FOR RELOCATED LOADING TO ORIGINAL SPOT
	MOVEM	0,SAVEAC(17)	;SAVE CALLER'S AC 0
	MOVSI	0,1		;START WITH AC 1
	HRRI	0,SAVEAC+1(17)	;SET UP BLT
	MOVEI	16,SAVEAC+15(17) ;COMPUTE END OF BLT
	BLT	0,(16)		;SAVE CALLER'S ACS 1-15
	MOVE	R,17		;SET RELOCATION AC
	MOVEM	R,SUBREL(R)	;SAVE SUBROUTINE RELOCATION FOR RETURN
	JSP	P1,SAVHDW(R)	;SAVE HARDWARE STATUS
	JSP	P1,SETMAP(R)	;RESET POINTERS IN OUR EPT
	MOVE	T1,EPTADR(R)	;GET PHYSICAL EPT ADDRESS
	LSH	T1,W2PLSH	;CONVERT TO A PAGE NUMBER
	TRO	T1,XG.TEN!XG.KLP ;WORD TO CHANGE THE EBR
IFN FTKL10,<
	MOVEI	T4,LG.IAM(T1)	;GET UPT PAGE NUMBER AND FLAG
	HRLI	T4,(XG.LUB)	;FLAG BITS TO LOAD THE UBR
>
IFN FTKS10,<
	MOVE	T4,T1		;GET UPT PAGE NUMBER
	HRLI	T4,(XG.LAB!XG.LUB) ;FLAGS TO LOAD THE UBR
>
	MOVE	P1,CHGEBR(R)	;GET INSTRUCTION TO CHANGE THE EBR
	MOVE	P2,CHGUBR(R)	;GET INSTRUCTION TO CHANGE THE UBR
	MOVE	P3,[JRST @P4](R) ;SETUP JRST TO GET BACK AFTER WE'RE MAPPED
	MOVEI	P4,SUBR1	;RETURN TO 0,,SUBR1
	JRST	P1		;CHANGE THE EBR AND UBR, COME BACK MAPPED

SUBR1:	MOVE	P,[IOWD PDLLEN,BTSPDL] ;SET UP A STACK
	SETZM	ERRFLG		;CLEAR ERROR FLAG
	MOVE	T1,BTSVEC+.BTCPN ;GET NUMBER OF CPU WHICH INVOKED BOOT
	LDB	T1,BTYCST(T1)	;GET THAT CPU'S SAVED CACHE STRATEGY
	DPB	T1,[POINT 2,CPCLL,19] ;SAVE FOR POSSIBLE RELOAD
	PUSHJ	P,DEFSPC	;DEFAULT THE FILESPEC
	MOVE	T1,BTSVEC+.BTFNC ;GET FUNCTION CODE
	CAILE	T1,DISPLN	;KNOWN?
	MOVEI	T1,0		;NO--ERROR
	SKIPG	DISP(T1)	;PRESERVE NXMTAB?
	SETZM	NXMFLG		;NXMTAB NOT VALID (CAN'T TRUST MONITOR)
	PUSHJ	P,@DISP(T1)	;DISPATCH
	MOVE	R,SUBREL	;GET RELOCATION BACK
	MOVE	T1,CPEBR	;GET OLD EBR
	MOVE	T4,CPUBR	;AND OLD UBR
	MOVE	P1,CHGEBR	;GET INSTRUCTION TO CHANGE THE EBR
	MOVE	P2,CHGUBR	;GET INSTRUCTION TO CHANGE THE UBR
IFN FTKL10,<MOVE P3,[XJRST P4]>	;GET INSTRUCTION TO RETURN TO RELOCATED ADDRESS
IFN FTKS10,<MOVE P3,[JRST @P4]>	;GET INSTRUCTION TO RETURN TO RELOCATED ADDRESS
	MOVEI	P4,SUBR2(R)	;GET LOCAL RELOCATED ADDRESS
	HLL	P4,R		;MAKE IT GLOBAL
	JRST	P1		;CHANGE BACK TO OLD EBR AND UBR
SUBR2:	JSP	P1,RSTHDW(R)	;RESTORE THE STATE OF THE HARDWARE
	SKIPN	ERRFLG(R)	;ERROR ALONG THE WAY?
	AOS	BTSVEC+.BTXPC+1(R) ;NO--GIVE SKIP RETURN
	MOVE	17,R		;COPY RELOCATION
	MOVSI	15,SAVEAC(17)	;SET UP BLT
	BLT	15,15		;RESTORE ACS 0-15
	XJRSTF	BTSVEC+.BTXPC(17) ;RETURN TO CALLER

;BYTE POINTERS FOR SAVED CACHE STRATEGY

BTYCST:	POINT	2,BTSVEC+.BTSCS,35 ;FOR CPU0
	POINT	2,BTSVEC+.BTSCS,33 ;FOR CPU1
	POINT	2,BTSVEC+.BTSCS,31 ;FOR CPU2
	POINT	2,BTSVEC+.BTSCS,29 ;FOR CPU3
	POINT	2,BTSVEC+.BTSCS,27 ;FOR CPU4
	POINT	2,BTSVEC+.BTSCS,25 ;FOR CPU5

;SUBROUTINE DISPATCH TABLE

DISP:	XWD	400000,ILLFNC	;ILLEGAL FUNCTIONS
	XWD	400000,RESTAR	;FUNCTION 1 - BOOT RESTART (DO NOT LOAD)
	XWD	     0,DODUMP	;FUNCTION 2 - DUMP
	XWD	400000,RELOAD	;FUNCTION 3 - LOAD (READ BOOTXT)
	XWD	     0,SLFUNC	;FUNCTION 4 - SYSTEM SLEEP DUMP
	XWD	     0,PGFUNC	;FUNCTION 5 - PAGE REPLACE
DISPLN==.-DISP			;LENGTH OF TABLE


ILLFNC:	SETOM	ERRFLG		;FLAG THE ERROR
	MOVEI	T1,[ASCIZ /
?BOOT error; illegal function code 
/]
	PUSHJ	P,PRMSG		;PRINT TEXT
	MOVE	T1,BTSVEC+.BTFNC ;GET OFFENDING FUNCTION CODE
	PJRST	PROCT		;PRINT IT AND RETURN
; SAVE HARDWARE STATUS ON SUBROUTINE ENTRY
; CALL:	JSP	P1,SAVHDW(R)

SAVHDW:
IFN FTKL10,<
	SWPUA			;SWEEP CACHE
	CONSO	APR,LP.CSD	;DONE YET?
	JRST	.-1(R)		;NO--WAIT
	CONI	PAG,CPEBR(R)	;SAVE CURRENT EPT MAPPING
	DATAI	PAG,CPUBR(R)	;SAVE CURRENT UPT MAPPING
	CONI	DTE0,CPDTE(R)	;SAVE CURRENT DTE PIA
	CONO	DTE0,PILDEN!0	;ZAP DTE PIA
	SETZM	EPT+DTEEPW(R)	;AND THE EXAMINE/PROTECTION WORD
>
IFN FTKS10,<
	CONI	PAG,CPEBR(R)	;SAVE CURRENT EPT MAPPING
	DATAI	PAG,CPUBR(R)	;SAVE CURRENT UPT MAPPING
	CONI	APR,CPAPR(R)	;SAVE CURRENT APR PI ASSIGNMENT
	RDHSB	CPHSB(R)	;SAVE CURRENT HALT STATUS BLOCK
	HRLZ	T1,DVCTAB(R)	;UBA NUMBER FOR DISK
	MOVEI	T2,MAPBLK(R)	;ADDRESS OF SAVE AREA
	HRLI	T2,(POINT 18)	;MAKE A BYTE POINTER
SVMAP1:	TRNE	T1,100		;DONE?
	JRST	SVMAP2(R)	;YES
	RDIO	T3,SO.UPR(T1)	;READ MAP REGISTER
	LSHC	T3,-^D20	;CONVERT READ FORMAT TO WRITE
	LSH	T3,-4
	LSHC	T3,^D11
	IDPB	T3,T2		;STORE IT
	AOJA	T1,SVMAP1(R)	;LOOP
SVMAP2:
>
	JRST	(P1)		;RETURN
; RESTORE HARDWARE STATUS ON SUBROUTINE EXIT
; CALL:	JSP	P1,RSTHDW(R)

RSTHDW:
IFN FTKL10,<
	HRRZ	T1,CPDTE(R)	;RESTORE DTE PIA
	ANDI	T1,PI0ENB!PIA	;KEEP JUST USEFUL BITS
	CONO	DTE0,PILDEN(T1)
>
IFN FTKS10,<
	HRLZ	T1,DVCTAB(R)	;UBA NUMBER FOR DISK
	MOVEI	T2,MAPBLK(R)	;ADDRESS OF SAVE AREA
	HRLI	T2,(POINT 18)	;MAKE A BYTE POINTER
RSMAP1:	TRNE	T1,100		;DONE?
	JRST	RSMAP2(R)	;YES
	ILDB	T3,T2		;GET ORIGINAL VALUE
	WRIO	T3,SO.UPR(T1)	;PUT IT BACK
	AOJA	T1,RSMAP1(R)	;LOOP
RSMAP2:	MOVE	T1,CPHSB(R)	;GET HALT STATUS BLOCK ADDRESS
	WRHSB	T1		;RESTORE IT
	MOVE	T1,CPAPR(R)	;GET CONI APR,
	ANDI	T1,7		;KEEP JUST PI ASSIGNMENT
	CONO	APR,(T1)	;RESTORE APR PI ASSIGNMENT

>
	JRST	(P1)		;RETURN
; SET UP THE EPT/UPT ON SUBROUTINE ENTRY
; CALL:	JSP	P1,SETMAP(R)

SETMAP:	XMOVEI	T1,BTSVEC(R)	;GET CURRENT VIRTUAL ORIGIN
	MAP	T1,(T1)		;TRANSLATE TO PHYSICAL
IFN FTKL10,<TLZ	T1,(^-<LG.EPT*PAGSIZ+PAGSIZ-1>)> ;KEEP ONLY ADDRESS
IFN FTKS10,<TLZ	T1,(^-<SG.EPT*PAGSIZ+PAGSIZ-1>)> ;KEEP ONLY ADDRESS
	MOVEM	T1,BTBOT(R)	;SAVE PHYSICAL START OF BOOT
	HRRZ	T2,BTSVEC+.BTSIZ(R) ;GET SIZE IN WORDS
	ADD	T2,T1		;GET FIRST ADDRESS BEYOND BOOT
	MOVEM	T2,BTTOP(R)	;SAVE THAT
	ADDI	T1,EPTOFS	;OFFSET TO THE EPT
	MOVEM	T1,EPTADR(R)	;SAVE PHYSICAL ADDRESS OF THE OUR EPT
	LSH	T1,W2PLSH	;CONVERT TO A PAGE NUMBER
	HRRM	T1,EPT+540(R)	;SAVE SECTION 0 MAP POINTER
	SUBI	T1,EPTPAG	;BACK TO THE BOOT ORIGIN PAGE
	HLLZ	T2,BTSVEC+.BTSIZ(R) ;GET -LENGTH OF BOOT IN PAGES
	HRRI	T2,EPT+.MBOOT(R) ;MAKE AN AOBJN POINTER
	HRRM	T1,(T2)		;STUFF PAGE NUMBER IN MAP
	AOS	T1		;ADVANCE
	AOBJN	T2,.-2(R)	;LOOP FOR ALL OUR PAGES
	JRST	(P1)		;RETURN
	SUBTTL	PROCESS COMMAND

;ROUTINE TO PROMPT THE USER AND DUMP/LOAD/RELOAD THE MONITOR.  CALL
;AFTER SETTING UP THE MAP SO THAT WE ARE RUNNING IN THE .VBOOT ADDRESS
;SPACE.  EXITS TO THE START ADDRESS OF THE NEW MONITOR.

RESTAR:	SETZM	SUBDAT		;INVALIDATE POSSIBLE BOOTXT
	PUSHJ	P,DEFSPC	;DEFAULT THE FILESPEC
RELOAD:	MOVE	T1,[POINT 7,SUBDAT] ;POINT TO DATA BUFFER (COPY OF BOOTXT)
	MOVEM	T1,BTXPTR	;SAVE FOR PARSE
RELOA1:	SKIPN	SUBDAT		;HAVE ANY DATA?
RLDMON:	TLO	S,(FL.DEF!FL.CMD) ;NO DEFAULTS AND READ FROM COMMAND BUFFER
	TDZ	S,[FX.CLR]	;CLEAR LOTS OF BITS
	MOVEI	P,BTSPDL	;SETUP PDL AGAIN IN CASE OF TRAP
	SETZM	AUTFLG		;IF ERROR, ALLOW TALKING TO OPR
				;<MATCH ANGLE BRACKET ON NEXT LINE
	MOVEI	T1,[ASCIZ/BOOT>/] ;OUR PROMPT
	MOVEI	T2,[0]		;DEFAULT ANSWER IS CR
	TLNE	S,(FL.CMD)	;READING FROM COMMAND BUFFER?
	PUSHJ	P,REDLIN	;YES--PROMPT AND GET A COMMAND
	PUSHJ	P,PARSE		;PARSE THE COMMAND
	  JRST	RESTAR		;SYNTAX ERROR
IFN FTTAPE,<
	SKIPE	W,TAPIDX	;SET UP DEVICE INDEX FOR LATER USE IF MAGTAPE
	PUSHJ	P,@RESTAB(W)	;FIND AND RESET THE CONTROLLER
	TRNE	S,FR.TAB	;ANY TAPE ACTION BITS SET?
	JRST	TAPACT		;YES
>; END IFN FTTAPE
	TRNN	S,FR.DMP	;/DUMP SEEN?
	JRST	RLDMO1		;NO
IFN FTTAPE,<
	SKIPE	TAPIDX		;MAGTAPE UNIT SPECIFIED?
	JRST	NTDERR		;YES
>; END IFN FTTAPE
	TLZE	S,(FL.DDD)	;WANT TO SKIP /D?
	TLNE	S,(FL.CMD)	;AND READING FROM BOOTXT?
	PUSHJ	P,DODUMP	;NO TO EITHER, TAKE A DUMP
	TLNN	S,(FL.CMD)	;READING FROM BOOTXT?
	JRST	RELOA1		;YES--PERHAPS NOT DONE WITH BOOTXT YET
	JRST	RESTAR		;JUST RESTART THINGS CLEANLY
RLDMO1:	TRNE	S,FR.STA	;/START SEEN?
	TRNE	S,FR.ALL-FR.STA	;AND NOTHING ELSE?
	TLOA	S,(FL.CMD)	;NO, READ NO MORE COMMANDS FROM BOOTXT
	JRST	RLDMO3		;YES, JUST START UP MONITOR
				;FALL INTO RLDMO2
RLDMO2:	PUSHJ	P,DOLOAD	;LOAD NEW MONITOR
	  JRST	RESTAR		;ERROR DETECTED
	TRNE	S,FR.LOD	;/LOAD SPECIFIED?
	JRST	RLDMON		;YES, DON'T START
IFN FTTAPE,<
	SKIPE	TAPIDX		;DON'T POSITION TAPE UNLESS LOADED VIA TAPE
	TRNE	S,FR.NOR	;/NOREWIND?
	JRST	RLDMO3		;DON'T TOUCH TAPE
	PUSHJ	P,REWIND	;REWIND THE TAPE
	PUSHJ	P,SKPEOF	;SKIP ONE FILE
IFN FTKS10,<
	PUSHJ	P,SKPEOF	;SKIP A SECOND FILE ON THE KS
>; END IFN FTKS10
>; END IFN FTTAPE
RLDMO3:	TRNE	S,FR.RBT	;THIS A /REBOOT REQUEST?
	JRST	RLDMO4		;YES, DON'T CHANGE CORE
	MOVE	T1,[DEV,,BTSVEC+.BTDEV] ;SET UP BLT
	BLT	T1,BTSVEC+.BTPTH+6 ;COPY MONITOR FILESPEC INTO VECTOR
	MOVE	T1,EPT+.MBOOT	;GET MAP ENTRY FOR START OF BOOT
	LSH	T1,P2WLSH	;CONVERT TO A PHYSICAL ADDRESS
	MOVEM	T1,.VPAG0+BOOTSA ;SAVE FOR MONITOR
	APRID	T1		;READ SERIAL NUMBER
	ANDI	T1,ASNMSK	;MASK DOWN TO ONLY THE SERIAL NUMBER
	MOVEM	T1,.VPAG0+BOOTWD ;SAVE FOR MONITOR

RLDMO4:	PUSHJ	P,LISTEN	;GIVE ONE MORE CHANCE TO CONTROL-C OUT
IFN FTTAPE,<
	SKIPN	NOTAPE		;TAPE DRIVER CODE STILL PRESENT?
	PUSHJ	P,ZAPTAP	;YES, DELETE IT SINCE MONITOR HAS NO USE FOR
				; IT ONCE IT IS RUNNING
>; END IFN FTTAPE
	SKIPN	T4,STSA		;START ADDRESS SPECIFIED ON /START?
	HRRZ	T4,.VPAG0+.JBSA	;NO, USE ADDRESS FROM FILE
	HRLI	T4,(JRST)	;MAKE IT A JRST
	MOVE	T3,CHGEBR	;GET INSTRUCTION TO CHANGE THE EBR
	MOVE	T1,CPCLL	;GET CACHE STRATEGY BITS (KL), TURN OFF PAGING
	MOVE	S,AUTFLG	;PASS FLAGS TO MONITOR IN CASE IT CARES
	JRST	T3		;TURN OFF PAGING AND START NEW MONITOR
CHGEBR:	CONO	PAG,(T1)	;CHANGE THE EBR

CHGUBR:	DATAO	PAG,T4		;CHANGE THE UBR


;BUILD THE BOOT VERSION MESSAGE

VERMSG:	VSTR	(\BOOVER,\BOOEDT)
	SUBTTL	DUMP MONITOR


;ROUTINE TO DUMP THE SYSTEM. CALL WITH INITIAL FILESPEC ON
;WHICH TO DUMP IN THE FILESPEC AREA.  ASKS THE USER FOR A NEW
;FILESPEC IF ERRORS ARE DETECTED.
;CALL:	PUSHJ	P,DODUMP
;RETURN+1 ALWAYS

SLFUNC:	TLO	S,(FL.DEF!FL.SSD) ;NO DEFAULTS, SYSTEM-SLEEP DUMP
	PJRST	DODUMP		;BUT MOSTLY NORMAL

ASKSTR:	TDO	S,[FL.1CM!FR.DMP] ;FORCE PARSE FROM COMMAND BUFFER AND /DUMP
	MOVEI	T1,[ASCIZ/File on which to dump: /]
	MOVEI	T2,[ASCIZ/DSK:CRASH.EXE[1,4]/]
	TLNN	S,(FL.SSD)	;IF THIS IS FOR A NORMAL DUMP,
	TLZ	S,(FL.DEF)	;MAKE SURE DEFAULTS ARE ALLOWED
	PUSHJ	P,REDLIN	;ASK WHERE HE WANTS THE DUMP
	PUSHJ	P,PARSE		;PARSE THE COMMAND
	  JRST	ASKSTR		;TRY AGAIN
	TLZ	S,(FL.1CM)	;CLEAR COMMAND FLAG
	TRNN	S,FR.ALL-FR.DMP	;SEE ANYTHING AT ALL?
	POPJ	P,		;NO, LONE CR MEANS NO DUMP

DODUMP:	SKIPN	NXMFLG		;NXMTAB VALID?
	PUSHJ	P,SUNXMT	;MUST REBUILD IT
	PUSHJ	P,SDLCHK	;CHECK FOR THE SDL
	  SKIPA	P1,['DSKA  '-10000] ;GET DISK NAME TO INCREMENT TO DSKA
	MOVE	P1,T1		;GET PREDECREMENTED AOBJN POINTER
	MOVE	T1,[SIXBIT/CRASH/] ;FILENAME IS CRASH
	TRNN	S,FR.FIL	;SEE A FILE NAME?
	MOVEM	T1,FILNAM	;NO, USE DEFAULT
	TLNN	S,(FL.WLD)	;WILD STR?
	JRST	DODUM4		;NO, USE THE ONE HE SAID
DODUM1:	TRNE	S,FR.FRC	;/FORCE (IGNORE THE SDL)?
	JRST	DODUM2		;YES
	AOBJP	P1,DODUM6	;ADVANCE POINTER
	SKIPN	T1,(P1)		;GET A STRUCTURE NAME
	AOBJN	P1,.-1		;NONE THERE, TRY NEXT
	JUMPL	P1,DODUM3	;JUMP IF HAVE A STRUCTURE NAME
	JRST	DODUM6		;GIVE UP
DODUM2:	CAMN	P1,[SIXBIT/DSKZ/] ;LOOKED AT THE LAST ONE?
	JRST	DODUM6		;YES, GIVE UP
	ADDI	P1,10000	;STEP TO NEXT DISK NAME
	MOVE	T1,P1		;COPY STRUCTURE NAME
DODUM3:	MOVEM	T1,DEV		;ELSE STORE STR NAME TO TRY THIS TIME
DODUM4:	TLZA	S,(FL.OVW)	;DON'T ALLOW OVERWRITING
DODUM5:	TLO	S,(FL.OVW)	;OVERWRITE IF HE SAYS TO
	TLZ	S,FR.DMP	;CLEAR DUMP FLAG FOR NEXT TIME
	PUSHJ	P,DUMP		;TRY TO DUMP THE MONITOR
	  JRST	DMPERR		;FAILED, ANALYZE ERROR AND TRY TO RECOVER
	POPJ	P,		;COMPLETED SUCCESSFULLY, RETURN
DODUM6:	MOVEI	T1,[ASCIZ/?Unable to find a file on which to dump
/]
	PUSHJ	P,PRMSG		;PRINT MESSAGE
	TLNE	S,(FL.SSD)	;SYSTEM SLEEP DUMP?
	JRST	ASKSTR		;YES, DON'T GIVE THEM A CHANCE TO BLOW IT
	MOVEI	T1,[ASCIZ/Do you want to keep this dump? /]
	MOVEI	T2,[ASCIZ/No/]
	PUSHJ	P,ASKYN		;ASK HIM WITH DEFAULT ANSWER
	  JRST	DODUM6		;CONFUSED USER--ASK AGAIN
	  POPJ	P,		;HE SAYS NO
	JRST	ASKSTR		;ASK ON WHAT STR TO DUMP
; CHECK FOR THE EXISTANCE OF ANY STRUCTURES IN THE PRESERVED
; COPIES OF THE SYSTEM SEARCH LIST OR DUMP LIST
; CALL:	PUSHJ	P,SSLCHK/SDLCHK
;	  <NON-SKIP>		;TABLE EMPTY OR /FORCE SEEN
;	<SKIP>			;USE TABLE, T1 = PREDECREMENTED POINTER

SSLCHK:	SKIPA	T1,BTSVEC+.BTSSL ;AOBJN POINTER TO SSL
SDLCHK:	MOVE	T1,BTSVEC+.BTSDL ;AOBJN POINTER TO SDL
	ADDI	T1,BTSVEC	;OFFSET TO START OF DESIRED TABLE
	MOVE	T2,T1		;MAKE A WORKING COPY
	ADJSP	T1,-1		;PREDECREMENT AOBJN POINTER FOR CALLER
	TRNE	S,FR.FRC	;/FORCE SEEN?
	POPJ	P,		;YES
	SKIPN	(T2)		;NON-ZERO ENTRY?
	AOBJN	T2,.-1		;KEEP SEARCHING
	JUMPL	T2,CPOPJ1	;RETURN IF FOUND A STRUCTURE
	TRO	S,FR.FRC	;NO--MUST FORCE SCANNING OF DSKA-DSKZ
	POPJ	P,		;RETURN
;HERE IF AN ERROR IS DETECTED IN THE DUMP OR LOAD.  USE THE ERROR
;CODE RETURNED IN T1 TO INDEX INTO EMSTAB AND PRINT A MESSAGE.
;FOR DUMP, INDEX INTO DMPDSP AND DISPATCH TO THE ROUTINE TO
;HANDLE THE ERROR.

LODERR:	TLOA	S,(FL.CMD!FL.LDE) ;INSURE NEXT READ IS FROM TTY
DMPERR:	TLZ	S,(FL.LDE)	;CLEAR BIT FOR DUMP ERRORS
	TLNE	S,(FL.WLD)	;WILD STRUCTURE?
	TLNE	S,(FL.FFL)	;YES, DID WE FIND THE FILE ON THIS STR?
	JRST	DMPER1		;YES, PROCEED NORMALLY
	CAIG	T1,FNFOFS	;NO, IS THIS ERROR JUST FILE OR STR NOT FOUND?
	JRST	DMPER2		;YES, DON'T PRINT MESSAGE
DMPER1:	PUSH	P,T1		;SAVE CODE FOR LATER
	HRRZ	T1,EMSTAB(T1)	;GET MESSAGE ADDRESS
	PUSHJ	P,PRMSG		;PRINT IT
	PUSHJ	P,PRFILE	;PRINT FILENAME
	PUSHJ	P,PRCRLF	;END THE LINE
	POP	P,T1		;RESTORE ERROR CODE
DMPER2:
IFN FTKL10,<
	CONSZ	APR,LP.SBE!LP.NXM!LP.PAR ;NXM OR PARITY ERROR?
>
IFN FTKS10,<
	CONSZ	APR,SP.NXM!SP.HMP ;NXM OR PARITY ERROR?
>
	JRST	DMPER3		;YES
	TLNN	S,(FL.LDE)	;SKIP IF LOAD ERROR
	SKIPA	T1,DMPDSP(T1)	;GET DISPATCH ADDRESSES FOR DUMP
	MOVE	T1,LODDSP(T1)	;DITTO FOR LOAD
	TLNN	S,(FL.WLD)	;DOING WILD STR?
	MOVSS	T1		;YES, USE LH DISPATCH ADDRESSES
	JRST	(T1)		;GO RECOVER

;HERE ON A NXM OR PARITY ERROR DETECTED IN THE CONI APR TO PRINT THE
;APR STATUS AND GIVE UP.

DMPER3:	MOVEI	T1,[ASCIZ/?NXM or memory parity error detected/]
	PUSHJ	P,PRMSG		;TELL WHAT HAPPENED
	PUSHJ	P,PRTHDW	;PRINT APR, EBR, AND UBR STATUS
	CONO	APR,CLRAPR	;RESET THE BITS
	TLO	S,(FL.DEF!FL.CMD) ;NO DEFAULTS, READ FROM CTY
	POPJ	P,		;AND GIVE UP
;HERE ON A FATAL ERROR WHICH WILL RESTART BOOT AT "RESTAR"
;INVOKED VIA THE "ERROR" MACRO

FATERR:	MOVEI	T1,[ASCIZ /
%/]
	PUSHJ	P,PRMSG		;START ON A NEW LINE
	HRRZ	T1,@(P)		;GET TEXT ADDRESS
	PUSHJ	P,PRMSG		;PRINT IT
	PUSHJ	P,PRCRLF	;NEW LINE
	PJRST	RESTAR		;START OVER
;TABLE OF ERROR MESSAGES INDEXED BY THE ERROR CODE RETURNED IN T1.
;THE STRUCTURE NOT FOUND AND FILE NOT FOUND ERRORS MUST BE THE FIRST
;IN THE TABLE BEFORE THE LABEL FNFOFS SO THAT WE CAN AVOID PRINTING
;A FILE/STRUCTURE NOT FOUND MESSAGE FOR EVERY STRUCTURE WHEN THE
;OPERATOR SPECIFIES A WILD STRUCTURE NAME.

EMSTAB:	[ASCIZ/%Structure not found for /]
	[ASCIZ/%File not found /]
FNFOFS==.-EMSTAB-1
	[ASCIZ/%Unprocessed dump on /]
	[ASCIZ/%Unexpected end-of-file on /]
	[ASCIZ\%I/O error on \]
	[ASCIZ/%Bad directory format for /]
	[ASCIZ/%Memory configuration too complicated for /]
	[ASCIZ/%Not a REBOOTable dump /]
	[ASCIZ/%Monitor extends past beginning of BOOT for /]
EMSTBL==.-EMSTAB


;DISPATCH TABLES INDEXED BY ERROR CODE.  LH GIVES THE DISPATCH ADDRESS
;IF AN EXPLICIT STRUCTURE WAS GIVEN, RH GIVES THE DISPATCH ADDRESS IF
;THE STRUCTURE WAS WILD (DSKA-DSKZ)

DMPDSP:	XWD	ASKSTR,DODUM1	;STRUCTURE NOT FOUND
	XWD	ASKSTR,DODUM1	;FILE NOT FOUND
	XWD	STRFUL,DODUM1	;UNPROCESSED DUMP
	XWD	ASKSTR,DODUM1	;UNEXPECTED EOF
	XWD	ASKSTR,DODUM1	;I/O ERROR
	XWD	ASKSTR,DODUM1	;BAD DIRECTORY FORMAT
	XWD	ASKSTR,DODUM1	;MEMORY CONFIGURATION TOO COMPLICATED
	XWD	ASKSTR,DODUM1	;NOT A REBOOTABLE CRASH
	XWD	ASKSTR,DODUM1	;MONITOR EXTENDS BEYOND BEGINNING OF BOOT
DMPDSL==.-DMPDSP

LODDSP:	XWD	CPOPJ,DOLOA1	;STRUCTURE NOT FOUND
	XWD	CPOPJ,DOLOA1	;FILE NOT FOUND
	XWD	CPOPJ,DOLOA1	;UNPROCESSED DUMP
	XWD	CPOPJ,DOLOA1	;UNEXPECTED EOF
	XWD	CPOPJ,DOLOA1	;I/O ERROR
	XWD	CPOPJ,DOLOA1	;BAD DIRECTORY FORMAT
	XWD	CPOPJ,DOLOA1	;MEMORY CONFIGURATION TOO COMPLICATED
	XWD	CPOPJ,DOLOA1	;NOT A REBOOTABLE CRASH
	XWD	CPOPJ,DOLOA1	;MONITOR EXTENDS BEYOND BEGINNING OF BOOT
LODDSL==.-LODDSP


IF2 <IFN EMSTBL-DMPDSL+LODDSL-ERRTBL,<
PRINTX ?Discrepency in lengths of EMSTAB, DMPDSP, LODDSP, ERRTAB
>>
;HERE IF AN EXPLICIT STR WAS GIVEN AND AN UNPROCESSED DUMP WAS FOUND
;ON THAT STR.

STRFUL:	MOVEI	T1,[ASCIZ/Do you want to overwrite it? /]
	MOVEI	T2,[ASCIZ/No/]
	PUSHJ	P,ASKYN
	  JRST	STRFUL		;CONFUSED USER--ASK AGAIN
	  JRST	ASKSTR		;ANSWER WAS NO
	JRST	DODUM5		;OVERWRITE FILE
;ROUTINE TO DUMP THE MONITOR ONTO THE CRASH FILE SPECIFIED IN THE
;COMMAND STRING.  DOES 5 ONE BLOCK TRANSFERS TO WRITE THE 4 BLOCKS
;OF THE DIRECTORY PLUS WORDS 0-177 OF PAGE 0 (SINCE THE RH20 CAN'T
;READ/WRITE ADDRESS 0) AND THEN DOES AS FEW TRANSFERS AS NECESSARY
;FOR EACH GROUP POINTER IN THE RIB.  (GENERALLY ONLY 1).  CALL WITH
;STRUCTURE NAME IN DEV.
;CALL:	PUSHJ	P,DUMP
;RETURN+1 IF ERROR DETECTED WITH ERROR CODE IN T1
;RETURN+2 IF SUCCESSFUL

DUMP:	PUSHJ	P,SAVE2		;SAVE P1-P2
	PUSHJ	P,FNDFIL	;FIND CRASH FILE FOR THIS STR
	  POPJ	P,		;NOT FOUND
	TLNE	S,(FL.SSD)	;SUSPENDING?
	SKIPA	T1,[[ASCIZ /[Suspending system on /]] ;YES, DIFFERENT MESSAGE
	MOVEI	T1,[ASCIZ/[Dumping on /]
	PUSHJ	P,PRMSG		;TELL THE OPERATOR WHAT
	PUSHJ	P,PRFILE	;  WE'RE DOING
	PUSHJ	P,PRRBCR	;END THE LINE
	MOVEI	T1,RIPDMP	;GET "UNPROCESSED DUMP BIT"
	TLNN	S,(FL.OVW)	;DOES CALLER CARE?
	TDNN	T1,RIB+RIBSTS	;YES, IS BIT SET IN RIB?
	CAIA			;NO, OR DOESN'T CARE
	JRST	UPDERR		;YES, GIVE ERROR RETURN
	IORM	T1,RIB+RIBSTS	;SET BIT IN RIB
	PUSHJ	P,WRTRIB	;REWRITE RIB
	  POPJ	P,		;FAILED
	PUSHJ	P,CLRBUF	;CLEAR BUFFER AREA
	MOVSI	P3,-BLKSIZ	;MAKE AOBJP POINTER TO BUF
	MOVEI	P4,1		;FIRST FILE PAGE IS 1
	MOVEI	P2,0		;FIRST CORE PAGE IS 0
DUMP1:	PUSHJ	P,FNDPGS	;FIND NEXT GROUP OF CONTIGUOUS PAGES
	JUMPLE	P1,DUMP3	;DONE IF NONE FOUND
	MOVE	T1,P1		;COPY NUMBER OF PAGES TO T1
	SUBI	T1,1		;REPEAT COUNT FOR LAST HUNK
	ROT	T1,-^D9		;NUMBER OF 256K HUNKS+REPEAT COUNT IN LH
	MOVEI	T2,1(T1)	;T2:=NUMBER OF DESCRIPTORS
DUMP2:	AOBJP	P3,MCCERR	;GO IF TOO MANY DESCRIPTORS
	HRRZM	P4,BUF(P3)	;STORE FILE PAGE NUMBER IN BUF
	MOVSI	T3,(SV%WRT)	;GET WRITABLE BIT
	HLLM	T3,BUF(P3)	;STORE FILE PAGE BITS
	MOVEI	T3,(P2)		;COPY CORE PAGE NUMBER TO T3
	HRLI	T3,777000	;512 PAGES IN THIS HUNK
	AOBJP	P3,MCCERR	;GO IF TOO MANY DESCRIPTORS
	MOVEM	T3,BUF(P3)	;STORE IN BUFFER
	ADDI	P2,<^D256*^D1024>/PAGSIZ ;INCR CORE PAGE
	ADDI	P4,<^D256*^D1024>/PAGSIZ ;DITTO FOR FILE PAGE
	SOJG	T2,DUMP2	;LOOP FOR ALL DESCRIPTORS
	HLLM	T1,BUF(P3)	;CORRECT REPEAT COUNT IN LAST DESCRIPTOR
	LSH	T1,-<^D9+^D18>	;RIGHT JUSTIFY REPEAT COUNT
	MOVNI	T1,-777(T1)	;HAVE TO BACK OFF ON CORE AND FILE PAGE
	SUBI	P2,(T1)		;  NUMBERS TO REFLECT THE (POSSIBLY)
	SUBI	P4,(T1)		;  PARTIAL ALLOCATION IN THE LAST DESCRIPTOR
	JRST	DUMP1		;LOOP FOR MORE
DUMP3:	MOVE	T1,[.SVEND,,1]	;GET END OF DESCRIPTOR MARKER
	AOBJP	P3,MCCERR	;GO IF TOO MANY DESCRIPTORS
	MOVEM	T1,BUF(P3)	;STORE IN BUFFER
	HRLI	P3,.SVDIR	;MAKE P3 BE 1ST WORD OF DIRECTORY
	MOVEM	P3,BUF		;AND STORE IT THERE
	PUSHJ	P,WRTBUF	;WRITE BUFFER TO FILE
	  POPJ	P,		;NO POINTERS OR WRITE FAILURE
	PUSHJ	P,CLRBUF	;CLEAR BUFFER AGAIN
	MOVEI	P1,3		;NEED TO WRITE 3 BLOCKS OF ZEROS
DUMP4:	PUSHJ	P,WRTBUF	;  TO COMPLETE DIRECTORY
	  POPJ	P,		;NO POINTERS OR WRITE FAILURE
	SOJG	P1,DUMP4	;LOOP FOR ALL
	MOVE	T1,[.VPAG0,,BUF] ;SETUP TO BLT WORD 0-177 TO BUF
	BLT	T1,BUF+BLKSIZ-1 ;DO SO
	PUSHJ	P,WRTBUF	;WRITE IT
	  POPJ	P,		;NO POINTERS OR WRITE FAILURE
	MOVEI	P2,0		;START WITH ADDRESS 0
DUMP5:	LSH	P2,W2PLSH	;CONVERT TO PAGE NUMBER
	PUSHJ	P,FNDPGS	;FIND NEXT GROUP OF CONTIGUOUS PAGES
	JUMPLE	P1,DUMP7	;ALMOST DONE IF NO MORE
	LSH	P2,P2WLSH	;CONVERT BACK TO ADDRESS
	LSH	P1,P2BLSH	;CONVERT PAGES TO BLOCKS
	JUMPN	P2,DUMP6	;GO IF NOT DOING PAGE ZERO
	ADDI	P2,BLKSIZ	;COMPENSATE FOR WORDS 0-177
	SUBI	P1,1		;  WHICH WERE WRITTEN ABOVE
DUMP6:	JUMPLE	P1,DUMP5	;LOOP IF NO MORE BLOCKS IN THIS CHUNK
	PUSHJ	P,LISTEN	;CHECK FOR CONTROL-C
	MOVE	T1,P1		;COPY NUMBER OF BLOCKS WE WANT TO XFER
	PUSHJ	P,SELBLK	;SETUP TO DO THAT MANY
	  JRST	EOFERR		;RAN OUT OF POINTERS
	MOVE	R,P2		;START AT THIS ADDRESS
	MOVE	P1,T1		;COPY NUMBER LEFT INTO P1 FOR LOOP TEST
	MOVE	T1,M		;GET NUMBER OF BLOCKS WE CAN DO
	LSH	T1,B2WLSH	;CONVERT TO WORDS
	ADD	P2,T1		;INCREMENT ADDRESS FOR NEXT TIME
	PUSHJ	P,@WRTTAB(W)	;DO THE WRITE
	  JRST	IOFERR		;WRITE ERROR
	JRST	DUMP6		;LOOP FOR ALL OF CORE

;FINALLY, STORE CRASH FILE SPEC
DUMP7:	MOVEI	T1,BTSVEC+.BTCRS ;POINT TO BASE OF FILESPEC
	MOVE	T2,DEV		;DEVICE NAME
	MOVEM	T2,0(T1)
	MOVE	T2,FILNAM	;FILENAME
	MOVEM	T2,1(T1)
	HLLZ	T2,EXT		;GET EXTENSION
	MOVEM	T2,2(T1)
	MOVSI	T2,PTHBLK	;START OF PATH
	HRRI	T2,3(T1)	;MAKE A BLT POINTER
	BLT	T2,3+7-1(T1)	;COPY PATH
	JRST	CPOPJ1		;ALL DONE
	SUBTTL	RELOAD MONITOR


;ROUTINE TO RELOAD THE MONITOR FROM A FILE ON DISK.  CALL WITH
;THE FILESPEC FROM WHICH TO LOAD SETUP IN THE FILESPEC AREA.
;CALL:	PUSHJ	P,DOLOAD
;RETURN+1 IF ERRORS DETECTED WITH MESSAGE ALREADY ISSUED
;RETURN+2 IF LOAD WAS SUCCESSFUL

DOLOAD:	SKIPN	NXMFLG		;NXMTAB VALID?
	PUSHJ	P,SUNXMT	;MUST REBUILD IT
	PUSHJ	P,ZERCOR	;START OFF CLEAN BY ZEROING CORE
	PUSHJ	P,SSLCHK	;CHECK FOR THE SSL
	  SKIPA	P1,['DSKA  '-10000] ;GET DISK NAME TO INCREMENT TO DSKA
	MOVE	P1,T1		;GET PREDECREMENTED AOBJN POINTER
	MOVE	T1,[SIXBIT/SYSTEM/] ;DEFAULT FILENAME IS SYSTEM
	TRNE	S,FR.RBT	;UNLESS A /REBOOT REQUEST
	MOVE	T1,[SIXBIT/CRASH/] ;IN WHICH CASE FILENAME IS CRASH
	TRNN	S,FR.FIL	;SEE A FILENAME?
	MOVEM	T1,FILNAM	;NO, USE DEFAULT
	TLNN	S,(FL.WLD)	;WILD STR?
	JRST	DOLOA4		;NO, USE THE ONE HE GAVE
DOLOA1:	TRNE	S,FR.FRC	;/FORCE SEEN?
	JRST	DOLOA2		;YES
	AOBJP	P1,DOLOA5	;ADVANCE POINTER
	SKIPN	T1,(P1)		;GET A STRUCTURE NAME
	AOBJN	P1,.-1		;NONE THERE, TRY NEXT
	JUMPL	P1,DOLOA3	;JUMP IF HAVE A STRUCTURE NAME
	JRST	DOLOA5		;GIVE UP
DOLOA2:	CAMN	P1,[SIXBIT/DSKZ/] ;LOOKED AT THEM ALL?
	JRST	DOLOA5		;YES, GIVE UP
	ADDI	P1,10000	;STEP TO NEXT DISK NAME
	MOVE	T1,P1		;COPY STRUCTURE NAME
DOLOA3:	MOVEM	T1,DEV		;STORE STR NAME
DOLOA4:	PUSHJ	P,LOAD		;LOAD IT
	  JRST	LODERR		;GIVE ERROR MESSAGE AND RETURN
	JRST	CPOPJ1		;GIVE SKIP RETURN
DOLOA5:	MOVEI	T1,[ASCIZ/?No file found on any structure
/]
	PJRST	PRMSG		;GIVE ERROR MESSAGE AND RETURN
;ROUTINE TO LOAD A NEW MONITOR INTO CORE. CALL WITH THE FILESPEC AREA
;CONTAINING THE FILE TO BE LOADED.
;CALL:	PUSHJ	P,LOAD
;RETURN+1 IF ERROR DETECTED WITH ERROR CODE IN T1
;RETURN+2 IF SUCCESSFUL

LOAD:	PUSHJ	P,SAVE2		;SAVE P1-P2
	PUSHJ	P,FNDMON	;FIND THE MONITOR, READ EXE DIRECTORY
	  POPJ	P,		;FAILED, RETURN CODE IN T1
	TRNE	S,FR.RBT	;THIS A REBOOT?
	SKIPA	T1,[[ASCIZ/[Reloading from /]] ;YES, CHANGE THE MESSAGE
	MOVEI	T1,[ASCIZ/[Loading from /]
	PUSHJ	P,PRMSG		;TELL WHAT'S HAPPENING
	PUSHJ	P,PRFILE	;PRINT FILENAME
	PUSHJ	P,PRRBCR	;END THE LINE
	MOVEI	P3,0		;START WITH CORE ADDRESS OF ZERO
LOAD1:	LDB	P2,[POINT 9,1(P1),8] ;GET REPEAT COUNT FOR THIS ENTRY
	ADDI	P2,1		;MAKE IT TOTAL PAGE COUNT
	LSH	P2,P2BLSH	;COMPUTE BLOCK COUNT
	HRRZ	P4,0(P1)	;GET FILE PAGE NUMBER
	LSH	P4,P2BLSH	;COMPUTE FILE BLOCK NUMBER
	JUMPE	P4,[LSH  P2,B2WLSH ;IF ALLOCATED BUT ZERO PAGE, COMPUTE
		    ADD  P3,P2	;  NUMBER OF WORDS IN THIS DESCRIPTOR
		    JRST LOAD11]	;  UPDATE CORE ADDRESS AND DO NEXT ONE
	CAMGE	P4,BLKNUM	;PAGE NUMBERS IN THE EXE DIRECTORY MUST
	JRST	BDFERR		;  BE MONOTONICALLY INCREASING
LOAD2:	PUSHJ	P,POSFIL	;POSITION FILE TO THAT BLOCK
	  POPJ	P,		;HIT EOF
LOAD3:	HRRZ	P3,1(P1)	;GET CORE PAGE NUMBER
	LSH	P3,P2WLSH	;COMPUTE CORE ADDRESS
	JUMPN	P3,LOAD5	;GO IF NOT ZERO
	HRL	P4,P2		;REMEMBER NUMBER OF BLOCKS
	MOVEI	P2,PAGSIZ/BLKSIZ ;  AND READ ONE PAGE
LOAD4:	MOVEI	P3,PAGSIZ	;  STARTING AT 1000
LOAD5:	PUSHJ	P,LISTEN	;CHECK FOR CONTROL-C
	CAML	P3,BTTOP	;IS THERE ANY CHANCE OF HITTING BOOT?
	JRST	LOAD9		;NO, DON'T BOTHER ME
	CAML	P3,BTBOT	;YES, DO WE KNOW FOR SURE THAT IT WILL?
	JRST	LOAD6		;YES, HANDLE
	MOVE	T1,P2		;NO, COPY NUMBER OF BLOCKS TO TRANSFER
	LSH	T1,B2WLSH	;MAKE NUMBER OF WORDS
	ADD	T1,P3		;GET END+1 OF TRANSFER
	CAMG	T1,BTBOT	;WILL IT HIT BOOT?
	JRST	LOAD9		;NO, DON'T SWEAT IT
LOAD6:	TRNN	S,FR.RBT	;YES, ARE WE RELOADING A SLEEP DUMP?
	JRST	MEPERR		;NO, CAN'T DO IT
	CAML	P3,BTBOT	;ARE WE ABOUT TO CLOBBER BOOT?
	JRST	LOAD7		;YES, BE SELECTIVE
	MOVE	T1,BTBOT	;NO, GET START OF BOOT
	SUB	T1,P3		;FIND WORDS UNTIL BOOT
	LSH	T1,W2BLSH	;MAKE NUMBER OF BLOCKS
	SUB	P2,T1		;GET NUMBER OF BLOCKS TO CLOBBER
	MOVEM	P2,SCR		;SAVE REMAINDER
	MOVE	P2,T1		;COPY NUMBER OF 'SAFE' BLOCKS
	PUSHJ	P,REDBLK	;READ THEM IN
	  POPJ	P,		;PROPAGATE ERROR
	MOVE	P2,SCR		;GET REMAINING NUMBER TO TRANSFER
	JRST	LOAD5		;CHECK IT AGAIN
LOAD7:	MOVE	T1,P3		;YES, COPY PAGE NUMBER
	SUB	T1,BTBOT	;CONVERT TO OFFSET
	CAIL	T1,.BTSVB	;IS THIS IN THE RANGE
	CAIL	T1,.BTSVE	; THAT WE CARE ABOUT?
	JRST	LOAD8		;NO, DON'T BOTHER ME WITH IT
	PUSHJ	P,BLOAD		;YES, LOAD SCR WITH A BLOCK
	  POPJ	P,		;PROPAGATE FAILURE
	MOVE	T1,P3		;COPY PHYS. ADDRESS AGAIN
	SUB	T1,BTBOT	;CONVERT TO OFFSET
	MOVE	T2,T1		;COPY OFFSET
	MOVE	T3,T1		;AGAIN
	ANDI	T1,<BLKSIZ-1>	;KEEP OFFSET INTO BLOCK
	HRLI	T2,SCR(T1)	;GET SOURCE POINTER
	ADDI	T2,BTSVEC(T1)	;FORM XFER WORD
	MOVEI	T1,BTSVEC+BLKSIZ(T3) ;GET PRESUMED TERMINATION POINTER
	CAIGE	T3,.BTSVE	;UNLESS PARTIAL LAST BLOCK,
	MOVEI	T1,BTSVEC+.BTSVE ;THEN KEEP ONLY WHAT WE NEED
	BLT	T2,-1(T1)	;COPY THE DATA
				;FALL INTO LOAD8 TO TRY THE NEXT BLOCK

LOAD8:	ADDI	P3,BLKSIZ	;SKIPPING ONE BLOCK
	SOJE	P2,LOAD11	;TRY THE NEXT POINTER IF EXHAUSTED COUNT
	ADDI	P4,1		;NO, BUMP FILE BLOCK NUMBER
	PUSHJ	P,POSFIL	;GET THERE
	  POPJ	P,		;PROPAGATE ERROR
	JRST	LOAD5		;AND TRY ANOTHER BLOCK

LOAD9:	PUSHJ	P,REDBLK	;READ THE SPECIFIED BLOCKS
	  POPJ	P,		;FAILED
	HLRZ	P2,P4		;WERE WE READING 0-777
	JUMPE	P2,LOAD11	;  INTO 1000-1777?
	TRNN	S,FR.RBT	;DOING A REBOOT?
	JRST	LOAD10		;NO, CONTINUE
	SKIPN	.VPAG0+PAGSIZ+MBTCOM ;GET PAGE NUMBER OF COMM AREA
	JRST	NSSERR		;NOT A REBOOTABLE CRASH
IFN FTTAPE,<
	SKIPN	NOTAPE		;TAPE DRIVER CODE STILL PRESENT?
	PUSHJ	P,ZAPTAP	;DELETE IT NOW SO BOOT SIZE IS CORRECTED
> ;END IFN FTTAPE
	MOVE	T2,.VPAG0+PAGSIZ+MBTCOM ;GET PAGE NUMBER OF COMM AREA
	HLLZ	T1,T2		;GET -NUMBER OF PAGES IN LH
	HLLZ	T3,BTSVEC+.BTSIZ ;GET PAGES IN BOOT
	CAMLE	T1,T3		;MAKE SURE WE'LL FIT
	JRST	MCCERR		;COMPLAIN
	HRRZS	T3,T2		;CLEAR JUNK
	LSH	T3,P2WLSH	;CONVERT PAGE TO ADDRESS
	CAME	T3,.VPAG0+PAGSIZ+BOOTSA ;DOES IT MATCH THE BOOT ADDRESS?
	JUMPL	T1,NSSERR	;NO, CAN'T DO IT
	PUSHJ	P,MOVBTS	;MOVE US TO THOSE PAGES
	SKIPA	T1,[.VPAG0+PAGSIZ,,.VPAG0] ;SETUP TO BLT ENTIRE PAGE
LOAD10:	MOVE	T1,[.VPAG0+PAGSIZ+40,,.VPAG0+40] ;SETUP TO BLT 40-777
	BLT	T1,.VPAG0+PAGSIZ-1 ;MOVE THEM TO WHERE THEY BELONG
	HRRZS	P4		;CLEAR FLAG
	SUBI	P2,PAGSIZ/BLKSIZ ;COMPENSATE FOR WHAT WE READ
	JUMPG	P2,LOAD4	;DO THE REST IF MORE
LOAD11:	AOBJP	P1,.+1		;SKIP PAST FIRST OF 2 WORDS
	AOBJN	P1,LOAD1	;AND DO NEXT DESCRIPTOR
	JRST	CPOPJ1		;GIVE SKIP RETURN

BLOAD:	PUSHJ	P,SAVE4		;PRESERVE THESE FOR LATER
	MOVEI	P2,1		;ONLY READ ONE BLOCK
	MOVEI	P3,SCR-BTSVEC	;OFFSET TO SCRATCH BUFFER
	ADD	P3,BTBOT	;PHYSICAL ADDRESS FOR READ
	PJRST	REDBLK		;DO THE READ & PROPAGATE ITS RETURN
	SUBTTL	PARITY ERROR PAGE REPLACEMENT

;ROUTINE TO REPLACE A MONITOR HIGH SEGMENT PAGE FROM THE DISK COPY
;OF THE MONITOR ON PARITY ERRORS, ETC.
;CALL:
;	SUBDAT+0/EXEC VIRTUAL PAGE NUMBER
;	SUBDAT+1/PHYSICAL ADDRESS OF START OF THAT PAGE
;	PUSHJ	P,PGFUNC
;RETURN +1 ALWAYS, WITH PAGE REPLACED OR ERRFLG LIT

PGFUNC:	SKIPN	BTSVEC+.BTDEV	;DO WE KNOW WHERE TO FIND THE MONITOR?
	JRST	PGFUN3		;NO, COMPLAIN
	DMOVE	P2,SUBDAT	;YES, GET OUR ARGUMENTS
	SKIPE	P2		;IF EITHER THE PAGE NUMBER
	SKIPN	P3		;OR THE DESTINATION IS ZERO,
	JRST	PGFUN4		;WHINE
	MOVE	T1,[BTSVEC+.BTDEV,,DEV]
	BLT	T1,PTHBLK+6	;COPY THE MONITOR FILESPEC
	MOVEI	S,FR.DEV!FR.FIL!FR.EXT!FR.PTH ;WE HAVE EVERYTHING
	PUSHJ	P,FNDMON	;FIND FILE CONTAINING THE MONITOR
	  JRST	PGFUN5		;FAILED
	DMOVE	P2,SUBDAT	;GET ARGUMENTS AGAIN
PGFUN1:	HRRZ	P4,0(P1)	;GET FILE PAGE NUMBER OF NEXT DESCRIPTOR
	JUMPE	P4,PGFUN2	;NO GOOD IF ALLOCATED BUT ZERO PAGE
	HRRZ	T1,1(P1)	;GET CORE PAGE NUMBER OF DESCRIPTOR
	LDB	T2,[POINT 9,1(P1),8]  ;  AND REPEAT COUNT
	ADD	T2,T1		;CALCULATE LAST PAGE IN THIS DESCRIPTOR
	CAML	P2,T1		;IS DESIRED PAGE DESCRIBED BY
	CAMLE	P2,T2		;  THIS DESCRIPTOR?
	JRST	PGFUN2		;NO, CONTINUE
	SUB	P2,T1		;COMPUTE RELATIVE OFFSET OF DESIRED PAGE
	ADD	P4,P2		;AND FILE PAGE CONTAINING IT
	LSH	P4,P2BLSH	;COMPUTE FILE BLOCK NUMBER
	PUSHJ	P,POSFIL	;POSITION FILE TO THAT BLOCK
	  JRST	PGFUN5		;HIT EOF
	MOVEI	P2,PAGSIZ/BLKSIZ ;NUMBER OF BLOCKS TO TRANSFER
	PUSHJ	P,REDBLK	;READ PAGE INTO CORE
	  JRST	PGFUN5		;FAILED
	POPJ	P,		;RETURN WITH ERRFLG CLEAR (WINNITUDE)
PGFUN2:	AOBJP	P1,.+1		;LOOP FOR ALL DESCRIPTORS
	AOBJN	P1,PGFUN1	;WHICH ARE 2 WORDS LONG
	MOVEI	T1,[ASCIZ /% Can't find requested page in /]
	JRST	PGFUN6		;COMPLAIN ABOUT MISSING PAGE

PGFUN3:	MOVEI	T1,[ASCIZ /
? BOOT error; no saved monitor filespec
/]
	TRNA			;SKIP INTO FOLLOWING
PGFUN4:	MOVEI	T1,[ASCIZ /
? BOOT error; can't replace page zero
/]
	SETOM	ERRFLG		;RETURN ERROR TO TOP LEVEL
	PJRST	PRMSG		;TYPE TEXT AND RETURN
PGFUN5:	HRRZ	T1,EMSTAB(T1)	;CONVERT ERROR CODE TO STRING
PGFUN6:	PUSHJ	P,PRMSG		;TYPE THE ERROR TEXT
	PUSHJ	P,PRFILE	;AND THE FILESPEC
	PUSHJ	P,PRCRLF	;END THE LINE
	SETOM	ERRFLG		;RETURN BADNESS
	POPJ	P,		;GIVE UP
	SUBTTL	FILE SEARCH SUBROUTINES


;ROUTINE TO FIND THE FILE CONTAINING THE MONITOR SPECIFIED IN THE
;FILESPEC AREA, READ THE EXE DIRECTORY INTO BUF AND SETUP TO READ
;THE FILE.
;CALL:	PUSHJ	P,FNDMON
;RETURN+1 IF FAILED WITH ERROR CODE IN T1
;RETURN+2 IF SUCCESSFUL WITH
; P1/AOBJN POINTER TO EXE DIRECTORY DESCRIPTORS
;DESTROYS P3-P4
;FOR TAPES WE BRANCH TO SCAN TO SEARCH THE TAPE FOR THE T$FIL RECORD
;FOR THE DESIRED FILE, READ THE BLOCK CONTAINING THE DIRECTORY AND BLT
;THE DIRECTORY INTO BUF, THEN REJOIN THE CODE AT FNDMOE.

FNDMON:
IFN FTTAPE,<
	SKIPE	TAPIDX		;TAPE I/O?
	JRST	TAPSCN		;YES, SEARCH THE TAPE FOR T$FIL RECORD
>; END IFN FTTAPE
	PUSHJ	P,FNDFIL	;FIND THE FILE
	  POPJ	P,		;FILE NOT FOUND
	PUSHJ	P,REDBUF	;READ 1ST BLOCK OF EXE DIRECTORY
	  POPJ	P,		;FAILED
FNDMOE:	HLRZ	T1,BUF		;GET CODE
	HRRZ	P1,BUF		;AND LENGTH OF DIRECTORY
	CAIN	T1,.SVDIR	;THIS AN EXE FILE?
	CAILE	P1,BLKSIZ-1	;AND NOT TOO LONG?
	JRST	BDFERR		;NO, BAD DIRECTORY FORMAT
	MOVNI	P1,-1(P1)	;BUILD -VE COUNT FOR AOBJN POINTER
	HRLI	P1,BUF+1	;AND FIRST WORD
	MOVSS	P1		;MAKE IT AN AOBJN POINTER TO BUF
	JRST	CPOPJ1		;GIVE SKIP RETURN
;ROUTINE TO FIND A FILE AND SETUP ITS RIB IN RIB.  CALL WITH
;FILESPEC AREA SETUP.
;CALL:	PUSHJ	P,FNDFIL
;RETURN+1 IF NOT FOUND OR READ ERROR ON DIRECTORY WITH CODE IN T1
;RETURN+2 IF FILE FOUND
;DESTROYS P3-P4

FNDFIL:	PUSHJ	P,LISTEN	;CHECK FOR CONTROL-C
	TLZ	S,(FL.FFL)	;HAVEN'T FOUND FILE YET
	PUSHJ	P,SAVE2		;SAVE P1-P2
	PUSHJ	P,FNDMFD	;FIND THE MFD
	  JRST	SNTERR		;FAILED
	MOVEI	P1,0		;SETUP LOOP POINTER TO PTHBLK
FNDFI1:	PUSHJ	P,LISTEN	;CHECK FOR CONTROL-C
	SKIPN	P3,PTHBLK(P1)	;GET NEXT UFD/SFD FROM PATH BLOCK
	MOVE	P3,FILNAM	;FOUND END, USE FILENAME
	MOVEI	P4,'UFD'	;ASSUME EXTENSION IS UFD
	JUMPE	P1,FNDFI2	;GO IF CORRECT
	MOVEI	P4,'SFD'	;ASSUME SFD
	SKIPN	PTHBLK(P1)	;DONE WITH PATH BLOCK?
	HLRZ	P4,EXT		;YES, USE REAL EXTENSION
FNDFI2:	PUSHJ	P,SRCHFD	;SEARCH THE DIRECTORY
	  JRST	FNTERR		;FILE NOT FOUND
	PUSH	P,T2		;SAVE BLOCK IN UNIT OF RIB
	PUSHJ	P,FNDLUN	;FIND SPECIFIED UNIT
	  JRST	[POP	P,(P)	;FLUSH STACK
		 JRST	SNTERR]	;GIVE ERROR CODE AND RETURN
	POP	P,F		;RESTORE BLOCK OF RIB
	PUSHJ	P,REDRBP	;READ THE RIB OF THE FILE
	  JRST	FNTERR		;FAILED
	SKIPE	PTHBLK(P1)	;FOUND UFD, ALL SFD'S AND FILE?
	AOJA	P1,FNDFI1	;NO, TRY NEXT LEVEL
	TLO	S,(FL.FFL)	;INDICATE THAT WE FOUND THE FILE
	JRST	CPOPJ1		;GIVE SKIP RETURN, RIB SETUP
;ROUTINE TO FIND THE MFD FOR A STRUCTURE.  CALL WITH DEV CONTAINING
;THE STRUCTURE NAME.
;CALL:	PUSHJ	P,FNDMFD
;RETURN+1 IF FAILED
;RETURN+2 IF FOUND WITH MFD RIB IN RIB
;DESTOYS P3-P4

FNDMFD:	SETZM	LUNPOS		;FIND UNIT ZERO OF STRUCTURE
	PUSHJ	P,FNDUNI	;FIND IT
	  POPJ	P,		;FAILED, GIVE UP
	MOVE	T1,HOM+HOMMFD	;GET BLOCK IN STR CONTAINING MFD RIB
	MOVE	T2,HOM+HOMBSC	;GET BLOCKS/SUPERCLUSTER
	IMUL	T2,HOM+HOMSCU	;TIME SUPERCLUSTERS/UNIT
	IDIV	T1,T2		;T1=UNIT, T2=BLOCK IN UNIT OF RIB
	PUSH	P,T2		;SAVE BLOCK NUMBER
	JUMPE	T1,FNDMF1	;GO IF ON UNIT ZERO
	MOVEM	T1,LUNPOS	;STORE UNIT
	PUSHJ	P,FNDUNI	;FIND UNIT
	  JRST	TPOPJ		;FAILED
FNDMF1:	POP	P,F		;RESTORE BLOCK IN UNIT
	MOVE	P3,[1,,1]	;FILENAME IS [1,,1]
	MOVEI	P4,'UFD'	;EXTENSION IS UFD
	PJRST	REDRBP		;READ RIB OF MFD AND RETURN


;ROUTINE TO SEARCH A UFD OR SFD FOR A FILE.  CALL WITH RIB SETUP
;IN RIB.
;CALL:
;	P3/FILENAME,	P4/0,,EXTENSION
;	PUSHJ	P,SRCHFD
;RETURN+1 IF FILE NOT FOUND
;RETURN+2 IF FOUND
;RETURNS T1=UNIT IN STR, T2=BLOCK IN UNIT OF RIB FOR FILE.

SRCHFD:	PUSHJ	P,REDBUF	;READ THE NEXT BLOCK OF THE DIRECTORY
	  POPJ	P,		;EOF OR READ ERROR
	MOVSI	T1,-BLKSIZ	;BUILD AOBJN POINTER TO BLOCK
SRCHF1:	HLRZ	T2,BUF+1(T1)	;GET EXTENSION
	CAMN	P3,BUF(T1)	;FILENAMES MATCH?
	CAME	P4,T2		;YES, EXTENSIONS MATCH?
	AOBJN	T1,.+2		;NO, INCREMENT PAST FILENAME
	JRST	SRCHF2		;YES
	AOBJN	T1,SRCHF1	;LOOP FOR ALL OF THIS BLOCK
	JRST	SRCHFD		;TRY NEXT BLOCK
SRCHF2:	HRRZ	T1,BUF+1(T1)	;GET CFP FROM DIRECTORY
	IDIV	T1,HOM+HOMSCU	;T1=UNIT, T2=SUPERCLUSTER IN UNIT
	IMUL	T2,HOM+HOMBSC	;T2=BLOCK IN UNIT
	JRST	CPOPJ1		;GIVE SKIP RETURN
	SUBTTL	BLOCK READ/WRITE SUBROUTINES


;ROUTINE TO WRITE BUF/RIB TO THE OUTPUT FILE.  CALL WITH RIB OF FILE
;SETUP.
;CALL:	PUSHJ	P,WRTBUF  -OR-  PUSHJ P,WRTRIB
;RETURN+1 IF ERROR DETECTED WITH ERROR CODE IN T1
;RETURN+2 IF SUCCESSFUL

WRTRIB:	MOVEI	R,RIB		;POINT TO RIB
	AOS	SAVSIZ		;COMPENSATE FOR SELBLK DECREMENTING SAVSIZ
	TLZA	S,(FL.RIB)	;FORCE SELBLK TO WRITE THE RIB
WRTBUF:	MOVEI	R,BUF		;POINT TO BUF
	MOVEI	T1,1		;NUMBER OF BLOCKS IS 1
	PUSHJ	P,SELBLK	;SETUP TO DO THAT MANY
	  JRST	EOFERR		;FILE MUST BE REALLY SCREWED UP
	JUMPN	T1,EOFERR	;DITTO
	PUSHJ	P,VRTWRT	;WRITE THE BLOCK
	  JRST	IOFERR		;WRITE ERROR
	JRST	CPOPJ1		;GIVE SKIP RETURN


;ROUTINE TO READ ONE BLOCK FROM THE INPUT FILE INTO BUF.  CALL WITH
;RIB OF FILE SETUP.
;CALL:	PUSHJ	P,REDBUF
;RETURN+1 IF ERROR DETECTED WITH ERROR CODE IN T1
;RETURN+2 IF SUCCESSFUL

REDBUF:	MOVEI	R,BUF		;POINT TO BUF
	MOVEI	T1,1		;NUMBER OF BLOCKS IS 1
	PUSHJ	P,SELBLK	;SETUP TO READ
	  JRST	EOFERR		;HIT EOF
	JUMPN	T1,EOFERR	;DITTO
	PUSHJ	P,VRTRED	;READ THE BLOCK
	  JRST	IOFERR		;READ ERROR
	JRST	CPOPJ1		;GIVE SKIP RETURN
;ROUTINE TO POSITION AN EXE FILE SO THAT THE NEXT READ WILL READ
;THE BLOCKS THAT WE WANT.
;CALL:
;	P4/DESIRED BLOCK IN FILE
;	PUSHJ	P,POSFIL
;RETURN+1 IF EOF ENCOUNTERED WITH ERROR CODE IN T1
;RETURN+2 WITH FILE POSITIONED CORRECTLY

POSFIL:	CAMN	P4,BLKNUM	;AT THE RIGHT BLOCK IN THE FILE NOW?
	JRST	CPOPJ1		;YES, GIVE SKIP RETURN
	MOVEI	T1,1		;DO ONE BLOCK
	PUSHJ	P,SELBLK	;USETI .+1
	  JRST	EOFERR		;CANNOT HAVE EOF HERE
	JRST	POSFIL		;TRY AGAIN


;ROUTINE TO READ ONE OR MORE BLOCKS FROM AN EXE FILE.
;CALL:	P2/NUMBER OF BLOCKS TO READ
;	P3/CORE ADDRESS OF WHERE TO READ FIRST BLOCK
;	P4/FILE BLOCK NUMBER OF FIRST BLOCK
;	PUSHJ	P,REDBLK
;RETURN+1 IF ERROR WITH ERROR CODE IN T1
;RETURN+2 IF SUCCESSFUL WITH P3 AND P4 UPDATED TO REFLECT THE TRANSFER

REDBLK:
IFN FTTAPE,<
	SKIPE	TAPIDX		;TAPE I/O
	PJRST	REDTAP		;YES, DO IT OVER THERE
>; END IFN FTTAPE
REDBL1:	JUMPLE	P2,CPOPJ1	;READ ALL BLOCKS YET?
	MOVE	T1,P2		;NO, GET NUMBER OF BLOCKS TO TRANSFER
	PUSHJ	P,SELBLK	;SETUP TO DO THAT MANY
	  JRST	EOFERR		;CAN'T HAVE EOF
	MOVE	R,P3		;PUT CORE ADDRESS IN R
	MOVE	P2,T1		;COPY BLOCKS WE COULDN'T DO FOR NEXT TIME
	ADD	P4,M		;INCREMENT FILE BLOCK NUMBER
	MOVE	T1,M		;GET NUMBER OF BLOCKS TO DO
	LSH	T1,B2WLSH	;CONVERT TO WORDS
	ADD	P3,T1		;UPDATE CORE ADDRESS
	PUSHJ	P,@REDTAB(W)	;READ THE SPECIFIED BLOCKS
	  JRST	IOFERR		;I/O ERROR
	JRST	REDBL1		;CONTINUE FOR ALL
;ROUTINE TO FIND A UNIT AND READ IT'S HOM BLOCK. CALL WITH LUNPOS
;CONTAINING THE LOGICAL UNIT NUMBER AND DEV CONTAINING THE DEVICE
;NAME.
;CALL:
;	T1/LOGICAL UNIT IN STRUCTURE
;	PUSHJ	P,FNDLUN
;RETURN+1 IF NOT FOUND
;RETURN+2 IF FOUND WITH HOM BLOCK IN HOM

FNDLUN:	EXCH	T1,LUNPOS	;STORE UNIT, GET CURRENT
	CAMN	T1,LUNPOS	;SAME AS CURRENT ONE?
	JRST	CPOPJ1		;YES, ALREADY THERE
;;	PJRST	FNDUNI		;FALL INTO FNDUNI


;ROUTINE TO FIND A UNIT BY EXHAUSTIVE SEARCH.  CALL WITH LUNPOS
;CONTAINING THE LOGICAL UNIT NUMBER IN THE STRUCTURE, DEV CONTAINING
;THE STRUCTURE NAME AND SDLPOS CONTAINING THE POSITION IN THE SYSTEM
;DUMP LIST.
;CALL:	PUSHJ	P,FNDUNI
;RETURN+1 IF NOT FOUND
;RETURN+2 IF FOUND WITH HOM BLOCK IN HOM

FNDUNI:	MOVSI	J,-DVCTBL	;AOBJN POINTER TO DEVICE CODE TABLE
FNDUN1:	MOVSI	U,-MAXUNI	;AOBJN POINTER FOR EACH UNIT
FNDUN2:	HLRZ	W,DVCTAB(J)	;SETUP TYPE OFFSET
	PUSHJ	P,SETIOT	;SETUP I/O INSTRUCTIONS
	PUSHJ	P,REDHOM	;READ HOM BLOCK FOR UNIT
	  JRST	FNDUN3		;FAILED OR BAD
	MOVE	T1,HOM+HOMLUN	;GET LOGICAL UNIT NUMBER OF THIS STR
	MOVE	T2,HOM+HOMSNM	;GET STR NAME
	CAMN	T1,LUNPOS	;UNIT NUMBER MATCH?
	CAME	T2,DEV		;YES, DOES IT?
	JRST	FNDUN3		;NO
	JRST	CPOPJ1		;YES, GIVE SKIP RETURN
FNDUN3:	AOBJN	U,FNDUN2	;LOOP FOR NEXT UNIT
	AOBJN	J,FNDUN1	;LOOP FOR NEXT CONTROLLER
	POPJ	P,		;ERROR RETURN
;ROUTINE TO READ A HOM BLOCK.
;CALL:
;	U/PHYSICAL UNIT NUMBER
;	J/OFFSET INTO DEVICE CODE TABLE
;	W/OFFSET INTO TYPE TABLES
;	PUSHJ	P,REDHOM
;RETURN+1 IF ERROR
;RETURN+2 IF SUCCESSFUL WITH HOM BLOCK IN HOM

REDHOM:	MOVEI	F,LBNHOM	;ADDRESS OF FIRST HOM BLOCK ON UNIT
REDHO1:	MOVEI	R,HOM		;ADDRESS OF WHERE TO PUT IT
	MOVEI	M,1		;READ 1 BLOCK
	PUSHJ	P,VRTRED	;READ THE BLOCK
	  JRST	REDHO2		;FAILED, TRY SECOND
	MOVS	T1,HOM+HOMNAM	;GET FIRST WORD OF BLOCK
	MOVE	T2,HOM+HOMCOD	;GET WORD CONTAINING UNLIKELY CODE
	CAIN	T1,'HOM'	;NAME MUST BE HOM
	CAIE	T2,CODHOM	;AND MUST MATCH UNLIKELY CODE
	JRST	REDHO2		;ONE FAILED
	CAMN	F,HOM+HOMSLF	;SELF POINTER MUST MATCH
	SKIPE	HOM+HOMREF	;AND MUST NOT NEED REFRESHING
	JRST	REDHO2		;FAILED
	MOVEI	T1,T4		;SETUP HOMCLP AND
	HRRM	T1,HOM+HOMCLP	;  HOMCNP TO POINT
	HRRM	T1,HOM+HOMCNP	;  TO T4
	JRST	CPOPJ1		;GIVE SKIP RETURN
REDHO2:	CAIE	F,LBNHOM	;DOING FIRST HOM BLOCK?
	POPJ	P,		;NO, GIVE FAIL RETURN
	MOVEI	F,LB2HOM	;GET ADDRESS OF 2ND
	JRST	REDHO1		;AND TRY THAT ONE
;ROUTINE TO READ A RIB.
;CALL:
;	U/PHYSICAL UNIT NUMBER
;	J/OFFSET INTO DEVICE CODE TABLE
;	W/OFFSET INTO TYPE TABLES
;	F/BLOCK IN UNIT
;	PUSHJ	P,REDRIB
;RETURN+1 IF READ OR RIB ERROR
;RETURN+2 IF SUCCESSFUL WITH RIB IN RIB
;CALL REDRBP IF FILENAME AND EXTENSION ALREADY IN P3,P4
;DESTROYS P3-P4

REDRIB:	MOVE	P3,FILNAM	;GET FILENAME
	HLRZ	P4,EXT		;AND EXT
REDRBP:	MOVEI	R,RIB		;ADDRESS OF WHERE TO READ IT
	MOVEI	M,1		;READ 1 BLOCK
	PUSHJ	P,VRTRED	;READ THE BLOCK
	  POPJ	P,		;FAILED
	MOVE	T1,RIB+RIBCOD	;GET WORD CONTAINING UNLIKELY CODE
	CAIN	T1,CODRIB	;MUST MATCH
	SKIPL	T1,RIB+RIBFIR	;POINTER MUST BE NEGATIVE
	POPJ	P,		;FAILED
	MOVEM	T1,SAVFIR	;SAVE FOR SELBLK
	MOVE	T1,RIB+RIBNAM	;GET FILENAME FROM RIB
	CAMN	T1,P3		;MATCH WITH WHAT WE WANT?
	CAME	F,RIB+RIBSLF	;SELF POINTER MUST MATCH
	POPJ	P,		;ELSE ERROR
	HLRZ	T1,RIB+RIBEXT	;GET EXTENSION FROM RIB
	MOVE	T2,PTHBLK	;GET PPN FROM PATH BLOCK
	CAIN	P4,'UFD'	;READING A UFD?
	MOVE	T2,[1,,1]	;YES, PPN IS 1,1
	CAMN	T1,P4		;EXTENSION MATCH?
	CAME	T2,RIB+RIBPPN	;  ALONG WITH PPN?
	POPJ	P,		;NO, ERROR
	TLO	S,(FL.RIB)	;TELL SELBLK THAT FIRST BLOCK IS A RIB
	SETOM	BLKCNT		;AND NO BLOCKS LEFT IN GROUP
	MOVE	T1,RIB+RIBSIZ	;GET RIBSIZ FROM RIB
	ADDI	T1,BLKSIZ-1	;ROUND UP TO A BLOCK
	LSH	T1,W2BLSH	;CONVERT TO BLOCKS
	TLZE	S,(FL.EXR)	;READING EXTENDED RIB?
	JRST	CPOPJ1		;YES, GIVE SKIP RETURN
	MOVEM	T1,SAVSIZ	;NO, SAVE SIZE FOR SELBLK
	SETZM	BLKNUM		;AND ZERO RELATIVE BLOCK IN FILE
	JRST	CPOPJ1		;AND GIVE SKIP RETURN
;ROUTINE TO SETUP A TRANSFER TO/FROM DISK.
;CALL:
;	T1/NUMBER OF BLOCKS DESIRED TO TRANSFER
;	PUSHJ	P,SELBLK
;RETURN+1 IF EOF DETECTED
;RETURN+2 IF SOME TRANSFER IS POSSIBLE
;RETURNS M/NUMBER OF BLOCKS POSSIBLE, T1/NUMBER OF BLOCKS IN REQUEST
;	 THAT COULDN'T BE TRANSFERED, F/BLOCK ON UNIT OF FIRST BLOCK.
;PRESERVES P3-P4

SELBLK:	TLNN	S,(FL.RIB)	;WANT TO SKIP FIRST RIB BLOCK?
	JRST	SELBL1		;NO
	PUSHJ	P,SAVE2		;SAVE P1-P2
	MOVE	P1,T1		;SAVE REQUESTED TRANSFER IN P1
	MOVEI	T1,1		;AND MAKE IT LOOK LIKE 1 BLOCK
SELBL1:	SKIPLE	BLKCNT		;AND MORE BLOCKS LEFT IN GROUP?
	JRST	SELBL4		;YES, USE THEM
SELBL2:	SKIPL	T2,SAVFIR	;RUN OUT OF POINTERS?
	JRST	SELBL5		;YES, CHECK FOR EXTENDED RIBS
	MOVE	T4,RIB(T2)	;GET NEXT POINTER
	AOBJN	T2,.+1		;INCREMENT POINTER TO POINTERS
	MOVEM	T2,SAVFIR	;STORE POINTER BACK
	LDB	T2,HOM+HOMCNP	;GET CLUSTER COUNT FROM THIS POINTER
	JUMPN	T2,SELBL3	;GO IF NON-ZERO
	TRZN	T4,RIPNUB	;UNIT CHANGE POINTER?
	POPJ	P,		;NO, THAT'S AN EOF POINTER
	PUSH	P,T1		;SAVE ARGUMENT
	MOVE	T1,T4		;COPY NEW UNIT NUMBER
	PUSHJ	P,FNDLUN	;FIND IT AND SETUP HOM BLOCK
	  JRST	TPOPJ		;NOT THERE, SIMULATE EOF
	POP	P,T1		;RESTORE ARGUMENT
	JRST	SELBL2		;TRY WITH NEXT POINTER
SELBL3:	IMUL	T2,HOM+HOMBPC	;COMPUTE NUMBER OF BLOCKS IN GROUP
	SKIPL	SAVFIR		;DOING LAST POINTER IN THIS RIB?
	SUBI	T2,1		;YES, DON'T OVERWRITE SPARE RIB
	TLNE	S,(FL.RIB)	;SKIPPING A RIB?
	AOS	SAVSIZ		;YES, FILE IS 1 MORE BLOCK LONG
	CAMLE	T2,SAVSIZ	;MORE THAN AMOUNT REMAINING IN FILE?
	MOVE	T2,SAVSIZ	;YES, USE THAT
	MOVEM	T2,BLKCNT	;STORE IT
	LDB	T2,HOM+HOMCLP	;GET CLUSTER ADDRESS OF 1ST CLUSTER IN GROUP
	IMUL	T2,HOM+HOMBPC	;COMPUTE BLOCK ADDRESS
	MOVEM	T2,BLKADR	;STORE ADDRESS OF BLOCK


				;CONTINUED ON THE NEXT PAGE
SELBL4:	MOVN	M,T1		;GET -VE NUMBER OF BLOCKS IN REQUEST
	SUB	T1,BLKCNT	;SUBTRACT AMOUNT LEFT IN GROUP
	SKIPLE	T1		;REQUEST LARGER THAN AMOUNT WE HAVE?
	MOVN	M,BLKCNT	;YES, USE WHAT WE HAVE
	ADDM	M,BLKCNT	;DECREASE BLKCNT BY APPROPRIATE AMOUNT
	ADDM	M,SAVSIZ	; AND SIZE OF FILE
	MOVNS	M		;SET M TO AMOUNT TO TRANSFER
	MOVE	F,BLKADR	;START AT THIS BLOCK
	ADDM	M,BLKADR	;INCREMENT BLOCK ADDRESS FOR NEXT CALL
	TLNN	S,(FL.RIB)	;SKIPING A RIB?
	ADDM	M,BLKNUM	;NO, UPDATE RELATIVE FILE BLOCK
	SKIPGE	T1		;CAN WE DO THE WHOLE REQUEST?
	MOVEI	T1,0		;YES, RETURN ZERO AS REMAINDER
	TLZN	S,(FL.RIB)	;SKIPPING 1 BLOCK FOR RIB?
	JRST	CPOPJ1		;NO, RETURN TO CALLER
	MOVE	T1,P1		;RESTORE ORIGINAL REQUEST
	JRST	SELBL1		;AND DO THE REAL REQUEST
SELBL5:	SKIPN	RIB+RIBXRA	;EXTENDED RIB POINTER?
	POPJ	P,		;NO, GIVE EOF RETURN
	PUSH	P,T1		;SAVE ARGUMENT
	PUSH	P,P3		;AND QUASI-PRESERVED REGISTERS
	PUSH	P,P4		;SMASHED BY REDRIB
	LDB	T1,DEYRBU	;GET UNIT ON WHICH NEXT RIB EXISTS
	PUSHJ	P,FNDLUN	;FIND UNIT, SETUP HOM BLOCK
	  JRST	SELBL6		;FAILED GIVE EOF RETURN
	LDB	F,DEYRBA	;GET CLUSTER ADDRESS ON THAT UNIT
	IMUL	F,HOM+HOMBPC	;CONVERT TO BLOCK ADDRESS
	TLO	S,(FL.EXR)	;DON'T CHANGE SAVSIZ FOR EXTENDED RIBS
	PUSHJ	P,REDRIB	;READ NEW RIB
	  JRST	SELBL6		;FAILED, GIVE EOF RETURN
	POP	P,P4		;RESTORE P4 AND
	POP	P,P3		;  P3
	POP	P,T1		;RESTORE ARGUMENT
	JRST	SELBLK		;AND TRY NEW POINTER FROM THIS RIB
SELBL6:	TLZ	S,(FL.EXR)	;MAKE SURE THIS FLAG IS OFF
	ADJSP	P,-3		;BRING STACK INTO SYNC
	POPJ	P,		;AND GIVE NON-SKIP RETURN
	SUBTTL	SUPPORT SUBROUTINES


;ROUTINE TO CLEAR BUF.
;CALL:	PUSHJ	P,CLRBUF	
;RETURN+1 ALWAYS

CLRBUF:	SETZM	BUF		;CLEAR FIRST WORD
	MOVE	T1,[BUF,,BUF+1]	;SETUP FOR BLT
	BLT	T1,BUF+BLKSIZ-1 ;CLEAR IT ALL
	POPJ	P,		;RETURN


;ROUTINE TO STORE A DEVICE CODE IN ALL I/O INSTRUCTIONS.
;CALL:
;	J/OFFSET INTO DEVICE CODE TABLE
;	PUSHJ	P,SETIOT
;OR (KL ONLY):
;	T1/DEVICE CODE
;	PUSHJ	P,SETIOC
;RETURN+1 ALWAYS

SETIOT:
IFN FTKL10,<
	HRRZ	T1,DVCTAB(J)	;GET DEVICE CODE
SETIOC:	MOVSI	T2,-IOTTBL	;BUILD AOBJN POINTER TO IOTTAB
	DPB	T1,[POINT 7,IOTTAB(T2),9] ;STORE DEVICE CODE IN INSTN.
	AOBJN	T2,.-1		;DO THEM ALL
>
	POPJ	P,		;RETURN


;RETURN POINTS TO SET T1 TO AN ERROR CODE AND NON-SKIP RETURN

ERRTAB:
SNTERR:	JSP	T1,ALLERR	;STRUCTURE NOT FOUND
FNTERR:	JSP	T1,ALLERR	;FILE NOT FOUND
UPDERR:	JSP	T1,ALLERR	;UNPROCESSED DUMP
EOFERR:	JSP	T1,ALLERR	;UNEXPECTED EOF
IOFERR:	JSP	T1,ALLERR	;I/O ERROR
BDFERR:	JSP	T1,ALLERR	;BAD DIRECTORY FORMAT
MCCERR:	JSP	T1,ALLERR	;MEM CONFIG TOO COMPLICATED
NSSERR:	JSP	T1,ALLERR	;NOT SYSTEM SLEEP DUMP
MEPERR:	JSP	T1,ALLERR	;MONITOR EXTENDS PAST BEGINNING OF BOOT
ERRTBL==.-ERRTAB
ALLERR:	SUBI	T1,ERRTAB+1	;COMPUTE ERROR CODE
	TLZ	T1,-1		;CLEAR LH JUNK
	POPJ	P,		;RETURN
;ROUTINE TO READ DATA INTO A VIRTUAL ADDRESS.
;CALL:
;	R/VIRTUAL ADDRESS
;	M/NUMBER OF BLOCKS TO TRANSFER
;	F/BLOCK ON UNIT
;	U/PHYSICAL UNIT
;	W/OFFSET INTO TYPE TABLE
;	J/OFFSET INTO DEVICE CODE TABLE
;	PUSHJ	P,VRTRED
;RETURN+1 IF ERROR
;RETURN+2 IF SUCCESSFUL

VRTRED:	PUSHJ	P,MAPADR	;CONVERT VIRTUAL TO PHYSICAL ADDRESS
	PJRST	@REDTAB(W)	;DO THE TRANSFER


;ROUTINE TO WRITE DATA FROM A VIRTUAL ADDRESS.  CALL WITH SAME ARGUMENTS
;AS VRTRED.
;CALL:	PUSHJ	P,VRTWRT
;RETURN+1 IF ERROR
;RETURN+2 IF SUCCESSFUL

VRTWRT:	PUSHJ	P,MAPADR	;CONVERT VIRTUAL TO PHYSICAL ADDRESS
	PJRST	@WRTTAB(W)	;DO THE TRANSFER


;ROUTINE TO CONVERT A VIRTUAL ADDRESS TO A PHYSICAL ADDRESS.
;CALL:
;	R/VIRTUAL ADDRESS
;	PUSHJ	P,MAPADR
;RETURN+1 ALWAYS WITH PHYSICAL ADDRESS IN R

MAPADR:	MAP	R,(R)		;CONVERT TO PHYSICAL ADDRESS
IFN FTKL10,<
	TLZ	R,(^-<LG.EPT*PAGSIZ+PAGSIZ-1>) ;KEEP ONLY ADDRESS
>
IFN FTKS10,<
	TLZ	R,(^-<SG.EPT*PAGSIZ+PAGSIZ-1>) ;KEEP ONLY ADDRESS
>
	POPJ	P,		;AND RETURN
;ROUTINE TO SAVE P1 AND P2 AND CALL THE CALLER AS A COROUTINE
;WHICH RESTORES P1 AND P2 WHEN THE CALLER RETURNS.
;CALL:	PUSHJ	P,SAVE2
;RETURN+1 ALWAYS

SAVE2:	EXCH	P1,(P)		;GET RETURN, SAVE P1
	PUSH	P,P2		;SAVE P2
	MOVEM	P1,1(P)		;SAVE RETURN
	MOVE	P1,-1(P)	;RESTORE P1
	PUSHJ	P,@1(P)		;CALL CALLER
	  CAIA			;NON SKIP
	AOS	-2(P)		;SKIP RET
	POP	P,P2		;RESTORE P2
	POP	P,P1		;RESTORE P1
	POPJ	P,		;RETURN


;ROUTINE TO SAVE P1-P4 AND CALL THE CALLER AS A COROUTINE
;WHICH RESTORES P1-P4 WHEN THE CALLER RETURNS.
;CALL:	PUSHJ	P,SAVE4
;RETURN+1 ALWAYS

SAVE4:	EXCH	P1,(P)		;GET RETURN, SAVE P1
	PUSH	P,P2		;SAVE P2
	PUSH	P,P3		;AND P3
	PUSH	P,P4		;AND EVEN P4
	MOVEM	P1,1(P)		;SAVE RETURN
	MOVE	P1,-3(P)	;RESTORE P1
	PUSHJ	P,@1(P)		;CALL CALLER
	  CAIA			;NON SKIP
	AOS	-4(P)		;SKIP RET
	DMOVE	P1,-3(P)	;RESTORE P1 AND P2
	DMOVE	P3,-1(P)	;RESTORE P3 AND P4
	ADJSP	P,-4		;TRIM STACK
	POPJ	P,		;RETURN


;ROUTINE TO SAVE F AND R AND CALL THE CALLER AS A COROUTINE
;WHICH RESTORES F AND R WHEN THE CALLER RETURNS.
;CALL:	PUSHJ	P,SAVFR
;RETURN+1 ALWAYS
SAVFR:	EXCH	F,(P)		;GET RETURN, SAVE F
	PUSH	P,R		;SAVE R
	MOVEM	F,1(P)		;SAVE RETURN
	MOVE	F,-1(P)		;RESTORE F
	PUSHJ	P,@1(P)		;CALL CALLER
	  CAIA			;NON SKIP
	AOS	-2(P)		;SKIP RET
	POP	P,R		;RESTORE R
	POP	P,F		;RESTORE F
	POPJ	P,		;RETURN
	SUBTTL	COPY ENTRY VECTOR DATA FROM PREVIOUS MONITOR


; ROUTINE TO CAUSE SSL, ASL, SDL, ETC. TO BE PRESERVED ACROSS
; MONITOR RELOADS.  DATA IS COPIED FROM THE PREVIOUS BOOT'S
; ENTRY VECTOR INTO OURS.  THIS DEPENDS ON PHYSICAL ADDRESS
; 20 CONTAINING THE ADDRESS OF THE OLD BOOT'S ENTRY VECTOR.

COPDAT:	SKIPN	P1,.VPAG0+BOOTSA ;GET VECTOR ADDRESS
	POPJ	P,		;OLD STYLE BOOTSTRAP
	LSH	P1,W2PLSH	;CONVERT TO A PAGE NUMBER
	PUSHJ	P,REFMEM	;MAKE SURE PAGE EXISTS
	  JFCL			;INTERLEAVING ERROR??
	  POPJ	P,		;NXM--CAN'T COPY DATA
	HRRM	P1,EPT+.MVECT	;MAKE PAGE ADDRESSABLE
	CLRPT	.VVECT		;FLUSH PAGE TABLE FOR VECTOR PAGE
	MOVEI	T1,.VVECT	;POINT TO OLD VECTOR
	MOVE	T2,BTSVEC+.BTNAM ;GET IDENTIFIER
	CAMN	T2,.BTNAM(T1)	;SAME?
	SKIPL	.BTSIZ(T1)	;-PAGE LENGTH SETUP?
	POPJ	P,		;NO
	SKIPN	T2,.BTSAV(T1)	;ANY SAVED DATA?
	POPJ	P,		;NO
	MOVSI	T3,.BTSVB(T1)	;POINT TO START OF SAVED DATA
	HRRI	T3,BTSVEC+.BTSVB ;DESTINATION ADDRESS
	BLT	T3,BTSVEC+.BTSVB-1(T2) ;COPY PRE