; > Stack ; BASIC stack manipulation .errTypeMis2 jmp errTypeMismatch ; UnstackIntAndCallOp ; =================== .UnstackIntAndCallOp ; On entry, r2/r3/r4=RHS value ; sp=> retaddr, operator, type, b0-b15, b16-b31 ; sp=> retaddr, operator, type, length, string... ; jsr pc,EnsureInteger ; If RHS value float, convert to integer ; UnstackValAndCallOp ; =================== .UnstackValAndCallOp ; sp=> retaddr, operator, type, b0-b15, b16-b31 ; sp=> retaddr, operator, type, length, string... mov 2(sp),r0 ; Get operator to r0 mov (sp)+,r1 ; sp=> operator, type, b0-b15, b16-b31 r1=retaddr mov r1,(sp) ; sp=> retaddr, type, b0-b15, b16-b31 ; sp=> retaddr, type, length, string cmp r0,#ASC"+" beq EvalFuncPlus ; '+' allowed to operate on strings bit r2,2(sp) bmi errTypeMis2 ; Other operations must be .EvalFuncPlus bit #&80,r0 bne EvalFunction ; Dispatch 'AND'..'OR' sub #3,r0 ; Reduce range for '*'..'/','^' bic #&FFF0,r0 ; Reduce to 7..15 ; EvalFunction - dispatch a function token ; ---------------------------------------- .EvalFunction bic #&FF80,r0 ; Reduce range add r0,r0 ; Offset into command table adr FunctionTable,r1 ; Point to command address table add r0,r1 ; Index into command table add (r1),r1 ; Calculate routine address jsr pc,SkipSpaces ; r5=>next char, r0=next char jmp (r1) ; Jump to function routine .UnstackStringDropOp ; On entry, sp=> retaddr, op, type, length, string... mov (sp)+,(sp) ; Overwrite op with return address ; UnstackString - Pop a stacked string ; ==================================== ; On entry, sp=> retaddr, type, length, string... ; On exit, r4=string start ; r3=string length ; r2=type ; r1=preserved ; r0=preserved ; .UnstackString mov sp,r2 ; Point to stack add #6,r2 ; Point to stacked string ; Must prevent SP from being odd adr SV_STRING,r4 ; Point to string buffer mov 4(sp),r3 ; Get length beq UnstackStrDone ; Zero-length string .UnstackStrLp movb (r2)+,(r4)+ ; Copy bytes from stack dec r3 bne UnstackStrLp ; Loop to 'pop' all characters inc r2 bic #1,r2 ; Align stack pointer .UnstackStrDone mov (sp)+,r4 ; Get return address mov 2(sp),r3 ; Get length mov r2,sp ; Update SP mov r4,-(sp) ; Push return address back adr SV_STRING,r4 ; r4=start of string mov #&8000,r2 ; r3=length, r2=string rts pc ; r1=preserved, r0=preserved ; StackValAndOp - Push a value and operator onto stack ; ==================================================== .StackValAndOp tst r2 bpl StackNumAndOp ; StackStringAndOp - Push a string and operator onto stack ; ======================================================== ; On entry, sp=> retaddr ; r4=string start, r3=string length, r0=operation ; On exit, sp=> operation, type, length, string... ; .StackStringAndOp mov (sp)+,r1 ; Get return address mov r3,r2 ; Copy string length to byte count bit #1,r2 ; Odd number of characters? beq StackStrGo inc r2 ; Ensure even number .StackStrGo sub r2,sp ; Drop stack to fit string mov r3,-(sp) ; Stack length mov #&8000,-(sp) ; Stack type mov r0,-(sp) ; Stack operation tst r3 beq StackStrDone ; Zero-length string mov sp,r2 ; Point to top of stack add #6,r2 ; Point to start of string space .StackStrLp movb (r4)+,(r2)+ ; Copy byte to stack dec r3 bne StackStrLp ; Loop to 'push' all characters .StackStrDone jmp (r1) ; Return via r1 ; StackIntAndOp - Push integer and operator onto stack ; ==================================================== ; On entry, r2/r3/r4=current value ; sp=> ; On exit, r2/r3/r4 may be corruputed ; sp=> operator, exponent, b0-b15, b16-b31 ; r0 r2 r4 r3 ; .StackIntAndOp jsr pc,EnsureInteger ; If float, convert to integer .StackNumAndOp ; sp=> retaddr mov r4,-(sp) ; sp=> r4, retaddr mov 2(sp),r4 ; sp=> r4, retaddr r4=retaddr mov r3,2(sp) ; sp=> r4, r3 r4=retaddr mov r2,-(sp) ; sp=> r2, r4, r3 r4=retaddr mov r0,-(sp) ; sp=> r0, r2, r4, r3 r4=retaddr mov r4,pc ; Return