;> Array Operations
LETARRAY LDRB R10,[AELINE],#1
 CMP R10,#" "
 BEQ LETARRAY
 CMP R10,#"-"
 BEQ ARRAYNEGATE
 STMFD SP!,{AELINE}
 BL LVCONT
 BEQ ARRAYFACT
 ADD SP,SP,#4
 CMP TYPE,#256
 BCC ARRAYFACTLV
 BL AESPAC
 CMP R10,#"+"
 CMPNE R10,#"-"
 CMPNE R10,#"*"
 CMPNE R10,#"/"
 CMPNE R10,#"."
 BEQ ARRAYBINARY
 BL AEDONE
ARRAYARRAYASSIGN LDMFD SP!,{R4,R5}
 CMP TYPE,R5
 BNE ERTYPEARRAYB
 LDR R6,[FACC]
 LDR R4,[R4]
 CMP R6,#16
 CMPCS R4,#16
 BCC ERARRZ
ARRAYARRAYASSIGNSIZE LDR R5,[R4],#4
 LDR R7,[R6],#4
 CMP R5,R7
 BNE ERTYPEARRAYC
 CMP R5,#0
 BNE ARRAYARRAYASSIGNSIZE
 LDR AELINE,[R4],#4 ;total number of elements
 ADD R6,R6,#4
 SUB TYPE,TYPE,#256
 CMP TYPE,#5
 BHI ARRAYARRAYASSIGNSTRING
 ADDEQ AELINE,AELINE,AELINE,LSL #2
 MOVNE AELINE,AELINE,LSL #2 ;calculate number of bytes to copy
ARRAYARRAYASSIGNCOPY LDR R0,[R6],#4
 STR R0,[R4],#4
 SUBS AELINE,AELINE,#4 ;copy the bytes using word moves
 BCS ARRAYARRAYASSIGNCOPY
 B NXT
ARRAYARRAYASSIGNSTRING MOV TYPE,R6 ;source
ARRAYARRAYASSIGNSTRING1 LOAD R3,TYPE,R6,R7
 LDRB R2,[TYPE,#4]
 ADD TYPE,TYPE,#5
 ADD R2,R2,R3
 BL STSTORE
 ADD R4,R4,#5
 SUBS AELINE,AELINE,#1
 BNE ARRAYARRAYASSIGNSTRING1
 B NXT
ARRAYBINARY STMFD SP!,{FACC,TYPE,R10}
 STMFD SP!,{AELINE}
 BL LVBLNK
 BEQ ARRAYBINARYCONST
 ADD SP,SP,#4
 BL AEDONES
 CMP TYPE,#256
 BCC ARRAYBINARYCONSTLV
 LDMFD SP!,{R1,R2,R3,R4,R5} ;R1,2=LV1,TYPE; R3=OP; R4,5=LV0,TYPE
 CMP TYPE,R2
 CMPEQ R2,R5
 BNE ERTYPEARRAYB
 LDR FACC,[FACC]
 LDR R1,[R1]
 LDR R4,[R4]
 CMP FACC,#16
 CMPCS R1,#16
 CMPCS R4,#16
 BCC ERARRZ ;if any array undimensioned
 CMP R3,#"."
 BEQ MATRIXMULTIPLY
ARRAYBINARYSIZE LDR R2,[FACC],#4
 LDR R5,[R1],#4
 LDR R6,[R4],#4
 CMP R2,R5
 CMPEQ R5,R6
 BNE ERTYPEARRAYC
 CMP R6,#0
 BNE ARRAYBINARYSIZE
 LDR AELINE,[R4],#4 ;number of items
 ADD FACC,FACC,#4
 ADD R1,R1,#4
 SUB TYPE,TYPE,#256
 CMP R3,#"-"
 BEQ ARRAYBINARYSUB
 CMP R3,#"*"
 BEQ ARRAYBINARYMUL
 CMP R3,#"/"
 BEQ ARRAYBINARYDIV
 CMP TYPE,#5
 BEQ ARRAYBINARYADDFP
 BCS ARRAYBINARYADDSTRING
ARRAYBINARYADDINT LDR R2,[FACC],#4
 LDR R3,[R1],#4
 ADD R2,R2,R3
 STR R2,[R4],#4
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYADDINT
 B NXT
ARRAYBINARYADDFP STMFD SP!,{R8,R10} ;save pointers
 MOV R10,R4
 MOV R8,R1
 MOV TYPE,R0
ARRAYBINARYADDFP1 BL F1LDA
 ADD R4,TYPE,#5
 MOV TYPE,R8
 MOV R8,R4
 BL F1ADD
 ADD R4,TYPE,#5
 MOV TYPE,R10
 BL F1STA
 MOV TYPE,R4
 ADD R10,R10,#5
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYADDFP1
 LDMFD SP!,{R8,R10}
 B NXT
ARRAYBINARYADDSTRING STMFD SP!,{R0,R10}
 MOV R10,R1
ARRAYBINARYADDSTRING1 MOV FACC,R10
 BL VARSTR
 ADD R10,R10,#5
 LDR FACC,[SP]
 ADD R1,FACC,#5
 STR R1,[SP]
 LDRB R5,[FACC,#4]
 TEQ R5,#0
 BEQ ARRAYBINARYADDSTRING3
 LOAD FACC,FACC,R1,R3
 ADD R6,CLEN,R5
 ADD R1,ARGP,#STRACC+256
 CMP R6,R1
 BCS ERLONG
ARRAYADDBINARYSTRING2 LDRB R1,[FACC],#1
 STRB R1,[CLEN],#1
 SUBS R5,R5,#1
 BNE ARRAYADDBINARYSTRING2
ARRAYBINARYADDSTRING3 ADD R3,ARGP,#STRACC
 BL STSTORE
 ADD R4,R4,#5
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYADDSTRING1
 LDMFD SP!,{R0,R10}
 B NXT 
ARRAYBINARYSUB CMP TYPE,#5
 BEQ ARRAYBINARYSUBFP
 BCS ERTYPEARRAYB
ARRAYBINARYSUBINT LDR R2,[FACC],#4
 LDR R3,[R1],#4
 SUB R2,R3,R2
 STR R2,[R4],#4
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYSUBINT
 B NXT
ARRAYBINARYSUBFP STMFD SP!,{R8,R10} ;save pointers
 MOV R10,R4
 MOV R8,R1
 MOV TYPE,R0
ARRAYBINARYSUBFP1 BL F1LDA
 ADD R4,TYPE,#5
 MOV TYPE,R8
 MOV R8,R4
 BL F1XSUB
 ADD R4,TYPE,#5
 MOV TYPE,R10
 BL F1STA
 MOV TYPE,R8
 MOV R8,R4
 ADD R10,R10,#5
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYSUBFP1
 LDMFD SP!,{R8,R10}
 B NXT
ARRAYBINARYMUL CMP TYPE,#5
 BEQ ARRAYBINARYMULFP
 BCS ERTYPEARRAYB
ARRAYBINARYMULINT LDR R2,[FACC],#4
 LDR R3,[R1],#4
 [ RRX=1
 MUL R2,R3,R2
 |
 BL MSG
 = 0,"Please ask for a 2u ARM if you want to do this.",0
 ]
 STR R2,[R4],#4
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYMULINT
 B NXT
ARRAYBINARYMULFP STMFD SP!,{R8,R10} ;save pointers
 MOV R10,R4
 MOV R8,R1
 MOV TYPE,R0
ARRAYBINARYMULFP1 BL F1LDA
 ADD R4,TYPE,#5
 MOV TYPE,R8
 MOV R8,R4
 BL F1MUL
 ADD R4,TYPE,#5
 MOV TYPE,R10
 BL F1STA
 MOV TYPE,R8
 MOV R8,R4
 ADD R10,R10,#5
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYMULFP1
 LDMFD SP!,{R8,R10}
 B NXT
ARRAYBINARYDIV CMP TYPE,#5
 BEQ ARRAYBINARYDIVFP
 BCS ERTYPEARRAYB
ARRAYBINARYDIVINT LDR R3,[FACC],#4
 LDR R2,[R1],#4
 BL ARRAYINTDIV
 STR TYPE,[R4],#4
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYDIVINT
 B NXT
ARRAYBINARYDIVFP STMFD SP!,{R8,R10} ;save pointers
 MOV R10,R4
 MOV R8,R1
 MOV TYPE,R0
ARRAYBINARYDIVFP1 BL F1LDA
 ADD R4,TYPE,#5
 MOV TYPE,R8
 MOV R8,R4
 BL F1XDIV
 ADD R4,TYPE,#5
 MOV TYPE,R10
 BL F1STA
 MOV TYPE,R8
 MOV R8,R4
 ADD R10,R10,#5
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYDIVFP1
 LDMFD SP!,{R8,R10}
 B NXT
ARRAYBINARYCONSTLV BL VARIND
 B ARRAYBINARYCONSTRV
ARRAYBINARYCONST LDMFD SP!,{AELINE}
 BL FACTOR
 BL AEDONES
;A()         =B()     op   C%
;sp+12,sp+16 =sp,sp+4 sp+8 in acc
ARRAYBINARYCONSTRV LDMFD SP!,{R4,R5,R6,R7,AELINE}
 CMP R6,#"-"
 BNE ARRAYBINARYCONST1
 TEQ TYPE,#0
 EORMI FSIGN,FSIGN,#&80000000
 RSBPL FACC,FACC,#0
 TEQ FACC,#0
 MOVEQ FSIGN,#0
 MOV R6,#"+"
ARRAYBINARYCONST1 CMP R6,#"+"
 CMPEQ R5,#256+128
 BEQ ARRAYBINARYCONST2
 BL PUSHTYPE
 STMFD SP!,{TYPE}
 MOV FACC,R4
 MOV TYPE,R5
 MOV R4,R7
 MOV R5,AELINE
 MOV R7,R6
 SUB R1,TYPE,#256
 CMP R7,#"/"
 BNE ARRAYCONSTBINARY1
 CMP R5,TYPE
 BNE ERTYPEARRAYB
 LDR R6,[FACC]
 LDR R4,[R4]
 CMP R6,#16
 CMPCS R4,#16
 BCC ERARRZ
ARRAYBINARYCONSTDIV1 LDR R5,[R4],#4
 LDR R2,[R6],#4
 CMP R5,R2
 BNE ERTYPEARRAYC
 CMP R5,#0
 BNE ARRAYBINARYCONSTDIV1
 LDR AELINE,[R4],#4 ;total number of elements
 ADD R6,R6,#4
 CMP R1,#5
 BHI ERTYPEARRAY
 BEQ ARRAYBINARYCONSTDIVFP
 BL PULLTYPE
 BL INTEGY
ARRAYBINARYCONSTDIVINT LDR R2,[R6],#4
 MOV R3,R0
 BL ARRAYINTDIV
 STR TYPE,[R4],#4
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYCONSTDIVINT
 B NXT
ARRAYBINARYCONSTDIVFP BL PULLTYPE
 BL FLOATY
 STMFD SP!,{R8,R10}
 MOV R10,R4 ;D
 MOV R8,R6 ;S
 BL FPUSH
 TEQ FACC,#0
 BEQ ZDIVOR
ARRAYBINARYCONSTDIVFP1 MOV TYPE,R8
 ADD R8,R8,#5
 BL F1LDA
 BEQ ARRAYBINARYCONSTDIVFP2
 BL FTOW
 MOV TYPE,SP
 BL FLDA
 BL FDIVA
ARRAYBINARYCONSTDIVFP2 MOV TYPE,R10
 ADD R10,R10,#5
 BL F1STA
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYCONSTDIVFP1
 LDMFD SP!,{R0,R1,R8,R10}
 B NXT
ARRAYBINARYCONST2 CMP R5,AELINE
 BNE ERTYPEARRAYB
 LDR R6,[R4]
 BL SPUSH
 LDR R4,[R7]
 CMP R4,#16
 CMPCS R6,#16
 BCC ERARRZ
ARRAYBINARYCONSTSIZE LDR R5,[R4],#4
 LDR R2,[R6],#4
 CMP R5,R2
 BNE ERTYPEARRAYC
 CMP R5,#0
 BNE ARRAYBINARYCONSTSIZE
 LDR AELINE,[R4],#4 ;total number of elements
 ADD R6,R6,#4
ARRAYBINARYCONSTADDSTRING STMFD SP!,{R10}
 MOV R10,R6
ARRAYBINARYCONSTADDSTRING1 MOV FACC,R10
 BL VARSTR
 ADD R3,ARGP,#STRACC
 LDR R5,[SP,#4]
 SUBS R1,R5,R3
 BEQ ARRAYBINARYCONSTADDSTRING3
 ADD R6,R1,CLEN
 ADD R5,ARGP,#STRACC+256
 CMP R6,R5
 BCS ERLONG
 ADD R6,SP,#8
ARRAYBINARYCONSTADDSTRING2 LDRB R5,[R6],#1
 STRB R5,[CLEN],#1
 SUBS R1,R1,#1
 BNE ARRAYBINARYCONSTADDSTRING2
ARRAYBINARYCONSTADDSTRING3 BL STSTORE
 ADD R4,R4,#5
 ADD R10,R10,#5
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYCONSTADDSTRING1
 LDMFD SP!,{R10}
 BL SPULL
 B NXT
ARRAYNEGATE STMFD SP!,{AELINE}
 BL LVBLNK
 BEQ ARRAYFACT
 ADD SP,SP,#4
 SUBS R1,TYPE,#256
 BCS ARRAYZEROMINUS
 BL VARIND
 BEQ ERTYPEINT
 RSBPL FACC,FACC,#0 ;negate integer
 BPL ARRAYFACTRV
 TEQ FACC,#0
 EORNE FSIGN,FSIGN,#&80000000 ;negate floating point
 B ARRAYFACTRV
ARRAYFACTLV BL VARIND
 B ARRAYFACTRV
ARRAYFACT LDMFD SP!,{AELINE}
 SUB AELINE,AELINE,#1
 BL FACTOR
ARRAYFACTRV BL AESPAC
 CMP R10,#"+"
 CMPNE R10,#"-"
 CMPNE R10,#"*"
 CMPNE R10,#"/"
 BEQ ARRAYCONSTBINARY
 BL AEDONE
ARRAYCONSTASSIGN LDMFD SP!,{R4,R5}
 LDR R4,[R4]
 CMP R4,#16
 BCC ERARRZ
ARRAYCONSTASSIGN1 LDR R6,[R4],#4
 CMP R6,#0
 BNE ARRAYCONSTASSIGN1
 LDR AELINE,[R4],#4 ;aeline=number of elements, r6=base
 SUB R5,R5,#256
 CMP R5,#5
 BHI ARRAYCONSTASSIGNSTRING
 BEQ ARRAYCONSTASSIGNFP
 BL INTEGY ;make sure of INT
ARRAYCONSTASSIGNINT STR FACC,[R4],#4
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTASSIGNINT
 B NXT
ARRAYCONSTASSIGNFP BL FLOATY ;make sure of FP
 BIC FGRD,FACC,#&80000000
 ORR FGRD,FGRD,FSIGN ;fsign only 0 or &80000000!
 MOV R5,FGRD,LSR #8
 MOV R6,FGRD,LSR #16
 MOV R7,FGRD,LSR #24
ARRAYCONSTASSIGNFP1 STRB FGRD,[R4],#1
 STRB R5,[R4],#1
 STRB R6,[R4],#1
 STRB R7,[R4],#1
 STRB FACCX,[R4],#1
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTASSIGNFP1
 B NXT
ARRAYCONSTASSIGNSTRING CMP TYPE,#0
 BNE ERTYPESTR
 ADD R3,ARGP,#STRACC
ARRAYCONSTASSIGNSTRING1 BL STSTORE
 ADD R4,R4,#5
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTASSIGNSTRING1
 B NXT
ARRAYZEROMINUS BL AEDONES
 MOV R2,#TINTEGER
 MOV R3,#0
 LDMFD SP!,{R4,R5}
 STMFD SP!,{R2,R3}
 MOV R7,#"-"
 B ARRAYCONSTBINARY1
ARRAYCONSTBINARY LDMFD SP!,{R6,R7}
 BL PUSHTYPE
 STMFD SP!,{TYPE}
 STMFD SP!,{R6,R7,R10}
 BL LVBLNK
 BEQ ERTYPEARRAY
 SUBS R1,TYPE,#256
 BCC ERTYPEARRAY
 BL AEDONES
 LDMFD SP!,{R4,R5,R7}
;A()      =B%              op C()
;facc,type=pushed on stack r7 r4,r5
ARRAYCONSTBINARY1 CMP R5,TYPE
 BNE ERTYPEARRAYB
 LDR R6,[FACC]
 LDR R4,[R4]
 CMP R6,#16
 CMPCS R4,#16
 BCC ERARRZ
ARRAYCONSTBINARYSIZE LDR R5,[R4],#4
 LDR R2,[R6],#4
 CMP R5,R2
 BNE ERTYPEARRAYC
 CMP R5,#0
 BNE ARRAYCONSTBINARYSIZE
 LDR AELINE,[R4],#4 ;total number of elements
 ADD R6,R6,#4
 CMP R7,#"-"
 BEQ ARRAYCONSTBINARYMINUS
 CMP R7,#"*"
 BEQ ARRAYCONSTBINARYMUL
 CMP R7,#"/"
 BEQ ARRAYCONSTBINARYDIV
 CMP R7,#"."
 BEQ ERTYPEARRAY
 CMP R1,#5
 BHI ARRAYCONSTBINARYADDSTRING
 BEQ ARRAYCONSTBINARYADDFP
 BL PULLTYPE
 BL INTEGY
ARRAYCONSTBINARYADDINT LDR R1,[R6],#4
 ADD R1,R1,R0
 STR R1,[R4],#4
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYADDINT
 B NXT
ARRAYCONSTBINARYADDFP BL PULLTYPE
 BL FLOATY
 STMFD SP!,{R8,R10}
 MOV R10,R4 ;D
 MOV R8,R6 ;S
 BL FPUSH
ARRAYCONSTBINARYADDFP1 MOV TYPE,R8
 ADD R8,R8,#5
 BL F1LDA
 MOV TYPE,SP
 BL FADD
 MOV TYPE,R10
 ADD R10,R10,#5
 BL F1STA
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYADDFP1
 LDMFD SP!,{R0,R1,R8,R10}
 B NXT
ARRAYCONSTBINARYADDSTRING BL PULLTYPE
 STMFD SP!,{CLEN,R10}
 ADD R3,ARGP,#STRACC
 MOV R10,R6
ARRAYCONSTBINARYADDSTRING1 LDR CLEN,[SP]
 LDRB R5,[R10,#4]
 TEQ R5,#0
 BEQ ARRAYCONSTBINARYADDSTRING3
 LOAD R0,R10,R6,R7
 ADD R6,CLEN,R5
 ADD R1,ARGP,#STRACC+256
 CMP R6,R1
 BCS ERLONG
ARRAYCONSTBINARYADDSTRING2 LDRB R1,[R0],#1
 STRB R1,[CLEN],#1
 SUBS R5,R5,#1
 BNE ARRAYCONSTBINARYADDSTRING2
ARRAYCONSTBINARYADDSTRING3 BL STSTORE
 ADD R4,R4,#5
 ADD R10,R10,#5
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYADDSTRING1
 LDMFD SP!,{CLEN,R10}
 B NXT
ARRAYCONSTBINARYMINUS CMP R1,#5
 BHI ERTYPEARRAY
 BEQ ARRAYCONSTBINARYMINUSFP
 BL PULLTYPE
 BL INTEGY
ARRAYCONSTBINARYMINUSINT LDR R1,[R6],#4
 SUB R1,R0,R1
 STR R1,[R4],#4
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYMINUSINT
 B NXT
ARRAYCONSTBINARYMINUSFP BL PULLTYPE
 BL FLOATY
 STMFD SP!,{R8,R10}
 MOV R10,R4 ;D
 MOV R8,R6 ;S
 BL FPUSH
ARRAYCONSTBINARYMINUSFP1 MOV TYPE,R8
 ADD R8,R8,#5
 BL F1LDA
 MOV TYPE,SP
 BL FXSUB
 MOV TYPE,R10
 ADD R10,R10,#5
 BL F1STA
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYMINUSFP1
 LDMFD SP!,{R0,R1,R8,R10}
 B NXT
ARRAYCONSTBINARYMUL CMP R1,#5
 BHI ERTYPEARRAY
 BEQ ARRAYCONSTBINARYMULFP
 BL PULLTYPE
 BL INTEGY
ARRAYCONSTBINARYMULINT LDR R1,[R6],#4
 [ RRX=1
 MUL R1,R0,R1
 |
 BL MSG
 = 0,"Please ask for a 2u ARM if you want to do this.",0
 ]
 STR R1,[R4],#4
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYMULINT
 B NXT
ARRAYCONSTBINARYMULFP BL PULLTYPE
 BL FLOATY
 STMFD SP!,{R8,R10}
 MOV R10,R4 ;D
 MOV R8,R6 ;S
 BL FPUSH
ARRAYCONSTBINARYMULFP1 MOV TYPE,R8
 ADD R8,R8,#5
 BL F1LDA
 MOV TYPE,SP
 BL FMUL
 MOV TYPE,R10
 ADD R10,R10,#5
 BL F1STA
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYMULFP1
 LDMFD SP!,{R0,R1,R8,R10}
 B NXT
ARRAYCONSTBINARYDIV CMP R1,#5
 BHI ERTYPEARRAY
 BEQ ARRAYCONSTBINARYDIVFP
 BL PULLTYPE
 BL INTEGY
ARRAYCONSTBINARYDIVINT LDR R3,[R6],#4
 MOV R2,R0
 BL ARRAYINTDIV
 STR TYPE,[R4],#4
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYDIVINT
 B NXT
ARRAYCONSTBINARYDIVFP BL PULLTYPE
 BL FLOATY
 STMFD SP!,{R8,R10}
 MOV R10,R4 ;D
 MOV R8,R6 ;S
 BL FPUSH
ARRAYCONSTBINARYDIVFP1 MOV TYPE,R8
 ADD R8,R8,#5
 BL F1LDA
 MOV TYPE,SP
 BL FXDIV
 MOV TYPE,R10
 ADD R10,R10,#5
 BL F1STA
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYDIVFP1
 LDMFD SP!,{R0,R1,R8,R10}
 B NXT
ARRAYPLUSBC LDMFD SP!,{R4,R5}
 MOV R6,#"+"
 MOV R7,R4
 MOV AELINE,R5
 B ARRAYBINARYCONST1
;and the function
SUM STMFD SP!,{R14}
 LDRB R10,[AELINE],#1
 CMP R10,#"("
 BEQ SUMBKT
 SUB AELINE,AELINE,#1
 BL LVBLNK
 BEQ ERARRY
SUM1 SUBS R1,TYPE,#256
 BCC ERARRY
 LDR TYPE,[FACC]
 CMP TYPE,#16
 BCC ERARRZ
SUM2 LDR R6,[TYPE],#4
 CMP R6,#0
 BNE SUM2
 LDR R10,[TYPE],#4
 CMP R1,#5
 BL FCLR
 BEQ SUMFP
 BHI SUMSTRING
SUMINT LDR R1,[TYPE],#4
 ADD FACC,FACC,R1
 SUBS R10,R10,#1
 BNE SUMINT
 B PSINSTK
SUMFP BL F1ADD
 ADD TYPE,TYPE,#5
 SUBS R10,R10,#1
 BNE SUMFP
 B FSINSTK
SUMSTRING ADD CLEN,ARGP,#STRACC
 ADD R7,CLEN,#256
SUMSTRING1 LDRB R0,[TYPE,#4]
 TEQ R0,#0
 BEQ SUMSTRING3
 ADD R5,CLEN,R0
 CMP R5,R7
 BCS ERLONG
 LOAD R1,TYPE,R4,R5
SUMSTRING2 LDRB R3,[R1],#1
 STRB R3,[CLEN],#1
 SUBS R0,R0,#1
 BNE SUMSTRING2
SUMSTRING3 ADD TYPE,TYPE,#5
 SUBS R10,R10,#1
 BNE SUMSTRING1
 MOVS TYPE,#0
 LDMFD SP!,{PC}
SUMBKT BL LVBLNK
 BEQ ERARRY
 BL AESPAC
 CMP R10,#")"
 BNE ERBRA
 B SUM1
; TYPE=R2 DIV R3. Uses r5,r7 also
ARRAYINTDIV EOR R5,R2,R3
 MOVS R2,R2
 RSBMI R2,R2,#0
 MOVS R3,R3
 BEQ ZDIVOR
 RSBMI R3,R3,#0
 MOV R7,R3
 CMP R7,R2,LSR #1
ARRAYINTDIV1 MOVLS R7,R7,LSL #1
 CMPLS R7,R2,LSR #1
 BLS ARRAYINTDIV1
 MOV TYPE,#0
ARRAYINTDIV2 CMP R2,R7
 SUBCS R2,R2,R7
 ADC TYPE,TYPE,TYPE
 MOV R7,R7,LSR #1
 CMP R7,R3
 BCS ARRAYINTDIV2
 TEQ R5,#0
 RSBMI TYPE,TYPE,#0
 MOV PC,R14
;A(LIMI,LIMK)=B(LIMI,LIMJ).C(LIMJ,LIMK)
;R0=[LVC], R1=[LVB], R4=[LVA], TYPE=TYPE!
MATRIXMULTIPLY SUB TYPE,TYPE,#256
 CMP TYPE,#128
 BCS ERTYPEARRAYB
 CMP R4,R1
 CMPNE R4,R0
 BNE MATRIXMULTIPLYNOCOPY
;as a kindness, copy the destination to free space if it is the same as either
;of the sources. Issue whacky error message if this is not possible.
 MOV R5,R4
 MOV R6,R4
MATRIXMULTIPLYDESTSIZE LDR R7,[R6],#4
 TEQ R7,#0
 BNE MATRIXMULTIPLYDESTSIZE
 LDR R7,[R6],#4
 CMP TYPE,#4
 MOVEQ R7,R7,LSL #2
 ADDNE R7,R7,R7,LSL #2 ;number of bytes to move
 SUB R6,R6,R5
 ADD R7,R7,R6
 LDR R6,[ARGP,#FSA]
 ADD R2,R6,R7
 ADD R2,R2,#1024
 CMP R2,SP
 BCS ERMATMULSPACE
MATRIXMULTIPLYCOPY LDR R2,[R5],#4
 STR R2,[R6],#4
 SUBS R7,R7,#4
 BCS MATRIXMULTIPLYCOPY
;set any identical source pointers to the copy
 CMP R4,R1
 LDREQ R1,[ARGP,#FSA]
 CMP R4,R0
 LDREQ R0,[ARGP,#FSA]
MATRIXMULTIPLYNOCOPY STMFD SP!,{R8,R10} ;more temporary registers
 LDR R2,[R4],#4 ;ALIMI
 LDR R3,[R1],#4 ;BLIMI
 LDR R5,[R0],#4 ;CLIMJ
 LDR R6,[R4],#4 ;ALIMK
 LDR R7,[R1],#4 ;BLIMJ
 LDR R10,[R0],#4 ;CLIMK
 CMP R6,#0
 BEQ VECTORMULTIPLY
 CMP R2,R3 ;test LIMI
 CMPEQ R7,R5 ;test LIMJ
 CMPEQ R6,R10 ;test LIMK
 LDR R3,[R4],#8 ;load 0 and skip number of items
 CMPEQ R3,#0
 LDR R3,[R1],#8
 CMPEQ R3,#0
 LDR R3,[R0],#8
 CMPEQ R3,#0
 BNE ERTYPEARRAYC
MATRIXMULTIPLYMAIN CMP TYPE,#5
;at this instant r3,r7,r8,r9,r10,r11,r14 are free
;r4=base of dest; r1=base of left source; r0=base of right source
;r2=LIMI; r5=LIMJ; r6=LIMK
 BEQ MATRIXMULTIPLYFP
 [ RRX=0
 BL MSG
 = 0,"Please ask for a 2u ARM if you want to do this.",0
 ]
MATRIXMULTIPLYINT STMFD SP!,{R0} ;save r source base
 MOV R6,R6,LSL #2 ;LIMK=LIMK*4
;main loop over i
MATRIXMULTIPLYINT1 LDMFD SP,{R0} ;reload r source base
 MOV R11,R6 ;loop count: LIMK*4
;outer loop over k
MATRIXMULTIPLYINT2 MOV R3,#0 ;result
 MOV R14,R1 ;l source
 MOV R7,R0 ;r source
 MOV R8,R5 ;loop count: LIMJ
;inner loop over j
MATRIXMULTIPLYINT3 LDR R9,[R14],#4 ;inner copy of l source
 LDR R10,[R7],R6 ;step inner copy of r source by LIMK*4
 MLA R3,R9,R10,R3
 SUBS R8,R8,#1
 BNE MATRIXMULTIPLYINT3
 STR R3,[R4],#4 ;step destination
 ADD R0,R0,#4 ;step outer r source
 SUBS R11,R11,#4
 BNE MATRIXMULTIPLYINT2
 ADD R1,R1,R5,LSL #2 ;step l source by LIMJ*4
 SUBS R2,R2,#1 ;decrement LIMI directly in main loop
 BNE MATRIXMULTIPLYINT1
 LDMFD SP!,{R0,R8,R10}
 B NXT
MATRIXMULTIPLYFP ADD R5,R5,R5,LSL #2 ;LIMJ'=LIMJ*5
 STMFD SP!,{R0,R1,R2,R4,R5}
 SUB SP,SP,#8
;SP+0 = r source base
;SP+4 = outer loop counter
;SP+8 = r source base (original)
;SP+12= l source base
;SP+16= LIMI
;SP+20= dest base
;SP+24= LIMJ*5
 ADD R11,R6,R6,LSL #2 ;LIMK'=LIMK*5
;main loop over i
MATRIXMULTIPLYFP1 LDR R0,[SP,#8] ;reload r source base
 STR R0,[SP]
 STR R11,[SP,#4] ;loop count: LIMK*5
;outer loop over k
MATRIXMULTIPLYFP2 BL FCLR ;result
 LDR R10,[SP,#12] ;l source
 LDR TYPE,[SP] ;r source
 LDR R8,[SP,#24] ;loop count: LIMJ*5
;inner loop over j
MATRIXMULTIPLYFP3 STMFD SP!,{R0-R3} ;save accumulated value
 MOV R4,TYPE
 MOV TYPE,R10
 ADD R10,R10,#5 ;step inner copy of l source
 BL F1LDA
 MOV TYPE,R4
 BL F1MUL
 ADD TYPE,TYPE,R11 ;step inner copy of r source by LIMK*5
 LDMFD SP!,{R4-R7}
 BL FADDW
 SUBS R8,R8,#5
 BNE MATRIXMULTIPLYFP3
 LDR TYPE,[SP,#20]
 BL F1STA
 ADD TYPE,TYPE,#5
 STR TYPE,[SP,#20] ;step destination
 LDR R0,[SP]
 ADD R0,R0,#5
 STR R0,[SP] ;step outer r source
 LDR R0,[SP,#4]
 SUBS R0,R0,#5
 STRNE R0,[SP,#4]
 BNE MATRIXMULTIPLYFP2
 LDR R0,[SP,#12]
 LDR R1,[SP,#24]
 ADD R0,R0,R1 ;step l source by LIMJ*5
 STR R0,[SP,#12]
 LDR R0,[SP,#16]
 SUBS R0,R0,#1
 STRNE R0,[SP,#16] ;decrement LIMI directly in main loop
 BNE MATRIXMULTIPLYFP1
 ADD SP,SP,#7*4
 LDMFD SP!,{R8,R10}
 B NXT
VECTORMULTIPLY ADD R4,R4,#4 ;skip number of elements
 CMP R7,#0
 BEQ VECTORROWMULTIPLY
 LDR R6,[R1],#8
 CMP R6,#0
 BNE ERTYPEARRAYC
 ADD R0,R0,#4
 MOV R6,#1 ;LIMK=1
 B MATRIXMULTIPLYMAIN
VECTORROWMULTIPLY LDR R6,[R0],#8
 CMP R6,#0
 BNE ERTYPEARRAYC
 ADD R1,R1,#4
 MOV R5,R3 ;move LIMJ
 MOV R6,R10 ;move LIMK
 MOV R2,#1 ;LIMI=1
 B MATRIXMULTIPLYMAIN
 LNK Assembler
