; example : POPM #6,IP pop Y,X,W,T,S,IP registers from return stack
-; ----------------------------------------------------------------------
-; DTCforthMSP430FR5xxx ASSEMBLER : STRUCTURE
-; ----------------------------------------------------------------------
-
-;X ASSEMBLER -- ; set ASSEMBLER the first context vocabulary
- .IFDEF VOCABULARY_SET
- FORTHWORD "ASSEMBLER"
- .ENDIF ; VOCABULARY_SET
-ASSEMBLER mDODOES ; leave BODYASSEMBLER on the stack and run VOCDOES
- .word VOCDOES
-BODYASSEMBLER .word lastasmword ; here is the structure created by VOCABULARY
- .SWITCH THREADS
- .CASE 2
- .word lastasmword1
- .CASE 4
- .word lastasmword1
- .word lastasmword2
- .word lastasmword3
- .CASE 8
- .word lastasmword1
- .word lastasmword2
- .word lastasmword3
- .word lastasmword4
- .word lastasmword5
- .word lastasmword6
- .word lastasmword7
- .CASE 16
- .word lastasmword1
- .word lastasmword2
- .word lastasmword3
- .word lastasmword4
- .word lastasmword5
- .word lastasmword6
- .word lastasmword7
- .word lastasmword8
- .word lastasmword9
- .word lastasmword10
- .word lastasmword11
- .word lastasmword12
- .word lastasmword13
- .word lastasmword14
- .word lastasmword15
- .CASE 32
- .word lastasmword1
- .word lastasmword2
- .word lastasmword3
- .word lastasmword4
- .word lastasmword5
- .word lastasmword6
- .word lastasmword7
- .word lastasmword8
- .word lastasmword9
- .word lastasmword10
- .word lastasmword11
- .word lastasmword12
- .word lastasmword13
- .word lastasmword14
- .word lastasmword15
- .word lastasmword16
- .word lastasmword17
- .word lastasmword18
- .word lastasmword19
- .word lastasmword20
- .word lastasmword21
- .word lastasmword22
- .word lastasmword23
- .word lastasmword24
- .word lastasmword25
- .word lastasmword26
- .word lastasmword27
- .word lastasmword28
- .word lastasmword29
- .word lastasmword30
- .word lastasmword31
- .ELSECASE
- .ENDCASE
- .word voclink
-voclink .set $-2
-
- FORTHWORDIMM "HI2LO" ; immediate, switch to low level, add ASSEMBLER context, set interpretation state
- mDOCOL
-HI2LO .word HERE,CELLPLUS,COMMA
- .word LEFTBRACKET
-HI2LONEXT .word ALSO,ASSEMBLER
- .word EXIT
-
- FORTHWORD "CODE" ; a CODE word must be finished with ENDCODE
-ASMCODE CALL #HEADER ;
-ASMCODE1 SUB #4,W ; W = CFA
- MOV W,&DDP ; CFA --> DDP
- mDOCOL
- .word SAVE_PSP
- .word BRAN,HI2LONEXT
-
-
- asmword "ENDCODE" ; restore previous context and test PSP balancing
-ENDCODE mDOCOL
- .word PREVIOUS,QREVEAL
- .word EXIT
-
- FORTHWORD "ASM" ; used to define an assembler word which is not executable by FORTH interpreter
- ; i.e. typically an assembler word called by CALL and ended by RET
- ; ASM words are only usable in another ASSEMBLER words
- ; an ASM word must be finished with ENDASM
- MOV &CURRENT,&SAV_CURRENT
- MOV #BODYASSEMBLER,&CURRENT
- JMP ASMCODE
-
- asmword "ENDASM" ; end of an ASM word
- MOV &SAV_CURRENT,&CURRENT
- JMP ENDCODE
-
-
- asmword "COLON" ; compile DOCOL, remove ASSEMBLER from CONTEXT, switch to compilation state
- MOV &DDP,W
-
- .SWITCH DTC
- .CASE 1
- MOV #DOCOL1,0(W) ; compile CALL xDOCOL
- ADD #2,&DDP
-
- .CASE 2
- MOV #DOCOL1,0(W) ; compile PUSH IP
-COLON1 MOV #DOCOL2,2(W) ; compile CALL rEXIT
- ADD #4,&DDP
-
- .CASE 3 ; inlined DOCOL
- MOV #DOCOL1,0(W) ; compile PUSH IP
-COLON1 MOV #DOCOL2,2(W) ; compile MOV PC,IP
- MOV #DOCOL3,4(W) ; compile ADD #4,IP
- MOV #NEXT,6(W) ; compile MOV @IP+,PC
- ADD #8,&DDP ;
- .ENDCASE ; DTC
-
-COLON2 MOV #-1,&STATE ; enter in compile state
- MOV #PREVIOUS,PC ; restore previous state of CONTEXT
-
-
- asmword "LO2HI" ; same as COLON but without saving IP
- .SWITCH DTC
- .CASE 1 ; compile 2 words
- MOV &DDP,W
- MOV #12B0h,0(W) ; compile CALL #EXIT, 2 words 4+6=10~
- MOV #EXIT,2(W)
- ADD #4,&DDP
- JMP COLON2
- .ELSECASE ; CASE 2 : compile 1 word, CASE 3 : compile 3 words
- SUB #2,&DDP ; to skip PUSH IP
- MOV &DDP,W
- JMP COLON1
- .ENDCASE
-
- .IFDEF NONAME
- FORTHWORD "CODENNM" ; CODENoNaMe is the assembly counterpart of :NONAME
-CODENNM mDOCOL
- .word COLONNONAME,LEFTBRACKET
- .word ASMCODE1,EXIT
- .ENDIF
-
;;Z SKIP char -- addr ; skip all occurring character 'char' in input stream
; FORTHWORD "SKIP" ; used by assembler to parse input stream
SKIP: MOV #SOURCE_LEN,Y ;
; DTCforthMSP430FR5xxx ASSEMBLER : search argument "xxxx", IP is free
; ----------------------------------------------------------------------
+SearchARG ; separator -- n|d or abort" not found"
+; ----------------------------------------------------------------------
; Search ARG of "#xxxx," ; <== PARAM10
; Search ARG of "&xxxx," ; <== PARAM111
; Search ARG of "xxxx(REG)," ; <== PARAM130
; Search ARG of ",&xxxx" ; <== PARAM111 <== PARAM20
; Search ARG of ",xxxx(REG)" ; <== PARAM210
-SearchARG PUSHM #2,S ; PUSHM S,T
+ PUSHM #2,S ; PUSHM S,T
ASMtoFORTH ; -- separator search word first
.word WORDD,FIND ; -- c-addr
- .word QZBRAN,SearchARGW ; -- c-addr if found
+ .word QTBRAN,SearchARGW ; -- c-addr if found
.word QNUMBER ;
- .word QBRAN,NotFound ; -- c-addr ABORT
+ .word QFBRAN,NotFound ; -- c-addr ABORT if not found
FsearchEnd .word SearchEnd ; -- value goto end if number found
SearchARGW FORTHtoASM ; -- xt xt = CFA
MOV @TOS,X
ADD #1,&TOIN ; skip "R"
ASMtoFORTH ; search xx of Rxx
.word WORDD,QNUMBER ;
- .word QBRAN,NOTaREG ; -- xxxx if Not a Number
+ .word QFBRAN,NOTaREG; -- xxxx if Not a Number
FORTHtoASM ; -- c-addr number is found
ADD #2,RSP ; remove >IN
CMP #16,TOS ; -- 000R register > 15 ?
.word FBLANK,SKIP ; -- sep c-addr
FORTHtoASM ; -- sep c-addr
MOV #0,S ; -- sep c-addr reset ASMTYPE
- MOV &DDP,T ; -- sep c-addr HERE --> OPCODEADR (opcode is preset to its address !)
+ MOV &DDP,T ; -- sep c-addr T=OPCODEADR (opcode is preset to its address !)
ADD #2,&DDP ; -- sep c-addr cell allot for opcode
MOV.B @TOS,W ; -- sep c-addr W=first char of instruction code
MOV @PSP+,TOS ; -- sep W=c-addr
; case of all others "#xxxx," ; -- xxxx
PARAM1000 MOV #0030h,S ; -- xxxx add immediate code type : @PC+,
+; case of all others "#xxxx," ; -- xxxx
; case of "&xxxx," ; <== PARAM110
; case of ",&xxxx" ; <== PARAM20
-StoreArg MOV &DDP,X ; -- xxxx
+StoreArg MOV &DDP,X ; -- xxxx don't use T=OPCODEADR
ADD #2,&DDP ; cell allot for arg
StoreTOS ; <== TYPE1DOES
- MOV TOS,0(X) ; compile arg
+ MOV TOS,0(X) ; compile arg
; endcase of all "&xxxx" ;
; endcase of all "#xxxx" ; <== PARAM101,102,104,108,10M1
; endcase of all "REG"|"@REG"|"@REG+" ; <== PARAM124
; case of "xxxx(REG)," ; -- 0R00 (src REG typeI or dst REG typeII)
; case of "@REG," ; -- 0R00 (src REG typeI)
; case of "REG," ; -- 0R00 (src REG typeI or dst REG typeII)
-
-
-
; case of ",REG" ; -- 000R <== PARAM21 (dst REG typeI)
; case of ",xxxx(REG)" ; -- 000R <== PARAM210 (dst REG typeI)
PARAM124 ADD TOS,S ; -- 0R00|000R
- JMP PARAMENDOF
+ JMP PARAMENDOF ;
; ------------------------------------------
; case of "REG,"|"xxxx(REG)," ; first, searg REG of "REG,"
; DTCforthMSP430FR5xxx ASSEMBLER : INTERPRET 2th OPERAND
; ----------------------------------------------------------------------
+INITPARAM2 ; for OPCODES TYPE III
+ MOV #0,S ; init ASMTYPE=0
+ MOV &DDP,T ; T=OPCODEADR
+ ADD #2,&DDP ; make room for opcode
+
; PARAM2 -- ; parse input buffer until BL and compute this 2th operand
PARAM2 mDOCOL ;
.word FBLANK,SKIP ; skip space(s) between "arg1," and "arg2" if any; use not S,T.
FORTHtoASM ; -- PFADOES
MAKEOPCODE MOV @TOS,TOS ; -- opcode part of instruction
BIS S,TOS ; -- opcode opcode is complete
- MOV T,X ; -- opcode X= OPCODEADR to compile opcode
+ MOV T,X ; -- opcode X=T= OPCODEADR to compile opcode
JMP StoreTOS ; then EXIT
asmword "MOV"
TYPE3DOES ; -- PFADOES
.word FBLANK,SKIP ; skip spaces if any
FORTHtoASM ; -- PFADOES c-addr
- MOV #0,S ; init ASMTYPE=0
- MOV &DDP,T ; init OPCODEADR=DP
- ADD #2,&DDP ; make room for opcode
ADD #1,&TOIN ; skip "#"
MOV #',',TOS ; -- PFADOES ","
- PUSHM #2,S ; PUSHM S,T
ASMtoFORTH
.word WORDD,QNUMBER
- .word QBRAN,NotFound ; ABORT
- FORTHtoASM
- POPM #2,S ; POPM T,S
- ASMtoFORTH
- .word PARAM2 ; -- PFADOES 0x000N S=ASMTYPE = 0x000R
+ .word QFBRAN,NotFound ; ABORT
+ .word INITPARAM2 ; -- PFADOES 0x000N S=ASMTYPE = 0x000R
FORTHtoASM
MOV TOS,W ; -- PFADOES n W = n
MOV @PSP+,TOS ; -- PFADOES