; LevBasic.asm -- must be loaded below its companion files in this level: 
;	InOutLd.asm, SwatResident.asm, ParityErrors.asm & UpdateTimer.asm
; Copyright Xerox Corporation 1979
; Last modified October 27, 1981  2:22 PM by Boggs

; outgoing statics
.ent LevBasic
.ent SerialNumber, AltoVersion
.ent OsVersion, OsVersionCompatible
.ent OsFinishCode, lvUserFinishProc, OsFinishSafeAdr
.ent UserName, UserPassword, EventVector, ErrorLogAddress
.ent CounterJunta, juntaTable
.ent OsFinish, SysErr
.ent pTopStatics

; incoming statics
.bext DiskIOSetup, DiskIOTransfer

lEventVector = 15.
lUserName = 10.
lUserPassword = 10.

nLevels = 14.		; number of Junta levels

fcOnceOnly = -10007.
fcAbort = 1

	.srel

; LevBasic is published to be at or above 175000b.
; That is, a Junta to levBasic frees 174777b and below.
; Mesa and Smalltalk both depend on this.
; Don't even THINK of changing it
LevBasic:		.LevBasic

; Use of the following two statics should be discouraged.
; They have gotten too many programs in trouble by being saved
;  in a core image, which was then fired up on a different
;  vintage Alto on the other side of the country.
SerialNumber:		-1
AltoVersion:		0

OsVersion:		.blk 1
OsVersionCompatible:	.blk 1
OsFinishCode:		fcOnceOnly
lvUserFinishProc:	.UFProc
OsFinishSafeAdr:	.blk 1
UserName:		.UserName
UserPassword:		.UserPassword
EventVector:		.EventVector
ErrorLogAddress:	.ErrorLogAddress
CounterJunta:		.CounterJunta
juntaTable:		.juntaTable
OsFinish:		.OsFinish

; SysErr is patched by BootInit to point at SysErrT (the true one) or
; at CallSwat if levBFSBase (where SysErrT lives) is not around.
SysErr:			0

; This static must be loaded at 176777, and gets filled in by once-only
; initialization with a pointer to the base of the top statics region.
pTopStatics:		0

	.nrel

.LevBasic:
		lEventVector
.EventVector:	.blk lEventVector
		lUserName
.UserName:	.blk lUserName
		lUserPassword
.UserPassword:	.blk lUserPassword
.ErrorLogAddress:3*400+5	; Net 3, host 5 (Maxc2)
		0
		30		; Alto error reports socket


NoCJ:	jsr @finishPC		; go off to operating system, never return
.UFProc: 0			; will be 0 by the time we get here

UpLoop:	mkzero 1 1		; zero UserFinishProc in case he doesn't
	sta 1 .UFProc
	jsr 0,3			; call procedure
	 1			; argument is finish code
	lda 0 @.OsFinishCode	; look again (he may have restored
				; another UFProc)
.OsFinish:			; come here with finish code in ac0
	sta 0 @.OsFinishCode	; save finish code
	lda 3 .UFProc
	sz 3 3			; check it
	 jmp UpLoop		; he has a procedure

	lda 2 finishAC2
	mkzero 0 0
.CounterJunta:
	sta 0 juntaReason	; 0=>Finish; else user proc.
	lda 3 juntaLevel	; pick up entry from junta table
	snz 3 3			; have we done a junta?
	 jmp NoCJ		; no, normal finish
	lda 0 1,3		; max addr to restore +1
	lda 1 c177400		; mask down
	and 1 0			; to even page number
	sta 0 lastPage		; base of final (partial) page 
	lda 0 juntaReturn	; first address to restore
	add 1 0			; back off for test in DKnxt
	sta 0 coreAddr		; first address

	jsr DKBlock		; get the control block
	mov 3 2			; its address goes in 2
	jsr juntaDL		; get the label for junta
	mov 3 1			; its address goes in 1
	lda 0 readD		; read command
	jsrii .DiskIOSetup	; go set it up.
	jsrii .DiskIOTransfer	; and transfer all pages....

	lda 3 juntaLevel	; pick up entry from junta table
	lda 1 1,3		; max addr to restore +1
	lda 3 lastPage		; base of final (partial) page
	sub 1 3			; 3=- number of words to move
	mkone 2 2
	sub 2 1			; last addr to load
	lda 0 @.osFinishSafeAddress ; from here
	sub 2 0			; source -1
	blt			; move last little bit.
; Now return to JuntaReturn in OS, which will set up its own stack.  
	jmp @juntaReturn	; place to go after junta

; incoming subroutines from InOutLd.asm:
.DiskIOSetup:	DiskIOSetup
.DiskIOTransfer: DiskIOTransfer

.OsFinishCode:	OsFinishCode
.osFinishSafeAddress: OsFinishSafeAdr
lastPage:	.blk 1
coreAddr:	.blk 1
c177400:	177400
readD:		44120		; check Header, check Label, read Data

DKBlock: jsr 0,3		; return address of work block
	.blk 2			; CUR,ALT
	.blk 22
	.blk 22			; 2 KCB's
	.blk 4			; try,t1,t2,t3
	77400			; Swat trap on error!
DKnxt:	lda 0 coreAddr		; previous core address
	lda 1 c177400
	sub 1 0			; advance to base of next page
	sta 0 coreAddr		; this is the one we are doing now
	lda 1 lastPage		; base of last (partial) page
	sleu 0 1		; already read that page?
	 jmp 0,3		; yes, all done
	sne 0 1			; now about to read that page?
	 lda 0 @.osFinishSafeAddress  ; yes, transfer data here instead
	jmp 1,3			; skip return to do more

;******************** J U N T A   T A B L E **********************************
juntaDL:	jsr 0,3
.juntaTable:	0		; vector of junta and finish goodies
		0		; label for junta file
		0
		0
		0
		0
		0
		0		; end of junta label

finishAC2:	0		; stack for regular finish
finishPC:	0		; and PC to go to.
juntaReason:	0		; 0 => finish, else user proc.
juntaLevel:	0		; pointer into current level
juntaReturn:	0		; -> JuntaReturn procedure
				; (also first address to restore--
				; must be on page boundary)
	nLevels			; number of junta levels
	.blk nLevels*2		; two words per level (level name, start addr)
;*****************************************************************************

	.end