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

📄 interpreter.inc

📁 This a basic compiler for MSP430
💻 INC
📖 第 1 页 / 共 5 页
字号:
        mov.w   r11, r10
        mov.w   @r15, r4
        call    #flash_write_word
        jmp     ready

; NEW
x_new:
        call    #new
        mov.w   #END_OF_RAM, sp              ; FIXME!
        jmp     ready

; Erase whole of flash
new:
        mov.w   #BREAK, &flags               ; BREAK ON
        call    #clear                       ; zero variables
        mov.w   #user_flash_begin, r10       ; erase flash pages
x_new_00:
        call    #flash_erase_page
#ifndef SIMULATOR
        add.w   #0x200, r10
        cmp.w   #0xfe00, r10
        jnz     x_new_00
#endif

        mov.w   #user_flash_begin+4, &flashtop
        mov.w   #0, r4
        mov.w   #user_flash_begin, r10
        call    #flash_write_word
        add.w   #2, r10
        call    #flash_write_word
        mov.w   #0, &program_start

        mov.w   #0, lp
        mov.w   #ENDOF(UDATA0), &ramtop
        ret

; RUN
x_run:
; Compute start line number
        mov.w   #0, r14                      ; prepare to run from the start
	cmp.b   #0, r4                       ; anything after RUN?
	jz      x_run_05                     ; ...no, skip parsing the line number
	call    #read_int                    ; get line number to start from

; Re-initialise interpreter
x_run_05:
        mov.w   #BREAK, &flags               ; allow break in processing
        mov.w   #END_OF_RAM, sp              ; initialise stack pointer, clearing stack
        mov.w   #ENDOF(UDATA0), &ramtop      ; initialise TOP
        mov.w   #0, &break_tp                ; remove ON BREAK handler
        mov.w   #0, &break_lp
	call    #clear                       ; zero variables on run

; Before running, check structural integrity of program
        mov.w   &program_start, lp           ; get start of program into lp
        cmp.w   #0, lp                       ; any program in flash?
        jz      ready                        ; ...no, nothing to run
        mov.w   lp, tp                       ; point tp to the start of the first line
        add.w   #4, tp
        mov.b   @tp+, r4                     ; get first token from program
        mov.w   #LAST_TOKEN, r11             ; special token for find_control_match
        call    #find_control_match          ; ensure loops match
        jc      x_run_10                     ; if controls match, that's great
        cmp.w   #T_END, r4                   ; END on its own?
        jnz     syntax_error                 ; ...no, then it's a syntax error
x_run_10:
        mov.w   &program_start, lp           ; get start of program
        mov.w   lp, tp                       ; point to start of line
        push.w  #T_END                       ; delimit nothing on stack (no loops, no RESUME)
	cmp.w   #0, r14                      ; run from start?
        jz      next_line                    ; ...yes, get first line
	jmp     x_goto_00

term:
        cmp.b   #':', r4                     ; statement separator?
        jeq     chrget                       ; ...yes, start interpreting next statement
        cmp.b   #0, r4                       ; end of line?
        jeq     term_10                      ; ...yes, skip to next line
        cmp.b   #T_TICK, r4                  ; comment?
        jz      x_rem                        ; ...yes, treat as REM
	jmp     syntax_error                 ; ...no, can't be anything other than an error
term_10:
        cmp.w   #0, lp                       ; at end of line, interpreting in immediate mode?
        jeq     ready                        ; ...yes, go back to ready loop
skip_line:
        mov.w   @lp, tp                      ; point tp to the next line to interpret by following forward link
        mov.w   tp, lp                       ; save start of line in lp
        cmp.w   #0, tp                       ; run off end of program?
        jz      ready                        ; ...yes, return to ready loop
next_line:
        add.w   #4, tp                       ; skip over line number and link
chrget:
        mov.b   @tp+, r4
chrgot:

; Break-in processing.
        bit.w   #BREAK, &flags               ; break-ins enabled?
        jz      chrgot_20                    ; ...no, carry on with life
        BRKTEST chrgot_20
        cmp.w   #0, &break_tp                ; ON BREAK set?
        jz      x_stop                       ; ...no, stop execution
        mov.w   tp, &cont_tp                 ; save current context for CONTINUE
        mov.w   lp, &cont_lp
        mov.w   &break_tp, tp                ; activate ON BREAK context
        mov.w   &break_lp, lp
        jmp     chrget                       ; start ON BREAK processing

chrgot_20:
#if 0
        bit.w   #TIMER, &flags               ; timer fired?
        jz      chrgot_30                    ; no, continue execution
        bic.w   #TIMER, &flags               ; reset timer fired flag
        cmp.w   #0, &timer_tp                ; an ON TIMER handler set?
        jz      chrgot_30                    ; no, ignore timer event
        push.w  sr                           ; save current context
        dint
        push.w  tp
        push.w  lp
        push.w  #T_RESUME                    ; flag RESUME needed
        mov.w   &timer_tp, tp                ; transfer to ON TIMER context
        mov.w   &timer_lp, lp
        jmp     chrget
chrgot_30:
#endif
        cmp.b   #0, r4
        jz      skip_line
        jge     chrgot_10

; Evaluate statement
next_00:
        cmp.w   #LAST_COMMAND_TOKEN+1, r4
        jc      syntax_error
        add.b   r4, r4
        mov.b   r4, r11
        mov.b   @tp+, r4
        br      cmdtab(r11)

chrgot_10:
        cmp.b   #':', r4
        jz      chrget

; LET var = expr
; LET var(index) = expr
x_let:
	call	#varptr                      ; parse variable and get its address into R14
	mov.w   r14, r11                     ; save variable address
	push.w  r15                          ; save variable size
        cmp.b   #T_EQ, r4                    ; '=' follows?
        jnz     syntax_error                 ; ...no, syntax error
        call    #get_eval_expr               ; evaluate the expression
	pop.w   r12                          ; restore varibale designation
	cmp.w   #2, r12                      ; assigning 16 bits?
	jz      x_let_20                     ; ...yes
	cmp.w   #4, r12                      ; assigning 32 bits?
	jz      x_let_10                     ; ...yes
        mov.b   r14, @r11                    ; must be 8 bits then
        jmp     term                         ; ensure that statement is correctly terminated
x_let_10:
        mov.w   r15, 2(r11)                  ; store high part of 32-bit value
x_let_20:
        mov.w   r14, @r11                    ; store low part of 32-bit value or 16 bit value
        jmp     term                         ; ensure that statement is correctly terminated

; REM comment
x_rem:
        cmp.w   #0, lp                       ; Special REM in immediate mode
        jz      ready                        ; if in immediate mode, just say we're ready
        jmp     skip_line                    ; if in program mode, skip to the next line

; POKE address, byte
x_poke:
        call    #eval_expr                   ; evaluate address
        mov.w   r14, r11                     ; ...and only use the low 16 bits
        call    #check_comma                 ; check ',' present
        call    #eval_expr                   ; evaluate byte
        mov.b   r14, @r11                    ; do the poke
        jmp     term                         ; ensure that statement is correctly terminated

; DPOKE address, byte
x_dpoke:
        call    #eval_expr                   ; evaluate address
        bic.w   #0, r14                      ; ensure address is word aligned
        mov.w   r14, r11                     ; ...and only use the low 16 bits
        call    #check_comma                 ; check ',' present
        call    #eval_expr                   ; evaluate byte
        mov.w   r14, @r11                    ; do the dpoke
        jmp     term                         ; ensure that statement is correctly terminated

; CLEAR
x_clear:
        call    #clear                       ; zero variables
        jmp     term                         ; ensure that statement is correctly terminated

; Clear variables and arrays to zero and restore data pointer
clear:
        mov.w   #ENDOF(UDATA0), &ramtop      ; reset TOP
        mov.w   #0, r11                      ; Clear A through Z
x_clear_10:
        mov.w   #0, vars(r11)
	mov.w   #0, arrays(r11)
        add.w   #2, r11
        cmp.w   #26*4, r11
        jnz     x_clear_10
	mov.w   #0, &data_lp
        mov.w   #0, &data_tp                 ; restore to start of program
        ret

; RESTORE
; RESTORE line
x_restore:
        mov.w   #0, &data_tp                 ; by default, restore to start of program
	call    #end_of_statement            ; end of statement?
	jz      term                         ; ...yes, just restore to start of program
	call    #read_int                    ; get line number to restore to
        mov.w   tp, r11                      ; save where we are in the program
	call    #find_line                   ; find the line in the program, setting R15
	mov.w   r15, tp                      ; tp is always used to search the program
	mov.w   tp, &data_lp                 ; save start of line
	call    #find_data_statement         ; find the next DATA statement
	mov.w   tp, &data_tp                 ; save DATA statement pointer
	mov.w   r11, tp                      ; restore the interpreting tp
	mov.b   -1(tp), r4                   ; restore interpreting token
	jmp     term                         ; and check termination

; Find the next DATA statement after R15
find_data_statement:
        cmp.w   #0, tp                       ; fallen off end of program?
	jz      out_of_data_error            ; ...yes, then out of data
	add.w   #4, tp                       ; skip over line number and forward pointer
find_data_statement_10:
	mov.b   @tp+, r4                     ; get first token of statement
	cmp.b   #T_DATA, r4                  ; is this a DATA statement?
	jz      find_data_statement_return   ; ...yes, found it so return
	call    #skip_statement              ; ...no, skip this statament
find_data_statement_20:                      ; entry point from READ
	cmp.b   #0, r4                       ; need to skip over line number and forward pointer?
	jnz     find_data_statement_10       ; ...no, continue searching for the data statement
	mov.w   &data_lp, tp                 ; ...yes, so skip them
	mov.w   @tp, tp                      ; follow forward pointer
	mov.w   tp, &data_lp                 ; save start of line
	jmp     find_data_statement          ; skip past header bytes
find_data_statement_return:
	ret

; READ var, var...
x_read:
	mov.w   tp, r11                      ; save tp as we'll use tp to search for DATA statements
	mov.w   &data_tp, tp                 ; any data?
	cmp.w   #0, tp
	jnz     x_read_10                    ; yes, go to next data item
	mov.w   &program_start, tp           ; search from start of program
	mov.w   tp, &data_lp
	call    #find_data_statement         ; find data statement
	mov.w   tp, &data_tp
x_read_10:
        mov.b   @tp+, r4                     ; prime for read
	cmp.b   #',', r4                     ; comma?
	jz      x_read_10                    ; ...yes, just skip it
	call    #end_of_statement            ; come to end of DATA statement?
	jnz     x_read_20                    ; ...no, read value from program
        call    #find_data_statement_20      ; ...yes, find next DATA statement
	jmp     x_read_10                    ; and see if anything in this DATA statement
x_read_20:
        call    #read_int                    ; read value
	sub.w   #1, tp                       ; tp already advanced, so bring it back
	mov.w   tp, &data_tp                 ; save for next read
	mov.w   r11, tp                      ; restore interpreter's tp
	mov.b   -1(tp), r4                   ; prime token
	push.w  r15                          ; save read value on stack
	push.w  r14
	call    #varptr                      ; compute variable's address
	cmp.w   #4, r15                      ; only allow READ on word variables
	jnz     syntax_error
	pop.w   0(r14)                       ; store read value to variable
	pop.w   2(r14)
	cmp.w   #',', r4                     ; more to read?
	jnz     term                         ; ...no, terminate statement
	mov.b   @tp+, r4                     ; prime next token
	jmp     x_read                       ; and read again

; DATA ...
x_data:
	call    #skip_statement              ; skip the statement
	jmp     term                         ; continue with the following statement

; Skip the current statement, and point to the following statement
skip_statement:
	cmp.b   #0, r4                       ; end of line?
	jz	skip_statement_return        ; ...yes, we've skipped it
	cmp.b   #':', r4                     ; separator?
	jz	skip_statement_return        ; ...yes, we've skipped it
	cmp.b   #T_TICK, r4                  ; remark?
	jz      skip_statement_10            ; ...yes, skip to end of line
	cmp.b   #T_REM, r4                   ; remark?
	jz      skip_statement_10            ; ...yes, skip to end of line
	mov.b   @tp+, r4                     ; get next token in statement
	jmp     skip_statement               ; and continue searching for the end of the statement
skip_statement_10:
	mov.b   @tp+, r4                     ; get next token
	cmp.b   #0, r4                       ; end of line?
	jnz     skip_statement_10            ; ...no, still skipping remark
skip_statement_return:
        ret

; DIM var1(n1), var2(n2)
x_dim:
        call    #is_letter                   ; dimensioning a valid array name?
        jnc     syntax_error                 ; ...no, it's a syntax error
        mov.w   r4, r11                      ; save variable name for later
        mov.b   @tp+, r4                     ; '(' next?
        cmp.b   #'(', r4
        jnz     syntax_error                 ; ...no, it's a syntax error
        call    #eval_unary                  ; get number of elements
        cmp.w   #0, r15                      ; high word non-zero?
        jnz     out_of_memory_error          ; ...yes, far too much memory required
        cmp.w   #16384, r14                  ; more than 64/4 = 16K elements?
        jc      out_of_memory_error          ; ...yes, array too big so report as out of memory
	add.w   #1, r14                      ; DIM X(10) means X has 11 elements, 0 through 10
	mov.w   r14, r9                      ; save maximum index
        add.w   r14, r14                     ; compute number of 32-bit elements
        add.w   r14, r14
        mov.w   &ramtop, r15                 ; 16-bit align TOP
        add.w   #1, r15
        bic.w   #1, r15
        mov.w   r15, r10                     ; save start address of array in R10
        add.w   r14, r15                     ; compute new TOP
        mov.w   sp, r14                      ; gap between SP and TOP must be at least 32 bytes
        sub.w   #32, r14
        cmp.w   r14, r15                     ; gap too small?
        jc      out_of_memory_error          ; ...yes, report out of memory
        mov.w   r15, &ramtop                 ; ...no, set new TOP
	sub.w   #'A', r11                    ; compute index into array table
	add.w   r11, r11
	add.w   r11, r11
	mov.w   r10, arrays(r11)             ; set array start address
	mov.w   r9, arrays+2(r11)            ; set array maximum index
	cmp.b   #',', @tp                    ; dimension another array?
        jnz     term                         ; no, check termination
	add.w   #1, tp                       ; skip '.'
	mov.b   @tp+, r4                     ; get array name
	jmp     x_dim                        ; and dimension again

; WHILE cond ... END WHILE
x_while:
        push.w  tp                           ; stack interpreter's context
        push.w  lp
        push.w  #T_WHILE                     ; indicate that this is a WHILE loop

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -