⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 runtime1.asm

📁 在单片机内嵌BASIC语言解释程序的完整代码
💻 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 + -