NEW AUTO 3,1 *-------------------------------------- * EXPRESSION CRACKER *------------------------------- EXPR.DEFINED JSR EXPR BMI .1 RTS .1 JMP UNDF *-------------------------------- OPERATOR.CHARS .AS "^!|&<=>/*)], " OPERATOR.CHARS.SIZE .EQ *-OPERATOR.CHARS *-------------------------------- OPERATOR.INDEX .HS 0C.0A.0A.08.0E.10.12.06.04.FF.FF.FF.FF * ^ ! | & < = > / * ) ] , SPC *-------------------------------- OPERATOR.TABLE .DA EXP.SUBTRACT-1 0 FOR -<=> .DA EXP.ADD-1 2 FOR + .DA EXP.MULTIPLY-1 4 FOR * .DA EXP.DIVIDE-1 6 FOR / .DA EXP.AND-1 8 FOR & .DA EXP.ORA-1 A FOR !| .DA EXP.EOR-1 C FOR ^ .DA EXP.LESS-1 E FOR < .DA EXP.EQUAL-1 10 FOR = .DA EXP.GREATER-1 12 FOR > *-------------------------------- ERBA3 JMP ERBA *-------------------------------- EXPR JSR GNNB GET NEXT NON-BLANK BCS ERBA3 NO EXPRESSION ON LINE JSR BACKUP.CHAR.PNTR *-------------------------------- EXP1 JSR ZERO.EXP.VALUE STA EXP.NEW NEW EXPRESSION FLAG = 0 STA EXP.UNDEF ZERO UNDEF FLAG LDX #$40 INIT FWD REF FLAG STX EXP.FWDREF *-------------------------------- EXP2 LDX #0 SET OPERATOR=0 FOR + JSR GNC.UC BCS .3 END OF LINE CMP #'- MINUS BEQ .6 X=0 FOR MINUS OR RELOPS LDX #2 X=2 FOR ADDITION CMP #'+ ADD BEQ .6 LDY EXP.NEW NOT + OR - BEQ .7 BUT IT IS NEW EXPR LDX #OPERATOR.CHARS.SIZE-1 .1 LDA OPERATOR.CHARS,X CMP CURRENT.CHAR BEQ .2 DEX BPL .1 JMP ERBA *---FOUND OP OR TERM CHAR-------- .2 LDA OPERATOR.INDEX,X BPL .5 ...OPERATOR *---END OF EXPRESSION----------- JSR BACKUP.CHAR.PNTR .3 LDY EXP.UNDEF UNDEF FLAG BPL .4 JSR ZERO.EXP.VALUE TYA RECOVER UNDEF STATUS .4 RTS *-------------------------------- .5 TAX .6 JSR GNC.UC .7 INC EXP.NEW NOT A NEW EXPRESSION ANYMORE LDA OPERATOR.TABLE+1,X PHA LDA OPERATOR.TABLE,X PHA *------------------------------- * GET OPERAND *------------------------------- GET.OPERAND JSR ZERO.SYM.VALUE LDA CURRENT.CHAR CMP #$30 FIRST CHAR OF OPERAND BCC .3 PUNCTUATION CMP #$3A BCS .2 MIGHT BE LETTER, TRY LABEL JSR DECN CONVERT DECIMAL NUMBER .15 JMP BACKUP.CHAR.PNTR *---TRY A LABEL------------------ .2 JSR PACK TRY LABEL BCC .4 NO GOOD JSR STSRCH LOOK UP THE VALUE LDY #6 UPDATE FWD REF FLAG >SYM LDA,STPNTR AND EXP.FWDREF STA EXP.FWDREF BCC .1 DEFINED LABEL ROR EXP.UNDEF UNDEFINED, MAKE FLAG NEGATIVE .1 RTS *---TRY LOCAL LABEL-------------- .3 CMP #'. BEQ .2 LOCAL LABEL *---TRY CONSTANTS---------------- LDX #3 3-->HEX CONSTANT CMP #'$ BEQ .5 HEX CONSTANT DEX 2-->OCT CONSTANT CMP #'&' BEQ .5 ...OCTAL LDX #0 0-->BIN CONSTANT CMP #'% BINARY CONSTANT BEQ .5 ...BINARY *---TRY LITERALS----------------- CMP #'' (X = 0) BEQ .6 LITERAL CMP #'" LITERAL WITH HIGH BIT SET BEQ .9 *---TRY STAR--------------------- CMP #'* BNE .4 ...NONE OF THE ABOVE, ERROR LDX #3 VALUE IS CURRENT LOCATION .7 LDA ORGN,X STA SYM.VALUE,X DEX BPL .7 RTS *---INVALID OPERAND-------------- .4 JMP ERBA BAD ADDRESS ERROR *---HEX/OCT/BIN CONSTANT-------- .5 JSR HEX.OCT.BIN.DGT $ABCD, &777, %1010 BCC .4 NO, ERROR BAD ADDRESS .8 JSR HEX.OCT.BIN.DGT.1 GET ANOTHER DIGIT BCS .8 BCC .15 ...ALWAYS *---TICK & QUOTE LITERALS------- .9 LDX #$80 HIBIT=1 .6 STX SYM.VALUE STA DGTCNT SAVE ' OR " FOR OPTIONAL TERMCHAR JSR GNC GET FOLLOWING CHAR BCS .4 END OF LINE ORA SYM.VALUE SET HIGH BIT STA SYM.VALUE JSR GNC SEE IF CLOSING QUOTE CMP DGTCNT (IT IS OPTIONAL) BNE .15 NO, BACK UP CHAR PNTR RTS *------------------------------- * IF NEXT CHAR IS VALID DIGIT, * APPEND IT TO CURRENT VALUE * * (X) DETERMINES BASE: 0-->2, 2-->8, 3-->16 *------------------------------- HEX.DIGIT LDX #3 HEX.OCT.BIN.DGT STX BASE.INDEX HEX.OCT.BIN.DGT.1 .1 JSR GNC.UC IGNORE CASE CMP #'.' ALLOW PERIODS BEQ .1 ...BUT IGNORE THEM EOR #$30 CMP #$0A BCC .3 ...0-9, TEXT VALIDITY ADC #$88 ...MIGHT BE A...F .2 CMP #$FA BCC .5 NOT A-F EITHER, RETURN CARRY CLEAR AND #$0F TRIM HEX A...F .3 LDX BASE.INDEX CMP BASE.TABLE,X CHECK REAL RANGE BCS .2 ...NOT VALID, CLR CARRY WITH 'CMP #$FA' PHA SAVE DIGIT .4 JSR ASL.SYM.VALUE DEX MAKE ROOM FOR DIGIT BPL .4 PLA GET DIGIT ORA SYM.VALUE MERGE WITH PREVIOUS STA SYM.VALUE SEC FLAG GOT A DIGIT .5 RTS *-------------------------------- BASE.TABLE .DA #2,#2,#8,#16 ASL.SYM.VALUE CLC ROL.SYM.VALUE ROL SYM.VALUE ROL SYM.VALUE+1 ROL SYM.VALUE+2 ROL SYM.VALUE+3 RTS *-------------------------------- ZERO.EXP.VALUE LDA #0 STA EXP.VALUE STA EXP.VALUE+1 STA EXP.VALUE+2 STA EXP.VALUE+3 RTS *-------------------------------- ZERO.EXP.VALUE64 LDA #0 STA EXP.VALUE64 STA EXP.VALUE64+1 STA EXP.VALUE64+2 STA EXP.VALUE64+3 RTS *-------------------------------- ZERO.SYM.VALUE LDA #0 STA SYM.VALUE STA SYM.VALUE+1 STA SYM.VALUE+2 STA SYM.VALUE+3 RTS *-------------------------------- EXP.AND LDX #3 .1 LDA EXP.VALUE,X AND SYM.VALUE,X STA EXP.VALUE,X DEX BPL .1 JMP EXP2 *-------------------------------- EXP.ORA LDX #3 .1 LDA EXP.VALUE,X ORA SYM.VALUE,X STA EXP.VALUE,X DEX BPL .1 JMP EXP2 *-------------------------------- EXP.EOR LDX #3 .1 LDA EXP.VALUE,X EOR SYM.VALUE,X STA EXP.VALUE,X DEX BPL .1 JMP EXP2 *-------------------------------- EXP.ADD CLC PLUS LDX #-4 .1 LDA EXP.VALUE+4,X ADC SYM.VALUE+4,X STA EXP.VALUE+4,X INX BNE .1 JMP EXP2 *-------------------------------- EXP.SUBTRACT JSR EXP.SUBTRACTION JMP EXP2 *-------------------------------- EXP.SUBTRACTION SEC LDX #-4 .7 LDA EXP.VALUE+4,X SBC SYM.VALUE+4,X STA EXP.VALUE+4,X INX BNE .7 RTS *-------------------------------- EXP.LESS JSR EXP.SUBTRACTION LDA EXP.VALUE+3 BMI EXP.TRUE EXP.FALSE CLC EXP.TRUE.OR.FALSE JSR ZERO.EXP.VALUE ROL EXP.VALUE JMP EXP2 *-------------------------------- EXP.EQUAL JSR EXP.SUBTRACTION JSR TEST.EXP.VALUE BNE EXP.FALSE EXP.TRUE SEC BCS EXP.TRUE.OR.FALSE *-------------------------------- TEST.EXP.VALUE.ZP LDA #0 .HS 2C TEST.EXP.VALUE LDA EXP.VALUE ORA EXP.VALUE+1 ORA EXP.VALUE+2 ORA EXP.VALUE+3 RTS *-------------------------------- EXP.GREATER JSR EXP.SUBTRACTION JSR TEST.EXP.VALUE BEQ EXP.FALSE LDA EXP.VALUE+3 LOOK AT SIGN BIT BMI EXP.FALSE BPL EXP.TRUE *------------------------------- EXP.DIVIDE JSR EXP.DIVISION JMP EXP2 *-------------------------------- EXP.DIVISION JSR ZERO.EXP.VALUE64 LDY #32 32 BITS .1 ASL EXP.VALUE SHIFT DIVIDEND/QUOTIENT LEFT ROL EXP.VALUE+1 ROL EXP.VALUE+2 ROL EXP.VALUE+3 ROL EXP.VALUE64 SHIFT PARTIAL DIVIDEND LEFT ROL EXP.VALUE64+1 ROL EXP.VALUE64+2 ROL EXP.VALUE64+3 SEC SUBTRACT DIVISOR FROM PARTIAL DIVIDEND LDA EXP.VALUE64 SBC SYM.VALUE PHA SAVE LO-BYTE OF DIFFERENCE ON STACK LDA EXP.VALUE64+1 SBC SYM.VALUE+1 PHA LDA EXP.VALUE64+2 SBC SYM.VALUE+2 PHA LDA EXP.VALUE64+3 SBC SYM.VALUE+3 BCC .2 REMAINDER TOO SMALL INC EXP.VALUE SET BIT IN QUOTIENT STA EXP.VALUE64+3 HI-BYTE OF REMAINDER PLA RETRIEVE NEXT BYTE OF REMAINDER STA EXP.VALUE64+2 PLA STA EXP.VALUE64+1 PLA STA EXP.VALUE64 BCS .3 .2 PLA STACK BACK TO NORMAL PLA PLA .3 DEY NEXT BIT BNE .1 RTS *-------------------------------- EXP.MULTIPLY JSR ZERO.EXP.VALUE64 LDY #32 32-BIT MULTIPLY .1 LDA EXP.VALUE CHECK LSB OF MULTIPLIER LSR BCC .2 IF 0, DON'T ADD MULTIPLICAND CLC ADD MULTIPLICAND LDA EXP.VALUE64 ADC SYM.VALUE STA EXP.VALUE64 LDA EXP.VALUE64+1 ADC SYM.VALUE+1 STA EXP.VALUE64+1 LDA EXP.VALUE64+2 ADC SYM.VALUE+2 STA EXP.VALUE64+2 LDA EXP.VALUE64+3 ADC SYM.VALUE+3 STA EXP.VALUE64+3 .2 ROR EXP.VALUE64+3 ROR EXP.VALUE64+2 ROR EXP.VALUE64+1 ROR EXP.VALUE64 ROR EXP.VALUE+3 ROR EXP.VALUE+2 ROR EXP.VALUE+1 ROR EXP.VALUE DEY BNE .1 JMP EXP2 *------------------------------- * MGO COMMAND *------------------------------- MGO JSR EXPR.DEFINED CRACK EXPRESSION JMP (EXP.VALUE) ENTER USER'S PROGRAM *-------------------------------- * VAL COMMAND *-------------------------------- VAL JSR EXPR.DEFINED GET VALUE OF EXPRESSION LDA #'$' JSR CHO JSR P.EXP.VALUE LDA #'=' JSR CHO JSR ZERO.SYM.VALUE TAX X=0 LDA #10 STA SYM.VALUE .1 JSR EXP.DIVISION LDA EXP.VALUE64 REMAINDER PHA INX JSR TEST.EXP.VALUE BNE .1 .2 PLA ORA #'0' JSR CHO DEX BNE .2 JMP CRLF *-------------------------------------- MAN SAVE usr/src/scmasm.31/scmasm.s.exp LOAD usr/src/scmasm.31/scmasm.s ASM