;> Funct
FNTRC TST R5,#&80
 BNE ESCAPE
 TST R5,#&8000
 MOVEQ PC,R14
 LDR R5,[ARGP,#TRCNUM]
 TST R5,#TFP ;check proc/fn trace bit
 MOVEQ PC,R14
 STMFD SP!,{R0,R4,R14}
 LDR R0,[ARGP,#TRACEFILE]
 CMP R0,#0
 BLEQ TRCSTART
 TEQ R10,#TPROC
 BNE FNTRC1
 MOV R0,#"P"
 BL CHOUTTRACE
 MOV R0,#"R"
 BL CHOUTTRACE
 MOV R0,#"O"
 BL CHOUTTRACE
 MOV R0,#"C"
 B FNTRC2
FNTRC1 MOV R0,#"F"
 BL CHOUTTRACE
 MOV R0,#"N"
FNTRC2 BL CHOUTTRACE
 MOV R0,R3
 BL CHOUTTRACE
FNTRC3 TEQ R4,AELINE
 BEQ FNTRC4
 LDRB R0,[R4],#1
 BL CHOUTTRACE
 B FNTRC3
FNTRC4 TEQ R10,#TPROC
 BL TRCEND
 LDMFD SP!,{R0,R4,PC}
TRCSTART TST R5,#TINTEGER
 SWIEQ WRITEI+"["
 SWINE WRITEI+"{"
 MOV PC,R14
TRCEND LDR R0,[ARGP,#TRACEFILE]
 CMP R0,#0
 BNE TRCEND0
 TST R5,#TINTEGER
 SWIEQ WRITEI+"]"
 SWINE WRITEI+"}"
 SWI WRITEI+" "
 B TRCEND1
TRCEND0 STMFD SP!,{R14}
 MOV R0,#10
 BL CHOUTTRACE
 LDMFD SP!,{R14}
TRCEND1 TST R5,#TINTEGER
 SWINE READC
 MOV PC,R14
;search program section
FNFIND LDRB R0,[R5,#1]
 CMP R0,#&FF
 MOVEQ PC,R14 ;run out of program section: not found EQ code
 ADD R2,R5,#4 ;first real section of line
 LDRB R0,[R5,#3]
 ADD R5,R5,R0 ;step R5 onto next line
FNFINS LDRB R0,[R2],#1
 CMP R0,#" "
 BEQ FNFINS
 CMP R0,#TDEF
 BNE FNFIND ;no def, so around again
FNDEFA LDRB R0,[R2],#1
 CMP R0,#" "
 BEQ FNDEFA ;multiple spaces between DEF and FN/PROC
 TEQ R0,R10 ;found FN/PROC ?
 LDREQB R0,[R2],#1
 TEQEQ R0,R3 ;if we have, then is first char ok?
 BNE FNFIND ;neither
 MOV R7,R4
FNDFLP LDRB R0,[R2],#1
 TEQ R7,AELINE
 BEQ FNDFEN ;list end
 LDRB R6,[R7],#1
 TEQ R6,R0
 BEQ FNDFLP
 B FNFIND
FNDFEN MOV R6,R14
 BL WORDCQ
 MOVS R14,R6
 BCS FNFIND ;next character was wordc so not finished
 MOV PC,R14
FNDEFLIST CMP R1,#0
 MOVEQ PC,R14
 ADD R5,R1,#4
 STMFD SP!,{R14}
 BL FNFIND
 LDMFD SP!,{R14}
 LDREQ R1,[R1]
 BEQ FNDEFLIST
 B FNINSTANT ;naughty exit
;Search for the function/procedure definition in all program sections
FNDEF MVN R5,#0
 STMFD SP!,{R5} ;write "not in overlay"
 LDR R5,[ARGP,#PAGE] ;look in main program
 BL FNFIND
 BNE FNINSTANT
 LDR R1,[ARGP,#LIBRARYLIST] ;look in LIBRARY
 BL FNDEFLIST
 LDR R1,[ARGP,#INSTALLLIST] ;look in INSTALL
 BL FNDEFLIST
 LDR TYPE,[ARGP,#OVERPTR]
 TEQ TYPE,#0
 BEQ FNMISS ;no overlays
 LDR R5,[TYPE,#4] ;current overlay
 CMN R5,#1
 BEQ FNDEF4
 STR R5,[SP]
 ADD R5,TYPE,#12 ;address of overlay block
 BL FNFIND
 BNE FNINSTANT
FNDEF4 LDR R1,[TYPE] ;array base
 MOV R6,#0
FNDEF5 STR R6,[SP] ;overlay index
 ADD R5,TYPE,#12 ;address of overlay block
 ADD R0,R6,R6,LSL #2 ;multiply by 5
 ADD IACC,R1,R0 ;place in array
 STMFD SP!,{R1,R3,R4,R5,TYPE}
 BL VARSTR
 SUB R4,CLEN,ARGP
 SUBS R4,R4,#STRACC
 LDMEQFD SP!,{R1,R3,R4,R5,TYPE}
 BEQ FNDEF6
 MOV R0,#13
 STRB R0,[CLEN]
 MOV R2,R5
 BL OSFILELOADSTRACC
 BL FLUSHCACHE
 LDMFD SP,{R1,R3,R4,R5,TYPE}
 STR R6,[TYPE,#4] ;update current overlay
 BL FNFIND
 LDMFD SP!,{R1,R3,R4,R5,TYPE}
 BNE FNINSTANT
FNDEF6 LDR R6,[SP]
 ADD R6,R6,#1
 LDR R7,[R1,#-4]
 CMP R6,R7
 BCC FNDEF5
 B FNMISS
;have now found the function: now define it using R2. R3, R4 have name info.
;create function/proc definition
;list of formal paramters terminated by 0
;list entry is actual address word followed by type word:
;  high zero; n type to push; m RETURN; l type
;Already pushed on stack is the value of the OVERLAY pointer (or -1)
FNPAR1 LDRB R0,[R2],#1
FNINSTANT CMP R0,#" "
 BEQ FNPAR1
 MOV R1,#0
 CMP R0,#"("
 SUBNE R2,R2,#1
 STMFD SP!,{R1} ;limit stop for parameter list on stack
 BNE FNPARZ
 STMFD SP!,{R3,R4,AELINE,R10,LINE}
 MOV AELINE,R2
 MOV LINE,R2 ;for error
FNPAR2 BL AESPAC
 TEQ R10,#TRETURN
 STMFD SP!,{R10}
 BLEQ AESPAC
 BL LVCONT
 BNE FNPAR3
 BCS FACERR
 BL CREATE
FNPAR3 CMP TYPE,#256
 ORRCS TYPE,TYPE,#&48000 ;integer type for arg store for arrays and array type
 ORRCC TYPE,TYPE,TYPE,LSL #16 ;type for arg store is current type
 LDMFD SP!,{R4}
 TEQ R4,#TRETURN
 TSTEQ TYPE,#&100 ;make sure not an array
 ORREQ TYPE,TYPE,#&500 ;indicate reference type
 LDMFD SP!,{R2,R3,R4,R5,R6} ;get off interesting info
 STMFD SP!,{IACC,TYPE} ;new stuff
 STMFD SP!,{R2,R3,R4,R5,R6} ;info
 BL AESPAC
 TEQ R10,#","
 BEQ FNPAR2
 TEQ R10,#")"
 BNE ERBRA
 MOV R2,AELINE
 LDMFD SP!,{R3,R4,AELINE,R10,LINE}
FNPARZ STMFD SP!,{R2};save target line pointer
 ADD R0,ARGP,#PROCPTR
 TEQ R10,#TFN
 ADDEQ R0,ARGP,#FNPTR
 MOV TYPE,#0 ;don't let create do it
 BL CREALP
 ADD R2,R2,#3
 BIC R2,R2,#3 ;word align pointer
 LDMFD SP!,{R7} ;address
 MOV IACC,R2 ;put info pointer in desired place
 LDMFD SP!,{R4}
 TEQ R4,#0
 BEQ FNPARX
 STMFD SP!,{R4}
 MOV R1,SP
FNPAR8 LDR R5,[R1],#8 ;find the end of the list up the stack
 TEQ R5,#0
 BNE FNPAR8
 SUB R6,R1,#8
FNPAR9 LDMEA R6!,{R4,R5}
 STMEA R2!,{R4,R5} ;put r4,r5 onto parameter list
 TEQ R6,SP
 BNE FNPAR9
 SUB SP,R1,#4
 MOV R4,#0
FNPARX STMFD SP!,{LINE,R10}
 MOV LINE,R7
 BL MUNGLE
 STMEA R2!,{R4,LINE} ;put in final zero and address
 LDMFD SP!,{LINE,R10}
 LDMFD SP!,{R4}
 STMEA R2!,{R4} ;put in overlay value
 ADD R2,R2,#3
 BIC R2,R2,#3
 STR R2,[ARGP,#FSA] ;update fsa!
 B FNGOA
FN LDR R1,[ARGP,#FNPTR] ;base for function lookup
 STMFD SP!,{R14}
FNBODY MOV R0,#0 ;must enter with R10=FN/PROC and R1 lookup base
 STMFD SP!,{R0} ;push end-of-return info 0 (NO link RQD!)
 AND R2,AELINE,#CACHEMASK
 ADD R2,ARGP,R2,LSL #CACHESHIFT
 LDMIA R2,{IACC,R2,R4,R5}
 CMP R4,AELINE
 ADDEQ AELINE,AELINE,R2
 BEQ FNGOACACHE
 STMFD SP!,{AELINE}
 LDRB R3,[AELINE],#1
 MOV R4,AELINE ;R4 start of information after r3
 CMP R3,#"z"
 BHI FNCALL
 CMP R3,#"_"
 BCS FNMULTI
 CMP R3,#"Z"
 BHI FNCALL
 CMP R3,#"@"
 BCS FNMULTI
 CMP R3,#"9"
 BHI FNCALL
 CMP R3,#"0"
 BCC FNCALL
FNMULTI LDRB R5,[AELINE],#1
 CMP R5,#"z"
 BHI FNMULE
 CMP R5,#"_"
 BCS FNMULTI
 CMP R5,#"Z"
 BHI FNMULE
 CMP R5,#"@"
 BCS FNMULTI
 CMP R5,#"9"
 BHI FNMULE
 CMP R5,#"0"
 BCS FNMULTI
FNMULE SUB AELINE,AELINE,#1
 LDR R5,[ARGP,#ESCWORD]
 CMP R5,#0
 BLNE FNTRC
 BL LOOKP1 ;R1 preserved to here
 BNE FNDEF
 ADD IACC,IACC,#3
 BIC IACC,IACC,#3 ;pointer to info (list, 0, addr)
FNGOA LDRB R5,[AELINE],#1
 CMP R5,#" "
 BEQ FNGOA
 LDMFD SP!,{R4}
 LDR R1,[ARGP,#ESCWORD]
 CMP R1,#0
 AND R1,R4,#CACHEMASK
 ADD R1,ARGP,R1,LSL #CACHESHIFT
 SUB R2,AELINE,R4
 STMEQIA R1,{IACC,R2,R4,R5} ;only make cached if no tracing (etc) here
FNGOACACHE LDR R4,[ARGP,#FSA]
 ADD R4,R4,#1024
 CMP R4,SP
 BCS ERDEEPPROC
 CMP R5,#"("
 BEQ FNARGS
 SUB AELINE,AELINE,#1
DOFN LDMIA IACC,{R4,R5,R6} ;load end of list, destination, overlay from list
 TEQ R4,#0
 BNE ARGMAT ;argument mismatch
 STMFD SP!,{R10,AELINE,LINE} ;push FN/PROC and state
 MOV LINE,R5
 CMN R6,#1
 BEQ STMT ;not in the overlay world!
DOFNOVERLAY LDR R7,[ARGP,#OVERPTR]
 CMP R7,#0
 BLE ERRQ1 ;panic if overlay procedure and nasty overlay pointer
 LDR R4,[R7,#4]
 CMP R4,R6
 BEQ STMT ;somewhere in current overlay
 LDR R1,[R7]
 ADD IACC,R6,R6,LSL #2 ;multiply by 5
 ADD IACC,R1,IACC ;place in array
 BL VARSTR
 SUB R4,CLEN,ARGP
 SUBS R4,R4,#STRACC
 BEQ FNMISS
 MOV R0,#13
 STRB R0,[CLEN]
 ADD R2,R7,#12
 BL OSFILELOADSTRACC
 BL FLUSHCACHE
 STR R6,[R7,#4] ;update current overlay
 B STMT
FNARGS MOV R6,IACC ;save info pointer
;first push the r v's of the formal parameters
 MOV R5,IACC
 LDMIA R5!,{IACC,TYPE}
 TEQ IACC,#0
 BEQ FNARG0
FNARGT MOV TYPE,TYPE,LSR #16 ;get type to push
 BL VARIND
 BL PUSHTYPE
 LDMIA R5!,{IACC,TYPE}
 TEQ IACC,#0
 BNE FNARGT
FNARG0 ORR R14,R5,#&C0000000 ;end of parameter list
 STMFD SP!,{R6} ;gsave beginning of parm list
 STMFD SP!,{R5,R10,R14} ;local save of address, R10 (FN/PROC). gsave of r14
;now read r v's of actual parameters onto stack (and l v's of any RETURNs)
 MOV R7,R6 ;temporary save beginning of parm list
FNARG1 LDMIA R6!,{R4,R5} ;get r4,r5 from block
 TEQ R4,#0 ;find out what if at end of list
 BEQ ARGMAT ;error if so
 STMFD SP!,{R6,R7} ;save block pointer and info ptr
 TST R5,#&100 ;special code needed for different types
 BNE FNARGA ;array/RETURN
 BL EXPR
 LDMFD SP!,{R6,R7} ;recover saved block parm and info ptr
 BL PUSHTYPE ;save rv
 STMFD SP!,{TYPE} ;save type of rv
 CMP R10,#","
 BEQ FNARG1
 CMP R10,#")" ;end of call list
 LDR R5,[R6]
 TEQEQ R5,#0 ;end of target list
 BNE ARGMAT
;then assign the rv's to the parms
FNARGZ BL PULLTYPE ;get value from stack
 LDMEA R6!,{R4,R5} ;go backwards down the list of items
 STMFD SP!,{R6,R7}
 MOV R5,R5,LSR #16 ;get store type
 BL STOREA
 LDMFD SP!,{R6,R7}
 CMP R6,R7
 BNE FNARGZ
 LDMFD SP!,{IACC,R10}
 STMFD SP!,{R10,AELINE,LINE} ;push FN/PROC and state
 LDR LINE,[IACC,#-4]
 LDR R6,[IACC]
 CMN R6,#1
 BEQ STMT
 B DOFNOVERLAY
;now duplicate code which deals with calls with RETURN or ARRAYs
FNHARDARG1 LDMIA R6!,{R4,R5} ;get r4,r5 from block
 TEQ R4,#0 ;find out what if at end of list
 BEQ ARGMAT ;error if so
 STMFD SP!,{R6,R7} ;save block pointer and info ptr
 TST R5,#&100 ;special code needed for different types
 BNE FNARGA ;array/RETURN
 BL EXPR
 LDMFD SP!,{R6,R7} ;recover saved block parm and info ptr
 BL PUSHTYPE ;save rv
 STMFD SP!,{TYPE} ;save type of rv
 B FNARG4
FNARGA TST R5,#&8000
 BEQ FNARGR
 STMFD SP!,{R5}
 BL LVBLNK
 BEQ ARGMATARR
 CMP TYPE,#256
 BCC ARGMATARR
 LDMFD SP!,{R7}
 BIC R7,R7,#&FF000
 CMP TYPE,R7
 BNE ERSIZE
 LDMFD SP!,{R6,R7} ;recover saved block parm and info ptr
 LDR IACC,[IACC]
 STMFD SP!,{IACC} ;save array pointer
 MOV TYPE,#4
 STMFD SP!,{TYPE} ;save type of array pointer (integer!)
 B FNARG3
FNARGR BL LVBLNK ;return type must be an lv
 BNE FNARG2
 BCS ARGMATRET
 BL CREATE
FNARG2 LDMFD SP!,{R6,R7} ;recover saved block parm and temp ptr
 STMFD SP!,{IACC,TYPE} ;save lv
 BL VARIND
 BL PUSHTYPE ;save rv
 STMFD SP!,{TYPE} ;save type of rv
FNARG3 LDRB R10,[AELINE],#1
 CMP R10,#" "
 BEQ FNARG3
FNARG4 CMP R10,#","
 BEQ FNHARDARG1
 CMP R10,#")" ;end of call list
 LDR R5,[R6]
 TEQEQ R5,#0 ;end of target list
 BNE ARGMAT
;then assign the rv's to the parms
 SUB R10,SP,#256 ;pointer to temporary stack
 STR R10,[ARGP,#FNTEMPLOC]
FNHARDARGZ BL PULLTYPE
 LDMEA R6!,{R4,R5} ;go backwards down the list of items
 STMFD SP!,{R5,R6,R7}
 MOV R5,R5,LSR #16 ;get store type
 BL STOREA
 LDMFD SP!,{R5,R6,R7}
 TST R5,#&400 ;RETURN parameter on stack?
 LDMNEFD SP!,{R4,R5} ;transfer to
 STMNEIA R10!,{R4,R5} ;temporary stack
 CMP R6,R7
 BNE FNHARDARGZ
 LDR R4,[ARGP,#FNTEMPLOC]
 MOV R5,R10
 LDMFD SP!,{IACC,R10}
 SUB IACC,IACC,#8
 TEQ R4,R5
 BEQ DOFN ;no RETURNs
 LDMFD SP!,{R6,R7}
FNPUSHRETURN LDMEA R5!,{R2,R3}
 STMFD SP!,{R2,R3}
 TEQ R4,R5
 BNE FNPUSHRETURN
 BIC R6,R6,#&40000000
 STMFD SP!,{R6,R7}
 B DOFN

;stack looks like:
; 0

; rv, type of parameters    repeated!      :
; parameter list start                     : may not exist
; parameter list end + &c0000000           :
;OR
; rv, type of parameters    repeated!      :
; lv of RETURN destinations repeated!      :
; parameter list start                     : may not exist
; parameter list end + &80000000           :

; rv, type, lv of LOCALs    repeated!      : may not exist

; LINE
; AELINE
; FN/PROC

FNRET BL AEEXPR
 BL AEDONE
FNRETA LDMFD SP!,{R4}
 CMP R4,#TFN
 BNE FNRETP
 BL GTARGS
 TEQ TYPE,#0
 MOV PC,R7
FNRETP SUB SP,SP,#4
 BL POPA
 BEQ FNRETA
 B ERRFN
GTARGS LDMFD SP!,{AELINE,LINE}
 LDMFD SP!,{R4,R7}
 TEQ R4,#0
 MOVEQ PC,R14 ;no args to replace
;R4,5,6,7 and 10 are the only free registers!
 MOV R10,R14 ;save link reg
 CMP R4,#&80000000
 BCS GTARGP ;get parms (no locals at all)
GTARGL MOV R6,R4 ;LOCALS!
 BL RETSTK
 LDMFD SP!,{R4,R7}
 TEQ R4,#0
 MOVEQ PC,R10 ;no ARGS, no more LOCALs
 CMP R4,#&80000000
 BCC GTARGL
GTARGP CMP R4,#&C0000000
 BIC R4,R4,#&C0000000 ;extract address of end of parm list
 SUB R4,R4,#8
 BCC GTARGRET
 MOV R5,R7 ;start of parm list
GTARP1 LDMEA R4!,{R6,R7} ;get l value of parm: addr R6, type R7
 MOV R7,R7,LSR #16
 BL RETSTK
 CMP R4,R5
 BNE GTARP1
 LDMFD SP!,{R4,R7}
 TEQ R4,#0
 MOVEQ PC,R10
 B ERRQ1
;The code to recover from function/procdure when there are RETURNs
GTARGRET MOV R6,R4
 STMFD SP!,{R6,R7} ;keep hands on end, start of parm list
 MOV R5,SP
 BL PUSHTYPE
 STMFD SP!,{TYPE}
 STMFD SP!,{R10,AELINE} ;clear the air!
 ADD AELINE,R5,#8 ;base of list of lv's
;first, read and push the rv's of the parameter list which are RETURNs
 MOV R10,#0
GTARGRETPUSHRV LDMIA R7!,{IACC,TYPE}
 TST TYPE,#&400
 BEQ GTARGRETPUSHRV1
 MOV TYPE,TYPE,LSR #16
 ADD R10,R10,#1
 BL VARIND
 BL PUSHTYPE
 STMFD SP!,{TYPE}
GTARGRETPUSHRV1 CMP R6,R7
 BNE GTARGRETPUSHRV
;now restore the rv's on stack to the parameters
 LDMFD R5!,{R6,R7} ;parm list
 ADD AELINE,AELINE,R10,LSL #3 ;skip lv's of RETURNs
 STR R5,[ARGP,#FNTEMPLOC] ;pointer to lv list
GTARGRETRESTRV LDMEA R6!,{R4,R5} ;get l value of parm
 MOV R5,R5,LSR #16
 CMP R5,#TFPLV
 BEQ GTARGRETRESTRVFP
 BCS GTARGRETRESTRVSTR
 LDMFD AELINE!,{IACC}
 MOV TYPE,#TINTEGER
 B GTARGRETRESTRV1
GTARGRETRESTRVSTR LDMFD AELINE!,{CLEN}
 ADD R0,ARGP,#STRACC
 SUBS R1,CLEN,R0
 BEQ GTARGRETRESTRVSTR2
 ADD R1,R1,#3
 BIC R1,R1,#3
GTARGRETRESTRVSTR1 LDR R3,[AELINE],#4
 STR R3,[R0],#4
 SUBS R1,R1,#4
 BNE GTARGRETRESTRVSTR1
GTARGRETRESTRVSTR2 STMFD SP!,{R6,R7}
 MOV TYPE,#0
 BL STOREA
 LDMFD SP!,{R6,R7}
 B GTARGRETRESTRV2
GTARGRETRESTRVFP
 [ FP=0
 LDMFD AELINE!,{FACC,FACCX}
 AND FSIGN,FACCX,#&80000000
 AND FACCX,FACCX,#255
 |
 LDFD FACC,[AELINE],#8
 ]
 MOV TYPE,#TFP
GTARGRETRESTRV1 BL STOREA
GTARGRETRESTRV2 CMP R6,R7
 BNE GTARGRETRESTRV
 STR AELINE,[ARGP,#FNTEMPLOC+4] ;stack frame end!
 LDR AELINE,[ARGP,#FNTEMPLOC]
;Now save the rv's from the stack into the variables
GTARGRETRET BL PULLTYPE
 LDMIA AELINE!,{R4,R5}
 BL STOREA
 SUBS R10,R10,#1
 BNE GTARGRETRET
 LDMFD SP!,{R10,AELINE}
 BL PULLTYPE
 LDR SP,[ARGP,#FNTEMPLOC+4]
 LDMFD SP!,{R4,R7}
 TEQ R4,#0
 MOVEQ PC,R10
 B ERRQ1
;return item type in r7, address in r6. Uses R8 as temporary!
RETSTK CMP R7,#TFPLV
 BEQ RETFP
 BCS RETSTR
 CMP R7,#4
 LDMFD SP!,{R7}
 BNE RETBYTE
 TST R6,#3
 STREQ R7,[R6]
 MOVEQ PC,R14
 [ FP=0
 B RETWORD
RETFP LDMFD SP!,{R7,R8}
 STRB R8,[R6,#4]
 BIC R7,R7,#&80000000
 AND R8,R8,#&80000000
 ORR R7,R7,R8
 MOV ARGP,#VARS
 ]
RETWORD STRB R7,[R6],#1
 MOV R7,R7,ROR #8
 STRB R7,[R6],#1
 MOV R7,R7,ROR #8
 STRB R7,[R6],#1
 MOV R7,R7,ROR #8
RETBYTE STRB R7,[R6]
 MOV PC,R14
 [ FP=1
RETFP LDMFD SP!,{R7,R8}
 STMIA R6,{R7,R8}
 MOV ARGP,#VARS
 MOV PC,R14
 ]
RETSTR CMP R7,#128
 BNE RETROP
 STMFD SP!,{R0-R5,R14}
 ADD R3,SP,#7*4 ;number of registers pushed
 LDMFD R3!,{CLEN}
 ADD R4,ARGP,#STRACC
 SUB CLEN,CLEN,R4
 ADD CLEN,CLEN,R3
 MOV R4,R6
 BL STSTORE
 ADD R7,CLEN,#3
 LDMFD SP!,{R0-R5,R14}
 BIC SP,R7,#3
 MOV PC,R14
RETROP LDMFD SP!,{R7}
 SUB R7,R7,ARGP
 SUBS R7,R7,#STRACC
 BEQ RETRPN
RETRP1 LDRB R8,[SP],#1
 STRB R8,[R6],#1
 SUBS R7,R7,#1
 BNE RETRP1
 MOV ARGP,#VARS
 ADD SP,SP,#3
 BIC SP,SP,#3
RETRPN MOV R7,#13
 STRB R7,[R6]
 MOV PC,R14
 LNK Stmt
