📄 runtime2.asm
字号:
* title RUNTIME2
* page
*
*
RTRON: EQU *
LDAA #$FF ; SET FLAG TO TURN TRACE MODE ON.
STAA TRFLAG ; PUT IT IN THE FLAG BYTE.
RTRON1: RTS ; BACK TO THE INTERPRET LOOP.
*
*
RTROFF: EQU *
CLR TRFLAG ; TURN THE TRACE MODE OFF.
RTS ; BACK TO THE INTERPRET LOOP.
*
*
RSLEEP: EQU *
SEI ; DON'T ALLOW AN INTERRUPT TO BRING US OUT OF THE SLEEP MODE.
TPA ; GET THE CONDITION CODE REGISTER.
ANDA #$7F ; CLEAR THE STOP BIT
TAP ; TRANSFER THE RESULT BACK TO THE CCR.
STOP ; HALT THE CPU.
TPA ; ON EXIT FROM THE STOP MODE, GET THE CCR.
ORAA #$80 ; DISABLE THE STOP INSTRUCTION.
TAP ; TRANSFER THE RESULT BACK TO THE CCR.
CLI ; ALLOW INTERRUPTS.
RTS ; RETURN TO WHAT WE WERE DOING.
*
*
RPRINT: EQU *
JSR CHCKDEV ; GO CHECK FOR ALTERNATE OUTPUT DEVICE.
LDAA 0,Y ; GET FIRST TOKEN.
CMPA #EOLTOK ; IS IT AN EOL TOKEN?
BEQ RPRINT1 ; YES. JUST PRINT A CR/LF.
CMPA #MEOLTOK ; IS IT A MID EOL TOKEN?
BNE RPRINT2 ; NO. GO PRINT A STRING OR NUMBER.
RPRINT1: JSR NL ; YES. JUST PRINT A CR/LF.
CLR DEVNUM ; GO BACK TO DEVICE #0.
RTS ; BACK TO MAIN INTERPRET LOOP.
RPRINT2: CMPA #SCONTOK ; IS IT A STRING CONSTANT?
BNE RPRINT3 ; NO. GO CHECK FOR A "PRINT FUNCTION".
PSHY
LDAB #2 ; COMPENSATE FOR CONSTANT & LENGTH BYTE.
ADDB 1,Y ; ADD IN LENGTH BYTE.
ABY ; POINT BEYOND PROMPT.
PULX ; GET POINTER INTO X.
INX ; POINT TO LENGTH BYTE.
LDAB 0,X ; GET IT.
SUBB #2 ; SUBTRACT OUT THE DELIMETER COUNT.
INX ; POINT TO STRING.
INX
JSR OUTSTR ; GO PRINT THE STRING.
BRA RPRINT4 ; GO DO NEXT EXPRESSION.
RPRINT3: CMPA #FUNCTFLG ; IS IT A FUNCTION?
BNE RPRINT10 ; NO. GO EVALUATE A NUMERIC EXPRESSION.
LDAA 1,Y ; GET THE FUNCTION TYPE.
CMPA #TABTOK ; IS IT A TAB?
BNE RPRINT11 ; NO GO CHECK FOR "CHR$".
JSR RTAB ; GO DO TAB.
BRA RPRINT4 ; GO SEE IF THERE'S MORE TO PRINT.
RPRINT11: CMPA #CHRTOK ; IS IT THE CHR$ FUNCTION.
BNE RPRINT12 ; NO. GO CHECK FOR HEX().
JSR RCHRS ; YES. GO DO CHR$.
BRA RPRINT4 ; GO SEE IF THERE'S MORE TO PRINT.
RPRINT12: CMPA #HEXTOK ; IS IT THE HEX() FUNCTION?
BNE RPRINT10 ; NO. GO DO A NUMERIC EXPRESSION.
JSR RHEX ; YES. GO PRINT THE NUMBER AS HEX.
BRA RPRINT4 ; GO SEE IF THERE'S MORE TO PRINT.
RPRINT10: CMPA #HEX2TOK ; IS IT THE HEX2() FUNCTION?
BNE RPRINT14 ; NO. GO DO A NUMERIC EXPRESSION.
JSR RHEX2 ; YES GO PRINT A NUMBER >=255 AS 2 HEX BYTES.
BRA RPRINT4 ; GO SEE IF THERE'S MORE TO PRINT.
RPRINT14: JSR DONEXP ; GO DO A NUMERIC EXPRESSION.
JSR PULNUM ; GET THE NUMBER OFF THE NUMERIC STACK.
JSR OUTDECI ; PRINT IT.
LDAA #SPC ; PUT A TRAILING SPACE AFTER ALL NUMBERS.
JSR OUTBYTE ; PRINT IT.
RPRINT4: JSR RSKIPSPC ; SKIP SPACES.
LDAA 0,Y ; GET SEPERATOR CHARACTER.
CMPA #COMMATOK ; IS IT A COMMA?
BEQ RPRINT5 ; NO.
CMPA #SEMITOK ; IS IT A SEMICOLIN?
BNE RPRINT6 ; NO. MUST BE AN EOLTOK.
INY ; DO NOTHING BUT BUMP THE IP.
BRA RPRINT7 ; GO CHECK FOR EOL AFTER COMMA OR SEMICOLIN.
RPRINT5: INY ; BUMP IP PAST THE COMMATOK.
LDAB PRINTPOS ; YES. "TAB" TO NEXT PRINT FIELD.
ANDB #$07 ; MASK OFF ALL BUT THE FIELD WIDTH.
NEGB ; MAKE IT NEGATIVE.
ADDB #8 ; ADD IN THE FIELD WIDTH. ARE WE ON A FIELD BOUND?
BEQ RPRINT7 ; YES. GO CHECK FOR AN EOL.
LDAA #SPC ; NO. GET A SPACE & PRINT TILL WE GET THERE.
RPRINT8: JSR OUTBYTE ; PRINT A SPACE.
DECB ; DECREMENT THE COUNT. ARE WE DONE?
BNE RPRINT8 ; NO. KEEP GOING.
RPRINT7: JSR RSKIPSPC ; SKIP ANY SPACES.
LDAA 0,Y ; GET THE NEXT TOKEN IN THE LINE.
CMPA #EOLTOK ; IS IT AN EOL TOKEN?
BEQ RPRINT9 ; YES. DONT DO A CR/LF AFTER A COMMA OR SEMI.
CMPA #MEOLTOK ; NO. IS IT A MID EOL?
BEQ RPRINT9 ; SAME AS BEFORE.
JMP RPRINT2 ; IF NEITHER, GO PRINT THE NEXT EXPRESSION.
RPRINT6: JSR NL ; DO A CR/LF IF EOL OR MIDEOL FOLLOWS EXPRESSION.
RPRINT9: CLR DEVNUM ; GO BACK TO DEVICE #0.
RTS ; GO DO NEXT LINE.
*
*
RTAB: EQU *
BSR PFUNCOM ; GO GET ARG. & CHECK MAGNITUDE. IS ARG. OK?
BEQ RTAB1 ; YES. GO DO TAB.
LDAA #TABARGER ; NO. ERROR.
RTAB3: JMP RPTRERR ; REPORT ERROR.
RTAB1: CMPB PRINTPOS ; ARE WE ALREADY PAST THE "TAB" POSITION?
BLS RTAB2 ; YES. DONE.
LDAA #SPC ; GET A SPACE.
JSR OUTBYTE ; PRINT IT.
BRA RTAB1
RTAB2: RTS ; RETURN.
*
*
RCHRS: EQU *
BSR PFUNCOM ; GO GET ARG. & CHECK MAGNITUDE. IS ARG. OK?
BEQ RCHRS1 ; YES. GO DO TAB.
LDAA #CHRARGER ; NO. ERROR.
BRA RTAB3 ; REPORT ERROR.
RCHRS1: TBA ; PUT BYTE INTO A
JMP OUTBYTE ; PRINT THE BYTE & RETURN.
*
*
RHEX2: EQU *
BSR PFUNCOM ; GO GET ARG. & CHECK MAGNITUDE. IS ARG. OK?
BEQ RHEX1 ; YES. GO PRINT 2 HEX CHARACTERS & RETURN.
LDAA #HEX2AERR ; NO. ARG. MUST BE >=0 & <=255.
BRA RTAB3 ; GO REPORT ERROR.
*
*
RHEX: EQU *
BSR PFUNCOM ; GO DO COMMON CODE FOR PRINT FUNCTIONS
BSR PRNT2HEX ; GO PRINT 2 HEX CHARACTERS.
RHEX1: TBA ; PUT LOWER BYTE IN A.
* ; FALL THRU TO PRINT 2 HEX CHARACTERS & RETURN.
*
*
PRNT2HEX: EQU *
PSHA ; SAVE THE CHARACTER.
BSR PRNTHXL ; PRINT THE LEFT HEX NYBBLE.
PULA ; GET BYTE BACK.
BRA PRNTHXR ; PRINT RIGHT NYBBLE & RETURN.
*
*
PRNTHXL: LSRA ; GET UPPER NYBBLE INTO LOWER ONE.
LSRA
LSRA
LSRA
PRNTHXR: ANDA #$0F ; MASK OFF UPPER NYBBLE.
ADDA #$30 ; MAKE IT A HEX NUMBER.
CMPA #$39 ; IS IT?
BLS PRNTHXR1 ; YES. PRINT IT.
ADDA #$07 ; NO. MAKE IT A HEX LETTER.
PRNTHXR1: JMP OUTBYTE ; PRINT IT & RETURN.
*
*
PFUNCOM: EQU *
LDAB #3 ; POINT PAST FUNCTION FLAG, FUNCTION TOKEN, &
ABY ; OPEN PAREN.
JSR DONEXP ; GO GET POSITION TO TAB TO.
INY ; BUMP IP PAST CLOSING PAREN.
JSR PULNUM ; GET OPERAND OFF STACK.
TSTA ; CHECK THAT OPERAND IS >0 & <=255 FOR FUNCTIONS
* ; THAT REQUIRE IT.
RTS ; RETURN.
*
*
*
RDIM: EQU *
LDAA 0,Y ; GET VARIABLE FLAG/TYPE.
BITA #$10 ; IS IT A SUBSCRIPTED VARIABLE?
BNE RDIM1 ; YES. GO DIMENSION IT.
LDAA #NOSUBERR ; NO. GET ERROR.
RDIM3: JMP RPTRERR ; GO REPORT THE ERROR.
RDIM1: LDD 1,Y ; GET THE OFFSET INTO THE DICTIONARY.
ADDD VARBEGIN ; ADD IN THE START OF THE DICTIONARY.
XGDX ; PUT THE ADDRESS INTO X.
LDD 3,X ; GET THE POINTER TO THE STORAGE. BEEN DIMENSIONED?
BEQ RDIM2 ; NO. GO DIMENSION IT.
LDAA #REDIMERR ; YES. ERROR.
BRA RDIM3
RDIM2: PSHX ; SAVE THE POINTER TO THE DICTIONARY.
LDAB #4 ; POINT TO 1ST TOKEN IN EXPRESSION.
ABY
JSR DONEXP ; EVALUATE THE SUBSCRIPT.
INY ; PASS UP THE CLOSING PAREN.
PULX ; RESTORE POINTER TO DICTIONARY.
LDD STRASTG ; GET THE DYNAMIC MEMORY POOL POINTER.
STD 3,X ; PUT THE POINTER IN THE DICTIONARY ENTRY.
ADDD #2 ; UP THE POINTER.
STD STRASTG ; SAVE NEW POINTER FOR NOW.
JSR PULNUM ; GET SUBSCRIPT OFF OF NUMERIC STACK.
BPL RDIM8 ; ONLY POSITIVE SUBSCRIPTS ALLOWED.
LDAA #NEGSUBER ; NEGATIVE NUMBER.
BRA RDIM9 ; REPORT ERROR.
RDIM8: PSHX
LDX 3,X ; GET POINTER TO STORAGE.
STD 0,X ; PUT MAX SUBSCRIPT IN POOL STORAGE.
ADDD #1 ; COMPENSATE FOR "0" SUBSCRIPT.
PULX ; RESTORE POINTER TO DICTIONARY ENTRY.
LSLD ; MULT. BY 2 (2 BYTES/INTEGER).
ADDD STRASTG ; ADD IN CURRENT POINTER TO POOL.
CPD STRASTG ; WAS THE SUBSCRIPT SO BIG WE WRAPPED AROUND?
BLS RDIM4 ; YES. ERROR.
CPD VARMEND ; DO WE HAVE ENOUGH MEMORY?
BLS RDIM5 ; YES.
RDIM4: LDAA #OMEMERR ; NO. ERROR.
RDIM9: JMP RPTRERR ; GO REPORT THE ERROR.
RDIM5: STD STRASTG ; SAVE POINTER.
LDX 3,X ; POINT TO START OF STORAGE.
INX
INX ; POINT PAST THE SUBSCRIPT LIMIT.
RDIM6: CLR 0,X ; CLEAR THE STORAGE.
INX ; POINT TO THE NEXT LOCATION.
CPX STRASTG ; ARE WE DONE?
BNE RDIM6 ; NO. KEEP GOING.
JSR RSKIPSPC ; SKIP SPACES.
LDAA 0,Y ; GET THE NEXT CHARACTER.
CMPA #EOLTOK ; ARE WE AT THE END OF THE LINE.
BEQ RDIM7 ; YES.
INY ; BUMP IP PAST THE COMMA.
JSR RSKIPSPC ; SKIP SPACES.
BRA RDIM ; DO DIMENSION THE NEXT VARIABLE.
RDIM7: RTS ; BACK TO MAIN INTERPRET LOOP.
*
*
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -