/
/
/	MODULA Nucleus Release 02.00
/	Jeremy Holden
/	University of York
/	23 April 1977 
/
/	UNIX Assembler version
/	Ian Wand
/	12 September 1977
/
/       Modified to cope with the LSI11
/	Nigel Hawkins
/	20 December 1977
/
/       Code added for runtime checks
/       Loop to clear globals removed
/       ( VALUE is in release 2 compiler)
/       Ian Cottam
/       19 December 1978
/
/       Rewritten for KSOS
/       Luke C. Dion
/       Ford Aerospace & Communications Corporation
/       3939 Fabian Way
/       Palo Alto, Ca.
/       Beginning 6/1/79
/
/       SCCS Version 1.1 of 6/18/86
/
/
/ Assembly parameters
/
/
/
/	TRACE = 1		/ for performance analysis
	TRACE = 0		/ for no perfromance analysis
/
/       Assembly parameters ... all numbers in this file are octal!
/
	corend  = 17777776	/ end of physical memory - 2
/
	modpar  = 17772374      / stack par
	modpdr  = 17772334      / stack pdr
/
	tmppar	= modpar-2	/ temporary stack par
	tmppdr	= modpdr-2	/ temporary stack pdr
/
	dumtrp  = 40            / dummy device for TRAP handler
	dumcpu  = 44            / dummy device for cpu errors
	buserr	= 50		/ dummy device for bus errors
	cpureg  = 17777766      / cpu error register
/
	devcnt  = 40            / maximum number of device processes
/
	vecsiz  = 14            / size of interrupt template
	savsiz  = 10            / size of save area
/
	vvecsz  = 600           / size of interrupt vector template area 24
				/ = devcnt*vecsiz
	vsavsz  = 400           / size of interrupt vector save area 24
				/ = devcnt*savsiz
/
	modsiz  = 1400		/ size of modula stack area - in blocks
	stkadr	= 160000	/ stack address for all processes
/
/
/
/
	.data
	<@(#)nuc.s	1.1\0>
	.even
/
/
	.text
/
/ System parameters
/
	ps	= 177776		/ Processor status
/
/
/
/ Machine instructions not defined in UNIX Assembler
/
	halt	= 0
	wait    = 1
	rti	= 2
	reset	= 5
	spl0    = 230
	spl7    = 237
	mfpi    = 6500^tst
	mtpi    = 6600^tst
/
/ Process descriptor offsets
/
	tpp     = r4                    / temporary process pointer
	pp	= r5			/ Process pointer
	p.sp    = 0                     / Process SP
	p.par   = 2                     / Process stack page par
	p.pdr   = 4                     / Process stack page pdr
	p.sc	= 6			/ Signal chain
	p.rank  = 10                    / Process rank
	p.veca  = 12                    / vector save area address device
	p.dom   = 12                    / non-Kernel domain if nonzero ordin
/
/       Interrupt Vector offsets
/
	v.sp    = 0                     / interrupted process sp
	v.par   = 2                     / interrupted process par
	v.pdr   = 4                     / interrupted process pdr
	v.pd    = 6                     / device process PD
	.text
/
/
	.globl	subs
	.globl	case
	.globl	nucl
	.globl	dcal
	.globl	pcal
	.globl	doio
	.globl	dexi
	.globl	pexi
	.globl	kerout
	.globl	p.dom
	.globl	idlept			/ label of idle point
/
/
/ Error stops
/
subs:	mov	r0,r1		/ save line number
	mov	$177770,r0	/ halt value
	jbr	stop		/ halt
/
case:	mov	r0,r1			/ save line number
	mov	$177767,r0		/ halt value
	jbr	stop			/ halt
/
/
/ Nucleus entry point
/
nucl:	clr     *$ps                    / clear ps
	spl7                            / set processor level 7
	mov     $tmpstk,sp              / move a(temp stack) into sp
/
	clr     baseis                  / base I-space block number
/
/
	mov     $_etext,r0              / get adr( end of text )
	dec     r0                      / rounding
	ash     $-6,r0                  / divide by 64 to get block count
	bic     $176000,r0              / mask off sign bit extension
	inc     r0                      / round up
	mov     r0,baseds               / base D-space block number
/
	mov     $_end,r1                / get adr( end of data )
	dec     r1                      / rounding
	ash     $-6,r1                  / divide by 64 to get block count
	bic     $176000,r1              / mask off sign bit extension
	inc     r1                      / round up
	add     r0,r1                   / add in base D-space block number
	mov     r1,begmod               / end of Kernel D-space block number
/
	mov	$typcpu,(sp)		/
	jsr	pc,cputyp		/ get cpu type for cpu error handling
/
	mov     $nxtppt,(sp)            /
	jsr     pc,adrppt               / adr( ppt )
/
	mov     $pptsiz,(sp)            /
	jsr     pc,sizppt               / size( ppt_entry )
/
	mov     $pptnum,(sp)            /
	jsr     pc,numppt               / number( ppt entries )
/
	mov     nxtppt,pp               / initial process PD
/
	mov     $botvec,vecbot          / save bottom of vector area
	mov	$botsav,savbot		/ save bottom of vector save area
	mov     $devcnt,vecall          / maximum number of device processes
/
	mov     begmod,r0               / beginning of modula stack area
	add     $modsiz,r0              / size of modula stack area
	mov	r0,endmod		/ top of stack area
/
	mov     r0,-(sp)                / end of Kernel
	jsr     pc,setend               / set end of Kernel memory
	mov	(sp)+,r0		/ pop
/
	mov	$gdyn,r1		/ get initial process stack size
	add	$100,r1			/ safety gap
	ash	$-6,r1			/ divided by 64 gives memory blocks
	inc	r1			/ add one for round up
	sub     r1,endmod		/ sub initial process stack size 
/
	sub	$200,r0			/ actual par
	mov     r0,*$modpar             / initial process par
	mov     r0,p.par(pp)            / save par
	mov	$100016,r0		/ base pdr
	ash	$8,r1			/ shift left 8 bits
	sub	r1,r0			/ actual pdr
	mov     r0,*$modpdr             / initial process pdr
	mov     r0,p.pdr(pp)            / save pdr
	mov     $stkadr,sp              / new stack pointer
/
/
	mov     $400,r0                 / highest interrupt vector allowed
1:      mov     $340,-(r0)              / unsolicited interrupt handler ps
	mov     $unsol,-(r0)            / unsolicited interrupt handler pc
	tst     r0                      / subtract from pointer
	jhi     1b                      / on > 0
/
	mov     $cpuerr,*$04            / set up cpu error handler
	mov     $pwrfl,*$24             / set up temporary power fail
	mov     $signl,*$34             / set up signal software trap
/
	clr	ready			/ init ready pointer
	clr	last			/ init last pointer
	clr	lastk			/ init lastk pointer
/
	clr	*$ps			/ Just in case.
	jmp	init			/ Enter program
/
/
/       Signal operations:      trap    0-3
/
signl:  bit     $30000,*$ps             / signal handling - from kernel?
	beq     1f                      / yes
	jmp     *dumtrp                 / no - fake interrupt from dummy
/
1:      mov     r2,-(sp)                / save r2
	mov     2(sp),r2                / get interrupted pc
	dec     r2                      / decrement r2 by 2
	dec     r2
	mfpi    (r2)                    / get word from previous i-space
	mov     (sp)+,r2                / get word
	bic     $177400,r2              / mask off high bite
	jeq     send                    / ordinary send
	dec     r2                      / decrement
	jeq     waitop                  / ordinary wait
	dec     r2                      / decrement
	jeq     dsen                    / device send
	dec     r2                      / decrement
	jeq     dwai                    / device wait
	dec     r2                      / decrement
	jeq     hstop                   / halt instruction
/
/       incorrect signal operation
	mov     $177777,r0              / halt value
stop:   
	mov	sp,tmpstk		/ save old sp
	mov	$tmpstk,sp		/ set up temporary stack
	mov	r0,-(sp)		/ put r0 onto stack
	mov	r1,-(sp)		/ put r1 onto stack
	jsr	pc,nucprt		/ print out message
	mov	(sp)+,r1		/ pop r1 from stack
	mov	(sp)+,r0		/ pop r0 from stack
	halt                            / halt on incorrect signal
/
hstop:  mov     r0,r1                   / save r0
	mov     $177773,r0              / halt value
	br      stop                    / stop
/
cpuerr: tst	typcpu			/ cputype = 11/70 ?
	beq	2f			/ no - 11/45
/
	bit	$20,*$cpureg		/ bus error?
	jne	*buserr			/ yes
/
	bit     $14,*$cpureg            / stack violations?
	beq     1f                      / no
/
2:	bit     $30000,*$177776		/ from Kernel ?
	bne     1f                      / no
/
	tst	typcpu			/ cputype = 11/70 ?
	bne	2f			/ yes
/
	jmp	*buserr			/ jump to bus error
/
2:	mov     $177776,r0              / halt value			
	jbr     stop                    / RED/YELLOW ZONE
/
1:      jmp     *dumcpu                 / jump to cpuerror process
/
/
pwrfl:  mov     $177775,r0              / powerfail handling
	jbr     stop                    / halt processor
/
unsol:                                  / unsolicited interrupt
/
	rti                             / no-op for now
/
/
/ Call device process:
/	R0 = start address
/	R1 = stack size
/       R2 = number of bytes in params
/ Calling sequence:
/	JSR	PC, DCAL
/
/       push pd address onto the device process' stack
/               used by doio,dwai and dexi
/
dcal:   mov     (sp),-(sp)              / save pc
	mov     *$ps,2(sp)              / save ps for contx
	mov     r2,-(sp)                / save byte count of params
	jsr     pc,callpd               / do common work
/
	mov	p.par(tpp),*$modpar	/ set stack par
	mov     p.pdr(tpp),*$modpdr     / set stack pdr
	mov     (tpp),r1                / get stack pointer
	clr	-(r1)			/ save area for doio
	mov     tpp,-(r1)               / push adr(pd)
	clr     -(r1)                   / PS
	mov     r0,-(r1)                / PC
	mov     r1,(tpp)                / save new sp
/
	mov     p.par(pp),*$modpar      / set old par
	mov     p.pdr(pp),*$modpdr      / set old pdr
/
	dec     p.rank(tpp)             / mark as device process
/
	dec     vecall                  / decrement vector remaining count
	bne     1f
	mov	$177772,r0		/ halt value
	jbr	stop			/ halt
/
1:      mov     vecbot,r0               / get vector address
/
	mov     savbot,r1               / get vector save area
	mov     r1,p.veca(tpp)          / save save area adr
	mov     tpp,v.pd(r1)            / save pd in vec save area
/
/   Register 0 to be used by the initialization portion of device process.
/
	add     $savsiz,savbot          / add save area size
	add     $vecsiz,vecbot          / add vector size
/
	mov     tpp,r1                  / put PD into r1
	mov     (sp)+,r2                / restore byte count of params
	jsr     pc,adjust               / adjust SP
	jbr     dcon                    / Enter the process
/
/ Call ordinary process
/	R0 = start address
/	R1 = stack size
/       R2 = number of bytes in params
/ Calling sequence
/	JSR	PC, PCAL
/
pcal:   mov     (sp),-(sp)              / save pc
	mov     *$ps,2(sp)              / save ps for contx
	mov     r2,-(sp)                / save number of bytes in params
	jsr     pc,callpd               / do common work
/
	clr     p.dom(tpp)              / set Kernel domain
/
	mov     p.par(tpp),*$modpar     / set stack par
	mov     p.pdr(tpp),*$modpdr     / set stack pdr
	mov     (tpp),r1                / set stack pointer
	clr     -(r1)                   / PS
	mov     r0,-(r1)                / PC
	mov     r1,(tpp)                / save new sp
/
	mov     p.par(pp),*$modpar      / set old par
	mov     p.pdr(pp),*$modpdr      / set old pdr
/
/
	mov     tpp,r1                  / put PD into r1
	jsr     pc,insert               / place in queue
	mov     (sp)+,r2                / restore byte count of params
	jsr     pc,adjust               / adjust SP
	jmp     cont                    / Start process
/
/       callpd: sets up process stack
/
callpd: dec	pptnum			/ one less process available
	bne	1f			/ still one left
/
	mov	$177771,r0		/ halt value
	jbr	stop			/ halt
/
1:	add     pptsiz,nxtppt		/ get new one
	mov     nxtppt,tpp              / get last PD address
/
	mov     $stkadr,(tpp)           / set sp
/
	add     $100,r1                 / safety gap
	ash     $-6,r1                  / divide by 64 for # blocks
	inc     r1                      / add one
/
	mov     endmod,r3               / get end of stack area
	sub     r1,endmod               / set new end of stack area
	cmp     begmod,endmod           / out of space?
	jlo     1f                      / yes
	mov     $177774,r0              / halt value
	jbr     stop                    / halt processor
/
1:      sub     $200,r3                 / real par
	mov     r3,p.par(tpp)           / save par
/
	sub     $200,r1                 / complement of length for downward
	neg     r1                      / need positive number
	ash     $8,r1                   / shift over for plf of pdr
	bis     $16,r1                  / add downward and read-write
	mov     r1,p.pdr(tpp)           / save pdr
/
	spl7                            / raise processor priority
	tst     r2                      / any params
	beq     callex                  / no
/
	mov     tmppar,-(sp)            / save old par
	mov     tmppdr,-(sp)            / save old pdr
/
	mov     r1,tmppdr               / save new pdr
	mov     r3,tmppar               / save new par
/
	mov     $stkadr-20000,r1        / get adjusted stack pointer
	mov     r2,r3                   / get number of bytes in params
	add     sp,r3                   / add in stack pointer
	add     $14,r3                  / 14(sp) = bottom of params
	asr     r2                      / shift right = number of words
/
1:      mov     -(r3),-(r1)             / move word
	dec     r2                      / one less word
	bgt     1b                      / >0 -> not done
/
	add     $20000,r1               / re-adjust new sp
	mov     r1,(tpp)                / save in PD
/
	mov     (sp)+,tmppdr            / restore pdr
	mov     (sp)+,tmppar            / restore par
/
callex: clr     p.rank(tpp)             / set rank to zero
	rts     pc                      / return
/
/
/ ADJUST: adjust SP after calling a process with parameters
/
adjust: add     sp,r2                   / add in current SP
/
	mov     4(sp),4(r2)             / save ps
	mov     2(sp),2(r2)             / save pc
	mov     (sp),(r2)               / save return pc
/
	mov     r2,sp                   / save new SP
adjstx: rts     pc                      / return
/
/
/
/ Send by a device process
/	R0 = queue
/ Called by
/       TRAP    2
/
dsen:   mov     (sp)+,r2                / retore r2
	mov     (r0), r1                / Get head of chain
	beq	1f			/ exit if empty
	mov	p.sc(r1), (r0)		/ Unlink head of chain
	jsr     pc,insert               / put process into ready queue
1:	rti
/
/ Wait by device process
/	R0 = queue
/       (R1) = PD
/ Called by
/       TRAP    3
/
dwai:   mov     (sp)+,r2                / retore r2
	mov     (r1),r1                 / load adr( PD )
	mov     (r0), p.sc(r1)          / Insert at head
	mov     r1, (r0)                / of signal queue
	jbr     1f                      / jump forward
/
/ Doio
/       (R1) = PD
/ Called by
/	JSR	PC, DOIO
/
doio:
/
/ Exit device process
/       (R1) = PD of caller
/ Called by:
/	JMP	DEXI
/
dexi:   spl7
	mov     (r1),r1                 / load adr( PD )
1:      mov     sp, (r1)                / Save callers context
/
	mov     p.veca(r1),r0           / load adr( interrupt save area )
	mov     v.par(r0),*$modpar      / reset par
	mov     v.pdr(r0),*$modpdr      / reset pdr
	mov     v.sp(r0), sp            / Restore interrupted context
/
intun:	mov     (sp)+, r1               / Restore saved regs
	mov	(sp)+, r0		/ of interrupted process
/
	bit     $140000,2(sp)           / non-Kernel ?
	bne     nonker                  / yes
/
	rti				/ and resume it.
/
/ DEVINT ( device interrupt )
/       R0 = interrupt save area
/
devint: mov     sp,v.sp(r0)             / save stack pointer
	mov     *$modpar,v.par(r0)      / save stack par
	mov     *$modpdr,v.pdr(r0)      / save stack pdr
	mov     v.pd(r0),r1             / load PD
/
	bit	$30000,6(sp)		/ from non-kernel domain ?
	beq	1f			/ no
/
	mov	4(sp),userpc		/ save user process pc
.if TRACE
	beq	2f			/ only needed to skip over following
.endif
/
1:
.if TRACE
/	came from kernel mode, save kernel pc for performance analysis
	mov	4(sp),kernpc
/	end of performance hack
.endif
2:	cmp     $1,p.sc(r1)             / unsolicited interrupt ?
	bne     intun                   / yes ...
/
	mov     (r1),sp                 / get sp
	mov     p.par(r1),*$modpar      / get stack par
	mov     p.pdr(r1),*$modpdr      / get stack pdr
	rts     pc                      / resume device process
/
/ Resume device process
/	R1 = new PP
/
dcon:	cmp	-(sp), -(sp)		/ Fake register save.
	mov     p.veca(r1),r2           / get vector save area address
	mov     sp,v.sp(r2)             / save sp
	mov     *$modpar,v.par(r2)      / save par
	mov     *$modpdr,v.pdr(r2)      / save pdr
/
	mov     $1,p.sc(r1)             / mark not waiting
	mov     (r1),sp                 / restore stack pointer
	mov     p.par(r1),*$modpar      / restore par
	mov     p.pdr(r1),*$modpdr      / restore pdr
	rti                             / continue
/
/
/ INSERT
/
/       R1 = PD of process to place at head of queue
/
insert: spl7				/ raise priority
	tst     p.rank(r1)              / device process ?
	bmi     1f                      / yes
/
	tst     p.dom(r1)               / no - Kernel ?
	bne     instnk                  / no
/
1:      mov     ready,p.sc(r1)          / place at head of queue
	bne     1f                      / if not empty ...
	mov     r1,last                 / set up end of queue
1:      mov     r1,ready                / set up head of queue
	tst     lastk                   / Kernel processes in queue ?
	bne     insrtx                  / yes
	mov     r1,lastk                / set up last Kernel
insrtx: rts     pc                      / return
/
/
/       INSTNK: insert a non-kernel process into ready queue
/
/               (R1) = PD of process
/
/       Calling sequence:       JSR     PC,INSTNK
/
/       process gets inserted after "last" if no time slice left
/       otherwise, it gets inserted after "lastk"
/
/
instnk: spl7			/ raise priority
	mov     r0,-(sp)        / save register zero
	mov     last,r0         / queue empty?
	beq	2f		/ yes
/
	cmp	$1,p.dom(r1)	/ clock ticks left?
	blos	1f		/ no
	mov	lastk,r0	/ get last kernel process
	beq	2f		/ none, insert at head
/
1:	mov	p.sc(r0),p.sc(r1)	/ link
	bne	1f	 	/ not end of queue
	mov	r1,last		/ put at end of queue
/
1:	mov	r1,p.sc(r0)	/ link after r0
	br	instex		/ exit
/
2:	mov	ready,p.sc(r1)	/ link at head of queue
	bne	1f		/ queue not empty
	mov	r1,last		/ make last too
/
1:	mov	r1,ready	/ at head of queue
/
instex: mov     (sp)+,r0        / restore register zero
	rts     pc              / return
/
/
/       NONKER: non-kernel process context save
/
/
nonker: spl7                    / raise processor level
	mov     ready,r0        / get head of ready queue
	beq     2f              / queue empty
/
	tst     p.rank(r0)      / device process ?
	bmi     1f              / yes
	tst     p.dom(r0)       / Kernel process ?
	beq     1f              / yes
/
2:      cmp     $1,p.dom(pp)    / time slice over ?
	beq     1f              / yes
/
	rti                     / no continue
/
1:	mov	p.dom(pp),-(sp)	/ save clock ticks
	clr	p.dom(pp)	/ mark as currently Kernel
/
	mov     sp,-(sp)        / save current SP
	spl0                    / lower processor level
        jsr     pc,nucsav       / save user process' context
	spl7                    / raise it back up
	tst     (sp)+           / pop stack
/
	mov	(sp)+,p.dom(pp)	/ restore clock ticks
	br	1f		/ continue
/
/
/       KEROUT: non-kernel process insert
/
/
/
kerout: spl7
	mov	10(sp),p.dom(pp)	/ mark as non-kernel process
1:	mov     pp,r1           / put PD in r1
	jsr     pc,instnk       / insert
	jbr     find            / get next process
/
/
/
/ Wait (ordinary process)
/ 	R0 = queue
/	R1 = priority
/ Called by:
/       TRAP    1
/
waitop: mov     (r0), r2                / look at next in queue
	beq	1f			/ Nonexistent ?
	cmp     r1, p.rank(r2)          / Is it higher prio?
	blt	1f			/ Yes, insert here
	mov	r2, r0			/ No, move along chain
	add	$p.sc, r0		/ and try next process
	br      waitop
1:      mov     (sp)+,r2                / retore r2
	mov     (r0), p.sc(pp)          / Link into signal chain
	mov	pp, (r0)
	mov     r1, p.rank(pp)          / Set status = prio
	jbr     find                    / continue
/
/ Send (ordinary process)
/	R0 = queue
/ Called by
/       TRAP    0
/
send:   mov     (sp)+,r2                / retore r2
	mov     (r0), r1                / Get head of chain
	beq	contx			/ Nothing, then exit.
	mov	p.sc(r1), (r0)		/ Unlink it
	tst     p.rank(r1)              / Device process ?
	jmi     dcon                    / Yes, its different
	jsr     pc,insert               / put at head of queue
/
/ Resume normal process
/
cont:   mov     lastk,r0                / get end of Kernel queue
	beq     2f                      / Kernel queue empty
	mov     p.sc(r0),p.sc(pp)       / link to rest of queue
	bne	1f			/ also last in queue
	mov	pp,last			/ set up as last
/
1:	mov     pp,p.sc(r0)             / link from front of queue
	br	1f			/ continue
/
2:	mov	ready,r0		/ get head of queue
	bne	2f			/ queue empty
	mov	pp,last			/ set up as last
/
2:	mov	r0,p.sc(pp)		/ link into head of queue
	mov	pp,ready		/ make head of queue
/
1:	mov     pp,lastk                / last Kernel
/
/
/ Exit process.
/ Called by:
/       JMP     PEXI
/
pexi:   spl7
/
/ Find runnable process
/
find:   mov     sp, (pp)                / Save callers context
1:      tst     ready                   / queue empty
	bne     1f                      / no ...
	spl0				/ enable interrupts
	wait                            / yes ... wait for interrupt
idlept:	spl7                            / disable interrupts
	br      1b                      / loop
/
1:      spl7				/ disable interrupts
/
/       DEBUG READY QUEUE PRINT OUT
/
/       mov     r0,-(sp)                / push r0
/       mov     r1,-(sp)                / push r1
/       mov     r2,-(sp)                / push r2
/       mov     r3,-(sp)                / push r3
/
/       mov     ready,-(sp)             / push ready
/       mov     lastk,-(sp)             / push lastk
/       mov     last,-(sp)              / push last
/       jsr     pc,prtchn               / print out
/       cmp     (sp)+,(sp)+             / pop stack
/
/ 2:    jsr     pc,prtnxt               / print next entry
/       mov     (sp),r0                 / get queue entry
/       beq     1f                      / end of queue
/       mov     p.sc(r0),(sp)           / step in queue
/       br      2b                      / print out next entry
/ 1:    tst     (sp)+                   / pop stack
/
/       mov     (sp)+,r3                / restore r3
/       mov     (sp)+,r2                / restore r2
/       mov     (sp)+,r1                / restore r1
/       mov     (sp)+,r0                / restore r0
/
	mov     ready,r1                / get head of queue
	mov     p.sc(r1),ready          / unlink head of queue
	bne     2f                      / queue not empty
	clr     last                    / clear end of queue
	br      1f
/
2:	cmp	r1,lastk		/ last Kernel?
	bne     2f                      / no 
/
1:      clr     lastk                   / no more Kernel processes
/
/
/
/	READY QUEUE CONSISTENCY CHECKING
/
/	mov	ready,r0		/ DEBUG - get head of queue
/	beq	2f			/ DEBUG - queue empty
/ 3:	tst	p.dom(r0)		/ DEBUG - Kernel ?
/	jeq	stop			/ DEBUG - yes STOP
/	mov	p.sc(r0),r0		/ DEBUG - next in queue
/	bne	3b			/ DEBUG - continue
/
2:      mov     r1, pp                  / Get new context
/
	mov     (pp), sp                / restore stack pointer
	mov     p.par(pp),*$modpar      / restore par
	mov     p.pdr(pp),*$modpdr      / restore pdr
	bit     $140000,2(sp)           / Kernel ?
	beq     contx                   / yes
/
	mov	p.dom(pp),-(sp)		/ save on stack
	mov	sp,-(sp)		/ save address
	clr     p.dom(pp)               / set Kernel temporarily
	mov     sp,-(sp)                / put current SP onto stack
	spl0                            / lower processor level
	jsr     pc,nucswh               / non-Kernel context switch
	spl7                            / raise processor level
	cmp	(sp)+,(sp)+		/ pop stack
	mov     (sp)+,p.dom(pp)		/ set time slice value
/
	mov     ready,r0                / get head of queue
	beq     contx                   / queue empty
	tst     p.rank(r0)              / device process ?
	jmi     kerout                  / yes
	tst     p.dom(r0)               / Kernel process ?
	jeq     kerout                  / yes
/
contx:	rti				/ and resume process
/
/
/
/       interrupt vector servicing - templates
/
/
/
botvec: 
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[0]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*2]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*3]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*4]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*5]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*6]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*7]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*10]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*11]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*12]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*13]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*14]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*15]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*16]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*17]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*20]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*21]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*22]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*23]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*24]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*25]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*26]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*27]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*30]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*31]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*32]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*33]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*34]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*35]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*36]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*37]],r0       / get save area address
	jmp     *$devint                / jump to devint        
	
	mov     r0,-(sp)                / save register 0
	mov     r1,-(sp)                / save register 1
	mov     $[botsav+[savsiz*devcnt]],r0       / get save area address
	jmp     *$devint                / jump to devint        


/
/
/       interrupt vector save locations
/
/
	.data
botsav: .=.+vsavsz
/
