198 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			198 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
#include "e.h"
 | 
						|
 exp $GETLINEN
 | 
						|
 exp $ME
 | 
						|
 exp $STATIC
 | 
						|
 exp $DYNAMIC
 | 
						|
 exp $ARGBASE
 | 
						|
 exp $SETMYSTA
 | 
						|
 exp $SETNSTAT
 | 
						|
 exp $ISA68
 | 
						|
 exp $ISPUT
 | 
						|
 exp $ISGET
 | 
						|
 exp $GETCALLE
 | 
						|
 | 
						|
 ; function getlineno :integer;
 | 
						|
 pro $GETLINEN,0	; return line no from hol0
 | 
						|
 loe 0
 | 
						|
 ret SZWORD
 | 
						|
 end 
 | 
						|
 | 
						|
 pro $ME,0
 | 
						|
 lor 0			; lb -> stack
 | 
						|
 dch			; caller's lb -> stack
 | 
						|
 ret SZADDR   		; clb -> function result area
 | 
						|
 end 0
 | 
						|
 | 
						|
 pro $STATIC,0
 | 
						|
 LFL SZADDR 		; param (lb of caller) (after static link)
 | 
						|
 lpb			; ab of param
 | 
						|
 loi SZADDR		; static link of param
 | 
						|
 ret SZADDR
 | 
						|
 end 0
 | 
						|
 | 
						|
 pro $DYNAMIC,0
 | 
						|
 LFL SZADDR		; param (lb of caller) (after static link)
 | 
						|
 dch			; follow dynamic chain, using lb of caller
 | 
						|
 ret SZADDR
 | 
						|
 end 0
 | 
						|
 | 
						|
 pro $ARGBASE,0
 | 
						|
 LFL SZADDR		; param (somebody's lb)
 | 
						|
 lpb			; convert to somebody's ab
 | 
						|
 ret SZADDR
 | 
						|
 end 0
 | 
						|
 | 
						|
 pro $SETMYSTA,0
 | 
						|
 LFL SZADDR		; place param on stack
 | 
						|
 lor 0			; lb -> stack , for dch
 | 
						|
 dch			; caller's lb -> stack
 | 
						|
 lpb			; caller's ab
 | 
						|
 sti SZADDR		; store param in caller's static link
 | 
						|
 ret 0
 | 
						|
 end 0
 | 
						|
 | 
						|
#ifndef VAX4
 | 
						|
 pro $SETNSTAT,0	; called from RNSTART of insert n extra levels in
 | 
						|
			; the static chain of A68 (i.e. RNSTART's caller);
 | 
						|
			; there is guaranteed to be enough vacant space at
 | 
						|
			; the top of the IB of A68
 | 
						|
 lor 0			; my LB
 | 
						|
 dch			; RNSTART LB
 | 
						|
 adp SZADDR		; fictitious LB
 | 
						|
			; BUT THIS MAY NOT BE LEGAL EM. REVIEW WHEN
 | 
						|
			; RNSTART IS REWRITTEN.
 | 
						|
 dup SZADDR
 | 
						|
 lxa 2			; A68 AB
 | 
						|
 loi SZADDR		; A68 static
 | 
						|
 exg SZADDR
 | 
						|
 lpb			; fictitious AB
 | 
						|
 sti SZADDR		; (fictitious AB) := A68 static
 | 
						|
 dup SZADDR
 | 
						|
 lxa 2			; A68 AB
 | 
						|
 sti SZADDR		; (A68 AB) := fictitious LB
 | 
						|
2
 | 
						|
 lol SZADDR		; n
 | 
						|
 loc 1
 | 
						|
 sbi SZWORD
 | 
						|
 dup SZWORD
 | 
						|
 stl SZADDR		; n := n-1
 | 
						|
 zeq *3
 | 
						|
 dup SZADDR
 | 
						|
 lpb			; fictitious AB
 | 
						|
 dup SZADDR
 | 
						|
 loi SZADDR
 | 
						|
 exg SZADDR
 | 
						|
 SFF SZADDR		; (fictitious AB + 1) := (fictitious AB)
 | 
						|
 adp SZADDR		; new fictitious LB
 | 
						|
 dup SZADDR
 | 
						|
 dup SZADDR
 | 
						|
 lpb			; new fictitious AB
 | 
						|
 SFF -SZADDR		; (new fictitious AB -l = old fictitious AB) :=
 | 
						|
						; new fictitious LB
 | 
						|
 bra *2			; with the new fictitious LB on the stack
 | 
						|
3
 | 
						|
 ret 0
 | 
						|
 end 0
 | 
						|
#else
 | 
						|
 pro $SETNSTAT,SZWORD	; called from RNSTART of insert n extra levels in
 | 
						|
			; the static chain of A68 (i.e. RNSTART's caller);
 | 
						|
			; this version does not assume that the space between
 | 
						|
			; LB and AB is a constant. It calls itself recursively
 | 
						|
			; to create n activation records, whose static chains
 | 
						|
			; are linked as required. The last activation then 
 | 
						|
			; copies the return status block of RNSTART over itself,
 | 
						|
			; so exiting from RNSTART but leaving the extra chains
 | 
						|
			; still within the stack.
 | 
						|
 lor 0			; SLB
 | 
						|
 dch			; RLB
 | 
						|
 dup SZADDR		; RLB | RLB
 | 
						|
 dch			; RLB | ALB
 | 
						|
 lpb			; RLB | AAB
 | 
						|
 dup SZADDR		; RLB | AAB | AAB
 | 
						|
 loi SZADDR		; RLB | AAB | (AAB)
 | 
						|
 lor 0			; RLB | AAB | (AAB) | SLB
 | 
						|
 dch			; RLB | AAB | (AAB) | RLB
 | 
						|
 lpb			; RLB | AAB | (AAB) | RAB
 | 
						|
 sti SZADDR		; RLB | AAB   (RAB) := (AAB)
 | 
						|
 sti SZADDR		; (AAB) := RLB
 | 
						|
			; now my caller (RNSTART the first time) has been linked
 | 
						|
			; into the static chain of HIS caller.
 | 
						|
 lol SZADDR		; n
 | 
						|
 loc 1
 | 
						|
 sbi SZWORD		; n-1
 | 
						|
 dup SZWORD
 | 
						|
 zeq *4
 | 
						|
 lxl 1
 | 
						|
 cal $SETNSTAT
 | 
						|
 asp SZWORD+SZADDR	; but it should never return here
 | 
						|
 nop
 | 
						|
4			; now we must move the return status block of RNSTART
 | 
						|
			; on top of our own. We are still statically within RNSTART
 | 
						|
 LFL 0			; RLB
 | 
						|
 dup SZADDR		; RLB | RLB
 | 
						|
 lpb			; RLB | RAB
 | 
						|
 exg SZADDR		; RAB | RLB
 | 
						|
 sbs SZWORD		; Amount to be moved
 | 
						|
 dup SZWORD		; A | A
 | 
						|
 stl -SZWORD		; A
 | 
						|
 lor 0			; A | SLB
 | 
						|
 dup SZADDR		; A | SLB | SLB
 | 
						|
 lpb			; A | SLB | SAB
 | 
						|
 exg SZADDR		; A | SAB | SLB
 | 
						|
 sbs SZWORD		; A | SA (the size of our own return status block)
 | 
						|
 exg SZWORD		; SA | A
 | 
						|
 sbi SZWORD		; SA-A
 | 
						|
 lor 0			; SLB
 | 
						|
 ads SZWORD		; new SLB to be
 | 
						|
 str 1			; set SP there
 | 
						|
 lor 1			; TO (=SP the destination of the move)
 | 
						|
 dup SZADDR		; TO | TO
 | 
						|
 LFL 0			; TO | TO | RLB (the source of the move)
 | 
						|
 exg SZADDR		; TO | RLB | TO
 | 
						|
 lol -SZWORD		; TO | RLB | TO | A
 | 
						|
 bls SZWORD		; TO
 | 
						|
 str 0			; set SLB to the moved copy of RNSTART's block
 | 
						|
 ret 0			; return to RNSTART's caller, resetting his registers
 | 
						|
 end SZWORD		; one local to store A
 | 
						|
#endif
 | 
						|
 | 
						|
 pro $GETCALLE,0	; returns LB of nearest A68 frame on stack, A68 caller
 | 
						|
 LFL SZADDR		; param (lb of callee, routine) (after static link)
 | 
						|
1
 | 
						|
 dch			; follow dynamic chain
 | 
						|
 dup SZADDR		; duplicate either to return or follow next time
 | 
						|
 lof -SZWORD		; lb - SZWORD is addres of frame stamp
 | 
						|
 loc A68STAMP
 | 
						|
 bne *1			; do again if not A68 frame
 | 
						|
 ret SZADDR		; return lb of frame
 | 
						|
 end 0
 | 
						|
 | 
						|
 pro $ISA68,0
 | 
						|
 LFL SZADDR		; get param, lb of frame to test
 | 
						|
 adp -SZWORD
 | 
						|
 loi SZWORD		; load frame stamp
 | 
						|
 loc A68STAMP
 | 
						|
 cmi SZWORD		; compare it with 'a68stamp'
 | 
						|
 teq			; is it the same
 | 
						|
 ret SZWORD		; return answer, true=1 false=0
 | 
						|
 end 0
 | 
						|
 | 
						|
 pro $ISPUT,0
 | 
						|
 LFL SZADDR		; get param, lb of frame to test
 | 
						|
 adp -SZWORD
 | 
						|
 loi SZWORD		; load  frame stamp
 | 
						|
 loc PUTSTAMP
 | 
						|
 cmi SZWORD             ; compare it with 'putstamp'
 | 
						|
 teq
 | 
						|
 ret SZWORD		; return answer, true=1 false=0
 | 
						|
 end 0
 | 
						|
 | 
						|
 pro $ISGET,0
 | 
						|
 LFL SZADDR		; get param, lb of frame to test
 | 
						|
 adp -SZWORD
 | 
						|
 loi SZWORD		; load  frame stamp
 | 
						|
 loc GETSTAMP
 | 
						|
 cmi SZWORD             ; compare it with 'getstamp'
 | 
						|
 teq
 | 
						|
 ret SZWORD		; return answer, true=1 false=0
 | 
						|
 end 0
 |