OSDN Git Service

V300 beautified
[fast-forth/master.git] / forthMSP430FR_ASM.asm
index 154c86b..e0f35a3 100644 (file)
 ;       MOV(.B) &EDE,&TON is coded as follow: MOV(.B) EDE(R2),TON(R2)   ; (R2=0), three words   AS=01, AD=1 x(reg) mode
 ; ----------------------------------------------------------------------
 
-; PUSHM order : R15,R14,R13,R12,R11,R10, R9, R8, R7, R6, R5, R4 (TI's reg)
-; or          : PSP,TOS, IP,  S,  T,  W,  X,  Y, R7, R6, R5, R4 (FastForth reg)
-; example : PUSHM IP,Y or PUSHM R13,R8
+; PUSHM order : PSP,TOS, IP,  S,  T,  W,  X,  Y, rEXIT,rDOVAR,rDOCON, rDODOES, R3, SR,RSP, PC
+; PUSHM order : R15,R14,R13,R12,R11,R10, R9, R8,  R7  ,  R6  ,  R5  ,   R4   , R3, R2, R1, R0
 
-; POPM  order :  R4, R5, R6, R7, R8, R9,R10,R11,R12,R13,R14,R15 (TI's reg)
-; or          :  R4, R5, R6, R7,  Y,  X,  W,  T,  S, IP,TOS,PSP (FastForth reg)
-; example : POPM Y,IP or POPM R8,R13
-
-; ----------------------------------------------------------------------
-; DTCforthMSP430FR5xxx ASSEMBLER : STRUCTURE
-; ----------------------------------------------------------------------
-
-;X  ASSEMBLER       --              ; set ASSEMBLER the first context vocabulary
-    .IFDEF VOCABULARY_SET
-            FORTHWORD "ASSEMBLER"
-    .ENDIF ; VOCABULARY_SET
-ASSEMBLER       mDODOES             ; leave ASSEMBLER_BODY on the stack and run VOCDOES
-                .word   VOCDOES
-ASSEMBLER_BODY  .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
-
-;             FORTHWORDIMM "SEMIC"   ; same as HI2LO, plus restore IP; counterpart of COLON
-;            mDOCOL
-;            .word   HI2LO
-;            .word   LIT,413Dh,COMMA ; compile MOV @RSP+,IP
-;            .word   EXIT
-
-           FORTHWORD "CODE"     ; a CODE word must be finished with ENDCODE
-ASMCODE     CALL #HEADER        ;
-            SUB #4,&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     #ASSEMBLER_BODY,&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
+; example : PUSHM #6,IP pushes IP,S,T,W,X,Y registers to return stack
+;
+; POPM  order :  PC,RSP, SR, R3, rDODOES,rDOCON,rDOVAR,rEXIT,  Y,  X,  W,  T,  S, IP,TOS,PSP
+; POPM  order :  R0, R1, R2, R3,   R4   ,  R5  ,  R6  ,  R7 , R8, R9,R10,R11,R12,R13,R14,R15
 
-    .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
+; example : POPM #6,IP   pop Y,X,W,T,S,IP registers from return stack
 
 ;;Z SKIP      char -- addr               ; skip all occurring character 'char' in input stream
 ;            FORTHWORD "SKIP"            ; used by assembler to parse input stream
@@ -219,135 +64,143 @@ SKIPEND:    MOV     W,TOS               ; -- addr
 ; DTCforthMSP430FR5xxx ASSEMBLER : search argument "xxxx", IP is free
 ; ----------------------------------------------------------------------
 
-; Search ARG of "#xxxx"<sep>                ; <== PARAM10
-; Search ARG of "&xxxx"<sep>                ; <== PARAM111
-; Search ARG of "xxxx(REG)"<sep>            ; <== PARAM130
-; Search ARG of <sep>"xxxx(REG)"            ; <== PARAM210
-SearchARG   ASMtoFORTH                      ; -- separator      search word first
-            .word   WORDD,FIND              ; -- c-addr
-;            .word   ZEROEQUAL
-;            .word   QBRAN,SearchARGW        ; -- c-addr         if found
-            .word   QZBRAN,SearchARGW        ; -- c-addr         if found
-            .word   QNUMBER                 ;
-            .word   QBRAN,NotFound          ; -- c-addr
-            .word   AsmSrchEnd              ; -- value          end if number found
-SearchARGW  FORTHtoASM                      ; -- xt             xt = CFA
+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
+            PUSHM #2,S                  ;                   PUSHM S,T
+            ASMtoFORTH                  ; -- separator      search word first
+            .word   WORDD,FIND          ; -- c-addr
+            .word   QTBRAN,SearchARGW   ; -- c-addr         if found
+            .word   QNUMBER             ;
+            .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
 QDOVAR      CMP     #DOVAR,X
             JNZ     QDOCON
-            ADD     #2,TOS                  ; remplace CFA by PFA for VARIABLE words
-            RET
+            ADD     #2,TOS              ; remplace CFA by PFA for VARIABLE words
+            JMP     SearchEnd
 QDOCON      CMP     #DOCON,X
             JNZ     QDODOES
-            MOV     2(TOS),TOS              ; remplace CFA by [PFA] for CONSTANT (and CREATEd) words
-            RET
+            MOV     2(TOS),TOS          ; remplace CFA by [PFA] for CONSTANT (and CREATEd) words
+            JMP     SearchEnd
 QDODOES     CMP     #DODOES,X
-            JNZ     AsmSrchEnd
-            ADD     #4,TOS                  ; leave BODY address for DOES words
-AsmSrchEnd  RET                             ;
+            JNZ     SearchEnd
+            ADD     #4,TOS              ; leave BODY address for DOES words
+SearchEnd   POPM    #2,S                ; POPM T,S
+            RET                         ;
 
 ; ----------------------------------------------------------------------
 ; DTCforthMSP430FR5xxx ASSEMBLER : search REG
 ; ----------------------------------------------------------------------
 
-; STOre ARGument xxxx of "xxxx(REG)"<sep>   ; <== PARAM130
-; STOre ARGument xxxx of <sep>"xxxx(REG)"   ; <== PARAM210
-StoARGsearchREG
+; compute "xxxx(REG),"          ; <== PARAM130
+; compute ",xxxx(REG)"          ; <== PARAM210
+ComputeARGParenREG
+            MOV #'(',TOS        ; -- "("        as WORD separator to find xxxx of "xxxx(REG),"
+            CALL #SearchARG     ; -- xxxx       aborted if not found
             MOV &DDP,X
             ADD #2,&DDP
-            MOV TOS,0(X)                    ; -- xxxx       compile xxxx
-            MOV #')',TOS                    ; -- ")"        prepare separator to search REG of "xxxx(REG)"
-
-; search REG of "xxxx(REG)"<sep> separator = ')'  ;
-; search REG of <sep>"xxxx(REG)" separator = ')'  ;
-; search REG of "@REG"<sep>      separator = <sep>; <== PARAM120
-; search REG of "@REG+"<sep>     separator = '+'  ; <== PARAM121
-; search REG of "REG"<sep>       separator = <sep>; <== PARAM13
-; search REG of <sep>"REG"       separator = ' '  ; <== PARAM21
-
-SearchREG   PUSH    &TOIN                   ; -- separator  save >IN
-            ADD     #1,&TOIN                ;               skip "R"
-            ASMtoFORTH                      ;               search xx of Rxx
-            .word   WORDD,QNUMBER           ;
-            .word   QBRAN,notREG            ; -- xxxx       if number found
-            FORTHtoASM                      ; -- c-addr     if number not found
-            ADD     #2,RSP                  ;           remove >IN
-            CMP     #16,TOS                 ; -- 000R   register > 15 ?
-            JHS     BOUNDERROR              ;           yes : abort
-            MOV     @RSP+,PC                ; -- 000R   Z=0 ==> found
-
-notREG      FORTHtoASM                      ; -- c-addr
-            MOV     @RSP+,&TOIN             ; -- c-addr          restore >IN
-            BIS     #Z,SR                   ;           Z=1 ==> not found
-            MOV     @RSP+,PC                ; -- c_addr
+            MOV TOS,0(X)        ; -- xxxx       compile xxxx
+            MOV #')',TOS        ; -- ")"        prepare separator to search REG of "xxxx(REG)"
+
+; search REG of "xxxx(REG),"    separator = ')'  ;
+; search REG of ",xxxx(REG)"    separator = ')'  ;
+; search REG of "@REG,"         separator = ','  ; <== PARAM120
+; search REG of "@REG+,"        separator = '+'  ; <== PARAM121
+; search REG of "REG,"          separator = ','  ; <== PARAM13
+; search REG of ",REG"          separator = ' '  ; <== PARAM21
+
+SearchREG   PUSHM #2,S          ;               PUSHM S,T
+            PUSH &TOIN          ; -- separator  save >IN
+            ADD #1,&TOIN        ;               skip "R"
+            ASMtoFORTH          ;               search xx of Rxx
+            .word WORDD,QNUMBER ;
+            .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 ?
+            JHS BOUNDERROR      ;               yes : abort
+            JLO SearchEnd       ; -- 000R       Z=0 ==> found
+
+NOTaREG     FORTHtoASM          ; -- c-addr     Z=1
+            MOV @RSP+,&TOIN     ; -- c-addr          restore >IN
+            JMP SearchEnd       ; -- c_addr     Z=1 ==> not a register 
+
 
 ; ----------------------------------------------------------------------
 ; DTCforthMSP430FR5xxx ASSEMBLER : INTERPRET FIRST OPERAND
 ; ----------------------------------------------------------------------
 
 ; PARAM1     separator --                   ; parse input buffer until separator and compute first operand of opcode
-                                            ; sep is comma or space.
+                                            ; sep is comma for src and space for dst .
 
 PARAM1      mDOCOL                          ; -- sep
             .word   FBLANK,SKIP             ; -- sep c-addr
             FORTHtoASM                      ; -- sep c-addr
-            MOV     #0,&ASMTYPE             ; -- sep c-addr        reset ASMTYPE
-            MOV     &DDP,&OPCODE            ; -- sep c-addr        HERE --> OPCODE (opcode is preset to its address !)
+            MOV     #0,S                    ; -- sep c-addr        reset ASMTYPE
+            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     TOS,W                   ; -- sep c-addr        W=c-addr
+            MOV.B   @TOS,W                  ; -- sep c-addr        W=first char of instruction code
             MOV     @PSP+,TOS               ; -- sep               W=c-addr
-            CMP.B   #'#',0(W)               ; -- sep               W=c-addr
+            CMP.B   #'#',W                  ; -- sep               W=first char
             JNE     PARAM11
 
-; "#" found : case of "#xxxx"<sep>
+; "#" found : case of "#xxxx,"
 PARAM10     ADD     #1,&TOIN                ; -- sep        skip # prefix
             CALL    #SearchARG              ; -- xxxx       abort if not found
 
 PARAM100    CMP #0,TOS                      ; -- xxxx       = 0 ?
             JNE PARAM101
-; case of "#0"<sep>
-            MOV #0300h,&ASMTYPE             ; -- 0          example : MOV #0,dst <=> MOV R3,dst
+; case of "#0,"
+            MOV #0300h,S                    ; -- 0          example : MOV #0,dst <=> MOV R3,dst
             JMP PARAMENDOF
 
 PARAM101    CMP #1,TOS                      ; -- xxxx       = 1 ?
             JNE PARAM102
-; case of "#1"<sep>
-            MOV #0310h,&ASMTYPE             ; -- 1          example : MOV #1,dst <=> MOV 0(R3),dst
+; case of "#1,"
+            MOV #0310h,S                    ; -- 1          example : MOV #1,dst <=> MOV 0(R3),dst
             JMP PARAMENDOF
 
 PARAM102    CMP #2,TOS                      ; -- xxxx       = 2 ?
             JNE PARAM104
-; case of "#2"<sep>
-            MOV #0320h,&ASMTYPE             ; -- 2          ASMTYPE = 0320h  example : MOV #2, <=> MOV @R3,
+; case of "#2,"
+            MOV #0320h,S                    ; -- 2          ASMTYPE = 0320h  example : MOV #2, <=> MOV @R3,
             JMP PARAMENDOF
 
 PARAM104    CMP #4,TOS                      ; -- xxxx       = 4 ?
             JNE PARAM108
-; case of "#4"<sep>
-            MOV #0220h,&ASMTYPE             ; -- 4          ASMTYPE = 0220h  example : MOV #4, <=> MOV @SR,
+; case of "#4,"
+            MOV #0220h,S                    ; -- 4          ASMTYPE = 0220h  example : MOV #4, <=> MOV @SR,
             JMP PARAMENDOF
 
 PARAM108    CMP #8,TOS                      ; -- xxxx       = 8 ?
             JNE PARAM10M1
-; case of "#8"<sep>
-            MOV #0230h,&ASMTYPE             ; -- 8          ASMTYPE = 0230h  example : MOV #8, <=> MOV @SR+,
+; case of "#8,"
+            MOV #0230h,S                    ; -- 8          ASMTYPE = 0230h  example : MOV #8, <=> MOV @SR+,
             JMP PARAMENDOF
 
 PARAM10M1   CMP #-1,TOS                     ; -- xxxx       = -1 ?
             JNE PARAM1000
-; case of "#-1"<sep>
-            MOV #0330h,&ASMTYPE             ; -- -1         ASMTYPE = 0330h  example : XOR #-1 <=> XOR @R3+,
+; case of "#-1,"
+            MOV #0330h,S                    ; -- -1         ASMTYPE = 0330h  example : XOR #-1 <=> XOR @R3+,
             JMP PARAMENDOF
 
-; case of all others "#xxxx"<sep>           ; -- xxxx
-PARAM1000   MOV #0030h,&ASMTYPE             ; -- xxxx       add immediate code type : @PC+,
+; case of all others "#xxxx,"               ; -- xxxx
+PARAM1000   MOV #0030h,S                    ; -- xxxx       add immediate code type : @PC+,
 
-; case of "&xxxx"<sep>                      ; <== PARAM110
-; case of <sep>"&xxxx"                      ; <== PARAM20
-StoreArg    MOV &DDP,X                      ; -- xxxx
+; case of all others "#xxxx,"               ; -- xxxx
+; case of "&xxxx,"                          ; <== PARAM110
+; case of ",&xxxx"                          ; <== PARAM20
+StoreArg    MOV &DDP,X                      ; -- xxxx       don't use T=OPCODEADR
             ADD #2,&DDP                     ;               cell allot for arg
-StoreTOS    MOV TOS,0(X)                    ;               compile arg
 
+StoreTOS                                    ; <== TYPE1DOES
+            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
@@ -356,97 +209,95 @@ PARAMENDOF  MOV @PSP+,TOS                   ; --
             mNEXT                           ; --
 ; ------------------------------------------
 
-PARAM11     CMP.B   #'&',0(W)               ; -- sep
+PARAM11     CMP.B   #'&',W                  ; -- sep
             JNE     PARAM12
 
-; case of "&xxxx"<sep>                      ; -- sep        search for "&xxxx,"
-PARAM110    MOV     #0210h,&ASMTYPE         ; -- sep        set code type : xxxx(SR) with AS=0b01 ==> x210h (and SR=0 !)
+; case of "&xxxx,"                          ; -- sep        search for "&xxxx,"
+PARAM110    MOV     #0210h,S                ; -- sep        set code type : xxxx(SR) with AS=0b01 ==> x210h (and SR=0 !)
 
-; case of "&xxxx"<sep>
-; case of <sep>"&xxxx"                      ; <== PARAM20
+; case of "&xxxx,"
+; case of ",&xxxx"                          ; <== PARAM20
 PARAM111    ADD     #1,&TOIN                ; -- sep        skip "&" prefix
-            PUSH    #StoreArg               ;               prepare next ret : compile xxxx then ret
-            JMP     SearchARG               ; -- sep        abort if not found
+            CALL    #SearchARG              ; -- arg        abort if not found
+            JMP     StoreArg                ; --            then ret
 ; ------------------------------------------
 
-PARAM12     CMP.B   #'@',0(W)               ; -- sep
+PARAM12     CMP.B   #'@',W                  ; -- sep
             JNE     PARAM13
 
-; case of "@REG"<sep>|"@REG+"<sep>
-PARAM120    MOV     #0020h,&ASMTYPE         ; -- sep        init ASMTYPE with indirect code type : AS=0b10
+; case of "@REG,"|"@REG+,"
+PARAM120    MOV     #0020h,S                ; -- sep        init ASMTYPE with indirect code type : AS=0b10
             ADD     #1,&TOIN                ; -- sep        skip "@" prefix
             CALL    #SearchREG              ;               Z = not found
             JNZ     PARAM123                ; -- value      REG of "@REG," found
 
-; case of "@REG+"<sep>                      ; -- c-addr     "@REG"<sep> not found, search REG of "@REG+"
-PARAM121    ADD     #0010h,&ASMTYPE         ;               change ASMTYPE from @REG to @REG+ type
+; case of "@REG+,"                          ; -- c-addr     REG of "@REG" not found, search REG of "@REG+"
+PARAM121    ADD     #0010h,S                ;               change ASMTYPE from @REG to @REG+ type
             MOV     #'+',TOS                ; -- "+"        as WORD separator to find REG of "@REG+,"
             CALL    #SearchREG              ; -- value|c-addr   X = flag
-
-; case of "REG" of "@REG+"<sep>
-; case of "REG" of "xxxx(REG)"<sep>         ; <== PARAM130
-PARAM122    JZ      REGnotFound             ; -- c-addr
-            CMP     &SOURCE_LEN,&TOIN       ;               test OPCODE II parameter ending by REG+ or (REG) without comma,
+            
+; case of "@REG+,"                          ;
+; case of "xxxx(REG),"                      ; <== PARAM130
+                                            ;               cases of double separator:   +, and ),
+PARAM122    CMP     &SOURCE_LEN,&TOIN       ;               test OPCODE II parameter ending by REG+ or (REG) without comma,
             JZ      PARAM123                ;               i.e. >IN = SOURCE_LEN : don't skip char CR !
             ADD     #1,&TOIN                ; -- 000R       skip "," ready for the second operand search
 
-; case of "REG" of "@REG+"<sep>
-; case of "REG" of "xxxx(REG)"<sep>
-; case of "REG" of "@REG"<sep>              ; <== PARAM120
-; case of "REG" of "REG"<sep>               ; <== PARAM13
+; case of "@REG+,"
+; case of "xxxx(REG),"
+; case of "@REG,"                           ; <== PARAM120
+; case of "REG,"                            ; <== PARAM13
 PARAM123    SWPB    TOS                     ; 000R -- 0R00  swap bytes because it's not a dst REG typeI (not a 2 ops inst.)
 
-; case of "REG" of "@REG+"<sep>             ; -- 0R00                   (src REG typeI)
-; case of "REG" of "xxxx(REG)"<sep>         ; -- 0R00                   (src REG typeI or dst REG typeII)
-; case of "REG" of "@REG"<sep>              ; -- 0R00                   (src REG typeI)
-; case of "REG" of "REG"<sep>               ; -- 0R00                   (src REG typeI or dst REG typeII)
-; case of "REG" of <sep>"REG"               ; -- 000R   <== PARAM21     (dst REG typeI)
-; case of "REG" of <sep>"xxxx(REG)"         ; -- 000R   <== PARAM210    (dst REG typeI)
-PARAM124    ADD     TOS,&ASMTYPE            ; -- 0R00|000R
-            JMP     PARAMENDOF
+; case of "@REG+,"                          ; -- 0R00                   (src REG typeI)
+; 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              ;
 ; ------------------------------------------
 
-; case of "REG"<sep>|"xxxx(REG)"<sep>       ;               first, searg REG of "REG,"
+; case of "REG,"|"xxxx(REG),"               ;               first, searg REG of "REG,"
 PARAM13     CALL    #SearchREG              ; -- sep        save >IN for second parsing (case of "xxxx(REG),")
-            JNZ     PARAM123                ; -- 000R       REG of "REG," found, ASMTYPE=0
+            JNZ     PARAM123                ; -- 000R       REG of "REG," found, S=ASMTYPE=0
 
-; case of "xxxx(REG)"<sep>                  ; -- c-addr     "REG," not found
-PARAM130    ADD     #0010h,&ASMTYPE         ;               AS=0b01 for indexing address
-            MOV     #'(',TOS                ; -- "("        as WORD separator to find xxxx of "xxxx(REG),"
-            CALL    #SearchARG              ; -- xxxx       aborted if not found
-            PUSH    #PARAM122               ;               prepare next ret : REG found or not found
-            JMP     StoARGsearchREG         ;               compile xxxx and search REG of "(REG)"
+; case of "xxxx(REG),"                      ; -- c-addr     "REG," not found
+PARAM130    ADD     #0010h,S         ;               AS=0b01 for indexing address
+            CALL    #ComputeARGparenREG     ;               compile xxxx and search REG of "(REG)"
+            JMP     PARAM122                ; 
 
 ; ----------------------------------------------------------------------
 ; DTCforthMSP430FR5xxx ASSEMBLER : INTERPRET 2th OPERAND
 ; ----------------------------------------------------------------------
 
-; PARAM2     --                             ; parse input buffer until BL and compute this 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
+            .word   FBLANK,SKIP             ;               skip space(s) between "arg1," and "arg2" if any; use not S,T.
             FORTHtoASM                      ; -- c-addr     search for '&' of "&xxxx
             CMP.B   #'&',0(TOS)             ;
             MOV     #20h,TOS                ; -- " "        as WORD separator to find xxxx of ",&xxxx"
             JNE     PARAM21                 ;               '&' not found
 
-; case of <sep>"&xxxx"                      ;
-PARAM20     ADD     #0082h,&ASMTYPE         ;               change ASMTYPE : AD=1, dst = R2
+; case of ",&xxxx"                          ;
+PARAM20     ADD     #0082h,S                ;               change ASMTYPE : AD=1, dst = R2
             JMP     PARAM111                ; -- " "
 ; ------------------------------------------
 
-; case of <sep>"REG"|<sep>"xxxx(REG)        ; -- " "        first, search REG of ",REG"
+; case of ",REG"|",xxxx(REG)                ; -- " "        first, search REG of ",REG"
 PARAM21     CALL    #SearchREG              ;
             JNZ     PARAM124                ; -- 000R       REG of ",REG" found
 
-; case of <sep>"xxxx(REG)                   ; -- c-addr     REG not found
-PARAM210    ADD     #0080h,&ASMTYPE         ;               set AD=1
-            MOV     #'(',TOS                ; -- "("        as WORD separator to find xxxx of ",xxxx(REG)"
-            CALL    #SearchARG              ; -- xxxx       aborted if not found
-            CALL    #StoARGsearchREG        ;               compile argument xxxx and search REG of "(REG)"
-            JNZ     PARAM124                ; -- 000R       REG of "(REG) found
-REGnotFound MOV     #NotFound,IP            ; -- c-addr     abort
-            mNEXT
+; case of ",xxxx(REG)                       ; -- c-addr     REG not found
+PARAM210    ADD     #0080h,S                ;               set AD=1
+            CALL    #ComputeARGparenREG     ;               compile argument xxxx and search REG of "(REG)"
+            JMP     PARAM124                ; -- 000R       REG of "(REG) found
 
 
 ; ----------------------------------------------------------------------
@@ -485,8 +336,8 @@ TYPE1DOES                                   ; -- PFADOES
             .word   PARAM2                  ; -- PFADOES            char separator (BL) included in PARAM2
             FORTHtoASM                      ; -- PFADOES
 MAKEOPCODE  MOV     @TOS,TOS                ; -- opcode             part of instruction
-            BIS     &ASMTYPE,TOS            ; -- opcode             opcode is complete
-            MOV     &OPCODE,X               ; -- opcode             X= addr to compile opcode
+            BIS     S,TOS                   ; -- opcode             opcode is complete
+            MOV     T,X                     ; -- opcode             X=T= OPCODEADR to compile opcode
             JMP     StoreTOS                ;                       then EXIT
 
             asmword "MOV"
@@ -607,11 +458,11 @@ TYPE2DOES                                   ; -- PFADOES
             .word   FBLANK                  ;               char separator for PARAM1
             .word   PARAM1
             FORTHtoASM                      ; -- PFADOES
-            MOV     &ASMTYPE,W              ;
-            AND     #0070h,&ASMTYPE         ;             keep B/W & AS infos in ASMTYPE
+            MOV     S,W                     ;
+            AND     #0070h,S                ;             keep B/W & AS infos in ASMTYPE
             SWPB    W                       ;             (REG org --> REG dst)
             AND     #000Fh,W                ;             keep REG
-BIS_ASMTYPE BIS     W,&ASMTYPE              ; -- PFADOES  add it in ASMTYPE
+BIS_ASMTYPE BIS     W,S                     ; -- PFADOES  add it in ASMTYPE
             JMP     MAKEOPCODE              ; -- then end
 
             asmword "RRC"          ; Rotate Right through Carry ( word)
@@ -650,40 +501,6 @@ BIS_ASMTYPE BIS     W,&ASMTYPE              ; -- PFADOES  add it in ASMTYPE
             mDODOES
             .word   TYPE2DOES,1280h
 
-; ----------------------------------------------------------------------
-; DTCforthMSP430FR5xxx ASSEMBLER, OPCODES TYPE III : PUSHM POPM
-; ----------------------------------------------------------------------
-; syntax :  PUSHM R13,R9    ; R-- R13 R12 R11 R10 R9    (first >= last)
-;           POPM  R9,R13    ; R--                       (last >= first)
-; this syntax is more explicit than TI's one and can reuse typeI template
-
-; PUSHM order : R15,R14,R13,R12,R11,R10, R9, R8, R7, R6, R5, R4 (TI's reg)
-; or          : PSP,TOS, IP,  S,  T,  W,  X,  Y, R7, R6, R5, R4 (FastForth reg)
-; example : PUSHM IP,Y or PUSHM R13,R8
-
-; POPM  order :  R4, R5, R6, R7, R8, R9,R10,R11,R12,R13,R14,R15 (TI's reg)
-; or          :  R4, R5, R6, R7,  Y,  X,  W,  T,  S, IP,TOS,PSP (FastForth reg)
-; example : POPM Y,IP or POPM R8,R13
-
-; TYPE3DOES     -- PFADOES       parse input stream to search :"   REG, REG " as operands of PUSHM|POPM then compile instruction
-TYPE3DOES                                   ; -- PFADOES
-            .word   lit,','                 ; -- PFADOES ","        char separator for PARAM1
-            .word   PARAM1                  ; -- PFADOES            ASMTYPE contains : 0x0S00    S=REGsrc
-            .word   PARAM2                  ; -- PFADOES            ASMTYPE contains : 0x0S0D    D=REGdst
-            FORTHtoASM                      ; -- PFADOES
-            MOV.B   &ASMTYPE,X              ;                       X=REGdst
-            MOV.B   &ASMTYPE+1,W            ;                       W=REGsrc
-            MOV     W,&ASMTYPE              ;                       ASMTYPE = 0x000S
-            CMP     #1500h,0(TOS)           ; -- PFADOES            PUSHM ?
-            JNZ     POPMCASEOF
-PUSHMCASEOF SUB     X,W                     ; -- PFADOES            PUSHM : REGsrc - REGdst = n-1
-            JMP     TYPE3QERR
-POPMCASEOF  SUB     W,X                     ; -- PFADOES            POPM  : REGdst - REGsrc = n-1
-            MOV     X,W
-TYPE3QERR   CMP     #16,W
-            JHS     BOUNDERRORW             ; -- PFADOES            (u>=)
-            .word   0E5Ah                   ;                       RLAM #4,R10 --> RLAM #4,W
-            JMP     BIS_ASMTYPE             ; --            then end
 
 BOUNDERRWM1 ADD     #1,W                    ; <== RRAM|RRUM|RRCM|RLAM error
 BOUNDERRORW MOV     W,TOS                   ; <== PUSHM|POPM|ASM_branch error
@@ -693,56 +510,81 @@ BOUNDERROR                                  ; <== REG number error
             .byte   13,"out of bounds"
             .word   QABORTYES
 
-            asmword "PUSHM"
-ASM_PUSHM   mDODOES
-            .word   TYPE3DOES,01500h
+; --------------------------------------------------------------------------------
+; DTCforthMSP430FR5xxx ASSEMBLER, OPCODES TYPE III : PUSHM|POPM|RLAM|RRAM|RRUM|RRCM
+; --------------------------------------------------------------------------------
+; PUSHM, syntax:    PUSHM #n,REG  with 0 < n < 17 
+; POPM syntax:       POPM #n,REG  with 0 < n < 17 
 
-            asmword "POPM"
-ASM_POPM    mDODOES
-            .word   TYPE3DOES,01700h
 
-; ----------------------------------------------------------------------
-; DTCforthMSP430FR5xxx ASSEMBLER, OPCODES TYPE IV : RLAM|RRAM|RRUM|RRCM
-; ----------------------------------------------------------------------
+; PUSHM order : PSP,TOS, IP,  S,  T,  W,  X,  Y, rEXIT,rDOVAR,rDOCON, rDODOES, R3, SR,RSP, PC
+; PUSHM order : R15,R14,R13,R12,R11,R10, R9, R8,  R7  ,  R6  ,  R5  ,   R4   , R3, R2, R1, R0
+
+; example : PUSHM #6,IP pushes IP,S,T,W,X,Y registers to return stack
+;
+; POPM  order :  PC,RSP, SR, R3, rDODOES,rDOCON,rDOVAR,rEXIT,  Y,  X,  W,  T,  S, IP,TOS,PSP
+; POPM  order :  R0, R1, R2, R3,   R4   ,  R5  ,  R6  ,  R7 , R8, R9,R10,R11,R12,R13,R14,R15
+
+; example : POPM #6,IP   pulls Y,X,W,T,S,IP registers from return stack
 
-; TYPE4DOES      -- PFADOES        parse input stream to search : "   #N, REG " as operands of RLAM|RRAM|RRUM|RRCM
-TYPE4DOES                                   ; -- PFADOES
+; RxxM syntax: RxxM #n,REG  with 0 < n < 5 
+
+; TYPE3DOES      -- PFADOES        parse input stream to search : "   #N, REG " as operands of RLAM|RRAM|RRUM|RRCM
+TYPE3DOES                                   ; -- PFADOES
             .word   FBLANK,SKIP             ;                       skip spaces if any
             FORTHtoASM                      ; -- PFADOES c-addr
-            MOV     #0,&ASMTYPE             ;                       init ASMTYPE=0
-            MOV     &DDP,&OPCODE            ;                       init OPCODE=DP
-            ADD     #2,&DDP                 ;                       make room for opcode
             ADD     #1,&TOIN                ;                       skip "#"
             MOV     #',',TOS                ; -- PFADOES ","
             ASMtoFORTH
             .word   WORDD,QNUMBER
-            .word   QBRAN,NotFound
-            .word   PARAM2                  ; -- PFADOES 0x000N     ASMTYPE = 0x000R
+            .word   QFBRAN,NotFound         ;                       ABORT
+            .word   INITPARAM2              ; -- PFADOES 0x000N     S=ASMTYPE = 0x000R
             FORTHtoASM
-            MOV     TOS,W                   ; -- PFADOES 0x000N     W = 0x000N
+            MOV     TOS,W                   ; -- PFADOES n          W = n
             MOV     @PSP+,TOS               ; -- PFADOES
-            SUB     #1,W                    ;                       W = N floored to 0
-            CMP     #4,W                    ;
+            SUB     #1,W                    ;                       W = n floored to 0
+            JN      BOUNDERRWM1
+            MOV     @TOS,X                  ;                       X=OPCODE
+            RLAM    #4,X                    ;                       OPCODE bit 1000h --> C
+            JNC     RxxMINSTRU              ;                       
+PxxxINSTRU  MOV     S,Y                     ;                       S=REG, Y=REG to test
+            RLAM    #3,X                    ;                       OPCODE bit 0200h --> C                  
+            JNC     PUSHMINSTRU             ;                       W=n-1 Y=REG
+POPMINSTRU  SUB     W,S                     ;                       to make POPM opcode, compute first REG to POP; TI is complicated....
+PUSHMINSTRU SUB     W,Y                     ;                       Y=REG-(n-1)
+            CMP     #16,Y
             JHS     BOUNDERRWM1             ;                       JC=JHS    (U>=)
-            SWPB    W                       ; -- PFADOES            W = N << 8
-            .word   065Ah                   ; RLAM #2,R10           W = N << 10
-            JMP     BIS_ASMTYPE             ; --
+            RLAM    #4,W                    ;                       W = n << 4      
+            JMP     BIS_ASMTYPE             ; PFADOES --            
+RxxMINSTRU  CMP     #4,W                    ;
+            JHS     BOUNDERRWM1             ;                       JC=JHS    (U>=)
+            SWPB    W                       ; -- PFADOES            W = n << 8
+            RLAM    #2,W                    ;                       W = N << 10
+            JMP     BIS_ASMTYPE             ; PFADOES --
 
             asmword "RRCM"
             mDODOES
-            .word   TYPE4DOES,0050h
+            .word   TYPE3DOES,0050h
 
             asmword "RRAM"
             mDODOES
-            .word   TYPE4DOES,0150h
+            .word   TYPE3DOES,0150h
 
             asmword "RLAM"
             mDODOES
-            .word   TYPE4DOES,0250h
+            .word   TYPE3DOES,0250h
 
             asmword "RRUM"
             mDODOES
-            .word   TYPE4DOES,0350h
+            .word   TYPE3DOES,0350h
+
+            asmword "PUSHM"
+            mDODOES
+            .word   TYPE3DOES,1500h
+
+            asmword "POPM"
+            mDODOES
+            .word   TYPE3DOES,1700h
 
 ; ----------------------------------------------------------------------
 ; DTCforthMSP430FR5xxx ASSEMBLER, CONDITIONAL BRANCHS
@@ -760,7 +602,7 @@ TYPE4DOES                                   ; -- PFADOES
 CODE_JMP    mDOCON                      ; branch always
             .word   3C00h
 
-            asmword "S>="               ; if >= assertion
+            asmword "S>="               ; if >= assertion (opposite of jump if < )
             mDOCON
             .word   3800h
 
@@ -795,7 +637,7 @@ CODE_JMP    mDOCON                      ; branch always
 ;ASM IF      OPCODE -- @OPCODE1
             asmword "IF"
 ASM_IF      MOV     &DDP,W
-            MOV     TOS,0(W)
+            MOV     TOS,0(W)            ; compile incomplete opcode
             ADD     #2,&DDP
             MOV     W,TOS
             mNEXT
@@ -820,8 +662,8 @@ ASM_ELSE    MOV     &DDP,W              ; --        W=HERE
             MOV     #3C00h,0(W)         ;           compile unconditionnal branch
             ADD     #2,&DDP             ; --        DP+2
             SUB     #2,PSP
-            MOV     W,0(PSP)            ; -- dst
-            JMP     ASM_THEN
+            MOV     W,0(PSP)            ; -- @OPCODE2 @OPCODE1
+            JMP     ASM_THEN            ; -- @OPCODE2
 
 ;C BEGIN    -- @BEGIN                   same as FORTH counterpart
 
@@ -865,37 +707,6 @@ ASM_REPEAT  mDOCOL                      ; -- @WHILE @BEGIN
             .word   ASM_THEN            ; --
             .word   EXIT
 
-; ----------------------------------------------------------------
-; DTCforthMSP430FR5xxx ASSEMBLER : branch to a previous definition
-; ----------------------------------------------------------------
-
-;ASM    JMP <word>          ;        --       unconditionnal branch to a previous definition
-            asmword "JMP"
-JUMP        mDOCOL
-            .word   TICK,CODE_JMP
-            .word   ASM_UNTIL,EXIT
-
-
-; invert FORTH conditionnal branch      FORTH_JMP_OPCODE -- LABEL_JMP_OPCODE
-INVJMP      BIT #1000h,TOS  ; 3xxxh case ?
-            JNZ INVJMP3xxxh ; yes
-INVJMP2xxxh XOR #0400h,TOS  ; no: case of JNE/JNZ JEQ/JZ JNC/JLO JC/JHS
-            mNEXT
-INVJMP3xxxh CMP #3400h,TOS
-            JLO INVJMPEND   ; case of 3000h, do nothing
-            JZ INVJMP3400h
-INVJMP3800h MOV #3400h,TOS  ; not jump if >= --> jump if <
-            mNEXT
-INVJMP3400h MOV #3800h,TOS  ; not jump if <  --> jump if >=
-INVJMPEND   mNEXT
-
-
-;ASM    <cond> ?JMP <word>  ;  OPCODE --       conditionnal branch to a previous definition
-            asmword "?JMP"
-            mDOCOL
-            .word   INVJMP,TICK,SWAP
-            .word   ASM_UNTIL,EXIT
-
 ; ------------------------------------------------------------------------------------------
 ; DTCforthMSP430FR5xxx ASSEMBLER : branch up to 3 backward labels and up to 3 forward labels
 ; ------------------------------------------------------------------------------------------
@@ -905,84 +716,109 @@ INVJMPEND   mNEXT
 BACKWARDDOES        ;
     FORTHtoASM
     MOV @RSP+,IP
-    MOV TOS,Y
-    MOV @PSP+,TOS
-    MOV @Y,W        ;               W = [PFA]
+    MOV @TOS,TOS
+    MOV TOS,Y       ; Y = ASMBWx
+    MOV @PSP+,TOS   ; 
+    MOV @Y,W        ;               W = [ASMBWx]
     CMP #0,W        ;               W = 0 ?
-    JNZ BACKWUSE
+    MOV #0,0(Y)     ;               clear [ASMBWx] for next use
+BACKWUSE            ; -- OPCODE
+    JNZ ASM_UNTIL1
 BACKWSET            ; --
-    MOV &DDP,0(Y)   ;               [PFA] = @LABEL
+    MOV &DDP,0(Y)   ;               [ASMBWx] = DDP
     mNEXT
-BACKWUSE            ; -- OPCODE
-    MOV #0,0(Y)     ;               reset [PFA] for next use
-    JMP ASM_UNTIL1  ;               resolve backward branch
 
 ; backward label 1
             asmword "BW1"
             mdodoes
             .word BACKWARDDOES
-CLRBW1      .word 0
+            .word ASMBW1    ; in RAM
 
 ; backward label 2
             asmword "BW2"
             mdodoes
             .word BACKWARDDOES
-CLRBW2      .word 0
+            .word ASMBW2    ; in RAM
 
 ; backward label 3
             asmword "BW3"
             mdodoes
             .word BACKWARDDOES
-CLRBW3      .word 0
+            .word ASMBW3    ; in RAM
 
 FORWARDDOES
     FORTHtoASM
     MOV @RSP+,IP
     MOV &DDP,W      ;
-    MOV @TOS,Y      ;           Y=@OPCODE
-    CMP #0,Y
-    JNZ FORWUSE
-FORWSET             ; OPCODE PFA --
+    MOV @TOS,TOS
+    MOV @TOS,Y      ;               Y=[ASMFWx]
+    CMP #0,Y        ;               ASMFWx = 0 ? (FWx is free?)
+    MOV #0,0(TOS)   ;               clear [ASMFWx] for next use
+FORWUSE             ; PFA -- @OPCODE
+    JNZ ASM_THEN1   ;               no
+FORWSET             ; OPCODE PFA -- 
     MOV @PSP+,0(W)  ; -- PFA        compile incomplete opcode
-    ADD #2,&DDP     ;
-    MOV W,0(TOS)    ;               store @OPCODE into PFA
+    ADD #2,&DDP     ;               increment DDP
+    MOV W,0(TOS)    ;               store @OPCODE into ASMFWx
     MOV @PSP+,TOS   ;   --
     mNEXT
-FORWUSE             ; PFA -- @OPCODE
-    MOV #0,0(TOS)   ;               reset PFA for next use
-    JMP ASM_THEN1   ;               resolve forward branch
 
 
 ; forward label 1
             asmword "FW1"
             mdodoes
             .word FORWARDDOES
-CLRFW1      .word 0
+            .word ASMFW1    ; in RAM
 
 ; forward label 2
             asmword "FW2"
             mdodoes
             .word FORWARDDOES
-CLRFW2      .word 0
+            .word ASMFW2    ; in RAM
 
 ; forward label 3
             asmword "FW3"
             mdodoes
             .word FORWARDDOES
-CLRFW3      .word 0
+            .word ASMFW3    ; in RAM
+
 
+; invert FORTH conditionnal branch      FORTH_JMP_OPCODE -- LABEL_JMP_OPCODE
+INVJMP      CMP #3000h,TOS  
+            JZ INVJMPEND    ; case of JN, do nothing
+            XOR #0400h,TOS  ; case of: JNZ<-->JZ  JNC<-->JC  JL<-->JGE
+            BIT #1000h,TOS  ; 3xxxh case ?
+            JZ  INVJMPEND   ; no
+            XOR #0800h,TOS  ; complementary action for JL<-->JGE
+INVJMPEND   mNEXT
 
 ;ASM    GOTO <label>                   --       unconditionnal branch to label
             asmword "GOTO"
             mDOCOL
-            .word   CODE_JMP,TICK   ;  -- OPCODE PFA<label>
+            .word   CODE_JMP,TICK   ;  -- OPCODE CFA<label>
             .word   EXECUTE,EXIT
 
 ;ASM    <cond> ?GOTO <label>    OPCODE --       conditionnal branch to label
             asmword "?GOTO"
             mDOCOL
-            .word   INVJMP,TICK     ;  -- OPCODE PFA<label>
+            .word   INVJMP,TICK     ;  -- OPCODE CFA<label>
             .word   EXECUTE,EXIT
 
+; ----------------------------------------------------------------
+; DTCforthMSP430FR5xxx ASSEMBLER : branch to a previous definition
+; ----------------------------------------------------------------
+
+;ASM    JMP <word>          ;        --       unconditionnal branch to a previous definition
+            asmword "JMP"
+JUMP        mDOCOL
+            .word   TICK            ; -- @BACKWARD
+            .word   ASM_AGAIN,EXIT
+
+
+;ASM    <cond> ?JMP <word>  ;  OPCODE --       conditionnal branch to a previous definition
+            asmword "?JMP"
+            mDOCOL
+            .word   INVJMP,TICK,SWAP    ; 
+            .word   ASM_UNTIL,EXIT