OSDN Git Service

la der de der
[fast-forth/master.git] / forthMSP430FR.asm
index 0a8846a..10113c3 100644 (file)
@@ -5,18 +5,21 @@
 ; Ajoutez quelquefois, et souvent effacez.               Boileau, L'Art poétique
 ;-------------------------------------------------------------------------------
 
-;-------------------------------------------------------------------------------
-; SCITE editor: copy https://www.scintilla.org/Sc4xx.exe to \prog\scite.exe
-;-------------------------------------------------------------------------------
-; MACRO ASSEMBLER AS
-; unzip http://john.ccac.rwth-aachen.de:8000/ftp/as/precompiled/i386-unknown-win32/aswcurr.zip
-;-------------------------------------------------------------------------------
+;===============================================================================
+; SCITE editor: copy https://www.scintilla.org/Sc531.exe to \prog\scite.exe
+;               copy \config\SciTEUser.properties in your $HOME directory
+;===============================================================================
+
+;===============================================================================
+; MACRO ASSEMBLER AS:  unzip to \prog
+; http://john.ccac.rwth-aachen.de:8000/ftp/as/precompiled/i386-unknown-win32/aswcurr.zip
+;===============================================================================
     .listing purecode   ; reduce listing to true conditionnal parts
     MACEXP_DFT noif     ; reduce macros listing to true part
     .PAGE  0            ; listing without pagination
 ;-------------------------------------------------------------------------------
 
-VER .equ "V400"     ; FORTH version
+VER .equ "V401"     ; FORTH version
 
 ;===============================================================================
 ; before assembling or programming you must set TARGET in scite param1 (SHIFT+F8)
@@ -25,16 +28,16 @@ VER .equ "V400"     ; FORTH version
 ;    TARGET        ;
 ;MSP_EXP430FR5739  ; compile for MSP-EXP430FR5739 launchpad
 ;MSP_EXP430FR5969  ; compile for MSP-EXP430FR5969 launchpad
-MSP_EXP430FR5994  ;; compile for MSP-EXP430FR5994 launchpad
+;MSP_EXP430FR5994  ; compile for MSP-EXP430FR5994 launchpad
 ;MSP_EXP430FR6989  ; compile for MSP-EXP430FR6989 launchpad
 ;MSP_EXP430FR4133  ; compile for MSP-EXP430FR4133 launchpad
-;MSP_EXP430FR2355  ; compile for MSP-EXP430FR2355 launchpad
+MSP_EXP430FR2355  ;; compile for MSP-EXP430FR2355 launchpad
 ;MSP_EXP430FR2433  ; compile for MSP-EXP430FR2433 launchpad
 ;LP_MSP430FR2476   ; compile for LP_MSP430FR2476  launchpad
 ;CHIPSTICK_FR2433  ; compile for "CHIPSTICK" of M. Ken BOAK
 
 ; choose DTC model (Direct Threaded Code); if you don't know, choose 2
-DTC .equ 2  ; DTC model 1 : DOCOL = CALL rDOCOL           14 cycles 1 word      shortest DTC model
+DTC .equ 2  ; DTC model 1 : DOCOL = CALL rDOCOL           14 cycles 1 word      shortest but a little slow DTC model
             ; DTC model 2 : DOCOL = PUSH IP, CALL rEXIT   13 cycles 2 words     best compromize to mix FORTH/ASM code
             ; DTC model 3 : inlined DOCOL (and LO2HI)      9 cycles 4 words     fastest
 
@@ -42,14 +45,14 @@ THREADS     .equ 16 ;  1,  2 ,  4 ,  8 ,  16,  32  search entries in word-set.
                     ; +0, +28, +48, +56, +90, +154 bytes, usefull to speed up compilation;
                     ; the FORTH interpreter is speed up by about a square root factor of THREADS.
 
-FREQUENCY   .equ 8 ; fully tested at 1,2,4,8,16 MHz, plus 24 MHz for MSP430FR57xx,MSP430FR2355
+FREQUENCY   .equ 24 ; fully tested at 1,2,4,8,16 MHz, plus 24 MHz for MSP430FR57xx,MSP430FR2355
 
 
 ; ==============================================================================
-;UART_TERMINAL ; COMMENT TO SWITCH FROM UART TO I2C TERMINAL
+UART_TERMINAL ; COMMENT TO SWITCH FROM UART TO I2C TERMINAL
 ; ==============================================================================
     .IFDEF UART_TERMINAL
-TERMINALBAUDRATE    .equ 4000000
+TERMINALBAUDRATE    .equ 115200
 TERMINAL3WIRES      ;; + 18 bytes  enable 3 wires XON/XOFF software flow control
 TERMINAL4WIRES      ;; + 12 bytes  enable 4 wires RTS hardware flow control
 ;TERMINAL5WIRES      ; + 10 bytes  enable 5 wires RTS/CTS hardware flow control
@@ -63,13 +66,12 @@ I2C_TERM_ADR .equ 18 ; I2C_TERMINAL_Slave_Address << 1
 ;===============================================================================
 DOUBLE_INPUT        ;; +   60 bytes : adds the interpretation engine for double numbers (numbers with dot)
 FIXPOINT_INPUT      ;; +   68 bytes : adds the interpretation engine for Q15.16 numbers (numbers with comma)
-VOCABULARY_SET      ;; +  194 bytes : adds words: WORDSET FORTH hidden PREVIOUS ONLY DEFINITIONS
-SD_CARD_LOADER      ;; + 1582 bytes : to load source files from SD_card
-BOOTLOADER          ;; +   82 bytes : includes in WARM process the bootloader SD_CARD\BOOT.4TH.
-SD_CARD_READ_WRITE  ;; + 1168 bytes : to read, create, write and del files + copy text files from PC to target SD_Card
-LARGE_CODE          ;; +  506 bytes : allows assembler to execute code up to 1MB.
-LARGE_DATA          ;; + 1212 bytes : extended assembler to 20 bits addresses and datas.
-;PROMPT              ; +   18 bytes : to display the prompt "ok ", (obsolete).
+;VOCABULARY_SET      ; +  194 bytes : adds words: WORDSET FORTH hidden PREVIOUS ONLY DEFINITIONS
+;SD_CARD_LOADER      ; + 1664 bytes : to load source files from SD_card
+;SD_CARD_READ_WRITE  ; + 1168 bytes : to read, create, write and del files + copy text files from PC to target SD_Card
+;LARGE_CODE          ; +  506 bytes : extended assembler to 20 bits addresses (1MB).
+;LARGE_DATA          ; + 1212 bytes : extended assembler to 20 bits datas.
+;PROMPT              ; +   18 bytes : to display the prompt "ok" (deprecated).
 ;===============================================================================
 
 ;-------------------------------------------------------------------------------
@@ -81,151 +83,105 @@ LARGE_DATA          ;; + 1212 bytes : extended assembler to 20 bits addresses an
 ;UTILITY             ; +  434/524 bytes (1/16threads) : add .S .RS WORDS U.R DUMP ?                 UTILITY.f
 ;SD_TOOLS            ; +  142 bytes for trivial DIR, FAT, CLUSTR. and SECTOR. view, (adds UTILITY)  SD_TOOLS.f
 ;DOUBLE              ;              DOUBLE word set                                                 DOUBLE.f
-    .save
-    .listing off
-;===============================================================================
-; Software control flow XON/XOFF configuration:
-;===============================================================================
-; Launchpad <-> UARTtoUSB device <-> TeraTerm TERMINAL
-;        RX <-- TX
-;        TX --> RX
-;       GND <-> GND
-;
-; TERATERM config terminal:     NewLine receive : LF,
-;                               NewLine transmit : CR+LF
-;                               Size : 96 chars x 49 lines (adjust lines according to your display)
-;
-; TERATERM config serial port:  TERMINALBAUDRATE value,
-;                               8 bits, no parity, 1 Stop bit,
-;                               XON/XOFF flow control,
-;                               delay = 0ms/line, 0ms/char
-;
-; don't forget to save always new TERATERM configuration !
 
 ; ------------------------------------------------------------------------------
-; Only two usb2uart bridges correctly handle XON / XOFF: cp2102 and pl2303.
-; ------------------------------------------------------------------------------
-; the best and cheapest: UARTtoUSB cable with Prolific PL2303HXD (or PL2303TA)
-; works well in 3 WIRES (XON/XOFF) and 4WIRES (GND,RX,TX,RTS) config
-; ------------------------------------------------------------------------------
-;       PL2303TA 4 wires CABLE                         PL2303HXD 6 wires CABLE
-; pads upside: 3V3,txd,rxd,gnd,5V               pads upside: gnd, 3V3,txd,rxd,5V
-;    downside: cts,dcd,dsr,rts,dtr                 downside:     rts,cts
-; ------------------------------------------------------------------------------
-; WARNING ! if you use PL2303TA/HXD cable as supply, open the box before to weld red wire on 3v3 pad !
-; ------------------------------------------------------------------------------
-; up to 115200  Bds  (500kHz)
-; up to 230400  Bds  (1MHz)
-; up to 460800  Bds  (2MHz)
-; up to 921600  Bds  (4MHz)
-; up to 1843200 Bds  (8MHz)
-; up to 3 MBds       (12MHz,PL2303HXD with shortened cable < 80cm)
-; up to 4 MBds       (16MHz,PL2303HXD with shortened cable < 60cm)
-; up to 5 MBds       (20MHz,PL2303HXD with shortened cable < 40cm)
-; up to 6 MBds       (24MHz,PL2303HXD with shortened cable < 20cm)
-
-; UARTtoUSB module with Silabs CP2102 (supply current = 20 mA)
-; ------------------------------------------------------------------------------
-; WARNING ! if you use it as supply, buy a CP2102 module with a VCC switch 5V/3V3 and swith on 3V3 !
-; ------------------------------------------------------------------------------
-; 9600,19200,38400 (250kHz)
-; + 57600, 115200 (500kHz)
-; + 134400,230400 (1MHz)
-; + 460800 (2MHz)
-; + 921600 (4MHz,8MHz,16MHz,24MHz)
-
-;===============================================================================
-; Hardware control flow configuration: RTS is wired on UART2USB CTS pin
-;===============================================================================
+    .include "ThingsInFirst.inc" ; macros, target definitions, RAM & INFO variables...
+;-------------------------------------------------------------------------------
+    .org    MAIN_ORG
+;-------------------------------------------------------------------------------
+; MEMORY OPERATIONS
+;-------------------------------------------------------------------------------
+            FORTHWORD "@"
+; https://forth-standard.org/standard/core/Fetch
+; @       a-addr -- x   fetch cell from memory
+FETCH       MOV @TOS,TOS
+            MOV @IP+,PC
 
-; Launchpad <-> UARTtoUSB
-;        RX <-- TX
-;        TX --> RX
-;       RTS --> CTS     (see launchpad.asm for RTS selected pin)
-;       GND <-> GND
+            FORTHWORD "!"
+; https://forth-standard.org/standard/core/Store
+; !        x a-addr --   store cell in memory
+STORE       MOV @PSP+,0(TOS);4
+            MOV @PSP+,TOS   ;2
+            MOV @IP+,PC     ;4
 
-; RTS pin may be permanently wired on SBWTCK/TEST pin without disturbing SBW 2 wires programming
+;-----------------------------------;
+; modifying TOs is forbidden here ! ;
+;-----------------------------------;
+INIT_FORTH                          ; common QABORT|WARM subroutine
+;-----------------------------------;
+            MOV @RSP+,IP            ; init IP with CALLER next address
+;                                   ;
+            MOV #PUC_ABORT_ORG,X    ; FRAM INFO         FRAM MAIN
+;                                   ; ---------         ---------
+            MOV @X+,&PFAACCEPT      ; BODYACCEPT    --> PFAACCEPT
+            MOV @X+,&PFAEMIT        ; BODYEMIT      --> PFAEMIT
+            MOV @X+,&PFAKEY         ; BODYKEY       --> PFAKEY
+            MOV @X+,&CIB_ORG        ; TIB_ORG       --> CIB_ORG             TIB = Terminal Input Buffer, CIB = Current Input Buffer
+;                                   ;
+;                                   ; FRAM INFO         REG|RAM
+;                                   ; ---------         -------
+            MOV @X+,RSP             ; INIT_RSTACK   --> R1=RSP              PSP is initialised with ABORT
+            MOV @X+,rDOCOL          ; EXIT          --> R4=rDOCOL           (if DTC=2)
+            MOV @X+,rDODOES         ; XDODOES       --> R5=rDODOES
+            MOV @X+,rDOCON          ; XDOCON        --> R6=rDOCON
+            MOV @X+,rDOVAR          ; RFROM         --> R7=rDOVAR
+            MOV @X+,&BASEADR        ; INIT_BASE     --> RAM BASE            init decimal base
+            MOV @X+,&LEAVEPTR       ; INIT_LEAVE    --> RAM LEAVEPTR
+            MOV #0,&STATE           ; 0             --> RAM STATE
+            CALL &SOFT_APP          ; default SOFT_APP = INIT_SOFT = RET_ADR, value set by DEEP_RESET.
+            MOV #SEL_RST,PC         ; goto PUC 7 to select the user's choice from TOS value: RST_RET|DEEP_RESET
+;-----------------------------------;
 
-; TERATERM config terminal      : NewLine receive : LF,
-;                                 NewLine transmit : CR+LF
-;                                 Size : 96 chars x 49 lines (adjust lines to your display)
+;-------------------------------------------------------------------------------
+; DTCforthMSP430FR5xxx program (FRAM) memory
+;-------------------------------------------------------------------------------
 
-; TERATERM config serial port   : TERMINALBAUDRATE value,
-;                                 8bits, no parity, 1Stopbit,
-;                                 Hardware flow control,
-;                                 delay = 0ms/line, 0ms/char
+    .IFNDEF UART_TERMINAL
+        .include "forthMSP430FR_TERM_I2C.asm"
+    .ELSE
+        .IFDEF HALFDUPLEX
+            .include "forthMSP430FR_TERM_HALF.asm"
+        .ELSE
+            .include "forthMSP430FR_TERM_UART.asm"
+        .ENDIF
+    .ENDIF
+    .IFDEF SD_CARD_LOADER
+        .include "forthMSP430FR_SD_ACCEPT.asm"
+    .ENDIF
 
-; don't forget : save new TERATERM configuration !
+    .IF DTC = 1                     ; DOCOL = CALL rDOCOL, [rDOCOL] = XDOCOL
+XDOCOL      MOV @RSP+,W             ; 2
+            PUSH IP                 ; 3     save old IP on return stack
+            MOV W,IP                ; 1     set new IP to PFA
+            MOV @IP+,PC             ; 4     = NEXT
+    .ENDIF                          ; 10 cycles
 
-; notice that the control flow seems not necessary for TX (CTS <-- RTS)
+            FORTHWORD "TYPE"
+;https://forth-standard.org/standard/core/TYPE
+;C TYPE    adr u --     type string to terminal
+TYPE        PUSH IP                 ;3
+            MOV #TYPE_NEXT+2,IP     ;2                  because SUB #2,IP
+            MOV @PSP+,X             ;2 -- len           X = adr
+TYPELOOP    SUB #2,IP               ;1                  [IP] = TYPE_NEXT
+            SUB #2,PSP              ;1 -- x len
+            MOV TOS,0(PSP)          ;3 -- len len
+            MOV.B @X+,TOS           ;2 -- len char
+            JMP EMIT                ;22                 S T W regs are free
+TYPE_NEXT   mNEXTADR                ;  -- len
+            SUB.B #1,TOS            ;1 -- len-1         byte operation, according to the /COUNTED-STRING value
+            JNZ TYPELOOP            ;2                  32~/19~ EMIT loop 312/526 kBds/MHz --> 7.5MBds @ 24 MHz
+            JZ DROPEXIT             ;2
 
-; UARTtoUSB module with PL2303TA/HXD
 ; ------------------------------------------------------------------------------
-; WARNING ! if you use PL2303TA/HXD cable as supply, open the box before to weld red wire on 3v3 pad !
-; ------------------------------------------------------------------------------
-; up to 250 kbds / MHz
-; ----------------------------------
-; 9600,19200,38400,57600    (250kHz)
-; + 115200                  (500kHz)
-; + 201600,230400,250000    (1MHz)
-; + 403200,460800           (2MHz)
-; + 806400,921600           (4MHz)
-; + 1843200                 (8MHz)
-; + 2764800                 (12MHz)
-; + 4000000                 (16MHz)
-; + 5000000                 (20MHz)
-; + 6000000                 (24MHz)
-
-; UARTtoUSB module with FTDI FT232RL (FT230X don't work correctly)
-; ------------------------------------------------------------------------------
-; WARNING ! buy a FT232RL module with a switch 5V/3V3 and select 3V3 !
-; ------------------------------------------------------------------------------
-; 9600,19200,38400,57600,115200 (500kHz)
-; + 230400 (1MHz)
-; + 460800 (2MHz)
-; + 921600 (4,8,16 MHz)
-
+; forthMSP430FR :  CONDITIONNAL COMPILATION, 114/109 words
 ; ------------------------------------------------------------------------------
-; UARTtoBluetooth 2.0 module (RN42 sparkfun bluesmirf) at 921600bds
+; goal: speed up the false conditionnal to reach true|false equal time: reached!
 ; ------------------------------------------------------------------------------
-; 9600,19200,38400,57600,115200 (500kHz)
-; + 230400 (1MHz)
-; + 460800 (2MHz)
-; + 921600 (4,8,16 MHz)
-
-; RN42 config : connect RN41/RN42 module on teraterm, via USBtoUART bridge,
-; -----------   8n1, 115200 bds, no flow control, echo on
-;               $$$         // enter control mode, response: AOK
-;               SU,92       // set 921600 bds, response: AOK
-;               R,1         // reset module to take effect
-;
-;               connect RN42 module on FastForth target
-;               add new bluetooth device on windows, password=1234
-;               open the created output COMx port with TERATERM at 921600bds
-
 
-; TERATERM config terminal      : NewLine receive : LF,
-;                                 NewLine transmit : CR+LF
-;                                 Size : 80 chars x 44 lines (adjust lines to your display)
-
-; TERATERM config serial port   : TERMINALBAUDRATE value,
-;                                 8bits, no parity, 1Stopbit,
-;                                 Hardware flow control or software flow control or ...no flow control!
-;                                 delay = 0ms/line, 0ms/char
-
-; don't forget : save new TERATERM configuration !
+            FORTHWORDIMM "[THEN]"   ; does nothing
+; https://forth-standard.org/standard/tools/BracketTHEN
+            MOV @IP+,PC
 
-; in fact, compared to using a UART USB bridge, only the COMx port is to be updated.
-    .restore
-; ------------------------------------------------------------------------------
-    .include "ThingsInFirst.inc" ; macros, target definitions, RAM & INFO variables...
-;-------------------------------------------------------------------------------
-    .org    MAIN_ORG
-;-------------------------------------------------------------------------------
-; DTCforthMSP430FR5xxx program (FRAM) memory
-;-------------------------------------------------------------------------------
-; here we place the FORTH primitives without name.
-; User can access them via declarations made in \inc\MSP430FRxxxx.pat
 ; ------------------------------------------------------------------------------
 ; COMPILING OPERATORS
 ; ------------------------------------------------------------------------------
@@ -252,62 +208,12 @@ XSQUOTE     SUB #4,PSP          ; 1                 push old TOS on stack
             ADDC #0,IP          ; 1                 IP=addr+u aligned
             MOV @IP+,PC         ; 4  16~
 
-; primitive MU/MOD; used by ?NUMBER UM/MOD, and M*/ in DOUBLE word set
-; MU/MOD    UDVDlo UDVDhi UDIVlo -- UREMlo UQUOTlo UQUOThi
-;-------------------------------------------------------------------------------
-; unsigned 32-BIT DiViDend : 16-BIT DIVisor --> 32-BIT QUOTient 16-BIT REMainder
-;-------------------------------------------------------------------------------
-; two times faster if 16 bits DiViDend (cases of U. and . among others)
-
-; reg     division            MU/MOD      NUM                       M*/
-; ---------------------------------------------------------------------
-; S     = DVD(15-0)         = ud1lo     = ud1lo                     ud1lo
-; TOS   = DVD(31-16)        = ud1hi     = ud1hi                     ud1mi
-; W     = DVD(47-32)/REM    = rem       = digit --> char --> -[HP]  ud1hi
-; T     = DIV(15-0)         = BASE      = BASE                      ud2
-; X     = QUOTlo            = ud2lo     = ud2lo                     QUOTlo
-; Y     = QUOThi            = ud2hi     = ud2hi                     QUOThi
-; rDODOES = count
-
-MUSMOD      MOV TOS,T               ;1 T = DIVlo
-            MOV 2(PSP),S            ;3 S = DVDlo
-            MOV @PSP,TOS            ;2 TOS = DVDhi
-MUSMOD1     MOV #0,W                ;1  W = REMlo = 0
-            MOV #32,rDODOES         ;2  init loop count
-            CMP #0,TOS              ;1  DVDhi=0 ?
-            JNZ MDIV1               ;2  no
-; ----------------------------------;
-MDIV1DIV2   RRA rDODOES             ;1  yes:loop count / 2
-            MOV S,TOS               ;1      DVDhi <-- DVDlo
-            MOV #0,S                ;1      DVDlo <-- 0
-            MOV #0,X                ;1      QUOTlo <-- 0 (to do QUOThi = 0 at the end of division)
-; ----------------------------------;
-MDIV1       CMP T,W                 ;1  REMlo U>= DIVlo ?
-            JNC MDIV2               ;2  no : carry is reset
-            SUB T,W                 ;1  yes: REMlo - DIVlo ; carry is set
-MDIV2       ADDC X,X                ;1  RLC quotLO
-            ADDC Y,Y                ;1  RLC quotHI
-            SUB #1,rDODOES          ;1  Decrement loop counter
-            JN ENDMDIV              ;2
-            ADD S,S                 ;1  RLA DVDlo
-            ADDC TOS,TOS            ;1  RLC DVDhi
-            ADDC W,W                ;1  RLC REMlo
-            JNC MDIV1               ;2
-            SUB T,W                 ;1  REMlo - DIVlo
-            BIS #1,SR               ;1  SETC
-            JMP MDIV2               ;2
-ENDMDIV     MOV #XDODOES,rDODOES    ;2  restore rDODOES
-            MOV W,2(PSP)            ;3  REMlo in 2(PSP)
-            MOV X,0(PSP)            ;3  QUOTlo in 0(PSP)
-            MOV Y,TOS               ;1  QUOThi in TOS
-RET_ADR     MOV @RSP+,PC            ;4  35 words, about 466/246 cycles, not FORTH executable !
-
 ; : SETIB SOURCE 2! 0 >IN ! ;
 ; SETIB      org len --        set Input Buffer, shared by INTERPRET and [ELSE]
 SETIB       MOV #0,&TOIN            ;3
             MOV @PSP+,&SOURCE_ORG   ;4 -- len
             MOV TOS,&SOURCE_LEN     ;3 -- len
-DROP        MOV @PSP+,TOS           ;2 --
+            MOV @PSP+,TOS           ;2 --
             MOV @IP+,PC             ;4
 
 ; REFILL    accept one line to input buffer and leave org len' of the filled input buffer
@@ -347,53 +253,6 @@ XDOCON                              ; 4 for CALL rDOCON
             MOV @TOS,TOS            ;+2 TOS = CONSTANT value
             MOV @IP+,PC             ;+4 = 16~ = ITC+4
 
-
-    .IFNDEF UART_TERMINAL
-        .include "forthMSP430FR_TERM_I2C.asm"
-    .ELSE
-        .IFDEF HALFDUPLEX
-            .include "forthMSP430FR_TERM_HALF.asm"
-        .ELSE
-            .include "forthMSP430FR_TERM_UART.asm"
-        .ENDIF
-    .ENDIF
-    .IFDEF SD_CARD_LOADER
-        .include "forthMSP430FR_SD_ACCEPT.asm"
-    .ENDIF
-
-    .IF DTC = 1                     ; DOCOL = CALL rDOCOL, [rDOCOL] = XDOCOL
-XDOCOL      MOV @RSP+,W             ; 2
-            PUSH IP                 ; 3     save old IP on return stack
-            MOV W,IP                ; 1     set new IP to PFA
-            MOV @IP+,PC             ; 4     = NEXT
-    .ENDIF                          ; 10 cycles
-
-            FORTHWORD "TYPE"
-;https://forth-standard.org/standard/core/TYPE
-;C TYPE    adr u --     type string to terminal
-TYPE        PUSH IP                 ;3
-            MOV #TYPE_NEXT+2,IP     ;2                  because SUB #2,IP
-            MOV @PSP+,X             ;2 -- len           X = adr
-TYPELOOP    SUB #2,IP               ;1                  [IP] = TYPE_NEXT
-            SUB #2,PSP              ;1 -- x len
-            MOV TOS,0(PSP)          ;3 -- len len
-            MOV.B @X+,TOS           ;2 -- len char
-            JMP EMIT                ;22                 S T W regs are free
-TYPE_NEXT   mNEXTADR                ;  -- len
-            SUB.B #1,TOS            ;1 -- len-1         byte operation, according to the /COUNTED-STRING value
-            JNZ TYPELOOP            ;2                  32~/19~ EMIT loop 312/526 kBds/MHz --> 7.5MBds @ 24 MHz
-            JZ DROPEXIT             ;2
-
-; ------------------------------------------------------------------------------
-; forthMSP430FR :  CONDITIONNAL COMPILATION, 114/109 words
-; ------------------------------------------------------------------------------
-; goal: speed up the false conditionnal to reach true|false equal time: reached!
-; ------------------------------------------------------------------------------
-
-            FORTHWORDIMM "[THEN]"   ; does nothing
-; https://forth-standard.org/standard/tools/BracketTHEN
-            MOV @IP+,PC
-
 ; ------------------------------------------------------------------------------
 ; BRanch if BAD strings COMParaison, [COMPARE ZEROEQUAL QFBRAN] replacement
 QBRBADCOMP                  ; addr1 u1 addr2 u2 --
@@ -417,8 +276,8 @@ QBRNEXTCMP                  ;    -- cnt addr u
             MOV @PSP+,TOS   ;2   -- cnt         + DROP = TWODROP 
             SUB #1,TOS      ;3   -- cnt-1       ONEMINUS
             JNZ BRAN        ;2   -- cnt-1       branch to next comparaison if <> 0
-DROPEXIT    MOV @PSP+,TOS   ;2   --
-            MOV @RSP+,IP    ;2
+DROPEXIT    MOV @RSP+,IP    ;2
+DROP        MOV @PSP+,TOS   ;2   --
             MOV @IP+,PC     ;4
 
             FORTHWORDIMM  "[ELSE]"
@@ -437,11 +296,11 @@ BRACKETELSE mDOCOL
             .word   BRAN,BRACKTELSE1        ;                   6~ versus 5~ for ONEPLUS
 BRACKTELSE0 .word   XSQUOTE                 ;                   end of skiped line
             .byte   5,13,"ko ",10           ;                   send CR + "ko " + LF
-            .word   TYPE                    ;                   CR ." ko " LF 
-            .word   TWODROP_REFILL          ;                   REFILL Input Buffer with next line
+            .word   TYPE                    ; -- cnt addr 0 
+            .word   TWODROP_REFILL          ; -- cnt            REFILL Input Buffer with next line
             .word   SETIB                   ;                   SET Input Buffer pointers SOURCE_LEN, SOURCE_ORG and clear >IN
 BRACKTELSE1 .word   BL_WORD,COUNT           ; -- cnt addr u     Z = 1 if u = 0
-            .word   ZBRAN,BRACKTELSE0       ; -- cnt addr 0     Z = 1 --> end of line, -6~
+            .word   ZBRAN,BRACKTELSE0       ; cnt addr 0 --     Z = 1 --> end of line, -6~
             .word   TWODUP_XSQUOTE          ;                   24 ~
             .byte   6,"[THEN]"              ; -- cnt addr u addr1 u1 addr2 u2
             .word   QBRBADCOMP,BRACKTELSE2  ; -- cnt addr u     if [THEN] not found, jump for next comparaison
@@ -468,7 +327,7 @@ BRACKTELSE4 .word   ONEPLUS                 ; -- cnt+1          if found,  same
 ;If the parse area becomes exhausted, it is refilled as with REFILL. [IF] is an immediate word.
 ;An ambiguous condition exists if [IF] is POSTPONEd,
 ;   or if the end of the input buffer is reached and cannot be refilled before the terminating [ELSE] or [THEN] is parsed.
-BRACKETIF   CMP #0,TOS      ; -- f
+            CMP #0,TOS      ; -- f
             MOV @PSP+,TOS   ; --
             JZ BRACKETELSE  ;       if false flag output
             MOV @IP+,PC     ;       if true flag output
@@ -485,7 +344,7 @@ BRACKETIF   CMP #0,TOS      ; -- f
             .word   BL_WORD,FIND
             mNEXTADR
             SUB #1,TOS      ;1 borrow if TOS was 0
-            SUBC TOS,TOS    ;1 TOS=-1 if borrow was set
+            SUBC TOS,TOS    ;1 TOS=-1 if borrow is set
 NIP_EXIT    MOV @RSP+,IP
 NIP         ADD #2,PSP      ;1
             MOV @IP+,PC     ;4
@@ -499,7 +358,7 @@ NIP         ADD #2,PSP      ;1
 ;Skip leading space delimiters. Parse name delimited by a space.
 ;Return a true flag if name is the name of a word that can be found,
 ;otherwise return a false flag. [DEFINED] is an immediate word.
-DEFINED     mDOCOL
+            mDOCOL
             .word   BL_WORD,FIND
             .word   NIP_EXIT
 
@@ -533,27 +392,11 @@ NEGATE      XOR #-1,TOS     ;1
 ONEPLUS     ADD #1,TOS      ;1  -- n3 = -(n2-n1) = n1-n2
             MOV @IP+,PC
 
-;-------------------------------------------------------------------------------
-; MEMORY OPERATIONS
-;-------------------------------------------------------------------------------
-            FORTHWORD "@"
-; https://forth-standard.org/standard/core/Fetch
-; @       a-addr -- x   fetch cell from memory
-FETCH       MOV @TOS,TOS
-            MOV @IP+,PC
-
-            FORTHWORD "!"
-; https://forth-standard.org/standard/core/Store
-; !        x a-addr --   store cell in memory
-STORE       MOV @PSP+,0(TOS);4
-            MOV @PSP+,TOS   ;2
-            MOV @IP+,PC     ;4
-
 ; ------------------------------------------------------------------------------
 ; STRINGS PROCESSING
 ; ------------------------------------------------------------------------------
 
-; use SQUOTE+10 to enable separator select
+; use SQUOTE+10 if you want to define another separator
 
             FORTHWORDIMM "S\34" ; immediate
 ; https://forth-standard.org/standard/core/Sq
@@ -561,8 +404,7 @@ STORE       MOV @PSP+,0(TOS);4
 SQUOTE      SUB #2,PSP              ;               first choose separator
             MOV TOS,0(PSP)
             MOV #'"',TOS            ;               separator = '"'
-; SQUOTE+10 address                 ;
-            MOV #0,T                ;               volatile CAPS OFF, only for WORDD+4 below
+            MOV #0,T                ;               volatile CAPS OFF, paired with WORDD+4
             mDOCOL              
             .word LIT,XSQUOTE,COMMA ;               obviously use not T register...
             .word WORDD+4           ; -- c-addr     = DP,  W=Count_of_chars
@@ -592,6 +434,56 @@ DOTQUOTE    mDOCOL
 LESSNUM     MOV #HOLD_BASE,&HP
             MOV @IP+,PC
 
+; primitive MU/MOD; used by ?NUMBER UM/MOD, and M*/ in DOUBLE word set
+; MU/MOD    UDVDlo UDVDhi UDIVlo -- UREMlo UQUOTlo UQUOThi
+;-------------------------------------------------------------------------------
+; unsigned 32-BIT DiViDend : 16-BIT DIVisor --> 32-BIT QUOTient 16-BIT REMainder
+;-------------------------------------------------------------------------------
+; two times faster if 16 bits DiViDend (cases of U. and . among others)
+
+; reg     division            MU/MOD      NUM                       M*/
+; ---------------------------------------------------------------------
+; S     = DVD(15-0)         = ud1lo     = ud1lo                     ud1lo
+; TOS   = DVD(31-16)        = ud1hi     = ud1hi                     ud1mi
+; W     = DVD(47-32)/REM    = rem       = digit --> char --> -[HP]  ud1hi
+; T     = DIV(15-0)         = BASE      = BASE                      ud2
+; X     = QUOTlo            = ud2lo     = ud2lo                     QUOTlo
+; Y     = QUOThi            = ud2hi     = ud2hi                     QUOThi
+; rDODOES = count
+
+MUSMOD      MOV TOS,T               ;1 T = DIVlo
+            MOV 2(PSP),S            ;3 S = DVDlo
+            MOV @PSP,TOS            ;2 TOS = DVDhi
+MUSMOD1     MOV #0,W                ;1  W = REMlo = 0
+            MOV #32,rDODOES         ;2  init loop count
+            CMP #0,TOS              ;1  DVDhi=0 ?
+            JNZ MDIV1               ;2  no
+; ----------------------------------;
+MDIV1DIV2   RRA rDODOES             ;1  yes:loop count / 2
+            MOV S,TOS               ;1      DVDhi <-- DVDlo
+            MOV #0,S                ;1      DVDlo <-- 0
+            MOV #0,X                ;1      QUOTlo <-- 0 (to do QUOThi = 0 at the end of division)
+; ----------------------------------;
+MDIV1       CMP T,W                 ;1  REMlo U>= DIVlo ?
+            JNC MDIV2               ;2  no : carry is reset
+            SUB T,W                 ;1  yes: REMlo - DIVlo ; carry is set
+MDIV2       ADDC X,X                ;1  RLC quotLO
+            ADDC Y,Y                ;1  RLC quotHI
+            SUB #1,rDODOES          ;1  Decrement loop counter
+            JN ENDMDIV              ;2
+            ADD S,S                 ;1  RLA DVDlo
+            ADDC TOS,TOS            ;1  RLC DVDhi
+            ADDC W,W                ;1  RLC REMlo
+            JNC MDIV1               ;2  14~
+            SUB T,W                 ;1  REMlo - DIVlo
+            BIS #1,SR               ;1  SETC
+            JMP MDIV2               ;2  14~
+ENDMDIV     MOV #XDODOES,rDODOES    ;2  restore rDODOES
+            MOV W,2(PSP)            ;3  REMlo in 2(PSP)
+            MOV X,0(PSP)            ;3  QUOTlo in 0(PSP)
+            MOV Y,TOS               ;1  QUOThi in TOS
+RET_ADR     MOV @RSP+,PC            ;4  35 words, about 440/240 cycles, not FORTH executable !
+
             FORTHWORD "#"
 ; https://forth-standard.org/standard/core/num
 ; #     ud1lo ud1hi -- ud2lo ud2hi          convert 1 digit of output
@@ -617,7 +509,7 @@ NUMS        mDOCOL
             mNEXTADR                ;       next adr
             SUB #2,IP               ;1      restore NUM return
             BIS TOS,X               ;1
-            CMP #0,X                ;1      ud = 0 ?
+            CMP #0,X                ;1 --   ud2lo ud2hi      ud = 0 ?
             JNZ NUM1                ;2
 EXIT        MOV @RSP+,IP            ;2      when DTC=2 rDOCOL is loaded with this EXIT address
             MOV @IP+,PC             ;4 10 words, about 294|494 cycles for u|ud one digit
@@ -640,50 +532,46 @@ HOLD        MOV.B TOS,W             ;1
             FORTHWORD "SIGN"
 ; https://forth-standard.org/standard/core/SIGN
 ; SIGN  n --           add minus sign if n<0
-SIGN        CMP #0,TOS
-            MOV @PSP+,TOS
-            MOV.B #'-',W
-            JN HOLDW                ; jump if 0<
-            MOV @IP+,PC
+SIGN        CMP #0,TOS              ; 1
+            MOV @PSP+,TOS           ; 2
+            MOV.B #'-',W            ; 2
+            JN HOLDW                ; jump if 0<
+            MOV @IP+,PC             ; 4
 
 BL          CALL rDOCON
-            .word   20h
+            .word   ' '
 
             FORTHWORD "U."
 ; https://forth-standard.org/standard/core/Ud
 ; U.    u --           display u (unsigned)
 ; note: DDOT = UDOT + 10 (see DOUBLE.f)
-UDOT        MOV #0,S                ; 1 -- hi=0
-            SUB #2,PSP              ; 1 convert n|u to d|ud with Y = -1|0
-            MOV TOS,0(PSP)          ; 3 -- lo lo
-            MOV S,TOS               ; 1 -- lo hi
-DDOT        PUSHM #2,IP             ; 4             R-- IP S=sign
-            AND #-1,TOS             ; clear V, set N
-            JGE DDOTNEXT            ; if hi positive (N=0)
-            XOR #-1,0(PSP)          ;4
-            XOR #-1,TOS             ;1
-            ADD #1,0(PSP)           ;4
-            ADDC #0,TOS             ;1
-DDOTNEXT    mASM2FORTH              ;10
+UDOT        MOV #0,S                ; 1                 S=sign
+            SUB #2,PSP              ; 1
+            MOV TOS,0(PSP)          ; 3 -- |lo| x
+            MOV #0,TOS              ; 1 -- |lo| |hi|     
+UDOTNEXT    PUSHM #2,IP             ; 4                 R-- IP sign
+            mASM2FORTH              ;10
             .word   LESSNUM
-            .word   BL,HOLD         ; add a trailing space
-            .word   NUMS            ;               R-- IP sign
-            .word   RFROM,SIGN      ;               R-- IP
+            .word   BL,HOLD         ;                   add a trailing space
+            .word   NUMS            ;
+            .word   RFROM,SIGN      ;           IP sign R-- IP
             .word   NUMGREATER,TYPE
-            .word   EXIT
+            .word   EXIT            ;                IP R-- 
 
             FORTHWORD "."
 ; https://forth-standard.org/standard/core/d
 ; .     n --           display n (signed)
 DOT         CMP #0,TOS
             JGE UDOT
-            MOV #-1,S
+            XOR #-1,TOS             ;1 set TOS = |lo|
+            ADD #1,TOS              ;1
+            MOV #-1,S               ;1 set S = minus sign
             JMP UDOT+2
 
 ;-------------------------------------------------------------------------------
 ; INTERPRETER
 ;-------------------------------------------------------------------------------
-
+;
 ; https://forth-standard.org/standard/core/WORD
 ; WORD   char -- addr        Z=1 if len=0
 ; parse a word delimited by char separator.
@@ -692,12 +580,13 @@ DOT         CMP #0,TOS
 ; notice that the average lenght of all CORE definitions is about 4.
             FORTHWORD "WORD"
             JMP WORDD           ;2
+
 ;-------------------------------;
 BL_WORD     SUB #2,PSP          ;1              )
             MOV TOS,0(PSP)      ;3              > 6~ instead of 16~ for CONSTANT BL runtime
             MOV #' ',TOS        ;2 -- BL        ) 
-WORDD       MOV &CAPS,T         ;3              CAPS OFF = 0, CAPS ON = $20.
-            MOV #SOURCE_LEN,S   ;2 --           WORDD+4 address
+WORDD       MOV #20h,T          ;3 -- sep       CAPS OFF = 0, CAPS ON = $20.
+            MOV #SOURCE_LEN,S   ;2              WORD+16 address
             MOV @S+,X           ;2              X = src_len
             MOV @S+,Y           ;2              Y = src_org
             ADD Y,X             ;1              X = src_len + src_org = src_end
@@ -708,13 +597,13 @@ SKIPSEPLOOP CMP X,Y             ;1              src_ptr >= src_end ?
             JC SKIPSEPEND       ;2              if yes : End Of Line !
             CMP.B @Y+,TOS       ;2              does char = separator ?
             JZ SKIPSEPLOOP      ;2              if yes; 7~ loop
-;-------------------------------;
             SUB #1,Y            ;1              decrement the post incremented src_ptr
-SCANTICK    CMP.B #"'",2(Y)     ;4              third char = TICK ? (allow ' as first char for a defined word)
+;-------------------------------;
+SCANTICK    CMP.B #"'",2(Y)     ;4              third char = TICK ? (that allows ' as first char for a definition name)
             JNZ SCANWRDLOOP     ;2              no
-            MOV #0,T            ;1              don't change to upper case for a 'char' input
+            MOV #0,T            ;1              don't capitalize a 'char' input
 ;-------------------------------;
-SCANWRDLOOP MOV.B S,0(W)        ;3              first, S makes room in dst for word length; next, put char here.
+SCANWRDLOOP MOV.B S,0(W)        ;3              first, make room in dst for word length; next, put char here.
             CMP X,Y             ;1              src_ptr = src_end ?
             JZ SCANWRDEND       ;2              if yes
             MOV.B @Y+,S         ;2              S=char
@@ -727,9 +616,10 @@ SCANWRDLOOP MOV.B S,0(W)        ;3              first, S makes room in dst for w
             JC SCANWRDLOOP      ;2              U>= loopback if yes
             SUB.B T,S           ;1              convert a...z to A...Z if CAPS ON (T=$20)
             JMP SCANWRDLOOP     ;2              23~ lower case char loop
+SKIPSEPEND
 SCANWRDEND  SUB &SOURCE_ORG,Y   ;3 -- sep       Y=src_ptr - src_org = new >IN (first char separator next)
-            MOV Y,&TOIN         ;3              update >IN for next word search in this input stream
-SKIPSEPEND  MOV &DP,TOS         ;3 -- addr      TOS = HERE
+            MOV Y,&TOIN         ;3              update >IN for next search in this input stream
+            MOV &DP,TOS         ;3 -- addr      TOS = HERE
             SUB TOS,W           ;1              W = Word_Length >= 0
             MOV.B W,0(TOS)      ;3 -- c-addr
             MOV @IP+,PC         ;4              Z=1 <==> Word_Length = 0 <==> EOL, tested by INTERPRET
@@ -740,12 +630,12 @@ SKIPSEPEND  MOV &DP,TOS         ;3 -- addr      TOS = HERE
 ;                  CFA -1      if found     ; flag Z=0
 ;                  CFA  1      if immediate ; flag Z=0
 ; compare WORD at c-addr (HERE)  with each of words in each of listed vocabularies in CONTEXT
-; start of FIND     : 5 cycles
-; VOCLOOP           : 5/12 cycles,
-; mismatch word loop: +14 cycles on len, 
+; start of FIND     : 24/33 cycles
 ;                     +7  cycles on first char,
-;                     +10 cycles char loop,
-; WORDFOUND to end  : 15/16 cycles.
+;                     +10 cycles x (n-1 char),
+; WORDFOUND to end  : 16 cycles.
+; VOCLOOP           : 12/19 cycles.
+; name loop         : 8  cycles. 
 ; note: with 16 threads vocabularies, FIND takes only! 75% of CORETEST.4th processing time
 FIND        SUB #2,PSP          ;1 -- ???? c-addr       reserve one cell, not at FINDEND which would kill the Z flag
             MOV TOS,S           ;1                      S=c-addr
@@ -786,71 +676,6 @@ WORDFOUND   BIT #1,X            ;1
 FINDEND     MOV S,0(PSP)        ;3 -- xt -1/0/1         if not found: -- c-addr 0    flag Z=1
             MOV @IP+,PC         ;4 34/40 words          return to interpreter
 
-;             FORTHWORD "FIND"    ;
-; ; https://forth-standard.org/standard/core/FIND
-; ; FIND     addr -- c-addr 0    if not found ; flag Z=1       c-addr at transient RAM area (HERE)
-; ;                  CFA -1      if found     ; flag Z=0
-; ;                  CFA  1      if immediate ; flag Z=0
-; ; compare WORD at c-addr (HERE)  with each of words in each of listed vocabularies in CONTEXT
-; ; start of FIND     : 4/11 cycles
-; ; VOCLOOP           : 6 cycles,
-; ; mismatch word loop: +14 cycles on len, 
-; ;                     +7  cycles on first char,
-; ;                     +10 cycles char loop,
-; ; WORDFOUND to end  : 15/17 cycles.
-; ; note: with 16 threads vocabularies, FIND takes only! 75% of CORETEST.4th processing time
-; FIND                            ;
-;     .SWITCH THREADS             ;
-;     .CASE   1                   ;                       nothing to do
-;     .ELSECASE                   ;                       searching thread adds 7 cycles & 6 words
-;             MOV.B 1(TOS),rDOCON ;3                      S=c-addr rDOCON=first char of c-addr string
-;             AND.B #(THREADS-1),rDOCON;2                 rDOCON=thread_x
-;             ADD rDOCON,rDOCON   ;1                      rDOCON=thread_offset_x
-;             ADD #2,rDOCON       ;1                      rDOCON=thread_offset_x+2
-;     .ENDCASE
-;             SUB #2,PSP          ;1 -- ???? c-addr       reserve one cell, not at FINDEND which would kill the Z flag
-;             MOV TOS,S           ;1                      S=c-addr
-;             MOV #CONTEXT,T      ;2                      T = first cell addr of CONTEXT stack
-; VOCLOOP     MOV @T+,TOS         ;2 -- ???? VOC_PFA      T=CTXT+2
-;             CMP #0,TOS          ;1                      no more vocabulary in CONTEXT ?
-;             JZ FINDEND          ;2 -- ???? 0            yes ==> exit; Z=1
-;     .SWITCH THREADS
-;     .CASE   1                   ;                       nothing to do
-;             ADD #2,TOS          ;1 -- ???? VOC_PFAx+2
-;     .ELSECASE                   ;                       searching thread adds 7 cycles & 6 words
-;             ADD rDOCON,TOS      ;1 -- ???? VOC_PFAx+2   TOS = words set entry
-;     .ENDCASE
-; WORDLOOP    MOV -2(TOS),TOS     ;3 -- ???? NFA          -2(TOS) = [VOC_PFAx] first, then [LFA]
-;             CMP #0,TOS          ;1                      no more word in the thread ?
-;             JZ VOCLOOP          ;2                      yes ==> search next voc in context
-;             MOV TOS,X           ;1
-;             MOV.B @X+,Y         ;2                      TOS = NFA,  X= NFA+1, Y = NFA_first_byte = cnt<<2+i (i= immediate flag)
-;             RRA.B Y             ;1                      remove immediate flag, the remainder is the count of the definition name.
-; LENCOMP     CMP.B @S,Y          ;2                      compare lenght
-;             JNZ WORDLOOP        ;2                      14~ word loop on lenght mismatch
-;             MOV S,W             ;1                      S=W=c-addr
-; CHARCOMP    CMP.B @X+,1(W)      ;4                      compare chars
-;             JNZ WORDLOOP        ;2                      21~ word loop on first char mismatch
-;             ADD #1,W            ;1
-;             SUB.B #1,Y          ;1                      decr count
-;             JNZ CHARCOMP        ;2                      10~ char loop
-; WORDFOUND   BIT #1,X            ;1
-;             ADDC #0,X           ;1
-;             MOV X,S             ;1                      S=aligned CFA
-;             MOV.B @TOS,TOS      ;2 -- ???? NFA_1st_byte 
-;             AND #1,TOS          ;1 -- ???? 0|1          test immediate flag
-;             JNZ FINDEND         ;2 -- ???? 1            jump if bit 1 is set, as immediate bit
-;             SUB #1,TOS          ;1 -- ???? -1
-; FINDEND
-;     .CASE   1                   ;                       nothing to do
-;     .ELSECASE                   ;                       searching thread adds 7 cycles & 6 words
-;             MOV #XDOCON,rDOCON  ;2
-;     .ENDCASE
-;             MOV S,0(PSP)        ;3 -- xt -1/0/1         if not found: -- c-addr 0    flag Z=1
-;             MOV @IP+,PC         ;4 34/40 words          return to interpreter
-
-    .IFDEF MPY_32 ; if 32 bits hardware multiplier
-
             FORTHWORD ">NUMBER"
 ; >NUMBER  ud1lo ud1hi addr1 cnt1 -- ud2lo ud2hi addr2 cnt2
 ; https://forth-standard.org/standard/core/toNUMBER
@@ -861,36 +686,66 @@ FINDEND     MOV S,0(PSP)        ;3 -- xt -1/0/1         if not found: -- c-addr
 ; or the first character past the end of the string if the string was entirely converted.
 ; cnt2 is the number of unconverted characters in the string.
 ; An ambiguous condition exists if ud2 overflows during the conversion.
-TONUMBER    MOV &BASEADR,T      ;3                      T = base
+
+            MOV &BASEADR,T      ;3                      T = base
             MOV @PSP+,S         ;2 -- ud1lo ud1hi cnt1  S = addr1
             MOV @PSP+,Y         ;2 -- ud1lo cnt1        Y = ud1hi
             MOV @PSP,X          ;2 -- x cnt1            X = ud1lo
             SUB #4,PSP          ;1 -- x x x cnt1
-TONUMLD_OP1 MOV T,&MPY          ;3                      base = MPY = OP1 loaded out of TONUMLOOP
+TONUM_INPUT                     ;                       for QNUMBER
+    .IFDEF MPY_32 ; if 32 bits hardware multiplier
+            MOV T,&MPY          ;3                      base = MPY = OP1 loaded out of TONUMLOOP
+    .ENDIF
 TONUMLOOP   MOV.B @S,W          ;2 -- x x x cnt         S=adr, T=base, W=char, X=udlo, Y=udhi
 DDIGITQ     SUB.B #':',W        ;2                      all Ctrl_Chars < '0'  and all chars '0' to '9' become negative
             JNC DDIGITQNEXT     ;2                      accept all chars U< ':'  (accept $0 up to $39)
             SUB.B #7,W          ;2                      W = char - (':' + $07 = 'A')
             JNC TONUMEND        ;2 -- x x x cnt         reject all Ctrl_Chars U< 'A', (with Z flag = 0)
 DDIGITQNEXT ADD.B #0Ah,W        ;2                      restore digit value: 0 to 15 (and beyond)
-            CMP T,W             ;1                      digit-base (U>= comparaison rejects all Ctrl_Chars)
-            BIC #Z,SR           ;1                      reset Z before return to QNUMBER because else
+            CMP T,W             ;1                      digit - base
+            BIC #Z,SR           ;1                      clear Z before return to QNUMBER
             JC TONUMEND         ;2                      to avoid QNUMBER conversion true with digit=base :-(
+    .IFDEF MPY_32 ; if 32 bits hardware multiplier      (ud * base) + digit --> ud 
             MOV X,&OP2L         ;3                      Load 2nd operand (ud1lo)
             MOV Y,&OP2H         ;3                      Load 2nd operand (ud1hi)
             MOV &RES0,X         ;3                      lo result in X (ud2lo)
             MOV &RES1,Y         ;3                      hi result in Y (ud2hi)
-            ADD W,X             ;1                      ud2lo + digit
+ADD_DIGIT   ADD W,X             ;1                      ud2lo + digit
             ADDC #0,Y           ;1                      ud2hi + carry
 TONUMPLUS   ADD #1,S            ;1                      adr+1
-            SUB #1,TOS          ;1 -- x x x cnt         cnt-1
-            JNZ TONUMLOOP       ;2                      if count <>0    34~ digit loop
+            SUB #1,TOS          ;1 -- x x x cnt-1       cnt-1
+            JNZ TONUMLOOP       ;2                      if count <>0    33~ per digit
 TONUMEND    MOV S,0(PSP)        ;3 -- x x addr2 cnt2
+    .ELSE ; no hardware multiplier                      (ud * base) + digit --> ud 
+            MOV #0,rDODOES      ;1 RESlo=0
+            MOV #0,rDOCON       ;1 REShi=0
+            MOV #1,rDOVAR       ;1 BIT TEST for base
+MUL_LOOP    BIT rDOVAR,T        ;1 test actual bit in base  (OP1)
+            JZ MUL_SHIFT        ;2
+            ADD X,rDODOES       ;1 IF 1: ADD ud1lo TO RESlo (OP2L + RES0 --> RES0)
+            ADDC Y,rDOCON       ;1      ADDC ud1hi TO REShi (OP2H + RES1 + C --> RES1)
+MUL_SHIFT   ADD X,X             ;1 (RLA LSBs) ud1lo *2      (OP2L*2)
+            ADDC Y,Y            ;1 (RLC MSBs) ud1hi *2      (OP2H*2)
+            ADD rDOVAR,rDOVAR   ;1 (RLA) NEXT BIT TO TEST   (BIT_TEST<1)
+            JNC MUL_LOOP        ;2 IF BIT IN CARRY: FINISHED
+            MOV rDODOES,X       ;1 RESlo --> ud2lo
+            MOV rDOCON,Y        ;1 REShi --> ud2hi
+ADD_DIGIT   ADD W,X             ;1                      ud2lo + digit
+            ADDC #0,Y           ;1                      ud2hi + carry
+TONUMPLUS   ADD #1,S            ;1                      adr+1
+            SUB #1,TOS          ;1 -- x x x cnt-1       cnt-1
+            JNZ TONUMLOOP       ;2                      if count <>0   158/160/158 ~ per digit with base 2/10/16
+TONUMEND    MOV #FORTH_ORG+4,W  ;2
+            MOV @W+,rDODOES     ;2                      XDODOES --> R5=rDODOES
+            MOV @W+,rDOCON      ;2                       XDOCON --> R6=rDOCON
+            MOV @W,rDOVAR       ;2                        RFROM --> R7=rDOVAR
+            MOV S,0(PSP)        ;3 -- x x addr2 cnt2
+    .ENDIF
             MOV Y,2(PSP)        ;3 -- x ud2hi addr2 cnt2
             MOV X,4(PSP)        ;3 -- ud2lo ud2hi addr2 cnt2
-            MOV @IP+,PC         ;4 40 words
+            MOV @IP+,PC         ;4
 
-; ?NUMBER makes the interface between INTERPRET and >NUMBER; it's a subset of INTERPRET.
+; ?NUMBER makes the interface between INTERPRET and >NUMBER; also used by ASSEMBLER.
 ; convert a string to a signed number; FORTH 2012 prefixes $  %  # are recognized,
 ; FORTH 2012 'char' numbers also, digits separator '_' also.
 ; with DOUBLE_INPUT option, 32 bits signed numbers (with decimal point) are recognized,
@@ -899,12 +754,14 @@ TONUMEND    MOV S,0(PSP)        ;3 -- x x addr2 cnt2
 ; chars . , _  are processed as >NUMBER exits.
 ;Z ?NUMBER  addr -- n|d -1  if convert ok ; flag Z=0, UF9=1 if double
 ;Z          addr -- addr 0  if convert ko ; flag Z=1
+
+INTQNUM     MOV #INTQNUMNEXT,IP ;2                          INTQNUMNEXT is the next of QNUMBER     
 QNUMBER                         ;  -- addr
         .IFDEF DOUBLE_NUMBERS   ;                           DOUBLE_NUMBERS = DOUBLE_INPUT | FIXPOINT_INPUT
-            BIC #UF9,SR         ;2                          reset UserFlag_9 used as double number flag
+            BIC #UF9,SR         ;2                          clear UserFlag_9 used as double number flag
         .ENDIF                  ;
             SUB #8,PSP          ;1 -- x x x x addr          make room for >NUMBER
-            MOV TOS,6(PSP)      ;3 -- addr x x x addr       save TOS
+            MOV TOS,6(PSP)      ;3 -- addr x x x addr       save TOS for TONUMEXIT 
             MOV #0,Y            ;1                          Y=ud1hi=0
             MOV #0,X            ;1                          X=ud1lo=0
             MOV &BASEADR,T      ;3                          T=BASE
@@ -914,9 +771,9 @@ QNUMBER                         ;  -- addr
             MOV #TONUMEXIT,IP   ;2                          set TONUMEXIT as return from >NUMBER
             MOV.B @S+,TOS       ;2 -- addr x x x cnt        TOS=count, S=addr+1
 QNUMLDCHAR  MOV.B @S,W          ;2                          W=char
-            SUB.B #'-',W        ;2
-            JZ QNUMMINUS        ;2
-            JC TONUMLD_OP1      ;2 -- addr x x x cnt        jump if char U> '-', case of numeric chars
+            SUB.B #'-',W        ;2                          char '-' ?
+            JZ QNUMMINUS        ;2                              negate sign
+            JC TONUM_INPUT      ;2 -- addr x x x cnt        jump if char U> '-', case of numeric chars
 QBINARY     MOV #2,T            ;1                          preset base 2
             ADD.B #8,W          ;1                          binary '%' prefix ?     '%' + 8 = '-'
             JZ PREFIXNEXT       ;2                          yes
@@ -933,12 +790,12 @@ QTICK       CMP.B #4,W          ;1                          ' prefix ?
             CMP.B @S+,1(S)      ;4 -- addr x x x 3          3rd char = 1st char ?
             MOV.B @S,S          ;2                          does byte to word conversion
             MOV S,4(PSP)        ;3 -- addr ud2lo x x 3      ud2lo = ASCII code of 'char'
-            JMP QNUMNEXT        ;2 -- addr ud2lo x x 3      with happy end only if 3rd char = 1st char = "'"
+            JMP QNUMNEXT        ;2 -- addr ud2lo x x 3      with happy end only if 3rd char = 1st char = '
 QNUMMINUS   MOV #-1,2(RSP)      ;3 R-- sign IP              set sign flag
 PREFIXNEXT  SUB #1,TOS          ;1 -- addr x x x cnt-1      TOS=count-1
             CMP.B @S+,0(S)      ;4                          S=adr+1; same prefix ?
             JNZ QNUMLDCHAR      ;2                          loopback if no
-            JZ TONUMLD_OP1      ;2                          if yes, this 2nd prefix will be rejected by >NUMBER
+            JZ TONUM_INPUT      ;2                          if yes, this double prefix will be rejected by >NUMBER
 ; ------------------------------;46
 TONUMEXIT   mNEXTADR            ;  -- addr ud2lo-hi addr2 cnt2      R-- IP sign BASE    S=addr2
             JZ QNUMNEXT         ;2                                  TOS=0 and Z=1 if conversion is ok
@@ -962,9 +819,10 @@ TONUMEXIT   mNEXTADR            ;  -- addr ud2lo-hi addr2 cnt2      R-- IP sign
             CMP.B #',',W        ;2                                  rejected char by >NUMBER is a comma ?
             .ENDIF              ;
             JNZ QNUMNEXT        ;2                                  no: with Z=0 ==> goto QNUMKO
-S15Q16      MOV TOS,W           ;1 -- addr ud2lo x x x              W=cnt2
-            MOV #0,X            ;1 -- addr ud2lo x 0 x              init X = ud2lo' = 0
-S15Q16LOOP  MOV X,2(PSP)        ;3 -- addr ud2lo ud2lo' 0 x         2(PSP) = ud2lo'
+; ------------------------------;  -- addr ud2lo   x      x     x   S=addr2, T=base
+S15Q16      MOV TOS,W           ;1 -- addr ud2lo   x      x     x   W=cnt2
+            MOV #0,X            ;1 -- addr ud2lo   x      x     x   init X = ud2lo' = 0
+S15Q16LOOP  MOV X,2(PSP)        ;3 -- addr ud2lo ud2lo'   x     x   2(PSP) = X = ud2lo' = 0 then uqlo
             SUB.B #1,W          ;1                                  decrement cnt2
             MOV W,X             ;1                                  X = cnt2-1
             ADD S,X             ;1                                  X = end_of_string-1,-2,-3...
@@ -975,15 +833,15 @@ S15Q16LOOP  MOV X,2(PSP)        ;3 -- addr ud2lo ud2lo' 0 x         2(PSP) = ud2
             JNC S15Q16EOC       ;2                                  reject all chars U< 'A'
 QS15Q16DIGI ADD.B #10,X         ;2                                  restore digit value
             CMP T,X             ;1                                  T=Base, is X a digit ?
-            JC S15Q16EOC        ;2 -- addr ud2lo ud2lo' ud2lo' x    if not a digit
-            MOV X,0(PSP)        ;3 -- addr ud2lo ud2lo' digit x
-            MOV T,TOS           ;1 -- addr ud2lo ud2lo' digit base  R-- IP sign
-            PUSHM #3,S          ;5                                  PUSH S,T,W: R-- IP sign addr2 base cnt2
-            CALL #MUSMOD        ;4 -- addr ud2lo ur uqlo uqhi       CALL MU/MOD
-            POPM #3,S           ;5                                  restore W,T,S: R-- IP sign
-            JMP S15Q16LOOP      ;2                                  W=cnt
-S15Q16EOC   MOV 4(PSP),2(PSP)   ;5 -- addr ud2lo ud2hi uqlo x       ud2lo from >NUMBER becomes here ud2hi part of Q15.16
-            MOV @PSP,4(PSP)     ;4 -- addr ud2lo ud2hi x x          uqlo becomes ud2lo part of Q15.16
+            JC S15Q16EOC        ;2 -- addr ud2lo ud2lo'   x     x   if not a digit, --> goto QNUMKO
+            MOV X,0(PSP)        ;3 -- addr ud2lo ud2lo' digit   x   
+            MOV T,TOS           ;1 -- addr ud2lo ud2lo' digit  base             R-- IP sign
+            PUSHM #3,S          ;5 -- addr ud2lo ud2lo' ud2hi' base PUSH S,T,W: R-- IP sign addr2 base cnt2
+            CALL #MUSMOD        ;4                                  CALL MU/MOD
+            POPM #3,S           ;5 -- addr ud2lo   ur   uqlo   uqhi restore W,T,S: R-- IP sign
+            JMP S15Q16LOOP      ;2                                  X=uqlo
+S15Q16EOC   MOV 4(PSP),2(PSP)   ;5 -- addr ud2lo ud2hi  uqlo   uqhi ud2lo from >NUMBER becomes ud2hi part of Q15.16
+            MOV @PSP,4(PSP)     ;4 -- addr ud2lo ud2hi  uqlo   uqhi uqlo becomes ud2lo part of Q15.16
             CMP.B #0,W          ;1                                  count = 0 if end of conversion ok
         .ENDIF ; FIXPOINT_INPUT
 ; ------------------------------;
@@ -1006,8 +864,8 @@ QDNEGATE    XOR #-1,2(PSP)      ;3 -- udlo udhi -1
             ADD #1,2(PSP)       ;3
             ADDC #0,0(PSP)      ;3
 QDOUBLE     BIT #UF9,SR         ;2 -- dlo dhi tf                    decimal point or comma fixpoint ?
-            JZ NIP              ;2                                  no, goto leave number
-QNUMEND     MOV @IP+,PC         ;4                                  TOS<>0 and Z=0 ==> conversion ok
+            JZ NIP              ;2                                  no, remove dhi, set Z=0
+QNUMEND     MOV @IP+,PC         ;4                                  TOS=tf and Z=0 ==> conversion ok
         .ELSE
 QNUMOK      ADD #4,PSP          ;1 -- addr ud2lo sign
             MOV @PSP,2(PSP)     ;4 -- u u sign                      note : PSP is incremented before write back !!!
@@ -1020,203 +878,6 @@ QNUMEND     ADD #2,PSP          ;1 -- n tf
             MOV @IP+,PC         ;4                                  TOS=-1 and Z=0 ==> conversion ok
         .ENDIF ; DOUBLE_NUMBERS ;
 
-    .ELSE ; if no hardware MPY
-            FORTHWORD "UM*"
-; T.I. UNSIGNED MULTIPLY SUBROUTINE: U1 x U2 -> Ud
-; https://forth-standard.org/standard/core/UMTimes
-; UM*     u1 u2 -- ud   unsigned 16x16->32 mult.
-UMSTAR      MOV @PSP,S          ;2 MDlo
-UMSTAR1     MOV #0,T            ;1 MDhi=0
-            MOV #0,X            ;1 RES0=0
-            MOV #0,Y            ;1 RES1=0
-            MOV #1,W            ;1 BIT TEST REGISTER
-UMSTARLOOP  BIT W,TOS           ;1 TEST ACTUAL BIT MRlo
-            JZ UMSTARNEXT       ;2 IF 0: DO NOTHING
-            ADD S,X             ;1 IF 1: ADD MDlo TO RES0
-            ADDC T,Y            ;1      ADDC MDhi TO RES1
-UMSTARNEXT  ADD S,S             ;1 (RLA LSBs) MDlo x 2
-            ADDC T,T            ;1 (RLC MSBs) MDhi x 2
-            ADD W,W             ;1 (RLA) NEXT BIT TO TEST
-            JNC UMSTARLOOP      ;2 IF BIT IN CARRY: FINISHED    10~ loop
-            MOV X,0(PSP)        ;3 low result on stack
-            MOV Y,TOS           ;1 high result in TOS
-            MOV @IP+,PC         ;4 17 words
-
-            FORTHWORD ">NUMBER"
-; https://forth-standard.org/standard/core/toNUMBER
-; ud2 is the unsigned result of converting the characters within the string specified by c-addr1 u1 into digits,
-; using the number in BASE, and adding each into ud1 after multiplying ud1 by the number in BASE.
-; Conversion continues left-to-right until a character that is not convertible, including '.', ',' or '_',
-; is encountered or the string is entirely converted. c-addr2 is the location of the first unconverted character
-; or the first character past the end of the string if the string was entirely converted.
-; u2 is the number of unconverted characters in the string.
-; An ambiguous condition exists if ud2 overflows during the conversion.
-; >NUMBER  ud1lo|ud1hi addr1 count1 -- ud2lo|ud2hi addr2 count2
-TONUMBER    MOV &BASEADR,W         ;3                          W = base
-            MOV @PSP,S          ;2                          S=adr
-            MOV TOS,T           ;1                          T=count
-TONUMLOOP   MOV.B @S,Y          ;2 -- ud1lo ud1hi x x       S=adr, T=count, W=BASE, Y=char
-DDIGITQ     SUB.B #':',Y        ;2
-            JNC DDIGITQNEXT     ;2                          accept all chars <= 9
-            SUB.B #07,Y         ;2                          reject all chars between "9" and "A"
-            JNC TONUMEND        ;2                          yes: for bad end
-DDIGITQNEXT ADD.B #10,Y         ;2                          restore number
-            CMP W,Y             ;1 -- ud1lo ud1hi x x       digit-base
-            BIC #Z,SR           ;1                          reset Z before jmp TONUMEND because...
-            JC TONUMEND         ;2                          ...QNUMBER conversion will be true if Z = 1  :-(
-UDSTAR      PUSHM #6,IP         ;8 -- ud1lo ud1hi x x       save IP S T W X Y used by UM*   r-- IP adr count base x digit
-            MOV 2(PSP),S        ;3 -- ud1lo ud1hi x x       S=ud1hi
-            MOV W,TOS           ;1 -- ud1lo ud1hi x base
-            MOV #UMSTARNEXT1,IP ;2
-UMSTARONE   JMP UMSTAR1         ;2                          ud1hi * base -- x ud3hi             X=ud3lo
-UMSTARNEXT1 mNEXTADR            ;  -- ud1lo ud1hi x ud3hi
-            MOV X,2(RSP)        ;3                                                          r-- IP adr count base ud3lo digit
-            MOV 4(PSP),S        ;3 -- ud1lo ud1hi x ud3hi   S=ud1lo
-            MOV 4(RSP),TOS      ;3 -- ud1lo ud1hi x base
-            MOV #UMSTARNEXT2,IP ;2
-UMSTARTWO   JMP UMSTAR1         ;2 -- ud1lo ud1hi x ud4hi   X=ud4lo
-UMSTARNEXT2 mNEXTADR            ;  -- ud1lo ud1hi x ud4hi
-            ADD @RSP+,X         ;2 -- ud1lo ud1hi x ud4hi   X=ud4lo+digit=ud2lo             r-- IP adr count base ud3lo
-            ADDC @RSP+,TOS      ;2 -- ud1lo ud1hi x ud2hi   TOS=ud4hi+ud3lo+carry=ud2hi     r-- IP adr count base
-            MOV X,4(PSP)        ;3 -- ud2lo ud1hi x ud2hi
-            MOV TOS,2(PSP)      ;3 -- ud2lo ud2hi x x                                       r-- IP adr count base
-            POPM #4,IP          ;6 -- ud2lo ud2hi x x       W=base, T=count, S=adr, IP=prevIP   r--
-TONUMPLUS   ADD #1,S            ;1
-            SUB #1,T            ;1
-            JNZ TONUMLOOP       ;2 -- ud2lo ud2hi x x       S=adr+1, T=count-1, W=base     68 cycles char loop
-TONUMEND    MOV S,0(PSP)        ;3 -- ud2lo ud2hi adr2 count2
-            MOV T,TOS           ;1 -- ud2lo ud2hi adr2 count2
-            MOV @IP+,PC         ;4 48/82 words/cycles, W = BASE
-
-; ?NUMBER makes the interface between >NUMBER and INTERPRET; it's a subset of INTERPRET.
-; convert a string to a signed number; FORTH 2012 prefixes ' $, %, # are recognized
-; digits separator '_' also.
-; with DOUBLE_INPUT switched ON, 32 bits signed numbers (with decimal point) are recognized
-; with FIXPOINT_INPUT switched ON, Q15.16 signed numbers (with comma) are recognized.
-; prefixes ' # % $ - are processed before calling >NUMBER
-; chars . , _ are processed as >NUMBER exits
-;Z ?NUMBER  addr -- n|d -1  if convert ok ; flag Z=0, UF9=1 if double
-;Z          addr -- addr 0  if convert ko ; flag Z=1
-QNUMBER
-        .IFDEF DOUBLE_NUMBERS   ;           DOUBLE_NUMBERS = DOUBLE_INPUT | FIXPOINT_INPUT
-            BIC #UF9,SR         ;2          reset flag UF9, before use as double number flag
-        .ENDIF                  ;
-            SUB #8,PSP          ;1 -- x x x x addr
-            MOV TOS,6(PSP)      ;3 -- addr x x x addr   save TOS
-            MOV #0,4(PSP)       ;3                      ud1hi=0
-            MOV #0,2(PSP)       ;3 -- addr 0 0 x addr   ud1lo=0
-            MOV &BASEADR,W      ;3                      W=BASE
-            MOV TOS,S           ;1 -- addr ud=0 x x     S=addr
-            MOV #0,TOS          ;1
-            PUSHM #2,TOS        ;4          R-- sign IP (push TOS,IP)
-            MOV #TONUMEXIT,IP   ;2                      define >NUMBER return
-            MOV.B @S+,T         ;2                      S=addr+1, T=count
-QNUMLDCHAR  MOV.B @S,Y          ;2                      Y=char
-            SUB.B #'-',Y        ;2 -- addr ud=0 x x     sign minus ?
-            JZ QNUMMINUS        ;2                      yes
-            JC TONUMLOOP        ;2                      if char U> '-'
-QBINARY     MOV #2,W            ;1                      preset base 2
-            ADD.B #8,Y          ;1                      binary prefix ?     '%' = '-' + 8
-            JZ PREFIXNEXT       ;2                      yes
-QDECIMAL    ADD #8,W            ;1                      preset base 10
-            ADD.B #2,Y          ;1                      decimal prefix ?    '#' = '%' + 2
-            JZ PREFIXNEXT       ;2                      yes
-QHEXA       MOV #16,W           ;2                      preset base 16
-            CMP.B #1,Y          ;1                      hex prefix ?        '$' = '#' + 1
-            JZ PREFIXNEXT       ;2                      yes
-QTICK       CMP.B #4,Y          ;1                      prefix = ' ?        "'" = '#' + 4
-            JNZ QNUMNEXT        ;2 -- addr x x x cnt    no, abort because other prefixes not recognized
-            CMP #3,TOS          ;
-            JNZ QNUMNEXT        ;
-            CMP.B @S+,1(S)      ;4                      compare 3rd with first char '
-            MOV.B @S,S          ;2                      does char to word conversion
-            MOV S,4(PSP)        ;5 -- addr ud2lo x x 3  ud2lo = ASCII code of 'char'
-            JMP QNUMNEXT        ;2                      with happy end if flag Z = 1
-QNUMMINUS   MOV #-1,2(RSP)      ;3 R-- sign IP          set sign flag
-PREFIXNEXT  SUB #1,T            ;1                      T=count-1
-            CMP.B @S+,0(S)      ;4                      S=adr+1; same prefix ?
-            JNZ QNUMLDCHAR      ;2                      no
-            JZ TONUMLOOP        ;2                      yes, that will abort conversion
-; ------------------------------;43
-TONUMEXIT   mNEXTADR            ;  -- addr ud2lo-hi addr2 cnt2      R-- IP sign BASE    S=addr2,T=cnt2
-            JZ QNUMNEXT         ;2                                  if conversion is ok
-            SUB #2,IP
-            MOV.B @S,Y          ;                                   regenerate rejected char
-            CMP.B #'_',Y        ;2                                  rejected char by >NUMBER is a underscore ?
-            JZ TONUMPLUS        ;                                   yes: loopback to >NUMBER to skip char
-        .IFDEF DOUBLE_NUMBERS   ;                                   DOUBLE_NUMBERS = DOUBLE_INPUT | FIXPOINT_INPUT
-            BIT #UF9,SR         ;                                   UF9 already set ? (you have wrongly typed two points)
-            JNZ QNUMNEXT        ;                                   yes, goto QNUMKO
-            BIS #UF9,SR         ;2                                  set double number flag
-        .ENDIF
-        .IFDEF DOUBLE_INPUT
-            SUB.B #'.',Y        ;1                                  rejected char by >NUMBER is a decimal point ?
-            JZ TONUMPLUS        ;2                                  to terminate conversion
-        .ENDIF
-        .IFDEF FIXPOINT_INPUT   ;
-            .IFDEF DOUBLE_INPUT
-            ADD.B #2,Y          ;1                                  rejected char by >NUMBER is a comma ?
-            .ELSE
-            SUB.B #',',Y        ;1                                  rejected char by >NUMBER is a comma ?
-            .ENDIF
-            JNZ QNUMNEXT        ;2                                  no, goto QNUMKO
-S15Q16      MOV #0,X            ;1 -- addr ud2lo x 0 x              init ud2lo' = 0
-S15Q16LOOP  MOV X,2(PSP)        ;3 -- addr ud2lo ud2lo' ud2lo' x    X = 0(PSP) = ud2lo'
-            SUB.B #1,T          ;1                                  decrement cnt2
-            MOV T,X             ;1                                  X = cnt2-1
-            ADD S,X             ;1                                  X = end_of_string-1, first...
-            MOV.B @X,X          ;2                                  X = last char of string, first...
-            SUB.B #':',X        ;2
-            JNC QS15Q16DIGI     ;2                                  accept all chars U< ':'
-            SUB.B #7,X          ;2
-            JNC S15Q16EOC       ;2                                  reject all chars U< 'A'
-QS15Q16DIGI ADD.B #10,X         ;2                                  restore number
-            CMP W,X             ;1                                  W=BASE, is X a digit ?
-            JC  S15Q16EOC       ;2 -- addr ud2lo ud2lo' x ud2lo'    if not a digit
-            MOV X,0(PSP)        ;3 -- addr ud2lo ud2lo' digit x
-            MOV W,TOS           ;1 -- addr ud2lo ud2lo' digit base  R-- IP sign
-            PUSHM #3,S          ;5                                  PUSH S,T,W: R-- IP sign addr2 cnt2 base
-            CALL #MUSMOD        ;4 -- addr ud2lo ur uqlo uqhi
-            POPM #3,S           ;5                                  restore W,T,S: R-- IP sign
-            JMP S15Q16LOOP      ;2                                  W=cnt
-S15Q16EOC   MOV 4(PSP),2(PSP)   ;5 -- addr ud2lo ud2lo uqlo x       ud2lo from >NUMBER part1 becomes here ud2hi=S15 part2
-            MOV @PSP,4(PSP)     ;4 -- addr ud2lo ud2hi x x          uqlo becomes ud2lo
-            CMP.B #0,T          ;1                                  cnt2 = 0 if end of conversion ok
-        .ENDIF ; FIXPOINT_INPUT ;
-; ------------------------------;97
-QNUMNEXT    POPM #2,TOS         ;4 -- addr ud2lo-hi x sign  R: --   POPM IP,TOS  TOS = sign flag = {-1;0}
-            JZ QNUMOK           ;2 -- addr ud2lo-hi x sign          conversion OK if Z=1
-; ------------------------------;
-QNUMKO      ADD #6,PSP          ;1 -- addr sign
-            AND #0,TOS          ;1 -- addr ff                       TOS=0 and Z=1 ==> conversion ko
-            MOV @IP+,PC         ;4
-; ------------------------------;
-        .IFDEF DOUBLE_NUMBERS
-QNUMOK      ADD #2,PSP          ;1 -- addr ud2lo ud2hi sign
-            MOV 2(PSP),4(PSP)   ;  -- udlo udlo udhi sign
-            MOV @PSP+,0(PSP)    ;4 -- udlo udhi sign                note : PSP is incremented before write back !!!
-            XOR #-1,TOS         ;1 -- udlo udhi inv(sign)
-            JNZ QDOUBLE         ;2                                  if jump : TOS=-1 and Z=0 ==> conversion ok
-            XOR #-1,TOS         ;1 -- udlo udhi tf
-Q2NEGATE    XOR #-1,2(PSP)      ;3
-            XOR #-1,0(PSP)      ;3
-            ADD #1,2(PSP)       ;3
-            ADDC #0,0(PSP)      ;3 -- dlo dhi tf
-QDOUBLE     BIT #UF9,SR         ;2 -- dlo dhi tf                decimal point added ?
-            JZ NIP              ;                                   no, goto leave number, Z=0
-QNUMEND     MOV @IP+,PC         ;4                              TOS=-1 and Z=0 ==> conversion ok
-        .ELSE
-QNUMOK      ADD #4,PSP          ;1 -- addr ud2lo sign
-            MOV @PSP,2(PSP)     ;4 -- udlo udlo sign            note : PSP is incremented before write back !!!
-            XOR #-1,TOS         ;1 -- udlo udlo inv(sign)
-            JNZ QNUMEND         ;2                              if jump : TOS=-1 and Z=0 ==> conversion ok
-            XOR #-1,TOS         ;1 -- udlo udlo tf                   TOS=-1 and Z=0
-QNEGATE     XOR #-1,2(PSP)      ;3
-            ADD #1,2(PSP)       ;3 -- n udlo tf
-QNUMEND     ADD #2,PSP          ;1
-            MOV @IP+,PC         ;4                              TOS=-1 and Z=0 ==> conversion ok
-        .ENDIF ; DOUBLE_NUMBERS
-    .ENDIF ; of Hardware/Software MPY
 
             FORTHWORDIMM "\\"       ; immediate
 ; https://forth-standard.org/standard/block/bs
@@ -1226,7 +887,10 @@ BACKSLASH   MOV &SOURCE_LEN,&TOIN   ;
             MOV @IP+,PC
 
 ; ------------------------------;
-; INTERPRET = BACKSLASH + 8     ;
+; INTERPRET=\\+8                ;
+; EXECUTE=\\+$28;               ;
+; ------------------------------;
+
 ; ------------------------------;
 ; INTERPRET    i*x addr u -- j*x      interpret given buffer
 ; This is the common factor of EVALUATE and QUIT.
@@ -1239,9 +903,8 @@ INTLOOP     .word BL_WORD       ; -- c-addr     flag Z = 1 <=> End Of Line
             mNEXTADR            ; -- xt|c-addr|xt -1|0|+1   Z=1 --> not found
             MOV TOS,W           ;                           W = flag = (-1|0|+1) as (not_immediate|not_found|immediate)
             MOV @PSP+,TOS       ; -- xt|c-addr|xt
-            MOV #INTQNUMNEXT,IP ;2              INTQNUMNEXT is the next of QNUMBER
-            JZ QNUMBER          ;2              if Z=1 --> not found, search a number
-            MOV #INTLOOP,IP     ;2              INTLOOP is the continuation of EXECUTE|COMMA
+            JZ INTQNUM          ;2              if Z=1 --> not found, search a number from c_addr
+            MOV #INTLOOP,IP     ;2              INTLOOP is the next of EXECUTE|COMMA
             XOR &STATE,W        ;3
             JZ COMMA            ;2 -- xt        if W xor STATE = 0 compile xt, then loop back to INTLOOP
 EXECUTE     PUSH TOS            ;3 -- xt
@@ -1250,9 +913,9 @@ EXECUTE     PUSH TOS            ;3 -- xt
 ; ------------------------------;
 INTQNUMNEXT mNEXTADR            ;  -- n|c-addr fl   Z = 1 --> not a number, SR(UF9) double number request
             MOV @PSP+,TOS       ;2 -- n|c-addr
-            MOV #INTLOOP,IP     ;2              INTLOOP is the continuation of LITERAL.
+            MOV #INTLOOP,IP     ;2              INTLOOP is the next of LITERAL.
             JNZ LITERAL         ;2 n --         Z = 0 --> is a number, execute LITERAL then loop back to INTLOOP
-NOTFOUND    MOV #FABORT_TERM,IP ;2              ABORT_TERM becomes the end of INTERPRET
+NOTFOUND    MOV #FQABORT_YES,IP ;2              QABORT_YES becomes the end of INTERPRET
             ADD.B #1,0(TOS)     ;3 c-addr --    Z = 1 --> Not a Number : incr string count to add '?'
             MOV.B @TOS,Y        ;2              Y=count+1
             ADD TOS,Y           ;1              Y=end of string addr
@@ -1306,6 +969,13 @@ ZEROLESS    ADD TOS,TOS         ;1 set carry if TOS negative
 INVERT      XOR #-1,TOS         ;1 TOS=-1 if carry was set
             MOV @IP+,PC         ;4
 
+QFRAM_FULL  SUB #2,PSP          ; 2
+            MOV TOS,0(PSP)      ; 3
+            MOV #0,TOS          ; 1
+            CMP #FRAM_FULL,&DP  ; 4
+            JC INVERT           ; 2
+            MOV @IP+,PC         ; 4 16~
+
             FORTHWORD "COUNT"
 ; https://forth-standard.org/standard/core/COUNT
 ; COUNT   c-addr1 -- adr len   counted->adr/len
@@ -1316,17 +986,10 @@ COUNT       SUB #2,PSP          ;1
             AND #-1,TOS         ;1       Z is set if u=0
             MOV @IP+,PC         ;4 12~
 
-QFRAM_FULL  SUB #2,PSP          ; 2
-            MOV TOS,0(PSP)      ; 3
-            MOV #0,TOS          ; 1
-            CMP #FRAM_FULL,&DP  ; 4
-            JC INVERT           ; 2
-            MOV @IP+,PC         ; 4 16~
-
             FORTHWORD "ALLOT"
 ; https://forth-standard.org/standard/core/ALLOT
 ; ALLOT   n --         allocate n bytes
-ALLOT       ADD TOS,&DP
+            ADD TOS,&DP
             MOV @PSP+,TOS
             MOV @IP+,PC
 
@@ -1353,7 +1016,7 @@ QUIT2       .word   XSQUOTE         ; 16~
             .byte   2,13,10         ; CR+LF
     .ENDIF
             .word   TYPE            ; 79~
-            .word   REFILL          ;       -- org len      refill the input line buffer from ACCEPT
+QUIT3       .word   REFILL          ;       -- org len      refill the input line buffer from ACCEPT
 QUIT4       .word   INTERPRET       ;                       interpret it
 QUIT5       .word   QDEPTH          ; 15~                   stack empty test
             .word   XSQUOTE         ; 16~                   ABORT" stack empty"
@@ -1371,8 +1034,8 @@ QUIT5       .word   QDEPTH          ; 15~                   stack empty test
     .ENDIF
             .word   BRAN,QUIT2      ; 6~
 
-            FORTHWORDIMM "ABORT\34"
-; ; ABORT" is enabled in interpretation mode (+ 11 words) :
+            FORTHWORDIMM "ABORT\34"
+; ; ABORT" is enabled in interpretation mode (+ 10 words) :
 ;             PUSH IP
 ;             CMP #0,&STATE
 ;             JNZ COMP_QABORT
@@ -1380,11 +1043,12 @@ QUIT5       .word   QDEPTH          ; 15~                   stack empty test
 ;             mASM2FORTH
 ;             .word   LIT,'"',WORDD+4,COUNT,QABORT
 ;             .word   DROPEXIT
-;COMP_QABORT mASM2FORTH
-;            .word   SQUOTE
-;            .word   LIT,QABORT,COMMA    ; see QABORT in forthMSP430FR_TERM_xxx.asm
-;FEXIT       .word   EXIT
+; COMP_QABORT mASM2FORTH
+;             .word   SQUOTE
+;             .word   LIT,QABORT,COMMA    ; see QABORT in forthMSP430FR_TERM_xxx.asm
+; FEXIT       .word   EXIT
 
+            FORTHWORDIMM "ABORT\34"
 ; https://forth-standard.org/standard/core/ABORTq
 ; ABORT" " (empty string) displays nothing
 ; ABORT"  i*x flag -- i*x   R: j*x -- j*x  flag=0
@@ -1450,7 +1114,7 @@ POST1       .word   COMMA,EXIT      ; then compile xt of word found if immediate
             FORTHWORD ":"
 ; https://forth-standard.org/standard/core/Colon
 ; : <name>     --      begin a colon definition
-COLON       PUSH #COLONNEXT         ;3              define COLONNEXT as HEADER return
+            PUSH #COLONNEXT         ;3              define COLONNEXT as HEADER return
 ;-----------------------------------;
 HEADER      BIT #1,&DP              ;3              carry set if odd
             ADDC #2,&DP             ;4              align and make room for LFA
@@ -1502,12 +1166,12 @@ COLONNEXT                           ;               Y is NFA              )
 
 ;;Z ?REVEAL   --      if no stack mismatch, link this new word in the CURRENT vocabulary
 QREVEAL     CMP PSP,&LAST_PSP       ; Check SP with its saved value by , :NONAME CODE...
-            JNZ BAD_CSP             ;
             JZ LINK_NFA             ;
-BAD_CSP     mASM2FORTH              ; if stack mismatch.
+            mASM2FORTH              ; if stack mismatch.
             .word   XSQUOTE
-            .byte   15,"stack mismatch!"
-FABORT_TERM .word   ABORT_TERM
+            .byte   15,"stack mismatch!" ; -- addr cnt
+FQABORT_YES .word   QABORT_YES      ;
+
 LINK_NFA    MOV &LAST_NFA,Y         ;                   if no error, link this definition in its thread
             MOV &LAST_THREAD,X      ;
 REVEAL      MOV @X,-2(Y)            ; [LAST_THREAD] --> LFA         (for NONAME: LFA --> 210h unused PA reg)
@@ -1527,7 +1191,7 @@ SEMICOLON   CMP #0,&STATE           ; if interpret mode, semicolon becomes a com
 ; https://forth-standard.org/standard/core/IMMEDIATE
 ; IMMEDIATE        --   make last definition immediate
 IMMEDIATE   MOV &LAST_NFA,Y         ;3
-            BIS.B #1,0(Y)           ;4 FIND process more easier with bit0 for IMMEDIATE flag than bit7
+            BIS.B #1,0(Y)           ;4 FIND process more easier with bit0 than bit7 for IMMEDIATE flag
             MOV @IP+,PC
 
             FORTHWORD "CREATE"
@@ -1538,7 +1202,7 @@ IMMEDIATE   MOV &LAST_NFA,Y         ;3
 CREATE      CALL #HEADER            ; --        W = DP
             MOV #DOCON,-4(W)        ;4          -4(W) = CFA = CALL rDOCON
             MOV W,-2(W)             ;3          -2(W) = PFA = W = next address
-CREATENEXT  JMP REVEAL              ;           to link the definition in vocabulary
+            JMP REVEAL              ;           to link the definition in vocabulary
 
             FORTHWORD "DOES>"
 ; https://forth-standard.org/standard/core/DOES
@@ -1563,8 +1227,8 @@ HEADERLESS  SUB #2,PSP              ; -- TOS    common part of :NONAME and CODEN
             BIT #1,W                ;
             ADDC #0,W               ;           W = aligned CFA
             MOV W,TOS               ; -- xt     aligned CFA of :NONAME | CODENNM
-            MOV #212h,X             ;           MOV Y,0(X)   writes to 212h = unused PA register address (lure for REVEAL)
-            MOV X,Y                 ;           MOV @X,-2(Y) writes to 210h = unused PA register address (lure for REVEAL and IMMEDIATE)
+            MOV #212h,X             ;           MOV Y,0(X)   will write to 212h = unused PA register address (lure for REVEAL)
+            MOV X,Y                 ;           MOV @X,-2(Y) will write to 210h = unused PA register address (lure for REVEAL and IMMEDIATE)
             JMP HEADEREND           ;
 
 ;; https://forth-standard.org/standard/core/DEFER
@@ -1592,11 +1256,11 @@ HEADERLESS  SUB #2,PSP              ; -- TOS    common part of :NONAME and CODEN
 ; or in a definition : ... ['] U. IS DISPLAY ... ;
 ; KEY, EMIT, CR, ACCEPT are examples of DEFERred words
 
-; IS <name>        xt --
             FORTHWORDIMM "IS"       ; immediate
 IS          PUSH IP
             CMP #0,&STATE
             JNZ IS_COMPILE
+; IS <name>        xt --
 IS_EXEC     mASM2FORTH
             .word   TICK
             mNEXTADR
@@ -1609,101 +1273,10 @@ IS_COMPILE  mASM2FORTH
             .word   LIT,DEFERSTORE  ; compile DEFERSTORE
             .word   COMMA,EXIT
 
-;-------------------------------------------------------------------------------
-; ASSEMBLER building definitions
-;-------------------------------------------------------------------------------
-           FORTHWORD "CODE"         ; a CODE word must be finished with ENDCODE
-ASMCODE     CALL #HEADER            ; (that sets CFA and PFA)
-ASMCODE1    SUB #4,&DP              ; remove default room for CFA + PFA
-    .IFDEF VOCABULARY_SET           ; if VOCABULARY_SET
-            JMP hidden              ; add hidden word set in CONTEXT stack
-    .ELSE                           ;
-hidden      MOV &CONTEXT,&CONTEXT+2 ; add hidden word set in CONTEXT stack
-            MOV #BODYhidden,&CONTEXT;
-            MOV @IP+,PC             ;
-    .ENDIF
-
-; HDNCODE (hidden CODE) is used to define a CODE word which must not to be executed by FORTH interpreter
-; i.e. typically the case of an assembler definition called by CALL and ended by RET, or an interrupt routine.
-; HDNCODE words are only usable in ASSEMBLER CONTEXT.
-            FORTHWORD "HDNCODE"
-            PUSH &CURRENT           ; save CURRENT
-            MOV #BODYhidden,&CURRENT; select hidden word set as CURRENT to link HDNCODE definition
-            mDOCOL
-            .word   ASMCODE
-            mNEXTADR
-            MOV @RSP+,IP
-            MOV @RSP+,&CURRENT      ; restore CURRENT
-            MOV @IP+,PC             ;
-
-            FORTHWORD "CODENNM"     ; CODENoNaMe is the assembly counterpart of :NONAME
-CODENNM     PUSH #ASMCODE1          ; define HEADERLESS return
-            JMP HEADERLESS          ; that makes room for CFA and PFA
-
-            asmword "ENDCODE"       ;
-ENDCODE     MOV IP,T                ; T is unused by QREVEAL
-            mASM2FORTH              ;
-            .word   QREVEAL
-            mNEXTADR
-            MOV T,IP
     .IFDEF VOCABULARY_SET
-            JMP PREVIOUS            ; remove hidden word set from CONTEXT stack
-    .ELSE                           ;
-PREVIOUS    MOV #BODYFORTH,&CONTEXT ; remove hidden word set from CONTEXT stack
-            MOV #0,&CONTEXT+2       ;
-            MOV @IP+,PC
-    .ENDIF
-
-; here are 3 words used to switch FORTH <--> ASSEMBLER
-
-; COLON --      compile DOCOL, remove ASSEMBLER from CONTEXT stack, switch to compilation state
-            asmword "COLON"
-            MOV &DP,W
-        .SWITCH DTC
-        .CASE 1
-            MOV #DOCOL,0(W)         ; compile CALL R4 = rDOCOL ([rDOCOL] = XDOCOL)
-            ADD #2,&DP
-        .CASE 2
-            MOV #120Dh,0(W)        ; compile PUSH IP
-COLON1      MOV #DOCOL,2(W)        ; compile CALL R4 = rDOCOL
-            ADD #4,&DP
-        .CASE 3 ; inlined DOCOL
-            MOV #120Dh,0(W)        ; compile PUSH IP
-COLON1      MOV #400Dh,2(W)        ; compile MOV PC,IP
-            MOV #522Dh,4(W)         ; compile ADD #4,IP
-            MOV #4D30h,6(W)         ; compile MOV @IP+,PC
-            ADD #8,&DP              ;
-        .ENDCASE ; DTC
-COLON2      MOV #-1,&STATE          ; enter in compile state
-            JMP PREVIOUS            ; to restore CONTEXT
-
-; LO2HI --       same as COLON but without saving IP
-            asmword "LO2HI"
-        .SWITCH DTC
-        .CASE 1                     ; compile 2 words
-            MOV &DP,W
-            MOV #12B0h,0(W)         ; compile CALL #EXIT, 2 words  4+6=10~
-            MOV #EXIT,2(W)
-            ADD #4,&DP
-            JMP COLON2
-        .ELSECASE                   ; CASE 2 : compile 1 word, CASE 3 : compile 3 words
-            SUB #2,&DP              ; to skip PUSH IP
-            MOV &DP,W
-            JMP COLON1
-        .ENDCASE
-
-; HI2LO --       immediate, switch to low level, set interpretation state, add ASSEMBLER to CONTEXT
-            FORTHWORDIMM "HI2LO"    ;
-            ADD #2,&DP              ; HERE+2
-            MOV &DP,W               ; W = HERE+2
-            MOV W,-2(W)             ; compile HERE+2 to HERE
-            MOV #0,&STATE           ; LEFTBRACKET
-            JMP hidden              ; to save CURRENT and add ASSEMBLER in context
-
 ;-------------------------------------------------------------------------------
 ; WORDS SET for VOCABULARY, not ANS compliant,
 ;-------------------------------------------------------------------------------
-    .IFDEF VOCABULARY_SET
 
             FORTHWORD "WORDSET"
 ;X VOCABULARY       -- create a new word_set
@@ -1738,27 +1311,27 @@ ALSOLOOP    SUB #2,X
 
             FORTHWORD "DEFINITIONS"
 ;X DEFINITIONS  --      set last context vocabulary as entry for further defining words
-DEFINITIONS MOV &CONTEXT,&CURRENT
+            MOV &CONTEXT,&CURRENT
             MOV @IP+,PC
 
             FORTHWORD "ONLY"
 ;X ONLY     --      fill the context stack with 0 to access only the first word-set, ex.: FORTH ONLY
-            MOV #8,T
+            MOV #8,W
             MOV #0,X
-ONLY_LOOP   ADD #2,X
-            MOV #0,CONTEXT(X)
-            SUB #1,T
+ONLY_LOOP   MOV #0,CONTEXT+2(X)
+            ADD #2,X
+            SUB #1,W
             JNZ ONLY_LOOP
             MOV @IP+,PC
 
             FORTHWORD "PREVIOUS"
 ;X  PREVIOUS   --               pop first word-set out of context stack
-PREVIOUS    MOV #8,Y                ;1 move down 8 words, first with CONTEXT+2 addr, last with NULL_WORD one
+PREVIOUS    MOV #8,W                ;1 move down 8 words, first with CONTEXT+2 addr, last with NULL_WORD one
             MOV #CONTEXT+2,X        ;2 X = org = CONTEXT+2, X-2 = dst = CONTEXT
             CMP #0,0(X)             ;3 [org] = 0 ?
             JZ PREVIOUSEND          ;2 to avoid scratch of the first CONTEXT cell by human mistake
 PREVIOUSLOO MOV @X+,-4(X)           ;4
-            SUB #1,Y                ;1
+            SUB #1,W                ;1 dec word
             JNZ PREVIOUSLOO         ;2 8~ loop * 8 = 64 ~
 PREVIOUSEND MOV @IP+,PC             ;4
 
@@ -1838,11 +1411,11 @@ BODYFORTH   .word   lastforthword   ; BODY of FORTH
 voclink     .set    $-2
 
     .IFDEF VOCABULARY_SET
-            FORTHWORD "hidden"  ; cannot be found by FORTH interpreter because the string is not capitalized
+            FORTHWORD "hidden"      ; cannot be found by FORTH interpreter because the string is not capitalized
 hidden      CALL rDODOES
             .word   VOCDOES
     .ENDIF
-BODYhidden  .word   lastasmword ; BODY of hidden words
+BODYhidden  .word   lastasmword     ; BODY of hidden words
     .SWITCH THREADS
     .CASE   2
             .word   lastasmword1
@@ -1912,6 +1485,97 @@ BODYhidden  .word   lastasmword ; BODY of hidden words
 voclink     .set    $-2
 
 ;-------------------------------------------------------------------------------
+; ASSEMBLER building definitions
+;-------------------------------------------------------------------------------
+           FORTHWORD "CODE"         ; a CODE word must be finished with ENDCODE
+ASMCODE     CALL #HEADER            ; (that sets CFA and PFA)
+ASMCODE1    SUB #4,&DP              ; remove default room for CFA + PFA
+    .IFDEF VOCABULARY_SET           ; if VOCABULARY_SET
+            JMP hidden              ; add hidden word set in CONTEXT stack
+    .ELSE                           ;
+hidden      MOV &CONTEXT,&CONTEXT+2 ; add hidden word set in CONTEXT stack
+            MOV #BODYhidden,&CONTEXT;
+            MOV @IP+,PC             ;
+    .ENDIF
+
+; HDNCODE (hidden CODE) is used to define a CODE word which must not to be executed by FORTH interpreter
+; i.e. typically the case of an assembler definition called by CALL and ended by RET, or an interrupt routine.
+; HDNCODE words are only usable in ASSEMBLER CONTEXT.
+            FORTHWORD "HDNCODE"
+            PUSH &CURRENT           ; save CURRENT word-set
+            MOV #BODYhidden,&CURRENT; select hidden word set as CURRENT
+            mDOCOL
+            .word   ASMCODE         ; thus, the created links of HDNCODE definitions are relative to the hidden word-set
+            mNEXTADR
+            MOV @RSP+,IP
+            MOV @RSP+,&CURRENT      ; restore previous CURRENT word-set
+            MOV @IP+,PC             ;
+
+            FORTHWORD "CODENNM"     ; CODENoNaMe is the assembly counterpart of :NONAME
+            PUSH #ASMCODE1          ; define HEADERLESS return
+            JMP HEADERLESS          ; that makes room for CFA and PFA
+
+            asmword "ENDCODE"       ;
+ENDCODE     MOV IP,T                ; T is unused by QREVEAL
+            mASM2FORTH              ;
+            .word   QREVEAL
+            mNEXTADR
+            MOV T,IP
+    .IFDEF VOCABULARY_SET
+            JMP PREVIOUS            ; remove hidden word set from CONTEXT stack
+    .ELSE                           ;
+PREVIOUS    MOV #BODYFORTH,&CONTEXT ; remove hidden word set from CONTEXT stack
+            MOV #0,&CONTEXT+2       ;
+            MOV @IP+,PC
+    .ENDIF
+
+; here are 3 words used to switch FORTH <--> ASSEMBLER
+
+; COLON --      compile DOCOL, remove ASSEMBLER from CONTEXT stack, switch to compilation state
+            asmword "COLON"
+            MOV &DP,W
+        .SWITCH DTC
+        .CASE 1
+            MOV #DOCOL,0(W)         ; compile CALL R4 = rDOCOL ([rDOCOL] = XDOCOL)
+            ADD #2,&DP
+        .CASE 2
+            MOV #120Dh,0(W)        ; compile PUSH IP
+COLON1      MOV #DOCOL,2(W)        ; compile CALL R4 = rDOCOL
+            ADD #4,&DP
+        .CASE 3 ; inlined DOCOL
+            MOV #120Dh,0(W)        ; compile PUSH IP
+COLON1      MOV #400Dh,2(W)        ; compile MOV PC,IP
+            MOV #522Dh,4(W)         ; compile ADD #4,IP
+            MOV #4D30h,6(W)         ; compile MOV @IP+,PC
+            ADD #8,&DP              ;
+        .ENDCASE ; DTC
+COLON2      MOV #-1,&STATE          ; enter in compile state
+            JMP PREVIOUS            ; to restore CONTEXT
+
+; LO2HI --       same as COLON but without saving IP
+            asmword "LO2HI"
+        .SWITCH DTC
+        .CASE 1                     ; compile 2 words
+            MOV &DP,W
+            MOV #12B0h,0(W)         ; compile CALL #EXIT, 2 words  4+6=10~
+            MOV #EXIT,2(W)
+            ADD #4,&DP
+            JMP COLON2
+        .ELSECASE                   ; CASE 2 : compile 1 word, CASE 3 : compile 3 words
+            SUB #2,&DP              ; to skip PUSH IP
+            MOV &DP,W
+            JMP COLON1
+        .ENDCASE
+
+; HI2LO --       immediate, switch to low level, set interpretation state, add ASSEMBLER to CONTEXT
+            FORTHWORDIMM "HI2LO"    ;
+            ADD #2,&DP              ; HERE+2
+            MOV &DP,W               ; W = HERE+2
+            MOV W,-2(W)             ; compile HERE+2 to HERE
+            MOV #0,&STATE           ; LEFTBRACKET
+            JMP hidden              ; to add ASSEMBLER in context stack
+
+;-------------------------------------------------------------------------------
 ; FASTFORTH environment management: RST_SET RST_RET MARKER
 ;-------------------------------------------------------------------------------
 ENV_COPY                            ; mini MOVE T words from X to W
@@ -2002,8 +1666,8 @@ MARKER_DOES                         ; execution part of MARKER definition
             mDOCOL
             .word BL_WORD,FIND      ; -- addr flag
             .word QFBRAN,MARKER_NEXT; -- addr           if not found
-            .word DUP,EXECUTE       ; -- MARKER_DOES    execute it
-MARKER_NEXT mNEXTADR                ; -- addr|MARKER_DOES
+            .word DUP,EXECUTE       ;                   execute it
+MARKER_NEXT mNEXTADR                ; -- addr
             MOV @PSP+,TOS           ; --
             MOV @RSP+,IP            ;
             MOV @RSP+,&TOIN         ;                   restore >IN for HEADER
@@ -2054,14 +1718,13 @@ INIVECLOOP  SUB #2,X                ;
             MOV #DEEP_ORG,X         ; DEEP_ORG values are in FRAM INFO, see \inc\ThingsInFirst.inc
             MOV @X+,&TERM_VEC       ; TERMINAL_INT           as default vector       --> FRAM TERM_VEC
 ;-----------------------------------;
-; DEEP INIT FRAM RST values         ; [COLD,SOFT,HARD,BACKGRND]_APP + RST_[DP,LASTVOC,CURRENT,CONTEXT]
+; DEEP INIT FRAM RST values         ; {COLD,ABORT,SOFT,HARD,BACKGRND}_APP + RST_{DP,LASTVOC,CURRENT,CONTEXT,0}
 ;-----------------------------------;
             MOV #RST_LEN/2,T        ; T = words count
             MOV #RST_ORG,W          ; W = dst, X = org
             CALL #MOV_WORDS         ;
-            MOV #0,&RST_CONTEXT+2   ; to do FORTH ONLY
 ;-----------------------------------;
-    .IFDEF BOOTLOADER               ; does NOBOOT:
+    .IFDEF SD_CARD_LOADER           ; does NOBOOT:
             MOV #WARM,&PUCNEXT      ; removes XBOOT from PUC chain.
     .ENDIF
 ;-----------------------------------;
@@ -2070,9 +1733,6 @@ INIVECLOOP  SUB #2,X                ;
             JMP RST_RET             ; then go to DUP|PUCNEXT,  resp. in QABORT|RESET
 ;-----------------------------------;
 
-;===============================================================================
-; ASSEMBLER KERNEL OPTION
-;===============================================================================
     .IFDEF LARGE_DATA
         .include "forthMSP430FR_EXTD_ASM.asm"
     .ELSE