?? runtime1.asm
字號:
* title RUNTIME1
* page
*
*
RREM: EQU * ; NON-EXECUTIBLE STATEMENT JUST SKIP IT.
RDATA: EQU *
LDAB 0,Y ; GET LENGTH OF REMARK OR DATA LINE.
ABY ; POINT TO THE EOLTOK.
RTS ; RETURN.
*
*
*
*
RLET: EQU *
LDAA 0,Y ; GET VARIABLE FLAG.
BSR RVARPTR ; GET POINTER TO ASIGNMENT VARIABLE.
* PSHD SAVE POINTER TO VARIABLE.
PSHB
PSHA
INY ; PUT IP PAST THE "=" TOKEN.
JSR DONEXP ; EVALUATE THE EXPRESSION.
JSR PULNUM ; GET VALUE INTO D.
PULX ; POINT TO THE DICTIONARY ENTRY.
STD 0,X ; STORE VALUE.
RTS ; BACK TO MAIN INTERPRET LOOP.
*
*
RVARPTR: LDAA 0,Y ; GET VARIABLE FLAG.
BITA #$02 ; IS IT A STRING VARIABLE?
BNE RVARPTR2 ; YES. GO GET POINTER FOR A STRING DESCRIPTOR.
BITA #$10 ; IS IT A NUMERIC ARRAY VARIABLE?
BNE RVARPTR1 ; YES. GO CALCULATE THE SUBSCRIPT.
RVARPTR3: LDD 1,Y ; GET THE OFFSET TO THE DICTIONARY ENTRY.
ADDD VARBEGIN ; ADD IN THE START ADDRESS OF THE DCTIONARY.
ADDD #3 ; MAKE POINTER POINT TO THE ACTUAL STORAGE LOCATION
PSHB ; SAVE B.
LDAB #3 ; POINT TO THE FIRST ELEMENT PAST THE VARIABLE.
ABY
PULB ; RESTORE B.
RTS
RVARPTR1: EQU *
JSR CALCSUB ; GO GET BASE ADDR & EVALUATE SUBSCRIPT EXPRESSION.
PSHX ; PUSH BASE ADDRESS ONTO STACK.
TSX ; POINT TO IT.
LSLD ; MULT THE SUBSCRIPT BY THE # OF BYTES/ELEMENT.
RVARPTR4: ADDD 0,X ; GET ADDRESS OF ELEMENT.
PULX ; RESTORE X.
RTS ; RETURN.
RVARPTR2: EQU *
BITA #$10 ; IS IT A STRING ARRAY?
BEQ RVARPTR3 ; NO. JUST GO GET POINTER TO DESCRIPTOR.
JSR CALCSUB ; GET BASE ADDR. & CALC SUBSCRIPT.
PSHX ; SAVE THE BASE ADDRESS.
* PSHD SAVE THE SUBSCRIPT VALUE.
PSHB
PSHA
TSX ; POINT TO THE VALUES.
LSLD ; MULT BY 2.
ADDD 0,X ; MULT BY 3.
INS ; GET RID OF SUBSCRIPT VALUE.
INS
TSX ; POINT TO BASE ADDRESS.
BRA RVARPTR4
*
*
*
*
RGOTO: EQU *
TST IMMID ; DID WE ENTER HERE FROM THE IMMIDIATE MODE?
BEQ RGOTO7 ; NO. JUST GO DO A GOTO.
LDD BASEND ; YES. SET ADRNXLIN TO END OF PROGRAM SO THE
STD ADRNXLIN ; SEARCH STARTS AT THE FIRST LINE.
RGOTO7: LDX ADRNXLIN ; POINT TO THE START OF THE NEXT LINE.
CPX BASEND ; IS THIS THE LAST LINE OF THE PROGRAM?
BNE RGOTO1 ; NO. SEARCH STARTING AT THE NEXT LINE.
RGOTO3: LDX BASBEG ; YES. POINT TO THE START OF THE BASIC PROGRAM.
BRA RGOTO2
RGOTO1: LDD 0,X ; GET THE NEXT LINE NUMBER IN THE PGM.
CPD 1,Y ; IS IT > THE LINE NUMBER WE ARE TO "GOTO"?
BHI RGOTO3 ; YES. START THE SEARCH AT THE BEGINING.
RGOTO2: LDD 0,X ; GET THE NEXT LINE NUMBER INTO D.
CPD 1,Y ; IS THIS THE CORRECT LINE?
BEQ RGOTO4 ; YES. "GOTO" THE NEW LINE.
BLO RGOTO5 ; NO. IS IT LESS THAN THE "TARGET LINE"?
RGOTO6: LDAA #LNFERR ; NO. THE LINE MUST NOT EXIST.
JMP RPTRERR ; REPORT THE ERROR & RETURN TO MAIN LOOP.
RGOTO5: LDAB 2,X ; GET THE LENGTH OF THIS LINE.
ABX ; POINT TO THE START OF THE NEXT LINE.
CPX BASEND ; DID WE HIT THE END OF THE PROGRAM?
BEQ RGOTO6 ; YES. THE LINE DOESN'T EXIST.
BRA RGOTO2 ; NO. GO SEE IF THIS IS THE CORRECT LINE.
RGOTO4: XGDX ; MAKE IT THE NEW IP.
XGDY
TST IMMID
BEQ RGOTO8
CLR IMMID
RGOTO9: JMP CRUN1
RGOTO8: INS
INS
BRA RGOTO9
*
*
RGOSUB: EQU *
PSHY ; SAVE THE I.P. TO THE LINE NUMBER.
TST IMMID ; DID WE GET HERE FROM THE IMMIDIATE MODE?
BEQ RGOSUB3 ; NO. GO DO A NORMAL GOSUB.
LDY BASEND ; YES. MAKE RETURN POINT TO THE LAST EOL TOKEN
DEY ; IN THE PROGRAM.
BRA RGOSUB2 ; GO PUT IT ON THE ARGUMENT STACK.
RGOSUB3: LDAB #3 ; BYPASS THE LINE NUMBER.
ABY
RGOSUB2: JSR RSKIPSPC ; SKIP SPACES AFTER THE LINE NUMBER.
LDX GOSTACK ; GET THE GOSUB STACK POINTER.
DEX ; POINT TO THE NEXT ENTRY ON THE STACK.
DEX
CPX EGOSTK ; OUT OF STACK SPACE?
BHS RGOSUB1 ; NO. GO PUSH THE "RETURN ADDRESS" ON THE STACK.
LDAA #GOSOVERR ; YES. GET THE ERRCODE.
JMP RPTRERR ; GO REPORT THE ERROR.
RGOSUB1: STX GOSTACK ; SAVE THE "GOSUB" STACK POINTER.
STY 0,X ; PUT THE RETURN ADDRESS ON THE STACK.
PULY ; GET THE POINTER TO THE LINE NUMBER.
JMP RGOTO ; GO DO A "GOTO".
*
*
RRETURN: EQU *
LDX GOSTACK ; GET THE GOSUB STACK POINTER.
CPX STGOSTK ; IS THERE A RETURN ADDRESS ON THE GOSUB STACK?
BNE RRETURN1 ; YES. GO RETURN.
LDAA #RWOGERR ; NO. RETURN W/O GOSUB ERROR.
JMP RPTRERR ; REPORT THE ERROR.
RRETURN1: LDY 0,X ; GET THE RETURN ADDRESS IN THE IP.
INX ; REMOVE THE ADDRESS FROM THE STACK.
INX
STX GOSTACK ; SAVE THE STACK POINTER.
RTS ; BACK TO THE MAIN INTERPRET LOOP.
*
*
RSTOP: EQU *
LDX #STOPSTR
JSR PL
LDD CURLINE
JSR OUTDECI
STY IPSAVE
BRA REND1
REND: EQU *
JSR NL
LDAA #1
STAA CONTFLAG
REND1: LDD #0
STD CURLINE
JMP MAINW
*
*
STOPSTR: FCB $0A,$0D
FCC "STOPPED AT LINE # "
FCB 0
*
*
RWHILE: EQU *
LDX WHSTACK ; GET THE WHILE STACK POINTER.
DEX ; POINT TO THE NEXT STACK LOCATION.
DEX
CPX EWHSTK ; ARE WE AT THE END OF THE STACK?
BHS RWHILE4 ; NO. GO STACK IT.
LDAA #WHSOVERR ; YES. WHILE STACK OVER FLOW.
JMP RPTRERR ; REPORT THE ERROR.
RWHILE4: STX WHSTACK ; SAVE THE WHILE STACK POINTER.
STY 0,X ; PUT IT ON THE STACK.
LDAB #$01 ; GET THE WHILE COUNT INTO B. (FOR NESTED WHILE'S)
RWHILE3: PSHB
LDY ADRNXLIN ; GET THE ADDRESS OF THE NEXT LINE.
BNE RWHILE2
RTS
RWHILE2: PSHY ; SAVE THE IP.
CPY BASEND ; ARE WE AT THE END OF THE PROGRAM?
BEQ REND ; YES. DO AN END.
LDX ADRNXLIN ; NO. GET THE ADDRESS OF THE NEXT LINE IN X.
LDAB 2,X ; GET THE LENGTH OF THIS LINE.
ABX ; POINT TO THE START OF THE NEXT LINE.
STX ADRNXLIN ; SAVE IT.
LDAB #3 ; POINT PAST THE LINE NUMBER & LINE LENGTH.
ABY
JSR RSKIPSPC ; SKIP ANY SPACES.
LDAA 0,Y ; GET THE KEYWORD TOKEN.
PULY ; RESTORE THE IP.
PULB ; GET THE NESTED WHILE COUNT.
CMPA #WHILETOK ; IS IT ANOTHER WHILE?
BNE RWHILE1 ; NO. GO CHECK FOR ENDWH.
INCB ; YES. UP THE NESTED WHILE COUNT.
RWHILE1: CMPA #ENDWHTOK ; IS IT THE END WHILE STATEMENT?
BNE RWHILE3 ; NO. GO LOOK AT THE NEXT LINE.
DECB ; YES. IS IT THE CORRECT 'ENDWH'?
BNE RWHILE3 ; NO. LOOK FOR ANOTHER ONE.
JMP RGOTO8 ; BACK TO INTERPRET LOOP.
*
*
*
*
RENDWH: EQU *
LDX WHSTACK ; GET THE WHILE STACK POINTER.
CPX STWHSTK ; HAS A WHILE STATEMENT BEEN EXECUTED?
BNE RENDWH1 ; YES. GO GET THE ADDRESS OF THE WHILE STATEMENT.
LDAA #ENDWHERR ; NO. GET ENDWHILE ERROR.
JMP RPTRERR ; REPORT THE ERROR.
RENDWH1: PSHY ; SAVE THE IP IN CASE THE WHILE TEST FAILS.
LDY 0,X ; GET THE IP POINTER TO THE WHILE EXPRESSION.
JSR DONEXP ; YES. GO EVALUATE A NUMERIC EXPRESSION.
JSR PULNUM ; GET RESULT OFF NUMERIC STACK. IS IT TRUE?
BNE RENDWH3 ; YES. GO EXECUTE CODE BETWEEN WHILE & ENDWH.
PULY ; NO. GET THE ADDRESS OF THE NEXT LINE/STATEMENT.
LDX WHSTACK ; GET WHILE STACK POINTER.
INX ; TAKE ADDRESS OFF OF WHILE STACK.
INX
STX WHSTACK ; SAVE STACK POINTER.
BRA RENDWH5 ; GO TO INTERPRET LOOP.
RENDWH3: INS ; REMOVE POINTER TO STATEMENT AFTER "ENDWH"
INS ; FROM STACK.
RENDWH5: RTS ; GO EXECUTE LINES TILL "ENDWH".
*
*
RON: EQU *
JSR DONEXP ; GO EVALUATE THE EXPRESSION.
JSR RSKIPSPC ; SKIP SPACES AFTER EXPRESSION.
LDAA 0,Y ; GET EITHER "GOTO" OR "GOSUB" TOKEN.
PSHA ; SAVE IT.
INY ; POINT TO NEXT TOKEN.
JSR RSKIPSPC ; SKIP SPACES.
LDX NUMSTACK ; POINT TO THE OPERAND STACK.
LDD 0,X ; GET EXPRESSION VALUE.
BPL RON1 ; IS IT NEGATIVE?
BNE RON1 ; OR ZERO?
RON5: LDAA #ONARGERR ; YES. REPORT ERROR.
JMP RPTRERR
RON1: LDD 0,X ; GET THE EXPRESSION VALUE.
SUBD #1 ; SUBTRACT 1. HAVE WE FOUND THE LINE NUMBER?
BEQ RON4 ; YES. GO DO "GOTO" OR "GOSUB".
STD 0,X ; NO. SAVE REMAINDER.
LDAB #3 ; POINT PAST THE LINE NUMBER VALUE.
ABY
JSR RSKIPSPC ; SKIP SPACES PAST THE LINE NUMBER.
LDAA 0,Y ; GET NEXT TOKEN.
CMPA #EOLTOK ; HAVE WE HIT THE END OF THE LINE?
BEQ RON5 ; YES. ERROR.
RON3: INY ; NO. MUST BE A COMMA. BYPASS IT.
JSR RSKIPSPC ; SKIP SPACES AFTER THE COMMA.
BRA RON1 ; GO SEE IF THE NEXT LINE NUMBER IS THE ONE.
RON4: JSR PULNUM ; GET RID OF ARGUMENT.
PULA ; GET "GO" TOKEN.
CMPA #GOTOTOK ; IS IT A "GOTO" TOKEN?
BNE RON6 ; NO. MUST BE A "GOSUB"
JMP RGOTO ; GO DO A "GOTO".
RON6: PSHY ; SAVE THE POINTER TO THE LINE NUMBER.
RON8: LDAB #3 ; POINT PAST THE LINE NUMBER.
ABY
JSR RSKIPSPC ; SKIP SPACES AFTER LINE NUMBER.
LDAA 0,Y ; GET NEXT TERMINATOR CHARACTER.
CMPA #EOLTOK ; HIT THE END OF THE LINE YET?
BEQ RON7 ; YES. GO DO THE GOSUB.
CMPA #MEOLTOK ; NO. HIT THE LOGICAL END OF THE LINE YET?
BEQ RON7 ; YES. GO DO THE GOSUB.
INY ; NO. MUST BE A COMMA.
JSR RSKIPSPC ; SKIP SPACES AFTER THE COMMA.
BRA RON8 ; GO FIND THE END OF THE LINE.
RON7: JMP RGOSUB2 ; GO DO A "GOSUB".
*
*
RPOKE: EQU *
INY ; PASS UP THE OPEN PAREN.
JSR RSKIPSPC ; PASS UP ANY SPACES.
JSR DONEXP ; GO EVALUATE THE ADDRESS EXPRESSION.
JSR RSKIPSPC ; SKIP ANY SPACES.
INY ; SKIP THE COMMA.
JSR RSKIPSPC ; SKIP ANY SPACES.
JSR DONEXP ; GET THE VALUE TO PUT INTO MEMORY.
INY ; PASS UP THE CLOSING PAREN.
JSR PULNUM ; GET THE MEMORY VALUE.
XGDX ; SAVE IT.
JSR PULNUM ; GET THE ADDRESS.
XGDX ; PUT ADDRESS INTO X & MEM VALUE INTO D.
STAB 0,X ; PUT VALUE INTO MEMORY.
RTS ; BACK TO THE INTERPRET LOOP.
*
*
RPORTA: LDAB #PORTAIO
RPORTA1: LDX IOBaseV ; GET ADDRESS OF PORTA I/O REGISTER.
ABX
PSHX ; SAVE POINTER TO VARIABLE.
INY ; PUT IP PAST THE "=" TOKEN.
JSR DONEXP ; EVALUATE THE EXPRESSION.
JSR PULNUM ; GET VALUE INTO D.
TSTA ; IS THE VALUE <0 AND >255?
BEQ RPORTA2 ; NO. GO PUT THE VALUE IN THE PORT.
LDAA #PRTASERR ; YES. ERROR.
JMP RPTRERR ; REPORT THE ERROR.
RPORTA2: PULX ; POINT TO THE DICTIONARY ENTRY.
STAB 0,X ; STORE VALUE.
RTS ; BACK TO MAIN INTERPRET LOOP.
*
*
RPORTB: LDAB #PORTBIO ; GET ADDRESS OF PORTB I/O REGISTER.
BRA RPORTA1 ; GO DO AN ASIGNMENT.
*
*
RPORTC: LDAB #PORTCIO ; GET ADDRESS OF PORTC I/O REGISTER.
BRA RPORTA1 ; GO DO AN ASIGNMENT.
*
*
RPORTD: LDAB #PORTDIO ; GET ADDRESS OF PORTD I/O REGISTER.
BRA RPORTA1 ; GO DO AN ASIGNMENT.
*
*
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -