--- /dev/null
+# Auto detect text files and perform LF normalization
+* text=auto
+
+# Custom for Visual Studio
+*.cs diff=csharp
+
+# Standard to msysgit
+*.doc diff=astextplain
+*.DOC diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot diff=astextplain
+*.DOT diff=astextplain
+*.pdf diff=astextplain
+*.PDF diff=astextplain
+*.rtf diff=astextplain
+*.RTF diff=astextplain
--- /dev/null
+# windows
+*.bak
+
+
+# It's better to unpack these files and commit the raw source because
+# git has its own built in compression methods.
+*.7z
+*.jar
+*.rar
+*.zip
+*.gz
+*.bzip
+*.bz2
+*.xz
+*.lzma
+*.cab
+
+
+# scite files are user-specific
+
+# macroassembler
+*.bin
+*.p
+Log/log.txt
+*.lst
+*.exe
+*.dll
+*.pdf
+*.msg
--- /dev/null
+; -*- coding: utf-8 -*-
+; http://patorjk.com/software/taag/#p=display&f=Banner&t=Fast Forth
+
+; Fast Forth For Texas Instrument MSP430FRxxxx FRAM devices
+; Copyright (C) <2015> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+;C ALIGNED addr -- a-addr align given addr
+ FORTHWORD "ALIGNED"
+ALIGNED BIT #1,TOS
+ ADDC #0,TOS
+ mNEXT
+
+;C ALIGN -- align HERE
+ FORTHWORD "ALIGN"
+ALIGNN BIT #1,&DDP ; 3
+ ADDC #0,&DDP ; 4
+ mNEXT
+
+
--- /dev/null
+; -*- coding: utf-8 -*-
+; http://patorjk.com/software/taag/#p=display&f=Banner&t=Fast Forth
+
+; Fast Forth For Texas Instrument MSP430FRxxxx FRAM devices
+; Copyright (C) <2015> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+ .IFNDEF ALIGNMENT
+ .include "ADDON\ALIGNMENT.asm"
+ .ENDIF
+ .IFNDEF ARITHMETIC
+ .include "ADDON\ARITHMETIC.asm"
+ .ENDIF
+ .IFNDEF PORTABILITY
+ .include "ADDON\PORTABILITY.asm"
+ .ENDIF
+ .IFNDEF DOUBLE
+ .include "ADDON\DOUBLE.asm"
+ .ENDIF
+
+;C INVERT x1 -- x2 bitwise inversion
+ FORTHWORD "INVERT"
+INVERT XOR #-1,TOS
+ mNEXT
+
+;C LSHIFT x1 u -- x2 logical L shift u places
+ FORTHWORD "LSHIFT"
+LSHIFT MOV @PSP+,W
+ AND #1Fh,TOS ; no need to shift more than 16
+ JZ LSH_X
+LSH_1: ADD W,W
+ SUB #1,TOS
+ JNZ LSH_1
+LSH_X: MOV W,TOS
+ mNEXT
+
+;C RSHIFT x1 u -- x2 logical R shift u places
+ FORTHWORD "RSHIFT"
+RSHIFT MOV @PSP+,W
+ AND #1Fh,TOS ; no need to shift more than 16
+ JZ RSH_X
+RSH_1: BIC #1,SR ; CLRC
+ RRC W
+ SUB #1,TOS
+ JNZ RSH_1
+RSH_X: MOV W,TOS
+ mNEXT
+
+;C 1+ n1/u1 -- n2/u2 add 1 to TOS
+ FORTHWORD "1+"
+ONEPLUS ADD #1,TOS
+ mNEXT
+
+;C 1- n1/u1 -- n2/u2 subtract 1 from TOS
+ FORTHWORD "1-"
+ONEMINUS SUB #1,TOS
+ mNEXT
+
+;C 2* x1 -- x2 arithmetic left shift
+ FORTHWORD "2*"
+TWOSTAR ADD TOS,TOS
+ mNEXT
+
+;C 2/ x1 -- x2 arithmetic right shift
+ FORTHWORD "2/"
+TWOSLASH RRA TOS
+ mNEXT
+
+;C MAX n1 n2 -- n3 signed maximum
+ FORTHWORD "MAX"
+MAX: CMP @PSP,TOS ; n2-n1
+ JL SELn1 ; n2<n1
+SELn2: ADD #2,PSP
+ mNEXT
+
+;C MIN n1 n2 -- n3 signed minimum
+ FORTHWORD "MIN"
+MIN: CMP @PSP,TOS ; n2-n1
+ JL SELn2 ; n2<n1
+SELn1: MOV @PSP+,TOS
+ mNEXT
+
+;C +! n/u a-addr -- add to memory
+ FORTHWORD "+!"
+PLUSSTORE ADD @PSP+,0(TOS)
+ MOV @PSP+,TOS
+ mNEXT
+
+;C CHAR -- char parse ASCII character
+ FORTHWORD "CHAR"
+CHARR mDOCOL
+ .word FBLANK,WORDD,ONEPLUS,CFETCH,EXIT
+
+;C [CHAR] -- compile character literal
+ FORTHWORDIMM "[CHAR]" ; immediate
+BRACCHAR mDOCOL
+ .word CHARR
+ .word lit,lit,COMMA
+ .word COMMA,EXIT
+
+;C FILL c-addr u char -- fill memory with char
+ FORTHWORD "FILL"
+FILL MOV @PSP+,X ; count
+ MOV @PSP+,W ; address
+ CMP #0,X
+ JZ FILL_X
+FILL_1: MOV.B TOS,0(W) ; store char in memory
+ ADD #1,W
+ SUB #1,X
+ JNZ FILL_1
+FILL_X: MOV @PSP+,TOS ; pop new TOS
+ mNEXT
+
+ FORTHWORD "HEX"
+HEX MOV #16,&BASE
+ mNEXT
+
+ FORTHWORD "DECIMAL"
+DECIMAL MOV #10,&BASE
+ mNEXT
+
+;C ( \ -- paren ; skip input until )
+ FORTHWORDIMM "\40" ; immediate
+LPAREN mDOCOL
+ .word lit,')',WORDD,DROP,EXIT
+
+ .IFDEF LOWERCASE
+
+; .( \ -- dotparen ; type comment immediatly.
+ FORTHWORDIMM ".\40" ; immediate
+DOTLPAREN mDOCOL
+ .word CAPS_OFF
+ .word lit,')',WORDD
+ .word CAPS_ON
+ .word COUNT,TYPE
+ .word EXIT
+ .ELSE
+
+; .( \ -- dotparen ; type comment immediatly.
+ FORTHWORDIMM ".\40" ; immediate
+DOTLPAREN mDOCOL
+ .word lit,')',WORDD
+ .word COUNT,TYPE
+ .word EXIT
+ .ENDIF ; LOWERCASE
+
+;C SOURCE -- adr u current input buffer
+ FORTHWORD "SOURCE"
+ SUB #4,PSP
+ MOV TOS,2(PSP)
+ MOV &SOURCE_LEN,TOS
+ MOV &SOURCE_ADR,0(PSP)
+ mNEXT
+
+; >BODY -- PFA leave PFA of created word
+ FORTHWORD ">BODY"
+ ADD #4,TOS
+ mNEXT
--- /dev/null
+; -*- coding: utf-8 -*-
+; http://patorjk.com/software/taag/#p=display&f=Banner&t=Fast Forth
+
+; Fast Forth For Texas Instrument MSP430FRxxxx FRAM devices
+; Copyright (C) <2015> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+;X NIP x1 x2 -- x2
+ FORTHWORD "NIP"
+NIP ADD #2,PSP ; 1
+ mNEXT ; 4
+
+;C S>D n -- d single -> double prec.
+ FORTHWORD "S>D"
+STOD: SUB #2,PSP
+ MOV TOS,0(PSP)
+ JMP ZEROLESS
+
+ .IFDEF MPY
+
+;C UM* u1 u2 -- ud unsigned 16x16->32 mult.
+ FORTHWORD "UM*"
+UMSTAR MOV @PSP,&MPY ; Load 1st operand
+ MOV TOS,&OP2 ; Load 2nd operand
+ MOV &RES0,0(PSP) ; low result on stack
+ MOV &RES1,TOS ; high result in TOS
+ mNEXT
+
+;C M* n1 n2 -- dlo dhi signed 16*16->32 multiply
+ FORTHWORD "M*"
+MSTAR MOV @PSP,&MPYS
+ MOV TOS,&OP2
+ MOV &RES0,0(PSP)
+ MOV &RES1,TOS
+ mNEXT
+
+ .ELSE
+
+;C M* n1 n2 -- dlo dhi signed 16*16->32 multiply
+ FORTHWORD "M*"
+MSTAR: MOV TOS,S ; TOS= n2
+ XOR @PSP,S ; S contains sign of result
+ CMP #0,0(PSP) ; n1 > -1 ?
+ JGE u1MSTARn2 ; yes
+ XOR #-1,0(PSP) ; no : n1 --> u1
+ ADD #1,0(PSP) ;
+u1MSTARn2 CMP #0,TOS ; n2 > -1 ?
+ JGE u1MSTARu2 ; yes
+ XOR #-1,TOS ; no : n2 --> u2
+ ADD #1,TOS ;
+u1MSTARu2
+ .word 151Dh ; -- ud1lo ud1hi adr count PUSHM IP,S (1+1 push,IP=D)
+ MOV #MSTARud,IP
+ MOV #UMSTAR,PC ; UMSTAR use S,T,W,X,Y
+MSTARud FORTHtoASM
+ .word 171Ch ; -- ud1lo ud1hi adr count POPM S,IP (1+1 pop,S=C)
+ CMP #0,S ; result > -1 ?
+ JGE MSTARend ; yes
+ XOR #-1,0(PSP) ; no : ud --> d
+ XOR #-1,TOS
+ ADD #1,0(PSP)
+ ADDC #0,TOS
+MSTARend mNEXT
+
+ .ENDIF ;MPY
+
+; TOS = DIVISOR
+; S = DIVIDENDlo
+; W = DIVIDENDhi
+; X = count
+; Y = QUOTIENT
+; T.I. UNSIGNED DIVISION SUBROUTINE 32-BIT BY 16-BIT
+; DVDhi|DVDlo : DIVISOR -> QUOT in Y, REM in DVDhi
+; RETURN: CARRY = 0: OK CARRY = 1: QUOTIENT > 16 BITS
+
+;C UM/MOD udlo|udhi u1 -- r q unsigned 32/16->16
+ FORTHWORD "UM/MOD"
+UMSLASHMOD MOV @PSP+,W ;2 W = DIVIDENDhi
+ MOV @PSP,S ;2 S = DIVIDENDlo
+ MOV #0,Y ;1 CLEAR RESULT
+ MOV #16,X ;2 INITIALIZE LOOP COUNTER
+DIV1: CMP TOS,W ;1 dividendHI-divisor
+ JNC DIV2 ;2 jump if U<
+ SUB TOS,W ;1
+DIV2: ADDC Y,Y ;1 RLC quotient
+ SUB #1,X ;1 Decrement loop counter
+ JN DIV3 ;2 If 0< --> end
+ ADD S,S ;1 RLA
+ ADDC W,W ;1 RLC
+ JNC DIV1 ;2 jump if U< 14~ loop
+ SUB TOS,W ;1
+ BIS #1,SR ;1 SETC
+ JMP DIV2 ;2 14~ loop
+DIV3 MOV W,0(PSP) ;3 remainder on stack
+ MOV Y,TOS ;1 quotient in TOS
+ mNEXT ;4 23 words 240 cycles
+
+;C SM/REM d1lo d1hi n2 -- n3 n4 symmetric signed div
+ FORTHWORD "SM/REM"
+SMSLASHREM MOV TOS,S ;1 S=divisor
+ MOV @PSP,T ;2 T=rem_sign
+ CMP #0,TOS ;1 n2 >= 0 ?
+ JGE d1u2SMSLASHREM ;2 yes
+ XOR #-1,TOS ;1
+ ADD #1,TOS ;1
+d1u2SMSLASHREM ; -- d1 u2
+ CMP #0,0(PSP) ;3 d1hi >= 0 ?
+ JGE ud1u2SMSLASHREM ;2 yes
+ XOR #-1,2(PSP) ;4 d1lo
+ XOR #-1,0(PSP) ;4 d1hi
+ ADD #1,2(PSP) ;4 d1lo+1
+ ADDC #0,0(PSP) ;4 d1hi+C
+ud1u2SMSLASHREM ; -- ud1 u2
+ .word 151Dh ;4 -- ud1lo ud1hi adr count PUSHM IP,S (1+1 push,IP=D)
+ MOV #SMSLASHREMu3u4,IP ;2
+ JMP UMSLASHMOD ;2 UM/MOD use S,W,X,Y, not T
+SMSLASHREMu3u4
+ FORTHtoASM ;240 -- u3 u4
+ .word 171Ch ;4 -- ud1lo ud1hi adr count POPM S,IP (1+1 pop,S=C)
+ CMP #0,T ;1 -- u3 u4 T=rem_sign>=0?
+ JGE SMSLASHREMn3u4 ;2 yes
+ XOR #-1,0(PSP) ;3
+ ADD #1,0(PSP) ;3
+SMSLASHREMn3u4
+ XOR S,T ;1 S=divisor T=quot_sign
+ CMP #0,T ;1 -- n3 u4 T=quot_sign>=0?
+ JGE SMSLASHREMn3n4 ;2 yes
+ XOR #-1,TOS ;1
+ ADD #1,TOS ;1
+SMSLASHREMn3n4 ; -- n3 n4 S=divisor
+ mNEXT ;4 36 words
+
+;C FM/MOD d1 n1 -- r q floored signed div'n
+ FORTHWORD "FM/MOD"
+FMSLASHMOD PUSH IP
+ MOV #FMSLASHMOD1,IP
+ JMP SMSLASHREM
+FMSLASHMOD1 FORTHtoASM ; -- remainder quotient S=divisor
+ CMP #0,0(PSP) ;
+ JZ FMSLASHMODEND
+ CMP #1,TOS ; quotient < 1 ?
+ JGE FMSLASHMODEND ;
+QUOTLESSONE ADD S,0(PSP) ; add divisor to remainder
+ SUB #1,TOS ; decrement quotient
+FMSLASHMODEND
+ MOV @RSP+,IP
+ mNEXT ;
+
+;C * n1 n2 -- n3 signed multiply
+ FORTHWORD "*"
+STAR: mDOCOL
+ .word MSTAR,DROP,EXIT
+
+;C /MOD n1 n2 -- n3 n4 signed divide/rem'dr
+ FORTHWORD "/MOD"
+SLASHMOD: mDOCOL
+ .word TOR,STOD,RFROM,FMSLASHMOD,EXIT
+
+;C / n1 n2 -- n3 signed divide
+ FORTHWORD "/"
+SLASH: mDOCOL
+ .word TOR,STOD,RFROM,FMSLASHMOD,NIP,EXIT
+
+;C MOD n1 n2 -- n3 signed remainder
+ FORTHWORD "MOD"
+MODD: mDOCOL
+ .word TOR,STOD,RFROM,FMSLASHMOD,DROP,EXIT
+
+;C */MOD n1 n2 n3 -- n4 n5 n1*n2/n3, rem"
+ FORTHWORD "*/MOD"
+SSMOD: mDOCOL
+ .word TOR,MSTAR,RFROM,FMSLASHMOD,EXIT
+
+;C */ n1 n2 n3 -- n4 n1*n2/n3
+ FORTHWORD "*/"
+STARSLASH mDOCOL
+ .word TOR,MSTAR,RFROM,FMSLASHMOD,NIP,EXIT
+
+
+
--- /dev/null
+; -*- coding: utf-8 -*-
+; http://patorjk.com/software/taag/#p=display&f=Banner&t=Fast Forth
+
+; Fast Forth For Texas Instrument MSP430FRxxxx FRAM devices
+; Copyright (C) <2015> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+;C 2@ a-addr -- x1 x2 fetch 2 cells ; the lower address will appear on top of stack
+ FORTHWORD "2@"
+ SUB #2, PSP
+ MOV 2(TOS),0(PSP)
+ MOV @TOS,TOS
+ mNEXT
+
+;C 2! x1 x2 a-addr -- store 2 cells ; the top of stack is stored at the lower adr
+ FORTHWORD "2!"
+ MOV @PSP+,0(TOS)
+ MOV @PSP+,2(TOS)
+ MOV @PSP+,TOS
+ mNEXT
+
+;C 2DUP x1 x2 -- x1 x2 x1 x2 dup top 2 cells
+ FORTHWORD "2DUP"
+ SUB #4,PSP ; -- x1 x x x2
+ MOV TOS,2(PSP) ; -- x1 x2 x x2
+ MOV 4(PSP),0(PSP) ; -- x1 x2 x1 x2
+ mNEXT
+
+;C 2DROP x1 x2 -- drop 2 cells
+ FORTHWORD "2DROP"
+ ADD #2,PSP
+ MOV @PSP+,TOS
+ mNEXT
+
+;C 2SWAP x1 x2 x3 x4 -- x3 x4 x1 x2
+ FORTHWORD "2SWAP"
+ MOV @PSP,W ; -- x1 x2 x3 x4 W=x3
+ MOV 4(PSP),0(PSP) ; -- x1 x2 x1 x4
+ MOV W,4(PSP) ; -- x3 x2 x1 x4
+ MOV TOS,W ; -- x3 x2 x1 x4 W=x4
+ MOV 2(PSP),TOS ; -- x3 x2 x1 x2 W=x4
+ MOV W,2(PSP) ; -- x3 x4 x1 x2
+ mNEXT
+
+;C 2OVER x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2
+ FORTHWORD "2OVER"
+ SUB #4,PSP ; -- x1 x2 x3 x x x4
+ MOV TOS,2(PSP) ; -- x1 x2 x3 x4 x x4
+ MOV 8(PSP),0(PSP) ; -- x1 x2 x3 x4 x1 x4
+ MOV 6(PSP),TOS ; -- x1 x2 x3 x4 x1 x2
+ mNEXT
--- /dev/null
+; -*- coding: utf-8 -*-
+; http://patorjk.com/software/taag/#p=display&f=Banner&t=Fast Forth
+
+; Fast Forth For Texas Instrument MSP430FRxxxx FRAM devices
+; Copyright (C) <2015> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+;C CHARS n1 -- n2 chars->adrs units
+ FORTHWORD "CHARS"
+ mNEXT
+
+;C CHAR+ c-addr1 -- c-addr2 add char size
+ FORTHWORD "CHAR+"
+ ADD #1,TOS
+ mNEXT
+
+;C CELLS n1 -- n2 cells->adrs units
+ FORTHWORD "CELLS"
+ ADD TOS,TOS
+ mNEXT
+
+;C CELL+ a-addr1 -- a-addr2 add cell size
+ FORTHWORD "CELL+"
+ ADD #2,TOS
+ mNEXT
+
--- /dev/null
+; -*- coding: utf-8 -*-
+; http://patorjk.com/software/taag/#p=display&f=Banner&t=Fast Forth
+
+; Fast Forth For Texas Instrument MSP430FRxxxx FRAM devices
+; Copyright (C) <2015> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+
+; read logical sector and dump it
+; ----------------------------------;
+ FORTHWORD "SECT_D" ; sector. -- don't forget to add decimal point to your sector number (if < 65536)
+; ----------------------------------;
+SECT_D
+ MOV TOS,X ; X = SectorH
+ MOV @PSP,W ; W = sectorL
+ CALL #readSectorWX ; W = SectorLO X = SectorHI
+DisplaySector
+ mDOCOL ;
+ .word UDDOT ; ud -- display the double number
+ .word lit,1E00h,lit,200h,DUMP ;
+ .word EXIT ;
+; ----------------------------------;
+
+; TIP : How to identify FAT16 or FAT32 SD_Card ?
+; 1 CLUSTER <==> FAT16 RootDIR
+; 2 CLUSTER <==> FAT32 RootDIR
+; ----------------------------------;
+; read first sector of Cluster and dump it
+; ----------------------------------;
+ FORTHWORD "CLUST_D" ; cluster. -- don't forget to add decimal point to your sector number (if < 65536)
+; ----------------------------------;
+ MOV TOS,&ClusterH ;
+ MOV @PSP,&ClusterL ;
+Clust_ClustProcess
+ CALL #ComputeClusFrstSect ;
+ MOV &SectorL,0(PSP) ;
+ MOV &SectorH,TOS ;
+ JMP SECT_D ;
+; ----------------------------------;
+
+; dump FAT1 sector of last entry
+; ----------------------------------;
+ FORTHWORD "FAT_D" ;VWXY Display FATsector
+; ----------------------------------;
+ SUB #4,PSP ;
+ MOV TOS,2(PSP) ;
+ MOV &FATsector,0(PSP) ; FATsectorLO
+ ADD &OrgFAT1,0(PSP) ;
+ MOV #0,TOS ; FATsectorHI = 0
+ JMP SECT_D ;
+; ----------------------------------;
+
+;; dump FAT1 sector of last entry
+;; ----------------------------------;
+; FORTHWORD "FAT1_D" ; Display FATsector
+;; ----------------------------------;
+; MOV &OrgFAT1,Y ;
+;AddFATsector ;
+; ADD &FATsector,Y ; FATsectorLO
+; SUB #4,PSP ;
+; MOV TOS,2(PSP) ; save TOS
+; MOV Y,0(PSP) ;
+; MOV #0,TOS ; FATsectorHI = 0
+; JMP SECT_D ;
+;; ----------------------------------;
+;
+;; dump FAT1 sector of last entry
+;; ----------------------------------;
+; FORTHWORD "FAT2_D" ; Display FATsector
+;; ----------------------------------;
+; MOV &OrgFAT2,Y ;
+; JMP AddFATsector ;
+;; ----------------------------------;
+
+
+
+; dump DIR sector of opened file or first sector of current DIR by default
+; ----------------------------------;
+ FORTHWORD "DIR_D" ; Display DIR sector of CurrentHdl or CurrentDir sector by default
+; ----------------------------------;
+ SUB #4,PSP ;
+ MOV TOS,2(PSP) ; save TOS
+ MOV &DIRClusterL,&ClusterL ;
+ MOV &DIRClusterH,&ClusterH ;
+ JMP Clust_ClustProcess ;
+; ----------------------------------;
+
--- /dev/null
+; -*- coding: utf-8 -*-
+; http://patorjk.com/software/taag/#p=display&f=Banner&t=Fast Forth
+
+; Fast Forth For Texas Instrument MSP430FRxxxx FRAM devices
+; Copyright (C) <2015> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+;X .S -- print <number> of cells and stack contents if not empty
+ FORTHWORD ".S"
+DOTS mDOCOL
+ .word lit,'<',EMIT
+ .word DEPTH,DOT
+ .word lit,08h,EMIT ; backspace
+ .word lit,'>',EMIT,SPACE
+ .word SPFETCH,lit,PSTACK,ULESS
+ .word QBRAN,DOTS2
+ .word SPFETCH,lit,PSTACK-2,xdo
+DOTS1: .word II,FETCH,UDOT
+ .word lit,-2
+ .word xploop,DOTS1
+DOTS2: .word EXIT
+
+;Z ? adr -- display the content of adr
+ FORTHWORD "?"
+ MOV @TOS,TOS
+ MOV #UDOT,PC
+
+;X WORDS -- list all words in all dicts. 53 words
+ .SWITCH THREADS
+ .CASE 1
+
+ FORTHWORD "WORDS"
+WORDS mDOCOL
+
+; vvvvvvvv may be skipped vvvvvvvv
+ .word CR ; type # of threads in vocabularies
+ .word lit,3,SPACES
+ .word XSQUOTE
+ .byte 23,"monothread vocabularies"
+ .word TYPE
+; ^^^^^^^^ may be skipped ^^^^^^^^
+
+ .word LIT,CONTEXT
+WORDS1 .word DUP,CELLPLUS,SWAP
+ .word FETCH,QDUP
+ .word QBRAN,WORDS5
+ .word CR
+ .word lit,3,SPACES
+WORDS3 .word FETCH,QDUP
+ .word QBRAN,WORDS4
+ .word DUP,DUP,COUNT
+ .word lit,07Fh,ANDD,TYPE
+ .word CFETCH,lit,0Fh,ANDD
+ .word lit,10h,SWAP,MINUS
+ .word SPACES,lit,2,MINUS
+ .word BRAN,WORDS3
+WORDS4 .word CR
+ .word BRAN,WORDS1
+WORDS5 .word DROP
+ .word EXIT
+
+
+ .ELSECASE
+
+ FORTHWORD "WORDS"
+WORDS mDOCOL
+
+; vvvvvvvv may be skipped vvvvvvvv
+ .word FBASE,FETCH
+ .word LIT,0Ah,FBASE,STORE
+ .word CR ; type # of threads in vocabularies
+ .word lit,3,SPACES
+ .word LIT,THREADS,DOT
+ .word XSQUOTE
+ .byte 20,"threads vocabularies"
+ .word TYPE
+ .word FBASE,STORE
+; ^^^^^^^^ may be skipped ^^^^^^^^
+
+ .word LIT,CONTEXT
+ ; BEGIN
+WORDS1 .word DUP,CELLPLUS,SWAP
+ .word FETCH,QDUP
+ .word QBRAN,WORDS6 ;
+ .word CR
+ .word lit,3,SPACES
+
+ .word DUP,LIT,PAD ;
+ .word LIT,THREADS,DUP,PLUS
+ .word MOVE
+ ; BEGIN
+WORDS2 .word LIT,0,DUP
+ .word LIT,THREADS,DUP,PLUS ; I = ptr = thread*2
+ .word LIT,0
+ .word xdo ; DO
+WORDS3 .word DUP
+ .word II,LIT,PAD,PLUS,FETCH ; old MAX NFA U< NFA ?
+ .word ULESS,QBRAN,WORDS4 ; no
+ .word DROP,DROP,II ; yes, replace old MAX of NFA by new MAX of NFA
+ .word DUP,LIT,PAD,PLUS,FETCH ;
+WORDS4 .word LIT,2,xploop,WORDS3 ; 2 +LOOP
+ .word QDUP ; MAX of NFA = 0 ?
+ .word QBRAN,WORDS5 ; WHILE
+ .word DUP,LIT,2,MINUS,FETCH ; replace NFA MAX by its [LFA]
+ .word ROT,LIT,PAD,PLUS,STORE
+ .word DUP,COUNT ; display NFA MAX in 10 chars format
+ .word lit,07Fh,ANDD,TYPE
+ .word CFETCH,lit,0Fh,ANDD
+ .word lit,10h,SWAP,MINUS
+ .word SPACES
+ .word BRAN,WORDS2 ; REPEAT
+WORDS5 .word DROP,DROP
+ .word CR
+ .word BRAN,WORDS1 ; REPEAT
+WORDS6 .word DROP
+ .word EXIT
+
+ .ENDCASE
+
+
+ .IFNDEF ANS_CORE_COMPLIANT
+
+;C MAX n1 n2 -- n3 signed maximum
+ FORTHWORD "MAX"
+MAX: CMP @PSP,TOS ; n2-n1
+ JL SELn1 ; n2<n1
+SELn2: ADD #2,PSP
+ mNEXT
+
+;C MIN n1 n2 -- n3 signed minimum
+ FORTHWORD "MIN"
+MIN: CMP @PSP,TOS ; n2-n1
+ JL SELn2 ; n2<n1
+SELn1: MOV @PSP+,TOS
+ mNEXT
+
+ .ENDIF
+
+;X U.R u n -- display u unsigned in n width
+ FORTHWORD "U.R"
+UDOTR mDOCOL
+ .word TOR,LESSNUM,lit,0,NUM,NUMS,NUMGREATER
+ .word RFROM,OVER,MINUS,lit,0,MAX,SPACES,TYPE
+ .word EXIT
+
+ FORTHWORD "DUMP"
+DUMP PUSH IP
+ PUSH &BASE
+ MOV #10h,&BASE
+ ADD @PSP,TOS ; compute end address
+ AND #0FFF0h,0(PSP) ; compute start address
+ ASMtoFORTH
+ .word SWAP,xdo ; generate line
+DUMP1 .word CR
+ .word II,lit,7,UDOTR,SPACE ; generate address
+ .word II,lit,10h,PLUS,II,xdo ; display 16 bytes
+DUMP2 .word II,CFETCH,lit,3,UDOTR
+ .word xloop,DUMP2
+ .word SPACE,SPACE
+ .word II,lit,10h,PLUS,II,xdo ; display 16 chars
+DUMP3 .word II,CFETCH
+ .word lit,7Eh,MIN,FBLANK,MAX,EMIT
+ .word xloop,DUMP3
+ .word lit,10h,xploop,DUMP1
+ .word RFROM,FBASE,STORE
+ .word EXIT
+
--- /dev/null
+; -*- coding: utf-8 -*-
+; CHIPSTICK_FR2433.inc
+
+; Fast Forth For Texas Instrument CHIPSTICK MSP430FR2433
+;
+; Copyright (C) <2016> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+; ======================================================================
+; INIT CHIPSTICK MSP430FR2433
+; ======================================================================
+
+; my USBtoUart :
+; http://www.ebay.fr/itm/CP2102-USB-UART-Board-mini-Data-Transfer-Convertor-Module-Development-Board-/251433941479
+
+; for sd card socket be carefull : pin CD must be present !
+; http://www.ebay.com/itm/2-PCS-SD-Card-Module-Slot-Socket-Reader-For-Arduino-MCU-/181211954262?pt=LH_DefaultDomain_0&hash=item2a3112fc56
+
+
+; ChipStick PROG Header
+; ------------------------
+; PR1 - GND
+; PR2 - TEST
+; PR3 - VCC
+; PR4 - UART0 RX
+; PR5 - UART0 TX
+; PR6 - /RST
+
+; ChipStick Header PL1
+; ------------------------
+; P1 - 24 - 3V3
+; P2 - 20 - P3.2
+; P3 - 4 - P1.5 UCA0 RXD
+; P4 - 3 - P1.4 UCA0 TXD
+; P5 - 5 - P1.6 UCA0 CLK
+; P6 - 13 - P2.3
+; P7 - 12 - P3.0
+; P8 - 7 - P1.0 UCB0 STE
+; P9 - 8 - P1.1 UCB0 CLK
+; P10- 9 - P1.2 UCB0 SIMO/SDA
+
+; ChipStick Header PL2
+; -------------------------
+; P1 - 23 - GND
+; P2 - 22 - P2.1 XIN
+; P3 - 21 - P2.0 XOUT
+; P4 - 2 - TEST
+; P5 - 1 - /RST
+; P6 - 17 - P2.6 UCA1 TX/SIMO
+; P7 - 16 - P2.5 UCA1 RX/SOMI
+; P8 - 15 - P2.4 UCA1 CLK
+; P9 - 11 - P2.2
+; P10- 10 - P1.3 UCB0 SOMI/SCL
+
+; LEDS:
+; LED1 - 14 - P3.1 UCA1 STE
+
+; switch-keys:
+; RST
+
+
+; ===================================================================================
+; in case of 3.3V powered by UARTtoUSB bridge, open J13 straps {RST,TST,V+,5V} BEFORE
+; then wire VCC and GND of bridge onto J13 connector
+; ===================================================================================
+
+; ---------------------------------------------------
+; CHIPSTICK_FR2433 <--> OUTPUT WORLD
+; ---------------------------------------------------
+; P3.1 - LED1
+
+; P2.1 - PL2.2 - SW1
+; P2.0 - PL2.3 - SW2
+
+; +--4k7-< DeepRST <-- GND
+; |
+; P1.4 - UCA0 TXD PL1.4 - <-+-> RX UARTtoUSB bridge
+; P1.5 - UCA0 RXD PL1.3 - <---- TX UARTtoUSB bridge
+; P3.2 - RTS PL1.2 - ----> CTS UARTtoUSB bridge (if TERMINALCTSRTS option)
+
+; P3.0 - PL1.7 - ----> /CS SPI_RAM
+; P1.1 - UCB0 CLK PL1.9 - ----> CLK SPI_RAM
+; P1.2 - UCB0 SIMO PL1.10 - ----> SI SPI_RAM
+; P1.3 - UCB0 SOMI PL2.10 - <---- S0 SPI_RAM
+
+
+; P1.1 - UCB0 CLK PL1.9 - ----> SD_CLK
+; P1.2 - UCB0 SIMO PL1.10 - ----> SD_SDI
+; P1.3 - UCB0 SOMI PL2.10 - <---- SD_SDO
+; P2.3 - PL1.6 - <---- SD_CD (Card Detect)
+; P2.2 - PL2.9 - ----> SD_CS (Card Select)
+
+; P1.2 - UCB0 SDA PL1.10 - <---> SDA I2C Slave
+; P1.3 - UCB0 SCL PL2.10 - ----> SCL I2C Slave
+
+; P2.2 - PL2.9 - ----> SCL I2C SoftMaster
+; P2.0 - PL2.3 - <---> SDA I2C SoftMaster
+
+; P1.0 - UCB0 STE PL1.8 - <---- TSSOP32236 (IR RC5)
+
+; ----------------------------------------------------------------------
+; INIT order : WDT, GPIOs, FRAM, Clock, UARTs...
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : LOCK PMM_LOCKLPM5
+; ----------------------------------------------------------------------
+
+; BIS #LOCKLPM5,&PM5CTL0 ; unlocked by WARM
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : WATCHDOG TIMER A
+; ----------------------------------------------------------------------
+
+; WDT code
+ MOV #WDTPW+WDTHOLD+WDTCNTCL,&WDTCTL ; stop WDT
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : I/O
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT1/2
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT1 usage
+
+Deep_RST_IN .equ P1IN ; TERMINAL TX pin as FORTH Deep_RST
+Deep_RST .equ 10h ; P1.4
+TERM_TXRX .equ 30h
+TERM_SEL .equ P1SEL0
+TERM_REN .equ P1REN
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #-1,&PAOUT ; OUT1 for all pins
+ BIS #-1,&PAREN ; all pins with pull resistors
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT3
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT3 usage
+; P3.1 - LED1
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV.B #001h,&P3DIR ; all pins as input else LED1
+ MOV.B #0FDh,&P3OUT ; all pins with pullup resistors else LED1 = output low
+ BIS.B #0FDh,&P3REN ; all pins with pull resistors else LED1
+
+ .IFDEF TERMINALCTSRTS
+HANDSHAKOUT .equ P3OUT
+HANDSHAKIN .equ P3IN
+RTS .equ 4 ; P3.2 bit position
+ BIS.B #RTS,&HANDSHAKOUT
+ .ENDIF
+
+; ----------------------------------------------------------------------
+; FRAM config
+; ----------------------------------------------------------------------
+
+ .IF FREQUENCY = 16
+NWAITS = 1
+ MOV.B #0A5h, &FRCTL0_H ; enable FRCTL0 access
+ MOV.B #10h, &FRCTL0 ; 1 waitstate @ 16 MHz
+ MOV.B #01h, &FRCTL0_H ; disable FRCTL0 access
+ .ENDIF
+
+; ----------------------------------------------------------------------
+; POWER ON RESET SYS config
+; ----------------------------------------------------------------------
+
+; SYS code
+; BIC #1,&SYSCFG0 ; enable write program in FRAM
+ MOV #0A500h,&SYSCFG0 ; enable write MAIN and INFO
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : CLOCK SYSTEM
+; ----------------------------------------------------------------------
+
+; CS code for EXP430FR2433
+
+; to measure REFO frequency, output ACLK on P2.2:
+; BIS.B #4,&P2SEL1
+; BIS.B #4,&P2DIR
+; result : REFO = 32.69kHz
+
+; ===================================================================
+; need to adjust FLLN (and DCO) for each device of MSP430fr2xxx family ?
+; (no problem with MSP430FR5xxx families without FLL).
+; ===================================================================
+
+ .IF FREQUENCY = 0.5
+
+ MOV #0D6h,&CSCTL0 ; preset DCO = 0xD6 (measured value @ 0x180 ; to measure, type 0x180 @ U.)
+
+ MOV #0001h,&CSCTL1 ; Set 1MHZ DCORSEL,disable DCOFTRIM,Modulation
+; ===================================== ; fCOCLKDIV = REFO x (FLLN+1)
+; MOV #100Dh,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO/2),set FLLN=0Dh
+ ; fCOCLKDIV = 32768 x (13+1) = 0.459 MHz ; measured : MHz
+; MOV #100Eh,&CSCTL2 ; Set FLLD=1 (DCOCLKCDIV=DCO/2),set FLLN=0Eh
+ ; fCOCLKDIV = 32768 x (14+1) = 0.491 MHz ; measured : MHz
+ MOV #100Fh,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=0Fh
+ ; fCOCLKDIV = 32768 x (15+1) = 0.524 MHz ; measured : MHz
+; =====================================
+ MOV #2,X
+
+ .ELSEIF FREQUENCY = 1
+
+ MOV #00B4h,&CSCTL0 ; preset DCO = 0xB4 (measured value @ 0x180 ; to measure, type HEX 0x180 ?)
+
+ MOV #0001h,&CSCTL1 ; Set 1MHZ DCORSEL,disable DCOFTRIM,Modulation
+; ===================================== ; fCOCLKDIV = REFO x (FLLN+1)
+; MOV #001Dh,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=1Dh
+ ; fCOCLKDIV = 32768 x (29+1) = 0.983 MHz ; measured : 0.989MHz
+ MOV #001Eh,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=1Eh
+ ; fCOCLKDIV = 32768 x (30+1) = 1.015 MHz ; measured : 1.013MHz
+; MOV #001Fh,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=1Fh
+ ; fCOCLKDIV = 32768 x (31+1) = 1.049 MHz ; measured : 1.046MHz
+; =====================================
+ MOV #4,X
+
+ .ELSEIF FREQUENCY = 2
+
+ MOV #00B4h,&CSCTL0 ; preset DCO = 0xB4 (measured value @ 0x180 ; to measure, type HEX 0x180 ?)
+
+ MOV #0003h,&CSCTL1 ; Set 2MHZ DCORSEL,disable DCOFTRIM,Modulation
+; ===================================== ; fCOCLKDIV = REFO x (FLLN+1)
+; MOV #003Bh,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=3Bh
+ ; fCOCLKDIV = 32768 x (59+1) = 1.996 MHz ; measured : MHz
+; MOV #003Ch,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=3Ch
+ ; fCOCLKDIV = 32768 x (60+1) = 1.998 MHz ; measured : MHz
+ MOV #003Dh,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=3Dh
+ ; fCOCLKDIV = 32768 x (61+1) = 2.031 MHz ; measured : MHz
+; =====================================
+ MOV #8,X
+
+ .ELSEIF FREQUENCY = 4
+
+ MOV #00D2h,&CSCTL0 ; preset DCO = 0xD2 (measured value @ 0x180)
+
+ MOV #0005h,&CSCTL1 ; Set 4MHZ DCORSEL,disable DCOFTRIM,Modulation
+; ===================================== ; fCOCLKDIV = REFO x (FLLN+1)
+; MOV #0078h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=78h
+ ; fCOCLKDIV = 32768 x (120+1) = 3.965 MHz ; measured : 3.96MHz
+
+ MOV #0079h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=79h
+ ; fCOCLKDIV = 32768 x (121+1) = 3.997 MHz ; measured : 3.99MHz
+
+; MOV #007Ah,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=7Ah
+ ; fCOCLKDIV = 32768 x (122+1) = 4.030 MHz ; measured : 4.020MHz
+; =====================================
+ MOV #16,X
+
+ .ELSEIF FREQUENCY = 8
+
+ MOV #00F3h,&CSCTL0 ; preset DCO = 0xF2 (measured value @ 0x180)
+
+ MOV #0007h,&CSCTL1 ; Set 8MHZ DCORSEL,disable DCOFTRIM,Modulation
+; ===================================== ; fCOCLKDIV = REFO x (FLLN+1)
+; MOV #00F2h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=F2h
+ ; fCOCLKDIV = 32768 x (242+1) = 7.963 MHz ; measured : 7.943MHz
+; MOV #00F3h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=F3h
+ ; fCOCLKDIV = 32768 x (243+1) = 7.995 MHz ; measured : 7.976MHz
+; MOV #00F4h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=F4h
+ ; fCOCLKDIV = 32768 x (244+1) = 8.028 MHz ; measured : 8.009MHz
+
+; MOV #00F5h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=F5h
+ ; fCOCLKDIV = 32768 x (245+1) = 8.061 MHz ; measured : 8.042MHz
+
+; MOV #00F8h,&CSCTL2 ; don't work with cp2102 (by low value)
+; MOV #00FAh,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=FAh
+ MOV #00FCh,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=FCh
+ ; fCOCLKDIV = 32768 x (252+1) = 8.290 MHz <============ why ?
+; MOV #00FEh,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=FEh
+; MOV #0100h,&CSCTL2 ; don't work with cp2102 (by high value)
+
+; =====================================
+ MOV #32,X
+
+ .ELSEIF FREQUENCY = 16
+
+ MOV #0129h,&CSCTL0 ; preset DCO = 0x129 (measured value @ 0x180)
+
+ MOV #000Bh,&CSCTL1 ; Set 16MHZ DCORSEL,disable DCOFTRIM,Modulation
+; ===================================== ; fCOCLKDIV = REFO x (FLLN+1)
+; MOV #01E6h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=1E6h
+ ; fCOCLKDIV = 32768 x 486+1) = 15.958 MHz ; measured : 15.92MHz
+; MOV #01E7h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=1E7h
+ ; fCOCLKDIV = 32768 x 487+1) = 15.991 MHz ; measured : 15.95MHz
+; MOV #01E8h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=1E8h
+ ; fCOCLKDIV = 32768 x 488+1) = 16.023 MHz ; measured : 15.99MHz
+ MOV #01E9h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=1E9h
+ ; fCOCLKDIV = 32768 x 489+1) = 16.056 MHz ; measured : 16.02MHz
+; =====================================
+ MOV #64,X
+
+ .ELSEIF
+ .error "bad frequency setting, only 0.5,1,2,4,8,16 MHz"
+ .ENDIF
+
+ .IFDEF LF_XTAL
+; MOV #0000h,&CSCTL3 ; FLL select XT1, FLLREFDIV=0 (default value)
+ MOV #0000h,&CSCTL4 ; ACLOCK select XT1, MCLK & SMCLK select DCOCLKDIV
+ .ELSE
+ BIS #0010h,&CSCTL3 ; FLL select REFCLOCK
+; MOV #0100h,&CSCTL4 ; ACLOCK select REFO, MCLK & SMCLK select DCOCLKDIV (default value)
+ .ENDIF
+
+
+ BIS &SYSRSTIV,&SAVE_SYSRSTIV; store volatile SYSRSTIV preserving a pending request for DEEP_RST
+ CMP #2,&SAVE_SYSRSTIV ; POWER ON ?
+ JZ ClockWaitX ; yes : wait 600ms to stabilize power source
+ .word 0359h ; no : RRUM #1,X --> wait still 300 ms...
+ ; ...because FLL lock time = 280 ms
+
+ClockWaitX MOV #50000,Y ;
+ClockWaitY SUB #1,Y ; 3 cycles loop
+ JNZ ClockWaitY ; 50000x3 = 150000 cycles delay = 150ms @ 1MHz
+ SUB #1,X ;
+ JNZ ClockWaitX ;
+
+
+
+
+
+
+
+
--- /dev/null
+@1800
+10 00 4C C8 80 3E 80 04 FD FF 18 00 32 DB E8 D3
+2A C8 38 C8 00 00 00 00
+@21AA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@C400
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 C4
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 C4 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 C4 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E C4 02 3E 52 00 0E 12 3E 4F 30 4D 8E C4
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 C4
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C C4 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 20 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 C4 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 C5
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 C4 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA C4 03 41 4E 44 3E FF 30 4D 7A C4 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E C5 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 C5 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E C5 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 C5 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 C4 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE C5 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 C5 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 C5 03 3E 49 4E 85 12 C2 21 10 C5
+04 42 41 53 45 00 85 12 DA 21 C0 C4 05 53 54 41
+54 45 85 12 B6 21 30 C6 02 42 4C 00 85 12 20 00
+94 C5 02 3C 23 00 B2 40 AA 21 AA 21 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 C6 01 23 1B 42 DA 21 2C 4F 0A 4E
+B0 12 5E C6 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 21 18 42 AA 21
+C8 4A 00 00 30 4D 96 C6 02 23 53 00 87 12 98 C6
+D2 C6 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 C6 02 23 3E 00 9F 42 AA 21 00 00 3E 40 AA 21
+2E 8F 30 4D 00 C6 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C C6 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 C5 03 55 44 2E 87 12 56 C6
+CC C6 E6 C6 32 C9 FA C8 2A C4 18 C7 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA C4
+02 44 2E 00 87 12 56 C6 6E C4 80 C4 3A C7 CC C6
+92 C4 0A C7 E6 C6 32 C9 FA C8 2A C4 52 C5 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 C6 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 21 30 4D
+62 C5 05 41 4C 4C 4F 54 82 5E C4 21 3E 4F 30 4D
+E2 C6 02 43 2C 00 1A 42 C4 21 CA 4E 00 00 92 53
+C4 21 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A C8
+92 B3 1C 05 FD 27 1E 42 0C 05 B0 12 38 C8 30 4D
+30 40 B6 C7 7E C7 05 28 4B 45 59 29 18 42 0C 05
+EA 3F 12 C6 03 4B 45 59 30 40 DC C7 92 C7 06 41
+43 43 45 50 54 00 3C 40 8A C8 3B 40 54 C8 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+7E C8 92 B3 1C 05 05 24 18 42 0C 05 38 90 0A 00
+04 20 21 53 39 40 46 C8 4D 15 B2 40 11 00 0E 05
+A2 B3 1C 05 FD 27 30 41 B2 40 13 00 0E 05 A2 B3
+1C 05 FD 27 30 41 12 D2 0A 18 FD 3F 21 52 3A 17
+58 42 0C 05 48 9B F0 27 48 9C 06 2C 78 92 11 20
+2E 9F 0F 24 1E 83 05 3C 0E 9A 03 24 CE 48 00 00
+1E 53 82 48 0E 05 A2 B3 1C 05 FD 27 30 4D 80 C8
+2D 83 92 B3 1C 05 FD 27 E3 23 B2 40 18 00 0A 18
+3E 8F 3D 41 30 4D D6 C7 06 28 45 4D 49 54 29 00
+08 4E 3E 4F E6 3F 50 C7 04 45 4D 49 54 00 30 40
+A0 C8 A8 C8 04 45 43 48 4F 00 B2 40 82 48 72 C8
+30 4D 6E C7 06 4E 4F 45 43 48 4F 00 B2 40 30 4D
+72 C8 30 4D 98 C8 04 28 43 52 29 00 2F 83 8F 4E
+00 00 3E 40 0D 00 E3 3F A2 C7 02 43 52 00 30 40
+DC C8 04 C7 05 53 50 41 43 45 2F 83 8F 4E 00 00
+3E 40 20 00 D4 3F F4 C8 06 53 50 41 43 45 53 00
+0E 93 09 24 0D 12 3D 40 1C C9 EF 3F 1E C9 2D 83
+1E 83 EB 23 3D 41 3E 4F 30 4D 2C C7 04 54 59 50
+45 00 0E 93 95 24 2A 4F 8F 5E 00 00 0E 4A 87 12
+CA C5 02 C6 0A C5 AE C8 EC C5 42 C9 2A C4 2F 82
+8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E 1D B3 0D 63
+30 4D 08 C9 82 53 22 00 87 12 34 C4 4E C9 B0 CB
+34 C4 22 00 A8 C9 78 C9 3D 41 6E 4E 1E 83 82 5E
+C4 21 3E 4F 92 B3 C4 21 A2 63 C4 21 30 4D C4 C8
+82 2E 22 00 87 12 68 C9 34 C4 32 C9 B0 CB 2A C4
+00 00 04 57 4F 52 44 00 3C 40 BE 21 39 4C 3A 4C
+09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A FC 27 1A 83
+3B 40 60 00 C8 4C 00 00 09 9A 0C 24 7C 4A 4E 9C
+09 24 18 53 4B 9C F6 2F 7C 90 7B 00 F3 2F 7C 80
+20 00 F0 3F 1A 82 C0 21 82 4A C2 21 1E 42 C4 21
+08 8E CE 48 00 00 30 4D 00 00 04 46 49 4E 44 00
+2F 83 0C 4E 65 4C 74 40 80 00 3B 40 CA 21 3E 4B
+0E 93 1E 24 58 4C 01 00 78 F0 1E 00 0E 58 2E 53
+1E 4E FE FF 0E 93 F3 27 09 4E 78 49 48 C4 48 95
+F7 23 0A 4C 1A 53 FA 99 00 00 F2 23 58 83 FA 23
+19 B3 09 63 0C 49 6A 4E 1E 43 4A 93 01 30 2E 83
+8F 4C 00 00 35 40 08 C4 34 40 14 C4 30 4D 2F 53
+2F 53 3E 4F 30 4D 26 C6 07 3E 4E 55 4D 42 45 52
+3C 4F 38 4F 29 4F 2F 82 1B 42 DA 21 6A 4C 7A 80
+30 00 7A 90 0A 00 02 28 7A 80 07 00 0A 9B 13 2C
+82 49 D0 04 82 48 D2 04 82 4B C8 04 19 42 E4 04
+18 42 E6 04 09 5A 08 63 1C 53 1E 83 E7 23 8F 49
+04 00 8F 48 02 00 8F 4C 00 00 30 4D 03 12 0D 12
+1B 42 DA 21 0B 12 32 C0 00 02 6D 4E 0D 5E 0C 4E
+7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23 32 D0 00 02
+FC 4C FE FF 0D 9C FC 2F DE 83 00 00 09 43 08 43
+3D 40 32 CB 3F 82 8F 4E 06 00 0C 4E 7E 4C 6A 4C
+7A 90 2D 00 10 2C 3B 40 10 00 7A 80 24 00 06 24
+2B 43 5A 83 03 24 3B 52 6A 53 B0 23 1C 53 1E 83
+6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83 B1 43 04 00
+A5 3F 34 CB 2F 53 0E 93 2C 17 82 4C DA 21 03 24
+2F 52 0E F3 30 4D 8F 93 00 00 15 20 32 B0 00 02
+14 20 0E 93 05 24 1A 4F 02 00 1A 83 0A 93 0B 38
+2F 53 BF 4F 00 00 3E E3 05 20 BF E3 00 00 9F 53
+00 00 3E E3 30 4D 32 D0 00 02 9F 4F 02 00 04 00
+BF 4F 00 00 3E E3 F6 23 BF E3 02 00 BF E3 00 00
+9F 53 02 00 8F 63 00 00 3E E3 30 4D B4 C8 07 45
+58 45 43 55 54 45 0A 4E 3E 4F 00 4A 28 C5 01 2C
+1A 42 C4 21 A2 53 C4 21 8A 4E 00 00 3E 4F 30 4D
+AE CB 87 4C 49 54 45 52 41 4C 82 93 B6 21 16 24
+32 B0 00 02 09 24 1A 42 C4 21 A2 52 C4 21 BA 40
+34 C4 00 00 BA 4F 02 00 1A 42 C4 21 A2 52 C4 21
+BA 40 34 C4 00 00 8A 4E 02 00 3E 4F 30 4D EA C8
+05 43 4F 55 4E 54 2F 83 1E 53 8F 4E 00 00 5E 4E
+FF FF 30 4D 82 4E BE 21 B2 4F C0 21 3E 4F 82 43
+C2 21 87 12 4C C6 A8 C9 2A CC 3D 40 36 CC E8 22
+3D 41 3E 4F 30 4D 38 CC 0A 4E 3E 4F 3D 40 4E CC
+3D 27 3D 40 24 CC 1A E2 B6 21 B2 27 AC 23 50 CC
+3E 4F 3D 40 24 CC B9 23 DE 53 00 00 68 4E 08 5E
+F8 40 3F 00 00 00 3D 40 16 CE CD 3F 9E CB 08 45
+56 41 4C 55 41 54 45 00 39 40 BE 21 39 12 39 12
+39 12 0D 12 B0 12 2A C4 14 CC 8C CC 3D 41 B2 41
+C2 21 B2 41 C0 21 B2 41 BE 21 30 4D 7A C5 04 51
+55 49 54 00 31 40 E0 20 B2 40 00 20 AC 21 82 43
+B6 21 82 43 08 18 B0 12 2A C4 4E C9 04 0D 6F 6B
+20 00 32 C9 34 C4 38 21 44 C4 34 C4 50 00 F6 C7
+FA C8 14 CC 34 C4 7E 20 CE C4 B2 C5 4E C9 0D 73
+74 61 63 6B 20 65 6D 70 74 79 20 21 28 CD 34 C4
+30 FF 84 C7 B2 C5 4E C9 0B 46 52 41 4D 20 66 75
+6C 6C 20 21 28 CD 42 C6 F4 C4 C0 C5 BA CC 4E C9
+04 0D 20 20 20 00 BC C5 C2 CC EE C7 05 41 42 4F
+52 54 3F 40 80 20 BE 3F 8F 93 02 00 98 26 B2 40
+82 48 72 C8 B0 12 10 D2 82 43 AC DA 82 43 B8 DA
+82 43 C4 DA 82 43 F4 DA 82 43 00 DB 82 43 0C DB
+A2 B3 1C 05 FD 27 B2 40 11 00 0E 05 92 C3 1C 05
+38 40 A0 AA 39 42 19 83 FE 23 18 83 FB 23 92 B3
+1C 05 F4 23 87 12 4E C9 04 1B 5B 37 6D 00 32 C9
+32 C9 4E C9 04 1B 5B 30 6D 00 32 C9 58 D1 9A D1
+A0 D1 22 CD 1C CD 86 41 42 4F 52 54 22 00 87 12
+68 C9 34 C4 28 CD B0 CB 2A C4 FA C9 01 27 87 12
+4C C6 A8 C9 00 CA C0 C5 BC CD 2A C4 58 CC 52 C6
+81 5C 92 42 BE 21 C2 21 30 4D 87 12 84 C9 4C C6
+A8 C9 D4 CD 08 4E 7A 4E 5A D3 5A 53 0A 58 19 42
+C8 21 6E 4E 3E F0 1E 00 09 5E 82 48 AE 21 82 49
+B0 21 82 4A B2 21 2A 52 82 4A C4 21 3E 4F 3D 41
+30 41 87 12 4E C9 0F 73 74 61 63 6B 20 6D 69 73
+6D 61 74 63 68 21 2E CD 82 9F B4 21 F2 23 18 42
+AE 21 19 42 B0 21 A8 49 FE FF 89 48 00 00 30 4D
+A2 C9 08 56 41 52 49 41 42 4C 45 00 B0 12 CA CD
+BA 40 86 12 FC FF EF 3F 00 CC 08 43 4F 4E 53 54
+41 4E 54 00 B0 12 CA CD BA 40 85 12 FC FF 8A 4E
+FE FF 3E 4F E0 3F 4A CE 06 43 52 45 41 54 45 00
+B0 12 CA CD BA 40 85 12 FC FF 8A 4A FE FF D3 3F
+6E CC 05 44 4F 45 53 3E 1A 42 B2 21 BA 40 84 12
+00 00 8A 4D 02 00 3D 41 30 4D 82 CE 05 44 45 46
+45 52 B0 12 CA CD BA 40 30 40 FC FF BA 40 98 CE
+FE FF B9 3F 00 00 81 5B 82 43 B6 21 30 4D C0 CD
+01 5D B2 43 B6 21 30 4D 64 C9 87 52 45 43 55 52
+53 45 19 42 C4 21 99 42 B2 21 00 00 A2 53 C4 21
+30 4D B6 CE 01 3A B0 12 CA CD BA 40 87 12 FC FF
+A2 83 C4 21 B2 43 B6 21 82 4F B4 21 30 4D E4 CE
+81 3B 82 93 B6 21 5D 27 87 12 34 C4 2A C4 B0 CB
+18 CE B8 CE 2A C4 D6 C8 09 49 4D 4D 45 44 49 41
+54 45 1A 42 AE 21 FA D0 80 00 00 00 30 4D BE 4F
+02 00 3E 4F 30 4D 18 CF 82 49 53 00 87 12 42 C6
+F4 C4 C0 C5 50 CF 5C CF 34 C4 2E CF B0 CB 2A C4
+AE CD 2E CF 2A C4 00 CF 83 5B 27 5D 87 12 AE CD
+34 C4 34 C4 B0 CB B0 CB 2A C4 9E CC 88 50 4F 53
+54 50 4F 4E 45 00 87 12 4C C6 A8 C9 00 CA 54 C4
+C0 C5 BC CD 7E C5 C0 C5 96 CF 34 C4 34 C4 B0 CB
+B0 CB 34 C4 B0 CB B0 CB 2A C4 9C CF 3A 4E 82 4A
+C6 21 2E 4E 82 4E C4 21 3D 40 10 00 09 4A 08 49
+29 83 18 48 FE FF 0E 98 FC 2B 89 48 00 00 1D 83
+F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41 30 4D 38 CF
+82 49 46 00 2F 83 8F 4E 00 00 1E 42 C4 21 BE 40
+C0 C5 00 00 A2 52 C4 21 2E 53 30 4D 9C CE 84 45
+4C 53 45 00 1A 42 C4 21 BA 40 BC C5 00 00 2A 52
+82 4A C4 21 8E 4A 00 00 2A 83 0E 4A 30 4D 2C C9
+84 54 48 45 4E 00 9E 42 C4 21 00 00 3E 4F 30 4D
+68 CE 85 42 45 47 49 4E 30 40 84 C7 10 D0 85 55
+4E 54 49 4C 39 40 C0 C5 1A 42 C4 21 A2 52 C4 21
+8A 49 00 00 8A 4E 02 00 3E 4F 30 4D 96 CD 85 41
+47 41 49 4E 39 40 BC C5 EF 3F 32 CE 85 57 48 49
+4C 45 87 12 D4 CF 6E C4 2A C4 CA CE 86 52 45 50
+45 41 54 00 87 12 54 D0 16 D0 2A C4 EE CF 82 44
+4F 00 2F 83 8F 4E 00 00 1E 42 C4 21 BE 40 CA C5
+00 00 2E 53 82 4E C4 21 A2 53 AC 21 1A 42 AC 21
+8A 43 00 00 30 4D C2 CB 84 4C 4F 4F 50 00 39 40
+EC C5 1A 42 C4 21 A2 52 C4 21 8A 49 00 00 8A 4E
+02 00 1E 42 AC 21 A2 83 AC 21 2E 4E 0E 93 04 24
+9E 42 C4 21 00 00 F5 3F 3E 4F 30 4D E4 C7 85 2B
+4C 4F 4F 50 39 40 DA C5 E4 3F A8 D0 85 4C 45 41
+56 45 1A 42 C4 21 BA 40 FC C5 00 00 BA 40 BC C5
+02 00 B2 50 06 00 C4 21 A2 53 AC 21 2A 52 19 42
+AC 21 89 4A 00 00 30 4D EC D0 04 4D 4F 56 45 00
+0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24 08 99 0F 24
+06 2C F8 49 00 00 18 53 1A 83 FB 23 30 4D 08 5A
+09 5A 19 83 18 83 E8 49 00 00 1A 83 FA 23 30 4D
+34 C4 CA 21 FC C4 2A C4 84 12 50 D1 1C D4 04 D4
+7E D0 AC CD EC D3 DE D0 1A D1 90 C9 BE D1 F2 D1
+2E D0 B2 D2 48 C5 58 CF C0 CE 68 CA 00 00 3A 40
+0C 00 39 40 CA 21 38 40 CC 21 D9 3F 3A 40 0E 00
+39 40 CC 21 38 40 CA 21 CC 3F 82 43 CC 21 30 4D
+92 42 CA 21 C8 21 30 4D 6C CF 09 50 57 52 5F 53
+54 41 54 45 84 12 9A CF E8 D3 32 DB AA D1 08 50
+57 52 5F 48 45 52 45 00 92 42 C4 21 BA D1 92 42
+C6 21 B8 D1 EF 3F 6C D0 09 52 53 54 5F 53 54 41
+54 45 92 42 0C 18 BA D1 92 42 0E 18 B8 D1 E2 3F
+D8 D1 08 52 53 54 5F 48 45 52 45 00 92 42 C4 21
+0C 18 92 42 C6 21 0E 18 DF 3F B2 40 58 D2 BA D2
+B2 40 A0 C8 B0 C8 B2 40 DC C8 F0 C8 B2 40 DC C7
+EA C7 30 41 5C D0 04 57 49 50 45 00 39 40 80 FF
+B9 43 00 00 29 53 39 90 DA FF FA 23 B0 12 0A D2
+B2 40 32 DB C4 21 B2 40 E8 D3 C6 21 D7 3F D0 CF
+06 28 57 41 52 4D 29 00 1E 42 08 18 87 12 4E C9
+05 0D 1B 5B 37 6D 32 C9 70 C7 4E C9 27 20 46 61
+73 74 46 6F 72 74 68 20 56 31 36 30 20 31 36 4D
+48 7A 20 28 43 29 20 4A 2E 4D 2E 54 68 6F 6F 72
+65 6E 73 20 32 C9 34 C4 30 FF 84 C7 2A C5 30 C7
+4E C9 0B 62 79 74 65 73 20 66 72 65 65 20 34 CD
+26 D2 04 57 41 52 4D 00 30 40 58 D2 22 D0 04 43
+4F 4C 44 00 B2 40 04 A5 20 01 B2 40 88 5A CC 01
+B2 43 02 02 B2 D3 06 02 D2 43 24 02 F2 40 FD 00
+22 02 F2 D0 FD 00 26 02 F2 40 A5 00 A1 01 F2 40
+10 00 A0 01 D2 43 A1 01 B2 40 00 A5 60 01 B2 40
+29 01 80 01 B2 40 0B 00 82 01 B2 40 E9 01 84 01
+39 40 40 00 B2 D0 10 00 86 01 92 D2 5E 01 08 18
+A2 93 08 18 01 24 59 03 38 40 50 C3 18 83 FE 23
+19 83 FA 23 3A 40 CA D2 39 40 DA FF 89 4A 00 00
+29 53 FC 23 92 42 02 18 E4 FF B2 40 18 00 0A 18
+31 40 E0 20 3F 40 80 20 37 40 00 C4 36 40 B4 C4
+35 40 08 C4 34 40 14 C4 B2 40 0A 00 DA 21 B2 43
+DC 21 92 C3 30 01 18 42 08 18 F2 B0 10 00 00 02
+04 20 38 E3 18 53 82 48 08 18 B2 40 81 00 00 05
+B2 42 06 05 B2 40 A1 F7 08 05 F2 D0 30 00 0A 02
+92 C3 00 05 92 D3 1A 05 3D 40 C2 D3 18 42 08 18
+38 90 0A 00 3B 27 38 90 16 00 38 2F 28 93 11 23
+F9 26 B8 D2 84 12 50 D1 10 DA BC DA C4 D9 10 DB
+8A D9 44 DA 8E D6 00 00 80 D9 30 DA E2 D9 20 DA
+9E D7 00 00 00 00 22 DB 7C D1 50 D2 85 48 49 32
+4C 4F 87 12 84 C7 E8 CF B0 CB B8 CE 7E D1 C4 D3
+2A C4 BE D2 04 43 4F 44 45 00 B0 12 CA CD A2 82
+C4 21 87 12 F8 CE BC C5 FC D3 4E D0 03 41 53 4D
+92 42 C8 21 B8 21 B2 40 C8 D3 C8 21 EE 3F 00 00
+07 45 4E 44 43 4F 44 45 87 12 8C D1 18 CE 2A C4
+30 D4 06 45 4E 44 41 53 4D 00 92 42 B8 21 C8 21
+F3 3F 00 00 05 43 4F 4C 4F 4E 1A 42 C4 21 BA 40
+87 12 00 00 A2 53 C4 21 B2 43 B6 21 30 40 8C D1
+00 00 05 4C 4F 32 48 49 1A 42 C4 21 BA 40 B0 12
+00 00 BA 40 2A C4 02 00 A2 52 C4 21 ED 3F 38 40
+BE 21 39 48 2A 48 09 5A 1A 52 C2 21 09 9A 03 24
+7E 9A FC 27 1A 83 0E 4A 2A 88 82 4A C2 21 30 4D
+B0 12 2A C4 A8 C9 00 CA 72 C5 C0 C5 C6 D4 BC CA
+C0 C5 BC CD E8 D4 C8 D4 29 4E 39 90 86 12 02 20
+2E 53 30 41 39 90 85 12 03 20 1E 4E 02 00 30 41
+39 90 84 12 01 20 2E 52 30 41 19 42 C4 21 A2 53
+C4 21 89 4E 00 00 3E 40 29 00 12 12 C2 21 92 53
+C2 21 B0 12 2A C4 A8 C9 BC CA C0 C5 1A D5 10 D5
+21 53 3E 90 10 00 BB 2D 30 41 1C D5 B2 41 C2 21
+22 D3 30 41 87 12 4C C6 8E D4 2C D5 82 43 BC 21
+92 42 C4 21 BA 21 A2 53 C4 21 0A 4E 3E 4F FA 90
+23 00 00 00 34 20 92 53 C2 21 B0 12 B0 D4 0E 93
+04 20 B2 40 00 03 BC 21 27 3C 1E 93 04 20 B2 40
+10 03 BC 21 21 3C 2E 93 04 20 B2 40 20 03 BC 21
+1B 3C 2E 92 04 20 B2 40 20 02 BC 21 15 3C 3E 92
+04 20 B2 40 30 02 BC 21 0F 3C 3E 93 04 20 B2 40
+30 03 BC 21 09 3C B2 40 30 00 BC 21 19 42 C4 21
+A2 53 C4 21 89 4E 00 00 3E 4F 3D 41 30 4D FA 90
+26 00 00 00 08 20 B2 40 10 02 BC 21 92 53 C2 21
+30 12 9C D5 75 3F FA 90 40 00 00 00 1A 20 B2 40
+20 00 BC 21 92 53 C2 21 B0 12 FA D4 0E 20 B2 50
+10 00 BC 21 3E 40 2B 00 B0 12 FA D4 32 24 92 92
+BE 21 C2 21 02 24 92 53 C2 21 8E 10 82 5E BC 21
+D3 3F B0 12 FA D4 F9 23 B2 50 10 00 BC 21 3E 40
+28 00 B0 12 B0 D4 30 12 EC D5 67 3F 87 12 4C C6
+8E D4 24 D6 FE 90 26 00 00 00 3E 40 20 00 04 20
+B2 50 82 00 BC 21 C2 3F B0 12 FA D4 DF 23 B2 50
+80 00 BC 21 3E 40 28 00 B0 12 B0 D4 B0 12 EA D4
+D5 23 3D 40 BC CD 30 4D 00 00 04 52 45 54 49 00
+87 12 34 C4 00 13 B0 CB 2A C4 34 C4 2C 00 24 D5
+1C D6 74 D6 2E 4E 1E D2 BC 21 19 42 BA 21 92 3F
+72 D4 03 4D 4F 56 84 12 6A D6 00 40 82 D6 05 4D
+4F 56 2E 42 84 12 6A D6 40 40 00 00 03 41 44 44
+84 12 6A D6 00 50 9C D6 05 41 44 44 2E 42 84 12
+6A D6 40 50 A8 D6 04 41 44 44 43 00 84 12 6A D6
+00 60 B6 D6 06 41 44 44 43 2E 42 00 84 12 6A D6
+40 60 5A D6 04 53 55 42 43 00 84 12 6A D6 00 70
+D4 D6 06 53 55 42 43 2E 42 00 84 12 6A D6 40 70
+E2 D6 03 53 55 42 84 12 6A D6 00 80 F2 D6 05 53
+55 42 2E 42 84 12 6A D6 40 80 54 D4 03 43 4D 50
+84 12 6A D6 00 90 0C D7 05 43 4D 50 2E 42 84 12
+6A D6 40 90 42 D4 04 44 41 44 44 00 84 12 6A D6
+00 A0 26 D7 06 44 41 44 44 2E 42 00 84 12 6A D6
+40 A0 18 D7 03 42 49 54 84 12 6A D6 00 B0 44 D7
+05 42 49 54 2E 42 84 12 6A D6 40 B0 50 D7 03 42
+49 43 84 12 6A D6 00 C0 5E D7 05 42 49 43 2E 42
+84 12 6A D6 40 C0 6A D7 03 42 49 53 84 12 6A D6
+00 D0 78 D7 05 42 49 53 2E 42 84 12 6A D6 40 D0
+00 00 03 58 4F 52 84 12 6A D6 00 E0 92 D7 05 58
+4F 52 2E 42 84 12 6A D6 40 E0 C4 D6 03 41 4E 44
+84 12 6A D6 00 F0 AC D7 05 41 4E 44 2E 42 84 12
+6A D6 40 F0 4C C6 24 D5 CA D7 1A 42 BC 21 B2 F0
+70 00 BC 21 8A 10 3A F0 0F 00 82 DA BC 21 4A 3F
+FE D6 03 52 52 43 84 12 C4 D7 00 10 E2 D7 05 52
+52 43 2E 42 84 12 C4 D7 40 10 EE D7 04 53 57 50
+42 00 84 12 C4 D7 80 10 FC D7 03 52 52 41 84 12
+C4 D7 00 11 0A D8 05 52 52 41 2E 42 84 12 C4 D7
+40 11 16 D8 03 53 58 54 84 12 C4 D7 80 11 00 00
+04 50 55 53 48 00 84 12 C4 D7 00 12 30 D8 06 50
+55 53 48 2E 42 00 84 12 C4 D7 40 12 84 D7 04 43
+41 4C 4C 00 84 12 C4 D7 80 12 34 C4 2C 00 24 D5
+1C D6 64 D8 59 42 BC 21 5A 42 BD 21 82 4A BC 21
+BE 90 00 15 00 00 02 20 0A 89 02 3C 09 8A 0A 49
+3A 90 10 00 03 2C 5A 0E A8 3F 1A 53 0E 4A 87 12
+70 C7 4E C9 0D 6F 75 74 20 6F 66 20 62 6F 75 6E
+64 73 2E CD 3E D8 05 50 55 53 48 4D 84 12 5A D8
+00 15 A6 D8 04 50 4F 50 4D 00 84 12 5A D8 00 17
+4C C6 8E D4 C6 D8 82 43 BC 21 92 42 C4 21 BA 21
+A2 53 C4 21 92 53 C2 21 3E 40 2C 00 B0 12 2A C4
+A8 C9 BC CA C0 C5 BC CD 1C D6 EC D8 0A 4E 3E 4F
+1A 83 2A 92 CA 2F 8A 10 5A 06 6F 3F 24 D8 04 52
+52 43 4D 00 84 12 C0 D8 50 00 FE D8 04 52 52 41
+4D 00 84 12 C0 D8 50 01 0C D9 04 52 4C 41 4D 00
+84 12 C0 D8 50 02 1A D9 04 52 52 55 4D 00 84 12
+C0 D8 50 03 85 12 00 3C 28 D9 03 53 3E 3D 85 12
+00 38 3A D9 02 53 3C 00 85 12 00 34 B4 D8 03 30
+3E 3D 85 12 00 30 4E D9 02 30 3C 00 85 12 00 30
+00 00 02 55 3C 00 85 12 00 2C 62 D9 03 55 3E 3D
+85 12 00 28 58 D9 03 30 3C 3E 85 12 00 24 76 D9
+02 30 3D 00 85 12 00 20 00 00 02 49 46 00 1A 42
+C4 21 8A 4E 00 00 A2 53 C4 21 0E 4A 30 4D 6C D9
+04 54 48 45 4E 00 1A 42 C4 21 08 4E 3E 4F 09 48
+29 53 0A 89 0A 11 3A 90 00 02 68 2F 88 DA 00 00
+30 4D 34 D7 04 45 4C 53 45 00 1A 42 C4 21 BA 40
+00 3C 00 00 A2 53 C4 21 2F 83 8F 4A 00 00 E3 3F
+A0 D9 05 55 4E 54 49 4C 3A 4F 08 4E 3E 4F 19 42
+C4 21 2A 83 0A 89 0A 11 3A 90 00 FE 47 3B 3A F0
+FF 03 08 DA 89 48 00 00 A2 53 C4 21 30 4D B8 D7
+05 41 47 41 49 4E 87 12 34 D9 E8 D9 2A C4 00 00
+05 57 48 49 4C 45 87 12 8E D9 6E C4 2A C4 44 D9
+06 52 45 50 45 41 54 00 87 12 34 D9 E8 D9 A6 D9
+2A C4 00 00 03 4A 4D 50 87 12 AE CD 34 D9 E8 D9
+2A C4 3E B0 00 10 03 20 3E E0 00 04 30 4D 3E 90
+00 34 06 28 03 24 3E 40 00 34 30 4D 3E 40 00 38
+30 4D 00 00 04 3F 4A 4D 50 00 87 12 52 DA AE CD
+6E C4 E8 D9 2A C4 88 DA 3D 41 08 4E 3E 4F 2A 48
+0A 93 04 20 98 42 C4 21 00 00 30 4D 88 43 00 00
+A4 3F 4E D8 03 42 57 31 84 12 86 DA 00 00 A4 DA
+03 42 57 32 84 12 86 DA 00 00 B0 DA 03 42 57 33
+84 12 86 DA 00 00 C8 DA 3D 41 1A 42 C4 21 28 4E
+08 93 08 20 BA 4F 00 00 A2 53 C4 21 8E 4A 00 00
+3E 4F 30 4D 8E 43 00 00 61 3F 00 00 03 46 57 31
+84 12 C6 DA 00 00 EC DA 03 46 57 32 84 12 C6 DA
+00 00 F8 DA 03 46 57 33 84 12 C6 DA 00 00 04 DB
+04 47 4F 54 4F 00 87 12 34 D9 AE CD A6 CB 2A C4
+74 DA 05 3F 47 4F 54 4F 87 12 52 DA AE CD A6 CB
+2A C4
+@FFDA
+CA D2 CA D2 CA D2 CA D2 CA D2 4C C8 CA D2 CA D2
+CA D2 CA D2 CA D2 CA D2 CA D2 CA D2 CA D2 CA D2
+CA D2 CA D2 CA D2
+q
--- /dev/null
+@1800
+10 00 4C C8 80 3E 30 75 FD FF 18 00 34 DB EA D3
+2A C8 38 C8 00 00 00 00
+@21AA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@C400
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 C4
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 C4 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 C4 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E C4 02 3E 52 00 0E 12 3E 4F 30 4D 8E C4
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 C4
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C C4 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 20 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 C4 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 C5
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 C4 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA C4 03 41 4E 44 3E FF 30 4D 7A C4 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E C5 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 C5 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E C5 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 C5 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 C4 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE C5 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 C5 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 C5 03 3E 49 4E 85 12 C2 21 10 C5
+04 42 41 53 45 00 85 12 DA 21 C0 C4 05 53 54 41
+54 45 85 12 B6 21 30 C6 02 42 4C 00 85 12 20 00
+94 C5 02 3C 23 00 B2 40 AA 21 AA 21 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 C6 01 23 1B 42 DA 21 2C 4F 0A 4E
+B0 12 5E C6 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 21 18 42 AA 21
+C8 4A 00 00 30 4D 96 C6 02 23 53 00 87 12 98 C6
+D2 C6 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 C6 02 23 3E 00 9F 42 AA 21 00 00 3E 40 AA 21
+2E 8F 30 4D 00 C6 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C C6 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 C5 03 55 44 2E 87 12 56 C6
+CC C6 E6 C6 32 C9 FA C8 2A C4 18 C7 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA C4
+02 44 2E 00 87 12 56 C6 6E C4 80 C4 3A C7 CC C6
+92 C4 0A C7 E6 C6 32 C9 FA C8 2A C4 52 C5 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 C6 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 21 30 4D
+62 C5 05 41 4C 4C 4F 54 82 5E C4 21 3E 4F 30 4D
+E2 C6 02 43 2C 00 1A 42 C4 21 CA 4E 00 00 92 53
+C4 21 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A C8
+92 B3 1C 05 FD 27 1E 42 0C 05 B0 12 38 C8 30 4D
+30 40 B6 C7 7E C7 05 28 4B 45 59 29 18 42 0C 05
+EA 3F 12 C6 03 4B 45 59 30 40 DC C7 92 C7 06 41
+43 43 45 50 54 00 3C 40 8A C8 3B 40 54 C8 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+7E C8 92 B3 1C 05 05 24 18 42 0C 05 38 90 0A 00
+04 20 21 53 39 40 46 C8 4D 15 B2 40 11 00 0E 05
+A2 B3 1C 05 FD 27 30 41 B2 40 13 00 0E 05 A2 B3
+1C 05 FD 27 30 41 12 D2 0A 18 FD 3F 21 52 3A 17
+58 42 0C 05 48 9B F0 27 48 9C 06 2C 78 92 11 20
+2E 9F 0F 24 1E 83 05 3C 0E 9A 03 24 CE 48 00 00
+1E 53 82 48 0E 05 A2 B3 1C 05 FD 27 30 4D 80 C8
+2D 83 92 B3 1C 05 FD 27 E3 23 B2 40 18 00 0A 18
+3E 8F 3D 41 30 4D D6 C7 06 28 45 4D 49 54 29 00
+08 4E 3E 4F E6 3F 50 C7 04 45 4D 49 54 00 30 40
+A0 C8 A8 C8 04 45 43 48 4F 00 B2 40 82 48 72 C8
+30 4D 6E C7 06 4E 4F 45 43 48 4F 00 B2 40 30 4D
+72 C8 30 4D 98 C8 04 28 43 52 29 00 2F 83 8F 4E
+00 00 3E 40 0D 00 E3 3F A2 C7 02 43 52 00 30 40
+DC C8 04 C7 05 53 50 41 43 45 2F 83 8F 4E 00 00
+3E 40 20 00 D4 3F F4 C8 06 53 50 41 43 45 53 00
+0E 93 09 24 0D 12 3D 40 1C C9 EF 3F 1E C9 2D 83
+1E 83 EB 23 3D 41 3E 4F 30 4D 2C C7 04 54 59 50
+45 00 0E 93 95 24 2A 4F 8F 5E 00 00 0E 4A 87 12
+CA C5 02 C6 0A C5 AE C8 EC C5 42 C9 2A C4 2F 82
+8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E 1D B3 0D 63
+30 4D 08 C9 82 53 22 00 87 12 34 C4 4E C9 B0 CB
+34 C4 22 00 A8 C9 78 C9 3D 41 6E 4E 1E 83 82 5E
+C4 21 3E 4F 92 B3 C4 21 A2 63 C4 21 30 4D C4 C8
+82 2E 22 00 87 12 68 C9 34 C4 32 C9 B0 CB 2A C4
+00 00 04 57 4F 52 44 00 3C 40 BE 21 39 4C 3A 4C
+09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A FC 27 1A 83
+3B 40 60 00 C8 4C 00 00 09 9A 0C 24 7C 4A 4E 9C
+09 24 18 53 4B 9C F6 2F 7C 90 7B 00 F3 2F 7C 80
+20 00 F0 3F 1A 82 C0 21 82 4A C2 21 1E 42 C4 21
+08 8E CE 48 00 00 30 4D 00 00 04 46 49 4E 44 00
+2F 83 0C 4E 65 4C 74 40 80 00 3B 40 CA 21 3E 4B
+0E 93 1E 24 58 4C 01 00 78 F0 1E 00 0E 58 2E 53
+1E 4E FE FF 0E 93 F3 27 09 4E 78 49 48 C4 48 95
+F7 23 0A 4C 1A 53 FA 99 00 00 F2 23 58 83 FA 23
+19 B3 09 63 0C 49 6A 4E 1E 43 4A 93 01 30 2E 83
+8F 4C 00 00 35 40 08 C4 34 40 14 C4 30 4D 2F 53
+2F 53 3E 4F 30 4D 26 C6 07 3E 4E 55 4D 42 45 52
+3C 4F 38 4F 29 4F 2F 82 1B 42 DA 21 6A 4C 7A 80
+30 00 7A 90 0A 00 02 28 7A 80 07 00 0A 9B 13 2C
+82 49 D0 04 82 48 D2 04 82 4B C8 04 19 42 E4 04
+18 42 E6 04 09 5A 08 63 1C 53 1E 83 E7 23 8F 49
+04 00 8F 48 02 00 8F 4C 00 00 30 4D 03 12 0D 12
+1B 42 DA 21 0B 12 32 C0 00 02 6D 4E 0D 5E 0C 4E
+7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23 32 D0 00 02
+FC 4C FE FF 0D 9C FC 2F DE 83 00 00 09 43 08 43
+3D 40 32 CB 3F 82 8F 4E 06 00 0C 4E 7E 4C 6A 4C
+7A 90 2D 00 10 2C 3B 40 10 00 7A 80 24 00 06 24
+2B 43 5A 83 03 24 3B 52 6A 53 B0 23 1C 53 1E 83
+6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83 B1 43 04 00
+A5 3F 34 CB 2F 53 0E 93 2C 17 82 4C DA 21 03 24
+2F 52 0E F3 30 4D 8F 93 00 00 15 20 32 B0 00 02
+14 20 0E 93 05 24 1A 4F 02 00 1A 83 0A 93 0B 38
+2F 53 BF 4F 00 00 3E E3 05 20 BF E3 00 00 9F 53
+00 00 3E E3 30 4D 32 D0 00 02 9F 4F 02 00 04 00
+BF 4F 00 00 3E E3 F6 23 BF E3 02 00 BF E3 00 00
+9F 53 02 00 8F 63 00 00 3E E3 30 4D B4 C8 07 45
+58 45 43 55 54 45 0A 4E 3E 4F 00 4A 28 C5 01 2C
+1A 42 C4 21 A2 53 C4 21 8A 4E 00 00 3E 4F 30 4D
+AE CB 87 4C 49 54 45 52 41 4C 82 93 B6 21 16 24
+32 B0 00 02 09 24 1A 42 C4 21 A2 52 C4 21 BA 40
+34 C4 00 00 BA 4F 02 00 1A 42 C4 21 A2 52 C4 21
+BA 40 34 C4 00 00 8A 4E 02 00 3E 4F 30 4D EA C8
+05 43 4F 55 4E 54 2F 83 1E 53 8F 4E 00 00 5E 4E
+FF FF 30 4D 82 4E BE 21 B2 4F C0 21 3E 4F 82 43
+C2 21 87 12 4C C6 A8 C9 2A CC 3D 40 36 CC E8 22
+3D 41 3E 4F 30 4D 38 CC 0A 4E 3E 4F 3D 40 4E CC
+3D 27 3D 40 24 CC 1A E2 B6 21 B2 27 AC 23 50 CC
+3E 4F 3D 40 24 CC B9 23 DE 53 00 00 68 4E 08 5E
+F8 40 3F 00 00 00 3D 40 16 CE CD 3F 9E CB 08 45
+56 41 4C 55 41 54 45 00 39 40 BE 21 39 12 39 12
+39 12 0D 12 B0 12 2A C4 14 CC 8C CC 3D 41 B2 41
+C2 21 B2 41 C0 21 B2 41 BE 21 30 4D 7A C5 04 51
+55 49 54 00 31 40 E0 20 B2 40 00 20 AC 21 82 43
+B6 21 82 43 08 18 B0 12 2A C4 4E C9 04 0D 6F 6B
+20 00 32 C9 34 C4 38 21 44 C4 34 C4 50 00 F6 C7
+FA C8 14 CC 34 C4 7E 20 CE C4 B2 C5 4E C9 0D 73
+74 61 63 6B 20 65 6D 70 74 79 20 21 28 CD 34 C4
+30 FF 84 C7 B2 C5 4E C9 0B 46 52 41 4D 20 66 75
+6C 6C 20 21 28 CD 42 C6 F4 C4 C0 C5 BA CC 4E C9
+04 0D 20 20 20 00 BC C5 C2 CC EE C7 05 41 42 4F
+52 54 3F 40 80 20 BE 3F 8F 93 02 00 98 26 B2 40
+82 48 72 C8 B0 12 10 D2 82 43 AE DA 82 43 BA DA
+82 43 C6 DA 82 43 F6 DA 82 43 02 DB 82 43 0E DB
+A2 B3 1C 05 FD 27 B2 40 11 00 0E 05 92 C3 1C 05
+38 40 A0 AA 39 42 19 83 FE 23 18 83 FB 23 92 B3
+1C 05 F4 23 87 12 4E C9 04 1B 5B 37 6D 00 32 C9
+32 C9 4E C9 04 1B 5B 30 6D 00 32 C9 58 D1 9A D1
+A0 D1 22 CD 1C CD 86 41 42 4F 52 54 22 00 87 12
+68 C9 34 C4 28 CD B0 CB 2A C4 FA C9 01 27 87 12
+4C C6 A8 C9 00 CA C0 C5 BC CD 2A C4 58 CC 52 C6
+81 5C 92 42 BE 21 C2 21 30 4D 87 12 84 C9 4C C6
+A8 C9 D4 CD 08 4E 7A 4E 5A D3 5A 53 0A 58 19 42
+C8 21 6E 4E 3E F0 1E 00 09 5E 82 48 AE 21 82 49
+B0 21 82 4A B2 21 2A 52 82 4A C4 21 3E 4F 3D 41
+30 41 87 12 4E C9 0F 73 74 61 63 6B 20 6D 69 73
+6D 61 74 63 68 21 2E CD 82 9F B4 21 F2 23 18 42
+AE 21 19 42 B0 21 A8 49 FE FF 89 48 00 00 30 4D
+A2 C9 08 56 41 52 49 41 42 4C 45 00 B0 12 CA CD
+BA 40 86 12 FC FF EF 3F 00 CC 08 43 4F 4E 53 54
+41 4E 54 00 B0 12 CA CD BA 40 85 12 FC FF 8A 4E
+FE FF 3E 4F E0 3F 4A CE 06 43 52 45 41 54 45 00
+B0 12 CA CD BA 40 85 12 FC FF 8A 4A FE FF D3 3F
+6E CC 05 44 4F 45 53 3E 1A 42 B2 21 BA 40 84 12
+00 00 8A 4D 02 00 3D 41 30 4D 82 CE 05 44 45 46
+45 52 B0 12 CA CD BA 40 30 40 FC FF BA 40 98 CE
+FE FF B9 3F 00 00 81 5B 82 43 B6 21 30 4D C0 CD
+01 5D B2 43 B6 21 30 4D 64 C9 87 52 45 43 55 52
+53 45 19 42 C4 21 99 42 B2 21 00 00 A2 53 C4 21
+30 4D B6 CE 01 3A B0 12 CA CD BA 40 87 12 FC FF
+A2 83 C4 21 B2 43 B6 21 82 4F B4 21 30 4D E4 CE
+81 3B 82 93 B6 21 5D 27 87 12 34 C4 2A C4 B0 CB
+18 CE B8 CE 2A C4 D6 C8 09 49 4D 4D 45 44 49 41
+54 45 1A 42 AE 21 FA D0 80 00 00 00 30 4D BE 4F
+02 00 3E 4F 30 4D 18 CF 82 49 53 00 87 12 42 C6
+F4 C4 C0 C5 50 CF 5C CF 34 C4 2E CF B0 CB 2A C4
+AE CD 2E CF 2A C4 00 CF 83 5B 27 5D 87 12 AE CD
+34 C4 34 C4 B0 CB B0 CB 2A C4 9E CC 88 50 4F 53
+54 50 4F 4E 45 00 87 12 4C C6 A8 C9 00 CA 54 C4
+C0 C5 BC CD 7E C5 C0 C5 96 CF 34 C4 34 C4 B0 CB
+B0 CB 34 C4 B0 CB B0 CB 2A C4 9C CF 3A 4E 82 4A
+C6 21 2E 4E 82 4E C4 21 3D 40 10 00 09 4A 08 49
+29 83 18 48 FE FF 0E 98 FC 2B 89 48 00 00 1D 83
+F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41 30 4D 38 CF
+82 49 46 00 2F 83 8F 4E 00 00 1E 42 C4 21 BE 40
+C0 C5 00 00 A2 52 C4 21 2E 53 30 4D 9C CE 84 45
+4C 53 45 00 1A 42 C4 21 BA 40 BC C5 00 00 2A 52
+82 4A C4 21 8E 4A 00 00 2A 83 0E 4A 30 4D 2C C9
+84 54 48 45 4E 00 9E 42 C4 21 00 00 3E 4F 30 4D
+68 CE 85 42 45 47 49 4E 30 40 84 C7 10 D0 85 55
+4E 54 49 4C 39 40 C0 C5 1A 42 C4 21 A2 52 C4 21
+8A 49 00 00 8A 4E 02 00 3E 4F 30 4D 96 CD 85 41
+47 41 49 4E 39 40 BC C5 EF 3F 32 CE 85 57 48 49
+4C 45 87 12 D4 CF 6E C4 2A C4 CA CE 86 52 45 50
+45 41 54 00 87 12 54 D0 16 D0 2A C4 EE CF 82 44
+4F 00 2F 83 8F 4E 00 00 1E 42 C4 21 BE 40 CA C5
+00 00 2E 53 82 4E C4 21 A2 53 AC 21 1A 42 AC 21
+8A 43 00 00 30 4D C2 CB 84 4C 4F 4F 50 00 39 40
+EC C5 1A 42 C4 21 A2 52 C4 21 8A 49 00 00 8A 4E
+02 00 1E 42 AC 21 A2 83 AC 21 2E 4E 0E 93 04 24
+9E 42 C4 21 00 00 F5 3F 3E 4F 30 4D E4 C7 85 2B
+4C 4F 4F 50 39 40 DA C5 E4 3F A8 D0 85 4C 45 41
+56 45 1A 42 C4 21 BA 40 FC C5 00 00 BA 40 BC C5
+02 00 B2 50 06 00 C4 21 A2 53 AC 21 2A 52 19 42
+AC 21 89 4A 00 00 30 4D EC D0 04 4D 4F 56 45 00
+0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24 08 99 0F 24
+06 2C F8 49 00 00 18 53 1A 83 FB 23 30 4D 08 5A
+09 5A 19 83 18 83 E8 49 00 00 1A 83 FA 23 30 4D
+34 C4 CA 21 FC C4 2A C4 84 12 50 D1 1E D4 06 D4
+7E D0 AC CD EE D3 DE D0 1A D1 90 C9 BE D1 F2 D1
+2E D0 B2 D2 48 C5 58 CF C0 CE 68 CA 00 00 3A 40
+0C 00 39 40 CA 21 38 40 CC 21 D9 3F 3A 40 0E 00
+39 40 CC 21 38 40 CA 21 CC 3F 82 43 CC 21 30 4D
+92 42 CA 21 C8 21 30 4D 6C CF 09 50 57 52 5F 53
+54 41 54 45 84 12 9A CF EA D3 34 DB AA D1 08 50
+57 52 5F 48 45 52 45 00 92 42 C4 21 BA D1 92 42
+C6 21 B8 D1 EF 3F 6C D0 09 52 53 54 5F 53 54 41
+54 45 92 42 0C 18 BA D1 92 42 0E 18 B8 D1 E2 3F
+D8 D1 08 52 53 54 5F 48 45 52 45 00 92 42 C4 21
+0C 18 92 42 C6 21 0E 18 DF 3F B2 40 58 D2 BA D2
+B2 40 A0 C8 B0 C8 B2 40 DC C8 F0 C8 B2 40 DC C7
+EA C7 30 41 5C D0 04 57 49 50 45 00 39 40 80 FF
+B9 43 00 00 29 53 39 90 DA FF FA 23 B0 12 0A D2
+B2 40 34 DB C4 21 B2 40 EA D3 C6 21 D7 3F D0 CF
+06 28 57 41 52 4D 29 00 1E 42 08 18 87 12 4E C9
+05 0D 1B 5B 37 6D 32 C9 70 C7 4E C9 27 20 46 61
+73 74 46 6F 72 74 68 20 56 31 36 30 20 31 36 4D
+48 7A 20 28 43 29 20 4A 2E 4D 2E 54 68 6F 6F 72
+65 6E 73 20 32 C9 34 C4 30 FF 84 C7 2A C5 30 C7
+4E C9 0B 62 79 74 65 73 20 66 72 65 65 20 34 CD
+26 D2 04 57 41 52 4D 00 30 40 58 D2 22 D0 04 43
+4F 4C 44 00 B2 40 04 A5 20 01 B2 40 88 5A CC 01
+B2 43 02 02 B2 D3 06 02 D2 43 24 02 F2 40 FD 00
+22 02 F2 D0 FD 00 26 02 F2 40 A5 00 A1 01 F2 40
+10 00 A0 01 D2 43 A1 01 B2 40 00 A5 60 01 B2 40
+29 01 80 01 B2 40 0B 00 82 01 B2 40 E9 01 84 01
+39 40 40 00 B2 D0 10 00 86 01 92 D2 5E 01 08 18
+A2 93 08 18 01 24 59 03 38 40 50 C3 18 83 FE 23
+19 83 FA 23 3A 40 CA D2 39 40 DA FF 89 4A 00 00
+29 53 FC 23 92 42 02 18 E4 FF B2 40 18 00 0A 18
+31 40 E0 20 3F 40 80 20 37 40 00 C4 36 40 B4 C4
+35 40 08 C4 34 40 14 C4 B2 40 0A 00 DA 21 B2 43
+DC 21 92 C3 30 01 18 42 08 18 F2 B0 10 00 00 02
+04 20 38 E3 18 53 82 48 08 18 B2 40 81 00 00 05
+B2 40 05 00 06 05 B2 40 00 49 08 05 F2 D0 30 00
+0A 02 92 C3 00 05 92 D3 1A 05 3D 40 C4 D3 18 42
+08 18 38 90 0A 00 3A 27 38 90 16 00 37 2F 28 93
+10 23 F8 26 B8 D2 84 12 50 D1 12 DA BE DA C6 D9
+12 DB 8C D9 46 DA 90 D6 00 00 82 D9 32 DA E4 D9
+22 DA A0 D7 00 00 00 00 24 DB 7C D1 50 D2 85 48
+49 32 4C 4F 87 12 84 C7 E8 CF B0 CB B8 CE 7E D1
+C6 D3 2A C4 BE D2 04 43 4F 44 45 00 B0 12 CA CD
+A2 82 C4 21 87 12 F8 CE BC C5 FE D3 4E D0 03 41
+53 4D 92 42 C8 21 B8 21 B2 40 CA D3 C8 21 EE 3F
+00 00 07 45 4E 44 43 4F 44 45 87 12 8C D1 18 CE
+2A C4 32 D4 06 45 4E 44 41 53 4D 00 92 42 B8 21
+C8 21 F3 3F 00 00 05 43 4F 4C 4F 4E 1A 42 C4 21
+BA 40 87 12 00 00 A2 53 C4 21 B2 43 B6 21 30 40
+8C D1 00 00 05 4C 4F 32 48 49 1A 42 C4 21 BA 40
+B0 12 00 00 BA 40 2A C4 02 00 A2 52 C4 21 ED 3F
+38 40 BE 21 39 48 2A 48 09 5A 1A 52 C2 21 09 9A
+03 24 7E 9A FC 27 1A 83 0E 4A 2A 88 82 4A C2 21
+30 4D B0 12 2A C4 A8 C9 00 CA 72 C5 C0 C5 C8 D4
+BC CA C0 C5 BC CD EA D4 CA D4 29 4E 39 90 86 12
+02 20 2E 53 30 41 39 90 85 12 03 20 1E 4E 02 00
+30 41 39 90 84 12 01 20 2E 52 30 41 19 42 C4 21
+A2 53 C4 21 89 4E 00 00 3E 40 29 00 12 12 C2 21
+92 53 C2 21 B0 12 2A C4 A8 C9 BC CA C0 C5 1C D5
+12 D5 21 53 3E 90 10 00 BB 2D 30 41 1E D5 B2 41
+C2 21 22 D3 30 41 87 12 4C C6 90 D4 2E D5 82 43
+BC 21 92 42 C4 21 BA 21 A2 53 C4 21 0A 4E 3E 4F
+FA 90 23 00 00 00 34 20 92 53 C2 21 B0 12 B2 D4
+0E 93 04 20 B2 40 00 03 BC 21 27 3C 1E 93 04 20
+B2 40 10 03 BC 21 21 3C 2E 93 04 20 B2 40 20 03
+BC 21 1B 3C 2E 92 04 20 B2 40 20 02 BC 21 15 3C
+3E 92 04 20 B2 40 30 02 BC 21 0F 3C 3E 93 04 20
+B2 40 30 03 BC 21 09 3C B2 40 30 00 BC 21 19 42
+C4 21 A2 53 C4 21 89 4E 00 00 3E 4F 3D 41 30 4D
+FA 90 26 00 00 00 08 20 B2 40 10 02 BC 21 92 53
+C2 21 30 12 9E D5 75 3F FA 90 40 00 00 00 1A 20
+B2 40 20 00 BC 21 92 53 C2 21 B0 12 FC D4 0E 20
+B2 50 10 00 BC 21 3E 40 2B 00 B0 12 FC D4 32 24
+92 92 BE 21 C2 21 02 24 92 53 C2 21 8E 10 82 5E
+BC 21 D3 3F B0 12 FC D4 F9 23 B2 50 10 00 BC 21
+3E 40 28 00 B0 12 B2 D4 30 12 EE D5 67 3F 87 12
+4C C6 90 D4 26 D6 FE 90 26 00 00 00 3E 40 20 00
+04 20 B2 50 82 00 BC 21 C2 3F B0 12 FC D4 DF 23
+B2 50 80 00 BC 21 3E 40 28 00 B0 12 B2 D4 B0 12
+EC D4 D5 23 3D 40 BC CD 30 4D 00 00 04 52 45 54
+49 00 87 12 34 C4 00 13 B0 CB 2A C4 34 C4 2C 00
+26 D5 1E D6 76 D6 2E 4E 1E D2 BC 21 19 42 BA 21
+92 3F 74 D4 03 4D 4F 56 84 12 6C D6 00 40 84 D6
+05 4D 4F 56 2E 42 84 12 6C D6 40 40 00 00 03 41
+44 44 84 12 6C D6 00 50 9E D6 05 41 44 44 2E 42
+84 12 6C D6 40 50 AA D6 04 41 44 44 43 00 84 12
+6C D6 00 60 B8 D6 06 41 44 44 43 2E 42 00 84 12
+6C D6 40 60 5C D6 04 53 55 42 43 00 84 12 6C D6
+00 70 D6 D6 06 53 55 42 43 2E 42 00 84 12 6C D6
+40 70 E4 D6 03 53 55 42 84 12 6C D6 00 80 F4 D6
+05 53 55 42 2E 42 84 12 6C D6 40 80 56 D4 03 43
+4D 50 84 12 6C D6 00 90 0E D7 05 43 4D 50 2E 42
+84 12 6C D6 40 90 44 D4 04 44 41 44 44 00 84 12
+6C D6 00 A0 28 D7 06 44 41 44 44 2E 42 00 84 12
+6C D6 40 A0 1A D7 03 42 49 54 84 12 6C D6 00 B0
+46 D7 05 42 49 54 2E 42 84 12 6C D6 40 B0 52 D7
+03 42 49 43 84 12 6C D6 00 C0 60 D7 05 42 49 43
+2E 42 84 12 6C D6 40 C0 6C D7 03 42 49 53 84 12
+6C D6 00 D0 7A D7 05 42 49 53 2E 42 84 12 6C D6
+40 D0 00 00 03 58 4F 52 84 12 6C D6 00 E0 94 D7
+05 58 4F 52 2E 42 84 12 6C D6 40 E0 C6 D6 03 41
+4E 44 84 12 6C D6 00 F0 AE D7 05 41 4E 44 2E 42
+84 12 6C D6 40 F0 4C C6 26 D5 CC D7 1A 42 BC 21
+B2 F0 70 00 BC 21 8A 10 3A F0 0F 00 82 DA BC 21
+4A 3F 00 D7 03 52 52 43 84 12 C6 D7 00 10 E4 D7
+05 52 52 43 2E 42 84 12 C6 D7 40 10 F0 D7 04 53
+57 50 42 00 84 12 C6 D7 80 10 FE D7 03 52 52 41
+84 12 C6 D7 00 11 0C D8 05 52 52 41 2E 42 84 12
+C6 D7 40 11 18 D8 03 53 58 54 84 12 C6 D7 80 11
+00 00 04 50 55 53 48 00 84 12 C6 D7 00 12 32 D8
+06 50 55 53 48 2E 42 00 84 12 C6 D7 40 12 86 D7
+04 43 41 4C 4C 00 84 12 C6 D7 80 12 34 C4 2C 00
+26 D5 1E D6 66 D8 59 42 BC 21 5A 42 BD 21 82 4A
+BC 21 BE 90 00 15 00 00 02 20 0A 89 02 3C 09 8A
+0A 49 3A 90 10 00 03 2C 5A 0E A8 3F 1A 53 0E 4A
+87 12 70 C7 4E C9 0D 6F 75 74 20 6F 66 20 62 6F
+75 6E 64 73 2E CD 40 D8 05 50 55 53 48 4D 84 12
+5C D8 00 15 A8 D8 04 50 4F 50 4D 00 84 12 5C D8
+00 17 4C C6 90 D4 C8 D8 82 43 BC 21 92 42 C4 21
+BA 21 A2 53 C4 21 92 53 C2 21 3E 40 2C 00 B0 12
+2A C4 A8 C9 BC CA C0 C5 BC CD 1E D6 EE D8 0A 4E
+3E 4F 1A 83 2A 92 CA 2F 8A 10 5A 06 6F 3F 26 D8
+04 52 52 43 4D 00 84 12 C2 D8 50 00 00 D9 04 52
+52 41 4D 00 84 12 C2 D8 50 01 0E D9 04 52 4C 41
+4D 00 84 12 C2 D8 50 02 1C D9 04 52 52 55 4D 00
+84 12 C2 D8 50 03 85 12 00 3C 2A D9 03 53 3E 3D
+85 12 00 38 3C D9 02 53 3C 00 85 12 00 34 B6 D8
+03 30 3E 3D 85 12 00 30 50 D9 02 30 3C 00 85 12
+00 30 00 00 02 55 3C 00 85 12 00 2C 64 D9 03 55
+3E 3D 85 12 00 28 5A D9 03 30 3C 3E 85 12 00 24
+78 D9 02 30 3D 00 85 12 00 20 00 00 02 49 46 00
+1A 42 C4 21 8A 4E 00 00 A2 53 C4 21 0E 4A 30 4D
+6E D9 04 54 48 45 4E 00 1A 42 C4 21 08 4E 3E 4F
+09 48 29 53 0A 89 0A 11 3A 90 00 02 68 2F 88 DA
+00 00 30 4D 36 D7 04 45 4C 53 45 00 1A 42 C4 21
+BA 40 00 3C 00 00 A2 53 C4 21 2F 83 8F 4A 00 00
+E3 3F A2 D9 05 55 4E 54 49 4C 3A 4F 08 4E 3E 4F
+19 42 C4 21 2A 83 0A 89 0A 11 3A 90 00 FE 47 3B
+3A F0 FF 03 08 DA 89 48 00 00 A2 53 C4 21 30 4D
+BA D7 05 41 47 41 49 4E 87 12 36 D9 EA D9 2A C4
+00 00 05 57 48 49 4C 45 87 12 90 D9 6E C4 2A C4
+46 D9 06 52 45 50 45 41 54 00 87 12 36 D9 EA D9
+A8 D9 2A C4 00 00 03 4A 4D 50 87 12 AE CD 36 D9
+EA D9 2A C4 3E B0 00 10 03 20 3E E0 00 04 30 4D
+3E 90 00 34 06 28 03 24 3E 40 00 34 30 4D 3E 40
+00 38 30 4D 00 00 04 3F 4A 4D 50 00 87 12 54 DA
+AE CD 6E C4 EA D9 2A C4 8A DA 3D 41 08 4E 3E 4F
+2A 48 0A 93 04 20 98 42 C4 21 00 00 30 4D 88 43
+00 00 A4 3F 50 D8 03 42 57 31 84 12 88 DA 00 00
+A6 DA 03 42 57 32 84 12 88 DA 00 00 B2 DA 03 42
+57 33 84 12 88 DA 00 00 CA DA 3D 41 1A 42 C4 21
+28 4E 08 93 08 20 BA 4F 00 00 A2 53 C4 21 8E 4A
+00 00 3E 4F 30 4D 8E 43 00 00 61 3F 00 00 03 46
+57 31 84 12 C8 DA 00 00 EE DA 03 46 57 32 84 12
+C8 DA 00 00 FA DA 03 46 57 33 84 12 C8 DA 00 00
+06 DB 04 47 4F 54 4F 00 87 12 36 D9 AE CD A6 CB
+2A C4 76 DA 05 3F 47 4F 54 4F 87 12 54 DA AE CD
+A6 CB 2A C4
+@FFDA
+CA D2 CA D2 CA D2 CA D2 CA D2 4C C8 CA D2 CA D2
+CA D2 CA D2 CA D2 CA D2 CA D2 CA D2 CA D2 CA D2
+CA D2 CA D2 CA D2
+q
--- /dev/null
+@1800
+10 00 40 C8 F4 01 80 04 FD FF 18 00 12 DB C8 D3
+2A C8 32 C8 00 00 00 00
+@21AA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@C400
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 C4
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 C4 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 C4 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E C4 02 3E 52 00 0E 12 3E 4F 30 4D 8E C4
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 C4
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C C4 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 20 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 C4 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 C5
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 C4 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA C4 03 41 4E 44 3E FF 30 4D 7A C4 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E C5 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 C5 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E C5 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 C5 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 C4 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE C5 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 C5 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 C5 03 3E 49 4E 85 12 C2 21 10 C5
+04 42 41 53 45 00 85 12 DA 21 C0 C4 05 53 54 41
+54 45 85 12 B6 21 30 C6 02 42 4C 00 85 12 20 00
+94 C5 02 3C 23 00 B2 40 AA 21 AA 21 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 C6 01 23 1B 42 DA 21 2C 4F 0A 4E
+B0 12 5E C6 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 21 18 42 AA 21
+C8 4A 00 00 30 4D 96 C6 02 23 53 00 87 12 98 C6
+D2 C6 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 C6 02 23 3E 00 9F 42 AA 21 00 00 3E 40 AA 21
+2E 8F 30 4D 00 C6 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C C6 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 C5 03 55 44 2E 87 12 56 C6
+CC C6 E6 C6 26 C9 EE C8 2A C4 18 C7 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA C4
+02 44 2E 00 87 12 56 C6 6E C4 80 C4 3A C7 CC C6
+92 C4 0A C7 E6 C6 26 C9 EE C8 2A C4 52 C5 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 C6 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 21 30 4D
+62 C5 05 41 4C 4C 4F 54 82 5E C4 21 3E 4F 30 4D
+E2 C6 02 43 2C 00 1A 42 C4 21 CA 4E 00 00 92 53
+C4 21 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A C8
+92 B3 1C 05 FD 27 1E 42 0C 05 B0 12 32 C8 30 4D
+30 40 B6 C7 7E C7 05 28 4B 45 59 29 18 42 0C 05
+EA 3F 12 C6 03 4B 45 59 30 40 DC C7 92 C7 06 41
+43 43 45 50 54 00 3C 40 78 C8 3B 40 48 C8 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+6C C8 92 B3 1C 05 05 24 18 42 0C 05 38 90 0A 00
+04 20 21 53 39 40 3A C8 4D 15 B2 40 11 00 0E 05
+30 41 B2 40 13 00 0E 05 30 41 12 D2 0A 18 FD 3F
+21 52 3A 17 58 42 0C 05 48 9B F3 27 48 9C 06 2C
+78 92 0E 20 2E 9F 0C 24 1E 83 05 3C 0E 9A 03 24
+CE 48 00 00 1E 53 82 48 0E 05 30 4D 6E C8 2D 83
+92 B3 1C 05 FD 27 E6 23 B2 40 18 00 0A 18 3E 8F
+3D 41 30 4D D6 C7 06 28 45 4D 49 54 29 00 08 4E
+3E 4F A2 B3 1C 05 FD 27 E6 3F 50 C7 04 45 4D 49
+54 00 30 40 8E C8 9C C8 04 45 43 48 4F 00 B2 40
+82 48 66 C8 30 4D 6E C7 06 4E 4F 45 43 48 4F 00
+B2 40 30 4D 66 C8 30 4D 86 C8 04 28 43 52 29 00
+2F 83 8F 4E 00 00 3E 40 0D 00 E3 3F A2 C7 02 43
+52 00 30 40 D0 C8 04 C7 05 53 50 41 43 45 2F 83
+8F 4E 00 00 3E 40 20 00 D4 3F E8 C8 06 53 50 41
+43 45 53 00 0E 93 09 24 0D 12 3D 40 10 C9 EF 3F
+12 C9 2D 83 1E 83 EB 23 3D 41 3E 4F 30 4D 2C C7
+04 54 59 50 45 00 0E 93 95 24 2A 4F 8F 5E 00 00
+0E 4A 87 12 CA C5 02 C6 0A C5 A2 C8 EC C5 36 C9
+2A C4 2F 82 8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E
+1D B3 0D 63 30 4D FC C8 82 53 22 00 87 12 34 C4
+42 C9 A4 CB 34 C4 22 00 9C C9 6C C9 3D 41 6E 4E
+1E 83 82 5E C4 21 3E 4F 92 B3 C4 21 A2 63 C4 21
+30 4D B8 C8 82 2E 22 00 87 12 5C C9 34 C4 26 C9
+A4 CB 2A C4 00 00 04 57 4F 52 44 00 3C 40 BE 21
+39 4C 3A 4C 09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A
+FC 27 1A 83 3B 40 60 00 C8 4C 00 00 09 9A 0C 24
+7C 4A 4E 9C 09 24 18 53 4B 9C F6 2F 7C 90 7B 00
+F3 2F 7C 80 20 00 F0 3F 1A 82 C0 21 82 4A C2 21
+1E 42 C4 21 08 8E CE 48 00 00 30 4D 00 00 04 46
+49 4E 44 00 2F 83 0C 4E 65 4C 74 40 80 00 3B 40
+CA 21 3E 4B 0E 93 1E 24 58 4C 01 00 78 F0 1E 00
+0E 58 2E 53 1E 4E FE FF 0E 93 F3 27 09 4E 78 49
+48 C4 48 95 F7 23 0A 4C 1A 53 FA 99 00 00 F2 23
+58 83 FA 23 19 B3 09 63 0C 49 6A 4E 1E 43 4A 93
+01 30 2E 83 8F 4C 00 00 35 40 08 C4 34 40 14 C4
+30 4D 2F 53 2F 53 3E 4F 30 4D 26 C6 07 3E 4E 55
+4D 42 45 52 3C 4F 38 4F 29 4F 2F 82 1B 42 DA 21
+6A 4C 7A 80 30 00 7A 90 0A 00 02 28 7A 80 07 00
+0A 9B 13 2C 82 49 D0 04 82 48 D2 04 82 4B C8 04
+19 42 E4 04 18 42 E6 04 09 5A 08 63 1C 53 1E 83
+E7 23 8F 49 04 00 8F 48 02 00 8F 4C 00 00 30 4D
+03 12 0D 12 1B 42 DA 21 0B 12 32 C0 00 02 6D 4E
+0D 5E 0C 4E 7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23
+32 D0 00 02 FC 4C FE FF 0D 9C FC 2F DE 83 00 00
+09 43 08 43 3D 40 26 CB 3F 82 8F 4E 06 00 0C 4E
+7E 4C 6A 4C 7A 90 2D 00 10 2C 3B 40 10 00 7A 80
+24 00 06 24 2B 43 5A 83 03 24 3B 52 6A 53 B0 23
+1C 53 1E 83 6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83
+B1 43 04 00 A5 3F 28 CB 2F 53 0E 93 2C 17 82 4C
+DA 21 03 24 2F 52 0E F3 30 4D 8F 93 00 00 15 20
+32 B0 00 02 14 20 0E 93 05 24 1A 4F 02 00 1A 83
+0A 93 0B 38 2F 53 BF 4F 00 00 3E E3 05 20 BF E3
+00 00 9F 53 00 00 3E E3 30 4D 32 D0 00 02 9F 4F
+02 00 04 00 BF 4F 00 00 3E E3 F6 23 BF E3 02 00
+BF E3 00 00 9F 53 02 00 8F 63 00 00 3E E3 30 4D
+A8 C8 07 45 58 45 43 55 54 45 0A 4E 3E 4F 00 4A
+28 C5 01 2C 1A 42 C4 21 A2 53 C4 21 8A 4E 00 00
+3E 4F 30 4D A2 CB 87 4C 49 54 45 52 41 4C 82 93
+B6 21 16 24 32 B0 00 02 09 24 1A 42 C4 21 A2 52
+C4 21 BA 40 34 C4 00 00 BA 4F 02 00 1A 42 C4 21
+A2 52 C4 21 BA 40 34 C4 00 00 8A 4E 02 00 3E 4F
+30 4D DE C8 05 43 4F 55 4E 54 2F 83 1E 53 8F 4E
+00 00 5E 4E FF FF 30 4D 82 4E BE 21 B2 4F C0 21
+3E 4F 82 43 C2 21 87 12 4C C6 9C C9 1E CC 3D 40
+2A CC E8 22 3D 41 3E 4F 30 4D 2C CC 0A 4E 3E 4F
+3D 40 42 CC 3D 27 3D 40 18 CC 1A E2 B6 21 B2 27
+AC 23 44 CC 3E 4F 3D 40 18 CC B9 23 DE 53 00 00
+68 4E 08 5E F8 40 3F 00 00 00 3D 40 0A CE CD 3F
+92 CB 08 45 56 41 4C 55 41 54 45 00 39 40 BE 21
+39 12 39 12 39 12 0D 12 B0 12 2A C4 08 CC 80 CC
+3D 41 B2 41 C2 21 B2 41 C0 21 B2 41 BE 21 30 4D
+7A C5 04 51 55 49 54 00 31 40 E0 20 B2 40 00 20
+AC 21 82 43 B6 21 82 43 08 18 B0 12 2A C4 42 C9
+04 0D 6F 6B 20 00 26 C9 34 C4 38 21 44 C4 34 C4
+50 00 F6 C7 EE C8 08 CC 34 C4 7E 20 CE C4 B2 C5
+42 C9 0D 73 74 61 63 6B 20 65 6D 70 74 79 20 21
+1C CD 34 C4 30 FF 84 C7 B2 C5 42 C9 0B 46 52 41
+4D 20 66 75 6C 6C 20 21 1C CD 42 C6 F4 C4 C0 C5
+AE CC 42 C9 04 0D 20 20 20 00 BC C5 B6 CC EE C7
+05 41 42 4F 52 54 3F 40 80 20 BE 3F 8F 93 02 00
+98 26 B2 40 82 48 66 C8 B0 12 04 D2 82 43 8C DA
+82 43 98 DA 82 43 A4 DA 82 43 D4 DA 82 43 E0 DA
+82 43 EC DA A2 B3 1C 05 FD 27 B2 40 11 00 0E 05
+92 C3 1C 05 38 40 55 05 39 42 19 83 FE 23 18 83
+FB 23 92 B3 1C 05 F4 23 87 12 42 C9 04 1B 5B 37
+6D 00 26 C9 26 C9 42 C9 04 1B 5B 30 6D 00 26 C9
+4C D1 8E D1 94 D1 16 CD 10 CD 86 41 42 4F 52 54
+22 00 87 12 5C C9 34 C4 1C CD A4 CB 2A C4 EE C9
+01 27 87 12 4C C6 9C C9 F4 C9 C0 C5 B0 CD 2A C4
+4C CC 52 C6 81 5C 92 42 BE 21 C2 21 30 4D 87 12
+78 C9 4C C6 9C C9 C8 CD 08 4E 7A 4E 5A D3 5A 53
+0A 58 19 42 C8 21 6E 4E 3E F0 1E 00 09 5E 82 48
+AE 21 82 49 B0 21 82 4A B2 21 2A 52 82 4A C4 21
+3E 4F 3D 41 30 41 87 12 42 C9 0F 73 74 61 63 6B
+20 6D 69 73 6D 61 74 63 68 21 22 CD 82 9F B4 21
+F2 23 18 42 AE 21 19 42 B0 21 A8 49 FE FF 89 48
+00 00 30 4D 96 C9 08 56 41 52 49 41 42 4C 45 00
+B0 12 BE CD BA 40 86 12 FC FF EF 3F F4 CB 08 43
+4F 4E 53 54 41 4E 54 00 B0 12 BE CD BA 40 85 12
+FC FF 8A 4E FE FF 3E 4F E0 3F 3E CE 06 43 52 45
+41 54 45 00 B0 12 BE CD BA 40 85 12 FC FF 8A 4A
+FE FF D3 3F 62 CC 05 44 4F 45 53 3E 1A 42 B2 21
+BA 40 84 12 00 00 8A 4D 02 00 3D 41 30 4D 76 CE
+05 44 45 46 45 52 B0 12 BE CD BA 40 30 40 FC FF
+BA 40 8C CE FE FF B9 3F 00 00 81 5B 82 43 B6 21
+30 4D B4 CD 01 5D B2 43 B6 21 30 4D 58 C9 87 52
+45 43 55 52 53 45 19 42 C4 21 99 42 B2 21 00 00
+A2 53 C4 21 30 4D AA CE 01 3A B0 12 BE CD BA 40
+87 12 FC FF A2 83 C4 21 B2 43 B6 21 82 4F B4 21
+30 4D D8 CE 81 3B 82 93 B6 21 5D 27 87 12 34 C4
+2A C4 A4 CB 0C CE AC CE 2A C4 CA C8 09 49 4D 4D
+45 44 49 41 54 45 1A 42 AE 21 FA D0 80 00 00 00
+30 4D BE 4F 02 00 3E 4F 30 4D 0C CF 82 49 53 00
+87 12 42 C6 F4 C4 C0 C5 44 CF 50 CF 34 C4 22 CF
+A4 CB 2A C4 A2 CD 22 CF 2A C4 F4 CE 83 5B 27 5D
+87 12 A2 CD 34 C4 34 C4 A4 CB A4 CB 2A C4 92 CC
+88 50 4F 53 54 50 4F 4E 45 00 87 12 4C C6 9C C9
+F4 C9 54 C4 C0 C5 B0 CD 7E C5 C0 C5 8A CF 34 C4
+34 C4 A4 CB A4 CB 34 C4 A4 CB A4 CB 2A C4 90 CF
+3A 4E 82 4A C6 21 2E 4E 82 4E C4 21 3D 40 10 00
+09 4A 08 49 29 83 18 48 FE FF 0E 98 FC 2B 89 48
+00 00 1D 83 F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41
+30 4D 2C CF 82 49 46 00 2F 83 8F 4E 00 00 1E 42
+C4 21 BE 40 C0 C5 00 00 A2 52 C4 21 2E 53 30 4D
+90 CE 84 45 4C 53 45 00 1A 42 C4 21 BA 40 BC C5
+00 00 2A 52 82 4A C4 21 8E 4A 00 00 2A 83 0E 4A
+30 4D 20 C9 84 54 48 45 4E 00 9E 42 C4 21 00 00
+3E 4F 30 4D 5C CE 85 42 45 47 49 4E 30 40 84 C7
+04 D0 85 55 4E 54 49 4C 39 40 C0 C5 1A 42 C4 21
+A2 52 C4 21 8A 49 00 00 8A 4E 02 00 3E 4F 30 4D
+8A CD 85 41 47 41 49 4E 39 40 BC C5 EF 3F 26 CE
+85 57 48 49 4C 45 87 12 C8 CF 6E C4 2A C4 BE CE
+86 52 45 50 45 41 54 00 87 12 48 D0 0A D0 2A C4
+E2 CF 82 44 4F 00 2F 83 8F 4E 00 00 1E 42 C4 21
+BE 40 CA C5 00 00 2E 53 82 4E C4 21 A2 53 AC 21
+1A 42 AC 21 8A 43 00 00 30 4D B6 CB 84 4C 4F 4F
+50 00 39 40 EC C5 1A 42 C4 21 A2 52 C4 21 8A 49
+00 00 8A 4E 02 00 1E 42 AC 21 A2 83 AC 21 2E 4E
+0E 93 04 24 9E 42 C4 21 00 00 F5 3F 3E 4F 30 4D
+E4 C7 85 2B 4C 4F 4F 50 39 40 DA C5 E4 3F 9C D0
+85 4C 45 41 56 45 1A 42 C4 21 BA 40 FC C5 00 00
+BA 40 BC C5 02 00 B2 50 06 00 C4 21 A2 53 AC 21
+2A 52 19 42 AC 21 89 4A 00 00 30 4D E0 D0 04 4D
+4F 56 45 00 0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24
+08 99 0F 24 06 2C F8 49 00 00 18 53 1A 83 FB 23
+30 4D 08 5A 09 5A 19 83 18 83 E8 49 00 00 1A 83
+FA 23 30 4D 34 C4 CA 21 FC C4 2A C4 84 12 44 D1
+FC D3 E4 D3 72 D0 A0 CD CC D3 D2 D0 0E D1 84 C9
+B2 D1 E6 D1 22 D0 A6 D2 48 C5 4C CF B4 CE 5C CA
+00 00 3A 40 0C 00 39 40 CA 21 38 40 CC 21 D9 3F
+3A 40 0E 00 39 40 CC 21 38 40 CA 21 CC 3F 82 43
+CC 21 30 4D 92 42 CA 21 C8 21 30 4D 60 CF 09 50
+57 52 5F 53 54 41 54 45 84 12 8E CF C8 D3 12 DB
+9E D1 08 50 57 52 5F 48 45 52 45 00 92 42 C4 21
+AE D1 92 42 C6 21 AC D1 EF 3F 60 D0 09 52 53 54
+5F 53 54 41 54 45 92 42 0C 18 AE D1 92 42 0E 18
+AC D1 E2 3F CC D1 08 52 53 54 5F 48 45 52 45 00
+92 42 C4 21 0C 18 92 42 C6 21 0E 18 DF 3F B2 40
+4C D2 AE D2 B2 40 8E C8 A4 C8 B2 40 D0 C8 E4 C8
+B2 40 DC C7 EA C7 30 41 50 D0 04 57 49 50 45 00
+39 40 80 FF B9 43 00 00 29 53 39 90 DA FF FA 23
+B0 12 FE D1 B2 40 12 DB C4 21 B2 40 C8 D3 C6 21
+D7 3F C4 CF 06 28 57 41 52 4D 29 00 1E 42 08 18
+87 12 42 C9 05 0D 1B 5B 37 6D 26 C9 70 C7 42 C9
+27 20 46 61 73 74 46 6F 72 74 68 20 56 31 36 30
+20 2E 35 4D 48 7A 20 28 43 29 20 4A 2E 4D 2E 54
+68 6F 6F 72 65 6E 73 20 26 C9 34 C4 30 FF 84 C7
+2A C5 30 C7 42 C9 0B 62 79 74 65 73 20 66 72 65
+65 20 28 CD 1A D2 04 57 41 52 4D 00 30 40 4C D2
+16 D0 04 43 4F 4C 44 00 B2 40 04 A5 20 01 B2 40
+88 5A CC 01 B2 43 02 02 B2 D3 06 02 D2 43 24 02
+F2 40 FD 00 22 02 F2 D0 FD 00 26 02 B2 40 00 A5
+60 01 B2 40 D6 00 80 01 92 43 82 01 B2 40 0F 10
+84 01 29 43 B2 D0 10 00 86 01 92 D2 5E 01 08 18
+A2 93 08 18 01 24 59 03 38 40 50 C3 18 83 FE 23
+19 83 FA 23 3A 40 BE D2 39 40 DA FF 89 4A 00 00
+29 53 FC 23 92 42 02 18 E4 FF B2 40 18 00 0A 18
+31 40 E0 20 3F 40 80 20 37 40 00 C4 36 40 B4 C4
+35 40 08 C4 34 40 14 C4 B2 40 0A 00 DA 21 B2 43
+DC 21 92 C3 30 01 18 42 08 18 F2 B0 10 00 00 02
+04 20 38 E3 18 53 82 48 08 18 B2 40 81 00 00 05
+A2 42 06 05 B2 40 00 49 08 05 F2 D0 30 00 0A 02
+92 C3 00 05 92 D3 1A 05 3D 40 A2 D3 18 42 08 18
+38 90 0A 00 45 27 38 90 16 00 42 2F 28 93 1B 23
+03 27 AC D2 84 12 44 D1 F0 D9 9C DA A4 D9 F0 DA
+6A D9 24 DA 6E D6 00 00 60 D9 10 DA C2 D9 00 DA
+7E D7 00 00 00 00 02 DB 70 D1 44 D2 85 48 49 32
+4C 4F 87 12 84 C7 DC CF A4 CB AC CE 72 D1 A4 D3
+2A C4 B2 D2 04 43 4F 44 45 00 B0 12 BE CD A2 82
+C4 21 87 12 EC CE BC C5 DC D3 42 D0 03 41 53 4D
+92 42 C8 21 B8 21 B2 40 A8 D3 C8 21 EE 3F 00 00
+07 45 4E 44 43 4F 44 45 87 12 80 D1 0C CE 2A C4
+10 D4 06 45 4E 44 41 53 4D 00 92 42 B8 21 C8 21
+F3 3F 00 00 05 43 4F 4C 4F 4E 1A 42 C4 21 BA 40
+87 12 00 00 A2 53 C4 21 B2 43 B6 21 30 40 80 D1
+00 00 05 4C 4F 32 48 49 1A 42 C4 21 BA 40 B0 12
+00 00 BA 40 2A C4 02 00 A2 52 C4 21 ED 3F 38 40
+BE 21 39 48 2A 48 09 5A 1A 52 C2 21 09 9A 03 24
+7E 9A FC 27 1A 83 0E 4A 2A 88 82 4A C2 21 30 4D
+B0 12 2A C4 9C C9 F4 C9 72 C5 C0 C5 A6 D4 B0 CA
+C0 C5 B0 CD C8 D4 A8 D4 29 4E 39 90 86 12 02 20
+2E 53 30 41 39 90 85 12 03 20 1E 4E 02 00 30 41
+39 90 84 12 01 20 2E 52 30 41 19 42 C4 21 A2 53
+C4 21 89 4E 00 00 3E 40 29 00 12 12 C2 21 92 53
+C2 21 B0 12 2A C4 9C C9 B0 CA C0 C5 FA D4 F0 D4
+21 53 3E 90 10 00 BB 2D 30 41 FC D4 B2 41 C2 21
+22 D3 30 41 87 12 4C C6 6E D4 0C D5 82 43 BC 21
+92 42 C4 21 BA 21 A2 53 C4 21 0A 4E 3E 4F FA 90
+23 00 00 00 34 20 92 53 C2 21 B0 12 90 D4 0E 93
+04 20 B2 40 00 03 BC 21 27 3C 1E 93 04 20 B2 40
+10 03 BC 21 21 3C 2E 93 04 20 B2 40 20 03 BC 21
+1B 3C 2E 92 04 20 B2 40 20 02 BC 21 15 3C 3E 92
+04 20 B2 40 30 02 BC 21 0F 3C 3E 93 04 20 B2 40
+30 03 BC 21 09 3C B2 40 30 00 BC 21 19 42 C4 21
+A2 53 C4 21 89 4E 00 00 3E 4F 3D 41 30 4D FA 90
+26 00 00 00 08 20 B2 40 10 02 BC 21 92 53 C2 21
+30 12 7C D5 75 3F FA 90 40 00 00 00 1A 20 B2 40
+20 00 BC 21 92 53 C2 21 B0 12 DA D4 0E 20 B2 50
+10 00 BC 21 3E 40 2B 00 B0 12 DA D4 32 24 92 92
+BE 21 C2 21 02 24 92 53 C2 21 8E 10 82 5E BC 21
+D3 3F B0 12 DA D4 F9 23 B2 50 10 00 BC 21 3E 40
+28 00 B0 12 90 D4 30 12 CC D5 67 3F 87 12 4C C6
+6E D4 04 D6 FE 90 26 00 00 00 3E 40 20 00 04 20
+B2 50 82 00 BC 21 C2 3F B0 12 DA D4 DF 23 B2 50
+80 00 BC 21 3E 40 28 00 B0 12 90 D4 B0 12 CA D4
+D5 23 3D 40 B0 CD 30 4D 00 00 04 52 45 54 49 00
+87 12 34 C4 00 13 A4 CB 2A C4 34 C4 2C 00 04 D5
+FC D5 54 D6 2E 4E 1E D2 BC 21 19 42 BA 21 92 3F
+52 D4 03 4D 4F 56 84 12 4A D6 00 40 62 D6 05 4D
+4F 56 2E 42 84 12 4A D6 40 40 00 00 03 41 44 44
+84 12 4A D6 00 50 7C D6 05 41 44 44 2E 42 84 12
+4A D6 40 50 88 D6 04 41 44 44 43 00 84 12 4A D6
+00 60 96 D6 06 41 44 44 43 2E 42 00 84 12 4A D6
+40 60 3A D6 04 53 55 42 43 00 84 12 4A D6 00 70
+B4 D6 06 53 55 42 43 2E 42 00 84 12 4A D6 40 70
+C2 D6 03 53 55 42 84 12 4A D6 00 80 D2 D6 05 53
+55 42 2E 42 84 12 4A D6 40 80 34 D4 03 43 4D 50
+84 12 4A D6 00 90 EC D6 05 43 4D 50 2E 42 84 12
+4A D6 40 90 22 D4 04 44 41 44 44 00 84 12 4A D6
+00 A0 06 D7 06 44 41 44 44 2E 42 00 84 12 4A D6
+40 A0 F8 D6 03 42 49 54 84 12 4A D6 00 B0 24 D7
+05 42 49 54 2E 42 84 12 4A D6 40 B0 30 D7 03 42
+49 43 84 12 4A D6 00 C0 3E D7 05 42 49 43 2E 42
+84 12 4A D6 40 C0 4A D7 03 42 49 53 84 12 4A D6
+00 D0 58 D7 05 42 49 53 2E 42 84 12 4A D6 40 D0
+00 00 03 58 4F 52 84 12 4A D6 00 E0 72 D7 05 58
+4F 52 2E 42 84 12 4A D6 40 E0 A4 D6 03 41 4E 44
+84 12 4A D6 00 F0 8C D7 05 41 4E 44 2E 42 84 12
+4A D6 40 F0 4C C6 04 D5 AA D7 1A 42 BC 21 B2 F0
+70 00 BC 21 8A 10 3A F0 0F 00 82 DA BC 21 4A 3F
+DE D6 03 52 52 43 84 12 A4 D7 00 10 C2 D7 05 52
+52 43 2E 42 84 12 A4 D7 40 10 CE D7 04 53 57 50
+42 00 84 12 A4 D7 80 10 DC D7 03 52 52 41 84 12
+A4 D7 00 11 EA D7 05 52 52 41 2E 42 84 12 A4 D7
+40 11 F6 D7 03 53 58 54 84 12 A4 D7 80 11 00 00
+04 50 55 53 48 00 84 12 A4 D7 00 12 10 D8 06 50
+55 53 48 2E 42 00 84 12 A4 D7 40 12 64 D7 04 43
+41 4C 4C 00 84 12 A4 D7 80 12 34 C4 2C 00 04 D5
+FC D5 44 D8 59 42 BC 21 5A 42 BD 21 82 4A BC 21
+BE 90 00 15 00 00 02 20 0A 89 02 3C 09 8A 0A 49
+3A 90 10 00 03 2C 5A 0E A8 3F 1A 53 0E 4A 87 12
+70 C7 42 C9 0D 6F 75 74 20 6F 66 20 62 6F 75 6E
+64 73 22 CD 1E D8 05 50 55 53 48 4D 84 12 3A D8
+00 15 86 D8 04 50 4F 50 4D 00 84 12 3A D8 00 17
+4C C6 6E D4 A6 D8 82 43 BC 21 92 42 C4 21 BA 21
+A2 53 C4 21 92 53 C2 21 3E 40 2C 00 B0 12 2A C4
+9C C9 B0 CA C0 C5 B0 CD FC D5 CC D8 0A 4E 3E 4F
+1A 83 2A 92 CA 2F 8A 10 5A 06 6F 3F 04 D8 04 52
+52 43 4D 00 84 12 A0 D8 50 00 DE D8 04 52 52 41
+4D 00 84 12 A0 D8 50 01 EC D8 04 52 4C 41 4D 00
+84 12 A0 D8 50 02 FA D8 04 52 52 55 4D 00 84 12
+A0 D8 50 03 85 12 00 3C 08 D9 03 53 3E 3D 85 12
+00 38 1A D9 02 53 3C 00 85 12 00 34 94 D8 03 30
+3E 3D 85 12 00 30 2E D9 02 30 3C 00 85 12 00 30
+00 00 02 55 3C 00 85 12 00 2C 42 D9 03 55 3E 3D
+85 12 00 28 38 D9 03 30 3C 3E 85 12 00 24 56 D9
+02 30 3D 00 85 12 00 20 00 00 02 49 46 00 1A 42
+C4 21 8A 4E 00 00 A2 53 C4 21 0E 4A 30 4D 4C D9
+04 54 48 45 4E 00 1A 42 C4 21 08 4E 3E 4F 09 48
+29 53 0A 89 0A 11 3A 90 00 02 68 2F 88 DA 00 00
+30 4D 14 D7 04 45 4C 53 45 00 1A 42 C4 21 BA 40
+00 3C 00 00 A2 53 C4 21 2F 83 8F 4A 00 00 E3 3F
+80 D9 05 55 4E 54 49 4C 3A 4F 08 4E 3E 4F 19 42
+C4 21 2A 83 0A 89 0A 11 3A 90 00 FE 47 3B 3A F0
+FF 03 08 DA 89 48 00 00 A2 53 C4 21 30 4D 98 D7
+05 41 47 41 49 4E 87 12 14 D9 C8 D9 2A C4 00 00
+05 57 48 49 4C 45 87 12 6E D9 6E C4 2A C4 24 D9
+06 52 45 50 45 41 54 00 87 12 14 D9 C8 D9 86 D9
+2A C4 00 00 03 4A 4D 50 87 12 A2 CD 14 D9 C8 D9
+2A C4 3E B0 00 10 03 20 3E E0 00 04 30 4D 3E 90
+00 34 06 28 03 24 3E 40 00 34 30 4D 3E 40 00 38
+30 4D 00 00 04 3F 4A 4D 50 00 87 12 32 DA A2 CD
+6E C4 C8 D9 2A C4 68 DA 3D 41 08 4E 3E 4F 2A 48
+0A 93 04 20 98 42 C4 21 00 00 30 4D 88 43 00 00
+A4 3F 2E D8 03 42 57 31 84 12 66 DA 00 00 84 DA
+03 42 57 32 84 12 66 DA 00 00 90 DA 03 42 57 33
+84 12 66 DA 00 00 A8 DA 3D 41 1A 42 C4 21 28 4E
+08 93 08 20 BA 4F 00 00 A2 53 C4 21 8E 4A 00 00
+3E 4F 30 4D 8E 43 00 00 61 3F 00 00 03 46 57 31
+84 12 A6 DA 00 00 CC DA 03 46 57 32 84 12 A6 DA
+00 00 D8 DA 03 46 57 33 84 12 A6 DA 00 00 E4 DA
+04 47 4F 54 4F 00 87 12 14 D9 A2 CD 9A CB 2A C4
+54 DA 05 3F 47 4F 54 4F 87 12 32 DA A2 CD 9A CB
+2A C4
+@FFDA
+BE D2 BE D2 BE D2 BE D2 BE D2 40 C8 BE D2 BE D2
+BE D2 BE D2 BE D2 BE D2 BE D2 BE D2 BE D2 BE D2
+BE D2 BE D2 BE D2
+q
--- /dev/null
+@1800
+10 00 4C C8 80 3E 00 24 FD FF 18 00 34 DB EA D3
+2A C8 38 C8 00 00 00 00
+@21AA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@C400
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 C4
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 C4 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 C4 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E C4 02 3E 52 00 0E 12 3E 4F 30 4D 8E C4
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 C4
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C C4 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 20 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 C4 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 C5
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 C4 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA C4 03 41 4E 44 3E FF 30 4D 7A C4 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E C5 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 C5 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E C5 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 C5 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 C4 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE C5 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 C5 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 C5 03 3E 49 4E 85 12 C2 21 10 C5
+04 42 41 53 45 00 85 12 DA 21 C0 C4 05 53 54 41
+54 45 85 12 B6 21 30 C6 02 42 4C 00 85 12 20 00
+94 C5 02 3C 23 00 B2 40 AA 21 AA 21 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 C6 01 23 1B 42 DA 21 2C 4F 0A 4E
+B0 12 5E C6 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 21 18 42 AA 21
+C8 4A 00 00 30 4D 96 C6 02 23 53 00 87 12 98 C6
+D2 C6 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 C6 02 23 3E 00 9F 42 AA 21 00 00 3E 40 AA 21
+2E 8F 30 4D 00 C6 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C C6 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 C5 03 55 44 2E 87 12 56 C6
+CC C6 E6 C6 32 C9 FA C8 2A C4 18 C7 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA C4
+02 44 2E 00 87 12 56 C6 6E C4 80 C4 3A C7 CC C6
+92 C4 0A C7 E6 C6 32 C9 FA C8 2A C4 52 C5 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 C6 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 21 30 4D
+62 C5 05 41 4C 4C 4F 54 82 5E C4 21 3E 4F 30 4D
+E2 C6 02 43 2C 00 1A 42 C4 21 CA 4E 00 00 92 53
+C4 21 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A C8
+92 B3 1C 05 FD 27 1E 42 0C 05 B0 12 38 C8 30 4D
+30 40 B6 C7 7E C7 05 28 4B 45 59 29 18 42 0C 05
+EA 3F 12 C6 03 4B 45 59 30 40 DC C7 92 C7 06 41
+43 43 45 50 54 00 3C 40 8A C8 3B 40 54 C8 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+7E C8 92 B3 1C 05 05 24 18 42 0C 05 38 90 0A 00
+04 20 21 53 39 40 46 C8 4D 15 B2 40 11 00 0E 05
+A2 B3 1C 05 FD 27 30 41 B2 40 13 00 0E 05 A2 B3
+1C 05 FD 27 30 41 12 D2 0A 18 FD 3F 21 52 3A 17
+58 42 0C 05 48 9B F0 27 48 9C 06 2C 78 92 11 20
+2E 9F 0F 24 1E 83 05 3C 0E 9A 03 24 CE 48 00 00
+1E 53 82 48 0E 05 A2 B3 1C 05 FD 27 30 4D 80 C8
+2D 83 92 B3 1C 05 FD 27 E3 23 B2 40 18 00 0A 18
+3E 8F 3D 41 30 4D D6 C7 06 28 45 4D 49 54 29 00
+08 4E 3E 4F E6 3F 50 C7 04 45 4D 49 54 00 30 40
+A0 C8 A8 C8 04 45 43 48 4F 00 B2 40 82 48 72 C8
+30 4D 6E C7 06 4E 4F 45 43 48 4F 00 B2 40 30 4D
+72 C8 30 4D 98 C8 04 28 43 52 29 00 2F 83 8F 4E
+00 00 3E 40 0D 00 E3 3F A2 C7 02 43 52 00 30 40
+DC C8 04 C7 05 53 50 41 43 45 2F 83 8F 4E 00 00
+3E 40 20 00 D4 3F F4 C8 06 53 50 41 43 45 53 00
+0E 93 09 24 0D 12 3D 40 1C C9 EF 3F 1E C9 2D 83
+1E 83 EB 23 3D 41 3E 4F 30 4D 2C C7 04 54 59 50
+45 00 0E 93 95 24 2A 4F 8F 5E 00 00 0E 4A 87 12
+CA C5 02 C6 0A C5 AE C8 EC C5 42 C9 2A C4 2F 82
+8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E 1D B3 0D 63
+30 4D 08 C9 82 53 22 00 87 12 34 C4 4E C9 B0 CB
+34 C4 22 00 A8 C9 78 C9 3D 41 6E 4E 1E 83 82 5E
+C4 21 3E 4F 92 B3 C4 21 A2 63 C4 21 30 4D C4 C8
+82 2E 22 00 87 12 68 C9 34 C4 32 C9 B0 CB 2A C4
+00 00 04 57 4F 52 44 00 3C 40 BE 21 39 4C 3A 4C
+09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A FC 27 1A 83
+3B 40 60 00 C8 4C 00 00 09 9A 0C 24 7C 4A 4E 9C
+09 24 18 53 4B 9C F6 2F 7C 90 7B 00 F3 2F 7C 80
+20 00 F0 3F 1A 82 C0 21 82 4A C2 21 1E 42 C4 21
+08 8E CE 48 00 00 30 4D 00 00 04 46 49 4E 44 00
+2F 83 0C 4E 65 4C 74 40 80 00 3B 40 CA 21 3E 4B
+0E 93 1E 24 58 4C 01 00 78 F0 1E 00 0E 58 2E 53
+1E 4E FE FF 0E 93 F3 27 09 4E 78 49 48 C4 48 95
+F7 23 0A 4C 1A 53 FA 99 00 00 F2 23 58 83 FA 23
+19 B3 09 63 0C 49 6A 4E 1E 43 4A 93 01 30 2E 83
+8F 4C 00 00 35 40 08 C4 34 40 14 C4 30 4D 2F 53
+2F 53 3E 4F 30 4D 26 C6 07 3E 4E 55 4D 42 45 52
+3C 4F 38 4F 29 4F 2F 82 1B 42 DA 21 6A 4C 7A 80
+30 00 7A 90 0A 00 02 28 7A 80 07 00 0A 9B 13 2C
+82 49 D0 04 82 48 D2 04 82 4B C8 04 19 42 E4 04
+18 42 E6 04 09 5A 08 63 1C 53 1E 83 E7 23 8F 49
+04 00 8F 48 02 00 8F 4C 00 00 30 4D 03 12 0D 12
+1B 42 DA 21 0B 12 32 C0 00 02 6D 4E 0D 5E 0C 4E
+7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23 32 D0 00 02
+FC 4C FE FF 0D 9C FC 2F DE 83 00 00 09 43 08 43
+3D 40 32 CB 3F 82 8F 4E 06 00 0C 4E 7E 4C 6A 4C
+7A 90 2D 00 10 2C 3B 40 10 00 7A 80 24 00 06 24
+2B 43 5A 83 03 24 3B 52 6A 53 B0 23 1C 53 1E 83
+6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83 B1 43 04 00
+A5 3F 34 CB 2F 53 0E 93 2C 17 82 4C DA 21 03 24
+2F 52 0E F3 30 4D 8F 93 00 00 15 20 32 B0 00 02
+14 20 0E 93 05 24 1A 4F 02 00 1A 83 0A 93 0B 38
+2F 53 BF 4F 00 00 3E E3 05 20 BF E3 00 00 9F 53
+00 00 3E E3 30 4D 32 D0 00 02 9F 4F 02 00 04 00
+BF 4F 00 00 3E E3 F6 23 BF E3 02 00 BF E3 00 00
+9F 53 02 00 8F 63 00 00 3E E3 30 4D B4 C8 07 45
+58 45 43 55 54 45 0A 4E 3E 4F 00 4A 28 C5 01 2C
+1A 42 C4 21 A2 53 C4 21 8A 4E 00 00 3E 4F 30 4D
+AE CB 87 4C 49 54 45 52 41 4C 82 93 B6 21 16 24
+32 B0 00 02 09 24 1A 42 C4 21 A2 52 C4 21 BA 40
+34 C4 00 00 BA 4F 02 00 1A 42 C4 21 A2 52 C4 21
+BA 40 34 C4 00 00 8A 4E 02 00 3E 4F 30 4D EA C8
+05 43 4F 55 4E 54 2F 83 1E 53 8F 4E 00 00 5E 4E
+FF FF 30 4D 82 4E BE 21 B2 4F C0 21 3E 4F 82 43
+C2 21 87 12 4C C6 A8 C9 2A CC 3D 40 36 CC E8 22
+3D 41 3E 4F 30 4D 38 CC 0A 4E 3E 4F 3D 40 4E CC
+3D 27 3D 40 24 CC 1A E2 B6 21 B2 27 AC 23 50 CC
+3E 4F 3D 40 24 CC B9 23 DE 53 00 00 68 4E 08 5E
+F8 40 3F 00 00 00 3D 40 16 CE CD 3F 9E CB 08 45
+56 41 4C 55 41 54 45 00 39 40 BE 21 39 12 39 12
+39 12 0D 12 B0 12 2A C4 14 CC 8C CC 3D 41 B2 41
+C2 21 B2 41 C0 21 B2 41 BE 21 30 4D 7A C5 04 51
+55 49 54 00 31 40 E0 20 B2 40 00 20 AC 21 82 43
+B6 21 82 43 08 18 B0 12 2A C4 4E C9 04 0D 6F 6B
+20 00 32 C9 34 C4 38 21 44 C4 34 C4 50 00 F6 C7
+FA C8 14 CC 34 C4 7E 20 CE C4 B2 C5 4E C9 0D 73
+74 61 63 6B 20 65 6D 70 74 79 20 21 28 CD 34 C4
+30 FF 84 C7 B2 C5 4E C9 0B 46 52 41 4D 20 66 75
+6C 6C 20 21 28 CD 42 C6 F4 C4 C0 C5 BA CC 4E C9
+04 0D 20 20 20 00 BC C5 C2 CC EE C7 05 41 42 4F
+52 54 3F 40 80 20 BE 3F 8F 93 02 00 98 26 B2 40
+82 48 72 C8 B0 12 10 D2 82 43 AE DA 82 43 BA DA
+82 43 C6 DA 82 43 F6 DA 82 43 02 DB 82 43 0E DB
+A2 B3 1C 05 FD 27 B2 40 11 00 0E 05 92 C3 1C 05
+38 40 A0 AA 39 42 19 83 FE 23 18 83 FB 23 92 B3
+1C 05 F4 23 87 12 4E C9 04 1B 5B 37 6D 00 32 C9
+32 C9 4E C9 04 1B 5B 30 6D 00 32 C9 58 D1 9A D1
+A0 D1 22 CD 1C CD 86 41 42 4F 52 54 22 00 87 12
+68 C9 34 C4 28 CD B0 CB 2A C4 FA C9 01 27 87 12
+4C C6 A8 C9 00 CA C0 C5 BC CD 2A C4 58 CC 52 C6
+81 5C 92 42 BE 21 C2 21 30 4D 87 12 84 C9 4C C6
+A8 C9 D4 CD 08 4E 7A 4E 5A D3 5A 53 0A 58 19 42
+C8 21 6E 4E 3E F0 1E 00 09 5E 82 48 AE 21 82 49
+B0 21 82 4A B2 21 2A 52 82 4A C4 21 3E 4F 3D 41
+30 41 87 12 4E C9 0F 73 74 61 63 6B 20 6D 69 73
+6D 61 74 63 68 21 2E CD 82 9F B4 21 F2 23 18 42
+AE 21 19 42 B0 21 A8 49 FE FF 89 48 00 00 30 4D
+A2 C9 08 56 41 52 49 41 42 4C 45 00 B0 12 CA CD
+BA 40 86 12 FC FF EF 3F 00 CC 08 43 4F 4E 53 54
+41 4E 54 00 B0 12 CA CD BA 40 85 12 FC FF 8A 4E
+FE FF 3E 4F E0 3F 4A CE 06 43 52 45 41 54 45 00
+B0 12 CA CD BA 40 85 12 FC FF 8A 4A FE FF D3 3F
+6E CC 05 44 4F 45 53 3E 1A 42 B2 21 BA 40 84 12
+00 00 8A 4D 02 00 3D 41 30 4D 82 CE 05 44 45 46
+45 52 B0 12 CA CD BA 40 30 40 FC FF BA 40 98 CE
+FE FF B9 3F 00 00 81 5B 82 43 B6 21 30 4D C0 CD
+01 5D B2 43 B6 21 30 4D 64 C9 87 52 45 43 55 52
+53 45 19 42 C4 21 99 42 B2 21 00 00 A2 53 C4 21
+30 4D B6 CE 01 3A B0 12 CA CD BA 40 87 12 FC FF
+A2 83 C4 21 B2 43 B6 21 82 4F B4 21 30 4D E4 CE
+81 3B 82 93 B6 21 5D 27 87 12 34 C4 2A C4 B0 CB
+18 CE B8 CE 2A C4 D6 C8 09 49 4D 4D 45 44 49 41
+54 45 1A 42 AE 21 FA D0 80 00 00 00 30 4D BE 4F
+02 00 3E 4F 30 4D 18 CF 82 49 53 00 87 12 42 C6
+F4 C4 C0 C5 50 CF 5C CF 34 C4 2E CF B0 CB 2A C4
+AE CD 2E CF 2A C4 00 CF 83 5B 27 5D 87 12 AE CD
+34 C4 34 C4 B0 CB B0 CB 2A C4 9E CC 88 50 4F 53
+54 50 4F 4E 45 00 87 12 4C C6 A8 C9 00 CA 54 C4
+C0 C5 BC CD 7E C5 C0 C5 96 CF 34 C4 34 C4 B0 CB
+B0 CB 34 C4 B0 CB B0 CB 2A C4 9C CF 3A 4E 82 4A
+C6 21 2E 4E 82 4E C4 21 3D 40 10 00 09 4A 08 49
+29 83 18 48 FE FF 0E 98 FC 2B 89 48 00 00 1D 83
+F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41 30 4D 38 CF
+82 49 46 00 2F 83 8F 4E 00 00 1E 42 C4 21 BE 40
+C0 C5 00 00 A2 52 C4 21 2E 53 30 4D 9C CE 84 45
+4C 53 45 00 1A 42 C4 21 BA 40 BC C5 00 00 2A 52
+82 4A C4 21 8E 4A 00 00 2A 83 0E 4A 30 4D 2C C9
+84 54 48 45 4E 00 9E 42 C4 21 00 00 3E 4F 30 4D
+68 CE 85 42 45 47 49 4E 30 40 84 C7 10 D0 85 55
+4E 54 49 4C 39 40 C0 C5 1A 42 C4 21 A2 52 C4 21
+8A 49 00 00 8A 4E 02 00 3E 4F 30 4D 96 CD 85 41
+47 41 49 4E 39 40 BC C5 EF 3F 32 CE 85 57 48 49
+4C 45 87 12 D4 CF 6E C4 2A C4 CA CE 86 52 45 50
+45 41 54 00 87 12 54 D0 16 D0 2A C4 EE CF 82 44
+4F 00 2F 83 8F 4E 00 00 1E 42 C4 21 BE 40 CA C5
+00 00 2E 53 82 4E C4 21 A2 53 AC 21 1A 42 AC 21
+8A 43 00 00 30 4D C2 CB 84 4C 4F 4F 50 00 39 40
+EC C5 1A 42 C4 21 A2 52 C4 21 8A 49 00 00 8A 4E
+02 00 1E 42 AC 21 A2 83 AC 21 2E 4E 0E 93 04 24
+9E 42 C4 21 00 00 F5 3F 3E 4F 30 4D E4 C7 85 2B
+4C 4F 4F 50 39 40 DA C5 E4 3F A8 D0 85 4C 45 41
+56 45 1A 42 C4 21 BA 40 FC C5 00 00 BA 40 BC C5
+02 00 B2 50 06 00 C4 21 A2 53 AC 21 2A 52 19 42
+AC 21 89 4A 00 00 30 4D EC D0 04 4D 4F 56 45 00
+0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24 08 99 0F 24
+06 2C F8 49 00 00 18 53 1A 83 FB 23 30 4D 08 5A
+09 5A 19 83 18 83 E8 49 00 00 1A 83 FA 23 30 4D
+34 C4 CA 21 FC C4 2A C4 84 12 50 D1 1E D4 06 D4
+7E D0 AC CD EE D3 DE D0 1A D1 90 C9 BE D1 F2 D1
+2E D0 B2 D2 48 C5 58 CF C0 CE 68 CA 00 00 3A 40
+0C 00 39 40 CA 21 38 40 CC 21 D9 3F 3A 40 0E 00
+39 40 CC 21 38 40 CA 21 CC 3F 82 43 CC 21 30 4D
+92 42 CA 21 C8 21 30 4D 6C CF 09 50 57 52 5F 53
+54 41 54 45 84 12 9A CF EA D3 34 DB AA D1 08 50
+57 52 5F 48 45 52 45 00 92 42 C4 21 BA D1 92 42
+C6 21 B8 D1 EF 3F 6C D0 09 52 53 54 5F 53 54 41
+54 45 92 42 0C 18 BA D1 92 42 0E 18 B8 D1 E2 3F
+D8 D1 08 52 53 54 5F 48 45 52 45 00 92 42 C4 21
+0C 18 92 42 C6 21 0E 18 DF 3F B2 40 58 D2 BA D2
+B2 40 A0 C8 B0 C8 B2 40 DC C8 F0 C8 B2 40 DC C7
+EA C7 30 41 5C D0 04 57 49 50 45 00 39 40 80 FF
+B9 43 00 00 29 53 39 90 DA FF FA 23 B0 12 0A D2
+B2 40 34 DB C4 21 B2 40 EA D3 C6 21 D7 3F D0 CF
+06 28 57 41 52 4D 29 00 1E 42 08 18 87 12 4E C9
+05 0D 1B 5B 37 6D 32 C9 70 C7 4E C9 27 20 46 61
+73 74 46 6F 72 74 68 20 56 31 36 30 20 31 36 4D
+48 7A 20 28 43 29 20 4A 2E 4D 2E 54 68 6F 6F 72
+65 6E 73 20 32 C9 34 C4 30 FF 84 C7 2A C5 30 C7
+4E C9 0B 62 79 74 65 73 20 66 72 65 65 20 34 CD
+26 D2 04 57 41 52 4D 00 30 40 58 D2 22 D0 04 43
+4F 4C 44 00 B2 40 04 A5 20 01 B2 40 88 5A CC 01
+B2 43 02 02 B2 D3 06 02 D2 43 24 02 F2 40 FD 00
+22 02 F2 D0 FD 00 26 02 F2 40 A5 00 A1 01 F2 40
+10 00 A0 01 D2 43 A1 01 B2 40 00 A5 60 01 B2 40
+29 01 80 01 B2 40 0B 00 82 01 B2 40 E9 01 84 01
+39 40 40 00 B2 D0 10 00 86 01 92 D2 5E 01 08 18
+A2 93 08 18 01 24 59 03 38 40 50 C3 18 83 FE 23
+19 83 FA 23 3A 40 CA D2 39 40 DA FF 89 4A 00 00
+29 53 FC 23 92 42 02 18 E4 FF B2 40 18 00 0A 18
+31 40 E0 20 3F 40 80 20 37 40 00 C4 36 40 B4 C4
+35 40 08 C4 34 40 14 C4 B2 40 0A 00 DA 21 B2 43
+DC 21 92 C3 30 01 18 42 08 18 F2 B0 10 00 00 02
+04 20 38 E3 18 53 82 48 08 18 B2 40 81 00 00 05
+B2 40 11 00 06 05 B2 40 00 4A 08 05 F2 D0 30 00
+0A 02 92 C3 00 05 92 D3 1A 05 3D 40 C4 D3 18 42
+08 18 38 90 0A 00 3A 27 38 90 16 00 37 2F 28 93
+10 23 F8 26 B8 D2 84 12 50 D1 12 DA BE DA C6 D9
+12 DB 8C D9 46 DA 90 D6 00 00 82 D9 32 DA E4 D9
+22 DA A0 D7 00 00 00 00 24 DB 7C D1 50 D2 85 48
+49 32 4C 4F 87 12 84 C7 E8 CF B0 CB B8 CE 7E D1
+C6 D3 2A C4 BE D2 04 43 4F 44 45 00 B0 12 CA CD
+A2 82 C4 21 87 12 F8 CE BC C5 FE D3 4E D0 03 41
+53 4D 92 42 C8 21 B8 21 B2 40 CA D3 C8 21 EE 3F
+00 00 07 45 4E 44 43 4F 44 45 87 12 8C D1 18 CE
+2A C4 32 D4 06 45 4E 44 41 53 4D 00 92 42 B8 21
+C8 21 F3 3F 00 00 05 43 4F 4C 4F 4E 1A 42 C4 21
+BA 40 87 12 00 00 A2 53 C4 21 B2 43 B6 21 30 40
+8C D1 00 00 05 4C 4F 32 48 49 1A 42 C4 21 BA 40
+B0 12 00 00 BA 40 2A C4 02 00 A2 52 C4 21 ED 3F
+38 40 BE 21 39 48 2A 48 09 5A 1A 52 C2 21 09 9A
+03 24 7E 9A FC 27 1A 83 0E 4A 2A 88 82 4A C2 21
+30 4D B0 12 2A C4 A8 C9 00 CA 72 C5 C0 C5 C8 D4
+BC CA C0 C5 BC CD EA D4 CA D4 29 4E 39 90 86 12
+02 20 2E 53 30 41 39 90 85 12 03 20 1E 4E 02 00
+30 41 39 90 84 12 01 20 2E 52 30 41 19 42 C4 21
+A2 53 C4 21 89 4E 00 00 3E 40 29 00 12 12 C2 21
+92 53 C2 21 B0 12 2A C4 A8 C9 BC CA C0 C5 1C D5
+12 D5 21 53 3E 90 10 00 BB 2D 30 41 1E D5 B2 41
+C2 21 22 D3 30 41 87 12 4C C6 90 D4 2E D5 82 43
+BC 21 92 42 C4 21 BA 21 A2 53 C4 21 0A 4E 3E 4F
+FA 90 23 00 00 00 34 20 92 53 C2 21 B0 12 B2 D4
+0E 93 04 20 B2 40 00 03 BC 21 27 3C 1E 93 04 20
+B2 40 10 03 BC 21 21 3C 2E 93 04 20 B2 40 20 03
+BC 21 1B 3C 2E 92 04 20 B2 40 20 02 BC 21 15 3C
+3E 92 04 20 B2 40 30 02 BC 21 0F 3C 3E 93 04 20
+B2 40 30 03 BC 21 09 3C B2 40 30 00 BC 21 19 42
+C4 21 A2 53 C4 21 89 4E 00 00 3E 4F 3D 41 30 4D
+FA 90 26 00 00 00 08 20 B2 40 10 02 BC 21 92 53
+C2 21 30 12 9E D5 75 3F FA 90 40 00 00 00 1A 20
+B2 40 20 00 BC 21 92 53 C2 21 B0 12 FC D4 0E 20
+B2 50 10 00 BC 21 3E 40 2B 00 B0 12 FC D4 32 24
+92 92 BE 21 C2 21 02 24 92 53 C2 21 8E 10 82 5E
+BC 21 D3 3F B0 12 FC D4 F9 23 B2 50 10 00 BC 21
+3E 40 28 00 B0 12 B2 D4 30 12 EE D5 67 3F 87 12
+4C C6 90 D4 26 D6 FE 90 26 00 00 00 3E 40 20 00
+04 20 B2 50 82 00 BC 21 C2 3F B0 12 FC D4 DF 23
+B2 50 80 00 BC 21 3E 40 28 00 B0 12 B2 D4 B0 12
+EC D4 D5 23 3D 40 BC CD 30 4D 00 00 04 52 45 54
+49 00 87 12 34 C4 00 13 B0 CB 2A C4 34 C4 2C 00
+26 D5 1E D6 76 D6 2E 4E 1E D2 BC 21 19 42 BA 21
+92 3F 74 D4 03 4D 4F 56 84 12 6C D6 00 40 84 D6
+05 4D 4F 56 2E 42 84 12 6C D6 40 40 00 00 03 41
+44 44 84 12 6C D6 00 50 9E D6 05 41 44 44 2E 42
+84 12 6C D6 40 50 AA D6 04 41 44 44 43 00 84 12
+6C D6 00 60 B8 D6 06 41 44 44 43 2E 42 00 84 12
+6C D6 40 60 5C D6 04 53 55 42 43 00 84 12 6C D6
+00 70 D6 D6 06 53 55 42 43 2E 42 00 84 12 6C D6
+40 70 E4 D6 03 53 55 42 84 12 6C D6 00 80 F4 D6
+05 53 55 42 2E 42 84 12 6C D6 40 80 56 D4 03 43
+4D 50 84 12 6C D6 00 90 0E D7 05 43 4D 50 2E 42
+84 12 6C D6 40 90 44 D4 04 44 41 44 44 00 84 12
+6C D6 00 A0 28 D7 06 44 41 44 44 2E 42 00 84 12
+6C D6 40 A0 1A D7 03 42 49 54 84 12 6C D6 00 B0
+46 D7 05 42 49 54 2E 42 84 12 6C D6 40 B0 52 D7
+03 42 49 43 84 12 6C D6 00 C0 60 D7 05 42 49 43
+2E 42 84 12 6C D6 40 C0 6C D7 03 42 49 53 84 12
+6C D6 00 D0 7A D7 05 42 49 53 2E 42 84 12 6C D6
+40 D0 00 00 03 58 4F 52 84 12 6C D6 00 E0 94 D7
+05 58 4F 52 2E 42 84 12 6C D6 40 E0 C6 D6 03 41
+4E 44 84 12 6C D6 00 F0 AE D7 05 41 4E 44 2E 42
+84 12 6C D6 40 F0 4C C6 26 D5 CC D7 1A 42 BC 21
+B2 F0 70 00 BC 21 8A 10 3A F0 0F 00 82 DA BC 21
+4A 3F 00 D7 03 52 52 43 84 12 C6 D7 00 10 E4 D7
+05 52 52 43 2E 42 84 12 C6 D7 40 10 F0 D7 04 53
+57 50 42 00 84 12 C6 D7 80 10 FE D7 03 52 52 41
+84 12 C6 D7 00 11 0C D8 05 52 52 41 2E 42 84 12
+C6 D7 40 11 18 D8 03 53 58 54 84 12 C6 D7 80 11
+00 00 04 50 55 53 48 00 84 12 C6 D7 00 12 32 D8
+06 50 55 53 48 2E 42 00 84 12 C6 D7 40 12 86 D7
+04 43 41 4C 4C 00 84 12 C6 D7 80 12 34 C4 2C 00
+26 D5 1E D6 66 D8 59 42 BC 21 5A 42 BD 21 82 4A
+BC 21 BE 90 00 15 00 00 02 20 0A 89 02 3C 09 8A
+0A 49 3A 90 10 00 03 2C 5A 0E A8 3F 1A 53 0E 4A
+87 12 70 C7 4E C9 0D 6F 75 74 20 6F 66 20 62 6F
+75 6E 64 73 2E CD 40 D8 05 50 55 53 48 4D 84 12
+5C D8 00 15 A8 D8 04 50 4F 50 4D 00 84 12 5C D8
+00 17 4C C6 90 D4 C8 D8 82 43 BC 21 92 42 C4 21
+BA 21 A2 53 C4 21 92 53 C2 21 3E 40 2C 00 B0 12
+2A C4 A8 C9 BC CA C0 C5 BC CD 1E D6 EE D8 0A 4E
+3E 4F 1A 83 2A 92 CA 2F 8A 10 5A 06 6F 3F 26 D8
+04 52 52 43 4D 00 84 12 C2 D8 50 00 00 D9 04 52
+52 41 4D 00 84 12 C2 D8 50 01 0E D9 04 52 4C 41
+4D 00 84 12 C2 D8 50 02 1C D9 04 52 52 55 4D 00
+84 12 C2 D8 50 03 85 12 00 3C 2A D9 03 53 3E 3D
+85 12 00 38 3C D9 02 53 3C 00 85 12 00 34 B6 D8
+03 30 3E 3D 85 12 00 30 50 D9 02 30 3C 00 85 12
+00 30 00 00 02 55 3C 00 85 12 00 2C 64 D9 03 55
+3E 3D 85 12 00 28 5A D9 03 30 3C 3E 85 12 00 24
+78 D9 02 30 3D 00 85 12 00 20 00 00 02 49 46 00
+1A 42 C4 21 8A 4E 00 00 A2 53 C4 21 0E 4A 30 4D
+6E D9 04 54 48 45 4E 00 1A 42 C4 21 08 4E 3E 4F
+09 48 29 53 0A 89 0A 11 3A 90 00 02 68 2F 88 DA
+00 00 30 4D 36 D7 04 45 4C 53 45 00 1A 42 C4 21
+BA 40 00 3C 00 00 A2 53 C4 21 2F 83 8F 4A 00 00
+E3 3F A2 D9 05 55 4E 54 49 4C 3A 4F 08 4E 3E 4F
+19 42 C4 21 2A 83 0A 89 0A 11 3A 90 00 FE 47 3B
+3A F0 FF 03 08 DA 89 48 00 00 A2 53 C4 21 30 4D
+BA D7 05 41 47 41 49 4E 87 12 36 D9 EA D9 2A C4
+00 00 05 57 48 49 4C 45 87 12 90 D9 6E C4 2A C4
+46 D9 06 52 45 50 45 41 54 00 87 12 36 D9 EA D9
+A8 D9 2A C4 00 00 03 4A 4D 50 87 12 AE CD 36 D9
+EA D9 2A C4 3E B0 00 10 03 20 3E E0 00 04 30 4D
+3E 90 00 34 06 28 03 24 3E 40 00 34 30 4D 3E 40
+00 38 30 4D 00 00 04 3F 4A 4D 50 00 87 12 54 DA
+AE CD 6E C4 EA D9 2A C4 8A DA 3D 41 08 4E 3E 4F
+2A 48 0A 93 04 20 98 42 C4 21 00 00 30 4D 88 43
+00 00 A4 3F 50 D8 03 42 57 31 84 12 88 DA 00 00
+A6 DA 03 42 57 32 84 12 88 DA 00 00 B2 DA 03 42
+57 33 84 12 88 DA 00 00 CA DA 3D 41 1A 42 C4 21
+28 4E 08 93 08 20 BA 4F 00 00 A2 53 C4 21 8E 4A
+00 00 3E 4F 30 4D 8E 43 00 00 61 3F 00 00 03 46
+57 31 84 12 C8 DA 00 00 EE DA 03 46 57 32 84 12
+C8 DA 00 00 FA DA 03 46 57 33 84 12 C8 DA 00 00
+06 DB 04 47 4F 54 4F 00 87 12 36 D9 AE CD A6 CB
+2A C4 76 DA 05 3F 47 4F 54 4F 87 12 54 DA AE CD
+A6 CB 2A C4
+@FFDA
+CA D2 CA D2 CA D2 CA D2 CA D2 4C C8 CA D2 CA D2
+CA D2 CA D2 CA D2 CA D2 CA D2 CA D2 CA D2 CA D2
+CA D2 CA D2 CA D2
+q
--- /dev/null
+\prog\MSP430Flasher\msp430flasher -m SBW2 -n MSP430fr2433 -v -w %1 -z [VCC=3000]
+exit
+
+tip : how to calculate MAIN program lenght ?
+
+open the prog.txt file with your editor, select MAIN section
+in status bar, keep the number of selected chars
+if lines are ended with CR+LF, substract the number of lines selected
+then divide by 3.
--- /dev/null
+
+FORTH vocabulary
+ COLD WARM (WARM) WIPE RST_HERE RST_STATE PWR_HERE PWR_STATE
+ MOVE LEAVE +LOOP LOOP DO REPEAT WHILE AGAIN
+ UNTIL BEGIN THEN ELSE IF POSTPONE ['] IS
+ IMMEDIATE ; : RECURSE ] [ DEFER DOES>
+ CREATE CONSTANT VARIABLE \ ' ABORT" ABORT QUIT
+ EVALUATE COUNT LITERAL , EXECUTE >NUMBER FIND WORD
+ ." S" TYPE SPACES SPACE CR (CR) NOECHO
+ ECHO EMIT (EMIT) ACCEPT KEY (KEY) C, ALLOT
+ HERE . D. U. UD. SIGN HOLD #>
+ #S # <# BL STATE BASE >IN J
+ I UNLOOP U< > < = 0< 0=
+ ABS NEGATE XOR OR AND - + C!
+ C@ ! @ DEPTH R@ R> >R ROT
+ OVER SWAP DROP ?DUP DUP LIT EXIT
+
+ASSEMBLER vocabulary
+ ?GOTO GOTO FW3 FW2 FW1 BW3 BW2 BW1
+ ?JMP JMP REPEAT WHILE AGAIN UNTIL ELSE THEN
+ IF 0= 0<> U>= U< 0< 0>= S<
+ S>= RRUM RLAM RRAM RRCM POPM PUSHM CALL
+ PUSH.B PUSH SXT RRA.B RRA SWPB RRC.B RRC
+ AND.B AND XOR.B XOR BIS.B BIS BIC.B BIC
+ BIT.B BIT DADD.B DADD CMP.B CMP SUB.B SUB
+ SUBC.B SUBC ADDC.B ADDC ADD.B ADD MOV.B MOV
+ RETI LO2HI COLON ENDASM ENDCODE ASM CODE HI2LO
+ ASSEMBLER
+
+VOCABULARY ADD-ON
+ DEFINITIONS ONLY PREVIOUS ALSO FORTH VOCABULARY
+
+ANS_COMPLEMENT ADD-ON
+ >BODY SOURCE .( ( DECIMAL HEX FILL +!
+ [CHAR] CHAR CELL+ CELLS CHAR+ CHARS ALIGN ALIGNED
+ 2OVER 2SWAP 2DROP 2DUP 2! 2@ */ */MOD
+ MOD / /MOD * FM/MOD SM/REM UM/MOD M*
+ UM* S>D NIP 2/ 2* MIN MAX 1-
+ 1+ RSHIFT LSHIFT INVERT
+
+SD_CARD_LOADER ADD-ON
+ LOAD" (ACCEPT)
+
+SD_CARD_READ_WRITE ADD-ON
+ TERM2SD" SD_EMIT WRITE WRITE" READ READ" CLOSE DEL"
+ CD"
+
+SD_TOOLS ADD-ON
+ DIR_D FAT_D CLUST_D SECT_D DUMP U.R MIN
+ MAX WORDS .S SP@ ?
+
--- /dev/null
+; -*- coding: utf-8 -*-
+; ForthThreads.mac
+
+voclink .set 0 ; initial vocabulary link
+
+
+forthlink .set 0
+forthlink1 .set 0
+forthlink2 .set 0
+forthlink3 .set 0
+forthlink4 .set 0
+forthlink5 .set 0
+forthlink6 .set 0
+forthlink7 .set 0
+forthlink8 .set 0
+forthlink9 .set 0
+forthlink10 .set 0
+forthlink11 .set 0
+forthlink12 .set 0
+forthlink13 .set 0
+forthlink14 .set 0
+forthlink15 .set 0
+forthlink16 .set 0
+forthlink17 .set 0
+forthlink18 .set 0
+forthlink19 .set 0
+forthlink20 .set 0
+forthlink21 .set 0
+forthlink22 .set 0
+forthlink23 .set 0
+forthlink24 .set 0
+forthlink25 .set 0
+forthlink26 .set 0
+forthlink27 .set 0
+forthlink28 .set 0
+forthlink29 .set 0
+forthlink30 .set 0
+forthlink31 .set 0
+
+asmlink .set 0
+asmlink1 .set 0
+asmlink2 .set 0
+asmlink3 .set 0
+asmlink4 .set 0
+asmlink5 .set 0
+asmlink6 .set 0
+asmlink7 .set 0
+asmlink8 .set 0
+asmlink9 .set 0
+asmlink10 .set 0
+asmlink11 .set 0
+asmlink12 .set 0
+asmlink13 .set 0
+asmlink14 .set 0
+asmlink15 .set 0
+asmlink16 .set 0
+asmlink17 .set 0
+asmlink18 .set 0
+asmlink19 .set 0
+asmlink20 .set 0
+asmlink21 .set 0
+asmlink22 .set 0
+asmlink23 .set 0
+asmlink24 .set 0
+asmlink25 .set 0
+asmlink26 .set 0
+asmlink27 .set 0
+asmlink28 .set 0
+asmlink29 .set 0
+asmlink30 .set 0
+asmlink31 .set 0
+
+;-------------------------------------------
+FORTHWORD .MACRO name
+;-------------------------------------------
+; (THREADS-1)*2 = AND mask to define CURRENT offset in vocabulary
+thread .set charfromstr(name,0) & ((THREADS-1)*2)
+
+
+ .SWITCH thread
+ .case 0
+ .word forthlink
+forthlink .set $
+ .case 2
+ .word forthlink1
+forthlink1 .set $
+ .case 4
+ .word forthlink2
+forthlink2 .set $
+ .case 6
+ .word forthlink3
+forthlink3 .set $
+ .case 8
+ .word forthlink4
+forthlink4 .set $
+ .case 10
+ .word forthlink5
+forthlink5 .set $
+ .case 12
+ .word forthlink6
+forthlink6 .set $
+ .case 14
+ .word forthlink7
+forthlink7 .set $
+ .case 16
+ .word forthlink8
+forthlink8 .set $
+ .case 18
+ .word forthlink9
+forthlink9 .set $
+ .case 20
+ .word forthlink10
+forthlink10 .set $
+ .case 22
+ .word forthlink11
+forthlink11 .set $
+ .case 24
+ .word forthlink12
+forthlink12 .set $
+ .case 26
+ .word forthlink13
+forthlink13 .set $
+ .case 28
+ .word forthlink14
+forthlink14 .set $
+ .case 30
+ .word forthlink15
+forthlink15 .set $
+ .case 32
+ .word forthlink16
+forthlink16 .set $
+ .case 34
+ .word forthlink17
+forthlink17 .set $
+ .case 36
+ .word forthlink18
+forthlink18 .set $
+ .case 38
+ .word forthlink19
+forthlink19 .set $
+ .case 40
+ .word forthlink20
+forthlink20 .set $
+ .case 42
+ .word forthlink21
+forthlink21 .set $
+ .case 44
+ .word forthlink22
+forthlink22 .set $
+ .case 46
+ .word forthlink23
+forthlink23 .set $
+ .case 48
+ .word forthlink24
+forthlink24 .set $
+ .case 50
+ .word forthlink25
+forthlink25 .set $
+ .case 52
+ .word forthlink26
+forthlink26 .set $
+ .case 54
+ .word forthlink27
+forthlink27 .set $
+ .case 56
+ .word forthlink28
+forthlink28 .set $
+ .case 58
+ .word forthlink29
+forthlink29 .set $
+ .case 60
+ .word forthlink30
+forthlink30 .set $
+ .case 62
+ .word forthlink31
+forthlink31 .set $
+
+ .endcase
+
+ .byte STRLEN(name),name
+ .align 2
+ .ENDM
+
+
+
+;-------------------------------------------
+FORTHWORDIMM .MACRO name
+;-------------------------------------------
+
+; (THREADS-1)*2 = AND mask to define CURRENT offset in vocabulary
+thread .set charfromstr(name,0) & ((THREADS-1)*2)
+
+
+ .SWITCH thread
+ .case 0
+ .word forthlink
+forthlink .set $
+ .case 2
+ .word forthlink1
+forthlink1 .set $
+ .case 4
+ .word forthlink2
+forthlink2 .set $
+ .case 6
+ .word forthlink3
+forthlink3 .set $
+ .case 8
+ .word forthlink4
+forthlink4 .set $
+ .case 10
+ .word forthlink5
+forthlink5 .set $
+ .case 12
+ .word forthlink6
+forthlink6 .set $
+ .case 14
+ .word forthlink7
+forthlink7 .set $
+ .case 16
+ .word forthlink8
+forthlink8 .set $
+ .case 18
+ .word forthlink9
+forthlink9 .set $
+ .case 20
+ .word forthlink10
+forthlink10 .set $
+ .case 22
+ .word forthlink11
+forthlink11 .set $
+ .case 24
+ .word forthlink12
+forthlink12 .set $
+ .case 26
+ .word forthlink13
+forthlink13 .set $
+ .case 28
+ .word forthlink14
+forthlink14 .set $
+ .case 30
+ .word forthlink15
+forthlink15 .set $
+ .case 32
+ .word forthlink16
+forthlink16 .set $
+ .case 34
+ .word forthlink17
+forthlink17 .set $
+ .case 36
+ .word forthlink18
+forthlink18 .set $
+ .case 38
+ .word forthlink19
+forthlink19 .set $
+ .case 40
+ .word forthlink20
+forthlink20 .set $
+ .case 42
+ .word forthlink21
+forthlink21 .set $
+ .case 44
+ .word forthlink22
+forthlink22 .set $
+ .case 46
+ .word forthlink23
+forthlink23 .set $
+ .case 48
+ .word forthlink24
+forthlink24 .set $
+ .case 50
+ .word forthlink25
+forthlink25 .set $
+ .case 52
+ .word forthlink26
+forthlink26 .set $
+ .case 54
+ .word forthlink27
+forthlink27 .set $
+ .case 56
+ .word forthlink28
+forthlink28 .set $
+ .case 58
+ .word forthlink29
+forthlink29 .set $
+ .case 60
+ .word forthlink30
+forthlink30 .set $
+ .case 62
+ .word forthlink31
+forthlink31 .set $
+
+
+ .endcase
+
+ .byte STRLEN(name)+128,name
+ .align 2
+ .ENDM
+
+
+
+;-------------------------------------------
+asmword .MACRO name
+;-------------------------------------------
+
+; (THREADS-1)*2 = AND mask to define CURRENT offset in vocabulary
+thread .set charfromstr(name,0) & ((THREADS-1)*2)
+
+
+ .SWITCH thread
+ .case 0
+ .word asmlink
+asmlink .set $
+ .case 2
+ .word asmlink1
+asmlink1 .set $
+ .case 4
+ .word asmlink2
+asmlink2 .set $
+ .case 6
+ .word asmlink3
+asmlink3 .set $
+ .case 8
+ .word asmlink4
+asmlink4 .set $
+ .case 10
+ .word asmlink5
+asmlink5 .set $
+ .case 12
+ .word asmlink6
+asmlink6 .set $
+ .case 14
+ .word asmlink7
+asmlink7 .set $
+ .case 16
+ .word asmlink8
+asmlink8 .set $
+ .case 18
+ .word asmlink9
+asmlink9 .set $
+ .case 20
+ .word asmlink10
+asmlink10 .set $
+ .case 22
+ .word asmlink11
+asmlink11 .set $
+ .case 24
+ .word asmlink12
+asmlink12 .set $
+ .case 26
+ .word asmlink13
+asmlink13 .set $
+ .case 28
+ .word asmlink14
+asmlink14 .set $
+ .case 30
+ .word asmlink15
+asmlink15 .set $
+ .case 32
+ .word asmlink16
+asmlink16 .set $
+ .case 34
+ .word asmlink17
+asmlink17 .set $
+ .case 36
+ .word asmlink18
+asmlink18 .set $
+ .case 38
+ .word asmlink19
+asmlink19 .set $
+ .case 40
+ .word asmlink20
+asmlink20 .set $
+ .case 42
+ .word asmlink21
+asmlink21 .set $
+ .case 44
+ .word asmlink22
+asmlink22 .set $
+ .case 46
+ .word asmlink23
+asmlink23 .set $
+ .case 48
+ .word asmlink24
+asmlink24 .set $
+ .case 50
+ .word asmlink25
+asmlink25 .set $
+ .case 52
+ .word asmlink26
+asmlink26 .set $
+ .case 54
+ .word asmlink27
+asmlink27 .set $
+ .case 56
+ .word asmlink28
+asmlink28 .set $
+ .case 58
+ .word asmlink29
+asmlink29 .set $
+ .case 60
+ .word asmlink30
+asmlink30 .set $
+ .case 62
+ .word asmlink31
+asmlink31 .set $
+
+
+ .endcase
+
+ .byte STRLEN(name),name
+ .align 2
+ .ENDM
+
+
--- /dev/null
+GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ {one line to give the program's name and a brief idea of what it does.}
+ Copyright (C) {year} {name of author}
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ {project} Copyright (C) {year} {fullname}
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
\ No newline at end of file
--- /dev/null
+; -------------------------------------------------------------------------------
+; ANS complement for MSP430FRxxxx devices with hardware_MPY, to pass CORETEST.4th
+; -------------------------------------------------------------------------------
+
+\ REGISTERS USAGE
+\ R4 to R7 must be saved before use and restored after
+\ scratch registers Y to S are free for use
+\ under interrupt, IP is free for use
+
+\ PUSHM order : PSP,TOS, IP, S, T, W, X, Y, R7, R6, R5, R4
+\ example : PUSHM IP,Y
+\
+\ POPM order : R4, R5, R6, R7, Y, X, W, T, S, IP,TOS,PSP
+\ example : POPM Y,IP
+
+\ ASSEMBLER conditionnal usage before IF UNTIL WHILE : S< S>= U< U>= 0= 0<> 0>=
+\ ASSEMBLER conditionnal usage before ?JMP ?GOTO : S< S>= U< U>= 0= 0<> 0<
+
+\ FORTH conditionnal usage before IF UNTIL WHILE : 0= 0< = < > U<
+
+
+
+\ ECHO ; if an error occurs, uncomment this line before new download to find it.
+ \
+
+CODE INVERT \ x1 -- x2 bitwise inversion
+ XOR #-1,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LSHIFT \ x1 u -- x2 logical L shift u places
+ MOV @PSP+,W
+ AND #$1F,TOS \ no need to shift more than 16
+0<> IF
+ BEGIN ADD W,W
+ SUB #1,TOS
+ 0= UNTIL
+THEN MOV W,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE RSHIFT \ x1 u -- x2 logical R shift u places
+ MOV @PSP+,W
+ AND #$1F,TOS \ no need to shift more than 16
+0<> IF
+ BEGIN BIC #C,SR \ Clr Carry
+ RRC W
+ SUB #1,TOS
+ 0= UNTIL
+THEN MOV W,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE 1+ \ n1/u1 -- n2/u2 add 1 to TOS
+ ADD #1,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE 1- \ n1/u1 -- n2/u2 subtract 1 from TOS
+ SUB #1,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE 2* \ x1 -- x2 arithmetic left shift
+ ADD TOS,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE 2/ \ x1 -- x2 arithmetic right shift
+ RRA TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+\ --------------------
+\ ARITHMETIC OPERATORS
+\ --------------------
+
+CODE NIP \ a b c -- a c
+ADD #2,PSP
+MOV @IP+,PC
+ENDCODE
+ \
+
+: S>D \ n -- d single -> double
+ DUP 0<
+;
+ \
+
+
+CODE UM* \ u1 u2 -- udlo udhi unsigned 16x16->32 mult.
+MOV @PSP,&MPY \ Load 1st operand
+MOV TOS,&OP2 \ Load 2nd operand
+MOV &RES0,0(PSP) \ low result on stack
+MOV &RES1,TOS \ high result in TOS
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE M* \ n1 n2 -- dlo dhi signed 16*16->32 multiply
+MOV @PSP,&MPYS
+MOV TOS,&OP2
+MOV &RES0,0(PSP)
+MOV &RES1,TOS
+MOV @IP+,PC
+ENDCODE
+ \
+
+
+\ TOS = DIVISOR
+\ S = DIVIDENDlo
+\ W = DIVIDENDhi
+\ X = count
+\ Y = QUOTIENT
+\ DVDhi|DVDlo : DIVISOR -> QUOT in Y, REM in DVDhi
+\ RETURN: CARRY = 0: OK CARRY = 1: QUOTIENT > 16 BITS
+
+\ C UM/MOD udlo|udhi u1 -- ur uq
+CODE UM/MOD
+ MOV @PSP+,W \ 2 W = DIVIDENDhi
+ MOV @PSP,S \ 2 S = DIVIDENDlo
+ MOV #16,X \ 2 INITIALIZE LOOP COUNTER
+BW1 CMP TOS,W \ 1 dividendHI-divisor
+ U< ?GOTO FW1 \ 2 if not carry
+ SUB TOS,W \ 1 if carry
+FW1 \ FW1 is resolved therefore reusable
+BW2 ADDC Y,Y \ 1 RLC quotient
+ SUB #1,X \ 1 Decrement loop counter
+ 0< ?GOTO FW1 \ 2 if 0< terminate
+ ADD S,S \ 1 RLA
+ ADDC W,W \ 1 RLC
+ U< ?GOTO BW1 \ 2 if not carry 14~ loop
+ SUB TOS,W \ 1
+ BIS #1,SR \ 1 SETC
+ GOTO BW2 \ 2 14~ loop
+FW1 MOV W,0(PSP) \ 3 remainder on stack
+ MOV Y,TOS \ 1 quotient in TOS
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE SM/REM \ d1lo d1hi n2 -- n3 n4 symmetric signed div
+MOV TOS,S \ S=divisor
+MOV @PSP,T \ T=dividend_sign=rem_sign
+CMP #0,TOS \ n2 >= 0 ?
+S< IF \
+ XOR #-1,TOS
+ ADD #1,TOS \ -- d1 u2
+THEN
+CMP #0,0(PSP) \ d1hi >= 0 ?
+S< IF \
+ XOR #-1,2(PSP) \ d1lo
+ XOR #-1,0(PSP) \ d1hi
+ ADD #1,2(PSP) \ d1lo+1
+ ADDC #0,0(PSP) \ d1hi+C
+THEN \ -- ud1 u2
+PUSHM IP,S \
+LO2HI \
+UM/MOD \ UM/MOD use S,W,X,Y, not T
+HI2LO \ -- u3 u4
+POPM S,IP \
+CMP #0,T \ T=rem_sign
+S< IF
+ XOR #-1,0(PSP)
+ ADD #1,0(PSP)
+THEN
+XOR S,T \ S=divisor T=quot_sign
+CMP #0,T \ -- n3 u4 T=quot_sign
+S< IF
+ XOR #-1,TOS
+ ADD #1,TOS
+THEN \ -- n3 n4 S=divisor
+MOV @IP+,PC
+ENDCODE
+ \
+
+
+: FM/MOD \ d1 n2 -- n3 n4 floored signed div
+SM/REM
+HI2LO \ -- remainder quotient S=divisor
+CMP #0,0(PSP) \ remainder <> 0 ?
+0<> IF
+ CMP #1,TOS \ quotient < 1 ?
+ S< IF
+ ADD S,0(PSP) \ add divisor to remainder
+ SUB #1,TOS \ decrement quotient
+ THEN
+THEN
+MOV @RSP+,IP
+MOV @IP+,PC
+ENDCODE
+ \
+
+: * \ n1 n2 -- n3 n1*n2 --> n3
+M* DROP
+;
+ \
+
+: /MOD \ n1 n2 -- n3 n4 n1/n2 --> rem quot
+>R DUP 0< R> FM/MOD
+;
+ \
+
+: / \ n1 n2 -- n3 n1/n2 --> quot
+>R DUP 0< R> FM/MOD NIP
+;
+ \
+
+: MOD \ n1 n2 -- n3 n1/n2 --> rem
+>R DUP 0< R> FM/MOD DROP
+;
+ \
+
+: */MOD \ n1 n2 n3 -- n4 n5 n1*n2/n3 --> rem quot
+>R M* R> FM/MOD
+;
+ \
+
+: */ \ n1 n2 n3 -- n4 n1*n2/n3 --> quot
+>R M* R> FM/MOD NIP
+;
+ \
+
+\ ----------------------------------------------------------------------
+\ DOUBLE OPERATORS
+\ ----------------------------------------------------------------------
+
+CODE 2@ \ a-addr -- x1 x2 fetch 2 cells \ the lower address will appear on top of stack
+SUB #2, PSP
+MOV 2(TOS),0(PSP)
+MOV @TOS,TOS
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE 2! \ x1 x2 a-addr -- store 2 cells \ the top of stack is stored at the lower adr
+MOV @PSP+,0(TOS)
+MOV @PSP+,2(TOS)
+MOV @PSP+,TOS
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE 2DUP \ x1 x2 -- x1 x2 x1 x2 dup top 2 cells
+SUB #4,PSP \ -- x1 x x x2
+MOV TOS,2(PSP) \ -- x1 x2 x x2
+MOV 4(PSP),0(PSP) \ -- x1 x2 x1 x2
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE 2DROP \ x1 x2 -- drop 2 cells
+ADD #2,PSP
+MOV @PSP+,TOS
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE 2SWAP \ x1 x2 x3 x4 -- x3 x4 x1 x2
+MOV @PSP,W \ -- x1 x2 x3 x4 W=x3
+MOV 4(PSP),0(PSP) \ -- x1 x2 x1 x4
+MOV W,4(PSP) \ -- x3 x2 x1 x4
+MOV TOS,W \ -- x3 x2 x1 x4 W=x4
+MOV 2(PSP),TOS \ -- x3 x2 x1 x2 W=x4
+MOV W,2(PSP) \ -- x3 x4 x1 x2
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE 2OVER \ x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2
+SUB #4,PSP \ -- x1 x2 x3 x x x4
+MOV TOS,2(PSP) \ -- x1 x2 x3 x4 x x4
+MOV 8(PSP),0(PSP) \ -- x1 x2 x3 x4 x1 x4
+MOV 6(PSP),TOS \ -- x1 x2 x3 x4 x1 x2
+MOV @IP+,PC
+ENDCODE
+ \
+
+
+\ ----------------------------------------------------------------------
+\ ALIGNMENT OPERATORS
+\ ----------------------------------------------------------------------
+
+CODE ALIGNED \ addr -- a-addr align given addr
+BIT #1,TOS
+ADDC #0,TOS
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE ALIGN \ -- align HERE
+BIT #1,&DP \ 3
+ADDC #0,&DP \ 4
+MOV @IP+,PC
+ENDCODE
+ \
+
+\ ---------------------
+\ PORTABILITY OPERATORS
+\ ---------------------
+
+CODE CHARS \ n1 -- n2 chars->adrs units
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE CHAR+ \ c-addr1 -- c-addr2 add char size
+ADD #1,TOS
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE CELLS \ n1 -- n2 cells->adrs units
+ADD TOS,TOS
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE CELL+ \ a-addr1 -- a-addr2 add cell size
+ADD #2,TOS
+MOV @IP+,PC
+ENDCODE
+ \
+\ ---------------------------
+\ BLOCK AND STRING COMPLEMENT
+\ ---------------------------
+
+: CHAR \ -- char parse ASCII character
+ BL WORD 1+ C@
+;
+
+: [CHAR] \ -- compile character literal
+ CHAR lit lit , ,
+; IMMEDIATE
+
+ \
+
+
+CODE +! \ n/u a-addr -- add to memory
+ADD @PSP+,0(TOS)
+MOV @PSP+,TOS
+MOV @IP+,PC
+ENDCODE
+ \
+
+
+CODE FILL \ c-addr u char -- fill memory with char
+MOV @PSP+,X \ count
+MOV @PSP+,W \ address
+CMP #0,X
+0<> IF
+ BEGIN
+ MOV.B TOS,0(W) \ store char in memory
+ ADD #1,W
+ SUB #1,X
+ 0= UNTIL
+THEN
+MOV @PSP+,TOS \ empties stack
+MOV @IP+,PC
+ENDCODE
+ \
+
+\ --------------------
+\ INTERPRET COMPLEMENT
+\ --------------------
+
+CODE HEX
+MOV #$10,&BASE
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE DECIMAL
+MOV #$0A,&BASE
+MOV @IP+,PC
+ENDCODE
+ \
+: ( \
+$29 WORD DROP
+; IMMEDIATE
+ \
+
+: .( \ -- dotparen \ type comment immediatly.
+\ CAPS_OFF \ -- set CAPS_OFF (recompile FORTH with LOWERCASE swith ON before, must be paired with set CAP_ON)
+$29 WORD
+COUNT TYPE
+\ CAPS_ON \ -- set CAPS_OFF (recompile FORTH with LOWERCASE swith ON before, must be paired with set CAP_ON)
+; IMMEDIATE
+ \
+
+CODE SOURCE \ -- adr u current input buffer
+SUB #4,PSP
+MOV TOS,2(PSP)
+MOV &SOURCE_LEN,TOS
+MOV &SOURCE_ADR,0(PSP)
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE >BODY
+ADD #4,TOS
+MOV @IP+,PC
+ENDCODE
+ \
+
+ECHO
+ ; added ANS_COMPLEMENT: INVERT LSHIFT RSHIFT 1+ 1- MAX MIN 2* 2/ CHAR [CHAR] +! FILL HEX DECIMAL ( .( SOURCE >BODY
+ ; ARITHMETIC: NIP S>D UM* M* UM/MOD SM/REM FM/MOD * /MOD / MOD */MOD */
+ ; DOUBLE: 2@ 2! 2DUP 2DROP 2SWAP 2OVER
+ ; ALIGMENT: ALIGNED ALIGN
+ ; PORTABIITY: CHARS CHAR+ CELLS CELL+
+ \
+PWR_HERE ; to protect this app against a RESET, type: RST_HERE
--- /dev/null
+; ----------------------------------------------------------------------------------
+; ANS complement for MSP430FR4xxx devices without hardware_MPY, to pass CORETEST.4th
+; ----------------------------------------------------------------------------------
+
+\ REGISTERS USAGE
+\ R4 to R7 must be saved before use and restored after
+\ scratch registers Y to S are free for use
+\ under interrupt, IP is free for use
+
+\ PUSHM order : PSP,TOS, IP, S, T, W, X, Y, R7, R6, R5, R4
+\ example : PUSHM IP,Y
+\
+\ POPM order : R4, R5, R6, R7, Y, X, W, T, S, IP,TOS,PSP
+\ example : POPM Y,IP
+
+\ ASSEMBLER conditionnal usage before IF UNTIL WHILE : S< S>= U< U>= 0= 0<> 0>=
+\ ASSEMBLER conditionnal usage before ?JMP ?GOTO : S< S>= U< U>= 0= 0<> 0<
+
+\ FORTH conditionnal usage before IF UNTIL WHILE : 0= 0< = < > U<
+
+
+
+\ ECHO ; if an error occurs, uncomment this line before new download to find it.
+ \
+
+CODE INVERT \ x1 -- x2 bitwise inversion
+ XOR #-1,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LSHIFT \ x1 u -- x2 logical L shift u places
+ MOV @PSP+,W
+ AND #$1F,TOS \ no need to shift more than 16
+0<> IF
+ BEGIN ADD W,W
+ SUB #1,TOS
+ 0= UNTIL
+THEN MOV W,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE RSHIFT \ x1 u -- x2 logical R shift u places
+ MOV @PSP+,W
+ AND #$1F,TOS \ no need to shift more than 16
+0<> IF
+ BEGIN BIC #C,SR \ Clr Carry
+ RRC W
+ SUB #1,TOS
+ 0= UNTIL
+THEN MOV W,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE 1+ \ n1/u1 -- n2/u2 add 1 to TOS
+ ADD #1,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE 1- \ n1/u1 -- n2/u2 subtract 1 from TOS
+ SUB #1,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE 2* \ x1 -- x2 arithmetic left shift
+ ADD TOS,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE 2/ \ x1 -- x2 arithmetic right shift
+ RRA TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+\ --------------------
+\ ARITHMETIC OPERATORS
+\ --------------------
+
+CODE NIP \ a b c -- a c
+ADD #2,PSP
+MOV @IP+,PC
+ENDCODE
+ \
+
+: S>D \ n -- d single -> double
+ DUP 0<
+;
+ \
+
+\ \ C UM* u1 u2 -- ud unsigned 16x16->32 mult.
+\ CODE UM*
+\ MOV @PSP,S
+\ \ u2 = TOS register
+\ \ MULTIPLIERl = S
+\ \ MULTIPLIERh = W
+\ \ BIT = X
+\ \ RESULTlo = Y
+\ \ RESULThi = T
+\ \ T.I. SIGNED MULTIPLY SUBROUTINE: u2 x u1 -> ud
+\ MOV #0,Y \ 0 -> LSBs RESULT
+\ MOV #0,T \ 0 -> MSBs RESULT
+\ MOV #0,W \ 0 -> MSBs MULTIPLIER
+\ MOV #1,X \ BIT TEST REGISTER
+\ BEGIN BIT X,TOS \ 1 TEST ACTUAL BIT ; IF 0: DO NOTHING
+\ 0<> IF \ 2 IF 1: ADD MULTIPLIER TO RESULT
+\ ADD S,Y \ 1
+\ ADDC W,T \ 1
+\ THEN ADD S,S \ 1 (RLA LSBs) MULTIPLIER x 2
+\ ADDC W,W \ 1 (RLC MSBs)
+\ ADD X,X \ 1 (RLA) NEXT BIT TO TEST
+\ U>= UNTIL \ 2 IF BIT IN CARRY: FINISHED 10~ loop
+\ MOV Y,0(PSP) \ low result on stack
+\ MOV T,TOS \ high result in TOS
+\ MOV @IP+,PC
+\ ENDCODE
+\ \
+
+CODE M* \ n1 n2 -- dlo dhi signed 16*16->32 multiply
+MOV TOS,S \ TOS= n2
+XOR @PSP,S \ S contains sign of result
+CMP #0,0(PSP) \ n1 > -1 ?
+S< IF
+ XOR #-1,0(PSP) \ n1 --> u1
+ ADD #1,0(PSP) \
+THEN
+CMP #0,TOS \ n2 > -1 ?
+S< IF
+ XOR #-1,TOS \ n2 --> u2
+ ADD #1,TOS \
+THEN
+PUSHM IP,S
+LO2HI \ -- ud1 u2
+UM* \ UMSTAR use S,T,W,X,Y
+HI2LO
+POPM S,IP
+CMP #0,S \ sign of result > -1 ?
+S< IF
+ XOR #-1,0(PSP) \ ud --> d
+ XOR #-1,TOS
+ ADD #1,0(PSP)
+ ADDC #0,TOS
+THEN
+MOV @IP+,PC
+ENDCODE
+ \
+
+\ TOS = DIVISOR
+\ S = DIVIDENDlo
+\ W = DIVIDENDhi
+\ X = count
+\ Y = QUOTIENT
+\ DVDhi|DVDlo : DIVISOR -> QUOT in Y, REM in DVDhi
+\ RETURN: CARRY = 0: OK CARRY = 1: QUOTIENT > 16 BITS
+
+\ C UM/MOD udlo|udhi u1 -- ur uq
+CODE UM/MOD
+ MOV @PSP+,W \ 2 W = DIVIDENDhi
+ MOV @PSP,S \ 2 S = DIVIDENDlo
+ MOV #16,X \ 2 INITIALIZE LOOP COUNTER
+BW1 CMP TOS,W \ 1 dividendHI-divisor
+ U< ?GOTO FW1 \ 2 if not carry
+ SUB TOS,W \ 1 if carry
+FW1 \ FW1 is resolved therefore reusable
+BW2 ADDC Y,Y \ 1 RLC quotient
+ SUB #1,X \ 1 Decrement loop counter
+ 0< ?GOTO FW1 \ 2 if 0< terminate
+ ADD S,S \ 1 RLA
+ ADDC W,W \ 1 RLC
+ U< ?GOTO BW1 \ 2 if not carry 14~ loop
+ SUB TOS,W \ 1
+ BIS #1,SR \ 1 SETC
+ GOTO BW2 \ 2 14~ loop
+FW1 MOV W,0(PSP) \ 3 remainder on stack
+ MOV Y,TOS \ 1 quotient in TOS
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE SM/REM \ d1lo d1hi n2 -- n3 n4 symmetric signed div
+MOV TOS,S \ S=divisor
+MOV @PSP,T \ T=dividend_sign=rem_sign
+CMP #0,TOS \ n2 >= 0 ?
+S< IF \
+ XOR #-1,TOS
+ ADD #1,TOS \ -- d1 u2
+THEN
+CMP #0,0(PSP) \ d1hi >= 0 ?
+S< IF \
+ XOR #-1,2(PSP) \ d1lo
+ XOR #-1,0(PSP) \ d1hi
+ ADD #1,2(PSP) \ d1lo+1
+ ADDC #0,0(PSP) \ d1hi+C
+THEN
+PUSHM IP,S
+LO2HI \ -- ud1 u2
+UM/MOD \ UM/MOD use S,W,X,Y, not T
+HI2LO \ -- u3 u4
+POPM S,IP
+CMP #0,T \ T=rem_sign
+S< IF
+ XOR #-1,0(PSP)
+ ADD #1,0(PSP)
+THEN \ -- n3 u4
+XOR S,T \ S=divisor T=quot_sign
+CMP #0,T \ T=quot_sign
+S< IF
+ XOR #-1,TOS
+ ADD #1,TOS
+THEN \ -- n3 n4 S=divisor
+MOV @IP+,PC
+ENDCODE
+ \
+
+
+: FM/MOD \ d1 n1 -- n2 n3 floored signed div'n
+SM/REM
+HI2LO \ -- remainder quotient S=divisor
+CMP #0,0(PSP) \
+0<> IF
+ CMP #1,TOS \ quotient < 1 ?
+ S< IF
+ ADD S,0(PSP) \ add divisor to remainder
+ SUB #1,TOS \ decrement quotient
+ THEN
+THEN
+MOV @RSP+,IP
+MOV @IP+,PC
+ENDCODE
+ \
+
+: * \ n1 n2 -- n3 n1*n2 --> n3
+M* DROP
+;
+ \
+
+: /MOD \ n1 n2 -- n3 n4 n1/n2 --> rem quot
+>R DUP 0< R> FM/MOD
+;
+ \
+
+: / \ n1 n2 -- n3 n1/n2 --> quot
+>R DUP 0< R> FM/MOD NIP
+;
+ \
+
+: MOD \ n1 n2 -- n3 n1/n2 --> rem
+>R DUP 0< R> FM/MOD DROP
+;
+ \
+
+: */MOD \ n1 n2 n3 -- n4 n5 n1*n2/n3 --> rem quot
+>R M* R> FM/MOD
+;
+ \
+
+: */ \ n1 n2 n3 -- n4 n1*n2/n3 --> quot
+>R M* R> FM/MOD NIP
+;
+ \
+
+\ ----------------------------------------------------------------------
+\ DOUBLE OPERATORS
+\ ----------------------------------------------------------------------
+
+CODE 2@ \ a-addr -- x1 x2 fetch 2 cells \ the lower address will appear on top of stack
+SUB #2, PSP
+MOV 2(TOS),0(PSP)
+MOV @TOS,TOS
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE 2! \ x1 x2 a-addr -- store 2 cells \ the top of stack is stored at the lower adr
+MOV @PSP+,0(TOS)
+MOV @PSP+,2(TOS)
+MOV @PSP+,TOS
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE 2DUP \ x1 x2 -- x1 x2 x1 x2 dup top 2 cells
+SUB #4,PSP \ -- x1 x x x2
+MOV TOS,2(PSP) \ -- x1 x2 x x2
+MOV 4(PSP),0(PSP) \ -- x1 x2 x1 x2
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE 2DROP \ x1 x2 -- drop 2 cells
+ADD #2,PSP
+MOV @PSP+,TOS
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE 2SWAP \ x1 x2 x3 x4 -- x3 x4 x1 x2
+MOV @PSP,W \ -- x1 x2 x3 x4 W=x3
+MOV 4(PSP),0(PSP) \ -- x1 x2 x1 x4
+MOV W,4(PSP) \ -- x3 x2 x1 x4
+MOV TOS,W \ -- x3 x2 x1 x4 W=x4
+MOV 2(PSP),TOS \ -- x3 x2 x1 x2 W=x4
+MOV W,2(PSP) \ -- x3 x4 x1 x2
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE 2OVER \ x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2
+SUB #4,PSP \ -- x1 x2 x3 x x x4
+MOV TOS,2(PSP) \ -- x1 x2 x3 x4 x x4
+MOV 8(PSP),0(PSP) \ -- x1 x2 x3 x4 x1 x4
+MOV 6(PSP),TOS \ -- x1 x2 x3 x4 x1 x2
+MOV @IP+,PC
+ENDCODE
+ \
+
+
+\ ----------------------------------------------------------------------
+\ ALIGNMENT OPERATORS
+\ ----------------------------------------------------------------------
+
+CODE ALIGNED \ addr -- a-addr align given addr
+BIT #1,TOS
+ADDC #0,TOS
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE ALIGN \ -- align HERE
+BIT #1,&DP \ 3
+ADDC #0,&DP \ 4
+MOV @IP+,PC
+ENDCODE
+ \
+
+\ ---------------------
+\ PORTABILITY OPERATORS
+\ ---------------------
+
+CODE CHARS \ n1 -- n2 chars->adrs units
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE CHAR+ \ c-addr1 -- c-addr2 add char size
+ADD #1,TOS
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE CELLS \ n1 -- n2 cells->adrs units
+ADD TOS,TOS
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE CELL+ \ a-addr1 -- a-addr2 add cell size
+ADD #2,TOS
+MOV @IP+,PC
+ENDCODE
+ \
+\ ---------------------------
+\ BLOCK AND STRING COMPLEMENT
+\ ---------------------------
+
+: CHAR \ -- char parse ASCII character
+ BL WORD 1+ C@
+;
+ \
+
+: [CHAR] \ -- compile character literal
+ CHAR lit lit , ,
+; IMMEDIATE
+ \
+
+CODE +! \ n/u a-addr -- add to memory
+ADD @PSP+,0(TOS)
+MOV @PSP+,TOS
+MOV @IP+,PC
+ENDCODE
+ \
+
+
+CODE FILL \ c-addr u char -- fill memory with char
+MOV @PSP+,X \ count
+MOV @PSP+,W \ address
+CMP #0,X
+0<> IF
+ BEGIN
+ MOV.B TOS,0(W) \ store char in memory
+ ADD #1,W
+ SUB #1,X
+ 0= UNTIL
+THEN
+MOV @PSP+,TOS \ empties stack
+MOV @IP+,PC
+ENDCODE
+ \
+
+\ --------------------
+\ INTERPRET COMPLEMENT
+\ --------------------
+
+CODE HEX
+MOV #$10,&BASE
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE DECIMAL
+MOV #$0A,&BASE
+MOV @IP+,PC
+ENDCODE
+ \
+: ( \
+$29 WORD DROP
+; IMMEDIATE
+ \
+
+: .( \ -- dotparen \ type comment immediatly.
+\ CAPS_OFF \ -- set CAPS_OFF (recompile FORTH with LOWERCASE swith ON before, must be paired with set CAP_ON)
+$29 WORD
+COUNT TYPE
+\ CAPS_ON \ -- set CAPS_OFF (recompile FORTH with LOWERCASE swith ON before, must be paired with set CAP_ON)
+; IMMEDIATE
+ \
+
+CODE SOURCE \ -- adr u current input buffer
+SUB #4,PSP
+MOV TOS,2(PSP)
+MOV &SOURCE_LEN,TOS
+MOV &SOURCE_ADR,0(PSP)
+MOV @IP+,PC
+ENDCODE
+ \
+
+CODE >BODY
+ADD #4,TOS
+MOV @IP+,PC
+ENDCODE
+ \
+
+ECHO
+PWR_HERE ; to protect this app against a RESET, type: RST_HERE
+
+ ; added : INVERT LSHIFT RSHIFT 1+ 1- MAX MIN 2* 2/ CHAR [CHAR] +! FILL HEX DECIMAL ( .( SOURCE >BODY
+ ; added ARITHMETIC : NIP S>D M* UM/MOD SM/REM FM/MOD * /MOD / MOD */MOD */
+ ; added DOUBLE : 2@ 2! 2DUP 2DROP 2SWAP 2OVER
+ ; added ALIGMENT : ALIGNED ALIGN
+ ; added PORTABIITY : CHARS CHAR+ CELLS CELL+
--- /dev/null
+; ------------------------
+; file name : coretest.4th
+; ------------------------
+
+RST_STATE ; so ANS_COMPLEMENT_xx_MPY is conserved ;
+\ NOECHO ; if an error occurs, comment this line before new download to find it.
+
+
+\ From: John Hayes S1I
+\ Subject: tester.fr
+\ Date: Mon, 27 Nov 95 13:10:09 PST
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.1
+
+\ 22/1/09 The words { and } have been changed to T{ and }T respectively to
+\ agree with the Forth 200X file ttester.fs. This avoids clashes with
+\ locals using { ... } and the FSL use of }
+
+
+\ 13/05/14 jmt. added colorised error messages.
+
+
+
+ 0 CONSTANT FALSE
+-1 CONSTANT TRUE
+
+\ SET THE FOLLOWING FLAG TO TRUE FOR MORE VERBOSE OUTPUT; THIS MAY
+\ ALLOW YOU TO TELL WHICH TEST CAUSED YOUR SYSTEM TO HANG.
+VARIABLE VERBOSE
+ FALSE VERBOSE !
+\ TRUE VERBOSE !
+
+\ : EMPTY-STACK ( ... -- ) \ EMPTY STACK: HANDLES UNDERFLOWED STACK TOO.
+\ DEPTH ?DUP
+\ IF DUP 0< IF NEGATE 0
+\ DO 0 LOOP
+\ ELSE 0 DO DROP LOOP THEN
+\ THEN ;
+\
+\ : ERROR \ ( C-ADDR U -- ) DISPLAY AN ERROR MESSAGE FOLLOWED BY
+\ \ THE LINE THAT HAD THE ERROR.
+\ TYPE SOURCE TYPE CR \ DISPLAY LINE CORRESPONDING TO ERROR
+\ EMPTY-STACK \ THROW AWAY EVERY THING ELSE
+\ QUIT \ *** Uncomment this line to QUIT on an error
+\ ;
+
+VARIABLE ACTUAL-DEPTH \ STACK RECORD
+CREATE ACTUAL-RESULTS 20 CELLS ALLOT
+
+: T{ \ ( -- ) SYNTACTIC SUGAR.
+ ;
+
+: -> \ ( ... -- ) RECORD DEPTH AND CONTENT OF STACK.
+ DEPTH DUP ACTUAL-DEPTH ! \ RECORD DEPTH
+ ?DUP IF \ IF THERE IS SOMETHING ON STACK
+ 0 DO ACTUAL-RESULTS I CELLS + ! LOOP \ SAVE THEM
+ THEN ;
+
+: }T \ ( ... -- ) COMPARE STACK (EXPECTED) CONTENTS WITH SAVED
+ \ (ACTUAL) CONTENTS.
+ DEPTH ACTUAL-DEPTH @ = IF \ IF DEPTHS MATCH
+ DEPTH ?DUP IF \ IF THERE IS SOMETHING ON THE STACK
+ 0 DO \ FOR EACH STACK ITEM
+ ACTUAL-RESULTS I CELLS + @ \ COMPARE ACTUAL WITH EXPECTED
+\ = 0= IF S" INCORRECT RESULT: " ERROR LEAVE THEN \ jmt
+ = 0= IF ABORT" INCORRECT RESULT: " THEN \ jmt : colorised message
+ LOOP
+ THEN
+ ELSE \ DEPTH MISMATCH
+\ S" WRONG NUMBER OF RESULTS: " ERROR \ jmt
+ ABORT" WRONG NUMBER OF RESULTS: " \ jmt : colorised message
+ THEN ;
+
+: TESTING \ ( -- ) TALKING COMMENT.
+ SOURCE VERBOSE @
+ IF DUP >R TYPE CR R> >IN !
+ ELSE >IN ! DROP [CHAR] * EMIT
+ THEN ;
+
+\ From: John Hayes S1I
+\ Subject: core.fr
+\ Date: Mon, 27 Nov 95 13:10
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.2
+\ THIS PROGRAM TESTS THE CORE WORDS OF AN ANS FORTH SYSTEM.
+\ THE PROGRAM ASSUMES A TWO'S COMPLEMENT IMPLEMENTATION WHERE
+\ THE RANGE OF SIGNED NUMBERS IS -2^(N-1) ... 2^(N-1)-1 AND
+\ THE RANGE OF UNSIGNED NUMBERS IS 0 ... 2^(N)-1.
+\ I HAVEN'T FIGURED OUT HOW TO TEST KEY, QUIT, ABORT, OR ABORT"...
+\ I ALSO HAVEN'T THOUGHT OF A WAY TO TEST ENVIRONMENT?...
+
+CR
+TESTING CORE WORDS
+HEX
+
+\ ------------------------------------------------------------------------
+TESTING BASIC ASSUMPTIONS
+
+T{ -> }T \ START WITH CLEAN SLATE
+( TEST IF ANY BITS ARE SET; ANSWER IN BASE 1 )
+T{ : BITSSET? IF 0 0 ELSE 0 THEN ; -> }T
+T{ 0 BITSSET? -> 0 }T ( ZERO IS ALL BITS CLEAR )
+T{ 1 BITSSET? -> 0 0 }T ( OTHER NUMBER HAVE AT LEAST ONE BIT )
+T{ -1 BITSSET? -> 0 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING BOOLEANS: INVERT AND OR XOR
+
+T{ 0 0 AND -> 0 }T
+T{ 0 1 AND -> 0 }T
+T{ 1 0 AND -> 0 }T
+T{ 1 1 AND -> 1 }T
+
+T{ 0 INVERT 1 AND -> 1 }T
+T{ 1 INVERT 1 AND -> 0 }T
+
+0 CONSTANT 0S
+0 INVERT CONSTANT 1S
+
+T{ 0S INVERT -> 1S }T
+T{ 1S INVERT -> 0S }T
+
+T{ 0S 0S AND -> 0S }T
+T{ 0S 1S AND -> 0S }T
+T{ 1S 0S AND -> 0S }T
+T{ 1S 1S AND -> 1S }T
+
+T{ 0S 0S OR -> 0S }T
+T{ 0S 1S OR -> 1S }T
+T{ 1S 0S OR -> 1S }T
+T{ 1S 1S OR -> 1S }T
+
+T{ 0S 0S XOR -> 0S }T
+T{ 0S 1S XOR -> 1S }T
+T{ 1S 0S XOR -> 1S }T
+T{ 1S 1S XOR -> 0S }T
+
+\ ------------------------------------------------------------------------
+TESTING 2* 2/ LSHIFT RSHIFT
+
+( WE TRUST 1S, INVERT, AND BITSSET?; WE WILL CONFIRM RSHIFT LATER )
+1S 1 RSHIFT INVERT CONSTANT MSB
+T{ MSB BITSSET? -> 0 0 }T
+
+T{ 0S 2* -> 0S }T
+T{ 1 2* -> 2 }T
+T{ 4000 2* -> 8000 }T
+T{ 1S 2* 1 XOR -> 1S }T
+T{ MSB 2* -> 0S }T
+
+T{ 0S 2/ -> 0S }T
+T{ 1 2/ -> 0 }T
+T{ 4000 2/ -> 2000 }T
+T{ 1S 2/ -> 1S }T \ MSB PROPOGATED
+T{ 1S 1 XOR 2/ -> 1S }T
+T{ MSB 2/ MSB AND -> MSB }T
+
+T{ 1 0 LSHIFT -> 1 }T
+T{ 1 1 LSHIFT -> 2 }T
+T{ 1 2 LSHIFT -> 4 }T
+T{ 1 F LSHIFT -> 8000 }T \ BIGGEST GUARANTEED SHIFT
+T{ 1S 1 LSHIFT 1 XOR -> 1S }T
+T{ MSB 1 LSHIFT -> 0 }T
+
+T{ 1 0 RSHIFT -> 1 }T
+T{ 1 1 RSHIFT -> 0 }T
+T{ 2 1 RSHIFT -> 1 }T
+T{ 4 2 RSHIFT -> 1 }T
+T{ 8000 F RSHIFT -> 1 }T \ BIGGEST
+T{ MSB 1 RSHIFT MSB AND -> 0 }T \ RSHIFT ZERO FILLS MSBS
+T{ MSB 1 RSHIFT 2* -> MSB }T
+
+\ ------------------------------------------------------------------------
+TESTING COMPARISONS: 0= = 0< < > U< MIN MAX
+0 INVERT CONSTANT MAX-UINT
+0 INVERT 1 RSHIFT CONSTANT MAX-INT
+0 INVERT 1 RSHIFT INVERT CONSTANT MIN-INT
+0 INVERT 1 RSHIFT CONSTANT MID-UINT
+0 INVERT 1 RSHIFT INVERT CONSTANT MID-UINT+1
+
+0S CONSTANT <FALSE>
+1S CONSTANT <TRUE>
+
+T{ 0 0= -> <TRUE> }T
+T{ 1 0= -> <FALSE> }T
+T{ 2 0= -> <FALSE> }T
+T{ -1 0= -> <FALSE> }T
+T{ MAX-UINT 0= -> <FALSE> }T
+T{ MIN-INT 0= -> <FALSE> }T
+T{ MAX-INT 0= -> <FALSE> }T
+
+T{ 0 0 = -> <TRUE> }T
+T{ 1 1 = -> <TRUE> }T
+T{ -1 -1 = -> <TRUE> }T
+T{ 1 0 = -> <FALSE> }T
+T{ -1 0 = -> <FALSE> }T
+T{ 0 1 = -> <FALSE> }T
+T{ 0 -1 = -> <FALSE> }T
+
+T{ 0 0< -> <FALSE> }T
+T{ -1 0< -> <TRUE> }T
+T{ MIN-INT 0< -> <TRUE> }T
+T{ 1 0< -> <FALSE> }T
+T{ MAX-INT 0< -> <FALSE> }T
+
+T{ 0 1 < -> <TRUE> }T
+T{ 1 2 < -> <TRUE> }T
+T{ -1 0 < -> <TRUE> }T
+T{ -1 1 < -> <TRUE> }T
+T{ MIN-INT 0 < -> <TRUE> }T
+T{ MIN-INT MAX-INT < -> <TRUE> }T
+T{ 0 MAX-INT < -> <TRUE> }T
+T{ 0 0 < -> <FALSE> }T
+T{ 1 1 < -> <FALSE> }T
+T{ 1 0 < -> <FALSE> }T
+T{ 2 1 < -> <FALSE> }T
+T{ 0 -1 < -> <FALSE> }T
+T{ 1 -1 < -> <FALSE> }T
+T{ 0 MIN-INT < -> <FALSE> }T
+T{ MAX-INT MIN-INT < -> <FALSE> }T
+T{ MAX-INT 0 < -> <FALSE> }T
+
+T{ 0 1 > -> <FALSE> }T
+T{ 1 2 > -> <FALSE> }T
+T{ -1 0 > -> <FALSE> }T
+T{ -1 1 > -> <FALSE> }T
+T{ MIN-INT 0 > -> <FALSE> }T
+T{ MIN-INT MAX-INT > -> <FALSE> }T
+T{ 0 MAX-INT > -> <FALSE> }T
+T{ 0 0 > -> <FALSE> }T
+T{ 1 1 > -> <FALSE> }T
+T{ 1 0 > -> <TRUE> }T
+T{ 2 1 > -> <TRUE> }T
+T{ 0 -1 > -> <TRUE> }T
+T{ 1 -1 > -> <TRUE> }T
+T{ 0 MIN-INT > -> <TRUE> }T
+T{ MAX-INT MIN-INT > -> <TRUE> }T
+T{ MAX-INT 0 > -> <TRUE> }T
+
+T{ 0 1 U< -> <TRUE> }T
+T{ 1 2 U< -> <TRUE> }T
+T{ 0 MID-UINT U< -> <TRUE> }T
+T{ 0 MAX-UINT U< -> <TRUE> }T
+T{ MID-UINT MAX-UINT U< -> <TRUE> }T
+T{ 0 0 U< -> <FALSE> }T
+T{ 1 1 U< -> <FALSE> }T
+T{ 1 0 U< -> <FALSE> }T
+T{ 2 1 U< -> <FALSE> }T
+T{ MID-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT MID-UINT U< -> <FALSE> }T
+
+T{ 0 1 MIN -> 0 }T
+T{ 1 2 MIN -> 1 }T
+T{ -1 0 MIN -> -1 }T
+T{ -1 1 MIN -> -1 }T
+T{ MIN-INT 0 MIN -> MIN-INT }T
+T{ MIN-INT MAX-INT MIN -> MIN-INT }T
+T{ 0 MAX-INT MIN -> 0 }T
+T{ 0 0 MIN -> 0 }T
+T{ 1 1 MIN -> 1 }T
+T{ 1 0 MIN -> 0 }T
+T{ 2 1 MIN -> 1 }T
+T{ 0 -1 MIN -> -1 }T
+T{ 1 -1 MIN -> -1 }T
+T{ 0 MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT 0 MIN -> 0 }T
+
+T{ 0 1 MAX -> 1 }T
+T{ 1 2 MAX -> 2 }T
+T{ -1 0 MAX -> 0 }T
+T{ -1 1 MAX -> 1 }T
+T{ MIN-INT 0 MAX -> 0 }T
+T{ MIN-INT MAX-INT MAX -> MAX-INT }T
+T{ 0 MAX-INT MAX -> MAX-INT }T
+T{ 0 0 MAX -> 0 }T
+T{ 1 1 MAX -> 1 }T
+T{ 1 0 MAX -> 1 }T
+T{ 2 1 MAX -> 2 }T
+T{ 0 -1 MAX -> 0 }T
+T{ 1 -1 MAX -> 1 }T
+T{ 0 MIN-INT MAX -> 0 }T
+T{ MAX-INT MIN-INT MAX -> MAX-INT }T
+T{ MAX-INT 0 MAX -> MAX-INT }T
+
+\ ------------------------------------------------------------------------
+TESTING STACK OPS: 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP
+
+T{ 1 2 2DROP -> }T
+T{ 1 2 2DUP -> 1 2 1 2 }T
+T{ 1 2 3 4 2OVER -> 1 2 3 4 1 2 }T
+T{ 1 2 3 4 2SWAP -> 3 4 1 2 }T
+T{ 0 ?DUP -> 0 }T
+T{ 1 ?DUP -> 1 1 }T
+T{ -1 ?DUP -> -1 -1 }T
+T{ DEPTH -> 0 }T
+T{ 0 DEPTH -> 0 1 }T
+T{ 0 1 DEPTH -> 0 1 2 }T
+T{ 0 DROP -> }T
+T{ 1 2 DROP -> 1 }T
+T{ 1 DUP -> 1 1 }T
+T{ 1 2 OVER -> 1 2 1 }T
+T{ 1 2 3 ROT -> 2 3 1 }T
+T{ 1 2 SWAP -> 2 1 }T
+
+\ ------------------------------------------------------------------------
+TESTING >R R> R@
+
+T{ : GR1 >R R> ; -> }T
+T{ : GR2 >R R@ R> DROP ; -> }T
+T{ 123 GR1 -> 123 }T
+T{ 123 GR2 -> 123 }T
+T{ 1S GR1 -> 1S }T ( RETURN STACK HOLDS CELLS )
+
+\ ------------------------------------------------------------------------
+TESTING ADD/SUBTRACT: + - 1+ 1- ABS NEGATE
+
+T{ 0 5 + -> 5 }T
+T{ 5 0 + -> 5 }T
+T{ 0 -5 + -> -5 }T
+T{ -5 0 + -> -5 }T
+T{ 1 2 + -> 3 }T
+T{ 1 -2 + -> -1 }T
+T{ -1 2 + -> 1 }T
+T{ -1 -2 + -> -3 }T
+T{ -1 1 + -> 0 }T
+T{ MID-UINT 1 + -> MID-UINT+1 }T
+
+T{ 0 5 - -> -5 }T
+T{ 5 0 - -> 5 }T
+T{ 0 -5 - -> 5 }T
+T{ -5 0 - -> -5 }T
+T{ 1 2 - -> -1 }T
+T{ 1 -2 - -> 3 }T
+T{ -1 2 - -> -3 }T
+T{ -1 -2 - -> 1 }T
+T{ 0 1 - -> -1 }T
+T{ MID-UINT+1 1 - -> MID-UINT }T
+
+T{ 0 1+ -> 1 }T
+T{ -1 1+ -> 0 }T
+T{ 1 1+ -> 2 }T
+T{ MID-UINT 1+ -> MID-UINT+1 }T
+
+T{ 2 1- -> 1 }T
+T{ 1 1- -> 0 }T
+T{ 0 1- -> -1 }T
+T{ MID-UINT+1 1- -> MID-UINT }T
+
+T{ 0 NEGATE -> 0 }T
+T{ 1 NEGATE -> -1 }T
+T{ -1 NEGATE -> 1 }T
+T{ 2 NEGATE -> -2 }T
+T{ -2 NEGATE -> 2 }T
+
+T{ 0 ABS -> 0 }T
+T{ 1 ABS -> 1 }T
+T{ -1 ABS -> 1 }T
+T{ MIN-INT ABS -> MID-UINT+1 }T
+
+\ ------------------------------------------------------------------------
+TESTING MULTIPLY: S>D * M* UM*
+
+T{ 0 S>D -> 0 0 }T
+T{ 1 S>D -> 1 0 }T
+T{ 2 S>D -> 2 0 }T
+T{ -1 S>D -> -1 -1 }T
+T{ -2 S>D -> -2 -1 }T
+T{ MIN-INT S>D -> MIN-INT -1 }T
+T{ MAX-INT S>D -> MAX-INT 0 }T
+
+T{ 0 0 M* -> 0 S>D }T
+T{ 0 1 M* -> 0 S>D }T
+T{ 1 0 M* -> 0 S>D }T
+T{ 1 2 M* -> 2 S>D }T
+T{ 2 1 M* -> 2 S>D }T
+T{ 3 3 M* -> 9 S>D }T
+T{ -3 3 M* -> -9 S>D }T
+T{ 3 -3 M* -> -9 S>D }T
+T{ -3 -3 M* -> 9 S>D }T
+T{ 0 MIN-INT M* -> 0 S>D }T
+T{ 1 MIN-INT M* -> MIN-INT S>D }T
+T{ 2 MIN-INT M* -> 0 1S }T
+T{ 0 MAX-INT M* -> 0 S>D }T
+T{ 1 MAX-INT M* -> MAX-INT S>D }T
+T{ 2 MAX-INT M* -> MAX-INT 1 LSHIFT 0 }T
+T{ MIN-INT MIN-INT M* -> 0 MSB 1 RSHIFT }T
+T{ MAX-INT MIN-INT M* -> MSB MSB 2/ }T
+T{ MAX-INT MAX-INT M* -> 1 MSB 2/ INVERT }T
+
+T{ 0 0 * -> 0 }T \ TEST IDENTITIES
+T{ 0 1 * -> 0 }T
+T{ 1 0 * -> 0 }T
+T{ 1 2 * -> 2 }T
+T{ 2 1 * -> 2 }T
+T{ 3 3 * -> 9 }T
+T{ -3 3 * -> -9 }T
+T{ 3 -3 * -> -9 }T
+T{ -3 -3 * -> 9 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 * -> MID-UINT+1 }T
+T{ MID-UINT+1 2 RSHIFT 4 * -> MID-UINT+1 }T
+T{ MID-UINT+1 1 RSHIFT MID-UINT+1 OR 2 * -> MID-UINT+1 }T
+
+T{ 0 0 UM* -> 0 0 }T
+T{ 0 1 UM* -> 0 0 }T
+T{ 1 0 UM* -> 0 0 }T
+T{ 1 2 UM* -> 2 0 }T
+T{ 2 1 UM* -> 2 0 }T
+T{ 3 3 UM* -> 9 0 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 UM* -> MID-UINT+1 0 }T
+T{ MID-UINT+1 2 UM* -> 0 1 }T
+T{ MID-UINT+1 4 UM* -> 0 2 }T
+T{ 1S 2 UM* -> 1S 1 LSHIFT 1 }T
+T{ MAX-UINT MAX-UINT UM* -> 1 1 INVERT }T
+
+\ ------------------------------------------------------------------------
+TESTING DIVIDE: FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD
+
+T{ 0 S>D 1 FM/MOD -> 0 0 }T
+T{ 1 S>D 1 FM/MOD -> 0 1 }T
+T{ 2 S>D 1 FM/MOD -> 0 2 }T
+T{ -1 S>D 1 FM/MOD -> 0 -1 }T
+T{ -2 S>D 1 FM/MOD -> 0 -2 }T
+T{ 0 S>D -1 FM/MOD -> 0 0 }T
+T{ 1 S>D -1 FM/MOD -> 0 -1 }T
+T{ 2 S>D -1 FM/MOD -> 0 -2 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -1 FM/MOD -> 0 2 }T
+T{ 2 S>D 2 FM/MOD -> 0 1 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -2 FM/MOD -> 0 1 }T
+T{ 7 S>D 3 FM/MOD -> 1 2 }T
+T{ 7 S>D -3 FM/MOD -> -2 -3 }T
+T{ -7 S>D 3 FM/MOD -> 2 -3 }T
+T{ -7 S>D -3 FM/MOD -> -1 2 }T
+T{ MAX-INT S>D 1 FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT FM/MOD -> 0 1 }T
+T{ MIN-INT S>D MIN-INT FM/MOD -> 0 1 }T
+T{ 1S 1 4 FM/MOD -> 3 MAX-INT }T
+T{ 1 MIN-INT M* 1 FM/MOD -> 0 MIN-INT }T
+T{ 1 MIN-INT M* MIN-INT FM/MOD -> 0 1 }T
+T{ 2 MIN-INT M* 2 FM/MOD -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT FM/MOD -> 0 2 }T
+T{ 1 MAX-INT M* 1 FM/MOD -> 0 MAX-INT }T
+T{ 1 MAX-INT M* MAX-INT FM/MOD -> 0 1 }T
+T{ 2 MAX-INT M* 2 FM/MOD -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT FM/MOD -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT FM/MOD -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT FM/MOD -> 0 MAX-INT }T
+
+T{ 0 S>D 1 SM/REM -> 0 0 }T
+T{ 1 S>D 1 SM/REM -> 0 1 }T
+T{ 2 S>D 1 SM/REM -> 0 2 }T
+T{ -1 S>D 1 SM/REM -> 0 -1 }T
+T{ -2 S>D 1 SM/REM -> 0 -2 }T
+T{ 0 S>D -1 SM/REM -> 0 0 }T
+T{ 1 S>D -1 SM/REM -> 0 -1 }T
+T{ 2 S>D -1 SM/REM -> 0 -2 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -1 SM/REM -> 0 2 }T
+T{ 2 S>D 2 SM/REM -> 0 1 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -2 SM/REM -> 0 1 }T
+T{ 7 S>D 3 SM/REM -> 1 2 }T
+T{ 7 S>D -3 SM/REM -> 1 -2 }T
+T{ -7 S>D 3 SM/REM -> -1 -2 }T
+T{ -7 S>D -3 SM/REM -> -1 2 }T
+T{ MAX-INT S>D 1 SM/REM -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 SM/REM -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT SM/REM -> 0 1 }T
+T{ MIN-INT S>D MIN-INT SM/REM -> 0 1 }T
+T{ 1S 1 4 SM/REM -> 3 MAX-INT }T
+T{ 2 MIN-INT M* 2 SM/REM -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT SM/REM -> 0 2 }T
+T{ 2 MAX-INT M* 2 SM/REM -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT SM/REM -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT SM/REM -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT SM/REM -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT SM/REM -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT SM/REM -> 0 MAX-INT }T
+
+T{ 0 0 1 UM/MOD -> 0 0 }T
+T{ 1 0 1 UM/MOD -> 0 1 }T
+T{ 1 0 2 UM/MOD -> 1 0 }T
+T{ 3 0 2 UM/MOD -> 1 1 }T
+T{ MAX-UINT 2 UM* 2 UM/MOD -> 0 MAX-UINT }T
+T{ MAX-UINT 2 UM* MAX-UINT UM/MOD -> 0 2 }T
+T{ MAX-UINT MAX-UINT UM* MAX-UINT UM/MOD -> 0 MAX-UINT }T
+
+: IFFLOORED
+ [ -3 2 / -2 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+: IFSYM
+ [ -3 2 / -1 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+\ THE SYSTEM MIGHT DO EITHER FLOORED OR SYMMETRIC DIVISION.
+\ SINCE WE HAVE ALREADY TESTED M*, FM/MOD, AND SM/REM WE CAN USE THEM IN TEST.
+
+IFFLOORED : T/MOD >R S>D R> FM/MOD ;
+IFFLOORED : T/ T/MOD SWAP DROP ;
+IFFLOORED : TMOD T/MOD DROP ;
+IFFLOORED : T*/MOD >R M* R> FM/MOD ;
+IFFLOORED : T*/ T*/MOD SWAP DROP ;
+IFSYM : T/MOD >R S>D R> SM/REM ;
+IFSYM : T/ T/MOD SWAP DROP ;
+IFSYM : TMOD T/MOD DROP ;
+IFSYM : T*/MOD >R M* R> SM/REM ;
+IFSYM : T*/ T*/MOD SWAP DROP ;
+
+T{ 0 1 /MOD -> 0 1 T/MOD }T
+T{ 1 1 /MOD -> 1 1 T/MOD }T
+T{ 2 1 /MOD -> 2 1 T/MOD }T
+T{ -1 1 /MOD -> -1 1 T/MOD }T
+T{ -2 1 /MOD -> -2 1 T/MOD }T
+T{ 0 -1 /MOD -> 0 -1 T/MOD }T
+T{ 1 -1 /MOD -> 1 -1 T/MOD }T
+T{ 2 -1 /MOD -> 2 -1 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -1 /MOD -> -2 -1 T/MOD }T
+T{ 2 2 /MOD -> 2 2 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -2 /MOD -> -2 -2 T/MOD }T
+T{ 7 3 /MOD -> 7 3 T/MOD }T
+T{ 7 -3 /MOD -> 7 -3 T/MOD }T
+T{ -7 3 /MOD -> -7 3 T/MOD }T
+T{ -7 -3 /MOD -> -7 -3 T/MOD }T
+T{ MAX-INT 1 /MOD -> MAX-INT 1 T/MOD }T
+T{ MIN-INT 1 /MOD -> MIN-INT 1 T/MOD }T
+T{ MAX-INT MAX-INT /MOD -> MAX-INT MAX-INT T/MOD }T
+T{ MIN-INT MIN-INT /MOD -> MIN-INT MIN-INT T/MOD }T
+
+T{ 0 1 / -> 0 1 T/ }T
+T{ 1 1 / -> 1 1 T/ }T
+T{ 2 1 / -> 2 1 T/ }T
+T{ -1 1 / -> -1 1 T/ }T
+T{ -2 1 / -> -2 1 T/ }T
+T{ 0 -1 / -> 0 -1 T/ }T
+T{ 1 -1 / -> 1 -1 T/ }T
+T{ 2 -1 / -> 2 -1 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -1 / -> -2 -1 T/ }T
+T{ 2 2 / -> 2 2 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -2 / -> -2 -2 T/ }T
+T{ 7 3 / -> 7 3 T/ }T
+T{ 7 -3 / -> 7 -3 T/ }T
+T{ -7 3 / -> -7 3 T/ }T
+T{ -7 -3 / -> -7 -3 T/ }T
+T{ MAX-INT 1 / -> MAX-INT 1 T/ }T
+T{ MIN-INT 1 / -> MIN-INT 1 T/ }T
+T{ MAX-INT MAX-INT / -> MAX-INT MAX-INT T/ }T
+T{ MIN-INT MIN-INT / -> MIN-INT MIN-INT T/ }T
+
+T{ 0 1 MOD -> 0 1 TMOD }T
+T{ 1 1 MOD -> 1 1 TMOD }T
+T{ 2 1 MOD -> 2 1 TMOD }T
+T{ -1 1 MOD -> -1 1 TMOD }T
+T{ -2 1 MOD -> -2 1 TMOD }T
+T{ 0 -1 MOD -> 0 -1 TMOD }T
+T{ 1 -1 MOD -> 1 -1 TMOD }T
+T{ 2 -1 MOD -> 2 -1 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -1 MOD -> -2 -1 TMOD }T
+T{ 2 2 MOD -> 2 2 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -2 MOD -> -2 -2 TMOD }T
+T{ 7 3 MOD -> 7 3 TMOD }T
+T{ 7 -3 MOD -> 7 -3 TMOD }T
+T{ -7 3 MOD -> -7 3 TMOD }T
+T{ -7 -3 MOD -> -7 -3 TMOD }T
+T{ MAX-INT 1 MOD -> MAX-INT 1 TMOD }T
+T{ MIN-INT 1 MOD -> MIN-INT 1 TMOD }T
+T{ MAX-INT MAX-INT MOD -> MAX-INT MAX-INT TMOD }T
+T{ MIN-INT MIN-INT MOD -> MIN-INT MIN-INT TMOD }T
+
+T{ 0 2 1 */ -> 0 2 1 T*/ }T
+T{ 1 2 1 */ -> 1 2 1 T*/ }T
+T{ 2 2 1 */ -> 2 2 1 T*/ }T
+T{ -1 2 1 */ -> -1 2 1 T*/ }T
+T{ -2 2 1 */ -> -2 2 1 T*/ }T
+T{ 0 2 -1 */ -> 0 2 -1 T*/ }T
+T{ 1 2 -1 */ -> 1 2 -1 T*/ }T
+T{ 2 2 -1 */ -> 2 2 -1 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -1 */ -> -2 2 -1 T*/ }T
+T{ 2 2 2 */ -> 2 2 2 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -2 */ -> -2 2 -2 T*/ }T
+T{ 7 2 3 */ -> 7 2 3 T*/ }T
+T{ 7 2 -3 */ -> 7 2 -3 T*/ }T
+T{ -7 2 3 */ -> -7 2 3 T*/ }T
+T{ -7 2 -3 */ -> -7 2 -3 T*/ }T
+T{ MAX-INT 2 MAX-INT */ -> MAX-INT 2 MAX-INT T*/ }T
+T{ MIN-INT 2 MIN-INT */ -> MIN-INT 2 MIN-INT T*/ }T
+
+T{ 0 2 1 */MOD -> 0 2 1 T*/MOD }T
+T{ 1 2 1 */MOD -> 1 2 1 T*/MOD }T
+T{ 2 2 1 */MOD -> 2 2 1 T*/MOD }T
+T{ -1 2 1 */MOD -> -1 2 1 T*/MOD }T
+T{ -2 2 1 */MOD -> -2 2 1 T*/MOD }T
+T{ 0 2 -1 */MOD -> 0 2 -1 T*/MOD }T
+T{ 1 2 -1 */MOD -> 1 2 -1 T*/MOD }T
+T{ 2 2 -1 */MOD -> 2 2 -1 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -1 */MOD -> -2 2 -1 T*/MOD }T
+T{ 2 2 2 */MOD -> 2 2 2 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -2 */MOD -> -2 2 -2 T*/MOD }T
+T{ 7 2 3 */MOD -> 7 2 3 T*/MOD }T
+T{ 7 2 -3 */MOD -> 7 2 -3 T*/MOD }T
+T{ -7 2 3 */MOD -> -7 2 3 T*/MOD }T
+T{ -7 2 -3 */MOD -> -7 2 -3 T*/MOD }T
+T{ MAX-INT 2 MAX-INT */MOD -> MAX-INT 2 MAX-INT T*/MOD }T
+T{ MIN-INT 2 MIN-INT */MOD -> MIN-INT 2 MIN-INT T*/MOD }T
+
+\ ------------------------------------------------------------------------
+TESTING HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2! ALIGN ALIGNED +! ALLOT
+
+HERE 1 ALLOT
+HERE
+CONSTANT 2NDA
+CONSTANT 1STA
+T{ 1STA 2NDA U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STA 1+ -> 2NDA }T \ ... BY ONE ADDRESS UNIT
+( MISSING TEST: NEGATIVE ALLOT )
+
+HERE 1 ,
+HERE 2 ,
+CONSTANT 2ND
+CONSTANT 1ST
+T{ 1ST 2ND U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1ST CELL+ -> 2ND }T \ ... BY ONE CELL
+T{ 1ST 1 CELLS + -> 2ND }T
+T{ 1ST @ 2ND @ -> 1 2 }T
+T{ 5 1ST ! -> }T
+T{ 1ST @ 2ND @ -> 5 2 }T
+T{ 6 2ND ! -> }T
+T{ 1ST @ 2ND @ -> 5 6 }T
+T{ 1ST 2@ -> 6 5 }T
+T{ 2 1 1ST 2! -> }T
+T{ 1ST 2@ -> 2 1 }T
+T{ 1S 1ST ! 1ST @ -> 1S }T \ CAN STORE CELL-WIDE VALUE
+
+HERE 1 C,
+HERE 2 C,
+CONSTANT 2NDC
+CONSTANT 1STC
+T{ 1STC 2NDC U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STC CHAR+ -> 2NDC }T \ ... BY ONE CHAR
+T{ 1STC 1 CHARS + -> 2NDC }T
+T{ 1STC C@ 2NDC C@ -> 1 2 }T
+T{ 3 1STC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 2 }T
+T{ 4 2NDC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 4 }T
+
+ALIGN 1 ALLOT HERE ALIGN HERE 3 CELLS ALLOT
+CONSTANT A-ADDR CONSTANT UA-ADDR
+T{ UA-ADDR ALIGNED -> A-ADDR }T
+T{ 1 A-ADDR C! A-ADDR C@ -> 1 }T
+T{ 1234 A-ADDR ! A-ADDR @ -> 1234 }T
+T{ 123 456 A-ADDR 2! A-ADDR 2@ -> 123 456 }T
+T{ 2 A-ADDR CHAR+ C! A-ADDR CHAR+ C@ -> 2 }T
+T{ 3 A-ADDR CELL+ C! A-ADDR CELL+ C@ -> 3 }T
+T{ 1234 A-ADDR CELL+ ! A-ADDR CELL+ @ -> 1234 }T
+T{ 123 456 A-ADDR CELL+ 2! A-ADDR CELL+ 2@ -> 123 456 }T
+
+: BITS ( X -- U )
+ 0 SWAP BEGIN DUP WHILE DUP MSB AND IF >R 1+ R> THEN 2* REPEAT DROP ;
+( CHARACTERS >= 1 AU, <= SIZE OF CELL, >= 8 BITS )
+T{ 1 CHARS 1 < -> <FALSE> }T
+T{ 1 CHARS 1 CELLS > -> <FALSE> }T
+( TBD: HOW TO FIND NUMBER OF BITS? )
+
+( CELLS >= 1 AU, INTEGRAL MULTIPLE OF CHAR SIZE, >= 16 BITS )
+T{ 1 CELLS 1 < -> <FALSE> }T
+T{ 1 CELLS 1 CHARS MOD -> 0 }T
+T{ 1S BITS 10 < -> <FALSE> }T
+
+T{ 0 1ST ! -> }T
+T{ 1 1ST +! -> }T
+T{ 1ST @ -> 1 }T
+T{ -1 1ST +! 1ST @ -> 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING CHAR [CHAR] [ ] BL S"
+
+T{ BL -> 20 }T
+T{ CHAR X -> 58 }T
+T{ CHAR HELLO -> 48 }T
+T{ : GC1 [CHAR] X ; -> }T
+T{ : GC2 [CHAR] HELLO ; -> }T
+T{ GC1 -> 58 }T
+T{ GC2 -> 48 }T
+T{ : GC3 [ GC1 ] LITERAL ; -> }T
+T{ GC3 -> 58 }T
+T{ : GC4 S" XY" ; -> }T
+T{ GC4 SWAP DROP -> 2 }T
+T{ GC4 DROP DUP C@ SWAP CHAR+ C@ -> 58 59 }T
+
+\ ------------------------------------------------------------------------
+TESTING ' ['] FIND EXECUTE IMMEDIATE COUNT LITERAL POSTPONE STATE
+
+T{ : GT1 123 ; -> }T
+T{ ' GT1 EXECUTE -> 123 }T
+T{ : GT2 ['] GT1 ; IMMEDIATE -> }T
+T{ GT2 EXECUTE -> 123 }T
+HERE 3 C, CHAR G C, CHAR T C, CHAR 1 C, CONSTANT GT1STRING
+HERE 3 C, CHAR G C, CHAR T C, CHAR 2 C, CONSTANT GT2STRING
+T{ GT1STRING FIND -> ' GT1 -1 }T
+T{ GT2STRING FIND -> ' GT2 1 }T
+( HOW TO SEARCH FOR NON-EXISTENT WORD? )
+T{ : GT3 GT2 LITERAL ; -> }T
+T{ GT3 -> ' GT1 }T
+T{ GT1STRING COUNT -> GT1STRING CHAR+ 3 }T
+
+T{ : GT4 POSTPONE GT1 ; IMMEDIATE -> }T
+T{ : GT5 GT4 ; -> }T
+T{ GT5 -> 123 }T
+T{ : GT6 345 ; IMMEDIATE -> }T
+T{ : GT7 POSTPONE GT6 ; -> }T
+T{ GT7 -> 345 }T
+
+T{ : GT8 STATE @ ; IMMEDIATE -> }T
+T{ GT8 -> 0 }T
+T{ : GT9 GT8 LITERAL ; -> }T
+T{ GT9 0= -> <FALSE> }T
+
+\ ------------------------------------------------------------------------
+TESTING IF ELSE THEN BEGIN WHILE REPEAT UNTIL RECURSE
+
+T{ : GI1 IF 123 THEN ; -> }T
+T{ : GI2 IF 123 ELSE 234 THEN ; -> }T
+T{ 0 GI1 -> }T
+T{ 1 GI1 -> 123 }T
+T{ -1 GI1 -> 123 }T
+T{ 0 GI2 -> 234 }T
+T{ 1 GI2 -> 123 }T
+T{ -1 GI1 -> 123 }T
+
+T{ : GI3 BEGIN DUP 5 < WHILE DUP 1+ REPEAT ; -> }T
+T{ 0 GI3 -> 0 1 2 3 4 5 }T
+T{ 4 GI3 -> 4 5 }T
+T{ 5 GI3 -> 5 }T
+T{ 6 GI3 -> 6 }T
+
+T{ : GI4 BEGIN DUP 1+ DUP 5 > UNTIL ; -> }T
+T{ 3 GI4 -> 3 4 5 6 }T
+T{ 5 GI4 -> 5 6 }T
+T{ 6 GI4 -> 6 7 }T
+
+T{ : GI5 BEGIN DUP 2 > WHILE DUP 5 < WHILE DUP 1+ REPEAT 123 ELSE 345 THEN ; -> }T
+T{ 1 GI5 -> 1 345 }T
+T{ 2 GI5 -> 2 345 }T
+T{ 3 GI5 -> 3 4 5 123 }T
+T{ 4 GI5 -> 4 5 123 }T
+T{ 5 GI5 -> 5 123 }T
+
+T{ : GI6 ( N -- 0,1,..N ) DUP IF DUP >R 1- RECURSE R> THEN ; -> }T
+T{ 0 GI6 -> 0 }T
+T{ 1 GI6 -> 0 1 }T
+T{ 2 GI6 -> 0 1 2 }T
+T{ 3 GI6 -> 0 1 2 3 }T
+T{ 4 GI6 -> 0 1 2 3 4 }T
+
+\ ------------------------------------------------------------------------
+TESTING DO LOOP +LOOP I J UNLOOP LEAVE EXIT
+
+T{ : GD1 DO I LOOP ; -> }T
+T{ 4 1 GD1 -> 1 2 3 }T
+T{ 2 -1 GD1 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD1 -> MID-UINT }T
+
+T{ : GD2 DO I -1 +LOOP ; -> }T
+T{ 1 4 GD2 -> 4 3 2 1 }T
+T{ -1 2 GD2 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD2 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD3 DO 1 0 DO J LOOP LOOP ; -> }T
+T{ 4 1 GD3 -> 1 2 3 }T
+T{ 2 -1 GD3 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD3 -> MID-UINT }T
+
+T{ : GD4 DO 1 0 DO J LOOP -1 +LOOP ; -> }T
+T{ 1 4 GD4 -> 4 3 2 1 }T
+T{ -1 2 GD4 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD4 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD5 123 SWAP 0 DO I 4 > IF DROP 234 LEAVE THEN LOOP ; -> }T
+T{ 1 GD5 -> 123 }T
+T{ 5 GD5 -> 123 }T
+T{ 6 GD5 -> 234 }T
+
+T{ : GD6 ( PAT: T{0 0}T,T{0 0}TT{1 0}TT{1 1}T,T{0 0}TT{1 0}TT{1 1}TT{2 0}TT{2 1}TT{2 2}T )
+ 0 SWAP 0 DO
+ I 1+ 0 DO I J + 3 = IF I UNLOOP I UNLOOP EXIT THEN 1+ LOOP
+ LOOP ; -> }T
+T{ 1 GD6 -> 1 }T
+T{ 2 GD6 -> 3 }T
+T{ 3 GD6 -> 4 1 2 }T
+
+\ ------------------------------------------------------------------------
+TESTING DEFINING WORDS: : ; CONSTANT VARIABLE CREATE DOES> >BODY
+
+T{ 123 CONSTANT X123 -> }T
+T{ X123 -> 123 }T
+T{ : EQU CONSTANT ; -> }T
+T{ X123 EQU Y123 -> }T
+T{ Y123 -> 123 }T
+
+T{ VARIABLE V1 -> }T
+T{ 123 V1 ! -> }T
+T{ V1 @ -> 123 }T
+
+T{ : NOP : POSTPONE ; ; -> }T
+T{ NOP NOP1 NOP NOP2 -> }T
+T{ NOP1 -> }T
+T{ NOP2 -> }T
+
+T{ : DOES1 DOES> @ 1 + ; -> }T
+T{ : DOES2 DOES> @ 2 + ; -> }T
+T{ CREATE CR1 -> }T
+T{ CR1 -> HERE }T
+T{ ' CR1 >BODY -> HERE }T
+T{ 1 , -> }T
+T{ CR1 @ -> 1 }T
+T{ DOES1 -> }T
+T{ CR1 -> 2 }T
+T{ DOES2 -> }T
+T{ CR1 -> 3 }T
+
+T{ : WEIRD: CREATE DOES> 1 + DOES> 2 + ; -> }T
+T{ WEIRD: W1 -> }T
+T{ ' W1 >BODY -> HERE }T
+T{ W1 -> HERE 1 + }T
+T{ W1 -> HERE 2 + }T
+
+\ ------------------------------------------------------------------------
+TESTING EVALUATE
+
+: GE1 S" 123" ; IMMEDIATE
+: GE2 S" 123 1+" ; IMMEDIATE
+: GE3 S" : GE4 345 ;" ;
+: GE5 EVALUATE ; IMMEDIATE
+
+T{ GE1 EVALUATE -> 123 }T ( TEST EVALUATE IN INTERP. STATE )
+T{ GE2 EVALUATE -> 124 }T
+T{ GE3 EVALUATE -> }T
+T{ GE4 -> 345 }T
+
+T{ : GE6 GE1 GE5 ; -> }T ( TEST EVALUATE IN COMPILE STATE )
+T{ GE6 -> 123 }T
+T{ : GE7 GE2 GE5 ; -> }T
+T{ GE7 -> 124 }T
+
+\ ------------------------------------------------------------------------
+TESTING SOURCE >IN WORD
+
+: GS1 S" SOURCE" 2DUP EVALUATE
+ >R SWAP >R = R> R> = ;
+T{ GS1 -> <TRUE> <TRUE> }T
+
+VARIABLE SCANS
+: RESCAN? -1 SCANS +! SCANS @ IF 0 >IN ! THEN ;
+
+T{ 2 SCANS !
+345 RESCAN?
+-> 345 345 }T
+
+: GS2 5 SCANS ! S" 123 RESCAN?" EVALUATE ;
+T{ GS2 -> 123 123 123 123 123 }T
+
+: GS3 WORD COUNT SWAP C@ ;
+T{ BL GS3 HELLO -> 5 CHAR H }T
+T{ CHAR " GS3 GOODBYE" -> 7 CHAR G }T
+T{ BL GS3
+DROP -> 0 }T \ BLANK LINE RETURN ZERO-LENGTH STRING
+
+: GS4 SOURCE >IN ! DROP ;
+T{ GS4 123 456
+-> }T
+
+\ ------------------------------------------------------------------------
+TESTING <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL
+
+: S= \ ( ADDR1 C1 ADDR2 C2 -- T/F ) COMPARE TWO STRINGS.
+ >R SWAP R@ = IF \ MAKE SURE STRINGS HAVE SAME LENGTH
+ R> ?DUP IF \ IF NON-EMPTY STRINGS
+ 0 DO
+ OVER C@ OVER C@ - IF
+ 2DROP <FALSE> UNLOOP EXIT THEN
+ SWAP CHAR+ SWAP CHAR+
+ LOOP
+ THEN
+ 2DROP <TRUE> \ IF WE GET HERE, STRINGS MATCH
+ ELSE
+ R> DROP 2DROP <FALSE> \ LENGTHS MISMATCH
+ THEN ;
+
+: GP1 <# 41 HOLD 42 HOLD 0 0 #> S" BA" S= ;
+T{ GP1 -> <TRUE> }T
+
+: GP2 <# -1 SIGN 0 SIGN -1 SIGN 0 0 #> S" --" S= ;
+T{ GP2 -> <TRUE> }T
+
+: GP3 <# 1 0 # # #> S" 01" S= ;
+T{ GP3 -> <TRUE> }T
+
+: GP4 <# 1 0 #S #> S" 1" S= ;
+T{ GP4 -> <TRUE> }T
+
+24 CONSTANT MAX-BASE \ BASE 2 .. 36
+: COUNT-BITS
+ 0 0 INVERT BEGIN DUP WHILE >R 1+ R> 2* REPEAT DROP ;
+COUNT-BITS 2* CONSTANT #BITS-UD \ NUMBER OF BITS IN UD
+
+: GP5
+ BASE @ <TRUE>
+ MAX-BASE 1+ 2 DO \ FOR EACH POSSIBLE BASE
+ I BASE ! \ TBD: ASSUMES BASE WORKS
+ I 0 <# #S #> S" 10" S= AND
+ LOOP
+ SWAP BASE ! ;
+T{ GP5 -> <TRUE> }T
+
+: GP6
+ BASE @ >R 2 BASE !
+ MAX-UINT MAX-UINT <# #S #> \ MAXIMUM UD TO BINARY
+ R> BASE ! \ S: C-ADDR U
+ DUP #BITS-UD = SWAP
+ 0 DO \ S: C-ADDR FLAG
+ OVER C@ [CHAR] 1 = AND \ ALL ONES
+ >R CHAR+ R>
+ LOOP SWAP DROP ;
+T{ GP6 -> <TRUE> }T
+
+: GP7
+ BASE @ >R MAX-BASE BASE !
+ <TRUE>
+ A 0 DO
+ I 0 <# #S #>
+ 1 = SWAP C@ I 30 + = AND AND
+ LOOP
+ MAX-BASE A DO
+ I 0 <# #S #>
+ 1 = SWAP C@ 41 I A - + = AND AND
+ LOOP
+ R> BASE ! ;
+
+T{ GP7 -> <TRUE> }T
+
+\ >NUMBER TESTS
+CREATE GN-BUF 0 C,
+: GN-STRING GN-BUF 1 ;
+: GN-CONSUMED GN-BUF CHAR+ 0 ;
+: GN' [CHAR] ' WORD CHAR+ C@ GN-BUF C! GN-STRING ;
+
+T{ 0 0 GN' 0' >NUMBER -> 0 0 GN-CONSUMED }T
+T{ 0 0 GN' 1' >NUMBER -> 1 0 GN-CONSUMED }T
+T{ 1 0 GN' 1' >NUMBER -> BASE @ 1+ 0 GN-CONSUMED }T
+T{ 0 0 GN' -' >NUMBER -> 0 0 GN-STRING }T \ SHOULD FAIL TO CONVERT THESE
+T{ 0 0 GN' +' >NUMBER -> 0 0 GN-STRING }T
+T{ 0 0 GN' .' >NUMBER -> 0 0 GN-STRING }T
+
+: >NUMBER-BASED
+ BASE @ >R BASE ! >NUMBER R> BASE ! ;
+
+T{ 0 0 GN' 2' 10 >NUMBER-BASED -> 2 0 GN-CONSUMED }T
+T{ 0 0 GN' 2' 2 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' F' 10 >NUMBER-BASED -> F 0 GN-CONSUMED }T
+T{ 0 0 GN' G' 10 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' G' MAX-BASE >NUMBER-BASED -> 10 0 GN-CONSUMED }T
+T{ 0 0 GN' Z' MAX-BASE >NUMBER-BASED -> 23 0 GN-CONSUMED }T
+
+: GN1 \ ( UD BASE -- UD' LEN ) UD SHOULD EQUAL UD' AND LEN SHOULD BE ZERO.
+ BASE @ >R BASE !
+ <# #S #>
+ 0 0 2SWAP >NUMBER SWAP DROP \ RETURN LENGTH ONLY
+ R> BASE ! ;
+T{ 0 0 2 GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 2 GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP 2 GN1 -> MAX-UINT DUP 0 }T
+T{ 0 0 MAX-BASE GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 MAX-BASE GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP MAX-BASE GN1 -> MAX-UINT DUP 0 }T
+
+: GN2 \ ( -- 16 10 )
+ BASE @ >R HEX BASE @ DECIMAL BASE @ R> BASE ! ;
+T{ GN2 -> 10 A }T
+
+\ ------------------------------------------------------------------------
+TESTING FILL MOVE
+
+CREATE FBUF 00 C, 00 C, 00 C,
+CREATE SBUF 12 C, 34 C, 56 C,
+: SEEBUF FBUF C@ FBUF CHAR+ C@ FBUF CHAR+ CHAR+ C@ ;
+
+T{ FBUF 0 20 FILL -> }T
+T{ SEEBUF -> 00 00 00 }T
+
+T{ FBUF 1 20 FILL -> }T
+T{ SEEBUF -> 20 00 00 }T
+
+T{ FBUF 3 20 FILL -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ FBUF FBUF 3 CHARS MOVE -> }T \ BIZARRE SPECIAL CASE
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 0 CHARS MOVE -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 1 CHARS MOVE -> }T
+T{ SEEBUF -> 12 20 20 }T
+
+T{ SBUF FBUF 3 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 56 }T
+
+T{ FBUF FBUF CHAR+ 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 12 34 }T
+
+T{ FBUF CHAR+ FBUF 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 34 }T
+
+\ ------------------------------------------------------------------------
+TESTING OUTPUT: . ." CR EMIT SPACE SPACES TYPE U.
+
+: OUTPUT-TEST
+ ." YOU SHOULD SEE THE STANDARD GRAPHIC CHARACTERS:" CR
+ 41 BL DO I EMIT LOOP CR
+ 61 41 DO I EMIT LOOP CR
+ 7F 61 DO I EMIT LOOP CR
+ ." YOU SHOULD SEE 0-9 SEPARATED BY A SPACE:" CR
+ 9 1+ 0 DO I . LOOP CR
+ ." YOU SHOULD SEE 0-9 (WITH NO SPACES):" CR
+ [CHAR] 9 1+ [CHAR] 0 DO I 0 SPACES EMIT LOOP CR
+ ." YOU SHOULD SEE A-G SEPARATED BY A SPACE:" CR
+ [CHAR] G 1+ [CHAR] A DO I EMIT SPACE LOOP CR
+ ." YOU SHOULD SEE 0-5 SEPARATED BY TWO SPACES:" CR
+ 5 1+ 0 DO I [CHAR] 0 + EMIT 2 SPACES LOOP CR
+ ." YOU SHOULD SEE TWO SEPARATE LINES:" CR
+ S" LINE 1" TYPE CR S" LINE 2" TYPE CR
+ ." YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:" CR
+ ." SIGNED: " MIN-INT . MAX-INT . CR
+ ." UNSIGNED: " 0 U. MAX-UINT U. CR
+;
+
+T{ OUTPUT-TEST -> }T
+\ ------------------------------------------------------------------------
+TESTING INPUT: ACCEPT
+
+CREATE ABUF 80 CHARS ALLOT
+
+: ACCEPT-TEST
+ CR ." PLEASE TYPE UP TO 80 CHARACTERS:" CR
+ ABUF 80 ACCEPT
+ CR ." RECEIVED: " [CHAR] " EMIT
+ ABUF SWAP TYPE [CHAR] " EMIT CR
+;
+
+T{ ACCEPT-TEST -> }T
+Vingt fois sur le métier remettez votre ouvrage, ... Boileau, L'Art poétique
+\ ------------------------------------------------------------------------
+TESTING DICTIONARY SEARCH RULES
+
+T{ : GDX 123 ; : GDX GDX 234 ; -> }T
+
+T{ GDX -> 123 234 }T
+
+CR .( End of Core word set tests) CR
+
+
+$0A BASE !
+ECHO
+ ; end of core test
+PWR_HERE ; preserved against power OFF ;
--- /dev/null
+; ------------------------
+; file name : coretest.4th
+; ------------------------
+
+RST_STATE ; so ANS_COMPLEMENT_xx_MPY is conserved
+\ NOECHO ; if an error occurs, comment this line before new download to find it.
+
+
+\ From: John Hayes S1I
+\ Subject: tester.fr
+\ Date: Mon, 27 Nov 95 13:10:09 PST
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.1
+
+\ 22/1/09 The words { and } have been changed to T{ and }T respectively to
+\ agree with the Forth 200X file ttester.fs. This avoids clashes with
+\ locals using { ... } and the FSL use of }
+
+
+\ 13/05/14 jmt. added colorised error messages.
+
+
+
+ 0 CONSTANT FALSE
+-1 CONSTANT TRUE
+
+\ SET THE FOLLOWING FLAG TO TRUE FOR MORE VERBOSE OUTPUT; THIS MAY
+\ ALLOW YOU TO TELL WHICH TEST CAUSED YOUR SYSTEM TO HANG.
+VARIABLE VERBOSE
+ FALSE VERBOSE !
+\ TRUE VERBOSE !
+
+\ : EMPTY-STACK ( ... -- ) \ EMPTY STACK: HANDLES UNDERFLOWED STACK TOO.
+\ DEPTH ?DUP
+\ IF DUP 0< IF NEGATE 0
+\ DO 0 LOOP
+\ ELSE 0 DO DROP LOOP THEN
+\ THEN ;
+\
+\ : ERROR \ ( C-ADDR U -- ) DISPLAY AN ERROR MESSAGE FOLLOWED BY
+\ \ THE LINE THAT HAD THE ERROR.
+\ TYPE SOURCE TYPE CR \ DISPLAY LINE CORRESPONDING TO ERROR
+\ EMPTY-STACK \ THROW AWAY EVERY THING ELSE
+\ QUIT \ *** Uncomment this line to QUIT on an error
+\ ;
+
+VARIABLE ACTUAL-DEPTH \ STACK RECORD
+CREATE ACTUAL-RESULTS 20 CELLS ALLOT
+
+: T{ \ ( -- ) SYNTACTIC SUGAR.
+ ;
+
+: -> \ ( ... -- ) RECORD DEPTH AND CONTENT OF STACK.
+ DEPTH DUP ACTUAL-DEPTH ! \ RECORD DEPTH
+ ?DUP IF \ IF THERE IS SOMETHING ON STACK
+ 0 DO ACTUAL-RESULTS I CELLS + ! LOOP \ SAVE THEM
+ THEN ;
+
+: }T \ ( ... -- ) COMPARE STACK (EXPECTED) CONTENTS WITH SAVED
+ \ (ACTUAL) CONTENTS.
+ DEPTH ACTUAL-DEPTH @ = IF \ IF DEPTHS MATCH
+ DEPTH ?DUP IF \ IF THERE IS SOMETHING ON THE STACK
+ 0 DO \ FOR EACH STACK ITEM
+ ACTUAL-RESULTS I CELLS + @ \ COMPARE ACTUAL WITH EXPECTED
+\ = 0= IF S" INCORRECT RESULT: " ERROR LEAVE THEN \ jmt
+ = 0= IF ABORT" INCORRECT RESULT: " THEN \ jmt : colorised message
+ LOOP
+ THEN
+ ELSE \ DEPTH MISMATCH
+\ S" WRONG NUMBER OF RESULTS: " ERROR \ jmt
+ ABORT" WRONG NUMBER OF RESULTS: " \ jmt : colorised message
+ THEN ;
+
+: TESTING \ ( -- ) TALKING COMMENT.
+ SOURCE VERBOSE @
+ IF DUP >R TYPE CR R> >IN !
+ ELSE >IN ! DROP [CHAR] * EMIT
+ THEN ;
+
+\ From: John Hayes S1I
+\ Subject: core.fr
+\ Date: Mon, 27 Nov 95 13:10
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.2
+\ THIS PROGRAM TESTS THE CORE WORDS OF AN ANS FORTH SYSTEM.
+\ THE PROGRAM ASSUMES A TWO'S COMPLEMENT IMPLEMENTATION WHERE
+\ THE RANGE OF SIGNED NUMBERS IS -2^(N-1) ... 2^(N-1)-1 AND
+\ THE RANGE OF UNSIGNED NUMBERS IS 0 ... 2^(N)-1.
+\ I HAVEN'T FIGURED OUT HOW TO TEST KEY, QUIT, ABORT, OR ABORT"...
+\ I ALSO HAVEN'T THOUGHT OF A WAY TO TEST ENVIRONMENT?...
+
+CR
+TESTING CORE WORDS
+HEX
+
+\ ------------------------------------------------------------------------
+TESTING BASIC ASSUMPTIONS
+
+T{ -> }T \ START WITH CLEAN SLATE
+( TEST IF ANY BITS ARE SET; ANSWER IN BASE 1 )
+T{ : BITSSET? IF 0 0 ELSE 0 THEN ; -> }T
+T{ 0 BITSSET? -> 0 }T ( ZERO IS ALL BITS CLEAR )
+T{ 1 BITSSET? -> 0 0 }T ( OTHER NUMBER HAVE AT LEAST ONE BIT )
+T{ -1 BITSSET? -> 0 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING BOOLEANS: INVERT AND OR XOR
+
+T{ 0 0 AND -> 0 }T
+T{ 0 1 AND -> 0 }T
+T{ 1 0 AND -> 0 }T
+T{ 1 1 AND -> 1 }T
+
+T{ 0 INVERT 1 AND -> 1 }T
+T{ 1 INVERT 1 AND -> 0 }T
+
+0 CONSTANT 0S
+0 INVERT CONSTANT 1S
+
+T{ 0S INVERT -> 1S }T
+T{ 1S INVERT -> 0S }T
+
+T{ 0S 0S AND -> 0S }T
+T{ 0S 1S AND -> 0S }T
+T{ 1S 0S AND -> 0S }T
+T{ 1S 1S AND -> 1S }T
+
+T{ 0S 0S OR -> 0S }T
+T{ 0S 1S OR -> 1S }T
+T{ 1S 0S OR -> 1S }T
+T{ 1S 1S OR -> 1S }T
+
+T{ 0S 0S XOR -> 0S }T
+T{ 0S 1S XOR -> 1S }T
+T{ 1S 0S XOR -> 1S }T
+T{ 1S 1S XOR -> 0S }T
+
+\ ------------------------------------------------------------------------
+TESTING 2* 2/ LSHIFT RSHIFT
+
+( WE TRUST 1S, INVERT, AND BITSSET?; WE WILL CONFIRM RSHIFT LATER )
+1S 1 RSHIFT INVERT CONSTANT MSB
+T{ MSB BITSSET? -> 0 0 }T
+
+T{ 0S 2* -> 0S }T
+T{ 1 2* -> 2 }T
+T{ 4000 2* -> 8000 }T
+T{ 1S 2* 1 XOR -> 1S }T
+T{ MSB 2* -> 0S }T
+
+T{ 0S 2/ -> 0S }T
+T{ 1 2/ -> 0 }T
+T{ 4000 2/ -> 2000 }T
+T{ 1S 2/ -> 1S }T \ MSB PROPOGATED
+T{ 1S 1 XOR 2/ -> 1S }T
+T{ MSB 2/ MSB AND -> MSB }T
+
+T{ 1 0 LSHIFT -> 1 }T
+T{ 1 1 LSHIFT -> 2 }T
+T{ 1 2 LSHIFT -> 4 }T
+T{ 1 F LSHIFT -> 8000 }T \ BIGGEST GUARANTEED SHIFT
+T{ 1S 1 LSHIFT 1 XOR -> 1S }T
+T{ MSB 1 LSHIFT -> 0 }T
+
+T{ 1 0 RSHIFT -> 1 }T
+T{ 1 1 RSHIFT -> 0 }T
+T{ 2 1 RSHIFT -> 1 }T
+T{ 4 2 RSHIFT -> 1 }T
+T{ 8000 F RSHIFT -> 1 }T \ BIGGEST
+T{ MSB 1 RSHIFT MSB AND -> 0 }T \ RSHIFT ZERO FILLS MSBS
+T{ MSB 1 RSHIFT 2* -> MSB }T
+
+\ ------------------------------------------------------------------------
+TESTING COMPARISONS: 0= = 0< < > U< MIN MAX
+0 INVERT CONSTANT MAX-UINT
+0 INVERT 1 RSHIFT CONSTANT MAX-INT
+0 INVERT 1 RSHIFT INVERT CONSTANT MIN-INT
+0 INVERT 1 RSHIFT CONSTANT MID-UINT
+0 INVERT 1 RSHIFT INVERT CONSTANT MID-UINT+1
+
+0S CONSTANT <FALSE>
+1S CONSTANT <TRUE>
+
+T{ 0 0= -> <TRUE> }T
+T{ 1 0= -> <FALSE> }T
+T{ 2 0= -> <FALSE> }T
+T{ -1 0= -> <FALSE> }T
+T{ MAX-UINT 0= -> <FALSE> }T
+T{ MIN-INT 0= -> <FALSE> }T
+T{ MAX-INT 0= -> <FALSE> }T
+
+T{ 0 0 = -> <TRUE> }T
+T{ 1 1 = -> <TRUE> }T
+T{ -1 -1 = -> <TRUE> }T
+T{ 1 0 = -> <FALSE> }T
+T{ -1 0 = -> <FALSE> }T
+T{ 0 1 = -> <FALSE> }T
+T{ 0 -1 = -> <FALSE> }T
+
+T{ 0 0< -> <FALSE> }T
+T{ -1 0< -> <TRUE> }T
+T{ MIN-INT 0< -> <TRUE> }T
+T{ 1 0< -> <FALSE> }T
+T{ MAX-INT 0< -> <FALSE> }T
+
+T{ 0 1 < -> <TRUE> }T
+T{ 1 2 < -> <TRUE> }T
+T{ -1 0 < -> <TRUE> }T
+T{ -1 1 < -> <TRUE> }T
+T{ MIN-INT 0 < -> <TRUE> }T
+T{ MIN-INT MAX-INT < -> <TRUE> }T
+T{ 0 MAX-INT < -> <TRUE> }T
+T{ 0 0 < -> <FALSE> }T
+T{ 1 1 < -> <FALSE> }T
+T{ 1 0 < -> <FALSE> }T
+T{ 2 1 < -> <FALSE> }T
+T{ 0 -1 < -> <FALSE> }T
+T{ 1 -1 < -> <FALSE> }T
+T{ 0 MIN-INT < -> <FALSE> }T
+T{ MAX-INT MIN-INT < -> <FALSE> }T
+T{ MAX-INT 0 < -> <FALSE> }T
+
+T{ 0 1 > -> <FALSE> }T
+T{ 1 2 > -> <FALSE> }T
+T{ -1 0 > -> <FALSE> }T
+T{ -1 1 > -> <FALSE> }T
+T{ MIN-INT 0 > -> <FALSE> }T
+T{ MIN-INT MAX-INT > -> <FALSE> }T
+T{ 0 MAX-INT > -> <FALSE> }T
+T{ 0 0 > -> <FALSE> }T
+T{ 1 1 > -> <FALSE> }T
+T{ 1 0 > -> <TRUE> }T
+T{ 2 1 > -> <TRUE> }T
+T{ 0 -1 > -> <TRUE> }T
+T{ 1 -1 > -> <TRUE> }T
+T{ 0 MIN-INT > -> <TRUE> }T
+T{ MAX-INT MIN-INT > -> <TRUE> }T
+T{ MAX-INT 0 > -> <TRUE> }T
+
+T{ 0 1 U< -> <TRUE> }T
+T{ 1 2 U< -> <TRUE> }T
+T{ 0 MID-UINT U< -> <TRUE> }T
+T{ 0 MAX-UINT U< -> <TRUE> }T
+T{ MID-UINT MAX-UINT U< -> <TRUE> }T
+T{ 0 0 U< -> <FALSE> }T
+T{ 1 1 U< -> <FALSE> }T
+T{ 1 0 U< -> <FALSE> }T
+T{ 2 1 U< -> <FALSE> }T
+T{ MID-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT MID-UINT U< -> <FALSE> }T
+
+T{ 0 1 MIN -> 0 }T
+T{ 1 2 MIN -> 1 }T
+T{ -1 0 MIN -> -1 }T
+T{ -1 1 MIN -> -1 }T
+T{ MIN-INT 0 MIN -> MIN-INT }T
+T{ MIN-INT MAX-INT MIN -> MIN-INT }T
+T{ 0 MAX-INT MIN -> 0 }T
+T{ 0 0 MIN -> 0 }T
+T{ 1 1 MIN -> 1 }T
+T{ 1 0 MIN -> 0 }T
+T{ 2 1 MIN -> 1 }T
+T{ 0 -1 MIN -> -1 }T
+T{ 1 -1 MIN -> -1 }T
+T{ 0 MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT 0 MIN -> 0 }T
+
+T{ 0 1 MAX -> 1 }T
+T{ 1 2 MAX -> 2 }T
+T{ -1 0 MAX -> 0 }T
+T{ -1 1 MAX -> 1 }T
+T{ MIN-INT 0 MAX -> 0 }T
+T{ MIN-INT MAX-INT MAX -> MAX-INT }T
+T{ 0 MAX-INT MAX -> MAX-INT }T
+T{ 0 0 MAX -> 0 }T
+T{ 1 1 MAX -> 1 }T
+T{ 1 0 MAX -> 1 }T
+T{ 2 1 MAX -> 2 }T
+T{ 0 -1 MAX -> 0 }T
+T{ 1 -1 MAX -> 1 }T
+T{ 0 MIN-INT MAX -> 0 }T
+T{ MAX-INT MIN-INT MAX -> MAX-INT }T
+T{ MAX-INT 0 MAX -> MAX-INT }T
+
+\ ------------------------------------------------------------------------
+TESTING STACK OPS: 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP
+
+T{ 1 2 2DROP -> }T
+T{ 1 2 2DUP -> 1 2 1 2 }T
+T{ 1 2 3 4 2OVER -> 1 2 3 4 1 2 }T
+T{ 1 2 3 4 2SWAP -> 3 4 1 2 }T
+T{ 0 ?DUP -> 0 }T
+T{ 1 ?DUP -> 1 1 }T
+T{ -1 ?DUP -> -1 -1 }T
+T{ DEPTH -> 0 }T
+T{ 0 DEPTH -> 0 1 }T
+T{ 0 1 DEPTH -> 0 1 2 }T
+T{ 0 DROP -> }T
+T{ 1 2 DROP -> 1 }T
+T{ 1 DUP -> 1 1 }T
+T{ 1 2 OVER -> 1 2 1 }T
+T{ 1 2 3 ROT -> 2 3 1 }T
+T{ 1 2 SWAP -> 2 1 }T
+
+\ ------------------------------------------------------------------------
+TESTING >R R> R@
+
+T{ : GR1 >R R> ; -> }T
+T{ : GR2 >R R@ R> DROP ; -> }T
+T{ 123 GR1 -> 123 }T
+T{ 123 GR2 -> 123 }T
+T{ 1S GR1 -> 1S }T ( RETURN STACK HOLDS CELLS )
+
+\ ------------------------------------------------------------------------
+TESTING ADD/SUBTRACT: + - 1+ 1- ABS NEGATE
+
+T{ 0 5 + -> 5 }T
+T{ 5 0 + -> 5 }T
+T{ 0 -5 + -> -5 }T
+T{ -5 0 + -> -5 }T
+T{ 1 2 + -> 3 }T
+T{ 1 -2 + -> -1 }T
+T{ -1 2 + -> 1 }T
+T{ -1 -2 + -> -3 }T
+T{ -1 1 + -> 0 }T
+T{ MID-UINT 1 + -> MID-UINT+1 }T
+
+T{ 0 5 - -> -5 }T
+T{ 5 0 - -> 5 }T
+T{ 0 -5 - -> 5 }T
+T{ -5 0 - -> -5 }T
+T{ 1 2 - -> -1 }T
+T{ 1 -2 - -> 3 }T
+T{ -1 2 - -> -3 }T
+T{ -1 -2 - -> 1 }T
+T{ 0 1 - -> -1 }T
+T{ MID-UINT+1 1 - -> MID-UINT }T
+
+T{ 0 1+ -> 1 }T
+T{ -1 1+ -> 0 }T
+T{ 1 1+ -> 2 }T
+T{ MID-UINT 1+ -> MID-UINT+1 }T
+
+T{ 2 1- -> 1 }T
+T{ 1 1- -> 0 }T
+T{ 0 1- -> -1 }T
+T{ MID-UINT+1 1- -> MID-UINT }T
+
+T{ 0 NEGATE -> 0 }T
+T{ 1 NEGATE -> -1 }T
+T{ -1 NEGATE -> 1 }T
+T{ 2 NEGATE -> -2 }T
+T{ -2 NEGATE -> 2 }T
+
+T{ 0 ABS -> 0 }T
+T{ 1 ABS -> 1 }T
+T{ -1 ABS -> 1 }T
+T{ MIN-INT ABS -> MID-UINT+1 }T
+
+\ ------------------------------------------------------------------------
+TESTING MULTIPLY: S>D * M* UM*
+
+T{ 0 S>D -> 0 0 }T
+T{ 1 S>D -> 1 0 }T
+T{ 2 S>D -> 2 0 }T
+T{ -1 S>D -> -1 -1 }T
+T{ -2 S>D -> -2 -1 }T
+T{ MIN-INT S>D -> MIN-INT -1 }T
+T{ MAX-INT S>D -> MAX-INT 0 }T
+
+T{ 0 0 M* -> 0 S>D }T
+T{ 0 1 M* -> 0 S>D }T
+T{ 1 0 M* -> 0 S>D }T
+T{ 1 2 M* -> 2 S>D }T
+T{ 2 1 M* -> 2 S>D }T
+T{ 3 3 M* -> 9 S>D }T
+T{ -3 3 M* -> -9 S>D }T
+T{ 3 -3 M* -> -9 S>D }T
+T{ -3 -3 M* -> 9 S>D }T
+T{ 0 MIN-INT M* -> 0 S>D }T
+T{ 1 MIN-INT M* -> MIN-INT S>D }T
+T{ 2 MIN-INT M* -> 0 1S }T
+T{ 0 MAX-INT M* -> 0 S>D }T
+T{ 1 MAX-INT M* -> MAX-INT S>D }T
+T{ 2 MAX-INT M* -> MAX-INT 1 LSHIFT 0 }T
+T{ MIN-INT MIN-INT M* -> 0 MSB 1 RSHIFT }T
+T{ MAX-INT MIN-INT M* -> MSB MSB 2/ }T
+T{ MAX-INT MAX-INT M* -> 1 MSB 2/ INVERT }T
+
+T{ 0 0 * -> 0 }T \ TEST IDENTITIES
+T{ 0 1 * -> 0 }T
+T{ 1 0 * -> 0 }T
+T{ 1 2 * -> 2 }T
+T{ 2 1 * -> 2 }T
+T{ 3 3 * -> 9 }T
+T{ -3 3 * -> -9 }T
+T{ 3 -3 * -> -9 }T
+T{ -3 -3 * -> 9 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 * -> MID-UINT+1 }T
+T{ MID-UINT+1 2 RSHIFT 4 * -> MID-UINT+1 }T
+T{ MID-UINT+1 1 RSHIFT MID-UINT+1 OR 2 * -> MID-UINT+1 }T
+
+T{ 0 0 UM* -> 0 0 }T
+T{ 0 1 UM* -> 0 0 }T
+T{ 1 0 UM* -> 0 0 }T
+T{ 1 2 UM* -> 2 0 }T
+T{ 2 1 UM* -> 2 0 }T
+T{ 3 3 UM* -> 9 0 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 UM* -> MID-UINT+1 0 }T
+T{ MID-UINT+1 2 UM* -> 0 1 }T
+T{ MID-UINT+1 4 UM* -> 0 2 }T
+T{ 1S 2 UM* -> 1S 1 LSHIFT 1 }T
+T{ MAX-UINT MAX-UINT UM* -> 1 1 INVERT }T
+
+\ ------------------------------------------------------------------------
+TESTING DIVIDE: FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD
+
+T{ 0 S>D 1 FM/MOD -> 0 0 }T
+T{ 1 S>D 1 FM/MOD -> 0 1 }T
+T{ 2 S>D 1 FM/MOD -> 0 2 }T
+T{ -1 S>D 1 FM/MOD -> 0 -1 }T
+T{ -2 S>D 1 FM/MOD -> 0 -2 }T
+T{ 0 S>D -1 FM/MOD -> 0 0 }T
+T{ 1 S>D -1 FM/MOD -> 0 -1 }T
+T{ 2 S>D -1 FM/MOD -> 0 -2 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -1 FM/MOD -> 0 2 }T
+T{ 2 S>D 2 FM/MOD -> 0 1 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -2 FM/MOD -> 0 1 }T
+T{ 7 S>D 3 FM/MOD -> 1 2 }T
+T{ 7 S>D -3 FM/MOD -> -2 -3 }T
+T{ -7 S>D 3 FM/MOD -> 2 -3 }T
+T{ -7 S>D -3 FM/MOD -> -1 2 }T
+T{ MAX-INT S>D 1 FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT FM/MOD -> 0 1 }T
+T{ MIN-INT S>D MIN-INT FM/MOD -> 0 1 }T
+T{ 1S 1 4 FM/MOD -> 3 MAX-INT }T
+T{ 1 MIN-INT M* 1 FM/MOD -> 0 MIN-INT }T
+T{ 1 MIN-INT M* MIN-INT FM/MOD -> 0 1 }T
+T{ 2 MIN-INT M* 2 FM/MOD -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT FM/MOD -> 0 2 }T
+T{ 1 MAX-INT M* 1 FM/MOD -> 0 MAX-INT }T
+T{ 1 MAX-INT M* MAX-INT FM/MOD -> 0 1 }T
+T{ 2 MAX-INT M* 2 FM/MOD -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT FM/MOD -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT FM/MOD -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT FM/MOD -> 0 MAX-INT }T
+
+T{ 0 S>D 1 SM/REM -> 0 0 }T
+T{ 1 S>D 1 SM/REM -> 0 1 }T
+T{ 2 S>D 1 SM/REM -> 0 2 }T
+T{ -1 S>D 1 SM/REM -> 0 -1 }T
+T{ -2 S>D 1 SM/REM -> 0 -2 }T
+T{ 0 S>D -1 SM/REM -> 0 0 }T
+T{ 1 S>D -1 SM/REM -> 0 -1 }T
+T{ 2 S>D -1 SM/REM -> 0 -2 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -1 SM/REM -> 0 2 }T
+T{ 2 S>D 2 SM/REM -> 0 1 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -2 SM/REM -> 0 1 }T
+T{ 7 S>D 3 SM/REM -> 1 2 }T
+T{ 7 S>D -3 SM/REM -> 1 -2 }T
+T{ -7 S>D 3 SM/REM -> -1 -2 }T
+T{ -7 S>D -3 SM/REM -> -1 2 }T
+T{ MAX-INT S>D 1 SM/REM -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 SM/REM -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT SM/REM -> 0 1 }T
+T{ MIN-INT S>D MIN-INT SM/REM -> 0 1 }T
+T{ 1S 1 4 SM/REM -> 3 MAX-INT }T
+T{ 2 MIN-INT M* 2 SM/REM -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT SM/REM -> 0 2 }T
+T{ 2 MAX-INT M* 2 SM/REM -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT SM/REM -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT SM/REM -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT SM/REM -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT SM/REM -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT SM/REM -> 0 MAX-INT }T
+
+T{ 0 0 1 UM/MOD -> 0 0 }T
+T{ 1 0 1 UM/MOD -> 0 1 }T
+T{ 1 0 2 UM/MOD -> 1 0 }T
+T{ 3 0 2 UM/MOD -> 1 1 }T
+T{ MAX-UINT 2 UM* 2 UM/MOD -> 0 MAX-UINT }T
+T{ MAX-UINT 2 UM* MAX-UINT UM/MOD -> 0 2 }T
+T{ MAX-UINT MAX-UINT UM* MAX-UINT UM/MOD -> 0 MAX-UINT }T
+
+: IFFLOORED
+ [ -3 2 / -2 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+: IFSYM
+ [ -3 2 / -1 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+\ THE SYSTEM MIGHT DO EITHER FLOORED OR SYMMETRIC DIVISION.
+\ SINCE WE HAVE ALREADY TESTED M*, FM/MOD, AND SM/REM WE CAN USE THEM IN TEST.
+
+IFFLOORED : T/MOD >R S>D R> FM/MOD ;
+IFFLOORED : T/ T/MOD SWAP DROP ;
+IFFLOORED : TMOD T/MOD DROP ;
+IFFLOORED : T*/MOD >R M* R> FM/MOD ;
+IFFLOORED : T*/ T*/MOD SWAP DROP ;
+IFSYM : T/MOD >R S>D R> SM/REM ;
+IFSYM : T/ T/MOD SWAP DROP ;
+IFSYM : TMOD T/MOD DROP ;
+IFSYM : T*/MOD >R M* R> SM/REM ;
+IFSYM : T*/ T*/MOD SWAP DROP ;
+
+T{ 0 1 /MOD -> 0 1 T/MOD }T
+T{ 1 1 /MOD -> 1 1 T/MOD }T
+T{ 2 1 /MOD -> 2 1 T/MOD }T
+T{ -1 1 /MOD -> -1 1 T/MOD }T
+T{ -2 1 /MOD -> -2 1 T/MOD }T
+T{ 0 -1 /MOD -> 0 -1 T/MOD }T
+T{ 1 -1 /MOD -> 1 -1 T/MOD }T
+T{ 2 -1 /MOD -> 2 -1 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -1 /MOD -> -2 -1 T/MOD }T
+T{ 2 2 /MOD -> 2 2 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -2 /MOD -> -2 -2 T/MOD }T
+T{ 7 3 /MOD -> 7 3 T/MOD }T
+T{ 7 -3 /MOD -> 7 -3 T/MOD }T
+T{ -7 3 /MOD -> -7 3 T/MOD }T
+T{ -7 -3 /MOD -> -7 -3 T/MOD }T
+T{ MAX-INT 1 /MOD -> MAX-INT 1 T/MOD }T
+T{ MIN-INT 1 /MOD -> MIN-INT 1 T/MOD }T
+T{ MAX-INT MAX-INT /MOD -> MAX-INT MAX-INT T/MOD }T
+T{ MIN-INT MIN-INT /MOD -> MIN-INT MIN-INT T/MOD }T
+
+T{ 0 1 / -> 0 1 T/ }T
+T{ 1 1 / -> 1 1 T/ }T
+T{ 2 1 / -> 2 1 T/ }T
+T{ -1 1 / -> -1 1 T/ }T
+T{ -2 1 / -> -2 1 T/ }T
+T{ 0 -1 / -> 0 -1 T/ }T
+T{ 1 -1 / -> 1 -1 T/ }T
+T{ 2 -1 / -> 2 -1 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -1 / -> -2 -1 T/ }T
+T{ 2 2 / -> 2 2 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -2 / -> -2 -2 T/ }T
+T{ 7 3 / -> 7 3 T/ }T
+T{ 7 -3 / -> 7 -3 T/ }T
+T{ -7 3 / -> -7 3 T/ }T
+T{ -7 -3 / -> -7 -3 T/ }T
+T{ MAX-INT 1 / -> MAX-INT 1 T/ }T
+T{ MIN-INT 1 / -> MIN-INT 1 T/ }T
+T{ MAX-INT MAX-INT / -> MAX-INT MAX-INT T/ }T
+T{ MIN-INT MIN-INT / -> MIN-INT MIN-INT T/ }T
+
+T{ 0 1 MOD -> 0 1 TMOD }T
+T{ 1 1 MOD -> 1 1 TMOD }T
+T{ 2 1 MOD -> 2 1 TMOD }T
+T{ -1 1 MOD -> -1 1 TMOD }T
+T{ -2 1 MOD -> -2 1 TMOD }T
+T{ 0 -1 MOD -> 0 -1 TMOD }T
+T{ 1 -1 MOD -> 1 -1 TMOD }T
+T{ 2 -1 MOD -> 2 -1 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -1 MOD -> -2 -1 TMOD }T
+T{ 2 2 MOD -> 2 2 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -2 MOD -> -2 -2 TMOD }T
+T{ 7 3 MOD -> 7 3 TMOD }T
+T{ 7 -3 MOD -> 7 -3 TMOD }T
+T{ -7 3 MOD -> -7 3 TMOD }T
+T{ -7 -3 MOD -> -7 -3 TMOD }T
+T{ MAX-INT 1 MOD -> MAX-INT 1 TMOD }T
+T{ MIN-INT 1 MOD -> MIN-INT 1 TMOD }T
+T{ MAX-INT MAX-INT MOD -> MAX-INT MAX-INT TMOD }T
+T{ MIN-INT MIN-INT MOD -> MIN-INT MIN-INT TMOD }T
+
+T{ 0 2 1 */ -> 0 2 1 T*/ }T
+T{ 1 2 1 */ -> 1 2 1 T*/ }T
+T{ 2 2 1 */ -> 2 2 1 T*/ }T
+T{ -1 2 1 */ -> -1 2 1 T*/ }T
+T{ -2 2 1 */ -> -2 2 1 T*/ }T
+T{ 0 2 -1 */ -> 0 2 -1 T*/ }T
+T{ 1 2 -1 */ -> 1 2 -1 T*/ }T
+T{ 2 2 -1 */ -> 2 2 -1 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -1 */ -> -2 2 -1 T*/ }T
+T{ 2 2 2 */ -> 2 2 2 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -2 */ -> -2 2 -2 T*/ }T
+T{ 7 2 3 */ -> 7 2 3 T*/ }T
+T{ 7 2 -3 */ -> 7 2 -3 T*/ }T
+T{ -7 2 3 */ -> -7 2 3 T*/ }T
+T{ -7 2 -3 */ -> -7 2 -3 T*/ }T
+T{ MAX-INT 2 MAX-INT */ -> MAX-INT 2 MAX-INT T*/ }T
+T{ MIN-INT 2 MIN-INT */ -> MIN-INT 2 MIN-INT T*/ }T
+
+T{ 0 2 1 */MOD -> 0 2 1 T*/MOD }T
+T{ 1 2 1 */MOD -> 1 2 1 T*/MOD }T
+T{ 2 2 1 */MOD -> 2 2 1 T*/MOD }T
+T{ -1 2 1 */MOD -> -1 2 1 T*/MOD }T
+T{ -2 2 1 */MOD -> -2 2 1 T*/MOD }T
+T{ 0 2 -1 */MOD -> 0 2 -1 T*/MOD }T
+T{ 1 2 -1 */MOD -> 1 2 -1 T*/MOD }T
+T{ 2 2 -1 */MOD -> 2 2 -1 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -1 */MOD -> -2 2 -1 T*/MOD }T
+T{ 2 2 2 */MOD -> 2 2 2 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -2 */MOD -> -2 2 -2 T*/MOD }T
+T{ 7 2 3 */MOD -> 7 2 3 T*/MOD }T
+T{ 7 2 -3 */MOD -> 7 2 -3 T*/MOD }T
+T{ -7 2 3 */MOD -> -7 2 3 T*/MOD }T
+T{ -7 2 -3 */MOD -> -7 2 -3 T*/MOD }T
+T{ MAX-INT 2 MAX-INT */MOD -> MAX-INT 2 MAX-INT T*/MOD }T
+T{ MIN-INT 2 MIN-INT */MOD -> MIN-INT 2 MIN-INT T*/MOD }T
+
+\ ------------------------------------------------------------------------
+TESTING HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2! ALIGN ALIGNED +! ALLOT
+
+HERE 1 ALLOT
+HERE
+CONSTANT 2NDA
+CONSTANT 1STA
+T{ 1STA 2NDA U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STA 1+ -> 2NDA }T \ ... BY ONE ADDRESS UNIT
+( MISSING TEST: NEGATIVE ALLOT )
+
+HERE 1 ,
+HERE 2 ,
+CONSTANT 2ND
+CONSTANT 1ST
+T{ 1ST 2ND U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1ST CELL+ -> 2ND }T \ ... BY ONE CELL
+T{ 1ST 1 CELLS + -> 2ND }T
+T{ 1ST @ 2ND @ -> 1 2 }T
+T{ 5 1ST ! -> }T
+T{ 1ST @ 2ND @ -> 5 2 }T
+T{ 6 2ND ! -> }T
+T{ 1ST @ 2ND @ -> 5 6 }T
+T{ 1ST 2@ -> 6 5 }T
+T{ 2 1 1ST 2! -> }T
+T{ 1ST 2@ -> 2 1 }T
+T{ 1S 1ST ! 1ST @ -> 1S }T \ CAN STORE CELL-WIDE VALUE
+
+HERE 1 C,
+HERE 2 C,
+CONSTANT 2NDC
+CONSTANT 1STC
+T{ 1STC 2NDC U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STC CHAR+ -> 2NDC }T \ ... BY ONE CHAR
+T{ 1STC 1 CHARS + -> 2NDC }T
+T{ 1STC C@ 2NDC C@ -> 1 2 }T
+T{ 3 1STC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 2 }T
+T{ 4 2NDC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 4 }T
+
+ALIGN 1 ALLOT HERE ALIGN HERE 3 CELLS ALLOT
+CONSTANT A-ADDR CONSTANT UA-ADDR
+T{ UA-ADDR ALIGNED -> A-ADDR }T
+T{ 1 A-ADDR C! A-ADDR C@ -> 1 }T
+T{ 1234 A-ADDR ! A-ADDR @ -> 1234 }T
+T{ 123 456 A-ADDR 2! A-ADDR 2@ -> 123 456 }T
+T{ 2 A-ADDR CHAR+ C! A-ADDR CHAR+ C@ -> 2 }T
+T{ 3 A-ADDR CELL+ C! A-ADDR CELL+ C@ -> 3 }T
+T{ 1234 A-ADDR CELL+ ! A-ADDR CELL+ @ -> 1234 }T
+T{ 123 456 A-ADDR CELL+ 2! A-ADDR CELL+ 2@ -> 123 456 }T
+
+: BITS ( X -- U )
+ 0 SWAP BEGIN DUP WHILE DUP MSB AND IF >R 1+ R> THEN 2* REPEAT DROP ;
+( CHARACTERS >= 1 AU, <= SIZE OF CELL, >= 8 BITS )
+T{ 1 CHARS 1 < -> <FALSE> }T
+T{ 1 CHARS 1 CELLS > -> <FALSE> }T
+( TBD: HOW TO FIND NUMBER OF BITS? )
+
+( CELLS >= 1 AU, INTEGRAL MULTIPLE OF CHAR SIZE, >= 16 BITS )
+T{ 1 CELLS 1 < -> <FALSE> }T
+T{ 1 CELLS 1 CHARS MOD -> 0 }T
+T{ 1S BITS 10 < -> <FALSE> }T
+
+T{ 0 1ST ! -> }T
+T{ 1 1ST +! -> }T
+T{ 1ST @ -> 1 }T
+T{ -1 1ST +! 1ST @ -> 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING CHAR [CHAR] [ ] BL S"
+
+T{ BL -> 20 }T
+T{ CHAR X -> 58 }T
+T{ CHAR HELLO -> 48 }T
+T{ : GC1 [CHAR] X ; -> }T
+T{ : GC2 [CHAR] HELLO ; -> }T
+T{ GC1 -> 58 }T
+T{ GC2 -> 48 }T
+T{ : GC3 [ GC1 ] LITERAL ; -> }T
+T{ GC3 -> 58 }T
+T{ : GC4 S" XY" ; -> }T
+T{ GC4 SWAP DROP -> 2 }T
+T{ GC4 DROP DUP C@ SWAP CHAR+ C@ -> 58 59 }T
+
+\ ------------------------------------------------------------------------
+TESTING ' ['] FIND EXECUTE IMMEDIATE COUNT LITERAL POSTPONE STATE
+
+T{ : GT1 123 ; -> }T
+T{ ' GT1 EXECUTE -> 123 }T
+T{ : GT2 ['] GT1 ; IMMEDIATE -> }T
+T{ GT2 EXECUTE -> 123 }T
+HERE 3 C, CHAR G C, CHAR T C, CHAR 1 C, CONSTANT GT1STRING
+HERE 3 C, CHAR G C, CHAR T C, CHAR 2 C, CONSTANT GT2STRING
+T{ GT1STRING FIND -> ' GT1 -1 }T
+T{ GT2STRING FIND -> ' GT2 1 }T
+( HOW TO SEARCH FOR NON-EXISTENT WORD? )
+T{ : GT3 GT2 LITERAL ; -> }T
+T{ GT3 -> ' GT1 }T
+T{ GT1STRING COUNT -> GT1STRING CHAR+ 3 }T
+
+T{ : GT4 POSTPONE GT1 ; IMMEDIATE -> }T
+T{ : GT5 GT4 ; -> }T
+T{ GT5 -> 123 }T
+T{ : GT6 345 ; IMMEDIATE -> }T
+T{ : GT7 POSTPONE GT6 ; -> }T
+T{ GT7 -> 345 }T
+
+T{ : GT8 STATE @ ; IMMEDIATE -> }T
+T{ GT8 -> 0 }T
+T{ : GT9 GT8 LITERAL ; -> }T
+T{ GT9 0= -> <FALSE> }T
+
+\ ------------------------------------------------------------------------
+TESTING IF ELSE THEN BEGIN WHILE REPEAT UNTIL RECURSE
+
+T{ : GI1 IF 123 THEN ; -> }T
+T{ : GI2 IF 123 ELSE 234 THEN ; -> }T
+T{ 0 GI1 -> }T
+T{ 1 GI1 -> 123 }T
+T{ -1 GI1 -> 123 }T
+T{ 0 GI2 -> 234 }T
+T{ 1 GI2 -> 123 }T
+T{ -1 GI1 -> 123 }T
+
+T{ : GI3 BEGIN DUP 5 < WHILE DUP 1+ REPEAT ; -> }T
+T{ 0 GI3 -> 0 1 2 3 4 5 }T
+T{ 4 GI3 -> 4 5 }T
+T{ 5 GI3 -> 5 }T
+T{ 6 GI3 -> 6 }T
+
+T{ : GI4 BEGIN DUP 1+ DUP 5 > UNTIL ; -> }T
+T{ 3 GI4 -> 3 4 5 6 }T
+T{ 5 GI4 -> 5 6 }T
+T{ 6 GI4 -> 6 7 }T
+
+T{ : GI5 BEGIN DUP 2 > WHILE DUP 5 < WHILE DUP 1+ REPEAT 123 ELSE 345 THEN ; -> }T
+T{ 1 GI5 -> 1 345 }T
+T{ 2 GI5 -> 2 345 }T
+T{ 3 GI5 -> 3 4 5 123 }T
+T{ 4 GI5 -> 4 5 123 }T
+T{ 5 GI5 -> 5 123 }T
+
+T{ : GI6 ( N -- 0,1,..N ) DUP IF DUP >R 1- RECURSE R> THEN ; -> }T
+T{ 0 GI6 -> 0 }T
+T{ 1 GI6 -> 0 1 }T
+T{ 2 GI6 -> 0 1 2 }T
+T{ 3 GI6 -> 0 1 2 3 }T
+T{ 4 GI6 -> 0 1 2 3 4 }T
+
+\ ------------------------------------------------------------------------
+TESTING DO LOOP +LOOP I J UNLOOP LEAVE EXIT
+
+T{ : GD1 DO I LOOP ; -> }T
+T{ 4 1 GD1 -> 1 2 3 }T
+T{ 2 -1 GD1 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD1 -> MID-UINT }T
+
+T{ : GD2 DO I -1 +LOOP ; -> }T
+T{ 1 4 GD2 -> 4 3 2 1 }T
+T{ -1 2 GD2 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD2 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD3 DO 1 0 DO J LOOP LOOP ; -> }T
+T{ 4 1 GD3 -> 1 2 3 }T
+T{ 2 -1 GD3 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD3 -> MID-UINT }T
+
+T{ : GD4 DO 1 0 DO J LOOP -1 +LOOP ; -> }T
+T{ 1 4 GD4 -> 4 3 2 1 }T
+T{ -1 2 GD4 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD4 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD5 123 SWAP 0 DO I 4 > IF DROP 234 LEAVE THEN LOOP ; -> }T
+T{ 1 GD5 -> 123 }T
+T{ 5 GD5 -> 123 }T
+T{ 6 GD5 -> 234 }T
+
+T{ : GD6 ( PAT: T{0 0}T,T{0 0}TT{1 0}TT{1 1}T,T{0 0}TT{1 0}TT{1 1}TT{2 0}TT{2 1}TT{2 2}T )
+ 0 SWAP 0 DO
+ I 1+ 0 DO I J + 3 = IF I UNLOOP I UNLOOP EXIT THEN 1+ LOOP
+ LOOP ; -> }T
+T{ 1 GD6 -> 1 }T
+T{ 2 GD6 -> 3 }T
+T{ 3 GD6 -> 4 1 2 }T
+
+\ ------------------------------------------------------------------------
+TESTING DEFINING WORDS: : ; CONSTANT VARIABLE CREATE DOES> >BODY
+
+T{ 123 CONSTANT X123 -> }T
+T{ X123 -> 123 }T
+T{ : EQU CONSTANT ; -> }T
+T{ X123 EQU Y123 -> }T
+T{ Y123 -> 123 }T
+
+T{ VARIABLE V1 -> }T
+T{ 123 V1 ! -> }T
+T{ V1 @ -> 123 }T
+
+T{ : NOP : POSTPONE ; ; -> }T
+T{ NOP NOP1 NOP NOP2 -> }T
+T{ NOP1 -> }T
+T{ NOP2 -> }T
+
+T{ : DOES1 DOES> @ 1 + ; -> }T
+T{ : DOES2 DOES> @ 2 + ; -> }T
+T{ CREATE CR1 -> }T
+T{ CR1 -> HERE }T
+T{ ' CR1 >BODY -> HERE }T
+T{ 1 , -> }T
+T{ CR1 @ -> 1 }T
+T{ DOES1 -> }T
+T{ CR1 -> 2 }T
+T{ DOES2 -> }T
+T{ CR1 -> 3 }T
+
+T{ : WEIRD: CREATE DOES> 1 + DOES> 2 + ; -> }T
+T{ WEIRD: W1 -> }T
+T{ ' W1 >BODY -> HERE }T
+T{ W1 -> HERE 1 + }T
+T{ W1 -> HERE 2 + }T
+
+\ ------------------------------------------------------------------------
+TESTING EVALUATE
+
+: GE1 S" 123" ; IMMEDIATE
+: GE2 S" 123 1+" ; IMMEDIATE
+: GE3 S" : GE4 345 ;" ;
+: GE5 EVALUATE ; IMMEDIATE
+
+T{ GE1 EVALUATE -> 123 }T ( TEST EVALUATE IN INTERP. STATE )
+T{ GE2 EVALUATE -> 124 }T
+T{ GE3 EVALUATE -> }T
+T{ GE4 -> 345 }T
+
+T{ : GE6 GE1 GE5 ; -> }T ( TEST EVALUATE IN COMPILE STATE )
+T{ GE6 -> 123 }T
+T{ : GE7 GE2 GE5 ; -> }T
+T{ GE7 -> 124 }T
+
+\ ------------------------------------------------------------------------
+TESTING SOURCE >IN WORD
+
+: GS1 S" SOURCE" 2DUP EVALUATE
+ >R SWAP >R = R> R> = ;
+T{ GS1 -> <TRUE> <TRUE> }T
+
+VARIABLE SCANS
+: RESCAN? -1 SCANS +! SCANS @ IF 0 >IN ! THEN ;
+
+T{ 2 SCANS !
+345 RESCAN?
+-> 345 345 }T
+
+: GS2 5 SCANS ! S" 123 RESCAN?" EVALUATE ;
+T{ GS2 -> 123 123 123 123 123 }T
+
+: GS3 WORD COUNT SWAP C@ ;
+T{ BL GS3 HELLO -> 5 CHAR H }T
+T{ CHAR " GS3 GOODBYE" -> 7 CHAR G }T
+T{ BL GS3
+DROP -> 0 }T \ BLANK LINE RETURN ZERO-LENGTH STRING
+
+: GS4 SOURCE >IN ! DROP ;
+T{ GS4 123 456
+-> }T
+
+\ ------------------------------------------------------------------------
+TESTING <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL
+
+: S= \ ( ADDR1 C1 ADDR2 C2 -- T/F ) COMPARE TWO STRINGS.
+ >R SWAP R@ = IF \ MAKE SURE STRINGS HAVE SAME LENGTH
+ R> ?DUP IF \ IF NON-EMPTY STRINGS
+ 0 DO
+ OVER C@ OVER C@ - IF
+ 2DROP <FALSE> UNLOOP EXIT THEN
+ SWAP CHAR+ SWAP CHAR+
+ LOOP
+ THEN
+ 2DROP <TRUE> \ IF WE GET HERE, STRINGS MATCH
+ ELSE
+ R> DROP 2DROP <FALSE> \ LENGTHS MISMATCH
+ THEN ;
+
+: GP1 <# 41 HOLD 42 HOLD 0 0 #> S" BA" S= ;
+T{ GP1 -> <TRUE> }T
+
+: GP2 <# -1 SIGN 0 SIGN -1 SIGN 0 0 #> S" --" S= ;
+T{ GP2 -> <TRUE> }T
+
+: GP3 <# 1 0 # # #> S" 01" S= ;
+T{ GP3 -> <TRUE> }T
+
+: GP4 <# 1 0 #S #> S" 1" S= ;
+T{ GP4 -> <TRUE> }T
+
+24 CONSTANT MAX-BASE \ BASE 2 .. 36
+: COUNT-BITS
+ 0 0 INVERT BEGIN DUP WHILE >R 1+ R> 2* REPEAT DROP ;
+COUNT-BITS 2* CONSTANT #BITS-UD \ NUMBER OF BITS IN UD
+
+: GP5
+ BASE @ <TRUE>
+ MAX-BASE 1+ 2 DO \ FOR EACH POSSIBLE BASE
+ I BASE ! \ TBD: ASSUMES BASE WORKS
+ I 0 <# #S #> S" 10" S= AND
+ LOOP
+ SWAP BASE ! ;
+T{ GP5 -> <TRUE> }T
+
+: GP6
+ BASE @ >R 2 BASE !
+ MAX-UINT MAX-UINT <# #S #> \ MAXIMUM UD TO BINARY
+ R> BASE ! \ S: C-ADDR U
+ DUP #BITS-UD = SWAP
+ 0 DO \ S: C-ADDR FLAG
+ OVER C@ [CHAR] 1 = AND \ ALL ONES
+ >R CHAR+ R>
+ LOOP SWAP DROP ;
+T{ GP6 -> <TRUE> }T
+
+: GP7
+ BASE @ >R MAX-BASE BASE !
+ <TRUE>
+ A 0 DO
+ I 0 <# #S #>
+ 1 = SWAP C@ I 30 + = AND AND
+ LOOP
+ MAX-BASE A DO
+ I 0 <# #S #>
+ 1 = SWAP C@ 41 I A - + = AND AND
+ LOOP
+ R> BASE ! ;
+
+T{ GP7 -> <TRUE> }T
+
+\ >NUMBER TESTS
+CREATE GN-BUF 0 C,
+: GN-STRING GN-BUF 1 ;
+: GN-CONSUMED GN-BUF CHAR+ 0 ;
+: GN' [CHAR] ' WORD CHAR+ C@ GN-BUF C! GN-STRING ;
+
+T{ 0 0 GN' 0' >NUMBER -> 0 0 GN-CONSUMED }T
+T{ 0 0 GN' 1' >NUMBER -> 1 0 GN-CONSUMED }T
+T{ 1 0 GN' 1' >NUMBER -> BASE @ 1+ 0 GN-CONSUMED }T
+T{ 0 0 GN' -' >NUMBER -> 0 0 GN-STRING }T \ SHOULD FAIL TO CONVERT THESE
+T{ 0 0 GN' +' >NUMBER -> 0 0 GN-STRING }T
+T{ 0 0 GN' .' >NUMBER -> 0 0 GN-STRING }T
+
+: >NUMBER-BASED
+ BASE @ >R BASE ! >NUMBER R> BASE ! ;
+
+T{ 0 0 GN' 2' 10 >NUMBER-BASED -> 2 0 GN-CONSUMED }T
+T{ 0 0 GN' 2' 2 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' F' 10 >NUMBER-BASED -> F 0 GN-CONSUMED }T
+T{ 0 0 GN' G' 10 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' G' MAX-BASE >NUMBER-BASED -> 10 0 GN-CONSUMED }T
+T{ 0 0 GN' Z' MAX-BASE >NUMBER-BASED -> 23 0 GN-CONSUMED }T
+
+: GN1 \ ( UD BASE -- UD' LEN ) UD SHOULD EQUAL UD' AND LEN SHOULD BE ZERO.
+ BASE @ >R BASE !
+ <# #S #>
+ 0 0 2SWAP >NUMBER SWAP DROP \ RETURN LENGTH ONLY
+ R> BASE ! ;
+T{ 0 0 2 GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 2 GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP 2 GN1 -> MAX-UINT DUP 0 }T
+T{ 0 0 MAX-BASE GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 MAX-BASE GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP MAX-BASE GN1 -> MAX-UINT DUP 0 }T
+
+: GN2 \ ( -- 16 10 )
+ BASE @ >R HEX BASE @ DECIMAL BASE @ R> BASE ! ;
+T{ GN2 -> 10 A }T
+
+\ ------------------------------------------------------------------------
+TESTING FILL MOVE
+
+CREATE FBUF 00 C, 00 C, 00 C,
+CREATE SBUF 12 C, 34 C, 56 C,
+: SEEBUF FBUF C@ FBUF CHAR+ C@ FBUF CHAR+ CHAR+ C@ ;
+
+T{ FBUF 0 20 FILL -> }T
+T{ SEEBUF -> 00 00 00 }T
+
+T{ FBUF 1 20 FILL -> }T
+T{ SEEBUF -> 20 00 00 }T
+
+T{ FBUF 3 20 FILL -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ FBUF FBUF 3 CHARS MOVE -> }T \ BIZARRE SPECIAL CASE
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 0 CHARS MOVE -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 1 CHARS MOVE -> }T
+T{ SEEBUF -> 12 20 20 }T
+
+T{ SBUF FBUF 3 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 56 }T
+
+T{ FBUF FBUF CHAR+ 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 12 34 }T
+
+T{ FBUF CHAR+ FBUF 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 34 }T
+
+\ ------------------------------------------------------------------------
+TESTING OUTPUT: . ." CR EMIT SPACE SPACES TYPE U.
+
+: OUTPUT-TEST
+ ." YOU SHOULD SEE THE STANDARD GRAPHIC CHARACTERS:" CR
+ 41 BL DO I EMIT LOOP CR
+ 61 41 DO I EMIT LOOP CR
+ 7F 61 DO I EMIT LOOP CR
+ ." YOU SHOULD SEE 0-9 SEPARATED BY A SPACE:" CR
+ 9 1+ 0 DO I . LOOP CR
+ ." YOU SHOULD SEE 0-9 (WITH NO SPACES):" CR
+ [CHAR] 9 1+ [CHAR] 0 DO I 0 SPACES EMIT LOOP CR
+ ." YOU SHOULD SEE A-G SEPARATED BY A SPACE:" CR
+ [CHAR] G 1+ [CHAR] A DO I EMIT SPACE LOOP CR
+ ." YOU SHOULD SEE 0-5 SEPARATED BY TWO SPACES:" CR
+ 5 1+ 0 DO I [CHAR] 0 + EMIT 2 SPACES LOOP CR
+ ." YOU SHOULD SEE TWO SEPARATE LINES:" CR
+ S" LINE 1" TYPE CR S" LINE 2" TYPE CR
+ ." YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:" CR
+ ." SIGNED: " MIN-INT . MAX-INT . CR
+ ." UNSIGNED: " 0 U. MAX-UINT U. CR
+;
+
+T{ OUTPUT-TEST -> }T
+\ ------------------------------------------------------------------------
+TESTING INPUT: ACCEPT
+
+CREATE ABUF 80 CHARS ALLOT
+
+: ACCEPT-TEST
+ CR ." PLEASE TYPE UP TO 80 CHARACTERS:" CR
+ ABUF 80 ACCEPT
+ CR ." RECEIVED: " [CHAR] " EMIT
+ ABUF SWAP TYPE [CHAR] " EMIT CR
+;
+
+T{ ACCEPT-TEST -> }T
+Vingt fois sur le métier remettez votre ouvrage, ...
+\ ------------------------------------------------------------------------
+TESTING DICTIONARY SEARCH RULES
+
+T{ : GDX 123 ; : GDX GDX 234 ; -> }T
+
+T{ GDX -> 123 234 }T
+
+CR .( End of Core word set tests) CR
+
+
+
+RST_STATE ; so ANS_COMPLEMENT_xx_MPY is conserved ;
+\ NOECHO ; if an error occurs, comment this line before new download to find it.
+
+
+\ From: John Hayes S1I
+\ Subject: tester.fr
+\ Date: Mon, 27 Nov 95 13:10:09 PST
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.1
+
+\ 22/1/09 The words { and } have been changed to T{ and }T respectively to
+\ agree with the Forth 200X file ttester.fs. This avoids clashes with
+\ locals using { ... } and the FSL use of }
+
+
+\ 13/05/14 jmt. added colorised error messages.
+
+
+
+ 0 CONSTANT FALSE
+-1 CONSTANT TRUE
+
+\ SET THE FOLLOWING FLAG TO TRUE FOR MORE VERBOSE OUTPUT; THIS MAY
+\ ALLOW YOU TO TELL WHICH TEST CAUSED YOUR SYSTEM TO HANG.
+VARIABLE VERBOSE
+ FALSE VERBOSE !
+\ TRUE VERBOSE !
+
+\ : EMPTY-STACK ( ... -- ) \ EMPTY STACK: HANDLES UNDERFLOWED STACK TOO.
+\ DEPTH ?DUP
+\ IF DUP 0< IF NEGATE 0
+\ DO 0 LOOP
+\ ELSE 0 DO DROP LOOP THEN
+\ THEN ;
+\
+\ : ERROR \ ( C-ADDR U -- ) DISPLAY AN ERROR MESSAGE FOLLOWED BY
+\ \ THE LINE THAT HAD THE ERROR.
+\ TYPE SOURCE TYPE CR \ DISPLAY LINE CORRESPONDING TO ERROR
+\ EMPTY-STACK \ THROW AWAY EVERY THING ELSE
+\ QUIT \ *** Uncomment this line to QUIT on an error
+\ ;
+
+VARIABLE ACTUAL-DEPTH \ STACK RECORD
+CREATE ACTUAL-RESULTS 20 CELLS ALLOT
+
+: T{ \ ( -- ) SYNTACTIC SUGAR.
+ ;
+
+: -> \ ( ... -- ) RECORD DEPTH AND CONTENT OF STACK.
+ DEPTH DUP ACTUAL-DEPTH ! \ RECORD DEPTH
+ ?DUP IF \ IF THERE IS SOMETHING ON STACK
+ 0 DO ACTUAL-RESULTS I CELLS + ! LOOP \ SAVE THEM
+ THEN ;
+
+: }T \ ( ... -- ) COMPARE STACK (EXPECTED) CONTENTS WITH SAVED
+ \ (ACTUAL) CONTENTS.
+ DEPTH ACTUAL-DEPTH @ = IF \ IF DEPTHS MATCH
+ DEPTH ?DUP IF \ IF THERE IS SOMETHING ON THE STACK
+ 0 DO \ FOR EACH STACK ITEM
+ ACTUAL-RESULTS I CELLS + @ \ COMPARE ACTUAL WITH EXPECTED
+\ = 0= IF S" INCORRECT RESULT: " ERROR LEAVE THEN \ jmt
+ = 0= IF ABORT" INCORRECT RESULT: " THEN \ jmt : colorised message
+ LOOP
+ THEN
+ ELSE \ DEPTH MISMATCH
+\ S" WRONG NUMBER OF RESULTS: " ERROR \ jmt
+ ABORT" WRONG NUMBER OF RESULTS: " \ jmt : colorised message
+ THEN ;
+
+: TESTING \ ( -- ) TALKING COMMENT.
+ SOURCE VERBOSE @
+ IF DUP >R TYPE CR R> >IN !
+ ELSE >IN ! DROP [CHAR] * EMIT
+ THEN ;
+
+\ From: John Hayes S1I
+\ Subject: core.fr
+\ Date: Mon, 27 Nov 95 13:10
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.2
+\ THIS PROGRAM TESTS THE CORE WORDS OF AN ANS FORTH SYSTEM.
+\ THE PROGRAM ASSUMES A TWO'S COMPLEMENT IMPLEMENTATION WHERE
+\ THE RANGE OF SIGNED NUMBERS IS -2^(N-1) ... 2^(N-1)-1 AND
+\ THE RANGE OF UNSIGNED NUMBERS IS 0 ... 2^(N)-1.
+\ I HAVEN'T FIGURED OUT HOW TO TEST KEY, QUIT, ABORT, OR ABORT"...
+\ I ALSO HAVEN'T THOUGHT OF A WAY TO TEST ENVIRONMENT?...
+
+CR
+TESTING CORE WORDS
+HEX
+
+\ ------------------------------------------------------------------------
+TESTING BASIC ASSUMPTIONS
+
+T{ -> }T \ START WITH CLEAN SLATE
+( TEST IF ANY BITS ARE SET; ANSWER IN BASE 1 )
+T{ : BITSSET? IF 0 0 ELSE 0 THEN ; -> }T
+T{ 0 BITSSET? -> 0 }T ( ZERO IS ALL BITS CLEAR )
+T{ 1 BITSSET? -> 0 0 }T ( OTHER NUMBER HAVE AT LEAST ONE BIT )
+T{ -1 BITSSET? -> 0 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING BOOLEANS: INVERT AND OR XOR
+
+T{ 0 0 AND -> 0 }T
+T{ 0 1 AND -> 0 }T
+T{ 1 0 AND -> 0 }T
+T{ 1 1 AND -> 1 }T
+
+T{ 0 INVERT 1 AND -> 1 }T
+T{ 1 INVERT 1 AND -> 0 }T
+
+0 CONSTANT 0S
+0 INVERT CONSTANT 1S
+
+T{ 0S INVERT -> 1S }T
+T{ 1S INVERT -> 0S }T
+
+T{ 0S 0S AND -> 0S }T
+T{ 0S 1S AND -> 0S }T
+T{ 1S 0S AND -> 0S }T
+T{ 1S 1S AND -> 1S }T
+
+T{ 0S 0S OR -> 0S }T
+T{ 0S 1S OR -> 1S }T
+T{ 1S 0S OR -> 1S }T
+T{ 1S 1S OR -> 1S }T
+
+T{ 0S 0S XOR -> 0S }T
+T{ 0S 1S XOR -> 1S }T
+T{ 1S 0S XOR -> 1S }T
+T{ 1S 1S XOR -> 0S }T
+
+\ ------------------------------------------------------------------------
+TESTING 2* 2/ LSHIFT RSHIFT
+
+( WE TRUST 1S, INVERT, AND BITSSET?; WE WILL CONFIRM RSHIFT LATER )
+1S 1 RSHIFT INVERT CONSTANT MSB
+T{ MSB BITSSET? -> 0 0 }T
+
+T{ 0S 2* -> 0S }T
+T{ 1 2* -> 2 }T
+T{ 4000 2* -> 8000 }T
+T{ 1S 2* 1 XOR -> 1S }T
+T{ MSB 2* -> 0S }T
+
+T{ 0S 2/ -> 0S }T
+T{ 1 2/ -> 0 }T
+T{ 4000 2/ -> 2000 }T
+T{ 1S 2/ -> 1S }T \ MSB PROPOGATED
+T{ 1S 1 XOR 2/ -> 1S }T
+T{ MSB 2/ MSB AND -> MSB }T
+
+T{ 1 0 LSHIFT -> 1 }T
+T{ 1 1 LSHIFT -> 2 }T
+T{ 1 2 LSHIFT -> 4 }T
+T{ 1 F LSHIFT -> 8000 }T \ BIGGEST GUARANTEED SHIFT
+T{ 1S 1 LSHIFT 1 XOR -> 1S }T
+T{ MSB 1 LSHIFT -> 0 }T
+
+T{ 1 0 RSHIFT -> 1 }T
+T{ 1 1 RSHIFT -> 0 }T
+T{ 2 1 RSHIFT -> 1 }T
+T{ 4 2 RSHIFT -> 1 }T
+T{ 8000 F RSHIFT -> 1 }T \ BIGGEST
+T{ MSB 1 RSHIFT MSB AND -> 0 }T \ RSHIFT ZERO FILLS MSBS
+T{ MSB 1 RSHIFT 2* -> MSB }T
+
+\ ------------------------------------------------------------------------
+TESTING COMPARISONS: 0= = 0< < > U< MIN MAX
+0 INVERT CONSTANT MAX-UINT
+0 INVERT 1 RSHIFT CONSTANT MAX-INT
+0 INVERT 1 RSHIFT INVERT CONSTANT MIN-INT
+0 INVERT 1 RSHIFT CONSTANT MID-UINT
+0 INVERT 1 RSHIFT INVERT CONSTANT MID-UINT+1
+
+0S CONSTANT <FALSE>
+1S CONSTANT <TRUE>
+
+T{ 0 0= -> <TRUE> }T
+T{ 1 0= -> <FALSE> }T
+T{ 2 0= -> <FALSE> }T
+T{ -1 0= -> <FALSE> }T
+T{ MAX-UINT 0= -> <FALSE> }T
+T{ MIN-INT 0= -> <FALSE> }T
+T{ MAX-INT 0= -> <FALSE> }T
+
+T{ 0 0 = -> <TRUE> }T
+T{ 1 1 = -> <TRUE> }T
+T{ -1 -1 = -> <TRUE> }T
+T{ 1 0 = -> <FALSE> }T
+T{ -1 0 = -> <FALSE> }T
+T{ 0 1 = -> <FALSE> }T
+T{ 0 -1 = -> <FALSE> }T
+
+T{ 0 0< -> <FALSE> }T
+T{ -1 0< -> <TRUE> }T
+T{ MIN-INT 0< -> <TRUE> }T
+T{ 1 0< -> <FALSE> }T
+T{ MAX-INT 0< -> <FALSE> }T
+
+T{ 0 1 < -> <TRUE> }T
+T{ 1 2 < -> <TRUE> }T
+T{ -1 0 < -> <TRUE> }T
+T{ -1 1 < -> <TRUE> }T
+T{ MIN-INT 0 < -> <TRUE> }T
+T{ MIN-INT MAX-INT < -> <TRUE> }T
+T{ 0 MAX-INT < -> <TRUE> }T
+T{ 0 0 < -> <FALSE> }T
+T{ 1 1 < -> <FALSE> }T
+T{ 1 0 < -> <FALSE> }T
+T{ 2 1 < -> <FALSE> }T
+T{ 0 -1 < -> <FALSE> }T
+T{ 1 -1 < -> <FALSE> }T
+T{ 0 MIN-INT < -> <FALSE> }T
+T{ MAX-INT MIN-INT < -> <FALSE> }T
+T{ MAX-INT 0 < -> <FALSE> }T
+
+T{ 0 1 > -> <FALSE> }T
+T{ 1 2 > -> <FALSE> }T
+T{ -1 0 > -> <FALSE> }T
+T{ -1 1 > -> <FALSE> }T
+T{ MIN-INT 0 > -> <FALSE> }T
+T{ MIN-INT MAX-INT > -> <FALSE> }T
+T{ 0 MAX-INT > -> <FALSE> }T
+T{ 0 0 > -> <FALSE> }T
+T{ 1 1 > -> <FALSE> }T
+T{ 1 0 > -> <TRUE> }T
+T{ 2 1 > -> <TRUE> }T
+T{ 0 -1 > -> <TRUE> }T
+T{ 1 -1 > -> <TRUE> }T
+T{ 0 MIN-INT > -> <TRUE> }T
+T{ MAX-INT MIN-INT > -> <TRUE> }T
+T{ MAX-INT 0 > -> <TRUE> }T
+
+T{ 0 1 U< -> <TRUE> }T
+T{ 1 2 U< -> <TRUE> }T
+T{ 0 MID-UINT U< -> <TRUE> }T
+T{ 0 MAX-UINT U< -> <TRUE> }T
+T{ MID-UINT MAX-UINT U< -> <TRUE> }T
+T{ 0 0 U< -> <FALSE> }T
+T{ 1 1 U< -> <FALSE> }T
+T{ 1 0 U< -> <FALSE> }T
+T{ 2 1 U< -> <FALSE> }T
+T{ MID-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT MID-UINT U< -> <FALSE> }T
+
+T{ 0 1 MIN -> 0 }T
+T{ 1 2 MIN -> 1 }T
+T{ -1 0 MIN -> -1 }T
+T{ -1 1 MIN -> -1 }T
+T{ MIN-INT 0 MIN -> MIN-INT }T
+T{ MIN-INT MAX-INT MIN -> MIN-INT }T
+T{ 0 MAX-INT MIN -> 0 }T
+T{ 0 0 MIN -> 0 }T
+T{ 1 1 MIN -> 1 }T
+T{ 1 0 MIN -> 0 }T
+T{ 2 1 MIN -> 1 }T
+T{ 0 -1 MIN -> -1 }T
+T{ 1 -1 MIN -> -1 }T
+T{ 0 MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT 0 MIN -> 0 }T
+
+T{ 0 1 MAX -> 1 }T
+T{ 1 2 MAX -> 2 }T
+T{ -1 0 MAX -> 0 }T
+T{ -1 1 MAX -> 1 }T
+T{ MIN-INT 0 MAX -> 0 }T
+T{ MIN-INT MAX-INT MAX -> MAX-INT }T
+T{ 0 MAX-INT MAX -> MAX-INT }T
+T{ 0 0 MAX -> 0 }T
+T{ 1 1 MAX -> 1 }T
+T{ 1 0 MAX -> 1 }T
+T{ 2 1 MAX -> 2 }T
+T{ 0 -1 MAX -> 0 }T
+T{ 1 -1 MAX -> 1 }T
+T{ 0 MIN-INT MAX -> 0 }T
+T{ MAX-INT MIN-INT MAX -> MAX-INT }T
+T{ MAX-INT 0 MAX -> MAX-INT }T
+
+\ ------------------------------------------------------------------------
+TESTING STACK OPS: 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP
+
+T{ 1 2 2DROP -> }T
+T{ 1 2 2DUP -> 1 2 1 2 }T
+T{ 1 2 3 4 2OVER -> 1 2 3 4 1 2 }T
+T{ 1 2 3 4 2SWAP -> 3 4 1 2 }T
+T{ 0 ?DUP -> 0 }T
+T{ 1 ?DUP -> 1 1 }T
+T{ -1 ?DUP -> -1 -1 }T
+T{ DEPTH -> 0 }T
+T{ 0 DEPTH -> 0 1 }T
+T{ 0 1 DEPTH -> 0 1 2 }T
+T{ 0 DROP -> }T
+T{ 1 2 DROP -> 1 }T
+T{ 1 DUP -> 1 1 }T
+T{ 1 2 OVER -> 1 2 1 }T
+T{ 1 2 3 ROT -> 2 3 1 }T
+T{ 1 2 SWAP -> 2 1 }T
+
+\ ------------------------------------------------------------------------
+TESTING >R R> R@
+
+T{ : GR1 >R R> ; -> }T
+T{ : GR2 >R R@ R> DROP ; -> }T
+T{ 123 GR1 -> 123 }T
+T{ 123 GR2 -> 123 }T
+T{ 1S GR1 -> 1S }T ( RETURN STACK HOLDS CELLS )
+
+\ ------------------------------------------------------------------------
+TESTING ADD/SUBTRACT: + - 1+ 1- ABS NEGATE
+
+T{ 0 5 + -> 5 }T
+T{ 5 0 + -> 5 }T
+T{ 0 -5 + -> -5 }T
+T{ -5 0 + -> -5 }T
+T{ 1 2 + -> 3 }T
+T{ 1 -2 + -> -1 }T
+T{ -1 2 + -> 1 }T
+T{ -1 -2 + -> -3 }T
+T{ -1 1 + -> 0 }T
+T{ MID-UINT 1 + -> MID-UINT+1 }T
+
+T{ 0 5 - -> -5 }T
+T{ 5 0 - -> 5 }T
+T{ 0 -5 - -> 5 }T
+T{ -5 0 - -> -5 }T
+T{ 1 2 - -> -1 }T
+T{ 1 -2 - -> 3 }T
+T{ -1 2 - -> -3 }T
+T{ -1 -2 - -> 1 }T
+T{ 0 1 - -> -1 }T
+T{ MID-UINT+1 1 - -> MID-UINT }T
+
+T{ 0 1+ -> 1 }T
+T{ -1 1+ -> 0 }T
+T{ 1 1+ -> 2 }T
+T{ MID-UINT 1+ -> MID-UINT+1 }T
+
+T{ 2 1- -> 1 }T
+T{ 1 1- -> 0 }T
+T{ 0 1- -> -1 }T
+T{ MID-UINT+1 1- -> MID-UINT }T
+
+T{ 0 NEGATE -> 0 }T
+T{ 1 NEGATE -> -1 }T
+T{ -1 NEGATE -> 1 }T
+T{ 2 NEGATE -> -2 }T
+T{ -2 NEGATE -> 2 }T
+
+T{ 0 ABS -> 0 }T
+T{ 1 ABS -> 1 }T
+T{ -1 ABS -> 1 }T
+T{ MIN-INT ABS -> MID-UINT+1 }T
+
+\ ------------------------------------------------------------------------
+TESTING MULTIPLY: S>D * M* UM*
+
+T{ 0 S>D -> 0 0 }T
+T{ 1 S>D -> 1 0 }T
+T{ 2 S>D -> 2 0 }T
+T{ -1 S>D -> -1 -1 }T
+T{ -2 S>D -> -2 -1 }T
+T{ MIN-INT S>D -> MIN-INT -1 }T
+T{ MAX-INT S>D -> MAX-INT 0 }T
+
+T{ 0 0 M* -> 0 S>D }T
+T{ 0 1 M* -> 0 S>D }T
+T{ 1 0 M* -> 0 S>D }T
+T{ 1 2 M* -> 2 S>D }T
+T{ 2 1 M* -> 2 S>D }T
+T{ 3 3 M* -> 9 S>D }T
+T{ -3 3 M* -> -9 S>D }T
+T{ 3 -3 M* -> -9 S>D }T
+T{ -3 -3 M* -> 9 S>D }T
+T{ 0 MIN-INT M* -> 0 S>D }T
+T{ 1 MIN-INT M* -> MIN-INT S>D }T
+T{ 2 MIN-INT M* -> 0 1S }T
+T{ 0 MAX-INT M* -> 0 S>D }T
+T{ 1 MAX-INT M* -> MAX-INT S>D }T
+T{ 2 MAX-INT M* -> MAX-INT 1 LSHIFT 0 }T
+T{ MIN-INT MIN-INT M* -> 0 MSB 1 RSHIFT }T
+T{ MAX-INT MIN-INT M* -> MSB MSB 2/ }T
+T{ MAX-INT MAX-INT M* -> 1 MSB 2/ INVERT }T
+
+T{ 0 0 * -> 0 }T \ TEST IDENTITIES
+T{ 0 1 * -> 0 }T
+T{ 1 0 * -> 0 }T
+T{ 1 2 * -> 2 }T
+T{ 2 1 * -> 2 }T
+T{ 3 3 * -> 9 }T
+T{ -3 3 * -> -9 }T
+T{ 3 -3 * -> -9 }T
+T{ -3 -3 * -> 9 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 * -> MID-UINT+1 }T
+T{ MID-UINT+1 2 RSHIFT 4 * -> MID-UINT+1 }T
+T{ MID-UINT+1 1 RSHIFT MID-UINT+1 OR 2 * -> MID-UINT+1 }T
+
+T{ 0 0 UM* -> 0 0 }T
+T{ 0 1 UM* -> 0 0 }T
+T{ 1 0 UM* -> 0 0 }T
+T{ 1 2 UM* -> 2 0 }T
+T{ 2 1 UM* -> 2 0 }T
+T{ 3 3 UM* -> 9 0 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 UM* -> MID-UINT+1 0 }T
+T{ MID-UINT+1 2 UM* -> 0 1 }T
+T{ MID-UINT+1 4 UM* -> 0 2 }T
+T{ 1S 2 UM* -> 1S 1 LSHIFT 1 }T
+T{ MAX-UINT MAX-UINT UM* -> 1 1 INVERT }T
+
+\ ------------------------------------------------------------------------
+TESTING DIVIDE: FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD
+
+T{ 0 S>D 1 FM/MOD -> 0 0 }T
+T{ 1 S>D 1 FM/MOD -> 0 1 }T
+T{ 2 S>D 1 FM/MOD -> 0 2 }T
+T{ -1 S>D 1 FM/MOD -> 0 -1 }T
+T{ -2 S>D 1 FM/MOD -> 0 -2 }T
+T{ 0 S>D -1 FM/MOD -> 0 0 }T
+T{ 1 S>D -1 FM/MOD -> 0 -1 }T
+T{ 2 S>D -1 FM/MOD -> 0 -2 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -1 FM/MOD -> 0 2 }T
+T{ 2 S>D 2 FM/MOD -> 0 1 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -2 FM/MOD -> 0 1 }T
+T{ 7 S>D 3 FM/MOD -> 1 2 }T
+T{ 7 S>D -3 FM/MOD -> -2 -3 }T
+T{ -7 S>D 3 FM/MOD -> 2 -3 }T
+T{ -7 S>D -3 FM/MOD -> -1 2 }T
+T{ MAX-INT S>D 1 FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT FM/MOD -> 0 1 }T
+T{ MIN-INT S>D MIN-INT FM/MOD -> 0 1 }T
+T{ 1S 1 4 FM/MOD -> 3 MAX-INT }T
+T{ 1 MIN-INT M* 1 FM/MOD -> 0 MIN-INT }T
+T{ 1 MIN-INT M* MIN-INT FM/MOD -> 0 1 }T
+T{ 2 MIN-INT M* 2 FM/MOD -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT FM/MOD -> 0 2 }T
+T{ 1 MAX-INT M* 1 FM/MOD -> 0 MAX-INT }T
+T{ 1 MAX-INT M* MAX-INT FM/MOD -> 0 1 }T
+T{ 2 MAX-INT M* 2 FM/MOD -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT FM/MOD -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT FM/MOD -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT FM/MOD -> 0 MAX-INT }T
+
+T{ 0 S>D 1 SM/REM -> 0 0 }T
+T{ 1 S>D 1 SM/REM -> 0 1 }T
+T{ 2 S>D 1 SM/REM -> 0 2 }T
+T{ -1 S>D 1 SM/REM -> 0 -1 }T
+T{ -2 S>D 1 SM/REM -> 0 -2 }T
+T{ 0 S>D -1 SM/REM -> 0 0 }T
+T{ 1 S>D -1 SM/REM -> 0 -1 }T
+T{ 2 S>D -1 SM/REM -> 0 -2 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -1 SM/REM -> 0 2 }T
+T{ 2 S>D 2 SM/REM -> 0 1 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -2 SM/REM -> 0 1 }T
+T{ 7 S>D 3 SM/REM -> 1 2 }T
+T{ 7 S>D -3 SM/REM -> 1 -2 }T
+T{ -7 S>D 3 SM/REM -> -1 -2 }T
+T{ -7 S>D -3 SM/REM -> -1 2 }T
+T{ MAX-INT S>D 1 SM/REM -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 SM/REM -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT SM/REM -> 0 1 }T
+T{ MIN-INT S>D MIN-INT SM/REM -> 0 1 }T
+T{ 1S 1 4 SM/REM -> 3 MAX-INT }T
+T{ 2 MIN-INT M* 2 SM/REM -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT SM/REM -> 0 2 }T
+T{ 2 MAX-INT M* 2 SM/REM -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT SM/REM -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT SM/REM -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT SM/REM -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT SM/REM -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT SM/REM -> 0 MAX-INT }T
+
+T{ 0 0 1 UM/MOD -> 0 0 }T
+T{ 1 0 1 UM/MOD -> 0 1 }T
+T{ 1 0 2 UM/MOD -> 1 0 }T
+T{ 3 0 2 UM/MOD -> 1 1 }T
+T{ MAX-UINT 2 UM* 2 UM/MOD -> 0 MAX-UINT }T
+T{ MAX-UINT 2 UM* MAX-UINT UM/MOD -> 0 2 }T
+T{ MAX-UINT MAX-UINT UM* MAX-UINT UM/MOD -> 0 MAX-UINT }T
+
+: IFFLOORED
+ [ -3 2 / -2 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+: IFSYM
+ [ -3 2 / -1 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+\ THE SYSTEM MIGHT DO EITHER FLOORED OR SYMMETRIC DIVISION.
+\ SINCE WE HAVE ALREADY TESTED M*, FM/MOD, AND SM/REM WE CAN USE THEM IN TEST.
+
+IFFLOORED : T/MOD >R S>D R> FM/MOD ;
+IFFLOORED : T/ T/MOD SWAP DROP ;
+IFFLOORED : TMOD T/MOD DROP ;
+IFFLOORED : T*/MOD >R M* R> FM/MOD ;
+IFFLOORED : T*/ T*/MOD SWAP DROP ;
+IFSYM : T/MOD >R S>D R> SM/REM ;
+IFSYM : T/ T/MOD SWAP DROP ;
+IFSYM : TMOD T/MOD DROP ;
+IFSYM : T*/MOD >R M* R> SM/REM ;
+IFSYM : T*/ T*/MOD SWAP DROP ;
+
+T{ 0 1 /MOD -> 0 1 T/MOD }T
+T{ 1 1 /MOD -> 1 1 T/MOD }T
+T{ 2 1 /MOD -> 2 1 T/MOD }T
+T{ -1 1 /MOD -> -1 1 T/MOD }T
+T{ -2 1 /MOD -> -2 1 T/MOD }T
+T{ 0 -1 /MOD -> 0 -1 T/MOD }T
+T{ 1 -1 /MOD -> 1 -1 T/MOD }T
+T{ 2 -1 /MOD -> 2 -1 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -1 /MOD -> -2 -1 T/MOD }T
+T{ 2 2 /MOD -> 2 2 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -2 /MOD -> -2 -2 T/MOD }T
+T{ 7 3 /MOD -> 7 3 T/MOD }T
+T{ 7 -3 /MOD -> 7 -3 T/MOD }T
+T{ -7 3 /MOD -> -7 3 T/MOD }T
+T{ -7 -3 /MOD -> -7 -3 T/MOD }T
+T{ MAX-INT 1 /MOD -> MAX-INT 1 T/MOD }T
+T{ MIN-INT 1 /MOD -> MIN-INT 1 T/MOD }T
+T{ MAX-INT MAX-INT /MOD -> MAX-INT MAX-INT T/MOD }T
+T{ MIN-INT MIN-INT /MOD -> MIN-INT MIN-INT T/MOD }T
+
+T{ 0 1 / -> 0 1 T/ }T
+T{ 1 1 / -> 1 1 T/ }T
+T{ 2 1 / -> 2 1 T/ }T
+T{ -1 1 / -> -1 1 T/ }T
+T{ -2 1 / -> -2 1 T/ }T
+T{ 0 -1 / -> 0 -1 T/ }T
+T{ 1 -1 / -> 1 -1 T/ }T
+T{ 2 -1 / -> 2 -1 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -1 / -> -2 -1 T/ }T
+T{ 2 2 / -> 2 2 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -2 / -> -2 -2 T/ }T
+T{ 7 3 / -> 7 3 T/ }T
+T{ 7 -3 / -> 7 -3 T/ }T
+T{ -7 3 / -> -7 3 T/ }T
+T{ -7 -3 / -> -7 -3 T/ }T
+T{ MAX-INT 1 / -> MAX-INT 1 T/ }T
+T{ MIN-INT 1 / -> MIN-INT 1 T/ }T
+T{ MAX-INT MAX-INT / -> MAX-INT MAX-INT T/ }T
+T{ MIN-INT MIN-INT / -> MIN-INT MIN-INT T/ }T
+
+T{ 0 1 MOD -> 0 1 TMOD }T
+T{ 1 1 MOD -> 1 1 TMOD }T
+T{ 2 1 MOD -> 2 1 TMOD }T
+T{ -1 1 MOD -> -1 1 TMOD }T
+T{ -2 1 MOD -> -2 1 TMOD }T
+T{ 0 -1 MOD -> 0 -1 TMOD }T
+T{ 1 -1 MOD -> 1 -1 TMOD }T
+T{ 2 -1 MOD -> 2 -1 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -1 MOD -> -2 -1 TMOD }T
+T{ 2 2 MOD -> 2 2 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -2 MOD -> -2 -2 TMOD }T
+T{ 7 3 MOD -> 7 3 TMOD }T
+T{ 7 -3 MOD -> 7 -3 TMOD }T
+T{ -7 3 MOD -> -7 3 TMOD }T
+T{ -7 -3 MOD -> -7 -3 TMOD }T
+T{ MAX-INT 1 MOD -> MAX-INT 1 TMOD }T
+T{ MIN-INT 1 MOD -> MIN-INT 1 TMOD }T
+T{ MAX-INT MAX-INT MOD -> MAX-INT MAX-INT TMOD }T
+T{ MIN-INT MIN-INT MOD -> MIN-INT MIN-INT TMOD }T
+
+T{ 0 2 1 */ -> 0 2 1 T*/ }T
+T{ 1 2 1 */ -> 1 2 1 T*/ }T
+T{ 2 2 1 */ -> 2 2 1 T*/ }T
+T{ -1 2 1 */ -> -1 2 1 T*/ }T
+T{ -2 2 1 */ -> -2 2 1 T*/ }T
+T{ 0 2 -1 */ -> 0 2 -1 T*/ }T
+T{ 1 2 -1 */ -> 1 2 -1 T*/ }T
+T{ 2 2 -1 */ -> 2 2 -1 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -1 */ -> -2 2 -1 T*/ }T
+T{ 2 2 2 */ -> 2 2 2 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -2 */ -> -2 2 -2 T*/ }T
+T{ 7 2 3 */ -> 7 2 3 T*/ }T
+T{ 7 2 -3 */ -> 7 2 -3 T*/ }T
+T{ -7 2 3 */ -> -7 2 3 T*/ }T
+T{ -7 2 -3 */ -> -7 2 -3 T*/ }T
+T{ MAX-INT 2 MAX-INT */ -> MAX-INT 2 MAX-INT T*/ }T
+T{ MIN-INT 2 MIN-INT */ -> MIN-INT 2 MIN-INT T*/ }T
+
+T{ 0 2 1 */MOD -> 0 2 1 T*/MOD }T
+T{ 1 2 1 */MOD -> 1 2 1 T*/MOD }T
+T{ 2 2 1 */MOD -> 2 2 1 T*/MOD }T
+T{ -1 2 1 */MOD -> -1 2 1 T*/MOD }T
+T{ -2 2 1 */MOD -> -2 2 1 T*/MOD }T
+T{ 0 2 -1 */MOD -> 0 2 -1 T*/MOD }T
+T{ 1 2 -1 */MOD -> 1 2 -1 T*/MOD }T
+T{ 2 2 -1 */MOD -> 2 2 -1 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -1 */MOD -> -2 2 -1 T*/MOD }T
+T{ 2 2 2 */MOD -> 2 2 2 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -2 */MOD -> -2 2 -2 T*/MOD }T
+T{ 7 2 3 */MOD -> 7 2 3 T*/MOD }T
+T{ 7 2 -3 */MOD -> 7 2 -3 T*/MOD }T
+T{ -7 2 3 */MOD -> -7 2 3 T*/MOD }T
+T{ -7 2 -3 */MOD -> -7 2 -3 T*/MOD }T
+T{ MAX-INT 2 MAX-INT */MOD -> MAX-INT 2 MAX-INT T*/MOD }T
+T{ MIN-INT 2 MIN-INT */MOD -> MIN-INT 2 MIN-INT T*/MOD }T
+
+\ ------------------------------------------------------------------------
+TESTING HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2! ALIGN ALIGNED +! ALLOT
+
+HERE 1 ALLOT
+HERE
+CONSTANT 2NDA
+CONSTANT 1STA
+T{ 1STA 2NDA U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STA 1+ -> 2NDA }T \ ... BY ONE ADDRESS UNIT
+( MISSING TEST: NEGATIVE ALLOT )
+
+HERE 1 ,
+HERE 2 ,
+CONSTANT 2ND
+CONSTANT 1ST
+T{ 1ST 2ND U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1ST CELL+ -> 2ND }T \ ... BY ONE CELL
+T{ 1ST 1 CELLS + -> 2ND }T
+T{ 1ST @ 2ND @ -> 1 2 }T
+T{ 5 1ST ! -> }T
+T{ 1ST @ 2ND @ -> 5 2 }T
+T{ 6 2ND ! -> }T
+T{ 1ST @ 2ND @ -> 5 6 }T
+T{ 1ST 2@ -> 6 5 }T
+T{ 2 1 1ST 2! -> }T
+T{ 1ST 2@ -> 2 1 }T
+T{ 1S 1ST ! 1ST @ -> 1S }T \ CAN STORE CELL-WIDE VALUE
+
+HERE 1 C,
+HERE 2 C,
+CONSTANT 2NDC
+CONSTANT 1STC
+T{ 1STC 2NDC U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STC CHAR+ -> 2NDC }T \ ... BY ONE CHAR
+T{ 1STC 1 CHARS + -> 2NDC }T
+T{ 1STC C@ 2NDC C@ -> 1 2 }T
+T{ 3 1STC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 2 }T
+T{ 4 2NDC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 4 }T
+
+ALIGN 1 ALLOT HERE ALIGN HERE 3 CELLS ALLOT
+CONSTANT A-ADDR CONSTANT UA-ADDR
+T{ UA-ADDR ALIGNED -> A-ADDR }T
+T{ 1 A-ADDR C! A-ADDR C@ -> 1 }T
+T{ 1234 A-ADDR ! A-ADDR @ -> 1234 }T
+T{ 123 456 A-ADDR 2! A-ADDR 2@ -> 123 456 }T
+T{ 2 A-ADDR CHAR+ C! A-ADDR CHAR+ C@ -> 2 }T
+T{ 3 A-ADDR CELL+ C! A-ADDR CELL+ C@ -> 3 }T
+T{ 1234 A-ADDR CELL+ ! A-ADDR CELL+ @ -> 1234 }T
+T{ 123 456 A-ADDR CELL+ 2! A-ADDR CELL+ 2@ -> 123 456 }T
+
+: BITS ( X -- U )
+ 0 SWAP BEGIN DUP WHILE DUP MSB AND IF >R 1+ R> THEN 2* REPEAT DROP ;
+( CHARACTERS >= 1 AU, <= SIZE OF CELL, >= 8 BITS )
+T{ 1 CHARS 1 < -> <FALSE> }T
+T{ 1 CHARS 1 CELLS > -> <FALSE> }T
+( TBD: HOW TO FIND NUMBER OF BITS? )
+
+( CELLS >= 1 AU, INTEGRAL MULTIPLE OF CHAR SIZE, >= 16 BITS )
+T{ 1 CELLS 1 < -> <FALSE> }T
+T{ 1 CELLS 1 CHARS MOD -> 0 }T
+T{ 1S BITS 10 < -> <FALSE> }T
+
+T{ 0 1ST ! -> }T
+T{ 1 1ST +! -> }T
+T{ 1ST @ -> 1 }T
+T{ -1 1ST +! 1ST @ -> 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING CHAR [CHAR] [ ] BL S"
+
+T{ BL -> 20 }T
+T{ CHAR X -> 58 }T
+T{ CHAR HELLO -> 48 }T
+T{ : GC1 [CHAR] X ; -> }T
+T{ : GC2 [CHAR] HELLO ; -> }T
+T{ GC1 -> 58 }T
+T{ GC2 -> 48 }T
+T{ : GC3 [ GC1 ] LITERAL ; -> }T
+T{ GC3 -> 58 }T
+T{ : GC4 S" XY" ; -> }T
+T{ GC4 SWAP DROP -> 2 }T
+T{ GC4 DROP DUP C@ SWAP CHAR+ C@ -> 58 59 }T
+
+\ ------------------------------------------------------------------------
+TESTING ' ['] FIND EXECUTE IMMEDIATE COUNT LITERAL POSTPONE STATE
+
+T{ : GT1 123 ; -> }T
+T{ ' GT1 EXECUTE -> 123 }T
+T{ : GT2 ['] GT1 ; IMMEDIATE -> }T
+T{ GT2 EXECUTE -> 123 }T
+HERE 3 C, CHAR G C, CHAR T C, CHAR 1 C, CONSTANT GT1STRING
+HERE 3 C, CHAR G C, CHAR T C, CHAR 2 C, CONSTANT GT2STRING
+T{ GT1STRING FIND -> ' GT1 -1 }T
+T{ GT2STRING FIND -> ' GT2 1 }T
+( HOW TO SEARCH FOR NON-EXISTENT WORD? )
+T{ : GT3 GT2 LITERAL ; -> }T
+T{ GT3 -> ' GT1 }T
+T{ GT1STRING COUNT -> GT1STRING CHAR+ 3 }T
+
+T{ : GT4 POSTPONE GT1 ; IMMEDIATE -> }T
+T{ : GT5 GT4 ; -> }T
+T{ GT5 -> 123 }T
+T{ : GT6 345 ; IMMEDIATE -> }T
+T{ : GT7 POSTPONE GT6 ; -> }T
+T{ GT7 -> 345 }T
+
+T{ : GT8 STATE @ ; IMMEDIATE -> }T
+T{ GT8 -> 0 }T
+T{ : GT9 GT8 LITERAL ; -> }T
+T{ GT9 0= -> <FALSE> }T
+
+\ ------------------------------------------------------------------------
+TESTING IF ELSE THEN BEGIN WHILE REPEAT UNTIL RECURSE
+
+T{ : GI1 IF 123 THEN ; -> }T
+T{ : GI2 IF 123 ELSE 234 THEN ; -> }T
+T{ 0 GI1 -> }T
+T{ 1 GI1 -> 123 }T
+T{ -1 GI1 -> 123 }T
+T{ 0 GI2 -> 234 }T
+T{ 1 GI2 -> 123 }T
+T{ -1 GI1 -> 123 }T
+
+T{ : GI3 BEGIN DUP 5 < WHILE DUP 1+ REPEAT ; -> }T
+T{ 0 GI3 -> 0 1 2 3 4 5 }T
+T{ 4 GI3 -> 4 5 }T
+T{ 5 GI3 -> 5 }T
+T{ 6 GI3 -> 6 }T
+
+T{ : GI4 BEGIN DUP 1+ DUP 5 > UNTIL ; -> }T
+T{ 3 GI4 -> 3 4 5 6 }T
+T{ 5 GI4 -> 5 6 }T
+T{ 6 GI4 -> 6 7 }T
+
+T{ : GI5 BEGIN DUP 2 > WHILE DUP 5 < WHILE DUP 1+ REPEAT 123 ELSE 345 THEN ; -> }T
+T{ 1 GI5 -> 1 345 }T
+T{ 2 GI5 -> 2 345 }T
+T{ 3 GI5 -> 3 4 5 123 }T
+T{ 4 GI5 -> 4 5 123 }T
+T{ 5 GI5 -> 5 123 }T
+
+T{ : GI6 ( N -- 0,1,..N ) DUP IF DUP >R 1- RECURSE R> THEN ; -> }T
+T{ 0 GI6 -> 0 }T
+T{ 1 GI6 -> 0 1 }T
+T{ 2 GI6 -> 0 1 2 }T
+T{ 3 GI6 -> 0 1 2 3 }T
+T{ 4 GI6 -> 0 1 2 3 4 }T
+
+\ ------------------------------------------------------------------------
+TESTING DO LOOP +LOOP I J UNLOOP LEAVE EXIT
+
+T{ : GD1 DO I LOOP ; -> }T
+T{ 4 1 GD1 -> 1 2 3 }T
+T{ 2 -1 GD1 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD1 -> MID-UINT }T
+
+T{ : GD2 DO I -1 +LOOP ; -> }T
+T{ 1 4 GD2 -> 4 3 2 1 }T
+T{ -1 2 GD2 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD2 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD3 DO 1 0 DO J LOOP LOOP ; -> }T
+T{ 4 1 GD3 -> 1 2 3 }T
+T{ 2 -1 GD3 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD3 -> MID-UINT }T
+
+T{ : GD4 DO 1 0 DO J LOOP -1 +LOOP ; -> }T
+T{ 1 4 GD4 -> 4 3 2 1 }T
+T{ -1 2 GD4 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD4 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD5 123 SWAP 0 DO I 4 > IF DROP 234 LEAVE THEN LOOP ; -> }T
+T{ 1 GD5 -> 123 }T
+T{ 5 GD5 -> 123 }T
+T{ 6 GD5 -> 234 }T
+
+T{ : GD6 ( PAT: T{0 0}T,T{0 0}TT{1 0}TT{1 1}T,T{0 0}TT{1 0}TT{1 1}TT{2 0}TT{2 1}TT{2 2}T )
+ 0 SWAP 0 DO
+ I 1+ 0 DO I J + 3 = IF I UNLOOP I UNLOOP EXIT THEN 1+ LOOP
+ LOOP ; -> }T
+T{ 1 GD6 -> 1 }T
+T{ 2 GD6 -> 3 }T
+T{ 3 GD6 -> 4 1 2 }T
+
+\ ------------------------------------------------------------------------
+TESTING DEFINING WORDS: : ; CONSTANT VARIABLE CREATE DOES> >BODY
+
+T{ 123 CONSTANT X123 -> }T
+T{ X123 -> 123 }T
+T{ : EQU CONSTANT ; -> }T
+T{ X123 EQU Y123 -> }T
+T{ Y123 -> 123 }T
+
+T{ VARIABLE V1 -> }T
+T{ 123 V1 ! -> }T
+T{ V1 @ -> 123 }T
+
+T{ : NOP : POSTPONE ; ; -> }T
+T{ NOP NOP1 NOP NOP2 -> }T
+T{ NOP1 -> }T
+T{ NOP2 -> }T
+
+T{ : DOES1 DOES> @ 1 + ; -> }T
+T{ : DOES2 DOES> @ 2 + ; -> }T
+T{ CREATE CR1 -> }T
+T{ CR1 -> HERE }T
+T{ ' CR1 >BODY -> HERE }T
+T{ 1 , -> }T
+T{ CR1 @ -> 1 }T
+T{ DOES1 -> }T
+T{ CR1 -> 2 }T
+T{ DOES2 -> }T
+T{ CR1 -> 3 }T
+
+T{ : WEIRD: CREATE DOES> 1 + DOES> 2 + ; -> }T
+T{ WEIRD: W1 -> }T
+T{ ' W1 >BODY -> HERE }T
+T{ W1 -> HERE 1 + }T
+T{ W1 -> HERE 2 + }T
+
+\ ------------------------------------------------------------------------
+TESTING EVALUATE
+
+: GE1 S" 123" ; IMMEDIATE
+: GE2 S" 123 1+" ; IMMEDIATE
+: GE3 S" : GE4 345 ;" ;
+: GE5 EVALUATE ; IMMEDIATE
+
+T{ GE1 EVALUATE -> 123 }T ( TEST EVALUATE IN INTERP. STATE )
+T{ GE2 EVALUATE -> 124 }T
+T{ GE3 EVALUATE -> }T
+T{ GE4 -> 345 }T
+
+T{ : GE6 GE1 GE5 ; -> }T ( TEST EVALUATE IN COMPILE STATE )
+T{ GE6 -> 123 }T
+T{ : GE7 GE2 GE5 ; -> }T
+T{ GE7 -> 124 }T
+
+\ ------------------------------------------------------------------------
+TESTING SOURCE >IN WORD
+
+: GS1 S" SOURCE" 2DUP EVALUATE
+ >R SWAP >R = R> R> = ;
+T{ GS1 -> <TRUE> <TRUE> }T
+
+VARIABLE SCANS
+: RESCAN? -1 SCANS +! SCANS @ IF 0 >IN ! THEN ;
+
+T{ 2 SCANS !
+345 RESCAN?
+-> 345 345 }T
+
+: GS2 5 SCANS ! S" 123 RESCAN?" EVALUATE ;
+T{ GS2 -> 123 123 123 123 123 }T
+
+: GS3 WORD COUNT SWAP C@ ;
+T{ BL GS3 HELLO -> 5 CHAR H }T
+T{ CHAR " GS3 GOODBYE" -> 7 CHAR G }T
+T{ BL GS3
+DROP -> 0 }T \ BLANK LINE RETURN ZERO-LENGTH STRING
+
+: GS4 SOURCE >IN ! DROP ;
+T{ GS4 123 456
+-> }T
+
+\ ------------------------------------------------------------------------
+TESTING <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL
+
+: S= \ ( ADDR1 C1 ADDR2 C2 -- T/F ) COMPARE TWO STRINGS.
+ >R SWAP R@ = IF \ MAKE SURE STRINGS HAVE SAME LENGTH
+ R> ?DUP IF \ IF NON-EMPTY STRINGS
+ 0 DO
+ OVER C@ OVER C@ - IF
+ 2DROP <FALSE> UNLOOP EXIT THEN
+ SWAP CHAR+ SWAP CHAR+
+ LOOP
+ THEN
+ 2DROP <TRUE> \ IF WE GET HERE, STRINGS MATCH
+ ELSE
+ R> DROP 2DROP <FALSE> \ LENGTHS MISMATCH
+ THEN ;
+
+: GP1 <# 41 HOLD 42 HOLD 0 0 #> S" BA" S= ;
+T{ GP1 -> <TRUE> }T
+
+: GP2 <# -1 SIGN 0 SIGN -1 SIGN 0 0 #> S" --" S= ;
+T{ GP2 -> <TRUE> }T
+
+: GP3 <# 1 0 # # #> S" 01" S= ;
+T{ GP3 -> <TRUE> }T
+
+: GP4 <# 1 0 #S #> S" 1" S= ;
+T{ GP4 -> <TRUE> }T
+
+24 CONSTANT MAX-BASE \ BASE 2 .. 36
+: COUNT-BITS
+ 0 0 INVERT BEGIN DUP WHILE >R 1+ R> 2* REPEAT DROP ;
+COUNT-BITS 2* CONSTANT #BITS-UD \ NUMBER OF BITS IN UD
+
+: GP5
+ BASE @ <TRUE>
+ MAX-BASE 1+ 2 DO \ FOR EACH POSSIBLE BASE
+ I BASE ! \ TBD: ASSUMES BASE WORKS
+ I 0 <# #S #> S" 10" S= AND
+ LOOP
+ SWAP BASE ! ;
+T{ GP5 -> <TRUE> }T
+
+: GP6
+ BASE @ >R 2 BASE !
+ MAX-UINT MAX-UINT <# #S #> \ MAXIMUM UD TO BINARY
+ R> BASE ! \ S: C-ADDR U
+ DUP #BITS-UD = SWAP
+ 0 DO \ S: C-ADDR FLAG
+ OVER C@ [CHAR] 1 = AND \ ALL ONES
+ >R CHAR+ R>
+ LOOP SWAP DROP ;
+T{ GP6 -> <TRUE> }T
+
+: GP7
+ BASE @ >R MAX-BASE BASE !
+ <TRUE>
+ A 0 DO
+ I 0 <# #S #>
+ 1 = SWAP C@ I 30 + = AND AND
+ LOOP
+ MAX-BASE A DO
+ I 0 <# #S #>
+ 1 = SWAP C@ 41 I A - + = AND AND
+ LOOP
+ R> BASE ! ;
+
+T{ GP7 -> <TRUE> }T
+
+\ >NUMBER TESTS
+CREATE GN-BUF 0 C,
+: GN-STRING GN-BUF 1 ;
+: GN-CONSUMED GN-BUF CHAR+ 0 ;
+: GN' [CHAR] ' WORD CHAR+ C@ GN-BUF C! GN-STRING ;
+
+T{ 0 0 GN' 0' >NUMBER -> 0 0 GN-CONSUMED }T
+T{ 0 0 GN' 1' >NUMBER -> 1 0 GN-CONSUMED }T
+T{ 1 0 GN' 1' >NUMBER -> BASE @ 1+ 0 GN-CONSUMED }T
+T{ 0 0 GN' -' >NUMBER -> 0 0 GN-STRING }T \ SHOULD FAIL TO CONVERT THESE
+T{ 0 0 GN' +' >NUMBER -> 0 0 GN-STRING }T
+T{ 0 0 GN' .' >NUMBER -> 0 0 GN-STRING }T
+
+: >NUMBER-BASED
+ BASE @ >R BASE ! >NUMBER R> BASE ! ;
+
+T{ 0 0 GN' 2' 10 >NUMBER-BASED -> 2 0 GN-CONSUMED }T
+T{ 0 0 GN' 2' 2 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' F' 10 >NUMBER-BASED -> F 0 GN-CONSUMED }T
+T{ 0 0 GN' G' 10 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' G' MAX-BASE >NUMBER-BASED -> 10 0 GN-CONSUMED }T
+T{ 0 0 GN' Z' MAX-BASE >NUMBER-BASED -> 23 0 GN-CONSUMED }T
+
+: GN1 \ ( UD BASE -- UD' LEN ) UD SHOULD EQUAL UD' AND LEN SHOULD BE ZERO.
+ BASE @ >R BASE !
+ <# #S #>
+ 0 0 2SWAP >NUMBER SWAP DROP \ RETURN LENGTH ONLY
+ R> BASE ! ;
+T{ 0 0 2 GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 2 GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP 2 GN1 -> MAX-UINT DUP 0 }T
+T{ 0 0 MAX-BASE GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 MAX-BASE GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP MAX-BASE GN1 -> MAX-UINT DUP 0 }T
+
+: GN2 \ ( -- 16 10 )
+ BASE @ >R HEX BASE @ DECIMAL BASE @ R> BASE ! ;
+T{ GN2 -> 10 A }T
+
+\ ------------------------------------------------------------------------
+TESTING FILL MOVE
+
+CREATE FBUF 00 C, 00 C, 00 C,
+CREATE SBUF 12 C, 34 C, 56 C,
+: SEEBUF FBUF C@ FBUF CHAR+ C@ FBUF CHAR+ CHAR+ C@ ;
+
+T{ FBUF 0 20 FILL -> }T
+T{ SEEBUF -> 00 00 00 }T
+
+T{ FBUF 1 20 FILL -> }T
+T{ SEEBUF -> 20 00 00 }T
+
+T{ FBUF 3 20 FILL -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ FBUF FBUF 3 CHARS MOVE -> }T \ BIZARRE SPECIAL CASE
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 0 CHARS MOVE -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 1 CHARS MOVE -> }T
+T{ SEEBUF -> 12 20 20 }T
+
+T{ SBUF FBUF 3 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 56 }T
+
+T{ FBUF FBUF CHAR+ 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 12 34 }T
+
+T{ FBUF CHAR+ FBUF 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 34 }T
+
+\ ------------------------------------------------------------------------
+TESTING OUTPUT: . ." CR EMIT SPACE SPACES TYPE U.
+
+: OUTPUT-TEST
+ ." YOU SHOULD SEE THE STANDARD GRAPHIC CHARACTERS:" CR
+ 41 BL DO I EMIT LOOP CR
+ 61 41 DO I EMIT LOOP CR
+ 7F 61 DO I EMIT LOOP CR
+ ." YOU SHOULD SEE 0-9 SEPARATED BY A SPACE:" CR
+ 9 1+ 0 DO I . LOOP CR
+ ." YOU SHOULD SEE 0-9 (WITH NO SPACES):" CR
+ [CHAR] 9 1+ [CHAR] 0 DO I 0 SPACES EMIT LOOP CR
+ ." YOU SHOULD SEE A-G SEPARATED BY A SPACE:" CR
+ [CHAR] G 1+ [CHAR] A DO I EMIT SPACE LOOP CR
+ ." YOU SHOULD SEE 0-5 SEPARATED BY TWO SPACES:" CR
+ 5 1+ 0 DO I [CHAR] 0 + EMIT 2 SPACES LOOP CR
+ ." YOU SHOULD SEE TWO SEPARATE LINES:" CR
+ S" LINE 1" TYPE CR S" LINE 2" TYPE CR
+ ." YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:" CR
+ ." SIGNED: " MIN-INT . MAX-INT . CR
+ ." UNSIGNED: " 0 U. MAX-UINT U. CR
+;
+
+T{ OUTPUT-TEST -> }T
+\ ------------------------------------------------------------------------
+TESTING INPUT: ACCEPT
+
+CREATE ABUF 80 CHARS ALLOT
+
+: ACCEPT-TEST
+ CR ." PLEASE TYPE UP TO 80 CHARACTERS:" CR
+ ABUF 80 ACCEPT
+ CR ." RECEIVED: " [CHAR] " EMIT
+ ABUF SWAP TYPE [CHAR] " EMIT CR
+;
+
+T{ ACCEPT-TEST -> }T
+Vingt fois sur le métier remettez votre ouvrage, ...
+\ ------------------------------------------------------------------------
+TESTING DICTIONARY SEARCH RULES
+
+T{ : GDX 123 ; : GDX GDX 234 ; -> }T
+
+T{ GDX -> 123 234 }T
+
+CR .( End of Core word set tests) CR
+
+
+
+RST_STATE ; so ANS_COMPLEMENT_xx_MPY is conserved ;
+\ NOECHO ; if an error occurs, comment this line before new download to find it.
+
+
+\ From: John Hayes S1I
+\ Subject: tester.fr
+\ Date: Mon, 27 Nov 95 13:10:09 PST
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.1
+
+\ 22/1/09 The words { and } have been changed to T{ and }T respectively to
+\ agree with the Forth 200X file ttester.fs. This avoids clashes with
+\ locals using { ... } and the FSL use of }
+
+
+\ 13/05/14 jmt. added colorised error messages.
+
+
+
+ 0 CONSTANT FALSE
+-1 CONSTANT TRUE
+
+\ SET THE FOLLOWING FLAG TO TRUE FOR MORE VERBOSE OUTPUT; THIS MAY
+\ ALLOW YOU TO TELL WHICH TEST CAUSED YOUR SYSTEM TO HANG.
+VARIABLE VERBOSE
+ FALSE VERBOSE !
+\ TRUE VERBOSE !
+
+\ : EMPTY-STACK ( ... -- ) \ EMPTY STACK: HANDLES UNDERFLOWED STACK TOO.
+\ DEPTH ?DUP
+\ IF DUP 0< IF NEGATE 0
+\ DO 0 LOOP
+\ ELSE 0 DO DROP LOOP THEN
+\ THEN ;
+\
+\ : ERROR \ ( C-ADDR U -- ) DISPLAY AN ERROR MESSAGE FOLLOWED BY
+\ \ THE LINE THAT HAD THE ERROR.
+\ TYPE SOURCE TYPE CR \ DISPLAY LINE CORRESPONDING TO ERROR
+\ EMPTY-STACK \ THROW AWAY EVERY THING ELSE
+\ QUIT \ *** Uncomment this line to QUIT on an error
+\ ;
+
+VARIABLE ACTUAL-DEPTH \ STACK RECORD
+CREATE ACTUAL-RESULTS 20 CELLS ALLOT
+
+: T{ \ ( -- ) SYNTACTIC SUGAR.
+ ;
+
+: -> \ ( ... -- ) RECORD DEPTH AND CONTENT OF STACK.
+ DEPTH DUP ACTUAL-DEPTH ! \ RECORD DEPTH
+ ?DUP IF \ IF THERE IS SOMETHING ON STACK
+ 0 DO ACTUAL-RESULTS I CELLS + ! LOOP \ SAVE THEM
+ THEN ;
+
+: }T \ ( ... -- ) COMPARE STACK (EXPECTED) CONTENTS WITH SAVED
+ \ (ACTUAL) CONTENTS.
+ DEPTH ACTUAL-DEPTH @ = IF \ IF DEPTHS MATCH
+ DEPTH ?DUP IF \ IF THERE IS SOMETHING ON THE STACK
+ 0 DO \ FOR EACH STACK ITEM
+ ACTUAL-RESULTS I CELLS + @ \ COMPARE ACTUAL WITH EXPECTED
+\ = 0= IF S" INCORRECT RESULT: " ERROR LEAVE THEN \ jmt
+ = 0= IF ABORT" INCORRECT RESULT: " THEN \ jmt : colorised message
+ LOOP
+ THEN
+ ELSE \ DEPTH MISMATCH
+\ S" WRONG NUMBER OF RESULTS: " ERROR \ jmt
+ ABORT" WRONG NUMBER OF RESULTS: " \ jmt : colorised message
+ THEN ;
+
+: TESTING \ ( -- ) TALKING COMMENT.
+ SOURCE VERBOSE @
+ IF DUP >R TYPE CR R> >IN !
+ ELSE >IN ! DROP [CHAR] * EMIT
+ THEN ;
+
+\ From: John Hayes S1I
+\ Subject: core.fr
+\ Date: Mon, 27 Nov 95 13:10
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.2
+\ THIS PROGRAM TESTS THE CORE WORDS OF AN ANS FORTH SYSTEM.
+\ THE PROGRAM ASSUMES A TWO'S COMPLEMENT IMPLEMENTATION WHERE
+\ THE RANGE OF SIGNED NUMBERS IS -2^(N-1) ... 2^(N-1)-1 AND
+\ THE RANGE OF UNSIGNED NUMBERS IS 0 ... 2^(N)-1.
+\ I HAVEN'T FIGURED OUT HOW TO TEST KEY, QUIT, ABORT, OR ABORT"...
+\ I ALSO HAVEN'T THOUGHT OF A WAY TO TEST ENVIRONMENT?...
+
+CR
+TESTING CORE WORDS
+HEX
+
+\ ------------------------------------------------------------------------
+TESTING BASIC ASSUMPTIONS
+
+T{ -> }T \ START WITH CLEAN SLATE
+( TEST IF ANY BITS ARE SET; ANSWER IN BASE 1 )
+T{ : BITSSET? IF 0 0 ELSE 0 THEN ; -> }T
+T{ 0 BITSSET? -> 0 }T ( ZERO IS ALL BITS CLEAR )
+T{ 1 BITSSET? -> 0 0 }T ( OTHER NUMBER HAVE AT LEAST ONE BIT )
+T{ -1 BITSSET? -> 0 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING BOOLEANS: INVERT AND OR XOR
+
+T{ 0 0 AND -> 0 }T
+T{ 0 1 AND -> 0 }T
+T{ 1 0 AND -> 0 }T
+T{ 1 1 AND -> 1 }T
+
+T{ 0 INVERT 1 AND -> 1 }T
+T{ 1 INVERT 1 AND -> 0 }T
+
+0 CONSTANT 0S
+0 INVERT CONSTANT 1S
+
+T{ 0S INVERT -> 1S }T
+T{ 1S INVERT -> 0S }T
+
+T{ 0S 0S AND -> 0S }T
+T{ 0S 1S AND -> 0S }T
+T{ 1S 0S AND -> 0S }T
+T{ 1S 1S AND -> 1S }T
+
+T{ 0S 0S OR -> 0S }T
+T{ 0S 1S OR -> 1S }T
+T{ 1S 0S OR -> 1S }T
+T{ 1S 1S OR -> 1S }T
+
+T{ 0S 0S XOR -> 0S }T
+T{ 0S 1S XOR -> 1S }T
+T{ 1S 0S XOR -> 1S }T
+T{ 1S 1S XOR -> 0S }T
+
+\ ------------------------------------------------------------------------
+TESTING 2* 2/ LSHIFT RSHIFT
+
+( WE TRUST 1S, INVERT, AND BITSSET?; WE WILL CONFIRM RSHIFT LATER )
+1S 1 RSHIFT INVERT CONSTANT MSB
+T{ MSB BITSSET? -> 0 0 }T
+
+T{ 0S 2* -> 0S }T
+T{ 1 2* -> 2 }T
+T{ 4000 2* -> 8000 }T
+T{ 1S 2* 1 XOR -> 1S }T
+T{ MSB 2* -> 0S }T
+
+T{ 0S 2/ -> 0S }T
+T{ 1 2/ -> 0 }T
+T{ 4000 2/ -> 2000 }T
+T{ 1S 2/ -> 1S }T \ MSB PROPOGATED
+T{ 1S 1 XOR 2/ -> 1S }T
+T{ MSB 2/ MSB AND -> MSB }T
+
+T{ 1 0 LSHIFT -> 1 }T
+T{ 1 1 LSHIFT -> 2 }T
+T{ 1 2 LSHIFT -> 4 }T
+T{ 1 F LSHIFT -> 8000 }T \ BIGGEST GUARANTEED SHIFT
+T{ 1S 1 LSHIFT 1 XOR -> 1S }T
+T{ MSB 1 LSHIFT -> 0 }T
+
+T{ 1 0 RSHIFT -> 1 }T
+T{ 1 1 RSHIFT -> 0 }T
+T{ 2 1 RSHIFT -> 1 }T
+T{ 4 2 RSHIFT -> 1 }T
+T{ 8000 F RSHIFT -> 1 }T \ BIGGEST
+T{ MSB 1 RSHIFT MSB AND -> 0 }T \ RSHIFT ZERO FILLS MSBS
+T{ MSB 1 RSHIFT 2* -> MSB }T
+
+\ ------------------------------------------------------------------------
+TESTING COMPARISONS: 0= = 0< < > U< MIN MAX
+0 INVERT CONSTANT MAX-UINT
+0 INVERT 1 RSHIFT CONSTANT MAX-INT
+0 INVERT 1 RSHIFT INVERT CONSTANT MIN-INT
+0 INVERT 1 RSHIFT CONSTANT MID-UINT
+0 INVERT 1 RSHIFT INVERT CONSTANT MID-UINT+1
+
+0S CONSTANT <FALSE>
+1S CONSTANT <TRUE>
+
+T{ 0 0= -> <TRUE> }T
+T{ 1 0= -> <FALSE> }T
+T{ 2 0= -> <FALSE> }T
+T{ -1 0= -> <FALSE> }T
+T{ MAX-UINT 0= -> <FALSE> }T
+T{ MIN-INT 0= -> <FALSE> }T
+T{ MAX-INT 0= -> <FALSE> }T
+
+T{ 0 0 = -> <TRUE> }T
+T{ 1 1 = -> <TRUE> }T
+T{ -1 -1 = -> <TRUE> }T
+T{ 1 0 = -> <FALSE> }T
+T{ -1 0 = -> <FALSE> }T
+T{ 0 1 = -> <FALSE> }T
+T{ 0 -1 = -> <FALSE> }T
+
+T{ 0 0< -> <FALSE> }T
+T{ -1 0< -> <TRUE> }T
+T{ MIN-INT 0< -> <TRUE> }T
+T{ 1 0< -> <FALSE> }T
+T{ MAX-INT 0< -> <FALSE> }T
+
+T{ 0 1 < -> <TRUE> }T
+T{ 1 2 < -> <TRUE> }T
+T{ -1 0 < -> <TRUE> }T
+T{ -1 1 < -> <TRUE> }T
+T{ MIN-INT 0 < -> <TRUE> }T
+T{ MIN-INT MAX-INT < -> <TRUE> }T
+T{ 0 MAX-INT < -> <TRUE> }T
+T{ 0 0 < -> <FALSE> }T
+T{ 1 1 < -> <FALSE> }T
+T{ 1 0 < -> <FALSE> }T
+T{ 2 1 < -> <FALSE> }T
+T{ 0 -1 < -> <FALSE> }T
+T{ 1 -1 < -> <FALSE> }T
+T{ 0 MIN-INT < -> <FALSE> }T
+T{ MAX-INT MIN-INT < -> <FALSE> }T
+T{ MAX-INT 0 < -> <FALSE> }T
+
+T{ 0 1 > -> <FALSE> }T
+T{ 1 2 > -> <FALSE> }T
+T{ -1 0 > -> <FALSE> }T
+T{ -1 1 > -> <FALSE> }T
+T{ MIN-INT 0 > -> <FALSE> }T
+T{ MIN-INT MAX-INT > -> <FALSE> }T
+T{ 0 MAX-INT > -> <FALSE> }T
+T{ 0 0 > -> <FALSE> }T
+T{ 1 1 > -> <FALSE> }T
+T{ 1 0 > -> <TRUE> }T
+T{ 2 1 > -> <TRUE> }T
+T{ 0 -1 > -> <TRUE> }T
+T{ 1 -1 > -> <TRUE> }T
+T{ 0 MIN-INT > -> <TRUE> }T
+T{ MAX-INT MIN-INT > -> <TRUE> }T
+T{ MAX-INT 0 > -> <TRUE> }T
+
+T{ 0 1 U< -> <TRUE> }T
+T{ 1 2 U< -> <TRUE> }T
+T{ 0 MID-UINT U< -> <TRUE> }T
+T{ 0 MAX-UINT U< -> <TRUE> }T
+T{ MID-UINT MAX-UINT U< -> <TRUE> }T
+T{ 0 0 U< -> <FALSE> }T
+T{ 1 1 U< -> <FALSE> }T
+T{ 1 0 U< -> <FALSE> }T
+T{ 2 1 U< -> <FALSE> }T
+T{ MID-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT MID-UINT U< -> <FALSE> }T
+
+T{ 0 1 MIN -> 0 }T
+T{ 1 2 MIN -> 1 }T
+T{ -1 0 MIN -> -1 }T
+T{ -1 1 MIN -> -1 }T
+T{ MIN-INT 0 MIN -> MIN-INT }T
+T{ MIN-INT MAX-INT MIN -> MIN-INT }T
+T{ 0 MAX-INT MIN -> 0 }T
+T{ 0 0 MIN -> 0 }T
+T{ 1 1 MIN -> 1 }T
+T{ 1 0 MIN -> 0 }T
+T{ 2 1 MIN -> 1 }T
+T{ 0 -1 MIN -> -1 }T
+T{ 1 -1 MIN -> -1 }T
+T{ 0 MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT 0 MIN -> 0 }T
+
+T{ 0 1 MAX -> 1 }T
+T{ 1 2 MAX -> 2 }T
+T{ -1 0 MAX -> 0 }T
+T{ -1 1 MAX -> 1 }T
+T{ MIN-INT 0 MAX -> 0 }T
+T{ MIN-INT MAX-INT MAX -> MAX-INT }T
+T{ 0 MAX-INT MAX -> MAX-INT }T
+T{ 0 0 MAX -> 0 }T
+T{ 1 1 MAX -> 1 }T
+T{ 1 0 MAX -> 1 }T
+T{ 2 1 MAX -> 2 }T
+T{ 0 -1 MAX -> 0 }T
+T{ 1 -1 MAX -> 1 }T
+T{ 0 MIN-INT MAX -> 0 }T
+T{ MAX-INT MIN-INT MAX -> MAX-INT }T
+T{ MAX-INT 0 MAX -> MAX-INT }T
+
+\ ------------------------------------------------------------------------
+TESTING STACK OPS: 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP
+
+T{ 1 2 2DROP -> }T
+T{ 1 2 2DUP -> 1 2 1 2 }T
+T{ 1 2 3 4 2OVER -> 1 2 3 4 1 2 }T
+T{ 1 2 3 4 2SWAP -> 3 4 1 2 }T
+T{ 0 ?DUP -> 0 }T
+T{ 1 ?DUP -> 1 1 }T
+T{ -1 ?DUP -> -1 -1 }T
+T{ DEPTH -> 0 }T
+T{ 0 DEPTH -> 0 1 }T
+T{ 0 1 DEPTH -> 0 1 2 }T
+T{ 0 DROP -> }T
+T{ 1 2 DROP -> 1 }T
+T{ 1 DUP -> 1 1 }T
+T{ 1 2 OVER -> 1 2 1 }T
+T{ 1 2 3 ROT -> 2 3 1 }T
+T{ 1 2 SWAP -> 2 1 }T
+
+\ ------------------------------------------------------------------------
+TESTING >R R> R@
+
+T{ : GR1 >R R> ; -> }T
+T{ : GR2 >R R@ R> DROP ; -> }T
+T{ 123 GR1 -> 123 }T
+T{ 123 GR2 -> 123 }T
+T{ 1S GR1 -> 1S }T ( RETURN STACK HOLDS CELLS )
+
+\ ------------------------------------------------------------------------
+TESTING ADD/SUBTRACT: + - 1+ 1- ABS NEGATE
+
+T{ 0 5 + -> 5 }T
+T{ 5 0 + -> 5 }T
+T{ 0 -5 + -> -5 }T
+T{ -5 0 + -> -5 }T
+T{ 1 2 + -> 3 }T
+T{ 1 -2 + -> -1 }T
+T{ -1 2 + -> 1 }T
+T{ -1 -2 + -> -3 }T
+T{ -1 1 + -> 0 }T
+T{ MID-UINT 1 + -> MID-UINT+1 }T
+
+T{ 0 5 - -> -5 }T
+T{ 5 0 - -> 5 }T
+T{ 0 -5 - -> 5 }T
+T{ -5 0 - -> -5 }T
+T{ 1 2 - -> -1 }T
+T{ 1 -2 - -> 3 }T
+T{ -1 2 - -> -3 }T
+T{ -1 -2 - -> 1 }T
+T{ 0 1 - -> -1 }T
+T{ MID-UINT+1 1 - -> MID-UINT }T
+
+T{ 0 1+ -> 1 }T
+T{ -1 1+ -> 0 }T
+T{ 1 1+ -> 2 }T
+T{ MID-UINT 1+ -> MID-UINT+1 }T
+
+T{ 2 1- -> 1 }T
+T{ 1 1- -> 0 }T
+T{ 0 1- -> -1 }T
+T{ MID-UINT+1 1- -> MID-UINT }T
+
+T{ 0 NEGATE -> 0 }T
+T{ 1 NEGATE -> -1 }T
+T{ -1 NEGATE -> 1 }T
+T{ 2 NEGATE -> -2 }T
+T{ -2 NEGATE -> 2 }T
+
+T{ 0 ABS -> 0 }T
+T{ 1 ABS -> 1 }T
+T{ -1 ABS -> 1 }T
+T{ MIN-INT ABS -> MID-UINT+1 }T
+
+\ ------------------------------------------------------------------------
+TESTING MULTIPLY: S>D * M* UM*
+
+T{ 0 S>D -> 0 0 }T
+T{ 1 S>D -> 1 0 }T
+T{ 2 S>D -> 2 0 }T
+T{ -1 S>D -> -1 -1 }T
+T{ -2 S>D -> -2 -1 }T
+T{ MIN-INT S>D -> MIN-INT -1 }T
+T{ MAX-INT S>D -> MAX-INT 0 }T
+
+T{ 0 0 M* -> 0 S>D }T
+T{ 0 1 M* -> 0 S>D }T
+T{ 1 0 M* -> 0 S>D }T
+T{ 1 2 M* -> 2 S>D }T
+T{ 2 1 M* -> 2 S>D }T
+T{ 3 3 M* -> 9 S>D }T
+T{ -3 3 M* -> -9 S>D }T
+T{ 3 -3 M* -> -9 S>D }T
+T{ -3 -3 M* -> 9 S>D }T
+T{ 0 MIN-INT M* -> 0 S>D }T
+T{ 1 MIN-INT M* -> MIN-INT S>D }T
+T{ 2 MIN-INT M* -> 0 1S }T
+T{ 0 MAX-INT M* -> 0 S>D }T
+T{ 1 MAX-INT M* -> MAX-INT S>D }T
+T{ 2 MAX-INT M* -> MAX-INT 1 LSHIFT 0 }T
+T{ MIN-INT MIN-INT M* -> 0 MSB 1 RSHIFT }T
+T{ MAX-INT MIN-INT M* -> MSB MSB 2/ }T
+T{ MAX-INT MAX-INT M* -> 1 MSB 2/ INVERT }T
+
+T{ 0 0 * -> 0 }T \ TEST IDENTITIES
+T{ 0 1 * -> 0 }T
+T{ 1 0 * -> 0 }T
+T{ 1 2 * -> 2 }T
+T{ 2 1 * -> 2 }T
+T{ 3 3 * -> 9 }T
+T{ -3 3 * -> -9 }T
+T{ 3 -3 * -> -9 }T
+T{ -3 -3 * -> 9 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 * -> MID-UINT+1 }T
+T{ MID-UINT+1 2 RSHIFT 4 * -> MID-UINT+1 }T
+T{ MID-UINT+1 1 RSHIFT MID-UINT+1 OR 2 * -> MID-UINT+1 }T
+
+T{ 0 0 UM* -> 0 0 }T
+T{ 0 1 UM* -> 0 0 }T
+T{ 1 0 UM* -> 0 0 }T
+T{ 1 2 UM* -> 2 0 }T
+T{ 2 1 UM* -> 2 0 }T
+T{ 3 3 UM* -> 9 0 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 UM* -> MID-UINT+1 0 }T
+T{ MID-UINT+1 2 UM* -> 0 1 }T
+T{ MID-UINT+1 4 UM* -> 0 2 }T
+T{ 1S 2 UM* -> 1S 1 LSHIFT 1 }T
+T{ MAX-UINT MAX-UINT UM* -> 1 1 INVERT }T
+
+\ ------------------------------------------------------------------------
+TESTING DIVIDE: FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD
+
+T{ 0 S>D 1 FM/MOD -> 0 0 }T
+T{ 1 S>D 1 FM/MOD -> 0 1 }T
+T{ 2 S>D 1 FM/MOD -> 0 2 }T
+T{ -1 S>D 1 FM/MOD -> 0 -1 }T
+T{ -2 S>D 1 FM/MOD -> 0 -2 }T
+T{ 0 S>D -1 FM/MOD -> 0 0 }T
+T{ 1 S>D -1 FM/MOD -> 0 -1 }T
+T{ 2 S>D -1 FM/MOD -> 0 -2 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -1 FM/MOD -> 0 2 }T
+T{ 2 S>D 2 FM/MOD -> 0 1 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -2 FM/MOD -> 0 1 }T
+T{ 7 S>D 3 FM/MOD -> 1 2 }T
+T{ 7 S>D -3 FM/MOD -> -2 -3 }T
+T{ -7 S>D 3 FM/MOD -> 2 -3 }T
+T{ -7 S>D -3 FM/MOD -> -1 2 }T
+T{ MAX-INT S>D 1 FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT FM/MOD -> 0 1 }T
+T{ MIN-INT S>D MIN-INT FM/MOD -> 0 1 }T
+T{ 1S 1 4 FM/MOD -> 3 MAX-INT }T
+T{ 1 MIN-INT M* 1 FM/MOD -> 0 MIN-INT }T
+T{ 1 MIN-INT M* MIN-INT FM/MOD -> 0 1 }T
+T{ 2 MIN-INT M* 2 FM/MOD -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT FM/MOD -> 0 2 }T
+T{ 1 MAX-INT M* 1 FM/MOD -> 0 MAX-INT }T
+T{ 1 MAX-INT M* MAX-INT FM/MOD -> 0 1 }T
+T{ 2 MAX-INT M* 2 FM/MOD -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT FM/MOD -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT FM/MOD -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT FM/MOD -> 0 MAX-INT }T
+
+T{ 0 S>D 1 SM/REM -> 0 0 }T
+T{ 1 S>D 1 SM/REM -> 0 1 }T
+T{ 2 S>D 1 SM/REM -> 0 2 }T
+T{ -1 S>D 1 SM/REM -> 0 -1 }T
+T{ -2 S>D 1 SM/REM -> 0 -2 }T
+T{ 0 S>D -1 SM/REM -> 0 0 }T
+T{ 1 S>D -1 SM/REM -> 0 -1 }T
+T{ 2 S>D -1 SM/REM -> 0 -2 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -1 SM/REM -> 0 2 }T
+T{ 2 S>D 2 SM/REM -> 0 1 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -2 SM/REM -> 0 1 }T
+T{ 7 S>D 3 SM/REM -> 1 2 }T
+T{ 7 S>D -3 SM/REM -> 1 -2 }T
+T{ -7 S>D 3 SM/REM -> -1 -2 }T
+T{ -7 S>D -3 SM/REM -> -1 2 }T
+T{ MAX-INT S>D 1 SM/REM -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 SM/REM -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT SM/REM -> 0 1 }T
+T{ MIN-INT S>D MIN-INT SM/REM -> 0 1 }T
+T{ 1S 1 4 SM/REM -> 3 MAX-INT }T
+T{ 2 MIN-INT M* 2 SM/REM -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT SM/REM -> 0 2 }T
+T{ 2 MAX-INT M* 2 SM/REM -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT SM/REM -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT SM/REM -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT SM/REM -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT SM/REM -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT SM/REM -> 0 MAX-INT }T
+
+T{ 0 0 1 UM/MOD -> 0 0 }T
+T{ 1 0 1 UM/MOD -> 0 1 }T
+T{ 1 0 2 UM/MOD -> 1 0 }T
+T{ 3 0 2 UM/MOD -> 1 1 }T
+T{ MAX-UINT 2 UM* 2 UM/MOD -> 0 MAX-UINT }T
+T{ MAX-UINT 2 UM* MAX-UINT UM/MOD -> 0 2 }T
+T{ MAX-UINT MAX-UINT UM* MAX-UINT UM/MOD -> 0 MAX-UINT }T
+
+: IFFLOORED
+ [ -3 2 / -2 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+: IFSYM
+ [ -3 2 / -1 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+\ THE SYSTEM MIGHT DO EITHER FLOORED OR SYMMETRIC DIVISION.
+\ SINCE WE HAVE ALREADY TESTED M*, FM/MOD, AND SM/REM WE CAN USE THEM IN TEST.
+
+IFFLOORED : T/MOD >R S>D R> FM/MOD ;
+IFFLOORED : T/ T/MOD SWAP DROP ;
+IFFLOORED : TMOD T/MOD DROP ;
+IFFLOORED : T*/MOD >R M* R> FM/MOD ;
+IFFLOORED : T*/ T*/MOD SWAP DROP ;
+IFSYM : T/MOD >R S>D R> SM/REM ;
+IFSYM : T/ T/MOD SWAP DROP ;
+IFSYM : TMOD T/MOD DROP ;
+IFSYM : T*/MOD >R M* R> SM/REM ;
+IFSYM : T*/ T*/MOD SWAP DROP ;
+
+T{ 0 1 /MOD -> 0 1 T/MOD }T
+T{ 1 1 /MOD -> 1 1 T/MOD }T
+T{ 2 1 /MOD -> 2 1 T/MOD }T
+T{ -1 1 /MOD -> -1 1 T/MOD }T
+T{ -2 1 /MOD -> -2 1 T/MOD }T
+T{ 0 -1 /MOD -> 0 -1 T/MOD }T
+T{ 1 -1 /MOD -> 1 -1 T/MOD }T
+T{ 2 -1 /MOD -> 2 -1 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -1 /MOD -> -2 -1 T/MOD }T
+T{ 2 2 /MOD -> 2 2 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -2 /MOD -> -2 -2 T/MOD }T
+T{ 7 3 /MOD -> 7 3 T/MOD }T
+T{ 7 -3 /MOD -> 7 -3 T/MOD }T
+T{ -7 3 /MOD -> -7 3 T/MOD }T
+T{ -7 -3 /MOD -> -7 -3 T/MOD }T
+T{ MAX-INT 1 /MOD -> MAX-INT 1 T/MOD }T
+T{ MIN-INT 1 /MOD -> MIN-INT 1 T/MOD }T
+T{ MAX-INT MAX-INT /MOD -> MAX-INT MAX-INT T/MOD }T
+T{ MIN-INT MIN-INT /MOD -> MIN-INT MIN-INT T/MOD }T
+
+T{ 0 1 / -> 0 1 T/ }T
+T{ 1 1 / -> 1 1 T/ }T
+T{ 2 1 / -> 2 1 T/ }T
+T{ -1 1 / -> -1 1 T/ }T
+T{ -2 1 / -> -2 1 T/ }T
+T{ 0 -1 / -> 0 -1 T/ }T
+T{ 1 -1 / -> 1 -1 T/ }T
+T{ 2 -1 / -> 2 -1 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -1 / -> -2 -1 T/ }T
+T{ 2 2 / -> 2 2 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -2 / -> -2 -2 T/ }T
+T{ 7 3 / -> 7 3 T/ }T
+T{ 7 -3 / -> 7 -3 T/ }T
+T{ -7 3 / -> -7 3 T/ }T
+T{ -7 -3 / -> -7 -3 T/ }T
+T{ MAX-INT 1 / -> MAX-INT 1 T/ }T
+T{ MIN-INT 1 / -> MIN-INT 1 T/ }T
+T{ MAX-INT MAX-INT / -> MAX-INT MAX-INT T/ }T
+T{ MIN-INT MIN-INT / -> MIN-INT MIN-INT T/ }T
+
+T{ 0 1 MOD -> 0 1 TMOD }T
+T{ 1 1 MOD -> 1 1 TMOD }T
+T{ 2 1 MOD -> 2 1 TMOD }T
+T{ -1 1 MOD -> -1 1 TMOD }T
+T{ -2 1 MOD -> -2 1 TMOD }T
+T{ 0 -1 MOD -> 0 -1 TMOD }T
+T{ 1 -1 MOD -> 1 -1 TMOD }T
+T{ 2 -1 MOD -> 2 -1 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -1 MOD -> -2 -1 TMOD }T
+T{ 2 2 MOD -> 2 2 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -2 MOD -> -2 -2 TMOD }T
+T{ 7 3 MOD -> 7 3 TMOD }T
+T{ 7 -3 MOD -> 7 -3 TMOD }T
+T{ -7 3 MOD -> -7 3 TMOD }T
+T{ -7 -3 MOD -> -7 -3 TMOD }T
+T{ MAX-INT 1 MOD -> MAX-INT 1 TMOD }T
+T{ MIN-INT 1 MOD -> MIN-INT 1 TMOD }T
+T{ MAX-INT MAX-INT MOD -> MAX-INT MAX-INT TMOD }T
+T{ MIN-INT MIN-INT MOD -> MIN-INT MIN-INT TMOD }T
+
+T{ 0 2 1 */ -> 0 2 1 T*/ }T
+T{ 1 2 1 */ -> 1 2 1 T*/ }T
+T{ 2 2 1 */ -> 2 2 1 T*/ }T
+T{ -1 2 1 */ -> -1 2 1 T*/ }T
+T{ -2 2 1 */ -> -2 2 1 T*/ }T
+T{ 0 2 -1 */ -> 0 2 -1 T*/ }T
+T{ 1 2 -1 */ -> 1 2 -1 T*/ }T
+T{ 2 2 -1 */ -> 2 2 -1 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -1 */ -> -2 2 -1 T*/ }T
+T{ 2 2 2 */ -> 2 2 2 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -2 */ -> -2 2 -2 T*/ }T
+T{ 7 2 3 */ -> 7 2 3 T*/ }T
+T{ 7 2 -3 */ -> 7 2 -3 T*/ }T
+T{ -7 2 3 */ -> -7 2 3 T*/ }T
+T{ -7 2 -3 */ -> -7 2 -3 T*/ }T
+T{ MAX-INT 2 MAX-INT */ -> MAX-INT 2 MAX-INT T*/ }T
+T{ MIN-INT 2 MIN-INT */ -> MIN-INT 2 MIN-INT T*/ }T
+
+T{ 0 2 1 */MOD -> 0 2 1 T*/MOD }T
+T{ 1 2 1 */MOD -> 1 2 1 T*/MOD }T
+T{ 2 2 1 */MOD -> 2 2 1 T*/MOD }T
+T{ -1 2 1 */MOD -> -1 2 1 T*/MOD }T
+T{ -2 2 1 */MOD -> -2 2 1 T*/MOD }T
+T{ 0 2 -1 */MOD -> 0 2 -1 T*/MOD }T
+T{ 1 2 -1 */MOD -> 1 2 -1 T*/MOD }T
+T{ 2 2 -1 */MOD -> 2 2 -1 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -1 */MOD -> -2 2 -1 T*/MOD }T
+T{ 2 2 2 */MOD -> 2 2 2 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -2 */MOD -> -2 2 -2 T*/MOD }T
+T{ 7 2 3 */MOD -> 7 2 3 T*/MOD }T
+T{ 7 2 -3 */MOD -> 7 2 -3 T*/MOD }T
+T{ -7 2 3 */MOD -> -7 2 3 T*/MOD }T
+T{ -7 2 -3 */MOD -> -7 2 -3 T*/MOD }T
+T{ MAX-INT 2 MAX-INT */MOD -> MAX-INT 2 MAX-INT T*/MOD }T
+T{ MIN-INT 2 MIN-INT */MOD -> MIN-INT 2 MIN-INT T*/MOD }T
+
+\ ------------------------------------------------------------------------
+TESTING HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2! ALIGN ALIGNED +! ALLOT
+
+HERE 1 ALLOT
+HERE
+CONSTANT 2NDA
+CONSTANT 1STA
+T{ 1STA 2NDA U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STA 1+ -> 2NDA }T \ ... BY ONE ADDRESS UNIT
+( MISSING TEST: NEGATIVE ALLOT )
+
+HERE 1 ,
+HERE 2 ,
+CONSTANT 2ND
+CONSTANT 1ST
+T{ 1ST 2ND U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1ST CELL+ -> 2ND }T \ ... BY ONE CELL
+T{ 1ST 1 CELLS + -> 2ND }T
+T{ 1ST @ 2ND @ -> 1 2 }T
+T{ 5 1ST ! -> }T
+T{ 1ST @ 2ND @ -> 5 2 }T
+T{ 6 2ND ! -> }T
+T{ 1ST @ 2ND @ -> 5 6 }T
+T{ 1ST 2@ -> 6 5 }T
+T{ 2 1 1ST 2! -> }T
+T{ 1ST 2@ -> 2 1 }T
+T{ 1S 1ST ! 1ST @ -> 1S }T \ CAN STORE CELL-WIDE VALUE
+
+HERE 1 C,
+HERE 2 C,
+CONSTANT 2NDC
+CONSTANT 1STC
+T{ 1STC 2NDC U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STC CHAR+ -> 2NDC }T \ ... BY ONE CHAR
+T{ 1STC 1 CHARS + -> 2NDC }T
+T{ 1STC C@ 2NDC C@ -> 1 2 }T
+T{ 3 1STC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 2 }T
+T{ 4 2NDC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 4 }T
+
+ALIGN 1 ALLOT HERE ALIGN HERE 3 CELLS ALLOT
+CONSTANT A-ADDR CONSTANT UA-ADDR
+T{ UA-ADDR ALIGNED -> A-ADDR }T
+T{ 1 A-ADDR C! A-ADDR C@ -> 1 }T
+T{ 1234 A-ADDR ! A-ADDR @ -> 1234 }T
+T{ 123 456 A-ADDR 2! A-ADDR 2@ -> 123 456 }T
+T{ 2 A-ADDR CHAR+ C! A-ADDR CHAR+ C@ -> 2 }T
+T{ 3 A-ADDR CELL+ C! A-ADDR CELL+ C@ -> 3 }T
+T{ 1234 A-ADDR CELL+ ! A-ADDR CELL+ @ -> 1234 }T
+T{ 123 456 A-ADDR CELL+ 2! A-ADDR CELL+ 2@ -> 123 456 }T
+
+: BITS ( X -- U )
+ 0 SWAP BEGIN DUP WHILE DUP MSB AND IF >R 1+ R> THEN 2* REPEAT DROP ;
+( CHARACTERS >= 1 AU, <= SIZE OF CELL, >= 8 BITS )
+T{ 1 CHARS 1 < -> <FALSE> }T
+T{ 1 CHARS 1 CELLS > -> <FALSE> }T
+( TBD: HOW TO FIND NUMBER OF BITS? )
+
+( CELLS >= 1 AU, INTEGRAL MULTIPLE OF CHAR SIZE, >= 16 BITS )
+T{ 1 CELLS 1 < -> <FALSE> }T
+T{ 1 CELLS 1 CHARS MOD -> 0 }T
+T{ 1S BITS 10 < -> <FALSE> }T
+
+T{ 0 1ST ! -> }T
+T{ 1 1ST +! -> }T
+T{ 1ST @ -> 1 }T
+T{ -1 1ST +! 1ST @ -> 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING CHAR [CHAR] [ ] BL S"
+
+T{ BL -> 20 }T
+T{ CHAR X -> 58 }T
+T{ CHAR HELLO -> 48 }T
+T{ : GC1 [CHAR] X ; -> }T
+T{ : GC2 [CHAR] HELLO ; -> }T
+T{ GC1 -> 58 }T
+T{ GC2 -> 48 }T
+T{ : GC3 [ GC1 ] LITERAL ; -> }T
+T{ GC3 -> 58 }T
+T{ : GC4 S" XY" ; -> }T
+T{ GC4 SWAP DROP -> 2 }T
+T{ GC4 DROP DUP C@ SWAP CHAR+ C@ -> 58 59 }T
+
+\ ------------------------------------------------------------------------
+TESTING ' ['] FIND EXECUTE IMMEDIATE COUNT LITERAL POSTPONE STATE
+
+T{ : GT1 123 ; -> }T
+T{ ' GT1 EXECUTE -> 123 }T
+T{ : GT2 ['] GT1 ; IMMEDIATE -> }T
+T{ GT2 EXECUTE -> 123 }T
+HERE 3 C, CHAR G C, CHAR T C, CHAR 1 C, CONSTANT GT1STRING
+HERE 3 C, CHAR G C, CHAR T C, CHAR 2 C, CONSTANT GT2STRING
+T{ GT1STRING FIND -> ' GT1 -1 }T
+T{ GT2STRING FIND -> ' GT2 1 }T
+( HOW TO SEARCH FOR NON-EXISTENT WORD? )
+T{ : GT3 GT2 LITERAL ; -> }T
+T{ GT3 -> ' GT1 }T
+T{ GT1STRING COUNT -> GT1STRING CHAR+ 3 }T
+
+T{ : GT4 POSTPONE GT1 ; IMMEDIATE -> }T
+T{ : GT5 GT4 ; -> }T
+T{ GT5 -> 123 }T
+T{ : GT6 345 ; IMMEDIATE -> }T
+T{ : GT7 POSTPONE GT6 ; -> }T
+T{ GT7 -> 345 }T
+
+T{ : GT8 STATE @ ; IMMEDIATE -> }T
+T{ GT8 -> 0 }T
+T{ : GT9 GT8 LITERAL ; -> }T
+T{ GT9 0= -> <FALSE> }T
+
+\ ------------------------------------------------------------------------
+TESTING IF ELSE THEN BEGIN WHILE REPEAT UNTIL RECURSE
+
+T{ : GI1 IF 123 THEN ; -> }T
+T{ : GI2 IF 123 ELSE 234 THEN ; -> }T
+T{ 0 GI1 -> }T
+T{ 1 GI1 -> 123 }T
+T{ -1 GI1 -> 123 }T
+T{ 0 GI2 -> 234 }T
+T{ 1 GI2 -> 123 }T
+T{ -1 GI1 -> 123 }T
+
+T{ : GI3 BEGIN DUP 5 < WHILE DUP 1+ REPEAT ; -> }T
+T{ 0 GI3 -> 0 1 2 3 4 5 }T
+T{ 4 GI3 -> 4 5 }T
+T{ 5 GI3 -> 5 }T
+T{ 6 GI3 -> 6 }T
+
+T{ : GI4 BEGIN DUP 1+ DUP 5 > UNTIL ; -> }T
+T{ 3 GI4 -> 3 4 5 6 }T
+T{ 5 GI4 -> 5 6 }T
+T{ 6 GI4 -> 6 7 }T
+
+T{ : GI5 BEGIN DUP 2 > WHILE DUP 5 < WHILE DUP 1+ REPEAT 123 ELSE 345 THEN ; -> }T
+T{ 1 GI5 -> 1 345 }T
+T{ 2 GI5 -> 2 345 }T
+T{ 3 GI5 -> 3 4 5 123 }T
+T{ 4 GI5 -> 4 5 123 }T
+T{ 5 GI5 -> 5 123 }T
+
+T{ : GI6 ( N -- 0,1,..N ) DUP IF DUP >R 1- RECURSE R> THEN ; -> }T
+T{ 0 GI6 -> 0 }T
+T{ 1 GI6 -> 0 1 }T
+T{ 2 GI6 -> 0 1 2 }T
+T{ 3 GI6 -> 0 1 2 3 }T
+T{ 4 GI6 -> 0 1 2 3 4 }T
+
+\ ------------------------------------------------------------------------
+TESTING DO LOOP +LOOP I J UNLOOP LEAVE EXIT
+
+T{ : GD1 DO I LOOP ; -> }T
+T{ 4 1 GD1 -> 1 2 3 }T
+T{ 2 -1 GD1 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD1 -> MID-UINT }T
+
+T{ : GD2 DO I -1 +LOOP ; -> }T
+T{ 1 4 GD2 -> 4 3 2 1 }T
+T{ -1 2 GD2 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD2 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD3 DO 1 0 DO J LOOP LOOP ; -> }T
+T{ 4 1 GD3 -> 1 2 3 }T
+T{ 2 -1 GD3 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD3 -> MID-UINT }T
+
+T{ : GD4 DO 1 0 DO J LOOP -1 +LOOP ; -> }T
+T{ 1 4 GD4 -> 4 3 2 1 }T
+T{ -1 2 GD4 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD4 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD5 123 SWAP 0 DO I 4 > IF DROP 234 LEAVE THEN LOOP ; -> }T
+T{ 1 GD5 -> 123 }T
+T{ 5 GD5 -> 123 }T
+T{ 6 GD5 -> 234 }T
+
+T{ : GD6 ( PAT: T{0 0}T,T{0 0}TT{1 0}TT{1 1}T,T{0 0}TT{1 0}TT{1 1}TT{2 0}TT{2 1}TT{2 2}T )
+ 0 SWAP 0 DO
+ I 1+ 0 DO I J + 3 = IF I UNLOOP I UNLOOP EXIT THEN 1+ LOOP
+ LOOP ; -> }T
+T{ 1 GD6 -> 1 }T
+T{ 2 GD6 -> 3 }T
+T{ 3 GD6 -> 4 1 2 }T
+
+\ ------------------------------------------------------------------------
+TESTING DEFINING WORDS: : ; CONSTANT VARIABLE CREATE DOES> >BODY
+
+T{ 123 CONSTANT X123 -> }T
+T{ X123 -> 123 }T
+T{ : EQU CONSTANT ; -> }T
+T{ X123 EQU Y123 -> }T
+T{ Y123 -> 123 }T
+
+T{ VARIABLE V1 -> }T
+T{ 123 V1 ! -> }T
+T{ V1 @ -> 123 }T
+
+T{ : NOP : POSTPONE ; ; -> }T
+T{ NOP NOP1 NOP NOP2 -> }T
+T{ NOP1 -> }T
+T{ NOP2 -> }T
+
+T{ : DOES1 DOES> @ 1 + ; -> }T
+T{ : DOES2 DOES> @ 2 + ; -> }T
+T{ CREATE CR1 -> }T
+T{ CR1 -> HERE }T
+T{ ' CR1 >BODY -> HERE }T
+T{ 1 , -> }T
+T{ CR1 @ -> 1 }T
+T{ DOES1 -> }T
+T{ CR1 -> 2 }T
+T{ DOES2 -> }T
+T{ CR1 -> 3 }T
+
+T{ : WEIRD: CREATE DOES> 1 + DOES> 2 + ; -> }T
+T{ WEIRD: W1 -> }T
+T{ ' W1 >BODY -> HERE }T
+T{ W1 -> HERE 1 + }T
+T{ W1 -> HERE 2 + }T
+
+\ ------------------------------------------------------------------------
+TESTING EVALUATE
+
+: GE1 S" 123" ; IMMEDIATE
+: GE2 S" 123 1+" ; IMMEDIATE
+: GE3 S" : GE4 345 ;" ;
+: GE5 EVALUATE ; IMMEDIATE
+
+T{ GE1 EVALUATE -> 123 }T ( TEST EVALUATE IN INTERP. STATE )
+T{ GE2 EVALUATE -> 124 }T
+T{ GE3 EVALUATE -> }T
+T{ GE4 -> 345 }T
+
+T{ : GE6 GE1 GE5 ; -> }T ( TEST EVALUATE IN COMPILE STATE )
+T{ GE6 -> 123 }T
+T{ : GE7 GE2 GE5 ; -> }T
+T{ GE7 -> 124 }T
+
+\ ------------------------------------------------------------------------
+TESTING SOURCE >IN WORD
+
+: GS1 S" SOURCE" 2DUP EVALUATE
+ >R SWAP >R = R> R> = ;
+T{ GS1 -> <TRUE> <TRUE> }T
+
+VARIABLE SCANS
+: RESCAN? -1 SCANS +! SCANS @ IF 0 >IN ! THEN ;
+
+T{ 2 SCANS !
+345 RESCAN?
+-> 345 345 }T
+
+: GS2 5 SCANS ! S" 123 RESCAN?" EVALUATE ;
+T{ GS2 -> 123 123 123 123 123 }T
+
+: GS3 WORD COUNT SWAP C@ ;
+T{ BL GS3 HELLO -> 5 CHAR H }T
+T{ CHAR " GS3 GOODBYE" -> 7 CHAR G }T
+T{ BL GS3
+DROP -> 0 }T \ BLANK LINE RETURN ZERO-LENGTH STRING
+
+: GS4 SOURCE >IN ! DROP ;
+T{ GS4 123 456
+-> }T
+
+\ ------------------------------------------------------------------------
+TESTING <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL
+
+: S= \ ( ADDR1 C1 ADDR2 C2 -- T/F ) COMPARE TWO STRINGS.
+ >R SWAP R@ = IF \ MAKE SURE STRINGS HAVE SAME LENGTH
+ R> ?DUP IF \ IF NON-EMPTY STRINGS
+ 0 DO
+ OVER C@ OVER C@ - IF
+ 2DROP <FALSE> UNLOOP EXIT THEN
+ SWAP CHAR+ SWAP CHAR+
+ LOOP
+ THEN
+ 2DROP <TRUE> \ IF WE GET HERE, STRINGS MATCH
+ ELSE
+ R> DROP 2DROP <FALSE> \ LENGTHS MISMATCH
+ THEN ;
+
+: GP1 <# 41 HOLD 42 HOLD 0 0 #> S" BA" S= ;
+T{ GP1 -> <TRUE> }T
+
+: GP2 <# -1 SIGN 0 SIGN -1 SIGN 0 0 #> S" --" S= ;
+T{ GP2 -> <TRUE> }T
+
+: GP3 <# 1 0 # # #> S" 01" S= ;
+T{ GP3 -> <TRUE> }T
+
+: GP4 <# 1 0 #S #> S" 1" S= ;
+T{ GP4 -> <TRUE> }T
+
+24 CONSTANT MAX-BASE \ BASE 2 .. 36
+: COUNT-BITS
+ 0 0 INVERT BEGIN DUP WHILE >R 1+ R> 2* REPEAT DROP ;
+COUNT-BITS 2* CONSTANT #BITS-UD \ NUMBER OF BITS IN UD
+
+: GP5
+ BASE @ <TRUE>
+ MAX-BASE 1+ 2 DO \ FOR EACH POSSIBLE BASE
+ I BASE ! \ TBD: ASSUMES BASE WORKS
+ I 0 <# #S #> S" 10" S= AND
+ LOOP
+ SWAP BASE ! ;
+T{ GP5 -> <TRUE> }T
+
+: GP6
+ BASE @ >R 2 BASE !
+ MAX-UINT MAX-UINT <# #S #> \ MAXIMUM UD TO BINARY
+ R> BASE ! \ S: C-ADDR U
+ DUP #BITS-UD = SWAP
+ 0 DO \ S: C-ADDR FLAG
+ OVER C@ [CHAR] 1 = AND \ ALL ONES
+ >R CHAR+ R>
+ LOOP SWAP DROP ;
+T{ GP6 -> <TRUE> }T
+
+: GP7
+ BASE @ >R MAX-BASE BASE !
+ <TRUE>
+ A 0 DO
+ I 0 <# #S #>
+ 1 = SWAP C@ I 30 + = AND AND
+ LOOP
+ MAX-BASE A DO
+ I 0 <# #S #>
+ 1 = SWAP C@ 41 I A - + = AND AND
+ LOOP
+ R> BASE ! ;
+
+T{ GP7 -> <TRUE> }T
+
+\ >NUMBER TESTS
+CREATE GN-BUF 0 C,
+: GN-STRING GN-BUF 1 ;
+: GN-CONSUMED GN-BUF CHAR+ 0 ;
+: GN' [CHAR] ' WORD CHAR+ C@ GN-BUF C! GN-STRING ;
+
+T{ 0 0 GN' 0' >NUMBER -> 0 0 GN-CONSUMED }T
+T{ 0 0 GN' 1' >NUMBER -> 1 0 GN-CONSUMED }T
+T{ 1 0 GN' 1' >NUMBER -> BASE @ 1+ 0 GN-CONSUMED }T
+T{ 0 0 GN' -' >NUMBER -> 0 0 GN-STRING }T \ SHOULD FAIL TO CONVERT THESE
+T{ 0 0 GN' +' >NUMBER -> 0 0 GN-STRING }T
+T{ 0 0 GN' .' >NUMBER -> 0 0 GN-STRING }T
+
+: >NUMBER-BASED
+ BASE @ >R BASE ! >NUMBER R> BASE ! ;
+
+T{ 0 0 GN' 2' 10 >NUMBER-BASED -> 2 0 GN-CONSUMED }T
+T{ 0 0 GN' 2' 2 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' F' 10 >NUMBER-BASED -> F 0 GN-CONSUMED }T
+T{ 0 0 GN' G' 10 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' G' MAX-BASE >NUMBER-BASED -> 10 0 GN-CONSUMED }T
+T{ 0 0 GN' Z' MAX-BASE >NUMBER-BASED -> 23 0 GN-CONSUMED }T
+
+: GN1 \ ( UD BASE -- UD' LEN ) UD SHOULD EQUAL UD' AND LEN SHOULD BE ZERO.
+ BASE @ >R BASE !
+ <# #S #>
+ 0 0 2SWAP >NUMBER SWAP DROP \ RETURN LENGTH ONLY
+ R> BASE ! ;
+T{ 0 0 2 GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 2 GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP 2 GN1 -> MAX-UINT DUP 0 }T
+T{ 0 0 MAX-BASE GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 MAX-BASE GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP MAX-BASE GN1 -> MAX-UINT DUP 0 }T
+
+: GN2 \ ( -- 16 10 )
+ BASE @ >R HEX BASE @ DECIMAL BASE @ R> BASE ! ;
+T{ GN2 -> 10 A }T
+
+\ ------------------------------------------------------------------------
+TESTING FILL MOVE
+
+CREATE FBUF 00 C, 00 C, 00 C,
+CREATE SBUF 12 C, 34 C, 56 C,
+: SEEBUF FBUF C@ FBUF CHAR+ C@ FBUF CHAR+ CHAR+ C@ ;
+
+T{ FBUF 0 20 FILL -> }T
+T{ SEEBUF -> 00 00 00 }T
+
+T{ FBUF 1 20 FILL -> }T
+T{ SEEBUF -> 20 00 00 }T
+
+T{ FBUF 3 20 FILL -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ FBUF FBUF 3 CHARS MOVE -> }T \ BIZARRE SPECIAL CASE
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 0 CHARS MOVE -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 1 CHARS MOVE -> }T
+T{ SEEBUF -> 12 20 20 }T
+
+T{ SBUF FBUF 3 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 56 }T
+
+T{ FBUF FBUF CHAR+ 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 12 34 }T
+
+T{ FBUF CHAR+ FBUF 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 34 }T
+
+\ ------------------------------------------------------------------------
+TESTING OUTPUT: . ." CR EMIT SPACE SPACES TYPE U.
+
+: OUTPUT-TEST
+ ." YOU SHOULD SEE THE STANDARD GRAPHIC CHARACTERS:" CR
+ 41 BL DO I EMIT LOOP CR
+ 61 41 DO I EMIT LOOP CR
+ 7F 61 DO I EMIT LOOP CR
+ ." YOU SHOULD SEE 0-9 SEPARATED BY A SPACE:" CR
+ 9 1+ 0 DO I . LOOP CR
+ ." YOU SHOULD SEE 0-9 (WITH NO SPACES):" CR
+ [CHAR] 9 1+ [CHAR] 0 DO I 0 SPACES EMIT LOOP CR
+ ." YOU SHOULD SEE A-G SEPARATED BY A SPACE:" CR
+ [CHAR] G 1+ [CHAR] A DO I EMIT SPACE LOOP CR
+ ." YOU SHOULD SEE 0-5 SEPARATED BY TWO SPACES:" CR
+ 5 1+ 0 DO I [CHAR] 0 + EMIT 2 SPACES LOOP CR
+ ." YOU SHOULD SEE TWO SEPARATE LINES:" CR
+ S" LINE 1" TYPE CR S" LINE 2" TYPE CR
+ ." YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:" CR
+ ." SIGNED: " MIN-INT . MAX-INT . CR
+ ." UNSIGNED: " 0 U. MAX-UINT U. CR
+;
+
+T{ OUTPUT-TEST -> }T
+\ ------------------------------------------------------------------------
+TESTING INPUT: ACCEPT
+
+CREATE ABUF 80 CHARS ALLOT
+
+: ACCEPT-TEST
+ CR ." PLEASE TYPE UP TO 80 CHARACTERS:" CR
+ ABUF 80 ACCEPT
+ CR ." RECEIVED: " [CHAR] " EMIT
+ ABUF SWAP TYPE [CHAR] " EMIT CR
+;
+
+T{ ACCEPT-TEST -> }T
+Vingt fois sur le métier remettez votre ouvrage, ...
+\ ------------------------------------------------------------------------
+TESTING DICTIONARY SEARCH RULES
+
+T{ : GDX 123 ; : GDX GDX 234 ; -> }T
+
+T{ GDX -> 123 234 }T
+
+CR .( End of Core word set tests) CR
+
+
+
+RST_STATE ; so ANS_COMPLEMENT_xx_MPY is conserved ;
+\ NOECHO ; if an error occurs, comment this line before new download to find it.
+
+
+\ From: John Hayes S1I
+\ Subject: tester.fr
+\ Date: Mon, 27 Nov 95 13:10:09 PST
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.1
+
+\ 22/1/09 The words { and } have been changed to T{ and }T respectively to
+\ agree with the Forth 200X file ttester.fs. This avoids clashes with
+\ locals using { ... } and the FSL use of }
+
+
+\ 13/05/14 jmt. added colorised error messages.
+
+
+
+ 0 CONSTANT FALSE
+-1 CONSTANT TRUE
+
+\ SET THE FOLLOWING FLAG TO TRUE FOR MORE VERBOSE OUTPUT; THIS MAY
+\ ALLOW YOU TO TELL WHICH TEST CAUSED YOUR SYSTEM TO HANG.
+VARIABLE VERBOSE
+ FALSE VERBOSE !
+\ TRUE VERBOSE !
+
+\ : EMPTY-STACK ( ... -- ) \ EMPTY STACK: HANDLES UNDERFLOWED STACK TOO.
+\ DEPTH ?DUP
+\ IF DUP 0< IF NEGATE 0
+\ DO 0 LOOP
+\ ELSE 0 DO DROP LOOP THEN
+\ THEN ;
+\
+\ : ERROR \ ( C-ADDR U -- ) DISPLAY AN ERROR MESSAGE FOLLOWED BY
+\ \ THE LINE THAT HAD THE ERROR.
+\ TYPE SOURCE TYPE CR \ DISPLAY LINE CORRESPONDING TO ERROR
+\ EMPTY-STACK \ THROW AWAY EVERY THING ELSE
+\ QUIT \ *** Uncomment this line to QUIT on an error
+\ ;
+
+VARIABLE ACTUAL-DEPTH \ STACK RECORD
+CREATE ACTUAL-RESULTS 20 CELLS ALLOT
+
+: T{ \ ( -- ) SYNTACTIC SUGAR.
+ ;
+
+: -> \ ( ... -- ) RECORD DEPTH AND CONTENT OF STACK.
+ DEPTH DUP ACTUAL-DEPTH ! \ RECORD DEPTH
+ ?DUP IF \ IF THERE IS SOMETHING ON STACK
+ 0 DO ACTUAL-RESULTS I CELLS + ! LOOP \ SAVE THEM
+ THEN ;
+
+: }T \ ( ... -- ) COMPARE STACK (EXPECTED) CONTENTS WITH SAVED
+ \ (ACTUAL) CONTENTS.
+ DEPTH ACTUAL-DEPTH @ = IF \ IF DEPTHS MATCH
+ DEPTH ?DUP IF \ IF THERE IS SOMETHING ON THE STACK
+ 0 DO \ FOR EACH STACK ITEM
+ ACTUAL-RESULTS I CELLS + @ \ COMPARE ACTUAL WITH EXPECTED
+\ = 0= IF S" INCORRECT RESULT: " ERROR LEAVE THEN \ jmt
+ = 0= IF ABORT" INCORRECT RESULT: " THEN \ jmt : colorised message
+ LOOP
+ THEN
+ ELSE \ DEPTH MISMATCH
+\ S" WRONG NUMBER OF RESULTS: " ERROR \ jmt
+ ABORT" WRONG NUMBER OF RESULTS: " \ jmt : colorised message
+ THEN ;
+
+: TESTING \ ( -- ) TALKING COMMENT.
+ SOURCE VERBOSE @
+ IF DUP >R TYPE CR R> >IN !
+ ELSE >IN ! DROP [CHAR] * EMIT
+ THEN ;
+
+\ From: John Hayes S1I
+\ Subject: core.fr
+\ Date: Mon, 27 Nov 95 13:10
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.2
+\ THIS PROGRAM TESTS THE CORE WORDS OF AN ANS FORTH SYSTEM.
+\ THE PROGRAM ASSUMES A TWO'S COMPLEMENT IMPLEMENTATION WHERE
+\ THE RANGE OF SIGNED NUMBERS IS -2^(N-1) ... 2^(N-1)-1 AND
+\ THE RANGE OF UNSIGNED NUMBERS IS 0 ... 2^(N)-1.
+\ I HAVEN'T FIGURED OUT HOW TO TEST KEY, QUIT, ABORT, OR ABORT"...
+\ I ALSO HAVEN'T THOUGHT OF A WAY TO TEST ENVIRONMENT?...
+
+CR
+TESTING CORE WORDS
+HEX
+
+\ ------------------------------------------------------------------------
+TESTING BASIC ASSUMPTIONS
+
+T{ -> }T \ START WITH CLEAN SLATE
+( TEST IF ANY BITS ARE SET; ANSWER IN BASE 1 )
+T{ : BITSSET? IF 0 0 ELSE 0 THEN ; -> }T
+T{ 0 BITSSET? -> 0 }T ( ZERO IS ALL BITS CLEAR )
+T{ 1 BITSSET? -> 0 0 }T ( OTHER NUMBER HAVE AT LEAST ONE BIT )
+T{ -1 BITSSET? -> 0 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING BOOLEANS: INVERT AND OR XOR
+
+T{ 0 0 AND -> 0 }T
+T{ 0 1 AND -> 0 }T
+T{ 1 0 AND -> 0 }T
+T{ 1 1 AND -> 1 }T
+
+T{ 0 INVERT 1 AND -> 1 }T
+T{ 1 INVERT 1 AND -> 0 }T
+
+0 CONSTANT 0S
+0 INVERT CONSTANT 1S
+
+T{ 0S INVERT -> 1S }T
+T{ 1S INVERT -> 0S }T
+
+T{ 0S 0S AND -> 0S }T
+T{ 0S 1S AND -> 0S }T
+T{ 1S 0S AND -> 0S }T
+T{ 1S 1S AND -> 1S }T
+
+T{ 0S 0S OR -> 0S }T
+T{ 0S 1S OR -> 1S }T
+T{ 1S 0S OR -> 1S }T
+T{ 1S 1S OR -> 1S }T
+
+T{ 0S 0S XOR -> 0S }T
+T{ 0S 1S XOR -> 1S }T
+T{ 1S 0S XOR -> 1S }T
+T{ 1S 1S XOR -> 0S }T
+
+\ ------------------------------------------------------------------------
+TESTING 2* 2/ LSHIFT RSHIFT
+
+( WE TRUST 1S, INVERT, AND BITSSET?; WE WILL CONFIRM RSHIFT LATER )
+1S 1 RSHIFT INVERT CONSTANT MSB
+T{ MSB BITSSET? -> 0 0 }T
+
+T{ 0S 2* -> 0S }T
+T{ 1 2* -> 2 }T
+T{ 4000 2* -> 8000 }T
+T{ 1S 2* 1 XOR -> 1S }T
+T{ MSB 2* -> 0S }T
+
+T{ 0S 2/ -> 0S }T
+T{ 1 2/ -> 0 }T
+T{ 4000 2/ -> 2000 }T
+T{ 1S 2/ -> 1S }T \ MSB PROPOGATED
+T{ 1S 1 XOR 2/ -> 1S }T
+T{ MSB 2/ MSB AND -> MSB }T
+
+T{ 1 0 LSHIFT -> 1 }T
+T{ 1 1 LSHIFT -> 2 }T
+T{ 1 2 LSHIFT -> 4 }T
+T{ 1 F LSHIFT -> 8000 }T \ BIGGEST GUARANTEED SHIFT
+T{ 1S 1 LSHIFT 1 XOR -> 1S }T
+T{ MSB 1 LSHIFT -> 0 }T
+
+T{ 1 0 RSHIFT -> 1 }T
+T{ 1 1 RSHIFT -> 0 }T
+T{ 2 1 RSHIFT -> 1 }T
+T{ 4 2 RSHIFT -> 1 }T
+T{ 8000 F RSHIFT -> 1 }T \ BIGGEST
+T{ MSB 1 RSHIFT MSB AND -> 0 }T \ RSHIFT ZERO FILLS MSBS
+T{ MSB 1 RSHIFT 2* -> MSB }T
+
+\ ------------------------------------------------------------------------
+TESTING COMPARISONS: 0= = 0< < > U< MIN MAX
+0 INVERT CONSTANT MAX-UINT
+0 INVERT 1 RSHIFT CONSTANT MAX-INT
+0 INVERT 1 RSHIFT INVERT CONSTANT MIN-INT
+0 INVERT 1 RSHIFT CONSTANT MID-UINT
+0 INVERT 1 RSHIFT INVERT CONSTANT MID-UINT+1
+
+0S CONSTANT <FALSE>
+1S CONSTANT <TRUE>
+
+T{ 0 0= -> <TRUE> }T
+T{ 1 0= -> <FALSE> }T
+T{ 2 0= -> <FALSE> }T
+T{ -1 0= -> <FALSE> }T
+T{ MAX-UINT 0= -> <FALSE> }T
+T{ MIN-INT 0= -> <FALSE> }T
+T{ MAX-INT 0= -> <FALSE> }T
+
+T{ 0 0 = -> <TRUE> }T
+T{ 1 1 = -> <TRUE> }T
+T{ -1 -1 = -> <TRUE> }T
+T{ 1 0 = -> <FALSE> }T
+T{ -1 0 = -> <FALSE> }T
+T{ 0 1 = -> <FALSE> }T
+T{ 0 -1 = -> <FALSE> }T
+
+T{ 0 0< -> <FALSE> }T
+T{ -1 0< -> <TRUE> }T
+T{ MIN-INT 0< -> <TRUE> }T
+T{ 1 0< -> <FALSE> }T
+T{ MAX-INT 0< -> <FALSE> }T
+
+T{ 0 1 < -> <TRUE> }T
+T{ 1 2 < -> <TRUE> }T
+T{ -1 0 < -> <TRUE> }T
+T{ -1 1 < -> <TRUE> }T
+T{ MIN-INT 0 < -> <TRUE> }T
+T{ MIN-INT MAX-INT < -> <TRUE> }T
+T{ 0 MAX-INT < -> <TRUE> }T
+T{ 0 0 < -> <FALSE> }T
+T{ 1 1 < -> <FALSE> }T
+T{ 1 0 < -> <FALSE> }T
+T{ 2 1 < -> <FALSE> }T
+T{ 0 -1 < -> <FALSE> }T
+T{ 1 -1 < -> <FALSE> }T
+T{ 0 MIN-INT < -> <FALSE> }T
+T{ MAX-INT MIN-INT < -> <FALSE> }T
+T{ MAX-INT 0 < -> <FALSE> }T
+
+T{ 0 1 > -> <FALSE> }T
+T{ 1 2 > -> <FALSE> }T
+T{ -1 0 > -> <FALSE> }T
+T{ -1 1 > -> <FALSE> }T
+T{ MIN-INT 0 > -> <FALSE> }T
+T{ MIN-INT MAX-INT > -> <FALSE> }T
+T{ 0 MAX-INT > -> <FALSE> }T
+T{ 0 0 > -> <FALSE> }T
+T{ 1 1 > -> <FALSE> }T
+T{ 1 0 > -> <TRUE> }T
+T{ 2 1 > -> <TRUE> }T
+T{ 0 -1 > -> <TRUE> }T
+T{ 1 -1 > -> <TRUE> }T
+T{ 0 MIN-INT > -> <TRUE> }T
+T{ MAX-INT MIN-INT > -> <TRUE> }T
+T{ MAX-INT 0 > -> <TRUE> }T
+
+T{ 0 1 U< -> <TRUE> }T
+T{ 1 2 U< -> <TRUE> }T
+T{ 0 MID-UINT U< -> <TRUE> }T
+T{ 0 MAX-UINT U< -> <TRUE> }T
+T{ MID-UINT MAX-UINT U< -> <TRUE> }T
+T{ 0 0 U< -> <FALSE> }T
+T{ 1 1 U< -> <FALSE> }T
+T{ 1 0 U< -> <FALSE> }T
+T{ 2 1 U< -> <FALSE> }T
+T{ MID-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT MID-UINT U< -> <FALSE> }T
+
+T{ 0 1 MIN -> 0 }T
+T{ 1 2 MIN -> 1 }T
+T{ -1 0 MIN -> -1 }T
+T{ -1 1 MIN -> -1 }T
+T{ MIN-INT 0 MIN -> MIN-INT }T
+T{ MIN-INT MAX-INT MIN -> MIN-INT }T
+T{ 0 MAX-INT MIN -> 0 }T
+T{ 0 0 MIN -> 0 }T
+T{ 1 1 MIN -> 1 }T
+T{ 1 0 MIN -> 0 }T
+T{ 2 1 MIN -> 1 }T
+T{ 0 -1 MIN -> -1 }T
+T{ 1 -1 MIN -> -1 }T
+T{ 0 MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT 0 MIN -> 0 }T
+
+T{ 0 1 MAX -> 1 }T
+T{ 1 2 MAX -> 2 }T
+T{ -1 0 MAX -> 0 }T
+T{ -1 1 MAX -> 1 }T
+T{ MIN-INT 0 MAX -> 0 }T
+T{ MIN-INT MAX-INT MAX -> MAX-INT }T
+T{ 0 MAX-INT MAX -> MAX-INT }T
+T{ 0 0 MAX -> 0 }T
+T{ 1 1 MAX -> 1 }T
+T{ 1 0 MAX -> 1 }T
+T{ 2 1 MAX -> 2 }T
+T{ 0 -1 MAX -> 0 }T
+T{ 1 -1 MAX -> 1 }T
+T{ 0 MIN-INT MAX -> 0 }T
+T{ MAX-INT MIN-INT MAX -> MAX-INT }T
+T{ MAX-INT 0 MAX -> MAX-INT }T
+
+\ ------------------------------------------------------------------------
+TESTING STACK OPS: 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP
+
+T{ 1 2 2DROP -> }T
+T{ 1 2 2DUP -> 1 2 1 2 }T
+T{ 1 2 3 4 2OVER -> 1 2 3 4 1 2 }T
+T{ 1 2 3 4 2SWAP -> 3 4 1 2 }T
+T{ 0 ?DUP -> 0 }T
+T{ 1 ?DUP -> 1 1 }T
+T{ -1 ?DUP -> -1 -1 }T
+T{ DEPTH -> 0 }T
+T{ 0 DEPTH -> 0 1 }T
+T{ 0 1 DEPTH -> 0 1 2 }T
+T{ 0 DROP -> }T
+T{ 1 2 DROP -> 1 }T
+T{ 1 DUP -> 1 1 }T
+T{ 1 2 OVER -> 1 2 1 }T
+T{ 1 2 3 ROT -> 2 3 1 }T
+T{ 1 2 SWAP -> 2 1 }T
+
+\ ------------------------------------------------------------------------
+TESTING >R R> R@
+
+T{ : GR1 >R R> ; -> }T
+T{ : GR2 >R R@ R> DROP ; -> }T
+T{ 123 GR1 -> 123 }T
+T{ 123 GR2 -> 123 }T
+T{ 1S GR1 -> 1S }T ( RETURN STACK HOLDS CELLS )
+
+\ ------------------------------------------------------------------------
+TESTING ADD/SUBTRACT: + - 1+ 1- ABS NEGATE
+
+T{ 0 5 + -> 5 }T
+T{ 5 0 + -> 5 }T
+T{ 0 -5 + -> -5 }T
+T{ -5 0 + -> -5 }T
+T{ 1 2 + -> 3 }T
+T{ 1 -2 + -> -1 }T
+T{ -1 2 + -> 1 }T
+T{ -1 -2 + -> -3 }T
+T{ -1 1 + -> 0 }T
+T{ MID-UINT 1 + -> MID-UINT+1 }T
+
+T{ 0 5 - -> -5 }T
+T{ 5 0 - -> 5 }T
+T{ 0 -5 - -> 5 }T
+T{ -5 0 - -> -5 }T
+T{ 1 2 - -> -1 }T
+T{ 1 -2 - -> 3 }T
+T{ -1 2 - -> -3 }T
+T{ -1 -2 - -> 1 }T
+T{ 0 1 - -> -1 }T
+T{ MID-UINT+1 1 - -> MID-UINT }T
+
+T{ 0 1+ -> 1 }T
+T{ -1 1+ -> 0 }T
+T{ 1 1+ -> 2 }T
+T{ MID-UINT 1+ -> MID-UINT+1 }T
+
+T{ 2 1- -> 1 }T
+T{ 1 1- -> 0 }T
+T{ 0 1- -> -1 }T
+T{ MID-UINT+1 1- -> MID-UINT }T
+
+T{ 0 NEGATE -> 0 }T
+T{ 1 NEGATE -> -1 }T
+T{ -1 NEGATE -> 1 }T
+T{ 2 NEGATE -> -2 }T
+T{ -2 NEGATE -> 2 }T
+
+T{ 0 ABS -> 0 }T
+T{ 1 ABS -> 1 }T
+T{ -1 ABS -> 1 }T
+T{ MIN-INT ABS -> MID-UINT+1 }T
+
+\ ------------------------------------------------------------------------
+TESTING MULTIPLY: S>D * M* UM*
+
+T{ 0 S>D -> 0 0 }T
+T{ 1 S>D -> 1 0 }T
+T{ 2 S>D -> 2 0 }T
+T{ -1 S>D -> -1 -1 }T
+T{ -2 S>D -> -2 -1 }T
+T{ MIN-INT S>D -> MIN-INT -1 }T
+T{ MAX-INT S>D -> MAX-INT 0 }T
+
+T{ 0 0 M* -> 0 S>D }T
+T{ 0 1 M* -> 0 S>D }T
+T{ 1 0 M* -> 0 S>D }T
+T{ 1 2 M* -> 2 S>D }T
+T{ 2 1 M* -> 2 S>D }T
+T{ 3 3 M* -> 9 S>D }T
+T{ -3 3 M* -> -9 S>D }T
+T{ 3 -3 M* -> -9 S>D }T
+T{ -3 -3 M* -> 9 S>D }T
+T{ 0 MIN-INT M* -> 0 S>D }T
+T{ 1 MIN-INT M* -> MIN-INT S>D }T
+T{ 2 MIN-INT M* -> 0 1S }T
+T{ 0 MAX-INT M* -> 0 S>D }T
+T{ 1 MAX-INT M* -> MAX-INT S>D }T
+T{ 2 MAX-INT M* -> MAX-INT 1 LSHIFT 0 }T
+T{ MIN-INT MIN-INT M* -> 0 MSB 1 RSHIFT }T
+T{ MAX-INT MIN-INT M* -> MSB MSB 2/ }T
+T{ MAX-INT MAX-INT M* -> 1 MSB 2/ INVERT }T
+
+T{ 0 0 * -> 0 }T \ TEST IDENTITIES
+T{ 0 1 * -> 0 }T
+T{ 1 0 * -> 0 }T
+T{ 1 2 * -> 2 }T
+T{ 2 1 * -> 2 }T
+T{ 3 3 * -> 9 }T
+T{ -3 3 * -> -9 }T
+T{ 3 -3 * -> -9 }T
+T{ -3 -3 * -> 9 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 * -> MID-UINT+1 }T
+T{ MID-UINT+1 2 RSHIFT 4 * -> MID-UINT+1 }T
+T{ MID-UINT+1 1 RSHIFT MID-UINT+1 OR 2 * -> MID-UINT+1 }T
+
+T{ 0 0 UM* -> 0 0 }T
+T{ 0 1 UM* -> 0 0 }T
+T{ 1 0 UM* -> 0 0 }T
+T{ 1 2 UM* -> 2 0 }T
+T{ 2 1 UM* -> 2 0 }T
+T{ 3 3 UM* -> 9 0 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 UM* -> MID-UINT+1 0 }T
+T{ MID-UINT+1 2 UM* -> 0 1 }T
+T{ MID-UINT+1 4 UM* -> 0 2 }T
+T{ 1S 2 UM* -> 1S 1 LSHIFT 1 }T
+T{ MAX-UINT MAX-UINT UM* -> 1 1 INVERT }T
+
+\ ------------------------------------------------------------------------
+TESTING DIVIDE: FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD
+
+T{ 0 S>D 1 FM/MOD -> 0 0 }T
+T{ 1 S>D 1 FM/MOD -> 0 1 }T
+T{ 2 S>D 1 FM/MOD -> 0 2 }T
+T{ -1 S>D 1 FM/MOD -> 0 -1 }T
+T{ -2 S>D 1 FM/MOD -> 0 -2 }T
+T{ 0 S>D -1 FM/MOD -> 0 0 }T
+T{ 1 S>D -1 FM/MOD -> 0 -1 }T
+T{ 2 S>D -1 FM/MOD -> 0 -2 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -1 FM/MOD -> 0 2 }T
+T{ 2 S>D 2 FM/MOD -> 0 1 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -2 FM/MOD -> 0 1 }T
+T{ 7 S>D 3 FM/MOD -> 1 2 }T
+T{ 7 S>D -3 FM/MOD -> -2 -3 }T
+T{ -7 S>D 3 FM/MOD -> 2 -3 }T
+T{ -7 S>D -3 FM/MOD -> -1 2 }T
+T{ MAX-INT S>D 1 FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT FM/MOD -> 0 1 }T
+T{ MIN-INT S>D MIN-INT FM/MOD -> 0 1 }T
+T{ 1S 1 4 FM/MOD -> 3 MAX-INT }T
+T{ 1 MIN-INT M* 1 FM/MOD -> 0 MIN-INT }T
+T{ 1 MIN-INT M* MIN-INT FM/MOD -> 0 1 }T
+T{ 2 MIN-INT M* 2 FM/MOD -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT FM/MOD -> 0 2 }T
+T{ 1 MAX-INT M* 1 FM/MOD -> 0 MAX-INT }T
+T{ 1 MAX-INT M* MAX-INT FM/MOD -> 0 1 }T
+T{ 2 MAX-INT M* 2 FM/MOD -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT FM/MOD -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT FM/MOD -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT FM/MOD -> 0 MAX-INT }T
+
+T{ 0 S>D 1 SM/REM -> 0 0 }T
+T{ 1 S>D 1 SM/REM -> 0 1 }T
+T{ 2 S>D 1 SM/REM -> 0 2 }T
+T{ -1 S>D 1 SM/REM -> 0 -1 }T
+T{ -2 S>D 1 SM/REM -> 0 -2 }T
+T{ 0 S>D -1 SM/REM -> 0 0 }T
+T{ 1 S>D -1 SM/REM -> 0 -1 }T
+T{ 2 S>D -1 SM/REM -> 0 -2 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -1 SM/REM -> 0 2 }T
+T{ 2 S>D 2 SM/REM -> 0 1 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -2 SM/REM -> 0 1 }T
+T{ 7 S>D 3 SM/REM -> 1 2 }T
+T{ 7 S>D -3 SM/REM -> 1 -2 }T
+T{ -7 S>D 3 SM/REM -> -1 -2 }T
+T{ -7 S>D -3 SM/REM -> -1 2 }T
+T{ MAX-INT S>D 1 SM/REM -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 SM/REM -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT SM/REM -> 0 1 }T
+T{ MIN-INT S>D MIN-INT SM/REM -> 0 1 }T
+T{ 1S 1 4 SM/REM -> 3 MAX-INT }T
+T{ 2 MIN-INT M* 2 SM/REM -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT SM/REM -> 0 2 }T
+T{ 2 MAX-INT M* 2 SM/REM -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT SM/REM -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT SM/REM -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT SM/REM -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT SM/REM -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT SM/REM -> 0 MAX-INT }T
+
+T{ 0 0 1 UM/MOD -> 0 0 }T
+T{ 1 0 1 UM/MOD -> 0 1 }T
+T{ 1 0 2 UM/MOD -> 1 0 }T
+T{ 3 0 2 UM/MOD -> 1 1 }T
+T{ MAX-UINT 2 UM* 2 UM/MOD -> 0 MAX-UINT }T
+T{ MAX-UINT 2 UM* MAX-UINT UM/MOD -> 0 2 }T
+T{ MAX-UINT MAX-UINT UM* MAX-UINT UM/MOD -> 0 MAX-UINT }T
+
+: IFFLOORED
+ [ -3 2 / -2 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+: IFSYM
+ [ -3 2 / -1 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+\ THE SYSTEM MIGHT DO EITHER FLOORED OR SYMMETRIC DIVISION.
+\ SINCE WE HAVE ALREADY TESTED M*, FM/MOD, AND SM/REM WE CAN USE THEM IN TEST.
+
+IFFLOORED : T/MOD >R S>D R> FM/MOD ;
+IFFLOORED : T/ T/MOD SWAP DROP ;
+IFFLOORED : TMOD T/MOD DROP ;
+IFFLOORED : T*/MOD >R M* R> FM/MOD ;
+IFFLOORED : T*/ T*/MOD SWAP DROP ;
+IFSYM : T/MOD >R S>D R> SM/REM ;
+IFSYM : T/ T/MOD SWAP DROP ;
+IFSYM : TMOD T/MOD DROP ;
+IFSYM : T*/MOD >R M* R> SM/REM ;
+IFSYM : T*/ T*/MOD SWAP DROP ;
+
+T{ 0 1 /MOD -> 0 1 T/MOD }T
+T{ 1 1 /MOD -> 1 1 T/MOD }T
+T{ 2 1 /MOD -> 2 1 T/MOD }T
+T{ -1 1 /MOD -> -1 1 T/MOD }T
+T{ -2 1 /MOD -> -2 1 T/MOD }T
+T{ 0 -1 /MOD -> 0 -1 T/MOD }T
+T{ 1 -1 /MOD -> 1 -1 T/MOD }T
+T{ 2 -1 /MOD -> 2 -1 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -1 /MOD -> -2 -1 T/MOD }T
+T{ 2 2 /MOD -> 2 2 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -2 /MOD -> -2 -2 T/MOD }T
+T{ 7 3 /MOD -> 7 3 T/MOD }T
+T{ 7 -3 /MOD -> 7 -3 T/MOD }T
+T{ -7 3 /MOD -> -7 3 T/MOD }T
+T{ -7 -3 /MOD -> -7 -3 T/MOD }T
+T{ MAX-INT 1 /MOD -> MAX-INT 1 T/MOD }T
+T{ MIN-INT 1 /MOD -> MIN-INT 1 T/MOD }T
+T{ MAX-INT MAX-INT /MOD -> MAX-INT MAX-INT T/MOD }T
+T{ MIN-INT MIN-INT /MOD -> MIN-INT MIN-INT T/MOD }T
+
+T{ 0 1 / -> 0 1 T/ }T
+T{ 1 1 / -> 1 1 T/ }T
+T{ 2 1 / -> 2 1 T/ }T
+T{ -1 1 / -> -1 1 T/ }T
+T{ -2 1 / -> -2 1 T/ }T
+T{ 0 -1 / -> 0 -1 T/ }T
+T{ 1 -1 / -> 1 -1 T/ }T
+T{ 2 -1 / -> 2 -1 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -1 / -> -2 -1 T/ }T
+T{ 2 2 / -> 2 2 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -2 / -> -2 -2 T/ }T
+T{ 7 3 / -> 7 3 T/ }T
+T{ 7 -3 / -> 7 -3 T/ }T
+T{ -7 3 / -> -7 3 T/ }T
+T{ -7 -3 / -> -7 -3 T/ }T
+T{ MAX-INT 1 / -> MAX-INT 1 T/ }T
+T{ MIN-INT 1 / -> MIN-INT 1 T/ }T
+T{ MAX-INT MAX-INT / -> MAX-INT MAX-INT T/ }T
+T{ MIN-INT MIN-INT / -> MIN-INT MIN-INT T/ }T
+
+T{ 0 1 MOD -> 0 1 TMOD }T
+T{ 1 1 MOD -> 1 1 TMOD }T
+T{ 2 1 MOD -> 2 1 TMOD }T
+T{ -1 1 MOD -> -1 1 TMOD }T
+T{ -2 1 MOD -> -2 1 TMOD }T
+T{ 0 -1 MOD -> 0 -1 TMOD }T
+T{ 1 -1 MOD -> 1 -1 TMOD }T
+T{ 2 -1 MOD -> 2 -1 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -1 MOD -> -2 -1 TMOD }T
+T{ 2 2 MOD -> 2 2 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -2 MOD -> -2 -2 TMOD }T
+T{ 7 3 MOD -> 7 3 TMOD }T
+T{ 7 -3 MOD -> 7 -3 TMOD }T
+T{ -7 3 MOD -> -7 3 TMOD }T
+T{ -7 -3 MOD -> -7 -3 TMOD }T
+T{ MAX-INT 1 MOD -> MAX-INT 1 TMOD }T
+T{ MIN-INT 1 MOD -> MIN-INT 1 TMOD }T
+T{ MAX-INT MAX-INT MOD -> MAX-INT MAX-INT TMOD }T
+T{ MIN-INT MIN-INT MOD -> MIN-INT MIN-INT TMOD }T
+
+T{ 0 2 1 */ -> 0 2 1 T*/ }T
+T{ 1 2 1 */ -> 1 2 1 T*/ }T
+T{ 2 2 1 */ -> 2 2 1 T*/ }T
+T{ -1 2 1 */ -> -1 2 1 T*/ }T
+T{ -2 2 1 */ -> -2 2 1 T*/ }T
+T{ 0 2 -1 */ -> 0 2 -1 T*/ }T
+T{ 1 2 -1 */ -> 1 2 -1 T*/ }T
+T{ 2 2 -1 */ -> 2 2 -1 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -1 */ -> -2 2 -1 T*/ }T
+T{ 2 2 2 */ -> 2 2 2 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -2 */ -> -2 2 -2 T*/ }T
+T{ 7 2 3 */ -> 7 2 3 T*/ }T
+T{ 7 2 -3 */ -> 7 2 -3 T*/ }T
+T{ -7 2 3 */ -> -7 2 3 T*/ }T
+T{ -7 2 -3 */ -> -7 2 -3 T*/ }T
+T{ MAX-INT 2 MAX-INT */ -> MAX-INT 2 MAX-INT T*/ }T
+T{ MIN-INT 2 MIN-INT */ -> MIN-INT 2 MIN-INT T*/ }T
+
+T{ 0 2 1 */MOD -> 0 2 1 T*/MOD }T
+T{ 1 2 1 */MOD -> 1 2 1 T*/MOD }T
+T{ 2 2 1 */MOD -> 2 2 1 T*/MOD }T
+T{ -1 2 1 */MOD -> -1 2 1 T*/MOD }T
+T{ -2 2 1 */MOD -> -2 2 1 T*/MOD }T
+T{ 0 2 -1 */MOD -> 0 2 -1 T*/MOD }T
+T{ 1 2 -1 */MOD -> 1 2 -1 T*/MOD }T
+T{ 2 2 -1 */MOD -> 2 2 -1 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -1 */MOD -> -2 2 -1 T*/MOD }T
+T{ 2 2 2 */MOD -> 2 2 2 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -2 */MOD -> -2 2 -2 T*/MOD }T
+T{ 7 2 3 */MOD -> 7 2 3 T*/MOD }T
+T{ 7 2 -3 */MOD -> 7 2 -3 T*/MOD }T
+T{ -7 2 3 */MOD -> -7 2 3 T*/MOD }T
+T{ -7 2 -3 */MOD -> -7 2 -3 T*/MOD }T
+T{ MAX-INT 2 MAX-INT */MOD -> MAX-INT 2 MAX-INT T*/MOD }T
+T{ MIN-INT 2 MIN-INT */MOD -> MIN-INT 2 MIN-INT T*/MOD }T
+
+\ ------------------------------------------------------------------------
+TESTING HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2! ALIGN ALIGNED +! ALLOT
+
+HERE 1 ALLOT
+HERE
+CONSTANT 2NDA
+CONSTANT 1STA
+T{ 1STA 2NDA U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STA 1+ -> 2NDA }T \ ... BY ONE ADDRESS UNIT
+( MISSING TEST: NEGATIVE ALLOT )
+
+HERE 1 ,
+HERE 2 ,
+CONSTANT 2ND
+CONSTANT 1ST
+T{ 1ST 2ND U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1ST CELL+ -> 2ND }T \ ... BY ONE CELL
+T{ 1ST 1 CELLS + -> 2ND }T
+T{ 1ST @ 2ND @ -> 1 2 }T
+T{ 5 1ST ! -> }T
+T{ 1ST @ 2ND @ -> 5 2 }T
+T{ 6 2ND ! -> }T
+T{ 1ST @ 2ND @ -> 5 6 }T
+T{ 1ST 2@ -> 6 5 }T
+T{ 2 1 1ST 2! -> }T
+T{ 1ST 2@ -> 2 1 }T
+T{ 1S 1ST ! 1ST @ -> 1S }T \ CAN STORE CELL-WIDE VALUE
+
+HERE 1 C,
+HERE 2 C,
+CONSTANT 2NDC
+CONSTANT 1STC
+T{ 1STC 2NDC U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STC CHAR+ -> 2NDC }T \ ... BY ONE CHAR
+T{ 1STC 1 CHARS + -> 2NDC }T
+T{ 1STC C@ 2NDC C@ -> 1 2 }T
+T{ 3 1STC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 2 }T
+T{ 4 2NDC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 4 }T
+
+ALIGN 1 ALLOT HERE ALIGN HERE 3 CELLS ALLOT
+CONSTANT A-ADDR CONSTANT UA-ADDR
+T{ UA-ADDR ALIGNED -> A-ADDR }T
+T{ 1 A-ADDR C! A-ADDR C@ -> 1 }T
+T{ 1234 A-ADDR ! A-ADDR @ -> 1234 }T
+T{ 123 456 A-ADDR 2! A-ADDR 2@ -> 123 456 }T
+T{ 2 A-ADDR CHAR+ C! A-ADDR CHAR+ C@ -> 2 }T
+T{ 3 A-ADDR CELL+ C! A-ADDR CELL+ C@ -> 3 }T
+T{ 1234 A-ADDR CELL+ ! A-ADDR CELL+ @ -> 1234 }T
+T{ 123 456 A-ADDR CELL+ 2! A-ADDR CELL+ 2@ -> 123 456 }T
+
+: BITS ( X -- U )
+ 0 SWAP BEGIN DUP WHILE DUP MSB AND IF >R 1+ R> THEN 2* REPEAT DROP ;
+( CHARACTERS >= 1 AU, <= SIZE OF CELL, >= 8 BITS )
+T{ 1 CHARS 1 < -> <FALSE> }T
+T{ 1 CHARS 1 CELLS > -> <FALSE> }T
+( TBD: HOW TO FIND NUMBER OF BITS? )
+
+( CELLS >= 1 AU, INTEGRAL MULTIPLE OF CHAR SIZE, >= 16 BITS )
+T{ 1 CELLS 1 < -> <FALSE> }T
+T{ 1 CELLS 1 CHARS MOD -> 0 }T
+T{ 1S BITS 10 < -> <FALSE> }T
+
+T{ 0 1ST ! -> }T
+T{ 1 1ST +! -> }T
+T{ 1ST @ -> 1 }T
+T{ -1 1ST +! 1ST @ -> 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING CHAR [CHAR] [ ] BL S"
+
+T{ BL -> 20 }T
+T{ CHAR X -> 58 }T
+T{ CHAR HELLO -> 48 }T
+T{ : GC1 [CHAR] X ; -> }T
+T{ : GC2 [CHAR] HELLO ; -> }T
+T{ GC1 -> 58 }T
+T{ GC2 -> 48 }T
+T{ : GC3 [ GC1 ] LITERAL ; -> }T
+T{ GC3 -> 58 }T
+T{ : GC4 S" XY" ; -> }T
+T{ GC4 SWAP DROP -> 2 }T
+T{ GC4 DROP DUP C@ SWAP CHAR+ C@ -> 58 59 }T
+
+\ ------------------------------------------------------------------------
+TESTING ' ['] FIND EXECUTE IMMEDIATE COUNT LITERAL POSTPONE STATE
+
+T{ : GT1 123 ; -> }T
+T{ ' GT1 EXECUTE -> 123 }T
+T{ : GT2 ['] GT1 ; IMMEDIATE -> }T
+T{ GT2 EXECUTE -> 123 }T
+HERE 3 C, CHAR G C, CHAR T C, CHAR 1 C, CONSTANT GT1STRING
+HERE 3 C, CHAR G C, CHAR T C, CHAR 2 C, CONSTANT GT2STRING
+T{ GT1STRING FIND -> ' GT1 -1 }T
+T{ GT2STRING FIND -> ' GT2 1 }T
+( HOW TO SEARCH FOR NON-EXISTENT WORD? )
+T{ : GT3 GT2 LITERAL ; -> }T
+T{ GT3 -> ' GT1 }T
+T{ GT1STRING COUNT -> GT1STRING CHAR+ 3 }T
+
+T{ : GT4 POSTPONE GT1 ; IMMEDIATE -> }T
+T{ : GT5 GT4 ; -> }T
+T{ GT5 -> 123 }T
+T{ : GT6 345 ; IMMEDIATE -> }T
+T{ : GT7 POSTPONE GT6 ; -> }T
+T{ GT7 -> 345 }T
+
+T{ : GT8 STATE @ ; IMMEDIATE -> }T
+T{ GT8 -> 0 }T
+T{ : GT9 GT8 LITERAL ; -> }T
+T{ GT9 0= -> <FALSE> }T
+
+\ ------------------------------------------------------------------------
+TESTING IF ELSE THEN BEGIN WHILE REPEAT UNTIL RECURSE
+
+T{ : GI1 IF 123 THEN ; -> }T
+T{ : GI2 IF 123 ELSE 234 THEN ; -> }T
+T{ 0 GI1 -> }T
+T{ 1 GI1 -> 123 }T
+T{ -1 GI1 -> 123 }T
+T{ 0 GI2 -> 234 }T
+T{ 1 GI2 -> 123 }T
+T{ -1 GI1 -> 123 }T
+
+T{ : GI3 BEGIN DUP 5 < WHILE DUP 1+ REPEAT ; -> }T
+T{ 0 GI3 -> 0 1 2 3 4 5 }T
+T{ 4 GI3 -> 4 5 }T
+T{ 5 GI3 -> 5 }T
+T{ 6 GI3 -> 6 }T
+
+T{ : GI4 BEGIN DUP 1+ DUP 5 > UNTIL ; -> }T
+T{ 3 GI4 -> 3 4 5 6 }T
+T{ 5 GI4 -> 5 6 }T
+T{ 6 GI4 -> 6 7 }T
+
+T{ : GI5 BEGIN DUP 2 > WHILE DUP 5 < WHILE DUP 1+ REPEAT 123 ELSE 345 THEN ; -> }T
+T{ 1 GI5 -> 1 345 }T
+T{ 2 GI5 -> 2 345 }T
+T{ 3 GI5 -> 3 4 5 123 }T
+T{ 4 GI5 -> 4 5 123 }T
+T{ 5 GI5 -> 5 123 }T
+
+T{ : GI6 ( N -- 0,1,..N ) DUP IF DUP >R 1- RECURSE R> THEN ; -> }T
+T{ 0 GI6 -> 0 }T
+T{ 1 GI6 -> 0 1 }T
+T{ 2 GI6 -> 0 1 2 }T
+T{ 3 GI6 -> 0 1 2 3 }T
+T{ 4 GI6 -> 0 1 2 3 4 }T
+
+\ ------------------------------------------------------------------------
+TESTING DO LOOP +LOOP I J UNLOOP LEAVE EXIT
+
+T{ : GD1 DO I LOOP ; -> }T
+T{ 4 1 GD1 -> 1 2 3 }T
+T{ 2 -1 GD1 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD1 -> MID-UINT }T
+
+T{ : GD2 DO I -1 +LOOP ; -> }T
+T{ 1 4 GD2 -> 4 3 2 1 }T
+T{ -1 2 GD2 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD2 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD3 DO 1 0 DO J LOOP LOOP ; -> }T
+T{ 4 1 GD3 -> 1 2 3 }T
+T{ 2 -1 GD3 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD3 -> MID-UINT }T
+
+T{ : GD4 DO 1 0 DO J LOOP -1 +LOOP ; -> }T
+T{ 1 4 GD4 -> 4 3 2 1 }T
+T{ -1 2 GD4 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD4 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD5 123 SWAP 0 DO I 4 > IF DROP 234 LEAVE THEN LOOP ; -> }T
+T{ 1 GD5 -> 123 }T
+T{ 5 GD5 -> 123 }T
+T{ 6 GD5 -> 234 }T
+
+T{ : GD6 ( PAT: T{0 0}T,T{0 0}TT{1 0}TT{1 1}T,T{0 0}TT{1 0}TT{1 1}TT{2 0}TT{2 1}TT{2 2}T )
+ 0 SWAP 0 DO
+ I 1+ 0 DO I J + 3 = IF I UNLOOP I UNLOOP EXIT THEN 1+ LOOP
+ LOOP ; -> }T
+T{ 1 GD6 -> 1 }T
+T{ 2 GD6 -> 3 }T
+T{ 3 GD6 -> 4 1 2 }T
+
+\ ------------------------------------------------------------------------
+TESTING DEFINING WORDS: : ; CONSTANT VARIABLE CREATE DOES> >BODY
+
+T{ 123 CONSTANT X123 -> }T
+T{ X123 -> 123 }T
+T{ : EQU CONSTANT ; -> }T
+T{ X123 EQU Y123 -> }T
+T{ Y123 -> 123 }T
+
+T{ VARIABLE V1 -> }T
+T{ 123 V1 ! -> }T
+T{ V1 @ -> 123 }T
+
+T{ : NOP : POSTPONE ; ; -> }T
+T{ NOP NOP1 NOP NOP2 -> }T
+T{ NOP1 -> }T
+T{ NOP2 -> }T
+
+T{ : DOES1 DOES> @ 1 + ; -> }T
+T{ : DOES2 DOES> @ 2 + ; -> }T
+T{ CREATE CR1 -> }T
+T{ CR1 -> HERE }T
+T{ ' CR1 >BODY -> HERE }T
+T{ 1 , -> }T
+T{ CR1 @ -> 1 }T
+T{ DOES1 -> }T
+T{ CR1 -> 2 }T
+T{ DOES2 -> }T
+T{ CR1 -> 3 }T
+
+T{ : WEIRD: CREATE DOES> 1 + DOES> 2 + ; -> }T
+T{ WEIRD: W1 -> }T
+T{ ' W1 >BODY -> HERE }T
+T{ W1 -> HERE 1 + }T
+T{ W1 -> HERE 2 + }T
+
+\ ------------------------------------------------------------------------
+TESTING EVALUATE
+
+: GE1 S" 123" ; IMMEDIATE
+: GE2 S" 123 1+" ; IMMEDIATE
+: GE3 S" : GE4 345 ;" ;
+: GE5 EVALUATE ; IMMEDIATE
+
+T{ GE1 EVALUATE -> 123 }T ( TEST EVALUATE IN INTERP. STATE )
+T{ GE2 EVALUATE -> 124 }T
+T{ GE3 EVALUATE -> }T
+T{ GE4 -> 345 }T
+
+T{ : GE6 GE1 GE5 ; -> }T ( TEST EVALUATE IN COMPILE STATE )
+T{ GE6 -> 123 }T
+T{ : GE7 GE2 GE5 ; -> }T
+T{ GE7 -> 124 }T
+
+\ ------------------------------------------------------------------------
+TESTING SOURCE >IN WORD
+
+: GS1 S" SOURCE" 2DUP EVALUATE
+ >R SWAP >R = R> R> = ;
+T{ GS1 -> <TRUE> <TRUE> }T
+
+VARIABLE SCANS
+: RESCAN? -1 SCANS +! SCANS @ IF 0 >IN ! THEN ;
+
+T{ 2 SCANS !
+345 RESCAN?
+-> 345 345 }T
+
+: GS2 5 SCANS ! S" 123 RESCAN?" EVALUATE ;
+T{ GS2 -> 123 123 123 123 123 }T
+
+: GS3 WORD COUNT SWAP C@ ;
+T{ BL GS3 HELLO -> 5 CHAR H }T
+T{ CHAR " GS3 GOODBYE" -> 7 CHAR G }T
+T{ BL GS3
+DROP -> 0 }T \ BLANK LINE RETURN ZERO-LENGTH STRING
+
+: GS4 SOURCE >IN ! DROP ;
+T{ GS4 123 456
+-> }T
+
+\ ------------------------------------------------------------------------
+TESTING <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL
+
+: S= \ ( ADDR1 C1 ADDR2 C2 -- T/F ) COMPARE TWO STRINGS.
+ >R SWAP R@ = IF \ MAKE SURE STRINGS HAVE SAME LENGTH
+ R> ?DUP IF \ IF NON-EMPTY STRINGS
+ 0 DO
+ OVER C@ OVER C@ - IF
+ 2DROP <FALSE> UNLOOP EXIT THEN
+ SWAP CHAR+ SWAP CHAR+
+ LOOP
+ THEN
+ 2DROP <TRUE> \ IF WE GET HERE, STRINGS MATCH
+ ELSE
+ R> DROP 2DROP <FALSE> \ LENGTHS MISMATCH
+ THEN ;
+
+: GP1 <# 41 HOLD 42 HOLD 0 0 #> S" BA" S= ;
+T{ GP1 -> <TRUE> }T
+
+: GP2 <# -1 SIGN 0 SIGN -1 SIGN 0 0 #> S" --" S= ;
+T{ GP2 -> <TRUE> }T
+
+: GP3 <# 1 0 # # #> S" 01" S= ;
+T{ GP3 -> <TRUE> }T
+
+: GP4 <# 1 0 #S #> S" 1" S= ;
+T{ GP4 -> <TRUE> }T
+
+24 CONSTANT MAX-BASE \ BASE 2 .. 36
+: COUNT-BITS
+ 0 0 INVERT BEGIN DUP WHILE >R 1+ R> 2* REPEAT DROP ;
+COUNT-BITS 2* CONSTANT #BITS-UD \ NUMBER OF BITS IN UD
+
+: GP5
+ BASE @ <TRUE>
+ MAX-BASE 1+ 2 DO \ FOR EACH POSSIBLE BASE
+ I BASE ! \ TBD: ASSUMES BASE WORKS
+ I 0 <# #S #> S" 10" S= AND
+ LOOP
+ SWAP BASE ! ;
+T{ GP5 -> <TRUE> }T
+
+: GP6
+ BASE @ >R 2 BASE !
+ MAX-UINT MAX-UINT <# #S #> \ MAXIMUM UD TO BINARY
+ R> BASE ! \ S: C-ADDR U
+ DUP #BITS-UD = SWAP
+ 0 DO \ S: C-ADDR FLAG
+ OVER C@ [CHAR] 1 = AND \ ALL ONES
+ >R CHAR+ R>
+ LOOP SWAP DROP ;
+T{ GP6 -> <TRUE> }T
+
+: GP7
+ BASE @ >R MAX-BASE BASE !
+ <TRUE>
+ A 0 DO
+ I 0 <# #S #>
+ 1 = SWAP C@ I 30 + = AND AND
+ LOOP
+ MAX-BASE A DO
+ I 0 <# #S #>
+ 1 = SWAP C@ 41 I A - + = AND AND
+ LOOP
+ R> BASE ! ;
+
+T{ GP7 -> <TRUE> }T
+
+\ >NUMBER TESTS
+CREATE GN-BUF 0 C,
+: GN-STRING GN-BUF 1 ;
+: GN-CONSUMED GN-BUF CHAR+ 0 ;
+: GN' [CHAR] ' WORD CHAR+ C@ GN-BUF C! GN-STRING ;
+
+T{ 0 0 GN' 0' >NUMBER -> 0 0 GN-CONSUMED }T
+T{ 0 0 GN' 1' >NUMBER -> 1 0 GN-CONSUMED }T
+T{ 1 0 GN' 1' >NUMBER -> BASE @ 1+ 0 GN-CONSUMED }T
+T{ 0 0 GN' -' >NUMBER -> 0 0 GN-STRING }T \ SHOULD FAIL TO CONVERT THESE
+T{ 0 0 GN' +' >NUMBER -> 0 0 GN-STRING }T
+T{ 0 0 GN' .' >NUMBER -> 0 0 GN-STRING }T
+
+: >NUMBER-BASED
+ BASE @ >R BASE ! >NUMBER R> BASE ! ;
+
+T{ 0 0 GN' 2' 10 >NUMBER-BASED -> 2 0 GN-CONSUMED }T
+T{ 0 0 GN' 2' 2 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' F' 10 >NUMBER-BASED -> F 0 GN-CONSUMED }T
+T{ 0 0 GN' G' 10 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' G' MAX-BASE >NUMBER-BASED -> 10 0 GN-CONSUMED }T
+T{ 0 0 GN' Z' MAX-BASE >NUMBER-BASED -> 23 0 GN-CONSUMED }T
+
+: GN1 \ ( UD BASE -- UD' LEN ) UD SHOULD EQUAL UD' AND LEN SHOULD BE ZERO.
+ BASE @ >R BASE !
+ <# #S #>
+ 0 0 2SWAP >NUMBER SWAP DROP \ RETURN LENGTH ONLY
+ R> BASE ! ;
+T{ 0 0 2 GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 2 GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP 2 GN1 -> MAX-UINT DUP 0 }T
+T{ 0 0 MAX-BASE GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 MAX-BASE GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP MAX-BASE GN1 -> MAX-UINT DUP 0 }T
+
+: GN2 \ ( -- 16 10 )
+ BASE @ >R HEX BASE @ DECIMAL BASE @ R> BASE ! ;
+T{ GN2 -> 10 A }T
+
+\ ------------------------------------------------------------------------
+TESTING FILL MOVE
+
+CREATE FBUF 00 C, 00 C, 00 C,
+CREATE SBUF 12 C, 34 C, 56 C,
+: SEEBUF FBUF C@ FBUF CHAR+ C@ FBUF CHAR+ CHAR+ C@ ;
+
+T{ FBUF 0 20 FILL -> }T
+T{ SEEBUF -> 00 00 00 }T
+
+T{ FBUF 1 20 FILL -> }T
+T{ SEEBUF -> 20 00 00 }T
+
+T{ FBUF 3 20 FILL -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ FBUF FBUF 3 CHARS MOVE -> }T \ BIZARRE SPECIAL CASE
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 0 CHARS MOVE -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 1 CHARS MOVE -> }T
+T{ SEEBUF -> 12 20 20 }T
+
+T{ SBUF FBUF 3 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 56 }T
+
+T{ FBUF FBUF CHAR+ 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 12 34 }T
+
+T{ FBUF CHAR+ FBUF 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 34 }T
+
+\ ------------------------------------------------------------------------
+TESTING OUTPUT: . ." CR EMIT SPACE SPACES TYPE U.
+
+: OUTPUT-TEST
+ ." YOU SHOULD SEE THE STANDARD GRAPHIC CHARACTERS:" CR
+ 41 BL DO I EMIT LOOP CR
+ 61 41 DO I EMIT LOOP CR
+ 7F 61 DO I EMIT LOOP CR
+ ." YOU SHOULD SEE 0-9 SEPARATED BY A SPACE:" CR
+ 9 1+ 0 DO I . LOOP CR
+ ." YOU SHOULD SEE 0-9 (WITH NO SPACES):" CR
+ [CHAR] 9 1+ [CHAR] 0 DO I 0 SPACES EMIT LOOP CR
+ ." YOU SHOULD SEE A-G SEPARATED BY A SPACE:" CR
+ [CHAR] G 1+ [CHAR] A DO I EMIT SPACE LOOP CR
+ ." YOU SHOULD SEE 0-5 SEPARATED BY TWO SPACES:" CR
+ 5 1+ 0 DO I [CHAR] 0 + EMIT 2 SPACES LOOP CR
+ ." YOU SHOULD SEE TWO SEPARATE LINES:" CR
+ S" LINE 1" TYPE CR S" LINE 2" TYPE CR
+ ." YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:" CR
+ ." SIGNED: " MIN-INT . MAX-INT . CR
+ ." UNSIGNED: " 0 U. MAX-UINT U. CR
+;
+
+T{ OUTPUT-TEST -> }T
+\ ------------------------------------------------------------------------
+TESTING INPUT: ACCEPT
+
+CREATE ABUF 80 CHARS ALLOT
+
+: ACCEPT-TEST
+ CR ." PLEASE TYPE UP TO 80 CHARACTERS:" CR
+ ABUF 80 ACCEPT
+ CR ." RECEIVED: " [CHAR] " EMIT
+ ABUF SWAP TYPE [CHAR] " EMIT CR
+;
+
+T{ ACCEPT-TEST -> }T
+Vingt fois sur le métier remettez votre ouvrage, ...
+\ ------------------------------------------------------------------------
+TESTING DICTIONARY SEARCH RULES
+
+T{ : GDX 123 ; : GDX GDX 234 ; -> }T
+
+T{ GDX -> 123 234 }T
+
+CR .( End of Core word set tests) CR
+
+
+
+RST_STATE ; so ANS_COMPLEMENT_xx_MPY is conserved ;
+\ NOECHO ; if an error occurs, comment this line before new download to find it.
+
+
+\ From: John Hayes S1I
+\ Subject: tester.fr
+\ Date: Mon, 27 Nov 95 13:10:09 PST
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.1
+
+\ 22/1/09 The words { and } have been changed to T{ and }T respectively to
+\ agree with the Forth 200X file ttester.fs. This avoids clashes with
+\ locals using { ... } and the FSL use of }
+
+
+\ 13/05/14 jmt. added colorised error messages.
+
+
+
+ 0 CONSTANT FALSE
+-1 CONSTANT TRUE
+
+\ SET THE FOLLOWING FLAG TO TRUE FOR MORE VERBOSE OUTPUT; THIS MAY
+\ ALLOW YOU TO TELL WHICH TEST CAUSED YOUR SYSTEM TO HANG.
+VARIABLE VERBOSE
+ FALSE VERBOSE !
+\ TRUE VERBOSE !
+
+\ : EMPTY-STACK ( ... -- ) \ EMPTY STACK: HANDLES UNDERFLOWED STACK TOO.
+\ DEPTH ?DUP
+\ IF DUP 0< IF NEGATE 0
+\ DO 0 LOOP
+\ ELSE 0 DO DROP LOOP THEN
+\ THEN ;
+\
+\ : ERROR \ ( C-ADDR U -- ) DISPLAY AN ERROR MESSAGE FOLLOWED BY
+\ \ THE LINE THAT HAD THE ERROR.
+\ TYPE SOURCE TYPE CR \ DISPLAY LINE CORRESPONDING TO ERROR
+\ EMPTY-STACK \ THROW AWAY EVERY THING ELSE
+\ QUIT \ *** Uncomment this line to QUIT on an error
+\ ;
+
+VARIABLE ACTUAL-DEPTH \ STACK RECORD
+CREATE ACTUAL-RESULTS 20 CELLS ALLOT
+
+: T{ \ ( -- ) SYNTACTIC SUGAR.
+ ;
+
+: -> \ ( ... -- ) RECORD DEPTH AND CONTENT OF STACK.
+ DEPTH DUP ACTUAL-DEPTH ! \ RECORD DEPTH
+ ?DUP IF \ IF THERE IS SOMETHING ON STACK
+ 0 DO ACTUAL-RESULTS I CELLS + ! LOOP \ SAVE THEM
+ THEN ;
+
+: }T \ ( ... -- ) COMPARE STACK (EXPECTED) CONTENTS WITH SAVED
+ \ (ACTUAL) CONTENTS.
+ DEPTH ACTUAL-DEPTH @ = IF \ IF DEPTHS MATCH
+ DEPTH ?DUP IF \ IF THERE IS SOMETHING ON THE STACK
+ 0 DO \ FOR EACH STACK ITEM
+ ACTUAL-RESULTS I CELLS + @ \ COMPARE ACTUAL WITH EXPECTED
+\ = 0= IF S" INCORRECT RESULT: " ERROR LEAVE THEN \ jmt
+ = 0= IF ABORT" INCORRECT RESULT: " THEN \ jmt : colorised message
+ LOOP
+ THEN
+ ELSE \ DEPTH MISMATCH
+\ S" WRONG NUMBER OF RESULTS: " ERROR \ jmt
+ ABORT" WRONG NUMBER OF RESULTS: " \ jmt : colorised message
+ THEN ;
+
+: TESTING \ ( -- ) TALKING COMMENT.
+ SOURCE VERBOSE @
+ IF DUP >R TYPE CR R> >IN !
+ ELSE >IN ! DROP [CHAR] * EMIT
+ THEN ;
+
+\ From: John Hayes S1I
+\ Subject: core.fr
+\ Date: Mon, 27 Nov 95 13:10
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.2
+\ THIS PROGRAM TESTS THE CORE WORDS OF AN ANS FORTH SYSTEM.
+\ THE PROGRAM ASSUMES A TWO'S COMPLEMENT IMPLEMENTATION WHERE
+\ THE RANGE OF SIGNED NUMBERS IS -2^(N-1) ... 2^(N-1)-1 AND
+\ THE RANGE OF UNSIGNED NUMBERS IS 0 ... 2^(N)-1.
+\ I HAVEN'T FIGURED OUT HOW TO TEST KEY, QUIT, ABORT, OR ABORT"...
+\ I ALSO HAVEN'T THOUGHT OF A WAY TO TEST ENVIRONMENT?...
+
+CR
+TESTING CORE WORDS
+HEX
+
+\ ------------------------------------------------------------------------
+TESTING BASIC ASSUMPTIONS
+
+T{ -> }T \ START WITH CLEAN SLATE
+( TEST IF ANY BITS ARE SET; ANSWER IN BASE 1 )
+T{ : BITSSET? IF 0 0 ELSE 0 THEN ; -> }T
+T{ 0 BITSSET? -> 0 }T ( ZERO IS ALL BITS CLEAR )
+T{ 1 BITSSET? -> 0 0 }T ( OTHER NUMBER HAVE AT LEAST ONE BIT )
+T{ -1 BITSSET? -> 0 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING BOOLEANS: INVERT AND OR XOR
+
+T{ 0 0 AND -> 0 }T
+T{ 0 1 AND -> 0 }T
+T{ 1 0 AND -> 0 }T
+T{ 1 1 AND -> 1 }T
+
+T{ 0 INVERT 1 AND -> 1 }T
+T{ 1 INVERT 1 AND -> 0 }T
+
+0 CONSTANT 0S
+0 INVERT CONSTANT 1S
+
+T{ 0S INVERT -> 1S }T
+T{ 1S INVERT -> 0S }T
+
+T{ 0S 0S AND -> 0S }T
+T{ 0S 1S AND -> 0S }T
+T{ 1S 0S AND -> 0S }T
+T{ 1S 1S AND -> 1S }T
+
+T{ 0S 0S OR -> 0S }T
+T{ 0S 1S OR -> 1S }T
+T{ 1S 0S OR -> 1S }T
+T{ 1S 1S OR -> 1S }T
+
+T{ 0S 0S XOR -> 0S }T
+T{ 0S 1S XOR -> 1S }T
+T{ 1S 0S XOR -> 1S }T
+T{ 1S 1S XOR -> 0S }T
+
+\ ------------------------------------------------------------------------
+TESTING 2* 2/ LSHIFT RSHIFT
+
+( WE TRUST 1S, INVERT, AND BITSSET?; WE WILL CONFIRM RSHIFT LATER )
+1S 1 RSHIFT INVERT CONSTANT MSB
+T{ MSB BITSSET? -> 0 0 }T
+
+T{ 0S 2* -> 0S }T
+T{ 1 2* -> 2 }T
+T{ 4000 2* -> 8000 }T
+T{ 1S 2* 1 XOR -> 1S }T
+T{ MSB 2* -> 0S }T
+
+T{ 0S 2/ -> 0S }T
+T{ 1 2/ -> 0 }T
+T{ 4000 2/ -> 2000 }T
+T{ 1S 2/ -> 1S }T \ MSB PROPOGATED
+T{ 1S 1 XOR 2/ -> 1S }T
+T{ MSB 2/ MSB AND -> MSB }T
+
+T{ 1 0 LSHIFT -> 1 }T
+T{ 1 1 LSHIFT -> 2 }T
+T{ 1 2 LSHIFT -> 4 }T
+T{ 1 F LSHIFT -> 8000 }T \ BIGGEST GUARANTEED SHIFT
+T{ 1S 1 LSHIFT 1 XOR -> 1S }T
+T{ MSB 1 LSHIFT -> 0 }T
+
+T{ 1 0 RSHIFT -> 1 }T
+T{ 1 1 RSHIFT -> 0 }T
+T{ 2 1 RSHIFT -> 1 }T
+T{ 4 2 RSHIFT -> 1 }T
+T{ 8000 F RSHIFT -> 1 }T \ BIGGEST
+T{ MSB 1 RSHIFT MSB AND -> 0 }T \ RSHIFT ZERO FILLS MSBS
+T{ MSB 1 RSHIFT 2* -> MSB }T
+
+\ ------------------------------------------------------------------------
+TESTING COMPARISONS: 0= = 0< < > U< MIN MAX
+0 INVERT CONSTANT MAX-UINT
+0 INVERT 1 RSHIFT CONSTANT MAX-INT
+0 INVERT 1 RSHIFT INVERT CONSTANT MIN-INT
+0 INVERT 1 RSHIFT CONSTANT MID-UINT
+0 INVERT 1 RSHIFT INVERT CONSTANT MID-UINT+1
+
+0S CONSTANT <FALSE>
+1S CONSTANT <TRUE>
+
+T{ 0 0= -> <TRUE> }T
+T{ 1 0= -> <FALSE> }T
+T{ 2 0= -> <FALSE> }T
+T{ -1 0= -> <FALSE> }T
+T{ MAX-UINT 0= -> <FALSE> }T
+T{ MIN-INT 0= -> <FALSE> }T
+T{ MAX-INT 0= -> <FALSE> }T
+
+T{ 0 0 = -> <TRUE> }T
+T{ 1 1 = -> <TRUE> }T
+T{ -1 -1 = -> <TRUE> }T
+T{ 1 0 = -> <FALSE> }T
+T{ -1 0 = -> <FALSE> }T
+T{ 0 1 = -> <FALSE> }T
+T{ 0 -1 = -> <FALSE> }T
+
+T{ 0 0< -> <FALSE> }T
+T{ -1 0< -> <TRUE> }T
+T{ MIN-INT 0< -> <TRUE> }T
+T{ 1 0< -> <FALSE> }T
+T{ MAX-INT 0< -> <FALSE> }T
+
+T{ 0 1 < -> <TRUE> }T
+T{ 1 2 < -> <TRUE> }T
+T{ -1 0 < -> <TRUE> }T
+T{ -1 1 < -> <TRUE> }T
+T{ MIN-INT 0 < -> <TRUE> }T
+T{ MIN-INT MAX-INT < -> <TRUE> }T
+T{ 0 MAX-INT < -> <TRUE> }T
+T{ 0 0 < -> <FALSE> }T
+T{ 1 1 < -> <FALSE> }T
+T{ 1 0 < -> <FALSE> }T
+T{ 2 1 < -> <FALSE> }T
+T{ 0 -1 < -> <FALSE> }T
+T{ 1 -1 < -> <FALSE> }T
+T{ 0 MIN-INT < -> <FALSE> }T
+T{ MAX-INT MIN-INT < -> <FALSE> }T
+T{ MAX-INT 0 < -> <FALSE> }T
+
+T{ 0 1 > -> <FALSE> }T
+T{ 1 2 > -> <FALSE> }T
+T{ -1 0 > -> <FALSE> }T
+T{ -1 1 > -> <FALSE> }T
+T{ MIN-INT 0 > -> <FALSE> }T
+T{ MIN-INT MAX-INT > -> <FALSE> }T
+T{ 0 MAX-INT > -> <FALSE> }T
+T{ 0 0 > -> <FALSE> }T
+T{ 1 1 > -> <FALSE> }T
+T{ 1 0 > -> <TRUE> }T
+T{ 2 1 > -> <TRUE> }T
+T{ 0 -1 > -> <TRUE> }T
+T{ 1 -1 > -> <TRUE> }T
+T{ 0 MIN-INT > -> <TRUE> }T
+T{ MAX-INT MIN-INT > -> <TRUE> }T
+T{ MAX-INT 0 > -> <TRUE> }T
+
+T{ 0 1 U< -> <TRUE> }T
+T{ 1 2 U< -> <TRUE> }T
+T{ 0 MID-UINT U< -> <TRUE> }T
+T{ 0 MAX-UINT U< -> <TRUE> }T
+T{ MID-UINT MAX-UINT U< -> <TRUE> }T
+T{ 0 0 U< -> <FALSE> }T
+T{ 1 1 U< -> <FALSE> }T
+T{ 1 0 U< -> <FALSE> }T
+T{ 2 1 U< -> <FALSE> }T
+T{ MID-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT MID-UINT U< -> <FALSE> }T
+
+T{ 0 1 MIN -> 0 }T
+T{ 1 2 MIN -> 1 }T
+T{ -1 0 MIN -> -1 }T
+T{ -1 1 MIN -> -1 }T
+T{ MIN-INT 0 MIN -> MIN-INT }T
+T{ MIN-INT MAX-INT MIN -> MIN-INT }T
+T{ 0 MAX-INT MIN -> 0 }T
+T{ 0 0 MIN -> 0 }T
+T{ 1 1 MIN -> 1 }T
+T{ 1 0 MIN -> 0 }T
+T{ 2 1 MIN -> 1 }T
+T{ 0 -1 MIN -> -1 }T
+T{ 1 -1 MIN -> -1 }T
+T{ 0 MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT 0 MIN -> 0 }T
+
+T{ 0 1 MAX -> 1 }T
+T{ 1 2 MAX -> 2 }T
+T{ -1 0 MAX -> 0 }T
+T{ -1 1 MAX -> 1 }T
+T{ MIN-INT 0 MAX -> 0 }T
+T{ MIN-INT MAX-INT MAX -> MAX-INT }T
+T{ 0 MAX-INT MAX -> MAX-INT }T
+T{ 0 0 MAX -> 0 }T
+T{ 1 1 MAX -> 1 }T
+T{ 1 0 MAX -> 1 }T
+T{ 2 1 MAX -> 2 }T
+T{ 0 -1 MAX -> 0 }T
+T{ 1 -1 MAX -> 1 }T
+T{ 0 MIN-INT MAX -> 0 }T
+T{ MAX-INT MIN-INT MAX -> MAX-INT }T
+T{ MAX-INT 0 MAX -> MAX-INT }T
+
+\ ------------------------------------------------------------------------
+TESTING STACK OPS: 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP
+
+T{ 1 2 2DROP -> }T
+T{ 1 2 2DUP -> 1 2 1 2 }T
+T{ 1 2 3 4 2OVER -> 1 2 3 4 1 2 }T
+T{ 1 2 3 4 2SWAP -> 3 4 1 2 }T
+T{ 0 ?DUP -> 0 }T
+T{ 1 ?DUP -> 1 1 }T
+T{ -1 ?DUP -> -1 -1 }T
+T{ DEPTH -> 0 }T
+T{ 0 DEPTH -> 0 1 }T
+T{ 0 1 DEPTH -> 0 1 2 }T
+T{ 0 DROP -> }T
+T{ 1 2 DROP -> 1 }T
+T{ 1 DUP -> 1 1 }T
+T{ 1 2 OVER -> 1 2 1 }T
+T{ 1 2 3 ROT -> 2 3 1 }T
+T{ 1 2 SWAP -> 2 1 }T
+
+\ ------------------------------------------------------------------------
+TESTING >R R> R@
+
+T{ : GR1 >R R> ; -> }T
+T{ : GR2 >R R@ R> DROP ; -> }T
+T{ 123 GR1 -> 123 }T
+T{ 123 GR2 -> 123 }T
+T{ 1S GR1 -> 1S }T ( RETURN STACK HOLDS CELLS )
+
+\ ------------------------------------------------------------------------
+TESTING ADD/SUBTRACT: + - 1+ 1- ABS NEGATE
+
+T{ 0 5 + -> 5 }T
+T{ 5 0 + -> 5 }T
+T{ 0 -5 + -> -5 }T
+T{ -5 0 + -> -5 }T
+T{ 1 2 + -> 3 }T
+T{ 1 -2 + -> -1 }T
+T{ -1 2 + -> 1 }T
+T{ -1 -2 + -> -3 }T
+T{ -1 1 + -> 0 }T
+T{ MID-UINT 1 + -> MID-UINT+1 }T
+
+T{ 0 5 - -> -5 }T
+T{ 5 0 - -> 5 }T
+T{ 0 -5 - -> 5 }T
+T{ -5 0 - -> -5 }T
+T{ 1 2 - -> -1 }T
+T{ 1 -2 - -> 3 }T
+T{ -1 2 - -> -3 }T
+T{ -1 -2 - -> 1 }T
+T{ 0 1 - -> -1 }T
+T{ MID-UINT+1 1 - -> MID-UINT }T
+
+T{ 0 1+ -> 1 }T
+T{ -1 1+ -> 0 }T
+T{ 1 1+ -> 2 }T
+T{ MID-UINT 1+ -> MID-UINT+1 }T
+
+T{ 2 1- -> 1 }T
+T{ 1 1- -> 0 }T
+T{ 0 1- -> -1 }T
+T{ MID-UINT+1 1- -> MID-UINT }T
+
+T{ 0 NEGATE -> 0 }T
+T{ 1 NEGATE -> -1 }T
+T{ -1 NEGATE -> 1 }T
+T{ 2 NEGATE -> -2 }T
+T{ -2 NEGATE -> 2 }T
+
+T{ 0 ABS -> 0 }T
+T{ 1 ABS -> 1 }T
+T{ -1 ABS -> 1 }T
+T{ MIN-INT ABS -> MID-UINT+1 }T
+
+\ ------------------------------------------------------------------------
+TESTING MULTIPLY: S>D * M* UM*
+
+T{ 0 S>D -> 0 0 }T
+T{ 1 S>D -> 1 0 }T
+T{ 2 S>D -> 2 0 }T
+T{ -1 S>D -> -1 -1 }T
+T{ -2 S>D -> -2 -1 }T
+T{ MIN-INT S>D -> MIN-INT -1 }T
+T{ MAX-INT S>D -> MAX-INT 0 }T
+
+T{ 0 0 M* -> 0 S>D }T
+T{ 0 1 M* -> 0 S>D }T
+T{ 1 0 M* -> 0 S>D }T
+T{ 1 2 M* -> 2 S>D }T
+T{ 2 1 M* -> 2 S>D }T
+T{ 3 3 M* -> 9 S>D }T
+T{ -3 3 M* -> -9 S>D }T
+T{ 3 -3 M* -> -9 S>D }T
+T{ -3 -3 M* -> 9 S>D }T
+T{ 0 MIN-INT M* -> 0 S>D }T
+T{ 1 MIN-INT M* -> MIN-INT S>D }T
+T{ 2 MIN-INT M* -> 0 1S }T
+T{ 0 MAX-INT M* -> 0 S>D }T
+T{ 1 MAX-INT M* -> MAX-INT S>D }T
+T{ 2 MAX-INT M* -> MAX-INT 1 LSHIFT 0 }T
+T{ MIN-INT MIN-INT M* -> 0 MSB 1 RSHIFT }T
+T{ MAX-INT MIN-INT M* -> MSB MSB 2/ }T
+T{ MAX-INT MAX-INT M* -> 1 MSB 2/ INVERT }T
+
+T{ 0 0 * -> 0 }T \ TEST IDENTITIES
+T{ 0 1 * -> 0 }T
+T{ 1 0 * -> 0 }T
+T{ 1 2 * -> 2 }T
+T{ 2 1 * -> 2 }T
+T{ 3 3 * -> 9 }T
+T{ -3 3 * -> -9 }T
+T{ 3 -3 * -> -9 }T
+T{ -3 -3 * -> 9 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 * -> MID-UINT+1 }T
+T{ MID-UINT+1 2 RSHIFT 4 * -> MID-UINT+1 }T
+T{ MID-UINT+1 1 RSHIFT MID-UINT+1 OR 2 * -> MID-UINT+1 }T
+
+T{ 0 0 UM* -> 0 0 }T
+T{ 0 1 UM* -> 0 0 }T
+T{ 1 0 UM* -> 0 0 }T
+T{ 1 2 UM* -> 2 0 }T
+T{ 2 1 UM* -> 2 0 }T
+T{ 3 3 UM* -> 9 0 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 UM* -> MID-UINT+1 0 }T
+T{ MID-UINT+1 2 UM* -> 0 1 }T
+T{ MID-UINT+1 4 UM* -> 0 2 }T
+T{ 1S 2 UM* -> 1S 1 LSHIFT 1 }T
+T{ MAX-UINT MAX-UINT UM* -> 1 1 INVERT }T
+
+\ ------------------------------------------------------------------------
+TESTING DIVIDE: FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD
+
+T{ 0 S>D 1 FM/MOD -> 0 0 }T
+T{ 1 S>D 1 FM/MOD -> 0 1 }T
+T{ 2 S>D 1 FM/MOD -> 0 2 }T
+T{ -1 S>D 1 FM/MOD -> 0 -1 }T
+T{ -2 S>D 1 FM/MOD -> 0 -2 }T
+T{ 0 S>D -1 FM/MOD -> 0 0 }T
+T{ 1 S>D -1 FM/MOD -> 0 -1 }T
+T{ 2 S>D -1 FM/MOD -> 0 -2 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -1 FM/MOD -> 0 2 }T
+T{ 2 S>D 2 FM/MOD -> 0 1 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -2 FM/MOD -> 0 1 }T
+T{ 7 S>D 3 FM/MOD -> 1 2 }T
+T{ 7 S>D -3 FM/MOD -> -2 -3 }T
+T{ -7 S>D 3 FM/MOD -> 2 -3 }T
+T{ -7 S>D -3 FM/MOD -> -1 2 }T
+T{ MAX-INT S>D 1 FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT FM/MOD -> 0 1 }T
+T{ MIN-INT S>D MIN-INT FM/MOD -> 0 1 }T
+T{ 1S 1 4 FM/MOD -> 3 MAX-INT }T
+T{ 1 MIN-INT M* 1 FM/MOD -> 0 MIN-INT }T
+T{ 1 MIN-INT M* MIN-INT FM/MOD -> 0 1 }T
+T{ 2 MIN-INT M* 2 FM/MOD -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT FM/MOD -> 0 2 }T
+T{ 1 MAX-INT M* 1 FM/MOD -> 0 MAX-INT }T
+T{ 1 MAX-INT M* MAX-INT FM/MOD -> 0 1 }T
+T{ 2 MAX-INT M* 2 FM/MOD -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT FM/MOD -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT FM/MOD -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT FM/MOD -> 0 MAX-INT }T
+
+T{ 0 S>D 1 SM/REM -> 0 0 }T
+T{ 1 S>D 1 SM/REM -> 0 1 }T
+T{ 2 S>D 1 SM/REM -> 0 2 }T
+T{ -1 S>D 1 SM/REM -> 0 -1 }T
+T{ -2 S>D 1 SM/REM -> 0 -2 }T
+T{ 0 S>D -1 SM/REM -> 0 0 }T
+T{ 1 S>D -1 SM/REM -> 0 -1 }T
+T{ 2 S>D -1 SM/REM -> 0 -2 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -1 SM/REM -> 0 2 }T
+T{ 2 S>D 2 SM/REM -> 0 1 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -2 SM/REM -> 0 1 }T
+T{ 7 S>D 3 SM/REM -> 1 2 }T
+T{ 7 S>D -3 SM/REM -> 1 -2 }T
+T{ -7 S>D 3 SM/REM -> -1 -2 }T
+T{ -7 S>D -3 SM/REM -> -1 2 }T
+T{ MAX-INT S>D 1 SM/REM -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 SM/REM -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT SM/REM -> 0 1 }T
+T{ MIN-INT S>D MIN-INT SM/REM -> 0 1 }T
+T{ 1S 1 4 SM/REM -> 3 MAX-INT }T
+T{ 2 MIN-INT M* 2 SM/REM -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT SM/REM -> 0 2 }T
+T{ 2 MAX-INT M* 2 SM/REM -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT SM/REM -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT SM/REM -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT SM/REM -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT SM/REM -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT SM/REM -> 0 MAX-INT }T
+
+T{ 0 0 1 UM/MOD -> 0 0 }T
+T{ 1 0 1 UM/MOD -> 0 1 }T
+T{ 1 0 2 UM/MOD -> 1 0 }T
+T{ 3 0 2 UM/MOD -> 1 1 }T
+T{ MAX-UINT 2 UM* 2 UM/MOD -> 0 MAX-UINT }T
+T{ MAX-UINT 2 UM* MAX-UINT UM/MOD -> 0 2 }T
+T{ MAX-UINT MAX-UINT UM* MAX-UINT UM/MOD -> 0 MAX-UINT }T
+
+: IFFLOORED
+ [ -3 2 / -2 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+: IFSYM
+ [ -3 2 / -1 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+\ THE SYSTEM MIGHT DO EITHER FLOORED OR SYMMETRIC DIVISION.
+\ SINCE WE HAVE ALREADY TESTED M*, FM/MOD, AND SM/REM WE CAN USE THEM IN TEST.
+
+IFFLOORED : T/MOD >R S>D R> FM/MOD ;
+IFFLOORED : T/ T/MOD SWAP DROP ;
+IFFLOORED : TMOD T/MOD DROP ;
+IFFLOORED : T*/MOD >R M* R> FM/MOD ;
+IFFLOORED : T*/ T*/MOD SWAP DROP ;
+IFSYM : T/MOD >R S>D R> SM/REM ;
+IFSYM : T/ T/MOD SWAP DROP ;
+IFSYM : TMOD T/MOD DROP ;
+IFSYM : T*/MOD >R M* R> SM/REM ;
+IFSYM : T*/ T*/MOD SWAP DROP ;
+
+T{ 0 1 /MOD -> 0 1 T/MOD }T
+T{ 1 1 /MOD -> 1 1 T/MOD }T
+T{ 2 1 /MOD -> 2 1 T/MOD }T
+T{ -1 1 /MOD -> -1 1 T/MOD }T
+T{ -2 1 /MOD -> -2 1 T/MOD }T
+T{ 0 -1 /MOD -> 0 -1 T/MOD }T
+T{ 1 -1 /MOD -> 1 -1 T/MOD }T
+T{ 2 -1 /MOD -> 2 -1 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -1 /MOD -> -2 -1 T/MOD }T
+T{ 2 2 /MOD -> 2 2 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -2 /MOD -> -2 -2 T/MOD }T
+T{ 7 3 /MOD -> 7 3 T/MOD }T
+T{ 7 -3 /MOD -> 7 -3 T/MOD }T
+T{ -7 3 /MOD -> -7 3 T/MOD }T
+T{ -7 -3 /MOD -> -7 -3 T/MOD }T
+T{ MAX-INT 1 /MOD -> MAX-INT 1 T/MOD }T
+T{ MIN-INT 1 /MOD -> MIN-INT 1 T/MOD }T
+T{ MAX-INT MAX-INT /MOD -> MAX-INT MAX-INT T/MOD }T
+T{ MIN-INT MIN-INT /MOD -> MIN-INT MIN-INT T/MOD }T
+
+T{ 0 1 / -> 0 1 T/ }T
+T{ 1 1 / -> 1 1 T/ }T
+T{ 2 1 / -> 2 1 T/ }T
+T{ -1 1 / -> -1 1 T/ }T
+T{ -2 1 / -> -2 1 T/ }T
+T{ 0 -1 / -> 0 -1 T/ }T
+T{ 1 -1 / -> 1 -1 T/ }T
+T{ 2 -1 / -> 2 -1 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -1 / -> -2 -1 T/ }T
+T{ 2 2 / -> 2 2 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -2 / -> -2 -2 T/ }T
+T{ 7 3 / -> 7 3 T/ }T
+T{ 7 -3 / -> 7 -3 T/ }T
+T{ -7 3 / -> -7 3 T/ }T
+T{ -7 -3 / -> -7 -3 T/ }T
+T{ MAX-INT 1 / -> MAX-INT 1 T/ }T
+T{ MIN-INT 1 / -> MIN-INT 1 T/ }T
+T{ MAX-INT MAX-INT / -> MAX-INT MAX-INT T/ }T
+T{ MIN-INT MIN-INT / -> MIN-INT MIN-INT T/ }T
+
+T{ 0 1 MOD -> 0 1 TMOD }T
+T{ 1 1 MOD -> 1 1 TMOD }T
+T{ 2 1 MOD -> 2 1 TMOD }T
+T{ -1 1 MOD -> -1 1 TMOD }T
+T{ -2 1 MOD -> -2 1 TMOD }T
+T{ 0 -1 MOD -> 0 -1 TMOD }T
+T{ 1 -1 MOD -> 1 -1 TMOD }T
+T{ 2 -1 MOD -> 2 -1 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -1 MOD -> -2 -1 TMOD }T
+T{ 2 2 MOD -> 2 2 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -2 MOD -> -2 -2 TMOD }T
+T{ 7 3 MOD -> 7 3 TMOD }T
+T{ 7 -3 MOD -> 7 -3 TMOD }T
+T{ -7 3 MOD -> -7 3 TMOD }T
+T{ -7 -3 MOD -> -7 -3 TMOD }T
+T{ MAX-INT 1 MOD -> MAX-INT 1 TMOD }T
+T{ MIN-INT 1 MOD -> MIN-INT 1 TMOD }T
+T{ MAX-INT MAX-INT MOD -> MAX-INT MAX-INT TMOD }T
+T{ MIN-INT MIN-INT MOD -> MIN-INT MIN-INT TMOD }T
+
+T{ 0 2 1 */ -> 0 2 1 T*/ }T
+T{ 1 2 1 */ -> 1 2 1 T*/ }T
+T{ 2 2 1 */ -> 2 2 1 T*/ }T
+T{ -1 2 1 */ -> -1 2 1 T*/ }T
+T{ -2 2 1 */ -> -2 2 1 T*/ }T
+T{ 0 2 -1 */ -> 0 2 -1 T*/ }T
+T{ 1 2 -1 */ -> 1 2 -1 T*/ }T
+T{ 2 2 -1 */ -> 2 2 -1 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -1 */ -> -2 2 -1 T*/ }T
+T{ 2 2 2 */ -> 2 2 2 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -2 */ -> -2 2 -2 T*/ }T
+T{ 7 2 3 */ -> 7 2 3 T*/ }T
+T{ 7 2 -3 */ -> 7 2 -3 T*/ }T
+T{ -7 2 3 */ -> -7 2 3 T*/ }T
+T{ -7 2 -3 */ -> -7 2 -3 T*/ }T
+T{ MAX-INT 2 MAX-INT */ -> MAX-INT 2 MAX-INT T*/ }T
+T{ MIN-INT 2 MIN-INT */ -> MIN-INT 2 MIN-INT T*/ }T
+
+T{ 0 2 1 */MOD -> 0 2 1 T*/MOD }T
+T{ 1 2 1 */MOD -> 1 2 1 T*/MOD }T
+T{ 2 2 1 */MOD -> 2 2 1 T*/MOD }T
+T{ -1 2 1 */MOD -> -1 2 1 T*/MOD }T
+T{ -2 2 1 */MOD -> -2 2 1 T*/MOD }T
+T{ 0 2 -1 */MOD -> 0 2 -1 T*/MOD }T
+T{ 1 2 -1 */MOD -> 1 2 -1 T*/MOD }T
+T{ 2 2 -1 */MOD -> 2 2 -1 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -1 */MOD -> -2 2 -1 T*/MOD }T
+T{ 2 2 2 */MOD -> 2 2 2 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -2 */MOD -> -2 2 -2 T*/MOD }T
+T{ 7 2 3 */MOD -> 7 2 3 T*/MOD }T
+T{ 7 2 -3 */MOD -> 7 2 -3 T*/MOD }T
+T{ -7 2 3 */MOD -> -7 2 3 T*/MOD }T
+T{ -7 2 -3 */MOD -> -7 2 -3 T*/MOD }T
+T{ MAX-INT 2 MAX-INT */MOD -> MAX-INT 2 MAX-INT T*/MOD }T
+T{ MIN-INT 2 MIN-INT */MOD -> MIN-INT 2 MIN-INT T*/MOD }T
+
+\ ------------------------------------------------------------------------
+TESTING HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2! ALIGN ALIGNED +! ALLOT
+
+HERE 1 ALLOT
+HERE
+CONSTANT 2NDA
+CONSTANT 1STA
+T{ 1STA 2NDA U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STA 1+ -> 2NDA }T \ ... BY ONE ADDRESS UNIT
+( MISSING TEST: NEGATIVE ALLOT )
+
+HERE 1 ,
+HERE 2 ,
+CONSTANT 2ND
+CONSTANT 1ST
+T{ 1ST 2ND U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1ST CELL+ -> 2ND }T \ ... BY ONE CELL
+T{ 1ST 1 CELLS + -> 2ND }T
+T{ 1ST @ 2ND @ -> 1 2 }T
+T{ 5 1ST ! -> }T
+T{ 1ST @ 2ND @ -> 5 2 }T
+T{ 6 2ND ! -> }T
+T{ 1ST @ 2ND @ -> 5 6 }T
+T{ 1ST 2@ -> 6 5 }T
+T{ 2 1 1ST 2! -> }T
+T{ 1ST 2@ -> 2 1 }T
+T{ 1S 1ST ! 1ST @ -> 1S }T \ CAN STORE CELL-WIDE VALUE
+
+HERE 1 C,
+HERE 2 C,
+CONSTANT 2NDC
+CONSTANT 1STC
+T{ 1STC 2NDC U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STC CHAR+ -> 2NDC }T \ ... BY ONE CHAR
+T{ 1STC 1 CHARS + -> 2NDC }T
+T{ 1STC C@ 2NDC C@ -> 1 2 }T
+T{ 3 1STC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 2 }T
+T{ 4 2NDC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 4 }T
+
+ALIGN 1 ALLOT HERE ALIGN HERE 3 CELLS ALLOT
+CONSTANT A-ADDR CONSTANT UA-ADDR
+T{ UA-ADDR ALIGNED -> A-ADDR }T
+T{ 1 A-ADDR C! A-ADDR C@ -> 1 }T
+T{ 1234 A-ADDR ! A-ADDR @ -> 1234 }T
+T{ 123 456 A-ADDR 2! A-ADDR 2@ -> 123 456 }T
+T{ 2 A-ADDR CHAR+ C! A-ADDR CHAR+ C@ -> 2 }T
+T{ 3 A-ADDR CELL+ C! A-ADDR CELL+ C@ -> 3 }T
+T{ 1234 A-ADDR CELL+ ! A-ADDR CELL+ @ -> 1234 }T
+T{ 123 456 A-ADDR CELL+ 2! A-ADDR CELL+ 2@ -> 123 456 }T
+
+: BITS ( X -- U )
+ 0 SWAP BEGIN DUP WHILE DUP MSB AND IF >R 1+ R> THEN 2* REPEAT DROP ;
+( CHARACTERS >= 1 AU, <= SIZE OF CELL, >= 8 BITS )
+T{ 1 CHARS 1 < -> <FALSE> }T
+T{ 1 CHARS 1 CELLS > -> <FALSE> }T
+( TBD: HOW TO FIND NUMBER OF BITS? )
+
+( CELLS >= 1 AU, INTEGRAL MULTIPLE OF CHAR SIZE, >= 16 BITS )
+T{ 1 CELLS 1 < -> <FALSE> }T
+T{ 1 CELLS 1 CHARS MOD -> 0 }T
+T{ 1S BITS 10 < -> <FALSE> }T
+
+T{ 0 1ST ! -> }T
+T{ 1 1ST +! -> }T
+T{ 1ST @ -> 1 }T
+T{ -1 1ST +! 1ST @ -> 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING CHAR [CHAR] [ ] BL S"
+
+T{ BL -> 20 }T
+T{ CHAR X -> 58 }T
+T{ CHAR HELLO -> 48 }T
+T{ : GC1 [CHAR] X ; -> }T
+T{ : GC2 [CHAR] HELLO ; -> }T
+T{ GC1 -> 58 }T
+T{ GC2 -> 48 }T
+T{ : GC3 [ GC1 ] LITERAL ; -> }T
+T{ GC3 -> 58 }T
+T{ : GC4 S" XY" ; -> }T
+T{ GC4 SWAP DROP -> 2 }T
+T{ GC4 DROP DUP C@ SWAP CHAR+ C@ -> 58 59 }T
+
+\ ------------------------------------------------------------------------
+TESTING ' ['] FIND EXECUTE IMMEDIATE COUNT LITERAL POSTPONE STATE
+
+T{ : GT1 123 ; -> }T
+T{ ' GT1 EXECUTE -> 123 }T
+T{ : GT2 ['] GT1 ; IMMEDIATE -> }T
+T{ GT2 EXECUTE -> 123 }T
+HERE 3 C, CHAR G C, CHAR T C, CHAR 1 C, CONSTANT GT1STRING
+HERE 3 C, CHAR G C, CHAR T C, CHAR 2 C, CONSTANT GT2STRING
+T{ GT1STRING FIND -> ' GT1 -1 }T
+T{ GT2STRING FIND -> ' GT2 1 }T
+( HOW TO SEARCH FOR NON-EXISTENT WORD? )
+T{ : GT3 GT2 LITERAL ; -> }T
+T{ GT3 -> ' GT1 }T
+T{ GT1STRING COUNT -> GT1STRING CHAR+ 3 }T
+
+T{ : GT4 POSTPONE GT1 ; IMMEDIATE -> }T
+T{ : GT5 GT4 ; -> }T
+T{ GT5 -> 123 }T
+T{ : GT6 345 ; IMMEDIATE -> }T
+T{ : GT7 POSTPONE GT6 ; -> }T
+T{ GT7 -> 345 }T
+
+T{ : GT8 STATE @ ; IMMEDIATE -> }T
+T{ GT8 -> 0 }T
+T{ : GT9 GT8 LITERAL ; -> }T
+T{ GT9 0= -> <FALSE> }T
+
+\ ------------------------------------------------------------------------
+TESTING IF ELSE THEN BEGIN WHILE REPEAT UNTIL RECURSE
+
+T{ : GI1 IF 123 THEN ; -> }T
+T{ : GI2 IF 123 ELSE 234 THEN ; -> }T
+T{ 0 GI1 -> }T
+T{ 1 GI1 -> 123 }T
+T{ -1 GI1 -> 123 }T
+T{ 0 GI2 -> 234 }T
+T{ 1 GI2 -> 123 }T
+T{ -1 GI1 -> 123 }T
+
+T{ : GI3 BEGIN DUP 5 < WHILE DUP 1+ REPEAT ; -> }T
+T{ 0 GI3 -> 0 1 2 3 4 5 }T
+T{ 4 GI3 -> 4 5 }T
+T{ 5 GI3 -> 5 }T
+T{ 6 GI3 -> 6 }T
+
+T{ : GI4 BEGIN DUP 1+ DUP 5 > UNTIL ; -> }T
+T{ 3 GI4 -> 3 4 5 6 }T
+T{ 5 GI4 -> 5 6 }T
+T{ 6 GI4 -> 6 7 }T
+
+T{ : GI5 BEGIN DUP 2 > WHILE DUP 5 < WHILE DUP 1+ REPEAT 123 ELSE 345 THEN ; -> }T
+T{ 1 GI5 -> 1 345 }T
+T{ 2 GI5 -> 2 345 }T
+T{ 3 GI5 -> 3 4 5 123 }T
+T{ 4 GI5 -> 4 5 123 }T
+T{ 5 GI5 -> 5 123 }T
+
+T{ : GI6 ( N -- 0,1,..N ) DUP IF DUP >R 1- RECURSE R> THEN ; -> }T
+T{ 0 GI6 -> 0 }T
+T{ 1 GI6 -> 0 1 }T
+T{ 2 GI6 -> 0 1 2 }T
+T{ 3 GI6 -> 0 1 2 3 }T
+T{ 4 GI6 -> 0 1 2 3 4 }T
+
+\ ------------------------------------------------------------------------
+TESTING DO LOOP +LOOP I J UNLOOP LEAVE EXIT
+
+T{ : GD1 DO I LOOP ; -> }T
+T{ 4 1 GD1 -> 1 2 3 }T
+T{ 2 -1 GD1 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD1 -> MID-UINT }T
+
+T{ : GD2 DO I -1 +LOOP ; -> }T
+T{ 1 4 GD2 -> 4 3 2 1 }T
+T{ -1 2 GD2 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD2 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD3 DO 1 0 DO J LOOP LOOP ; -> }T
+T{ 4 1 GD3 -> 1 2 3 }T
+T{ 2 -1 GD3 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD3 -> MID-UINT }T
+
+T{ : GD4 DO 1 0 DO J LOOP -1 +LOOP ; -> }T
+T{ 1 4 GD4 -> 4 3 2 1 }T
+T{ -1 2 GD4 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD4 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD5 123 SWAP 0 DO I 4 > IF DROP 234 LEAVE THEN LOOP ; -> }T
+T{ 1 GD5 -> 123 }T
+T{ 5 GD5 -> 123 }T
+T{ 6 GD5 -> 234 }T
+
+T{ : GD6 ( PAT: T{0 0}T,T{0 0}TT{1 0}TT{1 1}T,T{0 0}TT{1 0}TT{1 1}TT{2 0}TT{2 1}TT{2 2}T )
+ 0 SWAP 0 DO
+ I 1+ 0 DO I J + 3 = IF I UNLOOP I UNLOOP EXIT THEN 1+ LOOP
+ LOOP ; -> }T
+T{ 1 GD6 -> 1 }T
+T{ 2 GD6 -> 3 }T
+T{ 3 GD6 -> 4 1 2 }T
+
+\ ------------------------------------------------------------------------
+TESTING DEFINING WORDS: : ; CONSTANT VARIABLE CREATE DOES> >BODY
+
+T{ 123 CONSTANT X123 -> }T
+T{ X123 -> 123 }T
+T{ : EQU CONSTANT ; -> }T
+T{ X123 EQU Y123 -> }T
+T{ Y123 -> 123 }T
+
+T{ VARIABLE V1 -> }T
+T{ 123 V1 ! -> }T
+T{ V1 @ -> 123 }T
+
+T{ : NOP : POSTPONE ; ; -> }T
+T{ NOP NOP1 NOP NOP2 -> }T
+T{ NOP1 -> }T
+T{ NOP2 -> }T
+
+T{ : DOES1 DOES> @ 1 + ; -> }T
+T{ : DOES2 DOES> @ 2 + ; -> }T
+T{ CREATE CR1 -> }T
+T{ CR1 -> HERE }T
+T{ ' CR1 >BODY -> HERE }T
+T{ 1 , -> }T
+T{ CR1 @ -> 1 }T
+T{ DOES1 -> }T
+T{ CR1 -> 2 }T
+T{ DOES2 -> }T
+T{ CR1 -> 3 }T
+
+T{ : WEIRD: CREATE DOES> 1 + DOES> 2 + ; -> }T
+T{ WEIRD: W1 -> }T
+T{ ' W1 >BODY -> HERE }T
+T{ W1 -> HERE 1 + }T
+T{ W1 -> HERE 2 + }T
+
+\ ------------------------------------------------------------------------
+TESTING EVALUATE
+
+: GE1 S" 123" ; IMMEDIATE
+: GE2 S" 123 1+" ; IMMEDIATE
+: GE3 S" : GE4 345 ;" ;
+: GE5 EVALUATE ; IMMEDIATE
+
+T{ GE1 EVALUATE -> 123 }T ( TEST EVALUATE IN INTERP. STATE )
+T{ GE2 EVALUATE -> 124 }T
+T{ GE3 EVALUATE -> }T
+T{ GE4 -> 345 }T
+
+T{ : GE6 GE1 GE5 ; -> }T ( TEST EVALUATE IN COMPILE STATE )
+T{ GE6 -> 123 }T
+T{ : GE7 GE2 GE5 ; -> }T
+T{ GE7 -> 124 }T
+
+\ ------------------------------------------------------------------------
+TESTING SOURCE >IN WORD
+
+: GS1 S" SOURCE" 2DUP EVALUATE
+ >R SWAP >R = R> R> = ;
+T{ GS1 -> <TRUE> <TRUE> }T
+
+VARIABLE SCANS
+: RESCAN? -1 SCANS +! SCANS @ IF 0 >IN ! THEN ;
+
+T{ 2 SCANS !
+345 RESCAN?
+-> 345 345 }T
+
+: GS2 5 SCANS ! S" 123 RESCAN?" EVALUATE ;
+T{ GS2 -> 123 123 123 123 123 }T
+
+: GS3 WORD COUNT SWAP C@ ;
+T{ BL GS3 HELLO -> 5 CHAR H }T
+T{ CHAR " GS3 GOODBYE" -> 7 CHAR G }T
+T{ BL GS3
+DROP -> 0 }T \ BLANK LINE RETURN ZERO-LENGTH STRING
+
+: GS4 SOURCE >IN ! DROP ;
+T{ GS4 123 456
+-> }T
+
+\ ------------------------------------------------------------------------
+TESTING <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL
+
+: S= \ ( ADDR1 C1 ADDR2 C2 -- T/F ) COMPARE TWO STRINGS.
+ >R SWAP R@ = IF \ MAKE SURE STRINGS HAVE SAME LENGTH
+ R> ?DUP IF \ IF NON-EMPTY STRINGS
+ 0 DO
+ OVER C@ OVER C@ - IF
+ 2DROP <FALSE> UNLOOP EXIT THEN
+ SWAP CHAR+ SWAP CHAR+
+ LOOP
+ THEN
+ 2DROP <TRUE> \ IF WE GET HERE, STRINGS MATCH
+ ELSE
+ R> DROP 2DROP <FALSE> \ LENGTHS MISMATCH
+ THEN ;
+
+: GP1 <# 41 HOLD 42 HOLD 0 0 #> S" BA" S= ;
+T{ GP1 -> <TRUE> }T
+
+: GP2 <# -1 SIGN 0 SIGN -1 SIGN 0 0 #> S" --" S= ;
+T{ GP2 -> <TRUE> }T
+
+: GP3 <# 1 0 # # #> S" 01" S= ;
+T{ GP3 -> <TRUE> }T
+
+: GP4 <# 1 0 #S #> S" 1" S= ;
+T{ GP4 -> <TRUE> }T
+
+24 CONSTANT MAX-BASE \ BASE 2 .. 36
+: COUNT-BITS
+ 0 0 INVERT BEGIN DUP WHILE >R 1+ R> 2* REPEAT DROP ;
+COUNT-BITS 2* CONSTANT #BITS-UD \ NUMBER OF BITS IN UD
+
+: GP5
+ BASE @ <TRUE>
+ MAX-BASE 1+ 2 DO \ FOR EACH POSSIBLE BASE
+ I BASE ! \ TBD: ASSUMES BASE WORKS
+ I 0 <# #S #> S" 10" S= AND
+ LOOP
+ SWAP BASE ! ;
+T{ GP5 -> <TRUE> }T
+
+: GP6
+ BASE @ >R 2 BASE !
+ MAX-UINT MAX-UINT <# #S #> \ MAXIMUM UD TO BINARY
+ R> BASE ! \ S: C-ADDR U
+ DUP #BITS-UD = SWAP
+ 0 DO \ S: C-ADDR FLAG
+ OVER C@ [CHAR] 1 = AND \ ALL ONES
+ >R CHAR+ R>
+ LOOP SWAP DROP ;
+T{ GP6 -> <TRUE> }T
+
+: GP7
+ BASE @ >R MAX-BASE BASE !
+ <TRUE>
+ A 0 DO
+ I 0 <# #S #>
+ 1 = SWAP C@ I 30 + = AND AND
+ LOOP
+ MAX-BASE A DO
+ I 0 <# #S #>
+ 1 = SWAP C@ 41 I A - + = AND AND
+ LOOP
+ R> BASE ! ;
+
+T{ GP7 -> <TRUE> }T
+
+\ >NUMBER TESTS
+CREATE GN-BUF 0 C,
+: GN-STRING GN-BUF 1 ;
+: GN-CONSUMED GN-BUF CHAR+ 0 ;
+: GN' [CHAR] ' WORD CHAR+ C@ GN-BUF C! GN-STRING ;
+
+T{ 0 0 GN' 0' >NUMBER -> 0 0 GN-CONSUMED }T
+T{ 0 0 GN' 1' >NUMBER -> 1 0 GN-CONSUMED }T
+T{ 1 0 GN' 1' >NUMBER -> BASE @ 1+ 0 GN-CONSUMED }T
+T{ 0 0 GN' -' >NUMBER -> 0 0 GN-STRING }T \ SHOULD FAIL TO CONVERT THESE
+T{ 0 0 GN' +' >NUMBER -> 0 0 GN-STRING }T
+T{ 0 0 GN' .' >NUMBER -> 0 0 GN-STRING }T
+
+: >NUMBER-BASED
+ BASE @ >R BASE ! >NUMBER R> BASE ! ;
+
+T{ 0 0 GN' 2' 10 >NUMBER-BASED -> 2 0 GN-CONSUMED }T
+T{ 0 0 GN' 2' 2 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' F' 10 >NUMBER-BASED -> F 0 GN-CONSUMED }T
+T{ 0 0 GN' G' 10 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' G' MAX-BASE >NUMBER-BASED -> 10 0 GN-CONSUMED }T
+T{ 0 0 GN' Z' MAX-BASE >NUMBER-BASED -> 23 0 GN-CONSUMED }T
+
+: GN1 \ ( UD BASE -- UD' LEN ) UD SHOULD EQUAL UD' AND LEN SHOULD BE ZERO.
+ BASE @ >R BASE !
+ <# #S #>
+ 0 0 2SWAP >NUMBER SWAP DROP \ RETURN LENGTH ONLY
+ R> BASE ! ;
+T{ 0 0 2 GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 2 GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP 2 GN1 -> MAX-UINT DUP 0 }T
+T{ 0 0 MAX-BASE GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 MAX-BASE GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP MAX-BASE GN1 -> MAX-UINT DUP 0 }T
+
+: GN2 \ ( -- 16 10 )
+ BASE @ >R HEX BASE @ DECIMAL BASE @ R> BASE ! ;
+T{ GN2 -> 10 A }T
+
+\ ------------------------------------------------------------------------
+TESTING FILL MOVE
+
+CREATE FBUF 00 C, 00 C, 00 C,
+CREATE SBUF 12 C, 34 C, 56 C,
+: SEEBUF FBUF C@ FBUF CHAR+ C@ FBUF CHAR+ CHAR+ C@ ;
+
+T{ FBUF 0 20 FILL -> }T
+T{ SEEBUF -> 00 00 00 }T
+
+T{ FBUF 1 20 FILL -> }T
+T{ SEEBUF -> 20 00 00 }T
+
+T{ FBUF 3 20 FILL -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ FBUF FBUF 3 CHARS MOVE -> }T \ BIZARRE SPECIAL CASE
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 0 CHARS MOVE -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 1 CHARS MOVE -> }T
+T{ SEEBUF -> 12 20 20 }T
+
+T{ SBUF FBUF 3 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 56 }T
+
+T{ FBUF FBUF CHAR+ 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 12 34 }T
+
+T{ FBUF CHAR+ FBUF 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 34 }T
+
+\ ------------------------------------------------------------------------
+TESTING OUTPUT: . ." CR EMIT SPACE SPACES TYPE U.
+
+: OUTPUT-TEST
+ ." YOU SHOULD SEE THE STANDARD GRAPHIC CHARACTERS:" CR
+ 41 BL DO I EMIT LOOP CR
+ 61 41 DO I EMIT LOOP CR
+ 7F 61 DO I EMIT LOOP CR
+ ." YOU SHOULD SEE 0-9 SEPARATED BY A SPACE:" CR
+ 9 1+ 0 DO I . LOOP CR
+ ." YOU SHOULD SEE 0-9 (WITH NO SPACES):" CR
+ [CHAR] 9 1+ [CHAR] 0 DO I 0 SPACES EMIT LOOP CR
+ ." YOU SHOULD SEE A-G SEPARATED BY A SPACE:" CR
+ [CHAR] G 1+ [CHAR] A DO I EMIT SPACE LOOP CR
+ ." YOU SHOULD SEE 0-5 SEPARATED BY TWO SPACES:" CR
+ 5 1+ 0 DO I [CHAR] 0 + EMIT 2 SPACES LOOP CR
+ ." YOU SHOULD SEE TWO SEPARATE LINES:" CR
+ S" LINE 1" TYPE CR S" LINE 2" TYPE CR
+ ." YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:" CR
+ ." SIGNED: " MIN-INT . MAX-INT . CR
+ ." UNSIGNED: " 0 U. MAX-UINT U. CR
+;
+
+T{ OUTPUT-TEST -> }T
+\ ------------------------------------------------------------------------
+TESTING INPUT: ACCEPT
+
+CREATE ABUF 80 CHARS ALLOT
+
+: ACCEPT-TEST
+ CR ." PLEASE TYPE UP TO 80 CHARACTERS:" CR
+ ABUF 80 ACCEPT
+ CR ." RECEIVED: " [CHAR] " EMIT
+ ABUF SWAP TYPE [CHAR] " EMIT CR
+;
+
+T{ ACCEPT-TEST -> }T
+Vingt fois sur le métier remettez votre ouvrage, ...
+\ ------------------------------------------------------------------------
+TESTING DICTIONARY SEARCH RULES
+
+T{ : GDX 123 ; : GDX GDX 234 ; -> }T
+
+T{ GDX -> 123 234 }T
+
+CR .( End of Core word set tests) CR
+
+
+
+RST_STATE ; so ANS_COMPLEMENT_xx_MPY is conserved ;
+\ NOECHO ; if an error occurs, comment this line before new download to find it.
+
+
+\ From: John Hayes S1I
+\ Subject: tester.fr
+\ Date: Mon, 27 Nov 95 13:10:09 PST
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.1
+
+\ 22/1/09 The words { and } have been changed to T{ and }T respectively to
+\ agree with the Forth 200X file ttester.fs. This avoids clashes with
+\ locals using { ... } and the FSL use of }
+
+
+\ 13/05/14 jmt. added colorised error messages.
+
+
+
+ 0 CONSTANT FALSE
+-1 CONSTANT TRUE
+
+\ SET THE FOLLOWING FLAG TO TRUE FOR MORE VERBOSE OUTPUT; THIS MAY
+\ ALLOW YOU TO TELL WHICH TEST CAUSED YOUR SYSTEM TO HANG.
+VARIABLE VERBOSE
+ FALSE VERBOSE !
+\ TRUE VERBOSE !
+
+\ : EMPTY-STACK ( ... -- ) \ EMPTY STACK: HANDLES UNDERFLOWED STACK TOO.
+\ DEPTH ?DUP
+\ IF DUP 0< IF NEGATE 0
+\ DO 0 LOOP
+\ ELSE 0 DO DROP LOOP THEN
+\ THEN ;
+\
+\ : ERROR \ ( C-ADDR U -- ) DISPLAY AN ERROR MESSAGE FOLLOWED BY
+\ \ THE LINE THAT HAD THE ERROR.
+\ TYPE SOURCE TYPE CR \ DISPLAY LINE CORRESPONDING TO ERROR
+\ EMPTY-STACK \ THROW AWAY EVERY THING ELSE
+\ QUIT \ *** Uncomment this line to QUIT on an error
+\ ;
+
+VARIABLE ACTUAL-DEPTH \ STACK RECORD
+CREATE ACTUAL-RESULTS 20 CELLS ALLOT
+
+: T{ \ ( -- ) SYNTACTIC SUGAR.
+ ;
+
+: -> \ ( ... -- ) RECORD DEPTH AND CONTENT OF STACK.
+ DEPTH DUP ACTUAL-DEPTH ! \ RECORD DEPTH
+ ?DUP IF \ IF THERE IS SOMETHING ON STACK
+ 0 DO ACTUAL-RESULTS I CELLS + ! LOOP \ SAVE THEM
+ THEN ;
+
+: }T \ ( ... -- ) COMPARE STACK (EXPECTED) CONTENTS WITH SAVED
+ \ (ACTUAL) CONTENTS.
+ DEPTH ACTUAL-DEPTH @ = IF \ IF DEPTHS MATCH
+ DEPTH ?DUP IF \ IF THERE IS SOMETHING ON THE STACK
+ 0 DO \ FOR EACH STACK ITEM
+ ACTUAL-RESULTS I CELLS + @ \ COMPARE ACTUAL WITH EXPECTED
+\ = 0= IF S" INCORRECT RESULT: " ERROR LEAVE THEN \ jmt
+ = 0= IF ABORT" INCORRECT RESULT: " THEN \ jmt : colorised message
+ LOOP
+ THEN
+ ELSE \ DEPTH MISMATCH
+\ S" WRONG NUMBER OF RESULTS: " ERROR \ jmt
+ ABORT" WRONG NUMBER OF RESULTS: " \ jmt : colorised message
+ THEN ;
+
+: TESTING \ ( -- ) TALKING COMMENT.
+ SOURCE VERBOSE @
+ IF DUP >R TYPE CR R> >IN !
+ ELSE >IN ! DROP [CHAR] * EMIT
+ THEN ;
+
+\ From: John Hayes S1I
+\ Subject: core.fr
+\ Date: Mon, 27 Nov 95 13:10
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.2
+\ THIS PROGRAM TESTS THE CORE WORDS OF AN ANS FORTH SYSTEM.
+\ THE PROGRAM ASSUMES A TWO'S COMPLEMENT IMPLEMENTATION WHERE
+\ THE RANGE OF SIGNED NUMBERS IS -2^(N-1) ... 2^(N-1)-1 AND
+\ THE RANGE OF UNSIGNED NUMBERS IS 0 ... 2^(N)-1.
+\ I HAVEN'T FIGURED OUT HOW TO TEST KEY, QUIT, ABORT, OR ABORT"...
+\ I ALSO HAVEN'T THOUGHT OF A WAY TO TEST ENVIRONMENT?...
+
+CR
+TESTING CORE WORDS
+HEX
+
+\ ------------------------------------------------------------------------
+TESTING BASIC ASSUMPTIONS
+
+T{ -> }T \ START WITH CLEAN SLATE
+( TEST IF ANY BITS ARE SET; ANSWER IN BASE 1 )
+T{ : BITSSET? IF 0 0 ELSE 0 THEN ; -> }T
+T{ 0 BITSSET? -> 0 }T ( ZERO IS ALL BITS CLEAR )
+T{ 1 BITSSET? -> 0 0 }T ( OTHER NUMBER HAVE AT LEAST ONE BIT )
+T{ -1 BITSSET? -> 0 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING BOOLEANS: INVERT AND OR XOR
+
+T{ 0 0 AND -> 0 }T
+T{ 0 1 AND -> 0 }T
+T{ 1 0 AND -> 0 }T
+T{ 1 1 AND -> 1 }T
+
+T{ 0 INVERT 1 AND -> 1 }T
+T{ 1 INVERT 1 AND -> 0 }T
+
+0 CONSTANT 0S
+0 INVERT CONSTANT 1S
+
+T{ 0S INVERT -> 1S }T
+T{ 1S INVERT -> 0S }T
+
+T{ 0S 0S AND -> 0S }T
+T{ 0S 1S AND -> 0S }T
+T{ 1S 0S AND -> 0S }T
+T{ 1S 1S AND -> 1S }T
+
+T{ 0S 0S OR -> 0S }T
+T{ 0S 1S OR -> 1S }T
+T{ 1S 0S OR -> 1S }T
+T{ 1S 1S OR -> 1S }T
+
+T{ 0S 0S XOR -> 0S }T
+T{ 0S 1S XOR -> 1S }T
+T{ 1S 0S XOR -> 1S }T
+T{ 1S 1S XOR -> 0S }T
+
+\ ------------------------------------------------------------------------
+TESTING 2* 2/ LSHIFT RSHIFT
+
+( WE TRUST 1S, INVERT, AND BITSSET?; WE WILL CONFIRM RSHIFT LATER )
+1S 1 RSHIFT INVERT CONSTANT MSB
+T{ MSB BITSSET? -> 0 0 }T
+
+T{ 0S 2* -> 0S }T
+T{ 1 2* -> 2 }T
+T{ 4000 2* -> 8000 }T
+T{ 1S 2* 1 XOR -> 1S }T
+T{ MSB 2* -> 0S }T
+
+T{ 0S 2/ -> 0S }T
+T{ 1 2/ -> 0 }T
+T{ 4000 2/ -> 2000 }T
+T{ 1S 2/ -> 1S }T \ MSB PROPOGATED
+T{ 1S 1 XOR 2/ -> 1S }T
+T{ MSB 2/ MSB AND -> MSB }T
+
+T{ 1 0 LSHIFT -> 1 }T
+T{ 1 1 LSHIFT -> 2 }T
+T{ 1 2 LSHIFT -> 4 }T
+T{ 1 F LSHIFT -> 8000 }T \ BIGGEST GUARANTEED SHIFT
+T{ 1S 1 LSHIFT 1 XOR -> 1S }T
+T{ MSB 1 LSHIFT -> 0 }T
+
+T{ 1 0 RSHIFT -> 1 }T
+T{ 1 1 RSHIFT -> 0 }T
+T{ 2 1 RSHIFT -> 1 }T
+T{ 4 2 RSHIFT -> 1 }T
+T{ 8000 F RSHIFT -> 1 }T \ BIGGEST
+T{ MSB 1 RSHIFT MSB AND -> 0 }T \ RSHIFT ZERO FILLS MSBS
+T{ MSB 1 RSHIFT 2* -> MSB }T
+
+\ ------------------------------------------------------------------------
+TESTING COMPARISONS: 0= = 0< < > U< MIN MAX
+0 INVERT CONSTANT MAX-UINT
+0 INVERT 1 RSHIFT CONSTANT MAX-INT
+0 INVERT 1 RSHIFT INVERT CONSTANT MIN-INT
+0 INVERT 1 RSHIFT CONSTANT MID-UINT
+0 INVERT 1 RSHIFT INVERT CONSTANT MID-UINT+1
+
+0S CONSTANT <FALSE>
+1S CONSTANT <TRUE>
+
+T{ 0 0= -> <TRUE> }T
+T{ 1 0= -> <FALSE> }T
+T{ 2 0= -> <FALSE> }T
+T{ -1 0= -> <FALSE> }T
+T{ MAX-UINT 0= -> <FALSE> }T
+T{ MIN-INT 0= -> <FALSE> }T
+T{ MAX-INT 0= -> <FALSE> }T
+
+T{ 0 0 = -> <TRUE> }T
+T{ 1 1 = -> <TRUE> }T
+T{ -1 -1 = -> <TRUE> }T
+T{ 1 0 = -> <FALSE> }T
+T{ -1 0 = -> <FALSE> }T
+T{ 0 1 = -> <FALSE> }T
+T{ 0 -1 = -> <FALSE> }T
+
+T{ 0 0< -> <FALSE> }T
+T{ -1 0< -> <TRUE> }T
+T{ MIN-INT 0< -> <TRUE> }T
+T{ 1 0< -> <FALSE> }T
+T{ MAX-INT 0< -> <FALSE> }T
+
+T{ 0 1 < -> <TRUE> }T
+T{ 1 2 < -> <TRUE> }T
+T{ -1 0 < -> <TRUE> }T
+T{ -1 1 < -> <TRUE> }T
+T{ MIN-INT 0 < -> <TRUE> }T
+T{ MIN-INT MAX-INT < -> <TRUE> }T
+T{ 0 MAX-INT < -> <TRUE> }T
+T{ 0 0 < -> <FALSE> }T
+T{ 1 1 < -> <FALSE> }T
+T{ 1 0 < -> <FALSE> }T
+T{ 2 1 < -> <FALSE> }T
+T{ 0 -1 < -> <FALSE> }T
+T{ 1 -1 < -> <FALSE> }T
+T{ 0 MIN-INT < -> <FALSE> }T
+T{ MAX-INT MIN-INT < -> <FALSE> }T
+T{ MAX-INT 0 < -> <FALSE> }T
+
+T{ 0 1 > -> <FALSE> }T
+T{ 1 2 > -> <FALSE> }T
+T{ -1 0 > -> <FALSE> }T
+T{ -1 1 > -> <FALSE> }T
+T{ MIN-INT 0 > -> <FALSE> }T
+T{ MIN-INT MAX-INT > -> <FALSE> }T
+T{ 0 MAX-INT > -> <FALSE> }T
+T{ 0 0 > -> <FALSE> }T
+T{ 1 1 > -> <FALSE> }T
+T{ 1 0 > -> <TRUE> }T
+T{ 2 1 > -> <TRUE> }T
+T{ 0 -1 > -> <TRUE> }T
+T{ 1 -1 > -> <TRUE> }T
+T{ 0 MIN-INT > -> <TRUE> }T
+T{ MAX-INT MIN-INT > -> <TRUE> }T
+T{ MAX-INT 0 > -> <TRUE> }T
+
+T{ 0 1 U< -> <TRUE> }T
+T{ 1 2 U< -> <TRUE> }T
+T{ 0 MID-UINT U< -> <TRUE> }T
+T{ 0 MAX-UINT U< -> <TRUE> }T
+T{ MID-UINT MAX-UINT U< -> <TRUE> }T
+T{ 0 0 U< -> <FALSE> }T
+T{ 1 1 U< -> <FALSE> }T
+T{ 1 0 U< -> <FALSE> }T
+T{ 2 1 U< -> <FALSE> }T
+T{ MID-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT MID-UINT U< -> <FALSE> }T
+
+T{ 0 1 MIN -> 0 }T
+T{ 1 2 MIN -> 1 }T
+T{ -1 0 MIN -> -1 }T
+T{ -1 1 MIN -> -1 }T
+T{ MIN-INT 0 MIN -> MIN-INT }T
+T{ MIN-INT MAX-INT MIN -> MIN-INT }T
+T{ 0 MAX-INT MIN -> 0 }T
+T{ 0 0 MIN -> 0 }T
+T{ 1 1 MIN -> 1 }T
+T{ 1 0 MIN -> 0 }T
+T{ 2 1 MIN -> 1 }T
+T{ 0 -1 MIN -> -1 }T
+T{ 1 -1 MIN -> -1 }T
+T{ 0 MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT 0 MIN -> 0 }T
+
+T{ 0 1 MAX -> 1 }T
+T{ 1 2 MAX -> 2 }T
+T{ -1 0 MAX -> 0 }T
+T{ -1 1 MAX -> 1 }T
+T{ MIN-INT 0 MAX -> 0 }T
+T{ MIN-INT MAX-INT MAX -> MAX-INT }T
+T{ 0 MAX-INT MAX -> MAX-INT }T
+T{ 0 0 MAX -> 0 }T
+T{ 1 1 MAX -> 1 }T
+T{ 1 0 MAX -> 1 }T
+T{ 2 1 MAX -> 2 }T
+T{ 0 -1 MAX -> 0 }T
+T{ 1 -1 MAX -> 1 }T
+T{ 0 MIN-INT MAX -> 0 }T
+T{ MAX-INT MIN-INT MAX -> MAX-INT }T
+T{ MAX-INT 0 MAX -> MAX-INT }T
+
+\ ------------------------------------------------------------------------
+TESTING STACK OPS: 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP
+
+T{ 1 2 2DROP -> }T
+T{ 1 2 2DUP -> 1 2 1 2 }T
+T{ 1 2 3 4 2OVER -> 1 2 3 4 1 2 }T
+T{ 1 2 3 4 2SWAP -> 3 4 1 2 }T
+T{ 0 ?DUP -> 0 }T
+T{ 1 ?DUP -> 1 1 }T
+T{ -1 ?DUP -> -1 -1 }T
+T{ DEPTH -> 0 }T
+T{ 0 DEPTH -> 0 1 }T
+T{ 0 1 DEPTH -> 0 1 2 }T
+T{ 0 DROP -> }T
+T{ 1 2 DROP -> 1 }T
+T{ 1 DUP -> 1 1 }T
+T{ 1 2 OVER -> 1 2 1 }T
+T{ 1 2 3 ROT -> 2 3 1 }T
+T{ 1 2 SWAP -> 2 1 }T
+
+\ ------------------------------------------------------------------------
+TESTING >R R> R@
+
+T{ : GR1 >R R> ; -> }T
+T{ : GR2 >R R@ R> DROP ; -> }T
+T{ 123 GR1 -> 123 }T
+T{ 123 GR2 -> 123 }T
+T{ 1S GR1 -> 1S }T ( RETURN STACK HOLDS CELLS )
+
+\ ------------------------------------------------------------------------
+TESTING ADD/SUBTRACT: + - 1+ 1- ABS NEGATE
+
+T{ 0 5 + -> 5 }T
+T{ 5 0 + -> 5 }T
+T{ 0 -5 + -> -5 }T
+T{ -5 0 + -> -5 }T
+T{ 1 2 + -> 3 }T
+T{ 1 -2 + -> -1 }T
+T{ -1 2 + -> 1 }T
+T{ -1 -2 + -> -3 }T
+T{ -1 1 + -> 0 }T
+T{ MID-UINT 1 + -> MID-UINT+1 }T
+
+T{ 0 5 - -> -5 }T
+T{ 5 0 - -> 5 }T
+T{ 0 -5 - -> 5 }T
+T{ -5 0 - -> -5 }T
+T{ 1 2 - -> -1 }T
+T{ 1 -2 - -> 3 }T
+T{ -1 2 - -> -3 }T
+T{ -1 -2 - -> 1 }T
+T{ 0 1 - -> -1 }T
+T{ MID-UINT+1 1 - -> MID-UINT }T
+
+T{ 0 1+ -> 1 }T
+T{ -1 1+ -> 0 }T
+T{ 1 1+ -> 2 }T
+T{ MID-UINT 1+ -> MID-UINT+1 }T
+
+T{ 2 1- -> 1 }T
+T{ 1 1- -> 0 }T
+T{ 0 1- -> -1 }T
+T{ MID-UINT+1 1- -> MID-UINT }T
+
+T{ 0 NEGATE -> 0 }T
+T{ 1 NEGATE -> -1 }T
+T{ -1 NEGATE -> 1 }T
+T{ 2 NEGATE -> -2 }T
+T{ -2 NEGATE -> 2 }T
+
+T{ 0 ABS -> 0 }T
+T{ 1 ABS -> 1 }T
+T{ -1 ABS -> 1 }T
+T{ MIN-INT ABS -> MID-UINT+1 }T
+
+\ ------------------------------------------------------------------------
+TESTING MULTIPLY: S>D * M* UM*
+
+T{ 0 S>D -> 0 0 }T
+T{ 1 S>D -> 1 0 }T
+T{ 2 S>D -> 2 0 }T
+T{ -1 S>D -> -1 -1 }T
+T{ -2 S>D -> -2 -1 }T
+T{ MIN-INT S>D -> MIN-INT -1 }T
+T{ MAX-INT S>D -> MAX-INT 0 }T
+
+T{ 0 0 M* -> 0 S>D }T
+T{ 0 1 M* -> 0 S>D }T
+T{ 1 0 M* -> 0 S>D }T
+T{ 1 2 M* -> 2 S>D }T
+T{ 2 1 M* -> 2 S>D }T
+T{ 3 3 M* -> 9 S>D }T
+T{ -3 3 M* -> -9 S>D }T
+T{ 3 -3 M* -> -9 S>D }T
+T{ -3 -3 M* -> 9 S>D }T
+T{ 0 MIN-INT M* -> 0 S>D }T
+T{ 1 MIN-INT M* -> MIN-INT S>D }T
+T{ 2 MIN-INT M* -> 0 1S }T
+T{ 0 MAX-INT M* -> 0 S>D }T
+T{ 1 MAX-INT M* -> MAX-INT S>D }T
+T{ 2 MAX-INT M* -> MAX-INT 1 LSHIFT 0 }T
+T{ MIN-INT MIN-INT M* -> 0 MSB 1 RSHIFT }T
+T{ MAX-INT MIN-INT M* -> MSB MSB 2/ }T
+T{ MAX-INT MAX-INT M* -> 1 MSB 2/ INVERT }T
+
+T{ 0 0 * -> 0 }T \ TEST IDENTITIES
+T{ 0 1 * -> 0 }T
+T{ 1 0 * -> 0 }T
+T{ 1 2 * -> 2 }T
+T{ 2 1 * -> 2 }T
+T{ 3 3 * -> 9 }T
+T{ -3 3 * -> -9 }T
+T{ 3 -3 * -> -9 }T
+T{ -3 -3 * -> 9 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 * -> MID-UINT+1 }T
+T{ MID-UINT+1 2 RSHIFT 4 * -> MID-UINT+1 }T
+T{ MID-UINT+1 1 RSHIFT MID-UINT+1 OR 2 * -> MID-UINT+1 }T
+
+T{ 0 0 UM* -> 0 0 }T
+T{ 0 1 UM* -> 0 0 }T
+T{ 1 0 UM* -> 0 0 }T
+T{ 1 2 UM* -> 2 0 }T
+T{ 2 1 UM* -> 2 0 }T
+T{ 3 3 UM* -> 9 0 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 UM* -> MID-UINT+1 0 }T
+T{ MID-UINT+1 2 UM* -> 0 1 }T
+T{ MID-UINT+1 4 UM* -> 0 2 }T
+T{ 1S 2 UM* -> 1S 1 LSHIFT 1 }T
+T{ MAX-UINT MAX-UINT UM* -> 1 1 INVERT }T
+
+\ ------------------------------------------------------------------------
+TESTING DIVIDE: FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD
+
+T{ 0 S>D 1 FM/MOD -> 0 0 }T
+T{ 1 S>D 1 FM/MOD -> 0 1 }T
+T{ 2 S>D 1 FM/MOD -> 0 2 }T
+T{ -1 S>D 1 FM/MOD -> 0 -1 }T
+T{ -2 S>D 1 FM/MOD -> 0 -2 }T
+T{ 0 S>D -1 FM/MOD -> 0 0 }T
+T{ 1 S>D -1 FM/MOD -> 0 -1 }T
+T{ 2 S>D -1 FM/MOD -> 0 -2 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -1 FM/MOD -> 0 2 }T
+T{ 2 S>D 2 FM/MOD -> 0 1 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -2 FM/MOD -> 0 1 }T
+T{ 7 S>D 3 FM/MOD -> 1 2 }T
+T{ 7 S>D -3 FM/MOD -> -2 -3 }T
+T{ -7 S>D 3 FM/MOD -> 2 -3 }T
+T{ -7 S>D -3 FM/MOD -> -1 2 }T
+T{ MAX-INT S>D 1 FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT FM/MOD -> 0 1 }T
+T{ MIN-INT S>D MIN-INT FM/MOD -> 0 1 }T
+T{ 1S 1 4 FM/MOD -> 3 MAX-INT }T
+T{ 1 MIN-INT M* 1 FM/MOD -> 0 MIN-INT }T
+T{ 1 MIN-INT M* MIN-INT FM/MOD -> 0 1 }T
+T{ 2 MIN-INT M* 2 FM/MOD -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT FM/MOD -> 0 2 }T
+T{ 1 MAX-INT M* 1 FM/MOD -> 0 MAX-INT }T
+T{ 1 MAX-INT M* MAX-INT FM/MOD -> 0 1 }T
+T{ 2 MAX-INT M* 2 FM/MOD -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT FM/MOD -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT FM/MOD -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT FM/MOD -> 0 MAX-INT }T
+
+T{ 0 S>D 1 SM/REM -> 0 0 }T
+T{ 1 S>D 1 SM/REM -> 0 1 }T
+T{ 2 S>D 1 SM/REM -> 0 2 }T
+T{ -1 S>D 1 SM/REM -> 0 -1 }T
+T{ -2 S>D 1 SM/REM -> 0 -2 }T
+T{ 0 S>D -1 SM/REM -> 0 0 }T
+T{ 1 S>D -1 SM/REM -> 0 -1 }T
+T{ 2 S>D -1 SM/REM -> 0 -2 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -1 SM/REM -> 0 2 }T
+T{ 2 S>D 2 SM/REM -> 0 1 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -2 SM/REM -> 0 1 }T
+T{ 7 S>D 3 SM/REM -> 1 2 }T
+T{ 7 S>D -3 SM/REM -> 1 -2 }T
+T{ -7 S>D 3 SM/REM -> -1 -2 }T
+T{ -7 S>D -3 SM/REM -> -1 2 }T
+T{ MAX-INT S>D 1 SM/REM -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 SM/REM -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT SM/REM -> 0 1 }T
+T{ MIN-INT S>D MIN-INT SM/REM -> 0 1 }T
+T{ 1S 1 4 SM/REM -> 3 MAX-INT }T
+T{ 2 MIN-INT M* 2 SM/REM -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT SM/REM -> 0 2 }T
+T{ 2 MAX-INT M* 2 SM/REM -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT SM/REM -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT SM/REM -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT SM/REM -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT SM/REM -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT SM/REM -> 0 MAX-INT }T
+
+T{ 0 0 1 UM/MOD -> 0 0 }T
+T{ 1 0 1 UM/MOD -> 0 1 }T
+T{ 1 0 2 UM/MOD -> 1 0 }T
+T{ 3 0 2 UM/MOD -> 1 1 }T
+T{ MAX-UINT 2 UM* 2 UM/MOD -> 0 MAX-UINT }T
+T{ MAX-UINT 2 UM* MAX-UINT UM/MOD -> 0 2 }T
+T{ MAX-UINT MAX-UINT UM* MAX-UINT UM/MOD -> 0 MAX-UINT }T
+
+: IFFLOORED
+ [ -3 2 / -2 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+: IFSYM
+ [ -3 2 / -1 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+\ THE SYSTEM MIGHT DO EITHER FLOORED OR SYMMETRIC DIVISION.
+\ SINCE WE HAVE ALREADY TESTED M*, FM/MOD, AND SM/REM WE CAN USE THEM IN TEST.
+
+IFFLOORED : T/MOD >R S>D R> FM/MOD ;
+IFFLOORED : T/ T/MOD SWAP DROP ;
+IFFLOORED : TMOD T/MOD DROP ;
+IFFLOORED : T*/MOD >R M* R> FM/MOD ;
+IFFLOORED : T*/ T*/MOD SWAP DROP ;
+IFSYM : T/MOD >R S>D R> SM/REM ;
+IFSYM : T/ T/MOD SWAP DROP ;
+IFSYM : TMOD T/MOD DROP ;
+IFSYM : T*/MOD >R M* R> SM/REM ;
+IFSYM : T*/ T*/MOD SWAP DROP ;
+
+T{ 0 1 /MOD -> 0 1 T/MOD }T
+T{ 1 1 /MOD -> 1 1 T/MOD }T
+T{ 2 1 /MOD -> 2 1 T/MOD }T
+T{ -1 1 /MOD -> -1 1 T/MOD }T
+T{ -2 1 /MOD -> -2 1 T/MOD }T
+T{ 0 -1 /MOD -> 0 -1 T/MOD }T
+T{ 1 -1 /MOD -> 1 -1 T/MOD }T
+T{ 2 -1 /MOD -> 2 -1 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -1 /MOD -> -2 -1 T/MOD }T
+T{ 2 2 /MOD -> 2 2 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -2 /MOD -> -2 -2 T/MOD }T
+T{ 7 3 /MOD -> 7 3 T/MOD }T
+T{ 7 -3 /MOD -> 7 -3 T/MOD }T
+T{ -7 3 /MOD -> -7 3 T/MOD }T
+T{ -7 -3 /MOD -> -7 -3 T/MOD }T
+T{ MAX-INT 1 /MOD -> MAX-INT 1 T/MOD }T
+T{ MIN-INT 1 /MOD -> MIN-INT 1 T/MOD }T
+T{ MAX-INT MAX-INT /MOD -> MAX-INT MAX-INT T/MOD }T
+T{ MIN-INT MIN-INT /MOD -> MIN-INT MIN-INT T/MOD }T
+
+T{ 0 1 / -> 0 1 T/ }T
+T{ 1 1 / -> 1 1 T/ }T
+T{ 2 1 / -> 2 1 T/ }T
+T{ -1 1 / -> -1 1 T/ }T
+T{ -2 1 / -> -2 1 T/ }T
+T{ 0 -1 / -> 0 -1 T/ }T
+T{ 1 -1 / -> 1 -1 T/ }T
+T{ 2 -1 / -> 2 -1 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -1 / -> -2 -1 T/ }T
+T{ 2 2 / -> 2 2 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -2 / -> -2 -2 T/ }T
+T{ 7 3 / -> 7 3 T/ }T
+T{ 7 -3 / -> 7 -3 T/ }T
+T{ -7 3 / -> -7 3 T/ }T
+T{ -7 -3 / -> -7 -3 T/ }T
+T{ MAX-INT 1 / -> MAX-INT 1 T/ }T
+T{ MIN-INT 1 / -> MIN-INT 1 T/ }T
+T{ MAX-INT MAX-INT / -> MAX-INT MAX-INT T/ }T
+T{ MIN-INT MIN-INT / -> MIN-INT MIN-INT T/ }T
+
+T{ 0 1 MOD -> 0 1 TMOD }T
+T{ 1 1 MOD -> 1 1 TMOD }T
+T{ 2 1 MOD -> 2 1 TMOD }T
+T{ -1 1 MOD -> -1 1 TMOD }T
+T{ -2 1 MOD -> -2 1 TMOD }T
+T{ 0 -1 MOD -> 0 -1 TMOD }T
+T{ 1 -1 MOD -> 1 -1 TMOD }T
+T{ 2 -1 MOD -> 2 -1 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -1 MOD -> -2 -1 TMOD }T
+T{ 2 2 MOD -> 2 2 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -2 MOD -> -2 -2 TMOD }T
+T{ 7 3 MOD -> 7 3 TMOD }T
+T{ 7 -3 MOD -> 7 -3 TMOD }T
+T{ -7 3 MOD -> -7 3 TMOD }T
+T{ -7 -3 MOD -> -7 -3 TMOD }T
+T{ MAX-INT 1 MOD -> MAX-INT 1 TMOD }T
+T{ MIN-INT 1 MOD -> MIN-INT 1 TMOD }T
+T{ MAX-INT MAX-INT MOD -> MAX-INT MAX-INT TMOD }T
+T{ MIN-INT MIN-INT MOD -> MIN-INT MIN-INT TMOD }T
+
+T{ 0 2 1 */ -> 0 2 1 T*/ }T
+T{ 1 2 1 */ -> 1 2 1 T*/ }T
+T{ 2 2 1 */ -> 2 2 1 T*/ }T
+T{ -1 2 1 */ -> -1 2 1 T*/ }T
+T{ -2 2 1 */ -> -2 2 1 T*/ }T
+T{ 0 2 -1 */ -> 0 2 -1 T*/ }T
+T{ 1 2 -1 */ -> 1 2 -1 T*/ }T
+T{ 2 2 -1 */ -> 2 2 -1 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -1 */ -> -2 2 -1 T*/ }T
+T{ 2 2 2 */ -> 2 2 2 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -2 */ -> -2 2 -2 T*/ }T
+T{ 7 2 3 */ -> 7 2 3 T*/ }T
+T{ 7 2 -3 */ -> 7 2 -3 T*/ }T
+T{ -7 2 3 */ -> -7 2 3 T*/ }T
+T{ -7 2 -3 */ -> -7 2 -3 T*/ }T
+T{ MAX-INT 2 MAX-INT */ -> MAX-INT 2 MAX-INT T*/ }T
+T{ MIN-INT 2 MIN-INT */ -> MIN-INT 2 MIN-INT T*/ }T
+
+T{ 0 2 1 */MOD -> 0 2 1 T*/MOD }T
+T{ 1 2 1 */MOD -> 1 2 1 T*/MOD }T
+T{ 2 2 1 */MOD -> 2 2 1 T*/MOD }T
+T{ -1 2 1 */MOD -> -1 2 1 T*/MOD }T
+T{ -2 2 1 */MOD -> -2 2 1 T*/MOD }T
+T{ 0 2 -1 */MOD -> 0 2 -1 T*/MOD }T
+T{ 1 2 -1 */MOD -> 1 2 -1 T*/MOD }T
+T{ 2 2 -1 */MOD -> 2 2 -1 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -1 */MOD -> -2 2 -1 T*/MOD }T
+T{ 2 2 2 */MOD -> 2 2 2 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -2 */MOD -> -2 2 -2 T*/MOD }T
+T{ 7 2 3 */MOD -> 7 2 3 T*/MOD }T
+T{ 7 2 -3 */MOD -> 7 2 -3 T*/MOD }T
+T{ -7 2 3 */MOD -> -7 2 3 T*/MOD }T
+T{ -7 2 -3 */MOD -> -7 2 -3 T*/MOD }T
+T{ MAX-INT 2 MAX-INT */MOD -> MAX-INT 2 MAX-INT T*/MOD }T
+T{ MIN-INT 2 MIN-INT */MOD -> MIN-INT 2 MIN-INT T*/MOD }T
+
+\ ------------------------------------------------------------------------
+TESTING HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2! ALIGN ALIGNED +! ALLOT
+
+HERE 1 ALLOT
+HERE
+CONSTANT 2NDA
+CONSTANT 1STA
+T{ 1STA 2NDA U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STA 1+ -> 2NDA }T \ ... BY ONE ADDRESS UNIT
+( MISSING TEST: NEGATIVE ALLOT )
+
+HERE 1 ,
+HERE 2 ,
+CONSTANT 2ND
+CONSTANT 1ST
+T{ 1ST 2ND U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1ST CELL+ -> 2ND }T \ ... BY ONE CELL
+T{ 1ST 1 CELLS + -> 2ND }T
+T{ 1ST @ 2ND @ -> 1 2 }T
+T{ 5 1ST ! -> }T
+T{ 1ST @ 2ND @ -> 5 2 }T
+T{ 6 2ND ! -> }T
+T{ 1ST @ 2ND @ -> 5 6 }T
+T{ 1ST 2@ -> 6 5 }T
+T{ 2 1 1ST 2! -> }T
+T{ 1ST 2@ -> 2 1 }T
+T{ 1S 1ST ! 1ST @ -> 1S }T \ CAN STORE CELL-WIDE VALUE
+
+HERE 1 C,
+HERE 2 C,
+CONSTANT 2NDC
+CONSTANT 1STC
+T{ 1STC 2NDC U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STC CHAR+ -> 2NDC }T \ ... BY ONE CHAR
+T{ 1STC 1 CHARS + -> 2NDC }T
+T{ 1STC C@ 2NDC C@ -> 1 2 }T
+T{ 3 1STC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 2 }T
+T{ 4 2NDC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 4 }T
+
+ALIGN 1 ALLOT HERE ALIGN HERE 3 CELLS ALLOT
+CONSTANT A-ADDR CONSTANT UA-ADDR
+T{ UA-ADDR ALIGNED -> A-ADDR }T
+T{ 1 A-ADDR C! A-ADDR C@ -> 1 }T
+T{ 1234 A-ADDR ! A-ADDR @ -> 1234 }T
+T{ 123 456 A-ADDR 2! A-ADDR 2@ -> 123 456 }T
+T{ 2 A-ADDR CHAR+ C! A-ADDR CHAR+ C@ -> 2 }T
+T{ 3 A-ADDR CELL+ C! A-ADDR CELL+ C@ -> 3 }T
+T{ 1234 A-ADDR CELL+ ! A-ADDR CELL+ @ -> 1234 }T
+T{ 123 456 A-ADDR CELL+ 2! A-ADDR CELL+ 2@ -> 123 456 }T
+
+: BITS ( X -- U )
+ 0 SWAP BEGIN DUP WHILE DUP MSB AND IF >R 1+ R> THEN 2* REPEAT DROP ;
+( CHARACTERS >= 1 AU, <= SIZE OF CELL, >= 8 BITS )
+T{ 1 CHARS 1 < -> <FALSE> }T
+T{ 1 CHARS 1 CELLS > -> <FALSE> }T
+( TBD: HOW TO FIND NUMBER OF BITS? )
+
+( CELLS >= 1 AU, INTEGRAL MULTIPLE OF CHAR SIZE, >= 16 BITS )
+T{ 1 CELLS 1 < -> <FALSE> }T
+T{ 1 CELLS 1 CHARS MOD -> 0 }T
+T{ 1S BITS 10 < -> <FALSE> }T
+
+T{ 0 1ST ! -> }T
+T{ 1 1ST +! -> }T
+T{ 1ST @ -> 1 }T
+T{ -1 1ST +! 1ST @ -> 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING CHAR [CHAR] [ ] BL S"
+
+T{ BL -> 20 }T
+T{ CHAR X -> 58 }T
+T{ CHAR HELLO -> 48 }T
+T{ : GC1 [CHAR] X ; -> }T
+T{ : GC2 [CHAR] HELLO ; -> }T
+T{ GC1 -> 58 }T
+T{ GC2 -> 48 }T
+T{ : GC3 [ GC1 ] LITERAL ; -> }T
+T{ GC3 -> 58 }T
+T{ : GC4 S" XY" ; -> }T
+T{ GC4 SWAP DROP -> 2 }T
+T{ GC4 DROP DUP C@ SWAP CHAR+ C@ -> 58 59 }T
+
+\ ------------------------------------------------------------------------
+TESTING ' ['] FIND EXECUTE IMMEDIATE COUNT LITERAL POSTPONE STATE
+
+T{ : GT1 123 ; -> }T
+T{ ' GT1 EXECUTE -> 123 }T
+T{ : GT2 ['] GT1 ; IMMEDIATE -> }T
+T{ GT2 EXECUTE -> 123 }T
+HERE 3 C, CHAR G C, CHAR T C, CHAR 1 C, CONSTANT GT1STRING
+HERE 3 C, CHAR G C, CHAR T C, CHAR 2 C, CONSTANT GT2STRING
+T{ GT1STRING FIND -> ' GT1 -1 }T
+T{ GT2STRING FIND -> ' GT2 1 }T
+( HOW TO SEARCH FOR NON-EXISTENT WORD? )
+T{ : GT3 GT2 LITERAL ; -> }T
+T{ GT3 -> ' GT1 }T
+T{ GT1STRING COUNT -> GT1STRING CHAR+ 3 }T
+
+T{ : GT4 POSTPONE GT1 ; IMMEDIATE -> }T
+T{ : GT5 GT4 ; -> }T
+T{ GT5 -> 123 }T
+T{ : GT6 345 ; IMMEDIATE -> }T
+T{ : GT7 POSTPONE GT6 ; -> }T
+T{ GT7 -> 345 }T
+
+T{ : GT8 STATE @ ; IMMEDIATE -> }T
+T{ GT8 -> 0 }T
+T{ : GT9 GT8 LITERAL ; -> }T
+T{ GT9 0= -> <FALSE> }T
+
+\ ------------------------------------------------------------------------
+TESTING IF ELSE THEN BEGIN WHILE REPEAT UNTIL RECURSE
+
+T{ : GI1 IF 123 THEN ; -> }T
+T{ : GI2 IF 123 ELSE 234 THEN ; -> }T
+T{ 0 GI1 -> }T
+T{ 1 GI1 -> 123 }T
+T{ -1 GI1 -> 123 }T
+T{ 0 GI2 -> 234 }T
+T{ 1 GI2 -> 123 }T
+T{ -1 GI1 -> 123 }T
+
+T{ : GI3 BEGIN DUP 5 < WHILE DUP 1+ REPEAT ; -> }T
+T{ 0 GI3 -> 0 1 2 3 4 5 }T
+T{ 4 GI3 -> 4 5 }T
+T{ 5 GI3 -> 5 }T
+T{ 6 GI3 -> 6 }T
+
+T{ : GI4 BEGIN DUP 1+ DUP 5 > UNTIL ; -> }T
+T{ 3 GI4 -> 3 4 5 6 }T
+T{ 5 GI4 -> 5 6 }T
+T{ 6 GI4 -> 6 7 }T
+
+T{ : GI5 BEGIN DUP 2 > WHILE DUP 5 < WHILE DUP 1+ REPEAT 123 ELSE 345 THEN ; -> }T
+T{ 1 GI5 -> 1 345 }T
+T{ 2 GI5 -> 2 345 }T
+T{ 3 GI5 -> 3 4 5 123 }T
+T{ 4 GI5 -> 4 5 123 }T
+T{ 5 GI5 -> 5 123 }T
+
+T{ : GI6 ( N -- 0,1,..N ) DUP IF DUP >R 1- RECURSE R> THEN ; -> }T
+T{ 0 GI6 -> 0 }T
+T{ 1 GI6 -> 0 1 }T
+T{ 2 GI6 -> 0 1 2 }T
+T{ 3 GI6 -> 0 1 2 3 }T
+T{ 4 GI6 -> 0 1 2 3 4 }T
+
+\ ------------------------------------------------------------------------
+TESTING DO LOOP +LOOP I J UNLOOP LEAVE EXIT
+
+T{ : GD1 DO I LOOP ; -> }T
+T{ 4 1 GD1 -> 1 2 3 }T
+T{ 2 -1 GD1 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD1 -> MID-UINT }T
+
+T{ : GD2 DO I -1 +LOOP ; -> }T
+T{ 1 4 GD2 -> 4 3 2 1 }T
+T{ -1 2 GD2 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD2 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD3 DO 1 0 DO J LOOP LOOP ; -> }T
+T{ 4 1 GD3 -> 1 2 3 }T
+T{ 2 -1 GD3 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD3 -> MID-UINT }T
+
+T{ : GD4 DO 1 0 DO J LOOP -1 +LOOP ; -> }T
+T{ 1 4 GD4 -> 4 3 2 1 }T
+T{ -1 2 GD4 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD4 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD5 123 SWAP 0 DO I 4 > IF DROP 234 LEAVE THEN LOOP ; -> }T
+T{ 1 GD5 -> 123 }T
+T{ 5 GD5 -> 123 }T
+T{ 6 GD5 -> 234 }T
+
+T{ : GD6 ( PAT: T{0 0}T,T{0 0}TT{1 0}TT{1 1}T,T{0 0}TT{1 0}TT{1 1}TT{2 0}TT{2 1}TT{2 2}T )
+ 0 SWAP 0 DO
+ I 1+ 0 DO I J + 3 = IF I UNLOOP I UNLOOP EXIT THEN 1+ LOOP
+ LOOP ; -> }T
+T{ 1 GD6 -> 1 }T
+T{ 2 GD6 -> 3 }T
+T{ 3 GD6 -> 4 1 2 }T
+
+\ ------------------------------------------------------------------------
+TESTING DEFINING WORDS: : ; CONSTANT VARIABLE CREATE DOES> >BODY
+
+T{ 123 CONSTANT X123 -> }T
+T{ X123 -> 123 }T
+T{ : EQU CONSTANT ; -> }T
+T{ X123 EQU Y123 -> }T
+T{ Y123 -> 123 }T
+
+T{ VARIABLE V1 -> }T
+T{ 123 V1 ! -> }T
+T{ V1 @ -> 123 }T
+
+T{ : NOP : POSTPONE ; ; -> }T
+T{ NOP NOP1 NOP NOP2 -> }T
+T{ NOP1 -> }T
+T{ NOP2 -> }T
+
+T{ : DOES1 DOES> @ 1 + ; -> }T
+T{ : DOES2 DOES> @ 2 + ; -> }T
+T{ CREATE CR1 -> }T
+T{ CR1 -> HERE }T
+T{ ' CR1 >BODY -> HERE }T
+T{ 1 , -> }T
+T{ CR1 @ -> 1 }T
+T{ DOES1 -> }T
+T{ CR1 -> 2 }T
+T{ DOES2 -> }T
+T{ CR1 -> 3 }T
+
+T{ : WEIRD: CREATE DOES> 1 + DOES> 2 + ; -> }T
+T{ WEIRD: W1 -> }T
+T{ ' W1 >BODY -> HERE }T
+T{ W1 -> HERE 1 + }T
+T{ W1 -> HERE 2 + }T
+
+\ ------------------------------------------------------------------------
+TESTING EVALUATE
+
+: GE1 S" 123" ; IMMEDIATE
+: GE2 S" 123 1+" ; IMMEDIATE
+: GE3 S" : GE4 345 ;" ;
+: GE5 EVALUATE ; IMMEDIATE
+
+T{ GE1 EVALUATE -> 123 }T ( TEST EVALUATE IN INTERP. STATE )
+T{ GE2 EVALUATE -> 124 }T
+T{ GE3 EVALUATE -> }T
+T{ GE4 -> 345 }T
+
+T{ : GE6 GE1 GE5 ; -> }T ( TEST EVALUATE IN COMPILE STATE )
+T{ GE6 -> 123 }T
+T{ : GE7 GE2 GE5 ; -> }T
+T{ GE7 -> 124 }T
+
+\ ------------------------------------------------------------------------
+TESTING SOURCE >IN WORD
+
+: GS1 S" SOURCE" 2DUP EVALUATE
+ >R SWAP >R = R> R> = ;
+T{ GS1 -> <TRUE> <TRUE> }T
+
+VARIABLE SCANS
+: RESCAN? -1 SCANS +! SCANS @ IF 0 >IN ! THEN ;
+
+T{ 2 SCANS !
+345 RESCAN?
+-> 345 345 }T
+
+: GS2 5 SCANS ! S" 123 RESCAN?" EVALUATE ;
+T{ GS2 -> 123 123 123 123 123 }T
+
+: GS3 WORD COUNT SWAP C@ ;
+T{ BL GS3 HELLO -> 5 CHAR H }T
+T{ CHAR " GS3 GOODBYE" -> 7 CHAR G }T
+T{ BL GS3
+DROP -> 0 }T \ BLANK LINE RETURN ZERO-LENGTH STRING
+
+: GS4 SOURCE >IN ! DROP ;
+T{ GS4 123 456
+-> }T
+
+\ ------------------------------------------------------------------------
+TESTING <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL
+
+: S= \ ( ADDR1 C1 ADDR2 C2 -- T/F ) COMPARE TWO STRINGS.
+ >R SWAP R@ = IF \ MAKE SURE STRINGS HAVE SAME LENGTH
+ R> ?DUP IF \ IF NON-EMPTY STRINGS
+ 0 DO
+ OVER C@ OVER C@ - IF
+ 2DROP <FALSE> UNLOOP EXIT THEN
+ SWAP CHAR+ SWAP CHAR+
+ LOOP
+ THEN
+ 2DROP <TRUE> \ IF WE GET HERE, STRINGS MATCH
+ ELSE
+ R> DROP 2DROP <FALSE> \ LENGTHS MISMATCH
+ THEN ;
+
+: GP1 <# 41 HOLD 42 HOLD 0 0 #> S" BA" S= ;
+T{ GP1 -> <TRUE> }T
+
+: GP2 <# -1 SIGN 0 SIGN -1 SIGN 0 0 #> S" --" S= ;
+T{ GP2 -> <TRUE> }T
+
+: GP3 <# 1 0 # # #> S" 01" S= ;
+T{ GP3 -> <TRUE> }T
+
+: GP4 <# 1 0 #S #> S" 1" S= ;
+T{ GP4 -> <TRUE> }T
+
+24 CONSTANT MAX-BASE \ BASE 2 .. 36
+: COUNT-BITS
+ 0 0 INVERT BEGIN DUP WHILE >R 1+ R> 2* REPEAT DROP ;
+COUNT-BITS 2* CONSTANT #BITS-UD \ NUMBER OF BITS IN UD
+
+: GP5
+ BASE @ <TRUE>
+ MAX-BASE 1+ 2 DO \ FOR EACH POSSIBLE BASE
+ I BASE ! \ TBD: ASSUMES BASE WORKS
+ I 0 <# #S #> S" 10" S= AND
+ LOOP
+ SWAP BASE ! ;
+T{ GP5 -> <TRUE> }T
+
+: GP6
+ BASE @ >R 2 BASE !
+ MAX-UINT MAX-UINT <# #S #> \ MAXIMUM UD TO BINARY
+ R> BASE ! \ S: C-ADDR U
+ DUP #BITS-UD = SWAP
+ 0 DO \ S: C-ADDR FLAG
+ OVER C@ [CHAR] 1 = AND \ ALL ONES
+ >R CHAR+ R>
+ LOOP SWAP DROP ;
+T{ GP6 -> <TRUE> }T
+
+: GP7
+ BASE @ >R MAX-BASE BASE !
+ <TRUE>
+ A 0 DO
+ I 0 <# #S #>
+ 1 = SWAP C@ I 30 + = AND AND
+ LOOP
+ MAX-BASE A DO
+ I 0 <# #S #>
+ 1 = SWAP C@ 41 I A - + = AND AND
+ LOOP
+ R> BASE ! ;
+
+T{ GP7 -> <TRUE> }T
+
+\ >NUMBER TESTS
+CREATE GN-BUF 0 C,
+: GN-STRING GN-BUF 1 ;
+: GN-CONSUMED GN-BUF CHAR+ 0 ;
+: GN' [CHAR] ' WORD CHAR+ C@ GN-BUF C! GN-STRING ;
+
+T{ 0 0 GN' 0' >NUMBER -> 0 0 GN-CONSUMED }T
+T{ 0 0 GN' 1' >NUMBER -> 1 0 GN-CONSUMED }T
+T{ 1 0 GN' 1' >NUMBER -> BASE @ 1+ 0 GN-CONSUMED }T
+T{ 0 0 GN' -' >NUMBER -> 0 0 GN-STRING }T \ SHOULD FAIL TO CONVERT THESE
+T{ 0 0 GN' +' >NUMBER -> 0 0 GN-STRING }T
+T{ 0 0 GN' .' >NUMBER -> 0 0 GN-STRING }T
+
+: >NUMBER-BASED
+ BASE @ >R BASE ! >NUMBER R> BASE ! ;
+
+T{ 0 0 GN' 2' 10 >NUMBER-BASED -> 2 0 GN-CONSUMED }T
+T{ 0 0 GN' 2' 2 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' F' 10 >NUMBER-BASED -> F 0 GN-CONSUMED }T
+T{ 0 0 GN' G' 10 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' G' MAX-BASE >NUMBER-BASED -> 10 0 GN-CONSUMED }T
+T{ 0 0 GN' Z' MAX-BASE >NUMBER-BASED -> 23 0 GN-CONSUMED }T
+
+: GN1 \ ( UD BASE -- UD' LEN ) UD SHOULD EQUAL UD' AND LEN SHOULD BE ZERO.
+ BASE @ >R BASE !
+ <# #S #>
+ 0 0 2SWAP >NUMBER SWAP DROP \ RETURN LENGTH ONLY
+ R> BASE ! ;
+T{ 0 0 2 GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 2 GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP 2 GN1 -> MAX-UINT DUP 0 }T
+T{ 0 0 MAX-BASE GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 MAX-BASE GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP MAX-BASE GN1 -> MAX-UINT DUP 0 }T
+
+: GN2 \ ( -- 16 10 )
+ BASE @ >R HEX BASE @ DECIMAL BASE @ R> BASE ! ;
+T{ GN2 -> 10 A }T
+
+\ ------------------------------------------------------------------------
+TESTING FILL MOVE
+
+CREATE FBUF 00 C, 00 C, 00 C,
+CREATE SBUF 12 C, 34 C, 56 C,
+: SEEBUF FBUF C@ FBUF CHAR+ C@ FBUF CHAR+ CHAR+ C@ ;
+
+T{ FBUF 0 20 FILL -> }T
+T{ SEEBUF -> 00 00 00 }T
+
+T{ FBUF 1 20 FILL -> }T
+T{ SEEBUF -> 20 00 00 }T
+
+T{ FBUF 3 20 FILL -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ FBUF FBUF 3 CHARS MOVE -> }T \ BIZARRE SPECIAL CASE
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 0 CHARS MOVE -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 1 CHARS MOVE -> }T
+T{ SEEBUF -> 12 20 20 }T
+
+T{ SBUF FBUF 3 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 56 }T
+
+T{ FBUF FBUF CHAR+ 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 12 34 }T
+
+T{ FBUF CHAR+ FBUF 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 34 }T
+
+\ ------------------------------------------------------------------------
+TESTING OUTPUT: . ." CR EMIT SPACE SPACES TYPE U.
+
+: OUTPUT-TEST
+ ." YOU SHOULD SEE THE STANDARD GRAPHIC CHARACTERS:" CR
+ 41 BL DO I EMIT LOOP CR
+ 61 41 DO I EMIT LOOP CR
+ 7F 61 DO I EMIT LOOP CR
+ ." YOU SHOULD SEE 0-9 SEPARATED BY A SPACE:" CR
+ 9 1+ 0 DO I . LOOP CR
+ ." YOU SHOULD SEE 0-9 (WITH NO SPACES):" CR
+ [CHAR] 9 1+ [CHAR] 0 DO I 0 SPACES EMIT LOOP CR
+ ." YOU SHOULD SEE A-G SEPARATED BY A SPACE:" CR
+ [CHAR] G 1+ [CHAR] A DO I EMIT SPACE LOOP CR
+ ." YOU SHOULD SEE 0-5 SEPARATED BY TWO SPACES:" CR
+ 5 1+ 0 DO I [CHAR] 0 + EMIT 2 SPACES LOOP CR
+ ." YOU SHOULD SEE TWO SEPARATE LINES:" CR
+ S" LINE 1" TYPE CR S" LINE 2" TYPE CR
+ ." YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:" CR
+ ." SIGNED: " MIN-INT . MAX-INT . CR
+ ." UNSIGNED: " 0 U. MAX-UINT U. CR
+;
+
+T{ OUTPUT-TEST -> }T
+\ ------------------------------------------------------------------------
+TESTING INPUT: ACCEPT
+
+CREATE ABUF 80 CHARS ALLOT
+
+: ACCEPT-TEST
+ CR ." PLEASE TYPE UP TO 80 CHARACTERS:" CR
+ ABUF 80 ACCEPT
+ CR ." RECEIVED: " [CHAR] " EMIT
+ ABUF SWAP TYPE [CHAR] " EMIT CR
+;
+
+T{ ACCEPT-TEST -> }T
+Vingt fois sur le métier remettez votre ouvrage, ...
+\ ------------------------------------------------------------------------
+TESTING DICTIONARY SEARCH RULES
+
+T{ : GDX 123 ; : GDX GDX 234 ; -> }T
+
+T{ GDX -> 123 234 }T
+
+CR .( End of Core word set tests) CR
+
+
+
+RST_STATE ; so ANS_COMPLEMENT_xx_MPY is conserved ;
+\ NOECHO ; if an error occurs, comment this line before new download to find it.
+
+
+\ From: John Hayes S1I
+\ Subject: tester.fr
+\ Date: Mon, 27 Nov 95 13:10:09 PST
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.1
+
+\ 22/1/09 The words { and } have been changed to T{ and }T respectively to
+\ agree with the Forth 200X file ttester.fs. This avoids clashes with
+\ locals using { ... } and the FSL use of }
+
+
+\ 13/05/14 jmt. added colorised error messages.
+
+
+
+ 0 CONSTANT FALSE
+-1 CONSTANT TRUE
+
+\ SET THE FOLLOWING FLAG TO TRUE FOR MORE VERBOSE OUTPUT; THIS MAY
+\ ALLOW YOU TO TELL WHICH TEST CAUSED YOUR SYSTEM TO HANG.
+VARIABLE VERBOSE
+ FALSE VERBOSE !
+\ TRUE VERBOSE !
+
+\ : EMPTY-STACK ( ... -- ) \ EMPTY STACK: HANDLES UNDERFLOWED STACK TOO.
+\ DEPTH ?DUP
+\ IF DUP 0< IF NEGATE 0
+\ DO 0 LOOP
+\ ELSE 0 DO DROP LOOP THEN
+\ THEN ;
+\
+\ : ERROR \ ( C-ADDR U -- ) DISPLAY AN ERROR MESSAGE FOLLOWED BY
+\ \ THE LINE THAT HAD THE ERROR.
+\ TYPE SOURCE TYPE CR \ DISPLAY LINE CORRESPONDING TO ERROR
+\ EMPTY-STACK \ THROW AWAY EVERY THING ELSE
+\ QUIT \ *** Uncomment this line to QUIT on an error
+\ ;
+
+VARIABLE ACTUAL-DEPTH \ STACK RECORD
+CREATE ACTUAL-RESULTS 20 CELLS ALLOT
+
+: T{ \ ( -- ) SYNTACTIC SUGAR.
+ ;
+
+: -> \ ( ... -- ) RECORD DEPTH AND CONTENT OF STACK.
+ DEPTH DUP ACTUAL-DEPTH ! \ RECORD DEPTH
+ ?DUP IF \ IF THERE IS SOMETHING ON STACK
+ 0 DO ACTUAL-RESULTS I CELLS + ! LOOP \ SAVE THEM
+ THEN ;
+
+: }T \ ( ... -- ) COMPARE STACK (EXPECTED) CONTENTS WITH SAVED
+ \ (ACTUAL) CONTENTS.
+ DEPTH ACTUAL-DEPTH @ = IF \ IF DEPTHS MATCH
+ DEPTH ?DUP IF \ IF THERE IS SOMETHING ON THE STACK
+ 0 DO \ FOR EACH STACK ITEM
+ ACTUAL-RESULTS I CELLS + @ \ COMPARE ACTUAL WITH EXPECTED
+\ = 0= IF S" INCORRECT RESULT: " ERROR LEAVE THEN \ jmt
+ = 0= IF ABORT" INCORRECT RESULT: " THEN \ jmt : colorised message
+ LOOP
+ THEN
+ ELSE \ DEPTH MISMATCH
+\ S" WRONG NUMBER OF RESULTS: " ERROR \ jmt
+ ABORT" WRONG NUMBER OF RESULTS: " \ jmt : colorised message
+ THEN ;
+
+: TESTING \ ( -- ) TALKING COMMENT.
+ SOURCE VERBOSE @
+ IF DUP >R TYPE CR R> >IN !
+ ELSE >IN ! DROP [CHAR] * EMIT
+ THEN ;
+
+\ From: John Hayes S1I
+\ Subject: core.fr
+\ Date: Mon, 27 Nov 95 13:10
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.2
+\ THIS PROGRAM TESTS THE CORE WORDS OF AN ANS FORTH SYSTEM.
+\ THE PROGRAM ASSUMES A TWO'S COMPLEMENT IMPLEMENTATION WHERE
+\ THE RANGE OF SIGNED NUMBERS IS -2^(N-1) ... 2^(N-1)-1 AND
+\ THE RANGE OF UNSIGNED NUMBERS IS 0 ... 2^(N)-1.
+\ I HAVEN'T FIGURED OUT HOW TO TEST KEY, QUIT, ABORT, OR ABORT"...
+\ I ALSO HAVEN'T THOUGHT OF A WAY TO TEST ENVIRONMENT?...
+
+CR
+TESTING CORE WORDS
+HEX
+
+\ ------------------------------------------------------------------------
+TESTING BASIC ASSUMPTIONS
+
+T{ -> }T \ START WITH CLEAN SLATE
+( TEST IF ANY BITS ARE SET; ANSWER IN BASE 1 )
+T{ : BITSSET? IF 0 0 ELSE 0 THEN ; -> }T
+T{ 0 BITSSET? -> 0 }T ( ZERO IS ALL BITS CLEAR )
+T{ 1 BITSSET? -> 0 0 }T ( OTHER NUMBER HAVE AT LEAST ONE BIT )
+T{ -1 BITSSET? -> 0 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING BOOLEANS: INVERT AND OR XOR
+
+T{ 0 0 AND -> 0 }T
+T{ 0 1 AND -> 0 }T
+T{ 1 0 AND -> 0 }T
+T{ 1 1 AND -> 1 }T
+
+T{ 0 INVERT 1 AND -> 1 }T
+T{ 1 INVERT 1 AND -> 0 }T
+
+0 CONSTANT 0S
+0 INVERT CONSTANT 1S
+
+T{ 0S INVERT -> 1S }T
+T{ 1S INVERT -> 0S }T
+
+T{ 0S 0S AND -> 0S }T
+T{ 0S 1S AND -> 0S }T
+T{ 1S 0S AND -> 0S }T
+T{ 1S 1S AND -> 1S }T
+
+T{ 0S 0S OR -> 0S }T
+T{ 0S 1S OR -> 1S }T
+T{ 1S 0S OR -> 1S }T
+T{ 1S 1S OR -> 1S }T
+
+T{ 0S 0S XOR -> 0S }T
+T{ 0S 1S XOR -> 1S }T
+T{ 1S 0S XOR -> 1S }T
+T{ 1S 1S XOR -> 0S }T
+
+\ ------------------------------------------------------------------------
+TESTING 2* 2/ LSHIFT RSHIFT
+
+( WE TRUST 1S, INVERT, AND BITSSET?; WE WILL CONFIRM RSHIFT LATER )
+1S 1 RSHIFT INVERT CONSTANT MSB
+T{ MSB BITSSET? -> 0 0 }T
+
+T{ 0S 2* -> 0S }T
+T{ 1 2* -> 2 }T
+T{ 4000 2* -> 8000 }T
+T{ 1S 2* 1 XOR -> 1S }T
+T{ MSB 2* -> 0S }T
+
+T{ 0S 2/ -> 0S }T
+T{ 1 2/ -> 0 }T
+T{ 4000 2/ -> 2000 }T
+T{ 1S 2/ -> 1S }T \ MSB PROPOGATED
+T{ 1S 1 XOR 2/ -> 1S }T
+T{ MSB 2/ MSB AND -> MSB }T
+
+T{ 1 0 LSHIFT -> 1 }T
+T{ 1 1 LSHIFT -> 2 }T
+T{ 1 2 LSHIFT -> 4 }T
+T{ 1 F LSHIFT -> 8000 }T \ BIGGEST GUARANTEED SHIFT
+T{ 1S 1 LSHIFT 1 XOR -> 1S }T
+T{ MSB 1 LSHIFT -> 0 }T
+
+T{ 1 0 RSHIFT -> 1 }T
+T{ 1 1 RSHIFT -> 0 }T
+T{ 2 1 RSHIFT -> 1 }T
+T{ 4 2 RSHIFT -> 1 }T
+T{ 8000 F RSHIFT -> 1 }T \ BIGGEST
+T{ MSB 1 RSHIFT MSB AND -> 0 }T \ RSHIFT ZERO FILLS MSBS
+T{ MSB 1 RSHIFT 2* -> MSB }T
+
+\ ------------------------------------------------------------------------
+TESTING COMPARISONS: 0= = 0< < > U< MIN MAX
+0 INVERT CONSTANT MAX-UINT
+0 INVERT 1 RSHIFT CONSTANT MAX-INT
+0 INVERT 1 RSHIFT INVERT CONSTANT MIN-INT
+0 INVERT 1 RSHIFT CONSTANT MID-UINT
+0 INVERT 1 RSHIFT INVERT CONSTANT MID-UINT+1
+
+0S CONSTANT <FALSE>
+1S CONSTANT <TRUE>
+
+T{ 0 0= -> <TRUE> }T
+T{ 1 0= -> <FALSE> }T
+T{ 2 0= -> <FALSE> }T
+T{ -1 0= -> <FALSE> }T
+T{ MAX-UINT 0= -> <FALSE> }T
+T{ MIN-INT 0= -> <FALSE> }T
+T{ MAX-INT 0= -> <FALSE> }T
+
+T{ 0 0 = -> <TRUE> }T
+T{ 1 1 = -> <TRUE> }T
+T{ -1 -1 = -> <TRUE> }T
+T{ 1 0 = -> <FALSE> }T
+T{ -1 0 = -> <FALSE> }T
+T{ 0 1 = -> <FALSE> }T
+T{ 0 -1 = -> <FALSE> }T
+
+T{ 0 0< -> <FALSE> }T
+T{ -1 0< -> <TRUE> }T
+T{ MIN-INT 0< -> <TRUE> }T
+T{ 1 0< -> <FALSE> }T
+T{ MAX-INT 0< -> <FALSE> }T
+
+T{ 0 1 < -> <TRUE> }T
+T{ 1 2 < -> <TRUE> }T
+T{ -1 0 < -> <TRUE> }T
+T{ -1 1 < -> <TRUE> }T
+T{ MIN-INT 0 < -> <TRUE> }T
+T{ MIN-INT MAX-INT < -> <TRUE> }T
+T{ 0 MAX-INT < -> <TRUE> }T
+T{ 0 0 < -> <FALSE> }T
+T{ 1 1 < -> <FALSE> }T
+T{ 1 0 < -> <FALSE> }T
+T{ 2 1 < -> <FALSE> }T
+T{ 0 -1 < -> <FALSE> }T
+T{ 1 -1 < -> <FALSE> }T
+T{ 0 MIN-INT < -> <FALSE> }T
+T{ MAX-INT MIN-INT < -> <FALSE> }T
+T{ MAX-INT 0 < -> <FALSE> }T
+
+T{ 0 1 > -> <FALSE> }T
+T{ 1 2 > -> <FALSE> }T
+T{ -1 0 > -> <FALSE> }T
+T{ -1 1 > -> <FALSE> }T
+T{ MIN-INT 0 > -> <FALSE> }T
+T{ MIN-INT MAX-INT > -> <FALSE> }T
+T{ 0 MAX-INT > -> <FALSE> }T
+T{ 0 0 > -> <FALSE> }T
+T{ 1 1 > -> <FALSE> }T
+T{ 1 0 > -> <TRUE> }T
+T{ 2 1 > -> <TRUE> }T
+T{ 0 -1 > -> <TRUE> }T
+T{ 1 -1 > -> <TRUE> }T
+T{ 0 MIN-INT > -> <TRUE> }T
+T{ MAX-INT MIN-INT > -> <TRUE> }T
+T{ MAX-INT 0 > -> <TRUE> }T
+
+T{ 0 1 U< -> <TRUE> }T
+T{ 1 2 U< -> <TRUE> }T
+T{ 0 MID-UINT U< -> <TRUE> }T
+T{ 0 MAX-UINT U< -> <TRUE> }T
+T{ MID-UINT MAX-UINT U< -> <TRUE> }T
+T{ 0 0 U< -> <FALSE> }T
+T{ 1 1 U< -> <FALSE> }T
+T{ 1 0 U< -> <FALSE> }T
+T{ 2 1 U< -> <FALSE> }T
+T{ MID-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT MID-UINT U< -> <FALSE> }T
+
+T{ 0 1 MIN -> 0 }T
+T{ 1 2 MIN -> 1 }T
+T{ -1 0 MIN -> -1 }T
+T{ -1 1 MIN -> -1 }T
+T{ MIN-INT 0 MIN -> MIN-INT }T
+T{ MIN-INT MAX-INT MIN -> MIN-INT }T
+T{ 0 MAX-INT MIN -> 0 }T
+T{ 0 0 MIN -> 0 }T
+T{ 1 1 MIN -> 1 }T
+T{ 1 0 MIN -> 0 }T
+T{ 2 1 MIN -> 1 }T
+T{ 0 -1 MIN -> -1 }T
+T{ 1 -1 MIN -> -1 }T
+T{ 0 MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT 0 MIN -> 0 }T
+
+T{ 0 1 MAX -> 1 }T
+T{ 1 2 MAX -> 2 }T
+T{ -1 0 MAX -> 0 }T
+T{ -1 1 MAX -> 1 }T
+T{ MIN-INT 0 MAX -> 0 }T
+T{ MIN-INT MAX-INT MAX -> MAX-INT }T
+T{ 0 MAX-INT MAX -> MAX-INT }T
+T{ 0 0 MAX -> 0 }T
+T{ 1 1 MAX -> 1 }T
+T{ 1 0 MAX -> 1 }T
+T{ 2 1 MAX -> 2 }T
+T{ 0 -1 MAX -> 0 }T
+T{ 1 -1 MAX -> 1 }T
+T{ 0 MIN-INT MAX -> 0 }T
+T{ MAX-INT MIN-INT MAX -> MAX-INT }T
+T{ MAX-INT 0 MAX -> MAX-INT }T
+
+\ ------------------------------------------------------------------------
+TESTING STACK OPS: 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP
+
+T{ 1 2 2DROP -> }T
+T{ 1 2 2DUP -> 1 2 1 2 }T
+T{ 1 2 3 4 2OVER -> 1 2 3 4 1 2 }T
+T{ 1 2 3 4 2SWAP -> 3 4 1 2 }T
+T{ 0 ?DUP -> 0 }T
+T{ 1 ?DUP -> 1 1 }T
+T{ -1 ?DUP -> -1 -1 }T
+T{ DEPTH -> 0 }T
+T{ 0 DEPTH -> 0 1 }T
+T{ 0 1 DEPTH -> 0 1 2 }T
+T{ 0 DROP -> }T
+T{ 1 2 DROP -> 1 }T
+T{ 1 DUP -> 1 1 }T
+T{ 1 2 OVER -> 1 2 1 }T
+T{ 1 2 3 ROT -> 2 3 1 }T
+T{ 1 2 SWAP -> 2 1 }T
+
+\ ------------------------------------------------------------------------
+TESTING >R R> R@
+
+T{ : GR1 >R R> ; -> }T
+T{ : GR2 >R R@ R> DROP ; -> }T
+T{ 123 GR1 -> 123 }T
+T{ 123 GR2 -> 123 }T
+T{ 1S GR1 -> 1S }T ( RETURN STACK HOLDS CELLS )
+
+\ ------------------------------------------------------------------------
+TESTING ADD/SUBTRACT: + - 1+ 1- ABS NEGATE
+
+T{ 0 5 + -> 5 }T
+T{ 5 0 + -> 5 }T
+T{ 0 -5 + -> -5 }T
+T{ -5 0 + -> -5 }T
+T{ 1 2 + -> 3 }T
+T{ 1 -2 + -> -1 }T
+T{ -1 2 + -> 1 }T
+T{ -1 -2 + -> -3 }T
+T{ -1 1 + -> 0 }T
+T{ MID-UINT 1 + -> MID-UINT+1 }T
+
+T{ 0 5 - -> -5 }T
+T{ 5 0 - -> 5 }T
+T{ 0 -5 - -> 5 }T
+T{ -5 0 - -> -5 }T
+T{ 1 2 - -> -1 }T
+T{ 1 -2 - -> 3 }T
+T{ -1 2 - -> -3 }T
+T{ -1 -2 - -> 1 }T
+T{ 0 1 - -> -1 }T
+T{ MID-UINT+1 1 - -> MID-UINT }T
+
+T{ 0 1+ -> 1 }T
+T{ -1 1+ -> 0 }T
+T{ 1 1+ -> 2 }T
+T{ MID-UINT 1+ -> MID-UINT+1 }T
+
+T{ 2 1- -> 1 }T
+T{ 1 1- -> 0 }T
+T{ 0 1- -> -1 }T
+T{ MID-UINT+1 1- -> MID-UINT }T
+
+T{ 0 NEGATE -> 0 }T
+T{ 1 NEGATE -> -1 }T
+T{ -1 NEGATE -> 1 }T
+T{ 2 NEGATE -> -2 }T
+T{ -2 NEGATE -> 2 }T
+
+T{ 0 ABS -> 0 }T
+T{ 1 ABS -> 1 }T
+T{ -1 ABS -> 1 }T
+T{ MIN-INT ABS -> MID-UINT+1 }T
+
+\ ------------------------------------------------------------------------
+TESTING MULTIPLY: S>D * M* UM*
+
+T{ 0 S>D -> 0 0 }T
+T{ 1 S>D -> 1 0 }T
+T{ 2 S>D -> 2 0 }T
+T{ -1 S>D -> -1 -1 }T
+T{ -2 S>D -> -2 -1 }T
+T{ MIN-INT S>D -> MIN-INT -1 }T
+T{ MAX-INT S>D -> MAX-INT 0 }T
+
+T{ 0 0 M* -> 0 S>D }T
+T{ 0 1 M* -> 0 S>D }T
+T{ 1 0 M* -> 0 S>D }T
+T{ 1 2 M* -> 2 S>D }T
+T{ 2 1 M* -> 2 S>D }T
+T{ 3 3 M* -> 9 S>D }T
+T{ -3 3 M* -> -9 S>D }T
+T{ 3 -3 M* -> -9 S>D }T
+T{ -3 -3 M* -> 9 S>D }T
+T{ 0 MIN-INT M* -> 0 S>D }T
+T{ 1 MIN-INT M* -> MIN-INT S>D }T
+T{ 2 MIN-INT M* -> 0 1S }T
+T{ 0 MAX-INT M* -> 0 S>D }T
+T{ 1 MAX-INT M* -> MAX-INT S>D }T
+T{ 2 MAX-INT M* -> MAX-INT 1 LSHIFT 0 }T
+T{ MIN-INT MIN-INT M* -> 0 MSB 1 RSHIFT }T
+T{ MAX-INT MIN-INT M* -> MSB MSB 2/ }T
+T{ MAX-INT MAX-INT M* -> 1 MSB 2/ INVERT }T
+
+T{ 0 0 * -> 0 }T \ TEST IDENTITIES
+T{ 0 1 * -> 0 }T
+T{ 1 0 * -> 0 }T
+T{ 1 2 * -> 2 }T
+T{ 2 1 * -> 2 }T
+T{ 3 3 * -> 9 }T
+T{ -3 3 * -> -9 }T
+T{ 3 -3 * -> -9 }T
+T{ -3 -3 * -> 9 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 * -> MID-UINT+1 }T
+T{ MID-UINT+1 2 RSHIFT 4 * -> MID-UINT+1 }T
+T{ MID-UINT+1 1 RSHIFT MID-UINT+1 OR 2 * -> MID-UINT+1 }T
+
+T{ 0 0 UM* -> 0 0 }T
+T{ 0 1 UM* -> 0 0 }T
+T{ 1 0 UM* -> 0 0 }T
+T{ 1 2 UM* -> 2 0 }T
+T{ 2 1 UM* -> 2 0 }T
+T{ 3 3 UM* -> 9 0 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 UM* -> MID-UINT+1 0 }T
+T{ MID-UINT+1 2 UM* -> 0 1 }T
+T{ MID-UINT+1 4 UM* -> 0 2 }T
+T{ 1S 2 UM* -> 1S 1 LSHIFT 1 }T
+T{ MAX-UINT MAX-UINT UM* -> 1 1 INVERT }T
+
+\ ------------------------------------------------------------------------
+TESTING DIVIDE: FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD
+
+T{ 0 S>D 1 FM/MOD -> 0 0 }T
+T{ 1 S>D 1 FM/MOD -> 0 1 }T
+T{ 2 S>D 1 FM/MOD -> 0 2 }T
+T{ -1 S>D 1 FM/MOD -> 0 -1 }T
+T{ -2 S>D 1 FM/MOD -> 0 -2 }T
+T{ 0 S>D -1 FM/MOD -> 0 0 }T
+T{ 1 S>D -1 FM/MOD -> 0 -1 }T
+T{ 2 S>D -1 FM/MOD -> 0 -2 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -1 FM/MOD -> 0 2 }T
+T{ 2 S>D 2 FM/MOD -> 0 1 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -2 FM/MOD -> 0 1 }T
+T{ 7 S>D 3 FM/MOD -> 1 2 }T
+T{ 7 S>D -3 FM/MOD -> -2 -3 }T
+T{ -7 S>D 3 FM/MOD -> 2 -3 }T
+T{ -7 S>D -3 FM/MOD -> -1 2 }T
+T{ MAX-INT S>D 1 FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT FM/MOD -> 0 1 }T
+T{ MIN-INT S>D MIN-INT FM/MOD -> 0 1 }T
+T{ 1S 1 4 FM/MOD -> 3 MAX-INT }T
+T{ 1 MIN-INT M* 1 FM/MOD -> 0 MIN-INT }T
+T{ 1 MIN-INT M* MIN-INT FM/MOD -> 0 1 }T
+T{ 2 MIN-INT M* 2 FM/MOD -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT FM/MOD -> 0 2 }T
+T{ 1 MAX-INT M* 1 FM/MOD -> 0 MAX-INT }T
+T{ 1 MAX-INT M* MAX-INT FM/MOD -> 0 1 }T
+T{ 2 MAX-INT M* 2 FM/MOD -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT FM/MOD -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT FM/MOD -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT FM/MOD -> 0 MAX-INT }T
+
+T{ 0 S>D 1 SM/REM -> 0 0 }T
+T{ 1 S>D 1 SM/REM -> 0 1 }T
+T{ 2 S>D 1 SM/REM -> 0 2 }T
+T{ -1 S>D 1 SM/REM -> 0 -1 }T
+T{ -2 S>D 1 SM/REM -> 0 -2 }T
+T{ 0 S>D -1 SM/REM -> 0 0 }T
+T{ 1 S>D -1 SM/REM -> 0 -1 }T
+T{ 2 S>D -1 SM/REM -> 0 -2 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -1 SM/REM -> 0 2 }T
+T{ 2 S>D 2 SM/REM -> 0 1 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -2 SM/REM -> 0 1 }T
+T{ 7 S>D 3 SM/REM -> 1 2 }T
+T{ 7 S>D -3 SM/REM -> 1 -2 }T
+T{ -7 S>D 3 SM/REM -> -1 -2 }T
+T{ -7 S>D -3 SM/REM -> -1 2 }T
+T{ MAX-INT S>D 1 SM/REM -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 SM/REM -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT SM/REM -> 0 1 }T
+T{ MIN-INT S>D MIN-INT SM/REM -> 0 1 }T
+T{ 1S 1 4 SM/REM -> 3 MAX-INT }T
+T{ 2 MIN-INT M* 2 SM/REM -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT SM/REM -> 0 2 }T
+T{ 2 MAX-INT M* 2 SM/REM -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT SM/REM -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT SM/REM -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT SM/REM -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT SM/REM -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT SM/REM -> 0 MAX-INT }T
+
+T{ 0 0 1 UM/MOD -> 0 0 }T
+T{ 1 0 1 UM/MOD -> 0 1 }T
+T{ 1 0 2 UM/MOD -> 1 0 }T
+T{ 3 0 2 UM/MOD -> 1 1 }T
+T{ MAX-UINT 2 UM* 2 UM/MOD -> 0 MAX-UINT }T
+T{ MAX-UINT 2 UM* MAX-UINT UM/MOD -> 0 2 }T
+T{ MAX-UINT MAX-UINT UM* MAX-UINT UM/MOD -> 0 MAX-UINT }T
+
+: IFFLOORED
+ [ -3 2 / -2 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+: IFSYM
+ [ -3 2 / -1 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+\ THE SYSTEM MIGHT DO EITHER FLOORED OR SYMMETRIC DIVISION.
+\ SINCE WE HAVE ALREADY TESTED M*, FM/MOD, AND SM/REM WE CAN USE THEM IN TEST.
+
+IFFLOORED : T/MOD >R S>D R> FM/MOD ;
+IFFLOORED : T/ T/MOD SWAP DROP ;
+IFFLOORED : TMOD T/MOD DROP ;
+IFFLOORED : T*/MOD >R M* R> FM/MOD ;
+IFFLOORED : T*/ T*/MOD SWAP DROP ;
+IFSYM : T/MOD >R S>D R> SM/REM ;
+IFSYM : T/ T/MOD SWAP DROP ;
+IFSYM : TMOD T/MOD DROP ;
+IFSYM : T*/MOD >R M* R> SM/REM ;
+IFSYM : T*/ T*/MOD SWAP DROP ;
+
+T{ 0 1 /MOD -> 0 1 T/MOD }T
+T{ 1 1 /MOD -> 1 1 T/MOD }T
+T{ 2 1 /MOD -> 2 1 T/MOD }T
+T{ -1 1 /MOD -> -1 1 T/MOD }T
+T{ -2 1 /MOD -> -2 1 T/MOD }T
+T{ 0 -1 /MOD -> 0 -1 T/MOD }T
+T{ 1 -1 /MOD -> 1 -1 T/MOD }T
+T{ 2 -1 /MOD -> 2 -1 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -1 /MOD -> -2 -1 T/MOD }T
+T{ 2 2 /MOD -> 2 2 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -2 /MOD -> -2 -2 T/MOD }T
+T{ 7 3 /MOD -> 7 3 T/MOD }T
+T{ 7 -3 /MOD -> 7 -3 T/MOD }T
+T{ -7 3 /MOD -> -7 3 T/MOD }T
+T{ -7 -3 /MOD -> -7 -3 T/MOD }T
+T{ MAX-INT 1 /MOD -> MAX-INT 1 T/MOD }T
+T{ MIN-INT 1 /MOD -> MIN-INT 1 T/MOD }T
+T{ MAX-INT MAX-INT /MOD -> MAX-INT MAX-INT T/MOD }T
+T{ MIN-INT MIN-INT /MOD -> MIN-INT MIN-INT T/MOD }T
+
+T{ 0 1 / -> 0 1 T/ }T
+T{ 1 1 / -> 1 1 T/ }T
+T{ 2 1 / -> 2 1 T/ }T
+T{ -1 1 / -> -1 1 T/ }T
+T{ -2 1 / -> -2 1 T/ }T
+T{ 0 -1 / -> 0 -1 T/ }T
+T{ 1 -1 / -> 1 -1 T/ }T
+T{ 2 -1 / -> 2 -1 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -1 / -> -2 -1 T/ }T
+T{ 2 2 / -> 2 2 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -2 / -> -2 -2 T/ }T
+T{ 7 3 / -> 7 3 T/ }T
+T{ 7 -3 / -> 7 -3 T/ }T
+T{ -7 3 / -> -7 3 T/ }T
+T{ -7 -3 / -> -7 -3 T/ }T
+T{ MAX-INT 1 / -> MAX-INT 1 T/ }T
+T{ MIN-INT 1 / -> MIN-INT 1 T/ }T
+T{ MAX-INT MAX-INT / -> MAX-INT MAX-INT T/ }T
+T{ MIN-INT MIN-INT / -> MIN-INT MIN-INT T/ }T
+
+T{ 0 1 MOD -> 0 1 TMOD }T
+T{ 1 1 MOD -> 1 1 TMOD }T
+T{ 2 1 MOD -> 2 1 TMOD }T
+T{ -1 1 MOD -> -1 1 TMOD }T
+T{ -2 1 MOD -> -2 1 TMOD }T
+T{ 0 -1 MOD -> 0 -1 TMOD }T
+T{ 1 -1 MOD -> 1 -1 TMOD }T
+T{ 2 -1 MOD -> 2 -1 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -1 MOD -> -2 -1 TMOD }T
+T{ 2 2 MOD -> 2 2 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -2 MOD -> -2 -2 TMOD }T
+T{ 7 3 MOD -> 7 3 TMOD }T
+T{ 7 -3 MOD -> 7 -3 TMOD }T
+T{ -7 3 MOD -> -7 3 TMOD }T
+T{ -7 -3 MOD -> -7 -3 TMOD }T
+T{ MAX-INT 1 MOD -> MAX-INT 1 TMOD }T
+T{ MIN-INT 1 MOD -> MIN-INT 1 TMOD }T
+T{ MAX-INT MAX-INT MOD -> MAX-INT MAX-INT TMOD }T
+T{ MIN-INT MIN-INT MOD -> MIN-INT MIN-INT TMOD }T
+
+T{ 0 2 1 */ -> 0 2 1 T*/ }T
+T{ 1 2 1 */ -> 1 2 1 T*/ }T
+T{ 2 2 1 */ -> 2 2 1 T*/ }T
+T{ -1 2 1 */ -> -1 2 1 T*/ }T
+T{ -2 2 1 */ -> -2 2 1 T*/ }T
+T{ 0 2 -1 */ -> 0 2 -1 T*/ }T
+T{ 1 2 -1 */ -> 1 2 -1 T*/ }T
+T{ 2 2 -1 */ -> 2 2 -1 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -1 */ -> -2 2 -1 T*/ }T
+T{ 2 2 2 */ -> 2 2 2 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -2 */ -> -2 2 -2 T*/ }T
+T{ 7 2 3 */ -> 7 2 3 T*/ }T
+T{ 7 2 -3 */ -> 7 2 -3 T*/ }T
+T{ -7 2 3 */ -> -7 2 3 T*/ }T
+T{ -7 2 -3 */ -> -7 2 -3 T*/ }T
+T{ MAX-INT 2 MAX-INT */ -> MAX-INT 2 MAX-INT T*/ }T
+T{ MIN-INT 2 MIN-INT */ -> MIN-INT 2 MIN-INT T*/ }T
+
+T{ 0 2 1 */MOD -> 0 2 1 T*/MOD }T
+T{ 1 2 1 */MOD -> 1 2 1 T*/MOD }T
+T{ 2 2 1 */MOD -> 2 2 1 T*/MOD }T
+T{ -1 2 1 */MOD -> -1 2 1 T*/MOD }T
+T{ -2 2 1 */MOD -> -2 2 1 T*/MOD }T
+T{ 0 2 -1 */MOD -> 0 2 -1 T*/MOD }T
+T{ 1 2 -1 */MOD -> 1 2 -1 T*/MOD }T
+T{ 2 2 -1 */MOD -> 2 2 -1 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -1 */MOD -> -2 2 -1 T*/MOD }T
+T{ 2 2 2 */MOD -> 2 2 2 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -2 */MOD -> -2 2 -2 T*/MOD }T
+T{ 7 2 3 */MOD -> 7 2 3 T*/MOD }T
+T{ 7 2 -3 */MOD -> 7 2 -3 T*/MOD }T
+T{ -7 2 3 */MOD -> -7 2 3 T*/MOD }T
+T{ -7 2 -3 */MOD -> -7 2 -3 T*/MOD }T
+T{ MAX-INT 2 MAX-INT */MOD -> MAX-INT 2 MAX-INT T*/MOD }T
+T{ MIN-INT 2 MIN-INT */MOD -> MIN-INT 2 MIN-INT T*/MOD }T
+
+\ ------------------------------------------------------------------------
+TESTING HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2! ALIGN ALIGNED +! ALLOT
+
+HERE 1 ALLOT
+HERE
+CONSTANT 2NDA
+CONSTANT 1STA
+T{ 1STA 2NDA U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STA 1+ -> 2NDA }T \ ... BY ONE ADDRESS UNIT
+( MISSING TEST: NEGATIVE ALLOT )
+
+HERE 1 ,
+HERE 2 ,
+CONSTANT 2ND
+CONSTANT 1ST
+T{ 1ST 2ND U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1ST CELL+ -> 2ND }T \ ... BY ONE CELL
+T{ 1ST 1 CELLS + -> 2ND }T
+T{ 1ST @ 2ND @ -> 1 2 }T
+T{ 5 1ST ! -> }T
+T{ 1ST @ 2ND @ -> 5 2 }T
+T{ 6 2ND ! -> }T
+T{ 1ST @ 2ND @ -> 5 6 }T
+T{ 1ST 2@ -> 6 5 }T
+T{ 2 1 1ST 2! -> }T
+T{ 1ST 2@ -> 2 1 }T
+T{ 1S 1ST ! 1ST @ -> 1S }T \ CAN STORE CELL-WIDE VALUE
+
+HERE 1 C,
+HERE 2 C,
+CONSTANT 2NDC
+CONSTANT 1STC
+T{ 1STC 2NDC U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STC CHAR+ -> 2NDC }T \ ... BY ONE CHAR
+T{ 1STC 1 CHARS + -> 2NDC }T
+T{ 1STC C@ 2NDC C@ -> 1 2 }T
+T{ 3 1STC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 2 }T
+T{ 4 2NDC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 4 }T
+
+ALIGN 1 ALLOT HERE ALIGN HERE 3 CELLS ALLOT
+CONSTANT A-ADDR CONSTANT UA-ADDR
+T{ UA-ADDR ALIGNED -> A-ADDR }T
+T{ 1 A-ADDR C! A-ADDR C@ -> 1 }T
+T{ 1234 A-ADDR ! A-ADDR @ -> 1234 }T
+T{ 123 456 A-ADDR 2! A-ADDR 2@ -> 123 456 }T
+T{ 2 A-ADDR CHAR+ C! A-ADDR CHAR+ C@ -> 2 }T
+T{ 3 A-ADDR CELL+ C! A-ADDR CELL+ C@ -> 3 }T
+T{ 1234 A-ADDR CELL+ ! A-ADDR CELL+ @ -> 1234 }T
+T{ 123 456 A-ADDR CELL+ 2! A-ADDR CELL+ 2@ -> 123 456 }T
+
+: BITS ( X -- U )
+ 0 SWAP BEGIN DUP WHILE DUP MSB AND IF >R 1+ R> THEN 2* REPEAT DROP ;
+( CHARACTERS >= 1 AU, <= SIZE OF CELL, >= 8 BITS )
+T{ 1 CHARS 1 < -> <FALSE> }T
+T{ 1 CHARS 1 CELLS > -> <FALSE> }T
+( TBD: HOW TO FIND NUMBER OF BITS? )
+
+( CELLS >= 1 AU, INTEGRAL MULTIPLE OF CHAR SIZE, >= 16 BITS )
+T{ 1 CELLS 1 < -> <FALSE> }T
+T{ 1 CELLS 1 CHARS MOD -> 0 }T
+T{ 1S BITS 10 < -> <FALSE> }T
+
+T{ 0 1ST ! -> }T
+T{ 1 1ST +! -> }T
+T{ 1ST @ -> 1 }T
+T{ -1 1ST +! 1ST @ -> 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING CHAR [CHAR] [ ] BL S"
+
+T{ BL -> 20 }T
+T{ CHAR X -> 58 }T
+T{ CHAR HELLO -> 48 }T
+T{ : GC1 [CHAR] X ; -> }T
+T{ : GC2 [CHAR] HELLO ; -> }T
+T{ GC1 -> 58 }T
+T{ GC2 -> 48 }T
+T{ : GC3 [ GC1 ] LITERAL ; -> }T
+T{ GC3 -> 58 }T
+T{ : GC4 S" XY" ; -> }T
+T{ GC4 SWAP DROP -> 2 }T
+T{ GC4 DROP DUP C@ SWAP CHAR+ C@ -> 58 59 }T
+
+\ ------------------------------------------------------------------------
+TESTING ' ['] FIND EXECUTE IMMEDIATE COUNT LITERAL POSTPONE STATE
+
+T{ : GT1 123 ; -> }T
+T{ ' GT1 EXECUTE -> 123 }T
+T{ : GT2 ['] GT1 ; IMMEDIATE -> }T
+T{ GT2 EXECUTE -> 123 }T
+HERE 3 C, CHAR G C, CHAR T C, CHAR 1 C, CONSTANT GT1STRING
+HERE 3 C, CHAR G C, CHAR T C, CHAR 2 C, CONSTANT GT2STRING
+T{ GT1STRING FIND -> ' GT1 -1 }T
+T{ GT2STRING FIND -> ' GT2 1 }T
+( HOW TO SEARCH FOR NON-EXISTENT WORD? )
+T{ : GT3 GT2 LITERAL ; -> }T
+T{ GT3 -> ' GT1 }T
+T{ GT1STRING COUNT -> GT1STRING CHAR+ 3 }T
+
+T{ : GT4 POSTPONE GT1 ; IMMEDIATE -> }T
+T{ : GT5 GT4 ; -> }T
+T{ GT5 -> 123 }T
+T{ : GT6 345 ; IMMEDIATE -> }T
+T{ : GT7 POSTPONE GT6 ; -> }T
+T{ GT7 -> 345 }T
+
+T{ : GT8 STATE @ ; IMMEDIATE -> }T
+T{ GT8 -> 0 }T
+T{ : GT9 GT8 LITERAL ; -> }T
+T{ GT9 0= -> <FALSE> }T
+
+\ ------------------------------------------------------------------------
+TESTING IF ELSE THEN BEGIN WHILE REPEAT UNTIL RECURSE
+
+T{ : GI1 IF 123 THEN ; -> }T
+T{ : GI2 IF 123 ELSE 234 THEN ; -> }T
+T{ 0 GI1 -> }T
+T{ 1 GI1 -> 123 }T
+T{ -1 GI1 -> 123 }T
+T{ 0 GI2 -> 234 }T
+T{ 1 GI2 -> 123 }T
+T{ -1 GI1 -> 123 }T
+
+T{ : GI3 BEGIN DUP 5 < WHILE DUP 1+ REPEAT ; -> }T
+T{ 0 GI3 -> 0 1 2 3 4 5 }T
+T{ 4 GI3 -> 4 5 }T
+T{ 5 GI3 -> 5 }T
+T{ 6 GI3 -> 6 }T
+
+T{ : GI4 BEGIN DUP 1+ DUP 5 > UNTIL ; -> }T
+T{ 3 GI4 -> 3 4 5 6 }T
+T{ 5 GI4 -> 5 6 }T
+T{ 6 GI4 -> 6 7 }T
+
+T{ : GI5 BEGIN DUP 2 > WHILE DUP 5 < WHILE DUP 1+ REPEAT 123 ELSE 345 THEN ; -> }T
+T{ 1 GI5 -> 1 345 }T
+T{ 2 GI5 -> 2 345 }T
+T{ 3 GI5 -> 3 4 5 123 }T
+T{ 4 GI5 -> 4 5 123 }T
+T{ 5 GI5 -> 5 123 }T
+
+T{ : GI6 ( N -- 0,1,..N ) DUP IF DUP >R 1- RECURSE R> THEN ; -> }T
+T{ 0 GI6 -> 0 }T
+T{ 1 GI6 -> 0 1 }T
+T{ 2 GI6 -> 0 1 2 }T
+T{ 3 GI6 -> 0 1 2 3 }T
+T{ 4 GI6 -> 0 1 2 3 4 }T
+
+\ ------------------------------------------------------------------------
+TESTING DO LOOP +LOOP I J UNLOOP LEAVE EXIT
+
+T{ : GD1 DO I LOOP ; -> }T
+T{ 4 1 GD1 -> 1 2 3 }T
+T{ 2 -1 GD1 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD1 -> MID-UINT }T
+
+T{ : GD2 DO I -1 +LOOP ; -> }T
+T{ 1 4 GD2 -> 4 3 2 1 }T
+T{ -1 2 GD2 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD2 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD3 DO 1 0 DO J LOOP LOOP ; -> }T
+T{ 4 1 GD3 -> 1 2 3 }T
+T{ 2 -1 GD3 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD3 -> MID-UINT }T
+
+T{ : GD4 DO 1 0 DO J LOOP -1 +LOOP ; -> }T
+T{ 1 4 GD4 -> 4 3 2 1 }T
+T{ -1 2 GD4 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD4 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD5 123 SWAP 0 DO I 4 > IF DROP 234 LEAVE THEN LOOP ; -> }T
+T{ 1 GD5 -> 123 }T
+T{ 5 GD5 -> 123 }T
+T{ 6 GD5 -> 234 }T
+
+T{ : GD6 ( PAT: T{0 0}T,T{0 0}TT{1 0}TT{1 1}T,T{0 0}TT{1 0}TT{1 1}TT{2 0}TT{2 1}TT{2 2}T )
+ 0 SWAP 0 DO
+ I 1+ 0 DO I J + 3 = IF I UNLOOP I UNLOOP EXIT THEN 1+ LOOP
+ LOOP ; -> }T
+T{ 1 GD6 -> 1 }T
+T{ 2 GD6 -> 3 }T
+T{ 3 GD6 -> 4 1 2 }T
+
+\ ------------------------------------------------------------------------
+TESTING DEFINING WORDS: : ; CONSTANT VARIABLE CREATE DOES> >BODY
+
+T{ 123 CONSTANT X123 -> }T
+T{ X123 -> 123 }T
+T{ : EQU CONSTANT ; -> }T
+T{ X123 EQU Y123 -> }T
+T{ Y123 -> 123 }T
+
+T{ VARIABLE V1 -> }T
+T{ 123 V1 ! -> }T
+T{ V1 @ -> 123 }T
+
+T{ : NOP : POSTPONE ; ; -> }T
+T{ NOP NOP1 NOP NOP2 -> }T
+T{ NOP1 -> }T
+T{ NOP2 -> }T
+
+T{ : DOES1 DOES> @ 1 + ; -> }T
+T{ : DOES2 DOES> @ 2 + ; -> }T
+T{ CREATE CR1 -> }T
+T{ CR1 -> HERE }T
+T{ ' CR1 >BODY -> HERE }T
+T{ 1 , -> }T
+T{ CR1 @ -> 1 }T
+T{ DOES1 -> }T
+T{ CR1 -> 2 }T
+T{ DOES2 -> }T
+T{ CR1 -> 3 }T
+
+T{ : WEIRD: CREATE DOES> 1 + DOES> 2 + ; -> }T
+T{ WEIRD: W1 -> }T
+T{ ' W1 >BODY -> HERE }T
+T{ W1 -> HERE 1 + }T
+T{ W1 -> HERE 2 + }T
+
+\ ------------------------------------------------------------------------
+TESTING EVALUATE
+
+: GE1 S" 123" ; IMMEDIATE
+: GE2 S" 123 1+" ; IMMEDIATE
+: GE3 S" : GE4 345 ;" ;
+: GE5 EVALUATE ; IMMEDIATE
+
+T{ GE1 EVALUATE -> 123 }T ( TEST EVALUATE IN INTERP. STATE )
+T{ GE2 EVALUATE -> 124 }T
+T{ GE3 EVALUATE -> }T
+T{ GE4 -> 345 }T
+
+T{ : GE6 GE1 GE5 ; -> }T ( TEST EVALUATE IN COMPILE STATE )
+T{ GE6 -> 123 }T
+T{ : GE7 GE2 GE5 ; -> }T
+T{ GE7 -> 124 }T
+
+\ ------------------------------------------------------------------------
+TESTING SOURCE >IN WORD
+
+: GS1 S" SOURCE" 2DUP EVALUATE
+ >R SWAP >R = R> R> = ;
+T{ GS1 -> <TRUE> <TRUE> }T
+
+VARIABLE SCANS
+: RESCAN? -1 SCANS +! SCANS @ IF 0 >IN ! THEN ;
+
+T{ 2 SCANS !
+345 RESCAN?
+-> 345 345 }T
+
+: GS2 5 SCANS ! S" 123 RESCAN?" EVALUATE ;
+T{ GS2 -> 123 123 123 123 123 }T
+
+: GS3 WORD COUNT SWAP C@ ;
+T{ BL GS3 HELLO -> 5 CHAR H }T
+T{ CHAR " GS3 GOODBYE" -> 7 CHAR G }T
+T{ BL GS3
+DROP -> 0 }T \ BLANK LINE RETURN ZERO-LENGTH STRING
+
+: GS4 SOURCE >IN ! DROP ;
+T{ GS4 123 456
+-> }T
+
+\ ------------------------------------------------------------------------
+TESTING <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL
+
+: S= \ ( ADDR1 C1 ADDR2 C2 -- T/F ) COMPARE TWO STRINGS.
+ >R SWAP R@ = IF \ MAKE SURE STRINGS HAVE SAME LENGTH
+ R> ?DUP IF \ IF NON-EMPTY STRINGS
+ 0 DO
+ OVER C@ OVER C@ - IF
+ 2DROP <FALSE> UNLOOP EXIT THEN
+ SWAP CHAR+ SWAP CHAR+
+ LOOP
+ THEN
+ 2DROP <TRUE> \ IF WE GET HERE, STRINGS MATCH
+ ELSE
+ R> DROP 2DROP <FALSE> \ LENGTHS MISMATCH
+ THEN ;
+
+: GP1 <# 41 HOLD 42 HOLD 0 0 #> S" BA" S= ;
+T{ GP1 -> <TRUE> }T
+
+: GP2 <# -1 SIGN 0 SIGN -1 SIGN 0 0 #> S" --" S= ;
+T{ GP2 -> <TRUE> }T
+
+: GP3 <# 1 0 # # #> S" 01" S= ;
+T{ GP3 -> <TRUE> }T
+
+: GP4 <# 1 0 #S #> S" 1" S= ;
+T{ GP4 -> <TRUE> }T
+
+24 CONSTANT MAX-BASE \ BASE 2 .. 36
+: COUNT-BITS
+ 0 0 INVERT BEGIN DUP WHILE >R 1+ R> 2* REPEAT DROP ;
+COUNT-BITS 2* CONSTANT #BITS-UD \ NUMBER OF BITS IN UD
+
+: GP5
+ BASE @ <TRUE>
+ MAX-BASE 1+ 2 DO \ FOR EACH POSSIBLE BASE
+ I BASE ! \ TBD: ASSUMES BASE WORKS
+ I 0 <# #S #> S" 10" S= AND
+ LOOP
+ SWAP BASE ! ;
+T{ GP5 -> <TRUE> }T
+
+: GP6
+ BASE @ >R 2 BASE !
+ MAX-UINT MAX-UINT <# #S #> \ MAXIMUM UD TO BINARY
+ R> BASE ! \ S: C-ADDR U
+ DUP #BITS-UD = SWAP
+ 0 DO \ S: C-ADDR FLAG
+ OVER C@ [CHAR] 1 = AND \ ALL ONES
+ >R CHAR+ R>
+ LOOP SWAP DROP ;
+T{ GP6 -> <TRUE> }T
+
+: GP7
+ BASE @ >R MAX-BASE BASE !
+ <TRUE>
+ A 0 DO
+ I 0 <# #S #>
+ 1 = SWAP C@ I 30 + = AND AND
+ LOOP
+ MAX-BASE A DO
+ I 0 <# #S #>
+ 1 = SWAP C@ 41 I A - + = AND AND
+ LOOP
+ R> BASE ! ;
+
+T{ GP7 -> <TRUE> }T
+
+\ >NUMBER TESTS
+CREATE GN-BUF 0 C,
+: GN-STRING GN-BUF 1 ;
+: GN-CONSUMED GN-BUF CHAR+ 0 ;
+: GN' [CHAR] ' WORD CHAR+ C@ GN-BUF C! GN-STRING ;
+
+T{ 0 0 GN' 0' >NUMBER -> 0 0 GN-CONSUMED }T
+T{ 0 0 GN' 1' >NUMBER -> 1 0 GN-CONSUMED }T
+T{ 1 0 GN' 1' >NUMBER -> BASE @ 1+ 0 GN-CONSUMED }T
+T{ 0 0 GN' -' >NUMBER -> 0 0 GN-STRING }T \ SHOULD FAIL TO CONVERT THESE
+T{ 0 0 GN' +' >NUMBER -> 0 0 GN-STRING }T
+T{ 0 0 GN' .' >NUMBER -> 0 0 GN-STRING }T
+
+: >NUMBER-BASED
+ BASE @ >R BASE ! >NUMBER R> BASE ! ;
+
+T{ 0 0 GN' 2' 10 >NUMBER-BASED -> 2 0 GN-CONSUMED }T
+T{ 0 0 GN' 2' 2 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' F' 10 >NUMBER-BASED -> F 0 GN-CONSUMED }T
+T{ 0 0 GN' G' 10 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' G' MAX-BASE >NUMBER-BASED -> 10 0 GN-CONSUMED }T
+T{ 0 0 GN' Z' MAX-BASE >NUMBER-BASED -> 23 0 GN-CONSUMED }T
+
+: GN1 \ ( UD BASE -- UD' LEN ) UD SHOULD EQUAL UD' AND LEN SHOULD BE ZERO.
+ BASE @ >R BASE !
+ <# #S #>
+ 0 0 2SWAP >NUMBER SWAP DROP \ RETURN LENGTH ONLY
+ R> BASE ! ;
+T{ 0 0 2 GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 2 GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP 2 GN1 -> MAX-UINT DUP 0 }T
+T{ 0 0 MAX-BASE GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 MAX-BASE GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP MAX-BASE GN1 -> MAX-UINT DUP 0 }T
+
+: GN2 \ ( -- 16 10 )
+ BASE @ >R HEX BASE @ DECIMAL BASE @ R> BASE ! ;
+T{ GN2 -> 10 A }T
+
+\ ------------------------------------------------------------------------
+TESTING FILL MOVE
+
+CREATE FBUF 00 C, 00 C, 00 C,
+CREATE SBUF 12 C, 34 C, 56 C,
+: SEEBUF FBUF C@ FBUF CHAR+ C@ FBUF CHAR+ CHAR+ C@ ;
+
+T{ FBUF 0 20 FILL -> }T
+T{ SEEBUF -> 00 00 00 }T
+
+T{ FBUF 1 20 FILL -> }T
+T{ SEEBUF -> 20 00 00 }T
+
+T{ FBUF 3 20 FILL -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ FBUF FBUF 3 CHARS MOVE -> }T \ BIZARRE SPECIAL CASE
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 0 CHARS MOVE -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 1 CHARS MOVE -> }T
+T{ SEEBUF -> 12 20 20 }T
+
+T{ SBUF FBUF 3 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 56 }T
+
+T{ FBUF FBUF CHAR+ 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 12 34 }T
+
+T{ FBUF CHAR+ FBUF 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 34 }T
+
+\ ------------------------------------------------------------------------
+TESTING OUTPUT: . ." CR EMIT SPACE SPACES TYPE U.
+
+: OUTPUT-TEST
+ ." YOU SHOULD SEE THE STANDARD GRAPHIC CHARACTERS:" CR
+ 41 BL DO I EMIT LOOP CR
+ 61 41 DO I EMIT LOOP CR
+ 7F 61 DO I EMIT LOOP CR
+ ." YOU SHOULD SEE 0-9 SEPARATED BY A SPACE:" CR
+ 9 1+ 0 DO I . LOOP CR
+ ." YOU SHOULD SEE 0-9 (WITH NO SPACES):" CR
+ [CHAR] 9 1+ [CHAR] 0 DO I 0 SPACES EMIT LOOP CR
+ ." YOU SHOULD SEE A-G SEPARATED BY A SPACE:" CR
+ [CHAR] G 1+ [CHAR] A DO I EMIT SPACE LOOP CR
+ ." YOU SHOULD SEE 0-5 SEPARATED BY TWO SPACES:" CR
+ 5 1+ 0 DO I [CHAR] 0 + EMIT 2 SPACES LOOP CR
+ ." YOU SHOULD SEE TWO SEPARATE LINES:" CR
+ S" LINE 1" TYPE CR S" LINE 2" TYPE CR
+ ." YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:" CR
+ ." SIGNED: " MIN-INT . MAX-INT . CR
+ ." UNSIGNED: " 0 U. MAX-UINT U. CR
+;
+
+T{ OUTPUT-TEST -> }T
+\ ------------------------------------------------------------------------
+TESTING INPUT: ACCEPT
+
+CREATE ABUF 80 CHARS ALLOT
+
+: ACCEPT-TEST
+ CR ." PLEASE TYPE UP TO 80 CHARACTERS:" CR
+ ABUF 80 ACCEPT
+ CR ." RECEIVED: " [CHAR] " EMIT
+ ABUF SWAP TYPE [CHAR] " EMIT CR
+;
+
+T{ ACCEPT-TEST -> }T
+Vingt fois sur le métier remettez votre ouvrage, ...
+\ ------------------------------------------------------------------------
+TESTING DICTIONARY SEARCH RULES
+
+T{ : GDX 123 ; : GDX GDX 234 ; -> }T
+
+T{ GDX -> 123 234 }T
+
+CR .( End of Core word set tests) CR
+
+
+
+RST_STATE ; so ANS_COMPLEMENT_xx_MPY is conserved ;
+\ NOECHO ; if an error occurs, comment this line before new download to find it.
+
+
+\ From: John Hayes S1I
+\ Subject: tester.fr
+\ Date: Mon, 27 Nov 95 13:10:09 PST
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.1
+
+\ 22/1/09 The words { and } have been changed to T{ and }T respectively to
+\ agree with the Forth 200X file ttester.fs. This avoids clashes with
+\ locals using { ... } and the FSL use of }
+
+
+\ 13/05/14 jmt. added colorised error messages.
+
+
+
+ 0 CONSTANT FALSE
+-1 CONSTANT TRUE
+
+\ SET THE FOLLOWING FLAG TO TRUE FOR MORE VERBOSE OUTPUT; THIS MAY
+\ ALLOW YOU TO TELL WHICH TEST CAUSED YOUR SYSTEM TO HANG.
+VARIABLE VERBOSE
+ FALSE VERBOSE !
+\ TRUE VERBOSE !
+
+\ : EMPTY-STACK ( ... -- ) \ EMPTY STACK: HANDLES UNDERFLOWED STACK TOO.
+\ DEPTH ?DUP
+\ IF DUP 0< IF NEGATE 0
+\ DO 0 LOOP
+\ ELSE 0 DO DROP LOOP THEN
+\ THEN ;
+\
+\ : ERROR \ ( C-ADDR U -- ) DISPLAY AN ERROR MESSAGE FOLLOWED BY
+\ \ THE LINE THAT HAD THE ERROR.
+\ TYPE SOURCE TYPE CR \ DISPLAY LINE CORRESPONDING TO ERROR
+\ EMPTY-STACK \ THROW AWAY EVERY THING ELSE
+\ QUIT \ *** Uncomment this line to QUIT on an error
+\ ;
+
+VARIABLE ACTUAL-DEPTH \ STACK RECORD
+CREATE ACTUAL-RESULTS 20 CELLS ALLOT
+
+: T{ \ ( -- ) SYNTACTIC SUGAR.
+ ;
+
+: -> \ ( ... -- ) RECORD DEPTH AND CONTENT OF STACK.
+ DEPTH DUP ACTUAL-DEPTH ! \ RECORD DEPTH
+ ?DUP IF \ IF THERE IS SOMETHING ON STACK
+ 0 DO ACTUAL-RESULTS I CELLS + ! LOOP \ SAVE THEM
+ THEN ;
+
+: }T \ ( ... -- ) COMPARE STACK (EXPECTED) CONTENTS WITH SAVED
+ \ (ACTUAL) CONTENTS.
+ DEPTH ACTUAL-DEPTH @ = IF \ IF DEPTHS MATCH
+ DEPTH ?DUP IF \ IF THERE IS SOMETHING ON THE STACK
+ 0 DO \ FOR EACH STACK ITEM
+ ACTUAL-RESULTS I CELLS + @ \ COMPARE ACTUAL WITH EXPECTED
+\ = 0= IF S" INCORRECT RESULT: " ERROR LEAVE THEN \ jmt
+ = 0= IF ABORT" INCORRECT RESULT: " THEN \ jmt : colorised message
+ LOOP
+ THEN
+ ELSE \ DEPTH MISMATCH
+\ S" WRONG NUMBER OF RESULTS: " ERROR \ jmt
+ ABORT" WRONG NUMBER OF RESULTS: " \ jmt : colorised message
+ THEN ;
+
+: TESTING \ ( -- ) TALKING COMMENT.
+ SOURCE VERBOSE @
+ IF DUP >R TYPE CR R> >IN !
+ ELSE >IN ! DROP [CHAR] * EMIT
+ THEN ;
+
+\ From: John Hayes S1I
+\ Subject: core.fr
+\ Date: Mon, 27 Nov 95 13:10
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.2
+\ THIS PROGRAM TESTS THE CORE WORDS OF AN ANS FORTH SYSTEM.
+\ THE PROGRAM ASSUMES A TWO'S COMPLEMENT IMPLEMENTATION WHERE
+\ THE RANGE OF SIGNED NUMBERS IS -2^(N-1) ... 2^(N-1)-1 AND
+\ THE RANGE OF UNSIGNED NUMBERS IS 0 ... 2^(N)-1.
+\ I HAVEN'T FIGURED OUT HOW TO TEST KEY, QUIT, ABORT, OR ABORT"...
+\ I ALSO HAVEN'T THOUGHT OF A WAY TO TEST ENVIRONMENT?...
+
+CR
+TESTING CORE WORDS
+HEX
+
+\ ------------------------------------------------------------------------
+TESTING BASIC ASSUMPTIONS
+
+T{ -> }T \ START WITH CLEAN SLATE
+( TEST IF ANY BITS ARE SET; ANSWER IN BASE 1 )
+T{ : BITSSET? IF 0 0 ELSE 0 THEN ; -> }T
+T{ 0 BITSSET? -> 0 }T ( ZERO IS ALL BITS CLEAR )
+T{ 1 BITSSET? -> 0 0 }T ( OTHER NUMBER HAVE AT LEAST ONE BIT )
+T{ -1 BITSSET? -> 0 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING BOOLEANS: INVERT AND OR XOR
+
+T{ 0 0 AND -> 0 }T
+T{ 0 1 AND -> 0 }T
+T{ 1 0 AND -> 0 }T
+T{ 1 1 AND -> 1 }T
+
+T{ 0 INVERT 1 AND -> 1 }T
+T{ 1 INVERT 1 AND -> 0 }T
+
+0 CONSTANT 0S
+0 INVERT CONSTANT 1S
+
+T{ 0S INVERT -> 1S }T
+T{ 1S INVERT -> 0S }T
+
+T{ 0S 0S AND -> 0S }T
+T{ 0S 1S AND -> 0S }T
+T{ 1S 0S AND -> 0S }T
+T{ 1S 1S AND -> 1S }T
+
+T{ 0S 0S OR -> 0S }T
+T{ 0S 1S OR -> 1S }T
+T{ 1S 0S OR -> 1S }T
+T{ 1S 1S OR -> 1S }T
+
+T{ 0S 0S XOR -> 0S }T
+T{ 0S 1S XOR -> 1S }T
+T{ 1S 0S XOR -> 1S }T
+T{ 1S 1S XOR -> 0S }T
+
+\ ------------------------------------------------------------------------
+TESTING 2* 2/ LSHIFT RSHIFT
+
+( WE TRUST 1S, INVERT, AND BITSSET?; WE WILL CONFIRM RSHIFT LATER )
+1S 1 RSHIFT INVERT CONSTANT MSB
+T{ MSB BITSSET? -> 0 0 }T
+
+T{ 0S 2* -> 0S }T
+T{ 1 2* -> 2 }T
+T{ 4000 2* -> 8000 }T
+T{ 1S 2* 1 XOR -> 1S }T
+T{ MSB 2* -> 0S }T
+
+T{ 0S 2/ -> 0S }T
+T{ 1 2/ -> 0 }T
+T{ 4000 2/ -> 2000 }T
+T{ 1S 2/ -> 1S }T \ MSB PROPOGATED
+T{ 1S 1 XOR 2/ -> 1S }T
+T{ MSB 2/ MSB AND -> MSB }T
+
+T{ 1 0 LSHIFT -> 1 }T
+T{ 1 1 LSHIFT -> 2 }T
+T{ 1 2 LSHIFT -> 4 }T
+T{ 1 F LSHIFT -> 8000 }T \ BIGGEST GUARANTEED SHIFT
+T{ 1S 1 LSHIFT 1 XOR -> 1S }T
+T{ MSB 1 LSHIFT -> 0 }T
+
+T{ 1 0 RSHIFT -> 1 }T
+T{ 1 1 RSHIFT -> 0 }T
+T{ 2 1 RSHIFT -> 1 }T
+T{ 4 2 RSHIFT -> 1 }T
+T{ 8000 F RSHIFT -> 1 }T \ BIGGEST
+T{ MSB 1 RSHIFT MSB AND -> 0 }T \ RSHIFT ZERO FILLS MSBS
+T{ MSB 1 RSHIFT 2* -> MSB }T
+
+\ ------------------------------------------------------------------------
+TESTING COMPARISONS: 0= = 0< < > U< MIN MAX
+0 INVERT CONSTANT MAX-UINT
+0 INVERT 1 RSHIFT CONSTANT MAX-INT
+0 INVERT 1 RSHIFT INVERT CONSTANT MIN-INT
+0 INVERT 1 RSHIFT CONSTANT MID-UINT
+0 INVERT 1 RSHIFT INVERT CONSTANT MID-UINT+1
+
+0S CONSTANT <FALSE>
+1S CONSTANT <TRUE>
+
+T{ 0 0= -> <TRUE> }T
+T{ 1 0= -> <FALSE> }T
+T{ 2 0= -> <FALSE> }T
+T{ -1 0= -> <FALSE> }T
+T{ MAX-UINT 0= -> <FALSE> }T
+T{ MIN-INT 0= -> <FALSE> }T
+T{ MAX-INT 0= -> <FALSE> }T
+
+T{ 0 0 = -> <TRUE> }T
+T{ 1 1 = -> <TRUE> }T
+T{ -1 -1 = -> <TRUE> }T
+T{ 1 0 = -> <FALSE> }T
+T{ -1 0 = -> <FALSE> }T
+T{ 0 1 = -> <FALSE> }T
+T{ 0 -1 = -> <FALSE> }T
+
+T{ 0 0< -> <FALSE> }T
+T{ -1 0< -> <TRUE> }T
+T{ MIN-INT 0< -> <TRUE> }T
+T{ 1 0< -> <FALSE> }T
+T{ MAX-INT 0< -> <FALSE> }T
+
+T{ 0 1 < -> <TRUE> }T
+T{ 1 2 < -> <TRUE> }T
+T{ -1 0 < -> <TRUE> }T
+T{ -1 1 < -> <TRUE> }T
+T{ MIN-INT 0 < -> <TRUE> }T
+T{ MIN-INT MAX-INT < -> <TRUE> }T
+T{ 0 MAX-INT < -> <TRUE> }T
+T{ 0 0 < -> <FALSE> }T
+T{ 1 1 < -> <FALSE> }T
+T{ 1 0 < -> <FALSE> }T
+T{ 2 1 < -> <FALSE> }T
+T{ 0 -1 < -> <FALSE> }T
+T{ 1 -1 < -> <FALSE> }T
+T{ 0 MIN-INT < -> <FALSE> }T
+T{ MAX-INT MIN-INT < -> <FALSE> }T
+T{ MAX-INT 0 < -> <FALSE> }T
+
+T{ 0 1 > -> <FALSE> }T
+T{ 1 2 > -> <FALSE> }T
+T{ -1 0 > -> <FALSE> }T
+T{ -1 1 > -> <FALSE> }T
+T{ MIN-INT 0 > -> <FALSE> }T
+T{ MIN-INT MAX-INT > -> <FALSE> }T
+T{ 0 MAX-INT > -> <FALSE> }T
+T{ 0 0 > -> <FALSE> }T
+T{ 1 1 > -> <FALSE> }T
+T{ 1 0 > -> <TRUE> }T
+T{ 2 1 > -> <TRUE> }T
+T{ 0 -1 > -> <TRUE> }T
+T{ 1 -1 > -> <TRUE> }T
+T{ 0 MIN-INT > -> <TRUE> }T
+T{ MAX-INT MIN-INT > -> <TRUE> }T
+T{ MAX-INT 0 > -> <TRUE> }T
+
+T{ 0 1 U< -> <TRUE> }T
+T{ 1 2 U< -> <TRUE> }T
+T{ 0 MID-UINT U< -> <TRUE> }T
+T{ 0 MAX-UINT U< -> <TRUE> }T
+T{ MID-UINT MAX-UINT U< -> <TRUE> }T
+T{ 0 0 U< -> <FALSE> }T
+T{ 1 1 U< -> <FALSE> }T
+T{ 1 0 U< -> <FALSE> }T
+T{ 2 1 U< -> <FALSE> }T
+T{ MID-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT MID-UINT U< -> <FALSE> }T
+
+T{ 0 1 MIN -> 0 }T
+T{ 1 2 MIN -> 1 }T
+T{ -1 0 MIN -> -1 }T
+T{ -1 1 MIN -> -1 }T
+T{ MIN-INT 0 MIN -> MIN-INT }T
+T{ MIN-INT MAX-INT MIN -> MIN-INT }T
+T{ 0 MAX-INT MIN -> 0 }T
+T{ 0 0 MIN -> 0 }T
+T{ 1 1 MIN -> 1 }T
+T{ 1 0 MIN -> 0 }T
+T{ 2 1 MIN -> 1 }T
+T{ 0 -1 MIN -> -1 }T
+T{ 1 -1 MIN -> -1 }T
+T{ 0 MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT 0 MIN -> 0 }T
+
+T{ 0 1 MAX -> 1 }T
+T{ 1 2 MAX -> 2 }T
+T{ -1 0 MAX -> 0 }T
+T{ -1 1 MAX -> 1 }T
+T{ MIN-INT 0 MAX -> 0 }T
+T{ MIN-INT MAX-INT MAX -> MAX-INT }T
+T{ 0 MAX-INT MAX -> MAX-INT }T
+T{ 0 0 MAX -> 0 }T
+T{ 1 1 MAX -> 1 }T
+T{ 1 0 MAX -> 1 }T
+T{ 2 1 MAX -> 2 }T
+T{ 0 -1 MAX -> 0 }T
+T{ 1 -1 MAX -> 1 }T
+T{ 0 MIN-INT MAX -> 0 }T
+T{ MAX-INT MIN-INT MAX -> MAX-INT }T
+T{ MAX-INT 0 MAX -> MAX-INT }T
+
+\ ------------------------------------------------------------------------
+TESTING STACK OPS: 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP
+
+T{ 1 2 2DROP -> }T
+T{ 1 2 2DUP -> 1 2 1 2 }T
+T{ 1 2 3 4 2OVER -> 1 2 3 4 1 2 }T
+T{ 1 2 3 4 2SWAP -> 3 4 1 2 }T
+T{ 0 ?DUP -> 0 }T
+T{ 1 ?DUP -> 1 1 }T
+T{ -1 ?DUP -> -1 -1 }T
+T{ DEPTH -> 0 }T
+T{ 0 DEPTH -> 0 1 }T
+T{ 0 1 DEPTH -> 0 1 2 }T
+T{ 0 DROP -> }T
+T{ 1 2 DROP -> 1 }T
+T{ 1 DUP -> 1 1 }T
+T{ 1 2 OVER -> 1 2 1 }T
+T{ 1 2 3 ROT -> 2 3 1 }T
+T{ 1 2 SWAP -> 2 1 }T
+
+\ ------------------------------------------------------------------------
+TESTING >R R> R@
+
+T{ : GR1 >R R> ; -> }T
+T{ : GR2 >R R@ R> DROP ; -> }T
+T{ 123 GR1 -> 123 }T
+T{ 123 GR2 -> 123 }T
+T{ 1S GR1 -> 1S }T ( RETURN STACK HOLDS CELLS )
+
+\ ------------------------------------------------------------------------
+TESTING ADD/SUBTRACT: + - 1+ 1- ABS NEGATE
+
+T{ 0 5 + -> 5 }T
+T{ 5 0 + -> 5 }T
+T{ 0 -5 + -> -5 }T
+T{ -5 0 + -> -5 }T
+T{ 1 2 + -> 3 }T
+T{ 1 -2 + -> -1 }T
+T{ -1 2 + -> 1 }T
+T{ -1 -2 + -> -3 }T
+T{ -1 1 + -> 0 }T
+T{ MID-UINT 1 + -> MID-UINT+1 }T
+
+T{ 0 5 - -> -5 }T
+T{ 5 0 - -> 5 }T
+T{ 0 -5 - -> 5 }T
+T{ -5 0 - -> -5 }T
+T{ 1 2 - -> -1 }T
+T{ 1 -2 - -> 3 }T
+T{ -1 2 - -> -3 }T
+T{ -1 -2 - -> 1 }T
+T{ 0 1 - -> -1 }T
+T{ MID-UINT+1 1 - -> MID-UINT }T
+
+T{ 0 1+ -> 1 }T
+T{ -1 1+ -> 0 }T
+T{ 1 1+ -> 2 }T
+T{ MID-UINT 1+ -> MID-UINT+1 }T
+
+T{ 2 1- -> 1 }T
+T{ 1 1- -> 0 }T
+T{ 0 1- -> -1 }T
+T{ MID-UINT+1 1- -> MID-UINT }T
+
+T{ 0 NEGATE -> 0 }T
+T{ 1 NEGATE -> -1 }T
+T{ -1 NEGATE -> 1 }T
+T{ 2 NEGATE -> -2 }T
+T{ -2 NEGATE -> 2 }T
+
+T{ 0 ABS -> 0 }T
+T{ 1 ABS -> 1 }T
+T{ -1 ABS -> 1 }T
+T{ MIN-INT ABS -> MID-UINT+1 }T
+
+\ ------------------------------------------------------------------------
+TESTING MULTIPLY: S>D * M* UM*
+
+T{ 0 S>D -> 0 0 }T
+T{ 1 S>D -> 1 0 }T
+T{ 2 S>D -> 2 0 }T
+T{ -1 S>D -> -1 -1 }T
+T{ -2 S>D -> -2 -1 }T
+T{ MIN-INT S>D -> MIN-INT -1 }T
+T{ MAX-INT S>D -> MAX-INT 0 }T
+
+T{ 0 0 M* -> 0 S>D }T
+T{ 0 1 M* -> 0 S>D }T
+T{ 1 0 M* -> 0 S>D }T
+T{ 1 2 M* -> 2 S>D }T
+T{ 2 1 M* -> 2 S>D }T
+T{ 3 3 M* -> 9 S>D }T
+T{ -3 3 M* -> -9 S>D }T
+T{ 3 -3 M* -> -9 S>D }T
+T{ -3 -3 M* -> 9 S>D }T
+T{ 0 MIN-INT M* -> 0 S>D }T
+T{ 1 MIN-INT M* -> MIN-INT S>D }T
+T{ 2 MIN-INT M* -> 0 1S }T
+T{ 0 MAX-INT M* -> 0 S>D }T
+T{ 1 MAX-INT M* -> MAX-INT S>D }T
+T{ 2 MAX-INT M* -> MAX-INT 1 LSHIFT 0 }T
+T{ MIN-INT MIN-INT M* -> 0 MSB 1 RSHIFT }T
+T{ MAX-INT MIN-INT M* -> MSB MSB 2/ }T
+T{ MAX-INT MAX-INT M* -> 1 MSB 2/ INVERT }T
+
+T{ 0 0 * -> 0 }T \ TEST IDENTITIES
+T{ 0 1 * -> 0 }T
+T{ 1 0 * -> 0 }T
+T{ 1 2 * -> 2 }T
+T{ 2 1 * -> 2 }T
+T{ 3 3 * -> 9 }T
+T{ -3 3 * -> -9 }T
+T{ 3 -3 * -> -9 }T
+T{ -3 -3 * -> 9 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 * -> MID-UINT+1 }T
+T{ MID-UINT+1 2 RSHIFT 4 * -> MID-UINT+1 }T
+T{ MID-UINT+1 1 RSHIFT MID-UINT+1 OR 2 * -> MID-UINT+1 }T
+
+T{ 0 0 UM* -> 0 0 }T
+T{ 0 1 UM* -> 0 0 }T
+T{ 1 0 UM* -> 0 0 }T
+T{ 1 2 UM* -> 2 0 }T
+T{ 2 1 UM* -> 2 0 }T
+T{ 3 3 UM* -> 9 0 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 UM* -> MID-UINT+1 0 }T
+T{ MID-UINT+1 2 UM* -> 0 1 }T
+T{ MID-UINT+1 4 UM* -> 0 2 }T
+T{ 1S 2 UM* -> 1S 1 LSHIFT 1 }T
+T{ MAX-UINT MAX-UINT UM* -> 1 1 INVERT }T
+
+\ ------------------------------------------------------------------------
+TESTING DIVIDE: FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD
+
+T{ 0 S>D 1 FM/MOD -> 0 0 }T
+T{ 1 S>D 1 FM/MOD -> 0 1 }T
+T{ 2 S>D 1 FM/MOD -> 0 2 }T
+T{ -1 S>D 1 FM/MOD -> 0 -1 }T
+T{ -2 S>D 1 FM/MOD -> 0 -2 }T
+T{ 0 S>D -1 FM/MOD -> 0 0 }T
+T{ 1 S>D -1 FM/MOD -> 0 -1 }T
+T{ 2 S>D -1 FM/MOD -> 0 -2 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -1 FM/MOD -> 0 2 }T
+T{ 2 S>D 2 FM/MOD -> 0 1 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -2 FM/MOD -> 0 1 }T
+T{ 7 S>D 3 FM/MOD -> 1 2 }T
+T{ 7 S>D -3 FM/MOD -> -2 -3 }T
+T{ -7 S>D 3 FM/MOD -> 2 -3 }T
+T{ -7 S>D -3 FM/MOD -> -1 2 }T
+T{ MAX-INT S>D 1 FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT FM/MOD -> 0 1 }T
+T{ MIN-INT S>D MIN-INT FM/MOD -> 0 1 }T
+T{ 1S 1 4 FM/MOD -> 3 MAX-INT }T
+T{ 1 MIN-INT M* 1 FM/MOD -> 0 MIN-INT }T
+T{ 1 MIN-INT M* MIN-INT FM/MOD -> 0 1 }T
+T{ 2 MIN-INT M* 2 FM/MOD -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT FM/MOD -> 0 2 }T
+T{ 1 MAX-INT M* 1 FM/MOD -> 0 MAX-INT }T
+T{ 1 MAX-INT M* MAX-INT FM/MOD -> 0 1 }T
+T{ 2 MAX-INT M* 2 FM/MOD -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT FM/MOD -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT FM/MOD -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT FM/MOD -> 0 MAX-INT }T
+
+T{ 0 S>D 1 SM/REM -> 0 0 }T
+T{ 1 S>D 1 SM/REM -> 0 1 }T
+T{ 2 S>D 1 SM/REM -> 0 2 }T
+T{ -1 S>D 1 SM/REM -> 0 -1 }T
+T{ -2 S>D 1 SM/REM -> 0 -2 }T
+T{ 0 S>D -1 SM/REM -> 0 0 }T
+T{ 1 S>D -1 SM/REM -> 0 -1 }T
+T{ 2 S>D -1 SM/REM -> 0 -2 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -1 SM/REM -> 0 2 }T
+T{ 2 S>D 2 SM/REM -> 0 1 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -2 SM/REM -> 0 1 }T
+T{ 7 S>D 3 SM/REM -> 1 2 }T
+T{ 7 S>D -3 SM/REM -> 1 -2 }T
+T{ -7 S>D 3 SM/REM -> -1 -2 }T
+T{ -7 S>D -3 SM/REM -> -1 2 }T
+T{ MAX-INT S>D 1 SM/REM -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 SM/REM -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT SM/REM -> 0 1 }T
+T{ MIN-INT S>D MIN-INT SM/REM -> 0 1 }T
+T{ 1S 1 4 SM/REM -> 3 MAX-INT }T
+T{ 2 MIN-INT M* 2 SM/REM -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT SM/REM -> 0 2 }T
+T{ 2 MAX-INT M* 2 SM/REM -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT SM/REM -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT SM/REM -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT SM/REM -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT SM/REM -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT SM/REM -> 0 MAX-INT }T
+
+T{ 0 0 1 UM/MOD -> 0 0 }T
+T{ 1 0 1 UM/MOD -> 0 1 }T
+T{ 1 0 2 UM/MOD -> 1 0 }T
+T{ 3 0 2 UM/MOD -> 1 1 }T
+T{ MAX-UINT 2 UM* 2 UM/MOD -> 0 MAX-UINT }T
+T{ MAX-UINT 2 UM* MAX-UINT UM/MOD -> 0 2 }T
+T{ MAX-UINT MAX-UINT UM* MAX-UINT UM/MOD -> 0 MAX-UINT }T
+
+: IFFLOORED
+ [ -3 2 / -2 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+: IFSYM
+ [ -3 2 / -1 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+\ THE SYSTEM MIGHT DO EITHER FLOORED OR SYMMETRIC DIVISION.
+\ SINCE WE HAVE ALREADY TESTED M*, FM/MOD, AND SM/REM WE CAN USE THEM IN TEST.
+
+IFFLOORED : T/MOD >R S>D R> FM/MOD ;
+IFFLOORED : T/ T/MOD SWAP DROP ;
+IFFLOORED : TMOD T/MOD DROP ;
+IFFLOORED : T*/MOD >R M* R> FM/MOD ;
+IFFLOORED : T*/ T*/MOD SWAP DROP ;
+IFSYM : T/MOD >R S>D R> SM/REM ;
+IFSYM : T/ T/MOD SWAP DROP ;
+IFSYM : TMOD T/MOD DROP ;
+IFSYM : T*/MOD >R M* R> SM/REM ;
+IFSYM : T*/ T*/MOD SWAP DROP ;
+
+T{ 0 1 /MOD -> 0 1 T/MOD }T
+T{ 1 1 /MOD -> 1 1 T/MOD }T
+T{ 2 1 /MOD -> 2 1 T/MOD }T
+T{ -1 1 /MOD -> -1 1 T/MOD }T
+T{ -2 1 /MOD -> -2 1 T/MOD }T
+T{ 0 -1 /MOD -> 0 -1 T/MOD }T
+T{ 1 -1 /MOD -> 1 -1 T/MOD }T
+T{ 2 -1 /MOD -> 2 -1 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -1 /MOD -> -2 -1 T/MOD }T
+T{ 2 2 /MOD -> 2 2 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -2 /MOD -> -2 -2 T/MOD }T
+T{ 7 3 /MOD -> 7 3 T/MOD }T
+T{ 7 -3 /MOD -> 7 -3 T/MOD }T
+T{ -7 3 /MOD -> -7 3 T/MOD }T
+T{ -7 -3 /MOD -> -7 -3 T/MOD }T
+T{ MAX-INT 1 /MOD -> MAX-INT 1 T/MOD }T
+T{ MIN-INT 1 /MOD -> MIN-INT 1 T/MOD }T
+T{ MAX-INT MAX-INT /MOD -> MAX-INT MAX-INT T/MOD }T
+T{ MIN-INT MIN-INT /MOD -> MIN-INT MIN-INT T/MOD }T
+
+T{ 0 1 / -> 0 1 T/ }T
+T{ 1 1 / -> 1 1 T/ }T
+T{ 2 1 / -> 2 1 T/ }T
+T{ -1 1 / -> -1 1 T/ }T
+T{ -2 1 / -> -2 1 T/ }T
+T{ 0 -1 / -> 0 -1 T/ }T
+T{ 1 -1 / -> 1 -1 T/ }T
+T{ 2 -1 / -> 2 -1 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -1 / -> -2 -1 T/ }T
+T{ 2 2 / -> 2 2 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -2 / -> -2 -2 T/ }T
+T{ 7 3 / -> 7 3 T/ }T
+T{ 7 -3 / -> 7 -3 T/ }T
+T{ -7 3 / -> -7 3 T/ }T
+T{ -7 -3 / -> -7 -3 T/ }T
+T{ MAX-INT 1 / -> MAX-INT 1 T/ }T
+T{ MIN-INT 1 / -> MIN-INT 1 T/ }T
+T{ MAX-INT MAX-INT / -> MAX-INT MAX-INT T/ }T
+T{ MIN-INT MIN-INT / -> MIN-INT MIN-INT T/ }T
+
+T{ 0 1 MOD -> 0 1 TMOD }T
+T{ 1 1 MOD -> 1 1 TMOD }T
+T{ 2 1 MOD -> 2 1 TMOD }T
+T{ -1 1 MOD -> -1 1 TMOD }T
+T{ -2 1 MOD -> -2 1 TMOD }T
+T{ 0 -1 MOD -> 0 -1 TMOD }T
+T{ 1 -1 MOD -> 1 -1 TMOD }T
+T{ 2 -1 MOD -> 2 -1 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -1 MOD -> -2 -1 TMOD }T
+T{ 2 2 MOD -> 2 2 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -2 MOD -> -2 -2 TMOD }T
+T{ 7 3 MOD -> 7 3 TMOD }T
+T{ 7 -3 MOD -> 7 -3 TMOD }T
+T{ -7 3 MOD -> -7 3 TMOD }T
+T{ -7 -3 MOD -> -7 -3 TMOD }T
+T{ MAX-INT 1 MOD -> MAX-INT 1 TMOD }T
+T{ MIN-INT 1 MOD -> MIN-INT 1 TMOD }T
+T{ MAX-INT MAX-INT MOD -> MAX-INT MAX-INT TMOD }T
+T{ MIN-INT MIN-INT MOD -> MIN-INT MIN-INT TMOD }T
+
+T{ 0 2 1 */ -> 0 2 1 T*/ }T
+T{ 1 2 1 */ -> 1 2 1 T*/ }T
+T{ 2 2 1 */ -> 2 2 1 T*/ }T
+T{ -1 2 1 */ -> -1 2 1 T*/ }T
+T{ -2 2 1 */ -> -2 2 1 T*/ }T
+T{ 0 2 -1 */ -> 0 2 -1 T*/ }T
+T{ 1 2 -1 */ -> 1 2 -1 T*/ }T
+T{ 2 2 -1 */ -> 2 2 -1 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -1 */ -> -2 2 -1 T*/ }T
+T{ 2 2 2 */ -> 2 2 2 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -2 */ -> -2 2 -2 T*/ }T
+T{ 7 2 3 */ -> 7 2 3 T*/ }T
+T{ 7 2 -3 */ -> 7 2 -3 T*/ }T
+T{ -7 2 3 */ -> -7 2 3 T*/ }T
+T{ -7 2 -3 */ -> -7 2 -3 T*/ }T
+T{ MAX-INT 2 MAX-INT */ -> MAX-INT 2 MAX-INT T*/ }T
+T{ MIN-INT 2 MIN-INT */ -> MIN-INT 2 MIN-INT T*/ }T
+
+T{ 0 2 1 */MOD -> 0 2 1 T*/MOD }T
+T{ 1 2 1 */MOD -> 1 2 1 T*/MOD }T
+T{ 2 2 1 */MOD -> 2 2 1 T*/MOD }T
+T{ -1 2 1 */MOD -> -1 2 1 T*/MOD }T
+T{ -2 2 1 */MOD -> -2 2 1 T*/MOD }T
+T{ 0 2 -1 */MOD -> 0 2 -1 T*/MOD }T
+T{ 1 2 -1 */MOD -> 1 2 -1 T*/MOD }T
+T{ 2 2 -1 */MOD -> 2 2 -1 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -1 */MOD -> -2 2 -1 T*/MOD }T
+T{ 2 2 2 */MOD -> 2 2 2 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -2 */MOD -> -2 2 -2 T*/MOD }T
+T{ 7 2 3 */MOD -> 7 2 3 T*/MOD }T
+T{ 7 2 -3 */MOD -> 7 2 -3 T*/MOD }T
+T{ -7 2 3 */MOD -> -7 2 3 T*/MOD }T
+T{ -7 2 -3 */MOD -> -7 2 -3 T*/MOD }T
+T{ MAX-INT 2 MAX-INT */MOD -> MAX-INT 2 MAX-INT T*/MOD }T
+T{ MIN-INT 2 MIN-INT */MOD -> MIN-INT 2 MIN-INT T*/MOD }T
+
+\ ------------------------------------------------------------------------
+TESTING HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2! ALIGN ALIGNED +! ALLOT
+
+HERE 1 ALLOT
+HERE
+CONSTANT 2NDA
+CONSTANT 1STA
+T{ 1STA 2NDA U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STA 1+ -> 2NDA }T \ ... BY ONE ADDRESS UNIT
+( MISSING TEST: NEGATIVE ALLOT )
+
+HERE 1 ,
+HERE 2 ,
+CONSTANT 2ND
+CONSTANT 1ST
+T{ 1ST 2ND U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1ST CELL+ -> 2ND }T \ ... BY ONE CELL
+T{ 1ST 1 CELLS + -> 2ND }T
+T{ 1ST @ 2ND @ -> 1 2 }T
+T{ 5 1ST ! -> }T
+T{ 1ST @ 2ND @ -> 5 2 }T
+T{ 6 2ND ! -> }T
+T{ 1ST @ 2ND @ -> 5 6 }T
+T{ 1ST 2@ -> 6 5 }T
+T{ 2 1 1ST 2! -> }T
+T{ 1ST 2@ -> 2 1 }T
+T{ 1S 1ST ! 1ST @ -> 1S }T \ CAN STORE CELL-WIDE VALUE
+
+HERE 1 C,
+HERE 2 C,
+CONSTANT 2NDC
+CONSTANT 1STC
+T{ 1STC 2NDC U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STC CHAR+ -> 2NDC }T \ ... BY ONE CHAR
+T{ 1STC 1 CHARS + -> 2NDC }T
+T{ 1STC C@ 2NDC C@ -> 1 2 }T
+T{ 3 1STC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 2 }T
+T{ 4 2NDC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 4 }T
+
+ALIGN 1 ALLOT HERE ALIGN HERE 3 CELLS ALLOT
+CONSTANT A-ADDR CONSTANT UA-ADDR
+T{ UA-ADDR ALIGNED -> A-ADDR }T
+T{ 1 A-ADDR C! A-ADDR C@ -> 1 }T
+T{ 1234 A-ADDR ! A-ADDR @ -> 1234 }T
+T{ 123 456 A-ADDR 2! A-ADDR 2@ -> 123 456 }T
+T{ 2 A-ADDR CHAR+ C! A-ADDR CHAR+ C@ -> 2 }T
+T{ 3 A-ADDR CELL+ C! A-ADDR CELL+ C@ -> 3 }T
+T{ 1234 A-ADDR CELL+ ! A-ADDR CELL+ @ -> 1234 }T
+T{ 123 456 A-ADDR CELL+ 2! A-ADDR CELL+ 2@ -> 123 456 }T
+
+: BITS ( X -- U )
+ 0 SWAP BEGIN DUP WHILE DUP MSB AND IF >R 1+ R> THEN 2* REPEAT DROP ;
+( CHARACTERS >= 1 AU, <= SIZE OF CELL, >= 8 BITS )
+T{ 1 CHARS 1 < -> <FALSE> }T
+T{ 1 CHARS 1 CELLS > -> <FALSE> }T
+( TBD: HOW TO FIND NUMBER OF BITS? )
+
+( CELLS >= 1 AU, INTEGRAL MULTIPLE OF CHAR SIZE, >= 16 BITS )
+T{ 1 CELLS 1 < -> <FALSE> }T
+T{ 1 CELLS 1 CHARS MOD -> 0 }T
+T{ 1S BITS 10 < -> <FALSE> }T
+
+T{ 0 1ST ! -> }T
+T{ 1 1ST +! -> }T
+T{ 1ST @ -> 1 }T
+T{ -1 1ST +! 1ST @ -> 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING CHAR [CHAR] [ ] BL S"
+
+T{ BL -> 20 }T
+T{ CHAR X -> 58 }T
+T{ CHAR HELLO -> 48 }T
+T{ : GC1 [CHAR] X ; -> }T
+T{ : GC2 [CHAR] HELLO ; -> }T
+T{ GC1 -> 58 }T
+T{ GC2 -> 48 }T
+T{ : GC3 [ GC1 ] LITERAL ; -> }T
+T{ GC3 -> 58 }T
+T{ : GC4 S" XY" ; -> }T
+T{ GC4 SWAP DROP -> 2 }T
+T{ GC4 DROP DUP C@ SWAP CHAR+ C@ -> 58 59 }T
+
+\ ------------------------------------------------------------------------
+TESTING ' ['] FIND EXECUTE IMMEDIATE COUNT LITERAL POSTPONE STATE
+
+T{ : GT1 123 ; -> }T
+T{ ' GT1 EXECUTE -> 123 }T
+T{ : GT2 ['] GT1 ; IMMEDIATE -> }T
+T{ GT2 EXECUTE -> 123 }T
+HERE 3 C, CHAR G C, CHAR T C, CHAR 1 C, CONSTANT GT1STRING
+HERE 3 C, CHAR G C, CHAR T C, CHAR 2 C, CONSTANT GT2STRING
+T{ GT1STRING FIND -> ' GT1 -1 }T
+T{ GT2STRING FIND -> ' GT2 1 }T
+( HOW TO SEARCH FOR NON-EXISTENT WORD? )
+T{ : GT3 GT2 LITERAL ; -> }T
+T{ GT3 -> ' GT1 }T
+T{ GT1STRING COUNT -> GT1STRING CHAR+ 3 }T
+
+T{ : GT4 POSTPONE GT1 ; IMMEDIATE -> }T
+T{ : GT5 GT4 ; -> }T
+T{ GT5 -> 123 }T
+T{ : GT6 345 ; IMMEDIATE -> }T
+T{ : GT7 POSTPONE GT6 ; -> }T
+T{ GT7 -> 345 }T
+
+T{ : GT8 STATE @ ; IMMEDIATE -> }T
+T{ GT8 -> 0 }T
+T{ : GT9 GT8 LITERAL ; -> }T
+T{ GT9 0= -> <FALSE> }T
+
+\ ------------------------------------------------------------------------
+TESTING IF ELSE THEN BEGIN WHILE REPEAT UNTIL RECURSE
+
+T{ : GI1 IF 123 THEN ; -> }T
+T{ : GI2 IF 123 ELSE 234 THEN ; -> }T
+T{ 0 GI1 -> }T
+T{ 1 GI1 -> 123 }T
+T{ -1 GI1 -> 123 }T
+T{ 0 GI2 -> 234 }T
+T{ 1 GI2 -> 123 }T
+T{ -1 GI1 -> 123 }T
+
+T{ : GI3 BEGIN DUP 5 < WHILE DUP 1+ REPEAT ; -> }T
+T{ 0 GI3 -> 0 1 2 3 4 5 }T
+T{ 4 GI3 -> 4 5 }T
+T{ 5 GI3 -> 5 }T
+T{ 6 GI3 -> 6 }T
+
+T{ : GI4 BEGIN DUP 1+ DUP 5 > UNTIL ; -> }T
+T{ 3 GI4 -> 3 4 5 6 }T
+T{ 5 GI4 -> 5 6 }T
+T{ 6 GI4 -> 6 7 }T
+
+T{ : GI5 BEGIN DUP 2 > WHILE DUP 5 < WHILE DUP 1+ REPEAT 123 ELSE 345 THEN ; -> }T
+T{ 1 GI5 -> 1 345 }T
+T{ 2 GI5 -> 2 345 }T
+T{ 3 GI5 -> 3 4 5 123 }T
+T{ 4 GI5 -> 4 5 123 }T
+T{ 5 GI5 -> 5 123 }T
+
+T{ : GI6 ( N -- 0,1,..N ) DUP IF DUP >R 1- RECURSE R> THEN ; -> }T
+T{ 0 GI6 -> 0 }T
+T{ 1 GI6 -> 0 1 }T
+T{ 2 GI6 -> 0 1 2 }T
+T{ 3 GI6 -> 0 1 2 3 }T
+T{ 4 GI6 -> 0 1 2 3 4 }T
+
+\ ------------------------------------------------------------------------
+TESTING DO LOOP +LOOP I J UNLOOP LEAVE EXIT
+
+T{ : GD1 DO I LOOP ; -> }T
+T{ 4 1 GD1 -> 1 2 3 }T
+T{ 2 -1 GD1 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD1 -> MID-UINT }T
+
+T{ : GD2 DO I -1 +LOOP ; -> }T
+T{ 1 4 GD2 -> 4 3 2 1 }T
+T{ -1 2 GD2 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD2 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD3 DO 1 0 DO J LOOP LOOP ; -> }T
+T{ 4 1 GD3 -> 1 2 3 }T
+T{ 2 -1 GD3 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD3 -> MID-UINT }T
+
+T{ : GD4 DO 1 0 DO J LOOP -1 +LOOP ; -> }T
+T{ 1 4 GD4 -> 4 3 2 1 }T
+T{ -1 2 GD4 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD4 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD5 123 SWAP 0 DO I 4 > IF DROP 234 LEAVE THEN LOOP ; -> }T
+T{ 1 GD5 -> 123 }T
+T{ 5 GD5 -> 123 }T
+T{ 6 GD5 -> 234 }T
+
+T{ : GD6 ( PAT: T{0 0}T,T{0 0}TT{1 0}TT{1 1}T,T{0 0}TT{1 0}TT{1 1}TT{2 0}TT{2 1}TT{2 2}T )
+ 0 SWAP 0 DO
+ I 1+ 0 DO I J + 3 = IF I UNLOOP I UNLOOP EXIT THEN 1+ LOOP
+ LOOP ; -> }T
+T{ 1 GD6 -> 1 }T
+T{ 2 GD6 -> 3 }T
+T{ 3 GD6 -> 4 1 2 }T
+
+\ ------------------------------------------------------------------------
+TESTING DEFINING WORDS: : ; CONSTANT VARIABLE CREATE DOES> >BODY
+
+T{ 123 CONSTANT X123 -> }T
+T{ X123 -> 123 }T
+T{ : EQU CONSTANT ; -> }T
+T{ X123 EQU Y123 -> }T
+T{ Y123 -> 123 }T
+
+T{ VARIABLE V1 -> }T
+T{ 123 V1 ! -> }T
+T{ V1 @ -> 123 }T
+
+T{ : NOP : POSTPONE ; ; -> }T
+T{ NOP NOP1 NOP NOP2 -> }T
+T{ NOP1 -> }T
+T{ NOP2 -> }T
+
+T{ : DOES1 DOES> @ 1 + ; -> }T
+T{ : DOES2 DOES> @ 2 + ; -> }T
+T{ CREATE CR1 -> }T
+T{ CR1 -> HERE }T
+T{ ' CR1 >BODY -> HERE }T
+T{ 1 , -> }T
+T{ CR1 @ -> 1 }T
+T{ DOES1 -> }T
+T{ CR1 -> 2 }T
+T{ DOES2 -> }T
+T{ CR1 -> 3 }T
+
+T{ : WEIRD: CREATE DOES> 1 + DOES> 2 + ; -> }T
+T{ WEIRD: W1 -> }T
+T{ ' W1 >BODY -> HERE }T
+T{ W1 -> HERE 1 + }T
+T{ W1 -> HERE 2 + }T
+
+\ ------------------------------------------------------------------------
+TESTING EVALUATE
+
+: GE1 S" 123" ; IMMEDIATE
+: GE2 S" 123 1+" ; IMMEDIATE
+: GE3 S" : GE4 345 ;" ;
+: GE5 EVALUATE ; IMMEDIATE
+
+T{ GE1 EVALUATE -> 123 }T ( TEST EVALUATE IN INTERP. STATE )
+T{ GE2 EVALUATE -> 124 }T
+T{ GE3 EVALUATE -> }T
+T{ GE4 -> 345 }T
+
+T{ : GE6 GE1 GE5 ; -> }T ( TEST EVALUATE IN COMPILE STATE )
+T{ GE6 -> 123 }T
+T{ : GE7 GE2 GE5 ; -> }T
+T{ GE7 -> 124 }T
+
+\ ------------------------------------------------------------------------
+TESTING SOURCE >IN WORD
+
+: GS1 S" SOURCE" 2DUP EVALUATE
+ >R SWAP >R = R> R> = ;
+T{ GS1 -> <TRUE> <TRUE> }T
+
+VARIABLE SCANS
+: RESCAN? -1 SCANS +! SCANS @ IF 0 >IN ! THEN ;
+
+T{ 2 SCANS !
+345 RESCAN?
+-> 345 345 }T
+
+: GS2 5 SCANS ! S" 123 RESCAN?" EVALUATE ;
+T{ GS2 -> 123 123 123 123 123 }T
+
+: GS3 WORD COUNT SWAP C@ ;
+T{ BL GS3 HELLO -> 5 CHAR H }T
+T{ CHAR " GS3 GOODBYE" -> 7 CHAR G }T
+T{ BL GS3
+DROP -> 0 }T \ BLANK LINE RETURN ZERO-LENGTH STRING
+
+: GS4 SOURCE >IN ! DROP ;
+T{ GS4 123 456
+-> }T
+
+\ ------------------------------------------------------------------------
+TESTING <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL
+
+: S= \ ( ADDR1 C1 ADDR2 C2 -- T/F ) COMPARE TWO STRINGS.
+ >R SWAP R@ = IF \ MAKE SURE STRINGS HAVE SAME LENGTH
+ R> ?DUP IF \ IF NON-EMPTY STRINGS
+ 0 DO
+ OVER C@ OVER C@ - IF
+ 2DROP <FALSE> UNLOOP EXIT THEN
+ SWAP CHAR+ SWAP CHAR+
+ LOOP
+ THEN
+ 2DROP <TRUE> \ IF WE GET HERE, STRINGS MATCH
+ ELSE
+ R> DROP 2DROP <FALSE> \ LENGTHS MISMATCH
+ THEN ;
+
+: GP1 <# 41 HOLD 42 HOLD 0 0 #> S" BA" S= ;
+T{ GP1 -> <TRUE> }T
+
+: GP2 <# -1 SIGN 0 SIGN -1 SIGN 0 0 #> S" --" S= ;
+T{ GP2 -> <TRUE> }T
+
+: GP3 <# 1 0 # # #> S" 01" S= ;
+T{ GP3 -> <TRUE> }T
+
+: GP4 <# 1 0 #S #> S" 1" S= ;
+T{ GP4 -> <TRUE> }T
+
+24 CONSTANT MAX-BASE \ BASE 2 .. 36
+: COUNT-BITS
+ 0 0 INVERT BEGIN DUP WHILE >R 1+ R> 2* REPEAT DROP ;
+COUNT-BITS 2* CONSTANT #BITS-UD \ NUMBER OF BITS IN UD
+
+: GP5
+ BASE @ <TRUE>
+ MAX-BASE 1+ 2 DO \ FOR EACH POSSIBLE BASE
+ I BASE ! \ TBD: ASSUMES BASE WORKS
+ I 0 <# #S #> S" 10" S= AND
+ LOOP
+ SWAP BASE ! ;
+T{ GP5 -> <TRUE> }T
+
+: GP6
+ BASE @ >R 2 BASE !
+ MAX-UINT MAX-UINT <# #S #> \ MAXIMUM UD TO BINARY
+ R> BASE ! \ S: C-ADDR U
+ DUP #BITS-UD = SWAP
+ 0 DO \ S: C-ADDR FLAG
+ OVER C@ [CHAR] 1 = AND \ ALL ONES
+ >R CHAR+ R>
+ LOOP SWAP DROP ;
+T{ GP6 -> <TRUE> }T
+
+: GP7
+ BASE @ >R MAX-BASE BASE !
+ <TRUE>
+ A 0 DO
+ I 0 <# #S #>
+ 1 = SWAP C@ I 30 + = AND AND
+ LOOP
+ MAX-BASE A DO
+ I 0 <# #S #>
+ 1 = SWAP C@ 41 I A - + = AND AND
+ LOOP
+ R> BASE ! ;
+
+T{ GP7 -> <TRUE> }T
+
+\ >NUMBER TESTS
+CREATE GN-BUF 0 C,
+: GN-STRING GN-BUF 1 ;
+: GN-CONSUMED GN-BUF CHAR+ 0 ;
+: GN' [CHAR] ' WORD CHAR+ C@ GN-BUF C! GN-STRING ;
+
+T{ 0 0 GN' 0' >NUMBER -> 0 0 GN-CONSUMED }T
+T{ 0 0 GN' 1' >NUMBER -> 1 0 GN-CONSUMED }T
+T{ 1 0 GN' 1' >NUMBER -> BASE @ 1+ 0 GN-CONSUMED }T
+T{ 0 0 GN' -' >NUMBER -> 0 0 GN-STRING }T \ SHOULD FAIL TO CONVERT THESE
+T{ 0 0 GN' +' >NUMBER -> 0 0 GN-STRING }T
+T{ 0 0 GN' .' >NUMBER -> 0 0 GN-STRING }T
+
+: >NUMBER-BASED
+ BASE @ >R BASE ! >NUMBER R> BASE ! ;
+
+T{ 0 0 GN' 2' 10 >NUMBER-BASED -> 2 0 GN-CONSUMED }T
+T{ 0 0 GN' 2' 2 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' F' 10 >NUMBER-BASED -> F 0 GN-CONSUMED }T
+T{ 0 0 GN' G' 10 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' G' MAX-BASE >NUMBER-BASED -> 10 0 GN-CONSUMED }T
+T{ 0 0 GN' Z' MAX-BASE >NUMBER-BASED -> 23 0 GN-CONSUMED }T
+
+: GN1 \ ( UD BASE -- UD' LEN ) UD SHOULD EQUAL UD' AND LEN SHOULD BE ZERO.
+ BASE @ >R BASE !
+ <# #S #>
+ 0 0 2SWAP >NUMBER SWAP DROP \ RETURN LENGTH ONLY
+ R> BASE ! ;
+T{ 0 0 2 GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 2 GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP 2 GN1 -> MAX-UINT DUP 0 }T
+T{ 0 0 MAX-BASE GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 MAX-BASE GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP MAX-BASE GN1 -> MAX-UINT DUP 0 }T
+
+: GN2 \ ( -- 16 10 )
+ BASE @ >R HEX BASE @ DECIMAL BASE @ R> BASE ! ;
+T{ GN2 -> 10 A }T
+
+\ ------------------------------------------------------------------------
+TESTING FILL MOVE
+
+CREATE FBUF 00 C, 00 C, 00 C,
+CREATE SBUF 12 C, 34 C, 56 C,
+: SEEBUF FBUF C@ FBUF CHAR+ C@ FBUF CHAR+ CHAR+ C@ ;
+
+T{ FBUF 0 20 FILL -> }T
+T{ SEEBUF -> 00 00 00 }T
+
+T{ FBUF 1 20 FILL -> }T
+T{ SEEBUF -> 20 00 00 }T
+
+T{ FBUF 3 20 FILL -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ FBUF FBUF 3 CHARS MOVE -> }T \ BIZARRE SPECIAL CASE
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 0 CHARS MOVE -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 1 CHARS MOVE -> }T
+T{ SEEBUF -> 12 20 20 }T
+
+T{ SBUF FBUF 3 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 56 }T
+
+T{ FBUF FBUF CHAR+ 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 12 34 }T
+
+T{ FBUF CHAR+ FBUF 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 34 }T
+
+\ ------------------------------------------------------------------------
+TESTING OUTPUT: . ." CR EMIT SPACE SPACES TYPE U.
+
+: OUTPUT-TEST
+ ." YOU SHOULD SEE THE STANDARD GRAPHIC CHARACTERS:" CR
+ 41 BL DO I EMIT LOOP CR
+ 61 41 DO I EMIT LOOP CR
+ 7F 61 DO I EMIT LOOP CR
+ ." YOU SHOULD SEE 0-9 SEPARATED BY A SPACE:" CR
+ 9 1+ 0 DO I . LOOP CR
+ ." YOU SHOULD SEE 0-9 (WITH NO SPACES):" CR
+ [CHAR] 9 1+ [CHAR] 0 DO I 0 SPACES EMIT LOOP CR
+ ." YOU SHOULD SEE A-G SEPARATED BY A SPACE:" CR
+ [CHAR] G 1+ [CHAR] A DO I EMIT SPACE LOOP CR
+ ." YOU SHOULD SEE 0-5 SEPARATED BY TWO SPACES:" CR
+ 5 1+ 0 DO I [CHAR] 0 + EMIT 2 SPACES LOOP CR
+ ." YOU SHOULD SEE TWO SEPARATE LINES:" CR
+ S" LINE 1" TYPE CR S" LINE 2" TYPE CR
+ ." YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:" CR
+ ." SIGNED: " MIN-INT . MAX-INT . CR
+ ." UNSIGNED: " 0 U. MAX-UINT U. CR
+;
+
+T{ OUTPUT-TEST -> }T
+\ ------------------------------------------------------------------------
+TESTING INPUT: ACCEPT
+
+CREATE ABUF 80 CHARS ALLOT
+
+: ACCEPT-TEST
+ CR ." PLEASE TYPE UP TO 80 CHARACTERS:" CR
+ ABUF 80 ACCEPT
+ CR ." RECEIVED: " [CHAR] " EMIT
+ ABUF SWAP TYPE [CHAR] " EMIT CR
+;
+
+T{ ACCEPT-TEST -> }T
+Vingt fois sur le métier remettez votre ouvrage, ...
+\ ------------------------------------------------------------------------
+TESTING DICTIONARY SEARCH RULES
+
+T{ : GDX 123 ; : GDX GDX 234 ; -> }T
+
+T{ GDX -> 123 234 }T
+
+CR .( End of Core word set tests) CR
+
+
+
+RST_STATE ; so ANS_COMPLEMENT_xx_MPY is conserved ;
+\ NOECHO ; if an error occurs, comment this line before new download to find it.
+
+
+\ From: John Hayes S1I
+\ Subject: tester.fr
+\ Date: Mon, 27 Nov 95 13:10:09 PST
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.1
+
+\ 22/1/09 The words { and } have been changed to T{ and }T respectively to
+\ agree with the Forth 200X file ttester.fs. This avoids clashes with
+\ locals using { ... } and the FSL use of }
+
+
+\ 13/05/14 jmt. added colorised error messages.
+
+
+
+ 0 CONSTANT FALSE
+-1 CONSTANT TRUE
+
+\ SET THE FOLLOWING FLAG TO TRUE FOR MORE VERBOSE OUTPUT; THIS MAY
+\ ALLOW YOU TO TELL WHICH TEST CAUSED YOUR SYSTEM TO HANG.
+VARIABLE VERBOSE
+ FALSE VERBOSE !
+\ TRUE VERBOSE !
+
+\ : EMPTY-STACK ( ... -- ) \ EMPTY STACK: HANDLES UNDERFLOWED STACK TOO.
+\ DEPTH ?DUP
+\ IF DUP 0< IF NEGATE 0
+\ DO 0 LOOP
+\ ELSE 0 DO DROP LOOP THEN
+\ THEN ;
+\
+\ : ERROR \ ( C-ADDR U -- ) DISPLAY AN ERROR MESSAGE FOLLOWED BY
+\ \ THE LINE THAT HAD THE ERROR.
+\ TYPE SOURCE TYPE CR \ DISPLAY LINE CORRESPONDING TO ERROR
+\ EMPTY-STACK \ THROW AWAY EVERY THING ELSE
+\ QUIT \ *** Uncomment this line to QUIT on an error
+\ ;
+
+VARIABLE ACTUAL-DEPTH \ STACK RECORD
+CREATE ACTUAL-RESULTS 20 CELLS ALLOT
+
+: T{ \ ( -- ) SYNTACTIC SUGAR.
+ ;
+
+: -> \ ( ... -- ) RECORD DEPTH AND CONTENT OF STACK.
+ DEPTH DUP ACTUAL-DEPTH ! \ RECORD DEPTH
+ ?DUP IF \ IF THERE IS SOMETHING ON STACK
+ 0 DO ACTUAL-RESULTS I CELLS + ! LOOP \ SAVE THEM
+ THEN ;
+
+: }T \ ( ... -- ) COMPARE STACK (EXPECTED) CONTENTS WITH SAVED
+ \ (ACTUAL) CONTENTS.
+ DEPTH ACTUAL-DEPTH @ = IF \ IF DEPTHS MATCH
+ DEPTH ?DUP IF \ IF THERE IS SOMETHING ON THE STACK
+ 0 DO \ FOR EACH STACK ITEM
+ ACTUAL-RESULTS I CELLS + @ \ COMPARE ACTUAL WITH EXPECTED
+\ = 0= IF S" INCORRECT RESULT: " ERROR LEAVE THEN \ jmt
+ = 0= IF ABORT" INCORRECT RESULT: " THEN \ jmt : colorised message
+ LOOP
+ THEN
+ ELSE \ DEPTH MISMATCH
+\ S" WRONG NUMBER OF RESULTS: " ERROR \ jmt
+ ABORT" WRONG NUMBER OF RESULTS: " \ jmt : colorised message
+ THEN ;
+
+: TESTING \ ( -- ) TALKING COMMENT.
+ SOURCE VERBOSE @
+ IF DUP >R TYPE CR R> >IN !
+ ELSE >IN ! DROP [CHAR] * EMIT
+ THEN ;
+
+\ From: John Hayes S1I
+\ Subject: core.fr
+\ Date: Mon, 27 Nov 95 13:10
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.2
+\ THIS PROGRAM TESTS THE CORE WORDS OF AN ANS FORTH SYSTEM.
+\ THE PROGRAM ASSUMES A TWO'S COMPLEMENT IMPLEMENTATION WHERE
+\ THE RANGE OF SIGNED NUMBERS IS -2^(N-1) ... 2^(N-1)-1 AND
+\ THE RANGE OF UNSIGNED NUMBERS IS 0 ... 2^(N)-1.
+\ I HAVEN'T FIGURED OUT HOW TO TEST KEY, QUIT, ABORT, OR ABORT"...
+\ I ALSO HAVEN'T THOUGHT OF A WAY TO TEST ENVIRONMENT?...
+
+CR
+TESTING CORE WORDS
+HEX
+
+\ ------------------------------------------------------------------------
+TESTING BASIC ASSUMPTIONS
+
+T{ -> }T \ START WITH CLEAN SLATE
+( TEST IF ANY BITS ARE SET; ANSWER IN BASE 1 )
+T{ : BITSSET? IF 0 0 ELSE 0 THEN ; -> }T
+T{ 0 BITSSET? -> 0 }T ( ZERO IS ALL BITS CLEAR )
+T{ 1 BITSSET? -> 0 0 }T ( OTHER NUMBER HAVE AT LEAST ONE BIT )
+T{ -1 BITSSET? -> 0 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING BOOLEANS: INVERT AND OR XOR
+
+T{ 0 0 AND -> 0 }T
+T{ 0 1 AND -> 0 }T
+T{ 1 0 AND -> 0 }T
+T{ 1 1 AND -> 1 }T
+
+T{ 0 INVERT 1 AND -> 1 }T
+T{ 1 INVERT 1 AND -> 0 }T
+
+0 CONSTANT 0S
+0 INVERT CONSTANT 1S
+
+T{ 0S INVERT -> 1S }T
+T{ 1S INVERT -> 0S }T
+
+T{ 0S 0S AND -> 0S }T
+T{ 0S 1S AND -> 0S }T
+T{ 1S 0S AND -> 0S }T
+T{ 1S 1S AND -> 1S }T
+
+T{ 0S 0S OR -> 0S }T
+T{ 0S 1S OR -> 1S }T
+T{ 1S 0S OR -> 1S }T
+T{ 1S 1S OR -> 1S }T
+
+T{ 0S 0S XOR -> 0S }T
+T{ 0S 1S XOR -> 1S }T
+T{ 1S 0S XOR -> 1S }T
+T{ 1S 1S XOR -> 0S }T
+
+\ ------------------------------------------------------------------------
+TESTING 2* 2/ LSHIFT RSHIFT
+
+( WE TRUST 1S, INVERT, AND BITSSET?; WE WILL CONFIRM RSHIFT LATER )
+1S 1 RSHIFT INVERT CONSTANT MSB
+T{ MSB BITSSET? -> 0 0 }T
+
+T{ 0S 2* -> 0S }T
+T{ 1 2* -> 2 }T
+T{ 4000 2* -> 8000 }T
+T{ 1S 2* 1 XOR -> 1S }T
+T{ MSB 2* -> 0S }T
+
+T{ 0S 2/ -> 0S }T
+T{ 1 2/ -> 0 }T
+T{ 4000 2/ -> 2000 }T
+T{ 1S 2/ -> 1S }T \ MSB PROPOGATED
+T{ 1S 1 XOR 2/ -> 1S }T
+T{ MSB 2/ MSB AND -> MSB }T
+
+T{ 1 0 LSHIFT -> 1 }T
+T{ 1 1 LSHIFT -> 2 }T
+T{ 1 2 LSHIFT -> 4 }T
+T{ 1 F LSHIFT -> 8000 }T \ BIGGEST GUARANTEED SHIFT
+T{ 1S 1 LSHIFT 1 XOR -> 1S }T
+T{ MSB 1 LSHIFT -> 0 }T
+
+T{ 1 0 RSHIFT -> 1 }T
+T{ 1 1 RSHIFT -> 0 }T
+T{ 2 1 RSHIFT -> 1 }T
+T{ 4 2 RSHIFT -> 1 }T
+T{ 8000 F RSHIFT -> 1 }T \ BIGGEST
+T{ MSB 1 RSHIFT MSB AND -> 0 }T \ RSHIFT ZERO FILLS MSBS
+T{ MSB 1 RSHIFT 2* -> MSB }T
+
+\ ------------------------------------------------------------------------
+TESTING COMPARISONS: 0= = 0< < > U< MIN MAX
+0 INVERT CONSTANT MAX-UINT
+0 INVERT 1 RSHIFT CONSTANT MAX-INT
+0 INVERT 1 RSHIFT INVERT CONSTANT MIN-INT
+0 INVERT 1 RSHIFT CONSTANT MID-UINT
+0 INVERT 1 RSHIFT INVERT CONSTANT MID-UINT+1
+
+0S CONSTANT <FALSE>
+1S CONSTANT <TRUE>
+
+T{ 0 0= -> <TRUE> }T
+T{ 1 0= -> <FALSE> }T
+T{ 2 0= -> <FALSE> }T
+T{ -1 0= -> <FALSE> }T
+T{ MAX-UINT 0= -> <FALSE> }T
+T{ MIN-INT 0= -> <FALSE> }T
+T{ MAX-INT 0= -> <FALSE> }T
+
+T{ 0 0 = -> <TRUE> }T
+T{ 1 1 = -> <TRUE> }T
+T{ -1 -1 = -> <TRUE> }T
+T{ 1 0 = -> <FALSE> }T
+T{ -1 0 = -> <FALSE> }T
+T{ 0 1 = -> <FALSE> }T
+T{ 0 -1 = -> <FALSE> }T
+
+T{ 0 0< -> <FALSE> }T
+T{ -1 0< -> <TRUE> }T
+T{ MIN-INT 0< -> <TRUE> }T
+T{ 1 0< -> <FALSE> }T
+T{ MAX-INT 0< -> <FALSE> }T
+
+T{ 0 1 < -> <TRUE> }T
+T{ 1 2 < -> <TRUE> }T
+T{ -1 0 < -> <TRUE> }T
+T{ -1 1 < -> <TRUE> }T
+T{ MIN-INT 0 < -> <TRUE> }T
+T{ MIN-INT MAX-INT < -> <TRUE> }T
+T{ 0 MAX-INT < -> <TRUE> }T
+T{ 0 0 < -> <FALSE> }T
+T{ 1 1 < -> <FALSE> }T
+T{ 1 0 < -> <FALSE> }T
+T{ 2 1 < -> <FALSE> }T
+T{ 0 -1 < -> <FALSE> }T
+T{ 1 -1 < -> <FALSE> }T
+T{ 0 MIN-INT < -> <FALSE> }T
+T{ MAX-INT MIN-INT < -> <FALSE> }T
+T{ MAX-INT 0 < -> <FALSE> }T
+
+T{ 0 1 > -> <FALSE> }T
+T{ 1 2 > -> <FALSE> }T
+T{ -1 0 > -> <FALSE> }T
+T{ -1 1 > -> <FALSE> }T
+T{ MIN-INT 0 > -> <FALSE> }T
+T{ MIN-INT MAX-INT > -> <FALSE> }T
+T{ 0 MAX-INT > -> <FALSE> }T
+T{ 0 0 > -> <FALSE> }T
+T{ 1 1 > -> <FALSE> }T
+T{ 1 0 > -> <TRUE> }T
+T{ 2 1 > -> <TRUE> }T
+T{ 0 -1 > -> <TRUE> }T
+T{ 1 -1 > -> <TRUE> }T
+T{ 0 MIN-INT > -> <TRUE> }T
+T{ MAX-INT MIN-INT > -> <TRUE> }T
+T{ MAX-INT 0 > -> <TRUE> }T
+
+T{ 0 1 U< -> <TRUE> }T
+T{ 1 2 U< -> <TRUE> }T
+T{ 0 MID-UINT U< -> <TRUE> }T
+T{ 0 MAX-UINT U< -> <TRUE> }T
+T{ MID-UINT MAX-UINT U< -> <TRUE> }T
+T{ 0 0 U< -> <FALSE> }T
+T{ 1 1 U< -> <FALSE> }T
+T{ 1 0 U< -> <FALSE> }T
+T{ 2 1 U< -> <FALSE> }T
+T{ MID-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT MID-UINT U< -> <FALSE> }T
+
+T{ 0 1 MIN -> 0 }T
+T{ 1 2 MIN -> 1 }T
+T{ -1 0 MIN -> -1 }T
+T{ -1 1 MIN -> -1 }T
+T{ MIN-INT 0 MIN -> MIN-INT }T
+T{ MIN-INT MAX-INT MIN -> MIN-INT }T
+T{ 0 MAX-INT MIN -> 0 }T
+T{ 0 0 MIN -> 0 }T
+T{ 1 1 MIN -> 1 }T
+T{ 1 0 MIN -> 0 }T
+T{ 2 1 MIN -> 1 }T
+T{ 0 -1 MIN -> -1 }T
+T{ 1 -1 MIN -> -1 }T
+T{ 0 MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT 0 MIN -> 0 }T
+
+T{ 0 1 MAX -> 1 }T
+T{ 1 2 MAX -> 2 }T
+T{ -1 0 MAX -> 0 }T
+T{ -1 1 MAX -> 1 }T
+T{ MIN-INT 0 MAX -> 0 }T
+T{ MIN-INT MAX-INT MAX -> MAX-INT }T
+T{ 0 MAX-INT MAX -> MAX-INT }T
+T{ 0 0 MAX -> 0 }T
+T{ 1 1 MAX -> 1 }T
+T{ 1 0 MAX -> 1 }T
+T{ 2 1 MAX -> 2 }T
+T{ 0 -1 MAX -> 0 }T
+T{ 1 -1 MAX -> 1 }T
+T{ 0 MIN-INT MAX -> 0 }T
+T{ MAX-INT MIN-INT MAX -> MAX-INT }T
+T{ MAX-INT 0 MAX -> MAX-INT }T
+
+\ ------------------------------------------------------------------------
+TESTING STACK OPS: 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP
+
+T{ 1 2 2DROP -> }T
+T{ 1 2 2DUP -> 1 2 1 2 }T
+T{ 1 2 3 4 2OVER -> 1 2 3 4 1 2 }T
+T{ 1 2 3 4 2SWAP -> 3 4 1 2 }T
+T{ 0 ?DUP -> 0 }T
+T{ 1 ?DUP -> 1 1 }T
+T{ -1 ?DUP -> -1 -1 }T
+T{ DEPTH -> 0 }T
+T{ 0 DEPTH -> 0 1 }T
+T{ 0 1 DEPTH -> 0 1 2 }T
+T{ 0 DROP -> }T
+T{ 1 2 DROP -> 1 }T
+T{ 1 DUP -> 1 1 }T
+T{ 1 2 OVER -> 1 2 1 }T
+T{ 1 2 3 ROT -> 2 3 1 }T
+T{ 1 2 SWAP -> 2 1 }T
+
+\ ------------------------------------------------------------------------
+TESTING >R R> R@
+
+T{ : GR1 >R R> ; -> }T
+T{ : GR2 >R R@ R> DROP ; -> }T
+T{ 123 GR1 -> 123 }T
+T{ 123 GR2 -> 123 }T
+T{ 1S GR1 -> 1S }T ( RETURN STACK HOLDS CELLS )
+
+\ ------------------------------------------------------------------------
+TESTING ADD/SUBTRACT: + - 1+ 1- ABS NEGATE
+
+T{ 0 5 + -> 5 }T
+T{ 5 0 + -> 5 }T
+T{ 0 -5 + -> -5 }T
+T{ -5 0 + -> -5 }T
+T{ 1 2 + -> 3 }T
+T{ 1 -2 + -> -1 }T
+T{ -1 2 + -> 1 }T
+T{ -1 -2 + -> -3 }T
+T{ -1 1 + -> 0 }T
+T{ MID-UINT 1 + -> MID-UINT+1 }T
+
+T{ 0 5 - -> -5 }T
+T{ 5 0 - -> 5 }T
+T{ 0 -5 - -> 5 }T
+T{ -5 0 - -> -5 }T
+T{ 1 2 - -> -1 }T
+T{ 1 -2 - -> 3 }T
+T{ -1 2 - -> -3 }T
+T{ -1 -2 - -> 1 }T
+T{ 0 1 - -> -1 }T
+T{ MID-UINT+1 1 - -> MID-UINT }T
+
+T{ 0 1+ -> 1 }T
+T{ -1 1+ -> 0 }T
+T{ 1 1+ -> 2 }T
+T{ MID-UINT 1+ -> MID-UINT+1 }T
+
+T{ 2 1- -> 1 }T
+T{ 1 1- -> 0 }T
+T{ 0 1- -> -1 }T
+T{ MID-UINT+1 1- -> MID-UINT }T
+
+T{ 0 NEGATE -> 0 }T
+T{ 1 NEGATE -> -1 }T
+T{ -1 NEGATE -> 1 }T
+T{ 2 NEGATE -> -2 }T
+T{ -2 NEGATE -> 2 }T
+
+T{ 0 ABS -> 0 }T
+T{ 1 ABS -> 1 }T
+T{ -1 ABS -> 1 }T
+T{ MIN-INT ABS -> MID-UINT+1 }T
+
+\ ------------------------------------------------------------------------
+TESTING MULTIPLY: S>D * M* UM*
+
+T{ 0 S>D -> 0 0 }T
+T{ 1 S>D -> 1 0 }T
+T{ 2 S>D -> 2 0 }T
+T{ -1 S>D -> -1 -1 }T
+T{ -2 S>D -> -2 -1 }T
+T{ MIN-INT S>D -> MIN-INT -1 }T
+T{ MAX-INT S>D -> MAX-INT 0 }T
+
+T{ 0 0 M* -> 0 S>D }T
+T{ 0 1 M* -> 0 S>D }T
+T{ 1 0 M* -> 0 S>D }T
+T{ 1 2 M* -> 2 S>D }T
+T{ 2 1 M* -> 2 S>D }T
+T{ 3 3 M* -> 9 S>D }T
+T{ -3 3 M* -> -9 S>D }T
+T{ 3 -3 M* -> -9 S>D }T
+T{ -3 -3 M* -> 9 S>D }T
+T{ 0 MIN-INT M* -> 0 S>D }T
+T{ 1 MIN-INT M* -> MIN-INT S>D }T
+T{ 2 MIN-INT M* -> 0 1S }T
+T{ 0 MAX-INT M* -> 0 S>D }T
+T{ 1 MAX-INT M* -> MAX-INT S>D }T
+T{ 2 MAX-INT M* -> MAX-INT 1 LSHIFT 0 }T
+T{ MIN-INT MIN-INT M* -> 0 MSB 1 RSHIFT }T
+T{ MAX-INT MIN-INT M* -> MSB MSB 2/ }T
+T{ MAX-INT MAX-INT M* -> 1 MSB 2/ INVERT }T
+
+T{ 0 0 * -> 0 }T \ TEST IDENTITIES
+T{ 0 1 * -> 0 }T
+T{ 1 0 * -> 0 }T
+T{ 1 2 * -> 2 }T
+T{ 2 1 * -> 2 }T
+T{ 3 3 * -> 9 }T
+T{ -3 3 * -> -9 }T
+T{ 3 -3 * -> -9 }T
+T{ -3 -3 * -> 9 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 * -> MID-UINT+1 }T
+T{ MID-UINT+1 2 RSHIFT 4 * -> MID-UINT+1 }T
+T{ MID-UINT+1 1 RSHIFT MID-UINT+1 OR 2 * -> MID-UINT+1 }T
+
+T{ 0 0 UM* -> 0 0 }T
+T{ 0 1 UM* -> 0 0 }T
+T{ 1 0 UM* -> 0 0 }T
+T{ 1 2 UM* -> 2 0 }T
+T{ 2 1 UM* -> 2 0 }T
+T{ 3 3 UM* -> 9 0 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 UM* -> MID-UINT+1 0 }T
+T{ MID-UINT+1 2 UM* -> 0 1 }T
+T{ MID-UINT+1 4 UM* -> 0 2 }T
+T{ 1S 2 UM* -> 1S 1 LSHIFT 1 }T
+T{ MAX-UINT MAX-UINT UM* -> 1 1 INVERT }T
+
+\ ------------------------------------------------------------------------
+TESTING DIVIDE: FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD
+
+T{ 0 S>D 1 FM/MOD -> 0 0 }T
+T{ 1 S>D 1 FM/MOD -> 0 1 }T
+T{ 2 S>D 1 FM/MOD -> 0 2 }T
+T{ -1 S>D 1 FM/MOD -> 0 -1 }T
+T{ -2 S>D 1 FM/MOD -> 0 -2 }T
+T{ 0 S>D -1 FM/MOD -> 0 0 }T
+T{ 1 S>D -1 FM/MOD -> 0 -1 }T
+T{ 2 S>D -1 FM/MOD -> 0 -2 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -1 FM/MOD -> 0 2 }T
+T{ 2 S>D 2 FM/MOD -> 0 1 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -2 FM/MOD -> 0 1 }T
+T{ 7 S>D 3 FM/MOD -> 1 2 }T
+T{ 7 S>D -3 FM/MOD -> -2 -3 }T
+T{ -7 S>D 3 FM/MOD -> 2 -3 }T
+T{ -7 S>D -3 FM/MOD -> -1 2 }T
+T{ MAX-INT S>D 1 FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT FM/MOD -> 0 1 }T
+T{ MIN-INT S>D MIN-INT FM/MOD -> 0 1 }T
+T{ 1S 1 4 FM/MOD -> 3 MAX-INT }T
+T{ 1 MIN-INT M* 1 FM/MOD -> 0 MIN-INT }T
+T{ 1 MIN-INT M* MIN-INT FM/MOD -> 0 1 }T
+T{ 2 MIN-INT M* 2 FM/MOD -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT FM/MOD -> 0 2 }T
+T{ 1 MAX-INT M* 1 FM/MOD -> 0 MAX-INT }T
+T{ 1 MAX-INT M* MAX-INT FM/MOD -> 0 1 }T
+T{ 2 MAX-INT M* 2 FM/MOD -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT FM/MOD -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT FM/MOD -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT FM/MOD -> 0 MAX-INT }T
+
+T{ 0 S>D 1 SM/REM -> 0 0 }T
+T{ 1 S>D 1 SM/REM -> 0 1 }T
+T{ 2 S>D 1 SM/REM -> 0 2 }T
+T{ -1 S>D 1 SM/REM -> 0 -1 }T
+T{ -2 S>D 1 SM/REM -> 0 -2 }T
+T{ 0 S>D -1 SM/REM -> 0 0 }T
+T{ 1 S>D -1 SM/REM -> 0 -1 }T
+T{ 2 S>D -1 SM/REM -> 0 -2 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -1 SM/REM -> 0 2 }T
+T{ 2 S>D 2 SM/REM -> 0 1 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -2 SM/REM -> 0 1 }T
+T{ 7 S>D 3 SM/REM -> 1 2 }T
+T{ 7 S>D -3 SM/REM -> 1 -2 }T
+T{ -7 S>D 3 SM/REM -> -1 -2 }T
+T{ -7 S>D -3 SM/REM -> -1 2 }T
+T{ MAX-INT S>D 1 SM/REM -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 SM/REM -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT SM/REM -> 0 1 }T
+T{ MIN-INT S>D MIN-INT SM/REM -> 0 1 }T
+T{ 1S 1 4 SM/REM -> 3 MAX-INT }T
+T{ 2 MIN-INT M* 2 SM/REM -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT SM/REM -> 0 2 }T
+T{ 2 MAX-INT M* 2 SM/REM -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT SM/REM -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT SM/REM -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT SM/REM -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT SM/REM -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT SM/REM -> 0 MAX-INT }T
+
+T{ 0 0 1 UM/MOD -> 0 0 }T
+T{ 1 0 1 UM/MOD -> 0 1 }T
+T{ 1 0 2 UM/MOD -> 1 0 }T
+T{ 3 0 2 UM/MOD -> 1 1 }T
+T{ MAX-UINT 2 UM* 2 UM/MOD -> 0 MAX-UINT }T
+T{ MAX-UINT 2 UM* MAX-UINT UM/MOD -> 0 2 }T
+T{ MAX-UINT MAX-UINT UM* MAX-UINT UM/MOD -> 0 MAX-UINT }T
+
+: IFFLOORED
+ [ -3 2 / -2 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+: IFSYM
+ [ -3 2 / -1 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+\ THE SYSTEM MIGHT DO EITHER FLOORED OR SYMMETRIC DIVISION.
+\ SINCE WE HAVE ALREADY TESTED M*, FM/MOD, AND SM/REM WE CAN USE THEM IN TEST.
+
+IFFLOORED : T/MOD >R S>D R> FM/MOD ;
+IFFLOORED : T/ T/MOD SWAP DROP ;
+IFFLOORED : TMOD T/MOD DROP ;
+IFFLOORED : T*/MOD >R M* R> FM/MOD ;
+IFFLOORED : T*/ T*/MOD SWAP DROP ;
+IFSYM : T/MOD >R S>D R> SM/REM ;
+IFSYM : T/ T/MOD SWAP DROP ;
+IFSYM : TMOD T/MOD DROP ;
+IFSYM : T*/MOD >R M* R> SM/REM ;
+IFSYM : T*/ T*/MOD SWAP DROP ;
+
+T{ 0 1 /MOD -> 0 1 T/MOD }T
+T{ 1 1 /MOD -> 1 1 T/MOD }T
+T{ 2 1 /MOD -> 2 1 T/MOD }T
+T{ -1 1 /MOD -> -1 1 T/MOD }T
+T{ -2 1 /MOD -> -2 1 T/MOD }T
+T{ 0 -1 /MOD -> 0 -1 T/MOD }T
+T{ 1 -1 /MOD -> 1 -1 T/MOD }T
+T{ 2 -1 /MOD -> 2 -1 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -1 /MOD -> -2 -1 T/MOD }T
+T{ 2 2 /MOD -> 2 2 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -2 /MOD -> -2 -2 T/MOD }T
+T{ 7 3 /MOD -> 7 3 T/MOD }T
+T{ 7 -3 /MOD -> 7 -3 T/MOD }T
+T{ -7 3 /MOD -> -7 3 T/MOD }T
+T{ -7 -3 /MOD -> -7 -3 T/MOD }T
+T{ MAX-INT 1 /MOD -> MAX-INT 1 T/MOD }T
+T{ MIN-INT 1 /MOD -> MIN-INT 1 T/MOD }T
+T{ MAX-INT MAX-INT /MOD -> MAX-INT MAX-INT T/MOD }T
+T{ MIN-INT MIN-INT /MOD -> MIN-INT MIN-INT T/MOD }T
+
+T{ 0 1 / -> 0 1 T/ }T
+T{ 1 1 / -> 1 1 T/ }T
+T{ 2 1 / -> 2 1 T/ }T
+T{ -1 1 / -> -1 1 T/ }T
+T{ -2 1 / -> -2 1 T/ }T
+T{ 0 -1 / -> 0 -1 T/ }T
+T{ 1 -1 / -> 1 -1 T/ }T
+T{ 2 -1 / -> 2 -1 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -1 / -> -2 -1 T/ }T
+T{ 2 2 / -> 2 2 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -2 / -> -2 -2 T/ }T
+T{ 7 3 / -> 7 3 T/ }T
+T{ 7 -3 / -> 7 -3 T/ }T
+T{ -7 3 / -> -7 3 T/ }T
+T{ -7 -3 / -> -7 -3 T/ }T
+T{ MAX-INT 1 / -> MAX-INT 1 T/ }T
+T{ MIN-INT 1 / -> MIN-INT 1 T/ }T
+T{ MAX-INT MAX-INT / -> MAX-INT MAX-INT T/ }T
+T{ MIN-INT MIN-INT / -> MIN-INT MIN-INT T/ }T
+
+T{ 0 1 MOD -> 0 1 TMOD }T
+T{ 1 1 MOD -> 1 1 TMOD }T
+T{ 2 1 MOD -> 2 1 TMOD }T
+T{ -1 1 MOD -> -1 1 TMOD }T
+T{ -2 1 MOD -> -2 1 TMOD }T
+T{ 0 -1 MOD -> 0 -1 TMOD }T
+T{ 1 -1 MOD -> 1 -1 TMOD }T
+T{ 2 -1 MOD -> 2 -1 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -1 MOD -> -2 -1 TMOD }T
+T{ 2 2 MOD -> 2 2 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -2 MOD -> -2 -2 TMOD }T
+T{ 7 3 MOD -> 7 3 TMOD }T
+T{ 7 -3 MOD -> 7 -3 TMOD }T
+T{ -7 3 MOD -> -7 3 TMOD }T
+T{ -7 -3 MOD -> -7 -3 TMOD }T
+T{ MAX-INT 1 MOD -> MAX-INT 1 TMOD }T
+T{ MIN-INT 1 MOD -> MIN-INT 1 TMOD }T
+T{ MAX-INT MAX-INT MOD -> MAX-INT MAX-INT TMOD }T
+T{ MIN-INT MIN-INT MOD -> MIN-INT MIN-INT TMOD }T
+
+T{ 0 2 1 */ -> 0 2 1 T*/ }T
+T{ 1 2 1 */ -> 1 2 1 T*/ }T
+T{ 2 2 1 */ -> 2 2 1 T*/ }T
+T{ -1 2 1 */ -> -1 2 1 T*/ }T
+T{ -2 2 1 */ -> -2 2 1 T*/ }T
+T{ 0 2 -1 */ -> 0 2 -1 T*/ }T
+T{ 1 2 -1 */ -> 1 2 -1 T*/ }T
+T{ 2 2 -1 */ -> 2 2 -1 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -1 */ -> -2 2 -1 T*/ }T
+T{ 2 2 2 */ -> 2 2 2 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -2 */ -> -2 2 -2 T*/ }T
+T{ 7 2 3 */ -> 7 2 3 T*/ }T
+T{ 7 2 -3 */ -> 7 2 -3 T*/ }T
+T{ -7 2 3 */ -> -7 2 3 T*/ }T
+T{ -7 2 -3 */ -> -7 2 -3 T*/ }T
+T{ MAX-INT 2 MAX-INT */ -> MAX-INT 2 MAX-INT T*/ }T
+T{ MIN-INT 2 MIN-INT */ -> MIN-INT 2 MIN-INT T*/ }T
+
+T{ 0 2 1 */MOD -> 0 2 1 T*/MOD }T
+T{ 1 2 1 */MOD -> 1 2 1 T*/MOD }T
+T{ 2 2 1 */MOD -> 2 2 1 T*/MOD }T
+T{ -1 2 1 */MOD -> -1 2 1 T*/MOD }T
+T{ -2 2 1 */MOD -> -2 2 1 T*/MOD }T
+T{ 0 2 -1 */MOD -> 0 2 -1 T*/MOD }T
+T{ 1 2 -1 */MOD -> 1 2 -1 T*/MOD }T
+T{ 2 2 -1 */MOD -> 2 2 -1 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -1 */MOD -> -2 2 -1 T*/MOD }T
+T{ 2 2 2 */MOD -> 2 2 2 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -2 */MOD -> -2 2 -2 T*/MOD }T
+T{ 7 2 3 */MOD -> 7 2 3 T*/MOD }T
+T{ 7 2 -3 */MOD -> 7 2 -3 T*/MOD }T
+T{ -7 2 3 */MOD -> -7 2 3 T*/MOD }T
+T{ -7 2 -3 */MOD -> -7 2 -3 T*/MOD }T
+T{ MAX-INT 2 MAX-INT */MOD -> MAX-INT 2 MAX-INT T*/MOD }T
+T{ MIN-INT 2 MIN-INT */MOD -> MIN-INT 2 MIN-INT T*/MOD }T
+
+\ ------------------------------------------------------------------------
+TESTING HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2! ALIGN ALIGNED +! ALLOT
+
+HERE 1 ALLOT
+HERE
+CONSTANT 2NDA
+CONSTANT 1STA
+T{ 1STA 2NDA U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STA 1+ -> 2NDA }T \ ... BY ONE ADDRESS UNIT
+( MISSING TEST: NEGATIVE ALLOT )
+
+HERE 1 ,
+HERE 2 ,
+CONSTANT 2ND
+CONSTANT 1ST
+T{ 1ST 2ND U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1ST CELL+ -> 2ND }T \ ... BY ONE CELL
+T{ 1ST 1 CELLS + -> 2ND }T
+T{ 1ST @ 2ND @ -> 1 2 }T
+T{ 5 1ST ! -> }T
+T{ 1ST @ 2ND @ -> 5 2 }T
+T{ 6 2ND ! -> }T
+T{ 1ST @ 2ND @ -> 5 6 }T
+T{ 1ST 2@ -> 6 5 }T
+T{ 2 1 1ST 2! -> }T
+T{ 1ST 2@ -> 2 1 }T
+T{ 1S 1ST ! 1ST @ -> 1S }T \ CAN STORE CELL-WIDE VALUE
+
+HERE 1 C,
+HERE 2 C,
+CONSTANT 2NDC
+CONSTANT 1STC
+T{ 1STC 2NDC U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STC CHAR+ -> 2NDC }T \ ... BY ONE CHAR
+T{ 1STC 1 CHARS + -> 2NDC }T
+T{ 1STC C@ 2NDC C@ -> 1 2 }T
+T{ 3 1STC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 2 }T
+T{ 4 2NDC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 4 }T
+
+ALIGN 1 ALLOT HERE ALIGN HERE 3 CELLS ALLOT
+CONSTANT A-ADDR CONSTANT UA-ADDR
+T{ UA-ADDR ALIGNED -> A-ADDR }T
+T{ 1 A-ADDR C! A-ADDR C@ -> 1 }T
+T{ 1234 A-ADDR ! A-ADDR @ -> 1234 }T
+T{ 123 456 A-ADDR 2! A-ADDR 2@ -> 123 456 }T
+T{ 2 A-ADDR CHAR+ C! A-ADDR CHAR+ C@ -> 2 }T
+T{ 3 A-ADDR CELL+ C! A-ADDR CELL+ C@ -> 3 }T
+T{ 1234 A-ADDR CELL+ ! A-ADDR CELL+ @ -> 1234 }T
+T{ 123 456 A-ADDR CELL+ 2! A-ADDR CELL+ 2@ -> 123 456 }T
+
+: BITS ( X -- U )
+ 0 SWAP BEGIN DUP WHILE DUP MSB AND IF >R 1+ R> THEN 2* REPEAT DROP ;
+( CHARACTERS >= 1 AU, <= SIZE OF CELL, >= 8 BITS )
+T{ 1 CHARS 1 < -> <FALSE> }T
+T{ 1 CHARS 1 CELLS > -> <FALSE> }T
+( TBD: HOW TO FIND NUMBER OF BITS? )
+
+( CELLS >= 1 AU, INTEGRAL MULTIPLE OF CHAR SIZE, >= 16 BITS )
+T{ 1 CELLS 1 < -> <FALSE> }T
+T{ 1 CELLS 1 CHARS MOD -> 0 }T
+T{ 1S BITS 10 < -> <FALSE> }T
+
+T{ 0 1ST ! -> }T
+T{ 1 1ST +! -> }T
+T{ 1ST @ -> 1 }T
+T{ -1 1ST +! 1ST @ -> 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING CHAR [CHAR] [ ] BL S"
+
+T{ BL -> 20 }T
+T{ CHAR X -> 58 }T
+T{ CHAR HELLO -> 48 }T
+T{ : GC1 [CHAR] X ; -> }T
+T{ : GC2 [CHAR] HELLO ; -> }T
+T{ GC1 -> 58 }T
+T{ GC2 -> 48 }T
+T{ : GC3 [ GC1 ] LITERAL ; -> }T
+T{ GC3 -> 58 }T
+T{ : GC4 S" XY" ; -> }T
+T{ GC4 SWAP DROP -> 2 }T
+T{ GC4 DROP DUP C@ SWAP CHAR+ C@ -> 58 59 }T
+
+\ ------------------------------------------------------------------------
+TESTING ' ['] FIND EXECUTE IMMEDIATE COUNT LITERAL POSTPONE STATE
+
+T{ : GT1 123 ; -> }T
+T{ ' GT1 EXECUTE -> 123 }T
+T{ : GT2 ['] GT1 ; IMMEDIATE -> }T
+T{ GT2 EXECUTE -> 123 }T
+HERE 3 C, CHAR G C, CHAR T C, CHAR 1 C, CONSTANT GT1STRING
+HERE 3 C, CHAR G C, CHAR T C, CHAR 2 C, CONSTANT GT2STRING
+T{ GT1STRING FIND -> ' GT1 -1 }T
+T{ GT2STRING FIND -> ' GT2 1 }T
+( HOW TO SEARCH FOR NON-EXISTENT WORD? )
+T{ : GT3 GT2 LITERAL ; -> }T
+T{ GT3 -> ' GT1 }T
+T{ GT1STRING COUNT -> GT1STRING CHAR+ 3 }T
+
+T{ : GT4 POSTPONE GT1 ; IMMEDIATE -> }T
+T{ : GT5 GT4 ; -> }T
+T{ GT5 -> 123 }T
+T{ : GT6 345 ; IMMEDIATE -> }T
+T{ : GT7 POSTPONE GT6 ; -> }T
+T{ GT7 -> 345 }T
+
+T{ : GT8 STATE @ ; IMMEDIATE -> }T
+T{ GT8 -> 0 }T
+T{ : GT9 GT8 LITERAL ; -> }T
+T{ GT9 0= -> <FALSE> }T
+
+\ ------------------------------------------------------------------------
+TESTING IF ELSE THEN BEGIN WHILE REPEAT UNTIL RECURSE
+
+T{ : GI1 IF 123 THEN ; -> }T
+T{ : GI2 IF 123 ELSE 234 THEN ; -> }T
+T{ 0 GI1 -> }T
+T{ 1 GI1 -> 123 }T
+T{ -1 GI1 -> 123 }T
+T{ 0 GI2 -> 234 }T
+T{ 1 GI2 -> 123 }T
+T{ -1 GI1 -> 123 }T
+
+T{ : GI3 BEGIN DUP 5 < WHILE DUP 1+ REPEAT ; -> }T
+T{ 0 GI3 -> 0 1 2 3 4 5 }T
+T{ 4 GI3 -> 4 5 }T
+T{ 5 GI3 -> 5 }T
+T{ 6 GI3 -> 6 }T
+
+T{ : GI4 BEGIN DUP 1+ DUP 5 > UNTIL ; -> }T
+T{ 3 GI4 -> 3 4 5 6 }T
+T{ 5 GI4 -> 5 6 }T
+T{ 6 GI4 -> 6 7 }T
+
+T{ : GI5 BEGIN DUP 2 > WHILE DUP 5 < WHILE DUP 1+ REPEAT 123 ELSE 345 THEN ; -> }T
+T{ 1 GI5 -> 1 345 }T
+T{ 2 GI5 -> 2 345 }T
+T{ 3 GI5 -> 3 4 5 123 }T
+T{ 4 GI5 -> 4 5 123 }T
+T{ 5 GI5 -> 5 123 }T
+
+T{ : GI6 ( N -- 0,1,..N ) DUP IF DUP >R 1- RECURSE R> THEN ; -> }T
+T{ 0 GI6 -> 0 }T
+T{ 1 GI6 -> 0 1 }T
+T{ 2 GI6 -> 0 1 2 }T
+T{ 3 GI6 -> 0 1 2 3 }T
+T{ 4 GI6 -> 0 1 2 3 4 }T
+
+\ ------------------------------------------------------------------------
+TESTING DO LOOP +LOOP I J UNLOOP LEAVE EXIT
+
+T{ : GD1 DO I LOOP ; -> }T
+T{ 4 1 GD1 -> 1 2 3 }T
+T{ 2 -1 GD1 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD1 -> MID-UINT }T
+
+T{ : GD2 DO I -1 +LOOP ; -> }T
+T{ 1 4 GD2 -> 4 3 2 1 }T
+T{ -1 2 GD2 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD2 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD3 DO 1 0 DO J LOOP LOOP ; -> }T
+T{ 4 1 GD3 -> 1 2 3 }T
+T{ 2 -1 GD3 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD3 -> MID-UINT }T
+
+T{ : GD4 DO 1 0 DO J LOOP -1 +LOOP ; -> }T
+T{ 1 4 GD4 -> 4 3 2 1 }T
+T{ -1 2 GD4 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD4 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD5 123 SWAP 0 DO I 4 > IF DROP 234 LEAVE THEN LOOP ; -> }T
+T{ 1 GD5 -> 123 }T
+T{ 5 GD5 -> 123 }T
+T{ 6 GD5 -> 234 }T
+
+T{ : GD6 ( PAT: T{0 0}T,T{0 0}TT{1 0}TT{1 1}T,T{0 0}TT{1 0}TT{1 1}TT{2 0}TT{2 1}TT{2 2}T )
+ 0 SWAP 0 DO
+ I 1+ 0 DO I J + 3 = IF I UNLOOP I UNLOOP EXIT THEN 1+ LOOP
+ LOOP ; -> }T
+T{ 1 GD6 -> 1 }T
+T{ 2 GD6 -> 3 }T
+T{ 3 GD6 -> 4 1 2 }T
+
+\ ------------------------------------------------------------------------
+TESTING DEFINING WORDS: : ; CONSTANT VARIABLE CREATE DOES> >BODY
+
+T{ 123 CONSTANT X123 -> }T
+T{ X123 -> 123 }T
+T{ : EQU CONSTANT ; -> }T
+T{ X123 EQU Y123 -> }T
+T{ Y123 -> 123 }T
+
+T{ VARIABLE V1 -> }T
+T{ 123 V1 ! -> }T
+T{ V1 @ -> 123 }T
+
+T{ : NOP : POSTPONE ; ; -> }T
+T{ NOP NOP1 NOP NOP2 -> }T
+T{ NOP1 -> }T
+T{ NOP2 -> }T
+
+T{ : DOES1 DOES> @ 1 + ; -> }T
+T{ : DOES2 DOES> @ 2 + ; -> }T
+T{ CREATE CR1 -> }T
+T{ CR1 -> HERE }T
+T{ ' CR1 >BODY -> HERE }T
+T{ 1 , -> }T
+T{ CR1 @ -> 1 }T
+T{ DOES1 -> }T
+T{ CR1 -> 2 }T
+T{ DOES2 -> }T
+T{ CR1 -> 3 }T
+
+T{ : WEIRD: CREATE DOES> 1 + DOES> 2 + ; -> }T
+T{ WEIRD: W1 -> }T
+T{ ' W1 >BODY -> HERE }T
+T{ W1 -> HERE 1 + }T
+T{ W1 -> HERE 2 + }T
+
+\ ------------------------------------------------------------------------
+TESTING EVALUATE
+
+: GE1 S" 123" ; IMMEDIATE
+: GE2 S" 123 1+" ; IMMEDIATE
+: GE3 S" : GE4 345 ;" ;
+: GE5 EVALUATE ; IMMEDIATE
+
+T{ GE1 EVALUATE -> 123 }T ( TEST EVALUATE IN INTERP. STATE )
+T{ GE2 EVALUATE -> 124 }T
+T{ GE3 EVALUATE -> }T
+T{ GE4 -> 345 }T
+
+T{ : GE6 GE1 GE5 ; -> }T ( TEST EVALUATE IN COMPILE STATE )
+T{ GE6 -> 123 }T
+T{ : GE7 GE2 GE5 ; -> }T
+T{ GE7 -> 124 }T
+
+\ ------------------------------------------------------------------------
+TESTING SOURCE >IN WORD
+
+: GS1 S" SOURCE" 2DUP EVALUATE
+ >R SWAP >R = R> R> = ;
+T{ GS1 -> <TRUE> <TRUE> }T
+
+VARIABLE SCANS
+: RESCAN? -1 SCANS +! SCANS @ IF 0 >IN ! THEN ;
+
+T{ 2 SCANS !
+345 RESCAN?
+-> 345 345 }T
+
+: GS2 5 SCANS ! S" 123 RESCAN?" EVALUATE ;
+T{ GS2 -> 123 123 123 123 123 }T
+
+: GS3 WORD COUNT SWAP C@ ;
+T{ BL GS3 HELLO -> 5 CHAR H }T
+T{ CHAR " GS3 GOODBYE" -> 7 CHAR G }T
+T{ BL GS3
+DROP -> 0 }T \ BLANK LINE RETURN ZERO-LENGTH STRING
+
+: GS4 SOURCE >IN ! DROP ;
+T{ GS4 123 456
+-> }T
+
+\ ------------------------------------------------------------------------
+TESTING <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL
+
+: S= \ ( ADDR1 C1 ADDR2 C2 -- T/F ) COMPARE TWO STRINGS.
+ >R SWAP R@ = IF \ MAKE SURE STRINGS HAVE SAME LENGTH
+ R> ?DUP IF \ IF NON-EMPTY STRINGS
+ 0 DO
+ OVER C@ OVER C@ - IF
+ 2DROP <FALSE> UNLOOP EXIT THEN
+ SWAP CHAR+ SWAP CHAR+
+ LOOP
+ THEN
+ 2DROP <TRUE> \ IF WE GET HERE, STRINGS MATCH
+ ELSE
+ R> DROP 2DROP <FALSE> \ LENGTHS MISMATCH
+ THEN ;
+
+: GP1 <# 41 HOLD 42 HOLD 0 0 #> S" BA" S= ;
+T{ GP1 -> <TRUE> }T
+
+: GP2 <# -1 SIGN 0 SIGN -1 SIGN 0 0 #> S" --" S= ;
+T{ GP2 -> <TRUE> }T
+
+: GP3 <# 1 0 # # #> S" 01" S= ;
+T{ GP3 -> <TRUE> }T
+
+: GP4 <# 1 0 #S #> S" 1" S= ;
+T{ GP4 -> <TRUE> }T
+
+24 CONSTANT MAX-BASE \ BASE 2 .. 36
+: COUNT-BITS
+ 0 0 INVERT BEGIN DUP WHILE >R 1+ R> 2* REPEAT DROP ;
+COUNT-BITS 2* CONSTANT #BITS-UD \ NUMBER OF BITS IN UD
+
+: GP5
+ BASE @ <TRUE>
+ MAX-BASE 1+ 2 DO \ FOR EACH POSSIBLE BASE
+ I BASE ! \ TBD: ASSUMES BASE WORKS
+ I 0 <# #S #> S" 10" S= AND
+ LOOP
+ SWAP BASE ! ;
+T{ GP5 -> <TRUE> }T
+
+: GP6
+ BASE @ >R 2 BASE !
+ MAX-UINT MAX-UINT <# #S #> \ MAXIMUM UD TO BINARY
+ R> BASE ! \ S: C-ADDR U
+ DUP #BITS-UD = SWAP
+ 0 DO \ S: C-ADDR FLAG
+ OVER C@ [CHAR] 1 = AND \ ALL ONES
+ >R CHAR+ R>
+ LOOP SWAP DROP ;
+T{ GP6 -> <TRUE> }T
+
+: GP7
+ BASE @ >R MAX-BASE BASE !
+ <TRUE>
+ A 0 DO
+ I 0 <# #S #>
+ 1 = SWAP C@ I 30 + = AND AND
+ LOOP
+ MAX-BASE A DO
+ I 0 <# #S #>
+ 1 = SWAP C@ 41 I A - + = AND AND
+ LOOP
+ R> BASE ! ;
+
+T{ GP7 -> <TRUE> }T
+
+\ >NUMBER TESTS
+CREATE GN-BUF 0 C,
+: GN-STRING GN-BUF 1 ;
+: GN-CONSUMED GN-BUF CHAR+ 0 ;
+: GN' [CHAR] ' WORD CHAR+ C@ GN-BUF C! GN-STRING ;
+
+T{ 0 0 GN' 0' >NUMBER -> 0 0 GN-CONSUMED }T
+T{ 0 0 GN' 1' >NUMBER -> 1 0 GN-CONSUMED }T
+T{ 1 0 GN' 1' >NUMBER -> BASE @ 1+ 0 GN-CONSUMED }T
+T{ 0 0 GN' -' >NUMBER -> 0 0 GN-STRING }T \ SHOULD FAIL TO CONVERT THESE
+T{ 0 0 GN' +' >NUMBER -> 0 0 GN-STRING }T
+T{ 0 0 GN' .' >NUMBER -> 0 0 GN-STRING }T
+
+: >NUMBER-BASED
+ BASE @ >R BASE ! >NUMBER R> BASE ! ;
+
+T{ 0 0 GN' 2' 10 >NUMBER-BASED -> 2 0 GN-CONSUMED }T
+T{ 0 0 GN' 2' 2 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' F' 10 >NUMBER-BASED -> F 0 GN-CONSUMED }T
+T{ 0 0 GN' G' 10 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' G' MAX-BASE >NUMBER-BASED -> 10 0 GN-CONSUMED }T
+T{ 0 0 GN' Z' MAX-BASE >NUMBER-BASED -> 23 0 GN-CONSUMED }T
+
+: GN1 \ ( UD BASE -- UD' LEN ) UD SHOULD EQUAL UD' AND LEN SHOULD BE ZERO.
+ BASE @ >R BASE !
+ <# #S #>
+ 0 0 2SWAP >NUMBER SWAP DROP \ RETURN LENGTH ONLY
+ R> BASE ! ;
+T{ 0 0 2 GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 2 GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP 2 GN1 -> MAX-UINT DUP 0 }T
+T{ 0 0 MAX-BASE GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 MAX-BASE GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP MAX-BASE GN1 -> MAX-UINT DUP 0 }T
+
+: GN2 \ ( -- 16 10 )
+ BASE @ >R HEX BASE @ DECIMAL BASE @ R> BASE ! ;
+T{ GN2 -> 10 A }T
+
+\ ------------------------------------------------------------------------
+TESTING FILL MOVE
+
+CREATE FBUF 00 C, 00 C, 00 C,
+CREATE SBUF 12 C, 34 C, 56 C,
+: SEEBUF FBUF C@ FBUF CHAR+ C@ FBUF CHAR+ CHAR+ C@ ;
+
+T{ FBUF 0 20 FILL -> }T
+T{ SEEBUF -> 00 00 00 }T
+
+T{ FBUF 1 20 FILL -> }T
+T{ SEEBUF -> 20 00 00 }T
+
+T{ FBUF 3 20 FILL -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ FBUF FBUF 3 CHARS MOVE -> }T \ BIZARRE SPECIAL CASE
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 0 CHARS MOVE -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 1 CHARS MOVE -> }T
+T{ SEEBUF -> 12 20 20 }T
+
+T{ SBUF FBUF 3 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 56 }T
+
+T{ FBUF FBUF CHAR+ 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 12 34 }T
+
+T{ FBUF CHAR+ FBUF 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 34 }T
+
+\ ------------------------------------------------------------------------
+TESTING OUTPUT: . ." CR EMIT SPACE SPACES TYPE U.
+
+: OUTPUT-TEST
+ ." YOU SHOULD SEE THE STANDARD GRAPHIC CHARACTERS:" CR
+ 41 BL DO I EMIT LOOP CR
+ 61 41 DO I EMIT LOOP CR
+ 7F 61 DO I EMIT LOOP CR
+ ." YOU SHOULD SEE 0-9 SEPARATED BY A SPACE:" CR
+ 9 1+ 0 DO I . LOOP CR
+ ." YOU SHOULD SEE 0-9 (WITH NO SPACES):" CR
+ [CHAR] 9 1+ [CHAR] 0 DO I 0 SPACES EMIT LOOP CR
+ ." YOU SHOULD SEE A-G SEPARATED BY A SPACE:" CR
+ [CHAR] G 1+ [CHAR] A DO I EMIT SPACE LOOP CR
+ ." YOU SHOULD SEE 0-5 SEPARATED BY TWO SPACES:" CR
+ 5 1+ 0 DO I [CHAR] 0 + EMIT 2 SPACES LOOP CR
+ ." YOU SHOULD SEE TWO SEPARATE LINES:" CR
+ S" LINE 1" TYPE CR S" LINE 2" TYPE CR
+ ." YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:" CR
+ ." SIGNED: " MIN-INT . MAX-INT . CR
+ ." UNSIGNED: " 0 U. MAX-UINT U. CR
+;
+
+T{ OUTPUT-TEST -> }T
+\ ------------------------------------------------------------------------
+TESTING INPUT: ACCEPT
+
+CREATE ABUF 80 CHARS ALLOT
+
+: ACCEPT-TEST
+ CR ." PLEASE TYPE UP TO 80 CHARACTERS:" CR
+ ABUF 80 ACCEPT
+ CR ." RECEIVED: " [CHAR] " EMIT
+ ABUF SWAP TYPE [CHAR] " EMIT CR
+;
+
+T{ ACCEPT-TEST -> }T
+Vingt fois sur le métier remettez votre ouvrage, ...
+\ ------------------------------------------------------------------------
+TESTING DICTIONARY SEARCH RULES
+
+T{ : GDX 123 ; : GDX GDX 234 ; -> }T
+
+T{ GDX -> 123 234 }T
+
+CR .( End of Core word set tests) CR
+
+
+
+RST_STATE ; so ANS_COMPLEMENT_xx_MPY is conserved ;
+\ NOECHO ; if an error occurs, comment this line before new download to find it.
+
+
+\ From: John Hayes S1I
+\ Subject: tester.fr
+\ Date: Mon, 27 Nov 95 13:10:09 PST
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.1
+
+\ 22/1/09 The words { and } have been changed to T{ and }T respectively to
+\ agree with the Forth 200X file ttester.fs. This avoids clashes with
+\ locals using { ... } and the FSL use of }
+
+
+\ 13/05/14 jmt. added colorised error messages.
+
+
+
+ 0 CONSTANT FALSE
+-1 CONSTANT TRUE
+
+\ SET THE FOLLOWING FLAG TO TRUE FOR MORE VERBOSE OUTPUT; THIS MAY
+\ ALLOW YOU TO TELL WHICH TEST CAUSED YOUR SYSTEM TO HANG.
+VARIABLE VERBOSE
+ FALSE VERBOSE !
+\ TRUE VERBOSE !
+
+\ : EMPTY-STACK ( ... -- ) \ EMPTY STACK: HANDLES UNDERFLOWED STACK TOO.
+\ DEPTH ?DUP
+\ IF DUP 0< IF NEGATE 0
+\ DO 0 LOOP
+\ ELSE 0 DO DROP LOOP THEN
+\ THEN ;
+\
+\ : ERROR \ ( C-ADDR U -- ) DISPLAY AN ERROR MESSAGE FOLLOWED BY
+\ \ THE LINE THAT HAD THE ERROR.
+\ TYPE SOURCE TYPE CR \ DISPLAY LINE CORRESPONDING TO ERROR
+\ EMPTY-STACK \ THROW AWAY EVERY THING ELSE
+\ QUIT \ *** Uncomment this line to QUIT on an error
+\ ;
+
+VARIABLE ACTUAL-DEPTH \ STACK RECORD
+CREATE ACTUAL-RESULTS 20 CELLS ALLOT
+
+: T{ \ ( -- ) SYNTACTIC SUGAR.
+ ;
+
+: -> \ ( ... -- ) RECORD DEPTH AND CONTENT OF STACK.
+ DEPTH DUP ACTUAL-DEPTH ! \ RECORD DEPTH
+ ?DUP IF \ IF THERE IS SOMETHING ON STACK
+ 0 DO ACTUAL-RESULTS I CELLS + ! LOOP \ SAVE THEM
+ THEN ;
+
+: }T \ ( ... -- ) COMPARE STACK (EXPECTED) CONTENTS WITH SAVED
+ \ (ACTUAL) CONTENTS.
+ DEPTH ACTUAL-DEPTH @ = IF \ IF DEPTHS MATCH
+ DEPTH ?DUP IF \ IF THERE IS SOMETHING ON THE STACK
+ 0 DO \ FOR EACH STACK ITEM
+ ACTUAL-RESULTS I CELLS + @ \ COMPARE ACTUAL WITH EXPECTED
+\ = 0= IF S" INCORRECT RESULT: " ERROR LEAVE THEN \ jmt
+ = 0= IF ABORT" INCORRECT RESULT: " THEN \ jmt : colorised message
+ LOOP
+ THEN
+ ELSE \ DEPTH MISMATCH
+\ S" WRONG NUMBER OF RESULTS: " ERROR \ jmt
+ ABORT" WRONG NUMBER OF RESULTS: " \ jmt : colorised message
+ THEN ;
+
+: TESTING \ ( -- ) TALKING COMMENT.
+ SOURCE VERBOSE @
+ IF DUP >R TYPE CR R> >IN !
+ ELSE >IN ! DROP [CHAR] * EMIT
+ THEN ;
+
+\ From: John Hayes S1I
+\ Subject: core.fr
+\ Date: Mon, 27 Nov 95 13:10
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.2
+\ THIS PROGRAM TESTS THE CORE WORDS OF AN ANS FORTH SYSTEM.
+\ THE PROGRAM ASSUMES A TWO'S COMPLEMENT IMPLEMENTATION WHERE
+\ THE RANGE OF SIGNED NUMBERS IS -2^(N-1) ... 2^(N-1)-1 AND
+\ THE RANGE OF UNSIGNED NUMBERS IS 0 ... 2^(N)-1.
+\ I HAVEN'T FIGURED OUT HOW TO TEST KEY, QUIT, ABORT, OR ABORT"...
+\ I ALSO HAVEN'T THOUGHT OF A WAY TO TEST ENVIRONMENT?...
+
+CR
+TESTING CORE WORDS
+HEX
+
+\ ------------------------------------------------------------------------
+TESTING BASIC ASSUMPTIONS
+
+T{ -> }T \ START WITH CLEAN SLATE
+( TEST IF ANY BITS ARE SET; ANSWER IN BASE 1 )
+T{ : BITSSET? IF 0 0 ELSE 0 THEN ; -> }T
+T{ 0 BITSSET? -> 0 }T ( ZERO IS ALL BITS CLEAR )
+T{ 1 BITSSET? -> 0 0 }T ( OTHER NUMBER HAVE AT LEAST ONE BIT )
+T{ -1 BITSSET? -> 0 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING BOOLEANS: INVERT AND OR XOR
+
+T{ 0 0 AND -> 0 }T
+T{ 0 1 AND -> 0 }T
+T{ 1 0 AND -> 0 }T
+T{ 1 1 AND -> 1 }T
+
+T{ 0 INVERT 1 AND -> 1 }T
+T{ 1 INVERT 1 AND -> 0 }T
+
+0 CONSTANT 0S
+0 INVERT CONSTANT 1S
+
+T{ 0S INVERT -> 1S }T
+T{ 1S INVERT -> 0S }T
+
+T{ 0S 0S AND -> 0S }T
+T{ 0S 1S AND -> 0S }T
+T{ 1S 0S AND -> 0S }T
+T{ 1S 1S AND -> 1S }T
+
+T{ 0S 0S OR -> 0S }T
+T{ 0S 1S OR -> 1S }T
+T{ 1S 0S OR -> 1S }T
+T{ 1S 1S OR -> 1S }T
+
+T{ 0S 0S XOR -> 0S }T
+T{ 0S 1S XOR -> 1S }T
+T{ 1S 0S XOR -> 1S }T
+T{ 1S 1S XOR -> 0S }T
+
+\ ------------------------------------------------------------------------
+TESTING 2* 2/ LSHIFT RSHIFT
+
+( WE TRUST 1S, INVERT, AND BITSSET?; WE WILL CONFIRM RSHIFT LATER )
+1S 1 RSHIFT INVERT CONSTANT MSB
+T{ MSB BITSSET? -> 0 0 }T
+
+T{ 0S 2* -> 0S }T
+T{ 1 2* -> 2 }T
+T{ 4000 2* -> 8000 }T
+T{ 1S 2* 1 XOR -> 1S }T
+T{ MSB 2* -> 0S }T
+
+T{ 0S 2/ -> 0S }T
+T{ 1 2/ -> 0 }T
+T{ 4000 2/ -> 2000 }T
+T{ 1S 2/ -> 1S }T \ MSB PROPOGATED
+T{ 1S 1 XOR 2/ -> 1S }T
+T{ MSB 2/ MSB AND -> MSB }T
+
+T{ 1 0 LSHIFT -> 1 }T
+T{ 1 1 LSHIFT -> 2 }T
+T{ 1 2 LSHIFT -> 4 }T
+T{ 1 F LSHIFT -> 8000 }T \ BIGGEST GUARANTEED SHIFT
+T{ 1S 1 LSHIFT 1 XOR -> 1S }T
+T{ MSB 1 LSHIFT -> 0 }T
+
+T{ 1 0 RSHIFT -> 1 }T
+T{ 1 1 RSHIFT -> 0 }T
+T{ 2 1 RSHIFT -> 1 }T
+T{ 4 2 RSHIFT -> 1 }T
+T{ 8000 F RSHIFT -> 1 }T \ BIGGEST
+T{ MSB 1 RSHIFT MSB AND -> 0 }T \ RSHIFT ZERO FILLS MSBS
+T{ MSB 1 RSHIFT 2* -> MSB }T
+
+\ ------------------------------------------------------------------------
+TESTING COMPARISONS: 0= = 0< < > U< MIN MAX
+0 INVERT CONSTANT MAX-UINT
+0 INVERT 1 RSHIFT CONSTANT MAX-INT
+0 INVERT 1 RSHIFT INVERT CONSTANT MIN-INT
+0 INVERT 1 RSHIFT CONSTANT MID-UINT
+0 INVERT 1 RSHIFT INVERT CONSTANT MID-UINT+1
+
+0S CONSTANT <FALSE>
+1S CONSTANT <TRUE>
+
+T{ 0 0= -> <TRUE> }T
+T{ 1 0= -> <FALSE> }T
+T{ 2 0= -> <FALSE> }T
+T{ -1 0= -> <FALSE> }T
+T{ MAX-UINT 0= -> <FALSE> }T
+T{ MIN-INT 0= -> <FALSE> }T
+T{ MAX-INT 0= -> <FALSE> }T
+
+T{ 0 0 = -> <TRUE> }T
+T{ 1 1 = -> <TRUE> }T
+T{ -1 -1 = -> <TRUE> }T
+T{ 1 0 = -> <FALSE> }T
+T{ -1 0 = -> <FALSE> }T
+T{ 0 1 = -> <FALSE> }T
+T{ 0 -1 = -> <FALSE> }T
+
+T{ 0 0< -> <FALSE> }T
+T{ -1 0< -> <TRUE> }T
+T{ MIN-INT 0< -> <TRUE> }T
+T{ 1 0< -> <FALSE> }T
+T{ MAX-INT 0< -> <FALSE> }T
+
+T{ 0 1 < -> <TRUE> }T
+T{ 1 2 < -> <TRUE> }T
+T{ -1 0 < -> <TRUE> }T
+T{ -1 1 < -> <TRUE> }T
+T{ MIN-INT 0 < -> <TRUE> }T
+T{ MIN-INT MAX-INT < -> <TRUE> }T
+T{ 0 MAX-INT < -> <TRUE> }T
+T{ 0 0 < -> <FALSE> }T
+T{ 1 1 < -> <FALSE> }T
+T{ 1 0 < -> <FALSE> }T
+T{ 2 1 < -> <FALSE> }T
+T{ 0 -1 < -> <FALSE> }T
+T{ 1 -1 < -> <FALSE> }T
+T{ 0 MIN-INT < -> <FALSE> }T
+T{ MAX-INT MIN-INT < -> <FALSE> }T
+T{ MAX-INT 0 < -> <FALSE> }T
+
+T{ 0 1 > -> <FALSE> }T
+T{ 1 2 > -> <FALSE> }T
+T{ -1 0 > -> <FALSE> }T
+T{ -1 1 > -> <FALSE> }T
+T{ MIN-INT 0 > -> <FALSE> }T
+T{ MIN-INT MAX-INT > -> <FALSE> }T
+T{ 0 MAX-INT > -> <FALSE> }T
+T{ 0 0 > -> <FALSE> }T
+T{ 1 1 > -> <FALSE> }T
+T{ 1 0 > -> <TRUE> }T
+T{ 2 1 > -> <TRUE> }T
+T{ 0 -1 > -> <TRUE> }T
+T{ 1 -1 > -> <TRUE> }T
+T{ 0 MIN-INT > -> <TRUE> }T
+T{ MAX-INT MIN-INT > -> <TRUE> }T
+T{ MAX-INT 0 > -> <TRUE> }T
+
+T{ 0 1 U< -> <TRUE> }T
+T{ 1 2 U< -> <TRUE> }T
+T{ 0 MID-UINT U< -> <TRUE> }T
+T{ 0 MAX-UINT U< -> <TRUE> }T
+T{ MID-UINT MAX-UINT U< -> <TRUE> }T
+T{ 0 0 U< -> <FALSE> }T
+T{ 1 1 U< -> <FALSE> }T
+T{ 1 0 U< -> <FALSE> }T
+T{ 2 1 U< -> <FALSE> }T
+T{ MID-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT MID-UINT U< -> <FALSE> }T
+
+T{ 0 1 MIN -> 0 }T
+T{ 1 2 MIN -> 1 }T
+T{ -1 0 MIN -> -1 }T
+T{ -1 1 MIN -> -1 }T
+T{ MIN-INT 0 MIN -> MIN-INT }T
+T{ MIN-INT MAX-INT MIN -> MIN-INT }T
+T{ 0 MAX-INT MIN -> 0 }T
+T{ 0 0 MIN -> 0 }T
+T{ 1 1 MIN -> 1 }T
+T{ 1 0 MIN -> 0 }T
+T{ 2 1 MIN -> 1 }T
+T{ 0 -1 MIN -> -1 }T
+T{ 1 -1 MIN -> -1 }T
+T{ 0 MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT 0 MIN -> 0 }T
+
+T{ 0 1 MAX -> 1 }T
+T{ 1 2 MAX -> 2 }T
+T{ -1 0 MAX -> 0 }T
+T{ -1 1 MAX -> 1 }T
+T{ MIN-INT 0 MAX -> 0 }T
+T{ MIN-INT MAX-INT MAX -> MAX-INT }T
+T{ 0 MAX-INT MAX -> MAX-INT }T
+T{ 0 0 MAX -> 0 }T
+T{ 1 1 MAX -> 1 }T
+T{ 1 0 MAX -> 1 }T
+T{ 2 1 MAX -> 2 }T
+T{ 0 -1 MAX -> 0 }T
+T{ 1 -1 MAX -> 1 }T
+T{ 0 MIN-INT MAX -> 0 }T
+T{ MAX-INT MIN-INT MAX -> MAX-INT }T
+T{ MAX-INT 0 MAX -> MAX-INT }T
+
+\ ------------------------------------------------------------------------
+TESTING STACK OPS: 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP
+
+T{ 1 2 2DROP -> }T
+T{ 1 2 2DUP -> 1 2 1 2 }T
+T{ 1 2 3 4 2OVER -> 1 2 3 4 1 2 }T
+T{ 1 2 3 4 2SWAP -> 3 4 1 2 }T
+T{ 0 ?DUP -> 0 }T
+T{ 1 ?DUP -> 1 1 }T
+T{ -1 ?DUP -> -1 -1 }T
+T{ DEPTH -> 0 }T
+T{ 0 DEPTH -> 0 1 }T
+T{ 0 1 DEPTH -> 0 1 2 }T
+T{ 0 DROP -> }T
+T{ 1 2 DROP -> 1 }T
+T{ 1 DUP -> 1 1 }T
+T{ 1 2 OVER -> 1 2 1 }T
+T{ 1 2 3 ROT -> 2 3 1 }T
+T{ 1 2 SWAP -> 2 1 }T
+
+\ ------------------------------------------------------------------------
+TESTING >R R> R@
+
+T{ : GR1 >R R> ; -> }T
+T{ : GR2 >R R@ R> DROP ; -> }T
+T{ 123 GR1 -> 123 }T
+T{ 123 GR2 -> 123 }T
+T{ 1S GR1 -> 1S }T ( RETURN STACK HOLDS CELLS )
+
+\ ------------------------------------------------------------------------
+TESTING ADD/SUBTRACT: + - 1+ 1- ABS NEGATE
+
+T{ 0 5 + -> 5 }T
+T{ 5 0 + -> 5 }T
+T{ 0 -5 + -> -5 }T
+T{ -5 0 + -> -5 }T
+T{ 1 2 + -> 3 }T
+T{ 1 -2 + -> -1 }T
+T{ -1 2 + -> 1 }T
+T{ -1 -2 + -> -3 }T
+T{ -1 1 + -> 0 }T
+T{ MID-UINT 1 + -> MID-UINT+1 }T
+
+T{ 0 5 - -> -5 }T
+T{ 5 0 - -> 5 }T
+T{ 0 -5 - -> 5 }T
+T{ -5 0 - -> -5 }T
+T{ 1 2 - -> -1 }T
+T{ 1 -2 - -> 3 }T
+T{ -1 2 - -> -3 }T
+T{ -1 -2 - -> 1 }T
+T{ 0 1 - -> -1 }T
+T{ MID-UINT+1 1 - -> MID-UINT }T
+
+T{ 0 1+ -> 1 }T
+T{ -1 1+ -> 0 }T
+T{ 1 1+ -> 2 }T
+T{ MID-UINT 1+ -> MID-UINT+1 }T
+
+T{ 2 1- -> 1 }T
+T{ 1 1- -> 0 }T
+T{ 0 1- -> -1 }T
+T{ MID-UINT+1 1- -> MID-UINT }T
+
+T{ 0 NEGATE -> 0 }T
+T{ 1 NEGATE -> -1 }T
+T{ -1 NEGATE -> 1 }T
+T{ 2 NEGATE -> -2 }T
+T{ -2 NEGATE -> 2 }T
+
+T{ 0 ABS -> 0 }T
+T{ 1 ABS -> 1 }T
+T{ -1 ABS -> 1 }T
+T{ MIN-INT ABS -> MID-UINT+1 }T
+
+\ ------------------------------------------------------------------------
+TESTING MULTIPLY: S>D * M* UM*
+
+T{ 0 S>D -> 0 0 }T
+T{ 1 S>D -> 1 0 }T
+T{ 2 S>D -> 2 0 }T
+T{ -1 S>D -> -1 -1 }T
+T{ -2 S>D -> -2 -1 }T
+T{ MIN-INT S>D -> MIN-INT -1 }T
+T{ MAX-INT S>D -> MAX-INT 0 }T
+
+T{ 0 0 M* -> 0 S>D }T
+T{ 0 1 M* -> 0 S>D }T
+T{ 1 0 M* -> 0 S>D }T
+T{ 1 2 M* -> 2 S>D }T
+T{ 2 1 M* -> 2 S>D }T
+T{ 3 3 M* -> 9 S>D }T
+T{ -3 3 M* -> -9 S>D }T
+T{ 3 -3 M* -> -9 S>D }T
+T{ -3 -3 M* -> 9 S>D }T
+T{ 0 MIN-INT M* -> 0 S>D }T
+T{ 1 MIN-INT M* -> MIN-INT S>D }T
+T{ 2 MIN-INT M* -> 0 1S }T
+T{ 0 MAX-INT M* -> 0 S>D }T
+T{ 1 MAX-INT M* -> MAX-INT S>D }T
+T{ 2 MAX-INT M* -> MAX-INT 1 LSHIFT 0 }T
+T{ MIN-INT MIN-INT M* -> 0 MSB 1 RSHIFT }T
+T{ MAX-INT MIN-INT M* -> MSB MSB 2/ }T
+T{ MAX-INT MAX-INT M* -> 1 MSB 2/ INVERT }T
+
+T{ 0 0 * -> 0 }T \ TEST IDENTITIES
+T{ 0 1 * -> 0 }T
+T{ 1 0 * -> 0 }T
+T{ 1 2 * -> 2 }T
+T{ 2 1 * -> 2 }T
+T{ 3 3 * -> 9 }T
+T{ -3 3 * -> -9 }T
+T{ 3 -3 * -> -9 }T
+T{ -3 -3 * -> 9 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 * -> MID-UINT+1 }T
+T{ MID-UINT+1 2 RSHIFT 4 * -> MID-UINT+1 }T
+T{ MID-UINT+1 1 RSHIFT MID-UINT+1 OR 2 * -> MID-UINT+1 }T
+
+T{ 0 0 UM* -> 0 0 }T
+T{ 0 1 UM* -> 0 0 }T
+T{ 1 0 UM* -> 0 0 }T
+T{ 1 2 UM* -> 2 0 }T
+T{ 2 1 UM* -> 2 0 }T
+T{ 3 3 UM* -> 9 0 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 UM* -> MID-UINT+1 0 }T
+T{ MID-UINT+1 2 UM* -> 0 1 }T
+T{ MID-UINT+1 4 UM* -> 0 2 }T
+T{ 1S 2 UM* -> 1S 1 LSHIFT 1 }T
+T{ MAX-UINT MAX-UINT UM* -> 1 1 INVERT }T
+
+\ ------------------------------------------------------------------------
+TESTING DIVIDE: FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD
+
+T{ 0 S>D 1 FM/MOD -> 0 0 }T
+T{ 1 S>D 1 FM/MOD -> 0 1 }T
+T{ 2 S>D 1 FM/MOD -> 0 2 }T
+T{ -1 S>D 1 FM/MOD -> 0 -1 }T
+T{ -2 S>D 1 FM/MOD -> 0 -2 }T
+T{ 0 S>D -1 FM/MOD -> 0 0 }T
+T{ 1 S>D -1 FM/MOD -> 0 -1 }T
+T{ 2 S>D -1 FM/MOD -> 0 -2 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -1 FM/MOD -> 0 2 }T
+T{ 2 S>D 2 FM/MOD -> 0 1 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -2 FM/MOD -> 0 1 }T
+T{ 7 S>D 3 FM/MOD -> 1 2 }T
+T{ 7 S>D -3 FM/MOD -> -2 -3 }T
+T{ -7 S>D 3 FM/MOD -> 2 -3 }T
+T{ -7 S>D -3 FM/MOD -> -1 2 }T
+T{ MAX-INT S>D 1 FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT FM/MOD -> 0 1 }T
+T{ MIN-INT S>D MIN-INT FM/MOD -> 0 1 }T
+T{ 1S 1 4 FM/MOD -> 3 MAX-INT }T
+T{ 1 MIN-INT M* 1 FM/MOD -> 0 MIN-INT }T
+T{ 1 MIN-INT M* MIN-INT FM/MOD -> 0 1 }T
+T{ 2 MIN-INT M* 2 FM/MOD -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT FM/MOD -> 0 2 }T
+T{ 1 MAX-INT M* 1 FM/MOD -> 0 MAX-INT }T
+T{ 1 MAX-INT M* MAX-INT FM/MOD -> 0 1 }T
+T{ 2 MAX-INT M* 2 FM/MOD -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT FM/MOD -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT FM/MOD -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT FM/MOD -> 0 MAX-INT }T
+
+T{ 0 S>D 1 SM/REM -> 0 0 }T
+T{ 1 S>D 1 SM/REM -> 0 1 }T
+T{ 2 S>D 1 SM/REM -> 0 2 }T
+T{ -1 S>D 1 SM/REM -> 0 -1 }T
+T{ -2 S>D 1 SM/REM -> 0 -2 }T
+T{ 0 S>D -1 SM/REM -> 0 0 }T
+T{ 1 S>D -1 SM/REM -> 0 -1 }T
+T{ 2 S>D -1 SM/REM -> 0 -2 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -1 SM/REM -> 0 2 }T
+T{ 2 S>D 2 SM/REM -> 0 1 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -2 SM/REM -> 0 1 }T
+T{ 7 S>D 3 SM/REM -> 1 2 }T
+T{ 7 S>D -3 SM/REM -> 1 -2 }T
+T{ -7 S>D 3 SM/REM -> -1 -2 }T
+T{ -7 S>D -3 SM/REM -> -1 2 }T
+T{ MAX-INT S>D 1 SM/REM -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 SM/REM -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT SM/REM -> 0 1 }T
+T{ MIN-INT S>D MIN-INT SM/REM -> 0 1 }T
+T{ 1S 1 4 SM/REM -> 3 MAX-INT }T
+T{ 2 MIN-INT M* 2 SM/REM -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT SM/REM -> 0 2 }T
+T{ 2 MAX-INT M* 2 SM/REM -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT SM/REM -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT SM/REM -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT SM/REM -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT SM/REM -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT SM/REM -> 0 MAX-INT }T
+
+T{ 0 0 1 UM/MOD -> 0 0 }T
+T{ 1 0 1 UM/MOD -> 0 1 }T
+T{ 1 0 2 UM/MOD -> 1 0 }T
+T{ 3 0 2 UM/MOD -> 1 1 }T
+T{ MAX-UINT 2 UM* 2 UM/MOD -> 0 MAX-UINT }T
+T{ MAX-UINT 2 UM* MAX-UINT UM/MOD -> 0 2 }T
+T{ MAX-UINT MAX-UINT UM* MAX-UINT UM/MOD -> 0 MAX-UINT }T
+
+: IFFLOORED
+ [ -3 2 / -2 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+: IFSYM
+ [ -3 2 / -1 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+\ THE SYSTEM MIGHT DO EITHER FLOORED OR SYMMETRIC DIVISION.
+\ SINCE WE HAVE ALREADY TESTED M*, FM/MOD, AND SM/REM WE CAN USE THEM IN TEST.
+
+IFFLOORED : T/MOD >R S>D R> FM/MOD ;
+IFFLOORED : T/ T/MOD SWAP DROP ;
+IFFLOORED : TMOD T/MOD DROP ;
+IFFLOORED : T*/MOD >R M* R> FM/MOD ;
+IFFLOORED : T*/ T*/MOD SWAP DROP ;
+IFSYM : T/MOD >R S>D R> SM/REM ;
+IFSYM : T/ T/MOD SWAP DROP ;
+IFSYM : TMOD T/MOD DROP ;
+IFSYM : T*/MOD >R M* R> SM/REM ;
+IFSYM : T*/ T*/MOD SWAP DROP ;
+
+T{ 0 1 /MOD -> 0 1 T/MOD }T
+T{ 1 1 /MOD -> 1 1 T/MOD }T
+T{ 2 1 /MOD -> 2 1 T/MOD }T
+T{ -1 1 /MOD -> -1 1 T/MOD }T
+T{ -2 1 /MOD -> -2 1 T/MOD }T
+T{ 0 -1 /MOD -> 0 -1 T/MOD }T
+T{ 1 -1 /MOD -> 1 -1 T/MOD }T
+T{ 2 -1 /MOD -> 2 -1 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -1 /MOD -> -2 -1 T/MOD }T
+T{ 2 2 /MOD -> 2 2 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -2 /MOD -> -2 -2 T/MOD }T
+T{ 7 3 /MOD -> 7 3 T/MOD }T
+T{ 7 -3 /MOD -> 7 -3 T/MOD }T
+T{ -7 3 /MOD -> -7 3 T/MOD }T
+T{ -7 -3 /MOD -> -7 -3 T/MOD }T
+T{ MAX-INT 1 /MOD -> MAX-INT 1 T/MOD }T
+T{ MIN-INT 1 /MOD -> MIN-INT 1 T/MOD }T
+T{ MAX-INT MAX-INT /MOD -> MAX-INT MAX-INT T/MOD }T
+T{ MIN-INT MIN-INT /MOD -> MIN-INT MIN-INT T/MOD }T
+
+T{ 0 1 / -> 0 1 T/ }T
+T{ 1 1 / -> 1 1 T/ }T
+T{ 2 1 / -> 2 1 T/ }T
+T{ -1 1 / -> -1 1 T/ }T
+T{ -2 1 / -> -2 1 T/ }T
+T{ 0 -1 / -> 0 -1 T/ }T
+T{ 1 -1 / -> 1 -1 T/ }T
+T{ 2 -1 / -> 2 -1 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -1 / -> -2 -1 T/ }T
+T{ 2 2 / -> 2 2 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -2 / -> -2 -2 T/ }T
+T{ 7 3 / -> 7 3 T/ }T
+T{ 7 -3 / -> 7 -3 T/ }T
+T{ -7 3 / -> -7 3 T/ }T
+T{ -7 -3 / -> -7 -3 T/ }T
+T{ MAX-INT 1 / -> MAX-INT 1 T/ }T
+T{ MIN-INT 1 / -> MIN-INT 1 T/ }T
+T{ MAX-INT MAX-INT / -> MAX-INT MAX-INT T/ }T
+T{ MIN-INT MIN-INT / -> MIN-INT MIN-INT T/ }T
+
+T{ 0 1 MOD -> 0 1 TMOD }T
+T{ 1 1 MOD -> 1 1 TMOD }T
+T{ 2 1 MOD -> 2 1 TMOD }T
+T{ -1 1 MOD -> -1 1 TMOD }T
+T{ -2 1 MOD -> -2 1 TMOD }T
+T{ 0 -1 MOD -> 0 -1 TMOD }T
+T{ 1 -1 MOD -> 1 -1 TMOD }T
+T{ 2 -1 MOD -> 2 -1 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -1 MOD -> -2 -1 TMOD }T
+T{ 2 2 MOD -> 2 2 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -2 MOD -> -2 -2 TMOD }T
+T{ 7 3 MOD -> 7 3 TMOD }T
+T{ 7 -3 MOD -> 7 -3 TMOD }T
+T{ -7 3 MOD -> -7 3 TMOD }T
+T{ -7 -3 MOD -> -7 -3 TMOD }T
+T{ MAX-INT 1 MOD -> MAX-INT 1 TMOD }T
+T{ MIN-INT 1 MOD -> MIN-INT 1 TMOD }T
+T{ MAX-INT MAX-INT MOD -> MAX-INT MAX-INT TMOD }T
+T{ MIN-INT MIN-INT MOD -> MIN-INT MIN-INT TMOD }T
+
+T{ 0 2 1 */ -> 0 2 1 T*/ }T
+T{ 1 2 1 */ -> 1 2 1 T*/ }T
+T{ 2 2 1 */ -> 2 2 1 T*/ }T
+T{ -1 2 1 */ -> -1 2 1 T*/ }T
+T{ -2 2 1 */ -> -2 2 1 T*/ }T
+T{ 0 2 -1 */ -> 0 2 -1 T*/ }T
+T{ 1 2 -1 */ -> 1 2 -1 T*/ }T
+T{ 2 2 -1 */ -> 2 2 -1 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -1 */ -> -2 2 -1 T*/ }T
+T{ 2 2 2 */ -> 2 2 2 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -2 */ -> -2 2 -2 T*/ }T
+T{ 7 2 3 */ -> 7 2 3 T*/ }T
+T{ 7 2 -3 */ -> 7 2 -3 T*/ }T
+T{ -7 2 3 */ -> -7 2 3 T*/ }T
+T{ -7 2 -3 */ -> -7 2 -3 T*/ }T
+T{ MAX-INT 2 MAX-INT */ -> MAX-INT 2 MAX-INT T*/ }T
+T{ MIN-INT 2 MIN-INT */ -> MIN-INT 2 MIN-INT T*/ }T
+
+T{ 0 2 1 */MOD -> 0 2 1 T*/MOD }T
+T{ 1 2 1 */MOD -> 1 2 1 T*/MOD }T
+T{ 2 2 1 */MOD -> 2 2 1 T*/MOD }T
+T{ -1 2 1 */MOD -> -1 2 1 T*/MOD }T
+T{ -2 2 1 */MOD -> -2 2 1 T*/MOD }T
+T{ 0 2 -1 */MOD -> 0 2 -1 T*/MOD }T
+T{ 1 2 -1 */MOD -> 1 2 -1 T*/MOD }T
+T{ 2 2 -1 */MOD -> 2 2 -1 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -1 */MOD -> -2 2 -1 T*/MOD }T
+T{ 2 2 2 */MOD -> 2 2 2 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -2 */MOD -> -2 2 -2 T*/MOD }T
+T{ 7 2 3 */MOD -> 7 2 3 T*/MOD }T
+T{ 7 2 -3 */MOD -> 7 2 -3 T*/MOD }T
+T{ -7 2 3 */MOD -> -7 2 3 T*/MOD }T
+T{ -7 2 -3 */MOD -> -7 2 -3 T*/MOD }T
+T{ MAX-INT 2 MAX-INT */MOD -> MAX-INT 2 MAX-INT T*/MOD }T
+T{ MIN-INT 2 MIN-INT */MOD -> MIN-INT 2 MIN-INT T*/MOD }T
+
+\ ------------------------------------------------------------------------
+TESTING HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2! ALIGN ALIGNED +! ALLOT
+
+HERE 1 ALLOT
+HERE
+CONSTANT 2NDA
+CONSTANT 1STA
+T{ 1STA 2NDA U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STA 1+ -> 2NDA }T \ ... BY ONE ADDRESS UNIT
+( MISSING TEST: NEGATIVE ALLOT )
+
+HERE 1 ,
+HERE 2 ,
+CONSTANT 2ND
+CONSTANT 1ST
+T{ 1ST 2ND U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1ST CELL+ -> 2ND }T \ ... BY ONE CELL
+T{ 1ST 1 CELLS + -> 2ND }T
+T{ 1ST @ 2ND @ -> 1 2 }T
+T{ 5 1ST ! -> }T
+T{ 1ST @ 2ND @ -> 5 2 }T
+T{ 6 2ND ! -> }T
+T{ 1ST @ 2ND @ -> 5 6 }T
+T{ 1ST 2@ -> 6 5 }T
+T{ 2 1 1ST 2! -> }T
+T{ 1ST 2@ -> 2 1 }T
+T{ 1S 1ST ! 1ST @ -> 1S }T \ CAN STORE CELL-WIDE VALUE
+
+HERE 1 C,
+HERE 2 C,
+CONSTANT 2NDC
+CONSTANT 1STC
+T{ 1STC 2NDC U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STC CHAR+ -> 2NDC }T \ ... BY ONE CHAR
+T{ 1STC 1 CHARS + -> 2NDC }T
+T{ 1STC C@ 2NDC C@ -> 1 2 }T
+T{ 3 1STC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 2 }T
+T{ 4 2NDC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 4 }T
+
+ALIGN 1 ALLOT HERE ALIGN HERE 3 CELLS ALLOT
+CONSTANT A-ADDR CONSTANT UA-ADDR
+T{ UA-ADDR ALIGNED -> A-ADDR }T
+T{ 1 A-ADDR C! A-ADDR C@ -> 1 }T
+T{ 1234 A-ADDR ! A-ADDR @ -> 1234 }T
+T{ 123 456 A-ADDR 2! A-ADDR 2@ -> 123 456 }T
+T{ 2 A-ADDR CHAR+ C! A-ADDR CHAR+ C@ -> 2 }T
+T{ 3 A-ADDR CELL+ C! A-ADDR CELL+ C@ -> 3 }T
+T{ 1234 A-ADDR CELL+ ! A-ADDR CELL+ @ -> 1234 }T
+T{ 123 456 A-ADDR CELL+ 2! A-ADDR CELL+ 2@ -> 123 456 }T
+
+: BITS ( X -- U )
+ 0 SWAP BEGIN DUP WHILE DUP MSB AND IF >R 1+ R> THEN 2* REPEAT DROP ;
+( CHARACTERS >= 1 AU, <= SIZE OF CELL, >= 8 BITS )
+T{ 1 CHARS 1 < -> <FALSE> }T
+T{ 1 CHARS 1 CELLS > -> <FALSE> }T
+( TBD: HOW TO FIND NUMBER OF BITS? )
+
+( CELLS >= 1 AU, INTEGRAL MULTIPLE OF CHAR SIZE, >= 16 BITS )
+T{ 1 CELLS 1 < -> <FALSE> }T
+T{ 1 CELLS 1 CHARS MOD -> 0 }T
+T{ 1S BITS 10 < -> <FALSE> }T
+
+T{ 0 1ST ! -> }T
+T{ 1 1ST +! -> }T
+T{ 1ST @ -> 1 }T
+T{ -1 1ST +! 1ST @ -> 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING CHAR [CHAR] [ ] BL S"
+
+T{ BL -> 20 }T
+T{ CHAR X -> 58 }T
+T{ CHAR HELLO -> 48 }T
+T{ : GC1 [CHAR] X ; -> }T
+T{ : GC2 [CHAR] HELLO ; -> }T
+T{ GC1 -> 58 }T
+T{ GC2 -> 48 }T
+T{ : GC3 [ GC1 ] LITERAL ; -> }T
+T{ GC3 -> 58 }T
+T{ : GC4 S" XY" ; -> }T
+T{ GC4 SWAP DROP -> 2 }T
+T{ GC4 DROP DUP C@ SWAP CHAR+ C@ -> 58 59 }T
+
+\ ------------------------------------------------------------------------
+TESTING ' ['] FIND EXECUTE IMMEDIATE COUNT LITERAL POSTPONE STATE
+
+T{ : GT1 123 ; -> }T
+T{ ' GT1 EXECUTE -> 123 }T
+T{ : GT2 ['] GT1 ; IMMEDIATE -> }T
+T{ GT2 EXECUTE -> 123 }T
+HERE 3 C, CHAR G C, CHAR T C, CHAR 1 C, CONSTANT GT1STRING
+HERE 3 C, CHAR G C, CHAR T C, CHAR 2 C, CONSTANT GT2STRING
+T{ GT1STRING FIND -> ' GT1 -1 }T
+T{ GT2STRING FIND -> ' GT2 1 }T
+( HOW TO SEARCH FOR NON-EXISTENT WORD? )
+T{ : GT3 GT2 LITERAL ; -> }T
+T{ GT3 -> ' GT1 }T
+T{ GT1STRING COUNT -> GT1STRING CHAR+ 3 }T
+
+T{ : GT4 POSTPONE GT1 ; IMMEDIATE -> }T
+T{ : GT5 GT4 ; -> }T
+T{ GT5 -> 123 }T
+T{ : GT6 345 ; IMMEDIATE -> }T
+T{ : GT7 POSTPONE GT6 ; -> }T
+T{ GT7 -> 345 }T
+
+T{ : GT8 STATE @ ; IMMEDIATE -> }T
+T{ GT8 -> 0 }T
+T{ : GT9 GT8 LITERAL ; -> }T
+T{ GT9 0= -> <FALSE> }T
+
+\ ------------------------------------------------------------------------
+TESTING IF ELSE THEN BEGIN WHILE REPEAT UNTIL RECURSE
+
+T{ : GI1 IF 123 THEN ; -> }T
+T{ : GI2 IF 123 ELSE 234 THEN ; -> }T
+T{ 0 GI1 -> }T
+T{ 1 GI1 -> 123 }T
+T{ -1 GI1 -> 123 }T
+T{ 0 GI2 -> 234 }T
+T{ 1 GI2 -> 123 }T
+T{ -1 GI1 -> 123 }T
+
+T{ : GI3 BEGIN DUP 5 < WHILE DUP 1+ REPEAT ; -> }T
+T{ 0 GI3 -> 0 1 2 3 4 5 }T
+T{ 4 GI3 -> 4 5 }T
+T{ 5 GI3 -> 5 }T
+T{ 6 GI3 -> 6 }T
+
+T{ : GI4 BEGIN DUP 1+ DUP 5 > UNTIL ; -> }T
+T{ 3 GI4 -> 3 4 5 6 }T
+T{ 5 GI4 -> 5 6 }T
+T{ 6 GI4 -> 6 7 }T
+
+T{ : GI5 BEGIN DUP 2 > WHILE DUP 5 < WHILE DUP 1+ REPEAT 123 ELSE 345 THEN ; -> }T
+T{ 1 GI5 -> 1 345 }T
+T{ 2 GI5 -> 2 345 }T
+T{ 3 GI5 -> 3 4 5 123 }T
+T{ 4 GI5 -> 4 5 123 }T
+T{ 5 GI5 -> 5 123 }T
+
+T{ : GI6 ( N -- 0,1,..N ) DUP IF DUP >R 1- RECURSE R> THEN ; -> }T
+T{ 0 GI6 -> 0 }T
+T{ 1 GI6 -> 0 1 }T
+T{ 2 GI6 -> 0 1 2 }T
+T{ 3 GI6 -> 0 1 2 3 }T
+T{ 4 GI6 -> 0 1 2 3 4 }T
+
+\ ------------------------------------------------------------------------
+TESTING DO LOOP +LOOP I J UNLOOP LEAVE EXIT
+
+T{ : GD1 DO I LOOP ; -> }T
+T{ 4 1 GD1 -> 1 2 3 }T
+T{ 2 -1 GD1 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD1 -> MID-UINT }T
+
+T{ : GD2 DO I -1 +LOOP ; -> }T
+T{ 1 4 GD2 -> 4 3 2 1 }T
+T{ -1 2 GD2 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD2 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD3 DO 1 0 DO J LOOP LOOP ; -> }T
+T{ 4 1 GD3 -> 1 2 3 }T
+T{ 2 -1 GD3 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD3 -> MID-UINT }T
+
+T{ : GD4 DO 1 0 DO J LOOP -1 +LOOP ; -> }T
+T{ 1 4 GD4 -> 4 3 2 1 }T
+T{ -1 2 GD4 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD4 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD5 123 SWAP 0 DO I 4 > IF DROP 234 LEAVE THEN LOOP ; -> }T
+T{ 1 GD5 -> 123 }T
+T{ 5 GD5 -> 123 }T
+T{ 6 GD5 -> 234 }T
+
+T{ : GD6 ( PAT: T{0 0}T,T{0 0}TT{1 0}TT{1 1}T,T{0 0}TT{1 0}TT{1 1}TT{2 0}TT{2 1}TT{2 2}T )
+ 0 SWAP 0 DO
+ I 1+ 0 DO I J + 3 = IF I UNLOOP I UNLOOP EXIT THEN 1+ LOOP
+ LOOP ; -> }T
+T{ 1 GD6 -> 1 }T
+T{ 2 GD6 -> 3 }T
+T{ 3 GD6 -> 4 1 2 }T
+
+\ ------------------------------------------------------------------------
+TESTING DEFINING WORDS: : ; CONSTANT VARIABLE CREATE DOES> >BODY
+
+T{ 123 CONSTANT X123 -> }T
+T{ X123 -> 123 }T
+T{ : EQU CONSTANT ; -> }T
+T{ X123 EQU Y123 -> }T
+T{ Y123 -> 123 }T
+
+T{ VARIABLE V1 -> }T
+T{ 123 V1 ! -> }T
+T{ V1 @ -> 123 }T
+
+T{ : NOP : POSTPONE ; ; -> }T
+T{ NOP NOP1 NOP NOP2 -> }T
+T{ NOP1 -> }T
+T{ NOP2 -> }T
+
+T{ : DOES1 DOES> @ 1 + ; -> }T
+T{ : DOES2 DOES> @ 2 + ; -> }T
+T{ CREATE CR1 -> }T
+T{ CR1 -> HERE }T
+T{ ' CR1 >BODY -> HERE }T
+T{ 1 , -> }T
+T{ CR1 @ -> 1 }T
+T{ DOES1 -> }T
+T{ CR1 -> 2 }T
+T{ DOES2 -> }T
+T{ CR1 -> 3 }T
+
+T{ : WEIRD: CREATE DOES> 1 + DOES> 2 + ; -> }T
+T{ WEIRD: W1 -> }T
+T{ ' W1 >BODY -> HERE }T
+T{ W1 -> HERE 1 + }T
+T{ W1 -> HERE 2 + }T
+
+\ ------------------------------------------------------------------------
+TESTING EVALUATE
+
+: GE1 S" 123" ; IMMEDIATE
+: GE2 S" 123 1+" ; IMMEDIATE
+: GE3 S" : GE4 345 ;" ;
+: GE5 EVALUATE ; IMMEDIATE
+
+T{ GE1 EVALUATE -> 123 }T ( TEST EVALUATE IN INTERP. STATE )
+T{ GE2 EVALUATE -> 124 }T
+T{ GE3 EVALUATE -> }T
+T{ GE4 -> 345 }T
+
+T{ : GE6 GE1 GE5 ; -> }T ( TEST EVALUATE IN COMPILE STATE )
+T{ GE6 -> 123 }T
+T{ : GE7 GE2 GE5 ; -> }T
+T{ GE7 -> 124 }T
+
+\ ------------------------------------------------------------------------
+TESTING SOURCE >IN WORD
+
+: GS1 S" SOURCE" 2DUP EVALUATE
+ >R SWAP >R = R> R> = ;
+T{ GS1 -> <TRUE> <TRUE> }T
+
+VARIABLE SCANS
+: RESCAN? -1 SCANS +! SCANS @ IF 0 >IN ! THEN ;
+
+T{ 2 SCANS !
+345 RESCAN?
+-> 345 345 }T
+
+: GS2 5 SCANS ! S" 123 RESCAN?" EVALUATE ;
+T{ GS2 -> 123 123 123 123 123 }T
+
+: GS3 WORD COUNT SWAP C@ ;
+T{ BL GS3 HELLO -> 5 CHAR H }T
+T{ CHAR " GS3 GOODBYE" -> 7 CHAR G }T
+T{ BL GS3
+DROP -> 0 }T \ BLANK LINE RETURN ZERO-LENGTH STRING
+
+: GS4 SOURCE >IN ! DROP ;
+T{ GS4 123 456
+-> }T
+
+\ ------------------------------------------------------------------------
+TESTING <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL
+
+: S= \ ( ADDR1 C1 ADDR2 C2 -- T/F ) COMPARE TWO STRINGS.
+ >R SWAP R@ = IF \ MAKE SURE STRINGS HAVE SAME LENGTH
+ R> ?DUP IF \ IF NON-EMPTY STRINGS
+ 0 DO
+ OVER C@ OVER C@ - IF
+ 2DROP <FALSE> UNLOOP EXIT THEN
+ SWAP CHAR+ SWAP CHAR+
+ LOOP
+ THEN
+ 2DROP <TRUE> \ IF WE GET HERE, STRINGS MATCH
+ ELSE
+ R> DROP 2DROP <FALSE> \ LENGTHS MISMATCH
+ THEN ;
+
+: GP1 <# 41 HOLD 42 HOLD 0 0 #> S" BA" S= ;
+T{ GP1 -> <TRUE> }T
+
+: GP2 <# -1 SIGN 0 SIGN -1 SIGN 0 0 #> S" --" S= ;
+T{ GP2 -> <TRUE> }T
+
+: GP3 <# 1 0 # # #> S" 01" S= ;
+T{ GP3 -> <TRUE> }T
+
+: GP4 <# 1 0 #S #> S" 1" S= ;
+T{ GP4 -> <TRUE> }T
+
+24 CONSTANT MAX-BASE \ BASE 2 .. 36
+: COUNT-BITS
+ 0 0 INVERT BEGIN DUP WHILE >R 1+ R> 2* REPEAT DROP ;
+COUNT-BITS 2* CONSTANT #BITS-UD \ NUMBER OF BITS IN UD
+
+: GP5
+ BASE @ <TRUE>
+ MAX-BASE 1+ 2 DO \ FOR EACH POSSIBLE BASE
+ I BASE ! \ TBD: ASSUMES BASE WORKS
+ I 0 <# #S #> S" 10" S= AND
+ LOOP
+ SWAP BASE ! ;
+T{ GP5 -> <TRUE> }T
+
+: GP6
+ BASE @ >R 2 BASE !
+ MAX-UINT MAX-UINT <# #S #> \ MAXIMUM UD TO BINARY
+ R> BASE ! \ S: C-ADDR U
+ DUP #BITS-UD = SWAP
+ 0 DO \ S: C-ADDR FLAG
+ OVER C@ [CHAR] 1 = AND \ ALL ONES
+ >R CHAR+ R>
+ LOOP SWAP DROP ;
+T{ GP6 -> <TRUE> }T
+
+: GP7
+ BASE @ >R MAX-BASE BASE !
+ <TRUE>
+ A 0 DO
+ I 0 <# #S #>
+ 1 = SWAP C@ I 30 + = AND AND
+ LOOP
+ MAX-BASE A DO
+ I 0 <# #S #>
+ 1 = SWAP C@ 41 I A - + = AND AND
+ LOOP
+ R> BASE ! ;
+
+T{ GP7 -> <TRUE> }T
+
+\ >NUMBER TESTS
+CREATE GN-BUF 0 C,
+: GN-STRING GN-BUF 1 ;
+: GN-CONSUMED GN-BUF CHAR+ 0 ;
+: GN' [CHAR] ' WORD CHAR+ C@ GN-BUF C! GN-STRING ;
+
+T{ 0 0 GN' 0' >NUMBER -> 0 0 GN-CONSUMED }T
+T{ 0 0 GN' 1' >NUMBER -> 1 0 GN-CONSUMED }T
+T{ 1 0 GN' 1' >NUMBER -> BASE @ 1+ 0 GN-CONSUMED }T
+T{ 0 0 GN' -' >NUMBER -> 0 0 GN-STRING }T \ SHOULD FAIL TO CONVERT THESE
+T{ 0 0 GN' +' >NUMBER -> 0 0 GN-STRING }T
+T{ 0 0 GN' .' >NUMBER -> 0 0 GN-STRING }T
+
+: >NUMBER-BASED
+ BASE @ >R BASE ! >NUMBER R> BASE ! ;
+
+T{ 0 0 GN' 2' 10 >NUMBER-BASED -> 2 0 GN-CONSUMED }T
+T{ 0 0 GN' 2' 2 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' F' 10 >NUMBER-BASED -> F 0 GN-CONSUMED }T
+T{ 0 0 GN' G' 10 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' G' MAX-BASE >NUMBER-BASED -> 10 0 GN-CONSUMED }T
+T{ 0 0 GN' Z' MAX-BASE >NUMBER-BASED -> 23 0 GN-CONSUMED }T
+
+: GN1 \ ( UD BASE -- UD' LEN ) UD SHOULD EQUAL UD' AND LEN SHOULD BE ZERO.
+ BASE @ >R BASE !
+ <# #S #>
+ 0 0 2SWAP >NUMBER SWAP DROP \ RETURN LENGTH ONLY
+ R> BASE ! ;
+T{ 0 0 2 GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 2 GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP 2 GN1 -> MAX-UINT DUP 0 }T
+T{ 0 0 MAX-BASE GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 MAX-BASE GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP MAX-BASE GN1 -> MAX-UINT DUP 0 }T
+
+: GN2 \ ( -- 16 10 )
+ BASE @ >R HEX BASE @ DECIMAL BASE @ R> BASE ! ;
+T{ GN2 -> 10 A }T
+
+\ ------------------------------------------------------------------------
+TESTING FILL MOVE
+
+CREATE FBUF 00 C, 00 C, 00 C,
+CREATE SBUF 12 C, 34 C, 56 C,
+: SEEBUF FBUF C@ FBUF CHAR+ C@ FBUF CHAR+ CHAR+ C@ ;
+
+T{ FBUF 0 20 FILL -> }T
+T{ SEEBUF -> 00 00 00 }T
+
+T{ FBUF 1 20 FILL -> }T
+T{ SEEBUF -> 20 00 00 }T
+
+T{ FBUF 3 20 FILL -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ FBUF FBUF 3 CHARS MOVE -> }T \ BIZARRE SPECIAL CASE
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 0 CHARS MOVE -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 1 CHARS MOVE -> }T
+T{ SEEBUF -> 12 20 20 }T
+
+T{ SBUF FBUF 3 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 56 }T
+
+T{ FBUF FBUF CHAR+ 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 12 34 }T
+
+T{ FBUF CHAR+ FBUF 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 34 }T
+
+\ ------------------------------------------------------------------------
+TESTING OUTPUT: . ." CR EMIT SPACE SPACES TYPE U.
+
+: OUTPUT-TEST
+ ." YOU SHOULD SEE THE STANDARD GRAPHIC CHARACTERS:" CR
+ 41 BL DO I EMIT LOOP CR
+ 61 41 DO I EMIT LOOP CR
+ 7F 61 DO I EMIT LOOP CR
+ ." YOU SHOULD SEE 0-9 SEPARATED BY A SPACE:" CR
+ 9 1+ 0 DO I . LOOP CR
+ ." YOU SHOULD SEE 0-9 (WITH NO SPACES):" CR
+ [CHAR] 9 1+ [CHAR] 0 DO I 0 SPACES EMIT LOOP CR
+ ." YOU SHOULD SEE A-G SEPARATED BY A SPACE:" CR
+ [CHAR] G 1+ [CHAR] A DO I EMIT SPACE LOOP CR
+ ." YOU SHOULD SEE 0-5 SEPARATED BY TWO SPACES:" CR
+ 5 1+ 0 DO I [CHAR] 0 + EMIT 2 SPACES LOOP CR
+ ." YOU SHOULD SEE TWO SEPARATE LINES:" CR
+ S" LINE 1" TYPE CR S" LINE 2" TYPE CR
+ ." YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:" CR
+ ." SIGNED: " MIN-INT . MAX-INT . CR
+ ." UNSIGNED: " 0 U. MAX-UINT U. CR
+;
+
+T{ OUTPUT-TEST -> }T
+\ ------------------------------------------------------------------------
+TESTING INPUT: ACCEPT
+
+CREATE ABUF 80 CHARS ALLOT
+
+: ACCEPT-TEST
+ CR ." PLEASE TYPE UP TO 80 CHARACTERS:" CR
+ ABUF 80 ACCEPT
+ CR ." RECEIVED: " [CHAR] " EMIT
+ ABUF SWAP TYPE [CHAR] " EMIT CR
+;
+
+T{ ACCEPT-TEST -> }T
+Vingt fois sur le métier remettez votre ouvrage, ... Boileau, L'Art poétique
+\ ------------------------------------------------------------------------
+TESTING DICTIONARY SEARCH RULES
+
+T{ : GDX 123 ; : GDX GDX 234 ; -> }T
+
+T{ GDX -> 123 234 }T
+
+CR .( End of Core word set tests) CR
+
+
+$0A BASE !
+ECHO
+ ; end of core test
+PWR_HERE ; preserved against power OFF
--- /dev/null
+; ------------------------
+; file name : coretst1.4th
+; ------------------------
+
+ECHO ; if an error occurs, uncomment this line before new download to find it.
+
+
+\ From: John Hayes S1I
+\ Subject: tester.fr
+\ Date: Mon, 27 Nov 95 13:10:09 PST
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.1
+
+\ 22/1/09 The words { and } have been changed to T{ and }T respectively to
+\ agree with the Forth 200X file ttester.fs. This avoids clashes with
+\ locals using { ... } and the FSL use of }
+
+
+\ 13/05/14 jmt. added colorised error messages.
+
+
+
+ 0 CONSTANT FALSE
+-1 CONSTANT TRUE
+
+\ SET THE FOLLOWING FLAG TO TRUE FOR MORE VERBOSE OUTPUT; THIS MAY
+\ ALLOW YOU TO TELL WHICH TEST CAUSED YOUR SYSTEM TO HANG.
+VARIABLE VERBOSE
+ FALSE VERBOSE !
+\ TRUE VERBOSE !
+
+\ : EMPTY-STACK ( ... -- ) \ EMPTY STACK: HANDLES UNDERFLOWED STACK TOO.
+\ DEPTH ?DUP
+\ IF DUP 0< IF NEGATE 0
+\ DO 0 LOOP
+\ ELSE 0 DO DROP LOOP THEN
+\ THEN ;
+\
+\ : ERROR \ ( C-ADDR U -- ) DISPLAY AN ERROR MESSAGE FOLLOWED BY
+\ \ THE LINE THAT HAD THE ERROR.
+\ TYPE SOURCE TYPE CR \ DISPLAY LINE CORRESPONDING TO ERROR
+\ EMPTY-STACK \ THROW AWAY EVERY THING ELSE
+\ QUIT \ *** Uncomment this line to QUIT on an error
+\ ;
+
+VARIABLE ACTUAL-DEPTH \ STACK RECORD
+CREATE ACTUAL-RESULTS 20 CELLS ALLOT
+
+: T{ \ ( -- ) SYNTACTIC SUGAR.
+ ;
+
+: -> \ ( ... -- ) RECORD DEPTH AND CONTENT OF STACK.
+ DEPTH DUP ACTUAL-DEPTH ! \ RECORD DEPTH
+ ?DUP IF \ IF THERE IS SOMETHING ON STACK
+ 0 DO ACTUAL-RESULTS I CELLS + ! LOOP \ SAVE THEM
+ THEN ;
+
+: }T \ ( ... -- ) COMPARE STACK (EXPECTED) CONTENTS WITH SAVED
+ \ (ACTUAL) CONTENTS.
+ DEPTH ACTUAL-DEPTH @ = IF \ IF DEPTHS MATCH
+ DEPTH ?DUP IF \ IF THERE IS SOMETHING ON THE STACK
+ 0 DO \ FOR EACH STACK ITEM
+ ACTUAL-RESULTS I CELLS + @ \ COMPARE ACTUAL WITH EXPECTED
+\ = 0= IF S" INCORRECT RESULT: " ERROR LEAVE THEN \ jmt
+ = 0= IF ABORT" INCORRECT RESULT: " THEN \ jmt : colorised message
+ LOOP
+ THEN
+ ELSE \ DEPTH MISMATCH
+\ S" WRONG NUMBER OF RESULTS: " ERROR \ jmt
+ ABORT" WRONG NUMBER OF RESULTS: " \ jmt : colorised message
+ THEN ;
+
+: TESTING \ ( -- ) TALKING COMMENT.
+ SOURCE VERBOSE @
+ IF DUP >R TYPE CR R> >IN !
+ ELSE >IN ! DROP [CHAR] * EMIT
+ THEN ;
+
+\ From: John Hayes S1I
+\ Subject: core.fr
+\ Date: Mon, 27 Nov 95 13:10
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.2
+\ THIS PROGRAM TESTS THE CORE WORDS OF AN ANS FORTH SYSTEM.
+\ THE PROGRAM ASSUMES A TWO'S COMPLEMENT IMPLEMENTATION WHERE
+\ THE RANGE OF SIGNED NUMBERS IS -2^(N-1) ... 2^(N-1)-1 AND
+\ THE RANGE OF UNSIGNED NUMBERS IS 0 ... 2^(N)-1.
+\ I HAVEN'T FIGURED OUT HOW TO TEST KEY, QUIT, ABORT, OR ABORT"...
+\ I ALSO HAVEN'T THOUGHT OF A WAY TO TEST ENVIRONMENT?...
+
+CR
+TESTING CORE WORDS
+HEX
+
+\ ------------------------------------------------------------------------
+TESTING BASIC ASSUMPTIONS
+
+T{ -> }T \ START WITH CLEAN SLATE
+( TEST IF ANY BITS ARE SET; ANSWER IN BASE 1 )
+T{ : BITSSET? IF 0 0 ELSE 0 THEN ; -> }T
+T{ 0 BITSSET? -> 0 }T ( ZERO IS ALL BITS CLEAR )
+T{ 1 BITSSET? -> 0 0 }T ( OTHER NUMBER HAVE AT LEAST ONE BIT )
+T{ -1 BITSSET? -> 0 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING BOOLEANS: INVERT AND OR XOR
+
+T{ 0 0 AND -> 0 }T
+T{ 0 1 AND -> 0 }T
+T{ 1 0 AND -> 0 }T
+T{ 1 1 AND -> 1 }T
+
+T{ 0 INVERT 1 AND -> 1 }T
+T{ 1 INVERT 1 AND -> 0 }T
+
+0 CONSTANT 0S
+0 INVERT CONSTANT 1S
+
+T{ 0S INVERT -> 1S }T
+T{ 1S INVERT -> 0S }T
+
+T{ 0S 0S AND -> 0S }T
+T{ 0S 1S AND -> 0S }T
+T{ 1S 0S AND -> 0S }T
+T{ 1S 1S AND -> 1S }T
+
+T{ 0S 0S OR -> 0S }T
+T{ 0S 1S OR -> 1S }T
+T{ 1S 0S OR -> 1S }T
+T{ 1S 1S OR -> 1S }T
+
+T{ 0S 0S XOR -> 0S }T
+T{ 0S 1S XOR -> 1S }T
+T{ 1S 0S XOR -> 1S }T
+T{ 1S 1S XOR -> 0S }T
+
+\ ------------------------------------------------------------------------
+TESTING 2* 2/ LSHIFT RSHIFT
+
+( WE TRUST 1S, INVERT, AND BITSSET?; WE WILL CONFIRM RSHIFT LATER )
+1S 1 RSHIFT INVERT CONSTANT MSB
+T{ MSB BITSSET? -> 0 0 }T
+
+T{ 0S 2* -> 0S }T
+T{ 1 2* -> 2 }T
+T{ 4000 2* -> 8000 }T
+T{ 1S 2* 1 XOR -> 1S }T
+T{ MSB 2* -> 0S }T
+
+T{ 0S 2/ -> 0S }T
+T{ 1 2/ -> 0 }T
+T{ 4000 2/ -> 2000 }T
+T{ 1S 2/ -> 1S }T \ MSB PROPOGATED
+T{ 1S 1 XOR 2/ -> 1S }T
+T{ MSB 2/ MSB AND -> MSB }T
+
+T{ 1 0 LSHIFT -> 1 }T
+T{ 1 1 LSHIFT -> 2 }T
+T{ 1 2 LSHIFT -> 4 }T
+T{ 1 F LSHIFT -> 8000 }T \ BIGGEST GUARANTEED SHIFT
+T{ 1S 1 LSHIFT 1 XOR -> 1S }T
+T{ MSB 1 LSHIFT -> 0 }T
+
+T{ 1 0 RSHIFT -> 1 }T
+T{ 1 1 RSHIFT -> 0 }T
+T{ 2 1 RSHIFT -> 1 }T
+T{ 4 2 RSHIFT -> 1 }T
+T{ 8000 F RSHIFT -> 1 }T \ BIGGEST
+T{ MSB 1 RSHIFT MSB AND -> 0 }T \ RSHIFT ZERO FILLS MSBS
+T{ MSB 1 RSHIFT 2* -> MSB }T
+
+\ ------------------------------------------------------------------------
+TESTING COMPARISONS: 0= = 0< < > U< MIN MAX
+0 INVERT CONSTANT MAX-UINT
+0 INVERT 1 RSHIFT CONSTANT MAX-INT
+0 INVERT 1 RSHIFT INVERT CONSTANT MIN-INT
+0 INVERT 1 RSHIFT CONSTANT MID-UINT
+0 INVERT 1 RSHIFT INVERT CONSTANT MID-UINT+1
+
+0S CONSTANT <FALSE>
+1S CONSTANT <TRUE>
+
+T{ 0 0= -> <TRUE> }T
+T{ 1 0= -> <FALSE> }T
+T{ 2 0= -> <FALSE> }T
+T{ -1 0= -> <FALSE> }T
+T{ MAX-UINT 0= -> <FALSE> }T
+T{ MIN-INT 0= -> <FALSE> }T
+T{ MAX-INT 0= -> <FALSE> }T
+
+T{ 0 0 = -> <TRUE> }T
+T{ 1 1 = -> <TRUE> }T
+T{ -1 -1 = -> <TRUE> }T
+T{ 1 0 = -> <FALSE> }T
+T{ -1 0 = -> <FALSE> }T
+T{ 0 1 = -> <FALSE> }T
+T{ 0 -1 = -> <FALSE> }T
+
+T{ 0 0< -> <FALSE> }T
+T{ -1 0< -> <TRUE> }T
+T{ MIN-INT 0< -> <TRUE> }T
+T{ 1 0< -> <FALSE> }T
+T{ MAX-INT 0< -> <FALSE> }T
+
+T{ 0 1 < -> <TRUE> }T
+T{ 1 2 < -> <TRUE> }T
+T{ -1 0 < -> <TRUE> }T
+T{ -1 1 < -> <TRUE> }T
+T{ MIN-INT 0 < -> <TRUE> }T
+T{ MIN-INT MAX-INT < -> <TRUE> }T
+T{ 0 MAX-INT < -> <TRUE> }T
+T{ 0 0 < -> <FALSE> }T
+T{ 1 1 < -> <FALSE> }T
+T{ 1 0 < -> <FALSE> }T
+T{ 2 1 < -> <FALSE> }T
+T{ 0 -1 < -> <FALSE> }T
+T{ 1 -1 < -> <FALSE> }T
+T{ 0 MIN-INT < -> <FALSE> }T
+T{ MAX-INT MIN-INT < -> <FALSE> }T
+T{ MAX-INT 0 < -> <FALSE> }T
+
+T{ 0 1 > -> <FALSE> }T
+T{ 1 2 > -> <FALSE> }T
+T{ -1 0 > -> <FALSE> }T
+T{ -1 1 > -> <FALSE> }T
+T{ MIN-INT 0 > -> <FALSE> }T
+T{ MIN-INT MAX-INT > -> <FALSE> }T
+T{ 0 MAX-INT > -> <FALSE> }T
+T{ 0 0 > -> <FALSE> }T
+T{ 1 1 > -> <FALSE> }T
+T{ 1 0 > -> <TRUE> }T
+T{ 2 1 > -> <TRUE> }T
+T{ 0 -1 > -> <TRUE> }T
+T{ 1 -1 > -> <TRUE> }T
+T{ 0 MIN-INT > -> <TRUE> }T
+T{ MAX-INT MIN-INT > -> <TRUE> }T
+T{ MAX-INT 0 > -> <TRUE> }T
+
+T{ 0 1 U< -> <TRUE> }T
+T{ 1 2 U< -> <TRUE> }T
+T{ 0 MID-UINT U< -> <TRUE> }T
+T{ 0 MAX-UINT U< -> <TRUE> }T
+T{ MID-UINT MAX-UINT U< -> <TRUE> }T
+T{ 0 0 U< -> <FALSE> }T
+T{ 1 1 U< -> <FALSE> }T
+T{ 1 0 U< -> <FALSE> }T
+T{ 2 1 U< -> <FALSE> }T
+T{ MID-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT MID-UINT U< -> <FALSE> }T
+
+T{ 0 1 MIN -> 0 }T
+T{ 1 2 MIN -> 1 }T
+T{ -1 0 MIN -> -1 }T
+T{ -1 1 MIN -> -1 }T
+T{ MIN-INT 0 MIN -> MIN-INT }T
+T{ MIN-INT MAX-INT MIN -> MIN-INT }T
+T{ 0 MAX-INT MIN -> 0 }T
+T{ 0 0 MIN -> 0 }T
+T{ 1 1 MIN -> 1 }T
+T{ 1 0 MIN -> 0 }T
+T{ 2 1 MIN -> 1 }T
+T{ 0 -1 MIN -> -1 }T
+T{ 1 -1 MIN -> -1 }T
+T{ 0 MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT 0 MIN -> 0 }T
+
+T{ 0 1 MAX -> 1 }T
+T{ 1 2 MAX -> 2 }T
+T{ -1 0 MAX -> 0 }T
+T{ -1 1 MAX -> 1 }T
+T{ MIN-INT 0 MAX -> 0 }T
+T{ MIN-INT MAX-INT MAX -> MAX-INT }T
+T{ 0 MAX-INT MAX -> MAX-INT }T
+T{ 0 0 MAX -> 0 }T
+T{ 1 1 MAX -> 1 }T
+T{ 1 0 MAX -> 1 }T
+T{ 2 1 MAX -> 2 }T
+T{ 0 -1 MAX -> 0 }T
+T{ 1 -1 MAX -> 1 }T
+T{ 0 MIN-INT MAX -> 0 }T
+T{ MAX-INT MIN-INT MAX -> MAX-INT }T
+T{ MAX-INT 0 MAX -> MAX-INT }T
+
+\ ------------------------------------------------------------------------
+TESTING STACK OPS: 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP
+
+T{ 1 2 2DROP -> }T
+T{ 1 2 2DUP -> 1 2 1 2 }T
+T{ 1 2 3 4 2OVER -> 1 2 3 4 1 2 }T
+T{ 1 2 3 4 2SWAP -> 3 4 1 2 }T
+T{ 0 ?DUP -> 0 }T
+T{ 1 ?DUP -> 1 1 }T
+T{ -1 ?DUP -> -1 -1 }T
+T{ DEPTH -> 0 }T
+T{ 0 DEPTH -> 0 1 }T
+T{ 0 1 DEPTH -> 0 1 2 }T
+T{ 0 DROP -> }T
+T{ 1 2 DROP -> 1 }T
+T{ 1 DUP -> 1 1 }T
+T{ 1 2 OVER -> 1 2 1 }T
+T{ 1 2 3 ROT -> 2 3 1 }T
+T{ 1 2 SWAP -> 2 1 }T
+
+\ ------------------------------------------------------------------------
+TESTING >R R> R@
+
+T{ : GR1 >R R> ; -> }T
+T{ : GR2 >R R@ R> DROP ; -> }T
+T{ 123 GR1 -> 123 }T
+T{ 123 GR2 -> 123 }T
+T{ 1S GR1 -> 1S }T ( RETURN STACK HOLDS CELLS )
+
+\ ------------------------------------------------------------------------
+TESTING ADD/SUBTRACT: + - 1+ 1- ABS NEGATE
+
+T{ 0 5 + -> 5 }T
+T{ 5 0 + -> 5 }T
+T{ 0 -5 + -> -5 }T
+T{ -5 0 + -> -5 }T
+T{ 1 2 + -> 3 }T
+T{ 1 -2 + -> -1 }T
+T{ -1 2 + -> 1 }T
+T{ -1 -2 + -> -3 }T
+T{ -1 1 + -> 0 }T
+T{ MID-UINT 1 + -> MID-UINT+1 }T
+
+T{ 0 5 - -> -5 }T
+T{ 5 0 - -> 5 }T
+T{ 0 -5 - -> 5 }T
+T{ -5 0 - -> -5 }T
+T{ 1 2 - -> -1 }T
+T{ 1 -2 - -> 3 }T
+T{ -1 2 - -> -3 }T
+T{ -1 -2 - -> 1 }T
+T{ 0 1 - -> -1 }T
+T{ MID-UINT+1 1 - -> MID-UINT }T
+
+T{ 0 1+ -> 1 }T
+T{ -1 1+ -> 0 }T
+T{ 1 1+ -> 2 }T
+T{ MID-UINT 1+ -> MID-UINT+1 }T
+
+T{ 2 1- -> 1 }T
+T{ 1 1- -> 0 }T
+T{ 0 1- -> -1 }T
+T{ MID-UINT+1 1- -> MID-UINT }T
+
+T{ 0 NEGATE -> 0 }T
+T{ 1 NEGATE -> -1 }T
+T{ -1 NEGATE -> 1 }T
+T{ 2 NEGATE -> -2 }T
+T{ -2 NEGATE -> 2 }T
+
+T{ 0 ABS -> 0 }T
+T{ 1 ABS -> 1 }T
+T{ -1 ABS -> 1 }T
+T{ MIN-INT ABS -> MID-UINT+1 }T
+
+\ ------------------------------------------------------------------------
+TESTING MULTIPLY: S>D * M* UM*
+
+T{ 0 S>D -> 0 0 }T
+T{ 1 S>D -> 1 0 }T
+T{ 2 S>D -> 2 0 }T
+T{ -1 S>D -> -1 -1 }T
+T{ -2 S>D -> -2 -1 }T
+T{ MIN-INT S>D -> MIN-INT -1 }T
+T{ MAX-INT S>D -> MAX-INT 0 }T
+
+T{ 0 0 M* -> 0 S>D }T
+T{ 0 1 M* -> 0 S>D }T
+T{ 1 0 M* -> 0 S>D }T
+T{ 1 2 M* -> 2 S>D }T
+T{ 2 1 M* -> 2 S>D }T
+T{ 3 3 M* -> 9 S>D }T
+T{ -3 3 M* -> -9 S>D }T
+T{ 3 -3 M* -> -9 S>D }T
+T{ -3 -3 M* -> 9 S>D }T
+T{ 0 MIN-INT M* -> 0 S>D }T
+T{ 1 MIN-INT M* -> MIN-INT S>D }T
+T{ 2 MIN-INT M* -> 0 1S }T
+T{ 0 MAX-INT M* -> 0 S>D }T
+T{ 1 MAX-INT M* -> MAX-INT S>D }T
+T{ 2 MAX-INT M* -> MAX-INT 1 LSHIFT 0 }T
+T{ MIN-INT MIN-INT M* -> 0 MSB 1 RSHIFT }T
+T{ MAX-INT MIN-INT M* -> MSB MSB 2/ }T
+T{ MAX-INT MAX-INT M* -> 1 MSB 2/ INVERT }T
+
+T{ 0 0 * -> 0 }T \ TEST IDENTITIES
+T{ 0 1 * -> 0 }T
+T{ 1 0 * -> 0 }T
+T{ 1 2 * -> 2 }T
+T{ 2 1 * -> 2 }T
+T{ 3 3 * -> 9 }T
+T{ -3 3 * -> -9 }T
+T{ 3 -3 * -> -9 }T
+T{ -3 -3 * -> 9 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 * -> MID-UINT+1 }T
+T{ MID-UINT+1 2 RSHIFT 4 * -> MID-UINT+1 }T
+T{ MID-UINT+1 1 RSHIFT MID-UINT+1 OR 2 * -> MID-UINT+1 }T
+
+T{ 0 0 UM* -> 0 0 }T
+T{ 0 1 UM* -> 0 0 }T
+T{ 1 0 UM* -> 0 0 }T
+T{ 1 2 UM* -> 2 0 }T
+T{ 2 1 UM* -> 2 0 }T
+T{ 3 3 UM* -> 9 0 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 UM* -> MID-UINT+1 0 }T
+T{ MID-UINT+1 2 UM* -> 0 1 }T
+T{ MID-UINT+1 4 UM* -> 0 2 }T
+T{ 1S 2 UM* -> 1S 1 LSHIFT 1 }T
+T{ MAX-UINT MAX-UINT UM* -> 1 1 INVERT }T
+
+\ ------------------------------------------------------------------------
+TESTING DIVIDE: FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD
+
+T{ 0 S>D 1 FM/MOD -> 0 0 }T
+T{ 1 S>D 1 FM/MOD -> 0 1 }T
+T{ 2 S>D 1 FM/MOD -> 0 2 }T
+T{ -1 S>D 1 FM/MOD -> 0 -1 }T
+T{ -2 S>D 1 FM/MOD -> 0 -2 }T
+T{ 0 S>D -1 FM/MOD -> 0 0 }T
+T{ 1 S>D -1 FM/MOD -> 0 -1 }T
+T{ 2 S>D -1 FM/MOD -> 0 -2 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -1 FM/MOD -> 0 2 }T
+T{ 2 S>D 2 FM/MOD -> 0 1 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -2 FM/MOD -> 0 1 }T
+T{ 7 S>D 3 FM/MOD -> 1 2 }T
+T{ 7 S>D -3 FM/MOD -> -2 -3 }T
+T{ -7 S>D 3 FM/MOD -> 2 -3 }T
+T{ -7 S>D -3 FM/MOD -> -1 2 }T
+T{ MAX-INT S>D 1 FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT FM/MOD -> 0 1 }T
+T{ MIN-INT S>D MIN-INT FM/MOD -> 0 1 }T
+T{ 1S 1 4 FM/MOD -> 3 MAX-INT }T
+T{ 1 MIN-INT M* 1 FM/MOD -> 0 MIN-INT }T
+T{ 1 MIN-INT M* MIN-INT FM/MOD -> 0 1 }T
+T{ 2 MIN-INT M* 2 FM/MOD -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT FM/MOD -> 0 2 }T
+T{ 1 MAX-INT M* 1 FM/MOD -> 0 MAX-INT }T
+T{ 1 MAX-INT M* MAX-INT FM/MOD -> 0 1 }T
+T{ 2 MAX-INT M* 2 FM/MOD -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT FM/MOD -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT FM/MOD -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT FM/MOD -> 0 MAX-INT }T
+
+T{ 0 S>D 1 SM/REM -> 0 0 }T
+T{ 1 S>D 1 SM/REM -> 0 1 }T
+T{ 2 S>D 1 SM/REM -> 0 2 }T
+T{ -1 S>D 1 SM/REM -> 0 -1 }T
+T{ -2 S>D 1 SM/REM -> 0 -2 }T
+T{ 0 S>D -1 SM/REM -> 0 0 }T
+T{ 1 S>D -1 SM/REM -> 0 -1 }T
+T{ 2 S>D -1 SM/REM -> 0 -2 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -1 SM/REM -> 0 2 }T
+T{ 2 S>D 2 SM/REM -> 0 1 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -2 SM/REM -> 0 1 }T
+T{ 7 S>D 3 SM/REM -> 1 2 }T
+T{ 7 S>D -3 SM/REM -> 1 -2 }T
+T{ -7 S>D 3 SM/REM -> -1 -2 }T
+T{ -7 S>D -3 SM/REM -> -1 2 }T
+T{ MAX-INT S>D 1 SM/REM -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 SM/REM -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT SM/REM -> 0 1 }T
+T{ MIN-INT S>D MIN-INT SM/REM -> 0 1 }T
+T{ 1S 1 4 SM/REM -> 3 MAX-INT }T
+T{ 2 MIN-INT M* 2 SM/REM -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT SM/REM -> 0 2 }T
+T{ 2 MAX-INT M* 2 SM/REM -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT SM/REM -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT SM/REM -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT SM/REM -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT SM/REM -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT SM/REM -> 0 MAX-INT }T
+
+T{ 0 0 1 UM/MOD -> 0 0 }T
+T{ 1 0 1 UM/MOD -> 0 1 }T
+T{ 1 0 2 UM/MOD -> 1 0 }T
+T{ 3 0 2 UM/MOD -> 1 1 }T
+T{ MAX-UINT 2 UM* 2 UM/MOD -> 0 MAX-UINT }T
+T{ MAX-UINT 2 UM* MAX-UINT UM/MOD -> 0 2 }T
+T{ MAX-UINT MAX-UINT UM* MAX-UINT UM/MOD -> 0 MAX-UINT }T
+
+: IFFLOORED
+ [ -3 2 / -2 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+: IFSYM
+ [ -3 2 / -1 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+\ THE SYSTEM MIGHT DO EITHER FLOORED OR SYMMETRIC DIVISION.
+\ SINCE WE HAVE ALREADY TESTED M*, FM/MOD, AND SM/REM WE CAN USE THEM IN TEST.
+
+IFFLOORED : T/MOD >R S>D R> FM/MOD ;
+IFFLOORED : T/ T/MOD SWAP DROP ;
+IFFLOORED : TMOD T/MOD DROP ;
+IFFLOORED : T*/MOD >R M* R> FM/MOD ;
+IFFLOORED : T*/ T*/MOD SWAP DROP ;
+IFSYM : T/MOD >R S>D R> SM/REM ;
+IFSYM : T/ T/MOD SWAP DROP ;
+IFSYM : TMOD T/MOD DROP ;
+IFSYM : T*/MOD >R M* R> SM/REM ;
+IFSYM : T*/ T*/MOD SWAP DROP ;
+
+T{ 0 1 /MOD -> 0 1 T/MOD }T
+T{ 1 1 /MOD -> 1 1 T/MOD }T
+T{ 2 1 /MOD -> 2 1 T/MOD }T
+T{ -1 1 /MOD -> -1 1 T/MOD }T
+T{ -2 1 /MOD -> -2 1 T/MOD }T
+T{ 0 -1 /MOD -> 0 -1 T/MOD }T
+T{ 1 -1 /MOD -> 1 -1 T/MOD }T
+T{ 2 -1 /MOD -> 2 -1 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -1 /MOD -> -2 -1 T/MOD }T
+T{ 2 2 /MOD -> 2 2 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -2 /MOD -> -2 -2 T/MOD }T
+T{ 7 3 /MOD -> 7 3 T/MOD }T
+T{ 7 -3 /MOD -> 7 -3 T/MOD }T
+T{ -7 3 /MOD -> -7 3 T/MOD }T
+T{ -7 -3 /MOD -> -7 -3 T/MOD }T
+T{ MAX-INT 1 /MOD -> MAX-INT 1 T/MOD }T
+T{ MIN-INT 1 /MOD -> MIN-INT 1 T/MOD }T
+T{ MAX-INT MAX-INT /MOD -> MAX-INT MAX-INT T/MOD }T
+T{ MIN-INT MIN-INT /MOD -> MIN-INT MIN-INT T/MOD }T
+
+T{ 0 1 / -> 0 1 T/ }T
+T{ 1 1 / -> 1 1 T/ }T
+T{ 2 1 / -> 2 1 T/ }T
+T{ -1 1 / -> -1 1 T/ }T
+T{ -2 1 / -> -2 1 T/ }T
+T{ 0 -1 / -> 0 -1 T/ }T
+T{ 1 -1 / -> 1 -1 T/ }T
+T{ 2 -1 / -> 2 -1 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -1 / -> -2 -1 T/ }T
+T{ 2 2 / -> 2 2 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -2 / -> -2 -2 T/ }T
+T{ 7 3 / -> 7 3 T/ }T
+T{ 7 -3 / -> 7 -3 T/ }T
+T{ -7 3 / -> -7 3 T/ }T
+T{ -7 -3 / -> -7 -3 T/ }T
+T{ MAX-INT 1 / -> MAX-INT 1 T/ }T
+T{ MIN-INT 1 / -> MIN-INT 1 T/ }T
+T{ MAX-INT MAX-INT / -> MAX-INT MAX-INT T/ }T
+T{ MIN-INT MIN-INT / -> MIN-INT MIN-INT T/ }T
+
+T{ 0 1 MOD -> 0 1 TMOD }T
+T{ 1 1 MOD -> 1 1 TMOD }T
+T{ 2 1 MOD -> 2 1 TMOD }T
+T{ -1 1 MOD -> -1 1 TMOD }T
+T{ -2 1 MOD -> -2 1 TMOD }T
+T{ 0 -1 MOD -> 0 -1 TMOD }T
+T{ 1 -1 MOD -> 1 -1 TMOD }T
+T{ 2 -1 MOD -> 2 -1 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -1 MOD -> -2 -1 TMOD }T
+T{ 2 2 MOD -> 2 2 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -2 MOD -> -2 -2 TMOD }T
+T{ 7 3 MOD -> 7 3 TMOD }T
+T{ 7 -3 MOD -> 7 -3 TMOD }T
+T{ -7 3 MOD -> -7 3 TMOD }T
+T{ -7 -3 MOD -> -7 -3 TMOD }T
+T{ MAX-INT 1 MOD -> MAX-INT 1 TMOD }T
+T{ MIN-INT 1 MOD -> MIN-INT 1 TMOD }T
+T{ MAX-INT MAX-INT MOD -> MAX-INT MAX-INT TMOD }T
+T{ MIN-INT MIN-INT MOD -> MIN-INT MIN-INT TMOD }T
+
+T{ 0 2 1 */ -> 0 2 1 T*/ }T
+T{ 1 2 1 */ -> 1 2 1 T*/ }T
+T{ 2 2 1 */ -> 2 2 1 T*/ }T
+T{ -1 2 1 */ -> -1 2 1 T*/ }T
+T{ -2 2 1 */ -> -2 2 1 T*/ }T
+T{ 0 2 -1 */ -> 0 2 -1 T*/ }T
+T{ 1 2 -1 */ -> 1 2 -1 T*/ }T
+T{ 2 2 -1 */ -> 2 2 -1 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -1 */ -> -2 2 -1 T*/ }T
+T{ 2 2 2 */ -> 2 2 2 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -2 */ -> -2 2 -2 T*/ }T
+T{ 7 2 3 */ -> 7 2 3 T*/ }T
+T{ 7 2 -3 */ -> 7 2 -3 T*/ }T
+T{ -7 2 3 */ -> -7 2 3 T*/ }T
+T{ -7 2 -3 */ -> -7 2 -3 T*/ }T
+T{ MAX-INT 2 MAX-INT */ -> MAX-INT 2 MAX-INT T*/ }T
+T{ MIN-INT 2 MIN-INT */ -> MIN-INT 2 MIN-INT T*/ }T
+
+T{ 0 2 1 */MOD -> 0 2 1 T*/MOD }T
+T{ 1 2 1 */MOD -> 1 2 1 T*/MOD }T
+T{ 2 2 1 */MOD -> 2 2 1 T*/MOD }T
+T{ -1 2 1 */MOD -> -1 2 1 T*/MOD }T
+T{ -2 2 1 */MOD -> -2 2 1 T*/MOD }T
+T{ 0 2 -1 */MOD -> 0 2 -1 T*/MOD }T
+T{ 1 2 -1 */MOD -> 1 2 -1 T*/MOD }T
+T{ 2 2 -1 */MOD -> 2 2 -1 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -1 */MOD -> -2 2 -1 T*/MOD }T
+T{ 2 2 2 */MOD -> 2 2 2 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -2 */MOD -> -2 2 -2 T*/MOD }T
+T{ 7 2 3 */MOD -> 7 2 3 T*/MOD }T
+T{ 7 2 -3 */MOD -> 7 2 -3 T*/MOD }T
+T{ -7 2 3 */MOD -> -7 2 3 T*/MOD }T
+T{ -7 2 -3 */MOD -> -7 2 -3 T*/MOD }T
+T{ MAX-INT 2 MAX-INT */MOD -> MAX-INT 2 MAX-INT T*/MOD }T
+T{ MIN-INT 2 MIN-INT */MOD -> MIN-INT 2 MIN-INT T*/MOD }T
+
+\ ------------------------------------------------------------------------
+TESTING HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2! ALIGN ALIGNED +! ALLOT
+
+HERE 1 ALLOT
+HERE
+CONSTANT 2NDA
+CONSTANT 1STA
+T{ 1STA 2NDA U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STA 1+ -> 2NDA }T \ ... BY ONE ADDRESS UNIT
+( MISSING TEST: NEGATIVE ALLOT )
+
+HERE 1 ,
+HERE 2 ,
+CONSTANT 2ND
+CONSTANT 1ST
+T{ 1ST 2ND U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1ST CELL+ -> 2ND }T \ ... BY ONE CELL
+T{ 1ST 1 CELLS + -> 2ND }T
+T{ 1ST @ 2ND @ -> 1 2 }T
+T{ 5 1ST ! -> }T
+T{ 1ST @ 2ND @ -> 5 2 }T
+T{ 6 2ND ! -> }T
+T{ 1ST @ 2ND @ -> 5 6 }T
+T{ 1ST 2@ -> 6 5 }T
+T{ 2 1 1ST 2! -> }T
+T{ 1ST 2@ -> 2 1 }T
+T{ 1S 1ST ! 1ST @ -> 1S }T \ CAN STORE CELL-WIDE VALUE
+
+HERE 1 C,
+HERE 2 C,
+CONSTANT 2NDC
+CONSTANT 1STC
+T{ 1STC 2NDC U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STC CHAR+ -> 2NDC }T \ ... BY ONE CHAR
+T{ 1STC 1 CHARS + -> 2NDC }T
+T{ 1STC C@ 2NDC C@ -> 1 2 }T
+T{ 3 1STC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 2 }T
+T{ 4 2NDC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 4 }T
+
+ALIGN 1 ALLOT HERE ALIGN HERE 3 CELLS ALLOT
+CONSTANT A-ADDR CONSTANT UA-ADDR
+T{ UA-ADDR ALIGNED -> A-ADDR }T
+T{ 1 A-ADDR C! A-ADDR C@ -> 1 }T
+T{ 1234 A-ADDR ! A-ADDR @ -> 1234 }T
+T{ 123 456 A-ADDR 2! A-ADDR 2@ -> 123 456 }T
+T{ 2 A-ADDR CHAR+ C! A-ADDR CHAR+ C@ -> 2 }T
+T{ 3 A-ADDR CELL+ C! A-ADDR CELL+ C@ -> 3 }T
+T{ 1234 A-ADDR CELL+ ! A-ADDR CELL+ @ -> 1234 }T
+T{ 123 456 A-ADDR CELL+ 2! A-ADDR CELL+ 2@ -> 123 456 }T
+
+: BITS ( X -- U )
+ 0 SWAP BEGIN DUP WHILE DUP MSB AND IF >R 1+ R> THEN 2* REPEAT DROP ;
+( CHARACTERS >= 1 AU, <= SIZE OF CELL, >= 8 BITS )
+T{ 1 CHARS 1 < -> <FALSE> }T
+T{ 1 CHARS 1 CELLS > -> <FALSE> }T
+( TBD: HOW TO FIND NUMBER OF BITS? )
+
+( CELLS >= 1 AU, INTEGRAL MULTIPLE OF CHAR SIZE, >= 16 BITS )
+T{ 1 CELLS 1 < -> <FALSE> }T
+T{ 1 CELLS 1 CHARS MOD -> 0 }T
+T{ 1S BITS 10 < -> <FALSE> }T
+
+T{ 0 1ST ! -> }T
+T{ 1 1ST +! -> }T
+T{ 1ST @ -> 1 }T
+T{ -1 1ST +! 1ST @ -> 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING CHAR [CHAR] [ ] BL S"
+
+T{ BL -> 20 }T
+T{ CHAR X -> 58 }T
+T{ CHAR HELLO -> 48 }T
+T{ : GC1 [CHAR] X ; -> }T
+T{ : GC2 [CHAR] HELLO ; -> }T
+T{ GC1 -> 58 }T
+T{ GC2 -> 48 }T
+T{ : GC3 [ GC1 ] LITERAL ; -> }T
+T{ GC3 -> 58 }T
+T{ : GC4 S" XY" ; -> }T
+T{ GC4 SWAP DROP -> 2 }T
+T{ GC4 DROP DUP C@ SWAP CHAR+ C@ -> 58 59 }T
+
+\ ------------------------------------------------------------------------
+TESTING ' ['] FIND EXECUTE IMMEDIATE COUNT LITERAL POSTPONE STATE
+
+T{ : GT1 123 ; -> }T
+T{ ' GT1 EXECUTE -> 123 }T
+T{ : GT2 ['] GT1 ; IMMEDIATE -> }T
+T{ GT2 EXECUTE -> 123 }T
+HERE 3 C, CHAR G C, CHAR T C, CHAR 1 C, CONSTANT GT1STRING
+HERE 3 C, CHAR G C, CHAR T C, CHAR 2 C, CONSTANT GT2STRING
+T{ GT1STRING FIND -> ' GT1 -1 }T
+T{ GT2STRING FIND -> ' GT2 1 }T
+( HOW TO SEARCH FOR NON-EXISTENT WORD? )
+T{ : GT3 GT2 LITERAL ; -> }T
+T{ GT3 -> ' GT1 }T
+T{ GT1STRING COUNT -> GT1STRING CHAR+ 3 }T
+
+T{ : GT4 POSTPONE GT1 ; IMMEDIATE -> }T
+T{ : GT5 GT4 ; -> }T
+T{ GT5 -> 123 }T
+T{ : GT6 345 ; IMMEDIATE -> }T
+T{ : GT7 POSTPONE GT6 ; -> }T
+T{ GT7 -> 345 }T
+
+T{ : GT8 STATE @ ; IMMEDIATE -> }T
+T{ GT8 -> 0 }T
+T{ : GT9 GT8 LITERAL ; -> }T
+T{ GT9 0= -> <FALSE> }T
+
+\ ------------------------------------------------------------------------
+TESTING IF ELSE THEN BEGIN WHILE REPEAT UNTIL RECURSE
+
+T{ : GI1 IF 123 THEN ; -> }T
+T{ : GI2 IF 123 ELSE 234 THEN ; -> }T
+T{ 0 GI1 -> }T
+T{ 1 GI1 -> 123 }T
+T{ -1 GI1 -> 123 }T
+T{ 0 GI2 -> 234 }T
+T{ 1 GI2 -> 123 }T
+T{ -1 GI1 -> 123 }T
+
+T{ : GI3 BEGIN DUP 5 < WHILE DUP 1+ REPEAT ; -> }T
+T{ 0 GI3 -> 0 1 2 3 4 5 }T
+T{ 4 GI3 -> 4 5 }T
+T{ 5 GI3 -> 5 }T
+T{ 6 GI3 -> 6 }T
+
+T{ : GI4 BEGIN DUP 1+ DUP 5 > UNTIL ; -> }T
+T{ 3 GI4 -> 3 4 5 6 }T
+T{ 5 GI4 -> 5 6 }T
+T{ 6 GI4 -> 6 7 }T
+
+T{ : GI5 BEGIN DUP 2 > WHILE DUP 5 < WHILE DUP 1+ REPEAT 123 ELSE 345 THEN ; -> }T
+T{ 1 GI5 -> 1 345 }T
+T{ 2 GI5 -> 2 345 }T
+T{ 3 GI5 -> 3 4 5 123 }T
+T{ 4 GI5 -> 4 5 123 }T
+T{ 5 GI5 -> 5 123 }T
+
+T{ : GI6 ( N -- 0,1,..N ) DUP IF DUP >R 1- RECURSE R> THEN ; -> }T
+T{ 0 GI6 -> 0 }T
+T{ 1 GI6 -> 0 1 }T
+T{ 2 GI6 -> 0 1 2 }T
+T{ 3 GI6 -> 0 1 2 3 }T
+T{ 4 GI6 -> 0 1 2 3 4 }T
+
+\ ------------------------------------------------------------------------
+TESTING DO LOOP +LOOP I J UNLOOP LEAVE EXIT
+
+T{ : GD1 DO I LOOP ; -> }T
+T{ 4 1 GD1 -> 1 2 3 }T
+T{ 2 -1 GD1 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD1 -> MID-UINT }T
+
+T{ : GD2 DO I -1 +LOOP ; -> }T
+T{ 1 4 GD2 -> 4 3 2 1 }T
+T{ -1 2 GD2 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD2 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD3 DO 1 0 DO J LOOP LOOP ; -> }T
+T{ 4 1 GD3 -> 1 2 3 }T
+T{ 2 -1 GD3 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD3 -> MID-UINT }T
+
+T{ : GD4 DO 1 0 DO J LOOP -1 +LOOP ; -> }T
+T{ 1 4 GD4 -> 4 3 2 1 }T
+T{ -1 2 GD4 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD4 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD5 123 SWAP 0 DO I 4 > IF DROP 234 LEAVE THEN LOOP ; -> }T
+T{ 1 GD5 -> 123 }T
+T{ 5 GD5 -> 123 }T
+T{ 6 GD5 -> 234 }T
+
+T{ : GD6 ( PAT: T{0 0}T,T{0 0}TT{1 0}TT{1 1}T,T{0 0}TT{1 0}TT{1 1}TT{2 0}TT{2 1}TT{2 2}T )
+ 0 SWAP 0 DO
+ I 1+ 0 DO I J + 3 = IF I UNLOOP I UNLOOP EXIT THEN 1+ LOOP
+ LOOP ; -> }T
+T{ 1 GD6 -> 1 }T
+T{ 2 GD6 -> 3 }T
+T{ 3 GD6 -> 4 1 2 }T
+
+\ ------------------------------------------------------------------------
+TESTING DEFINING WORDS: : ; CONSTANT VARIABLE CREATE DOES> >BODY
+
+T{ 123 CONSTANT X123 -> }T
+T{ X123 -> 123 }T
+T{ : EQU CONSTANT ; -> }T
+T{ X123 EQU Y123 -> }T
+T{ Y123 -> 123 }T
+
+T{ VARIABLE V1 -> }T
+T{ 123 V1 ! -> }T
+T{ V1 @ -> 123 }T
+
+T{ : NOP : POSTPONE ; ; -> }T
+T{ NOP NOP1 NOP NOP2 -> }T
+T{ NOP1 -> }T
+T{ NOP2 -> }T
+
+T{ : DOES1 DOES> @ 1 + ; -> }T
+T{ : DOES2 DOES> @ 2 + ; -> }T
+T{ CREATE CR1 -> }T
+T{ CR1 -> HERE }T
+T{ ' CR1 >BODY -> HERE }T
+T{ 1 , -> }T
+T{ CR1 @ -> 1 }T
+T{ DOES1 -> }T
+T{ CR1 -> 2 }T
+T{ DOES2 -> }T
+T{ CR1 -> 3 }T
+
+T{ : WEIRD: CREATE DOES> 1 + DOES> 2 + ; -> }T
+T{ WEIRD: W1 -> }T
+T{ ' W1 >BODY -> HERE }T
+T{ W1 -> HERE 1 + }T
+T{ W1 -> HERE 2 + }T
+
+\ ------------------------------------------------------------------------
+TESTING EVALUATE
+
+: GE1 S" 123" ; IMMEDIATE
+: GE2 S" 123 1+" ; IMMEDIATE
+: GE3 S" : GE4 345 ;" ;
+: GE5 EVALUATE ; IMMEDIATE
+
+T{ GE1 EVALUATE -> 123 }T ( TEST EVALUATE IN INTERP. STATE )
+T{ GE2 EVALUATE -> 124 }T
+T{ GE3 EVALUATE -> }T
+T{ GE4 -> 345 }T
+
+T{ : GE6 GE1 GE5 ; -> }T ( TEST EVALUATE IN COMPILE STATE )
+T{ GE6 -> 123 }T
+T{ : GE7 GE2 GE5 ; -> }T
+T{ GE7 -> 124 }T
+
+\ ------------------------------------------------------------------------
+TESTING SOURCE >IN WORD
+
+: GS1 S" SOURCE" 2DUP EVALUATE
+ >R SWAP >R = R> R> = ;
+T{ GS1 -> <TRUE> <TRUE> }T
+
+VARIABLE SCANS
+: RESCAN? -1 SCANS +! SCANS @ IF 0 >IN ! THEN ;
+
+T{ 2 SCANS !
+345 RESCAN?
+-> 345 345 }T
+
+: GS2 5 SCANS ! S" 123 RESCAN?" EVALUATE ;
+T{ GS2 -> 123 123 123 123 123 }T
+
+: GS3 WORD COUNT SWAP C@ ;
+T{ BL GS3 HELLO -> 5 CHAR H }T
+T{ CHAR " GS3 GOODBYE" -> 7 CHAR G }T
+T{ BL GS3
+DROP -> 0 }T \ BLANK LINE RETURN ZERO-LENGTH STRING
+
+: GS4 SOURCE >IN ! DROP ;
+T{ GS4 123 456
+-> }T
+
+\ ------------------------------------------------------------------------
+TESTING <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL
+
+: S= \ ( ADDR1 C1 ADDR2 C2 -- T/F ) COMPARE TWO STRINGS.
+ >R SWAP R@ = IF \ MAKE SURE STRINGS HAVE SAME LENGTH
+ R> ?DUP IF \ IF NON-EMPTY STRINGS
+ 0 DO
+ OVER C@ OVER C@ - IF
+ 2DROP <FALSE> UNLOOP EXIT THEN
+ SWAP CHAR+ SWAP CHAR+
+ LOOP
+ THEN
+ 2DROP <TRUE> \ IF WE GET HERE, STRINGS MATCH
+ ELSE
+ R> DROP 2DROP <FALSE> \ LENGTHS MISMATCH
+ THEN ;
+
+: GP1 <# 41 HOLD 42 HOLD 0 0 #> S" BA" S= ;
+T{ GP1 -> <TRUE> }T
+
+: GP2 <# -1 SIGN 0 SIGN -1 SIGN 0 0 #> S" --" S= ;
+T{ GP2 -> <TRUE> }T
+
+: GP3 <# 1 0 # # #> S" 01" S= ;
+T{ GP3 -> <TRUE> }T
+
+: GP4 <# 1 0 #S #> S" 1" S= ;
+T{ GP4 -> <TRUE> }T
+
+24 CONSTANT MAX-BASE \ BASE 2 .. 36
+: COUNT-BITS
+ 0 0 INVERT BEGIN DUP WHILE >R 1+ R> 2* REPEAT DROP ;
+COUNT-BITS 2* CONSTANT #BITS-UD \ NUMBER OF BITS IN UD
+
+: GP5
+ BASE @ <TRUE>
+ MAX-BASE 1+ 2 DO \ FOR EACH POSSIBLE BASE
+ I BASE ! \ TBD: ASSUMES BASE WORKS
+ I 0 <# #S #> S" 10" S= AND
+ LOOP
+ SWAP BASE ! ;
+T{ GP5 -> <TRUE> }T
+
+: GP6
+ BASE @ >R 2 BASE !
+ MAX-UINT MAX-UINT <# #S #> \ MAXIMUM UD TO BINARY
+ R> BASE ! \ S: C-ADDR U
+ DUP #BITS-UD = SWAP
+ 0 DO \ S: C-ADDR FLAG
+ OVER C@ [CHAR] 1 = AND \ ALL ONES
+ >R CHAR+ R>
+ LOOP SWAP DROP ;
+T{ GP6 -> <TRUE> }T
+
+: GP7
+ BASE @ >R MAX-BASE BASE !
+ <TRUE>
+ A 0 DO
+ I 0 <# #S #>
+ 1 = SWAP C@ I 30 + = AND AND
+ LOOP
+ MAX-BASE A DO
+ I 0 <# #S #>
+ 1 = SWAP C@ 41 I A - + = AND AND
+ LOOP
+ R> BASE ! ;
+
+T{ GP7 -> <TRUE> }T
+
+\ >NUMBER TESTS
+CREATE GN-BUF 0 C,
+: GN-STRING GN-BUF 1 ;
+: GN-CONSUMED GN-BUF CHAR+ 0 ;
+: GN' [CHAR] ' WORD CHAR+ C@ GN-BUF C! GN-STRING ;
+
+T{ 0 0 GN' 0' >NUMBER -> 0 0 GN-CONSUMED }T
+T{ 0 0 GN' 1' >NUMBER -> 1 0 GN-CONSUMED }T
+T{ 1 0 GN' 1' >NUMBER -> BASE @ 1+ 0 GN-CONSUMED }T
+T{ 0 0 GN' -' >NUMBER -> 0 0 GN-STRING }T \ SHOULD FAIL TO CONVERT THESE
+T{ 0 0 GN' +' >NUMBER -> 0 0 GN-STRING }T
+T{ 0 0 GN' .' >NUMBER -> 0 0 GN-STRING }T
+
+: >NUMBER-BASED
+ BASE @ >R BASE ! >NUMBER R> BASE ! ;
+
+T{ 0 0 GN' 2' 10 >NUMBER-BASED -> 2 0 GN-CONSUMED }T
+T{ 0 0 GN' 2' 2 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' F' 10 >NUMBER-BASED -> F 0 GN-CONSUMED }T
+T{ 0 0 GN' G' 10 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' G' MAX-BASE >NUMBER-BASED -> 10 0 GN-CONSUMED }T
+T{ 0 0 GN' Z' MAX-BASE >NUMBER-BASED -> 23 0 GN-CONSUMED }T
+
+: GN1 \ ( UD BASE -- UD' LEN ) UD SHOULD EQUAL UD' AND LEN SHOULD BE ZERO.
+ BASE @ >R BASE !
+ <# #S #>
+ 0 0 2SWAP >NUMBER SWAP DROP \ RETURN LENGTH ONLY
+ R> BASE ! ;
+T{ 0 0 2 GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 2 GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP 2 GN1 -> MAX-UINT DUP 0 }T
+T{ 0 0 MAX-BASE GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 MAX-BASE GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP MAX-BASE GN1 -> MAX-UINT DUP 0 }T
+
+: GN2 \ ( -- 16 10 )
+ BASE @ >R HEX BASE @ DECIMAL BASE @ R> BASE ! ;
+T{ GN2 -> 10 A }T
+
+\ ------------------------------------------------------------------------
+TESTING FILL MOVE
+
+CREATE FBUF 00 C, 00 C, 00 C,
+CREATE SBUF 12 C, 34 C, 56 C,
+: SEEBUF FBUF C@ FBUF CHAR+ C@ FBUF CHAR+ CHAR+ C@ ;
+
+T{ FBUF 0 20 FILL -> }T
+T{ SEEBUF -> 00 00 00 }T
+
+T{ FBUF 1 20 FILL -> }T
+T{ SEEBUF -> 20 00 00 }T
+
+T{ FBUF 3 20 FILL -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ FBUF FBUF 3 CHARS MOVE -> }T \ BIZARRE SPECIAL CASE
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 0 CHARS MOVE -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 1 CHARS MOVE -> }T
+T{ SEEBUF -> 12 20 20 }T
+
+T{ SBUF FBUF 3 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 56 }T
+
+T{ FBUF FBUF CHAR+ 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 12 34 }T
+
+T{ FBUF CHAR+ FBUF 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 34 }T
+
+\ ------------------------------------------------------------------------
+TESTING OUTPUT: . ." CR EMIT SPACE SPACES TYPE U.
+
+: OUTPUT-TEST
+ ." YOU SHOULD SEE THE STANDARD GRAPHIC CHARACTERS:" CR
+ 41 BL DO I EMIT LOOP CR
+ 61 41 DO I EMIT LOOP CR
+ 7F 61 DO I EMIT LOOP CR
+ ." YOU SHOULD SEE 0-9 SEPARATED BY A SPACE:" CR
+ 9 1+ 0 DO I . LOOP CR
+ ." YOU SHOULD SEE 0-9 (WITH NO SPACES):" CR
+ [CHAR] 9 1+ [CHAR] 0 DO I 0 SPACES EMIT LOOP CR
+ ." YOU SHOULD SEE A-G SEPARATED BY A SPACE:" CR
+ [CHAR] G 1+ [CHAR] A DO I EMIT SPACE LOOP CR
+ ." YOU SHOULD SEE 0-5 SEPARATED BY TWO SPACES:" CR
+ 5 1+ 0 DO I [CHAR] 0 + EMIT 2 SPACES LOOP CR
+ ." YOU SHOULD SEE TWO SEPARATE LINES:" CR
+ S" LINE 1" TYPE CR S" LINE 2" TYPE CR
+ ." YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:" CR
+ ." SIGNED: " MIN-INT . MAX-INT . CR
+ ." UNSIGNED: " 0 U. MAX-UINT U. CR
+;
+
+T{ OUTPUT-TEST -> }T
+\ ------------------------------------------------------------------------
+TESTING INPUT: ACCEPT
+
+CREATE ABUF 80 CHARS ALLOT
+
+: ACCEPT-TEST
+ CR ." PLEASE TYPE UP TO 80 CHARACTERS:" CR
+\ ABUF 80 ACCEPT
+ ABUF 80 (ACCEPT) \ JMT: because ACCEPT is DEFERred to SD_ACCEPT
+ CR ." RECEIVED: " [CHAR] " EMIT
+ ABUF SWAP TYPE [CHAR] " EMIT CR
+;
+
+T{ ACCEPT-TEST -> }T
+\ ------------------------------------------------------------------------
+TESTING DICTIONARY SEARCH RULES
+
+T{ : GDX 123 ; : GDX GDX 234 ; -> }T
+
+T{ GDX -> 123 234 }T
+
+CR .( End of Core word set tests) CR
+
+
+$0A BASE !
+
+ ; happy end of core test
--- /dev/null
+; -------------------------------------------------------------------------------
+; ANS complement for MSP430FRxxxx devices with hardware_MPY, to pass CORETEST.4th
+; -------------------------------------------------------------------------------
+
+CODE INVERT
+ XOR #-1,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE LSHIFT
+ MOV @R15+,R10
+ AND #$1F,R14
+0<> IF
+ BEGIN ADD R10,R10
+ SUB #1,R14
+ 0= UNTIL
+THEN MOV R10,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE RSHIFT
+ MOV @R15+,R10
+ AND #$1F,R14
+0<> IF
+ BEGIN BIC #1,R2
+ RRC R10
+ SUB #1,R14
+ 0= UNTIL
+THEN MOV R10,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE 1+
+ ADD #1,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE 1-
+ SUB #1,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE MAX
+ CMP @R15,R14
+ S< ?GOTO FW1
+BW1 ADD #2,R15
+ MOV @R13+,R0
+ENDCODE
+
+CODE MIN
+ CMP @R15,R14
+ S< ?GOTO BW1
+FW1 MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE 2*
+ ADD R14,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE 2/
+ RRA R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE NIP
+ADD #2,R15
+MOV @R13+,R0
+ENDCODE
+
+: S>D
+ DUP 0<
+;
+
+CODE UM*
+MOV @R15,&$4C0
+MOV R14,&$4C8
+MOV &$4E4,0(R15)
+MOV &$4E6,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE M*
+MOV @R15,&$4C2
+MOV R14,&$4C8
+MOV &$4E4,0(R15)
+MOV &$4E6,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE UM/MOD
+ MOV @R15+,R10
+ MOV @R15,R12
+ MOV #16,R9
+BW1 CMP R14,R10
+ U< ?GOTO FW1
+ SUB R14,R10
+FW1
+BW2 ADDC R8,R8
+ SUB #1,R9
+ 0< ?GOTO FW1
+ ADD R12,R12
+ ADDC R10,R10
+ U< ?GOTO BW1
+ SUB R14,R10
+ BIS #1,R2
+ GOTO BW2
+FW1 MOV R10,0(R15)
+ MOV R8,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE SM/REM
+MOV R14,R12
+MOV @R15,R11
+CMP #0,R14
+S< IF
+ XOR #-1,R14
+ ADD #1,R14
+THEN
+CMP #0,0(R15)
+S< IF
+ XOR #-1,2(R15)
+ XOR #-1,0(R15)
+ ADD #1,2(R15)
+ ADDC #0,0(R15)
+THEN
+PUSHM R13,R12
+LO2HI
+UM/MOD
+HI2LO
+POPM R12,R13
+CMP #0,R11
+S< IF
+ XOR #-1,0(R15)
+ ADD #1,0(R15)
+THEN
+XOR R12,R11
+CMP #0,R11
+S< IF
+ XOR #-1,R14
+ ADD #1,R14
+THEN
+MOV @R13+,R0
+ENDCODE
+
+: FM/MOD
+SM/REM
+HI2LO
+CMP #0,0(R15)
+0<> IF
+ CMP #1,R14
+ S< IF
+ ADD R12,0(R15)
+ SUB #1,R14
+ THEN
+THEN
+MOV @R1+,R13
+MOV @R13+,R0
+ENDCODE
+
+: *
+M* DROP
+;
+
+: /MOD
+>R DUP 0< R> FM/MOD
+;
+
+: /
+>R DUP 0< R> FM/MOD NIP
+;
+
+: MOD
+>R DUP 0< R> FM/MOD DROP
+;
+
+: */MOD
+>R M* R> FM/MOD
+;
+
+: */
+>R M* R> FM/MOD NIP
+;
+
+CODE 2@
+SUB #2, R15
+MOV 2(R14),0(R15)
+MOV @R14,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE 2!
+MOV @R15+,0(R14)
+MOV @R15+,2(R14)
+MOV @R15+,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE 2DUP
+SUB #4,R15
+MOV R14,2(R15)
+MOV 4(R15),0(R15)
+MOV @R13+,R0
+ENDCODE
+
+CODE 2DROP
+ADD #2,R15
+MOV @R15+,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE 2SWAP
+MOV @R15,R10
+MOV 4(R15),0(R15)
+MOV R10,4(R15)
+MOV R14,R10
+MOV 2(R15),R14
+MOV R10,2(R15)
+MOV @R13+,R0
+ENDCODE
+
+CODE 2OVER
+SUB #4,R15
+MOV R14,2(R15)
+MOV 8(R15),0(R15)
+MOV 6(R15),R14
+MOV @R13+,R0
+ENDCODE
+
+CODE ALIGNED
+BIT #1,R14
+ADDC #0,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE ALIGN
+BIT #1,&$1DC4
+ADDC #0,&$1DC4
+MOV @R13+,R0
+ENDCODE
+
+CODE CHARS
+MOV @R13+,R0
+ENDCODE
+
+CODE CHAR+
+ADD #1,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE CELLS
+ADD R14,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE CELL+
+ADD #2,R14
+MOV @R13+,R0
+ENDCODE
+
+: CHAR
+ BL WORD 1+ C@
+;
+: [CHAR]
+ CHAR lit lit , ,
+; IMMEDIATE
+
+CODE +!
+ADD @R15+,0(R14)
+MOV @R15+,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE FILL
+MOV @R15+,R9
+MOV @R15+,R10
+CMP #0,R9
+0<> IF
+ BEGIN
+ MOV.B R14,0(R10)
+ ADD #1,R10
+ SUB #1,R9
+ 0= UNTIL
+THEN
+MOV @R15+,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE HEX
+MOV #$10,&$1DDA
+MOV @R13+,R0
+ENDCODE
+
+CODE DECIMAL
+MOV #$0A,&$1DDA
+MOV @R13+,R0
+ENDCODE
+
+: (
+$29 WORD DROP
+; IMMEDIATE
+
+: .(
+$29 WORD
+COUNT TYPE
+; IMMEDIATE
+
+CODE SOURCE
+SUB #4,R15
+MOV R14,2(R15)
+MOV &$1DBE,R14
+MOV &$1DC0,0(R15)
+MOV @R13+,R0
+ENDCODE
+
+CODE >BODY
+ADD #4,R14
+MOV @R13+,R0
+ENDCODE
+
+
+ECHO
+
+; ===============================================================
+;
+; ##### ####### ###### ####### ####### ####### ##### #######
+; # # # # # # # # # # # #
+; # # # # # # # # # #
+; # # # ###### ##### # ##### ##### #
+; # # # # # # # # # #
+; # # # # # # # # # # # #
+; ##### ####### # # ####### # ####### ##### #
+;
+; ===============================================================
+
+
+\ From: John Hayes S1I
+\ Subject: tester.fr
+\ Date: Mon, 27 Nov 95 13:10:09 PST
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.1
+
+\ 22/1/09 The words { and } have been changed to T{ and }T respectively to
+\ agree with the Forth 200X file ttester.fs. This avoids clashes with
+\ locals using { ... } and the FSL use of }
+
+
+\ 13/05/14 jmt. added colorised error messages.
+
+
+
+ 0 CONSTANT FALSE
+-1 CONSTANT TRUE
+
+\ SET THE FOLLOWING FLAG TO TRUE FOR MORE VERBOSE OUTPUT; THIS MAY
+\ ALLOW YOU TO TELL WHICH TEST CAUSED YOUR SYSTEM TO HANG.
+VARIABLE VERBOSE
+ FALSE VERBOSE !
+\ TRUE VERBOSE !
+
+\ : EMPTY-STACK ( ... -- ) \ EMPTY STACK: HANDLES UNDERFLOWED STACK TOO.
+\ DEPTH ?DUP
+\ IF DUP 0< IF NEGATE 0
+\ DO 0 LOOP
+\ ELSE 0 DO DROP LOOP THEN
+\ THEN ;
+\
+\ : ERROR \ ( C-ADDR U -- ) DISPLAY AN ERROR MESSAGE FOLLOWED BY
+\ \ THE LINE THAT HAD THE ERROR.
+\ TYPE SOURCE TYPE CR \ DISPLAY LINE CORRESPONDING TO ERROR
+\ EMPTY-STACK \ THROW AWAY EVERY THING ELSE
+\ QUIT \ *** Uncomment this line to QUIT on an error
+\ ;
+
+VARIABLE ACTUAL-DEPTH \ STACK RECORD
+CREATE ACTUAL-RESULTS 20 CELLS ALLOT
+
+: T{ \ ( -- ) SYNTACTIC SUGAR.
+ ;
+
+: -> \ ( ... -- ) RECORD DEPTH AND CONTENT OF STACK.
+ DEPTH DUP ACTUAL-DEPTH ! \ RECORD DEPTH
+ ?DUP IF \ IF THERE IS SOMETHING ON STACK
+ 0 DO ACTUAL-RESULTS I CELLS + ! LOOP \ SAVE THEM
+ THEN ;
+
+: }T \ ( ... -- ) COMPARE STACK (EXPECTED) CONTENTS WITH SAVED
+ \ (ACTUAL) CONTENTS.
+ DEPTH ACTUAL-DEPTH @ = IF \ IF DEPTHS MATCH
+ DEPTH ?DUP IF \ IF THERE IS SOMETHING ON THE STACK
+ 0 DO \ FOR EACH STACK ITEM
+ ACTUAL-RESULTS I CELLS + @ \ COMPARE ACTUAL WITH EXPECTED
+\ = 0= IF S" INCORRECT RESULT: " ERROR LEAVE THEN \ jmt
+ = 0= IF ABORT" INCORRECT RESULT: " THEN \ jmt : colorised message
+ LOOP
+ THEN
+ ELSE \ DEPTH MISMATCH
+\ S" WRONG NUMBER OF RESULTS: " ERROR \ jmt
+ ABORT" WRONG NUMBER OF RESULTS: " \ jmt : colorised message
+ THEN ;
+
+: TESTING \ ( -- ) TALKING COMMENT.
+ SOURCE VERBOSE @
+ IF DUP >R TYPE CR R> >IN !
+ ELSE >IN ! DROP [CHAR] * EMIT
+ THEN ;
+
+\ From: John Hayes S1I
+\ Subject: core.fr
+\ Date: Mon, 27 Nov 95 13:10
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.2
+\ THIS PROGRAM TESTS THE CORE WORDS OF AN ANS FORTH SYSTEM.
+\ THE PROGRAM ASSUMES A TWO'S COMPLEMENT IMPLEMENTATION WHERE
+\ THE RANGE OF SIGNED NUMBERS IS -2^(N-1) ... 2^(N-1)-1 AND
+\ THE RANGE OF UNSIGNED NUMBERS IS 0 ... 2^(N)-1.
+\ I HAVEN'T FIGURED OUT HOW TO TEST KEY, QUIT, ABORT, OR ABORT"...
+\ I ALSO HAVEN'T THOUGHT OF A WAY TO TEST ENVIRONMENT?...
+
+CR
+TESTING CORE WORDS
+HEX
+
+\ ------------------------------------------------------------------------
+TESTING BASIC ASSUMPTIONS
+
+T{ -> }T \ START WITH CLEAN SLATE
+( TEST IF ANY BITS ARE SET; ANSWER IN BASE 1 )
+T{ : BITSSET? IF 0 0 ELSE 0 THEN ; -> }T
+T{ 0 BITSSET? -> 0 }T ( ZERO IS ALL BITS CLEAR )
+T{ 1 BITSSET? -> 0 0 }T ( OTHER NUMBER HAVE AT LEAST ONE BIT )
+T{ -1 BITSSET? -> 0 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING BOOLEANS: INVERT AND OR XOR
+
+T{ 0 0 AND -> 0 }T
+T{ 0 1 AND -> 0 }T
+T{ 1 0 AND -> 0 }T
+T{ 1 1 AND -> 1 }T
+
+T{ 0 INVERT 1 AND -> 1 }T
+T{ 1 INVERT 1 AND -> 0 }T
+
+0 CONSTANT 0S
+0 INVERT CONSTANT 1S
+
+T{ 0S INVERT -> 1S }T
+T{ 1S INVERT -> 0S }T
+
+T{ 0S 0S AND -> 0S }T
+T{ 0S 1S AND -> 0S }T
+T{ 1S 0S AND -> 0S }T
+T{ 1S 1S AND -> 1S }T
+
+T{ 0S 0S OR -> 0S }T
+T{ 0S 1S OR -> 1S }T
+T{ 1S 0S OR -> 1S }T
+T{ 1S 1S OR -> 1S }T
+
+T{ 0S 0S XOR -> 0S }T
+T{ 0S 1S XOR -> 1S }T
+T{ 1S 0S XOR -> 1S }T
+T{ 1S 1S XOR -> 0S }T
+
+\ ------------------------------------------------------------------------
+TESTING 2* 2/ LSHIFT RSHIFT
+
+( WE TRUST 1S, INVERT, AND BITSSET?; WE WILL CONFIRM RSHIFT LATER )
+1S 1 RSHIFT INVERT CONSTANT MSB
+T{ MSB BITSSET? -> 0 0 }T
+
+T{ 0S 2* -> 0S }T
+T{ 1 2* -> 2 }T
+T{ 4000 2* -> 8000 }T
+T{ 1S 2* 1 XOR -> 1S }T
+T{ MSB 2* -> 0S }T
+
+T{ 0S 2/ -> 0S }T
+T{ 1 2/ -> 0 }T
+T{ 4000 2/ -> 2000 }T
+T{ 1S 2/ -> 1S }T \ MSB PROPOGATED
+T{ 1S 1 XOR 2/ -> 1S }T
+T{ MSB 2/ MSB AND -> MSB }T
+
+T{ 1 0 LSHIFT -> 1 }T
+T{ 1 1 LSHIFT -> 2 }T
+T{ 1 2 LSHIFT -> 4 }T
+T{ 1 F LSHIFT -> 8000 }T \ BIGGEST GUARANTEED SHIFT
+T{ 1S 1 LSHIFT 1 XOR -> 1S }T
+T{ MSB 1 LSHIFT -> 0 }T
+
+T{ 1 0 RSHIFT -> 1 }T
+T{ 1 1 RSHIFT -> 0 }T
+T{ 2 1 RSHIFT -> 1 }T
+T{ 4 2 RSHIFT -> 1 }T
+T{ 8000 F RSHIFT -> 1 }T \ BIGGEST
+T{ MSB 1 RSHIFT MSB AND -> 0 }T \ RSHIFT ZERO FILLS MSBS
+T{ MSB 1 RSHIFT 2* -> MSB }T
+
+\ ------------------------------------------------------------------------
+TESTING COMPARISONS: 0= = 0< < > U< MIN MAX
+0 INVERT CONSTANT MAX-UINT
+0 INVERT 1 RSHIFT CONSTANT MAX-INT
+0 INVERT 1 RSHIFT INVERT CONSTANT MIN-INT
+0 INVERT 1 RSHIFT CONSTANT MID-UINT
+0 INVERT 1 RSHIFT INVERT CONSTANT MID-UINT+1
+
+0S CONSTANT <FALSE>
+1S CONSTANT <TRUE>
+
+T{ 0 0= -> <TRUE> }T
+T{ 1 0= -> <FALSE> }T
+T{ 2 0= -> <FALSE> }T
+T{ -1 0= -> <FALSE> }T
+T{ MAX-UINT 0= -> <FALSE> }T
+T{ MIN-INT 0= -> <FALSE> }T
+T{ MAX-INT 0= -> <FALSE> }T
+
+T{ 0 0 = -> <TRUE> }T
+T{ 1 1 = -> <TRUE> }T
+T{ -1 -1 = -> <TRUE> }T
+T{ 1 0 = -> <FALSE> }T
+T{ -1 0 = -> <FALSE> }T
+T{ 0 1 = -> <FALSE> }T
+T{ 0 -1 = -> <FALSE> }T
+
+T{ 0 0< -> <FALSE> }T
+T{ -1 0< -> <TRUE> }T
+T{ MIN-INT 0< -> <TRUE> }T
+T{ 1 0< -> <FALSE> }T
+T{ MAX-INT 0< -> <FALSE> }T
+
+T{ 0 1 < -> <TRUE> }T
+T{ 1 2 < -> <TRUE> }T
+T{ -1 0 < -> <TRUE> }T
+T{ -1 1 < -> <TRUE> }T
+T{ MIN-INT 0 < -> <TRUE> }T
+T{ MIN-INT MAX-INT < -> <TRUE> }T
+T{ 0 MAX-INT < -> <TRUE> }T
+T{ 0 0 < -> <FALSE> }T
+T{ 1 1 < -> <FALSE> }T
+T{ 1 0 < -> <FALSE> }T
+T{ 2 1 < -> <FALSE> }T
+T{ 0 -1 < -> <FALSE> }T
+T{ 1 -1 < -> <FALSE> }T
+T{ 0 MIN-INT < -> <FALSE> }T
+T{ MAX-INT MIN-INT < -> <FALSE> }T
+T{ MAX-INT 0 < -> <FALSE> }T
+
+T{ 0 1 > -> <FALSE> }T
+T{ 1 2 > -> <FALSE> }T
+T{ -1 0 > -> <FALSE> }T
+T{ -1 1 > -> <FALSE> }T
+T{ MIN-INT 0 > -> <FALSE> }T
+T{ MIN-INT MAX-INT > -> <FALSE> }T
+T{ 0 MAX-INT > -> <FALSE> }T
+T{ 0 0 > -> <FALSE> }T
+T{ 1 1 > -> <FALSE> }T
+T{ 1 0 > -> <TRUE> }T
+T{ 2 1 > -> <TRUE> }T
+T{ 0 -1 > -> <TRUE> }T
+T{ 1 -1 > -> <TRUE> }T
+T{ 0 MIN-INT > -> <TRUE> }T
+T{ MAX-INT MIN-INT > -> <TRUE> }T
+T{ MAX-INT 0 > -> <TRUE> }T
+
+T{ 0 1 U< -> <TRUE> }T
+T{ 1 2 U< -> <TRUE> }T
+T{ 0 MID-UINT U< -> <TRUE> }T
+T{ 0 MAX-UINT U< -> <TRUE> }T
+T{ MID-UINT MAX-UINT U< -> <TRUE> }T
+T{ 0 0 U< -> <FALSE> }T
+T{ 1 1 U< -> <FALSE> }T
+T{ 1 0 U< -> <FALSE> }T
+T{ 2 1 U< -> <FALSE> }T
+T{ MID-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT MID-UINT U< -> <FALSE> }T
+
+T{ 0 1 MIN -> 0 }T
+T{ 1 2 MIN -> 1 }T
+T{ -1 0 MIN -> -1 }T
+T{ -1 1 MIN -> -1 }T
+T{ MIN-INT 0 MIN -> MIN-INT }T
+T{ MIN-INT MAX-INT MIN -> MIN-INT }T
+T{ 0 MAX-INT MIN -> 0 }T
+T{ 0 0 MIN -> 0 }T
+T{ 1 1 MIN -> 1 }T
+T{ 1 0 MIN -> 0 }T
+T{ 2 1 MIN -> 1 }T
+T{ 0 -1 MIN -> -1 }T
+T{ 1 -1 MIN -> -1 }T
+T{ 0 MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT 0 MIN -> 0 }T
+
+T{ 0 1 MAX -> 1 }T
+T{ 1 2 MAX -> 2 }T
+T{ -1 0 MAX -> 0 }T
+T{ -1 1 MAX -> 1 }T
+T{ MIN-INT 0 MAX -> 0 }T
+T{ MIN-INT MAX-INT MAX -> MAX-INT }T
+T{ 0 MAX-INT MAX -> MAX-INT }T
+T{ 0 0 MAX -> 0 }T
+T{ 1 1 MAX -> 1 }T
+T{ 1 0 MAX -> 1 }T
+T{ 2 1 MAX -> 2 }T
+T{ 0 -1 MAX -> 0 }T
+T{ 1 -1 MAX -> 1 }T
+T{ 0 MIN-INT MAX -> 0 }T
+T{ MAX-INT MIN-INT MAX -> MAX-INT }T
+T{ MAX-INT 0 MAX -> MAX-INT }T
+
+\ ------------------------------------------------------------------------
+TESTING STACK OPS: 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP
+
+T{ 1 2 2DROP -> }T
+T{ 1 2 2DUP -> 1 2 1 2 }T
+T{ 1 2 3 4 2OVER -> 1 2 3 4 1 2 }T
+T{ 1 2 3 4 2SWAP -> 3 4 1 2 }T
+T{ 0 ?DUP -> 0 }T
+T{ 1 ?DUP -> 1 1 }T
+T{ -1 ?DUP -> -1 -1 }T
+T{ DEPTH -> 0 }T
+T{ 0 DEPTH -> 0 1 }T
+T{ 0 1 DEPTH -> 0 1 2 }T
+T{ 0 DROP -> }T
+T{ 1 2 DROP -> 1 }T
+T{ 1 DUP -> 1 1 }T
+T{ 1 2 OVER -> 1 2 1 }T
+T{ 1 2 3 ROT -> 2 3 1 }T
+T{ 1 2 SWAP -> 2 1 }T
+
+\ ------------------------------------------------------------------------
+TESTING >R R> R@
+
+T{ : GR1 >R R> ; -> }T
+T{ : GR2 >R R@ R> DROP ; -> }T
+T{ 123 GR1 -> 123 }T
+T{ 123 GR2 -> 123 }T
+T{ 1S GR1 -> 1S }T ( RETURN STACK HOLDS CELLS )
+
+\ ------------------------------------------------------------------------
+TESTING ADD/SUBTRACT: + - 1+ 1- ABS NEGATE
+
+T{ 0 5 + -> 5 }T
+T{ 5 0 + -> 5 }T
+T{ 0 -5 + -> -5 }T
+T{ -5 0 + -> -5 }T
+T{ 1 2 + -> 3 }T
+T{ 1 -2 + -> -1 }T
+T{ -1 2 + -> 1 }T
+T{ -1 -2 + -> -3 }T
+T{ -1 1 + -> 0 }T
+T{ MID-UINT 1 + -> MID-UINT+1 }T
+
+T{ 0 5 - -> -5 }T
+T{ 5 0 - -> 5 }T
+T{ 0 -5 - -> 5 }T
+T{ -5 0 - -> -5 }T
+T{ 1 2 - -> -1 }T
+T{ 1 -2 - -> 3 }T
+T{ -1 2 - -> -3 }T
+T{ -1 -2 - -> 1 }T
+T{ 0 1 - -> -1 }T
+T{ MID-UINT+1 1 - -> MID-UINT }T
+
+T{ 0 1+ -> 1 }T
+T{ -1 1+ -> 0 }T
+T{ 1 1+ -> 2 }T
+T{ MID-UINT 1+ -> MID-UINT+1 }T
+
+T{ 2 1- -> 1 }T
+T{ 1 1- -> 0 }T
+T{ 0 1- -> -1 }T
+T{ MID-UINT+1 1- -> MID-UINT }T
+
+T{ 0 NEGATE -> 0 }T
+T{ 1 NEGATE -> -1 }T
+T{ -1 NEGATE -> 1 }T
+T{ 2 NEGATE -> -2 }T
+T{ -2 NEGATE -> 2 }T
+
+T{ 0 ABS -> 0 }T
+T{ 1 ABS -> 1 }T
+T{ -1 ABS -> 1 }T
+T{ MIN-INT ABS -> MID-UINT+1 }T
+
+\ ------------------------------------------------------------------------
+TESTING MULTIPLY: S>D * M* UM*
+
+T{ 0 S>D -> 0 0 }T
+T{ 1 S>D -> 1 0 }T
+T{ 2 S>D -> 2 0 }T
+T{ -1 S>D -> -1 -1 }T
+T{ -2 S>D -> -2 -1 }T
+T{ MIN-INT S>D -> MIN-INT -1 }T
+T{ MAX-INT S>D -> MAX-INT 0 }T
+
+T{ 0 0 M* -> 0 S>D }T
+T{ 0 1 M* -> 0 S>D }T
+T{ 1 0 M* -> 0 S>D }T
+T{ 1 2 M* -> 2 S>D }T
+T{ 2 1 M* -> 2 S>D }T
+T{ 3 3 M* -> 9 S>D }T
+T{ -3 3 M* -> -9 S>D }T
+T{ 3 -3 M* -> -9 S>D }T
+T{ -3 -3 M* -> 9 S>D }T
+T{ 0 MIN-INT M* -> 0 S>D }T
+T{ 1 MIN-INT M* -> MIN-INT S>D }T
+T{ 2 MIN-INT M* -> 0 1S }T
+T{ 0 MAX-INT M* -> 0 S>D }T
+T{ 1 MAX-INT M* -> MAX-INT S>D }T
+T{ 2 MAX-INT M* -> MAX-INT 1 LSHIFT 0 }T
+T{ MIN-INT MIN-INT M* -> 0 MSB 1 RSHIFT }T
+T{ MAX-INT MIN-INT M* -> MSB MSB 2/ }T
+T{ MAX-INT MAX-INT M* -> 1 MSB 2/ INVERT }T
+
+T{ 0 0 * -> 0 }T \ TEST IDENTITIES
+T{ 0 1 * -> 0 }T
+T{ 1 0 * -> 0 }T
+T{ 1 2 * -> 2 }T
+T{ 2 1 * -> 2 }T
+T{ 3 3 * -> 9 }T
+T{ -3 3 * -> -9 }T
+T{ 3 -3 * -> -9 }T
+T{ -3 -3 * -> 9 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 * -> MID-UINT+1 }T
+T{ MID-UINT+1 2 RSHIFT 4 * -> MID-UINT+1 }T
+T{ MID-UINT+1 1 RSHIFT MID-UINT+1 OR 2 * -> MID-UINT+1 }T
+
+T{ 0 0 UM* -> 0 0 }T
+T{ 0 1 UM* -> 0 0 }T
+T{ 1 0 UM* -> 0 0 }T
+T{ 1 2 UM* -> 2 0 }T
+T{ 2 1 UM* -> 2 0 }T
+T{ 3 3 UM* -> 9 0 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 UM* -> MID-UINT+1 0 }T
+T{ MID-UINT+1 2 UM* -> 0 1 }T
+T{ MID-UINT+1 4 UM* -> 0 2 }T
+T{ 1S 2 UM* -> 1S 1 LSHIFT 1 }T
+T{ MAX-UINT MAX-UINT UM* -> 1 1 INVERT }T
+
+\ ------------------------------------------------------------------------
+TESTING DIVIDE: FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD
+
+T{ 0 S>D 1 FM/MOD -> 0 0 }T
+T{ 1 S>D 1 FM/MOD -> 0 1 }T
+T{ 2 S>D 1 FM/MOD -> 0 2 }T
+T{ -1 S>D 1 FM/MOD -> 0 -1 }T
+T{ -2 S>D 1 FM/MOD -> 0 -2 }T
+T{ 0 S>D -1 FM/MOD -> 0 0 }T
+T{ 1 S>D -1 FM/MOD -> 0 -1 }T
+T{ 2 S>D -1 FM/MOD -> 0 -2 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -1 FM/MOD -> 0 2 }T
+T{ 2 S>D 2 FM/MOD -> 0 1 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -2 FM/MOD -> 0 1 }T
+T{ 7 S>D 3 FM/MOD -> 1 2 }T
+T{ 7 S>D -3 FM/MOD -> -2 -3 }T
+T{ -7 S>D 3 FM/MOD -> 2 -3 }T
+T{ -7 S>D -3 FM/MOD -> -1 2 }T
+T{ MAX-INT S>D 1 FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT FM/MOD -> 0 1 }T
+T{ MIN-INT S>D MIN-INT FM/MOD -> 0 1 }T
+T{ 1S 1 4 FM/MOD -> 3 MAX-INT }T
+T{ 1 MIN-INT M* 1 FM/MOD -> 0 MIN-INT }T
+T{ 1 MIN-INT M* MIN-INT FM/MOD -> 0 1 }T
+T{ 2 MIN-INT M* 2 FM/MOD -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT FM/MOD -> 0 2 }T
+T{ 1 MAX-INT M* 1 FM/MOD -> 0 MAX-INT }T
+T{ 1 MAX-INT M* MAX-INT FM/MOD -> 0 1 }T
+T{ 2 MAX-INT M* 2 FM/MOD -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT FM/MOD -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT FM/MOD -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT FM/MOD -> 0 MAX-INT }T
+
+T{ 0 S>D 1 SM/REM -> 0 0 }T
+T{ 1 S>D 1 SM/REM -> 0 1 }T
+T{ 2 S>D 1 SM/REM -> 0 2 }T
+T{ -1 S>D 1 SM/REM -> 0 -1 }T
+T{ -2 S>D 1 SM/REM -> 0 -2 }T
+T{ 0 S>D -1 SM/REM -> 0 0 }T
+T{ 1 S>D -1 SM/REM -> 0 -1 }T
+T{ 2 S>D -1 SM/REM -> 0 -2 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -1 SM/REM -> 0 2 }T
+T{ 2 S>D 2 SM/REM -> 0 1 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -2 SM/REM -> 0 1 }T
+T{ 7 S>D 3 SM/REM -> 1 2 }T
+T{ 7 S>D -3 SM/REM -> 1 -2 }T
+T{ -7 S>D 3 SM/REM -> -1 -2 }T
+T{ -7 S>D -3 SM/REM -> -1 2 }T
+T{ MAX-INT S>D 1 SM/REM -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 SM/REM -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT SM/REM -> 0 1 }T
+T{ MIN-INT S>D MIN-INT SM/REM -> 0 1 }T
+T{ 1S 1 4 SM/REM -> 3 MAX-INT }T
+T{ 2 MIN-INT M* 2 SM/REM -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT SM/REM -> 0 2 }T
+T{ 2 MAX-INT M* 2 SM/REM -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT SM/REM -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT SM/REM -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT SM/REM -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT SM/REM -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT SM/REM -> 0 MAX-INT }T
+
+T{ 0 0 1 UM/MOD -> 0 0 }T
+T{ 1 0 1 UM/MOD -> 0 1 }T
+T{ 1 0 2 UM/MOD -> 1 0 }T
+T{ 3 0 2 UM/MOD -> 1 1 }T
+T{ MAX-UINT 2 UM* 2 UM/MOD -> 0 MAX-UINT }T
+T{ MAX-UINT 2 UM* MAX-UINT UM/MOD -> 0 2 }T
+T{ MAX-UINT MAX-UINT UM* MAX-UINT UM/MOD -> 0 MAX-UINT }T
+
+: IFFLOORED
+ [ -3 2 / -2 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+: IFSYM
+ [ -3 2 / -1 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+\ THE SYSTEM MIGHT DO EITHER FLOORED OR SYMMETRIC DIVISION.
+\ SINCE WE HAVE ALREADY TESTED M*, FM/MOD, AND SM/REM WE CAN USE THEM IN TEST.
+
+IFFLOORED : T/MOD >R S>D R> FM/MOD ;
+IFFLOORED : T/ T/MOD SWAP DROP ;
+IFFLOORED : TMOD T/MOD DROP ;
+IFFLOORED : T*/MOD >R M* R> FM/MOD ;
+IFFLOORED : T*/ T*/MOD SWAP DROP ;
+IFSYM : T/MOD >R S>D R> SM/REM ;
+IFSYM : T/ T/MOD SWAP DROP ;
+IFSYM : TMOD T/MOD DROP ;
+IFSYM : T*/MOD >R M* R> SM/REM ;
+IFSYM : T*/ T*/MOD SWAP DROP ;
+
+T{ 0 1 /MOD -> 0 1 T/MOD }T
+T{ 1 1 /MOD -> 1 1 T/MOD }T
+T{ 2 1 /MOD -> 2 1 T/MOD }T
+T{ -1 1 /MOD -> -1 1 T/MOD }T
+T{ -2 1 /MOD -> -2 1 T/MOD }T
+T{ 0 -1 /MOD -> 0 -1 T/MOD }T
+T{ 1 -1 /MOD -> 1 -1 T/MOD }T
+T{ 2 -1 /MOD -> 2 -1 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -1 /MOD -> -2 -1 T/MOD }T
+T{ 2 2 /MOD -> 2 2 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -2 /MOD -> -2 -2 T/MOD }T
+T{ 7 3 /MOD -> 7 3 T/MOD }T
+T{ 7 -3 /MOD -> 7 -3 T/MOD }T
+T{ -7 3 /MOD -> -7 3 T/MOD }T
+T{ -7 -3 /MOD -> -7 -3 T/MOD }T
+T{ MAX-INT 1 /MOD -> MAX-INT 1 T/MOD }T
+T{ MIN-INT 1 /MOD -> MIN-INT 1 T/MOD }T
+T{ MAX-INT MAX-INT /MOD -> MAX-INT MAX-INT T/MOD }T
+T{ MIN-INT MIN-INT /MOD -> MIN-INT MIN-INT T/MOD }T
+
+T{ 0 1 / -> 0 1 T/ }T
+T{ 1 1 / -> 1 1 T/ }T
+T{ 2 1 / -> 2 1 T/ }T
+T{ -1 1 / -> -1 1 T/ }T
+T{ -2 1 / -> -2 1 T/ }T
+T{ 0 -1 / -> 0 -1 T/ }T
+T{ 1 -1 / -> 1 -1 T/ }T
+T{ 2 -1 / -> 2 -1 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -1 / -> -2 -1 T/ }T
+T{ 2 2 / -> 2 2 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -2 / -> -2 -2 T/ }T
+T{ 7 3 / -> 7 3 T/ }T
+T{ 7 -3 / -> 7 -3 T/ }T
+T{ -7 3 / -> -7 3 T/ }T
+T{ -7 -3 / -> -7 -3 T/ }T
+T{ MAX-INT 1 / -> MAX-INT 1 T/ }T
+T{ MIN-INT 1 / -> MIN-INT 1 T/ }T
+T{ MAX-INT MAX-INT / -> MAX-INT MAX-INT T/ }T
+T{ MIN-INT MIN-INT / -> MIN-INT MIN-INT T/ }T
+
+T{ 0 1 MOD -> 0 1 TMOD }T
+T{ 1 1 MOD -> 1 1 TMOD }T
+T{ 2 1 MOD -> 2 1 TMOD }T
+T{ -1 1 MOD -> -1 1 TMOD }T
+T{ -2 1 MOD -> -2 1 TMOD }T
+T{ 0 -1 MOD -> 0 -1 TMOD }T
+T{ 1 -1 MOD -> 1 -1 TMOD }T
+T{ 2 -1 MOD -> 2 -1 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -1 MOD -> -2 -1 TMOD }T
+T{ 2 2 MOD -> 2 2 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -2 MOD -> -2 -2 TMOD }T
+T{ 7 3 MOD -> 7 3 TMOD }T
+T{ 7 -3 MOD -> 7 -3 TMOD }T
+T{ -7 3 MOD -> -7 3 TMOD }T
+T{ -7 -3 MOD -> -7 -3 TMOD }T
+T{ MAX-INT 1 MOD -> MAX-INT 1 TMOD }T
+T{ MIN-INT 1 MOD -> MIN-INT 1 TMOD }T
+T{ MAX-INT MAX-INT MOD -> MAX-INT MAX-INT TMOD }T
+T{ MIN-INT MIN-INT MOD -> MIN-INT MIN-INT TMOD }T
+
+T{ 0 2 1 */ -> 0 2 1 T*/ }T
+T{ 1 2 1 */ -> 1 2 1 T*/ }T
+T{ 2 2 1 */ -> 2 2 1 T*/ }T
+T{ -1 2 1 */ -> -1 2 1 T*/ }T
+T{ -2 2 1 */ -> -2 2 1 T*/ }T
+T{ 0 2 -1 */ -> 0 2 -1 T*/ }T
+T{ 1 2 -1 */ -> 1 2 -1 T*/ }T
+T{ 2 2 -1 */ -> 2 2 -1 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -1 */ -> -2 2 -1 T*/ }T
+T{ 2 2 2 */ -> 2 2 2 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -2 */ -> -2 2 -2 T*/ }T
+T{ 7 2 3 */ -> 7 2 3 T*/ }T
+T{ 7 2 -3 */ -> 7 2 -3 T*/ }T
+T{ -7 2 3 */ -> -7 2 3 T*/ }T
+T{ -7 2 -3 */ -> -7 2 -3 T*/ }T
+T{ MAX-INT 2 MAX-INT */ -> MAX-INT 2 MAX-INT T*/ }T
+T{ MIN-INT 2 MIN-INT */ -> MIN-INT 2 MIN-INT T*/ }T
+
+T{ 0 2 1 */MOD -> 0 2 1 T*/MOD }T
+T{ 1 2 1 */MOD -> 1 2 1 T*/MOD }T
+T{ 2 2 1 */MOD -> 2 2 1 T*/MOD }T
+T{ -1 2 1 */MOD -> -1 2 1 T*/MOD }T
+T{ -2 2 1 */MOD -> -2 2 1 T*/MOD }T
+T{ 0 2 -1 */MOD -> 0 2 -1 T*/MOD }T
+T{ 1 2 -1 */MOD -> 1 2 -1 T*/MOD }T
+T{ 2 2 -1 */MOD -> 2 2 -1 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -1 */MOD -> -2 2 -1 T*/MOD }T
+T{ 2 2 2 */MOD -> 2 2 2 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -2 */MOD -> -2 2 -2 T*/MOD }T
+T{ 7 2 3 */MOD -> 7 2 3 T*/MOD }T
+T{ 7 2 -3 */MOD -> 7 2 -3 T*/MOD }T
+T{ -7 2 3 */MOD -> -7 2 3 T*/MOD }T
+T{ -7 2 -3 */MOD -> -7 2 -3 T*/MOD }T
+T{ MAX-INT 2 MAX-INT */MOD -> MAX-INT 2 MAX-INT T*/MOD }T
+T{ MIN-INT 2 MIN-INT */MOD -> MIN-INT 2 MIN-INT T*/MOD }T
+
+\ ------------------------------------------------------------------------
+TESTING HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2! ALIGN ALIGNED +! ALLOT
+
+HERE 1 ALLOT
+HERE
+CONSTANT 2NDA
+CONSTANT 1STA
+T{ 1STA 2NDA U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STA 1+ -> 2NDA }T \ ... BY ONE ADDRESS UNIT
+( MISSING TEST: NEGATIVE ALLOT )
+
+HERE 1 ,
+HERE 2 ,
+CONSTANT 2ND
+CONSTANT 1ST
+T{ 1ST 2ND U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1ST CELL+ -> 2ND }T \ ... BY ONE CELL
+T{ 1ST 1 CELLS + -> 2ND }T
+T{ 1ST @ 2ND @ -> 1 2 }T
+T{ 5 1ST ! -> }T
+T{ 1ST @ 2ND @ -> 5 2 }T
+T{ 6 2ND ! -> }T
+T{ 1ST @ 2ND @ -> 5 6 }T
+T{ 1ST 2@ -> 6 5 }T
+T{ 2 1 1ST 2! -> }T
+T{ 1ST 2@ -> 2 1 }T
+T{ 1S 1ST ! 1ST @ -> 1S }T \ CAN STORE CELL-WIDE VALUE
+
+HERE 1 C,
+HERE 2 C,
+CONSTANT 2NDC
+CONSTANT 1STC
+T{ 1STC 2NDC U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STC CHAR+ -> 2NDC }T \ ... BY ONE CHAR
+T{ 1STC 1 CHARS + -> 2NDC }T
+T{ 1STC C@ 2NDC C@ -> 1 2 }T
+T{ 3 1STC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 2 }T
+T{ 4 2NDC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 4 }T
+
+ALIGN 1 ALLOT HERE ALIGN HERE 3 CELLS ALLOT
+CONSTANT A-ADDR CONSTANT UA-ADDR
+T{ UA-ADDR ALIGNED -> A-ADDR }T
+T{ 1 A-ADDR C! A-ADDR C@ -> 1 }T
+T{ 1234 A-ADDR ! A-ADDR @ -> 1234 }T
+T{ 123 456 A-ADDR 2! A-ADDR 2@ -> 123 456 }T
+T{ 2 A-ADDR CHAR+ C! A-ADDR CHAR+ C@ -> 2 }T
+T{ 3 A-ADDR CELL+ C! A-ADDR CELL+ C@ -> 3 }T
+T{ 1234 A-ADDR CELL+ ! A-ADDR CELL+ @ -> 1234 }T
+T{ 123 456 A-ADDR CELL+ 2! A-ADDR CELL+ 2@ -> 123 456 }T
+
+: BITS ( X -- U )
+ 0 SWAP BEGIN DUP WHILE DUP MSB AND IF >R 1+ R> THEN 2* REPEAT DROP ;
+( CHARACTERS >= 1 AU, <= SIZE OF CELL, >= 8 BITS )
+T{ 1 CHARS 1 < -> <FALSE> }T
+T{ 1 CHARS 1 CELLS > -> <FALSE> }T
+( TBD: HOW TO FIND NUMBER OF BITS? )
+
+( CELLS >= 1 AU, INTEGRAL MULTIPLE OF CHAR SIZE, >= 16 BITS )
+T{ 1 CELLS 1 < -> <FALSE> }T
+T{ 1 CELLS 1 CHARS MOD -> 0 }T
+T{ 1S BITS 10 < -> <FALSE> }T
+
+T{ 0 1ST ! -> }T
+T{ 1 1ST +! -> }T
+T{ 1ST @ -> 1 }T
+T{ -1 1ST +! 1ST @ -> 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING CHAR [CHAR] [ ] BL S"
+
+T{ BL -> 20 }T
+T{ CHAR X -> 58 }T
+T{ CHAR HELLO -> 48 }T
+T{ : GC1 [CHAR] X ; -> }T
+T{ : GC2 [CHAR] HELLO ; -> }T
+T{ GC1 -> 58 }T
+T{ GC2 -> 48 }T
+T{ : GC3 [ GC1 ] LITERAL ; -> }T
+T{ GC3 -> 58 }T
+T{ : GC4 S" XY" ; -> }T
+T{ GC4 SWAP DROP -> 2 }T
+T{ GC4 DROP DUP C@ SWAP CHAR+ C@ -> 58 59 }T
+
+\ ------------------------------------------------------------------------
+TESTING ' ['] FIND EXECUTE IMMEDIATE COUNT LITERAL POSTPONE STATE
+
+T{ : GT1 123 ; -> }T
+T{ ' GT1 EXECUTE -> 123 }T
+T{ : GT2 ['] GT1 ; IMMEDIATE -> }T
+T{ GT2 EXECUTE -> 123 }T
+HERE 3 C, CHAR G C, CHAR T C, CHAR 1 C, CONSTANT GT1STRING
+HERE 3 C, CHAR G C, CHAR T C, CHAR 2 C, CONSTANT GT2STRING
+T{ GT1STRING FIND -> ' GT1 -1 }T
+T{ GT2STRING FIND -> ' GT2 1 }T
+( HOW TO SEARCH FOR NON-EXISTENT WORD? )
+T{ : GT3 GT2 LITERAL ; -> }T
+T{ GT3 -> ' GT1 }T
+T{ GT1STRING COUNT -> GT1STRING CHAR+ 3 }T
+
+T{ : GT4 POSTPONE GT1 ; IMMEDIATE -> }T
+T{ : GT5 GT4 ; -> }T
+T{ GT5 -> 123 }T
+T{ : GT6 345 ; IMMEDIATE -> }T
+T{ : GT7 POSTPONE GT6 ; -> }T
+T{ GT7 -> 345 }T
+
+T{ : GT8 STATE @ ; IMMEDIATE -> }T
+T{ GT8 -> 0 }T
+T{ : GT9 GT8 LITERAL ; -> }T
+T{ GT9 0= -> <FALSE> }T
+
+\ ------------------------------------------------------------------------
+TESTING IF ELSE THEN BEGIN WHILE REPEAT UNTIL RECURSE
+
+T{ : GI1 IF 123 THEN ; -> }T
+T{ : GI2 IF 123 ELSE 234 THEN ; -> }T
+T{ 0 GI1 -> }T
+T{ 1 GI1 -> 123 }T
+T{ -1 GI1 -> 123 }T
+T{ 0 GI2 -> 234 }T
+T{ 1 GI2 -> 123 }T
+T{ -1 GI1 -> 123 }T
+
+T{ : GI3 BEGIN DUP 5 < WHILE DUP 1+ REPEAT ; -> }T
+T{ 0 GI3 -> 0 1 2 3 4 5 }T
+T{ 4 GI3 -> 4 5 }T
+T{ 5 GI3 -> 5 }T
+T{ 6 GI3 -> 6 }T
+
+T{ : GI4 BEGIN DUP 1+ DUP 5 > UNTIL ; -> }T
+T{ 3 GI4 -> 3 4 5 6 }T
+T{ 5 GI4 -> 5 6 }T
+T{ 6 GI4 -> 6 7 }T
+
+T{ : GI5 BEGIN DUP 2 > WHILE DUP 5 < WHILE DUP 1+ REPEAT 123 ELSE 345 THEN ; -> }T
+T{ 1 GI5 -> 1 345 }T
+T{ 2 GI5 -> 2 345 }T
+T{ 3 GI5 -> 3 4 5 123 }T
+T{ 4 GI5 -> 4 5 123 }T
+T{ 5 GI5 -> 5 123 }T
+
+T{ : GI6 ( N -- 0,1,..N ) DUP IF DUP >R 1- RECURSE R> THEN ; -> }T
+T{ 0 GI6 -> 0 }T
+T{ 1 GI6 -> 0 1 }T
+T{ 2 GI6 -> 0 1 2 }T
+T{ 3 GI6 -> 0 1 2 3 }T
+T{ 4 GI6 -> 0 1 2 3 4 }T
+
+\ ------------------------------------------------------------------------
+TESTING DO LOOP +LOOP I J UNLOOP LEAVE EXIT
+
+T{ : GD1 DO I LOOP ; -> }T
+T{ 4 1 GD1 -> 1 2 3 }T
+T{ 2 -1 GD1 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD1 -> MID-UINT }T
+
+T{ : GD2 DO I -1 +LOOP ; -> }T
+T{ 1 4 GD2 -> 4 3 2 1 }T
+T{ -1 2 GD2 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD2 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD3 DO 1 0 DO J LOOP LOOP ; -> }T
+T{ 4 1 GD3 -> 1 2 3 }T
+T{ 2 -1 GD3 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD3 -> MID-UINT }T
+
+T{ : GD4 DO 1 0 DO J LOOP -1 +LOOP ; -> }T
+T{ 1 4 GD4 -> 4 3 2 1 }T
+T{ -1 2 GD4 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD4 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD5 123 SWAP 0 DO I 4 > IF DROP 234 LEAVE THEN LOOP ; -> }T
+T{ 1 GD5 -> 123 }T
+T{ 5 GD5 -> 123 }T
+T{ 6 GD5 -> 234 }T
+
+T{ : GD6 ( PAT: T{0 0}T,T{0 0}TT{1 0}TT{1 1}T,T{0 0}TT{1 0}TT{1 1}TT{2 0}TT{2 1}TT{2 2}T )
+ 0 SWAP 0 DO
+ I 1+ 0 DO I J + 3 = IF I UNLOOP I UNLOOP EXIT THEN 1+ LOOP
+ LOOP ; -> }T
+T{ 1 GD6 -> 1 }T
+T{ 2 GD6 -> 3 }T
+T{ 3 GD6 -> 4 1 2 }T
+
+\ ------------------------------------------------------------------------
+TESTING DEFINING WORDS: : ; CONSTANT VARIABLE CREATE DOES> >BODY
+
+T{ 123 CONSTANT X123 -> }T
+T{ X123 -> 123 }T
+T{ : EQU CONSTANT ; -> }T
+T{ X123 EQU Y123 -> }T
+T{ Y123 -> 123 }T
+
+T{ VARIABLE V1 -> }T
+T{ 123 V1 ! -> }T
+T{ V1 @ -> 123 }T
+
+T{ : NOP : POSTPONE ; ; -> }T
+T{ NOP NOP1 NOP NOP2 -> }T
+T{ NOP1 -> }T
+T{ NOP2 -> }T
+
+T{ : DOES1 DOES> @ 1 + ; -> }T
+T{ : DOES2 DOES> @ 2 + ; -> }T
+T{ CREATE CR1 -> }T
+T{ CR1 -> HERE }T
+T{ ' CR1 >BODY -> HERE }T
+T{ 1 , -> }T
+T{ CR1 @ -> 1 }T
+T{ DOES1 -> }T
+T{ CR1 -> 2 }T
+T{ DOES2 -> }T
+T{ CR1 -> 3 }T
+
+T{ : WEIRD: CREATE DOES> 1 + DOES> 2 + ; -> }T
+T{ WEIRD: W1 -> }T
+T{ ' W1 >BODY -> HERE }T
+T{ W1 -> HERE 1 + }T
+T{ W1 -> HERE 2 + }T
+
+\ ------------------------------------------------------------------------
+TESTING EVALUATE
+
+: GE1 S" 123" ; IMMEDIATE
+: GE2 S" 123 1+" ; IMMEDIATE
+: GE3 S" : GE4 345 ;" ;
+: GE5 EVALUATE ; IMMEDIATE
+
+T{ GE1 EVALUATE -> 123 }T ( TEST EVALUATE IN INTERP. STATE )
+T{ GE2 EVALUATE -> 124 }T
+T{ GE3 EVALUATE -> }T
+T{ GE4 -> 345 }T
+
+T{ : GE6 GE1 GE5 ; -> }T ( TEST EVALUATE IN COMPILE STATE )
+T{ GE6 -> 123 }T
+T{ : GE7 GE2 GE5 ; -> }T
+T{ GE7 -> 124 }T
+
+\ ------------------------------------------------------------------------
+TESTING SOURCE >IN WORD
+
+: GS1 S" SOURCE" 2DUP EVALUATE
+ >R SWAP >R = R> R> = ;
+T{ GS1 -> <TRUE> <TRUE> }T
+
+VARIABLE SCANS
+: RESCAN? -1 SCANS +! SCANS @ IF 0 >IN ! THEN ;
+
+T{ 2 SCANS !
+345 RESCAN?
+-> 345 345 }T
+
+: GS2 5 SCANS ! S" 123 RESCAN?" EVALUATE ;
+T{ GS2 -> 123 123 123 123 123 }T
+
+: GS3 WORD COUNT SWAP C@ ;
+T{ BL GS3 HELLO -> 5 CHAR H }T
+T{ CHAR " GS3 GOODBYE" -> 7 CHAR G }T
+T{ BL GS3
+DROP -> 0 }T \ BLANK LINE RETURN ZERO-LENGTH STRING
+
+: GS4 SOURCE >IN ! DROP ;
+T{ GS4 123 456
+-> }T
+
+\ ------------------------------------------------------------------------
+TESTING <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL
+
+: S= \ ( ADDR1 C1 ADDR2 C2 -- T/F ) COMPARE TWO STRINGS.
+ >R SWAP R@ = IF \ MAKE SURE STRINGS HAVE SAME LENGTH
+ R> ?DUP IF \ IF NON-EMPTY STRINGS
+ 0 DO
+ OVER C@ OVER C@ - IF
+ 2DROP <FALSE> UNLOOP EXIT THEN
+ SWAP CHAR+ SWAP CHAR+
+ LOOP
+ THEN
+ 2DROP <TRUE> \ IF WE GET HERE, STRINGS MATCH
+ ELSE
+ R> DROP 2DROP <FALSE> \ LENGTHS MISMATCH
+ THEN ;
+
+: GP1 <# 41 HOLD 42 HOLD 0 0 #> S" BA" S= ;
+T{ GP1 -> <TRUE> }T
+
+: GP2 <# -1 SIGN 0 SIGN -1 SIGN 0 0 #> S" --" S= ;
+T{ GP2 -> <TRUE> }T
+
+: GP3 <# 1 0 # # #> S" 01" S= ;
+T{ GP3 -> <TRUE> }T
+
+: GP4 <# 1 0 #S #> S" 1" S= ;
+T{ GP4 -> <TRUE> }T
+
+24 CONSTANT MAX-BASE \ BASE 2 .. 36
+: COUNT-BITS
+ 0 0 INVERT BEGIN DUP WHILE >R 1+ R> 2* REPEAT DROP ;
+COUNT-BITS 2* CONSTANT #BITS-UD \ NUMBER OF BITS IN UD
+
+: GP5
+ BASE @ <TRUE>
+ MAX-BASE 1+ 2 DO \ FOR EACH POSSIBLE BASE
+ I BASE ! \ TBD: ASSUMES BASE WORKS
+ I 0 <# #S #> S" 10" S= AND
+ LOOP
+ SWAP BASE ! ;
+T{ GP5 -> <TRUE> }T
+
+: GP6
+ BASE @ >R 2 BASE !
+ MAX-UINT MAX-UINT <# #S #> \ MAXIMUM UD TO BINARY
+ R> BASE ! \ S: C-ADDR U
+ DUP #BITS-UD = SWAP
+ 0 DO \ S: C-ADDR FLAG
+ OVER C@ [CHAR] 1 = AND \ ALL ONES
+ >R CHAR+ R>
+ LOOP SWAP DROP ;
+T{ GP6 -> <TRUE> }T
+
+: GP7
+ BASE @ >R MAX-BASE BASE !
+ <TRUE>
+ A 0 DO
+ I 0 <# #S #>
+ 1 = SWAP C@ I 30 + = AND AND
+ LOOP
+ MAX-BASE A DO
+ I 0 <# #S #>
+ 1 = SWAP C@ 41 I A - + = AND AND
+ LOOP
+ R> BASE ! ;
+
+T{ GP7 -> <TRUE> }T
+
+\ >NUMBER TESTS
+CREATE GN-BUF 0 C,
+: GN-STRING GN-BUF 1 ;
+: GN-CONSUMED GN-BUF CHAR+ 0 ;
+: GN' [CHAR] ' WORD CHAR+ C@ GN-BUF C! GN-STRING ;
+
+T{ 0 0 GN' 0' >NUMBER -> 0 0 GN-CONSUMED }T
+T{ 0 0 GN' 1' >NUMBER -> 1 0 GN-CONSUMED }T
+T{ 1 0 GN' 1' >NUMBER -> BASE @ 1+ 0 GN-CONSUMED }T
+T{ 0 0 GN' -' >NUMBER -> 0 0 GN-STRING }T \ SHOULD FAIL TO CONVERT THESE
+T{ 0 0 GN' +' >NUMBER -> 0 0 GN-STRING }T
+T{ 0 0 GN' .' >NUMBER -> 0 0 GN-STRING }T
+
+: >NUMBER-BASED
+ BASE @ >R BASE ! >NUMBER R> BASE ! ;
+
+T{ 0 0 GN' 2' 10 >NUMBER-BASED -> 2 0 GN-CONSUMED }T
+T{ 0 0 GN' 2' 2 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' F' 10 >NUMBER-BASED -> F 0 GN-CONSUMED }T
+T{ 0 0 GN' G' 10 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' G' MAX-BASE >NUMBER-BASED -> 10 0 GN-CONSUMED }T
+T{ 0 0 GN' Z' MAX-BASE >NUMBER-BASED -> 23 0 GN-CONSUMED }T
+
+: GN1 \ ( UD BASE -- UD' LEN ) UD SHOULD EQUAL UD' AND LEN SHOULD BE ZERO.
+ BASE @ >R BASE !
+ <# #S #>
+ 0 0 2SWAP >NUMBER SWAP DROP \ RETURN LENGTH ONLY
+ R> BASE ! ;
+T{ 0 0 2 GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 2 GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP 2 GN1 -> MAX-UINT DUP 0 }T
+T{ 0 0 MAX-BASE GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 MAX-BASE GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP MAX-BASE GN1 -> MAX-UINT DUP 0 }T
+
+: GN2 \ ( -- 16 10 )
+ BASE @ >R HEX BASE @ DECIMAL BASE @ R> BASE ! ;
+T{ GN2 -> 10 A }T
+
+\ ------------------------------------------------------------------------
+TESTING FILL MOVE
+
+CREATE FBUF 00 C, 00 C, 00 C,
+CREATE SBUF 12 C, 34 C, 56 C,
+: SEEBUF FBUF C@ FBUF CHAR+ C@ FBUF CHAR+ CHAR+ C@ ;
+
+T{ FBUF 0 20 FILL -> }T
+T{ SEEBUF -> 00 00 00 }T
+
+T{ FBUF 1 20 FILL -> }T
+T{ SEEBUF -> 20 00 00 }T
+
+T{ FBUF 3 20 FILL -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ FBUF FBUF 3 CHARS MOVE -> }T \ BIZARRE SPECIAL CASE
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 0 CHARS MOVE -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 1 CHARS MOVE -> }T
+T{ SEEBUF -> 12 20 20 }T
+
+T{ SBUF FBUF 3 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 56 }T
+
+T{ FBUF FBUF CHAR+ 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 12 34 }T
+
+T{ FBUF CHAR+ FBUF 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 34 }T
+
+\ ------------------------------------------------------------------------
+TESTING OUTPUT: . ." CR EMIT SPACE SPACES TYPE U.
+
+: OUTPUT-TEST
+ ." YOU SHOULD SEE THE STANDARD GRAPHIC CHARACTERS:" CR
+ 41 BL DO I EMIT LOOP CR
+ 61 41 DO I EMIT LOOP CR
+ 7F 61 DO I EMIT LOOP CR
+ ." YOU SHOULD SEE 0-9 SEPARATED BY A SPACE:" CR
+ 9 1+ 0 DO I . LOOP CR
+ ." YOU SHOULD SEE 0-9 (WITH NO SPACES):" CR
+ [CHAR] 9 1+ [CHAR] 0 DO I 0 SPACES EMIT LOOP CR
+ ." YOU SHOULD SEE A-G SEPARATED BY A SPACE:" CR
+ [CHAR] G 1+ [CHAR] A DO I EMIT SPACE LOOP CR
+ ." YOU SHOULD SEE 0-5 SEPARATED BY TWO SPACES:" CR
+ 5 1+ 0 DO I [CHAR] 0 + EMIT 2 SPACES LOOP CR
+ ." YOU SHOULD SEE TWO SEPARATE LINES:" CR
+ S" LINE 1" TYPE CR S" LINE 2" TYPE CR
+ ." YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:" CR
+ ." SIGNED: " MIN-INT . MAX-INT . CR
+ ." UNSIGNED: " 0 U. MAX-UINT U. CR
+;
+
+T{ OUTPUT-TEST -> }T
+\ ------------------------------------------------------------------------
+TESTING INPUT: ACCEPT
+
+CREATE ABUF 80 CHARS ALLOT
+
+: ACCEPT-TEST
+ CR ." PLEASE TYPE UP TO 80 CHARACTERS:" CR
+\ ABUF 80 ACCEPT
+ ABUF 80 (ACCEPT) \ JMT: because ACCEPT is DEFERred to SD_ACCEPT
+ CR ." RECEIVED: " [CHAR] " EMIT
+ ABUF SWAP TYPE [CHAR] " EMIT CR
+;
+
+T{ ACCEPT-TEST -> }T
+\ ------------------------------------------------------------------------
+TESTING DICTIONARY SEARCH RULES
+
+T{ : GDX 123 ; : GDX GDX 234 ; -> }T
+
+T{ GDX -> 123 234 }T
+
+CR .( End of Core word set tests) CR
+
+
+$0A BASE !
+
+ ; happy end of core test
--- /dev/null
+; ----------------------------------------------------------------------------------
+; ANS complement for MSP430FR4xxx devices without hardware_MPY, to pass CORETEST.4th
+; ----------------------------------------------------------------------------------
+
+CODE INVERT
+ XOR #-1,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE LSHIFT
+ MOV @R15+,R10
+ AND #$1F,R14
+0<> IF
+ BEGIN ADD R10,R10
+ SUB #1,R14
+ 0= UNTIL
+THEN MOV R10,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE RSHIFT
+ MOV @R15+,R10
+ AND #$1F,R14
+0<> IF
+ BEGIN BIC #1,R2
+ RRC R10
+ SUB #1,R14
+ 0= UNTIL
+THEN MOV R10,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE 1+
+ ADD #1,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE 1-
+ SUB #1,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE MAX
+ CMP @R15,R14
+ S< ?GOTO FW1
+BW1 ADD #2,R15
+ MOV @R13+,R0
+ENDCODE
+
+CODE MIN
+ CMP @R15,R14
+ S< ?GOTO BW1
+FW1 MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE 2*
+ ADD R14,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE 2/
+ RRA R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE NIP
+ADD #2,R15
+MOV @R13+,R0
+ENDCODE
+
+: S>D
+ DUP 0<
+;
+
+CODE M*
+MOV R14,R12
+XOR @R15,R12
+CMP #0,0(R15)
+S< IF
+ XOR #-1,0(R15)
+ ADD #1,0(R15)
+THEN
+CMP #0,R14
+S< IF
+ XOR #-1,R14
+ ADD #1,R14
+THEN
+PUSHM R13,R12
+LO2HI
+UM*
+HI2LO
+POPM R12,R13
+CMP #0,R12
+S< IF
+ XOR #-1,0(R15)
+ XOR #-1,R14
+ ADD #1,0(R15)
+ ADDC #0,R14
+THEN
+MOV @R13+,R0
+ENDCODE
+
+CODE UM/MOD
+ MOV @R15+,R10
+ MOV @R15,R12
+ MOV #16,R9
+BW1 CMP R14,R10
+ U< ?GOTO FW1
+ SUB R14,R10
+FW1
+BW2 ADDC R8,R8
+ SUB #1,R9
+ 0< ?GOTO FW1
+ ADD R12,R12
+ ADDC R10,R10
+ U< ?GOTO BW1
+ SUB R14,R10
+ BIS #1,R2
+ GOTO BW2
+FW1 MOV R10,0(R15)
+ MOV R8,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE SM/REM
+MOV R14,R12
+MOV @R15,R11
+CMP #0,R14
+S< IF
+ XOR #-1,R14
+ ADD #1,R14
+THEN
+CMP #0,0(R15)
+S< IF
+ XOR #-1,2(R15)
+ XOR #-1,0(R15)
+ ADD #1,2(R15)
+ ADDC #0,0(R15)
+THEN
+PUSHM R13,R12
+LO2HI
+UM/MOD
+HI2LO
+POPM R12,R13
+CMP #0,R11
+S< IF
+ XOR #-1,0(R15)
+ ADD #1,0(R15)
+THEN
+XOR R12,R11
+CMP #0,R11
+S< IF
+ XOR #-1,R14
+ ADD #1,R14
+THEN
+MOV @R13+,R0
+ENDCODE
+
+: FM/MOD
+SM/REM
+HI2LO
+CMP #0,0(R15)
+0<> IF
+ CMP #1,R14
+ S< IF
+ ADD R12,0(R15)
+ SUB #1,R14
+ THEN
+THEN
+MOV @R1+,R13
+MOV @R13+,R0
+ENDCODE
+
+: *
+M* DROP
+;
+
+: /MOD
+>R DUP 0< R> FM/MOD
+;
+
+: /
+>R DUP 0< R> FM/MOD NIP
+;
+
+: MOD
+>R DUP 0< R> FM/MOD DROP
+;
+
+: */MOD
+>R M* R> FM/MOD
+;
+
+: */
+>R M* R> FM/MOD NIP
+;
+
+CODE 2@
+SUB #2, R15
+MOV 2(R14),0(R15)
+MOV @R14,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE 2!
+MOV @R15+,0(R14)
+MOV @R15+,2(R14)
+MOV @R15+,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE 2DUP
+SUB #4,R15
+MOV R14,2(R15)
+MOV 4(R15),0(R15)
+MOV @R13+,R0
+ENDCODE
+
+CODE 2DROP
+ADD #2,R15
+MOV @R15+,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE 2SWAP
+MOV @R15,R10
+MOV 4(R15),0(R15)
+MOV R10,4(R15)
+MOV R14,R10
+MOV 2(R15),R14
+MOV R10,2(R15)
+MOV @R13+,R0
+ENDCODE
+
+CODE 2OVER
+SUB #4,R15
+MOV R14,2(R15)
+MOV 8(R15),0(R15)
+MOV 6(R15),R14
+MOV @R13+,R0
+ENDCODE
+
+CODE ALIGNED
+BIT #1,R14
+ADDC #0,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE ALIGN
+BIT #1,&$21C4
+ADDC #0,&$21C4
+MOV @R13+,R0
+ENDCODE
+
+CODE CHARS
+MOV @R13+,R0
+ENDCODE
+
+CODE CHAR+
+ADD #1,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE CELLS
+ADD R14,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE CELL+
+ADD #2,R14
+MOV @R13+,R0
+ENDCODE
+
+: CHAR
+ BL WORD 1+ C@
+;
+
+: [CHAR]
+ CHAR lit lit , ,
+; IMMEDIATE
+
+CODE +!
+ADD @R15+,0(R14)
+MOV @R15+,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE FILL
+MOV @R15+,R9
+MOV @R15+,R10
+CMP #0,R9
+0<> IF
+ BEGIN
+ MOV.B R14,0(R10)
+ ADD #1,R10
+ SUB #1,R9
+ 0= UNTIL
+THEN
+MOV @R15+,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE HEX
+MOV #$10,&$21DA
+MOV @R13+,R0
+ENDCODE
+
+CODE DECIMAL
+MOV #$0A,&$21DA
+MOV @R13+,R0
+ENDCODE
+
+: (
+$29 WORD DROP
+; IMMEDIATE
+
+: .(
+$29 WORD
+COUNT TYPE
+; IMMEDIATE
+
+CODE SOURCE
+SUB #4,R15
+MOV R14,2(R15)
+MOV &$21BE,R14
+MOV &$21C0,0(R15)
+MOV @R13+,R0
+ENDCODE
+
+CODE >BODY
+ADD #4,R14
+MOV @R13+,R0
+ENDCODE
+
+
+ECHO
+
+; ===============================================================
+;
+; ##### ####### ###### ####### ####### ####### ##### #######
+; # # # # # # # # # # # #
+; # # # # # # # # # #
+; # # # ###### ##### # ##### ##### #
+; # # # # # # # # # #
+; # # # # # # # # # # # #
+; ##### ####### # # ####### # ####### ##### #
+;
+; ===============================================================
+
+
+\ From: John Hayes S1I
+\ Subject: tester.fr
+\ Date: Mon, 27 Nov 95 13:10:09 PST
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.1
+
+\ 22/1/09 The words { and } have been changed to T{ and }T respectively to
+\ agree with the Forth 200X file ttester.fs. This avoids clashes with
+\ locals using { ... } and the FSL use of }
+
+
+\ 13/05/14 jmt. added colorised error messages.
+
+
+
+ 0 CONSTANT FALSE
+-1 CONSTANT TRUE
+
+\ SET THE FOLLOWING FLAG TO TRUE FOR MORE VERBOSE OUTPUT; THIS MAY
+\ ALLOW YOU TO TELL WHICH TEST CAUSED YOUR SYSTEM TO HANG.
+VARIABLE VERBOSE
+ FALSE VERBOSE !
+\ TRUE VERBOSE !
+
+\ : EMPTY-STACK ( ... -- ) \ EMPTY STACK: HANDLES UNDERFLOWED STACK TOO.
+\ DEPTH ?DUP
+\ IF DUP 0< IF NEGATE 0
+\ DO 0 LOOP
+\ ELSE 0 DO DROP LOOP THEN
+\ THEN ;
+\
+\ : ERROR \ ( C-ADDR U -- ) DISPLAY AN ERROR MESSAGE FOLLOWED BY
+\ \ THE LINE THAT HAD THE ERROR.
+\ TYPE SOURCE TYPE CR \ DISPLAY LINE CORRESPONDING TO ERROR
+\ EMPTY-STACK \ THROW AWAY EVERY THING ELSE
+\ QUIT \ *** Uncomment this line to QUIT on an error
+\ ;
+
+VARIABLE ACTUAL-DEPTH \ STACK RECORD
+CREATE ACTUAL-RESULTS 20 CELLS ALLOT
+
+: T{ \ ( -- ) SYNTACTIC SUGAR.
+ ;
+
+: -> \ ( ... -- ) RECORD DEPTH AND CONTENT OF STACK.
+ DEPTH DUP ACTUAL-DEPTH ! \ RECORD DEPTH
+ ?DUP IF \ IF THERE IS SOMETHING ON STACK
+ 0 DO ACTUAL-RESULTS I CELLS + ! LOOP \ SAVE THEM
+ THEN ;
+
+: }T \ ( ... -- ) COMPARE STACK (EXPECTED) CONTENTS WITH SAVED
+ \ (ACTUAL) CONTENTS.
+ DEPTH ACTUAL-DEPTH @ = IF \ IF DEPTHS MATCH
+ DEPTH ?DUP IF \ IF THERE IS SOMETHING ON THE STACK
+ 0 DO \ FOR EACH STACK ITEM
+ ACTUAL-RESULTS I CELLS + @ \ COMPARE ACTUAL WITH EXPECTED
+\ = 0= IF S" INCORRECT RESULT: " ERROR LEAVE THEN \ jmt
+ = 0= IF ABORT" INCORRECT RESULT: " THEN \ jmt : colorised message
+ LOOP
+ THEN
+ ELSE \ DEPTH MISMATCH
+\ S" WRONG NUMBER OF RESULTS: " ERROR \ jmt
+ ABORT" WRONG NUMBER OF RESULTS: " \ jmt : colorised message
+ THEN ;
+
+: TESTING \ ( -- ) TALKING COMMENT.
+ SOURCE VERBOSE @
+ IF DUP >R TYPE CR R> >IN !
+ ELSE >IN ! DROP [CHAR] * EMIT
+ THEN ;
+
+\ From: John Hayes S1I
+\ Subject: core.fr
+\ Date: Mon, 27 Nov 95 13:10
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.2
+\ THIS PROGRAM TESTS THE CORE WORDS OF AN ANS FORTH SYSTEM.
+\ THE PROGRAM ASSUMES A TWO'S COMPLEMENT IMPLEMENTATION WHERE
+\ THE RANGE OF SIGNED NUMBERS IS -2^(N-1) ... 2^(N-1)-1 AND
+\ THE RANGE OF UNSIGNED NUMBERS IS 0 ... 2^(N)-1.
+\ I HAVEN'T FIGURED OUT HOW TO TEST KEY, QUIT, ABORT, OR ABORT"...
+\ I ALSO HAVEN'T THOUGHT OF A WAY TO TEST ENVIRONMENT?...
+
+CR
+TESTING CORE WORDS
+HEX
+
+\ ------------------------------------------------------------------------
+TESTING BASIC ASSUMPTIONS
+
+T{ -> }T \ START WITH CLEAN SLATE
+( TEST IF ANY BITS ARE SET; ANSWER IN BASE 1 )
+T{ : BITSSET? IF 0 0 ELSE 0 THEN ; -> }T
+T{ 0 BITSSET? -> 0 }T ( ZERO IS ALL BITS CLEAR )
+T{ 1 BITSSET? -> 0 0 }T ( OTHER NUMBER HAVE AT LEAST ONE BIT )
+T{ -1 BITSSET? -> 0 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING BOOLEANS: INVERT AND OR XOR
+
+T{ 0 0 AND -> 0 }T
+T{ 0 1 AND -> 0 }T
+T{ 1 0 AND -> 0 }T
+T{ 1 1 AND -> 1 }T
+
+T{ 0 INVERT 1 AND -> 1 }T
+T{ 1 INVERT 1 AND -> 0 }T
+
+0 CONSTANT 0S
+0 INVERT CONSTANT 1S
+
+T{ 0S INVERT -> 1S }T
+T{ 1S INVERT -> 0S }T
+
+T{ 0S 0S AND -> 0S }T
+T{ 0S 1S AND -> 0S }T
+T{ 1S 0S AND -> 0S }T
+T{ 1S 1S AND -> 1S }T
+
+T{ 0S 0S OR -> 0S }T
+T{ 0S 1S OR -> 1S }T
+T{ 1S 0S OR -> 1S }T
+T{ 1S 1S OR -> 1S }T
+
+T{ 0S 0S XOR -> 0S }T
+T{ 0S 1S XOR -> 1S }T
+T{ 1S 0S XOR -> 1S }T
+T{ 1S 1S XOR -> 0S }T
+
+\ ------------------------------------------------------------------------
+TESTING 2* 2/ LSHIFT RSHIFT
+
+( WE TRUST 1S, INVERT, AND BITSSET?; WE WILL CONFIRM RSHIFT LATER )
+1S 1 RSHIFT INVERT CONSTANT MSB
+T{ MSB BITSSET? -> 0 0 }T
+
+T{ 0S 2* -> 0S }T
+T{ 1 2* -> 2 }T
+T{ 4000 2* -> 8000 }T
+T{ 1S 2* 1 XOR -> 1S }T
+T{ MSB 2* -> 0S }T
+
+T{ 0S 2/ -> 0S }T
+T{ 1 2/ -> 0 }T
+T{ 4000 2/ -> 2000 }T
+T{ 1S 2/ -> 1S }T \ MSB PROPOGATED
+T{ 1S 1 XOR 2/ -> 1S }T
+T{ MSB 2/ MSB AND -> MSB }T
+
+T{ 1 0 LSHIFT -> 1 }T
+T{ 1 1 LSHIFT -> 2 }T
+T{ 1 2 LSHIFT -> 4 }T
+T{ 1 F LSHIFT -> 8000 }T \ BIGGEST GUARANTEED SHIFT
+T{ 1S 1 LSHIFT 1 XOR -> 1S }T
+T{ MSB 1 LSHIFT -> 0 }T
+
+T{ 1 0 RSHIFT -> 1 }T
+T{ 1 1 RSHIFT -> 0 }T
+T{ 2 1 RSHIFT -> 1 }T
+T{ 4 2 RSHIFT -> 1 }T
+T{ 8000 F RSHIFT -> 1 }T \ BIGGEST
+T{ MSB 1 RSHIFT MSB AND -> 0 }T \ RSHIFT ZERO FILLS MSBS
+T{ MSB 1 RSHIFT 2* -> MSB }T
+
+\ ------------------------------------------------------------------------
+TESTING COMPARISONS: 0= = 0< < > U< MIN MAX
+0 INVERT CONSTANT MAX-UINT
+0 INVERT 1 RSHIFT CONSTANT MAX-INT
+0 INVERT 1 RSHIFT INVERT CONSTANT MIN-INT
+0 INVERT 1 RSHIFT CONSTANT MID-UINT
+0 INVERT 1 RSHIFT INVERT CONSTANT MID-UINT+1
+
+0S CONSTANT <FALSE>
+1S CONSTANT <TRUE>
+
+T{ 0 0= -> <TRUE> }T
+T{ 1 0= -> <FALSE> }T
+T{ 2 0= -> <FALSE> }T
+T{ -1 0= -> <FALSE> }T
+T{ MAX-UINT 0= -> <FALSE> }T
+T{ MIN-INT 0= -> <FALSE> }T
+T{ MAX-INT 0= -> <FALSE> }T
+
+T{ 0 0 = -> <TRUE> }T
+T{ 1 1 = -> <TRUE> }T
+T{ -1 -1 = -> <TRUE> }T
+T{ 1 0 = -> <FALSE> }T
+T{ -1 0 = -> <FALSE> }T
+T{ 0 1 = -> <FALSE> }T
+T{ 0 -1 = -> <FALSE> }T
+
+T{ 0 0< -> <FALSE> }T
+T{ -1 0< -> <TRUE> }T
+T{ MIN-INT 0< -> <TRUE> }T
+T{ 1 0< -> <FALSE> }T
+T{ MAX-INT 0< -> <FALSE> }T
+
+T{ 0 1 < -> <TRUE> }T
+T{ 1 2 < -> <TRUE> }T
+T{ -1 0 < -> <TRUE> }T
+T{ -1 1 < -> <TRUE> }T
+T{ MIN-INT 0 < -> <TRUE> }T
+T{ MIN-INT MAX-INT < -> <TRUE> }T
+T{ 0 MAX-INT < -> <TRUE> }T
+T{ 0 0 < -> <FALSE> }T
+T{ 1 1 < -> <FALSE> }T
+T{ 1 0 < -> <FALSE> }T
+T{ 2 1 < -> <FALSE> }T
+T{ 0 -1 < -> <FALSE> }T
+T{ 1 -1 < -> <FALSE> }T
+T{ 0 MIN-INT < -> <FALSE> }T
+T{ MAX-INT MIN-INT < -> <FALSE> }T
+T{ MAX-INT 0 < -> <FALSE> }T
+
+T{ 0 1 > -> <FALSE> }T
+T{ 1 2 > -> <FALSE> }T
+T{ -1 0 > -> <FALSE> }T
+T{ -1 1 > -> <FALSE> }T
+T{ MIN-INT 0 > -> <FALSE> }T
+T{ MIN-INT MAX-INT > -> <FALSE> }T
+T{ 0 MAX-INT > -> <FALSE> }T
+T{ 0 0 > -> <FALSE> }T
+T{ 1 1 > -> <FALSE> }T
+T{ 1 0 > -> <TRUE> }T
+T{ 2 1 > -> <TRUE> }T
+T{ 0 -1 > -> <TRUE> }T
+T{ 1 -1 > -> <TRUE> }T
+T{ 0 MIN-INT > -> <TRUE> }T
+T{ MAX-INT MIN-INT > -> <TRUE> }T
+T{ MAX-INT 0 > -> <TRUE> }T
+
+T{ 0 1 U< -> <TRUE> }T
+T{ 1 2 U< -> <TRUE> }T
+T{ 0 MID-UINT U< -> <TRUE> }T
+T{ 0 MAX-UINT U< -> <TRUE> }T
+T{ MID-UINT MAX-UINT U< -> <TRUE> }T
+T{ 0 0 U< -> <FALSE> }T
+T{ 1 1 U< -> <FALSE> }T
+T{ 1 0 U< -> <FALSE> }T
+T{ 2 1 U< -> <FALSE> }T
+T{ MID-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT MID-UINT U< -> <FALSE> }T
+
+T{ 0 1 MIN -> 0 }T
+T{ 1 2 MIN -> 1 }T
+T{ -1 0 MIN -> -1 }T
+T{ -1 1 MIN -> -1 }T
+T{ MIN-INT 0 MIN -> MIN-INT }T
+T{ MIN-INT MAX-INT MIN -> MIN-INT }T
+T{ 0 MAX-INT MIN -> 0 }T
+T{ 0 0 MIN -> 0 }T
+T{ 1 1 MIN -> 1 }T
+T{ 1 0 MIN -> 0 }T
+T{ 2 1 MIN -> 1 }T
+T{ 0 -1 MIN -> -1 }T
+T{ 1 -1 MIN -> -1 }T
+T{ 0 MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT 0 MIN -> 0 }T
+
+T{ 0 1 MAX -> 1 }T
+T{ 1 2 MAX -> 2 }T
+T{ -1 0 MAX -> 0 }T
+T{ -1 1 MAX -> 1 }T
+T{ MIN-INT 0 MAX -> 0 }T
+T{ MIN-INT MAX-INT MAX -> MAX-INT }T
+T{ 0 MAX-INT MAX -> MAX-INT }T
+T{ 0 0 MAX -> 0 }T
+T{ 1 1 MAX -> 1 }T
+T{ 1 0 MAX -> 1 }T
+T{ 2 1 MAX -> 2 }T
+T{ 0 -1 MAX -> 0 }T
+T{ 1 -1 MAX -> 1 }T
+T{ 0 MIN-INT MAX -> 0 }T
+T{ MAX-INT MIN-INT MAX -> MAX-INT }T
+T{ MAX-INT 0 MAX -> MAX-INT }T
+
+\ ------------------------------------------------------------------------
+TESTING STACK OPS: 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP
+
+T{ 1 2 2DROP -> }T
+T{ 1 2 2DUP -> 1 2 1 2 }T
+T{ 1 2 3 4 2OVER -> 1 2 3 4 1 2 }T
+T{ 1 2 3 4 2SWAP -> 3 4 1 2 }T
+T{ 0 ?DUP -> 0 }T
+T{ 1 ?DUP -> 1 1 }T
+T{ -1 ?DUP -> -1 -1 }T
+T{ DEPTH -> 0 }T
+T{ 0 DEPTH -> 0 1 }T
+T{ 0 1 DEPTH -> 0 1 2 }T
+T{ 0 DROP -> }T
+T{ 1 2 DROP -> 1 }T
+T{ 1 DUP -> 1 1 }T
+T{ 1 2 OVER -> 1 2 1 }T
+T{ 1 2 3 ROT -> 2 3 1 }T
+T{ 1 2 SWAP -> 2 1 }T
+
+\ ------------------------------------------------------------------------
+TESTING >R R> R@
+
+T{ : GR1 >R R> ; -> }T
+T{ : GR2 >R R@ R> DROP ; -> }T
+T{ 123 GR1 -> 123 }T
+T{ 123 GR2 -> 123 }T
+T{ 1S GR1 -> 1S }T ( RETURN STACK HOLDS CELLS )
+
+\ ------------------------------------------------------------------------
+TESTING ADD/SUBTRACT: + - 1+ 1- ABS NEGATE
+
+T{ 0 5 + -> 5 }T
+T{ 5 0 + -> 5 }T
+T{ 0 -5 + -> -5 }T
+T{ -5 0 + -> -5 }T
+T{ 1 2 + -> 3 }T
+T{ 1 -2 + -> -1 }T
+T{ -1 2 + -> 1 }T
+T{ -1 -2 + -> -3 }T
+T{ -1 1 + -> 0 }T
+T{ MID-UINT 1 + -> MID-UINT+1 }T
+
+T{ 0 5 - -> -5 }T
+T{ 5 0 - -> 5 }T
+T{ 0 -5 - -> 5 }T
+T{ -5 0 - -> -5 }T
+T{ 1 2 - -> -1 }T
+T{ 1 -2 - -> 3 }T
+T{ -1 2 - -> -3 }T
+T{ -1 -2 - -> 1 }T
+T{ 0 1 - -> -1 }T
+T{ MID-UINT+1 1 - -> MID-UINT }T
+
+T{ 0 1+ -> 1 }T
+T{ -1 1+ -> 0 }T
+T{ 1 1+ -> 2 }T
+T{ MID-UINT 1+ -> MID-UINT+1 }T
+
+T{ 2 1- -> 1 }T
+T{ 1 1- -> 0 }T
+T{ 0 1- -> -1 }T
+T{ MID-UINT+1 1- -> MID-UINT }T
+
+T{ 0 NEGATE -> 0 }T
+T{ 1 NEGATE -> -1 }T
+T{ -1 NEGATE -> 1 }T
+T{ 2 NEGATE -> -2 }T
+T{ -2 NEGATE -> 2 }T
+
+T{ 0 ABS -> 0 }T
+T{ 1 ABS -> 1 }T
+T{ -1 ABS -> 1 }T
+T{ MIN-INT ABS -> MID-UINT+1 }T
+
+\ ------------------------------------------------------------------------
+TESTING MULTIPLY: S>D * M* UM*
+
+T{ 0 S>D -> 0 0 }T
+T{ 1 S>D -> 1 0 }T
+T{ 2 S>D -> 2 0 }T
+T{ -1 S>D -> -1 -1 }T
+T{ -2 S>D -> -2 -1 }T
+T{ MIN-INT S>D -> MIN-INT -1 }T
+T{ MAX-INT S>D -> MAX-INT 0 }T
+
+T{ 0 0 M* -> 0 S>D }T
+T{ 0 1 M* -> 0 S>D }T
+T{ 1 0 M* -> 0 S>D }T
+T{ 1 2 M* -> 2 S>D }T
+T{ 2 1 M* -> 2 S>D }T
+T{ 3 3 M* -> 9 S>D }T
+T{ -3 3 M* -> -9 S>D }T
+T{ 3 -3 M* -> -9 S>D }T
+T{ -3 -3 M* -> 9 S>D }T
+T{ 0 MIN-INT M* -> 0 S>D }T
+T{ 1 MIN-INT M* -> MIN-INT S>D }T
+T{ 2 MIN-INT M* -> 0 1S }T
+T{ 0 MAX-INT M* -> 0 S>D }T
+T{ 1 MAX-INT M* -> MAX-INT S>D }T
+T{ 2 MAX-INT M* -> MAX-INT 1 LSHIFT 0 }T
+T{ MIN-INT MIN-INT M* -> 0 MSB 1 RSHIFT }T
+T{ MAX-INT MIN-INT M* -> MSB MSB 2/ }T
+T{ MAX-INT MAX-INT M* -> 1 MSB 2/ INVERT }T
+
+T{ 0 0 * -> 0 }T \ TEST IDENTITIES
+T{ 0 1 * -> 0 }T
+T{ 1 0 * -> 0 }T
+T{ 1 2 * -> 2 }T
+T{ 2 1 * -> 2 }T
+T{ 3 3 * -> 9 }T
+T{ -3 3 * -> -9 }T
+T{ 3 -3 * -> -9 }T
+T{ -3 -3 * -> 9 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 * -> MID-UINT+1 }T
+T{ MID-UINT+1 2 RSHIFT 4 * -> MID-UINT+1 }T
+T{ MID-UINT+1 1 RSHIFT MID-UINT+1 OR 2 * -> MID-UINT+1 }T
+
+T{ 0 0 UM* -> 0 0 }T
+T{ 0 1 UM* -> 0 0 }T
+T{ 1 0 UM* -> 0 0 }T
+T{ 1 2 UM* -> 2 0 }T
+T{ 2 1 UM* -> 2 0 }T
+T{ 3 3 UM* -> 9 0 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 UM* -> MID-UINT+1 0 }T
+T{ MID-UINT+1 2 UM* -> 0 1 }T
+T{ MID-UINT+1 4 UM* -> 0 2 }T
+T{ 1S 2 UM* -> 1S 1 LSHIFT 1 }T
+T{ MAX-UINT MAX-UINT UM* -> 1 1 INVERT }T
+
+\ ------------------------------------------------------------------------
+TESTING DIVIDE: FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD
+
+T{ 0 S>D 1 FM/MOD -> 0 0 }T
+T{ 1 S>D 1 FM/MOD -> 0 1 }T
+T{ 2 S>D 1 FM/MOD -> 0 2 }T
+T{ -1 S>D 1 FM/MOD -> 0 -1 }T
+T{ -2 S>D 1 FM/MOD -> 0 -2 }T
+T{ 0 S>D -1 FM/MOD -> 0 0 }T
+T{ 1 S>D -1 FM/MOD -> 0 -1 }T
+T{ 2 S>D -1 FM/MOD -> 0 -2 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -1 FM/MOD -> 0 2 }T
+T{ 2 S>D 2 FM/MOD -> 0 1 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -2 FM/MOD -> 0 1 }T
+T{ 7 S>D 3 FM/MOD -> 1 2 }T
+T{ 7 S>D -3 FM/MOD -> -2 -3 }T
+T{ -7 S>D 3 FM/MOD -> 2 -3 }T
+T{ -7 S>D -3 FM/MOD -> -1 2 }T
+T{ MAX-INT S>D 1 FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT FM/MOD -> 0 1 }T
+T{ MIN-INT S>D MIN-INT FM/MOD -> 0 1 }T
+T{ 1S 1 4 FM/MOD -> 3 MAX-INT }T
+T{ 1 MIN-INT M* 1 FM/MOD -> 0 MIN-INT }T
+T{ 1 MIN-INT M* MIN-INT FM/MOD -> 0 1 }T
+T{ 2 MIN-INT M* 2 FM/MOD -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT FM/MOD -> 0 2 }T
+T{ 1 MAX-INT M* 1 FM/MOD -> 0 MAX-INT }T
+T{ 1 MAX-INT M* MAX-INT FM/MOD -> 0 1 }T
+T{ 2 MAX-INT M* 2 FM/MOD -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT FM/MOD -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT FM/MOD -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT FM/MOD -> 0 MAX-INT }T
+
+T{ 0 S>D 1 SM/REM -> 0 0 }T
+T{ 1 S>D 1 SM/REM -> 0 1 }T
+T{ 2 S>D 1 SM/REM -> 0 2 }T
+T{ -1 S>D 1 SM/REM -> 0 -1 }T
+T{ -2 S>D 1 SM/REM -> 0 -2 }T
+T{ 0 S>D -1 SM/REM -> 0 0 }T
+T{ 1 S>D -1 SM/REM -> 0 -1 }T
+T{ 2 S>D -1 SM/REM -> 0 -2 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -1 SM/REM -> 0 2 }T
+T{ 2 S>D 2 SM/REM -> 0 1 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -2 SM/REM -> 0 1 }T
+T{ 7 S>D 3 SM/REM -> 1 2 }T
+T{ 7 S>D -3 SM/REM -> 1 -2 }T
+T{ -7 S>D 3 SM/REM -> -1 -2 }T
+T{ -7 S>D -3 SM/REM -> -1 2 }T
+T{ MAX-INT S>D 1 SM/REM -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 SM/REM -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT SM/REM -> 0 1 }T
+T{ MIN-INT S>D MIN-INT SM/REM -> 0 1 }T
+T{ 1S 1 4 SM/REM -> 3 MAX-INT }T
+T{ 2 MIN-INT M* 2 SM/REM -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT SM/REM -> 0 2 }T
+T{ 2 MAX-INT M* 2 SM/REM -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT SM/REM -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT SM/REM -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT SM/REM -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT SM/REM -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT SM/REM -> 0 MAX-INT }T
+
+T{ 0 0 1 UM/MOD -> 0 0 }T
+T{ 1 0 1 UM/MOD -> 0 1 }T
+T{ 1 0 2 UM/MOD -> 1 0 }T
+T{ 3 0 2 UM/MOD -> 1 1 }T
+T{ MAX-UINT 2 UM* 2 UM/MOD -> 0 MAX-UINT }T
+T{ MAX-UINT 2 UM* MAX-UINT UM/MOD -> 0 2 }T
+T{ MAX-UINT MAX-UINT UM* MAX-UINT UM/MOD -> 0 MAX-UINT }T
+
+: IFFLOORED
+ [ -3 2 / -2 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+: IFSYM
+ [ -3 2 / -1 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+\ THE SYSTEM MIGHT DO EITHER FLOORED OR SYMMETRIC DIVISION.
+\ SINCE WE HAVE ALREADY TESTED M*, FM/MOD, AND SM/REM WE CAN USE THEM IN TEST.
+
+IFFLOORED : T/MOD >R S>D R> FM/MOD ;
+IFFLOORED : T/ T/MOD SWAP DROP ;
+IFFLOORED : TMOD T/MOD DROP ;
+IFFLOORED : T*/MOD >R M* R> FM/MOD ;
+IFFLOORED : T*/ T*/MOD SWAP DROP ;
+IFSYM : T/MOD >R S>D R> SM/REM ;
+IFSYM : T/ T/MOD SWAP DROP ;
+IFSYM : TMOD T/MOD DROP ;
+IFSYM : T*/MOD >R M* R> SM/REM ;
+IFSYM : T*/ T*/MOD SWAP DROP ;
+
+T{ 0 1 /MOD -> 0 1 T/MOD }T
+T{ 1 1 /MOD -> 1 1 T/MOD }T
+T{ 2 1 /MOD -> 2 1 T/MOD }T
+T{ -1 1 /MOD -> -1 1 T/MOD }T
+T{ -2 1 /MOD -> -2 1 T/MOD }T
+T{ 0 -1 /MOD -> 0 -1 T/MOD }T
+T{ 1 -1 /MOD -> 1 -1 T/MOD }T
+T{ 2 -1 /MOD -> 2 -1 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -1 /MOD -> -2 -1 T/MOD }T
+T{ 2 2 /MOD -> 2 2 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -2 /MOD -> -2 -2 T/MOD }T
+T{ 7 3 /MOD -> 7 3 T/MOD }T
+T{ 7 -3 /MOD -> 7 -3 T/MOD }T
+T{ -7 3 /MOD -> -7 3 T/MOD }T
+T{ -7 -3 /MOD -> -7 -3 T/MOD }T
+T{ MAX-INT 1 /MOD -> MAX-INT 1 T/MOD }T
+T{ MIN-INT 1 /MOD -> MIN-INT 1 T/MOD }T
+T{ MAX-INT MAX-INT /MOD -> MAX-INT MAX-INT T/MOD }T
+T{ MIN-INT MIN-INT /MOD -> MIN-INT MIN-INT T/MOD }T
+
+T{ 0 1 / -> 0 1 T/ }T
+T{ 1 1 / -> 1 1 T/ }T
+T{ 2 1 / -> 2 1 T/ }T
+T{ -1 1 / -> -1 1 T/ }T
+T{ -2 1 / -> -2 1 T/ }T
+T{ 0 -1 / -> 0 -1 T/ }T
+T{ 1 -1 / -> 1 -1 T/ }T
+T{ 2 -1 / -> 2 -1 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -1 / -> -2 -1 T/ }T
+T{ 2 2 / -> 2 2 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -2 / -> -2 -2 T/ }T
+T{ 7 3 / -> 7 3 T/ }T
+T{ 7 -3 / -> 7 -3 T/ }T
+T{ -7 3 / -> -7 3 T/ }T
+T{ -7 -3 / -> -7 -3 T/ }T
+T{ MAX-INT 1 / -> MAX-INT 1 T/ }T
+T{ MIN-INT 1 / -> MIN-INT 1 T/ }T
+T{ MAX-INT MAX-INT / -> MAX-INT MAX-INT T/ }T
+T{ MIN-INT MIN-INT / -> MIN-INT MIN-INT T/ }T
+
+T{ 0 1 MOD -> 0 1 TMOD }T
+T{ 1 1 MOD -> 1 1 TMOD }T
+T{ 2 1 MOD -> 2 1 TMOD }T
+T{ -1 1 MOD -> -1 1 TMOD }T
+T{ -2 1 MOD -> -2 1 TMOD }T
+T{ 0 -1 MOD -> 0 -1 TMOD }T
+T{ 1 -1 MOD -> 1 -1 TMOD }T
+T{ 2 -1 MOD -> 2 -1 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -1 MOD -> -2 -1 TMOD }T
+T{ 2 2 MOD -> 2 2 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -2 MOD -> -2 -2 TMOD }T
+T{ 7 3 MOD -> 7 3 TMOD }T
+T{ 7 -3 MOD -> 7 -3 TMOD }T
+T{ -7 3 MOD -> -7 3 TMOD }T
+T{ -7 -3 MOD -> -7 -3 TMOD }T
+T{ MAX-INT 1 MOD -> MAX-INT 1 TMOD }T
+T{ MIN-INT 1 MOD -> MIN-INT 1 TMOD }T
+T{ MAX-INT MAX-INT MOD -> MAX-INT MAX-INT TMOD }T
+T{ MIN-INT MIN-INT MOD -> MIN-INT MIN-INT TMOD }T
+
+T{ 0 2 1 */ -> 0 2 1 T*/ }T
+T{ 1 2 1 */ -> 1 2 1 T*/ }T
+T{ 2 2 1 */ -> 2 2 1 T*/ }T
+T{ -1 2 1 */ -> -1 2 1 T*/ }T
+T{ -2 2 1 */ -> -2 2 1 T*/ }T
+T{ 0 2 -1 */ -> 0 2 -1 T*/ }T
+T{ 1 2 -1 */ -> 1 2 -1 T*/ }T
+T{ 2 2 -1 */ -> 2 2 -1 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -1 */ -> -2 2 -1 T*/ }T
+T{ 2 2 2 */ -> 2 2 2 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -2 */ -> -2 2 -2 T*/ }T
+T{ 7 2 3 */ -> 7 2 3 T*/ }T
+T{ 7 2 -3 */ -> 7 2 -3 T*/ }T
+T{ -7 2 3 */ -> -7 2 3 T*/ }T
+T{ -7 2 -3 */ -> -7 2 -3 T*/ }T
+T{ MAX-INT 2 MAX-INT */ -> MAX-INT 2 MAX-INT T*/ }T
+T{ MIN-INT 2 MIN-INT */ -> MIN-INT 2 MIN-INT T*/ }T
+
+T{ 0 2 1 */MOD -> 0 2 1 T*/MOD }T
+T{ 1 2 1 */MOD -> 1 2 1 T*/MOD }T
+T{ 2 2 1 */MOD -> 2 2 1 T*/MOD }T
+T{ -1 2 1 */MOD -> -1 2 1 T*/MOD }T
+T{ -2 2 1 */MOD -> -2 2 1 T*/MOD }T
+T{ 0 2 -1 */MOD -> 0 2 -1 T*/MOD }T
+T{ 1 2 -1 */MOD -> 1 2 -1 T*/MOD }T
+T{ 2 2 -1 */MOD -> 2 2 -1 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -1 */MOD -> -2 2 -1 T*/MOD }T
+T{ 2 2 2 */MOD -> 2 2 2 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -2 */MOD -> -2 2 -2 T*/MOD }T
+T{ 7 2 3 */MOD -> 7 2 3 T*/MOD }T
+T{ 7 2 -3 */MOD -> 7 2 -3 T*/MOD }T
+T{ -7 2 3 */MOD -> -7 2 3 T*/MOD }T
+T{ -7 2 -3 */MOD -> -7 2 -3 T*/MOD }T
+T{ MAX-INT 2 MAX-INT */MOD -> MAX-INT 2 MAX-INT T*/MOD }T
+T{ MIN-INT 2 MIN-INT */MOD -> MIN-INT 2 MIN-INT T*/MOD }T
+
+\ ------------------------------------------------------------------------
+TESTING HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2! ALIGN ALIGNED +! ALLOT
+
+HERE 1 ALLOT
+HERE
+CONSTANT 2NDA
+CONSTANT 1STA
+T{ 1STA 2NDA U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STA 1+ -> 2NDA }T \ ... BY ONE ADDRESS UNIT
+( MISSING TEST: NEGATIVE ALLOT )
+
+HERE 1 ,
+HERE 2 ,
+CONSTANT 2ND
+CONSTANT 1ST
+T{ 1ST 2ND U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1ST CELL+ -> 2ND }T \ ... BY ONE CELL
+T{ 1ST 1 CELLS + -> 2ND }T
+T{ 1ST @ 2ND @ -> 1 2 }T
+T{ 5 1ST ! -> }T
+T{ 1ST @ 2ND @ -> 5 2 }T
+T{ 6 2ND ! -> }T
+T{ 1ST @ 2ND @ -> 5 6 }T
+T{ 1ST 2@ -> 6 5 }T
+T{ 2 1 1ST 2! -> }T
+T{ 1ST 2@ -> 2 1 }T
+T{ 1S 1ST ! 1ST @ -> 1S }T \ CAN STORE CELL-WIDE VALUE
+
+HERE 1 C,
+HERE 2 C,
+CONSTANT 2NDC
+CONSTANT 1STC
+T{ 1STC 2NDC U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STC CHAR+ -> 2NDC }T \ ... BY ONE CHAR
+T{ 1STC 1 CHARS + -> 2NDC }T
+T{ 1STC C@ 2NDC C@ -> 1 2 }T
+T{ 3 1STC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 2 }T
+T{ 4 2NDC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 4 }T
+
+ALIGN 1 ALLOT HERE ALIGN HERE 3 CELLS ALLOT
+CONSTANT A-ADDR CONSTANT UA-ADDR
+T{ UA-ADDR ALIGNED -> A-ADDR }T
+T{ 1 A-ADDR C! A-ADDR C@ -> 1 }T
+T{ 1234 A-ADDR ! A-ADDR @ -> 1234 }T
+T{ 123 456 A-ADDR 2! A-ADDR 2@ -> 123 456 }T
+T{ 2 A-ADDR CHAR+ C! A-ADDR CHAR+ C@ -> 2 }T
+T{ 3 A-ADDR CELL+ C! A-ADDR CELL+ C@ -> 3 }T
+T{ 1234 A-ADDR CELL+ ! A-ADDR CELL+ @ -> 1234 }T
+T{ 123 456 A-ADDR CELL+ 2! A-ADDR CELL+ 2@ -> 123 456 }T
+
+: BITS ( X -- U )
+ 0 SWAP BEGIN DUP WHILE DUP MSB AND IF >R 1+ R> THEN 2* REPEAT DROP ;
+( CHARACTERS >= 1 AU, <= SIZE OF CELL, >= 8 BITS )
+T{ 1 CHARS 1 < -> <FALSE> }T
+T{ 1 CHARS 1 CELLS > -> <FALSE> }T
+( TBD: HOW TO FIND NUMBER OF BITS? )
+
+( CELLS >= 1 AU, INTEGRAL MULTIPLE OF CHAR SIZE, >= 16 BITS )
+T{ 1 CELLS 1 < -> <FALSE> }T
+T{ 1 CELLS 1 CHARS MOD -> 0 }T
+T{ 1S BITS 10 < -> <FALSE> }T
+
+T{ 0 1ST ! -> }T
+T{ 1 1ST +! -> }T
+T{ 1ST @ -> 1 }T
+T{ -1 1ST +! 1ST @ -> 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING CHAR [CHAR] [ ] BL S"
+
+T{ BL -> 20 }T
+T{ CHAR X -> 58 }T
+T{ CHAR HELLO -> 48 }T
+T{ : GC1 [CHAR] X ; -> }T
+T{ : GC2 [CHAR] HELLO ; -> }T
+T{ GC1 -> 58 }T
+T{ GC2 -> 48 }T
+T{ : GC3 [ GC1 ] LITERAL ; -> }T
+T{ GC3 -> 58 }T
+T{ : GC4 S" XY" ; -> }T
+T{ GC4 SWAP DROP -> 2 }T
+T{ GC4 DROP DUP C@ SWAP CHAR+ C@ -> 58 59 }T
+
+\ ------------------------------------------------------------------------
+TESTING ' ['] FIND EXECUTE IMMEDIATE COUNT LITERAL POSTPONE STATE
+
+T{ : GT1 123 ; -> }T
+T{ ' GT1 EXECUTE -> 123 }T
+T{ : GT2 ['] GT1 ; IMMEDIATE -> }T
+T{ GT2 EXECUTE -> 123 }T
+HERE 3 C, CHAR G C, CHAR T C, CHAR 1 C, CONSTANT GT1STRING
+HERE 3 C, CHAR G C, CHAR T C, CHAR 2 C, CONSTANT GT2STRING
+T{ GT1STRING FIND -> ' GT1 -1 }T
+T{ GT2STRING FIND -> ' GT2 1 }T
+( HOW TO SEARCH FOR NON-EXISTENT WORD? )
+T{ : GT3 GT2 LITERAL ; -> }T
+T{ GT3 -> ' GT1 }T
+T{ GT1STRING COUNT -> GT1STRING CHAR+ 3 }T
+
+T{ : GT4 POSTPONE GT1 ; IMMEDIATE -> }T
+T{ : GT5 GT4 ; -> }T
+T{ GT5 -> 123 }T
+T{ : GT6 345 ; IMMEDIATE -> }T
+T{ : GT7 POSTPONE GT6 ; -> }T
+T{ GT7 -> 345 }T
+
+T{ : GT8 STATE @ ; IMMEDIATE -> }T
+T{ GT8 -> 0 }T
+T{ : GT9 GT8 LITERAL ; -> }T
+T{ GT9 0= -> <FALSE> }T
+
+\ ------------------------------------------------------------------------
+TESTING IF ELSE THEN BEGIN WHILE REPEAT UNTIL RECURSE
+
+T{ : GI1 IF 123 THEN ; -> }T
+T{ : GI2 IF 123 ELSE 234 THEN ; -> }T
+T{ 0 GI1 -> }T
+T{ 1 GI1 -> 123 }T
+T{ -1 GI1 -> 123 }T
+T{ 0 GI2 -> 234 }T
+T{ 1 GI2 -> 123 }T
+T{ -1 GI1 -> 123 }T
+
+T{ : GI3 BEGIN DUP 5 < WHILE DUP 1+ REPEAT ; -> }T
+T{ 0 GI3 -> 0 1 2 3 4 5 }T
+T{ 4 GI3 -> 4 5 }T
+T{ 5 GI3 -> 5 }T
+T{ 6 GI3 -> 6 }T
+
+T{ : GI4 BEGIN DUP 1+ DUP 5 > UNTIL ; -> }T
+T{ 3 GI4 -> 3 4 5 6 }T
+T{ 5 GI4 -> 5 6 }T
+T{ 6 GI4 -> 6 7 }T
+
+T{ : GI5 BEGIN DUP 2 > WHILE DUP 5 < WHILE DUP 1+ REPEAT 123 ELSE 345 THEN ; -> }T
+T{ 1 GI5 -> 1 345 }T
+T{ 2 GI5 -> 2 345 }T
+T{ 3 GI5 -> 3 4 5 123 }T
+T{ 4 GI5 -> 4 5 123 }T
+T{ 5 GI5 -> 5 123 }T
+
+T{ : GI6 ( N -- 0,1,..N ) DUP IF DUP >R 1- RECURSE R> THEN ; -> }T
+T{ 0 GI6 -> 0 }T
+T{ 1 GI6 -> 0 1 }T
+T{ 2 GI6 -> 0 1 2 }T
+T{ 3 GI6 -> 0 1 2 3 }T
+T{ 4 GI6 -> 0 1 2 3 4 }T
+
+\ ------------------------------------------------------------------------
+TESTING DO LOOP +LOOP I J UNLOOP LEAVE EXIT
+
+T{ : GD1 DO I LOOP ; -> }T
+T{ 4 1 GD1 -> 1 2 3 }T
+T{ 2 -1 GD1 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD1 -> MID-UINT }T
+
+T{ : GD2 DO I -1 +LOOP ; -> }T
+T{ 1 4 GD2 -> 4 3 2 1 }T
+T{ -1 2 GD2 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD2 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD3 DO 1 0 DO J LOOP LOOP ; -> }T
+T{ 4 1 GD3 -> 1 2 3 }T
+T{ 2 -1 GD3 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD3 -> MID-UINT }T
+
+T{ : GD4 DO 1 0 DO J LOOP -1 +LOOP ; -> }T
+T{ 1 4 GD4 -> 4 3 2 1 }T
+T{ -1 2 GD4 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD4 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD5 123 SWAP 0 DO I 4 > IF DROP 234 LEAVE THEN LOOP ; -> }T
+T{ 1 GD5 -> 123 }T
+T{ 5 GD5 -> 123 }T
+T{ 6 GD5 -> 234 }T
+
+T{ : GD6 ( PAT: T{0 0}T,T{0 0}TT{1 0}TT{1 1}T,T{0 0}TT{1 0}TT{1 1}TT{2 0}TT{2 1}TT{2 2}T )
+ 0 SWAP 0 DO
+ I 1+ 0 DO I J + 3 = IF I UNLOOP I UNLOOP EXIT THEN 1+ LOOP
+ LOOP ; -> }T
+T{ 1 GD6 -> 1 }T
+T{ 2 GD6 -> 3 }T
+T{ 3 GD6 -> 4 1 2 }T
+
+\ ------------------------------------------------------------------------
+TESTING DEFINING WORDS: : ; CONSTANT VARIABLE CREATE DOES> >BODY
+
+T{ 123 CONSTANT X123 -> }T
+T{ X123 -> 123 }T
+T{ : EQU CONSTANT ; -> }T
+T{ X123 EQU Y123 -> }T
+T{ Y123 -> 123 }T
+
+T{ VARIABLE V1 -> }T
+T{ 123 V1 ! -> }T
+T{ V1 @ -> 123 }T
+
+T{ : NOP : POSTPONE ; ; -> }T
+T{ NOP NOP1 NOP NOP2 -> }T
+T{ NOP1 -> }T
+T{ NOP2 -> }T
+
+T{ : DOES1 DOES> @ 1 + ; -> }T
+T{ : DOES2 DOES> @ 2 + ; -> }T
+T{ CREATE CR1 -> }T
+T{ CR1 -> HERE }T
+T{ ' CR1 >BODY -> HERE }T
+T{ 1 , -> }T
+T{ CR1 @ -> 1 }T
+T{ DOES1 -> }T
+T{ CR1 -> 2 }T
+T{ DOES2 -> }T
+T{ CR1 -> 3 }T
+
+T{ : WEIRD: CREATE DOES> 1 + DOES> 2 + ; -> }T
+T{ WEIRD: W1 -> }T
+T{ ' W1 >BODY -> HERE }T
+T{ W1 -> HERE 1 + }T
+T{ W1 -> HERE 2 + }T
+
+\ ------------------------------------------------------------------------
+TESTING EVALUATE
+
+: GE1 S" 123" ; IMMEDIATE
+: GE2 S" 123 1+" ; IMMEDIATE
+: GE3 S" : GE4 345 ;" ;
+: GE5 EVALUATE ; IMMEDIATE
+
+T{ GE1 EVALUATE -> 123 }T ( TEST EVALUATE IN INTERP. STATE )
+T{ GE2 EVALUATE -> 124 }T
+T{ GE3 EVALUATE -> }T
+T{ GE4 -> 345 }T
+
+T{ : GE6 GE1 GE5 ; -> }T ( TEST EVALUATE IN COMPILE STATE )
+T{ GE6 -> 123 }T
+T{ : GE7 GE2 GE5 ; -> }T
+T{ GE7 -> 124 }T
+
+\ ------------------------------------------------------------------------
+TESTING SOURCE >IN WORD
+
+: GS1 S" SOURCE" 2DUP EVALUATE
+ >R SWAP >R = R> R> = ;
+T{ GS1 -> <TRUE> <TRUE> }T
+
+VARIABLE SCANS
+: RESCAN? -1 SCANS +! SCANS @ IF 0 >IN ! THEN ;
+
+T{ 2 SCANS !
+345 RESCAN?
+-> 345 345 }T
+
+: GS2 5 SCANS ! S" 123 RESCAN?" EVALUATE ;
+T{ GS2 -> 123 123 123 123 123 }T
+
+: GS3 WORD COUNT SWAP C@ ;
+T{ BL GS3 HELLO -> 5 CHAR H }T
+T{ CHAR " GS3 GOODBYE" -> 7 CHAR G }T
+T{ BL GS3
+DROP -> 0 }T \ BLANK LINE RETURN ZERO-LENGTH STRING
+
+: GS4 SOURCE >IN ! DROP ;
+T{ GS4 123 456
+-> }T
+
+\ ------------------------------------------------------------------------
+TESTING <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL
+
+: S= \ ( ADDR1 C1 ADDR2 C2 -- T/F ) COMPARE TWO STRINGS.
+ >R SWAP R@ = IF \ MAKE SURE STRINGS HAVE SAME LENGTH
+ R> ?DUP IF \ IF NON-EMPTY STRINGS
+ 0 DO
+ OVER C@ OVER C@ - IF
+ 2DROP <FALSE> UNLOOP EXIT THEN
+ SWAP CHAR+ SWAP CHAR+
+ LOOP
+ THEN
+ 2DROP <TRUE> \ IF WE GET HERE, STRINGS MATCH
+ ELSE
+ R> DROP 2DROP <FALSE> \ LENGTHS MISMATCH
+ THEN ;
+
+: GP1 <# 41 HOLD 42 HOLD 0 0 #> S" BA" S= ;
+T{ GP1 -> <TRUE> }T
+
+: GP2 <# -1 SIGN 0 SIGN -1 SIGN 0 0 #> S" --" S= ;
+T{ GP2 -> <TRUE> }T
+
+: GP3 <# 1 0 # # #> S" 01" S= ;
+T{ GP3 -> <TRUE> }T
+
+: GP4 <# 1 0 #S #> S" 1" S= ;
+T{ GP4 -> <TRUE> }T
+
+24 CONSTANT MAX-BASE \ BASE 2 .. 36
+: COUNT-BITS
+ 0 0 INVERT BEGIN DUP WHILE >R 1+ R> 2* REPEAT DROP ;
+COUNT-BITS 2* CONSTANT #BITS-UD \ NUMBER OF BITS IN UD
+
+: GP5
+ BASE @ <TRUE>
+ MAX-BASE 1+ 2 DO \ FOR EACH POSSIBLE BASE
+ I BASE ! \ TBD: ASSUMES BASE WORKS
+ I 0 <# #S #> S" 10" S= AND
+ LOOP
+ SWAP BASE ! ;
+T{ GP5 -> <TRUE> }T
+
+: GP6
+ BASE @ >R 2 BASE !
+ MAX-UINT MAX-UINT <# #S #> \ MAXIMUM UD TO BINARY
+ R> BASE ! \ S: C-ADDR U
+ DUP #BITS-UD = SWAP
+ 0 DO \ S: C-ADDR FLAG
+ OVER C@ [CHAR] 1 = AND \ ALL ONES
+ >R CHAR+ R>
+ LOOP SWAP DROP ;
+T{ GP6 -> <TRUE> }T
+
+: GP7
+ BASE @ >R MAX-BASE BASE !
+ <TRUE>
+ A 0 DO
+ I 0 <# #S #>
+ 1 = SWAP C@ I 30 + = AND AND
+ LOOP
+ MAX-BASE A DO
+ I 0 <# #S #>
+ 1 = SWAP C@ 41 I A - + = AND AND
+ LOOP
+ R> BASE ! ;
+
+T{ GP7 -> <TRUE> }T
+
+\ >NUMBER TESTS
+CREATE GN-BUF 0 C,
+: GN-STRING GN-BUF 1 ;
+: GN-CONSUMED GN-BUF CHAR+ 0 ;
+: GN' [CHAR] ' WORD CHAR+ C@ GN-BUF C! GN-STRING ;
+
+T{ 0 0 GN' 0' >NUMBER -> 0 0 GN-CONSUMED }T
+T{ 0 0 GN' 1' >NUMBER -> 1 0 GN-CONSUMED }T
+T{ 1 0 GN' 1' >NUMBER -> BASE @ 1+ 0 GN-CONSUMED }T
+T{ 0 0 GN' -' >NUMBER -> 0 0 GN-STRING }T \ SHOULD FAIL TO CONVERT THESE
+T{ 0 0 GN' +' >NUMBER -> 0 0 GN-STRING }T
+T{ 0 0 GN' .' >NUMBER -> 0 0 GN-STRING }T
+
+: >NUMBER-BASED
+ BASE @ >R BASE ! >NUMBER R> BASE ! ;
+
+T{ 0 0 GN' 2' 10 >NUMBER-BASED -> 2 0 GN-CONSUMED }T
+T{ 0 0 GN' 2' 2 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' F' 10 >NUMBER-BASED -> F 0 GN-CONSUMED }T
+T{ 0 0 GN' G' 10 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' G' MAX-BASE >NUMBER-BASED -> 10 0 GN-CONSUMED }T
+T{ 0 0 GN' Z' MAX-BASE >NUMBER-BASED -> 23 0 GN-CONSUMED }T
+
+: GN1 \ ( UD BASE -- UD' LEN ) UD SHOULD EQUAL UD' AND LEN SHOULD BE ZERO.
+ BASE @ >R BASE !
+ <# #S #>
+ 0 0 2SWAP >NUMBER SWAP DROP \ RETURN LENGTH ONLY
+ R> BASE ! ;
+T{ 0 0 2 GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 2 GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP 2 GN1 -> MAX-UINT DUP 0 }T
+T{ 0 0 MAX-BASE GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 MAX-BASE GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP MAX-BASE GN1 -> MAX-UINT DUP 0 }T
+
+: GN2 \ ( -- 16 10 )
+ BASE @ >R HEX BASE @ DECIMAL BASE @ R> BASE ! ;
+T{ GN2 -> 10 A }T
+
+\ ------------------------------------------------------------------------
+TESTING FILL MOVE
+
+CREATE FBUF 00 C, 00 C, 00 C,
+CREATE SBUF 12 C, 34 C, 56 C,
+: SEEBUF FBUF C@ FBUF CHAR+ C@ FBUF CHAR+ CHAR+ C@ ;
+
+T{ FBUF 0 20 FILL -> }T
+T{ SEEBUF -> 00 00 00 }T
+
+T{ FBUF 1 20 FILL -> }T
+T{ SEEBUF -> 20 00 00 }T
+
+T{ FBUF 3 20 FILL -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ FBUF FBUF 3 CHARS MOVE -> }T \ BIZARRE SPECIAL CASE
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 0 CHARS MOVE -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 1 CHARS MOVE -> }T
+T{ SEEBUF -> 12 20 20 }T
+
+T{ SBUF FBUF 3 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 56 }T
+
+T{ FBUF FBUF CHAR+ 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 12 34 }T
+
+T{ FBUF CHAR+ FBUF 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 34 }T
+
+\ ------------------------------------------------------------------------
+TESTING OUTPUT: . ." CR EMIT SPACE SPACES TYPE U.
+
+: OUTPUT-TEST
+ ." YOU SHOULD SEE THE STANDARD GRAPHIC CHARACTERS:" CR
+ 41 BL DO I EMIT LOOP CR
+ 61 41 DO I EMIT LOOP CR
+ 7F 61 DO I EMIT LOOP CR
+ ." YOU SHOULD SEE 0-9 SEPARATED BY A SPACE:" CR
+ 9 1+ 0 DO I . LOOP CR
+ ." YOU SHOULD SEE 0-9 (WITH NO SPACES):" CR
+ [CHAR] 9 1+ [CHAR] 0 DO I 0 SPACES EMIT LOOP CR
+ ." YOU SHOULD SEE A-G SEPARATED BY A SPACE:" CR
+ [CHAR] G 1+ [CHAR] A DO I EMIT SPACE LOOP CR
+ ." YOU SHOULD SEE 0-5 SEPARATED BY TWO SPACES:" CR
+ 5 1+ 0 DO I [CHAR] 0 + EMIT 2 SPACES LOOP CR
+ ." YOU SHOULD SEE TWO SEPARATE LINES:" CR
+ S" LINE 1" TYPE CR S" LINE 2" TYPE CR
+ ." YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:" CR
+ ." SIGNED: " MIN-INT . MAX-INT . CR
+ ." UNSIGNED: " 0 U. MAX-UINT U. CR
+;
+
+T{ OUTPUT-TEST -> }T
+\ ------------------------------------------------------------------------
+TESTING INPUT: ACCEPT
+
+CREATE ABUF 80 CHARS ALLOT
+
+: ACCEPT-TEST
+ CR ." PLEASE TYPE UP TO 80 CHARACTERS:" CR
+\ ABUF 80 ACCEPT
+ ABUF 80 (ACCEPT) \ JMT: because ACCEPT is DEFERred to SD_ACCEPT
+ CR ." RECEIVED: " [CHAR] " EMIT
+ ABUF SWAP TYPE [CHAR] " EMIT CR
+;
+
+T{ ACCEPT-TEST -> }T
+\ ------------------------------------------------------------------------
+TESTING DICTIONARY SEARCH RULES
+
+T{ : GDX 123 ; : GDX GDX 234 ; -> }T
+
+T{ GDX -> 123 234 }T
+
+CR .( End of Core word set tests) CR
+
+
+$0A BASE !
+
+ ; happy end of core test
--- /dev/null
+! -*- coding: utf-8 -*-
+! ChipStick_FR2433.pat
+!
+! Fast Forth For M. Ken Boak "ChipStick"
+!
+! Copyright (C) <2016> <J.M. THOORENS>
+!
+! This program is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! This program is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with this program. If not, see <http://www.gnu.org/licenses/>.
+!
+!
+!
+! ======================================================================
+! MSP430FR2433 Config
+! ======================================================================
+
+@define{@read{/config/gema/MSP430FR2433.pat}}
+@define{@read{/config/gema/MSP430FR2x4x_FastForth.pat}}
+@define{@read{/config/gema/FastForthREGtoTI.pat}}
+@define{@read{/config/gema/RemoveComments.pat}}
+
+! ---------------------------------------------------
+! CHIPSTICK_FR2433 <--> OUTPUT WORLD
+! ---------------------------------------------------
+! P3.1 - LED1
+!
+! P2.1 - PL2.2 - SW1
+! P2.0 - PL2.3 - SW2
+!
+! +--4k7-< DeepRST <-- GND
+! |
+! P1.4 - UCA0 TXD PL1.4 - <-+-> RX UARTtoUSB bridge
+! P1.5 - UCA0 RXD PL1.3 - <---- TX UARTtoUSB bridge
+! P3.2 - RTS PL1.2 - ----> CTS UARTtoUSB bridge (if TERMINALCTSRTS option)
+! -
+! P3.0 - PL1.7 - ----> /CS SPI_RAM
+! P1.1 - UCB0 CLK PL1.9 - ----> CLK SPI_RAM
+! P1.2 - UCB0 SIMO PL1.10 - ----> SI SPI_RAM
+! P1.3 - UCB0 SOMI PL2.10 - <---- S0 SPI_RAM
+!
+!
+! P1.1 - UCB0 CLK PL1.9 - ----> SD_CLK
+! P1.2 - UCB0 SIMO PL1.10 - ----> SD_SDI
+! P1.3 - UCB0 SOMI PL2.10 - <---- SD_SDO
+! P2.3 - PL1.6 - <---- SD_CD (Card Detect)
+! P2.2 - PL2.9 - ----> SD_CS (Card Select)
+!
+! P1.2 - UCB0 SDA PL1.10 - <---> SDA I2C Slave
+! P1.3 - UCB0 SCL PL2.10 - ----> SCL I2C Slave
+!
+! P2.2 - PL2.9 - ----> SCL I2C SoftMaster
+! P2.0 - PL2.3 - <---> SDA I2C SoftMaster
+!
+! P1.0 - UCB0 STE PL1.8 - <---- TSSOP32236 (IR RC5)
+
+
+LED1_OUT=\$222!
+LED1=\$02! P3.1
+
+SW1_IN=\$201!
+SW1=\$02! P2.1
+
+SW2_IN=\$201!
+SW2=\$01! P2.0
+
+
+IR_IN=\$200!
+IR_OUT=\$202!
+IR_DIR=\$204!
+IR_REN=\$208!
+IR_IES=\$218!
+IR_IE=\$21A!
+IR_IFG=\$21C!
+IR_Vec=\$FFDC! P1 int
+RC5_=RC5_!
+RC5=\$01! P1.0
+
+I2CSM_IN=\$201!
+I2CSM_OUT=\$203!
+I2CSM_DIR=\$205!
+I2CSM_REN=\$207!
+SMSDA=\$01! P2.0
+SMSCL=\$04! P2.2
+SM_BUS=\$05!
+
+I2CSMM_IN=\$201!
+I2CSMM_OUT=\$203!
+I2CSMM_DIR=\$205!
+I2CSMM_REN=\$207!
+SMMSDA=\$01! P2.0
+SMMSCL=\$04! P2.2
+SMM_BUS=\$05!
+
+I2CMM_IN=\$200!
+I2CMM_OUT=\$202!
+I2CMM_DIR=\$204!
+I2CMM_REN=\$206!
+I2CMM_SEL1=\$20C!
+I2CMM_Vec=\$FFE0!
+MMSDA=\$04! P1.2
+MMSCL=\$08! P1.3
+MM_BUS=\$0C!
+
+I2CM_IN=\$200!
+I2CM_OUT=\$202!
+I2CM_DIR=\$204!
+I2CM_REN=\$206!
+I2CM_SEL1=\$20C!
+I2CM_Vec=\$FFE0!
+MSDA=\$04! P1.2
+MSCL=\$08! P1.3
+M_BUS=\$0C!
+
+I2CS_IN=\$200!
+I2CS_OUT=\$202!
+I2CS_DIR=\$204!
+I2CS_REN=\$206!
+I2CS_SEL1=\$20C!
+I2CS_Vec=\$FFE0!
+SSDA=\$40! P1.2
+SSCL=\$80! P1.3
+S_BUS=\$C0!
+
--- /dev/null
+-1 SAVE_SYSRSTIV ! COLD
+\ download to unlock JTAG and BSL, for example
--- /dev/null
+! -*- coding: utf-8 -*-
+! MSP_EXP430FR4133.pat
+!
+! Fast Forth For Texas Instrument MSP_EXP430FR4133
+!
+! Copyright (C) <2016> <J.M. THOORENS>
+!
+! This program is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! This program is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with this program. If not, see <http://www.gnu.org/licenses/>.
+!
+!
+!
+! ======================================================================
+! MSP430FR4133 Config
+! ======================================================================
+
+@define{@read{/config/gema/MSP430FR4133.pat}}
+@define{@read{/config/gema/MSP430FR2x4x_FastForth.pat}}
+@define{@read{/config/gema/FastForthREGtoTI.pat}}
+@define{@read{/config/gema/RemoveComments.pat}}
+
+! ======================================================================
+! MSP_EXP430FR4133 board
+! ======================================================================
+!
+! J101 eZ-FET <-> target
+! -----------------------
+! P1 <-> P2 - NC
+! P3 <-> P4 - TEST - TEST
+! P5 <-> P6 - RST - RST
+! P7 <-> P8 - TX1 - P1.0 UCA0 TXD ---> RX UARTtoUSB module
+! P9 <->P10 - RX1 - P1.1 UCA0 RXD <--- TX UARTtoUSB module
+! P11<->P12 - CTS - P2.4
+! P13<->P14 - RTS - P2.3
+! P15<->P16 - VCC - 3V3
+! P17<->P18 - 5V
+! P19<->P20 - GND - VSS
+!
+! Launchpad Header Left J1
+! ------------------------
+! P1 - 3V3
+! P2 - P8.1 ACLK/A9
+! P3 - P1.1 UCA0 RXD
+! P4 - P1.0 UCA0 TXD
+! P5 - P2.7
+! P6 - P8.0 SMCLK/A8
+! P7 - P5.1 UCB0 CLK
+! P8 - P2.5
+! P9 - P8.2 TA1CLK
+! P10- P8.3 TA1.2
+!
+! Launchpad Header Right J2
+! -------------------------
+! P1 - GND
+! P2 - P1.7 TA0.1/TDO/A7
+! P3 - P1.6 TA0.2/TDI/TCLK/A6
+! P4 - P5.0 UCB0STE
+! P5 - RST
+! P6 - P5.2 UCB0SIMO/UCB0SDA
+! P7 - P5.3 UCB0SOMI/UCB0SCL
+! P8 - P1.3 UCA0STE/A3
+! P9 - P1.4 MCLK/TCK/A4
+! P10- P1.5 TA0CLK/TMS/A5
+!
+! switch-keys:
+! S1 - P1.2
+! S2 - P2.6
+! S3 - RST
+!
+! LEDS:
+! LED1 - P1.0/TXD
+! LED2 - P4.0
+!
+! XTAL LF 32768 Hz
+! Y4 - P4.1 XIN
+! Y4 - P4.2 XOUT
+!
+! LCD
+! L0 - P7.0
+! L1 - P7.1
+! L2 - P7.2
+! L3 - P7.3
+! L4 - P7.4
+! L5 - P7.5
+! L6 - P7.6
+! L7 - P7.7
+! L8 - P3.0
+! L9 - P3.1
+! L10 - P3.2
+! L11 - P3.3
+! L12 - P3.4
+! L13 - P3.5
+! L14 - P3.6
+! L15 - P3.7
+! L16 - P6.0
+! L17 - P6.1
+! L18 - P6.2
+! L19 - P6.3
+! L20 - P6.4
+! L21 - P6.5
+! L22 - P6.6
+! L23 - P6.7
+! L24 - P2.0
+! L25 - P2.1
+! L26 - P2.2
+! L36 - P5.4
+! L37 - P5.5
+! L38 - P5.6
+! L39 - P5.7
+!
+!
+!
+!
+!
+!
+! ===================================================================================
+! in case of 3.3V powered by UARTtoUSB bridge, open J13 straps {RST,TST,V+,5V} BEFORE
+! then wire VCC and GND of bridge onto J13 connector
+! ===================================================================================
+!
+! ---------------------------------------------------
+! MSP - MSP-EXP430FR4133 LAUNCHPAD <--> OUTPUT WORLD
+! ---------------------------------------------------
+!
+! +-4k7-< DeepRST <-- GND
+! |
+! P1.0 - UCA0 TXD J101.8 --+-> RX UARTtoUSB bridge
+! P1.1 - UCA0 RXD J101.10 <---- TX UARTtoUSB bridge
+! P2.3 - RTS J101.14 ----> CTS UARTtoUSB bridge (if TERMINALCTSRTS option)
+! VCC - J101.16 <---- VCC (optional supply from UARTtoUSB bridge - WARNING ! 3.3V !)
+! GND - J101.20 <---> GND (optional supply from UARTtoUSB bridge)
+!
+! P1.0 - STRAP JP1 MUST BE REMOVED (LED red)
+! =========================
+!
+! P4.0 - LED green
+!
+! P1.2 - Switch SW1 <--- LCD contrast + (finger :-)
+! P2.6 - Switch SW2 <--- LCD contrast - (finger ;-)
+!
+!
+! GND - J1.2 <-------+---0V0----------> 1 LCD_Vss
+! VCC - J1.3 >------ | --3V6-----+----> 2 LCD_Vdd
+! | |
+! ___ 470n ---
+! ^ ---
+! / \ 1n4148 |
+! --- |
+! 100n | 2k2 |
+! P1.6 - TA0.2 J2.18 >---||--+--^/\/\/v--+----> 3 LCD_Vo (=0V6 without modulation)
+! P1.3 - J2.13 -------------------------> 4 LCD_RS
+! P1.4 - J2.12 -------------------------> 5 LCD_R/W
+! P1.5 - J2.11 -------------------------> 6 LCD_EN
+! P5.0 - J2.17 <------------------------> 11 LCD_DB4
+! P5.1 - J1.7 <------------------------> 12 LCD_DB5
+! P5.2 - J2.15 <------------------------> 13 LCD_DB5
+! P5.3 - J2.14 <------------------------> 14 LCD_DB7
+!
+!
+! P1.7 - J2.19 <---- OUT IR_Receiver (1 TSOP32236)
+!
+! P4.1 - LFXIN 32768Hz quartz
+! P4.2 - LFXOUT 32768Hz quartz
+!
+!
+!
+! P8.2 - Soft I2C_Master J1.9 ----> SDA software I2C Master
+! P8.3 - Soft I2C_Master J1.10 <---> SCL software I2C Master
+
+
+!LEDs
+!----
+invert LED numbers because LED1=TXD !
+LED2_OUT=\$202!
+LED2=\$01! P1.0 red LED
+LED1_OUT=\$223!
+LED1=\$01! P4.0 green LED
+
+!switches
+!--------
+SW1_IN=\$200!
+SW1=\$04! P1.2 SW1
+SW2_IN=\$201!
+SW2=\$40! P2.6 SW2
+
+!LCD Vo driver
+!-------------
+LCDVo_DIR=\$204! P1.6 = LCDVo
+LCDVo_SEL=\$20A! SEL0
+LCDVo=\$40!
+! FR4133 hasn't TB0: let TA0 addresses for TA0.2=LCDVo on P1.6
+TB0CTL=\$300!
+TB0CCTL2=\$306!
+TB0CCR0=\$312!
+TB0CCR2=\$316!
+TB0EX0=\$320!
+
+!LCD command bus
+!---------------
+LCD_CMD_IN=\$200!
+LCD_CMD_OUT=\$202!
+LCD_CMD_DIR=\$204!
+LCD_CMD_REN=\$206!
+LCD_RS=\$08! P1.3 LCD_RS
+LCD_RW=\$10! P1.4 LCD_RW
+LCD_EN=\$20! P1.5 LCD_EN
+LCD_CMD=\$38!
+
+!LCD data bus
+!------------
+LCD_DB_IN=\$240!
+LCD_DB_OUT=\$242!
+LCD_DB_DIR=\$244!
+LCD_DB_REN=\$246!
+LCD_DB=\$0F! P5.0-3 LCD_DATA_BUS
+
+!IR_RC5 input
+!------------
+IR_IN=\$200!
+IR_OUT=\$202!
+IR_DIR=\$204!
+IR_REN=\$206!
+IR_IES=\$218!
+IR_IE=\$21A!
+IR_IFG=\$21C!
+IR_Vec=\$FFE6! P1 int
+RC5=\$80! P1.7 IR_RC5
+! replace TA0 addrs by TA1 addrs because TA0 used for LCDVo
+TA0CTL=\$340!
+TA0CCTL2=\$346!
+TA0R=\$350!
+TA0CCR0=\$352!
+TA0CCR2=\$356!
+TA0EX0=\$360!
+
+
+I2CSM_IN=\$261!
+I2CSM_OUT=\$263!
+I2CSM_DIR=\$265!
+I2CSM_REN=\$267!
+SMSDA=\$04! P8.2 SDA software MASTER
+SMSCL=\$08! P8.3 SCL software MASTER
+SM_BUS=\$0C!
+
+I2CSMM_IN=\$261!
+I2CSMM_OUT=\$263!
+I2CSMM_DIR=\$265!
+I2CSMM_REN=\$267!
+SMMSDA=\$04! P8.2 SDA software MULTI_MASTER
+SMMSCL=\$08! P8.3 SCL software MULTI_MASTER
+SMM_BUS=\$0C!
+
+I2CMM_IN=\$240!
+I2CMM_OUT=\$242!
+I2CMM_DIR=\$244!
+I2CMM_REN=\$246!
+I2CMM_SEL=\$24A! SEL0
+I2CMM_Vec=\$FFEA!
+MMSDA=\$04! P5.2 SDA hadware MULTI_MASTER
+MMSCL=\$08! P5.3 SCL hadware MULTI_MASTER
+MM_BUS=\$0C!
+
+I2CM_IN=\$240!
+I2CM_OUT=\$242!
+I2CM_DIR=\$244!
+I2CM_REN=\$246!
+I2CM_SEL=\$24A! SEL0
+I2CM_Vec=\$FFEA!
+MSDA=\$04! P5.2 SDA hadware MASTER
+MSCL=\$08! P5.3 SCL hadware MASTER
+M_BUS=\$0C!
+
+I2CS_IN=\$240!
+I2CS_OUT=\$242!
+I2CS_DIR=\$244!
+I2CS_REN=\$246!
+I2CS_SEL=\$24A! SEL0
+I2CS_Vec=\$FFEA!
+SSDA=\$04! P5.2 SDA hadware SLAVE
+SSCL=\$08! P5.3 SCL hadware SLAVE
+S_BUS=\$0C!
+
--- /dev/null
+! -*- coding: utf-8 -*-
+! MSP_EXP430FR5739.pat
+!
+! Fast Forth For Texas Instrument MSP_EXP430FR5739
+!
+! Copyright (C) <2016> <J.M. THOORENS>
+!
+! This program is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! This program is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with this program. If not, see <http://www.gnu.org/licenses/>.
+!
+!
+!
+! ======================================================================
+! MSP430FR5739 Config
+! ======================================================================
+
+@define{@read{/config/gema/MSP430FR5739.pat}}
+@define{@read{/config/gema/MSP430FR57xx_FastForth.pat}}
+@define{@read{/config/gema/FastForthREGtoTI.pat}}
+@define{@read{/config/gema/RemoveComments.pat}}
+
+! ======================================================================
+! MSP_EXP430FR5739 board
+! ======================================================================
+
+! blue LEDs (Px.y ---> resistor ---> LED ---> GND)
+! PJ.0 - LED1
+! PJ.1 - LED2
+! PJ.2 - LED3
+! PJ.3 - LED4
+! P3.4 - LED5
+! P3.5 - LED6
+! P3.6 - LED7
+! P3.7 - LED8
+!
+! I/O pins on SV1:
+! P1.0 - SV1.1
+! P1.1 - SV1.2
+! P1.2 - SV1.3
+! P3.0 - SV1.4
+! P3.1 - SV1.5
+! P3.2 - SV1.6
+! P3.3 - SV1.7
+! P1.3 - SV1.8
+! P1.4 - SV1.9
+! P1.5 - SV1.10
+! P4.0 - SV1.11
+! GND - SV1.12
+!
+! I/O pins on SV2:
+! P1.7 - SV2.1
+! P1.6 - SV2.2
+! P3.7 - SV2.3
+! P3.6 - SV2.4
+! P3.5 - SV2.5
+! P3.4 - SV2.6
+! P2.2 - SV2.7
+! P2.1 - SV2.8
+! P2.6 - SV2.9
+! P2.5 - SV2.10
+! P2.0 - SV2.11
+! VCC - SV2.12
+!
+! I/O pins on RF:
+! GND - RF.1
+! VCC - RF.2
+! P2.0 - RF.3
+! P1.0 - RF.4
+! P2.6 - RF.5
+! P1.1 - RF.6
+! P2.5 - RF.7
+! P1.2 - RF.8
+! P2.7 - RF.9
+! P2.3 - RF.10
+! P4.0 - RF.11
+! GND - RF.12
+! P4.1 - RF.13
+! P2.4 - RF.14
+! P1.7 - RF.15
+! P2.2 - RF.16
+! P1.3 - RF.17
+! P1.6 - RF.18
+!
+! Accelerometer:
+! P2.7 - VS
+! P3.0 - XOUT
+! P3.1 - YOUT
+! P3.2 - ZOUT
+!
+! LDR and NTC:
+! P2.7 - VS
+! P3.3 - LDR
+! P1.4 - NTC
+!
+! RST - reset
+!
+! ======================================================================
+! MSP-EXP430FR5739 LAUNCHPAD <--> OUTPUT WORLD
+! ======================================================================
+!
+! P4.0 - Switch S1 <--- LCD contrast + (finger :-)
+! P4.1 - Switch S2 <--- LCD contrast - (finger :-)
+!
+! GND <-------+---0V0----------> 1 LCD_Vss
+! VCC >------ | --3V6-----+----> 2 LCD_Vdd
+! | |
+! |___ 470n ---
+! ^ | ---
+! / \ BAT54 |
+! --- |
+! 100n | 2k2 |
+! P1.5 - UCB0 CLK TB0.2 SV1.10 >---||--+--^/\/\/v--+----> 3 LCD_Vo (=0V6 without modulation)
+! P3.4 - SV2.6 -------------------------> 4 LCD_RS
+! P3.5 - SV2.5 -------------------------> 5 LCD_R/W
+! P3.6 - SV2.4 -------------------------> 6 LCD_EN
+! P1.0 - SV1.1 <------------------------> 11 LCD_DB4
+! P1.1 - SV1.2 <------------------------> 12 LCD_DB5
+! P1.2 - SV1.3 <------------------------> 13 LCD_DB5
+! P1.3 - SV1.8 <------------------------> 14 LCD_DB7
+!
+! PJ.4 - LFXI 32768Hz quartz
+! PJ.5 - LFXO 32768Hz quartz
+! PJ.6 - HFXI
+! PJ.7 - HFXO
+! +--4k7-< DeepRST <-- GND
+! |
+! P2.0 - UCA0 TXD SV2.11 --+-> RX UARTtoUSB bridge
+! P2.1 - UCA0 RXD SV2.8 <---- TX UARTtoUSB bridge
+! VCC - <---- VCC (optional supply from UARTtoUSB bridge - WARNING ! 3.3V !)
+! GND - <---> GND (optional supply from UARTtoUSB bridge)
+!
+! VCC - RF.2
+! VSS - RF.1
+! P2.2 - RF.16 <---- CD SD_CardAdapter (Card Detect)
+! P2.3 - RF.10 ----> CS SD_CardAdapter (Card Select)
+! P2.4 - UCA1 CLK RF.14 ----> CLK SD_CardAdapter (SCK)
+! P2.5 - UCA1 TXD/SIMO RF.7 ----> SDI SD_CardAdapter (MOSI)
+! P2.6 - UCA1 RXD/SOMI RF.5 <---- SDO SD_CardAdapter (MISO)
+!
+! P2.7 - RF.9 <---- OUT IR_Receiver (1 TSOP32236)
+!
+! P1.7 - UCB0 SCL/SOMI SV2.1 <---> SCL I2C MASTER/SLAVE
+! P1.6 - UCB0 SDA/SIMO SV2.2 <---> SDA I2C MASTER/SLAVE
+
+LED1_OUT=\$322!
+LED1=\$01! PJ.0
+
+LED2_OUT=\$322!
+LED2=\$02! PJ.1
+
+SW1_IN=\$221!
+SW1=\$01! P4.0
+
+SW2_IN=\$221!
+SW2=\$02! P4.1
+
+LCDVo_DIR=\$204!
+LCDVo_SEL=\$20A! SEL0
+LCDVo=\$20! P1.5
+
+LCD_CMD_IN=\$220!
+LCD_CMD_OUT=\$222!
+LCD_CMD_DIR=\$224!
+LCD_CMD_REN=\$226!
+LCD_RS=\$10! P3.4
+LCD_RW=\$20! P3.5
+LCD_EN=\$40! P3.6
+LCD_CMD=\$70!
+
+LCD_DB_IN=\$200!
+LCD_DB_OUT=\$202!
+LCD_DB_DIR=\$204!
+LCD_DB_REN=\$206!
+LCD_DB=\$0F! P1.0-3
+
+
+IR_IN=\$201!
+IR_OUT=\$203!
+IR_DIR=\$205!
+IR_REN=\$207!
+IR_IES=\$219!
+IR_IE=\$21B!
+IR_IFG=\$21D!
+RC5_=RC5_!
+RC5=\$40! P2.6
+IR_Vec=\$FFD8! P2 int
+
+I2CSM_IN=\$200!
+I2CSM_OUT=\$202!
+I2CSM_DIR=\$204!
+I2CSM_REN=\$206!
+SMSDA=\$40! P1.6
+SMSCL=\$80! P1.7
+SM_BUS=\$C0!
+
+I2CSMM_IN=\$200!
+I2CSMM_OUT=\$202!
+I2CSMM_DIR=\$204!
+I2CSMM_REN=\$206!
+SMMSDA=\$40! P1.6
+SMMSCL=\$80! P1.7
+SMM_BUS=\$C0!
+
+I2CMM_IN=\$200!
+I2CMM_OUT=\$202!
+I2CMM_DIR=\$204!
+I2CMM_REN=\$206!
+I2CMM_SEL=\$20C! SEL1
+I2CMM_Vec=\$FFEE!
+MMSDA=\$40! P1.6
+MMSCL=\$80! P1.7
+MM_BUS=\$C0!
+
+I2CM_IN=\$200!
+I2CM_OUT=\$202!
+I2CM_DIR=\$204!
+I2CM_REN=\$206!
+I2CM_SEL=\$20C!
+I2CM_Vec=\$FFEE!
+MSDA=\$40! P1.6
+MSCL=\$80! P1.7
+M_BUS=\$C0!
+
+I2CS_IN=\$200!
+I2CS_OUT=\$202!
+I2CS_DIR=\$204!
+I2CS_REN=\$206!
+I2CS_SEL=\$20C!
+I2CS_Vec=\$FFEE!
+SSDA=\$40! P1.6
+SSCL=\$80! P1.7
+S_BUS=\$C0!
+
--- /dev/null
+! -*- coding: utf-8 -*-
+! MSP_EXP430FR5969.pat
+!
+! Fast Forth For Texas Instrument MSP_EXP430FR5969
+!
+! Copyright (C) <2016> <J.M. THOORENS>
+!
+! This program is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! This program is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with this program. If not, see <http://www.gnu.org/licenses/>.
+!
+!
+!
+! ======================================================================
+! MSP430FR5969 Config
+! ======================================================================
+
+@define{@read{/config/gema/MSP430FR5969.pat}}
+@define{@read{/config/gema/MSP430FR5x6x_FastForth.pat}}
+@define{@read{/config/gema/FastForthREGtoTI.pat}}
+@define{@read{/config/gema/RemoveComments.pat}}
+
+! ======================================================================
+! MSP_EXP430FR5969 board
+! ======================================================================
+
+! J3: JTAG
+! --------
+! P1 - TDO - PJ.0
+! P2 - V_debug
+! P3 - TDI - PJ.1
+! P4 - V_ext
+! P5 - TMS - PJ.2
+! P6 - NC
+! P7 - TCK - PJ.3
+! P8 - TEST - TEST
+! P9 - GND
+! P10- CTS - P4.0
+! P11- RST - RESET
+! P12- TX0 - P2.0
+! P13- RTS - P4.1
+! P14- RX0 - P2.1
+
+! Launchpad Header Left J4
+! ------------------------
+! P1 - VCC
+! P2 - P4.2
+! P3 - P2.6 UCA1 RX/SOMI
+! P4 - P2.5 UCA1 TX/SIMO
+! P5 - P4.3
+! P6 - P2.4 UCA1 CLK
+! P7 - P2.2 TB0.2 UCB0CLK
+! P8 - P3.4
+! P9 - P3.5
+! P10- P3.6
+
+! Launchpad Header Right J5
+! -------------------------
+! P11- P1.3
+! P12- P1.4
+! P13- P1.5
+! P14- P1.6 UCB0 SIMO/SDA
+! P15- P1.7 UCB0 SOMI/SCL
+! P16- RST
+! P17- NC
+! P18- P3.0
+! P19- P1.2
+! P20- GND
+
+! J13 eZ-FET <=> target
+! ---------------------------
+! P1 P2 NC NC
+! P3 <-> P4 TEST <-> TEST
+! P5 <-> P6 RST <-> RST
+! P7 P8 TX0 P2.0 (no strap)
+! P9 P10 RX0 P2.1 (no strap)
+! P11 P12 CTS P4.0 (no strap)
+! P13 P14 RTS P4.1 (no strap)
+! P15<->P16 V+ <-> VCC
+! P17 P18 5V (no strap)
+! P19---P20 GND-----VSS
+
+! J21 : external target
+! ---------------------
+! P1 - RX0 - P2.1
+! P2 - VCC
+! P3 - TEST - TEST
+! P4 - RST - RST
+! P5 - GND
+! P6 - TX0 - P2.0
+
+
+! -----------------------------------------------
+! MSP430FR5969 LAUNCHPAD <--> OUTPUT WORLD
+! -----------------------------------------------
+
+! J13 jumpers : device <-> eZ-FET
+! -------------------------------
+! P2 P1 NC NC
+! P4<->P3 TEST <-> TEST
+! P6<->P5 RST <-> RST
+! P8 P7 P2.0 TX0 (no jumper)
+! P10 P9 P2.1 RX0 (no jumper)
+! P12 P11 P4.0 CTS (no jumper)
+! P14 P13 P4.1 RTS (no jumper)
+! P16<->P15 VCC <-> V+
+! P18 P17 5V 5V (no jumper)
+! P20---P19 VSS-----GND
+
+! P4.6 - J6 - LED1 red
+! P1.0 - LED2 green
+!
+! P4.5 - Switch S1 <--- LCD contrast + (finger :-)
+! P1.1 - Switch S2 <--- LCD contrast - (finger ;-)
+!
+! GND - J1.2 <-------+---0V0----------> 1 LCD_Vss
+! VCC - J1.3 >------ | --3V6-----+----> 2 LCD_Vdd
+! | |
+! ___ 470n ---
+! ^ ---
+! / \ 1n4148 |
+! --- |
+! 100n | 2k2 |
+! P2.2 - UCB0 CLK TB0.2 J4.7 >---||--+--^/\/\/v--+----> 3 LCD_Vo (=0V6 without modulation)
+! P3.4 - J4.8 -------------------------> 4 LCD_RS
+! P3.5 - J4.9 -------------------------> 5 LCD_R/W
+! P3.6 - J4.10 -------------------------> 6 LCD_EN
+! PJ.0 - J3.1 <------------------------> 11 LCD_DB4
+! PJ.1 - J3.3 <------------------------> 12 LCD_DB5
+! PJ.2 - J3.5 <------------------------> 13 LCD_DB5
+! PJ.3 - J3.7 <------------------------> 14 LCD_DB7
+!
+! +--4k7-< DeepRST <-- GND
+! |
+! P2.0 - UCA0 TXD J13.8 <-+-> RX UARTtoUSB bridge
+! P2.1 - UCA0 RXD J13.10 <---- TX UARTtoUSB bridge
+! P4.1 - RTS J13.14 ----> CTS UARTtoUSB bridge (optional hardware control flow)
+! VCC - J13.16 <---- VCC (optional supply from UARTtoUSB bridge - WARNING ! 3.3V !)
+! GND - J13.20 <---> GND (optional supply from UARTtoUSB bridge)
+!
+! VCC - J11.1 ----> VCC SD_CardAdapter
+! GND - J12.3 <---> GND SD_CardAdapter
+! P2.4 - UCA1 CLK J4.6 ----> CLK SD_CardAdapter (SCK)
+! P4.3 - J4.5 ----> CS SD_CardAdapter (Card Select)
+! P2.5 - UCA1 TXD/SIMO J4.4 ----> SDI SD_CardAdapter (MOSI)
+! P2.6 - UCA1 RXD/SOMI J4.3 <---- SDO SD_CardAdapter (MISO)
+! P4.2 - J4.2 <---- CD SD_CardAdapter (Card Detect)
+!
+! P4.0 - J3.10 <---- OUT IR_Receiver (1 TSOP32236)
+! VCC - J3.2 ----> VCC IR_Receiver (2 TSOP32236)
+! GND - J3.9 <---> GND IR_Receiver (3 TSOP32236)
+!
+! P1.2 - J5.19 <---> SDA I2C SOFTWARE MASTER
+! P1.3 - J5.11 <---> SCL I2C SOFTWARE MASTER
+! P1.4 - TB0.1 J5.12 <---> free
+! P1.5 - UCA0 CLK TB0.2 J5.13 <---> free
+! P1.7 - UCB0 SCL/SOMI J5.14 ----> SCL I2C MASTER/SLAVE
+! P1.6 - UCB0 SDA/SIMO J5.15 <---> SDA I2C MASTER/SLAVE
+! P3.0 - J5.7 <---- free
+!
+! PJ.4 - LFXI 32768Hz quartz
+! PJ.5 - LFXO 32768Hz quartz
+! PJ.6 - HFXI
+! PJ.7 - HFXO
+!
+! P2.3 - NC
+! P2.7 - NC
+! P3.1 - NC
+! P3.2 - NC
+! P3.3 - NC
+! P3.7 - NC
+! P4.4 - NC
+! P4.7 - NC
+
+SD_CDIN=\$221
+SD_CD=4! P4.2
+
+SD_CSOUT=\$223
+SD_CSDIR=\$225
+SD_CS=8! P4.3
+
+SD_SEL1=\$22D
+SD_REN=\$227
+SD_BUS=\$70
+
+LED1_OUT=\$223
+LED1=\$40! P4.6
+
+LED2_OUT=\$202
+lLED2=\$01! P1.0
+
+SW1_IN=\$221
+SW1=\$20! P4.5
+
+SW2_IN=\$200
+SW2=\$02! P1.1
+
+LCDVo_DIR=\$205! P2
+LCDVo_SEL=\$20B! SEL0
+LCDVo=\$04
+
+LCD_CMD_IN=\$220! P3
+LCD_CMD_OUT=\$222
+LCD_CMD_DIR=\$224
+LCD_CMD_REN=\$226
+LCD_RS=\$10
+LCD_RW=\$20
+LCD_EN=\$40
+LCD_CMD=\$70
+
+LCD_DB_IN=\$320! PJ
+LCD_DB_OUT=\$322
+LCD_DB_DIR=\$324
+LCD_DB_REN=\$326
+LCD_DB=\$0F
+
+
+IR_IN=\$221
+IR_OUT=\$223
+IR_DIR=\$225
+IR_REN=\$227
+IR_IES=\$239
+IR_IE=\$23B
+IR_IFG=\$23D
+IR_Vec=\$FFD0! P4 int
+RC5=\$01! P4.0
+
+I2CSM_IN=\$200
+I2CSM_OUT=\$202
+I2CSM_DIR=\$204
+I2CSM_REN=\$206
+SMSDA=\$04! P1.2
+SMSCL=\$08! P1.3
+SM_BUS=\$0C
+
+I2CSMM_IN=\$200
+I2CSMM_OUT=\$202
+I2CSMM_DIR=\$204
+I2CSMM_REN=\$206
+SMMSDA=\$04! P1.2
+SMMSCL=\$08! P1.3
+SMM_BUS=\$0C
+
+I2CMM_IN=\$200
+I2CMM_OUT=\$202
+I2CMM_DIR=\$204
+I2CMM_REN=\$206
+I2CMM_SEL=\$20C! SEL1
+I2CMM_Vec=\$FFEE! eUSCIB0_INT
+MMSDA=\$40! P1.6
+MMSCL=\$80! P1.7
+MM_BUS=\$C0
+
+I2CM_IN=\$200
+I2CM_OUT=\$202
+I2CM_DIR=\$204
+I2CM_REN=\$206
+I2CM_SEL=\$20C
+I2CM_Vec=\$FFEE! eUSCIB0_INT
+MSDA=\$40! P1.6
+MSCL=\$80! P1.7
+M_BUS=\$C0
+
+I2CS_IN=\$200
+I2CS_OUT=\$202
+I2CS_DIR=\$204
+I2CS_REN=\$206
+I2CS_SEL=\$20C
+I2CS_Vec=\$FFEE! eUSCIB0_INT
+SSDA=\$40! P1.6
+SSCL=\$80! P1.7
+S_BUS=\$C0
+
--- /dev/null
+! -*- coding: utf-8 -*-
+! MSP_EXP430FR5994.pat
+!
+! Fast Forth For Texas Instrument MSP_EXP430FR5994
+!
+! Copyright (C) <2016> <J.M. THOORENS>
+!
+! This program is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! This program is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with this program. If not, see <http://www.gnu.org/licenses/>.
+!
+!
+!
+! ======================================================================
+! MSP430FR5994 Config
+! ======================================================================
+
+@define{@read{/config/gema/MSP430FR5994.pat}}
+@define{@read{/config/gema/MSP430FR5x6x_FastForth.pat}}
+@define{@read{/config/gema/FastForthREGtoTI.pat}}
+@define{@read{/config/gema/RemoveComments.pat}}
+
+! ======================================================================
+! MSP_EXP430FR5994 board
+! ======================================================================
+
+! J101 Target <---> eZ-FET
+! GND 14-13 GND
+! +5V 12-11
+! 3V3 10-9
+! P2.1 UCA0_RX 8-7 <---- TX UARTtoUSB bridge
+! +--4k7-< DeepRST <-- GND
+! |
+! P2.0 UCA0_TX 6-5 <-+-> RX UARTtoUSB bridge
+! /RST 4-3
+! TEST 2-1
+
+
+! P5.6 - sw1 <--- LCD contrast + (finger :-)
+! P5.5 - sw2 <--- LCD contrast - (finger ;-)
+! RST - sw3
+
+! P1.0 - led1 red
+! P1.1 - led2 green
+
+! J1 - left ext.
+! 3v3
+! P1.2/TA1.1/TA0CLK/COUT/A2/C2 <--- OUT IR_Receiver (1 TSOP32236)
+! P6.1/UCA3RXD/UCA3SOMI -------------------------> 4 LCD_RS
+! P6.0/UCA3TXD/UCA3SIMO -------------------------> 5 LCD_R/W
+! P6.2/UCA3CLK -------------------------> 6 LCD_EN0
+! P1.3/TA1.2/UCB0STE/A3/C3
+! P5.2/UCB1CLK/TA4CLK
+! P6.3/UCA3STE
+! P7.1/UCB2SOMI/UCB2SCL ---> SCL I2C MASTER/SLAVE
+! P7.0/UCB2SIMO/UCB2SDA <--> SDA I2C MASTER/SLAVE
+
+! J3 - left int.
+! 5V
+! GND
+! P3.0/A12/C12 <------------------------> 11 LCD_DB4
+! P3.1/A13/C13 <------------------------> 12 LCD_DB5
+! P3.2/A14/C14 <------------------------> 13 LCD_DB5
+! P3.3/A15/C15 <------------------------> 14 LCD_DB7
+! P1.4/TB0.1/UCA0STE/A4/C4
+! P1.5/TB0.2/UCA0CLK/A5/C5 >---||--+--^/\/\/v--+----> 3 LCD_Vo (=0V6 without modulation)
+! P4.7
+! P8.0
+
+! J4 - right int.
+! P3.7/TB0.6
+! P3.6/TB0.5
+! P3.5/TB0.4/COUT
+! P3.4/TB0.3/SMCLK
+! P7.3/UCB2STE/TA4.1 RTS ----> CTS UARTtoUSB bridge (optional hardware control flow)
+! P2.6/TB0.1/UCA1RXD/UCA1SOMI
+! P2.5/TB0.0/UCA1TXD/UCA1SIMO
+! P4.3/A11
+! P4.2/A10
+! P4.1/A9
+
+! J2 - right ext.
+! GND
+! P5.7/UCA2STE/TA4.1/MCLK
+! P4.4/TB0.5
+! P5.3/UCB1STE
+! /RST
+! P5.0/UCB1SIMO/UCB1SDA
+! P5.1/UCB1SOMI/UCB1SCL
+! P8.3
+! P8.2 <--> SDA I2C SOFTWARE MASTER
+! P8.1 <--> SCL I2C SOFTWARE MASTER
+
+
+! SD_CARD
+! P7.2/UCB2CLK <--- SD_CD
+! P1.6/TB0.3/UCB0SIMO/UCB0SDA/TA0.0 ---> SD_MOSI
+! P1.7/TB0.4/UCB0SOMI/UCB0SCL/TA1.0 <--- SD_MISO
+! P4.0/A8 ---> SD_CS
+! P2.2/TB0.2/UCB0CLK ---> SD_CLK
+
+
+
+! XTAL LF 32768 Hz
+! PJ.4/LFXIN
+! PJ.5/LFXOUT
+
+! XTAL HF
+! PJ.6/HFXIN
+! PJ.7/HFXOUT
+
+! -----------------------------------------------
+! LCD config
+! -----------------------------------------------
+
+! <-------+---0V0----------> 1 LCD_Vss
+! >------ | --3V6-----+----> 2 LCD_Vdd
+! | |
+! |___ 470n ---
+! ^ | ---
+! / \ BAT54 |
+! --- |
+! 100n | 2k2 |
+! TB0.2 >---||--+--^/\/\/v--+----> 3 LCD_Vo (=0V6 without modulation)
+! -------------------------> 4 LCD_RS
+! -------------------------> 5 LCD_R/W
+! -------------------------> 6 LCD_EN0
+! <------------------------> 11 LCD_DB4
+! <------------------------> 12 LCD_DB5
+! <------------------------> 13 LCD_DB5
+! <------------------------> 14 LCD_DB7
+
+
+
+
+LED1_OUT=\$202!
+led1=1! P1.0
+
+LED2_OUT=\$202!
+led2=2! P1.1
+
+SW1_IN=\$240!
+SW1=\$40! P5.6
+
+SW2_IN=\$240!
+SW2=\$20! P5.5
+
+LCDVo_DIR=\$204!
+LCDVo_SEL=\$20A! SEL0
+LCDVo=\$20! P1.5
+
+LCD_CMD_IN=\$241!
+LCD_CMD_OUT=\$243!
+LCD_CMD_DIR=\$245!
+LCD_CMD_REN=\$247!
+LCD_RS=2! P6.1
+LCD_RW=1! P6.0
+LCD_EN=4! P6.2
+LCD_CMD=7!
+
+LCD_DB_IN=\$220!
+LCD_DB_OUT=\$222!
+LCD_DB_DIR=\$224!
+LCD_DB_REN=\$226!
+LCD_DB=\$0F! P3.3210
+
+
+IR_IN=\$200!
+IR_OUT=\$202!
+IR_DIR=\$204!
+IR_REN=\$206!
+IR_IES=\$208!
+IR_IE=\$20A!
+IR_IFG=\$20C!
+IR_Vec=\$FFDE! P1 int
+RC5_=RC5_!
+RC5=4! P1.2
+
+
+SD_CS=1! P4.0
+SD_CSIN=\$221!
+
+SD_CD=4! P7.2
+SD_CDIN=\$260!
+
+I2CSM_IN=\$261!
+I2CSM_OUT=\$263!
+I2CSM_DIR=\$265!
+I2CSM_REN=\$267!
+SMSDA=4! P8.2
+SMSCL=2! P8.1
+SM_BUS=6!
+
+I2CSMM_IN=\$261!
+I2CSMM_OUT=\$263!
+I2CSMM_DIR=\$265!
+I2CSMM_REN=\$267!
+SMMSDA=4! P8.2
+SMMSCL=2! P8.1
+SMM_BUS=6!
+
+I2CMM_IN=\$260!
+I2CMM_OUT=\$262!
+I2CMM_DIR=\$264!
+I2CMM_REN=\$266!
+I2CMM_SEL1=\$26C!
+I2CMM_Vec=\$FFBC! UCB2_Vec
+MMSDA=1! P7.0
+MMSCL=2! P7.1
+MM_BUS=3!
+
+I2CM_IN=\$260!
+I2CM_OUT=\$262!
+I2CM_DIR=\$264!
+I2CM_REN=\$266!
+I2CM_SEL1=\$26C!
+I2CM_Vec=\$FFBC!
+MSDA=1! P7.0
+MSCL=2! P7.1
+M_BUS=3!
+
+I2CS_IN=\$260!
+I2CS_OUT=\$262!
+I2CS_DIR=\$264!
+I2CS_REN=\$266!
+I2CS_SEL1=\$26C!
+I2CS_Vec=\$FFBC!
+SSDA=1! P7.0
+SSCL=2! P7.1
+S_BUS=3!
+
--- /dev/null
+! -*- coding: utf-8 -*-
+! MSP_EXP430FR6989.pat
+!
+! Fast Forth For Texas Instrument MSP_EXP430FR6989
+!
+! Copyright (C) <2016> <J.M. THOORENS>
+!
+! This program is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! This program is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with this program. If not, see <http://www.gnu.org/licenses/>.
+!
+!
+!
+! ======================================================================
+! MSP430FR6989 Config
+! ======================================================================
+
+@define{@read{/config/gema/MSP430FR6989.pat}}
+@define{@read{/config/gema/MSP430FR5x6x_FastForth.pat}}
+@define{@read{/config/gema/FastForthREGtoTI.pat}}
+@define{@read{/config/gema/RemoveComments.pat}}
+
+! ======================================================================
+! MSP_EXP430FR6989 board
+! ======================================================================
+
+! ---------------------------------------------------
+! MSP - MSP-EXP430FR6989 LAUNCHPAD <--> OUTPUT WORLD
+! ---------------------------------------------------
+! P1.0 - LED1 red
+! P9.7 - LED2 green
+!
+! P1.1 - Switch S1 <--- LCD contrast + (finger :-)
+! P1.2 - Switch S2 <--- LCD contrast - (finger ;-)
+!
+! note : ESI1.1 = lowest left pin
+! note : ESI1.2 is not connected to 3.3V
+! GND J6.2 <-------+---0V0----------> 1 LCD_Vss
+! VCC J6.1 >------ | --3V3-----+----> 2 LCD_Vdd
+! | |
+! |___ 470n ---
+! ^ | ---
+! / \ BAT54 |
+! --- |
+! 100n | 2k2 |
+! P3.6 - UCA1 CLK TB0.2 J4.37 >---||--+--^/\/\/v--+----> 3 LCD_Vo (=0V6 without modulation)
+! P9.0/ESICH0 - ESI1.14 <------------------------> 11 LCD_DB4 brown
+! P9.1/ESICH1 - ESI1.13 <------------------------> 12 LCD_DB5 red
+! P9.2/ESICH2 - ESI1.12 <------------------------> 13 LCD_DB5 orange
+! P9.3/ESICH3 - ESI1.11 <------------------------> 14 LCD_DB7 yellow
+! P4.1 -------------------------> 4 LCD_RS yellow
+! P4.2 -------------------------> 5 LCD_R/W green
+! P4.3 -------------------------> 6 LCD_EN blue
+!
+! +--4k7-< DeepRST <-- GND
+! |
+! P3.4 - UCA1 TXD J101.8 <-+-> RX UARTtoUSB bridge
+! P3.5 - UCA1 RXD J101.10 <---- TX UARTtoUSB bridge
+! P3.0 - RTS J101.14 ----> CTS UARTtoUSB bridge (optional hardware control flow)
+! VCC - J101.16 <---- VCC (optional supply from UARTtoUSB bridge - WARNING ! 3.3V !)
+! GND - J101.20 <---> GND (optional supply from UARTtoUSB bridge)
+!
+! VCC - J1.1 ----> VCC SD_CardAdapter
+! GND - J2.20 <---> GND SD_CardAdapter
+! P2.2 - UCA0 CLK J4.35 ----> CLK SD_CardAdapter (SCK)
+! P2.6 - J4.39 ----> CS SD_CardAdapter (Card Select)
+! P2.0 - UCA0 TXD/SIMO J1.8 ----> SDI SD_CardAdapter (MOSI)
+! P2.1 - UCA0 RXD/SOMI J2.19 <---- SDO SD_CardAdapter (MISO)
+! P2.7 - J4.40 <---- CD SD_CardAdapter (Card Detect)
+!
+! P4.0 - J1.10 <---- OUT IR_Receiver (1 TSOP32236)
+! VCC - J1.1 ----> VCC IR_Receiver (2 TSOP32236)
+! GND - J2.20 <---> GND IR_Receiver (3 TSOP32236)
+!
+! P1.3 - J4.34 <---> SDA software I2C Master
+! P1.5 - J2.18 ----> SCL software I2C Master
+!
+! P1.4 -UCB0 CLK TA1.0 J1.7 <---> free
+!
+! P1.6 -UCB0 SDA/SIMO J2.15 <---> SDA hardware I2C Master or Slave
+! P1.7 -UCB0 SCL/SOMI J2.14 ----> SCL hardware I2C Master or Slave
+!
+! P3.0 -UCB1 CLK J4.33 ----> free (if UARTtoUSB with software control flow)
+! P3.1 -UCB1 SDA/SIMO J4.32 <---> free
+! P3.2 -UCB1 SCL/SOMI J1.5 ----> free
+! P3.3 - TA1.1 J1.5 <---> free
+!
+! PJ.4 - LFXI 32768Hz quartz
+! PJ.5 - LFXO 32768Hz quartz
+! PJ.6 - HFXI
+! PJ.7 - HFXO
+
+
+LED1_OUT=\$202!
+LED1=1! P1.0
+
+LED2_OUT=\$282!
+LED2=\$80! P9.7
+
+SW1_IN=\$200!
+SW1=2! P1.1
+
+SW2_IN=\$200!
+SW2=4! P1.2
+
+LCDVo_DIR=\$224!
+LCDVo_SEL=\$22C! SEL1
+LCDVo=\$40! P3.6
+
+LCD_CMD_IN=\$221!
+LCD_CMD_OUT=\$223!
+LCD_CMD_DIR=\$225!
+LCD_CMD_REN=\$227!
+LCD_RS=2! P4.1
+LCD_RW=4! P4.2
+LCD_EN=8! P4.3
+LCD_CMD=\$0E!
+
+LCD_DB_IN=\$280!
+LCD_DB_OUT=\$282!
+LCD_DB_DIR=\$284!
+LCD_DB_REN=\$286!
+LCD_DB=\$0F! P9.3-0
+
+
+IR_IN=\$221!
+IR_OUT=\$223!
+IR_DIR=\$225!
+IR_REN=\$227!
+IR_IES=\$239!
+IR_IE=\$23B!
+IR_IFG=\$23D!
+RC5_=RC5_!
+RC5=1! P4.0
+IR_Vec=\$FFCC! P4 int
+
+I2CSM_IN=\$200!
+I2CSM_OUT=\$202!
+I2CSM_DIR=\$204!
+I2CSM_REN=\$206!
+SMSDA=8! P1.3
+SMSCL=\$20! P1.5
+SM_BUS=\$28!
+
+I2CSMM_IN=\$200!
+I2CSMM_OUT=\$202!
+I2CSMM_DIR=\$204!
+I2CSMM_REN=\$206!
+SMMSDA=8! P1.3
+SMMSCL=\$20! P1.5
+SMM_BUS=\$28!
+
+I2CMM_IN=\$200!
+I2CMM_OUT=\$202!
+I2CMM_DIR=\$204!
+I2CMM_REN=\$206!
+I2CMM_SEL=\$20C! SEL1
+I2CMM_Vec=\$FFEC!
+MMSDA=\$40! P1.6
+MMSCL=\$80! P1.7
+MM_BUS=\$C0!
+
+I2CM_IN=\$200!
+I2CM_OUT=\$202!
+I2CM_DIR=\$204!
+I2CM_REN=\$206!
+I2CM_SEL=\$20C!
+I2CM_Vec=\$FFEC!
+MSDA=\$40! P1.6
+MSCL=\$80! P1.7
+M_BUS=\$C0!
+
+I2CS_IN=\$200!
+I2CS_OUT=\$202!
+I2CS_DIR=\$204!
+I2CS_REN=\$206!
+I2CS_SEL=\$20C!
+I2CS_Vec=\$FFEC!
+SSDA=\$40! P1.6
+SSCL=\$80! P1.7
+S_BUS=\$C0!
+
--- /dev/null
+\ PRIMES.4th
+
+PWR_STATE
+: PRIMES
+\ 2 SWAP 2 . 3 . 5
+ 2 SWAP 2 4 U.R 3 4 U.R 5
+ DO DUP DUP * I
+ < IF 1+ THEN
+ 1 OVER 1+ 3
+ DO J I MOD
+ 0= IF 1- LEAVE THEN
+ 2 +LOOP
+\ IF I . THEN
+ IF I 4 U.R THEN
+ 2 +LOOP
+ DROP ;
+
+\ 1000 PRIMES : display prime numbers up to 1000
+\ FAST FORTH for MSP430FR5969 @16MHz + TERATERM @921600Bds : 0.13 s
+
+: TEST \ 1.3s @ 16 MHz
+10 0 DO
+ CR
+ 1000 PRIMES
+LOOP ;
+
+TEST
\ No newline at end of file
--- /dev/null
+; -----------------------------------
+; prog100k.4th, to test speed of downloading
+; -----------------------------------
+ \
+WIPE
+NOECHO ; if an error occurs during download, comment this line then download again
+ \
+\ Copyright (C) <2016> <J.M. THOORENS>
+\
+\ This program is free software: you can redistribute it and/or modify
+\ it under the terms of the GNU General Public License as published by
+\ the Free Software Foundation, either version 3 of the License, or
+\ (at your option) any later version.
+\
+\ This program is distributed in the hope that it will be useful,
+\ but WITHOUT ANY WARRANTY\ without even the implied warranty of
+\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+\ GNU General Public License for more details.
+\
+\ You should have received a copy of the GNU General Public License
+\ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+\ ===========================================================================
+\ remember: for good downloading to target, all lines must be ended with CR+LF !
+\ ===========================================================================
+
+
+\ REGISTERS USAGE
+\ R4 to R7 must be saved before use and restored after
+\ scratch registers Y to S are free for use
+\ under interrupt, IP is free for use
+
+\ PUSHM order : PSP,TOS, IP, S, T, W, X, Y, R7, R6, R5, R4
+\ example : PUSHM IP,Y
+\
+\ POPM order : R4, R5, R6, R7, Y, X, W, T, S, IP,TOS,PSP
+\ example : POPM Y,IP
+
+\ ASSEMBLER conditionnal usage after IF UNTIL WHILE : S< S>= U< U>= 0= 0<> 0>=
+\ ASSEMBLER conditionnal usage before ?JMP ?GOTO : S< S>= U< U>= 0= 0<> 0<
+
+\ FORTH conditionnal : 0= 0< = < > U<
+
+\ display on a LCD 2x20 CHAR the code sent by an IR remote under philips RC5 protocol
+\ target : any TI MSP-EXP430FRxxxx launchpad (FRAM)
+\ LPM_MODE = LPM0 because use SMCLK for LCDVo
+
+\ DEMO : driver for IR remote compatible with the PHILIPS RC5 protocol
+\ plus : driver for 5V LCD 2x20 characters display with 4 bits data interface
+\ without usage of an auxiliary 5V to feed the LCD_Vo
+\ and without potentiometer to adjust the LCD contrast :
+\ to adjust LCD contrast, just press S1 (-) or S2 (+)
+\ LCDVo current consumption ~ 500 uA.
+
+\ ===================================================================================
+\ notice : adjust TA0EX0,TB0CTL,TB0EX0 and 20_us to the target frequency if <> 8MHz !
+\ ===================================================================================
+
+
+\ layout : I/O are defined in the launchpad.pat file (don't work with ChipStick_FR2433)
+
+\ GND <-------+---0V0----------> 1 LCD_Vss
+\ VCC >------ | --3V6-----+----> 2 LCD_Vdd
+\ | |
+\ ___ 470n ---
+\ ^ ---
+\ / \ 1N4148 |
+\ --- |
+\ 100n | 2k2 |
+\ TB0.2 >---||--+--^/\/\/v--+----> 3 LCD_Vo (= 0V6 without modulation)
+\ -------------------------> 4 LCD_RW
+\ -------------------------> 5 LCD_RW
+\ -------------------------> 6 LCD_EN
+\ <------------------------> 11 LCD_DB4
+\ <------------------------> 12 LCD_DB5
+\ <------------------------> 13 LCD_DB5
+\ <------------------------> 14 LCD_DB7
+
+\ <----- LCD contrast + <--- Sw1 <--- (finger) :-)
+\ <----- LCD contrast - <--- Sw2 <--- (finger) :-)
+
+\ rc5 <--- OUT IR_Receiver (1 TSOP32236)
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+RST_STATE ;
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+
+ECHO
+ ; download is done
+RST_HERE ; this app is protected against <reset>,
+\ START
--- /dev/null
+; -----------------------------------
+; prog10k.4th
+; -----------------------------------
+ \
+PWR_STATE
+\ NOECHO ; if an error occurs during download, comment this line then download again
+ \
+\ Copyright (C) <2016> <J.M. THOORENS>
+\
+\ This program is free software: you can redistribute it and/or modify
+\ it under the terms of the GNU General Public License as published by
+\ the Free Software Foundation, either version 3 of the License, or
+\ (at your option) any later version.
+\
+\ This program is distributed in the hope that it will be useful,
+\ but WITHOUT ANY WARRANTY\ without even the implied warranty of
+\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+\ GNU General Public License for more details.
+\
+\ You should have received a copy of the GNU General Public License
+\ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+\ ===========================================================================
+\ remember: for good downloading to target, all lines must be ended with CR+LF !
+\ ===========================================================================
+
+
+\ REGISTERS USAGE
+\ R4 to R7 must be saved before use and restored after
+\ scratch registers Y to S are free for use
+\ under interrupt, IP is free for use
+
+\ PUSHM order : PSP,TOS, IP, S, T, W, X, Y, R7, R6, R5, R4
+\ example : PUSHM IP,Y
+\
+\ POPM order : R4, R5, R6, R7, Y, X, W, T, S, IP,TOS,PSP
+\ example : POPM Y,IP
+
+\ ASSEMBLER conditionnal usage after IF UNTIL WHILE : S< S>= U< U>= 0= 0<> 0>=
+\ ASSEMBLER conditionnal usage before ?JMP ?GOTO : S< S>= U< U>= 0= 0<> 0<
+
+\ FORTH conditionnal : 0= 0< = < > U<
+
+\ display on a LCD 2x20 CHAR the code sent by an IR remote under philips RC5 protocol
+\ target : any TI MSP-EXP430FRxxxx launchpad (FRAM)
+\ LPM_MODE = LPM0 because use SMCLK for LCDVo
+
+\ DEMO : driver for IR remote compatible with the PHILIPS RC5 protocol
+\ plus : driver for 5V LCD 2x20 characters display with 4 bits data interface
+\ without usage of an auxiliary 5V to feed the LCD_Vo
+\ and without potentiometer to adjust the LCD contrast :
+\ to adjust LCD contrast, just press S1 (-) or S2 (+)
+\ LCDVo current consumption ~ 500 uA.
+
+\ ===================================================================================
+\ notice : adjust TA0EX0,TB0CTL,TB0EX0 and 20_us to the target frequency if <> 8MHz !
+\ ===================================================================================
+
+
+\ layout : I/O are defined in the launchpad.pat file (don't work with ChipStick_FR2433)
+
+\ GND <-------+---0V0----------> 1 LCD_Vss
+\ VCC >------ | --3V6-----+----> 2 LCD_Vdd
+\ | |
+\ ___ 470n ---
+\ ^ ---
+\ / \ 1N4148 |
+\ --- |
+\ 100n | 2k2 |
+\ TB0.2 >---||--+--^/\/\/v--+----> 3 LCD_Vo (= 0V6 without modulation)
+\ -------------------------> 4 LCD_RW
+\ -------------------------> 5 LCD_RW
+\ -------------------------> 6 LCD_EN
+\ <------------------------> 11 LCD_DB4
+\ <------------------------> 12 LCD_DB5
+\ <------------------------> 13 LCD_DB5
+\ <------------------------> 14 LCD_DB7
+
+\ <----- LCD contrast + <--- Sw1 <--- (finger) :-)
+\ <----- LCD contrast - <--- Sw2 <--- (finger) :-)
+
+\ rc5 <--- OUT IR_Receiver (1 TSOP32236)
+
+
+PWR_STATE
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+PWR_STATE
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+
+PWR_STATE
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+
+PWR_STATE
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+
+PWR_STATE
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+
+PWR_STATE
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+
+PWR_STATE
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+
+PWR_STATE
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+
+PWR_STATE
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+
+PWR_STATE
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+
+PWR_STATE
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+
+
+ECHO
+ ; download is done
+PWR_HERE ; this app is protected against power ON/OFF,
+\ START
--- /dev/null
+; -----------------------------------
+; RC5toLCD.4th
+; -----------------------------------
+ \
+RST_STATE ;
+\ NOECHO ; if an error occurs during download, comment this line then download again
+ \
+\ Copyright (C) <2016> <J.M. THOORENS>
+\
+\ This program is free software: you can redistribute it and/or modify
+\ it under the terms of the GNU General Public License as published by
+\ the Free Software Foundation, either version 3 of the License, or
+\ (at your option) any later version.
+\
+\ This program is distributed in the hope that it will be useful,
+\ but WITHOUT ANY WARRANTY\ without even the implied warranty of
+\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+\ GNU General Public License for more details.
+\
+\ You should have received a copy of the GNU General Public License
+\ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+\ ===========================================================================
+\ remember: for good downloading to target, all lines must be ended with CR+LF !
+\ ===========================================================================
+
+
+\ REGISTERS USAGE
+\ R4 to R7 must be saved before use and restored after
+\ scratch registers Y to S are free for use
+\ under interrupt, IP is free for use
+
+\ PUSHM order : PSP,TOS, IP, S, T, W, X, Y, R7, R6, R5, R4
+\ example : PUSHM IP,Y
+\
+\ POPM order : R4, R5, R6, R7, Y, X, W, T, S, IP,TOS,PSP
+\ example : POPM Y,IP
+
+\ ASSEMBLER conditionnal usage after IF UNTIL WHILE : S< S>= U< U>= 0= 0<> 0>=
+\ ASSEMBLER conditionnal usage before ?JMP ?GOTO : S< S>= U< U>= 0= 0<> 0<
+
+\ FORTH conditionnal : 0= 0< = < > U<
+
+\ display on a LCD 2x20 CHAR the code sent by an IR remote under philips RC5 protocol
+\ target : any TI MSP-EXP430FRxxxx launchpad (FRAM)
+\ LPM_MODE = LPM0 because use SMCLK for LCDVo
+
+\ DEMO : driver for IR remote compatible with the PHILIPS RC5 protocol
+\ plus : driver for 5V LCD 2x20 characters display with 4 bits data interface
+\ without usage of an auxiliary 5V to feed the LCD_Vo
+\ and without potentiometer to adjust the LCD contrast :
+\ to adjust LCD contrast, just press S1 (-) or S2 (+)
+\ LCDVo current consumption ~ 500 uA.
+
+\ ===================================================================================
+\ notice : adjust TA0EX0,TB0CTL,TB0EX0 and 20_us to the target frequency if <> 8MHz !
+\ ===================================================================================
+
+
+\ layout : I/O are defined in the launchpad.pat file (don't work with ChipStick_FR2433)
+
+\ GND <-------+---0V0----------> 1 LCD_Vss
+\ VCC >------ | --3V6-----+----> 2 LCD_Vdd
+\ | |
+\ ___ 470n ---
+\ ^ ---
+\ / \ 1N4148 |
+\ --- |
+\ 100n | 2k2 |
+\ TB0.2 >---||--+--^/\/\/v--+----> 3 LCD_Vo (= 0V6 without modulation)
+\ -------------------------> 4 LCD_RW
+\ -------------------------> 5 LCD_RW
+\ -------------------------> 6 LCD_EN
+\ <------------------------> 11 LCD_DB4
+\ <------------------------> 12 LCD_DB5
+\ <------------------------> 13 LCD_DB5
+\ <------------------------> 14 LCD_DB7
+
+\ <----- LCD contrast + <--- Sw1 <--- (finger) :-)
+\ <----- LCD contrast - <--- Sw2 <--- (finger) :-)
+
+\ rc5 <--- OUT IR_Receiver (1 TSOP32236)
+
+
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE 20_US \ n -- n * 20 us
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+CODE TOP_LCD \ LCD Sample
+\ \ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND.B #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE LCD_W \ byte -- write byte to LCD
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+COLON \ high level word starts here
+ TOP_LCD 2 20_US \ write high nibble first
+ TOP_LCD 2 20_US
+;
+ \
+
+CODE LCD_WrC \ char -- Write Char
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+
+CODE LCD_WrF \ func -- Write Fonction
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us \ $01 LCD_WrF 80 20_us ==> bad init !
+;
+ \
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+ \
+
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ CODE LCD_R \ -- byte read byte from LCD
+\ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+\ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+\ COLON \ starts a FORTH word
+\ TOP_LCD 2 20_us \ -- %0000HHHH
+\ TOP_LCD 2 20_us \ -- %0000HHHH %0000LLLL
+\ HI2LO \ switch from FORTH to assembler
+\ RLAM #4,0(PSP) \ -- %HHHH0000 %0000LLLL
+\ ADD.B @PSP+,TOS \ -- %HHHHLLLL
+\ MOV @RSP+,IP \ restore IP saved by COLON
+\ MOV @IP+,PC \
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdS \ -- status Read Status
+\ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ CODE LCD_RdC \ -- char Read Char
+\ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+\ JMP LCD_R
+\ ENDCODE
+\ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+
+\ ******************************\
+ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR to force fall down to LPM mode
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #38,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM RC5_INT \ wake up on Px.RC5 change interrupt
+\ ******************************\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : BASE,TOS,IP,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+BIC #$F8,0(RSP) \ CPU is ON and GIE is OFF in retiSR to force fall down to LPM0_LOOP
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+BIC #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old UF1 = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, UserFlag1 = SR(9) = 1
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+SUB #4,PSP \
+MOV &BASE,2(PSP) \ save variable BASE before use
+MOV TOS,0(PSP) \ save TOS before use
+MOV.B IP,TOS \ TOS = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,TOS \ TOS = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #$4000,IP \ test /C6 bit in IP
+0= IF BIS #$40,TOS \ set C6 bit in S
+THEN \ TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+
+\ ------------------------------\
+\ Display IR_RC5 code \
+\ ------------------------------\
+\ BIS.B #LED1,&LED1_OUT \ switch ON LED1, comment if no LED
+\ ------------------------------\
+LO2HI \ switch from assembler to FORTH
+ ['] LCD_CLEAR IS CR \ redirects CR
+ ['] LCD_WrC IS EMIT \ redirects EMIT
+ $10 BASE ! \ change BASE to hexadecimal
+ CR ." $" 2 U.R \ print IR_RC5 code
+ ['] (CR) IS CR \ restore CR
+ ['] (EMIT) IS EMIT \ restore EMIT
+HI2LO \ switch from FORTH to assembler
+\ ------------------------------\
+\ BIC.B #LED1,&LED1_OUT \ switch OFF LED1, comment if no LED
+\ ------------------------------\
+MOV @PSP+,&BASE \ restore variable BASE
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up to TB0CCR0
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate PWM for LCD_Vo
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL \ SEL.2 TB0.2
+\ ------------------------------\
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+ BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+ MOV #$5A5E,&WDTCTL \ init WDT VLOCLK source ~10kHz /2^9 (50 ms), interval mode
+\ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init RC5_Int \
+\ ------------------------------\
+ BIS.B #RC5,&IR_IE \ enable RC5_Int
+ BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_INT,&WDT_Vec \ init WDT interval vector interrupt
+ MOV #RC5_INT,&IR_Vec \ init interrupt vector
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+
+LO2HI \ no need to push IP because (WARM) resets the Return Stack !
+
+\ ------------------------------\
+\ Init LCD 2x20 \
+\ ------------------------------\
+ $03E8 20_US \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_US \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ $5 20_US \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ $2 20_US \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ $2 20_US \ wait 40 us = LCD cycle
+ $28 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+ LIT RECURSE IS WARM \ insert this START routine between WARM and (WARM)...
+ (WARM) \ ...and continue with (WARM) (very, very usefull after COLD or RESET !:-)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+
+
+ECHO
+ ; download is done
+RST_HERE ; this app is protected against <reset>,
+\ START
--- /dev/null
+; --------------------
+; RTC_B.f
+; --------------------
+
+\ Copyright (C) <2016> <J.M. THOORENS>
+\
+\ This program is free software: you can redistribute it and/or modify
+\ it under the terms of the GNU General Public License as published by
+\ the Free Software Foundation, either version 3 of the License, or
+\ (at your option) any later version.
+\
+\ This program is distributed in the hope that it will be useful,
+\ but WITHOUT ANY WARRANTY; without even the implied warranty of
+\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+\ GNU General Public License for more details.
+\
+\ You should have received a copy of the GNU General Public License
+\ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+\ REGISTERS USAGE
+\ R4 to R7 must be saved before use and restored after
+\ scratch registers Y to S are free for use
+\ under interrupt, IP is free for use
+
+\ PUSHM order : PSP,TOS, IP, S, T, W, X, Y, R7, R6, R5, R4
+\ example : PUSHM IP,Y
+\
+\ POPM order : R4, R5, R6, R7, Y, X, W, T, S, IP,TOS,PSP
+\ example : POPM Y,IP
+
+\ ASSEMBLER conditionnal usage after IF UNTIL WHILE : S< S>= U< U>= 0= 0<> 0>=
+\ ASSEMBLER conditionnal usage before GOTO ?GOTO : S< S>= U< U>= 0= 0<> <0
+
+\ FORTH conditionnal usage after IF UNTIL WHILE : 0= 0< = < > U<
+
+
+
+\ routines RTC for MSP430fr5xxx and MSP430FR6xxx families
+\ target must have a LF_XTAL 32768Hz.
+
+\ compile DTCforthMSP430FR5xxx.asm with the switch LF_XTAL set to ON (uncommment the line).
+
+\ use :
+\ to set date, type : dd mm yyyy DATE!
+\ to view date, type DATE?
+\ to set time, type : hh mm ss TIME!, or hh mm TIME!
+\ to view time, type TIME?
+
+\ allow to write on a SD_Card file with a valid date and a valid time
+
+\ ECHO ; if an error occurs during download, uncomment this line then download again
+
+ \
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+CODE DATE?
+ SUB #6,PSP
+ MOV TOS,4(PSP)
+ BEGIN
+ BIT #$1000,&RTCCTL0 \ test RTCRDY flag
+ 0<> UNTIL \ wait until RTCRDY high
+ MOV &RTCYEARL,2(PSP) \ year
+ MOV.B &RTCMON,TOS
+ MOV TOS,0(PSP) \ month
+ MOV.B &RTCDAY,TOS \ day
+COLON
+ 2 U.R $2F EMIT
+ 2 U.R $2F EMIT .
+;
+ \
+CODE DATE!
+ MOV TOS,&RTCYEARL \ year
+ MOV.B @PSP,&RTCMON \ month \ @PSP+ don't work because byte format !
+ MOV.B 2(PSP),&RTCDAY \ day \ @PSP+ don't work because byte format !
+ ADD #4,PSP
+ MOV @PSP+,TOS \
+COLON
+ ." we are on " DATE?
+;
+ \
+CODE TIME?
+ SUB #6,PSP
+ MOV TOS,4(PSP) \ save TOS
+ BEGIN
+ BIT #$1000,&RTCCTL0 \ test RTCRDY flag
+ 0<> UNTIL \ wait until RTCRDY high
+ MOV.B &RTCSEC,TOS
+ MOV TOS,2(PSP) \ seconds
+ MOV.B &RTCMIN,TOS
+ MOV TOS,0(PSP) \ minutes
+ MOV.B &RTCHOUR,TOS \ hours
+COLON
+ 2 U.R $3A EMIT
+ 2 U.R $3A EMIT 2 U.R
+;
+ \
+: TIME!
+ DEPTH 2 = IF 0 THEN \ to allow "hour min TIME!" scheme
+ HI2LO
+ MOV TOS,&RTCSEC \ seconds
+ MOV.B @PSP,&RTCMIN \ minutes \ @PSP+ don't work because byte format !
+ MOV.B 2(PSP),&RTCHOUR \ hours \ @PSP+ don't work because byte format !
+ ADD #4,PSP
+ MOV @PSP+,TOS \
+ LO2HI
+ ." it is " TIME?
+;
+ \
+CREATE ABUF 20 ALLOT
+ \
+: GET_TIME
+ ECHO
+ CR CR ." DATE (DMY): "
+ ABUF ABUF 20 (ACCEPT) EVALUATE CR 3 SPACES DATE!
+ CR CR ." TIME (HMS or HM): "
+ ABUF ABUF 20 (ACCEPT) EVALUATE CR 3 SPACES TIME!
+ CR
+ PWR_STATE \ auto remove all this application !
+ HI2LO
+ MOV #PSTACK,PSP \ to avoid stack empty error if lack of typed values.
+ MOV @RSP+,IP
+ MOV @IP+,PC
+ENDCODE
+
+ \
+GET_TIME \ all words created by RTC.f are removed
--- /dev/null
+; --------------------
+; RTC_C.f
+; --------------------
+
+\ Copyright (C) <2016> <J.M. THOORENS>
+\
+\ This program is free software: you can redistribute it and/or modify
+\ it under the terms of the GNU General Public License as published by
+\ the Free Software Foundation, either version 3 of the License, or
+\ (at your option) any later version.
+\
+\ This program is distributed in the hope that it will be useful,
+\ but WITHOUT ANY WARRANTY; without even the implied warranty of
+\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+\ GNU General Public License for more details.
+\
+\ You should have received a copy of the GNU General Public License
+\ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+\ REGISTERS USAGE
+\ R4 to R7 must be saved before use and restored after
+\ scratch registers Y to S are free for use
+\ under interrupt, IP is free for use
+
+\ PUSHM order : PSP,TOS, IP, S, T, W, X, Y, R7, R6, R5, R4
+\ example : PUSHM IP,Y
+\
+\ POPM order : R4, R5, R6, R7, Y, X, W, T, S, IP,TOS,PSP
+\ example : POPM Y,IP
+
+\ ASSEMBLER conditionnal usage after IF UNTIL WHILE : S< S>= U< U>= 0= 0<> 0>=
+\ ASSEMBLER conditionnal usage before GOTO ?GOTO : S< S>= U< U>= 0= 0<> <0
+
+\ FORTH conditionnal usage after IF UNTIL WHILE : 0= 0< = < > U<
+
+
+
+\ routines RTC for MSP430fr5xxx and MSP430FR6xxx families
+\ target must have a LF_XTAL 32768Hz.
+
+\ compile DTCforthMSP430FR5xxx.asm with the switch LF_XTAL set to ON (uncommment the line).
+
+\ use :
+\ to set date, type : dd mm yyyy DATE!
+\ to view date, type DATE?
+\ to set time, type : hh mm ss TIME!, or hh mm TIME!
+\ to view time, type TIME?
+
+\ allow to write on a SD_Card file with a valid date and a valid time
+
+\ ECHO ; if an error occurs during download, uncomment this line then download again
+
+ \
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+CODE DATE?
+ SUB #6,PSP
+ MOV TOS,4(PSP)
+ BEGIN
+ BIT.B #$10,&RTCCTL2 \ test RTCRDY flag
+ 0<> UNTIL \ wait until RTCRDY high
+ MOV &RTCYEARL,2(PSP) \ year
+ MOV.B &RTCMON,TOS
+ MOV TOS,0(PSP) \ month
+ MOV.B &RTCDAY,TOS \ day
+COLON
+ 2 U.R $2F EMIT
+ 2 U.R $2F EMIT .
+;
+ \
+CODE DATE!
+ MOV.B #$A5,&RTCCTL1
+ MOV TOS,&RTCYEARL \ year
+ MOV.B @PSP,&RTCMON \ month \ @PSP+ don't work because byte format !
+ MOV.B 2(PSP),&RTCDAY \ day \ @PSP+ don't work because byte format !
+ ADD #4,PSP
+ MOV @PSP+,TOS \
+COLON
+ ." we are on " DATE?
+;
+ \
+CODE TIME?
+ SUB #6,PSP
+ MOV TOS,4(PSP) \ save TOS
+ BEGIN
+ BIT.B #$10,&RTCCTL2 \ test RTCRDY flag
+ 0<> UNTIL \ wait until RTCRDY high
+ MOV.B &RTCSEC,TOS
+ MOV TOS,2(PSP) \ seconds
+ MOV.B &RTCMIN,TOS
+ MOV TOS,0(PSP) \ minutes
+ MOV.B &RTCHOUR,TOS \ hours
+COLON
+ 2 U.R $3A EMIT
+ 2 U.R $3A EMIT 2 U.R
+;
+ \
+: TIME!
+ DEPTH 2 = IF 0 THEN \ to allow "hour min TIME!" scheme
+ HI2LO
+ MOV.B #$A5,&RTCCTL1
+ MOV TOS,&RTCSEC \ seconds
+ MOV.B @PSP,&RTCMIN \ minutes \ @PSP+ don't work because byte format !
+ MOV.B 2(PSP),&RTCHOUR \ hours \ @PSP+ don't work because byte format !
+ ADD #4,PSP
+ MOV @PSP+,TOS \
+ LO2HI
+ ." it is " TIME?
+;
+ \
+CREATE ABUF 20 ALLOT
+ \
+: GET_TIME
+ ECHO
+ CR CR ." DATE (DMY): "
+ ABUF ABUF 20 (ACCEPT) EVALUATE CR 3 SPACES DATE!
+ CR CR ." TIME (HMS or HM): "
+ ABUF ABUF 20 (ACCEPT) EVALUATE CR 3 SPACES TIME!
+ CR
+ PWR_STATE \ auto remove all this application !
+ HI2LO
+ MOV #PSTACK,PSP \ to avoid stack empty error if lack of typed values.
+ MOV @RSP+,IP
+ MOV @IP+,PC
+ENDCODE
+
+ \
+GET_TIME \ all words created by RTC.f are removed
--- /dev/null
+; -------------------------------------------------------------------------------
+; ANS complement for MSP430FRxxxx devices with hardware_MPY, to pass CORETEST.4th
+; -------------------------------------------------------------------------------
+
+CODE INVERT
+ XOR #-1,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE LSHIFT
+ MOV @R15+,R10
+ AND #$1F,R14
+0<> IF
+ BEGIN ADD R10,R10
+ SUB #1,R14
+ 0= UNTIL
+THEN MOV R10,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE RSHIFT
+ MOV @R15+,R10
+ AND #$1F,R14
+0<> IF
+ BEGIN BIC #1,R2
+ RRC R10
+ SUB #1,R14
+ 0= UNTIL
+THEN MOV R10,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE 1+
+ ADD #1,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE 1-
+ SUB #1,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE MAX
+ CMP @R15,R14
+ S< ?GOTO FW1
+BW1 ADD #2,R15
+ MOV @R13+,R0
+ENDCODE
+
+CODE MIN
+ CMP @R15,R14
+ S< ?GOTO BW1
+FW1 MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE 2*
+ ADD R14,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE 2/
+ RRA R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE NIP
+ADD #2,R15
+MOV @R13+,R0
+ENDCODE
+
+: S>D
+ DUP 0<
+;
+
+CODE UM*
+MOV @R15,&$4C0
+MOV R14,&$4C8
+MOV &$4E4,0(R15)
+MOV &$4E6,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE M*
+MOV @R15,&$4C2
+MOV R14,&$4C8
+MOV &$4E4,0(R15)
+MOV &$4E6,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE UM/MOD
+ MOV @R15+,R10
+ MOV @R15,R12
+ MOV #16,R9
+BW1 CMP R14,R10
+ U< ?GOTO FW1
+ SUB R14,R10
+FW1
+BW2 ADDC R8,R8
+ SUB #1,R9
+ 0< ?GOTO FW1
+ ADD R12,R12
+ ADDC R10,R10
+ U< ?GOTO BW1
+ SUB R14,R10
+ BIS #1,R2
+ GOTO BW2
+FW1 MOV R10,0(R15)
+ MOV R8,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE SM/REM
+MOV R14,R12
+MOV @R15,R11
+CMP #0,R14
+S< IF
+ XOR #-1,R14
+ ADD #1,R14
+THEN
+CMP #0,0(R15)
+S< IF
+ XOR #-1,2(R15)
+ XOR #-1,0(R15)
+ ADD #1,2(R15)
+ ADDC #0,0(R15)
+THEN
+PUSHM R13,R12
+LO2HI
+UM/MOD
+HI2LO
+POPM R12,R13
+CMP #0,R11
+S< IF
+ XOR #-1,0(R15)
+ ADD #1,0(R15)
+THEN
+XOR R12,R11
+CMP #0,R11
+S< IF
+ XOR #-1,R14
+ ADD #1,R14
+THEN
+MOV @R13+,R0
+ENDCODE
+
+: FM/MOD
+SM/REM
+HI2LO
+CMP #0,0(R15)
+0<> IF
+ CMP #1,R14
+ S< IF
+ ADD R12,0(R15)
+ SUB #1,R14
+ THEN
+THEN
+MOV @R1+,R13
+MOV @R13+,R0
+ENDCODE
+
+: *
+M* DROP
+;
+
+: /MOD
+>R DUP 0< R> FM/MOD
+;
+
+: /
+>R DUP 0< R> FM/MOD NIP
+;
+
+: MOD
+>R DUP 0< R> FM/MOD DROP
+;
+
+: */MOD
+>R M* R> FM/MOD
+;
+
+: */
+>R M* R> FM/MOD NIP
+;
+
+CODE 2@
+SUB #2, R15
+MOV 2(R14),0(R15)
+MOV @R14,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE 2!
+MOV @R15+,0(R14)
+MOV @R15+,2(R14)
+MOV @R15+,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE 2DUP
+SUB #4,R15
+MOV R14,2(R15)
+MOV 4(R15),0(R15)
+MOV @R13+,R0
+ENDCODE
+
+CODE 2DROP
+ADD #2,R15
+MOV @R15+,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE 2SWAP
+MOV @R15,R10
+MOV 4(R15),0(R15)
+MOV R10,4(R15)
+MOV R14,R10
+MOV 2(R15),R14
+MOV R10,2(R15)
+MOV @R13+,R0
+ENDCODE
+
+CODE 2OVER
+SUB #4,R15
+MOV R14,2(R15)
+MOV 8(R15),0(R15)
+MOV 6(R15),R14
+MOV @R13+,R0
+ENDCODE
+
+CODE ALIGNED
+BIT #1,R14
+ADDC #0,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE ALIGN
+BIT #1,&$1DC4
+ADDC #0,&$1DC4
+MOV @R13+,R0
+ENDCODE
+
+CODE CHARS
+MOV @R13+,R0
+ENDCODE
+
+CODE CHAR+
+ADD #1,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE CELLS
+ADD R14,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE CELL+
+ADD #2,R14
+MOV @R13+,R0
+ENDCODE
+
+: CHAR
+ BL WORD 1+ C@
+;
+: [CHAR]
+ CHAR lit lit , ,
+; IMMEDIATE
+
+CODE +!
+ADD @R15+,0(R14)
+MOV @R15+,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE FILL
+MOV @R15+,R9
+MOV @R15+,R10
+CMP #0,R9
+0<> IF
+ BEGIN
+ MOV.B R14,0(R10)
+ ADD #1,R10
+ SUB #1,R9
+ 0= UNTIL
+THEN
+MOV @R15+,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE HEX
+MOV #$10,&$1DDA
+MOV @R13+,R0
+ENDCODE
+
+CODE DECIMAL
+MOV #$0A,&$1DDA
+MOV @R13+,R0
+ENDCODE
+
+: (
+$29 WORD DROP
+; IMMEDIATE
+
+: .(
+$29 WORD
+COUNT TYPE
+; IMMEDIATE
+
+CODE SOURCE
+SUB #4,R15
+MOV R14,2(R15)
+MOV &$1DBE,R14
+MOV &$1DC0,0(R15)
+MOV @R13+,R0
+ENDCODE
+
+CODE >BODY
+ADD #4,R14
+MOV @R13+,R0
+ENDCODE
+
+ECHO
+ ; added ANS_COMPLEMENT: INVERT LSHIFT RSHIFT 1+ 1- MAX MIN 2* 2/ CHAR [CHAR] +! FILL HEX DECIMAL ( .( SOURCE >BODY
+ ; ARITHMETIC: NIP S>D UM* M* UM/MOD SM/REM FM/MOD * /MOD / MOD */MOD */
+ ; DOUBLE: 2@ 2! 2DUP 2DROP 2SWAP 2OVER
+ ; ALIGMENT: ALIGNED ALIGN
+ ; PORTABIITY: CHARS CHAR+ CELLS CELL+
+
+PWR_HERE ; to protect this app against a RESET, type: RST_HERE
--- /dev/null
+; -------------------------------------------------------------------------------
+; ANS complement for MSP430FRxxxx devices with hardware_MPY, to pass CORETEST.4th
+; -------------------------------------------------------------------------------
+
+CODE INVERT
+ XOR #-1,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE LSHIFT
+ MOV @R15+,R10
+ AND #$1F,R14
+0<> IF
+ BEGIN ADD R10,R10
+ SUB #1,R14
+ 0= UNTIL
+THEN MOV R10,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE RSHIFT
+ MOV @R15+,R10
+ AND #$1F,R14
+0<> IF
+ BEGIN BIC #1,R2
+ RRC R10
+ SUB #1,R14
+ 0= UNTIL
+THEN MOV R10,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE 1+
+ ADD #1,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE 1-
+ SUB #1,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE MAX
+ CMP @R15,R14
+ S< ?GOTO FW1
+BW1 ADD #2,R15
+ MOV @R13+,R0
+ENDCODE
+
+CODE MIN
+ CMP @R15,R14
+ S< ?GOTO BW1
+FW1 MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE 2*
+ ADD R14,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE 2/
+ RRA R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE NIP
+ADD #2,R15
+MOV @R13+,R0
+ENDCODE
+
+: S>D
+ DUP 0<
+;
+
+CODE UM*
+MOV @R15,&$4C0
+MOV R14,&$4C8
+MOV &$4E4,0(R15)
+MOV &$4E6,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE M*
+MOV @R15,&$4C2
+MOV R14,&$4C8
+MOV &$4E4,0(R15)
+MOV &$4E6,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE UM/MOD
+ MOV @R15+,R10
+ MOV @R15,R12
+ MOV #16,R9
+BW1 CMP R14,R10
+ U< ?GOTO FW1
+ SUB R14,R10
+FW1
+BW2 ADDC R8,R8
+ SUB #1,R9
+ 0< ?GOTO FW1
+ ADD R12,R12
+ ADDC R10,R10
+ U< ?GOTO BW1
+ SUB R14,R10
+ BIS #1,R2
+ GOTO BW2
+FW1 MOV R10,0(R15)
+ MOV R8,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE SM/REM
+MOV R14,R12
+MOV @R15,R11
+CMP #0,R14
+S< IF
+ XOR #-1,R14
+ ADD #1,R14
+THEN
+CMP #0,0(R15)
+S< IF
+ XOR #-1,2(R15)
+ XOR #-1,0(R15)
+ ADD #1,2(R15)
+ ADDC #0,0(R15)
+THEN
+PUSHM R13,R12
+LO2HI
+UM/MOD
+HI2LO
+POPM R12,R13
+CMP #0,R11
+S< IF
+ XOR #-1,0(R15)
+ ADD #1,0(R15)
+THEN
+XOR R12,R11
+CMP #0,R11
+S< IF
+ XOR #-1,R14
+ ADD #1,R14
+THEN
+MOV @R13+,R0
+ENDCODE
+
+: FM/MOD
+SM/REM
+HI2LO
+CMP #0,0(R15)
+0<> IF
+ CMP #1,R14
+ S< IF
+ ADD R12,0(R15)
+ SUB #1,R14
+ THEN
+THEN
+MOV @R1+,R13
+MOV @R13+,R0
+ENDCODE
+
+: *
+M* DROP
+;
+
+: /MOD
+>R DUP 0< R> FM/MOD
+;
+
+: /
+>R DUP 0< R> FM/MOD NIP
+;
+
+: MOD
+>R DUP 0< R> FM/MOD DROP
+;
+
+: */MOD
+>R M* R> FM/MOD
+;
+
+: */
+>R M* R> FM/MOD NIP
+;
+
+CODE 2@
+SUB #2, R15
+MOV 2(R14),0(R15)
+MOV @R14,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE 2!
+MOV @R15+,0(R14)
+MOV @R15+,2(R14)
+MOV @R15+,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE 2DUP
+SUB #4,R15
+MOV R14,2(R15)
+MOV 4(R15),0(R15)
+MOV @R13+,R0
+ENDCODE
+
+CODE 2DROP
+ADD #2,R15
+MOV @R15+,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE 2SWAP
+MOV @R15,R10
+MOV 4(R15),0(R15)
+MOV R10,4(R15)
+MOV R14,R10
+MOV 2(R15),R14
+MOV R10,2(R15)
+MOV @R13+,R0
+ENDCODE
+
+CODE 2OVER
+SUB #4,R15
+MOV R14,2(R15)
+MOV 8(R15),0(R15)
+MOV 6(R15),R14
+MOV @R13+,R0
+ENDCODE
+
+CODE ALIGNED
+BIT #1,R14
+ADDC #0,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE ALIGN
+BIT #1,&$1DC4
+ADDC #0,&$1DC4
+MOV @R13+,R0
+ENDCODE
+
+CODE CHARS
+MOV @R13+,R0
+ENDCODE
+
+CODE CHAR+
+ADD #1,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE CELLS
+ADD R14,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE CELL+
+ADD #2,R14
+MOV @R13+,R0
+ENDCODE
+
+: CHAR
+ BL WORD 1+ C@
+;
+: [CHAR]
+ CHAR lit lit , ,
+; IMMEDIATE
+
+CODE +!
+ADD @R15+,0(R14)
+MOV @R15+,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE FILL
+MOV @R15+,R9
+MOV @R15+,R10
+CMP #0,R9
+0<> IF
+ BEGIN
+ MOV.B R14,0(R10)
+ ADD #1,R10
+ SUB #1,R9
+ 0= UNTIL
+THEN
+MOV @R15+,R14
+MOV @R13+,R0
+ENDCODE
+
+CODE HEX
+MOV #$10,&$1DDA
+MOV @R13+,R0
+ENDCODE
+
+CODE DECIMAL
+MOV #$0A,&$1DDA
+MOV @R13+,R0
+ENDCODE
+
+: (
+$29 WORD DROP
+; IMMEDIATE
+
+: .(
+$29 WORD
+COUNT TYPE
+; IMMEDIATE
+
+CODE SOURCE
+SUB #4,R15
+MOV R14,2(R15)
+MOV &$1DBE,R14
+MOV &$1DC0,0(R15)
+MOV @R13+,R0
+ENDCODE
+
+CODE >BODY
+ADD #4,R14
+MOV @R13+,R0
+ENDCODE
+
+
+ECHO
+
+; ===============================================================
+;
+; ##### ####### ###### ####### ####### ####### ##### #######
+; # # # # # # # # # # # #
+; # # # # # # # # # #
+; # # # ###### ##### # ##### ##### #
+; # # # # # # # # # #
+; # # # # # # # # # # # #
+; ##### ####### # # ####### # ####### ##### #
+;
+; ===============================================================
+
+
+\ From: John Hayes S1I
+\ Subject: tester.fr
+\ Date: Mon, 27 Nov 95 13:10:09 PST
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.1
+
+\ 22/1/09 The words { and } have been changed to T{ and }T respectively to
+\ agree with the Forth 200X file ttester.fs. This avoids clashes with
+\ locals using { ... } and the FSL use of }
+
+
+\ 13/05/14 jmt. added colorised error messages.
+
+
+
+ 0 CONSTANT FALSE
+-1 CONSTANT TRUE
+
+\ SET THE FOLLOWING FLAG TO TRUE FOR MORE VERBOSE OUTPUT; THIS MAY
+\ ALLOW YOU TO TELL WHICH TEST CAUSED YOUR SYSTEM TO HANG.
+VARIABLE VERBOSE
+ FALSE VERBOSE !
+\ TRUE VERBOSE !
+
+\ : EMPTY-STACK ( ... -- ) \ EMPTY STACK: HANDLES UNDERFLOWED STACK TOO.
+\ DEPTH ?DUP
+\ IF DUP 0< IF NEGATE 0
+\ DO 0 LOOP
+\ ELSE 0 DO DROP LOOP THEN
+\ THEN ;
+\
+\ : ERROR \ ( C-ADDR U -- ) DISPLAY AN ERROR MESSAGE FOLLOWED BY
+\ \ THE LINE THAT HAD THE ERROR.
+\ TYPE SOURCE TYPE CR \ DISPLAY LINE CORRESPONDING TO ERROR
+\ EMPTY-STACK \ THROW AWAY EVERY THING ELSE
+\ QUIT \ *** Uncomment this line to QUIT on an error
+\ ;
+
+VARIABLE ACTUAL-DEPTH \ STACK RECORD
+CREATE ACTUAL-RESULTS 20 CELLS ALLOT
+
+: T{ \ ( -- ) SYNTACTIC SUGAR.
+ ;
+
+: -> \ ( ... -- ) RECORD DEPTH AND CONTENT OF STACK.
+ DEPTH DUP ACTUAL-DEPTH ! \ RECORD DEPTH
+ ?DUP IF \ IF THERE IS SOMETHING ON STACK
+ 0 DO ACTUAL-RESULTS I CELLS + ! LOOP \ SAVE THEM
+ THEN ;
+
+: }T \ ( ... -- ) COMPARE STACK (EXPECTED) CONTENTS WITH SAVED
+ \ (ACTUAL) CONTENTS.
+ DEPTH ACTUAL-DEPTH @ = IF \ IF DEPTHS MATCH
+ DEPTH ?DUP IF \ IF THERE IS SOMETHING ON THE STACK
+ 0 DO \ FOR EACH STACK ITEM
+ ACTUAL-RESULTS I CELLS + @ \ COMPARE ACTUAL WITH EXPECTED
+\ = 0= IF S" INCORRECT RESULT: " ERROR LEAVE THEN \ jmt
+ = 0= IF ABORT" INCORRECT RESULT: " THEN \ jmt : colorised message
+ LOOP
+ THEN
+ ELSE \ DEPTH MISMATCH
+\ S" WRONG NUMBER OF RESULTS: " ERROR \ jmt
+ ABORT" WRONG NUMBER OF RESULTS: " \ jmt : colorised message
+ THEN ;
+
+: TESTING \ ( -- ) TALKING COMMENT.
+ SOURCE VERBOSE @
+ IF DUP >R TYPE CR R> >IN !
+ ELSE >IN ! DROP [CHAR] * EMIT
+ THEN ;
+
+\ From: John Hayes S1I
+\ Subject: core.fr
+\ Date: Mon, 27 Nov 95 13:10
+
+\ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
+\ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
+\ VERSION 1.2
+\ THIS PROGRAM TESTS THE CORE WORDS OF AN ANS FORTH SYSTEM.
+\ THE PROGRAM ASSUMES A TWO'S COMPLEMENT IMPLEMENTATION WHERE
+\ THE RANGE OF SIGNED NUMBERS IS -2^(N-1) ... 2^(N-1)-1 AND
+\ THE RANGE OF UNSIGNED NUMBERS IS 0 ... 2^(N)-1.
+\ I HAVEN'T FIGURED OUT HOW TO TEST KEY, QUIT, ABORT, OR ABORT"...
+\ I ALSO HAVEN'T THOUGHT OF A WAY TO TEST ENVIRONMENT?...
+
+CR
+TESTING CORE WORDS
+HEX
+
+\ ------------------------------------------------------------------------
+TESTING BASIC ASSUMPTIONS
+
+T{ -> }T \ START WITH CLEAN SLATE
+( TEST IF ANY BITS ARE SET; ANSWER IN BASE 1 )
+T{ : BITSSET? IF 0 0 ELSE 0 THEN ; -> }T
+T{ 0 BITSSET? -> 0 }T ( ZERO IS ALL BITS CLEAR )
+T{ 1 BITSSET? -> 0 0 }T ( OTHER NUMBER HAVE AT LEAST ONE BIT )
+T{ -1 BITSSET? -> 0 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING BOOLEANS: INVERT AND OR XOR
+
+T{ 0 0 AND -> 0 }T
+T{ 0 1 AND -> 0 }T
+T{ 1 0 AND -> 0 }T
+T{ 1 1 AND -> 1 }T
+
+T{ 0 INVERT 1 AND -> 1 }T
+T{ 1 INVERT 1 AND -> 0 }T
+
+0 CONSTANT 0S
+0 INVERT CONSTANT 1S
+
+T{ 0S INVERT -> 1S }T
+T{ 1S INVERT -> 0S }T
+
+T{ 0S 0S AND -> 0S }T
+T{ 0S 1S AND -> 0S }T
+T{ 1S 0S AND -> 0S }T
+T{ 1S 1S AND -> 1S }T
+
+T{ 0S 0S OR -> 0S }T
+T{ 0S 1S OR -> 1S }T
+T{ 1S 0S OR -> 1S }T
+T{ 1S 1S OR -> 1S }T
+
+T{ 0S 0S XOR -> 0S }T
+T{ 0S 1S XOR -> 1S }T
+T{ 1S 0S XOR -> 1S }T
+T{ 1S 1S XOR -> 0S }T
+
+\ ------------------------------------------------------------------------
+TESTING 2* 2/ LSHIFT RSHIFT
+
+( WE TRUST 1S, INVERT, AND BITSSET?; WE WILL CONFIRM RSHIFT LATER )
+1S 1 RSHIFT INVERT CONSTANT MSB
+T{ MSB BITSSET? -> 0 0 }T
+
+T{ 0S 2* -> 0S }T
+T{ 1 2* -> 2 }T
+T{ 4000 2* -> 8000 }T
+T{ 1S 2* 1 XOR -> 1S }T
+T{ MSB 2* -> 0S }T
+
+T{ 0S 2/ -> 0S }T
+T{ 1 2/ -> 0 }T
+T{ 4000 2/ -> 2000 }T
+T{ 1S 2/ -> 1S }T \ MSB PROPOGATED
+T{ 1S 1 XOR 2/ -> 1S }T
+T{ MSB 2/ MSB AND -> MSB }T
+
+T{ 1 0 LSHIFT -> 1 }T
+T{ 1 1 LSHIFT -> 2 }T
+T{ 1 2 LSHIFT -> 4 }T
+T{ 1 F LSHIFT -> 8000 }T \ BIGGEST GUARANTEED SHIFT
+T{ 1S 1 LSHIFT 1 XOR -> 1S }T
+T{ MSB 1 LSHIFT -> 0 }T
+
+T{ 1 0 RSHIFT -> 1 }T
+T{ 1 1 RSHIFT -> 0 }T
+T{ 2 1 RSHIFT -> 1 }T
+T{ 4 2 RSHIFT -> 1 }T
+T{ 8000 F RSHIFT -> 1 }T \ BIGGEST
+T{ MSB 1 RSHIFT MSB AND -> 0 }T \ RSHIFT ZERO FILLS MSBS
+T{ MSB 1 RSHIFT 2* -> MSB }T
+
+\ ------------------------------------------------------------------------
+TESTING COMPARISONS: 0= = 0< < > U< MIN MAX
+0 INVERT CONSTANT MAX-UINT
+0 INVERT 1 RSHIFT CONSTANT MAX-INT
+0 INVERT 1 RSHIFT INVERT CONSTANT MIN-INT
+0 INVERT 1 RSHIFT CONSTANT MID-UINT
+0 INVERT 1 RSHIFT INVERT CONSTANT MID-UINT+1
+
+0S CONSTANT <FALSE>
+1S CONSTANT <TRUE>
+
+T{ 0 0= -> <TRUE> }T
+T{ 1 0= -> <FALSE> }T
+T{ 2 0= -> <FALSE> }T
+T{ -1 0= -> <FALSE> }T
+T{ MAX-UINT 0= -> <FALSE> }T
+T{ MIN-INT 0= -> <FALSE> }T
+T{ MAX-INT 0= -> <FALSE> }T
+
+T{ 0 0 = -> <TRUE> }T
+T{ 1 1 = -> <TRUE> }T
+T{ -1 -1 = -> <TRUE> }T
+T{ 1 0 = -> <FALSE> }T
+T{ -1 0 = -> <FALSE> }T
+T{ 0 1 = -> <FALSE> }T
+T{ 0 -1 = -> <FALSE> }T
+
+T{ 0 0< -> <FALSE> }T
+T{ -1 0< -> <TRUE> }T
+T{ MIN-INT 0< -> <TRUE> }T
+T{ 1 0< -> <FALSE> }T
+T{ MAX-INT 0< -> <FALSE> }T
+
+T{ 0 1 < -> <TRUE> }T
+T{ 1 2 < -> <TRUE> }T
+T{ -1 0 < -> <TRUE> }T
+T{ -1 1 < -> <TRUE> }T
+T{ MIN-INT 0 < -> <TRUE> }T
+T{ MIN-INT MAX-INT < -> <TRUE> }T
+T{ 0 MAX-INT < -> <TRUE> }T
+T{ 0 0 < -> <FALSE> }T
+T{ 1 1 < -> <FALSE> }T
+T{ 1 0 < -> <FALSE> }T
+T{ 2 1 < -> <FALSE> }T
+T{ 0 -1 < -> <FALSE> }T
+T{ 1 -1 < -> <FALSE> }T
+T{ 0 MIN-INT < -> <FALSE> }T
+T{ MAX-INT MIN-INT < -> <FALSE> }T
+T{ MAX-INT 0 < -> <FALSE> }T
+
+T{ 0 1 > -> <FALSE> }T
+T{ 1 2 > -> <FALSE> }T
+T{ -1 0 > -> <FALSE> }T
+T{ -1 1 > -> <FALSE> }T
+T{ MIN-INT 0 > -> <FALSE> }T
+T{ MIN-INT MAX-INT > -> <FALSE> }T
+T{ 0 MAX-INT > -> <FALSE> }T
+T{ 0 0 > -> <FALSE> }T
+T{ 1 1 > -> <FALSE> }T
+T{ 1 0 > -> <TRUE> }T
+T{ 2 1 > -> <TRUE> }T
+T{ 0 -1 > -> <TRUE> }T
+T{ 1 -1 > -> <TRUE> }T
+T{ 0 MIN-INT > -> <TRUE> }T
+T{ MAX-INT MIN-INT > -> <TRUE> }T
+T{ MAX-INT 0 > -> <TRUE> }T
+
+T{ 0 1 U< -> <TRUE> }T
+T{ 1 2 U< -> <TRUE> }T
+T{ 0 MID-UINT U< -> <TRUE> }T
+T{ 0 MAX-UINT U< -> <TRUE> }T
+T{ MID-UINT MAX-UINT U< -> <TRUE> }T
+T{ 0 0 U< -> <FALSE> }T
+T{ 1 1 U< -> <FALSE> }T
+T{ 1 0 U< -> <FALSE> }T
+T{ 2 1 U< -> <FALSE> }T
+T{ MID-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT 0 U< -> <FALSE> }T
+T{ MAX-UINT MID-UINT U< -> <FALSE> }T
+
+T{ 0 1 MIN -> 0 }T
+T{ 1 2 MIN -> 1 }T
+T{ -1 0 MIN -> -1 }T
+T{ -1 1 MIN -> -1 }T
+T{ MIN-INT 0 MIN -> MIN-INT }T
+T{ MIN-INT MAX-INT MIN -> MIN-INT }T
+T{ 0 MAX-INT MIN -> 0 }T
+T{ 0 0 MIN -> 0 }T
+T{ 1 1 MIN -> 1 }T
+T{ 1 0 MIN -> 0 }T
+T{ 2 1 MIN -> 1 }T
+T{ 0 -1 MIN -> -1 }T
+T{ 1 -1 MIN -> -1 }T
+T{ 0 MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT MIN-INT MIN -> MIN-INT }T
+T{ MAX-INT 0 MIN -> 0 }T
+
+T{ 0 1 MAX -> 1 }T
+T{ 1 2 MAX -> 2 }T
+T{ -1 0 MAX -> 0 }T
+T{ -1 1 MAX -> 1 }T
+T{ MIN-INT 0 MAX -> 0 }T
+T{ MIN-INT MAX-INT MAX -> MAX-INT }T
+T{ 0 MAX-INT MAX -> MAX-INT }T
+T{ 0 0 MAX -> 0 }T
+T{ 1 1 MAX -> 1 }T
+T{ 1 0 MAX -> 1 }T
+T{ 2 1 MAX -> 2 }T
+T{ 0 -1 MAX -> 0 }T
+T{ 1 -1 MAX -> 1 }T
+T{ 0 MIN-INT MAX -> 0 }T
+T{ MAX-INT MIN-INT MAX -> MAX-INT }T
+T{ MAX-INT 0 MAX -> MAX-INT }T
+
+\ ------------------------------------------------------------------------
+TESTING STACK OPS: 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP
+
+T{ 1 2 2DROP -> }T
+T{ 1 2 2DUP -> 1 2 1 2 }T
+T{ 1 2 3 4 2OVER -> 1 2 3 4 1 2 }T
+T{ 1 2 3 4 2SWAP -> 3 4 1 2 }T
+T{ 0 ?DUP -> 0 }T
+T{ 1 ?DUP -> 1 1 }T
+T{ -1 ?DUP -> -1 -1 }T
+T{ DEPTH -> 0 }T
+T{ 0 DEPTH -> 0 1 }T
+T{ 0 1 DEPTH -> 0 1 2 }T
+T{ 0 DROP -> }T
+T{ 1 2 DROP -> 1 }T
+T{ 1 DUP -> 1 1 }T
+T{ 1 2 OVER -> 1 2 1 }T
+T{ 1 2 3 ROT -> 2 3 1 }T
+T{ 1 2 SWAP -> 2 1 }T
+
+\ ------------------------------------------------------------------------
+TESTING >R R> R@
+
+T{ : GR1 >R R> ; -> }T
+T{ : GR2 >R R@ R> DROP ; -> }T
+T{ 123 GR1 -> 123 }T
+T{ 123 GR2 -> 123 }T
+T{ 1S GR1 -> 1S }T ( RETURN STACK HOLDS CELLS )
+
+\ ------------------------------------------------------------------------
+TESTING ADD/SUBTRACT: + - 1+ 1- ABS NEGATE
+
+T{ 0 5 + -> 5 }T
+T{ 5 0 + -> 5 }T
+T{ 0 -5 + -> -5 }T
+T{ -5 0 + -> -5 }T
+T{ 1 2 + -> 3 }T
+T{ 1 -2 + -> -1 }T
+T{ -1 2 + -> 1 }T
+T{ -1 -2 + -> -3 }T
+T{ -1 1 + -> 0 }T
+T{ MID-UINT 1 + -> MID-UINT+1 }T
+
+T{ 0 5 - -> -5 }T
+T{ 5 0 - -> 5 }T
+T{ 0 -5 - -> 5 }T
+T{ -5 0 - -> -5 }T
+T{ 1 2 - -> -1 }T
+T{ 1 -2 - -> 3 }T
+T{ -1 2 - -> -3 }T
+T{ -1 -2 - -> 1 }T
+T{ 0 1 - -> -1 }T
+T{ MID-UINT+1 1 - -> MID-UINT }T
+
+T{ 0 1+ -> 1 }T
+T{ -1 1+ -> 0 }T
+T{ 1 1+ -> 2 }T
+T{ MID-UINT 1+ -> MID-UINT+1 }T
+
+T{ 2 1- -> 1 }T
+T{ 1 1- -> 0 }T
+T{ 0 1- -> -1 }T
+T{ MID-UINT+1 1- -> MID-UINT }T
+
+T{ 0 NEGATE -> 0 }T
+T{ 1 NEGATE -> -1 }T
+T{ -1 NEGATE -> 1 }T
+T{ 2 NEGATE -> -2 }T
+T{ -2 NEGATE -> 2 }T
+
+T{ 0 ABS -> 0 }T
+T{ 1 ABS -> 1 }T
+T{ -1 ABS -> 1 }T
+T{ MIN-INT ABS -> MID-UINT+1 }T
+
+\ ------------------------------------------------------------------------
+TESTING MULTIPLY: S>D * M* UM*
+
+T{ 0 S>D -> 0 0 }T
+T{ 1 S>D -> 1 0 }T
+T{ 2 S>D -> 2 0 }T
+T{ -1 S>D -> -1 -1 }T
+T{ -2 S>D -> -2 -1 }T
+T{ MIN-INT S>D -> MIN-INT -1 }T
+T{ MAX-INT S>D -> MAX-INT 0 }T
+
+T{ 0 0 M* -> 0 S>D }T
+T{ 0 1 M* -> 0 S>D }T
+T{ 1 0 M* -> 0 S>D }T
+T{ 1 2 M* -> 2 S>D }T
+T{ 2 1 M* -> 2 S>D }T
+T{ 3 3 M* -> 9 S>D }T
+T{ -3 3 M* -> -9 S>D }T
+T{ 3 -3 M* -> -9 S>D }T
+T{ -3 -3 M* -> 9 S>D }T
+T{ 0 MIN-INT M* -> 0 S>D }T
+T{ 1 MIN-INT M* -> MIN-INT S>D }T
+T{ 2 MIN-INT M* -> 0 1S }T
+T{ 0 MAX-INT M* -> 0 S>D }T
+T{ 1 MAX-INT M* -> MAX-INT S>D }T
+T{ 2 MAX-INT M* -> MAX-INT 1 LSHIFT 0 }T
+T{ MIN-INT MIN-INT M* -> 0 MSB 1 RSHIFT }T
+T{ MAX-INT MIN-INT M* -> MSB MSB 2/ }T
+T{ MAX-INT MAX-INT M* -> 1 MSB 2/ INVERT }T
+
+T{ 0 0 * -> 0 }T \ TEST IDENTITIES
+T{ 0 1 * -> 0 }T
+T{ 1 0 * -> 0 }T
+T{ 1 2 * -> 2 }T
+T{ 2 1 * -> 2 }T
+T{ 3 3 * -> 9 }T
+T{ -3 3 * -> -9 }T
+T{ 3 -3 * -> -9 }T
+T{ -3 -3 * -> 9 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 * -> MID-UINT+1 }T
+T{ MID-UINT+1 2 RSHIFT 4 * -> MID-UINT+1 }T
+T{ MID-UINT+1 1 RSHIFT MID-UINT+1 OR 2 * -> MID-UINT+1 }T
+
+T{ 0 0 UM* -> 0 0 }T
+T{ 0 1 UM* -> 0 0 }T
+T{ 1 0 UM* -> 0 0 }T
+T{ 1 2 UM* -> 2 0 }T
+T{ 2 1 UM* -> 2 0 }T
+T{ 3 3 UM* -> 9 0 }T
+
+T{ MID-UINT+1 1 RSHIFT 2 UM* -> MID-UINT+1 0 }T
+T{ MID-UINT+1 2 UM* -> 0 1 }T
+T{ MID-UINT+1 4 UM* -> 0 2 }T
+T{ 1S 2 UM* -> 1S 1 LSHIFT 1 }T
+T{ MAX-UINT MAX-UINT UM* -> 1 1 INVERT }T
+
+\ ------------------------------------------------------------------------
+TESTING DIVIDE: FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD
+
+T{ 0 S>D 1 FM/MOD -> 0 0 }T
+T{ 1 S>D 1 FM/MOD -> 0 1 }T
+T{ 2 S>D 1 FM/MOD -> 0 2 }T
+T{ -1 S>D 1 FM/MOD -> 0 -1 }T
+T{ -2 S>D 1 FM/MOD -> 0 -2 }T
+T{ 0 S>D -1 FM/MOD -> 0 0 }T
+T{ 1 S>D -1 FM/MOD -> 0 -1 }T
+T{ 2 S>D -1 FM/MOD -> 0 -2 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -1 FM/MOD -> 0 2 }T
+T{ 2 S>D 2 FM/MOD -> 0 1 }T
+T{ -1 S>D -1 FM/MOD -> 0 1 }T
+T{ -2 S>D -2 FM/MOD -> 0 1 }T
+T{ 7 S>D 3 FM/MOD -> 1 2 }T
+T{ 7 S>D -3 FM/MOD -> -2 -3 }T
+T{ -7 S>D 3 FM/MOD -> 2 -3 }T
+T{ -7 S>D -3 FM/MOD -> -1 2 }T
+T{ MAX-INT S>D 1 FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT FM/MOD -> 0 1 }T
+T{ MIN-INT S>D MIN-INT FM/MOD -> 0 1 }T
+T{ 1S 1 4 FM/MOD -> 3 MAX-INT }T
+T{ 1 MIN-INT M* 1 FM/MOD -> 0 MIN-INT }T
+T{ 1 MIN-INT M* MIN-INT FM/MOD -> 0 1 }T
+T{ 2 MIN-INT M* 2 FM/MOD -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT FM/MOD -> 0 2 }T
+T{ 1 MAX-INT M* 1 FM/MOD -> 0 MAX-INT }T
+T{ 1 MAX-INT M* MAX-INT FM/MOD -> 0 1 }T
+T{ 2 MAX-INT M* 2 FM/MOD -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT FM/MOD -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT FM/MOD -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT FM/MOD -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT FM/MOD -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT FM/MOD -> 0 MAX-INT }T
+
+T{ 0 S>D 1 SM/REM -> 0 0 }T
+T{ 1 S>D 1 SM/REM -> 0 1 }T
+T{ 2 S>D 1 SM/REM -> 0 2 }T
+T{ -1 S>D 1 SM/REM -> 0 -1 }T
+T{ -2 S>D 1 SM/REM -> 0 -2 }T
+T{ 0 S>D -1 SM/REM -> 0 0 }T
+T{ 1 S>D -1 SM/REM -> 0 -1 }T
+T{ 2 S>D -1 SM/REM -> 0 -2 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -1 SM/REM -> 0 2 }T
+T{ 2 S>D 2 SM/REM -> 0 1 }T
+T{ -1 S>D -1 SM/REM -> 0 1 }T
+T{ -2 S>D -2 SM/REM -> 0 1 }T
+T{ 7 S>D 3 SM/REM -> 1 2 }T
+T{ 7 S>D -3 SM/REM -> 1 -2 }T
+T{ -7 S>D 3 SM/REM -> -1 -2 }T
+T{ -7 S>D -3 SM/REM -> -1 2 }T
+T{ MAX-INT S>D 1 SM/REM -> 0 MAX-INT }T
+T{ MIN-INT S>D 1 SM/REM -> 0 MIN-INT }T
+T{ MAX-INT S>D MAX-INT SM/REM -> 0 1 }T
+T{ MIN-INT S>D MIN-INT SM/REM -> 0 1 }T
+T{ 1S 1 4 SM/REM -> 3 MAX-INT }T
+T{ 2 MIN-INT M* 2 SM/REM -> 0 MIN-INT }T
+T{ 2 MIN-INT M* MIN-INT SM/REM -> 0 2 }T
+T{ 2 MAX-INT M* 2 SM/REM -> 0 MAX-INT }T
+T{ 2 MAX-INT M* MAX-INT SM/REM -> 0 2 }T
+T{ MIN-INT MIN-INT M* MIN-INT SM/REM -> 0 MIN-INT }T
+T{ MIN-INT MAX-INT M* MIN-INT SM/REM -> 0 MAX-INT }T
+T{ MIN-INT MAX-INT M* MAX-INT SM/REM -> 0 MIN-INT }T
+T{ MAX-INT MAX-INT M* MAX-INT SM/REM -> 0 MAX-INT }T
+
+T{ 0 0 1 UM/MOD -> 0 0 }T
+T{ 1 0 1 UM/MOD -> 0 1 }T
+T{ 1 0 2 UM/MOD -> 1 0 }T
+T{ 3 0 2 UM/MOD -> 1 1 }T
+T{ MAX-UINT 2 UM* 2 UM/MOD -> 0 MAX-UINT }T
+T{ MAX-UINT 2 UM* MAX-UINT UM/MOD -> 0 2 }T
+T{ MAX-UINT MAX-UINT UM* MAX-UINT UM/MOD -> 0 MAX-UINT }T
+
+: IFFLOORED
+ [ -3 2 / -2 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+: IFSYM
+ [ -3 2 / -1 = INVERT ] LITERAL IF POSTPONE \ THEN ;
+
+\ THE SYSTEM MIGHT DO EITHER FLOORED OR SYMMETRIC DIVISION.
+\ SINCE WE HAVE ALREADY TESTED M*, FM/MOD, AND SM/REM WE CAN USE THEM IN TEST.
+
+IFFLOORED : T/MOD >R S>D R> FM/MOD ;
+IFFLOORED : T/ T/MOD SWAP DROP ;
+IFFLOORED : TMOD T/MOD DROP ;
+IFFLOORED : T*/MOD >R M* R> FM/MOD ;
+IFFLOORED : T*/ T*/MOD SWAP DROP ;
+IFSYM : T/MOD >R S>D R> SM/REM ;
+IFSYM : T/ T/MOD SWAP DROP ;
+IFSYM : TMOD T/MOD DROP ;
+IFSYM : T*/MOD >R M* R> SM/REM ;
+IFSYM : T*/ T*/MOD SWAP DROP ;
+
+T{ 0 1 /MOD -> 0 1 T/MOD }T
+T{ 1 1 /MOD -> 1 1 T/MOD }T
+T{ 2 1 /MOD -> 2 1 T/MOD }T
+T{ -1 1 /MOD -> -1 1 T/MOD }T
+T{ -2 1 /MOD -> -2 1 T/MOD }T
+T{ 0 -1 /MOD -> 0 -1 T/MOD }T
+T{ 1 -1 /MOD -> 1 -1 T/MOD }T
+T{ 2 -1 /MOD -> 2 -1 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -1 /MOD -> -2 -1 T/MOD }T
+T{ 2 2 /MOD -> 2 2 T/MOD }T
+T{ -1 -1 /MOD -> -1 -1 T/MOD }T
+T{ -2 -2 /MOD -> -2 -2 T/MOD }T
+T{ 7 3 /MOD -> 7 3 T/MOD }T
+T{ 7 -3 /MOD -> 7 -3 T/MOD }T
+T{ -7 3 /MOD -> -7 3 T/MOD }T
+T{ -7 -3 /MOD -> -7 -3 T/MOD }T
+T{ MAX-INT 1 /MOD -> MAX-INT 1 T/MOD }T
+T{ MIN-INT 1 /MOD -> MIN-INT 1 T/MOD }T
+T{ MAX-INT MAX-INT /MOD -> MAX-INT MAX-INT T/MOD }T
+T{ MIN-INT MIN-INT /MOD -> MIN-INT MIN-INT T/MOD }T
+
+T{ 0 1 / -> 0 1 T/ }T
+T{ 1 1 / -> 1 1 T/ }T
+T{ 2 1 / -> 2 1 T/ }T
+T{ -1 1 / -> -1 1 T/ }T
+T{ -2 1 / -> -2 1 T/ }T
+T{ 0 -1 / -> 0 -1 T/ }T
+T{ 1 -1 / -> 1 -1 T/ }T
+T{ 2 -1 / -> 2 -1 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -1 / -> -2 -1 T/ }T
+T{ 2 2 / -> 2 2 T/ }T
+T{ -1 -1 / -> -1 -1 T/ }T
+T{ -2 -2 / -> -2 -2 T/ }T
+T{ 7 3 / -> 7 3 T/ }T
+T{ 7 -3 / -> 7 -3 T/ }T
+T{ -7 3 / -> -7 3 T/ }T
+T{ -7 -3 / -> -7 -3 T/ }T
+T{ MAX-INT 1 / -> MAX-INT 1 T/ }T
+T{ MIN-INT 1 / -> MIN-INT 1 T/ }T
+T{ MAX-INT MAX-INT / -> MAX-INT MAX-INT T/ }T
+T{ MIN-INT MIN-INT / -> MIN-INT MIN-INT T/ }T
+
+T{ 0 1 MOD -> 0 1 TMOD }T
+T{ 1 1 MOD -> 1 1 TMOD }T
+T{ 2 1 MOD -> 2 1 TMOD }T
+T{ -1 1 MOD -> -1 1 TMOD }T
+T{ -2 1 MOD -> -2 1 TMOD }T
+T{ 0 -1 MOD -> 0 -1 TMOD }T
+T{ 1 -1 MOD -> 1 -1 TMOD }T
+T{ 2 -1 MOD -> 2 -1 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -1 MOD -> -2 -1 TMOD }T
+T{ 2 2 MOD -> 2 2 TMOD }T
+T{ -1 -1 MOD -> -1 -1 TMOD }T
+T{ -2 -2 MOD -> -2 -2 TMOD }T
+T{ 7 3 MOD -> 7 3 TMOD }T
+T{ 7 -3 MOD -> 7 -3 TMOD }T
+T{ -7 3 MOD -> -7 3 TMOD }T
+T{ -7 -3 MOD -> -7 -3 TMOD }T
+T{ MAX-INT 1 MOD -> MAX-INT 1 TMOD }T
+T{ MIN-INT 1 MOD -> MIN-INT 1 TMOD }T
+T{ MAX-INT MAX-INT MOD -> MAX-INT MAX-INT TMOD }T
+T{ MIN-INT MIN-INT MOD -> MIN-INT MIN-INT TMOD }T
+
+T{ 0 2 1 */ -> 0 2 1 T*/ }T
+T{ 1 2 1 */ -> 1 2 1 T*/ }T
+T{ 2 2 1 */ -> 2 2 1 T*/ }T
+T{ -1 2 1 */ -> -1 2 1 T*/ }T
+T{ -2 2 1 */ -> -2 2 1 T*/ }T
+T{ 0 2 -1 */ -> 0 2 -1 T*/ }T
+T{ 1 2 -1 */ -> 1 2 -1 T*/ }T
+T{ 2 2 -1 */ -> 2 2 -1 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -1 */ -> -2 2 -1 T*/ }T
+T{ 2 2 2 */ -> 2 2 2 T*/ }T
+T{ -1 2 -1 */ -> -1 2 -1 T*/ }T
+T{ -2 2 -2 */ -> -2 2 -2 T*/ }T
+T{ 7 2 3 */ -> 7 2 3 T*/ }T
+T{ 7 2 -3 */ -> 7 2 -3 T*/ }T
+T{ -7 2 3 */ -> -7 2 3 T*/ }T
+T{ -7 2 -3 */ -> -7 2 -3 T*/ }T
+T{ MAX-INT 2 MAX-INT */ -> MAX-INT 2 MAX-INT T*/ }T
+T{ MIN-INT 2 MIN-INT */ -> MIN-INT 2 MIN-INT T*/ }T
+
+T{ 0 2 1 */MOD -> 0 2 1 T*/MOD }T
+T{ 1 2 1 */MOD -> 1 2 1 T*/MOD }T
+T{ 2 2 1 */MOD -> 2 2 1 T*/MOD }T
+T{ -1 2 1 */MOD -> -1 2 1 T*/MOD }T
+T{ -2 2 1 */MOD -> -2 2 1 T*/MOD }T
+T{ 0 2 -1 */MOD -> 0 2 -1 T*/MOD }T
+T{ 1 2 -1 */MOD -> 1 2 -1 T*/MOD }T
+T{ 2 2 -1 */MOD -> 2 2 -1 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -1 */MOD -> -2 2 -1 T*/MOD }T
+T{ 2 2 2 */MOD -> 2 2 2 T*/MOD }T
+T{ -1 2 -1 */MOD -> -1 2 -1 T*/MOD }T
+T{ -2 2 -2 */MOD -> -2 2 -2 T*/MOD }T
+T{ 7 2 3 */MOD -> 7 2 3 T*/MOD }T
+T{ 7 2 -3 */MOD -> 7 2 -3 T*/MOD }T
+T{ -7 2 3 */MOD -> -7 2 3 T*/MOD }T
+T{ -7 2 -3 */MOD -> -7 2 -3 T*/MOD }T
+T{ MAX-INT 2 MAX-INT */MOD -> MAX-INT 2 MAX-INT T*/MOD }T
+T{ MIN-INT 2 MIN-INT */MOD -> MIN-INT 2 MIN-INT T*/MOD }T
+
+\ ------------------------------------------------------------------------
+TESTING HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2! ALIGN ALIGNED +! ALLOT
+
+HERE 1 ALLOT
+HERE
+CONSTANT 2NDA
+CONSTANT 1STA
+T{ 1STA 2NDA U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STA 1+ -> 2NDA }T \ ... BY ONE ADDRESS UNIT
+( MISSING TEST: NEGATIVE ALLOT )
+
+HERE 1 ,
+HERE 2 ,
+CONSTANT 2ND
+CONSTANT 1ST
+T{ 1ST 2ND U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1ST CELL+ -> 2ND }T \ ... BY ONE CELL
+T{ 1ST 1 CELLS + -> 2ND }T
+T{ 1ST @ 2ND @ -> 1 2 }T
+T{ 5 1ST ! -> }T
+T{ 1ST @ 2ND @ -> 5 2 }T
+T{ 6 2ND ! -> }T
+T{ 1ST @ 2ND @ -> 5 6 }T
+T{ 1ST 2@ -> 6 5 }T
+T{ 2 1 1ST 2! -> }T
+T{ 1ST 2@ -> 2 1 }T
+T{ 1S 1ST ! 1ST @ -> 1S }T \ CAN STORE CELL-WIDE VALUE
+
+HERE 1 C,
+HERE 2 C,
+CONSTANT 2NDC
+CONSTANT 1STC
+T{ 1STC 2NDC U< -> <TRUE> }T \ HERE MUST GROW WITH ALLOT
+T{ 1STC CHAR+ -> 2NDC }T \ ... BY ONE CHAR
+T{ 1STC 1 CHARS + -> 2NDC }T
+T{ 1STC C@ 2NDC C@ -> 1 2 }T
+T{ 3 1STC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 2 }T
+T{ 4 2NDC C! -> }T
+T{ 1STC C@ 2NDC C@ -> 3 4 }T
+
+ALIGN 1 ALLOT HERE ALIGN HERE 3 CELLS ALLOT
+CONSTANT A-ADDR CONSTANT UA-ADDR
+T{ UA-ADDR ALIGNED -> A-ADDR }T
+T{ 1 A-ADDR C! A-ADDR C@ -> 1 }T
+T{ 1234 A-ADDR ! A-ADDR @ -> 1234 }T
+T{ 123 456 A-ADDR 2! A-ADDR 2@ -> 123 456 }T
+T{ 2 A-ADDR CHAR+ C! A-ADDR CHAR+ C@ -> 2 }T
+T{ 3 A-ADDR CELL+ C! A-ADDR CELL+ C@ -> 3 }T
+T{ 1234 A-ADDR CELL+ ! A-ADDR CELL+ @ -> 1234 }T
+T{ 123 456 A-ADDR CELL+ 2! A-ADDR CELL+ 2@ -> 123 456 }T
+
+: BITS ( X -- U )
+ 0 SWAP BEGIN DUP WHILE DUP MSB AND IF >R 1+ R> THEN 2* REPEAT DROP ;
+( CHARACTERS >= 1 AU, <= SIZE OF CELL, >= 8 BITS )
+T{ 1 CHARS 1 < -> <FALSE> }T
+T{ 1 CHARS 1 CELLS > -> <FALSE> }T
+( TBD: HOW TO FIND NUMBER OF BITS? )
+
+( CELLS >= 1 AU, INTEGRAL MULTIPLE OF CHAR SIZE, >= 16 BITS )
+T{ 1 CELLS 1 < -> <FALSE> }T
+T{ 1 CELLS 1 CHARS MOD -> 0 }T
+T{ 1S BITS 10 < -> <FALSE> }T
+
+T{ 0 1ST ! -> }T
+T{ 1 1ST +! -> }T
+T{ 1ST @ -> 1 }T
+T{ -1 1ST +! 1ST @ -> 0 }T
+
+\ ------------------------------------------------------------------------
+TESTING CHAR [CHAR] [ ] BL S"
+
+T{ BL -> 20 }T
+T{ CHAR X -> 58 }T
+T{ CHAR HELLO -> 48 }T
+T{ : GC1 [CHAR] X ; -> }T
+T{ : GC2 [CHAR] HELLO ; -> }T
+T{ GC1 -> 58 }T
+T{ GC2 -> 48 }T
+T{ : GC3 [ GC1 ] LITERAL ; -> }T
+T{ GC3 -> 58 }T
+T{ : GC4 S" XY" ; -> }T
+T{ GC4 SWAP DROP -> 2 }T
+T{ GC4 DROP DUP C@ SWAP CHAR+ C@ -> 58 59 }T
+
+\ ------------------------------------------------------------------------
+TESTING ' ['] FIND EXECUTE IMMEDIATE COUNT LITERAL POSTPONE STATE
+
+T{ : GT1 123 ; -> }T
+T{ ' GT1 EXECUTE -> 123 }T
+T{ : GT2 ['] GT1 ; IMMEDIATE -> }T
+T{ GT2 EXECUTE -> 123 }T
+HERE 3 C, CHAR G C, CHAR T C, CHAR 1 C, CONSTANT GT1STRING
+HERE 3 C, CHAR G C, CHAR T C, CHAR 2 C, CONSTANT GT2STRING
+T{ GT1STRING FIND -> ' GT1 -1 }T
+T{ GT2STRING FIND -> ' GT2 1 }T
+( HOW TO SEARCH FOR NON-EXISTENT WORD? )
+T{ : GT3 GT2 LITERAL ; -> }T
+T{ GT3 -> ' GT1 }T
+T{ GT1STRING COUNT -> GT1STRING CHAR+ 3 }T
+
+T{ : GT4 POSTPONE GT1 ; IMMEDIATE -> }T
+T{ : GT5 GT4 ; -> }T
+T{ GT5 -> 123 }T
+T{ : GT6 345 ; IMMEDIATE -> }T
+T{ : GT7 POSTPONE GT6 ; -> }T
+T{ GT7 -> 345 }T
+
+T{ : GT8 STATE @ ; IMMEDIATE -> }T
+T{ GT8 -> 0 }T
+T{ : GT9 GT8 LITERAL ; -> }T
+T{ GT9 0= -> <FALSE> }T
+
+\ ------------------------------------------------------------------------
+TESTING IF ELSE THEN BEGIN WHILE REPEAT UNTIL RECURSE
+
+T{ : GI1 IF 123 THEN ; -> }T
+T{ : GI2 IF 123 ELSE 234 THEN ; -> }T
+T{ 0 GI1 -> }T
+T{ 1 GI1 -> 123 }T
+T{ -1 GI1 -> 123 }T
+T{ 0 GI2 -> 234 }T
+T{ 1 GI2 -> 123 }T
+T{ -1 GI1 -> 123 }T
+
+T{ : GI3 BEGIN DUP 5 < WHILE DUP 1+ REPEAT ; -> }T
+T{ 0 GI3 -> 0 1 2 3 4 5 }T
+T{ 4 GI3 -> 4 5 }T
+T{ 5 GI3 -> 5 }T
+T{ 6 GI3 -> 6 }T
+
+T{ : GI4 BEGIN DUP 1+ DUP 5 > UNTIL ; -> }T
+T{ 3 GI4 -> 3 4 5 6 }T
+T{ 5 GI4 -> 5 6 }T
+T{ 6 GI4 -> 6 7 }T
+
+T{ : GI5 BEGIN DUP 2 > WHILE DUP 5 < WHILE DUP 1+ REPEAT 123 ELSE 345 THEN ; -> }T
+T{ 1 GI5 -> 1 345 }T
+T{ 2 GI5 -> 2 345 }T
+T{ 3 GI5 -> 3 4 5 123 }T
+T{ 4 GI5 -> 4 5 123 }T
+T{ 5 GI5 -> 5 123 }T
+
+T{ : GI6 ( N -- 0,1,..N ) DUP IF DUP >R 1- RECURSE R> THEN ; -> }T
+T{ 0 GI6 -> 0 }T
+T{ 1 GI6 -> 0 1 }T
+T{ 2 GI6 -> 0 1 2 }T
+T{ 3 GI6 -> 0 1 2 3 }T
+T{ 4 GI6 -> 0 1 2 3 4 }T
+
+\ ------------------------------------------------------------------------
+TESTING DO LOOP +LOOP I J UNLOOP LEAVE EXIT
+
+T{ : GD1 DO I LOOP ; -> }T
+T{ 4 1 GD1 -> 1 2 3 }T
+T{ 2 -1 GD1 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD1 -> MID-UINT }T
+
+T{ : GD2 DO I -1 +LOOP ; -> }T
+T{ 1 4 GD2 -> 4 3 2 1 }T
+T{ -1 2 GD2 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD2 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD3 DO 1 0 DO J LOOP LOOP ; -> }T
+T{ 4 1 GD3 -> 1 2 3 }T
+T{ 2 -1 GD3 -> -1 0 1 }T
+T{ MID-UINT+1 MID-UINT GD3 -> MID-UINT }T
+
+T{ : GD4 DO 1 0 DO J LOOP -1 +LOOP ; -> }T
+T{ 1 4 GD4 -> 4 3 2 1 }T
+T{ -1 2 GD4 -> 2 1 0 -1 }T
+T{ MID-UINT MID-UINT+1 GD4 -> MID-UINT+1 MID-UINT }T
+
+T{ : GD5 123 SWAP 0 DO I 4 > IF DROP 234 LEAVE THEN LOOP ; -> }T
+T{ 1 GD5 -> 123 }T
+T{ 5 GD5 -> 123 }T
+T{ 6 GD5 -> 234 }T
+
+T{ : GD6 ( PAT: T{0 0}T,T{0 0}TT{1 0}TT{1 1}T,T{0 0}TT{1 0}TT{1 1}TT{2 0}TT{2 1}TT{2 2}T )
+ 0 SWAP 0 DO
+ I 1+ 0 DO I J + 3 = IF I UNLOOP I UNLOOP EXIT THEN 1+ LOOP
+ LOOP ; -> }T
+T{ 1 GD6 -> 1 }T
+T{ 2 GD6 -> 3 }T
+T{ 3 GD6 -> 4 1 2 }T
+
+\ ------------------------------------------------------------------------
+TESTING DEFINING WORDS: : ; CONSTANT VARIABLE CREATE DOES> >BODY
+
+T{ 123 CONSTANT X123 -> }T
+T{ X123 -> 123 }T
+T{ : EQU CONSTANT ; -> }T
+T{ X123 EQU Y123 -> }T
+T{ Y123 -> 123 }T
+
+T{ VARIABLE V1 -> }T
+T{ 123 V1 ! -> }T
+T{ V1 @ -> 123 }T
+
+T{ : NOP : POSTPONE ; ; -> }T
+T{ NOP NOP1 NOP NOP2 -> }T
+T{ NOP1 -> }T
+T{ NOP2 -> }T
+
+T{ : DOES1 DOES> @ 1 + ; -> }T
+T{ : DOES2 DOES> @ 2 + ; -> }T
+T{ CREATE CR1 -> }T
+T{ CR1 -> HERE }T
+T{ ' CR1 >BODY -> HERE }T
+T{ 1 , -> }T
+T{ CR1 @ -> 1 }T
+T{ DOES1 -> }T
+T{ CR1 -> 2 }T
+T{ DOES2 -> }T
+T{ CR1 -> 3 }T
+
+T{ : WEIRD: CREATE DOES> 1 + DOES> 2 + ; -> }T
+T{ WEIRD: W1 -> }T
+T{ ' W1 >BODY -> HERE }T
+T{ W1 -> HERE 1 + }T
+T{ W1 -> HERE 2 + }T
+
+\ ------------------------------------------------------------------------
+TESTING EVALUATE
+
+: GE1 S" 123" ; IMMEDIATE
+: GE2 S" 123 1+" ; IMMEDIATE
+: GE3 S" : GE4 345 ;" ;
+: GE5 EVALUATE ; IMMEDIATE
+
+T{ GE1 EVALUATE -> 123 }T ( TEST EVALUATE IN INTERP. STATE )
+T{ GE2 EVALUATE -> 124 }T
+T{ GE3 EVALUATE -> }T
+T{ GE4 -> 345 }T
+
+T{ : GE6 GE1 GE5 ; -> }T ( TEST EVALUATE IN COMPILE STATE )
+T{ GE6 -> 123 }T
+T{ : GE7 GE2 GE5 ; -> }T
+T{ GE7 -> 124 }T
+
+\ ------------------------------------------------------------------------
+TESTING SOURCE >IN WORD
+
+: GS1 S" SOURCE" 2DUP EVALUATE
+ >R SWAP >R = R> R> = ;
+T{ GS1 -> <TRUE> <TRUE> }T
+
+VARIABLE SCANS
+: RESCAN? -1 SCANS +! SCANS @ IF 0 >IN ! THEN ;
+
+T{ 2 SCANS !
+345 RESCAN?
+-> 345 345 }T
+
+: GS2 5 SCANS ! S" 123 RESCAN?" EVALUATE ;
+T{ GS2 -> 123 123 123 123 123 }T
+
+: GS3 WORD COUNT SWAP C@ ;
+T{ BL GS3 HELLO -> 5 CHAR H }T
+T{ CHAR " GS3 GOODBYE" -> 7 CHAR G }T
+T{ BL GS3
+DROP -> 0 }T \ BLANK LINE RETURN ZERO-LENGTH STRING
+
+: GS4 SOURCE >IN ! DROP ;
+T{ GS4 123 456
+-> }T
+
+\ ------------------------------------------------------------------------
+TESTING <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL
+
+: S= \ ( ADDR1 C1 ADDR2 C2 -- T/F ) COMPARE TWO STRINGS.
+ >R SWAP R@ = IF \ MAKE SURE STRINGS HAVE SAME LENGTH
+ R> ?DUP IF \ IF NON-EMPTY STRINGS
+ 0 DO
+ OVER C@ OVER C@ - IF
+ 2DROP <FALSE> UNLOOP EXIT THEN
+ SWAP CHAR+ SWAP CHAR+
+ LOOP
+ THEN
+ 2DROP <TRUE> \ IF WE GET HERE, STRINGS MATCH
+ ELSE
+ R> DROP 2DROP <FALSE> \ LENGTHS MISMATCH
+ THEN ;
+
+: GP1 <# 41 HOLD 42 HOLD 0 0 #> S" BA" S= ;
+T{ GP1 -> <TRUE> }T
+
+: GP2 <# -1 SIGN 0 SIGN -1 SIGN 0 0 #> S" --" S= ;
+T{ GP2 -> <TRUE> }T
+
+: GP3 <# 1 0 # # #> S" 01" S= ;
+T{ GP3 -> <TRUE> }T
+
+: GP4 <# 1 0 #S #> S" 1" S= ;
+T{ GP4 -> <TRUE> }T
+
+24 CONSTANT MAX-BASE \ BASE 2 .. 36
+: COUNT-BITS
+ 0 0 INVERT BEGIN DUP WHILE >R 1+ R> 2* REPEAT DROP ;
+COUNT-BITS 2* CONSTANT #BITS-UD \ NUMBER OF BITS IN UD
+
+: GP5
+ BASE @ <TRUE>
+ MAX-BASE 1+ 2 DO \ FOR EACH POSSIBLE BASE
+ I BASE ! \ TBD: ASSUMES BASE WORKS
+ I 0 <# #S #> S" 10" S= AND
+ LOOP
+ SWAP BASE ! ;
+T{ GP5 -> <TRUE> }T
+
+: GP6
+ BASE @ >R 2 BASE !
+ MAX-UINT MAX-UINT <# #S #> \ MAXIMUM UD TO BINARY
+ R> BASE ! \ S: C-ADDR U
+ DUP #BITS-UD = SWAP
+ 0 DO \ S: C-ADDR FLAG
+ OVER C@ [CHAR] 1 = AND \ ALL ONES
+ >R CHAR+ R>
+ LOOP SWAP DROP ;
+T{ GP6 -> <TRUE> }T
+
+: GP7
+ BASE @ >R MAX-BASE BASE !
+ <TRUE>
+ A 0 DO
+ I 0 <# #S #>
+ 1 = SWAP C@ I 30 + = AND AND
+ LOOP
+ MAX-BASE A DO
+ I 0 <# #S #>
+ 1 = SWAP C@ 41 I A - + = AND AND
+ LOOP
+ R> BASE ! ;
+
+T{ GP7 -> <TRUE> }T
+
+\ >NUMBER TESTS
+CREATE GN-BUF 0 C,
+: GN-STRING GN-BUF 1 ;
+: GN-CONSUMED GN-BUF CHAR+ 0 ;
+: GN' [CHAR] ' WORD CHAR+ C@ GN-BUF C! GN-STRING ;
+
+T{ 0 0 GN' 0' >NUMBER -> 0 0 GN-CONSUMED }T
+T{ 0 0 GN' 1' >NUMBER -> 1 0 GN-CONSUMED }T
+T{ 1 0 GN' 1' >NUMBER -> BASE @ 1+ 0 GN-CONSUMED }T
+T{ 0 0 GN' -' >NUMBER -> 0 0 GN-STRING }T \ SHOULD FAIL TO CONVERT THESE
+T{ 0 0 GN' +' >NUMBER -> 0 0 GN-STRING }T
+T{ 0 0 GN' .' >NUMBER -> 0 0 GN-STRING }T
+
+: >NUMBER-BASED
+ BASE @ >R BASE ! >NUMBER R> BASE ! ;
+
+T{ 0 0 GN' 2' 10 >NUMBER-BASED -> 2 0 GN-CONSUMED }T
+T{ 0 0 GN' 2' 2 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' F' 10 >NUMBER-BASED -> F 0 GN-CONSUMED }T
+T{ 0 0 GN' G' 10 >NUMBER-BASED -> 0 0 GN-STRING }T
+T{ 0 0 GN' G' MAX-BASE >NUMBER-BASED -> 10 0 GN-CONSUMED }T
+T{ 0 0 GN' Z' MAX-BASE >NUMBER-BASED -> 23 0 GN-CONSUMED }T
+
+: GN1 \ ( UD BASE -- UD' LEN ) UD SHOULD EQUAL UD' AND LEN SHOULD BE ZERO.
+ BASE @ >R BASE !
+ <# #S #>
+ 0 0 2SWAP >NUMBER SWAP DROP \ RETURN LENGTH ONLY
+ R> BASE ! ;
+T{ 0 0 2 GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 2 GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP 2 GN1 -> MAX-UINT DUP 0 }T
+T{ 0 0 MAX-BASE GN1 -> 0 0 0 }T
+T{ MAX-UINT 0 MAX-BASE GN1 -> MAX-UINT 0 0 }T
+T{ MAX-UINT DUP MAX-BASE GN1 -> MAX-UINT DUP 0 }T
+
+: GN2 \ ( -- 16 10 )
+ BASE @ >R HEX BASE @ DECIMAL BASE @ R> BASE ! ;
+T{ GN2 -> 10 A }T
+
+\ ------------------------------------------------------------------------
+TESTING FILL MOVE
+
+CREATE FBUF 00 C, 00 C, 00 C,
+CREATE SBUF 12 C, 34 C, 56 C,
+: SEEBUF FBUF C@ FBUF CHAR+ C@ FBUF CHAR+ CHAR+ C@ ;
+
+T{ FBUF 0 20 FILL -> }T
+T{ SEEBUF -> 00 00 00 }T
+
+T{ FBUF 1 20 FILL -> }T
+T{ SEEBUF -> 20 00 00 }T
+
+T{ FBUF 3 20 FILL -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ FBUF FBUF 3 CHARS MOVE -> }T \ BIZARRE SPECIAL CASE
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 0 CHARS MOVE -> }T
+T{ SEEBUF -> 20 20 20 }T
+
+T{ SBUF FBUF 1 CHARS MOVE -> }T
+T{ SEEBUF -> 12 20 20 }T
+
+T{ SBUF FBUF 3 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 56 }T
+
+T{ FBUF FBUF CHAR+ 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 12 34 }T
+
+T{ FBUF CHAR+ FBUF 2 CHARS MOVE -> }T
+T{ SEEBUF -> 12 34 34 }T
+
+\ ------------------------------------------------------------------------
+TESTING OUTPUT: . ." CR EMIT SPACE SPACES TYPE U.
+
+: OUTPUT-TEST
+ ." YOU SHOULD SEE THE STANDARD GRAPHIC CHARACTERS:" CR
+ 41 BL DO I EMIT LOOP CR
+ 61 41 DO I EMIT LOOP CR
+ 7F 61 DO I EMIT LOOP CR
+ ." YOU SHOULD SEE 0-9 SEPARATED BY A SPACE:" CR
+ 9 1+ 0 DO I . LOOP CR
+ ." YOU SHOULD SEE 0-9 (WITH NO SPACES):" CR
+ [CHAR] 9 1+ [CHAR] 0 DO I 0 SPACES EMIT LOOP CR
+ ." YOU SHOULD SEE A-G SEPARATED BY A SPACE:" CR
+ [CHAR] G 1+ [CHAR] A DO I EMIT SPACE LOOP CR
+ ." YOU SHOULD SEE 0-5 SEPARATED BY TWO SPACES:" CR
+ 5 1+ 0 DO I [CHAR] 0 + EMIT 2 SPACES LOOP CR
+ ." YOU SHOULD SEE TWO SEPARATE LINES:" CR
+ S" LINE 1" TYPE CR S" LINE 2" TYPE CR
+ ." YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:" CR
+ ." SIGNED: " MIN-INT . MAX-INT . CR
+ ." UNSIGNED: " 0 U. MAX-UINT U. CR
+;
+
+T{ OUTPUT-TEST -> }T
+\ ------------------------------------------------------------------------
+TESTING INPUT: ACCEPT
+
+CREATE ABUF 80 CHARS ALLOT
+
+: ACCEPT-TEST
+ CR ." PLEASE TYPE UP TO 80 CHARACTERS:" CR
+\ ABUF 80 ACCEPT
+ ABUF 80 (ACCEPT) \ JMT: because ACCEPT is DEFERred to SD_ACCEPT
+ CR ." RECEIVED: " [CHAR] " EMIT
+ ABUF SWAP TYPE [CHAR] " EMIT CR
+;
+
+T{ ACCEPT-TEST -> }T
+\ ------------------------------------------------------------------------
+TESTING DICTIONARY SEARCH RULES
+
+T{ : GDX 123 ; : GDX GDX 234 ; -> }T
+
+T{ GDX -> 123 234 }T
+
+CR .( End of Core word set tests) CR
+
+
+$0A BASE !
+
+ ; happy end of core test
--- /dev/null
+\ -----------------------------------------------------------------------
+\ File Name TestASM.4th
+\ -----------------------------------------------------------------------
+
+\ -----------------------------------------------------------------------
+\ test CPUx instructions PUSHM, POPM, RLAM, RRAM, RRCM, RRUM
+\ -----------------------------------------------------------------------
+CODE TESTPUSHM
+ MOV #22222,Y
+ MOV #3,X
+ MOV #2,W
+ MOV #1,T
+ MOV #0,S
+\ PUSHM Y,IP \ uncomment to test error (registers bad order)
+ PUSHM IP,W \ PUSHM order : PSP,TOS,IP,S,T,W,X,Y,rEXIT,rDOVAR,rDOCON,rDODOES
+ POPM W,IP \ POPM order : rDODOES,rDOCON,rDOVAR,rEXIT,Y,X,W,T,S,IP,TOS,PSP
+ SUB #10,PSP
+ MOV TOS,8(PSP) \ save old TOS
+ MOV S,6(PSP)
+ MOV T,4(PSP)
+ MOV W,2(PSP)
+ MOV X,0(PSP)
+ MOV Y,TOS
+\ RLAM #0,TOS \ uncomment to test error (bad shift value)
+ RRAM #1,TOS \ 0 < shift value < 5
+ RLAM #2,TOS
+ RRCM #1,TOS
+ RRUM #1,TOS
+ COLON \ high level part of the word starts here...
+ space . . . . .
+ ; \ and finishes here.
+ \
+TESTPUSHM ; you should see 11111 3 2 1 0 -->
+
+CODE TESTPOPM
+ MOV #22222,Y
+ MOV #3,X
+ MOV #2,W
+ MOV #1,T
+ MOV #0,S
+\ PUSHM W,IP \ uncomment to test error "out of bounds"
+ PUSHM IP,W \ PUSHM order : PSP,TOS,IP,S,T,W,X,Y,rEXIT,rDOVAR,rDOCON,rDODOES
+ POPM W,IP \ POPM order : rDODOES,rDOCON,rDOVAR,rEXIT,Y,X,W,T,S,IP,TOS,PSP
+ SUB #10,PSP
+ MOV TOS,8(PSP) \ save old TOS
+ MOV S,6(PSP)
+ MOV T,4(PSP)
+ MOV W,2(PSP)
+ MOV X,0(PSP)
+ MOV Y,TOS
+\ RLAM #0,TOS \ uncomment to test error "out of bounds"
+\ RLAM #5,TOS \ uncomment to test error "out of bounds"
+ RRAM #1,TOS \ 0 < shift value < 5
+ RLAM #2,TOS
+ RRCM #1,TOS
+ RRUM #1,TOS
+ COLON \ high level part of the word starts here...
+ space . . . . .
+ ; \ and finishes here.
+ \
+TESTPOPM ; you should see 11111 3 2 1 0 -->
+
+
+
+\ -----------------------------------------------------------------------
+\ test symbolic branch in assembler
+\ test a FORTH section encapsulated in an assembly word
+\ -----------------------------------------------------------------------
+CODE TEST1 \ the word "CODE" add ASSEMBLER as CONTEXT vocabulary...
+
+ MOV &BASE,&BASE \ to test &xxxx src operand
+ CMP #%10,&BASE
+0<> IF MOV #2,&BASE \ if base <> 2
+ELSE MOV #$0A,&BASE \ else base = 2
+THEN
+ COLON \ tips : no "ok" displayed in start of line <==> compilation mode
+ BASE @ U. \ always display 10 !
+ ;
+ \
+
+\ -----------------------------------------------------------------------
+\ test a word that starts as word FORTH and ends as assembly word
+\ -----------------------------------------------------------------------
+: TEST2 \ ":" starts compilation
+ BASE @ U. \ always display 10 !
+ HI2LO \ switch FORTH to ASM : compile one word (next address)
+ \ add vocabulary ASSEMBLER as CONTEXT vocabulary
+ \ switch in interpret mode
+ CMP #2, &BASE
+0<> IF MOV #2, &BASE \ if variable system BASE <> 2
+ELSE MOV #10,&BASE \ else (BASE = 2)
+THEN
+\ MOV #EXIT,PC \ to pair with ":" i.e. to restore IP saved by : then execute NEXT.
+\ but even compile two words, it's better to compile an inline EXIT :
+ MOV @RSP+,IP \ restore IP
+ MOV @IP+,PC \ = NEXT
+ENDCODE \ ends assembler : remove vocabulary ASSEMBLER from CONTEXT
+ \
+
+\ -----------------------------------------------------------------------
+\ test a word that starts as assembly word and ends as FORTH word
+\ -----------------------------------------------------------------------
+CODE TEST3 \ "CODE" starts assembler, i.e. add ASSEMBLER as CONTEXT vocabulary
+ CMP #2, &BASE
+0<> IF MOV #2, &BASE \ if variable system BASE <> 2
+ELSE MOV #10,&BASE \ else (BASE = 2)
+THEN COLON \
+ BASE @ U. \ always display 10 !
+; \
+ \
+
+
+\ -----------------------------------------------------------------------
+\ test an assembly jump spanning a section written in FORTH
+\ -----------------------------------------------------------------------
+: TEST5
+ SPACE
+ HI2LO
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ MOV #%1010,TOS \ init count = 10
+BEGIN SUB #$0001,TOS
+ LO2HI
+ \ IP is already saved by word ":"
+ DUP U. \ display count
+ HI2LO
+ CMP #0,TOS
+0= UNTIL MOV @PSP+,TOS
+\ MOV #EXIT,PC \ to pair with ":" i.e. to restore IP saved by : then execute NEXT.
+ MOV @RSP+,IP \ restore IP
+ MOV @IP+,PC \ = NEXT
+ENDCODE
+ \
+TEST5 ; you should see : 9 8 7 6 5 4 3 2 1 0 -->
+ \
+
+\ -----------------------------------------------------------------------
+\ tests indexing address
+\ -----------------------------------------------------------------------
+
+: TABLE
+CREATE
+0 DO I C,
+LOOP
+DOES>
++
+;
+
+8 TABLE BYTES_TABLE
+ \
+2 BYTES_TABLE C@ . ; you should see 2 -->
+\
+
+
+VARIABLE BYTES_TABLE1
+
+$0201 BYTES_TABLE1 ! \ words written in memory are little endian !
+
+CODE IDX_TEST1 \ index -- value
+ MOV.B BYTES_TABLE1(TOS),TOS \ -- value
+COLON
+ U.
+;
+
+0 IDX_TEST1 ; you should see 1 -->
+
+CODE TEST6
+ MOV 0(PSP),0(PSP) \
+ MOV @IP+,PC
+ENDCODE
+
+
+1 TEST6 . ; you should see 1 -->
+
+
+\ -----------------------------------------------------------------------
+\ tests behaviour of assembly error
+\ -----------------------------------------------------------------------
+\ R16 causes an error, assembler context is aborted and the word TEST7 is "hidden".
+
+; CODE TEST7
+; MOV 0(PSP),0(R16) ; display an error "out of bounds" -->
+
+
+
+
+
+
--- /dev/null
+; -----------------------------------
+; prog10k.4th
+; -----------------------------------
+
+PWR_STATE
+
+PWR_STATE
+CODE MAX
+ CMP @R15,R14
+ S< ?GOTO FW1
+BW1 ADD #2,R15
+ MOV @R13+,R0
+ENDCODE
+
+CODE MIN
+ CMP @R15,R14
+ S< ?GOTO BW1
+FW1 MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+: U.R
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+
+CODE 20_US
+BEGIN
+ MOV #51,R10
+ BEGIN
+ SUB #1,R10
+ 0= UNTIL
+ SUB #1,R14
+0= UNTIL
+ MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE TOP_LCD
+ BIS.B #4,&$243
+ BIT.B #1,&$241
+0= IF
+ AND.B #$0F,R14
+ MOV.B R14,&$222
+ BIC.B #4,&$243
+ MOV @R15+,R14
+ MOV @R13+,R0
+THEN
+ SUB #2,R15
+ MOV R14,0(R15)
+ BIC.B #4,&$243
+ MOV.B &$220,R14
+ AND.B #$0F,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE LCD_W
+ SUB #2,R15
+ MOV R14,0(R15)
+ RRUM #4,R14
+ BIC.B #1,&$243
+ BIS.B #$0F,&$224
+COLON
+ TOP_LCD 2 20_US
+ TOP_LCD 2 20_US
+;
+
+CODE LCD_WrC
+ BIS.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+CODE LCD_WrF
+ BIC.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us
+;
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+
+ASM WDT_INT
+BIC #$F8,0(R1)
+BIT.B #$20,&$240
+0= IF
+ CMP #38,&$3D6
+ U< IF
+ ADD #1,&$3D6
+ THEN
+ELSE
+ BIT.B #$40,&$240
+ 0= IF
+ CMP #7,&$3D6
+ U>= IF
+ SUB #1,&$3D6
+ THEN
+ THEN
+THEN
+RETI
+ENDASM
+
+ASM RC5_INT
+BIC #$F8,0(R1)
+MOV #0,&$360
+MOV #1778,R9
+MOV #14,R10
+BEGIN
+ MOV #%1011100100,&$340
+ RRUM #1,R9
+ MOV R9,R8
+ RRUM #1,R8
+ ADD R9,R8
+ BEGIN CMP R8,&$350
+ 0= UNTIL
+ BIT.B #4,&$200
+ ADDC R13,R13
+ MOV &$200,&$208
+ BIC.B #4,&$20C
+ SUB #1,R10
+0<> WHILE
+ ADD R9,R8
+ BEGIN
+ CMP R8,&$350
+ 0>= IF
+ BIC #$30,&$340
+ RETI
+ THEN
+ BIT.B #4,&$20C
+ 0<> UNTIL
+ MOV &$350,R9
+REPEAT
+BIC #$30,&$340
+RLAM #1,R13
+MOV @R1,R9
+RLAM #4,R9
+XOR R13,R9
+BIT #$2000,R9
+0= IF RETI
+THEN
+XOR #$200,0(R1)
+SUB #4,R15
+MOV &$1DDA,2(R15)
+MOV R14,0(R15)
+MOV.B R13,R14
+RRUM #2,R14
+BIT #$4000,R13
+0= IF BIS #$40,R14
+THEN
+LO2HI
+ ['] LCD_CLEAR IS CR
+ ['] LCD_WrC IS EMIT
+ $10 $1DDA !
+ CR ." $" 2 U.R
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+HI2LO
+MOV @R15+,&$1DDA
+RETI
+ENDASM
+
+CODE START
+ MOV #%1010010100,&$3C0
+ MOV #0,&$3E0
+ MOV #40,&$3D2
+ MOV #%1100000,&$3C6
+ MOV #25,&$3D6
+ BIS.B #$20,&$204
+ BIS.B #$20,&$20A
+ BIS.B #7,&$245
+ BIC.B #7,&$247
+ BIS.B #$0F,&$224
+ BIC.B #$0F,&$226
+ MOV #$5A5E,&$15C
+ BIS #1,&$100
+ BIS.B #4,&$20A
+ BIC.B #4,&$20C
+ MOV #WDT_INT,&$FFF2
+ MOV #RC5_INT,&$FFDE
+LO2HI
+ $03E8 20_US
+ $03 TOP_LCD
+ $CD 20_US
+ $03 TOP_LCD
+ $5 20_US
+ $03 TOP_LCD
+ $2 20_US
+ $02 TOP_LCD
+ $2 20_US
+ $28 LCD_WRF
+ $08 LCD_WRF
+ LCD_Clear
+ $06 LCD_WRF
+ $0C LCD_WRF
+ LCD_Clear
+ ['] LCD_HOME IS CR
+ ['] LCD_WRC IS EMIT
+ CR ." I love you"
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+ LIT RECURSE IS WARM
+ (WARM)
+;
+
+: STOP
+ ['] (WARM) IS WARM
+ ECHO COLD
+;
+
+PWR_STATE
+CODE MAX
+ CMP @R15,R14
+ S< ?GOTO FW1
+BW1 ADD #2,R15
+ MOV @R13+,R0
+ENDCODE
+
+CODE MIN
+ CMP @R15,R14
+ S< ?GOTO BW1
+FW1 MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+: U.R
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+
+CODE 20_US
+BEGIN
+ MOV #51,R10
+ BEGIN
+ SUB #1,R10
+ 0= UNTIL
+ SUB #1,R14
+0= UNTIL
+ MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE TOP_LCD
+ BIS.B #4,&$243
+ BIT.B #1,&$241
+0= IF
+ AND.B #$0F,R14
+ MOV.B R14,&$222
+ BIC.B #4,&$243
+ MOV @R15+,R14
+ MOV @R13+,R0
+THEN
+ SUB #2,R15
+ MOV R14,0(R15)
+ BIC.B #4,&$243
+ MOV.B &$220,R14
+ AND.B #$0F,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE LCD_W
+ SUB #2,R15
+ MOV R14,0(R15)
+ RRUM #4,R14
+ BIC.B #1,&$243
+ BIS.B #$0F,&$224
+COLON
+ TOP_LCD 2 20_US
+ TOP_LCD 2 20_US
+;
+
+CODE LCD_WrC
+ BIS.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+CODE LCD_WrF
+ BIC.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us
+;
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+
+ASM WDT_INT
+BIC #$F8,0(R1)
+BIT.B #$20,&$240
+0= IF
+ CMP #38,&$3D6
+ U< IF
+ ADD #1,&$3D6
+ THEN
+ELSE
+ BIT.B #$40,&$240
+ 0= IF
+ CMP #7,&$3D6
+ U>= IF
+ SUB #1,&$3D6
+ THEN
+ THEN
+THEN
+RETI
+ENDASM
+
+ASM RC5_INT
+BIC #$F8,0(R1)
+MOV #0,&$360
+MOV #1778,R9
+MOV #14,R10
+BEGIN
+ MOV #%1011100100,&$340
+ RRUM #1,R9
+ MOV R9,R8
+ RRUM #1,R8
+ ADD R9,R8
+ BEGIN CMP R8,&$350
+ 0= UNTIL
+ BIT.B #4,&$200
+ ADDC R13,R13
+ MOV &$200,&$208
+ BIC.B #4,&$20C
+ SUB #1,R10
+0<> WHILE
+ ADD R9,R8
+ BEGIN
+ CMP R8,&$350
+ 0>= IF
+ BIC #$30,&$340
+ RETI
+ THEN
+ BIT.B #4,&$20C
+ 0<> UNTIL
+ MOV &$350,R9
+REPEAT
+BIC #$30,&$340
+RLAM #1,R13
+MOV @R1,R9
+RLAM #4,R9
+XOR R13,R9
+BIT #$2000,R9
+0= IF RETI
+THEN
+XOR #$200,0(R1)
+SUB #4,R15
+MOV &$1DDA,2(R15)
+MOV R14,0(R15)
+MOV.B R13,R14
+RRUM #2,R14
+BIT #$4000,R13
+0= IF BIS #$40,R14
+THEN
+LO2HI
+ ['] LCD_CLEAR IS CR
+ ['] LCD_WrC IS EMIT
+ $10 $1DDA !
+ CR ." $" 2 U.R
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+HI2LO
+MOV @R15+,&$1DDA
+RETI
+ENDASM
+
+CODE START
+ MOV #%1010010100,&$3C0
+ MOV #0,&$3E0
+ MOV #40,&$3D2
+ MOV #%1100000,&$3C6
+ MOV #25,&$3D6
+ BIS.B #$20,&$204
+ BIS.B #$20,&$20A
+ BIS.B #7,&$245
+ BIC.B #7,&$247
+ BIS.B #$0F,&$224
+ BIC.B #$0F,&$226
+ MOV #$5A5E,&$15C
+ BIS #1,&$100
+ BIS.B #4,&$20A
+ BIC.B #4,&$20C
+ MOV #WDT_INT,&$FFF2
+ MOV #RC5_INT,&$FFDE
+LO2HI
+ $03E8 20_US
+ $03 TOP_LCD
+ $CD 20_US
+ $03 TOP_LCD
+ $5 20_US
+ $03 TOP_LCD
+ $2 20_US
+ $02 TOP_LCD
+ $2 20_US
+ $28 LCD_WRF
+ $08 LCD_WRF
+ LCD_Clear
+ $06 LCD_WRF
+ $0C LCD_WRF
+ LCD_Clear
+ ['] LCD_HOME IS CR
+ ['] LCD_WRC IS EMIT
+ CR ." I love you"
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+ LIT RECURSE IS WARM
+ (WARM)
+;
+
+: STOP
+ ['] (WARM) IS WARM
+ ECHO COLD
+;
+
+PWR_STATE
+CODE MAX
+ CMP @R15,R14
+ S< ?GOTO FW1
+BW1 ADD #2,R15
+ MOV @R13+,R0
+ENDCODE
+
+CODE MIN
+ CMP @R15,R14
+ S< ?GOTO BW1
+FW1 MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+: U.R
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+
+CODE 20_US
+BEGIN
+ MOV #51,R10
+ BEGIN
+ SUB #1,R10
+ 0= UNTIL
+ SUB #1,R14
+0= UNTIL
+ MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE TOP_LCD
+ BIS.B #4,&$243
+ BIT.B #1,&$241
+0= IF
+ AND.B #$0F,R14
+ MOV.B R14,&$222
+ BIC.B #4,&$243
+ MOV @R15+,R14
+ MOV @R13+,R0
+THEN
+ SUB #2,R15
+ MOV R14,0(R15)
+ BIC.B #4,&$243
+ MOV.B &$220,R14
+ AND.B #$0F,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE LCD_W
+ SUB #2,R15
+ MOV R14,0(R15)
+ RRUM #4,R14
+ BIC.B #1,&$243
+ BIS.B #$0F,&$224
+COLON
+ TOP_LCD 2 20_US
+ TOP_LCD 2 20_US
+;
+
+CODE LCD_WrC
+ BIS.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+CODE LCD_WrF
+ BIC.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us
+;
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+
+ASM WDT_INT
+BIC #$F8,0(R1)
+BIT.B #$20,&$240
+0= IF
+ CMP #38,&$3D6
+ U< IF
+ ADD #1,&$3D6
+ THEN
+ELSE
+ BIT.B #$40,&$240
+ 0= IF
+ CMP #7,&$3D6
+ U>= IF
+ SUB #1,&$3D6
+ THEN
+ THEN
+THEN
+RETI
+ENDASM
+
+ASM RC5_INT
+BIC #$F8,0(R1)
+MOV #0,&$360
+MOV #1778,R9
+MOV #14,R10
+BEGIN
+ MOV #%1011100100,&$340
+ RRUM #1,R9
+ MOV R9,R8
+ RRUM #1,R8
+ ADD R9,R8
+ BEGIN CMP R8,&$350
+ 0= UNTIL
+ BIT.B #4,&$200
+ ADDC R13,R13
+ MOV &$200,&$208
+ BIC.B #4,&$20C
+ SUB #1,R10
+0<> WHILE
+ ADD R9,R8
+ BEGIN
+ CMP R8,&$350
+ 0>= IF
+ BIC #$30,&$340
+ RETI
+ THEN
+ BIT.B #4,&$20C
+ 0<> UNTIL
+ MOV &$350,R9
+REPEAT
+BIC #$30,&$340
+RLAM #1,R13
+MOV @R1,R9
+RLAM #4,R9
+XOR R13,R9
+BIT #$2000,R9
+0= IF RETI
+THEN
+XOR #$200,0(R1)
+SUB #4,R15
+MOV &$1DDA,2(R15)
+MOV R14,0(R15)
+MOV.B R13,R14
+RRUM #2,R14
+BIT #$4000,R13
+0= IF BIS #$40,R14
+THEN
+LO2HI
+ ['] LCD_CLEAR IS CR
+ ['] LCD_WrC IS EMIT
+ $10 $1DDA !
+ CR ." $" 2 U.R
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+HI2LO
+MOV @R15+,&$1DDA
+RETI
+ENDASM
+
+CODE START
+ MOV #%1010010100,&$3C0
+ MOV #0,&$3E0
+ MOV #40,&$3D2
+ MOV #%1100000,&$3C6
+ MOV #25,&$3D6
+ BIS.B #$20,&$204
+ BIS.B #$20,&$20A
+ BIS.B #7,&$245
+ BIC.B #7,&$247
+ BIS.B #$0F,&$224
+ BIC.B #$0F,&$226
+ MOV #$5A5E,&$15C
+ BIS #1,&$100
+ BIS.B #4,&$20A
+ BIC.B #4,&$20C
+ MOV #WDT_INT,&$FFF2
+ MOV #RC5_INT,&$FFDE
+LO2HI
+ $03E8 20_US
+ $03 TOP_LCD
+ $CD 20_US
+ $03 TOP_LCD
+ $5 20_US
+ $03 TOP_LCD
+ $2 20_US
+ $02 TOP_LCD
+ $2 20_US
+ $28 LCD_WRF
+ $08 LCD_WRF
+ LCD_Clear
+ $06 LCD_WRF
+ $0C LCD_WRF
+ LCD_Clear
+ ['] LCD_HOME IS CR
+ ['] LCD_WRC IS EMIT
+ CR ." I love you"
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+ LIT RECURSE IS WARM
+ (WARM)
+;
+
+: STOP
+ ['] (WARM) IS WARM
+ ECHO COLD
+;
+
+PWR_STATE
+CODE MAX
+ CMP @R15,R14
+ S< ?GOTO FW1
+BW1 ADD #2,R15
+ MOV @R13+,R0
+ENDCODE
+
+CODE MIN
+ CMP @R15,R14
+ S< ?GOTO BW1
+FW1 MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+: U.R
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+
+CODE 20_US
+BEGIN
+ MOV #51,R10
+ BEGIN
+ SUB #1,R10
+ 0= UNTIL
+ SUB #1,R14
+0= UNTIL
+ MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE TOP_LCD
+ BIS.B #4,&$243
+ BIT.B #1,&$241
+0= IF
+ AND.B #$0F,R14
+ MOV.B R14,&$222
+ BIC.B #4,&$243
+ MOV @R15+,R14
+ MOV @R13+,R0
+THEN
+ SUB #2,R15
+ MOV R14,0(R15)
+ BIC.B #4,&$243
+ MOV.B &$220,R14
+ AND.B #$0F,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE LCD_W
+ SUB #2,R15
+ MOV R14,0(R15)
+ RRUM #4,R14
+ BIC.B #1,&$243
+ BIS.B #$0F,&$224
+COLON
+ TOP_LCD 2 20_US
+ TOP_LCD 2 20_US
+;
+
+CODE LCD_WrC
+ BIS.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+CODE LCD_WrF
+ BIC.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us
+;
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+
+ASM WDT_INT
+BIC #$F8,0(R1)
+BIT.B #$20,&$240
+0= IF
+ CMP #38,&$3D6
+ U< IF
+ ADD #1,&$3D6
+ THEN
+ELSE
+ BIT.B #$40,&$240
+ 0= IF
+ CMP #7,&$3D6
+ U>= IF
+ SUB #1,&$3D6
+ THEN
+ THEN
+THEN
+RETI
+ENDASM
+
+ASM RC5_INT
+BIC #$F8,0(R1)
+MOV #0,&$360
+MOV #1778,R9
+MOV #14,R10
+BEGIN
+ MOV #%1011100100,&$340
+ RRUM #1,R9
+ MOV R9,R8
+ RRUM #1,R8
+ ADD R9,R8
+ BEGIN CMP R8,&$350
+ 0= UNTIL
+ BIT.B #4,&$200
+ ADDC R13,R13
+ MOV &$200,&$208
+ BIC.B #4,&$20C
+ SUB #1,R10
+0<> WHILE
+ ADD R9,R8
+ BEGIN
+ CMP R8,&$350
+ 0>= IF
+ BIC #$30,&$340
+ RETI
+ THEN
+ BIT.B #4,&$20C
+ 0<> UNTIL
+ MOV &$350,R9
+REPEAT
+BIC #$30,&$340
+RLAM #1,R13
+MOV @R1,R9
+RLAM #4,R9
+XOR R13,R9
+BIT #$2000,R9
+0= IF RETI
+THEN
+XOR #$200,0(R1)
+SUB #4,R15
+MOV &$1DDA,2(R15)
+MOV R14,0(R15)
+MOV.B R13,R14
+RRUM #2,R14
+BIT #$4000,R13
+0= IF BIS #$40,R14
+THEN
+LO2HI
+ ['] LCD_CLEAR IS CR
+ ['] LCD_WrC IS EMIT
+ $10 $1DDA !
+ CR ." $" 2 U.R
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+HI2LO
+MOV @R15+,&$1DDA
+RETI
+ENDASM
+
+CODE START
+ MOV #%1010010100,&$3C0
+ MOV #0,&$3E0
+ MOV #40,&$3D2
+ MOV #%1100000,&$3C6
+ MOV #25,&$3D6
+ BIS.B #$20,&$204
+ BIS.B #$20,&$20A
+ BIS.B #7,&$245
+ BIC.B #7,&$247
+ BIS.B #$0F,&$224
+ BIC.B #$0F,&$226
+ MOV #$5A5E,&$15C
+ BIS #1,&$100
+ BIS.B #4,&$20A
+ BIC.B #4,&$20C
+ MOV #WDT_INT,&$FFF2
+ MOV #RC5_INT,&$FFDE
+LO2HI
+ $03E8 20_US
+ $03 TOP_LCD
+ $CD 20_US
+ $03 TOP_LCD
+ $5 20_US
+ $03 TOP_LCD
+ $2 20_US
+ $02 TOP_LCD
+ $2 20_US
+ $28 LCD_WRF
+ $08 LCD_WRF
+ LCD_Clear
+ $06 LCD_WRF
+ $0C LCD_WRF
+ LCD_Clear
+ ['] LCD_HOME IS CR
+ ['] LCD_WRC IS EMIT
+ CR ." I love you"
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+ LIT RECURSE IS WARM
+ (WARM)
+;
+
+: STOP
+ ['] (WARM) IS WARM
+ ECHO COLD
+;
+
+PWR_STATE
+CODE MAX
+ CMP @R15,R14
+ S< ?GOTO FW1
+BW1 ADD #2,R15
+ MOV @R13+,R0
+ENDCODE
+
+CODE MIN
+ CMP @R15,R14
+ S< ?GOTO BW1
+FW1 MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+: U.R
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+
+CODE 20_US
+BEGIN
+ MOV #51,R10
+ BEGIN
+ SUB #1,R10
+ 0= UNTIL
+ SUB #1,R14
+0= UNTIL
+ MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE TOP_LCD
+ BIS.B #4,&$243
+ BIT.B #1,&$241
+0= IF
+ AND.B #$0F,R14
+ MOV.B R14,&$222
+ BIC.B #4,&$243
+ MOV @R15+,R14
+ MOV @R13+,R0
+THEN
+ SUB #2,R15
+ MOV R14,0(R15)
+ BIC.B #4,&$243
+ MOV.B &$220,R14
+ AND.B #$0F,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE LCD_W
+ SUB #2,R15
+ MOV R14,0(R15)
+ RRUM #4,R14
+ BIC.B #1,&$243
+ BIS.B #$0F,&$224
+COLON
+ TOP_LCD 2 20_US
+ TOP_LCD 2 20_US
+;
+
+CODE LCD_WrC
+ BIS.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+CODE LCD_WrF
+ BIC.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us
+;
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+
+ASM WDT_INT
+BIC #$F8,0(R1)
+BIT.B #$20,&$240
+0= IF
+ CMP #38,&$3D6
+ U< IF
+ ADD #1,&$3D6
+ THEN
+ELSE
+ BIT.B #$40,&$240
+ 0= IF
+ CMP #7,&$3D6
+ U>= IF
+ SUB #1,&$3D6
+ THEN
+ THEN
+THEN
+RETI
+ENDASM
+
+ASM RC5_INT
+BIC #$F8,0(R1)
+MOV #0,&$360
+MOV #1778,R9
+MOV #14,R10
+BEGIN
+ MOV #%1011100100,&$340
+ RRUM #1,R9
+ MOV R9,R8
+ RRUM #1,R8
+ ADD R9,R8
+ BEGIN CMP R8,&$350
+ 0= UNTIL
+ BIT.B #4,&$200
+ ADDC R13,R13
+ MOV &$200,&$208
+ BIC.B #4,&$20C
+ SUB #1,R10
+0<> WHILE
+ ADD R9,R8
+ BEGIN
+ CMP R8,&$350
+ 0>= IF
+ BIC #$30,&$340
+ RETI
+ THEN
+ BIT.B #4,&$20C
+ 0<> UNTIL
+ MOV &$350,R9
+REPEAT
+BIC #$30,&$340
+RLAM #1,R13
+MOV @R1,R9
+RLAM #4,R9
+XOR R13,R9
+BIT #$2000,R9
+0= IF RETI
+THEN
+XOR #$200,0(R1)
+SUB #4,R15
+MOV &$1DDA,2(R15)
+MOV R14,0(R15)
+MOV.B R13,R14
+RRUM #2,R14
+BIT #$4000,R13
+0= IF BIS #$40,R14
+THEN
+LO2HI
+ ['] LCD_CLEAR IS CR
+ ['] LCD_WrC IS EMIT
+ $10 $1DDA !
+ CR ." $" 2 U.R
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+HI2LO
+MOV @R15+,&$1DDA
+RETI
+ENDASM
+
+CODE START
+ MOV #%1010010100,&$3C0
+ MOV #0,&$3E0
+ MOV #40,&$3D2
+ MOV #%1100000,&$3C6
+ MOV #25,&$3D6
+ BIS.B #$20,&$204
+ BIS.B #$20,&$20A
+ BIS.B #7,&$245
+ BIC.B #7,&$247
+ BIS.B #$0F,&$224
+ BIC.B #$0F,&$226
+ MOV #$5A5E,&$15C
+ BIS #1,&$100
+ BIS.B #4,&$20A
+ BIC.B #4,&$20C
+ MOV #WDT_INT,&$FFF2
+ MOV #RC5_INT,&$FFDE
+LO2HI
+ $03E8 20_US
+ $03 TOP_LCD
+ $CD 20_US
+ $03 TOP_LCD
+ $5 20_US
+ $03 TOP_LCD
+ $2 20_US
+ $02 TOP_LCD
+ $2 20_US
+ $28 LCD_WRF
+ $08 LCD_WRF
+ LCD_Clear
+ $06 LCD_WRF
+ $0C LCD_WRF
+ LCD_Clear
+ ['] LCD_HOME IS CR
+ ['] LCD_WRC IS EMIT
+ CR ." I love you"
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+ LIT RECURSE IS WARM
+ (WARM)
+;
+
+: STOP
+ ['] (WARM) IS WARM
+ ECHO COLD
+;
+
+PWR_STATE
+CODE MAX
+ CMP @R15,R14
+ S< ?GOTO FW1
+BW1 ADD #2,R15
+ MOV @R13+,R0
+ENDCODE
+
+CODE MIN
+ CMP @R15,R14
+ S< ?GOTO BW1
+FW1 MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+: U.R
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+
+CODE 20_US
+BEGIN
+ MOV #51,R10
+ BEGIN
+ SUB #1,R10
+ 0= UNTIL
+ SUB #1,R14
+0= UNTIL
+ MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE TOP_LCD
+ BIS.B #4,&$243
+ BIT.B #1,&$241
+0= IF
+ AND.B #$0F,R14
+ MOV.B R14,&$222
+ BIC.B #4,&$243
+ MOV @R15+,R14
+ MOV @R13+,R0
+THEN
+ SUB #2,R15
+ MOV R14,0(R15)
+ BIC.B #4,&$243
+ MOV.B &$220,R14
+ AND.B #$0F,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE LCD_W
+ SUB #2,R15
+ MOV R14,0(R15)
+ RRUM #4,R14
+ BIC.B #1,&$243
+ BIS.B #$0F,&$224
+COLON
+ TOP_LCD 2 20_US
+ TOP_LCD 2 20_US
+;
+
+CODE LCD_WrC
+ BIS.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+CODE LCD_WrF
+ BIC.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us
+;
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+
+ASM WDT_INT
+BIC #$F8,0(R1)
+BIT.B #$20,&$240
+0= IF
+ CMP #38,&$3D6
+ U< IF
+ ADD #1,&$3D6
+ THEN
+ELSE
+ BIT.B #$40,&$240
+ 0= IF
+ CMP #7,&$3D6
+ U>= IF
+ SUB #1,&$3D6
+ THEN
+ THEN
+THEN
+RETI
+ENDASM
+
+ASM RC5_INT
+BIC #$F8,0(R1)
+MOV #0,&$360
+MOV #1778,R9
+MOV #14,R10
+BEGIN
+ MOV #%1011100100,&$340
+ RRUM #1,R9
+ MOV R9,R8
+ RRUM #1,R8
+ ADD R9,R8
+ BEGIN CMP R8,&$350
+ 0= UNTIL
+ BIT.B #4,&$200
+ ADDC R13,R13
+ MOV &$200,&$208
+ BIC.B #4,&$20C
+ SUB #1,R10
+0<> WHILE
+ ADD R9,R8
+ BEGIN
+ CMP R8,&$350
+ 0>= IF
+ BIC #$30,&$340
+ RETI
+ THEN
+ BIT.B #4,&$20C
+ 0<> UNTIL
+ MOV &$350,R9
+REPEAT
+BIC #$30,&$340
+RLAM #1,R13
+MOV @R1,R9
+RLAM #4,R9
+XOR R13,R9
+BIT #$2000,R9
+0= IF RETI
+THEN
+XOR #$200,0(R1)
+SUB #4,R15
+MOV &$1DDA,2(R15)
+MOV R14,0(R15)
+MOV.B R13,R14
+RRUM #2,R14
+BIT #$4000,R13
+0= IF BIS #$40,R14
+THEN
+LO2HI
+ ['] LCD_CLEAR IS CR
+ ['] LCD_WrC IS EMIT
+ $10 $1DDA !
+ CR ." $" 2 U.R
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+HI2LO
+MOV @R15+,&$1DDA
+RETI
+ENDASM
+
+CODE START
+ MOV #%1010010100,&$3C0
+ MOV #0,&$3E0
+ MOV #40,&$3D2
+ MOV #%1100000,&$3C6
+ MOV #25,&$3D6
+ BIS.B #$20,&$204
+ BIS.B #$20,&$20A
+ BIS.B #7,&$245
+ BIC.B #7,&$247
+ BIS.B #$0F,&$224
+ BIC.B #$0F,&$226
+ MOV #$5A5E,&$15C
+ BIS #1,&$100
+ BIS.B #4,&$20A
+ BIC.B #4,&$20C
+ MOV #WDT_INT,&$FFF2
+ MOV #RC5_INT,&$FFDE
+LO2HI
+ $03E8 20_US
+ $03 TOP_LCD
+ $CD 20_US
+ $03 TOP_LCD
+ $5 20_US
+ $03 TOP_LCD
+ $2 20_US
+ $02 TOP_LCD
+ $2 20_US
+ $28 LCD_WRF
+ $08 LCD_WRF
+ LCD_Clear
+ $06 LCD_WRF
+ $0C LCD_WRF
+ LCD_Clear
+ ['] LCD_HOME IS CR
+ ['] LCD_WRC IS EMIT
+ CR ." I love you"
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+ LIT RECURSE IS WARM
+ (WARM)
+;
+
+: STOP
+ ['] (WARM) IS WARM
+ ECHO COLD
+;
+
+PWR_STATE
+CODE MAX
+ CMP @R15,R14
+ S< ?GOTO FW1
+BW1 ADD #2,R15
+ MOV @R13+,R0
+ENDCODE
+
+CODE MIN
+ CMP @R15,R14
+ S< ?GOTO BW1
+FW1 MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+: U.R
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+
+CODE 20_US
+BEGIN
+ MOV #51,R10
+ BEGIN
+ SUB #1,R10
+ 0= UNTIL
+ SUB #1,R14
+0= UNTIL
+ MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE TOP_LCD
+ BIS.B #4,&$243
+ BIT.B #1,&$241
+0= IF
+ AND.B #$0F,R14
+ MOV.B R14,&$222
+ BIC.B #4,&$243
+ MOV @R15+,R14
+ MOV @R13+,R0
+THEN
+ SUB #2,R15
+ MOV R14,0(R15)
+ BIC.B #4,&$243
+ MOV.B &$220,R14
+ AND.B #$0F,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE LCD_W
+ SUB #2,R15
+ MOV R14,0(R15)
+ RRUM #4,R14
+ BIC.B #1,&$243
+ BIS.B #$0F,&$224
+COLON
+ TOP_LCD 2 20_US
+ TOP_LCD 2 20_US
+;
+
+CODE LCD_WrC
+ BIS.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+CODE LCD_WrF
+ BIC.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us
+;
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+
+ASM WDT_INT
+BIC #$F8,0(R1)
+BIT.B #$20,&$240
+0= IF
+ CMP #38,&$3D6
+ U< IF
+ ADD #1,&$3D6
+ THEN
+ELSE
+ BIT.B #$40,&$240
+ 0= IF
+ CMP #7,&$3D6
+ U>= IF
+ SUB #1,&$3D6
+ THEN
+ THEN
+THEN
+RETI
+ENDASM
+
+ASM RC5_INT
+BIC #$F8,0(R1)
+MOV #0,&$360
+MOV #1778,R9
+MOV #14,R10
+BEGIN
+ MOV #%1011100100,&$340
+ RRUM #1,R9
+ MOV R9,R8
+ RRUM #1,R8
+ ADD R9,R8
+ BEGIN CMP R8,&$350
+ 0= UNTIL
+ BIT.B #4,&$200
+ ADDC R13,R13
+ MOV &$200,&$208
+ BIC.B #4,&$20C
+ SUB #1,R10
+0<> WHILE
+ ADD R9,R8
+ BEGIN
+ CMP R8,&$350
+ 0>= IF
+ BIC #$30,&$340
+ RETI
+ THEN
+ BIT.B #4,&$20C
+ 0<> UNTIL
+ MOV &$350,R9
+REPEAT
+BIC #$30,&$340
+RLAM #1,R13
+MOV @R1,R9
+RLAM #4,R9
+XOR R13,R9
+BIT #$2000,R9
+0= IF RETI
+THEN
+XOR #$200,0(R1)
+SUB #4,R15
+MOV &$1DDA,2(R15)
+MOV R14,0(R15)
+MOV.B R13,R14
+RRUM #2,R14
+BIT #$4000,R13
+0= IF BIS #$40,R14
+THEN
+LO2HI
+ ['] LCD_CLEAR IS CR
+ ['] LCD_WrC IS EMIT
+ $10 $1DDA !
+ CR ." $" 2 U.R
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+HI2LO
+MOV @R15+,&$1DDA
+RETI
+ENDASM
+
+CODE START
+ MOV #%1010010100,&$3C0
+ MOV #0,&$3E0
+ MOV #40,&$3D2
+ MOV #%1100000,&$3C6
+ MOV #25,&$3D6
+ BIS.B #$20,&$204
+ BIS.B #$20,&$20A
+ BIS.B #7,&$245
+ BIC.B #7,&$247
+ BIS.B #$0F,&$224
+ BIC.B #$0F,&$226
+ MOV #$5A5E,&$15C
+ BIS #1,&$100
+ BIS.B #4,&$20A
+ BIC.B #4,&$20C
+ MOV #WDT_INT,&$FFF2
+ MOV #RC5_INT,&$FFDE
+LO2HI
+ $03E8 20_US
+ $03 TOP_LCD
+ $CD 20_US
+ $03 TOP_LCD
+ $5 20_US
+ $03 TOP_LCD
+ $2 20_US
+ $02 TOP_LCD
+ $2 20_US
+ $28 LCD_WRF
+ $08 LCD_WRF
+ LCD_Clear
+ $06 LCD_WRF
+ $0C LCD_WRF
+ LCD_Clear
+ ['] LCD_HOME IS CR
+ ['] LCD_WRC IS EMIT
+ CR ." I love you"
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+ LIT RECURSE IS WARM
+ (WARM)
+;
+
+: STOP
+ ['] (WARM) IS WARM
+ ECHO COLD
+;
+
+PWR_STATE
+CODE MAX
+ CMP @R15,R14
+ S< ?GOTO FW1
+BW1 ADD #2,R15
+ MOV @R13+,R0
+ENDCODE
+
+CODE MIN
+ CMP @R15,R14
+ S< ?GOTO BW1
+FW1 MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+: U.R
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+
+CODE 20_US
+BEGIN
+ MOV #51,R10
+ BEGIN
+ SUB #1,R10
+ 0= UNTIL
+ SUB #1,R14
+0= UNTIL
+ MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE TOP_LCD
+ BIS.B #4,&$243
+ BIT.B #1,&$241
+0= IF
+ AND.B #$0F,R14
+ MOV.B R14,&$222
+ BIC.B #4,&$243
+ MOV @R15+,R14
+ MOV @R13+,R0
+THEN
+ SUB #2,R15
+ MOV R14,0(R15)
+ BIC.B #4,&$243
+ MOV.B &$220,R14
+ AND.B #$0F,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE LCD_W
+ SUB #2,R15
+ MOV R14,0(R15)
+ RRUM #4,R14
+ BIC.B #1,&$243
+ BIS.B #$0F,&$224
+COLON
+ TOP_LCD 2 20_US
+ TOP_LCD 2 20_US
+;
+
+CODE LCD_WrC
+ BIS.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+CODE LCD_WrF
+ BIC.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us
+;
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+
+ASM WDT_INT
+BIC #$F8,0(R1)
+BIT.B #$20,&$240
+0= IF
+ CMP #38,&$3D6
+ U< IF
+ ADD #1,&$3D6
+ THEN
+ELSE
+ BIT.B #$40,&$240
+ 0= IF
+ CMP #7,&$3D6
+ U>= IF
+ SUB #1,&$3D6
+ THEN
+ THEN
+THEN
+RETI
+ENDASM
+
+ASM RC5_INT
+BIC #$F8,0(R1)
+MOV #0,&$360
+MOV #1778,R9
+MOV #14,R10
+BEGIN
+ MOV #%1011100100,&$340
+ RRUM #1,R9
+ MOV R9,R8
+ RRUM #1,R8
+ ADD R9,R8
+ BEGIN CMP R8,&$350
+ 0= UNTIL
+ BIT.B #4,&$200
+ ADDC R13,R13
+ MOV &$200,&$208
+ BIC.B #4,&$20C
+ SUB #1,R10
+0<> WHILE
+ ADD R9,R8
+ BEGIN
+ CMP R8,&$350
+ 0>= IF
+ BIC #$30,&$340
+ RETI
+ THEN
+ BIT.B #4,&$20C
+ 0<> UNTIL
+ MOV &$350,R9
+REPEAT
+BIC #$30,&$340
+RLAM #1,R13
+MOV @R1,R9
+RLAM #4,R9
+XOR R13,R9
+BIT #$2000,R9
+0= IF RETI
+THEN
+XOR #$200,0(R1)
+SUB #4,R15
+MOV &$1DDA,2(R15)
+MOV R14,0(R15)
+MOV.B R13,R14
+RRUM #2,R14
+BIT #$4000,R13
+0= IF BIS #$40,R14
+THEN
+LO2HI
+ ['] LCD_CLEAR IS CR
+ ['] LCD_WrC IS EMIT
+ $10 $1DDA !
+ CR ." $" 2 U.R
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+HI2LO
+MOV @R15+,&$1DDA
+RETI
+ENDASM
+
+CODE START
+ MOV #%1010010100,&$3C0
+ MOV #0,&$3E0
+ MOV #40,&$3D2
+ MOV #%1100000,&$3C6
+ MOV #25,&$3D6
+ BIS.B #$20,&$204
+ BIS.B #$20,&$20A
+ BIS.B #7,&$245
+ BIC.B #7,&$247
+ BIS.B #$0F,&$224
+ BIC.B #$0F,&$226
+ MOV #$5A5E,&$15C
+ BIS #1,&$100
+ BIS.B #4,&$20A
+ BIC.B #4,&$20C
+ MOV #WDT_INT,&$FFF2
+ MOV #RC5_INT,&$FFDE
+LO2HI
+ $03E8 20_US
+ $03 TOP_LCD
+ $CD 20_US
+ $03 TOP_LCD
+ $5 20_US
+ $03 TOP_LCD
+ $2 20_US
+ $02 TOP_LCD
+ $2 20_US
+ $28 LCD_WRF
+ $08 LCD_WRF
+ LCD_Clear
+ $06 LCD_WRF
+ $0C LCD_WRF
+ LCD_Clear
+ ['] LCD_HOME IS CR
+ ['] LCD_WRC IS EMIT
+ CR ." I love you"
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+ LIT RECURSE IS WARM
+ (WARM)
+;
+
+: STOP
+ ['] (WARM) IS WARM
+ ECHO COLD
+;
+
+PWR_STATE
+CODE MAX
+ CMP @R15,R14
+ S< ?GOTO FW1
+BW1 ADD #2,R15
+ MOV @R13+,R0
+ENDCODE
+
+CODE MIN
+ CMP @R15,R14
+ S< ?GOTO BW1
+FW1 MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+: U.R
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+
+CODE 20_US
+BEGIN
+ MOV #51,R10
+ BEGIN
+ SUB #1,R10
+ 0= UNTIL
+ SUB #1,R14
+0= UNTIL
+ MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE TOP_LCD
+ BIS.B #4,&$243
+ BIT.B #1,&$241
+0= IF
+ AND.B #$0F,R14
+ MOV.B R14,&$222
+ BIC.B #4,&$243
+ MOV @R15+,R14
+ MOV @R13+,R0
+THEN
+ SUB #2,R15
+ MOV R14,0(R15)
+ BIC.B #4,&$243
+ MOV.B &$220,R14
+ AND.B #$0F,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE LCD_W
+ SUB #2,R15
+ MOV R14,0(R15)
+ RRUM #4,R14
+ BIC.B #1,&$243
+ BIS.B #$0F,&$224
+COLON
+ TOP_LCD 2 20_US
+ TOP_LCD 2 20_US
+;
+
+CODE LCD_WrC
+ BIS.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+CODE LCD_WrF
+ BIC.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us
+;
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+
+ASM WDT_INT
+BIC #$F8,0(R1)
+BIT.B #$20,&$240
+0= IF
+ CMP #38,&$3D6
+ U< IF
+ ADD #1,&$3D6
+ THEN
+ELSE
+ BIT.B #$40,&$240
+ 0= IF
+ CMP #7,&$3D6
+ U>= IF
+ SUB #1,&$3D6
+ THEN
+ THEN
+THEN
+RETI
+ENDASM
+
+ASM RC5_INT
+BIC #$F8,0(R1)
+MOV #0,&$360
+MOV #1778,R9
+MOV #14,R10
+BEGIN
+ MOV #%1011100100,&$340
+ RRUM #1,R9
+ MOV R9,R8
+ RRUM #1,R8
+ ADD R9,R8
+ BEGIN CMP R8,&$350
+ 0= UNTIL
+ BIT.B #4,&$200
+ ADDC R13,R13
+ MOV &$200,&$208
+ BIC.B #4,&$20C
+ SUB #1,R10
+0<> WHILE
+ ADD R9,R8
+ BEGIN
+ CMP R8,&$350
+ 0>= IF
+ BIC #$30,&$340
+ RETI
+ THEN
+ BIT.B #4,&$20C
+ 0<> UNTIL
+ MOV &$350,R9
+REPEAT
+BIC #$30,&$340
+RLAM #1,R13
+MOV @R1,R9
+RLAM #4,R9
+XOR R13,R9
+BIT #$2000,R9
+0= IF RETI
+THEN
+XOR #$200,0(R1)
+SUB #4,R15
+MOV &$1DDA,2(R15)
+MOV R14,0(R15)
+MOV.B R13,R14
+RRUM #2,R14
+BIT #$4000,R13
+0= IF BIS #$40,R14
+THEN
+LO2HI
+ ['] LCD_CLEAR IS CR
+ ['] LCD_WrC IS EMIT
+ $10 $1DDA !
+ CR ." $" 2 U.R
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+HI2LO
+MOV @R15+,&$1DDA
+RETI
+ENDASM
+
+CODE START
+ MOV #%1010010100,&$3C0
+ MOV #0,&$3E0
+ MOV #40,&$3D2
+ MOV #%1100000,&$3C6
+ MOV #25,&$3D6
+ BIS.B #$20,&$204
+ BIS.B #$20,&$20A
+ BIS.B #7,&$245
+ BIC.B #7,&$247
+ BIS.B #$0F,&$224
+ BIC.B #$0F,&$226
+ MOV #$5A5E,&$15C
+ BIS #1,&$100
+ BIS.B #4,&$20A
+ BIC.B #4,&$20C
+ MOV #WDT_INT,&$FFF2
+ MOV #RC5_INT,&$FFDE
+LO2HI
+ $03E8 20_US
+ $03 TOP_LCD
+ $CD 20_US
+ $03 TOP_LCD
+ $5 20_US
+ $03 TOP_LCD
+ $2 20_US
+ $02 TOP_LCD
+ $2 20_US
+ $28 LCD_WRF
+ $08 LCD_WRF
+ LCD_Clear
+ $06 LCD_WRF
+ $0C LCD_WRF
+ LCD_Clear
+ ['] LCD_HOME IS CR
+ ['] LCD_WRC IS EMIT
+ CR ." I love you"
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+ LIT RECURSE IS WARM
+ (WARM)
+;
+
+: STOP
+ ['] (WARM) IS WARM
+ ECHO COLD
+;
+
+PWR_STATE
+CODE MAX
+ CMP @R15,R14
+ S< ?GOTO FW1
+BW1 ADD #2,R15
+ MOV @R13+,R0
+ENDCODE
+
+CODE MIN
+ CMP @R15,R14
+ S< ?GOTO BW1
+FW1 MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+: U.R
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+
+CODE 20_US
+BEGIN
+ MOV #51,R10
+ BEGIN
+ SUB #1,R10
+ 0= UNTIL
+ SUB #1,R14
+0= UNTIL
+ MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE TOP_LCD
+ BIS.B #4,&$243
+ BIT.B #1,&$241
+0= IF
+ AND.B #$0F,R14
+ MOV.B R14,&$222
+ BIC.B #4,&$243
+ MOV @R15+,R14
+ MOV @R13+,R0
+THEN
+ SUB #2,R15
+ MOV R14,0(R15)
+ BIC.B #4,&$243
+ MOV.B &$220,R14
+ AND.B #$0F,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE LCD_W
+ SUB #2,R15
+ MOV R14,0(R15)
+ RRUM #4,R14
+ BIC.B #1,&$243
+ BIS.B #$0F,&$224
+COLON
+ TOP_LCD 2 20_US
+ TOP_LCD 2 20_US
+;
+
+CODE LCD_WrC
+ BIS.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+CODE LCD_WrF
+ BIC.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us
+;
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+
+ASM WDT_INT
+BIC #$F8,0(R1)
+BIT.B #$20,&$240
+0= IF
+ CMP #38,&$3D6
+ U< IF
+ ADD #1,&$3D6
+ THEN
+ELSE
+ BIT.B #$40,&$240
+ 0= IF
+ CMP #7,&$3D6
+ U>= IF
+ SUB #1,&$3D6
+ THEN
+ THEN
+THEN
+RETI
+ENDASM
+
+ASM RC5_INT
+BIC #$F8,0(R1)
+MOV #0,&$360
+MOV #1778,R9
+MOV #14,R10
+BEGIN
+ MOV #%1011100100,&$340
+ RRUM #1,R9
+ MOV R9,R8
+ RRUM #1,R8
+ ADD R9,R8
+ BEGIN CMP R8,&$350
+ 0= UNTIL
+ BIT.B #4,&$200
+ ADDC R13,R13
+ MOV &$200,&$208
+ BIC.B #4,&$20C
+ SUB #1,R10
+0<> WHILE
+ ADD R9,R8
+ BEGIN
+ CMP R8,&$350
+ 0>= IF
+ BIC #$30,&$340
+ RETI
+ THEN
+ BIT.B #4,&$20C
+ 0<> UNTIL
+ MOV &$350,R9
+REPEAT
+BIC #$30,&$340
+RLAM #1,R13
+MOV @R1,R9
+RLAM #4,R9
+XOR R13,R9
+BIT #$2000,R9
+0= IF RETI
+THEN
+XOR #$200,0(R1)
+SUB #4,R15
+MOV &$1DDA,2(R15)
+MOV R14,0(R15)
+MOV.B R13,R14
+RRUM #2,R14
+BIT #$4000,R13
+0= IF BIS #$40,R14
+THEN
+LO2HI
+ ['] LCD_CLEAR IS CR
+ ['] LCD_WrC IS EMIT
+ $10 $1DDA !
+ CR ." $" 2 U.R
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+HI2LO
+MOV @R15+,&$1DDA
+RETI
+ENDASM
+
+CODE START
+ MOV #%1010010100,&$3C0
+ MOV #0,&$3E0
+ MOV #40,&$3D2
+ MOV #%1100000,&$3C6
+ MOV #25,&$3D6
+ BIS.B #$20,&$204
+ BIS.B #$20,&$20A
+ BIS.B #7,&$245
+ BIC.B #7,&$247
+ BIS.B #$0F,&$224
+ BIC.B #$0F,&$226
+ MOV #$5A5E,&$15C
+ BIS #1,&$100
+ BIS.B #4,&$20A
+ BIC.B #4,&$20C
+ MOV #WDT_INT,&$FFF2
+ MOV #RC5_INT,&$FFDE
+LO2HI
+ $03E8 20_US
+ $03 TOP_LCD
+ $CD 20_US
+ $03 TOP_LCD
+ $5 20_US
+ $03 TOP_LCD
+ $2 20_US
+ $02 TOP_LCD
+ $2 20_US
+ $28 LCD_WRF
+ $08 LCD_WRF
+ LCD_Clear
+ $06 LCD_WRF
+ $0C LCD_WRF
+ LCD_Clear
+ ['] LCD_HOME IS CR
+ ['] LCD_WRC IS EMIT
+ CR ." I love you"
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+ LIT RECURSE IS WARM
+ (WARM)
+;
+
+: STOP
+ ['] (WARM) IS WARM
+ ECHO COLD
+;
+
+PWR_STATE
+CODE MAX
+ CMP @R15,R14
+ S< ?GOTO FW1
+BW1 ADD #2,R15
+ MOV @R13+,R0
+ENDCODE
+
+CODE MIN
+ CMP @R15,R14
+ S< ?GOTO BW1
+FW1 MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+: U.R
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+
+CODE 20_US
+BEGIN
+ MOV #51,R10
+ BEGIN
+ SUB #1,R10
+ 0= UNTIL
+ SUB #1,R14
+0= UNTIL
+ MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE TOP_LCD
+ BIS.B #4,&$243
+ BIT.B #1,&$241
+0= IF
+ AND.B #$0F,R14
+ MOV.B R14,&$222
+ BIC.B #4,&$243
+ MOV @R15+,R14
+ MOV @R13+,R0
+THEN
+ SUB #2,R15
+ MOV R14,0(R15)
+ BIC.B #4,&$243
+ MOV.B &$220,R14
+ AND.B #$0F,R14
+ MOV @R13+,R0
+ENDCODE
+
+CODE LCD_W
+ SUB #2,R15
+ MOV R14,0(R15)
+ RRUM #4,R14
+ BIC.B #1,&$243
+ BIS.B #$0F,&$224
+COLON
+ TOP_LCD 2 20_US
+ TOP_LCD 2 20_US
+;
+
+CODE LCD_WrC
+ BIS.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+CODE LCD_WrF
+ BIC.B #2,&$243
+ JMP LCD_W
+ENDCODE
+
+: LCD_Clear
+ $01 LCD_WrF 100 20_us
+;
+
+: LCD_Home
+ $02 LCD_WrF 100 20_us
+;
+
+ASM WDT_INT
+BIC #$F8,0(R1)
+BIT.B #$20,&$240
+0= IF
+ CMP #38,&$3D6
+ U< IF
+ ADD #1,&$3D6
+ THEN
+ELSE
+ BIT.B #$40,&$240
+ 0= IF
+ CMP #7,&$3D6
+ U>= IF
+ SUB #1,&$3D6
+ THEN
+ THEN
+THEN
+RETI
+ENDASM
+
+ASM RC5_INT
+BIC #$F8,0(R1)
+MOV #0,&$360
+MOV #1778,R9
+MOV #14,R10
+BEGIN
+ MOV #%1011100100,&$340
+ RRUM #1,R9
+ MOV R9,R8
+ RRUM #1,R8
+ ADD R9,R8
+ BEGIN CMP R8,&$350
+ 0= UNTIL
+ BIT.B #4,&$200
+ ADDC R13,R13
+ MOV &$200,&$208
+ BIC.B #4,&$20C
+ SUB #1,R10
+0<> WHILE
+ ADD R9,R8
+ BEGIN
+ CMP R8,&$350
+ 0>= IF
+ BIC #$30,&$340
+ RETI
+ THEN
+ BIT.B #4,&$20C
+ 0<> UNTIL
+ MOV &$350,R9
+REPEAT
+BIC #$30,&$340
+RLAM #1,R13
+MOV @R1,R9
+RLAM #4,R9
+XOR R13,R9
+BIT #$2000,R9
+0= IF RETI
+THEN
+XOR #$200,0(R1)
+SUB #4,R15
+MOV &$1DDA,2(R15)
+MOV R14,0(R15)
+MOV.B R13,R14
+RRUM #2,R14
+BIT #$4000,R13
+0= IF BIS #$40,R14
+THEN
+LO2HI
+ ['] LCD_CLEAR IS CR
+ ['] LCD_WrC IS EMIT
+ $10 $1DDA !
+ CR ." $" 2 U.R
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+HI2LO
+MOV @R15+,&$1DDA
+RETI
+ENDASM
+
+CODE START
+ MOV #%1010010100,&$3C0
+ MOV #0,&$3E0
+ MOV #40,&$3D2
+ MOV #%1100000,&$3C6
+ MOV #25,&$3D6
+ BIS.B #$20,&$204
+ BIS.B #$20,&$20A
+ BIS.B #7,&$245
+ BIC.B #7,&$247
+ BIS.B #$0F,&$224
+ BIC.B #$0F,&$226
+ MOV #$5A5E,&$15C
+ BIS #1,&$100
+ BIS.B #4,&$20A
+ BIC.B #4,&$20C
+ MOV #WDT_INT,&$FFF2
+ MOV #RC5_INT,&$FFDE
+LO2HI
+ $03E8 20_US
+ $03 TOP_LCD
+ $CD 20_US
+ $03 TOP_LCD
+ $5 20_US
+ $03 TOP_LCD
+ $2 20_US
+ $02 TOP_LCD
+ $2 20_US
+ $28 LCD_WRF
+ $08 LCD_WRF
+ LCD_Clear
+ $06 LCD_WRF
+ $0C LCD_WRF
+ LCD_Clear
+ ['] LCD_HOME IS CR
+ ['] LCD_WRC IS EMIT
+ CR ." I love you"
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+ CR
+ ." RC5toLCD is running. Type STOP to quit"
+ LIT RECURSE IS WARM
+ (WARM)
+;
+
+: STOP
+ ['] (WARM) IS WARM
+ ECHO COLD
+;
+
+ECHO
+ ; download is done
+PWR_HERE ; this app is protected against power ON/OFF,
--- /dev/null
+; --------------------
+; RTC_C.f
+; --------------------
+
+
+CODE MAX
+ CMP @R15,R14
+ S< ?GOTO FW1
+BW1 ADD #2,R15
+ MOV @R13+,R0
+ENDCODE
+
+CODE MIN
+ CMP @R15,R14
+ S< ?GOTO BW1
+FW1 MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+: U.R
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+
+CODE DATE?
+ SUB #6,R15
+ MOV R14,4(R15)
+ BEGIN
+ BIT.B #$10,&$4A2
+ 0<> UNTIL
+ MOV &$4B6,2(R15)
+ MOV.B &$4B5,R14
+ MOV R14,0(R15)
+ MOV.B &$4B4,R14
+COLON
+ 2 U.R $2F EMIT
+ 2 U.R $2F EMIT .
+;
+
+CODE DATE!
+ MOV.B #$A5,&$4A1
+ MOV R14,&$4B6
+ MOV.B @R15,&$4B5
+ MOV.B 2(R15),&$4B4
+ ADD #4,R15
+ MOV @R15+,R14
+COLON
+ ." we are on " DATE?
+;
+
+CODE TIME?
+ SUB #6,R15
+ MOV R14,4(R15)
+ BEGIN
+ BIT.B #$10,&$4A2
+ 0<> UNTIL
+ MOV.B &$4B0,R14
+ MOV R14,2(R15)
+ MOV.B &$4B1,R14
+ MOV R14,0(R15)
+ MOV.B &$4B2,R14
+COLON
+ 2 U.R $3A EMIT
+ 2 U.R $3A EMIT 2 U.R
+;
+
+: TIME!
+ DEPTH 2 = IF 0 THEN
+ HI2LO
+ MOV.B #$A5,&$4A1
+ MOV R14,&$4B0
+ MOV.B @R15,&$4B1
+ MOV.B 2(R15),&$4B2
+ ADD #4,R15
+ MOV @R15+,R14
+ LO2HI
+ ." it is " TIME?
+;
+
+CREATE ABUF 20 ALLOT
+
+: GET_TIME
+ ECHO
+ CR CR ." DATE (DMY): "
+ ABUF ABUF 20 (ACCEPT) EVALUATE CR 3 SPACES DATE!
+ CR CR ." TIME (HMS or HM): "
+ ABUF ABUF 20 (ACCEPT) EVALUATE CR 3 SPACES TIME!
+ CR
+ PWR_STATE
+ HI2LO
+ MOV #$1C80,R15
+ MOV @R1+,R13
+ MOV @R13+,R0
+ENDCODE
+
+GET_TIME
--- /dev/null
+
+LOAD" SD_TOOLS.4TH"
+RST_HERE
+NOECHO
+: SD_TEST
+ ECHO CR
+ ." 1 Load ANS core tests" CR
+ ." 2 Load, compile and run a 10k program "
+ ." from its source file (quiet mode)" CR
+ ." 3 Read only this source file (quiet mode)" CR
+ ." 4 Write a dump of the FORTH kernel to yourfile.txt" CR
+ ." 5 append a dump of the FORTH kernel to yourfile.txt" CR
+ ." 6 Load truc (test error)" CR
+ ." your choice : "
+ KEY
+ 48 -
+ DUP 1 =
+ IF .
+ LOAD" CORETSTH.4TH"
+ ELSE DUP 2 =
+ IF .
+ LOAD" Prog10k.4th"
+ ELSE DUP 3 =
+ IF .
+ READ" Prog10k.4th"
+ BEGIN
+ READ
+ UNTIL
+ ELSE DUP 4 =
+ IF .
+ DEL" yourfile.txt"
+ WRITE" yourfile.txt"
+ ['] SD_EMIT IS EMIT
+ $4000 HERE OVER - DUMP
+ ['] (EMIT) IS EMIT
+ CLOSE
+ ELSE DUP 5 =
+ IF .
+ WRITE" yourfile.txt"
+ ['] SD_EMIT IS EMIT
+ $4000 HERE OVER - DUMP
+ ['] (EMIT) IS EMIT
+ CLOSE
+ ELSE DUP 6 =
+ IF .
+ LOAD" truc"
+ ELSE
+ DROP ." ?"
+ CR ." loading TSTWORDS.4th..."
+ LOAD" TSTWORDS.4TH"
+ THEN
+ THEN
+ THEN
+ THEN
+ THEN
+ THEN
+ CR ." It's done..."
+;
+PWR_HERE
+SD_TEST
--- /dev/null
+; ------------------------------------------------------------------------
+; BASIC TOOLS for SD Card : {DIR FAT SECTOR CLUSER} DUMP ; include UTILITY
+; ------------------------------------------------------------------------
+
+CODE ?
+ MOV @R14,R14
+ MOV #U.,R0
+ENDCODE
+
+CODE SP@
+ SUB #2,R15
+ MOV R14,0(R15)
+ MOV R15,R14
+ MOV @R13+,R0
+ENDCODE
+: .S
+$3C EMIT
+DEPTH .
+8 EMIT
+$3E EMIT SPACE
+SP@ $1C80 OVER OVER U<
+IF 2 -
+ DO I @ U.
+ -2 +LOOP
+ELSE
+ DROP DROP
+THEN
+;
+
+: WORDS
+$1DDA @
+#10 $1DDA !
+CR ." "
+$1800 @ DUP
+1 = IF DROP ." monothread"
+ ELSE . ." threads"
+ THEN ." vocabularies"
+$1DDA !
+$1DCA
+BEGIN
+ DUP
+ 2 + SWAP
+ @ ?DUP
+WHILE
+CR ." "
+ DUP $1CE2 $1800 @ DUP +
+ MOVE
+ BEGIN
+ 0 DUP
+ $1800 @ DUP + 0 DO
+ DUP I $1CE2 + @
+ U< IF
+ DROP DROP I DUP $1CE2 + @
+ THEN
+ 2 +LOOP
+ ?DUP
+ WHILE
+ DUP
+ 2 - @
+ ROT
+ $1CE2 +
+ !
+ DUP
+ COUNT $7F AND TYPE
+ C@ $0F AND
+ $10 SWAP - SPACES
+ REPEAT
+
+ DROP DROP
+ CR
+REPEAT
+DROP
+;
+
+CODE MAX
+ CMP @R15,R14
+ S< ?GOTO FW1
+BW1 ADD #2,R15
+ MOV @R13+,R0
+ENDCODE
+
+CODE MIN
+ CMP @R15,R14
+ S< ?GOTO BW1
+FW1 MOV @R15+,R14
+ MOV @R13+,R0
+ENDCODE
+
+: U.R
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+
+: DUMP
+ $1DDA @ >R $10 $1DDA !
+ SWAP $FFF0 AND SWAP
+ OVER + SWAP
+ DO CR
+ I 7 U.R SPACE
+ I $10 + I
+ DO I C@ 3 U.R LOOP
+ SPACE SPACE
+ I $10 + I
+ DO I C@ $7E MIN BL MAX EMIT LOOP
+ $10 +LOOP
+ R> $1DDA !
+;
+
+CODE SECT_D
+ MOV R14,R9
+ MOV @R15,R10
+ CALL &$1814
+COLON
+ UD.
+ $1E00 $200 DUMP CR ;
+
+CODE CLUST_D
+ MOV R14,&$2024
+ MOV @R15,&$2022
+BW1 MOV &$2010,&$4E4
+ MOV #0,&$4E6
+ MOV &$2022,&$4D8
+ MOV &$2024,&$4DA
+ MOV &$2012,&$4C8
+ MOV &$4E4,0(R15)
+ MOV &$4E6,R14
+ JMP SECT_D
+ENDCODE
+
+CODE FAT_D
+ SUB #4,R15
+ MOV R14,2(R15)
+ MOV &$202A,0(R15)
+ ADD &$2008,0(R15)
+ MOV #0,R14
+ JMP SECT_D
+ENDCODE
+
+CODE DIR_D
+ SUB #4,R15
+ MOV R14,2(R15)
+ CMP #1,&$202E
+ 0= IF
+ CMP.B #0,&$2030
+ 0= IF
+ MOV #0,R14
+ MOV &$200E,0(R15)
+ JMP SECT_D
+ THEN
+ THEN
+ MOV &$202E,&$2022
+ MOV &$2030,&$2024
+ GOTO BW1
+ENDCODE
+
+ECHO
+ ; added : UTILITY : ? SP@ .S WORDS MAX MIN U.R DUMP
+ ; added : FAT_D to DUMP first sector of FAT1 and DIR_D for that of current DIRectory.
+ ; added : SECT_D to DUMP a sector and CLUST_D for first sector of a cluster
+ ; include a decimal point to force 32 bits number, example : 2. CLUST_D
+
+PWR_HERE ; to protect this app against a RESET, type: RST_HERE
--- /dev/null
+\ -----------------------------
+\ MSP-EXP430FR5969_TSTWORDS.4th
+\ -----------------------------
+
+ECHO
+PWR_HERE
+
+\ -----------------------------------------------------------------------
+\ test some assembler words and show how to mix FORTH/ASSEMBLER routines
+\ -----------------------------------------------------------------------
+LOAD" \misc\TestASM.4th"
+
+\ -------------------------------------
+\ here we returned in the TestWords.4th
+\ -------------------------------------
+
+\ ----------
+\ LOOP tests
+\ ----------
+: LOOP_TEST 8 0 DO I . LOOP
+;
+
+LOOP_TEST \ you should see 0 1 2 3 4 5 6 7 -->
+
+
+: LOOP_TEST1 \ n <LOOP_TEST1> ---
+
+ BEGIN DUP U. 1 -
+ ?DUP
+ 0= UNTIL
+;
+
+
+: FIND_NOTHING \ FIND_NOTHING --
+ 25000 0
+ DO
+ LOOP \ 14 cycles by loop
+ ABORT" 25000 x nothing = nothing..."
+;
+
+
+
+ : FIND_TEST \ FIND_TEST <word> --
+ BL WORD \ -- c-addr
+ 50000 0
+ DO \ -- c-addr
+ DUP
+ FIND DROP DROP
+ LOOP
+ FIND
+ 0= IF ABORT" <-- not found !"
+ ELSE ABORT" <-- found !"
+ THEN
+ ;
+
+\ seeking $ word, FIND jumps all words on their first character so time of word loop is 20 cycles
+\ see FIND in the source file for more information
+
+\ FIND_TEST <lastword> result @ 8MHz, monothread : 1,2s
+
+\ FIND_TEST $ results @ 8MHz, monothread, 201 words in vocabulary FORTH :
+\ 27 seconds with only FORTH vocabulary in CONTEXT
+\ 540 us for one search ( which gives the delay for QNUMBER in INTERPRET routine)
+\ 2.6866 us / word, 21,49 cycles / word (for 20 cycles calculated (see FIND in source file)
+
+
+\ FIND_TEST $ results @ 8MHz, 2 threads, 201 words in vocabulary FORTH :
+\ 13 second with only FORTH vocabulary in CONTEXT
+\ 260 us for one search ( which gives the delay for QNUMBER in INTERPRET routine)
+\ 1,293 us / word, 10,34 cycles / word
+
+\ FIND_TEST $ results @ 8MHz, 4 threads, 201 words in vocabulary FORTH :
+\ 8 second with only FORTH vocabulary in CONTEXT
+\ 160 us for one search ( which gives the delay for QNUMBER in INTERPRET routine)
+\ 0,796 us / word, 6,37 cycles / word
+
+\ FIND_TEST $ results @ 8MHz, 8 threads, 201 words in vocabulary FORTH :
+\ 4.66 second with only FORTH vocabulary in CONTEXT
+\ 93 us for one search ( which gives the delay for QNUMBER in INTERPRET routine)
+\ 0,4463 us / word, 3,7 cycles / word
+
+\ FIND_TEST $ results @ 8MHz, 16 threads, 201 words in vocabulary FORTH :
+\ 2,8 second with only FORTH vocabulary in CONTEXT
+\ 56 us for one search ( which gives the delay for QNUMBER in INTERPRET routine)
+\ 0,278 us / word, 2,22 cycles / word
+
+
+\ --------
+\ KEY test
+\ --------
+: KEY_TEST
+ ." type a key : "
+ KEY EMIT \ wait for a KEY, then emit it
+;
+\ KEY_TEST
--- /dev/null
+
+\ how to test SD_CARD driver on your target (excepted MSP-EXP430FR4133 without hardware multiplier) :
+
+
+\ connect the launchpad to your PC on a free USB port
+\ on the launchpad remove the jumpers GND, RX, TX of programming port (don't remove TST, RST and VCC jumpers)
+\ connect the PL2303TA/HXD cable to your PC on another free USB port
+\ wire PL2303TA/HXD to the programming port of your launchpad : GND <-> GND, RX <-- TX, TX --> RX
+\ start TERATERM, select PL2303TA/HXD port
+\ configure TERATERM as indicated in forthMSP430FR.asm
+
+\ if you have a MSP-EXP430FR5994, program your launchpad with MSP_EXP430FR5994_3Mbds_SD_CARD.txt via TI interface:
+\ drag and drop this file onto MSP430FR5994prog.bat
+
+\ else edit forthMSP430FR.asm with scite editor
+
+\ with (SHIFT+F8), set param1 as DEVICE and param2 as TARGET
+\ uncomment your target,
+\ set DTC .equ 1
+\ FREQUENCY .equ 16
+\ THREADS .equ 16
+\ TERMINALBAUDRATE .equ 3000000
+\
+\ uncomment TERMINALXONXOFF
+\ LF_XTAL
+\ MSP430ASSEMBLER
+\ SD_CARD_LOADER
+\ SD_CARD_READ_WRITE
+
+\ compile for your target (CTRL+0)
+\ then program your target via TI interface (CTRL+1).
+
+
+\ format FAT16 or FAT32 a SD_CARD memory (max 64GB)
+\ create folder \MISC on this SD_CARD (FastForth don't do yet)
+\ put it in the target SD slot wired as described in MSP430-FORTH\target.pat,
+
+\ type COLD from the console input to reset FAST FORTH,
+
+
+\ with Send_File.4th_to_SD_CARD_target.bat (or from scite editor, menu tools), send to SD_CARD:
+\ CORETSTH.4th
+\ TSTWORDS.4th
+
+\ with Send_File.4th_to_SD_CARD_target.bat, send to SD_CARD\MISC:
+\ TESTASM.4TH (don't forget to add path \MISC on the 2th window opened by TERATERM)
+
+\ and if don't know how to do, double clic on this bat file.
+
+
+\ with Send_file.f_to_SD_CARD_target.bat, send to SD_CARD: (on SD_CARD files will have 4th extension)
+\ SD_TOOLS.f
+\ SD_TEST.f
+\ PROG10k.f
+\ RTC.f
+
+
+
+\ then, from input terminal (TERATERM),
+\ LOAD" RTC.4th", type (with spaces) Day Month Year, then type Hours Minutes Seconds (or Hours Minutes),
+\ LOAD" SD_TEST.4TH" that load this file.
+
+
+
+LOAD" SD_TOOLS.4TH"
+RST_HERE
+NOECHO
+
+\ we can see interest of preprocessing that allows the use of the PROGRAMSTART address, not recognized by FASTFORTH
+\ in the preprocessed file SD_TEST.4th, PROGRAMSTART will be replaced by its value.
+\ PROGRAMSTART is defined in \config\gema\MSP430FR_FastForth.pat
+
+: SD_TEST
+ ECHO CR
+ ." 1 Load ANS core tests" CR
+ ." 2 Load, compile and run a 10k program "
+ ." from its source file (quiet mode)" CR
+ ." 3 Read only this source file (quiet mode)" CR
+ ." 4 Write a dump of the FORTH kernel to yourfile.txt" CR
+ ." 5 append a dump of the FORTH kernel to yourfile.txt" CR
+ ." 6 Load truc (test error)" CR
+ ." your choice : "
+ KEY
+ 48 -
+ DUP 1 =
+ IF .
+\ LOAD" COMPHMPY.4TH" \ bug, bug, bug: only 2th line is executed
+\ LOAD" CORETST1.4TH" \ why ?
+ LOAD" CORETSTH.4TH" \ so CORETSTH.4TH is the sum of two previous files
+ ELSE DUP 2 =
+ IF .
+ LOAD" Prog10k.4th"
+ ELSE DUP 3 =
+ IF .
+ READ" Prog10k.4th"
+ BEGIN
+ READ
+ UNTIL
+ ELSE DUP 4 =
+ IF .
+ DEL" yourfile.txt"
+ WRITE" yourfile.txt"
+ ['] SD_EMIT IS EMIT
+ PROGRAMSTART HERE OVER - DUMP
+ ['] (EMIT) IS EMIT
+ CLOSE
+ ELSE DUP 5 =
+ IF .
+ WRITE" yourfile.txt"
+ ['] SD_EMIT IS EMIT
+ PROGRAMSTART HERE OVER - DUMP
+ ['] (EMIT) IS EMIT
+ CLOSE
+ ELSE DUP 6 =
+ IF .
+ LOAD" truc"
+ ELSE
+ DROP ." ?"
+ CR ." loading TSTWORDS.4th..."
+ LOAD" TSTWORDS.4TH"
+ THEN
+ THEN
+ THEN
+ THEN
+ THEN
+ THEN
+ CR ." It's done..."
+;
+
+PWR_HERE
+
+SD_TEST
--- /dev/null
+; ------------------------------------------------------------------------
+; BASIC TOOLS for SD Card : {DIR FAT SECTOR CLUSER} DUMP ; include UTILITY
+; ------------------------------------------------------------------------
+
+\ Fast Forth For Texas Instrument MSP430FRxxxx FRAM devices
+\ Copyright (C) <2017> <J.M. THOORENS>
+\
+\ This program is free software: you can redistribute it and/or modify
+\ it under the terms of the GNU General Public License as published by
+\ the Free Software Foundation, either version 3 of the License, or
+\ (at your option) any later version.
+\
+\ This program is distributed in the hope that it will be useful,
+\ but WITHOUT ANY WARRANTY; without even the implied warranty of
+\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+\ GNU General Public License for more details.
+\
+\ You should have received a copy of the GNU General Public License
+\ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+\ REGISTERS USAGE
+\ R4 to R7 must be saved before use and restored after
+\ scratch registers Y to S are free for use
+\ under interrupt, IP is free for use
+
+\ PUSHM order : PSP,TOS, IP, S, T, W, X, Y, R7, R6, R5, R4
+\ example : PUSHM IP,Y
+\
+\ POPM order : R4, R5, R6, R7, Y, X, W, T, S, IP,TOS,PSP
+\ example : POPM Y,IP
+
+\ ASSEMBLER conditionnal usage after IF UNTIL WHILE : S< S>= U< U>= 0= 0<> 0>=
+\ ASSEMBLER conditionnal usage before GOTO ?GOTO : S< S>= U< U>= 0= 0<> <0
+
+\ FORTH conditionnal usage after IF UNTIL WHILE : 0= 0< = < > U<
+
+
+
+
+\ ECHO ; if an error occurs, uncomment this line before new download to find it.
+
+ \
+
+CODE ? \ adr -- display the content of adr
+ MOV @TOS,TOS
+ MOV #U.,PC \ goto U.
+ENDCODE
+ \
+
+CODE SP@ \ -- SP
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ MOV PSP,TOS
+ MOV @IP+,PC
+ENDCODE
+
+: .S \ -- print <number> of cells and stack contents if not empty
+$3C EMIT \ -- char "<"
+DEPTH .
+8 EMIT \ backspace
+$3E EMIT SPACE \ char ">"
+SP@ PSTACK OVER OVER U< \
+IF 2 -
+ DO I @ U.
+ -2 +LOOP
+ELSE
+ DROP DROP
+THEN
+;
+ \
+
+: WORDS \ -- list all words in all dicts in CONTEXT.
+
+\ vvvvvvvv may be skipped vvvvvvvv
+BASE @ \ -- BASE
+#10 BASE !
+CR ." "
+INI_THREAD @ DUP
+1 = IF DROP ." monothread"
+ ELSE . ." threads"
+ THEN ." vocabularies"
+BASE ! \ --
+\ ^^^^^^^^ may be skipped ^^^^^^^^
+
+CONTEXT \ -- CONTEXT
+BEGIN \ search dictionnary
+ DUP
+ 2 + SWAP \ -- CONTEXT+2 CONTEXT
+ @ ?DUP \ -- CONTEXT+2 (VOC_BODY VOC_BODY or 0)
+WHILE \ -- CONTEXT+2 VOC_BODY dictionnary found
+CR ." " \
+\ MOVE all threads of VOC_BODY in PAD
+ DUP PAD INI_THREAD @ DUP + \ -- CONTEXT+2 VOC_BODY VOC_BODY PAD THREAD*2
+ MOVE \ char MOVE
+
+ BEGIN \ -- CONTEXT+2 VOC_BODY
+ 0 DUP \ -- CONTEXT+2 VOC_BODY ptr MAX
+\ select the MAX of NFA in threads
+ INI_THREAD @ DUP + 0 DO \ ptr = threads*2
+ DUP I PAD + @ \ -- CONTEXT+2 VOC_BODY ptr MAX MAX NFAx
+ U< IF
+ DROP DROP I DUP PAD + @ \ -- CONTEXT+2 VOC_BODY ptr MAX if MAX U< NFAx replace adr and MAX
+ THEN \
+ 2 +LOOP \ -- CONTEXT+2 VOC_BODY ptr MAX
+ ?DUP \ -- CONTEXT+2 VOC_BODY ptr MAX max NFA = 0 ? end of vocabulary ?
+ WHILE \ -- CONTEXT+2 VOC_BODY ptr MAX
+\ replace it by its LFA
+ DUP \ -- CONTEXT+2 VOC_BODY ptr MAX MAX
+ 2 - @ \ -- CONTEXT+2 VOC_BODY ptr MAX [LFA]
+ ROT \ -- CONTEXT+2 VOC_BODY MAX [LFA] ptr
+ PAD + \ -- CONTEXT+2 VOC_BODY MAX [LFA] thread
+ ! \ -- CONTEXT+2 VOC_BODY MAX
+\ type it in 16 chars format
+ DUP \ -- CONTEXT+2 VOC_BODY MAX MAX
+ COUNT $7F AND TYPE \ -- CONTEXT+2 VOC_BODY MAX
+ C@ $0F AND \ --
+ $10 SWAP - SPACES \ -- CONTEXT+2 VOC_BODY
+\ search next MAX of NFA
+ REPEAT
+ \ -- CONTEXT+2 VOC_BODY 0
+ DROP DROP \ -- CONTEXT+2
+ CR
+\ repeat for each CONTEXT vocabulary
+
+REPEAT \ -- 0
+DROP \ --
+;
+ \
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+: DUMP \ adr n -- dump memory
+ BASE @ >R $10 BASE !
+ SWAP $FFF0 AND SWAP
+ OVER + SWAP
+ DO CR \ generate line
+ I 7 U.R SPACE \ generate address
+ I $10 + I \ display 16 bytes
+ DO I C@ 3 U.R LOOP
+ SPACE SPACE
+ I $10 + I \ display 16 chars
+ DO I C@ $7E MIN BL MAX EMIT LOOP
+ $10 +LOOP
+ R> BASE !
+;
+ \
+
+\ ----------------------------------\
+\ read sector and dump it \ sector. -- don't forget to add decimal point to your sector number (if < 65536)
+\ ----------------------------------\
+CODE SECT_D \
+ MOV TOS,X \ X = SectorH
+ MOV @PSP,W \ W = sectorL
+ CALL &ReadSectorWX \ W = SectorLO X = SectorHI
+COLON \
+ UD. \ display the sector number
+ BUFFER $200 DUMP CR ; \ then dump the sector
+\ ----------------------------------\
+ \
+
+\ TIP : How to identify FAT16 or FAT32 SD_Card ?
+\ 1 CLUSTER <==> FAT16 RootDIR
+\ 2 CLUSTER <==> FAT32 RootDIR
+\ ----------------------------------\
+\ read first sector of Cluster and dump it
+\ ----------------------------------\
+CODE CLUST_D \ cluster. -- don't forget to add decimal point to your cluster number (if < 65536)
+\ ----------------------------------\
+ MOV TOS,&ClusterH \
+ MOV @PSP,&ClusterL \
+BW1 MOV &OrgClusters,&RES0 \ OrgClusters = sector of virtual cluster 0, word size
+ MOV #0,&RES1
+ MOV &ClusterL,&MAC32L
+ MOV &ClusterH,&MAC32H
+ MOV &SecPerClus,&OP2
+ MOV &RES0,0(PSP) \ cluster sectorL
+ MOV &RES1,TOS \ cluster sectorH
+ JMP SECT_D \ jump to a defined word
+ENDCODE
+\ ----------------------------------\
+ \
+
+\ dump FAT1 sector of last entry
+\ ----------------------------------\
+CODE FAT_D \ Display CurFATsector
+\ ----------------------------------\
+ SUB #4,PSP \
+ MOV TOS,2(PSP) \
+ MOV &FATsector,0(PSP) \ FATsectorLO
+ ADD &OrgFAT1,0(PSP) \
+ MOV #0,TOS \ FATsectorHI = 0
+ JMP SECT_D \ jump to a defined word
+ENDCODE
+\ ----------------------------------\
+ \
+
+\ dump DIR sector of opened file or first sector of current DIR by default
+\ ----------------------------------\
+CODE DIR_D \ Display DIR sector of CurrentHdl or CurrentDir sector by default
+\ ----------------------------------\
+ SUB #4,PSP \
+ MOV TOS,2(PSP) \ save TOS
+\ ComputeClusFrstSect \ If Cluster = 1 ==> RootDirectory ==> SectorL = OrgRootDir
+ CMP #1,&DIRclusterL \ clusterL = 1 ? (FAT16 specificity)
+ 0= IF
+ CMP.B #0,&DIRclusterH \ clusterT = 0 ?
+ 0= IF
+ MOV #0,TOS \
+ MOV &OrgRootDir,0(PSP) \ sectorL for FAT16 OrgRootDIR is done
+ JMP SECT_D
+ THEN
+ THEN \
+ MOV &DIRclusterL,&ClusterL \
+ MOV &DIRclusterH,&ClusterH \
+ GOTO BW1 \ jump to the backward LABEL BW1
+ENDCODE
+\ ----------------------------------\
+ \
+
+ECHO
+ ; added : UTILITY : ? SP@ .S WORDS MAX MIN U.R DUMP
+ ; added : FAT_D to DUMP first sector of FAT1 and DIR_D for that of current DIRectory.
+ ; added : SECT_D to DUMP a sector and CLUST_D for first sector of a cluster
+ ; include a decimal point to force 32 bits number, example : 2. CLUST_D
+ \
+PWR_HERE ; to protect this app against a RESET, type: RST_HERE
+
--- /dev/null
+\ -----------------------------------------------------------------------
+\ File Name TestASM.4th
+\ -----------------------------------------------------------------------
+ECHO
+
+\ -----------------------------------------------------------------------
+\ test CPUx instructions PUSHM, POPM, RLAM, RRAM, RRCM, RRUM
+\ -----------------------------------------------------------------------
+CODE TESTPUSHM
+ MOV #22222,Y
+ MOV #3,X
+ MOV #2,W
+ MOV #1,T
+ MOV #0,S
+\ PUSHM Y,IP \ uncomment to test error (registers bad order)
+ PUSHM IP,W \ PUSHM order : PSP,TOS,IP,S,T,W,X,Y,rEXIT,rDOVAR,rDOCON,rDODOES
+ POPM W,IP \ POPM order : rDODOES,rDOCON,rDOVAR,rEXIT,Y,X,W,T,S,IP,TOS,PSP
+ SUB #10,PSP
+ MOV TOS,8(PSP) \ save old TOS
+ MOV S,6(PSP)
+ MOV T,4(PSP)
+ MOV W,2(PSP)
+ MOV X,0(PSP)
+ MOV Y,TOS
+\ RLAM #0,TOS \ uncomment to test error (bad shift value)
+ RRAM #1,TOS \ 0 < shift value < 5
+ RLAM #2,TOS
+ RRCM #1,TOS
+ RRUM #1,TOS
+ COLON \ high level part of the word starts here...
+ space . . . . .
+ ; \ and finishes here.
+ \
+TESTPUSHM ; you should see 11111 3 2 1 0 -->
+
+CODE TESTPOPM
+ MOV #22222,Y
+ MOV #3,X
+ MOV #2,W
+ MOV #1,T
+ MOV #0,S
+\ PUSHM W,IP \ uncomment to test error "out of bounds"
+ PUSHM IP,W \ PUSHM order : PSP,TOS,IP,S,T,W,X,Y,rEXIT,rDOVAR,rDOCON,rDODOES
+ POPM W,IP \ POPM order : rDODOES,rDOCON,rDOVAR,rEXIT,Y,X,W,T,S,IP,TOS,PSP
+ SUB #10,PSP
+ MOV TOS,8(PSP) \ save old TOS
+ MOV S,6(PSP)
+ MOV T,4(PSP)
+ MOV W,2(PSP)
+ MOV X,0(PSP)
+ MOV Y,TOS
+\ RLAM #0,TOS \ uncomment to test error "out of bounds"
+\ RLAM #5,TOS \ uncomment to test error "out of bounds"
+ RRAM #1,TOS \ 0 < shift value < 5
+ RLAM #2,TOS
+ RRCM #1,TOS
+ RRUM #1,TOS
+ COLON \ high level part of the word starts here...
+ space . . . . .
+ ; \ and finishes here.
+ \
+TESTPOPM ; you should see 11111 3 2 1 0 -->
+
+
+
+\ -----------------------------------------------------------------------
+\ test symbolic branch in assembler
+\ test a FORTH section encapsulated in an assembly word
+\ -----------------------------------------------------------------------
+CODE TEST1 \ the word "CODE" add ASSEMBLER as CONTEXT vocabulary...
+
+ MOV &BASE,&BASE \ to test &xxxx src operand
+ CMP #%10,&BASE
+0<> IF MOV #2,&BASE \ if base <> 2
+ELSE MOV #$0A,&BASE \ else base = 2
+THEN
+ COLON \ tips : no "ok" displayed in start of line <==> compilation mode
+ BASE @ U. \ always display 10 !
+ ;
+ \
+
+\ -----------------------------------------------------------------------
+\ test a word that starts as word FORTH and ends as assembly word
+\ -----------------------------------------------------------------------
+: TEST2 \ ":" starts compilation
+ BASE @ U. \ always display 10 !
+ HI2LO \ switch FORTH to ASM : compile one word (next address)
+ \ add vocabulary ASSEMBLER as CONTEXT vocabulary
+ \ switch in interpret mode
+ CMP #2, &BASE
+0<> IF MOV #2, &BASE \ if variable system BASE <> 2
+ELSE MOV #10,&BASE \ else (BASE = 2)
+THEN
+\ MOV #EXIT,PC \ to pair with ":" i.e. to restore IP saved by : then execute NEXT.
+\ but even compile two words, it's better to compile an inline EXIT :
+ MOV @RSP+,IP \ restore IP
+ MOV @IP+,PC \ = NEXT
+ENDCODE \ ends assembler : remove vocabulary ASSEMBLER from CONTEXT
+ \
+
+\ -----------------------------------------------------------------------
+\ test a word that starts as assembly word and ends as FORTH word
+\ -----------------------------------------------------------------------
+CODE TEST3 \ "CODE" starts assembler, i.e. add ASSEMBLER as CONTEXT vocabulary
+ CMP #2, &BASE
+0<> IF MOV #2, &BASE \ if variable system BASE <> 2
+ELSE MOV #10,&BASE \ else (BASE = 2)
+THEN COLON \
+ BASE @ U. \ always display 10 !
+; \
+ \
+
+
+\ -----------------------------------------------------------------------
+\ test an assembly jump spanning a section written in FORTH
+\ -----------------------------------------------------------------------
+: TEST5
+ SPACE
+ HI2LO
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ MOV #%1010,TOS \ init count = 10
+BEGIN SUB #$0001,TOS
+ LO2HI
+ \ IP is already saved by word ":"
+ DUP U. \ display count
+ HI2LO
+ CMP #0,TOS
+0= UNTIL MOV @PSP+,TOS
+\ MOV #EXIT,PC \ to pair with ":" i.e. to restore IP saved by : then execute NEXT.
+ MOV @RSP+,IP \ restore IP
+ MOV @IP+,PC \ = NEXT
+ENDCODE
+ \
+TEST5 ; you should see : 9 8 7 6 5 4 3 2 1 0 -->
+ \
+
+\ -----------------------------------------------------------------------
+\ tests indexing address
+\ -----------------------------------------------------------------------
+
+: TABLE
+CREATE
+0 DO I C,
+LOOP
+DOES>
++
+;
+
+8 TABLE BYTES_TABLE
+ \
+2 BYTES_TABLE C@ . ; you should see 2 -->
+\
+
+
+VARIABLE BYTES_TABLE1
+
+$0201 BYTES_TABLE1 ! \ words written in memory are little endian !
+
+CODE IDX_TEST1 \ index -- value
+ MOV.B BYTES_TABLE1(TOS),TOS \ -- value
+COLON
+ U.
+;
+
+0 IDX_TEST1 ; you should see 1 -->
+
+CODE TEST6
+ MOV 0(PSP),0(PSP) \
+ MOV @IP+,PC
+ENDCODE
+
+
+1 TEST6 . ; you should see 1 -->
+
+
+\ -----------------------------------------------------------------------
+\ tests behaviour of assembly error
+\ -----------------------------------------------------------------------
+\ R16 causes an error, assembler context is aborted and the word TEST7 is "hidden".
+
+; CODE TEST7
+; MOV 0(PSP),0(R16) ; display an error "out of bounds" -->
+
+
+
+
+
+
--- /dev/null
+\ -----------------------------
+\ MSP-EXP430FR5969_TSTWORDS.4th
+\ -----------------------------
+
+ECHO
+PWR_HERE
+
+\ -----------------------------------------------------------------------
+\ test some assembler words and show how to mix FORTH/ASSEMBLER routines
+\ -----------------------------------------------------------------------
+LOAD" \misc\TestASM.4th"
+
+\ -------------------------------------
+\ here we returned in the TestWords.4th
+\ -------------------------------------
+
+\ ----------
+\ LOOP tests
+\ ----------
+: LOOP_TEST 8 0 DO I . LOOP
+;
+
+LOOP_TEST \ you should see 0 1 2 3 4 5 6 7 -->
+
+
+: LOOP_TEST1 \ n <LOOP_TEST1> ---
+
+ BEGIN DUP U. 1 -
+ ?DUP
+ 0= UNTIL
+;
+
+
+: FIND_NOTHING \ FIND_NOTHING --
+ 25000 0
+ DO
+ LOOP \ 14 cycles by loop
+ ABORT" 25000 x nothing = nothing..."
+;
+
+
+
+ : FIND_TEST \ FIND_TEST <word> --
+ BL WORD \ -- c-addr
+ 50000 0
+ DO \ -- c-addr
+ DUP
+ FIND DROP DROP
+ LOOP
+ FIND
+ 0= IF ABORT" <-- not found !"
+ ELSE ABORT" <-- found !"
+ THEN
+ ;
+
+\ seeking $ word, FIND jumps all words on their first character so time of word loop is 20 cycles
+\ see FIND in the source file for more information
+
+\ FIND_TEST <lastword> result @ 8MHz, monothread : 1,2s
+
+\ FIND_TEST $ results @ 8MHz, monothread, 201 words in vocabulary FORTH :
+\ 27 seconds with only FORTH vocabulary in CONTEXT
+\ 540 us for one search ( which gives the delay for QNUMBER in INTERPRET routine)
+\ 2.6866 us / word, 21,49 cycles / word (for 20 cycles calculated (see FIND in source file)
+
+
+\ FIND_TEST $ results @ 8MHz, 2 threads, 201 words in vocabulary FORTH :
+\ 13 second with only FORTH vocabulary in CONTEXT
+\ 260 us for one search ( which gives the delay for QNUMBER in INTERPRET routine)
+\ 1,293 us / word, 10,34 cycles / word
+
+\ FIND_TEST $ results @ 8MHz, 4 threads, 201 words in vocabulary FORTH :
+\ 8 second with only FORTH vocabulary in CONTEXT
+\ 160 us for one search ( which gives the delay for QNUMBER in INTERPRET routine)
+\ 0,796 us / word, 6,37 cycles / word
+
+\ FIND_TEST $ results @ 8MHz, 8 threads, 201 words in vocabulary FORTH :
+\ 4.66 second with only FORTH vocabulary in CONTEXT
+\ 93 us for one search ( which gives the delay for QNUMBER in INTERPRET routine)
+\ 0,4463 us / word, 3,7 cycles / word
+
+\ FIND_TEST $ results @ 8MHz, 16 threads, 201 words in vocabulary FORTH :
+\ 2,8 second with only FORTH vocabulary in CONTEXT
+\ 56 us for one search ( which gives the delay for QNUMBER in INTERPRET routine)
+\ 0,278 us / word, 2,22 cycles / word
+
+
+\ --------
+\ KEY test
+\ --------
+: KEY_TEST
+ ." type a key : "
+ KEY EMIT \ wait for a KEY, then emit it
+;
+\ KEY_TEST
--- /dev/null
+\ UTILITY.f
+\ must be preprocessed with yourtarget.pat file, for PSTACK,CONTEXT,INI_THREAD
+
+\ REGISTERS USAGE
+\ R4 to R7 must be saved before use and restored after
+\ scratch registers Y to S are free for use
+\ under interrupt, IP is free for use
+
+\ PUSHM order : PSP,TOS, IP, S, T, W, X, Y, R7, R6, R5, R4
+\ example : PUSHM IP,Y
+\
+\ POPM order : R4, R5, R6, R7, Y, X, W, T, S, IP,TOS,PSP
+\ example : POPM Y,IP
+
+\ ASSEMBLER conditionnal usage after IF UNTIL WHILE : S< S>= U< U>= 0= 0<> 0>=
+\ ASSEMBLER conditionnal usage before GOTO ?GOTO : S< S>= U< U>= 0= 0<> <0
+
+\ FORTH conditionnal usage after IF UNTIL WHILE : 0= 0< = < > U<
+
+
+\ WIPE ; remove all previous apps,
+RST_STATE ; preserve all previous apps,
+\ NOECHO ; if an error occurs, comment this line before new download to find it.
+ \
+
+
+CODE ? \ adr -- display the content of adr
+ MOV @TOS,TOS
+ MOV #U.,PC \ goto U.
+ENDCODE
+ \
+
+CODE SP@ \ -- SP
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ MOV PSP,TOS
+ MOV @IP+,PC
+ENDCODE
+
+: .S \ -- print <number> of cells and stack contents if not empty
+$3C EMIT \ -- char "<"
+DEPTH .
+8 EMIT \ backspace
+$3E EMIT SPACE \ char ">"
+SP@ PSTACK OVER OVER U< \
+IF 2 -
+ DO I @ U.
+ -2 +LOOP
+ELSE
+ DROP DROP
+THEN
+;
+ \
+
+: WORDS \ -- list all words in all dicts in CONTEXT.
+
+\ vvvvvvvv may be skipped vvvvvvvv
+BASE @ \ -- BASE
+#10 BASE !
+CR ." "
+INI_THREAD @ DUP
+1 = IF DROP ." monothread"
+ ELSE . ." threads"
+ THEN ." vocabularies"
+BASE ! \ --
+\ ^^^^^^^^ may be skipped ^^^^^^^^
+
+CONTEXT \ -- CONTEXT
+BEGIN \ search dictionnary
+ DUP
+ 2 + SWAP \ -- CONTEXT+2 CONTEXT
+ @ ?DUP \ -- CONTEXT+2 (VOC_BODY VOC_BODY or 0)
+WHILE \ -- CONTEXT+2 VOC_BODY dictionnary found
+CR ." " \
+\ MOVE all threads of VOC_BODY in PAD
+ DUP PAD INI_THREAD @ DUP + \ -- CONTEXT+2 VOC_BODY VOC_BODY PAD THREAD*2
+ MOVE \ char MOVE
+
+ BEGIN \ -- CONTEXT+2 VOC_BODY
+ 0 DUP \ -- CONTEXT+2 VOC_BODY ptr MAX
+\ select the MAX of NFA in threads
+ INI_THREAD @ DUP + 0 DO \ ptr = threads*2
+ DUP I PAD + @ \ -- CONTEXT+2 VOC_BODY ptr MAX MAX NFAx
+ U< IF
+ DROP DROP I DUP PAD + @ \ -- CONTEXT+2 VOC_BODY ptr MAX if MAX U< NFAx replace adr and MAX
+ THEN \
+ 2 +LOOP \ -- CONTEXT+2 VOC_BODY ptr MAX
+ ?DUP \ -- CONTEXT+2 VOC_BODY ptr MAX max NFA = 0 ? end of vocabulary ?
+ WHILE \ -- CONTEXT+2 VOC_BODY ptr MAX
+\ replace it by its LFA
+ DUP \ -- CONTEXT+2 VOC_BODY ptr MAX MAX
+ 2 - @ \ -- CONTEXT+2 VOC_BODY ptr MAX [LFA]
+ ROT \ -- CONTEXT+2 VOC_BODY MAX [LFA] ptr
+ PAD + \ -- CONTEXT+2 VOC_BODY MAX [LFA] thread
+ ! \ -- CONTEXT+2 VOC_BODY MAX
+\ type it in 16 chars format
+ DUP \ -- CONTEXT+2 VOC_BODY MAX MAX
+ COUNT $7F AND TYPE \ -- CONTEXT+2 VOC_BODY MAX
+ C@ $0F AND \ --
+ $10 SWAP - SPACES \ -- CONTEXT+2 VOC_BODY
+\ search next MAX of NFA
+ REPEAT
+ \ -- CONTEXT+2 VOC_BODY 0
+ DROP DROP \ -- CONTEXT+2
+ CR
+\ repeat for each CONTEXT vocabulary
+
+REPEAT \ -- 0
+DROP \ --
+;
+ \
+
+CODE MAX \ n1 n2 -- n3 signed maximum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO FW1 \ n2<n1
+BW1 ADD #2,PSP
+ MOV @IP+,PC
+ENDCODE
+ \
+
+CODE MIN \ n1 n2 -- n3 signed minimum
+ CMP @PSP,TOS \ n2-n1
+ S< ?GOTO BW1 \ n2<n1
+FW1 MOV @PSP+,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+
+: U.R \ u n -- display u unsigned in n width (n >= 2)
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+: DUMP \ adr n -- dump memory
+ BASE @ >R $10 BASE !
+ SWAP $FFF0 AND SWAP
+ OVER + SWAP
+ DO CR \ generate line
+ I 7 U.R SPACE \ generate address
+ I $10 + I \ display 16 bytes
+ DO I C@ 3 U.R LOOP
+ SPACE SPACE
+ I $10 + I \ display 16 chars
+ DO I C@ $7E MIN BL MAX EMIT LOOP
+ $10 +LOOP
+ R> BASE !
+;
+
+ \
+
+ECHO
+ ; added : ? SP@ .S WORDS U.R MAX MIN DUMP
+ ; v--- use backspaces before hit "CR" if you want decrease level of app protection
+PWR_HERE RST_HERE
\ No newline at end of file
--- /dev/null
+\ name : MSP430FR5xxx_I2CF_Soft_Master.asm
+
+WIPE
+\ NOECHO
+
+\ Copyright (C) <2015> <J.M. THOORENS>
+\
+\ This program is free software: you can redistribute it and/or modify
+\ it under the terms of the GNU General Public License as published by
+\ the Free Software Foundation, either version 3 of the License, or
+\ (at your option) any later version.
+\
+\ This program is distributed in the hope that it will be useful,
+\ but WITHOUT ANY WARRANTY\ without even the implied warranty of
+\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+\ GNU General Public License for more details.
+\
+\ You should have received a copy of the GNU General Public License
+\ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+\ version 2.0 2015-07-30
+\
+\
+\ -------------------------------------------------------------------------------------------------------------------\
+\ I2CF Soft MASTER, FAST MODE, 8MHz
+\ -------------------------------------------------------------------------------------------------------------------\
+
+\ ======================================================================================================
+\ ======================================================================================================
+
+\ ### ##### ##### ###### ##### # #
+\ # # # # # # # # #### ###### ##### ## ## ## #### ##### ###### #####
+\ # # # # # # # # # # # # # # # # # # # #
+\ # ##### # ##### ##### # # ##### # # # # # # #### # ##### # #
+\ # # # # # # # # # # # ###### # # # #####
+\ # # # # # # # # # # # # # # # # # # # # #
+\ ### ####### ##### # ##### #### # # # # # # #### # ###### # #
+
+\ ======================================================================================================
+\ ======================================================================================================
+
+\ use Px.0 to Px.3 pins as SCL and SDA pins to use immediate instruction in one byte (#1,#2,#4,#8)
+
+\ tested with P1.6 SDA, P1.7 SCL :
+\ Start + Adr + Write 3 bytes + Stop + Start + adr + read 2 bytes + stop = 300us ==> 210 kHz
+\ See MSP430FR5xxx_I2CF_Soft_Master.png
+
+VARIABLE I2CS_ADR \ low(I2CS_ADR) = slave I2C address with RW flag, high(I2CS_ADR) = RX buffer,data0
+2 ALLOT \ data1,data2
+VARIABLE I2CM_BUF \ low(I2CM_BUF) = RX or TX lentgh, high(I2CM_BUF) = TX buffer,data0
+2 ALLOT \ data1,data2
+ \
+
+\ ----------------------------------\
+AMS I2C_MTX \ MASTER TX \ shared code for address and TX data
+\ ----------------------------------\
+BEGIN \
+ ADD.B X,X \ 1 l shift one left
+ U>= IF \ 2 l carry set ?
+ BIC.B #MSDA,&I2CSM_DIR \ 4 l yes : SDA as input ==> SDA high because pull up resistor
+ ELSE \ 2 l
+ BIS.B #MSDA,&I2CSM_DIR \ 4 l no : SDA as output ==> SDA low
+ THEN \ l _
+ BIC.B #MSCL,&I2CSM_DIR \ 4 l _^ release SCL (high)
+ BEGIN \ 14/16~l
+ BIT.B #MSCL,&I2CSM_IN \ 3 h test if SCL is released
+ 0<> UNTIL \ 2 h _
+ BIS.B #MSCL,&I2CSM_DIR \ 4 h v_ SCL as output : force SCL low
+ SUB #1,W \ 1 l count of bits
+0= UNTIL \ 2 l
+BIC.B #MSDA,&I2CSM_DIR \ 5 l _ SDA as input : release SDA high to prepare read Ack/Nack
+MOV @RSP+,PC
+ENDASM \
+ \
+
+
+\ ==================================\
+ASM I2C_M \
+\ ==================================\
+\ \ in I2CS_ADR/I2CM_BUF as RX/TX buffer requested by I2CS_ADR(0(0))
+\ \ I2CS_ADR(0) = I2C_Slave_addr&R/w
+\ \ I2CM_BUF(0) = TX/RX count of datas
+\ \ I2CM_BUF(0) = 0 ==> send only I2C address
+\ \ used S BUF ptr
+\ \ T datas countdown
+\ \ W bits countdown
+\ \ X data
+\ \ out I2CSLA_ADR & (R/W) unCHNGd
+\ \ S = BUF PTR pointing on first data not exCHNGd
+\ \ T = count+1 of TX/RX datas exCHNGd
+\ \ I2CS_ADR(0) = unCHNGd
+\ \ I2CM_BUF(0) = count of data not exCHNGd (normally = 0)
+\ \ I2CM_BUF(0) = -1 <==> Nack on address
+\ ----------------------------------\
+\ I2C_Master_Start_Cond: \ here, SDA and SCL are in idle state
+\ ----------------------------------\
+BIS.B #MSDA,&I2CSM_DIR \ 4 l force SDA as output (low)
+MOV #I2CM_BUF,W \ 2 h W=buffer out
+MOV.B @W+,T \ 2 h T=datas countdown
+MOV #I2CS_ADR,S \ 2 h S=buffer in
+MOV.B @S+,X \ 2 h X=Slave address to TX
+BIT.B #1,X \ 1 h test I2C R/w flag
+0= IF \ 2 h if write
+ MOV W,S \ 2 h S= buffer out ptr
+THEN \ S= buffer ptr
+BIS.B #MSCL,&I2CSM_DIR \ 4 h force SCL as output (low)
+\ ----------------------------------\
+\ I2C_Master_Start_EndOf: \
+\ ----------------------------------\
+\ I2C_Master_Send_address \ may be SCL is held low by slave
+\ ----------------------------------\
+ADD #1,T \ 1 l to add address in count
+MOV #8,W \ 1 l prepare 8 bit Master writing
+CALL #I2C_MTX \ 21 l to send address
+\ ----------------------------------\
+\ I2C_Master_Loop_Data \
+\ ----------------------------------\
+BEGIN \ 4 l here ack/nack is received/transmitted
+\ --------------------------------\ l
+\ Master TX/RX ACK/NACK \
+\ --------------------------------\ l _
+ BIC.B #MSCL,&I2CSM_DIR \ 3 l _^ release SCL (high)
+ BEGIN \
+ BIT.B #MSCL,&I2CSM_IN \ 3 h test if SCL is released
+ 0<> UNTIL \ 2 h
+ BIT.B #MSDA,&I2CSM_IN \ 3 h _ get SDA
+ BIS.B #MSCL,&I2CSM_DIR \ 3 h v_ SCL as output : force SCL low
+\ --------------------------------\ l
+\ I2C_Master_Loop_Data \
+\ --------------------------------\
+ 0<> IF BIS #Z,SR \ 5 l if Nack (TX), force Z=1 ==> StopCond
+ ELSE SUB.B #1,T \ 3 l else dec count
+ THEN \ l
+\ --------------------------------\
+\ I2C_Master_CheckCountDown \ count=0 (TX) or Nack received
+\ --------------------------------\
+ 0= IF \ 2 l send stop
+\ ----------------------------\
+\ Send Stop \
+\ ----------------------------\ _
+ BIS.B #MSDA,&I2CSM_DIR \ 4 l v_ SDA as output ==> SDA low
+ SUB.B T,&I2CM_BUF \ 4 l _ refresh buffer length and reach tSU:STO
+ BIC.B #MSCL,&I2CSM_DIR \ 4 l _^ release SCL (high)
+ BEGIN \
+ BIT.B #MSCL,&I2CSM_IN \ 3 h SCL released ?
+ 0<> UNTIL \ 2 h
+ BIC.B #MSDA,&I2CSM_DIR \ 4 h _^ SDA as input ==> SDA high with pull up resistor
+ MOV @RSP+,PC \ RET ====>
+ THEN \
+ MOV.B #8,W \ 1 l prepare 8 bits transaction
+ BIT.B #1,&I2CS_ADR \ 3 l I2C_Master Read/write bit test
+ 0= IF \ 2 l write flag test
+\ ============================\
+\ I2C_Master_TX \
+\ ============================\
+ MOV.B @S+,X \ 2 l next byte to transmit
+ CALL #I2C_MTX \ l to send data
+ ELSE \ l
+\ ============================\
+\ I2C_Master_RX: \ here, SDA is indetermined, SCL is strech low by master
+\ ============================\
+ BIC.B #MSDA,&I2CSM_DIR \ 5 l After ACK we must release SDA
+ BEGIN \
+\ ------------------------\ _
+\ send bit \ SCL _| |_
+\ ------------------------\ _
+ BIC.B #MSCL,&I2CSM_DIR \ 4 l _^ release SCL (high)
+ BEGIN \ 14/16~l
+ BIT.B #MSCL,&I2CSM_IN \ 3 h test if SCL is released
+ 0<> UNTIL \ 2 h
+ BIT.B #MSDA,&I2CSM_IN \ 4 h _ get SDA
+ BIS.B #MSCL,&I2CSM_DIR \ 4 h v_ SCL as output : force SCL low 13~
+ ADDC.B X,X \ 1 l C <-- X <--- C
+ SUB #1,W \ 1 l count of bits
+ 0= UNTIL \ 2 l
+ MOV.B X,0(S) \ 3 l store byte in buffer
+ ADD #1,S \ 1 l
+\ ----------------------------\
+\ Compute Ack Or Nack \ here, SDA is released by slave, SCL is strech low by master
+\ ----------------------------\
+ CMP.B #1,T \
+ 0<> IF \ 2 l
+ BIS.B #MSDA,&I2CSM_DIR \ 5 l yes : send Ack
+ THEN \
+ THEN \
+AGAIN \ 2 l
+ENDASM \
+ \
+
+
+
+\ ==================================\
+\ version reduced for TX only
+\ ==================================\
+VARIABLE I2CS_ADR \ low(I2CS_ADR) = slave I2C address with RW flag
+VARIABLE I2CM_BUF \ low(I2CM_BUF) = RX or TX lentgh, high(I2CM_BUF) = TX buffer,data0
+2 ALLOT \ data1,data2
+ \
+\ ==================================\
+ASM I2C_M_TX \
+\ ==================================\
+\ \ in I2CS_ADR/I2CM_BUF as RX/TX buffer requested by I2CS_ADR(0(0))
+\ \ I2CS_ADR(0) = I2C_Slave_addr&R/w
+\ \ I2CM_BUF(0) = TX/RX count of datas
+\ \ I2CM_BUF(0) = 0 ==> send only I2C address
+\ \ used S BUF ptr
+\ \ T datas countdown
+\ \ W bits countdown
+\ \ X data
+\ \ out I2CSLA_ADR & (R/W) unCHNGd
+\ \ S = BUF PTR pointing on first data not exCHNGd
+\ \ T = count+1 of TX/RX datas exCHNGd
+\ \ I2CS_ADR(0) = unCHNGd
+\ \ I2CM_BUF(0) = count of data not exCHNGd (normally = 0)
+\ \ I2CM_BUF(0) = -1 <==> Nack on address
+\ ----------------------------------\
+\ I2C_Master_Start_Cond: \ here, SDA and SCL are in idle state
+\ ----------------------------------\
+BIS.B #MSDA,&PI2CMDIR \ 4 l force SDA as output (low)
+MOV #I2CM_BUF,W \ 2 h W=buffer out
+MOV.B @W+,T \ 2 h T=datas countdown
+MOV.B &I2CS_ADR,X \ 3 h X=Slave address to TX
+BIS.B #MSCL,&PI2CMDIR \ 4 h force SCL as output (low)
+\ ----------------------------------\
+\ I2C_Master_Start_EndOf: \
+\ ----------------------------------\
+\ I2C_Master_Send_address \ may be SCL is held low by slave
+\ ----------------------------------\
+ADD #1,T \ 1 l to add address in count
+\ ----------------------------------\
+\ I2C_Master_Loop_Data \
+\ ----------------------------------\
+BEGIN \ 2 l
+\ --------------------------------\
+\ I2C_MTX \
+\ --------------------------------\
+ MOV #8,W \ 1 l prepare 8 bit Master writing
+ BEGIN \
+ ADD.B X,X \ 1 l shift one left
+ U>= IF \ 2 l carry set ?
+ BIC.B #MSDA,&PI2CMDIR \ 4 l yes : SDA as input ==> SDA high because pull up resistor
+ ELSE \ 2 l
+ BIS.B #MSDA,&PI2CMDIR \ 4 l no : SDA as output ==> SDA low
+ THEN \ l
+ BIC.B #MSCL,&PI2CMDIR \ 4 l _^ release SCL (high)
+ BEGIN \ 14/16~l
+ BIT.B #MSCL,&PI2CMIN \ 3 h test if SCL is released
+ 0<> UNTIL \ 2 h _
+ BIS.B #MSCL,&PI2CMDIR \ 4 h v_ SCL as output : force SCL low
+ SUB #1,W \ 1 l count of bits
+ 0= UNTIL \ 2 l
+ BIC.B #MSDA,&PI2CMDIR \ 5 l _ SDA as input : release SDA high to prepare read Ack/Nack
+\ --------------------------------\ l
+\ Master TX/RX ACK/NACK \
+\ --------------------------------\ l _
+ BIC.B #MSCL,&PI2CMDIR \ 3 l _^ P1DIR.3 release SCL (high)
+ BEGIN \
+ BIT.B #MSCL,&PI2CMIN \ 3 h test if SCL is released
+ 0<> UNTIL \ 2 h
+ BIT.B #MSDA,&PI2CMIN \ 3 h _ get SDA
+ BIS.B #MSCL,&PI2CMDIR \ 3 h v_ SCL as output : force SCL low
+\ --------------------------------\ l
+ 0<> IF BIS #Z,SR \ 5 l if Nack (TX), force Z=1 ==> StopCond
+ ELSE SUB.B #1,T \ 3 l else dec count
+ THEN \ l
+\ --------------------------------\
+\ I2C_Master_CheckCountDown \ count=0 (TX) or Nack received
+\ --------------------------------\
+ 0= IF \ 2 l send stop
+\ ----------------------------\
+\ Send Stop \
+\ ----------------------------\ _
+ BIS.B #MSDA,&PI2CMDIR \ 4 l v_ SDA as output ==> SDA low
+ SUB.B T,&I2CM_BUF \ 4 l _ refresh buffer length and reach tSU:STO
+ BIC.B #MSCL,&PI2CMDIR \ 4 l _^ release SCL (high)
+ BEGIN \
+ BIT.B #MSCL,&PI2CMIN \ 3 h SCL released ?
+ 0<> UNTIL \ 2 h
+ BIC.B #MSDA,&PI2CMDIR \ 4 h _^ SDA as input ==> SDA high with pull up resistor
+ MOV @RSP+,PC \ RET ====>
+ THEN \
+ MOV.B @S+,X \ 2 l next byte to transmit
+AGAIN \ 2 l
+ENDASM \ 93 words
+ \
+
+
+
+\ ------------------------------\
+CODE START \
+\ ------------------------------\
+\ init PORTA (P2:P1) (complement) when reset occurs all I/O are set in input with resistors pullup
+BIC.B #M_BUS,&I2CSM_OUT \ preset SDA + SCL output low
+BIC.B #M_BUS,&I2CSM_REN \ SDA + SCL pullup/down disable
+\ ------------------------------\
+LO2HI
+." \ type stop to stop :-)"
+LIT recurse is WARM \ insert this starting routine between COLD and WARM...
+(WARM) \ ...and continue with (WARM)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+RST_HERE \ set here the reset dictionnary
+
+\ ---------------------------------------------------------------------------------------------------------------------\
+\ SCL clock generation, timing, and test of data(s) number are made by I2C_Master.
+\ slave can strech SCL low after Start Condition and after any bit.
+\
+\ address Ack/Nack is generated by the slave on SDA line (released by the master)
+\ Two groups of eight addresses (000xxxy and 1111xxxy) are not allowed (reserved)
+\ after address or data is sent, the transmitter (Master or Slave) must release SDA line to allow (N)Ack by the receiver
+\ data Ack/Nack are generated by the receiver (master or slave) on SDA line
+\ a master receiver must signal the end of data to the slave transmitter by sending a Nack bit
+\ Stop or restart conditions must be generated by master after a Nack bit.
+\ after Ack bit is sent, Slave must release SDA line to allow master to do stop or restart conditions.
+\
+\
+\ first byte = address + R/W flag | byte data (one, for example)
+\ __ _____ _____ _..._ _____ __R__ _NAK_ _____ _____ _..._ _____ _____ _NAK_ _
+\ SDA \____/_MSB_X_____X_..._X_LSB_X__W__x_ACK_x_MSB_X_____X_..._X_____X_LSB_X_ACK_X___/
+\ _____ _ _ _ _ _ _ _ _ _ _ ___
+\ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/
+\ ^ ^ ^ ^ ^ ^ ^
+\ | |SSL |SSL |SSL |SSL |SSL |
+\ | |
+\ |Start Condition |stoP Condition
+\
+\ first byte = address + R/W flag | byte data (one, for example)
+\ __ _____ _____ _..._ _____ __R__ _NAK_ _____ _____ _..._ _____ _____ _NAK_ ___
+\ SDA \____/_MSB_X_____X_..._X_LSB_X__W__x_ACK_x_MSB_X_____X_..._X_____X_LSB_X_ACK_X \____...
+\ _____ _ _ _ _ _ _ _ _ _ _ ____
+\ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/ \_...
+\ ^ ^ ^ ^ ^ ^ ^
+\ | |SSL |SSL |SSL |SSL |SSL |
+\ | |
+\ |Start Condition |reStart Condition
+\
+\ SSL : Slave can strech SCL low
+\ tHIGH : SCL high time
+\ tLOW : SCL low time
+\ tBUF : SDA high time between Stop and Start conditions
+\ tHD:STA : Start_Condition SCL high time after SDA is low
+\ tSU:STO : Stop_Condition SCL high time before SDA rise
+\ tSU:STA : Start_Condition SCL high time before SDA fall
+\ tHD:DAT : SDA data change time after SCL is low
+\ the SDA line must be strobe just after SCL is high
+\ the SDA data must be change just after SCL is low
+\ standard mode (up to 100 kHz) : tHIGH = tHD:STA = tSU:STO = 4µs
+\ tLOW = tSU:STA = tBUF = 4,7µs
+\ tHD:DAT <= 3,45 µs
+\ -------------------------------------------------------------------------------------------------------------------\
--- /dev/null
+\ name : msp430FR5xxx_I2CF_Soft_MultiMaster.asm
+
+\ Copyright (C) <2015> <J.M. THOORENS>
+\
+\ This program is free software: you can redistribute it and/or modify
+\ it under the terms of the GNU General Public License as published by
+\ the Free Software Foundation, either version 3 of the License, or
+\ (at your option) any later version.
+\
+\ This program is distributed in the hope that it will be useful,
+\ but WITHOUT ANY WARRANTY\ without even the implied warranty of
+\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+\ GNU General Public License for more details.
+\
+\ You should have received a copy of the GNU General Public License
+\ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+\ I2C MASTER Standard Mode software driver without interrupt, with detection collision
+\ Target: MSP430FR5xxx, tested @ 8,16,24 MHz and adjusted @ 16,24 MHz
+\ SDA = P1.2, SCL = P1.3, with 3k3 pullup resistors
+
+\ version 1.0 2015-03-24
+
+WIPE
+\ ==============================================================================================================
+\ ==============================================================================================================
+
+\ ### ##### ##### ###### ##### # # # #
+\ # # # # # # # # #### ###### ##### ## ## ## ## ## #### ##### ###### #####
+\ # # # # # # # # # # # # # # # # # # # # # # # #
+\ # ##### # ##### ##### # # ##### # # # # # # # # # #### # ##### # #
+\ # # # # # # # # # # # # # ###### # # # #####
+\ # # # # # # # # # # # # # # # # # # # # # # #
+\ ### ####### ##### # ##### #### # # # # # # # # #### # ###### # #
+
+\ ==============================================================================================================
+\ ==============================================================================================================
+
+\ use Px.0 to Px.3 for good timing at 8 MHz
+
+\ tested with P1.6 SDA, P1.7 SCL :
+\ Start + Adr + Write 3 bytes + Stop + Start + adr + read 2 bytes + stop = 310us ==> 200 kHz
+\ See MSP430FR5xxx_I2CF_Soft_MultiMaster.png
+
+VARIABLE I2CS_ADR \ low(I2CS_ADR) = slave I2C address with RW flag, high(I2CS_ADR) = RX buffer,data0
+2 ALLOT \ data1,data2
+VARIABLE I2CM_BUF \ low(I2CM_BUF) = RX or TX lentgh, high(I2CM_BUF) = TX buffer,data0
+2 ALLOT \ data1,data2
+ \
+
+\ ==================================\
+ASM I2C_MM \ soft I2C_MultiMaster driver
+\ ==================================\
+\ \ in : I2CS_ADR pointer
+\ \ : I2CM_BUF pointer
+\ \ used: S BUF_PTR
+\ \ T count of I2C datas exchanged
+\ \ W count of bits
+\ \ X data
+\ \ Y BUF_ORG
+\ \ SR(10) collision flag
+\ \ out : I2CS_ADR(0) unchanged
+\ \ I2CM_BUF(0) = count of data not exchanged (normally = 0)
+\ \ I2CM_BUF(0) = -1 <==> Nack on address
+\ ----------------------------------\
+\ I2CMM_Stop_UCBxI2CSlave \ if SDA SCL of I2C_MultiMaster are hard wired onto SDA SCL of I2C_Slave under interrupt...
+\ ----------------------------------\
+\ BIS #1,&UCB0CTLW0 \ set eUSCI_B0 in reset state, reset StartCond int in UCB0IFG
+\ BIC.B #SMM_BUS,&PI2CMSEL1 \ disable I2C I/O
+\ ----------------------------------\
+\ I2C_MR_DC_listenBeforeStart: \ test if SCL & SDA lines are idle (high)
+\ ----------------------------------\
+BEGIN \
+ BIC.B #SMM_BUS,&I2CSMM_DIR \ SDA & SCL pins as input
+ BIC.B #SMM_BUS,&I2CSMM_OUT \ preset output LOW for SDA & SCL pins
+ MOV #2,T \ I2C_MR_DC_Wait_Start_Loop = 3 µs @ 8 MHz
+ BEGIN \ 15~loop
+ BEGIN \
+ BEGIN \
+ BIT.B #SMMSCL,&I2CSMM_IN \ 4 SCL high ?
+ 0<> UNTIL \ 2
+ BIT.B #SMMSDA,&I2CSMM_IN \ 4 SDA high ?
+ 0<> UNTIL \ 2
+ SUB #1,T \ 1
+ 0= UNTIL \ 2 here the I2C bus is idle
+\ --------------------------------\
+\ I2C_Master_Start_Cond: \ here, SDA and SCL are in idle state
+\ --------------------------------\
+ BIS.B #SMMSDA,&I2CSMM_DIR \ 4 h force SDA output (low)
+ MOV #I2CS_ADR,S \ 2 l
+ MOV.B @S+,X \ 3 l X = slave address, S = RX buffer
+ MOV #I2CM_BUF,W \ 2 l
+ MOV.B @W+,T \ 2 l T = count of datas, W = TX buffer
+ ADD.B #1,T \ 1 l to add address in count
+ BIT.B #1,X \ 1 l test I2C R/w flag
+ 0= IF \ 2 l write flag ?
+ MOV W,S \ 3 l TX buffer
+ THEN \
+ BIS.B #SMMSCL,&I2CSMM_DIR \ 4 h force SCL output (low)
+\ --------------------------------\ l
+\ I2C_Master_Start_EndOf: \ l
+\ --------------------------------\
+\ I2C_Master_Send_address \ l SCL
+\ --------------------------------\
+ BIC #UF2,SR \ 2 reset detection collision SR(10) flag
+ MOV #8,W \ 1 l 8 bits TX
+ BEGIN \
+ ADD.B X,X \ 1 l shift one left
+ U>= IF \ 2 l carry set ?
+ BIC.B #SMMSDA,&I2CSMM_DIR \ 4 l yes : releas SDA high because pull up resistor
+ ELSE \ 2 l
+ BIS.B #SMMSDA,&I2CSMM_DIR \ 4 l no : set as output ==> SDA low
+ THEN \ l _
+ BIC.B #SMMSCL,&I2CSMM_DIR \ 4 l _^ release SCL (high)
+ BEGIN \
+ BIT.B #SMMSCL,&I2CSMM_IN \ 4 h test if SCL is released
+ 0<> UNTIL \ 2 h
+ MOV.B &I2CSMM_IN,Y \ 3 h _ get SDA in Y
+ BIS.B #SMMSCL,&I2CSMM_DIR \ 4 h v_ force SCL low
+\ ----------------------------\
+\ collision detection \ l
+\ ----------------------------\
+ XOR.B &I2CSMM_DIR,Y \ 3 normal : IN(SMMSDA) XOR DIR(SMMSDA) = 1
+ BIT.B #SMMSDA,Y \ 2 collision : IN(SMMSDA=0) XOR DIR(SMMSDA=0) = 0
+ 0= IF BIS #$0402,SR \ 6 set collision detection flag SR(10) and set Z=1 to force end of loop
+ ELSE SUB #1,W \ 3 dec count of bits
+ THEN \
+ 0= UNTIL \ 2
+ BIT #UF2,SR \ 2 collision ?
+0= UNTIL \ 2 loop back if collision during send address
+BIC.B #SMMSDA,&I2CSMM_DIR \ 5 release SDA high before 9th bit
+\ ----------------------------------\
+\ I2C_Master_Loop \
+\ ----------------------------------\
+BEGIN \ 4 l
+\ --------------------------------\ l
+\ Master TX/RX ACK/NACK \
+\ --------------------------------\ l _
+ BIC.B #SMMSCL,&I2CSMM_DIR \ 3 l _^ release SCL (high)
+ BEGIN \
+ BIT.B #SMMSCL,&I2CSMM_IN \ 3 h test if SCL is released
+ 0<> UNTIL \ 2 h
+ BIT.B #SMMSDA,&I2CSMM_IN \ 3 h _ get SDA
+ BIS.B #SMMSCL,&I2CSMM_DIR \ 3 h v_ force SCL low
+\ --------------------------------\ 4 l here ack/nack is received/transmitted
+\ I2C_Master_Loop_Data \
+\ --------------------------------\
+ 0<> IF BIS #Z,SR \ 5 if Nack (TX), force Z+1 ==> StopCond
+ ELSE SUB.B #1,T \ 3 else dec count
+ THEN \
+\ --------------------------------\
+\ I2C_Master_CheckCountDown \ count=0 or Nack received
+\ --------------------------------\
+ 0= IF \ count reached or Nack
+\ ----------------------------\
+\ I2C_Master_StopCond \
+\ ----------------------------\ _
+ BIS.B #SMMSDA,&I2CSMM_DIR \ 4 l v_ force SDA low
+ SUB.B T,&I2CM_BUF \ 4 l refresh buffer length and reach tSU:STO
+ BIC.B #SMMSCL,&I2CSMM_DIR \ 4 l _^ release SCL (high)
+ BEGIN \
+ BIT.B #SMMSCL,&I2CSMM_IN \ 3 h SCL released ?
+ 0<> UNTIL \ 2 h _
+ BIC.B #SMMSDA,&I2CSMM_DIR \ _| as input ==> SDA high with the hard wired pull up resistor
+\ ----------------------------\
+\ I2C_Master_Endof \
+\ ----------------------------\
+\ Restart I2C_Slave_Int \ if any
+\ ----------------------------\
+\ MOV #4,&UCB0IE \ enable StartCond interrupt in UCB0IE register
+\ BIC #1,&UCB0CTLW0 \ restart eUSCI_B
+\ BIS.B #SMM_BUS,&I2CSMM_SEL1 \ reenable I2C I/O
+\ ----------------------------\
+ MOV @RSP+,PC \ ====> out
+\ ----------------------------\
+ THEN \
+ MOV.B #8,W \ 1 l prepare 8 bits transaction
+ BIT #1,&I2CS_ADR \ 3 l I2C_Master Read/write bit test
+ 0= IF \ 2 l write flag test
+\ ----------------------------\
+\ I2C Master write \
+\ ----------------------------\
+ MOV.B @S+,X \ 2 l X = TX data
+ BEGIN \
+ ADD.B X,X \ 1 l shift one left
+ U>= IF \ 2 l carry set ?
+ BIC.B #SMMSDA,&I2CSMM_DIR \ 4 l yes : release SDA (high because pull up resistor)
+ ELSE \ 2 l
+ BIS.B #SMMSDA,&I2CSMM_DIR \ 4 l no : force SDA low
+ THEN \ l _
+ BIC.B #SMMSCL,&I2CSMM_DIR \ 4 l _^ release SCL (high)
+ BEGIN \
+ BIT.B #SMMSCL,&I2CSMM_IN \ 4 h test if SCL is released
+ 0<> UNTIL \ 2 h _
+ BIS.B #SMMSCL,&I2CSMM_DIR \ 4 h v_ force SCL low
+ SUB #1,W \ 1 l count of bits
+ 0= UNTIL \ 2 l
+ BIC.B #SMMSDA,&I2CSMM_DIR \ 4 l release SDA high
+ ELSE \ 2 l
+\ ============================\
+\ I2C_Master_RX: \ here, SDA is indetermined, SCL is strech low by master
+\ ============================\
+ BIC.B #SMMSDA,&I2CSMM_DIR \ 5 l _ After ACK we must release SDA
+ BEGIN \
+\ ------------------------\ _
+\ send bit \ SCL _| |_
+\ ------------------------\ _
+ BIC.B #SMMSCL,&I2CSMM_DIR \ 3 l _^ release SCL (high)
+ BEGIN \
+ BIT.B #SMMSCL,&I2CSMM_IN \ 3 h test if SCL is released
+ 0<> UNTIL \ 2 h
+ BIT.B #SMMSDA,&I2CSMM_IN \ 3 h _ get SDA
+ BIS.B #SMMSCL,&I2CSMM_DIR \ 3 h v_ force SCL low
+ ADDC.B X,X \ 1 l C <-- X <--- C
+ SUB #1,W \ 1 l count of bits
+ 0= UNTIL \ 2 l
+ MOV.B X,0(S) \ 3 l store byte @ BUF_PTR
+ ADD #1,S \ 1 l
+\ ----------------------------\
+\ I2C_MSendAckOrNack \ here, SDA is released by slave, SCL is strech low by master
+\ ----------------------------\
+ CMP.B #1,T \
+ 0<> IF \ 2
+ BIS.B #SMMSDA,&I2CSMM_DIR \ 4 l prepare send Ack if byte count <> 1
+ THEN \
+ THEN \
+AGAIN \ 2 l
+ENDASM \
+ \
+
+\ ------------------------------\
+CODE START \
+\ ------------------------------\
+\ init PORTA (P2:P1) (complement) when reset occurs all I/O are set in input with resistors pullup
+BIC.B #SMM_BUS,&I2CSMM_OUT \ preset SDA + SCL output low
+BIC.B #SMM_BUS,&I2CSMM_REN \ SDA + SCL pullup/down disable
+\ ------------------------------\
+LO2HI
+." Type STOP to stop :-)"
+LIT RECURSE IS WARM \ insert this routine between COLD and WARM...
+(WARM) ; \ ...and continue with WARM
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+RST_HERE
+
+
+\ ---------------------------------------------------------------------------------------------------------------------\
+\ SCL clock generation, timing, and test of data(s) number are made by I2C_Master.
+\ slave can strech SCL low after Start Condition and after any bit.
+
+\ address Ack/Nack is generated by the slave on SDA line (released by the master)
+\ Two groups of eight addresses (000xxxy and 1111xxxy) are not allowed (reserved)
+\ after address or data is sent, the transmitter (Master or Slave) must release SDA line to allow (N)Ack by the receiver
+\ data Ack/Nack are generated by the receiver (master or slave) on SDA line
+\ a master receiver must signal the end of data to the slave transmitter by sending a Nack bit
+\ Stop or restart conditions must be generated by master after a Nack bit.
+\ after Ack bit is sent, Slave must release SDA line to allow master to do stop or restart conditions
+\
+\ __ _____ _____ _..._ _____ _____ _NACK _____ _____ _..._ _____ _____ _NACK _
+\ SDA \____/_MSB_X_____X_..._X_LSB_X_R/W_x_ACK_x_MSB_X_____X_..._X_____X_LSB_X_ACK_X___/
+\ _____ _ _ _ _ _ _ _ _ _ _ ___
+\ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/
+\ ^ ^ ^ ^ ^ ^ ^
+\ | |Slave Stretch Low |SSL |SSL |SSL |SSL |
+\ | |
+\ |Start Condition |stoP Condition
+\
+\ __ _____ _____ _..._ _____ _____ _NACK _____ _____ _..._ _____ _____ _NACK ___
+\ SDA \____/_MSB_X_____X_..._X_LSB_X_R/W_x_ACK_x_MSB_X_____X_..._X_____X_LSB_X_ACK_X \____...
+\ _____ _ _ _ _ _ _ _ _ _ _ ____
+\ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/ \_...
+\ ^ ^ ^ ^ ^ ^ ^
+\ | |Slave Stretch Low |SSL |SSL |SSL |SSL |
+\ | |
+\ |Start Condition |reStart Condition
+\
+\ tHIGH : SCL high time
+\ tLOW : SCL low time
+\ tBUF : SDA high time between Stop and Start conditions
+\ tHD:STA : Start_Condition SCL high time after SDA is low
+\ tSU:STO : Stop_Condition SCL high time before SDA rise
+\ tSU:STA : Start_Condition SCL high time before SDA fall
+\ tHD:DAT : SDA data change time after SCL is low
+\ the SDA line must be strobe just after SCL is high
+\ the SDA data must be change just after SCL is low
+\ standard mode (up to 100 kHz) : tHIGH = tHD:STA = tSU:STO = 4µs
+\ tLOW = tSU:STA = tBUF = 4,7µs
+\ tHD:DAT <= 3,45 µs
+\ -------------------------------------------------------------------------------------------------------------------\
--- /dev/null
+\ name : msp430FR5xxx_I2C_Master.asm
+\
+\ Copyright (C) <2016> <J.M. THOORENS>
+\
+\ This program is free software: you can redistribute it and/or modify
+\ it under the terms of the GNU General Public License as published by
+\ the Free Software Foundation, either version 3 of the License, or
+\ (at your option) any later version.
+\
+\ This program is distributed in the hope that it will be useful,
+\ but WITHOUT ANY WARRANTY; without even the implied warranty of
+\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+\ GNU General Public License for more details.
+\
+\ You should have received a copy of the GNU General Public License
+\ along with this program. If not, see <http://www.gnu.org/licenses/>.
+\
+\
+\ I2C MASTER Standard Mode software driver without interrupt
+\ Target: MSP-EXP430FR5969 @ 8,16MHz
+\ version 1.1 2016-03-18
+\
+\ ---------------------------------------------------------------------------------------------------------------------;
+\ SCL clock generation, timing, and test of data(s) number are made by I2C_Master.
+\ slave can strech SCL low after Start Condition and after any bit.
+\
+\ address Ack/Nack is generated by the slave on SDA line (released by the master)
+\ Two groups of eight addresses (000$xxy and 1111xxxy) are not allowed (reserved)
+\ after address or data is sent, the transmitter (Master or Slave) must release SDA line to allow (N)Ack by the receiver
+\ data Ack/Nack are generated by the receiver (master or slave) on SDA line
+\ a master receiver must signal the end of data to the slave transmitter by sending a Nack bit
+\ Stop or restart conditions must be generated by master after a Nack bit.
+\ after Ack bit is sent, Slave must release SDA line to allow master to do stop or restart conditions
+\
+\ __ _____ _____ _..._ _____ _____ _NACK _____ _____ _..._ _____ _____ _NACK _
+\ SDA \____/_MSB_X_____X_..._X_LSB_X_R/W_x_ACK_x_MSB_X_____X_..._X_____X_LSB_X_ACK_X___/
+\ _____ _ _ _ _ _ _ _ _ _ _ ___
+\ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/
+\ ^ ^ ^ ^ ^ ^ ^
+\ | |Slave Stretch Low |SSL |SSL |SSL |SSL |
+\ | |
+\ |Start Condition |stoP Condition
+\
+\ __ _____ _____ _..._ _____ _____ _NACK _____ _____ _..._ _____ _____ _NACK ___
+\ SDA \____/_MSB_X_____X_..._X_LSB_X_R/W_x_ACK_x_MSB_X_____X_..._X_____X_LSB_X_ACK_X \____...
+\ _____ _ _ _ _ _ _ _ _ _ _ ____
+\ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/ \_...
+\ ^ ^ ^ ^ ^ ^ ^
+\ | |Slave Stretch Low |SSL |SSL |SSL |SSL |
+\ | |
+\ |Start Condition |reStart Condition
+\
+\ tHIGH : SCL high time
+\ tLOW : SCL low time
+\ tBUF : SDA high time between Stop and Start conditions
+\ tHD:STA : Start_Condition SCL high time after SDA is low
+\ tSU:STO : Stop_Condition SCL high time before SDA rise
+\ tSU:STA : Start_Condition SCL high time before SDA fall
+\ tHD:DAT : SDA data change time after SCL is low
+\ the SDA line must be strobe just after SCL is high
+\ the SDA data must be change just after SCL is low
+\ standard mode (up to 100 kHz) : tHIGH = tHD:STA = tSU:STO = 4µs
+\ tLOW = tSU:STA = tBUF = 4,7µs
+\ tHD:DAT <= 3,45 µs
+\
+\ fast mode (up to 400 kHz) : tHIGH = tHD:STA = tSU:STO = 0,6µs
+\ tLOW = tSU:STA = tBUF = 1,3µs
+\ tHD:DAT <= 0,9 µs
+\ -------------------------------------------------------------------------------------------------------------------;
+
+\ =================================================================
+\ =================================================================
+
+\ ### ##### ##### # #
+\ # # # # # ## ## ## #### ##### ###### #####
+\ # # # # # # # # # # # # # #
+\ # ##### # # # # # # #### # ##### # #
+\ # # # # # ###### # # # #####
+\ # # # # # # # # # # # # # #
+\ ### ####### ##### # # # # #### # ###### # #
+
+\ =================================================================
+\ =================================================================
+
+\ tested with P1.6 SDA, P1.7 SCL :
+\ Start + Adr + Write 3 bytes + Stop + Start + adr + read 2 bytes + stop = 204us ==> 308 kHz (STOP=10us)
+\ See MSP430FR5xxx_I2C_Master.png
+
+
+
+VARIABLE I2CS_ADR \ low(I2CS_ADR) = slave I2C address with RW flag, high(I2CS_ADR) = RX buffer,data0
+2 ALLOT \ data1,data2
+VARIABLE I2CM_BUF \ low(I2CM_BUF) = RX or TX lentgh, high(I2CM_BUF) = TX buffer,data0
+2 ALLOT \ data1,data2
+ \
+
+
+
+\ ----------------------------------\
+ASM I2C_M \
+\ ----------------------------------\
+\ \ in I2CS_ADR/I2CM_BUF as RX/TX buffer requested by I2CS_ADR(0(0))
+\ \ I2CS_ADR(0) = I2C_Slave_addr&R/w
+\ \ I2CM_BUF(0) = TX/RX count of datas
+\ \ I2CM_BUF(0) = 0 ==> send only I2C address
+\ \ used S = BUF ptr
+\ \ T
+\ \ out I2CSLA_ADR & (R/W) unCHNGd
+\ \ S = BUF PTR pointing on first data not exCHNGd
+\ \ T = count of TX/RX datas exCHNGd
+\ \ T = -1 ==> NACK on address
+\ \ I2CS_ADR(0) = unCHNGd
+\ \ I2CM_BUF(0) = unCHNGd
+BIS #1,&UCB0CTLW0 \ SWRST
+MOV #$0FD3,&UCB0CTLW0 \ master mode + UCTR + START + SWRST, IFG=IE=0
+MOV #$00C8,&UCB0CTLW1 \ set automatic stop (count byte reached)
+MOV #$14,&UCB0BRW \ baudrate = SMCLK/20 = 400 kHz @8MHz ; 340 kHz measured
+MOV #I2CM_BUF,S \ count & TX buf
+MOV.B @S+,&UCB0TBCNT \
+CMP.B #0,&UCB0TBCNT \
+0= IF \ count = 0
+ BIS #4,&UCB0CTLW0 \ add Stop cmd to Start cmd ==> Master send only I2C address
+THEN
+MOV #I2CS_ADR,T \ I2Cadr & RX buf
+MOV.B @T+,&UCB0I2CSA \ UCB0I2CSA = slave_address & R/w bit
+RRA &UCB0I2CSA \ UCB0I2CSA = slave_address, C flag = R/w flag
+U>= IF \ C flag = 1
+ MOV T,S \ Master read : S = RX buffer
+ BIC #$10,&UCB0CTLW0 \ UCB0CTLW0 <-- UCTR=0
+THEN \
+\ ------------------------------ \
+\ Start \
+\ ------------------------------ \
+MOV.B #-1,T \ T=-1
+BIC #1,&UCB0CTLW0 \ UCB0CTLW0 : clear SWRST, start I2C MASTER
+BIT.B #1,&I2CS_ADR \ R/W test
+0= IF \
+\ ---------------------------- \
+\ MASTER TX \
+\ ---------------------------- \
+ BEGIN \
+ MOV.B &UCBCNT0,T \ store count of byte
+ BIT #8,&UCB0IFG \ test UCSTPIFG
+ 0<> IF \
+ MOV @RSP+,PC \ end of I2C_M TX driver
+ THEN \
+ BIT #$20,&UCB0IFG \ test UCNACKIFG
+ 0<> IF \
+ BIS #4,&UCB0CTLW0 \ generate stop bit
+ MOV @RSP+,PC \ end of I2C_M TX driver
+ THEN \
+ BIT #2,&UCB0IFG \ test UCTXIFG0
+ 0<> IF \
+ MOV.B @S+,&UCB0TXBUF \ load data into UCB0TXBUF
+ THEN \
+ AGAIN \
+THEN \
+\ ------------------------------ \
+\ MASTER RX \
+\ ------------------------------ \
+BEGIN \ of Master RX
+ MOV.B &UCBCNT0,T \ store count of byte
+ BIT #8,&UCB0IFG \ test UCSTPIFG
+ 0<> IF \
+ MOV @RSP+,PC \ end of I2C_M RX driver
+ THEN \
+ BIT #1,&UCB0IFG \ test UCRXIFG0
+ 0<> IF \
+ MOV.B &UCB0RXBUF,0(S) \ load data from UCB0RXBUF
+ ADD #1,S \
+ THEN \
+AGAIN \
+ENDASM \ 62 words + 9 init words
+ \
+
+\ ------------------------------\
+CODE START \ init
+\ ------------------------------\
+\ init I2C_Master \
+\ ------------------------------\
+\ %0000 1111 1101 0011 $640 = $0FD3
+\ - UCMM = 1 : multi master mode
+\ - UCMST = 1 : I2C_Master
+\ -- UCMODE = %11 = I2C
+\ _ USYNC=1 (always 1)
+\ -- UCSSEL=SMCLK=8MHz
+\ - UCTXACK=0 not auto ACK slave address
+\ - UCTR=1/0 : TX/RX modes
+\ - UCTXSTP
+\ - UCTXSTT send start
+\ - UCSWRST=1
+\ ------------------------------\
+\ %0000 0000 1100 1000 $642 = $00C8
+\ - UCETXINT=0 : UCTXIFG0 set address match UCxI2COAx and TX mode
+\ -- UCCLTO=%11 : SCL low time out = 34 ms
+\ - UCSWACK=1 : UCTXACK must be written to continue
+\ -- UCASTP0=%10 : automatic Stop when UCBxTBCNT is reached
+\ ------------------------------\
+\ PORTX (PORTx:y) default values\ DIR0,REN1,OUT1 (input with pullup resistors)
+\ ------------------------------\
+\ notice : UCB0 I2C driver seems to control only DIR register !!!
+BIC.B #M_BUS,&I2CM_REN \ REN0 : no_resistor
+BIC.B #M_BUS,&I2CM_OUT \ OUT0 : preset output low
+BIS.B #M_BUS,&I2CM_SEL1 \ SEL11 : enable I2C I/O
+COLON
+." type stop to stop :-)"
+LIT RECURSE IS WARM \ insert this starting routine between COLD and WARM...
+(WARM) \ ...and continue with (WARM)
+;
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
--- /dev/null
+\ name : msp430FR5xxx_I2C_MMultiMaster.f
+\
+\ Copyright (C) <2016> <J.M. THOORENS>
+\
+\ This program is free software: you can redistribute it and/or modify
+\ it under the terms of the GNU General Public License as published by
+\ the Free Software Foundation, either version 3 of the License, or
+\ (at your option) any later version.
+\
+\ This program is distributed in the hope that it will be useful,
+\ but WITHOUT ANY WARRANTY; without even the implied warranty of
+\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+\ GNU General Public License for more details.
+\
+\ You should have received a copy of the GNU General Public License
+\ along with this program. If not, see <http://www.gnu.org/licenses/>.
+\
+\
+\ I2C MASTER Standard Mode software driver without interrupt
+\ Target: MSP-EXP430FR5969 @ 8,16MHz
+\ version 1.1 2016-03-18
+\
+\ ---------------------------------------------------------------------------------------------------------------------;
+\ SCL clock generation, timing, and test of data(s) number are made by I2C_MMaster.
+\ slave can strech SCL low after Start Condition and after any bit.
+\
+\ address Ack/Nack is generated by the slave on SDA line (released by the master)
+\ Two groups of eight addresses (000$xxy and 1111xxxy) are not allowed (reserved)
+\ after address or data is sent, the transmitter (Master or Slave) must release SDA line to allow (N)Ack by the receiver
+\ data Ack/Nack are generated by the receiver (master or slave) on SDA line
+\ a master receiver must signal the end of data to the slave transmitter by sending a Nack bit
+\ Stop or restart conditions must be generated by master after a Nack bit.
+\ after Ack bit is sent, Slave must release SDA line to allow master to do stop or restart conditions
+\
+\ __ _____ _____ _..._ _____ _____ _NACK _____ _____ _..._ _____ _____ _NACK _
+\ SDA \____/_MSB_X_____X_..._X_LSB_X_R/W_x_ACK_x_MSB_X_____X_..._X_____X_LSB_X_ACK_X___/
+\ _____ _ _ _ _ _ _ _ _ _ _ ___
+\ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/
+\ ^ ^ ^ ^ ^ ^ ^
+\ | |Slave Stretch Low |SSL |SSL |SSL |SSL |
+\ | |
+\ |Start Condition |stoP Condition
+\
+\ __ _____ _____ _..._ _____ _____ _NACK _____ _____ _..._ _____ _____ _NACK ___
+\ SDA \____/_MSB_X_____X_..._X_LSB_X_R/W_x_ACK_x_MSB_X_____X_..._X_____X_LSB_X_ACK_X \____...
+\ _____ _ _ _ _ _ _ _ _ _ _ ____
+\ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/ \_...
+\ ^ ^ ^ ^ ^ ^ ^
+\ | |Slave Stretch Low |SSL |SSL |SSL |SSL |
+\ | |
+\ |Start Condition |reStart Condition
+\
+\ tHIGH : SCL high time
+\ tLOW : SCL low time
+\ tBUF : SDA high time between Stop and Start conditions
+\ tHD:STA : Start_Condition SCL high time after SDA is low
+\ tSU:STO : Stop_Condition SCL high time before SDA rise
+\ tSU:STA : Start_Condition SCL high time before SDA fall
+\ tHD:DAT : SDA data change time after SCL is low
+\ the SDA line must be strobe just after SCL is high
+\ the SDA data must be change just after SCL is low
+\ standard mode (up to 100 kHz) : tHIGH = tHD:STA = tSU:STO = 4µs
+\ tLOW = tSU:STA = tBUF = 4,7µs
+\ tHD:DAT <= 3,45 µs
+\
+\ fast mode (up to 400 kHz) : tHIGH = tHD:STA = tSU:STO = 0,6µs
+\ tLOW = tSU:STA = tBUF = 1,3µs
+\ tHD:DAT <= 0,9 µs
+\ -------------------------------------------------------------------------------------------------------------------;
+
+\ =========================================================================
+\ =========================================================================
+
+\ ### ##### ##### # ## #
+\ # # # # # ## ## ## ## ## #### ##### ###### #####
+\ # # # # # # # # # # # # # # # # # #
+\ # ##### # # # # # # # # # #### # ##### # #
+\ # # # # # # # ###### # # # #####
+\ # # # # # # # # # # # # # # # #
+\ ### ####### ##### # # # # # # #### # ###### # #
+
+\ =========================================================================
+\ =========================================================================
+
+\ tested with P1.6 SDA, P1.7 SCL :
+\ Start + Adr + Write 3 bytes + Stop + Start + adr + read 2 bytes + stop = 206us ==> 305 kHz (STOP=14us)
+\ See MSP430FR5xxx_I2C_MultiMaster.png
+
+
+CREATE I2CMS_ADR \ low(I2CMS_ADR) = slave I2C address with RW flag, high(I2CMS_ADR) = RX buffer,data0
+4 ALLOT \ data1,data2
+CREATE I2CMM_BUF \ low(I2CMM_BUF) = RX or TX lentgh, high(I2CMM_BUF) = TX buffer,data0
+4 ALLOT \ data1,data2
+ \
+VARIABLE MY_OWN_ADR
+
+
+\ ----------------------------------\
+ASM I2C_MM \
+\ ----------------------------------\
+\ \ in I2CMS_ADR/I2CMM_BUF as RX/TX buffer requested by I2CMS_ADR(0(0))
+\ \ I2CMS_ADR(0) = I2C_Slave_addr&R/w
+\ \ I2CMM_BUF(0) = TX/RX count of datas
+\ \ I2CMM_BUF(0) = 0 ==> send only I2C address
+\ \ used S = BUF ptr
+\ \ T
+\ \ out S = BUF PTR pointing on first data not exCHNGd
+\ \ T = count of TX/RX datas exCHNGd
+\ \ T = -1 ==> NACK on address
+\ \ I2CMS_ADR(0) = -1 ==> arbitration lost, else unchanged
+\ \ I2CMM_BUF(0) = unchanged
+\ ------------------------------ \
+\ Swap Slave to Master mode \
+\ ------------------------------ \
+BIS #1,&UCB0CTLW0 \ SWRST
+MOV #$2FD3,&UCB0CTLW0 \ master mode + UCMM + UCTR + START + SWRST, IFG=IE=0
+MOV #$00C8,&UCB0CTLW1 \ set automatic stop (count byte reached)
+MOV #$14,&UCB0BRW \ baudrate = SMCLK/20 = 400 kHz @8MHz ; 340 kHz measured
+MOV &MY_OWN_ADR,&UCB0I2COA0 \ (required by multimaster mode)
+BIS #$0400,&UCB0I2COA0 \ UCOAEN=1 enable UCB0I2COA0 with address slave
+\ ------------------------------ \
+MOV #I2CMM_BUF,S \ count & TX buf
+MOV.B @S+,&UCB0TBCNT \
+CMP.B #0,&UCB0TBCNT \
+0= IF \ count = 0
+ BIS #4,&UCB0CTLW0 \ add Stop to Start cmd ==> Master send only I2C address
+THEN
+MOV #I2CMS_ADR,T \ I2Cadr & RX buf
+MOV.B @T+,&UCB0I2CSA \ UCB0I2CSA = slave_address & R/w bit
+RRA &UCB0I2CSA \ UCB0I2CSA = slave_address, C flag = R/w flag
+U>= IF \ C flag = 1
+ MOV T,S \ Master read : S = RX buffer
+ BIC #$10,&UCB0CTLW0 \ UCB0CTLW0 <-- UCTR=0
+THEN \
+\ ------------------------------ \
+\ Start \
+\ ------------------------------ \
+MOV.B #-1,T \ T=-1
+BIC #1,&UCB0CTLW0 \ UCB0CTLW0 : clear SWRST, start I2C MASTER
+BIT.B #1,&I2CMS_ADR \ R/W test
+0= IF \
+\ ---------------------------- \
+\ MASTER TX \
+\ ---------------------------- \
+ BEGIN \
+ MOV.B &UCBCNT0,T \ store count of byte
+ BIT #$10,&UCB0IFG \ test UCALIFG : arbitration lost interrupt
+ 0<> ?GOTO FW1 \ eUSCI is already in Slave mode
+ BIT #8,&UCB0IFG \ test UCSTPIFG
+ 0<> ?GOTO FW2 \
+ BIT #$20,&UCB0IFG \ test UCNACKIFG
+ 0<> IF \
+ BIS #4,&UCB0CTLW0 \ generate stop bit
+ THEN \
+ BIT #2,&UCB0IFG \ test UCTXIFG0
+ 0<> IF \
+ MOV.B @S+,&UCB0TXBUF \ load data into UCB0TXBUF
+ THEN \
+ AGAIN \
+THEN \
+\ ------------------------------ \
+\ MASTER RX \
+\ ------------------------------ \
+BEGIN \ of Master RX
+ MOV.B &UCBCNT0,T \ store count of byte
+ BIT #8,&UCB0IFG \ test UCSTPIFG
+ 0<> IF \
+ MOV @RSP+,PC \ end of I2C_MM RX driver
+ THEN \
+ BIT #1,&UCB0IFG \ test UCRXIFG0
+ 0<> IF \
+ MOV.B &UCB0RXBUF,0(S) \ load data from UCB0RXBUF
+ ADD #1,S \
+ THEN \
+AGAIN \
+\ ------------------------------ \
+\ Swap Master to Slave mode \
+\ ------------------------------ \
+FW2 MOV #1,&UCB0CTLW0 \ set eUSCI_B in reset state, clear UCB0IE & UCB0IFG all flags
+ BIS #$07A0,&UCB0CTLW0 \
+\ BIS #$10,&UCB0CTLW1 \ set software ack address (UCSWACK=1)
+\ MOV #0,&UCB0ADDMSK \ enable address mask for all addresses i.e. software address
+ BIC #1,&UCB0CTLW0 \ activate eUSCI_B
+ MOV #4,&UCB0IE \ enable StartCond interrupt
+FW1 MOV @RSP+,PC \
+\ ------------------------------ \
+ENDASM \ 62 words + 9 init words
+ \
+
+\ ------------------------------\
+CODE START \ init
+\ ------------------------------\
+\ init I2C_MMaster \
+\ ------------------------------\
+\ %0000 1111 1101 0011 $640 = $0FD3
+\ - UCMM = 1 : multi master mode
+\ - UCMST = 1 : I2C_MMaster
+\ -- UCMODE = %11 = I2C
+\ _ USYNC=1 (always 1)
+\ -- UCSSEL=SMCLK=8MHz
+\ - UCTXACK=0 not auto ACK slave address
+\ - UCTR=1/0 : TX/RX modes
+\ - UCTXSTP
+\ - UCTXSTT send start
+\ - UCSWRST=1
+\ ------------------------------\
+\ %0000 0000 1100 1000 $642 = $00C8
+\ - UCETXINT=0 : UCTXIFG0 set address match UCxI2COAx and TX mode
+\ -- UCCLTO=%11 : SCL low time out = 34 ms
+\ - UCSWACK=1 : UCTXACK must be written to continue
+\ -- UCASTP0=%10 : automatic Stop when UCBxTBCNT is reached
+\ ------------------------------\
+\ PORTX (PORTx:y) default values\ DIR0,REN1,OUT1 (input with pullup resistors)
+\ ------------------------------\
+\ notice : UCB0 I2C driver seems to control only DIR register !!!
+BIC.B #MM_BUS,&I2CMM_REN \ REN0 : no_resistor
+BIC.B #MM_BUS,&I2CMM_OUT \ OUT0 : preset output low
+BIS.B #MM_BUS,&I2CMM_SEL1 \ SEL11 : enable I2C I/O
+COLON
+." ; type stop to stop :-)"
+LIT recurse is WARM \ insert this starting routine between COLD and WARM...
+(WARM) \ ...and continue with (WARM)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
--- /dev/null
+\ name : MSP430FR5xxx_I2C_Slave.f
+RST_STATE
+\ NOECHO
+
+\ Copyright (C) <2015> <J.M. THOORENS>
+\
+\ This program is free software: you can redistribute it and/or modify
+\ it under the terms of the GNU General Public License as published by
+\ the Free Software Foundation, either version 3 of the License, or
+\ (at your option) any later version.
+\
+\ This program is distributed in the hope that it will be useful,
+\ but WITHOUT ANY WARRANTY\ without even the implied warranty of
+\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+\ GNU General Public License for more details.
+\
+\ You should have received a copy of the GNU General Public License
+\ along with this program. If not, see <http://www.gnu.org/licenses/>.
+\
+\ driver I2C SLAVE with START interrupt only, for any I2C_Slave addresses
+\ Target: MSP430FR5xxx @ 8,16,24 MHz
+\ version 1.0 2015-03-17
+
+\ ---------------------------------------------------------------------------------------------------------------------;
+\ SCL clock generation, timing, and test of data(s) number are made by I2C_Master.
+\ slave can strech SCL low after Start Condition and after any bit.
+\
+\ address Ack/Nack is generated by the slave on SDA line (released by the master)
+\ Two groups of eight addresses (000$xxy and 1111xxxy) are not allowed (reserved)
+\ after address or data is sent, the transmitter (Master or Slave) must release SDA line to allow (N)Ack by the receiver
+\ data Ack/Nack are generated by the receiver (master or slave) on SDA line
+\ a master receiver must signal the end of data to the slave transmitter by sending a Nack bit
+\ Stop or restart conditions must be generated by master after a Nack bit.
+\ after Ack bit is sent, Slave must release SDA line to allow master to do stop or restart conditions
+\
+\ __ _____ _____ _..._ _____ _____ _NACK _____ _____ _..._ _____ _____ _NACK _
+\ SDA \____/_MSB_X_____X_..._X_LSB_X_R/W_x_ACK_x_MSB_X_____X_..._X_____X_LSB_X_ACK_X___/
+\ _____ _ _ _ _ _ _ _ _ _ _ ___
+\ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/
+\ ^ ^ ^ ^ ^ ^ ^
+\ | |Slave Stretch Low |SSL |SSL |SSL |SSL |
+\ | |
+\ |Start Condition |stoP Condition
+\
+\ __ _____ _____ _..._ _____ _____ _NACK _____ _____ _..._ _____ _____ _NACK ___
+\ SDA \____/_MSB_X_____X_..._X_LSB_X_R/W_x_ACK_x_MSB_X_____X_..._X_____X_LSB_X_ACK_X \____...
+\ _____ _ _ _ _ _ _ _ _ _ _ ____
+\ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/ \_...
+\ ^ ^ ^ ^ ^ ^ ^
+\ | |Slave Stretch Low |SSL |SSL |SSL |SSL |
+\ | |
+\ |Start Condition |reStart Condition
+\
+\ tHIGH : SCL high time
+\ tLOW : SCL low time
+\ tBUF : SDA high time between Stop and Start conditions
+\ tHD:STA : Start_Condition SCL high time after SDA is low
+\ tSU:STO : Stop_Condition SCL high time before SDA rise
+\ tSU:STA : Start_Condition SCL high time before SDA fall
+\ tHD:DAT : SDA data change time after SCL is low
+\ the SDA line must be strobe just after SCL is high
+\ the SDA data must be change just after SCL is low
+\ standard mode (up to 100 kHz) : tHIGH = tHD:STA = tSU:STO = 4µs
+\ tLOW = tSU:STA = tBUF = 4,7µs
+\ tHD:DAT <= 3,45 µs
+\
+\ fast mode (up to 400 kHz) : tHIGH = tHD:STA = tSU:STO = 0,6µs
+\ tLOW = tSU:STA = tBUF = 1,3µs
+\ tHD:DAT <= 0,9 µs
+\ -------------------------------------------------------------------------------------------------------------------;
+
+
+
+VARIABLE I2CS_OWN \ slave I2C address without RW flag (low byte) + DATA0 input (HIGH byte)
+\ 2 ALLOT \ next the low byte of I2CS_OWN word, it is the input buffer
+VARIABLE I2CS_BUF \ buffer output, lentgh (low byte),DATA0 output (HIGH byte)
+\ 2 ALLOT \ this byte lentgh is shared by input and output buffers
+
+\ ******************************\
+ASM I2CS_TX \ TX part of I2C_Slave
+\ ******************************\
+\ \ T = TX buffer_org
+\ \ use W = TX buffer_ptr
+\ \ out : low(I2CS_BUF) = RX or TX lentgh
+\ ------------------------------\
+MOV T,W \ W = TX_buf_ptr -1
+BEGIN \
+ ADD #1,W \ first reserve one byte for length then inc
+ MOV.B @W,&UCB0TXBUF \ +[W] --> UCB0TXBUF
+\ ----------------------------\
+\ slave send byte \
+\ ----------------------------\
+ BEGIN \
+ BIT #$0C,&UCB0IFG \ UCB0IFG(STP,STT) = 1 ?
+ 0<> IF \
+\ --------------------\
+\ stop or restart received
+\ --------------------\
+ SUB T,W \
+ SUB.B #1,W \ sub #1, because char +[W] is not sent
+ MOV.B W,0(T) \ store length in first byte of buffer output
+ BIC #UCTR,&UCB0CTLW0 \ reset UCTR R/W bit for next START
+ MOV @RSP+,PC \ ===> ret
+\ --------------------\
+ THEN \
+ BIT #2,&UCB0IFG \ UCB0IFG(TX0) = 1 ?
+ 0<> UNTIL \
+AGAIN \
+ENDASM \
+ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+\ **************************************\
+ASM I2C_S \ <== eUSCIB0 interrupt vector : i2c_addres&R/w sent by master is received
+\ **************************************\
+BIC #$F8,0(RSP) \ SCG1,SCG0,OSCOFF,CPUOFF and GIE are OFF in retiSR to force LPM0_LOOP with pending interrupt
+MOV #$98,&LPM_MODE \ to reenter in LPM2 mode. LPM3-4 don't work with MSP430FR57xx.
+\ --------------------------------------\
+MOV #I2CS_BUF,T \ T = buffer output address -1
+MOV #I2CS_OWN,S \ S = buffer input address -1
+MOV #0,&UCB0IFG \ write UCB0IFG to clear all int flags (STTIFG,TXIFG,..)
+CMP.B &UCB0I2COA0,&UCB0ADDRX \ UCB0ADDRX = own address ?
+0= IF \
+\ --------------------------------------\
+\ It's my own address \
+\ --------------------------------------\
+ BIS #UCTXACK,&UCB0CTLW0 \ send software Ack address
+ BIT #UCTR,&UCB0CTLW0 \ test UCB0CTLW0(UCTR) R/W bit
+ 0= IF \ I2C_Master Write
+\ --------------------------------\
+\ slave receive datas \ yes
+\ --------------------------------\
+ MOV S,W \ W = input buffer address - 1
+ BEGIN \
+\ ----------------------------\
+\ slave receive one byte \
+\ ----------------------------\
+ BEGIN \
+ BIT #$8C,&UCB0IFG \ UCB0IFG(STP,STT,CLTO) = 1 ? (STOP, START, SCL low timeout)
+ 0<> IF \
+\ --------------------\
+\ TX stop or restart \ from master
+\ --------------------\
+ SUB S,W \ W = Adr_end - Adr_start = length
+ MOV.B W,0(T) \ store length in first byte of buffer output
+\ --------------------\
+\ insert here post RX code
+\ --------------------\
+ RETI \
+ THEN \ if not (stop, restart, CLTO)
+ BIT #1,&UCB0IFG \ UCB0IFG(RX0) = 1 ?
+ 0<> UNTIL \
+ ADD #1,W \ reserve one byte for length first, then preincrement
+ MOV.B &UCB0RXBUF,0(W) \ [UCB0RXBUF] = data --> +[W]
+ AGAIN \ loop for new received data if any
+ THEN \ end of I2C_Master read
+\ ------------------------------------\
+\ slave transmit datas variant 1 \ to loop back after bad_own_address code
+\ ------------------------------------\
+ CALL #I2CS_TX \
+ RETI \
+\ ------------------------------------\
+\ slave transmit datas variant 2 \
+\ ------------------------------------\
+\ MOV T,W \ W = output buffer address -1
+\ BEGIN \
+\ ADD #1,W \ first reserve one byte for length
+\ MOV.B @W,&UCB0TXBUF \ +[W] --> UCB0TXBUF
+\ \ ----------------------------\
+\ \ slave send byte \
+\ \ ----------------------------\
+\ BEGIN \
+\ BIT.B #$0C,&UCB0IFG \ UCB0IFG(STP,STT) = 1 ?
+\ 0<> IF \
+\ \ ------------------------\
+\ \ RX stop or restart \ from master
+\ \ ------------------------\
+\ SUB T,W \ W = Adr_end - Adr_start = length
+\ SUB.B #1,W \ sub #1, because char +[W] is not sent
+\ MOV.B W,0(T) \ store length in first byte of buffer output
+\ BIC.B #UCTR,&UCB0CTLW0 \ reset UCTR R/W bit for next START
+\ RETI \
+\ THEN \
+\ BIT.B #$02,&UCB0IFG \ UCB0IFG(TX0) = 1 ?
+\ 0<> UNTIL \
+\ AGAIN \
+\ ------------------------------------\
+\ End of slave transmit datas variants\
+\ ------------------------------------\
+THEN \ if bad I2C address
+\ --------------------------------------\
+\ BAD I2C ADDRESS CaseOf \
+\ --------------------------------------\
+\ insert here post BAD I2C address code \
+\ ...that can loop back to I2CS_TX... \
+\ --------------------------------------\
+BIC #UCTXACK,&UCB0CTLW0 \ send Nack address
+RETI \
+ENDASM
+ \
+
+\ --------------------------------------\
+CODE START \ init I2C_slave
+\ --------------------------------------\
+\ UCB0CTLW0 = %0000 0111 1100 0001 $640
+\ - UCMST = 0 : I2C_Slave
+\ -- UCMODE = %11 = I2C
+\ _ USYNC=1 (always 1)
+\ -- UCSSEL=SMCLK (don't care in slave mode)
+\ - UCTXACK=0 not auto ACK slave address
+\ - UCTR=0 : RX (for RX address)
+\ - UCSWRST=1
+\ UCB0CTLW1 = %0000 0000 1101 0000 $642
+\ - UCETXINT=0 : UCTXIFG0 set address match UCxI2COAx and TX mode
+\ -- UCCLTO=%11 : SCL low time out = 34 ms
+\ - UCSWACK=1 : UCTXACK must be written to continue
+\ UCB0RXBUF $64C
+\ UCB0TXBUF $64E
+\ UCB0I2COA0 $654 must be written ? enabled ?
+\ UCB0ADDRX $65C
+\ UCB0ADDMSK $65E
+\ UCB0IE = %0000 0000 0000 0100 $66A
+\ - UCSTTIE : StartCond Interrupt only
+\ UCB0IFG $66C
+\ UCB0IV $66E : write it to clear all IFG
+
+\ ------------------------------\
+\ init I2C_slave \
+MOV #1,&UCB0CTLW0 \ set eUSCI_B in reset state, clear UCB0IE & UCB0IFG all flags
+BIS #$07A0,&UCB0CTLW0 \
+BIS #$10,&UCB0CTLW1 \ set software ack address (UCSWACK=1)
+MOV #%1010,&UCB0I2COA0 \ set my own address
+BIS #$0400,&UCB0I2COA0 \ UCOAEN=1 enable UCB0I2COA0 with address slave
+\ MOV #0,&UCB0ADDMSK \ enable address mask for all addresses i.e. software address
+BIC #1,&UCB0CTLW0 \ activate eUSCI_B
+MOV #4,&UCB0IE \ enable StartCond interrupt
+\ ------------------------------\
+\ init interrupt vectors
+MOV #I2C_S,&$FFEE \ eUSCIB0 interrupt vector
+\ ------------------------------\
+\ init PORTA (P2:P1) (complement)
+\ notice : UCB0 I2C driver seems to control only DIR register !!!
+BIC.B #S_BUS,&I2CS_REN \ SDA + SCL pullup/down disable
+BIC.B #S_BUS,&I2CS_OUT \ OUT0 : preset output low
+BIS.B #S_BUS,&I2CS_SEL1 \ enable I2C I/O
+\ ------------------------------\
+COLON
+." I2C_Slave is running. Type STOP to quit"
+LIT recurse is WARM \ insert this routine between COLD and WARM...
+(WARM) ; \ ...and continue with WARM
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+ECHO
+PWR_HERE
+\ START
--- /dev/null
+\ name : I2C_Slave_to_LCD_2x20.f
+
+\ Copyright (C) <2015> <J.M. THOORENS>
+\
+\ This program is free software: you can redistribute it and/or modify
+\ it under the terms of the GNU General Public License as published by
+\ the Free Software Foundation, either version 3 of the License, or
+\ (at your option) any later version.
+\
+\ This program is distributed in the hope that it will be useful,
+\ but WITHOUT ANY WARRANTY\ without even the implied warranty of
+\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+\ GNU General Public License for more details.
+\
+\ You should have received a copy of the GNU General Public License
+\ along with this program. If not, see <http://www.gnu.org/licenses/>.
+\
+
+\ --------------------------------------\
+\ example of App running under interrupt
+\ --------------------------------------\
+
+\ for MSP_EXP430FR5739, MSP_EXP430FR5969, MSP_EXP430FR6989, ... launchpads @ 8MHz
+\
+\ prerequisites : your launchpad is wired as described in launchpad.pat file : UART0, SDA, SCL, LCD parts
+\ and FastForth runs @ 8MHz
+\ usage : create a logical network drive ( a: b: as you want) from your local copy of Gitlab FAST FORTH
+\ with scite.exe open this file MSP430-FORTH\I2C_Slave_to_LCD_2x20.f,
+\ select "tools" menu, "preprocess" item 2 (CTRL+1),
+\ a dialog box asks you for 4 parameters $(1) to $(4),
+\ in the 2th param. field, type your launchpad to select the launchpad.pat to be used : for example MSP_EXP430FR5969,
+\ in the 3th param. field, type the COMx port of your USBtoUART device.
+\ result : a file.4th in which all symbolic addresses are resolved according to the rules described in the selected launchpad.pat
+\ the word START starts the app that runs under LPMx.
+\ to recover the console input (i.e. to quit LPMx), type a space. Then you can enter a command, for example STOP.
+
+WIPE
+ \
+
+: U.R \ u n -- display u unsigned in n width
+ >R <# 0 # #S #>
+ R> OVER - 0 MAX SPACES TYPE
+;
+ \
+
+CODE ? \ adr -- display the content of adr
+ MOV @TOS,TOS
+ MOV #U.,PC
+ENDCODE
+ \
+
+
+\ ------------------------------\
+CODE 20_us \ n -- n * 20 us
+\ ------------------------------\
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+\ ------------------------------\
+CODE TOP_LCD \ LCD Sample
+\ ------------------------------\ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+\ ------------------------------\
+CODE LCD_W \ byte -- write byte
+\ ------------------------------\
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+ COLON
+ TOP_LCD 2 20_us \ write high nibble first
+ TOP_LCD 2 20_us ;
+ \
+\ ------------------------------\
+CODE LCD_R \ -- byte read byte
+\ ------------------------------\
+ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+ COLON
+ TOP_LCD 2 20_us \ read high nibble first
+ TOP_LCD 2 20_us
+ HI2LO \ -- %0000HHHH %0000LLLL
+ MOV @RSP+,IP
+ MOV @PSP+,W \ W = high nibble
+ RLAM #4,W \ -- %0000LLLL W = %HHHH0000
+ ADD.B W,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+\ ------------------------------\
+CODE LCD_WrF \ func -- Write Fonction
+\ ------------------------------\
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+\ ------------------------------\
+CODE LCD_RdS \ -- status Read Status
+\ ------------------------------\
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_R
+ENDCODE
+ \
+\ ------------------------------\
+CODE LCD_WrC \ char -- Write Char
+\ ------------------------------\
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+\ ------------------------------\
+CODE LCD_RdC \ -- char Read Char
+\ ------------------------------\
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_R
+ENDCODE
+ \
+\ ------------------------------\
+\ : LCD_Clear $01 LCD_WrF 80 20_us \ bad init !
+: LCD_Clear $01 LCD_WrF 100 20_us ;
+ \
+\ ------------------------------\
+: LCD_Home $02 LCD_WrF 80 20_us ;
+ \
+\ ------------------------------\
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+\ ******************************\
+ASM WDT_Int \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR
+\ ------------------------------\
+\ define LPM mode for ACCEPT \ LPM0 is the default mode.
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0
+\ ------------------------------\
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #34,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+
+VARIABLE I2CS_OWN \ slave I2C address without RW flag (low byte) + DATA0 input (HIGH byte)
+\ 2 ALLOT \ next the low byte of I2CS_OWN word, it is the input buffer
+VARIABLE I2CS_BUF \ buffer output, lentgh (low byte),DATA0 output (HIGH byte)
+\ 2 ALLOT \ this byte lentgh is shared by input and output buffers
+
+\ ******************************\
+ASM I2CS_TX \ TX part of I2C_Slave
+\ ******************************\
+\ \ T = TX buffer_org
+\ \ use W = TX buffer_ptr
+\ \ out : low(I2CS_BUF) = RX or TX lentgh
+\ ------------------------------\
+MOV T,W \ W = TX_buf_ptr -1
+BEGIN \
+ ADD #1,W \ first reserve one byte for length then inc
+ MOV.B @W,&UCB0TXBUF \ +[W] --> UCB0TXBUF
+\ ----------------------------\
+\ slave send byte \
+\ ----------------------------\
+ BEGIN \
+ BIT #$0C,&UCB0IFG \ UCB0IFG(STP,STT) = 1 ?
+ 0<> IF \
+\ --------------------\
+\ stop or restart received
+\ --------------------\
+ SUB T,W \
+ SUB.B #1,W \ sub #1, because char +[W] is not sent
+ MOV.B W,0(T) \ store length in first byte of buffer output
+ BIC #UCTR,&UCB0CTLW0 \ reset UCTR R/W bit for next START
+ MOV @RSP+,PC \ ===> ret
+\ --------------------\
+ THEN \
+ BIT #2,&UCB0IFG \ UCB0IFG(TX0) = 1 ?
+ 0<> UNTIL \
+AGAIN \
+ENDASM \
+ \
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+\ **************************************\
+ASM I2C_S \ <== eUSCIB0 interrupt vector : i2c_addres&R/w sent by master is received
+\ **************************************\
+BIC #$F8,0(RSP) \ SCG1,SCG0,OSCOFF,CPUOFF and GIE are OFF in retiSR to force LPM0_LOOP with pending interrupt
+\ --------------------------------------\
+\ define LPM mode for ACCEPT \ LPM0 is the default mode.
+\ --------------------------------------\
+\ MOV #LPM4,&LPM_MODE \ MSP430FR59xx family : LPM 0 to 4
+\ MOV #LPM2,&LPM_MODE \ MSP430FR57xx family : terminal input don't work for LPMx > 2
+\ \ MSP430FR2xxx family : terminal input don't work for LPMx > 0
+\ --------------------------------------\
+MOV #I2CS_BUF,T \ T = buffer output address -1
+MOV #I2CS_OWN,S \ S = buffer input address -1
+MOV #0,&UCB0IFG \ write UCB0IFG to clear all int flags (STTIFG,TXIFG,..)
+CMP.B &UCB0I2COA0,&UCB0ADDRX \ UCB0ADDRX = own address ?
+0= IF \
+ BIS #UCTXACK,&UCB0CTLW0 \ send software Ack address
+ BIT #UCTR,&UCB0CTLW0 \ test UCB0CTLW0(UCTR) R/W bit
+ 0= IF \ I2C_Master Write
+\ --------------------------------\
+\ slave receive datas \ yes
+\ --------------------------------\
+ MOV S,W \ W = input buffer address - 1
+ BEGIN \
+\ ----------------------------\
+\ slave receive one byte \
+\ ----------------------------\
+ BEGIN \
+ BIT #$8C,&UCB0IFG \ UCB0IFG(STP,STT,CLTO) = 1 ? (STOP, START, SCL low timeout)
+ 0<> IF \
+\ --------------------\
+\ TX stop or restart \ from master
+\ --------------------\
+ SUB S,W \ W = Adr_end - Adr_start = length
+ MOV.B W,0(T) \ store length in first byte of buffer output
+\ --------------------\
+\ insert here post RX code
+\ --------------------\
+\ BIS.B #LED1,&LED1_OUT \ OUT high ==> switch ON LED1 to test
+\ display IR_RC5 command
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \
+ MOV.B 1(X),TOS \ display RC6 command
+\ MOV.B 0(W),TOS \ display count
+ LO2HI \ IP is free
+ ['] LCD_Clear IS CR
+ ['] LCD_WrC IS EMIT
+ BASE @ HEX \ save BASE before change
+ CR ." $" 2 U.R SPACE \ display received byte
+ ." LPM = $" LPM_MODE ? \ display also LPM value
+ ['] (CR) IS CR
+ ['] (EMIT) IS EMIT
+ BASE ! \ restore BASE
+ HI2LO \ nice code, right ?
+\ ; endof display
+\ BIC.B #LED1,&LED1_OUT \ OUT low ==> switch OFF LED1 to test
+\ --------------------\
+ RETI \
+\ --------------------\
+ THEN \ if not (stop, restart, CLTO)
+ BIT #1,&UCB0IFG \ UCB0IFG(RX0) = 1 ?
+ 0<> UNTIL \
+ ADD #1,W \ reserve one byte for length first, then preincrement
+ MOV.B &UCB0RXBUF,0(W) \ [UCB0RXBUF] = data --> +[W]
+ AGAIN \ loop for new received data if any
+ THEN \ end of I2C_Master read
+\ ------------------------------------\
+\ slave transmit datas variant 1 \ to loop back after bad_own_address code
+\ ------------------------------------\
+ CALL #I2CS_TX \
+ RETI \
+\ ------------------------------------\
+\ slave transmit datas variant 2 \
+\ ------------------------------------\
+\ MOV T,W \ W = output buffer address -1
+\ BEGIN \
+\ ADD #1,W \ first reserve one byte for length
+\ MOV.B @W,&UCB0TXBUF \ +[W] --> UCB0TXBUF
+\ \ ----------------------------\
+\ \ slave send byte \
+\ \ ----------------------------\
+\ BEGIN \
+\ BIT.B #$0C,&UCB0IFG \ UCB0IFG(STP,STT) = 1 ?
+\ 0<> IF \
+\ \ ------------------------\
+\ \ RX stop or restart \ from master
+\ \ ------------------------\
+\ SUB T,W \ W = Adr_end - Adr_start = length
+\ SUB.B #1,W \ sub #1, because char +[W] is not sent
+\ MOV.B W,0(T) \ store length in first byte of buffer output
+\ BIC.B #UCTR,&UCB0CTLW0 \ reset UCTR R/W bit for next START
+\ RETI \
+\ THEN \
+\ BIT.B #$02,&UCB0IFG \ UCB0IFG(TX0) = 1 ?
+\ 0<> UNTIL \
+\ AGAIN \
+\ ------------------------------------\
+\ End of slave transmit datas variants\
+\ ------------------------------------\
+THEN \ if bad I2C address
+\ --------------------------------------\
+\ BAD I2C ADDRESS CaseOf \
+\ --------------------------------------\
+\ insert here post BAD I2C address code \
+\ ...that can loop back to I2CS_TX... \
+\ --------------------------------------\
+BIC #UCTXACK,&UCB0CTLW0 \ send Nack address
+RETI \
+ENDASM
+ \
+
+
+
+
+\ START performs a complementary initialisation of the FAST FORTH system to start your app.
+\ START is inserted COLD and ABORT via the fragment of code : LIT RECURSE IS WARM.
+\ --------------------------------------\
+CODE START \ init I2C_slave
+\ --------------------------------------\
+\ %0000 0111 1100 0001 UCB0CTLW0
+\ - UCMST = 0 : I2C_Slave
+\ -- UCMODE = %11 = I2C
+\ _ USYNC =1 (always 1)
+\ -- UCSSEL =SMCLK (don't care in slave mode)
+\ - UCTXACK =0 not auto ACK slave address
+\ - UCTR =0 : RX (for RX address)
+\ - UCSWRST =1
+\ --------------------------------------\
+\ %0000 0000 1101 0000 UCB0CTLW1
+\ - UCETXINT =0 : UCTXIFG0 set address match UCxI2COAx and TX mode
+\ -- UCCLTO =%11 : SCL low time out = 34 ms
+\ - UCSWACK =1 : UCTXACK must be written to continue
+\ --------------------------------------\
+\ UCB0RXBUF
+\ UCB0TXBUF
+\ UCB0I2COA0 must be written ? enabled ?
+\ UCB0ADDRX
+\ UCB0ADDMSK
+\ --------------------------------------\
+\ %0000 0000 0000 0100 UCB0IE
+\ - UCSTTIE : StartCond Interrupt only
+\ --------------------------------------\
+\ UCB0IFG
+\ UCB0IV : write it to clear all IFG
+
+\ ------------------------------\
+\ init I2C_slave \
+\ ------------------------------\
+MOV #1,&UCB0CTLW0 \ set eUSCI_B in reset state, clear UCB0IE & UCB0IFG all flags
+BIS #$07A0,&UCB0CTLW0 \
+BIS #$10,&UCB0CTLW1 \ set software ack address (UCSWACK=1)
+MOV #%1010,&UCB0I2COA0 \ set my own address
+BIS #$0400,&UCB0I2COA0 \ UCOAEN=1 enable UCB0I2COA0 with address slave
+\ MOV #0,&UCB0ADDMSK \ enable address mask for all addresses i.e. software address
+BIC #1,&UCB0CTLW0 \ activate eUSCI_B
+MOV #4,&UCB0IE \ enable StartCond interrupt
+MOV #%1010,&I2CS_OWN \ my slave address, without RW flag !
+\ ------------------------------\
+\ init PORT complement
+\ ------------------------------\
+\ notice : UCB0 I2C driver seems to control only DIR register !!!
+BIC.B #S_BUS,&I2CS_REN \ SDA + SCL pullup/down disable
+BIC.B #S_BUS,&I2CS_OUT \ OUT0 : preset output low
+BIS.B #S_BUS,&I2CS_SEL1 \ enable I2C I/O
+\ ------------------------------\
+BIS.B #LCDVo,&LCDVo_DIR \
+BIS.B #LCDVo,&LCDVo_SEL0 \ TB0.2
+\ ------------------------------\
+BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+BIS.B #LCD_DB,&LCD_DB_DIR \ lcd_db as output, wired to DB(4-7) LCD_Data
+BIC.B #LCD_DB,&LCD_DB_REN \ lcd_db pullup/down disable
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up mode
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate LCD_V0 via TB0.2 and P1.5/P2.2
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+\ MOV #$5A5E,&WDTCTL \ init WDT Vloclk source 10kHz /2^9 (50 ms), interval mode
+ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #I2C_S,&I2CS_Vec \ eUSCIB0 interrupt vector
+ MOV #WDT_Int,&WDT_Vec \ init WDT interval vector interrupt
+\ ------------------------------\
+\ define LPM mode for ACCEPT \ LPM0 is the default mode.
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0
+\ ------------------------------\
+\ Init LCD
+ COLON
+ $03E8 20_us \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_us \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ 5 20_us \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ 2 20_us \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ 2 20_us \ wait 40 us = LCD cycle
+ $28 LCD_WrF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WrF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WrF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WrF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+
+ ['] LCD_HOME IS CR \ CR redirected to LCD_HOME
+ ['] LCD_WrC IS EMIT \ EMIT redirected to LCD_WrC
+ CR ." I love you" \ display it on the LCD
+ ['] (EMIT) IS EMIT \ restore EMIT
+ ['] (CR) IS CR \ restore CR
+ ." I2C_Slave_to_LCD is running. Type STOP to quit" \ display on terminal
+\ NOECHO \ uncomment to run this app without terminal connexion
+ lit RECURSE IS WARM \ insert this starting routine between COLD and WARM...
+ (WARM) ; \ ...and continue with (WARM)
+ \
+
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+RST_HERE
+
+
+\ START runs your App.
+\ when downloading this file, all lines beyond the START command are ignored. Usefull to comment.
+
+\ driver for LCD 2x20 characters display with 4 bits data interface
+\ without usage of an auxiliary 5V to feed the Vo of LCD
+\ without potentiometer to adjust the LCD contrast
+\ LCD contrast software adjustable by 2 switches
+\ TB0.2 current consumption ~ 500 uA
+
+\ layout : see config.pat file for defining I/O
+
+\ GND <-------+---0V0----------> 1 LCD_Vss
+\ VCC >------ | --3V6-----+----> 2 LCD_Vdd
+\ | |
+\ |___ 470n ---
+\ ^ | ---
+\ / \ BAT54 |
+\ --- |
+\ 100n | 2k2 |
+\ TB0.2 >---||--+--^/\/\/v--+----> 3 LCD_Vo (=0V6 without modulation)
+\ -------------------------> 4 LCD_RW
+\ -------------------------> 5 LCD_RW
+\ -------------------------> 6 LCD_EN
+\ <------------------------> 11 LCD_DB4
+\ <------------------------> 12 LCD_DB5
+\ <------------------------> 13 LCD_DB5
+\ <------------------------> 14 LCD_DB7
+
+\ Sw1 <--- LCD contrast + (finger :-)
+\ Sw2 <--- LCD contrast - (finger \-)
+
--- /dev/null
+\ name : msp430FR5xxx_I2C_Soft_Master.asm
+
+WIPE
+
+\ Copyright (C) <2015> <J.M. THOORENS>
+\
+\ This program is free software: you can redistribute it and/or modify
+\ it under the terms of the GNU General Public License as published by
+\ the Free Software Foundation, either version 3 of the License, or
+\ (at your option) any later version.
+\
+\ This program is distributed in the hope that it will be useful,
+\ but WITHOUT ANY WARRANTY\ without even the implied warranty of
+\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+\ GNU General Public License for more details.
+\
+\ You should have received a copy of the GNU General Public License
+\ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+\ version 2.0 2015-07-30
+\ ---------------------------------------------------------------------------------------------------------------------\
+\ SCL clock generation, timing, and test of data(s) number are made by I2C_Master.
+\ slave can strech SCL low after Start Condition and after any bit.
+\
+\ address Ack/Nack is generated by the slave on SDA line (released by the master)
+\ Two groups of eight addresses (000xxxy and 1111xxxy) are not allowed (reserved)
+\ after address or data is sent, the transmitter (Master or Slave) must release SDA line to allow (N)Ack by the receiver
+\ data Ack/Nack are generated by the receiver (master or slave) on SDA line
+\ a master receiver must signal the end of data to the slave transmitter by sending a Nack bit
+\ Stop or restart conditions must be generated by master after a Nack bit.
+\ after Ack bit is sent, Slave must release SDA line to allow master to do stop or restart conditions.
+\
+\
+\ first byte = address + R/W flag | byte data (one, for example)
+\ __ _____ _____ _..._ _____ __R__ _NAK_ _____ _____ _..._ _____ _____ _NAK_ _
+\ SDA \____/_MSB_X_____X_..._X_LSB_X__W__x_ACK_x_MSB_X_____X_..._X_____X_LSB_X_ACK_X___/
+\ _____ _ _ _ _ _ _ _ _ _ _ ___
+\ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/
+\ ^ ^ ^ ^ ^ ^ ^
+\ | |SSL |SSL |SSL |SSL |SSL |
+\ | |
+\ |Start Condition |stoP Condition
+\
+\ first byte = address + R/W flag | byte data (one, for example)
+\ __ _____ _____ _..._ _____ __R__ _NAK_ _____ _____ _..._ _____ _____ _NAK_ ___
+\ SDA \____/_MSB_X_____X_..._X_LSB_X__W__x_ACK_x_MSB_X_____X_..._X_____X_LSB_X_ACK_X \____...
+\ _____ _ _ _ _ _ _ _ _ _ _ ____
+\ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/ \_...
+\ ^ ^ ^ ^ ^ ^ ^
+\ | |SSL |SSL |SSL |SSL |SSL |
+\ | |
+\ |Start Condition |reStart Condition
+\
+\ SSL : Slave can strech SCL low
+\ tHIGH : SCL high time
+\ tLOW : SCL low time
+\ tBUF : SDA high time between Stop and Start conditions
+\ tHD:STA : Start_Condition SCL high time after SDA is low
+\ tSU:STO : Stop_Condition SCL high time before SDA rise
+\ tSU:STA : Start_Condition SCL high time before SDA fall
+\ tHD:DAT : SDA data change time after SCL is low
+\ the SDA line must be strobe just after SCL is high
+\ the SDA data must be change just after SCL is low
+\ standard mode (up to 100 kHz) : tHIGH = tHD:STA = tSU:STO = 4µs
+\ tLOW = tSU:STA = tBUF = 4,7µs
+\ tHD:DAT <= 3,45 µs
+\ -------------------------------------------------------------------------------------------------------------------\
+\
+\
+\ -------------------------------------------------------------------------------------------------------------------\
+\ I2C Soft MASTER, Standard MODE, 8,16,24MHz
+\ -------------------------------------------------------------------------------------------------------------------\
+
+\ ===============================================================================================
+\ ===============================================================================================
+
+\ ### ##### ##### ##### # #
+\ # # # # # # # #### ###### ##### ## ## ## #### ##### ###### #####
+\ # # # # # # # # # # # # # # # # # # #
+\ # ##### # ##### # # ##### # # # # # # #### # ##### # #
+\ # # # # # # # # # # ###### # # # #####
+\ # # # # # # # # # # # # # # # # # # # #
+\ ### ####### ##### ##### #### # # # # # # #### # ###### # #
+
+\ ===============================================================================================
+\ ===============================================================================================
+
+\ use Px.0 to Px.3 pins as SCL and SDA pins to use immediate instruction in one byte (#1,#2,#4,#8)
+
+\ tested with P1.6 SDA, P1.7 SCL @8 MHZ :
+\ Start + Adr + Write 3 bytes + Stop + Start + adr + read 2 bytes + stop = 600us ==> 105 kHz
+\ See MSP430FR5xxx_I2C_Soft_Master.png
+
+VARIABLE I2CS_ADR \ low(I2CS_ADR) = slave I2C address with RW flag, high(I2CS_ADR) = RX buffer,data0
+2 ALLOT \ data1,data2
+VARIABLE I2CM_BUF \ low(I2CM_BUF) = RX or TX lentgh, high(I2CM_BUF) = TX buffer,data0
+2 ALLOT \ data1,data2
+ \
+
+\ ------------------------------\
+ASM T_I2C \ 4 init first once !!!
+\ ------------------------------\
+BEGIN \ 3~ loop
+ SUB #1,Y \ 1
+0= UNTIL \ 2
+ MOV #1,Y \ 2 set I2C tHIGH time @ 8MHz
+\ MOV #9,Y \ 2 set I2C tHIGH time @ 16MHz
+\ MOV #20,Y \ 2 set I2C tHIGH time @ 24MHz
+ MOV @RSP+,PC \ 4 ret
+ENDASM \
+ \
+
+\ ------------------------------\ _
+ASM I2C_PLS \ SCL _| |_ pulse
+\ ------------------------------\
+CALL #T_I2C \ _ wait tLOW
+BIC.B #SMSCL,&I2CSM_DIR \ _^ release SCL (high)
+BEGIN
+ BIT.B #SMSCL,&I2CSM_IN \ test if SCL is released
+0<> UNTIL
+CALL #T_I2C \ wait tHIGH
+BIT.B #SMSDA,&I2CSM_IN \ _ get SDA
+BIS.B #SMSCL,&I2CSM_DIR \ v_ force SCL low
+MOV @RSP+,PC \ ret
+ENDASM \
+ \
+
+\ ------------------------------\
+ASM I2C_MTX \ MASTER TX \ shared code for address and TX data
+\ ------------------------------\
+BEGIN \
+ ADD.B X,X \ 1 l shift one left
+ U>= IF \ 2 l carry set ?
+ BIC.B #SMSDA,&I2CSM_DIR \ 4 l yes : SDA as input ==> SDA high because pull up resistor
+ ELSE \ 2 l
+ BIS.B #SMSDA,&I2CSM_DIR \ 4 l no : SDA as output ==> SDA low
+ THEN \ l _
+ CALL I2C_PLS \ _| |_ SCL
+ SUB.B #1,W \ l count of bits
+0= UNTIL \ l
+BIC.B #SMSDA,&I2CSM_DIR \ 5 l _ SDA as input : release SDA high to prepare read Ack/Nack
+MOV @RSP+,PC \ ret
+ENDASM \
+ \
+
+\ ==================================\
+ASM I2C_M \
+\ ==================================\
+\ \ in I2CS_ADR/I2CM_BUF as RX/TX buffer requested by I2CS_ADR(0(0))
+\ \ I2CS_ADR(0) = I2C_Slave_addr&R/w
+\ \ I2CM_BUF(0) = TX/RX count of datas
+\ \ I2CM_BUF(0) = 0 ==> send only I2C address
+\ \ used S BUF ptr
+\ \ T datas countdown
+\ \ W bits countdown
+\ \ X dataI2CM_
+\ \ out I2CSLA_ADR & (R/W) unCHNGd
+\ \ S = BUF PTR pointing on first data not exCHNGd
+\ \ T = count+1 of TX/RX datas exCHNGd
+\ \ I2CS_ADR(0) = unCHNGd
+\ \ I2CM_BUF(0) = count of data not exCHNGd (normally = 0)
+\ \ I2CM_BUF(0) = -1 <==> Nack on address
+\ ----------------------------------\
+\ I2C_MR_DC_ListenBeforeStart: \ test if SCL & SDA lines are idle (high)
+\ ----------------------------------\
+ BIC.B #SM_BUS,&I2CSM_DIR \ SDA & SCL pins as input
+ BIC.B #SM_BUS,&I2CSM_OUT \ preset output LOW for SDA & SCL pins
+ MOV #2,T \ I2C_MR_DC_Wait_Start_Loop = 8 µs @ 8 MHz
+\ MOV #4,T \ I2C_MR_DC_Wait_Start_Loop = 8 µs @ 16 MHz
+\ MOV #6,T \ I2C_MR_DC_Wait_Start_Loop = 8 µs @ 24 MHz
+ BEGIN \
+ BEGIN \
+ BEGIN \
+ BIT.B #SMSCL,&I2CSM_IN \ 4 P1DIR.3 SCL high ?
+ 0<> UNTIL \ 2
+ BIT.B #SMSDA,&I2CSM_IN \ 4 P1IN.2 SDA high ?
+ 0<> UNTIL \ 2
+ SUB #1,T \ 1
+ 0= UNTIL \ 2 here the I2C bus is idle
+\ ------------------------------\
+\ I2C_Master_Start_Cond: \ here, SDA and SCL are in idle state
+\ ------------------------------\
+BIS.B #SMSDA,&I2CSM_DIR \ 4- P1DIR.2 force SDA output (low)
+MOV #5,Y \ 2 tHD\STA time 8 MHz
+\ MOV #15,Y \ 2 tHD\STA time 16MHz
+\ MOV #25,Y \ 2 tHD\STA time 24MHz
+CALL #T_I2C \ wait tHD\STA
+BIS.B #SMSCL,&I2CSM_DIR \ 4- P1DIR.3 force SCL output (low)
+\ ------------------------------\
+\ I2C_Master_Start_EndOf: \
+\ ------------------------------\
+MOV #I2CS_ADR,S \ 2 l
+MOV.B @S+,X \ 3 l X = slave address, S = RX buffer
+MOV #I2CM_BUF,W \ 2 l
+MOV.B @W+,T \ 2 l T = count of datas, W = TX buffer
+BIT.B #1,X \ 1 l test I2C R/w flag
+0= IF \ 2 l write flag
+ MOV W,S \ 3 l TX buffer
+THEN \
+\ ------------------------------\
+\ I2C_Master_Send_address \ SCL is held low by slave
+\ ------------------------------\
+ADD #1,T \ to add address in count
+MOV #8,W \ 1 l prepare 8 bit Master writing
+MOV #1,Y \ 2 tHD\STA time 8 MHz value
+\ MOV #5,Y \ 2 tHD\STA time 16MHz value
+\ MOV #15,Y \ 2 tHD\STA time 24MHz value
+CALL #I2C_MTX \ 4 to send address
+\ ------------------------------\
+\ I2C_Master_Loop_Data \
+\ ------------------------------\
+BEGIN \
+\ ----------------------------\
+\ Master TX/RX ACK/NACK \
+\ ----------------------------\
+ MOV #2,Y \ 2 tLOW time complement @ 8MHz
+\ MOV #15,Y \ 2 tLOW time complement @ 16MHz
+\ MOV #20,Y \ 2 tLOW time complement @ 24MHz
+ CALL #I2C_PLS \ _| |_ SCL with BIT SDA, then ret
+ 0<> IF BIS #2,SR \ l if Nack (TX), force Z=1 ==> StopCond
+ ELSE SUB.B #1,T \ else dec count
+ THEN \ l
+\ ----------------------------\
+\ I2C_Master_CheckCountDown \ count=0 or Nack received
+\ ----------------------------\
+ 0= IF \ count reached or Nack
+\ ----------------------------\
+\ I2C_Master_StopCond \
+\ ----------------------------\ before releasing SCL
+ BIS.B #SMSDA,&I2CSM_DIR \ l P1DIR.2 as output ==> SDA low
+ CALL #T_I2C \ l _ wait 4 us
+ BIC.B #SMSCL,&I2CSM_DIR \ _| P1DIR.2 release SCL (high)
+ MOV #5,Y \ 2 tSU:STO time 8 MHz value
+\ MOV #15,Y \ 2 tSU:STO time 16MHz value
+\ MOV #25,Y \ 2 tSU:STO time 24MHz value
+ CALL #T_I2C \ _ wait tSU:STO
+ BIC.B #SMSDA,&I2CSM_DIR \ _| P1DIR.2 as input ==> SDA high with pull up resistor
+ SUB.B T,&I2CM_BUF \ 4 l refresh buffer length and reach tSU:STO
+ MOV @RSP+,PC \ ====>
+\ ----------------------------\
+ THEN \
+\ ----------------------------\
+ MOV.B #8,W \ 1 l prepare 8 bits transaction
+ BIT.B #1,&I2CS_ADR \ 3 l I2C_Master Read/write bit test
+ 0= IF \ 2 l write flag test
+\ ------------------------\
+\ I2C write \
+\ ------------------------\
+ MOV.B @S+,X \ 2 l next byte to transmit
+ CALL #I2C_MTX \ 4 to send data + test ack
+ ELSE \ l
+\ ------------------------\
+\ I2C read \
+\ ========================\
+\ I2C_Master_RX: \ here, SDA is indetermined, SCL is strech low by master
+\ ========================\
+ BEGIN \
+ BIC.B #SMSDA,&I2CSM_DIR \ 4 l _ P1DIR.2 as input ==> release SDA high because pull up resistor
+ MOV #3,Y \ 2 tLOW time complement @ 8 MHz
+\ MOV #15,Y \ 2 tLOW time complement @ 16MHz
+\ MOV #24,Y \ 2 tLOW time complement @ 24MHz
+ CALL #I2C_PLS \ _| |_ SCL + BIT SDA input (SDA-->carry)
+ ADDC.B X,X \ 1 l C <-- X <--- C
+ SUB #1,W \ 1 l count of bits
+ 0= UNTIL \ 2 l
+ MOV.B X, 0(S) \ 3 l store byte in buffer
+ ADD #1,S \ 1 l
+\ ------------------------\
+\ Compute Ack Or Nack \ here, SDA is released by slave, SCL is strech low by master
+\ ------------------------\
+ CMP #1,T \ 1 l here, SDA is released by slave = Nack
+ 0<> IF \ 2
+ BIS.B #SMSDA,&I2CSM_DIR \ 4 l send Ack if byte count <> 1
+ THEN \ l
+ THEN \
+AGAIN \ l
+ENDASM \
+ \
+
+\ ------------------------------\
+CODE START \
+\ ------------------------------\
+\ init PORTA (P2:P1) (complement) when reset occurs all I/O are set in input with resistors pullup
+BIC.B #SM_BUS,&I2CSM_OUT \ P1OUT.32 preset SDA + SCL output low
+BIC.B #SM_BUS,&I2CSM_REN \ P1REN.32 SDA + SCL pullup/down disable
+\ ------------------------------\
+LO2HI
+." \ type stop to stop :-)"
+LIT recurse is WARM \ insert this starting routine between COLD and WARM...
+(WARM) \ ...and continue with (WARM)
+;
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
--- /dev/null
+\ name : msp430FR5xxx_I2C_Soft_MultiMaster.f
+
+\ Copyright (C) <2015> <J.M. THOORENS>
+\
+\ This program is free software: you can redistribute it and/or modify
+\ it under the terms of the GNU General Public License as published by
+\ the Free Software Foundation, either version 3 of the License, or
+\ (at your option) any later version.
+\
+\ This program is distributed in the hope that it will be useful,
+\ but WITHOUT ANY WARRANTY\ without even the implied warranty of
+\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+\ GNU General Public License for more details.
+\
+\ You should have received a copy of the GNU General Public License
+\ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+\ I2C MASTER Standard Mode software driver without interrupt, with detection collision
+\ Target: MSP430FR5xxx, tested @ 8,16,24 MHz and adjusted @ 16,24 MHz
+\ SDA = P1.2, SCL = P1.3, with 3k3 pullup resistors
+
+\ version 1.0 2016-04-10
+
+WIPE
+\ ========================================================================================================
+\ ========================================================================================================
+
+\ ### ##### ##### ##### # # # #
+\ # # # # # # # #### ###### ##### ## ## ## ## ## #### ##### ###### #####
+\ # # # # # # # # # # # # # # # # # # # # # # #
+\ # ##### # ##### # # ##### # # # # # # # # # #### # ##### # #
+\ # # # # # # # # # # # # ###### # # # #####
+\ # # # # # # # # # # # # # # # # # # # # # #
+\ ### ####### ##### ##### #### # # # # # # # # #### # ###### # #
+
+\ ========================================================================================================
+\ ========================================================================================================
+
+\ P1.2 = SDA, P1.3 = SCL
+\ use Px.0 to Px.3 for good timing at 8 MHz (immediate addressing is less of one cycle)
+
+\ tested with P1.6 SDA, P1.7 SCL @ 8MHz :
+\ Start + Adr + Write 3 bytes + Stop + Start + adr + read 2 bytes + stop = 628us ==> 100 kHz
+\ See MSP430FR5xxx_I2C_Soft_MultiMaster.png
+
+VARIABLE I2CS_ADR \ low(I2CS_ADR) = slave I2C address with RW flag, high(I2CS_ADR) = RX buffer,data0
+2 ALLOT \ data1,data2
+VARIABLE I2CM_BUF \ low(I2CM_BUF) = RX or TX lentgh, high(I2CM_BUF) = TX buffer,data0
+2 ALLOT \ data1,data2
+ \
+
+\ ------------------------------\
+ASM T_I2C \ 4 init first once !!!
+\ ------------------------------\
+BEGIN \ 3~ loop
+ SUB #1,Y \ 1
+0= UNTIL \ 2
+ MOV #1,Y \ 2 set I2C tHIGH time @ 8MHz
+\ MOV #9,Y \ 2 set I2C tHIGH time @ 16MHz
+\ MOV #20,Y \ 2 set I2C tHIGH time @ 24MHz
+ MOV @RSP+,PC \ 4 ret
+ENDASM \
+ \
+
+
+\ ------------------------------\
+ASM I2C_PLS \ SCL Pulse
+\ ------------------------------\
+ CALL #R11_I2C \ _ wait tLOW
+ BIC.B #SMMSCL,&I2CSMM_DIR \ _^ release SCL (high)
+ BEGIN
+ BIT.B #SMMSCL,&I2CSMM_IN \ test if SCL is released
+ 0<> UNTIL
+ CALL #R11_I2C \ wait tHIGH
+ MOV.B &I2CSMM_IN,Y \ 3
+ BIT.B #SMMSDA,Y \ _ get SDA
+ BIS.B #SMMSCL,&I2CSMM_DIR \ v_ force SCL low
+ MOV @RSP+,PC \ ret
+ENDASM \
+ \
+
+\ ------------------------------\
+ASM I2C_BTX \ MASTER TX \ one bit shared code for address and TX data
+\ ------------------------------\
+ ADD.B X,X \ 1 l shift one left
+ U>= IF \ 2 l carry set ?
+ BIC.B #SMMSDA,&I2CSMM_DIR \ 4 l yes : SDA as input ==> SDA high because pull up resistor
+ ELSE \ 2 l
+ BIS.B #SMMSDA,&I2CSMM_DIR \ 4 l no : SDA as output ==> SDA low
+ THEN \ l _
+ JMP I2C_PLS \ SCL _| |_ pulse
+ENDASM \
+ \
+
+\ ==================================\
+ASM I2C_MM \ soft I2C_MultiMaster driver
+\ ==================================\
+\ \ in : I2CS_ADR pointer
+\ \ : I2CM_BUF pointer
+\ \ used: S datas pointer
+\ \ T count of I2C datas exchanged
+\ \ W count of bits
+\ \ X data
+\ \ Y I2C_time
+\ \ SR(10) collision flag
+\ \ out : I2CS_ADR(0) unchanged
+\ \ I2CM_BUF(0) = count of data not exchanged (normally = 0)
+\ \ I2CM_BUF(0) = -1 <==> Nack on address
+\ ----------------------------------\
+\ I2CMM_Stop_UCBxI2CSlave \ if SDA SCL of I2C_MultiMaster are hard wired onto SDA SCL of I2C_Slave under interrupt...
+\ ----------------------------------\
+\ BIS #1,&UCB0CTLW0 \ set eUSCI_B0 in reset state, reset StartCond int in UCB0IFG
+\ BIC.B #I2CM_BUS,&I2CSMM_SEL1 \ disable I2C I/O
+\ ----------------------------------\
+\ I2C_MR_DC_ListenBeforeStart: \ test if SCL & SDA lines are idle (high)
+\ ----------------------------------\
+BEGIN \
+ BIC.B #SMM_BUS,&I2CSMM_DIR \ SDA & SCL pins as input
+ BIC.B #SMM_BUS,&I2CSMM_OUT \ preset output LOW for SDA & SCL pins
+ MOV #2,T \ I2C_MR_DC_Wait_Start_Loop = 8 µs @ 8 MHz
+\ MOV #4,T \ I2C_MR_DC_Wait_Start_Loop = 8 µs @ 16 MHz
+\ MOV #6,T \ I2C_MR_DC_Wait_Start_Loop = 8 µs @ 24 MHz
+ BEGIN \
+ BEGIN \
+ BEGIN \
+ BIT.B #SMMSCL,&I2CSMM_IN \ 4 P1DIR.3 SCL high ?
+ 0<> UNTIL \ 2
+ BIT.B #SMMSDA,&I2CSMM_IN \ 4 P1IN.2 SDA high ?
+ 0<> UNTIL \ 2
+ SUB #1,T \ 1
+ 0= UNTIL \ 2 here the I2C bus is idle
+\ --------------------------------\
+\ I2CMR_DC_Shutdown_Slave_Int \ if SDA SCL of I2C_MultiMaster are hard wired onto SDA SCL of I2C_Slave under interrupt...
+\ --------------------------------\
+\ BIS #1,&$640 \ ...set eUSCI_B0 in reset state, that allows I/O use for SDA & SCL...
+\ BIC.B #SMM_BUS,&PI2CSSEL1 \ disable I2C I/O
+\ --------------------------------\
+\ I2C_Master_Start_Cond: \ here, SDA and SCL are in idle state
+\ --------------------------------\
+ BIS.B #SMMSDA,&I2CSMM_DIR \ 4- force SDA output (low)
+ MOV #I2CS_ADR,S \ 2 l
+ MOV.B @S+,X \ 3 l X = slave address, S = RX buffer
+ MOV #I2CM_BUF,W \ 2 l
+ MOV.B @W+,T \ 2 l T = count of datas, W = TX buffer
+ ADD.B #1,T \ to include address in count
+ BIT.B #1,X \ 1 l test I2C R/w flag
+ 0= IF \ 2 l write flag
+ MOV W,S \ 3 l TX buffer
+ THEN \
+ MOV #5,Y \ 2 tHD\STA time 8 MHz complement
+\ MOV #14,Y \ 2 tHD\STA time 16MHz complement
+\ MOV #25,Y \ 2 tHD\STA time 24MHz complement
+ CALL #R11_I2C \ wait 4 us
+ BIS.B #SMMSCL,&I2CSMM_DIR \ 4- force SCL output (low)
+\ --------------------------------\
+\ I2C_Master_Start_EndOf: \
+\ --------------------------------\
+\ I2C_Master_Send_address \
+\ --------------------------------\
+ BIC #$0400,SR \ 2 reset detection collision SR(10) flag
+ MOV.B #8,W \ 1 l prepare 8 bit Master writing
+ BEGIN \
+ MOV #1,Y \ 2 tHD\STA time =8MHz complement
+\ MOV #2,Y \ 2 tHD\STA time =16MHz complement
+\ MOV #13,Y \ 2 tHD\STA time =24MHz complement
+ CALL #I2C_BTX \ l send one bit
+\ ----------------------------\
+\ collision detection \
+\ ----------------------------\
+ XOR.B &I2CSMM_DIR,Y \ 3 normal : IN(SMMSDA) XOR DIR(SMMSDA) = 1
+ BIT.B #SMMSDA,Y \ 2 collision : IN(SMMSDA=0) XOR DIR(SMMSDA=0) = 0
+ 0= IF BIS #$0402,SR \ 6 set collision detection flag SR(10) and set Z=1 to force end of loop
+ ELSE SUB #1,W \ 3 dec count of bits
+ THEN \
+ 0= UNTIL \ 2
+ BIT #$0400,SR \ 2 collision ?
+0= UNTIL \ 2 loop back if collision during send address
+BIC.B #SMMSDA,&I2CSMM_DIR \ 5 release SDA high before 9th bit
+\ ----------------------------------\
+\ I2C_Master_Loop \
+\ ----------------------------------\
+BEGIN
+\ --------------------------------\
+\ Master TX/RX ACK/NACK \
+\ --------------------------------\
+ MOV #1,Y \ 2 tLOW time complement @ 8MHz
+\ MOV #7,Y \ 2 tLOW time complement @ 16MHz
+\ MOV #18,Y \ 2 tLOW time complement @ 24MHz
+ CALL #I2C_PLS \ _| |_ SCL pulse with SDA bit test
+ 0<> IF BIS #2,SR \ l if Nack, force Z=1 ==> StopCond
+ ELSE SUB.B #1,T \ else dec count
+ THEN \ l
+\ --------------------------------\
+\ I2C_Master_CheckCountDown \ count=0 or Nack received
+\ --------------------------------\
+ 0= IF \ count reached or Nack
+\ --------------------------------\
+\ I2C_Master_StopCond \
+\ --------------------------------\ before releasing SCL
+ BIS.B #SMMSDA,&I2CSMM_DIR \ l force SDA low
+ MOV #1,Y \ 2 l tLOW time complement @ 8MHz
+\ MOV #7,Y \ 2 tLOW time complement @ 16MHz
+\ MOV #18,Y \ 2 tLOW time complement @ 24MHz
+ CALL #R11_I2C \ _ wait 4 us
+ BIC.B #SMMSCL,&I2CSMM_DIR \ _| release SCL (high with pull up resistor)
+ SUB.B T,&I2CM_BUF \ 4 refresh buffer length
+ MOV #5,Y \ 2 tSU:STO time 8 MHz complement
+\ MOV #15,Y \ 2 tSU:STO time 16MHz complement
+\ MOV #25,Y \ 2 tSU:STO time 24MHz complement
+ CALL #R11_I2C \ _ wait tSU:STO
+ BIC.B #SMMSDA,&I2CSMM_DIR \ _| release SDA (high with pull up resistor)
+\ ----------------------------\
+\ I2C_Master_Endof \
+\ ----------------------------\
+\ Restart I2C_Slave_Int \ if any
+\ ----------------------------\
+\ BIC #1,&UCB0CTLW0 \ restart eUSCI_B
+\ BIS.B #SMM_BUS,&I2CSMM_SEL1 \ reenable I2C I/O
+\ ----------------------------\
+ MOV @RSP+,PC \ ====>
+\ --------------------------------\
+ THEN \
+\ --------------------------------\
+ MOV.B #8,W \ 1 l prepare 8 bits transaction
+ BIT.B #1,&I2CS_ADR \ 3 l I2C_Master Read/write bit test
+ 0= IF \ 2 l write flag test
+\ ============================\
+\ I2C_Master_TX \
+\ ============================\
+ MOV.B @S+,X \ 2 l next byte to TX
+ BEGIN \
+ MOV #1,Y \ 2 tHD\STA time =8MHz complement
+\ MOV #2,Y \ 2 tHD\STA time =16MHz complement
+\ MOV #13,Y \ 2 tHD\STA time =24MHz complement
+ CALL #I2C_BTX \ l send one bit
+ SUB.B #1,W \ l count of bits
+ 0= UNTIL \ l
+ BIC.B #SMMSDA,&I2CSMM_DIR \ 5 l release SDA high before 9th bit
+ ELSE \ l
+\ ============================\
+\ I2C_Master_RX: \ here, SDA is indetermined, SCL is strech low by master
+\ ============================\
+ BIC.B #SMMSDA,&I2CSMM_DIR \ 5 l _ After ACK we must release SDA
+ BEGIN \
+ MOV #3,Y \ 2 tLOW time complement @ 8 MHz
+\ MOV #15,Y \ 2 tLOW time complement @ 16MHz
+\ MOV #24,Y \ 2 tLOW time complement @ 24MHz
+ CALL #I2C_PLS \ _| |_ SCL pulse with SDA bit test
+ ADDC.B X,X \ 1 l C <-- X <--- C ; C flag = SDA
+ SUB #1,W \ 1 l count of bits
+ 0= UNTIL \ 2 l
+ MOV.B X, 0(S) \ 3 l store RX byte in buffer
+ ADD #1,S \ 1 l
+\ ----------------------------\
+\ Compute RX Ack/Nack \
+\ ----------------------------\
+ CMP #1,T \ 1 l here, SDA is released by slave = Nack
+ 0<> IF \ 2
+ BIS.B #SMMSDA,&I2CSMM_DIR \ 4 l send Ack if byte count <> 1
+ THEN \ l
+ THEN \
+AGAIN \ l
+ENDASM \
+ \
+
+\ ------------------------------\
+CODE START \
+\ ------------------------------\
+\ init PORTA (P2:P1) (complement) when reset occurs all I/O are set in input with resistors pullup
+BIC.B #SMM_BUS,&I2CSMM_OUT \ preset SDA + SCL output low
+BIC.B #SMM_BUS,&I2CSMM_REN \ SDA + SCL pullup/down disable
+\ ------------------------------\
+ LO2HI
+ ." Type STOP to stop :-)"
+ LIT recurse is WARM \ insert this routine between COLD and WARM...
+ (WARM) ; \ ...and continue with WARM
+ \
+
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+RST_HERE
+
+\ ---------------------------------------------------------------------------------------------------------------------\
+\ SCL clock generation, timing, and test of data(s) number are made by I2C_Master.
+\ slave can strech SCL low after Start Condition and after any bit.
+
+\ address Ack/Nack is generated by the slave on SDA line (released by the master)
+\ Two groups of eight addresses (000xxxy and 1111xxxy) are not allowed (reserved)
+\ after address or data is sent, the transmitter (Master or Slave) must release SDA line to allow (N)Ack by the receiver
+\ data Ack/Nack are generated by the receiver (master or slave) on SDA line
+\ a master receiver must signal the end of data to the slave transmitter by sending a Nack bit
+\ Stop or restart conditions must be generated by master after a Nack bit.
+\ after Ack bit is sent, Slave must release SDA line to allow master to do stop or restart conditions
+\
+\ __ _____ _____ _..._ _____ _____ _NACK _____ _____ _..._ _____ _____ _NACK _
+\ SDA \____/_MSB_X_____X_..._X_LSB_X_R/Wx_ACK_x_MSB_X_____X_..._X_____X_LSB_X_ACK_X___/
+\ _____ _ _ _ _ _ _ _ _ _ _ ___
+\ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/
+\ ^ ^ ^ ^ ^ ^ ^
+\ | |Slave Stretch Low |SSL |SSL |SSL |SSL |
+\ | |
+\ |Start Condition |stoP Condition
+\
+\ __ _____ _____ _..._ _____ _____ _NACK _____ _____ _..._ _____ _____ _NACK ___
+\ SDA \____/_MSB_X_____X_..._X_LSB_X_R/W_x_ACK_x_MSB_X_____X_..._X_____X_LSB_X_ACK_X \____...
+\ _____ _ _ _ _ _ _ _ _ _ _ ____
+\ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/ \_...
+\ ^ ^ ^ ^ ^ ^ ^
+\ | |Slave Stretch Low |SSL |SSL |SSL |SSL |
+\ | |
+\ |Start Condition |reStart Condition
+\
+\ tHIGH : SCL high time
+\ tLOW : SCL low time
+\ tBUF : SDA high time between Stop and Start conditions
+\ tHD:STA : Start_Condition SCL high time after SDA is low
+\ tSU:STO : Stop_Condition SCL high time before SDA rise
+\ tSU:STA : Start_Condition SCL high time before SDA fall
+\ tHD:DAT : SDA data change time after SCL is low
+\ the SDA line must be strobe just after SCL is high
+\ the SDA data must be change just after SCL is low
+\ standard mode (up to 100 kHz) : tHIGH = tHD:STA = tSU:STO = 4µs
+\ tLOW = tSU:STA = tBUF = 4,7µs
+\ tHD:DAT <= 3,45 µs
+\ -------------------------------------------------------------------------------------------------------------------\
--- /dev/null
+\ ---------------
+\ IR_RC5_P1.2.f
+\ ---------------
+RST_STATE \ to rub out this test with <reset> or RST_STATE or COLD
+
+\ Copyright (C) <2014> <J.M. THOORENS>
+\
+\ This program is free software: you can redistribute it and/or modify
+\ it under the terms of the GNU General Public License as published by
+\ the Free Software Foundation, either version 3 of the License, or
+\ (at your option) any later version.
+\
+\ This program is distributed in the hope that it will be useful,
+\ but WITHOUT ANY WARRANTY\ without even the implied warranty of
+\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+\ GNU General Public License for more details.
+\
+\ You should have received a copy of the GNU General Public License
+\ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+\ FORTH driver for IR remote compatible with the PHILIPS RC5 protocol, with select new/repeated command
+\ target : see IR_RC5.pat
+
+\ Send to terminal the RC5 new command.
+\ Press S1 to send also RC5 repeated command.
+
+
+\ HERE \ general minidump, part 1
+
+\ --------------------------------------------------------------------------------------------
+\ MSP-EXP430FR5969 driver for IR_RC5 receiver TSOP32236 wired on Px.y input \ 65 words, 24.5ms
+\ --------------------------------------------------------------------------------------------
+
+\ layout : see config.pat file for defining I/O
+
+\ ******************************\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM INT_RC5 \ wake up on P1.2 change interrupt \ IP,TOS,W,X,Y are free for use
+\ ------------------------------\
+BIC #$F8,0(RSP) \ SCG1,SCG0,OSCOFF,CPUOFF and GIE are OFF in retiSR to force LPM0_LOOP with pending interrupt
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : IP,TOS,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+ MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+ MOV #1778,X \ RC5_Period in us
+ MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 1us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+ BIC #$30,&TA0CTL \ stop timer_A0
+ RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+ MOV @RSP,X \ retiSR(9) = old RC5 toggle bit
+ RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+ XOR IP,X \ (new XOR old) Toggle bit (13)
+ BIT #BIT13,X \ X(13) = New_RC5_command
+ 0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change
+ THEN \
+ XOR #UF1,0(RSP) \ change Toggle bit memory, User Flag 1 ( SR(9))
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+ MOV.B IP,S \ S = C5 C4 C3 C2 C1 C0 0 0
+ RRUM #2,S \ S = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+ BIT #BIT14,IP \ test /C6 bit in IP
+ 0= IF BIS #BIT6,S \ set C6 bit in S
+ THEN \ S = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+ RETI
+ENDASM
+ \
+
+
+
+\ ------------------------------
+\ Start process RC5 part
+\ ------------------------------
+\ ------------------------------\
+CODE START \
+\ ------------------------------\
+\ init PORTX (P2:P1) (complement) default I/O are input with pullup resistors
+ BIC.B #RC5,&PIRIFG \ P1IFG.2 clear int flag for TSOP32236 (after IES select)
+ BIS.B #RC5,&PIRIE \ P1IE.2 enable interrupt for TSOP32236
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ init interrupt vectors \
+\ ------------------------------\
+ MOV #INT_RC5,&IR_Vec \ init Px vector interrupt
+\ ------------------------------\
+ LO2HI
+ ." RC5toLCD is running. Type STOP to quit"
+ LIT RECURSE IS WARM \ insert this starting routine between COLD and WARM...
+ (WARM) ; \ ...and continue with WARM (very, very usefull after COLD or RESET !:-)
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+\ HERE OVER - DUMP \ general minidump, part 2
+
+RST_HERE \
+
+
+
+\ --------------------------------------------------\
+\ PHILIPS IR REMOTE RC5/RC6 protocol \
+\ --------------------------------------------------\
+\ first half bit = no light, same as idle state
+\ second half bit : 32 IR-light pulses of 6,944us,light ON/off ratio = 1/3
+
+\ |<------32 IR light pulses = second half of first start bit ------->|
+\ |_ _ _ _ _ _ _ _ _ _ _ _|
+\ ...____| |___| |___| |___| |___| |___| |...| |___| |___| |___| |___| |___| |____________________________________...
+\ | |
+\
+
+
+\ at the output of IR receiver TSOPxxx during the first start bit :
+
+\ ...idle state ->|<----- first half bit ------>|<- second half bit (IR light) ->|
+\ ..._____________|_____________________________| |_________...
+\ | | |
+\ | | |
+\ | |________________________________|
+
+\ 32 cycles of 27,777us (36kHz) = 888,888 us
+\ one bit = 888,888 x 2 = 1778 us.
+
+
+
+\ 14 bits of active message = 24.889 ms
+\ + 50 bits of silent (idle) = 88.888 ms
+\ = RC5 message = 113.792 ms
+
+\
+\ RC5_message on IR LIGHT \ idle state = light off
+
+\ 89ms>|<--------------------------------------------------24.889 ms-------------------------------------------------->|<88,
+\ | |
+\ | | | | | | | | | | | | | | |
+\ | ST1 | ST2/C6| Tog | A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | C0 |
+\ | | | | | | | | | | | | | | |
+\ 1 1 1 1 0 0 1 1 1 1 1 1 1 1
+\ ___ ___ ___ _______ ___ ___ ___ ___ ___ ___ ___ ___ ___
+\ ^ | ^ | ^ | ^ | | | ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^ |
+\ idle____| |___| |___| |___| v___| v_______| |___| |___| |___| |___| |___| |___| |___| |____
+\
+\
+\ notice that each cycle contains its bit value preceded by its complement
+
+
+
+
+\ the same RC5_message inverted at the output of IR receiver : idle state = 1
+\
+\ | | | | | | | | | | | | | | |
+\ | ST1 | ST2/C6| Tog | A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | C0 |
+\ | | | | | | | | | | | | | | |
+\ 1 1 1 1 0 0 1 1 1 1 1 1 1 1
+\ idle_____ ___ ___ ___ ___ _______ ___ ___ ___ ___ ___ ___ ___ __idle
+\ | | | | | | | ^ | ^ | | | | | | | | | | | | | | | |
+\ v___| v___| v___| v_______| |___| v___| v___| v___| v___| v___| v___| v___| v___|
+\ I R R R R R R R R R R R R R
+\
+\ notice that each cycle contains its bit value followed by its complement
+
+
+
+
+\ principe of the driver : 13 samples at 1/4 period and Resynchronise (R) on 1/2 period (two examples)
+
+\ 0,888 ms
+\ |<->|<--------------------------------routine time = 12 3/4 cycles = 22.644 ms--------------------------->|
+\ | | | | | | | | | | | | | | | |
+\ | ST1 | ST2/C6| Toggle| A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | |C0 |
+\ | | | | | | | | | | | | | | | |
+\ 1 1 1 1 0 0 1 1 1 1 1 1 1 | 1
+\ idle_____ _s_ _s_ _s_ ___ _____s_ _s_ _s_ _s_ _s_ _s_ _s_ _s_ __idle
+\ | | | | | | | ^ | ^ | | | | | | | | | | | | | | | |
+\ v___| v___| v___| v_____s_| |_s_| v___| v___| v___| v___| v___| v___| v___| v___|
+\ S R R R R R R R R R R R R ^ ^
+\ samples : 1 2 3 4 5 6 4 8 9 10 11 12 13 | |
+\ | |
+\ I I
+\ 0,888 ms
+\ |<->|<--------------------------------routine time = 12 3/4 cycles = 22.644 ms--------------------------->|
+\ | | | | | | | | | | | | | | | |
+\ | ST1 | ST2/C6| Toggle| A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | |C0 |
+\ | | | | | | | | | | | | | | | |
+\ 1 1 1 1 0 0 1 1 1 1 1 1 1 | 1
+\ idle_____ _s_ _s_ ___ _o_ _o___s_ _s_ _s_ _s_ _s_ _s_ _s_ ______idle
+\ | | | | | | | ^ | ^ | | | | | | | | | | | | | ^
+\ v___| v_o_| v_o_| v_o___s_| |_s_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o___s_|
+\ S R R R R R R R R R R R R ^
+\ samples : 1 2 3 4 5 6 7 8 9 10 11 12 13|
+\ |
+\ I
+\ good ! but we have too many of RC5_Int...
+
+
+
+
+\ So, to avoid these RC5_Int after end : 13+1=14 samples, then the result is shifted one to right (two examples)
+
+\ 0,888 ms
+\ |<->|<--------------------------------routine time = 13 3/4 cycles = 24.447 ms----------------------------------->|
+\ | | | | | | | | | | | | | | | |
+\ | ST1 | ST2/C6| Toggle| A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | C0 | |
+\ | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | |
+\ | | | | | | | | | | | | | | | |
+\ idle_____ _s_ _s_ _s_ _o_ _o___s_ _s_ _s_ _s_ _s_ _s_ _s_ _s_ _s_idle
+\ | | | | | | | ^ | ^ | | | | | | | | | | | | | | | |
+\ v___| v_o_| v_o_| v_o___s_| |_s_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o_|
+\ S i R i R i R R i R R i R i R i R i R i R i R i R i
+\ samples : 1 2 3 4 5 6 7 8 9 10 11 12 13 14
+\
+\
+\ 0,888 ms
+\ |<->|<--------------------------------routine time = 13 3/4 cycles = 24.447 ms----------------------------------->|
+\ | | | | | | | | | | | | | | | |
+\ | ST1 | ST2/C6| Toggle| A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | C0 | |
+\ | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | |
+\ | | | | | | | | | | | | | | | |
+\ idle_____ _s_ _s_ ___ _o_ _o___s_ _s_ _s_ _s_ _s_ _s_ _s_ _o___s_idle
+\ | | | | | | | ^ | ^ | | | | | | | | | | | | | ^
+\ v___| v_o_| v_o_| v_o___s_| |_s_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o___s_|
+\ S i R i R i R R i R R i R i R i R i R i R i R R
+\ samples : 1 2 3 4 5 6 7 8 9 10 11 12 13 14
+
+
+\ S = Wake up on RC5_Int at 1/2 cycle : clear and start timer
+\ i = useless RC5_Int (not periodic) at 4/4 cycle
+\ s = sample RC5_intput at (1/2+3/4) = 5/4 cycle = 1/4 cycle+1 and clear useless RC5_Int
+\ R = usefull (periodic) RC5_Int at 6/4 cycle = 1/2 cycle+1 : cycle value = timer value then clear it and restart it
+\ o = RC5_Int time out at 7/4 cycle = 3/4 cycle+1, used to detect (samples<14) truncated RC5_message
+
+\ see also : http://www.sbprojects.com/knowledge/ir/rc5.php
+\ http://laurent.deschamps.free.fr/ir/rc5/rc5.htm
+\ Code RC5 : http://en.wikipedia.org/wiki/RC-5
+
--- /dev/null
+\ IR_RC5_to_I2CF_Soft_Master.f
+
+\ Copyright (C) <2016> <J.M. THOORENS>
+\
+\ This program is free software: you can redistribute it and/or modify
+\ it under the terms of the GNU General Public License as published by
+\ the Free Software Foundation, either version 3 of the License, or
+\ (at your option) any later version.
+\
+\ This program is distributed in the hope that it will be useful,
+\ but WITHOUT ANY WARRANTY\ without even the implied warranty of
+\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+\ GNU General Public License for more details.
+\
+\ You should have received a copy of the GNU General Public License
+\ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+\ --------------------------------------\
+\ example of App running under interrupt
+\ --------------------------------------\
+\ FORTH driver for IR remote compatible with the PHILIPS RC5 protocol, with select new/repeated command
+
+\ target : any MSP430FRxxxx @ 8Mhz
+
+\ prerequisites : your launchpad is wired as described in launchpad.pat file : UART0, Soft_Master(SDA,SCL), IR_RC5 parts.
+\ FastForth runs @ 8MHz
+\ add 3k3 pull up resistors on SDA and SCL lines.
+
+\ usage : create a logical network drive ( a: b: ...as you want) from your local copy of Gitlab FAST FORTH
+\ with scite.exe open this file MSP430-FORTH\IR_RC5_to_I2CF_Soft_Master.f,
+\ select "tools" menu, "preprocess" item 1 (CTRL+0),
+\ a dialog box asks you for 4 parameters $(1) to $(4),
+\ in the 2th param. field, type your launchpad to select the launchpad.pat to be used : for example MSP_EXP430FR5969,
+\ result : the word START starts the app that runs under LPMx.
+
+\ to recover the console input (i.e. to quit LPMx), type a space. Then you can enter a command, for example STOP.
+
+\ select one initial state :
+WIPE \ to suppress any previous app
+\ RST_STATE \ to conserve the previous app protected against <reset>
+\ PWR_STATE \ to conserve the previous app protected against POWER OFF
+NOECHO \ comment if an error occurs, to detect it with new download
+
+\ HERE \ uncomment for a dump, part 1
+ \
+
+
+
+\ -------------------------------------------------------------------------------------------------------------------\
+\ I2CF Soft MASTER driver, FAST MODE, 8MHz
+\ -------------------------------------------------------------------------------------------------------------------\
+
+VARIABLE I2CS_ADR \ low(I2CS_ADR) = slave I2C address with RW flag, high(I2CS_ADR) = RX buffer,data0
+2 ALLOT \ data1,data2
+VARIABLE I2CM_BUF \ low(I2CM_BUF) = RX or TX lentgh, high(I2CM_BUF) = TX buffer,data0
+2 ALLOT \ data1,data2
+ \
+
+\ ------------------------------\
+ASM I2C_MTX \ MASTER TX \ shared code for address and TX data
+\ ------------------------------\
+BEGIN \
+ ADD.B X,X \ 1 l shift one left
+ U>= IF \ 2 l carry set ?
+ BIC.B #MSDA,&I2CSM_DIR \ 4 l yes : SDA as input ==> SDA high because pull up resistor
+ ELSE \ 2 l
+ BIS.B #MSDA,&I2CSM_DIR \ 4 l no : SDA as output ==> SDA low
+ THEN \ l _
+ BIC.B #MSCL,&I2CSM_DIR \ 4 l _^ release SCL (high)
+ BEGIN \ 14/16~l
+ BIT.B #MSCL,&I2CSM_IN \ 3 h test if SCL is released
+ 0<> UNTIL \ 2 h _
+ BIS.B #MSCL,&I2CSM_DIR \ 4 h v_ SCL as output : force SCL low
+ SUB #1,W \ 1 l count of bits
+0= UNTIL \ 2 l
+BIC.B #MSDA,&I2CSM_DIR \ 5 l _ SDA as input : release SDA high to prepare read Ack/Nack
+RET
+ENDASM \
+ \
+
+\ ******************************\
+\ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
+\ ******************************\
+ASM INT_RC5 \ wake up on P1.2 change interrupt \ IP,TOS,W,X,Y are free for use
+\ ------------------------------\
+BIC #$F8,0(RSP) \ SCG1,SCG0,OSCOFF,CPUOFF and GIE are OFF in retiSR to force LPMx_LOOP with pending interrupt
+\ BIC #$B8,0(RSP) \ {SCG1,OSCOFF,CPUOFF,GIE}=OFF after RETI to force goto label "LPMx_LOOP" with any pending interrupt
+\ ------------------------------\
+\ define LPM mode for ACCEPT \ uncomment a line
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ \ in : SR(9)=old Toggle bit memory (ADD on)
+\ \ SMclock = 8|16|24 MHz
+\ \ use : IP,TOS,W,X,Y, TA0 timer, TA0R register
+\ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
+\ \ SR(9)=new Toggle bit memory (ADD on)
+\ ------------------------------\
+\ RC5_FirstStartBitHalfCycle: \
+\ ------------------------------\
+MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
+\ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ)
+\ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ)
+MOV #1778,X \ RC5_Period in us
+MOV #14,W \ count of loop
+BEGIN \
+\ ------------------------------\
+\ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period
+\ ------------------------------\ | here, we are just after 1/2 RC5_cycle
+ MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 2us time interval,free running,clear TA0_IFG and TA0R
+\ RC5_Compute_3/4_Period: \ |
+ RRUM #1,X \ X=1/2 cycle |
+ MOV X,Y \ Y=1/2 ^
+ RRUM #1,Y \ Y=1/4
+ ADD X,Y \ Y=3/4
+\ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1
+ BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value
+ 0= UNTIL \
+\ ------------------------------\
+\ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first
+\ ------------------------------\
+ BIT.B #RC5,&IR_IN \ C_flag = IR bit
+ ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag
+ MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
+ BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
+ SUB #1,W \ decrement count loop
+\ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6
+\ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
+0<> WHILE \ ----> out of loop ----+
+\ RC5_compute_7/4_Time_out: \ |
+ ADD X,Y \ | out of bound = 7/4 period
+\ RC5_WaitHalfCycleP1.2_IFG: \ |
+ BEGIN \ |
+ CMP Y,&TA0R \ | TA0R = 5/4 cycle test
+ 0>= IF \ | if cycle time out of bound
+ BIC #$30,&TA0CTL \ | stop timer_A0
+ RETI \ | then quit to do nothing
+ THEN \ |
+\ ------------------------------\ |
+ BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG
+ 0<> UNTIL \ | |
+ MOV &TA0R,X \ | | get new RC5_period value
+REPEAT \ ----> loop back --+ |
+\ ------------------------------\ |
+\ RC5_SampleEndOf: \ <---------------------+
+\ ------------------------------\
+MOV #$30,&TA0CTL \ stop timer_A0
+RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0
+\ ******************************\
+\ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
+\ ******************************\
+MOV @RSP,X \ retiSR(9) = old RC5 toggle bit
+RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13)
+XOR IP,X \ (new XOR old) Toggle bit (13)
+BIT #BIT13,X \ X(13) = New_RC5_command
+0= IF
+ RETI \ case of repeated RC5_command : RETI without SR(9) change
+THEN \
+XOR #UF1,0(RSP) \ change Toggle bit memory, User Flag 1 = SR(9)
+\ ******************************\
+\ RC5_ComputeNewRC5word \
+\ ******************************\
+MOV.B IP,S \ S = C5 C4 C3 C2 C1 C0 0 0
+RRUM #2,S \ S = 0 0 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_ComputeC6bit \
+\ ******************************\
+BIT #BIT14,IP \ test /C6 bit in IP
+0= IF
+ BIS #BIT6,S \ set C6 bit in S
+THEN \ S = 0 C6 C5 C4 C3 C2 C1 C0
+\ ******************************\
+\ RC5_CommandByteIsDone \ RC5_code --
+\ ******************************\
+\ ------------------------------\
+\ Prepare I2C_MASTER \
+\ ------------------------------\
+SWPB S \ 1 high byte = data
+ADD #1,S \ 1 low byte = count
+MOV S,&I2CM_BUF \ 3
+MOV #%0010100,&I2CS_ADR \ MSP-EXP430FRxxx I2C slave address
+\ ------------------------------\
+\ echo code to terminal option \
+\ ------------------------------\
+\ SUB #2,PSP
+\ MOV TOS,0(PSP)
+\ MOV.B S,TOS
+\ LO2HI
+\ cr ." $" HEX 2 U.R
+\ HI2LO
+
+\ ==================================\
+\ CODE I2C_M \ fast I2C soft Master, only 8 MHz
+\ ==================================\
+\ \ in I2CS_ADR/I2CM_BUF as RX/TX buffer requested by I2CS_ADR(0(0))
+\ \ I2CS_ADR(0) = I2C_Slave_addr&R/w
+\ \ I2CM_BUF(0) = TX/RX count of datas
+\ \ I2CM_BUF(0) = 0 ==> send only I2C address
+\ \ used S BUF ptr
+\ \ T datas countdown
+\ \ W bits countdown
+\ \ X data
+\ \ out I2CSLA_ADR & (R/W) unCHNGd
+\ \ S = BUF PTR pointing on first data not exCHNGd
+\ \ T = count+1 of TX/RX datas exCHNGd
+\ \ I2CS_ADR(0) = unCHNGd
+\ \ I2CM_BUF(0) = count of data not exCHNGd (normally = 0)
+\ \ I2CM_BUF(0) = -1 <==> Nack on address
+\ ----------------------------------\
+\ I2C_MR_DC_ListenBeforeStart: \ test if SCL & SDA lines are idle (high)
+\ ----------------------------------\
+BIC.B #M_BUS,&I2CSM_DIR \ SDA & SCL pins as input
+BIC.B #M_BUS,&I2CSM_OUT \ preset output LOW for SDA & SCL pins
+MOV #2,T \ I2C_MR_DC_Wait_Start_Loop = 8 µs @ 8 MHz
+\ MOV #4,T \ I2C_MR_DC_Wait_Start_Loop = 8 µs @ 16 MHz
+\ MOV #6,T \ I2C_MR_DC_Wait_Start_Loop = 8 µs @ 24 MHz
+BEGIN \
+ BEGIN \
+ BEGIN \
+ BIT.B #MSCL,&I2CSM_IN \ 4 P1DIR.3 SCL high ?
+ 0<> UNTIL \ 2
+ BIT.B #MSDA,&I2CSM_IN \ 4 P1IN.2 SDA high ?
+ 0<> UNTIL \ 2
+ SUB #1,T \ 1
+0= UNTIL \ 2 here the I2C bus is idle
+\ ----------------------------------\
+\ I2C_Master_Start_Cond: \ here, SDA and SCL are in idle state
+\ ----------------------------------\
+BIS.B #MSDA,&I2CSM_DIR \ 4 l force SDA as output (low)
+MOV #I2CM_BUF,W \ 2 h W=buffer out
+MOV.B @W+,T \ 2 h T=datas countdown
+MOV #I2CS_ADR,S \ 2 h S=buffer in
+MOV.B @S+,X \ 2 h X=Slave address to TX
+BIT.B #1,X \ 1 h test I2C R/w flag
+0= IF \ 2 h if write
+ MOV W,S \ 2 h S= buffer out ptr
+THEN \ S= buffer ptr
+BIS.B #MSCL,&I2CSM_DIR \ 4 h force SCL as output (low)
+\ ----------------------------------\
+\ I2C_Master_Start_EndOf: \
+\ ----------------------------------\
+\ I2C_Master_Send_address \ may be SCL is held low by slave
+\ ----------------------------------\
+ADD #1,T \ 1 l to add address in count
+MOV #8,W \ 1 l prepare 8 bit Master writing
+CALL #I2C_MTX \ 21 l to send address
+\ ----------------------------------\
+\ I2C_Master_Loop_Data \
+\ ----------------------------------\
+BEGIN \ 4 l here ack/nack is received/transmitted
+\ --------------------------------\ l
+\ Master TX/RX ACK/NACK \
+\ --------------------------------\ l _
+ BIC.B #MSCL,&I2CSM_DIR \ 3 l _^ release SCL (high)
+ BEGIN \
+ BIT.B #MSCL,&I2CSM_IN \ 3 h test if SCL is released
+ 0<> UNTIL \ 2 h
+ BIT.B #MSDA,&I2CSM_IN \ 3 h _ get SDA
+ BIS.B #MSCL,&I2CSM_DIR \ 3 h v_ SCL as output : force SCL low
+\ --------------------------------\ l
+\ I2C_Master_Loop_Data \
+\ --------------------------------\
+ 0<> IF BIS #Z,SR \ 5 l if Nack (TX), force Z=1 ==> StopCond
+ ELSE SUB.B #1,T \ 3 l else dec count
+ THEN \ l
+\ --------------------------------\
+\ I2C_Master_CheckCountDown \ count=0 (TX) or Nack received
+\ --------------------------------\
+ 0= IF \ 2 l send stop
+\ ----------------------------\
+\ Send Stop \
+\ ----------------------------\ _
+ BIS.B #MSDA,&I2CSM_DIR \ 4 l v_ SDA as output ==> SDA low
+ SUB.B T,&I2CM_BUF \ 4 l _ refresh buffer length and reach tSU:STO
+ BIC.B #MSCL,&I2CSM_DIR \ 4 l _^ release SCL (high)
+ BEGIN \
+ BIT.B #MSCL,&I2CSM_IN \ 3 h SCL released ?
+ 0<> UNTIL \ 2 h
+ BIC.B #MSDA,&I2CSM_DIR \ 4 h _^ SDA as input ==> SDA high with pull up resistor
+\ MOV @RSP+,PC \ RET ====>
+ RETI \
+ THEN \
+ MOV.B #8,W \ 1 l prepare 8 bits transaction
+ BIT.B #1,&I2CS_ADR \ 3 l I2C_Master Read/write bit test
+ 0= IF \ 2 l write flag test
+\ ============================\
+\ I2C_Master_TX \
+\ ============================\
+ MOV.B @S+,X \ 2 l next byte to transmit
+ CALL #I2C_MTX \ l to send data
+ ELSE \ l
+\ ============================\
+\ I2C_Master_RX: \ here, SDA is indetermined, SCL is strech low by master
+\ ============================\
+ BIC.B #MSDA,&I2CSM_DIR \ 5 l _ After ACK we must release SDA
+ BEGIN \
+\ ------------------------\ _
+\ send bit \ SCL _| |_
+\ ------------------------\ _
+ BIC.B #MSCL,&I2CSM_DIR \ 4 l _^ release SCL (high)
+ BEGIN \ 14/16~l
+ BIT.B #MSCL,&I2CSM_IN \ 3 h test if SCL is released
+ 0<> UNTIL \ 2 h
+ BIT.B #MSDA,&I2CSM_IN \ 4 h _ get SDA
+ BIS.B #MSCL,&I2CSM_DIR \ 4 h v_ SCL as output : force SCL low 13~
+ ADDC.B X,X \ 1 l C <-- X <--- C
+ SUB #1,W \ 1 l count of bits
+ 0= UNTIL \ 2 l
+ MOV.B X,0(S) \ 3 l store byte in buffer
+ ADD #1,S \ 1 l
+\ ----------------------------\
+\ Compute Ack Or Nack \ here, SDA is released by slave, SCL is strech low by master
+\ ----------------------------\
+ CMP.B #1,T \
+ 0<> IF \ 2 l
+ BIS.B #MSDA,&I2CSM_DIR \ 5 l yes : send Ack
+ THEN \
+ THEN \
+AGAIN \ 2 l
+ENDASM \
+ \
+
+
+\ ------------------------------\
+CODE START \
+\ ------------------------------\
+\ init PORT M_BUS (complement) \ when reset occurs all I/O are set in input with resistors pullup
+BIC.B #M_BUS,&I2CSM_OUT \ preset SDA + SCL output low
+BIC.B #M_BUS,&I2CSM_REN \ SDA + SCL pullup/down disable
+\ ------------------------------\
+\ init PORT IR (complement) default I/O are input with pullup resistors
+BIS.B #RC5,&IR_IE \ enable interrupt for TSOP32236
+BIC.B #RC5,&IR_IFG \ clear int flag for TSOP32236
+\ ------------------------------\
+\ init interrupt vectors \
+\ ------------------------------\
+MOV #INT_RC5,&IR_Vec \ init IR vector interrupt
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+LO2HI
+." RC5toI2CF_Master is running. Type STOP to quit"
+\ NOECHO \ uncomment to run this app without terminal connexion
+LIT RECURSE IS WARM \ insert this starting routine between COLD and WARM...
+(WARM) ; \ ...and continue with WARM (very, very usefull after COLD or RESET !:-)
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+ECHO
+
+\ DUP HERE SWAP - DUMP \ uncomment for a dump, part 2
+ \
+
+\ select one end state :
+RST_HERE \ this app is protected against POWER OFF, <reset>, COLD, ...and STOP that executes COLD.
+\ PWR_HERE \ this app is protected only againt POWER OFF
+\ nothing \ this app is volatile !
+
+
+\ all lines beyond START command are ignored
+
+\ --------------------------------------------------\
+\ PHILIPS IR REMOTE RC5/RC6 protocol \
+\ --------------------------------------------------\
+\ first half bit = no light, same as idle state
+\ second half bit : 32 IR-light pulses of 6,944us,light ON/off ratio = 1/3
+
+\ |<------32 IR light pulses = second half of first start bit ------->|
+\ |_ _ _ _ _ _ _ _ _ _ _ _|
+\ ...____| |___| |___| |___| |___| |___| |...| |___| |___| |___| |___| |___| |____________________________________...
+\ | |
+\
+
+
+\ at the output of IR receiver TSOPxxx during the first start bit :
+
+\ ...idle state ->|<----- first half bit ------>|<- second half bit (IR light) ->|
+\ ..._____________|_____________________________| |_________...
+\ | | |
+\ | | |
+\ | |________________________________|
+
+\ 32 cycles of 27,777us (36kHz) = 888,888 us
+\ one bit = 888,888 x 2 = 1778 us.
+
+
+
+\ 14 bits of active message = 24.889 ms
+\ + 50 bits of silent (idle) = 88.888 ms
+\ = RC5 message = 113.792 ms
+
+\
+\ RC5_message on IR LIGHT \ idle state = light off
+
+\ 89ms>|<--------------------------------------------------24.889 ms-------------------------------------------------->|<88,
+\ | |
+\ | | | | | | | | | | | | | | |
+\ | ST1 | ST2/C6| Tog | A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | C0 |
+\ | | | | | | | | | | | | | | |
+\ 1 1 1 1 0 0 1 1 1 1 1 1 1 1
+\ ___ ___ ___ _______ ___ ___ ___ ___ ___ ___ ___ ___ ___
+\ ^ | ^ | ^ | ^ | | | ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^ |
+\ idle____| |___| |___| |___| v___| v_______| |___| |___| |___| |___| |___| |___| |___| |____
+\
+\
+\ notice that each cycle contains its bit value preceded by its complement
+
+
+
+
+\ the same RC5_message inverted at the output of IR receiver : idle state = 1
+\
+\ | | | | | | | | | | | | | | |
+\ | ST1 | ST2/C6| Tog | A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | C0 |
+\ | | | | | | | | | | | | | | |
+\ 1 1 1 1 0 0 1 1 1 1 1 1 1 1
+\ idle_____ ___ ___ ___ ___ _______ ___ ___ ___ ___ ___ ___ ___ __idle
+\ | | | | | | | ^ | ^ | | | | | | | | | | | | | | | |
+\ v___| v___| v___| v_______| |___| v___| v___| v___| v___| v___| v___| v___| v___|
+\ I R R R R R R R R R R R R R
+\
+\ notice that each cycle contains its bit value followed by its complement
+
+
+
+
+\ principe of the driver : 13 samples at 1/4 period and Resynchronise (R) on 1/2 period (two examples)
+
+\ 0,888 ms
+\ |<->|<--------------------------------routine time = 12 3/4 cycles = 22.644 ms--------------------------->|
+\ | | | | | | | | | | | | | | | |
+\ | ST1 | ST2/C6| Toggle| A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | |C0 |
+\ | | | | | | | | | | | | | | | |
+\ 1 1 1 1 0 0 1 1 1 1 1 1 1 | 1
+\ idle_____ _s_ _s_ _s_ ___ _____s_ _s_ _s_ _s_ _s_ _s_ _s_ _s_ __idle
+\ | | | | | | | ^ | ^ | | | | | | | | | | | | | | | |
+\ v___| v___| v___| v_____s_| |_s_| v___| v___| v___| v___| v___| v___| v___| v___|
+\ S R R R R R R R R R R R R ^ ^
+\ samples : 1 2 3 4 5 6 4 8 9 10 11 12 13 | |
+\ | |
+\ I I
+\ 0,888 ms
+\ |<->|<--------------------------------routine time = 12 3/4 cycles = 22.644 ms--------------------------->|
+\ | | | | | | | | | | | | | | | |
+\ | ST1 | ST2/C6| Toggle| A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | |C0 |
+\ | | | | | | | | | | | | | | | |
+\ 1 1 1 1 0 0 1 1 1 1 1 1 1 | 1
+\ idle_____ _s_ _s_ ___ _o_ _o___s_ _s_ _s_ _s_ _s_ _s_ _s_ ______idle
+\ | | | | | | | ^ | ^ | | | | | | | | | | | | | ^
+\ v___| v_o_| v_o_| v_o___s_| |_s_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o___s_|
+\ S R R R R R R R R R R R R ^
+\ samples : 1 2 3 4 5 6 7 8 9 10 11 12 13|
+\ |
+\ I
+\ good ! but we have too many of RC5_Int...
+
+
+
+
+\ So, to avoid these RC5_Int after end : 13+1=14 samples, then the result is shifted one to right (two examples)
+
+\ 0,888 ms
+\ |<->|<--------------------------------routine time = 13 3/4 cycles = 24.447 ms----------------------------------->|
+\ | | | | | | | | | | | | | | | |
+\ | ST1 | ST2/C6| Toggle| A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | C0 | |
+\ | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | |
+\ | | | | | | | | | | | | | | | |
+\ idle_____ _s_ _s_ _s_ _o_ _o___s_ _s_ _s_ _s_ _s_ _s_ _s_ _s_ _s_idle
+\ | | | | | | | ^ | ^ | | | | | | | | | | | | | | | |
+\ v___| v_o_| v_o_| v_o___s_| |_s_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o_|
+\ S i R i R i R R i R R i R i R i R i R i R i R i R i
+\ samples : 1 2 3 4 5 6 7 8 9 10 11 12 13 14
+\
+\
+\ 0,888 ms
+\ |<->|<--------------------------------routine time = 13 3/4 cycles = 24.447 ms----------------------------------->|
+\ | | | | | | | | | | | | | | | |
+\ | ST1 | ST2/C6| Toggle| A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | C0 | |
+\ | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | |
+\ | | | | | | | | | | | | | | | |
+\ idle_____ _s_ _s_ ___ _o_ _o___s_ _s_ _s_ _s_ _s_ _s_ _s_ _o___s_idle
+\ | | | | | | | ^ | ^ | | | | | | | | | | | | | ^
+\ v___| v_o_| v_o_| v_o___s_| |_s_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o___s_|
+\ S i R i R i R R i R R i R i R i R i R i R i R R
+\ samples : 1 2 3 4 5 6 7 8 9 10 11 12 13 14
+
+
+\ S = Wake up on RC5_Int at 1/2 cycle : clear and start timer
+\ i = useless RC5_Int (not periodic) at 4/4 cycle
+\ s = sample RC5_intput at (1/2+3/4) = 5/4 cycle = 1/4 cycle+1 and clear useless RC5_Int
+\ R = usefull (periodic) RC5_Int at 6/4 cycle = 1/2 cycle+1 : cycle value = timer value then clear it and restart it
+\ o = RC5_Int time out at 7/4 cycle = 3/4 cycle+1, used to detect (samples<14) truncated RC5_message
+
+\ see also : http://www.sbprojects.com/knowledge/ir/rc5.php
+\ http://laurent.deschamps.free.fr/ir/rc5/rc5.htm
+\ Code RC5 : http://en.wikipedia.org/wiki/RC-5
+
+
+\ ---------------------------------------------------------------------------------------------------------------------\
+\ SCL clock generation, timing, and test of data(s) number are made by I2C_Master.
+\ slave can strech SCL low after Start Condition and after any bit.
+\
+\ address Ack/Nack is generated by the slave on SDA line (released by the master)
+\ Two groups of eight addresses (000xxxy and 1111xxxy) are not allowed (reserved)
+\ after address or data is sent, the transmitter (Master or Slave) must release SDA line to allow (N)Ack by the receiver
+\ data Ack/Nack are generated by the receiver (master or slave) on SDA line
+\ a master receiver must signal the end of data to the slave transmitter by sending a Nack bit
+\ Stop or restart conditions must be generated by master after a Nack bit.
+\ after Ack bit is sent, Slave must release SDA line to allow master to do stop or restart conditions.
+\
+\
+\ first byte = address + R/W flag | byte data (one, for example)
+\ __ _____ _____ _..._ _____ __R__ _NAK_ _____ _____ _..._ _____ _____ _NAK_ _
+\ SDA \____/_MSB_R9_____R9_..._R9_LSB_R9__R10__x_ACK_x_MSB_R9_____R9_..._R9_____R9_LSB_R9_ACK_R9___/
+\ _____ _ _ _ _ _ _ _ _ _ _ ___
+\ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/
+\ ^ ^ ^ ^ ^ ^ ^
+\ | |SSL |SSL |SSL |SSL |SSL |
+\ | |
+\ |Start Condition |stoP Condition
+\
+\ first byte = address + R/W flag | byte data (one, for example)
+\ __ _____ _____ _..._ _____ __R__ _NAK_ _____ _____ _..._ _____ _____ _NAK_ ___
+\ SDA \____/_MSB_R9_____R9_..._R9_LSB_R9__R10__x_ACK_x_MSB_R9_____R9_..._R9_____R9_LSB_R9_ACK_R9 \____...
+\ _____ _ _ _ _ _ _ _ _ _ _ ____
+\ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/ \_...
+\ ^ ^ ^ ^ ^ ^ ^
+\ | |SSL |SSL |SSL |SSL |SSL |
+\ | |
+\ |Start Condition |reStart Condition
+\
+\ SSL : Slave can strech SCL low
+\ tHIGH : SCL high time
+\ tLOW : SCL low time
+\ tBUF : SDA high time between Stop and Start conditions
+\ tHD:STA : Start_Condition SCL high time after SDA is low
+\ tSU:STO : Stop_Condition SCL high time before SDA rise
+\ tSU:STA : Start_Condition SCL high time before SDA fall
+\ tHD:DAT : SDA data change time after SCL is low
+\ the SDA line must be strobe just after SCL is high
+\ the SDA data must be change just after SCL is low
+\ standard mode (up to 100 kHz) : tHIGH = tHD:STA = tSU:STO = 4µs
+\ tLOW = tSU:STA = tBUF = 4,7µs
+\ tHD:DAT <= 3,45 µs
+\ -------------------------------------------------------------------------------------------------------------------\
+
--- /dev/null
+\ ------------------------------
+\ MSP430FR5xxx_LCD_20.f
+\ ------------------------------
+RST_STATE
+\ NOECHO
+\ Copyright (C) <2014> <J.M. THOORENS>
+\
+\ This program is free software: you can redistribute it and/or modify
+\ it under the terms of the GNU General Public License as published by
+\ the Free Software Foundation, either version 3 of the License, or
+\ (at your option) any later version.
+\
+\ This program is distributed in the hope that it will be useful,
+\ but WITHOUT ANY WARRANTY\ without even the implied warranty of
+\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+\ GNU General Public License for more details.
+\
+\ You should have received a copy of the GNU General Public License
+\ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+
+\ driver for LCD 2x20 characters display with 4 bits data interface
+\ without usage of an auxiliary 5V to feed the Vo of LCD
+\ without potentiometer to adjust the LCD contrast
+\ LCD contrast software adjustable by 2 switches
+\ TB0.2 current consumption ~ 500 uA
+
+\ layout : see config.pat file for defining I/O
+
+\ GND <-------+---0V0----------> 1 LCD_Vss
+\ VCC >------ | --3V6-----+----> 2 LCD_Vdd
+\ | |
+\ |___ 470n ---
+\ ^ | ---
+\ / \ BAT54 |
+\ --- |
+\ 100n | 2k2 |
+\ TB0.2 >---||--+--^/\/\/v--+----> 3 LCD_Vo (=0V6 without modulation)
+\ -------------------------> 4 LCD_RW
+\ -------------------------> 5 LCD_RW
+\ -------------------------> 6 LCD_EN
+\ <------------------------> 11 LCD_DB4
+\ <------------------------> 12 LCD_DB5
+\ <------------------------> 13 LCD_DB5
+\ <------------------------> 14 LCD_DB7
+
+\ Sw1 <--- LCD contrast + (finger :-)
+\ Sw2 <--- LCD contrast - (finger \-)
+
+
+
+\ ------------------------------\
+CODE 20_us \ n -- n * 20 us
+\ ------------------------------\
+BEGIN \ 3 cycles loop + 6~
+\ MOV #5,W \ 3 MCLK = 1 MHz
+\ MOV #23,W \ 3 MCLK = 4 MHz
+ MOV #51,W \ 3 MCLK = 8 MHz
+\ MOV #104,W \ 3 MCLK = 16 MHz
+\ MOV #158,W \ 3 MCLK = 24 MHz
+ BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
+ SUB #1,W \ 1
+ 0= UNTIL \ 2
+ SUB #1,TOS \ 1
+0= UNTIL \ 2
+ MOV @PSP+,TOS \ 2
+ MOV @IP+,PC \ 4
+ENDCODE
+ \
+
+\ ------------------------------\
+CODE TOP_LCD \ LCD Sample
+\ ------------------------------\ if write : %xxxxWWWW --
+\ \ if read : -- %0000RRRR
+ BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
+ BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
+0= IF \ write LCD bits pattern
+ AND #LCD_DB,TOS \
+ MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV @PSP+,TOS \
+ MOV @IP+,PC
+THEN \ read LCD bits pattern
+ SUB #2,PSP
+ MOV TOS,0(PSP)
+ BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
+ MOV.B &LCD_DB_IN,TOS \ get LCD_Data
+ AND.B #LCD_DB,TOS \
+ MOV @IP+,PC
+ENDCODE
+ \
+
+\ ------------------------------\
+CODE LCD_W \ byte -- write byte
+\ ------------------------------\
+ SUB #2,PSP \
+ MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
+ RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
+ BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
+ BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
+ COLON
+ TOP_LCD 2 20_us \ write high nibble first
+ TOP_LCD 2 20_us ;
+ \
+
+\ ------------------------------\
+CODE LCD_R \ -- byte read byte
+\ ------------------------------\
+ BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
+ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
+ COLON
+ TOP_LCD 2 20_us \ read high nibble first
+ TOP_LCD 2 20_us
+ HI2LO \ -- %0000HHHH %0000LLLL
+ MOV @RSP+,IP
+ MOV @PSP+,W \ W = high nibble
+ RLAM #4,W \ -- %0000LLLL W = %HHHH0000
+ ADD.B W,TOS
+ MOV @IP+,PC
+ENDCODE
+ \
+\ ------------------------------\
+CODE LCD_WrF \ func -- Write Fonction
+\ ------------------------------\
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_W
+ENDCODE
+ \
+\ ------------------------------\
+CODE LCD_RdS \ -- status Read Status
+\ ------------------------------\
+ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
+ JMP LCD_R
+ENDCODE
+ \
+\ ------------------------------\
+CODE LCD_WrC \ char -- Write Char
+\ ------------------------------\
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_W
+ENDCODE
+ \
+\ ------------------------------\
+CODE LCD_RdC \ -- char Read Char
+\ ------------------------------\
+ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
+ JMP LCD_R
+ENDCODE
+ \
+\ ------------------------------\
+\ : LCD_Clear $01 LCD_WrF 80 20_us ; \ bad init !
+: LCD_Clear $01 LCD_WrF 100 20_us ;
+ \
+\ ------------------------------\
+: LCD_Home $02 LCD_WrF 80 20_us ;
+ \
+\ ------------------------------\
+\ : LCD_Entry_set $04 OR LCD_WrF ;
+\ : LCD_Display_Ctrl $08 OR LCD_WrF ;
+\ : LCD_Display_Shift $10 OR LCD_WrF ;
+\ : LCD_Fn_Set $20 OR LCD_WrF ;
+\ : LCD_CGRAM_Set $40 OR LCD_WrF ;
+\ : LCD_Goto $80 OR LCD_WrF ;
+
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+\ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
+\ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
+\ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
+\ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
+\ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
+\ -------------+------+------+------+------++---+---+---+---+---------+
+
+\ ******************************\
+ASM WDT_Int \ Watchdog interrupt routine, warning : not FORTH executable !
+\ ******************************\
+BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+BIT.B #SW2,&SW2_IN \ test switch S2
+0= IF \ case of switch S2 pressed
+ CMP #34,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
+ U< IF
+ ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
+ THEN
+ELSE
+ BIT.B #SW1,&SW1_IN \ test switch S1 input
+ 0= IF \ case of Switch S1 pressed
+ CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
+ U>= IF \
+ SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
+ THEN \
+ THEN \
+THEN \
+RETI \ CPU is ON, GIE is OFF
+ENDASM \
+ \
+
+
+\ ------------------------------\
+CODE START \
+\ ------------------------------\
+\ TB0CTL = %0000 0010 1001 0100\$3C0
+\ - - \CNTL Counter lentgh \ 00 = 16 bits
+\ -- \TBSSEL TimerB clock select \ 10 = SMCLK
+\ -- \ID input divider \ 10 = /4
+\ -- \MC Mode Control \ 01 = up mode
+\ - \TBCLR TimerB Clear
+\ - \TBIE
+\ -\TBIFG
+\ --------------------------------\\
+\ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
+\ -- \CM Capture Mode
+\ -- \CCIS
+\ - \SCS
+\ -- \CLLD
+\ - \CAP
+\ --- \OUTMOD \ 011 = set/reset
+\ - \CCIE
+\ - \CCI
+\ - \OUT
+\ - \COV
+\ -\CCIFG
+\ TB0CCRx \$3D{2,4,6,8,A,C,E}
+\ TB0EX0 \$3E0
+\ ------------------------------\
+\ set TimerB to make 50kHz PWM \
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
+\ ------------------------------\
+\ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
+\ ------------------------------\
+ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
+\ ------------------------------\
+\ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
+\ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
+\ ------------------------------\
+ MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
+\ ------------------------------\
+\ set TimerB to generate LCD_V0 via TB0.2 and P1.5/P2.2
+\ ------------------------------\
+ MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
+\ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
+ MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
+\ ------------------------------\
+\ ------------------------------\
+\ WDT interval init part \
+\ ------------------------------\
+\ MOV #$5A5E,&WDTCTL \ init WDT Vloclk source 10kHz /2^9 (50 ms), interval mode
+ MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
+\ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
+ BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
+\ ------------------------------\
+\ init interrupt vectors
+\ ------------------------------\
+ MOV #WDT_Int,&WDT_Vec \ init WDT interval vector interrupt
+\ ------------------------------\
+\ init PORTA (P2:P1) (complement)
+ BIS.B #LCDVo,&LCDVo_DIR \
+ BIS.B #LCDVo,&LCDVo_SEL0 \ SEL0.2 TB0.2
+\ ------------------------------\
+\ init PORTB (P4:P3) (complement)
+ BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
+ BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
+\ ------------------------------\
+\ init PORTJ (PJ) (complement)
+ BIS.B #LCD_DB,&LCD_DB_DIR \ PJDIR.(0-3) as output, wired to DB(4-7) LCD_Data
+ BIC.B #LCD_DB,&LCD_DB_REN \ PJREN.(0-3) LCD_Data pullup/down disable
+\ ------------------------------\
+\ define LPM mode for ACCEPT \
+\ ------------------------------\
+\ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
+\ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
+\ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
+\ ------------------------------\
+\ Init LCD
+ LO2HI
+ $3E8 20_us \ 1- wait 20 ms
+ $03 TOP_LCD \ 2- send DB5=DB4=1
+ $CD 20_us \ 3- wait 4,1 ms
+ $03 TOP_LCD \ 4- send again DB5=DB4=1
+ 5 20_us \ 5- wait 0,1 ms
+ $03 TOP_LCD \ 6- send again again DB5=DB4=1
+ 2 20_us \ wait 40 us = LCD cycle
+ $02 TOP_LCD \ 7- send DB5=1 DB4=0
+ 2 20_us \ wait 40 us = LCD cycle
+ $28 LCD_WrF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
+ $08 LCD_WrF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
+ LCD_Clear \ 10- "LCD_Clear"
+ $06 LCD_WrF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
+ $0C LCD_WrF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
+ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
+ ['] LCD_WrC IS EMIT \ ' EMIT redirected to LCD_WrC
+ CR ." I love you"
+ ['] (CR) IS CR \ ' (CR) is CR
+ ['] (EMIT) IS EMIT \ ' (EMIT) is EMIT
+ ." xxxx_to_LCD is running. Type STOP to quit"
+ LIT recurse is WARM \ insert this starting routine between COLD and WARM...
+\ NOECHO \ uncomment to run this app without terminal connexion
+ (WARM) ; \ ...and continue with WARM
+ \
+
+: STOP \ stops multitasking, must to be used before downloading app
+ ['] (WARM) IS WARM \ remove START app from FORTH init process
+ ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
+;
+ \
+
+PWR_HERE \ set here the power_on dictionnary
--- /dev/null
+you have downloaded your copy of gitlab fast forth onto a folder shared and connected as virtual drive (A: or B: or ... or Y: or Z:)
+ so config files.pat for the preprocessor gema.exe are in the folder \config\gema\
+ and batch file are in the folder \config\scite\msp430_as\,
+you have installed the last version of teraterm,
+you have installed the last version of gema.exe in the folder \prog\gema\.
+
+finally, edit properties of these three shortcuts "send_file.f_to_target.bat", "send_file.4th_to_target.bat file" and
+process_file.f_to_file.4th.bat to change the drive letter B: as yours.
+
+before sending a file :
+=====================
+ teraterm must be well configured, and its config must be saved,
+ i.e. you must see the FAST FORTH prompt "ok" when you type <return> on the teraterm terminal. (you can then close the teraterm window).
+
+
+to send a file.f to a specific target :
+=====================================
+ 1 clic on the what_you_want.f file example : utility.f
+ 2 ctrl+clic on the what_you_want.pat file example : MSP_EXP430FR5969.pat (target = MSP_EXP430FR5969 launchpad)
+ 3 release ctrl and clic
+ 4 then drag and drop the what_you_want.f file onto the send_file.f_to_target.bat file
+ - -
+the *.pat files are used by the preprocesor GEMA.exe to translate symbolic labels from *.f files in their values to *.4th files.
+
+to send a file.4th to any target :
+================================
+ drag and drop the what_you_want.4th file onto the send_file.4th_to_target.bat file example : coretest.4th
+ --- ---
+
+to preprocess file.f to file.4th (debug) :
+========================================
+do same as to send a file.f, but with process_file.f_to_file.4th.bat
+
+
+To send a file to be written on SD_CARD target, process with the specific SD_CARD_target.bat.
+When TERATERM ask you for file to send, you can add a path to the file to be written on SD_CARD.
+
+
+
+
+As these bat files are in fact shortcuts, you can define them to execute with hidden window.
+
+
+
--- /dev/null
+\prog\MSP430Flasher\msp430flasher -m SBW2 -n MSP430fr2433 -v -w %1 -z [VCC=3000]
+exit
+
+tip : how to calculate MAIN program lenght ?
+
+open the prog.txt file with your editor, select MAIN section
+in status bar, keep the number of selected chars
+if lines are ended with CR+LF, substract the number of lines selected
+then divide by 3.
--- /dev/null
+; MSP430fr2x4x.inc : MSP430FR2xxx and MSP430FR4xxx declarations
+
+
+ .IF DEVICE = "MSP430FR2433"
+
+; ----------------------------------------------------------------------
+; MSP430FR2433 Peripheral File Map
+; ----------------------------------------------------------------------
+SFR_SFR .equ 0100h ; Special function
+PMM_SFR .equ 0120h ; PMM
+SYS_SFR .equ 0140h ; SYS
+CS_SFR .equ 0180h ; Clock System
+FRAM_SFR .equ 01A0h ; FRAM control
+CRC16_SFR .equ 01C0h
+WDT_A_SFR .equ 01CCh ; Watchdog
+PA_SFR .equ 0200h ; PORT1/2
+PB_SFR .equ 0220h ; PORT3
+RTC_SFR .equ 0300h
+TA0_SFR .equ 0380h
+TA1_SFR .equ 03C0h
+TA2_SFR .equ 0400h
+TA3_SFR .equ 0440h
+MPY_SFR .equ 04C0h
+eUSCI_A0_SFR .equ 0500h ; eUSCI_A0
+eUSCI_A1_SFR .equ 0520h ; eUSCI_A1
+eUSCI_B0_SFR .equ 0540h ; eUSCI_B0
+BACK_MEM_SFR .equ 0660h
+ADC10_B_SFR .equ 0700h
+
+
+; ----------------------------------------------
+; MSP430FR2433 MEMORY MAP
+; ----------------------------------------------
+; 0000-0FFF = peripherals (4 KB)
+; 1000-17FF = ROM bootstrap loader BSL1 (2k)
+; 1800-19FF = info B (FRAM 512 B)
+; 1A00-1A7F = TLV device descriptor info (FRAM 128 B)
+; 1A80-1FFF = unused
+; 2000-2FFF = RAM (4 KB)
+; 2800-C3FF = unused
+; C400-FF7F = code memory (FRAM 15232 B)
+; FF80-FFFF = interrupt vectors (FRAM 128 B)
+; FFC00-FFFFF = BSL2 (2k)
+; ----------------------------------------------
+PAGESIZE .equ 512 ; MPU unit
+; ----------------------------------------------
+; BSL
+; ----------------------------------------------
+BSL1 .equ 01000h
+BSL2 .equ 0FFC00h
+; ----------------------------------------------
+; FRAM ; INFO B, TLV
+; ----------------------------------------------
+INFOSTART .equ 01800h
+INFOBSTART .equ 01800h
+INFOBEND .equ 019FFh
+INFOEND .equ 019FFh
+TLVSTART .equ 01A00h ; Device Descriptor Info (Tag-Lenght-Value)
+TLVEND .equ 01A7Fh ;
+; ----------------------------------------------
+; RAM
+; ----------------------------------------------
+RAMSTART .equ 02000h
+RAMEND .equ 02FFFh
+; ----------------------------------------------
+; FRAM
+; ----------------------------------------------
+PROGRAMSTART .equ 0C400h ; Code space start
+SIGNATURES .equ 0FF80h ; JTAG/BSL signatures
+JTAG_SIG1 .equ 0FF80h ; if 0 (electronic fuse=0) enable JTAG/SBW ; reset by wipe and by S1+<reset>
+JTAG_SIG2 .equ 0FF82h ; if JTAG_SIG <> |0xFFFFFFFF, 0x00000000|, SBW and JTAG are locked
+BSL_SIG1 .equ 0FF84h ;
+BSL_SIG2 .equ 0FF86h ;
+JTAG_PASSWORD .equ 0FF88h ; 256 bits
+INTVECT .equ 0FFDAh ; FFDA-FFFF
+BSL_PASSWORD .equ 0FFE0h ; 256 bits
+; ----------------------------------------------
+
+; ----------------------------------------------
+; Interrupt Vectors and signatures - MSP430FR243x
+; ----------------------------------------------
+
+; .org SIGNATURES
+;;Start of JTAG and BSL signatures
+; .word 0 ; JTAG signature 1
+; .word 0 ; JTAG signature 2
+; .word 0 ; BSL signature 1
+; .word 0 ; BSL signature 2
+
+ .org INTVECT ; FFDA-FFFF 18 vectors + reset
+
+ .word reset ; FFDAh - P2
+ .word reset ; FFDCh - P1
+ .word reset ; FFDEh - ADC10
+ .word reset ; FFE0h - eUSCI_B0
+ .word reset ; FFE2h - eUSCI_A1
+TERMVEC .word TERMINAL_INT ; FFE4h - eUSCI_A0
+ .word reset ; FFE6h - WDT
+ .word reset ; FFE8h - RTC
+ .word reset ; FFEAh - TA3_x
+ .word reset ; FFECh - TA3_0
+ .word reset ; FFEEh - TA2_x
+ .word reset ; FFF0h - TA2_0
+ .word reset ; FFF2h - TA1_x
+ .word reset ; FFF4h - TA1_0
+ .word reset ; FFF6h - TA0_x
+ .word reset ; FFF8h - TA0_0
+ .word reset ; FFFAh - UserNMI
+ .word reset ; FFFCh - SysNMI
+RST_ADR .word reset ; FFFEh - Reset
+
+; ----------------------------------------------------------------------
+; MPY_32
+; ----------------------------------------------------------------------
+
+MPY .equ MPY_SFR + 00h ; Multiply16 Unsigned/Operand 1 */
+MPYS .equ MPY_SFR + 02h ; Multiply16 signed/Operand 1
+MAC .equ MPY_SFR + 04h ; MultiplyAccumulate16 Unsigned/Operand 1 */
+MACS .equ MPY_SFR + 06h ; MultiplyAccumulate16 signed/Operand 1
+OP2 .equ MPY_SFR + 08h ; Operand2_16 */
+RESLO .equ MPY_SFR + 0Ah ; 16x16-bit result low - least significant word */
+RESHI .equ MPY_SFR + 0Ch ; 16x16-bit result high */
+SUMEXT .equ MPY_SFR + 0Eh ; 16x16-bit sum extension register
+MPY32L .equ MPY_SFR + 10h ; Multiply32 Unsigned/Operand 1
+MPY32H .equ MPY_SFR + 12h ; Multiply32 Unsigned/Operand 1
+MPYS32L .equ MPY_SFR + 14h ; Multiply32 signed/Operand 1
+MPYS32H .equ MPY_SFR + 16h ; Multiply32 signed/Operand 1
+MAC32L .equ MPY_SFR + 18h ; MultiplyAccumulate32 Unsigned/Operand 1
+MAC32H .equ MPY_SFR + 1Ah ; MultiplyAccumulate32 Unsigned/Operand 1
+MACS32L .equ MPY_SFR + 1Ch ; MultiplyAccumulate32 signed/Operand 1
+MACS32H .equ MPY_SFR + 1Eh ; MultiplyAccumulate32 signed/Operand 1
+OP2L .equ MPY_SFR + 20h ; Multiply32 Operand 2
+OP2H .equ MPY_SFR + 22h ; Multiply32 Operand 2
+RES0 .equ MPY_SFR + 24h ; 32x32-bit result 0 - least significant word */
+RES1 .equ MPY_SFR + 26h ; 32x32-bit result 1 */
+RES2 .equ MPY_SFR + 28h ; 32x32-bit result 2 */
+RES3 .equ MPY_SFR + 2Ah ; 32x32-bit result 3 */
+MPY32CTL0 .equ MPY_SFR + 2Ch ; MPY32 control register 0
+
+
+ .ENDIF ; MSP430FR2433
+
+
+
+ .IF DEVICE = "MSP430FR4133"
+
+; ----------------------------------------------------------------------
+; EXP430FR4133 Peripheral File Map
+; ----------------------------------------------------------------------
+SFR_SFR .set 0100h ; Special function
+PMM_SFR .set 0120h ; PMM
+SYS_SFR .set 0140h ; SYS
+CS_SFR .set 0180h ; Clock System
+FRAM_SFR .set 01A0h ; FRAM control
+CRC16_SFR .set 01C0h
+WDT_A_SFR .set 01CCh ; Watchdog
+PA_SFR .set 0200h ; PORT1/2
+PB_SFR .set 0220h ; PORT3/4
+PC_SFR .set 0240h ; PORT5/6
+PD_SFR .set 0260h ; PORT7/8
+CTIO0_SFR .set 02E0h ; Capacitive Touch IO
+TA0_SFR .set 0300h
+TA1_SFR .set 0340h
+RTC_SFR .set 03C0h
+eUSCI_A0_SFR .set 0500h ; eUSCI_A0
+eUSCI_B0_SFR .set 0540h ; eUSCI_B0
+LCD_SFR .set 0600h
+BACK_MEM_SFR .set 0660h
+ADC10_B_SFR .equ 0700h
+
+; ----------------------------------------------
+; MSP430FR4133 MEMORY MAP
+; ----------------------------------------------
+; 0000-0FFF = peripherals (4 KB)
+; 1000-17FF = ROM bootstrap loader BSL0..3 (4x512 B)
+; 1800-19FF = info B (FRAM 512 B)
+; 1A00-1A7F = TLV device descriptor info (FRAM 128 B)
+; 1A80-1FFF = unused
+; 2000-27FF = RAM (2 KB)
+; 2800-C3FF = unused
+; C400-FF7F = code memory (FRAM 15232 B)
+; FF80-FFFF = interrupt vectors (FRAM 128 B)
+; ----------------------------------------------
+PAGESIZE .equ 512 ; MPU unit
+; ----------------------------------------------
+; FRAM ; INFO B, TLV
+; ----------------------------------------------
+INFOSTART .equ 01800h
+INFOBSTART .equ 01800h
+INFOBEND .equ 019FFh
+INFOEND .equ 019FFh
+TLVSTART .equ 01A00h ; Device Descriptor Info (Tag-Lenght-Value)
+TLVEND .equ 01A7Fh ;
+; ----------------------------------------------
+; RAM
+; ----------------------------------------------
+RAMSTART .equ 02000h
+RAMEND .equ 027FFh
+; ----------------------------------------------
+; FRAM
+; ----------------------------------------------
+PROGRAMSTART .equ 0C400h ; Code space start
+SIGNATURES .equ 0FF80h ; JTAG/BSL signatures
+JTAG_SIG1 .equ 0FF80h ; if 0 (electronic fuse=0) enable JTAG/SBW ; reset by wipe and by S1+<reset>
+JTAG_SIG2 .equ 0FF82h ; if JTAG_SIG <> |0xFFFFFFFF, 0x00000000|, SBW and JTAG are locked
+BSL_SIG1 .equ 0FF84h ;
+BSL_SIG2 .equ 0FF86h ;
+JTAG_PASSWORD .equ 0FF88h ; 256 bits
+INTVECT .equ 0FFE2h ; FFE2-FFFF
+BSL_PASSWORD .equ 0FFE0h ; 256 bits
+; ----------------------------------------------
+; ----------------------------------------------
+; Interrupt Vectors and signatures - MSP430FR4133
+; ----------------------------------------------
+
+; .org SIGNATURES
+;;Start of JTAG and BSL signatures
+; .word 0 ; JTAG signature 1
+; .word 0 ; JTAG signature 2
+; .word 0 ; BSL signature 1
+; .word 0 ; BSL signature 2
+
+ .org INTVECT ; FFE2-FFFF 14 vectors + reset
+
+ .word reset ; FFE2h - LCD
+ .word reset ; FFE4h - P2
+ .word reset ; FFE6h - P1
+ .word reset ; FFE8h - ADC10
+ .word reset ; FFEAh - eUSCI_B0
+TERMVEC .word TERMINAL_INT ; FFECh - eUSCI_A0
+ .word reset ; FFEEh - WDT
+ .word reset ; FFF0h - RTC
+ .word reset ; FFF2h - TA1_x
+ .word reset ; FFF4h - TA1_0
+ .word reset ; FFF6h - TA0_x
+ .word reset ; FFF8h - TA0_0
+ .word reset ; FFFAh - UserNMI
+ .word reset ; FFFCh - SysNMI
+RST_ADR .word reset ; FFFEh - Reset
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT3/4
+; ----------------------------------------------------------------------
+; PB = P4:P3
+
+PBIN .set PB_SFR + 00h ; Port B Input
+PBOUT .set PB_SFR + 02h ; Port B Output 1/0 or pullup/pulldown resistor
+PBDIR .set PB_SFR + 04h ; Port B Direction
+PBREN .set PB_SFR + 06h ; Port B Resistor Enable
+PBSEL0 .set PB_SFR + 0Ah ; Port B Selection 0
+PBSEL1 .set PB_SFR + 0Ch ; Port B Selection 1
+PBSELC .set PB_SFR + 16h ; Port B Complement Selection
+
+P4IN .set PB_SFR + 01h ; Port 4 Input */
+P4OUT .set PB_SFR + 03h ; Port 4 Output
+P4DIR .set PB_SFR + 05h ; Port 4 Direction
+P4REN .set PB_SFR + 07h ; Port 4 Resistor Enable
+P4SEL0 .set PB_SFR + 0Bh ; Port 4 Selection 0
+P4SEL1 .set PB_SFR + 0Dh ; Port 4 Selection 1
+P4SELC .set PB_SFR + 17h ; Port 4 Complement Selection
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT5/6
+; ----------------------------------------------------------------------
+; PC = P6:P5
+
+PCIN .set PC_SFR + 00h ; Port C Input
+PCOUT .set PC_SFR + 02h ; Port C Output 1/0 or pullup/pulldown resistor
+PCDIR .set PC_SFR + 04h ; Port C Direction
+PCREN .set PC_SFR + 06h ; Port C Resistor Enable
+PCSEL0 .set PC_SFR + 0Ah ; Port C Selection 0
+PCSEL1 .set PC_SFR + 0Ch ; Port C Selection 1
+PCSELC .set PC_SFR + 16h ; Port C Complement Selection
+
+P5IN .set PC_SFR + 00h ; Port 5 Input */
+P5OUT .set PC_SFR + 02h ; Port 5 Output
+P5DIR .set PC_SFR + 04h ; Port 5 Direction
+P5REN .set PC_SFR + 06h ; Port 5 Resistor Enable
+P5SEL0 .set PC_SFR + 0Ah ; Port 5 Selection 0
+P5SEL1 .set PC_SFR + 0Ch ; Port 5 Selection 1
+P5SELC .set PC_SFR + 16h ; Port 5 Complement Selection
+
+P6IN .set PC_SFR + 01h ; Port 6 Input */
+P6OUT .set PC_SFR + 03h ; Port 6 Output
+P6DIR .set PC_SFR + 05h ; Port 6 Direction
+P6REN .set PC_SFR + 07h ; Port 6 Resistor Enable
+P6SEL0 .set PC_SFR + 0Bh ; Port 6 Selection 0
+P6SEL1 .set PC_SFR + 0Dh ; Port 6 Selection 1
+P6SELC .set PC_SFR + 17h ; Port 6 Complement Selection
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT7/8
+; ----------------------------------------------------------------------
+; PD = P8:P7
+
+PDIN .set PD_SFR + 00h ; Port D Input
+PDOUT .set PD_SFR + 02h ; Port D Output 1/0 or pullup/pulldown resistor
+PDDIR .set PD_SFR + 04h ; Port D Direction
+PDREN .set PD_SFR + 06h ; Port D Resistor Enable
+PDSEL0 .set PD_SFR + 0Ah ; Port D Selection 0
+PDSEL1 .set PD_SFR + 0Ch ; Port D Selection 1
+PDSELC .set PD_SFR + 16h ; Port D Complement Selection
+
+P7IN .set PD_SFR + 00h ; Port 7 Input */
+P7OUT .set PD_SFR + 02h ; Port 7 Output
+P7DIR .set PD_SFR + 04h ; Port 7 Direction
+P7REN .set PD_SFR + 06h ; Port 7 Resistor Enable
+P7SEL0 .set PD_SFR + 0Ah ; Port 7 Selection 0
+P7SEL1 .set PD_SFR + 0Ch ; Port 7 Selection 1
+P7SELC .set PD_SFR + 16h ; Port 7 Complement Selection
+
+P8IN .set PD_SFR + 01h ; Port 8 Input */
+P8OUT .set PD_SFR + 03h ; Port 8 Output
+P8DIR .set PD_SFR + 05h ; Port 8 Direction
+P8REN .set PD_SFR + 07h ; Port 8 Resistor Enable
+P8SEL0 .set PD_SFR + 0Bh ; Port 8 Selection 0
+P8SEL1 .set PD_SFR + 0Dh ; Port 8 Selection 1
+P8SELC .set PD_SFR + 17h ; Port 8 Complement Selection
+
+ .ENDIF ; MSP_EXP430FR4133
+
+
+
+;=======================================================================
+; COMMON PARTS
+;=======================================================================
+
+UCSWRST .equ 1 ; eUSCI Software Reset
+UCTXIE .equ 2 ; eUSCI Transmit Interrupt Enable
+UCRXIE .equ 1 ; eUSCI Receive Interrupt Enable
+UCTXIFG .equ 2 ; eUSCI Transmit Interrupt Flag
+UCRXIFG .equ 1 ; eUSCI Receive Interrupt Flag
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : LOCK PMM_LOCKLPM5
+; ----------------------------------------------------------------------
+PMMCTL0 .equ PMM_SFR
+PMMSWBOR .equ 4
+
+PM5CTL0 .equ PMM_SFR + 10h ; Power mode 5 control register 0
+LOCKLPM5 .equ 1 ; bit position
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : WATCHDOG TIMER A
+; ----------------------------------------------------------------------
+
+WDTCTL .equ WDT_A_SFR + 00h ; Watchdog Timer Control */
+
+; WDTCTL Control Bits
+WDTPW .equ 5A00h
+WDTHOLD .equ 0080h ; WDT - Timer hold
+WDTCNTCL .equ 0008h ; WDT timer counter clear
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT1/2
+; ----------------------------------------------------------------------
+
+PAIN .equ PA_SFR + 00h ; Port A Input
+PAOUT .equ PA_SFR + 02h ; Port A Output
+PADIR .equ PA_SFR + 04h ; Port A Direction
+PAREN .equ PA_SFR + 06h ; Port A Resistor Enable
+PASEL0 .equ PA_SFR + 0Ah ; Port A Selection 0
+PASEL1 .equ PA_SFR + 0Ch ; Port A Selection 1
+PASELC .equ PA_SFR + 16h ; Port A Complement Selection
+PAIES .equ PA_SFR + 18h ; Port A Interrupt Edge Select
+PAIE .equ PA_SFR + 1Ah ; Port A Interrupt Enable
+PAIFG .equ PA_SFR + 1Ch ; Port A Interrupt Flag
+
+P1IN .equ PA_SFR + 00h ; Port 1 Input
+P1OUT .equ PA_SFR + 02h ; Port 1 Output
+P1DIR .equ PA_SFR + 04h ; Port 1 Direction
+P1REN .equ PA_SFR + 06h ; Port 1 Resistor Enable
+P1SEL0 .equ PA_SFR + 0Ah ; Port 1 Selection 0
+P1SEL1 .equ PA_SFR + 0Ch ; Port 1 Selection 1
+P1IV .equ PA_SFR + 0Eh ; Port 1 Interrupt Vector word
+P1IES .equ PA_SFR + 18h ; Port 1 Interrupt Edge Select
+P1IE .equ PA_SFR + 1Ah ; Port 1 Interrupt Enable
+P1IFG .equ PA_SFR + 1Ch ; Port 1 Interrupt Flag
+
+P2IN .equ PA_SFR + 01h ; Port 2 Input
+P2OUT .equ PA_SFR + 03h ; Port 2 Output
+P2DIR .equ PA_SFR + 05h ; Port 2 Direction
+P2REN .equ PA_SFR + 07h ; Port 2 Resistor Enable
+P2SEL0 .equ PA_SFR + 0Bh ; Port 2 Selection 0
+P2SEL1 .equ PA_SFR + 0Dh ; Port 2 Selection 1
+P2IES .equ PA_SFR + 19h ; Port 2 Interrupt Edge Select
+P2IE .equ PA_SFR + 1Bh ; Port 2 Interrupt Enable
+P2IFG .equ PA_SFR + 1Dh ; Port 2 Interrupt Flag
+P2IV .equ PA_SFR + 1Eh ; Port 2 Interrupt Vector word
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT3
+; ----------------------------------------------------------------------
+
+P3IN .equ PB_SFR + 00h ; Port 3 Input */
+P3OUT .equ PB_SFR + 02h ; Port 3 Output
+P3DIR .equ PB_SFR + 04h ; Port 3 Direction
+P3REN .equ PB_SFR + 06h ; Port 3 Resistor Enable
+P3SEL0 .equ PB_SFR + 0Ah ; Port 3 Selection 0
+P3SEL1 .equ PB_SFR + 0Ch ; Port 3 Selection 1
+
+; ----------------------------------------------------------------------
+; FRAM config
+; ----------------------------------------------------------------------
+
+FRCTL0 .equ FRAM_SFR + 00h ; FRAM Controller Control 0
+FRCTL0_H .equ FRAM_SFR + 01h ; FRAM Controller Control 0 high byte
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : CLOCK SYSTEM
+; ----------------------------------------------------------------------
+
+CSCTL0 .equ CS_SFR + 00h ; Clock System Control Register 0
+CSCTL1 .equ CS_SFR + 02h ; Clock System Control Register 1
+CSCTL2 .equ CS_SFR + 04h ; Clock System Control Register 2
+CSCTL3 .equ CS_SFR + 06h ; Clock System Control Register 3
+CSCTL4 .equ CS_SFR + 08h ; Clock System Control Register 4
+CSCTL5 .equ CS_SFR + 0Ah ; Clock System Control Register 5
+CSCTL6 .equ CS_SFR + 0Ch ; Clock System Control Register 6
+CSCTL7 .equ CS_SFR + 0Eh ; Clock System Control Register 7
+CSCTL8 .equ CS_SFR + 10h ; Clock System Control Register 8
+
+
+
+; ----------------------------------------------------------------------
+; eUSCI_A0
+; ----------------------------------------------------------------------
+
+ .IFDEF UCA0_UART
+TERMCTLW0 .equ eUSCI_A0_SFR + 00h ; eUSCI_A0 Control Word Register 0
+TERMBRW .equ eUSCI_A0_SFR + 06h ; eUSCI_A0 Baud Word Rate 0
+TERMMCTLW .equ eUSCI_A0_SFR + 08h ; eUSCI_A0 Modulation Control
+TERMRXBUF .equ eUSCI_A0_SFR + 0Ch ; eUSCI_A0 Receive Buffer
+TERMTXBUF .equ eUSCI_A0_SFR + 0Eh ; eUSCI_A0 Transmit Buffer
+TERMIE .equ eUSCI_A0_SFR + 1Ah ; eUSCI_A0 Interrupt Enable Register
+TERMIFG .equ eUSCI_A0_SFR + 1Ch ; eUSCI_A0 Interrupt Flags Register
+ .ENDIF ;UCA0_UART
+
+
+; ----------------------------------------------------------------------
+; eUSCI_B0
+; ----------------------------------------------------------------------
+ .IFDEF UCB0_SD
+SD_CTLW0 .equ eUSCI_B0_SFR + 00h ; USCI_B0 Control Word Register 0
+SD_BRW .equ eUSCI_B0_SFR + 06h ; USCI_B0 Baud Word Rate 0
+SD_RXBUF .equ eUSCI_B0_SFR + 0Ch ; USCI_B0 Receive Buffer 8
+SD_TXBUF .equ eUSCI_B0_SFR + 0Eh ; USCI_B0 Transmit Buffer 8
+SD_IFG .equ eUSCI_B0_SFR + 2Ch ; USCI_B0 Interrupt Flags Register
+ .ENDIF ;UCB0_SD
+
+; ----------------------------------------------------------------------
+; POWER ON RESET SYS config
+; ----------------------------------------------------------------------
+SYSCTL .equ SYS_SFR + 00h ; System control
+SYSBSLC .equ SYS_SFR + 02h ; Bootstrap loader configuration area
+SYSJMBC .equ SYS_SFR + 06h ; JTAG mailbox control
+SYSJMBI0 .equ SYS_SFR + 08h ; JTAG mailbox input 0
+SYSJMBI1 .equ SYS_SFR + 0Ah ; JTAG mailbox input 1
+SYSJMBO0 .equ SYS_SFR + 0Ch ; JTAG mailbox output 0
+SYSJMBO1 .equ SYS_SFR + 0Eh ; JTAG mailbox output 1
+SYSBERRIV .equ SYS_SFR + 18h ; Bus Error vector generator
+SYSUNIV .equ SYS_SFR + 1Ah ; User NMI vector generator
+SYSSNIV .equ SYS_SFR + 1Ch ; System NMI vector generator
+SYSRSTIV .equ SYS_SFR + 1Eh ; Reset vector generator
+SYSCFG0 .equ SYS_SFR + 20h ; System configuration 0
+SYSCFG1 .equ SYS_SFR + 22h ; System configuration 1
+SYSCFG2 .equ SYS_SFR + 24h ; System configuration 2
+
+; SYS Control Bits
+; ...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+\prog\MSP430Flasher\msp430flasher -m SBW2 -n MSP430fr4133 -v -w %1 -z [VCC=3000]
+exit
+
+tip : how to calculate MAIN program lenght ?
+
+open the prog.txt file with your editor, select MAIN section
+in status bar, keep the number of selected chars
+if lines are ended with CR+LF, substract the number of lines selected
+then divide by 3.
--- /dev/null
+\prog\MSP430Flasher\msp430flasher -m SBW2 -n MSP430fr5738 -v -w %1 -z [VCC=3000]
+exit
+
+tip : how to calculate MAIN program lenght ?
+
+open the prog.txt file with your editor, select MAIN section
+in status bar, keep the number of selected chars
+if lines are ended with CR+LF, substract the number of lines selected
+then divide by 3.
--- /dev/null
+\prog\MSP430Flasher\msp430flasher -m SBW2 -n MSP430fr5739 -v -w %1 -z [VCC=3000]
+exit
+
+tip : how to calculate MAIN program lenght ?
+
+open the prog.txt file with your editor, select MAIN section
+in status bar, keep the number of selected chars
+if lines are ended with CR+LF, substract the number of lines selected
+then divide by 3.
--- /dev/null
+; MSP430fr57xx.inc : MSP430FR57xx declarations
+
+
+ .IF DEVICE = "MSP430FR5734"
+
+; ----------------------------------------------------------------------
+; MSP430FR5734 Peripheral File Map
+; ----------------------------------------------------------------------
+SFR_SFR .equ 0100h ; Special function
+PMM_SFR .equ 0120h ; PMM
+FRAM_SFR .equ 0140h ; FRAM control
+CRC16_SFR .equ 0150h
+WDT_A_SFR .equ 015Ch ; Watchdog
+CS_SFR .equ 0160h
+SYS_SFR .equ 0180h ; SYS
+REF_SFR .equ 01B0h ; REF
+PA_SFR .equ 0200h ; PORT1/2
+PJ_SFR .equ 0320h ; PORTJ
+TA0_SFR .equ 0340h
+TA1_SFR .equ 0380h
+TB0_SFR .equ 03C0h
+TB1_SFR .equ 0400h
+TB2_SFR .equ 0440h
+RTC_B_SFR .equ 04A0h
+MPY_SFR .equ 04C0h
+DMA_CTRL_SFR .equ 0500h
+DMA_CHN0_SFR .equ 0510h
+DMA_CHN1_SFR .equ 0520h
+DMA_CHN2_SFR .equ 0530h
+MPU_SFR .equ 05A0h ; memory protect unit
+eUSCI_A0_SFR .equ 05C0h ; eUSCI_A0
+eUSCI_B0_SFR .equ 0640h ; eUSCI_B0
+ADC10_B_SFR .equ 0700h
+COMP_D_SFR .equ 08C0h
+
+
+; ----------------------------------------------
+; MSP430FR5734 MEMORY MAP
+; ----------------------------------------------
+; 0000-0FFF = peripherals (4 KB)
+; 1000-17FF = ROM bootstrap loader BSL0..3 (4x512 B)
+; 1800-187F = info B (FRAM 128 B)
+; 1880-18FF = info A (FRAM 128 B)
+; 1900-19FF = N/A (mirrored into info A/B)
+; 1A00-1A7F = TLV device descriptor info (FRAM 128 B)
+; 1A80-1BFF = unused (385 B)
+; 1C00-1FFF = RAM (1 KB)
+; 2000-C1FF = unused (41472 B)
+; E000-FF7F = code memory (FRAM 15743 B)
+; FF80-FFFF = interrupt vectors (FRAM 127 B)
+; ----------------------------------------------
+PAGESIZE .equ 512 ; MPU unit
+; ----------------------------------------------
+; FRAM ; INFO B, A, TLV
+; ----------------------------------------------
+INFOSTART .equ 01800h
+INFOBSTART .equ 01800h
+INFOBEND .equ 0187Fh
+INFOASTART .equ 01880h
+INFOAEND .equ 018FFh
+TLVSTAT .equ 01A00h ; Device Descriptor Info (Tag-Lenght-Value)
+TLVEND .equ 01A7Fh ;
+; ----------------------------------------------
+; RAM
+; ----------------------------------------------
+RAMSTART .equ 01C00h
+RAMEND .equ 01FFFh
+; ----------------------------------------------
+; FRAM
+; ----------------------------------------------
+PROGRAMSTART .equ 0E000h ; Code space start
+SIGNATURES .equ 0FF80h ; JTAG/BSL signatures
+JTAG_SIG1 .equ 0FF80h ; if 0 (electronic fuse=0) enable JTAG/SBW; must be reset by wipe.
+JTAG_SIG2 .equ 0FF82h ; if JTAG_SIG1=0xAAAA, length of password string @ JTAG_PASSWORD
+BSL_SIG1 .equ 0FF84h ;
+BSL_SIG2 .equ 0FF86h ;
+JTAG_PASSWORD .equ 0FF88h ; 256 bits
+INTVECT .equ 0FFCEh ; FFCE-FFFF
+BSL_PASSWORD .equ 0FFE0h ; 256 bits
+; ----------------------------------------------
+
+
+; ----------------------------------------------
+; Interrupt Vectors and signatures - MSP430FR57xx
+; ----------------------------------------------
+
+; .org SIGNATURES
+;;Start of JTAG and BSL signatures
+; .word 0 ; JTAG signature 1
+; .word 0 ; JTAG signature 2
+; .word 0 ; 5555h ; BSL signature 1 ; disable BSL
+; .word 0 ; BSL signature 2
+
+; .org JTAG_PASSWORD ;Start of JTAG PASSWORD
+
+ .org INTVECT ; FFCE-FFFF 24 vectors + reset
+ .word reset ; $FFCE - RTC_B
+ .word reset ; $FFD0 - I/O Port 4
+ .word reset ; $FFD2 - I/O Port 3
+ .word reset ; $FFD4 - TB2_1
+ .word reset ; $FFD6 - TB2_0
+ .word reset ; $FFD8 - I/O Port P2
+ .word reset ; $FFDA - TB1_1
+ .word reset ; $FFDC - TB1_0
+ .word reset ; $FFDE - I/O Port P1
+; .org BSL_PASSWORD ;Start of BSL PASSWORD
+ .word reset ; $FFE0 - TA1_1
+ .word reset ; $FFE2 - TA1_0
+ .word reset ; $FFE4 - DMA
+ .word reset ; $FFE6 - eUSCI_A1
+ .word reset ; $FFE8 - TA0_1
+ .word reset ; $FFEA - TA0_0
+ .word reset ; $FFEC - ADC10_B
+ .word reset ; $FFEE - eUSCI_B0
+TERMVEC .word TERMINAL_INT ; $FFF0 - eUSCI_A0
+ .word reset ; $FFF2 - Watchdog
+ .word reset ; $FFF4 - TB0_1
+ .word reset ; $FFF6 - TB0_0
+ .word reset ; $FFF8 - COMP_D
+ .word reset ; $FFFA - userNMI
+ .word reset ; $FFFC - sysNMI
+RST_ADR .word reset ; $FFFE - reset
+
+
+ .ENDIF ; DEVICE="MSP430fr5734
+
+
+ .IF DEVICE = "MSP430FR5738"
+
+; ----------------------------------------------------------------------
+; MSP430FR5738 Peripheral File Map
+; ----------------------------------------------------------------------
+SFR_SFR .equ 0100h ; Special function
+PMM_SFR .equ 0120h ; PMM
+FRAM_SFR .equ 0140h ; FRAM control
+CRC16_SFR .equ 0150h
+WDT_A_SFR .equ 015Ch ; Watchdog
+CS_SFR .equ 0160h
+SYS_SFR .equ 0180h ; SYS
+REF_SFR .equ 01B0h ; REF
+PA_SFR .equ 0200h ; PORT1/2
+PJ_SFR .equ 0320h ; PORTJ
+TA0_SFR .equ 0340h
+TA1_SFR .equ 0380h
+TB0_SFR .equ 03C0h
+TB1_SFR .equ 0400h
+TB2_SFR .equ 0440h
+RTC_B_SFR .equ 04A0h
+MPY_SFR .equ 04C0h
+DMA_CTRL_SFR .equ 0500h
+DMA_CHN0_SFR .equ 0510h
+DMA_CHN1_SFR .equ 0520h
+DMA_CHN2_SFR .equ 0530h
+MPU_SFR .equ 05A0h ; memory protect unit
+eUSCI_A0_SFR .equ 05C0h ; eUSCI_A0
+eUSCI_B0_SFR .equ 0640h ; eUSCI_B0
+ADC10_B_SFR .equ 0700h
+COMP_D_SFR .equ 08C0h
+
+
+; ----------------------------------------------
+; MSP430FR5738 MEMORY MAP
+; ----------------------------------------------
+; 0000-0FFF = peripherals (4 KB)
+; 1000-17FF = ROM bootstrap loader BSL0..3 (4x512 B)
+; 1800-187F = info B (FRAM 128 B)
+; 1880-18FF = info A (FRAM 128 B)
+; 1900-19FF = N/A (mirrored into info A/B)
+; 1A00-1A7F = TLV device descriptor info (FRAM 128 B)
+; 1A80-1BFF = unused (385 B)
+; 1C00-1FFF = RAM (1 KB)
+; 2000-C1FF = unused (41472 B)
+; C200-FF7F = code memory (FRAM 15743 B)
+; FF80-FFFF = interrupt vectors (FRAM 127 B)
+; ----------------------------------------------
+PAGESIZE .equ 512 ; MPU unit
+; ----------------------------------------------
+; FRAM ; INFO B, A, TLV
+; ----------------------------------------------
+INFOSTART .equ 01800h
+INFOBSTART .equ 01800h
+INFOBEND .equ 0187Fh
+INFOASTART .equ 01880h
+INFOAEND .equ 018FFh
+TLVSTAT .equ 01A00h ; Device Descriptor Info (Tag-Lenght-Value)
+TLVEND .equ 01A7Fh ;
+; ----------------------------------------------
+; RAM
+; ----------------------------------------------
+RAMSTART .equ 01C00h
+RAMEND .equ 01FFFh
+; ----------------------------------------------
+; FRAM
+; ----------------------------------------------
+PROGRAMSTART .equ 0C200h ; Code space start
+SIGNATURES .equ 0FF80h ; JTAG/BSL signatures
+JTAG_SIG1 .equ 0FF80h ; if 0 (electronic fuse=0) enable JTAG/SBW; must be reset by wipe.
+JTAG_SIG2 .equ 0FF82h ; if JTAG_SIG1=0xAAAA, length of password string @ JTAG_PASSWORD
+BSL_SIG1 .equ 0FF84h ;
+BSL_SIG2 .equ 0FF86h ;
+JTAG_PASSWORD .equ 0FF88h ; 256 bits
+INTVECT .equ 0FFCEh ; FFCE-FFFF
+BSL_PASSWORD .equ 0FFE0h ; 256 bits
+; ----------------------------------------------
+
+
+; ----------------------------------------------
+; Interrupt Vectors and signatures - MSP430FR57xx
+; ----------------------------------------------
+
+; .org SIGNATURES
+;;Start of JTAG and BSL signatures
+; .word 0 ; JTAG signature 1
+; .word 0 ; JTAG signature 2
+; .word 0 ; 5555h ; BSL signature 1 ; disable BSL
+; .word 0 ; BSL signature 2
+
+; .org JTAG_PASSWORD ;Start of JTAG PASSWORD
+
+ .org INTVECT ; FFCE-FFFF 24 vectors + reset
+ .word reset ; $FFCE - RTC_B
+ .word reset ; $FFD0 - I/O Port 4
+ .word reset ; $FFD2 - I/O Port 3
+ .word reset ; $FFD4 - TB2_1
+ .word reset ; $FFD6 - TB2_0
+ .word reset ; $FFD8 - I/O Port P2
+ .word reset ; $FFDA - TB1_1
+ .word reset ; $FFDC - TB1_0
+ .word reset ; $FFDE - I/O Port P1
+; .org BSL_PASSWORD ;Start of BSL PASSWORD
+ .word reset ; $FFE0 - TA1_1
+ .word reset ; $FFE2 - TA1_0
+ .word reset ; $FFE4 - DMA
+ .word reset ; $FFE6 - eUSCI_A1
+ .word reset ; $FFE8 - TA0_1
+ .word reset ; $FFEA - TA0_0
+ .word reset ; $FFEC - ADC10_B
+ .word reset ; $FFEE - eUSCI_B0
+TERMVEC .word TERMINAL_INT ; $FFF0 - eUSCI_A0
+ .word reset ; $FFF2 - Watchdog
+ .word reset ; $FFF4 - TB0_1
+ .word reset ; $FFF6 - TB0_0
+ .word reset ; $FFF8 - COMP_D
+ .word reset ; $FFFA - userNMI
+ .word reset ; $FFFC - sysNMI
+RST_ADR .word reset ; $FFFE - reset
+
+
+ .ENDIF ; DEVICE="MSP430fr5738
+
+
+
+ .IF DEVICE = "MSP430FR5739"
+
+; ----------------------------------------------------------------------
+; MSP430FR5739 Peripheral File Map
+; ----------------------------------------------------------------------
+SFR_SFR .equ 0100h ; Special function
+PMM_SFR .equ 0120h ; PMM
+FRAM_SFR .equ 0140h ; FRAM control
+CRC16_SFR .equ 0150h
+WDT_A_SFR .equ 015Ch ; Watchdog
+CS_SFR .equ 0160h
+SYS_SFR .equ 0180h ; SYS
+REF_SFR .equ 01B0h ; REF
+PA_SFR .equ 0200h ; PORT1/2
+PB_SFR .equ 0220h ; PORT3/4
+PJ_SFR .equ 0320h ; PORTJ
+TA0_SFR .equ 0340h
+TA1_SFR .equ 0380h
+TB0_SFR .equ 03C0h
+TB1_SFR .equ 0400h
+TB2_SFR .equ 0440h
+RTC_B_SFR .equ 04A0h
+MPY_SFR .equ 04C0h
+DMA_CTRL_SFR .equ 0500h
+DMA_CHN0_SFR .equ 0510h
+DMA_CHN1_SFR .equ 0520h
+DMA_CHN2_SFR .equ 0530h
+MPU_SFR .equ 05A0h ; memory protect unit
+eUSCI_A0_SFR .equ 05C0h ; eUSCI_A0
+eUSCI_A1_SFR .equ 05E0h ; eUSCI_A1
+eUSCI_B0_SFR .equ 0640h ; eUSCI_B0
+ADC10_B_SFR .equ 0700h
+COMP_D_SFR .equ 08C0h
+
+; ----------------------------------------------
+; MSP430FR5739 MEMORY MAP
+; ----------------------------------------------
+; 0000-0FFF = peripherals (4 KB)
+; 1000-17FF = ROM bootstrap loader BSL0..3 (4x512 B)
+; 1800-187F = info B (FRAM 128 B)
+; 1880-18FF = info A (FRAM 128 B)
+; 1900-19FF = N/A (mirrored into info A/B)
+; 1A00-1A7F = TLV device descriptor info (FRAM 128 B)
+; 1A80-1BFF = unused (385 B)
+; 1C00-1FFF = RAM (1 KB)
+; 2000-C1FF = unused (41472 B)
+; C200-FF7F = code memory (FRAM 15743 B)
+; FF80-FFFF = interrupt vectors (FRAM 127 B)
+; ----------------------------------------------
+PAGESIZE .equ 512 ; MPU unit
+; ----------------------------------------------
+; FRAM ; INFO B, A, TLV
+; ----------------------------------------------
+INFOSTART .equ 01800h
+INFOBSTART .equ 01800h
+INFOBEND .equ 0187Fh
+INFOASTART .equ 01880h
+INFOAEND .equ 018FFh
+TLVSTAT .equ 01A00h ; Device Descriptor Info (Tag-Lenght-Value)
+TLVEND .equ 01A7Fh ;
+; ----------------------------------------------
+; RAM
+; ----------------------------------------------
+RAMSTART .equ 01C00h
+RAMEND .equ 01FFFh
+; ----------------------------------------------
+; FRAM
+; ----------------------------------------------
+PROGRAMSTART .equ 0C200h ; Code space start
+SIGNATURES .equ 0FF80h ; JTAG/BSL signatures
+JTAG_SIG1 .equ 0FF80h ; if 0 (electronic fuse=0) enable JTAG/SBW; must be reset by wipe.
+JTAG_SIG2 .equ 0FF82h ; if JTAG_SIG1=0xAAAA, length of password string @ JTAG_PASSWORD
+BSL_SIG1 .equ 0FF84h ;
+BSL_SIG2 .equ 0FF86h ;
+JTAG_PASSWORD .equ 0FF88h ; 256 bits
+INTVECT .equ 0FFCEh ; FFCE-FFFF
+BSL_PASSWORD .equ 0FFE0h ; 256 bits
+; ----------------------------------------------
+
+; ----------------------------------------------
+; Interrupt Vectors and signatures - MSP430FR57xx
+; ----------------------------------------------
+
+; .org SIGNATURES
+;;Start of JTAG and BSL signatures
+; .word 0 ; JTAG signature 1
+; .word 0 ; JTAG signature 2
+; .word 0 ; 5555h ; BSL signature 1; disable BSL
+; .word 0 ; BSL signature 2
+
+; .org JTAG_PASSWORD ;Start of JTAG PASSWORD
+
+ .org INTVECT ; FFCE-FFFF 24 vectors + reset
+ .word reset ; $FFCE - RTC_B
+ .word reset ; $FFD0 - I/O Port 4
+ .word reset ; $FFD2 - I/O Port 3
+ .word reset ; $FFD4 - TB2_1
+ .word reset ; $FFD6 - TB2_0
+ .word reset ; $FFD8 - I/O Port P2
+ .word reset ; $FFDA - TB1_1
+ .word reset ; $FFDC - TB1_0
+ .word reset ; $FFDE - I/O Port P1
+; .org BSL_PASSWORD ;Start of BSL PASSWORD
+ .word reset ; $FFE0 - TA1_1
+ .word reset ; $FFE2 - TA1_0
+ .word reset ; $FFE4 - DMA
+ .IFDEF UCA1_UART
+TERMVEC .word TERMINAL_INT ; $FFE6 - eUSCI_A1
+ .ELSE
+ .word reset ; $FFE6 - eUSCI_A1
+ .ENDIF
+ .word reset ; $FFE8 - TA0_1
+ .word reset ; $FFEA - TA0_0
+ .word reset ; $FFEC - ADC10_B
+ .word reset ; $FFEE - eUSCI_B0
+ .IFDEF UCA0_UART
+TERMVEC .word TERMINAL_INT ; $FFF0 - eUSCI_A0
+ .ELSE
+ .word reset ; $FFF0 - eUSCI_A0
+ .ENDIF
+ .word reset ; $FFF2 - Watchdog
+ .word reset ; $FFF4 - TB0_1
+ .word reset ; $FFF6 - TB0_0
+ .word reset ; $FFF8 - COMP_D
+ .word reset ; $FFFA - userNMI
+ .word reset ; $FFFC - sysNMI
+RST_ADR .word reset ; $FFFE - reset
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT3/4
+; ----------------------------------------------------------------------
+; PB = P4:P3
+
+PBIN .set PB_SFR + 00h ; Port B Input
+PBOUT .set PB_SFR + 02h ; Port B Output 1/0 or pullup/pulldown resistor
+PBDIR .set PB_SFR + 04h ; Port B Direction
+PBREN .set PB_SFR + 06h ; Port B Resistor Enable
+PBSEL0 .set PB_SFR + 0Ah ; Port B Selection 0
+PBSEL1 .set PB_SFR + 0Ch ; Port B Selection 1
+PBSELC .set PB_SFR + 16h ; Port B Complement Selection
+PBIES .set PB_SFR + 18h ; Port B Interrupt Edge Select
+PBIE .set PB_SFR + 1Ah ; Port B Interrupt Enable
+PBIFG .set PB_SFR + 1Ch ; Port B Interrupt Flag
+
+P3IN .set PB_SFR + 00h ; Port 3 Input */
+P3OUT .set PB_SFR + 02h ; Port 3 Output
+P3DIR .set PB_SFR + 04h ; Port 3 Direction
+P3REN .set PB_SFR + 06h ; Port 3 Resistor Enable
+P3SEL0 .set PB_SFR + 0Ah ; Port 3 Selection 0
+P3SEL1 .set PB_SFR + 0Ch ; Port 3 Selection 1
+P3SELC .set PB_SFR + 16h ; Port 3 Complement Selection
+P3IES .set PB_SFR + 18h ; Port 3 Interrupt Edge Select
+P3IE .set PB_SFR + 1Ah ; Port 3 Interrupt Enable
+P3IFG .set PB_SFR + 1Ch ; Port 3 Interrupt Flag
+
+P4IN .set PB_SFR + 01h ; Port 4 Input */
+P4OUT .set PB_SFR + 03h ; Port 4 Output
+P4DIR .set PB_SFR + 05h ; Port 4 Direction
+P4REN .set PB_SFR + 07h ; Port 4 Resistor Enable
+P4SEL0 .set PB_SFR + 0Bh ; Port 4 Selection 0
+P4SEL1 .set PB_SFR + 0Dh ; Port 4 Selection 1
+P4SELC .set PB_SFR + 17h ; Port 4 Complement Selection
+P4IES .set PB_SFR + 19h ; Port 4 Interrupt Edge Select
+P4IE .set PB_SFR + 1Bh ; Port 4 Interrupt Enable
+P4IFG .set PB_SFR + 1Dh ; Port 4 Interrupt Flag
+
+; ----------------------------------------------------------------------
+; eUSCI_A1
+; ----------------------------------------------------------------------
+
+ .IFDEF UCA1_UART
+TERMCTLW0 .equ eUSCI_A1_SFR + 00h ; eUSCI_A1 Control Word Register 0
+TERMBRW .equ eUSCI_A1_SFR + 06h ; eUSCI_A1 Baud Word Rate 0
+TERMMCTLW .equ eUSCI_A1_SFR + 08h ; eUSCI_A1 Modulation Control
+TERMRXBUF .equ eUSCI_A1_SFR + 0Ch ; eUSCI_A1 Receive Buffer
+TERMTXBUF .equ eUSCI_A1_SFR + 0Eh ; eUSCI_A1 Transmit Buffer
+TERMIE .equ eUSCI_A1_SFR + 1Ah ; eUSCI_A1 Interrupt Enable Register
+TERMIFG .equ eUSCI_A1_SFR + 1Ch ; eUSCI_A1 Interrupt Flags Register
+ .ENDIF ;UCA1_UART
+
+ .ENDIF ;DEVICE="MSP430FR5739"
+
+
+
+
+;=======================================================================
+; COMMON PARTS
+;=======================================================================
+
+UCSWRST .equ 1 ; eUSCI Software Reset
+UCTXIE .equ 2 ; eUSCI Transmit Interrupt Enable
+UCRXIE .equ 1 ; eUSCI Receive Interrupt Enable
+UCTXIFG .equ 2 ; eUSCI Transmit Interrupt Flag
+UCRXIFG .equ 1 ; eUSCI Receive Interrupt Flag
+
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : LOCK I/O as high impedance state
+; ----------------------------------------------------------------------
+PMMCTL0 .equ PMM_SFR
+PMMSWBOR .equ 4
+
+PM5CTL0 .equ PMM_SFR + 10h ; Power mode 5 control register 0
+LOCKLPM5 .equ 1
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : WATCHDOG TIMER A
+; ----------------------------------------------------------------------
+
+WDTCTL .equ WDT_A_SFR + 00h ; Watchdog Timer Control */
+
+; WDTCTL Control Bits
+WDTPW .equ 5A00h
+WDTHOLD .equ 0080h ; WDT - Timer hold
+WDTCNTCL .equ 0008h ; WDT timer counter clear
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION PAIN=PORT2:PORT1
+; ----------------------------------------------------------------------
+
+PAIN .equ PA_SFR + 00h ; Port A INput
+PAOUT .equ PA_SFR + 02h ; Port A OUTput
+PADIR .equ PA_SFR + 04h ; Port A DIRection
+PAREN .equ PA_SFR + 06h ; Port A Resistor ENable
+PASEL0 .equ PA_SFR + 0Ah ; Port A SELection 0
+PASEL1 .equ PA_SFR + 0Ch ; Port A SELection 1
+PASELC .equ PA_SFR + 16h ; Port A SELection Complement
+PAIES .equ PA_SFR + 18h ; Port A Interrupt Edge Select
+PAIE .equ PA_SFR + 1Ah ; Port A Interrupt Enable
+PAIFG .equ PA_SFR + 1Ch ; Port A Interrupt FlaG
+
+P1IN .equ PA_SFR + 00h ; Port 1 INput
+P1OUT .equ PA_SFR + 02h ; Port 1 OUTput
+P1DIR .equ PA_SFR + 04h ; Port 1 DIRection
+P1REN .equ PA_SFR + 06h ; Port 1 Resistor ENable
+P1SEL0 .equ PA_SFR + 0Ah ; Port 1 SELection 0
+P1SEL1 .equ PA_SFR + 0Ch ; Port 1 SELection 1
+P1IV .equ PA_SFR + 0Eh ; Port 1 Interrupt Vector word
+P1SELC .equ PA_SFR + 16h ; Port 1 SELection Complement
+P1IES .equ PA_SFR + 18h ; Port 1 Interrupt Edge Select
+P1IE .equ PA_SFR + 1Ah ; Port 1 Interrupt Enable
+P1IFG .equ PA_SFR + 1Ch ; Port 1 Interrupt FlaG
+
+P2IN .equ PA_SFR + 01h ; Port 2 INput
+P2OUT .equ PA_SFR + 03h ; Port 2 OUTput
+P2DIR .equ PA_SFR + 05h ; Port 2 DIRection
+P2REN .equ PA_SFR + 07h ; Port 2 Resistor ENable
+P2SEL0 .equ PA_SFR + 0Bh ; Port 2 SELection 0
+P2SEL1 .equ PA_SFR + 0Dh ; Port 2 SELection 1
+P2SELC .equ PA_SFR + 17h ; Port 2 SELection Complement
+P2IES .equ PA_SFR + 19h ; Port 2 Interrupt Edge Select
+P2IE .equ PA_SFR + 1Bh ; Port 2 Interrupt Enable
+P2IFG .equ PA_SFR + 1Dh ; Port 2 Interrupt Flag
+P2IV .equ PA_SFR + 1Eh ; Port 2 Interrupt Vector word
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORTJ
+; ----------------------------------------------------------------------
+
+PJIN .set PJ_SFR + 00h ; Port B Input
+PJOUT .set PJ_SFR + 02h ; Port B Output
+PJDIR .set PJ_SFR + 04h ; Port B Direction
+PJREN .set PJ_SFR + 06h ; Port B Resistor Enable
+PJSEL0 .set PJ_SFR + 0Ah ; Port B Selection 0
+PJSEL1 .set PJ_SFR + 0Ch ; Port B Selection 1
+PJSELC .set PJ_SFR + 16h ; Port B Complement Selection
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : CLOCK SYSTEM
+; ----------------------------------------------------------------------
+
+CSCTL0 .equ CS_SFR + 00h ; CS Control Register 0
+CSCTL0_H .equ CS_SFR + 01h ; CS Control Register 0 high byte
+CSCTL1 .equ CS_SFR + 02h ; CS Control Register 1
+CSCTL2 .equ CS_SFR + 04h ; CS Control Register 2
+CSCTL3 .equ CS_SFR + 06h ; CS Control Register 3
+
+; CSCTL0 Control Bits
+CSKEY .equ 0A5h ; CS Password
+; CSCTL1 Control Bits
+DCORSEL .equ 0080h
+DCOFSEL0 .equ 0002h ; DCO frequency select Bit: 0
+DCOFSEL1 .equ 0004h ; DCO frequency select Bit: 1
+; CSCTL2 Control Bits
+; SELA_LFXCLK .equ 0000h ; 0 : ACLK Source Select LFXCLK
+SELA_LFXCLK .equ 0000h ; 0 : ACLK Source Select LFXCLK
+SELA_VLOCLK .equ 0100h ; 1 ACLK Source Select VLOCLK 10kHz
+SELS_DCOCLK .equ 0030h ; 3 SMCLK Source Select DCOCLK
+SELM_DCOCLK .equ 0003h ; 3 MCLK Source Select DCOCLK
+; CSCTL3 Control Bits
+DIVA_0 .equ 0000h ; ACLK Source Divider 0
+DIVS_0 .equ 0000h ; SMCLK Source Divider 0
+DIVM_0 .equ 0000h ; MCLK Source Divider 0
+DIVA_2 .equ 0100h ; ACLK Source Divider 0
+DIVS_2 .equ 0010h ; SMCLK Source Divider 0
+DIVM_2 .equ 0001h ; MCLK Source Divider 0
+DIVA_4 .equ 0200h ; ACLK Source Divider 0
+DIVS_4 .equ 0020h ; SMCLK Source Divider 0
+DIVM_4 .equ 0002h ; MCLK Source Divider 0
+DIVA_8 .equ 0300h ; ACLK Source Divider 0
+DIVS_8 .equ 0030h ; SMCLK Source Divider 0
+DIVM_8 .equ 0003h ; MCLK Source Divider 0
+DIVA_16 .equ 0400h ; ACLK Source Divider 0
+DIVS_16 .equ 0040h ; SMCLK Source Divider 0
+DIVM_16 .equ 0004h ; MCLK Source Divider 0
+DIVA_32 .equ 0500h ; ACLK Source Divider 0
+DIVS_32 .equ 0050h ; SMCLK Source Divider 0
+DIVM_32 .equ 0005h ; MCLK Source Divider 0
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : REF
+; ----------------------------------------------------------------------
+
+REFCTL .equ REF_SFR + 00h ; REF Shared Reference control register 0
+
+; REFCTL0 Control Bits
+REFON .equ 0001h ; REF Reference On
+REFTCOFF .equ 0008h ; REF Temp.Sensor off
+
+
+; ----------------------------------------------------------------------
+; MPY_32
+; ----------------------------------------------------------------------
+
+MPY .equ MPY_SFR + 00h ; Multiply16 Unsigned/Operand 1 */
+MPYS .equ MPY_SFR + 02h ; Multiply16 signed/Operand 1
+MAC .equ MPY_SFR + 04h ; MultiplyAccumulate16 Unsigned/Operand 1 */
+MACS .equ MPY_SFR + 06h ; MultiplyAccumulate16 signed/Operand 1
+OP2 .equ MPY_SFR + 08h ; Operand2_16 */
+RESLO .equ MPY_SFR + 0Ah ; 16x16-bit result low - least significant word */
+RESHI .equ MPY_SFR + 0Ch ; 16x16-bit result high */
+SUMEXT .equ MPY_SFR + 0Eh ; 16x16-bit sum extension register
+MPY32L .equ MPY_SFR + 10h ; Multiply32 Unsigned/Operand 1
+MPY32H .equ MPY_SFR + 12h ; Multiply32 Unsigned/Operand 1
+MPYS32L .equ MPY_SFR + 14h ; Multiply32 signed/Operand 1
+MPYS32H .equ MPY_SFR + 16h ; Multiply32 signed/Operand 1
+MAC32L .equ MPY_SFR + 18h ; MultiplyAccumulate32 Unsigned/Operand 1
+MAC32H .equ MPY_SFR + 1Ah ; MultiplyAccumulate32 Unsigned/Operand 1
+MACS32L .equ MPY_SFR + 1Ch ; MultiplyAccumulate32 signed/Operand 1
+MACS32H .equ MPY_SFR + 1Eh ; MultiplyAccumulate32 signed/Operand 1
+OP2L .equ MPY_SFR + 20h ; Multiply32 Operand 2
+OP2H .equ MPY_SFR + 22h ; Multiply32 Operand 2
+RES0 .equ MPY_SFR + 24h ; 32x32-bit result 0 - least significant word */
+RES1 .equ MPY_SFR + 26h ; 32x32-bit result 1 */
+RES2 .equ MPY_SFR + 28h ; 32x32-bit result 2 */
+RES3 .equ MPY_SFR + 2Ah ; 32x32-bit result 3 */
+MPY32CTL0 .equ MPY_SFR + 2Ch ; MPY32 control register 0
+
+
+; ----------------------------------------------------------------------
+; eUSCI_A0
+; ----------------------------------------------------------------------
+
+ .IFDEF UCA0_UART
+TERMCTLW0 .equ eUSCI_A0_SFR + 00h ; eUSCI_A0 Control Word Register 0
+TERMBRW .equ eUSCI_A0_SFR + 06h ; eUSCI_A0 Baud Word Rate 0
+TERMMCTLW .equ eUSCI_A0_SFR + 08h ; eUSCI_A0 Modulation Control
+TERMRXBUF .equ eUSCI_A0_SFR + 0Ch ; eUSCI_A0 Receive Buffer
+TERMTXBUF .equ eUSCI_A0_SFR + 0Eh ; eUSCI_A0 Transmit Buffer
+TERMIE .equ eUSCI_A0_SFR + 1Ah ; eUSCI_A0 Interrupt Enable Register
+TERMIFG .equ eUSCI_A0_SFR + 1Ch ; eUSCI_A0 Interrupt Flags Register
+ .ENDIF ;UCA0_UART
+
+; ----------------------------------------------------------------------
+; eUSCI_B0
+; ----------------------------------------------------------------------
+ .IFDEF UCB0_SD
+SD_CTLW0 .equ eUSCI_B0_SFR + 00h ; USCI_B0 Control Word Register 0
+SD_BRW .equ eUSCI_B0_SFR + 06h ; USCI_B0 Baud Word Rate 0
+SD_RXBUF .equ eUSCI_B0_SFR + 0Ch ; USCI_B0 Receive Buffer 8
+SD_TXBUF .equ eUSCI_B0_SFR + 0Eh ; USCI_B0 Transmit Buffer 8
+SD_IFG .equ eUSCI_B0_SFR + 2Ch ; USCI_B0 Interrupt Flags Register
+ .ENDIF ;UCB0_SD
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : RTC REGISTERS
+; ----------------------------------------------------------------------
+RTCCTL01 .equ RTC_B_SFR + 00h
+RTCCTL0 .equ RTC_B_SFR + 00h
+RTCCTL1 .equ RTC_B_SFR + 01h
+RTCCTL23 .equ RTC_B_SFR + 02h
+RTCPS0CTL .equ RTC_B_SFR + 08h
+RTCPS1CTL .equ RTC_B_SFR + 0Ah
+RTCPS .equ RTC_B_SFR + 0Ch
+RTCIV .equ RTC_B_SFR + 0Eh
+RTCSEC .equ RTC_B_SFR + 10h
+RTCMIN .equ RTC_B_SFR + 11h
+RTCHOUR .equ RTC_B_SFR + 12h
+RTCDOW .equ RTC_B_SFR + 13h
+RTCDAY .equ RTC_B_SFR + 14h
+RTCMON .equ RTC_B_SFR + 15h
+RTCYEAR .equ RTC_B_SFR + 16h
+
+RTCHOLD .equ 40h
+RTCRDY .equ 10h
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : SYS REGISTERS
+; ----------------------------------------------------------------------
+
+SYSRSTIV .equ SYS_SFR + 001Eh
+
+
--- /dev/null
+\prog\MSP430Flasher\msp430flasher -m SBW2 -n MSP430fr5948 -v -w %1 -z [VCC=3000]
+exit
+
+tip : how to calculate MAIN program lenght ?
+
+open the prog.txt file with your editor, select MAIN section
+in status bar, keep the number of selected chars
+if lines are ended with CR+LF, substract the number of lines selected
+then divide by 3.
--- /dev/null
+\prog\MSP430Flasher\msp430flasher -m SBW2 -n MSP430fr5969 -v -w %1 -z [VCC=3000]
+exit
+
+tip : how to calculate MAIN program lenght ?
+
+open the prog.txt file with your editor, select MAIN section
+in status bar, keep the number of selected chars
+if lines are ended with CR+LF, substract the number of lines selected
+then divide by 3.
--- /dev/null
+\prog\MSP430Flasher\msp430flasher -m SBW2 -n MSP430fr5994 -v -w %1 -z [VCC=3000]
+exit
+
+tip : how to calculate MAIN program lenght ?
+
+open the prog.txt file with your editor, select MAIN section
+in status bar, keep the number of selected chars
+if lines are ended with CR+LF, substract the number of lines selected
+then divide by 3.
--- /dev/null
+a:\prog\MSP430Flasher\msp430flasher -e ERASE_TOTAL
\ No newline at end of file
--- /dev/null
+; MSP430FR5x6x.inc : MSP430FR5xxx and MSP430FR6xxx declarations (MSP430FR57xx excluded)
+
+
+ .IF DEVICE = "MSP430FR5948"
+
+; ----------------------------------------------------------------------
+; MSP430FR5948 Peripheral File Map
+; ----------------------------------------------------------------------
+SFR_SFR .set 0100h ; Special function
+PMM_SFR .set 0120h ; PMM
+FRAM_SFR .set 0140h ; FRAM control
+CRC16_SFR .set 0150h
+WDT_A_SFR .set 015Ch ; Watchdog
+CS_SFR .set 0160h ; Clock System
+SYS_SFR .set 0180h ; SYS
+REF_SFR .set 01B0h ; REF
+PA_SFR .set 0200h ; PORT1/2
+PB_SFR .set 0220h ; PORT3/4
+PJ_SFR .set 0320h ; PORTJ
+TA0_SFR .set 0340h
+TA1_SFR .set 0380h
+TB0_SFR .set 03C0h
+TA2_SFR .set 0400h
+CTIO0_SFR .set 0430h ; Capacitive Touch IO
+TA3_SFR .set 0440h
+CTIO1_SFR .set 0470h ; Capacitive Touch IO
+RTC_B_SFR .set 04A0h
+MPY_SFR .set 04C0h
+DMA_CTRL_SFR .set 0500h
+DMA_CHN0_SFR .set 0510h
+DMA_CHN1_SFR .set 0520h
+DMA_CHN2_SFR .set 0530h
+MPU_SFR .set 05A0h ; memory protect unit
+eUSCI_A0_SFR .set 05C0h ; eUSCI_A0
+eUSCI_A1_SFR .set 05E0h ; eUSCI_A1
+eUSCI_B0_SFR .set 0640h ; eUSCI_B0
+ADC12_B_SFR .set 0800h
+COMP_E_SFR .set 08C0h
+AES_SFR .set 09C0h
+
+; ----------------------------------------------
+; MSP430FR5948 MEMORY MAP
+; ----------------------------------------------
+; 0000-0FFF = peripherals (4 KB)
+; 1000-17FF = ROM bootstrap loader BSL0..3 (4x512 B)
+; 1800-187F = FRAM info D (128 B)
+; 1880-18FF = FRAM info C (128 B)
+; 1900-197F = FRAM info B (128 B)
+; 1980-19FF = FRAM info A (128 B)
+; 1A00-1AFF = FRAM TLV device descriptor info (256 B)
+; 1B00-1BFF = unused (256 B)
+; 1C00-23FF = RAM (2KB)
+; 23FF-43FF = unused (8kB)
+; 4400-FF7F = FRAM code memory (FRAM) (MSP430FR59x8/9)
+; 8000-FF7F = FRAM code memory (FRAM) (MSP430FR59x7/8/9)
+; FF80-FFFF = FRAM interrupt vectors and signatures (FRAM)
+
+; ----------------------------------------------
+PAGESIZE .equ 512 ; MPU unit
+; ----------------------------------------------
+; BSL
+; ----------------------------------------------
+BSL .equ 1000h
+; ----------------------------------------------
+; FRAM ; INFO B, A, TLV
+; ----------------------------------------------
+INFOSTART .equ 01800h
+INFODSTART .equ 01800h
+INFODEND .equ 0187Fh
+INFOCSTART .equ 01880h
+INFOCEND .equ 018FFh
+INFOBSTART .equ 01900h
+INFOBEND .equ 0197Fh
+INFOASTART .equ 01980h
+INFOAEND .equ 019FFh
+TLVSTART .equ 01A00h ; Device Descriptor Info (Tag-Lenght-Value)
+TLVEND .equ 01AFFh ;
+; ----------------------------------------------
+; RAM
+; ----------------------------------------------
+RAMSTART .equ 01C00h
+RAMEND .equ 023FFh
+; ----------------------------------------------
+; FRAM
+; ----------------------------------------------
+PROGRAMSTART .equ 04400h ; Code space start
+FRAMEND .equ 0FFFFh ; 48 k FRAM
+SIGNATURES .equ 0FF80h ; JTAG/BSL signatures
+JTAG_SIG1 .equ 0FF80h ; if 0, enable JTAG/SBW
+JTAG_SIG2 .equ 0FF82h ; if JTAG_SIG1=0xAAAA, length of password string @ JTAG_PASSWORD
+BSL_SIG1 .equ 0FF84h ;
+BSL_SIG2 .equ 0FF86h ;
+JTAG_PASSWORD .equ 0FF88h ; 256 bits max
+IPE_SIG_VALID .equ 0FF88h ; one word
+IPE_STR_PTR_SRC .equ 0FF8Ah ; one word
+INTVECT .equ 0FFCCh ; FFCC-FFFF
+BSL_PASSWORD .equ 0FFE0h ; 256 bits
+; ----------------------------------------------
+; .org SIGNATURES
+;;Start of JTAG and BSL signatures
+; .word 0 ; JTAG signature 1
+; .word 0 ; JTAG signature 2
+; .word 0;5555h ; BSL signature 1; disable BSL
+; .word 0 ; BSL signature 2
+
+; ----------------------------------------------
+; Interrupt Vectors and signatures - MSP430FR5948
+; ----------------------------------------------
+
+ .org INTVECT ; FFCC-FFFF 25 vectors + reset
+ .word reset ; $FFCC - AES
+ .word reset ; $FFCE - RTC_B
+ .word reset ; $FFD0 - I/O Port 4
+ .word reset ; $FFD2 - I/O Port 3
+ .word reset ; $FFD4 - TB2_1
+ .word reset ; $FFD6 - TB2_0
+ .word reset ; $FFD8 - I/O Port P2
+ .word reset ; $FFDA - TB1_1
+ .word reset ; $FFDC - TB1_0
+ .word reset ; $FFDE - I/O Port P1
+
+
+; .org BSL_PASSWORD ;Start of BSL PASSWORD
+ .word reset ; $FFE0 - TA1_1
+ .word reset ; $FFE2 - TA1_0
+ .word reset ; $FFE4 - DMA
+ .word reset ; $FFE6 - eUSCI_A1
+ .word reset ; $FFE8 - TA0_1
+ .word reset ; $FFEA - TA0_0
+ .word reset ; $FFEC - ADC12_B
+ .word reset ; $FFEE - eUSCI_B0
+TERMVEC .word TERMINAL_INT ; $FFF0 - eUSCI_A0
+ .word reset ; $FFF2 - Watchdog
+ .word reset ; $FFF4 - TB0_1
+ .word reset ; $FFF6 - TB0_0
+ .word reset ; $FFF8 - COMP_D
+ .word reset ; $FFFA - userNMI
+ .word reset ; $FFFC - sysNMI
+RST_ADR .word reset ; $FFFE - reset
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : RTC REGISTERS
+; ----------------------------------------------------------------------
+RTCCTL01 .equ RTC_B_SFR + 00h
+RTCCTL0 .equ RTC_B_SFR + 00h
+RTCCTL1 .equ RTC_B_SFR + 01h
+RTCCTL23 .equ RTC_B_SFR + 02h
+RTCPS0CTL .equ RTC_B_SFR + 08h
+RTCPS1CTL .equ RTC_B_SFR + 0Ah
+RTCPS .equ RTC_B_SFR + 0Ch
+RTCIV .equ RTC_B_SFR + 0Eh
+RTCSEC .equ RTC_B_SFR + 10h
+RTCMIN .equ RTC_B_SFR + 11h
+RTCHOUR .equ RTC_B_SFR + 12h
+RTCDOW .equ RTC_B_SFR + 13h
+RTCDAY .equ RTC_B_SFR + 14h
+RTCMON .equ RTC_B_SFR + 15h
+RTCYEAR .equ RTC_B_SFR + 16h
+
+RTCHOLD .equ 40h
+RTCRDY .equ 10h
+
+
+ .ENDIF ; MSP430FR5948
+
+
+
+ .IF DEVICE = "MSP430FR5969"
+
+; ----------------------------------------------------------------------
+; MSP430FR5969 Peripheral File Map
+; ----------------------------------------------------------------------
+SFR_SFR .set 0100h ; Special function
+PMM_SFR .set 0120h ; PMM
+FRAM_SFR .set 0140h ; FRAM control
+CRC16_SFR .set 0150h
+WDT_A_SFR .set 015Ch ; Watchdog
+CS_SFR .set 0160h ; Clock System
+SYS_SFR .set 0180h ; SYS
+REF_SFR .set 01B0h ; REF
+PA_SFR .set 0200h ; PORT1/2
+PB_SFR .set 0220h ; PORT3/4
+PJ_SFR .set 0320h ; PORTJ
+TA0_SFR .set 0340h
+TA1_SFR .set 0380h
+TB0_SFR .set 03C0h
+TA2_SFR .set 0400h
+CTIO0_SFR .set 0430h ; Capacitive Touch IO
+TA3_SFR .set 0440h
+CTIO1_SFR .set 0470h ; Capacitive Touch IO
+RTC_B_SFR .set 04A0h
+MPY_SFR .set 04C0h
+DMA_CTRL_SFR .set 0500h
+DMA_CHN0_SFR .set 0510h
+DMA_CHN1_SFR .set 0520h
+DMA_CHN2_SFR .set 0530h
+MPU_SFR .set 05A0h ; memory protect unit
+eUSCI_A0_SFR .set 05C0h ; eUSCI_A0
+eUSCI_A1_SFR .set 05E0h ; eUSCI_A1
+eUSCI_B0_SFR .set 0640h ; eUSCI_B0
+ADC12_B_SFR .set 0800h
+COMP_E_SFR .set 08C0h
+AES_SFR .set 09C0h
+
+; ----------------------------------------------
+; MSP430FR5969 MEMORY MAP
+; ----------------------------------------------
+; 0000-0FFF = peripherals (4 KB)
+; 1000-17FF = ROM bootstrap loader BSL0..3 (4x512 B)
+; 1800-187F = FRAM info D (128 B)
+; 1880-18FF = FRAM info C (128 B)
+; 1900-197F = FRAM info B (128 B)
+; 1980-19FF = FRAM info A (128 B)
+; 1A00-1AFF = FRAM TLV device descriptor info (256 B)
+; 1B00-1BFF = unused (256 B)
+; 1C00-23FF = RAM (2KB)
+; 23FF-43FF = unused (8kB)
+; 4400-FF7F = FRAM code memory (FRAM) (MSP430FR59x8/9)
+; 8000-FF7F = FRAM code memory (FRAM) (MSP430FR59x7/8/9)
+; FF80-FFFF = FRAM interrupt vectors and signatures (FRAM)
+; 10000-13FFF = FRAM (MSP430FR59x9)
+
+; ----------------------------------------------
+PAGESIZE .equ 512 ; MPU unit
+; ----------------------------------------------
+; BSL
+; ----------------------------------------------
+BSL .equ 1000h
+; ----------------------------------------------
+; FRAM ; INFO B, A, TLV
+; ----------------------------------------------
+INFOSTART .equ 01800h
+INFODSTART .equ 01800h
+INFODEND .equ 0187Fh
+INFOCSTART .equ 01880h
+INFOCEND .equ 018FFh
+INFOBSTART .equ 01900h
+INFOBEND .equ 0197Fh
+INFOASTART .equ 01980h
+INFOAEND .equ 019FFh
+TLVSTART .equ 01A00h ; Device Descriptor Info (Tag-Lenght-Value)
+TLVEND .equ 01AFFh ;
+; ----------------------------------------------
+; RAM
+; ----------------------------------------------
+RAMSTART .equ 01C00h
+RAMEND .equ 023FFh
+; ----------------------------------------------
+; FRAM
+; ----------------------------------------------
+PROGRAMSTART .equ 04400h ; Code space start
+FRAMEND .equ 0FFFFh ; 48 k FRAM
+SIGNATURES .equ 0FF80h ; JTAG/BSL signatures
+JTAG_SIG1 .equ 0FF80h ; if 0, enable JTAG/SBW
+JTAG_SIG2 .equ 0FF82h ; if JTAG_SIG1=0xAAAA, length of password string @ JTAG_PASSWORD
+BSL_SIG1 .equ 0FF84h ;
+BSL_SIG2 .equ 0FF86h ;
+JTAG_PASSWORD .equ 0FF88h ; 256 bits max
+IPE_SIG_VALID .equ 0FF88h ; one word
+IPE_STR_PTR_SRC .equ 0FF8Ah ; one word
+INTVECT .equ 0FFCCh ; FFCC-FFFF
+BSL_PASSWORD .equ 0FFE0h ; 256 bits
+; ----------------------------------------------
+; .org SIGNATURES
+;;Start of JTAG and BSL signatures
+; .word 0 ; JTAG signature 1
+; .word 0 ; JTAG signature 2
+; .word 0;5555h ; BSL signature 1, disable BSL
+; .word 0 ; BSL signature 2
+
+; .org JTAG_PASSWORD ;Start of JTAG PASSWORD
+
+ .org INTVECT ; FFCC-FFFF 25 vectors + reset
+ .word reset ; $FFCC - AES
+ .word reset ; $FFCE - RTC_B
+ .word reset ; $FFD0 - I/O Port 4
+ .word reset ; $FFD2 - I/O Port 3
+ .word reset ; $FFD4 - TB2_1
+ .word reset ; $FFD6 - TB2_0
+ .word reset ; $FFD8 - I/O Port P2
+ .word reset ; $FFDA - TB1_1
+ .word reset ; $FFDC - TB1_0
+ .word reset ; $FFDE - I/O Port P1
+
+
+; .org BSL_PASSWORD ;Start of BSL PASSWORD
+ .word reset ; $FFE0 - TA1_1
+ .word reset ; $FFE2 - TA1_0
+ .word reset ; $FFE4 - DMA
+ .word reset ; $FFE6 - eUSCI_A1
+ .word reset ; $FFE8 - TA0_1
+ .word reset ; $FFEA - TA0_0
+ .word reset ; $FFEC - ADC12_B
+ .word reset ; $FFEE - eUSCI_B0
+TERMVEC .word TERMINAL_INT ; $FFF0 - eUSCI_A0
+ .word reset ; $FFF2 - Watchdog
+ .word reset ; $FFF4 - TB0_1
+ .word reset ; $FFF6 - TB0_0
+ .word reset ; $FFF8 - COMP_D
+ .word reset ; $FFFA - userNMI
+ .word reset ; $FFFC - sysNMI
+RST_ADR .word reset ; $FFFE - reset
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : RTC REGISTERS
+; ----------------------------------------------------------------------
+RTCCTL01 .equ RTC_B_SFR + 00h
+RTCCTL0 .equ RTC_B_SFR + 00h
+RTCCTL1 .equ RTC_B_SFR + 01h
+RTCCTL23 .equ RTC_B_SFR + 02h
+RTCPS0CTL .equ RTC_B_SFR + 08h
+RTCPS1CTL .equ RTC_B_SFR + 0Ah
+RTCPS .equ RTC_B_SFR + 0Ch
+RTCIV .equ RTC_B_SFR + 0Eh
+RTCSEC .equ RTC_B_SFR + 10h
+RTCMIN .equ RTC_B_SFR + 11h
+RTCHOUR .equ RTC_B_SFR + 12h
+RTCDOW .equ RTC_B_SFR + 13h
+RTCDAY .equ RTC_B_SFR + 14h
+RTCMON .equ RTC_B_SFR + 15h
+RTCYEAR .equ RTC_B_SFR + 16h
+
+RTCHOLD .equ 40h
+RTCRDY .equ 10h
+
+ .ENDIF ; MSP430FR5969
+
+
+
+
+
+
+ .IF DEVICE = "MSP430FR5994"
+
+; ----------------------------------------------------------------------
+; MSP430FR5994 Peripheral File Map
+; ----------------------------------------------------------------------
+SFR_SFR .set 0100h ; Special function
+PMM_SFR .set 0120h ; PMM
+FRAM_SFR .set 0140h ; FRAM control
+CRC16_SFR .set 0150h
+RAM_SFR .set 0158h
+WDT_A_SFR .set 015Ch ; Watchdog
+CS_SFR .set 0160h ; Clock System
+SYS_SFR .set 0180h ; SYS
+REF_SFR .set 01B0h ; REF
+PA_SFR .set 0200h ; PORT1/2
+PB_SFR .set 0220h ; PORT3/4
+PC_SFR .set 0240h ; PORT3/4
+PD_SFR .set 0260h ; PORT3/4
+PJ_SFR .set 0320h ; PORTJ
+TA0_SFR .set 0340h
+TA1_SFR .set 0380h
+TB0_SFR .set 03C0h
+TA2_SFR .set 0400h
+CTIO0_SFR .set 0430h ; Capacitive Touch IO
+TA3_SFR .set 0440h
+CTIO1_SFR .set 0470h ; Capacitive Touch IO
+RTC_C_SFR .set 04A0h
+MPY_SFR .set 04C0h
+DMA_CTRL_SFR .set 0500h
+DMA_CHN0_SFR .set 0510h
+DMA_CHN1_SFR .set 0520h
+DMA_CHN2_SFR .set 0530h
+DMA_CHN3_SFR .set 0540h
+DMA_CHN4_SFR .set 0550h
+DMA_CHN5_SFR .set 0560h
+MPU_SFR .set 05A0h ; memory protect unit
+eUSCI_A0_SFR .set 05C0h ; eUSCI_A0
+eUSCI_A1_SFR .set 05E0h ; eUSCI_A1
+eUSCI_A2_SFR .set 0600h ; eUSCI_A1
+eUSCI_A3_SFR .set 0620h ; eUSCI_A1
+eUSCI_B0_SFR .set 0640h ; eUSCI_B0
+eUSCI_B1_SFR .set 0680h ; eUSCI_B0
+eUSCI_B2_SFR .set 06C0h ; eUSCI_B0
+eUSCI_B3_SFR .set 0700h ; eUSCI_B0
+TA4_SFR .set 07C0h
+ADC12_B_SFR .set 0800h
+COMP_E_SFR .set 08C0h
+CRC32_SFR .set 0980h
+AES_SFR .set 09C0h
+LEA_SFR .set 0A80h
+
+; ----------------------------------------------
+; MSP430FR5994 MEMORY MAP
+; ----------------------------------------------
+; 000A-001F = tiny RAM
+; 0020-0FFF = peripherals (4 KB)
+; 1000-17FF = ROM bootstrap loader BSL0..3 (4x512 B)
+; 1800-187F = FRAM info D (128 B)
+; 1880-18FF = FRAM info C (128 B)
+; 1900-197F = FRAM info B (128 B)
+; 1980-19FF = FRAM info A (128 B)
+; 1A00-1AFF = FRAM TLV device descriptor info (256 B)
+; 1B00-1BFF = unused (256 B)
+; 1C00-2BFF = RAM (4KB)
+; 2C00-3BFF = sharedRAM (4kB)
+; 4400-FF7F = FRAM code memory (FRAM) (MSP430FR59x8/9)
+; 8000-FF7F = FRAM code memory (FRAM) (MSP430FR59x7/8/9)
+; FF80-FFFF = FRAM interrupt vectors and signatures (FRAM)
+
+; ----------------------------------------------
+PAGESIZE .equ 512 ; MPU unit
+; ----------------------------------------------
+; BSL
+; ----------------------------------------------
+BSL .equ 1000h
+; ----------------------------------------------
+; FRAM ; INFO B, A, TLV
+; ----------------------------------------------
+INFOSTART .equ 01800h
+INFODSTART .equ 01800h
+INFODEND .equ 0187Fh
+INFOCSTART .equ 01880h
+INFOCEND .equ 018FFh
+INFOBSTART .equ 01900h
+INFOBEND .equ 0197Fh
+INFOASTART .equ 01980h
+INFOAEND .equ 019FFh
+TLVSTART .equ 01A00h ; Device Descriptor Info (Tag-Lenght-Value)
+TLVEND .equ 01AFFh ;
+; ----------------------------------------------
+; RAM
+; ----------------------------------------------
+TinyRAM .equ 00Ah
+TinyRAMEnd .equ 01Fh
+RAMSTART .equ 01C00h
+RAMEND .equ 02BFFh
+SharedRAMSTART .equ 02C00h
+SharedRAMEND .equ 03BFFh
+; ----------------------------------------------
+; FRAM
+; ----------------------------------------------
+PROGRAMSTART .equ 04000h ; Code space start
+FRAMEND .equ 043FFFh ; 256 k FRAM
+SIGNATURES .equ 0FF80h ; JTAG/BSL signatures
+JTAG_SIG1 .equ 0FF80h ; if 0, enable JTAG/SBW
+JTAG_SIG2 .equ 0FF82h ; if JTAG_SIG1=0xAAAA, length of password string @ JTAG_PASSWORD
+BSL_SIG1 .equ 0FF84h ;
+BSL_SIG2 .equ 0FF86h ;
+JTAG_PASSWORD .equ 0FF88h ; 256 bits max
+IPE_SIG_VALID .equ 0FF88h ; one word
+IPE_STR_PTR_SRC .equ 0FF8Ah ; one word
+INTVECT .equ 0FFB4h ; FFB4-FFFF
+BSL_PASSWORD .equ 0FFE0h ; 256 bits
+; ----------------------------------------------
+; .org SIGNATURES
+;;Start of JTAG and BSL signatures
+; .word 0 ; JTAG signature 1
+; .word 0 ; JTAG signature 2
+; .word 0;5555h ; BSL signature 1, disable BSL
+; .word 0 ; BSL signature 2
+
+; .org JTAG_PASSWORD ;Start of JTAG PASSWORD
+
+ .org INTVECT ; FFB4-FFFF 37 vectors + reset
+ .word reset ; 0FFB4h - LEA_Vec
+ .word reset ; 0FFB6h - P8_Vec
+ .word reset ; 0FFB8h - P7_Vec
+ .word reset ; 0FFBAh - eUSCI_B3_Vec
+ .word reset ; 0FFBCh - eUSCI_B2_Vec
+ .word reset ; 0FFBEh - eUSCI_B1_Vec
+ .word reset ; 0FFC0h - eUSCI_A3_Vec
+ .word reset ; 0FFC2h - eUSCI_A2_Vec
+ .word reset ; 0FFC4h - P6_Vec
+ .word reset ; 0FFC6h - P5_Vec
+ .word reset ; 0FFC8h - TA4_x_Vec
+ .word reset ; 0FFCAh - TA4_0_Vec
+ .word reset ; 0FFCCh - AES_Vec
+ .word reset ; 0FFCEh - RTC_C_Vec
+ .word reset ; 0FFD0h - P4_Vec=
+ .word reset ; 0FFD2h - P3_Vec=
+ .word reset ; 0FFD4h - TA3_x_Vec
+ .word reset ; 0FFD6h - TA3_0_Vec
+ .word reset ; 0FFD8h - P2_Vec
+ .word reset ; 0FFDAh - TA2_x_Vec
+ .word reset ; 0FFDCh - TA2_0_Vec
+ .word reset ; 0FFDEh - P1_Vec=
+; .org BSL_PASSWORD ;Start of BSL PASSWORD
+ .word reset ; 0FFE0h - TA1_x_Vec
+ .word reset ; 0FFE2h - TA1_0_Vec
+ .word reset ; 0FFE4h - DMA_Vec
+ .word reset ; 0FFE6h - eUSCI_A1_Vec
+ .word reset ; 0FFE8h - TA0_x_Vec
+ .word reset ; 0FFEAh - TA0_0_Vec
+ .word reset ; 0FFECh - ADC12_B_Vec
+ .word reset ; 0FFEEh - eUSCI_B0_Vec
+TERMVEC .word TERMINAL_INT ; 0FFF0h - eUSCI_A0_Vec
+ .word reset ; 0FFF2h - WDT_Vec
+ .word reset ; 0FFF4h - TB0_x_Vec
+ .word reset ; 0FFF6h - TB0_0_Vec
+ .word reset ; 0FFF8h - COMP_E_Vec
+ .word reset ; 0FFFAh - U_NMI_Vec
+ .word reset ; 0FFFCh - S_NMI_Vec
+RST_ADR .word reset ; 0FFFEh - RST_Vec
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT5/6
+; ----------------------------------------------------------------------
+
+PCIN .equ PC_SFR + 00h ; Port C Input
+PCOUT .equ PC_SFR + 02h ; Port C Output
+PCDIR .equ PC_SFR + 04h ; Port C Direction
+PCREN .equ PC_SFR + 06h ; Port C Resistor Enable
+PCSEL0 .equ PC_SFR + 0Ah ; Port C Selection 0
+PCSEL1 .equ PC_SFR + 0Ch ; Port C Selection 1
+PCSELC .equ PC_SFR + 16h ; Port C Complement Selection
+PCIES .equ PC_SFR + 18h ; Port C Interrupt Edge Select
+PCIE .equ PC_SFR + 1Ah ; Port C Interrupt Enable
+PCIFG .equ PC_SFR + 1Ch ; Port C Interrupt Flag
+
+P5IN .equ PC_SFR + 00h ; Port 5 Input
+P5OUT .equ PC_SFR + 02h ; Port 5 Output
+P5DIR .equ PC_SFR + 04h ; Port 5 Direction
+P5REN .equ PC_SFR + 06h ; Port 5 Resistor Enable
+P5SEL0 .equ PC_SFR + 0Ah ; Port 5 Selection 0
+P5SEL1 .equ PC_SFR + 0Ch ; Port 5 Selection 1
+P5IV .equ PC_SFR + 0Eh ; Port 5 Interrupt Vector word
+P5SELC .set PC_SFR + 16h ; Port 5 Complement Selection
+P5IES .equ PC_SFR + 18h ; Port 5 Interrupt Edge Select
+P5IE .equ PC_SFR + 1Ah ; Port 5 Interrupt Enable
+P5IFG .equ PC_SFR + 1Ch ; Port 5 Interrupt Flag
+
+P6IN .equ PC_SFR + 01h ; Port 6 Input
+P6OUT .equ PC_SFR + 03h ; Port 6 Output
+P6DIR .equ PC_SFR + 05h ; Port 6 Direction
+P6REN .equ PC_SFR + 07h ; Port 6 Resistor Enable
+P6SEL0 .equ PC_SFR + 0Bh ; Port 6 Selection 0
+P6SEL1 .equ PC_SFR + 0Dh ; Port 6 Selection 1
+P6SELC .set PC_SFR + 17h ; Port 6 Complement Selection
+P6IES .equ PC_SFR + 19h ; Port 6 Interrupt Edge Select
+P6IE .equ PC_SFR + 1Bh ; Port 6 Interrupt Enable
+P6IFG .equ PC_SFR + 1Dh ; Port 6 Interrupt Flag
+P6IV .equ PC_SFR + 1Eh ; Port 6 Interrupt Vector word
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT7/8
+; ----------------------------------------------------------------------
+
+PDIN .equ PD_SFR + 00h ; Port D Input
+PDOUT .equ PD_SFR + 02h ; Port D Output
+PDDIR .equ PD_SFR + 04h ; Port D Direction
+PDREN .equ PD_SFR + 06h ; Port D Resistor Enable
+PDSEL0 .equ PD_SFR + 0Ah ; Port D Selection 0
+PDSEL1 .equ PD_SFR + 0Ch ; Port D Selection 1
+PDSELC .equ PD_SFR + 16h ; Port D Complement Selection
+PDIES .equ PD_SFR + 18h ; Port D Interrupt Edge Select
+PDIE .equ PD_SFR + 1Ah ; Port D Interrupt Enable
+PDIFG .equ PD_SFR + 1Ch ; Port D Interrupt Flag
+
+P7IN .equ PD_SFR + 00h ; Port 7 Input
+P7OUT .equ PD_SFR + 02h ; Port 7 Output
+P7DIR .equ PD_SFR + 04h ; Port 7 Direction
+P7REN .equ PD_SFR + 06h ; Port 7 Resistor Enable
+P7SEL0 .equ PD_SFR + 0Ah ; Port 7 Selection 0
+P7SEL1 .equ PD_SFR + 0Ch ; Port 7 Selection 1
+P7IV .equ PD_SFR + 0Eh ; Port 7 Interrupt Vector word
+P7SELC .set PD_SFR + 16h ; Port 7 Complement Selection
+P7IES .equ PD_SFR + 18h ; Port 7 Interrupt Edge Select
+P7IE .equ PD_SFR + 1Ah ; Port 7 Interrupt Enable
+P7IFG .equ PD_SFR + 1Ch ; Port 7 Interrupt Flag
+
+P8IN .equ PD_SFR + 01h ; Port 8 Input
+P8OUT .equ PD_SFR + 03h ; Port 8 Output
+P8DIR .equ PD_SFR + 05h ; Port 8 Direction
+P8REN .equ PD_SFR + 07h ; Port 8 Resistor Enable
+P8SEL0 .equ PD_SFR + 0Bh ; Port 8 Selection 0
+P8SEL1 .equ PD_SFR + 0Dh ; Port 8 Selection 1
+P8SELC .set PD_SFR + 16h ; Port 8 Complement Selection
+P8IES .equ PD_SFR + 19h ; Port 8 Interrupt Edge Select
+P8IE .equ PD_SFR + 1Bh ; Port 8 Interrupt Enable
+P8IFG .equ PD_SFR + 1Dh ; Port 8 Interrupt Flag
+P8IV .equ PD_SFR + 1Eh ; Port 8 Interrupt Vector word
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : RTC REGISTERS
+; ----------------------------------------------------------------------
+RTCCTL0_L .set RTC_C_SFR + 00h
+RTCCTL0_H .set RTC_C_SFR + 01h
+RTCCTL1 .set RTC_C_SFR + 02h
+RTCCTL3 .set RTC_C_SFR + 03h
+RTCOCAL .set RTC_C_SFR + 04h
+RTCTCMP .set RTC_C_SFR + 06h
+RTCPS0CTL .set RTC_C_SFR + 08h
+RTCPS1CTL .set RTC_C_SFR + 0Ah
+RTCPS .set RTC_C_SFR + 0Ch
+RTCIV .set RTC_C_SFR + 0Eh
+RTCSEC .set RTC_C_SFR + 10h
+RTCMIN .set RTC_C_SFR + 11h
+RTCHOUR .set RTC_C_SFR + 12h
+RTCDOW .set RTC_C_SFR + 13h
+RTCDAY .set RTC_C_SFR + 14h
+RTCMON .set RTC_C_SFR + 15h
+RTCYEAR .set RTC_C_SFR + 16h
+
+
+RTCHOLD .set 40h
+RTCRDY .set 10h
+
+ .ENDIF ; MSP_EXP430FR5994
+
+
+
+
+ .IF DEVICE = "MSP430FR6989"
+
+; ----------------------------------------------------------------------
+; EXP430FR6989 Peripheral File Map
+; ----------------------------------------------------------------------
+SFR_SFR .set 0100h ; Special function
+PMM_SFR .set 0120h ; PMM
+FRAM_SFR .set 0140h ; FRAM control
+CRC16_SFR .set 0150h
+RAMC_SFR .set 0158h ; RAM controller
+WDT_A_SFR .set 015Ch ; Watchdog
+CS_SFR .set 0160h ; Clock System
+SYS_SFR .set 0180h ; SYS
+REF_SFR .set 01B0h ; shared REF
+PA_SFR .set 0200h ; PORT1/2
+PB_SFR .set 0220h ; PORT3/4
+PC_SFR .set 0240h ; PORT5/6
+PD_SFR .set 0260h ; PORT7/8
+PE_SFR .set 0280h ; PORT9/10
+PJ_SFR .set 0320h ; PORTJ
+TA0_SFR .set 0340h
+TA1_SFR .set 0380h
+TB0_SFR .set 03C0h
+TA2_SFR .set 0400h
+CTIO0_SFR .set 0430h ; Capacitive Touch IO
+TA3_SFR .set 0440h
+CTIO1_SFR .set 0470h ; Capacitive Touch IO
+RTC_C_SFR .set 04A0h
+MPY_SFR .set 04C0h
+DMA_CTRL_SFR .set 0500h
+DMA_CHN0_SFR .set 0510h
+DMA_CHN1_SFR .set 0520h
+DMA_CHN2_SFR .set 0530h
+MPU_SFR .set 05A0h ; memory protect unit
+eUSCI_A0_SFR .set 05C0h ; eUSCI_A0
+eUSCI_A1_SFR .set 05E0h ; eUSCI_A1
+eUSCI_B0_SFR .set 0640h ; eUSCI_B0
+eUSCI_B1_SFR .set 0680h ; eUSCI_B1
+ADC12_B_SFR .set 0800h
+COMP_E_SFR .set 08C0h
+CRC32_SFR .set 0980h
+AES_SFR .set 09C0h
+LCD_SFR .set 0A00h
+ESI_SFR .set 0D00h
+ESI_RAM .set 0E00h ; 128 bytes
+
+; ----------------------------------------------
+; MSP430FR6989 MEMORY MAP
+; ----------------------------------------------
+
+; 0020-0FFF = peripherals (4 KB)
+; 1000-17FF = BootStrap Loader BSL0..3 (ROM 4x512 B)
+; 1800-187F = info D (FRAM 128 B)
+; 1880-18FF = info C (FRAM 128 B)
+; 1900-197F = info B (FRAM 128 B)
+; 1980-19FF = info A (FRAM 128 B)
+; 1A00-1AFF = TLV device descriptor info (FRAM 256 B)
+; 1B00-1BFF = Boot memory (ROM 256 B)
+; 1C00-23FF = RAM (2 KB)
+; 2000-43FF = unused
+; 4400-FF7F = code memory (FRAM 47999 B)
+; FF80-FFFF = interrupt vectors (FRAM 128 B)
+; 10000-23FFF = FRAM
+; ----------------------------------------------
+PAGESIZE .equ 512 ; MPU unit
+; ----------------------------------------------
+; FRAM ; INFO{D,C,B,A},TLV
+; ----------------------------------------------
+INFOSTART .equ 01800h
+INFODSTART .equ 01800h
+INFODEND .equ 0187Fh
+INFOCSTART .equ 01880h
+INFOCEND .equ 018FFh
+INFOBSTART .equ 01900h
+INFOBEND .equ 0197Fh
+INFOASTART .equ 01980h
+INFOAEND .equ 019FFh
+TLVSTAT .equ 01A00h ; Device Descriptor Info (Tag-Lenght-Value)
+TLVEND .equ 01AFFh ;
+; ----------------------------------------------
+; RAM
+; ----------------------------------------------
+RAMSTART .equ 01C00h
+RAMEND .equ 023FFh
+; ----------------------------------------------
+; FRAM
+; ----------------------------------------------
+PROGRAMSTART .equ 04400h ; Code space start
+SIGNATURES .equ 0FF80h ; JTAG, BSL and IP Encapsulation signatures 1 and 2
+JTAG_SIG1 .equ 0FF80h ; if 0, enable JTAG/SBW
+JTAG_SIG2 .equ 0FF82h ; if JTAG_SIG1=0xAAAA, length of password string @ JTAG_PASSWORD
+BSL_SIG1 .equ 0FF84h ;
+BSL_SIG2 .equ 0FF86h ;
+JTAG_PASSWORD .equ 0FF86h ; up to 0FFC5h : 256 bits
+INTVECT .equ 0FFC6h ; FFC6-FFFF
+BSL_PASSWORD .equ 0FFE0h ; up to 0FFFFh : 256 bits
+; ----------------------------------------------
+; ----------------------------------------------
+; Interrupt Vectors and signatures - MSP430FR6989
+; ----------------------------------------------
+
+; .org SIGNATURES
+;;Start of JTAG and BSL signatures
+; .word 0 ; JTAG signature 1
+; .word 0 ; JTAG signature 2
+; .word 0;5555h ; BSL signature 1, disable BSL
+; .word 0 ; BSL signature 2
+
+; .org JTAG_PASSWORD ;Start of JTAG PASSWORD
+
+ .org INTVECT ; FFC6-FFFF 28 vectors + reset
+ .word reset ; $FFC6 - AES
+ .word reset ; $FFC8 - RTC_C
+ .word reset ; $FFCA - LCD_C
+ .word reset ; $FFCC - I/O Port 4
+ .word reset ; $FFCE - I/O Port 3
+ .word reset ; $FFD0 - TA3_x
+ .word reset ; $FFD2 - TA3_0
+ .word reset ; $FFD4 - I/O Port P2
+ .word reset ; $FFD6 - TA2_x
+ .word reset ; $FFD8 - TA2_0
+ .word reset ; $FFDA - I/O Port P1
+ .word reset ; $FFDC - TA1_x
+ .word reset ; $FFDE - TA1_0
+; .org BSL_PASSWORD ;Start of BSL PASSWORD
+ .word reset ; $FFE0 - DMA
+ .word reset ; $FFE2 - eUSCI_B1
+TERMVEC .word TERMINAL_INT ; $FFE4 - eUSCI_A1
+ .word reset ; $FFE6 - TA0_x
+ .word reset ; $FFE8 - TA0_0
+ .word reset ; $FFEA - ADC12_B
+ .word reset ; $FFEC - eUSCI_B0
+ .word reset ; $FFEE - eUSCI_A0
+ .word reset ; $FFF0 - Extended Scan IF
+ .word reset ; $FFF2 - Watchdog
+ .word reset ; $FFF4 - TB0_x
+ .word reset ; $FFF6 - TB0_0
+ .word reset ; $FFF8 - COMP_E
+ .word reset ; $FFFA - userNMI
+ .word reset ; $FFFC - sysNMI
+RST_ADR .word reset ; $FFFE - reset
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT5/6
+; ----------------------------------------------------------------------
+
+PCIN .set PC_SFR + 00h ; Port C Input
+PCOUT .set PC_SFR + 02h ; Port C Output 1/0 or pullup/pulldown resistor
+PCDIR .set PC_SFR + 04h ; Port C Direction
+PCREN .set PC_SFR + 06h ; Port C Resistor Enable
+PCSEL0 .set PC_SFR + 0Ah ; Port C Selection 0
+PCSEL1 .set PC_SFR + 0Ch ; Port C Selection 1
+PCSELC .set PC_SFR + 16h ; Port C Complement Selection
+
+P5IN .set PC_SFR + 00h ; Port 5 Input */
+P5OUT .set PC_SFR + 02h ; Port 5 Output
+P5DIR .set PC_SFR + 04h ; Port 5 Direction
+P5REN .set PC_SFR + 06h ; Port 5 Resistor Enable
+P5SEL0 .set PC_SFR + 0Ah ; Port 5 Selection 0
+P5SEL1 .set PC_SFR + 0Ch ; Port 5 Selection 1
+P5SELC .set PC_SFR + 16h ; Port 5 Complement Selection
+
+P6IN .set PC_SFR + 01h ; Port 6 Input */
+P6OUT .set PC_SFR + 03h ; Port 6 Output
+P6DIR .set PC_SFR + 05h ; Port 6 Direction
+P6REN .set PC_SFR + 07h ; Port 6 Resistor Enable
+P6SEL0 .set PC_SFR + 0Bh ; Port 6 Selection 0
+P6SEL1 .set PC_SFR + 0Dh ; Port 6 Selection 1
+P6SELC .set PC_SFR + 17h ; Port 6 Complement Selection
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT7/8
+; ----------------------------------------------------------------------
+
+PDIN .set PD_SFR + 00h ; Port D Input
+PDOUT .set PD_SFR + 02h ; Port D Output 1/0 or pullup/pulldown resistor
+PDDIR .set PD_SFR + 04h ; Port D Direction
+PDREN .set PD_SFR + 06h ; Port D Resistor Enable
+PDSEL0 .set PD_SFR + 0Ah ; Port D Selection 0
+PDSEL1 .set PD_SFR + 0Ch ; Port D Selection 1
+PDSELC .set PD_SFR + 16h ; Port D Complement Selection
+
+P7IN .set PD_SFR + 00h ; Port 7 Input */
+P7OUT .set PD_SFR + 02h ; Port 7 Output
+P7DIR .set PD_SFR + 04h ; Port 7 Direction
+P7REN .set PD_SFR + 06h ; Port 7 Resistor Enable
+P7SEL0 .set PD_SFR + 0Ah ; Port 7 Selection 0
+P7SEL1 .set PD_SFR + 0Ch ; Port 7 Selection 1
+P7SELC .set PD_SFR + 16h ; Port 7 Complement Selection
+
+P8IN .set PD_SFR + 01h ; Port 8 Input */
+P8OUT .set PD_SFR + 03h ; Port 8 Output
+P8DIR .set PD_SFR + 05h ; Port 8 Direction
+P8REN .set PD_SFR + 07h ; Port 8 Resistor Enable
+P8SEL0 .set PD_SFR + 0Bh ; Port 8 Selection 0
+P8SEL1 .set PD_SFR + 0Dh ; Port 8 Selection 1
+P8SELC .set PD_SFR + 17h ; Port 8 Complement Selection
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT9/10
+; ----------------------------------------------------------------------
+
+PEIN .set PE_SFR + 00h ; Port E Input
+PEOUT .set PE_SFR + 02h ; Port E Output 1/0 or pullup/pulldown resistor
+PEDIR .set PE_SFR + 04h ; Port E Direction
+PEREN .set PE_SFR + 06h ; Port E Resistor Enable
+PESEL0 .set PE_SFR + 0Ah ; Port E Selection 0
+PESEL1 .set PE_SFR + 0Ch ; Port E Selection 1
+PESELC .set PE_SFR + 16h ; Port E Complement Selection
+
+P9IN .set PE_SFR + 00h ; Port 9 Input */
+P9OUT .set PE_SFR + 02h ; Port 9 Output
+P9DIR .set PE_SFR + 04h ; Port 9 Direction
+P9REN .set PE_SFR + 06h ; Port 9 Resistor Enable
+P9SEL0 .set PE_SFR + 0Ah ; Port 9 Selection 0
+P9SEL1 .set PE_SFR + 0Ch ; Port 9 Selection 1
+P9SELC .set PE_SFR + 16h ; Port 9 Complement Selection
+
+P10IN .set PE_SFR + 01h ; Port 10 Input */
+P10OUT .set PE_SFR + 03h ; Port 10 Output
+P10DIR .set PE_SFR + 05h ; Port 10 Direction
+P10REN .set PE_SFR + 07h ; Port 10 Resistor Enable
+P10SEL0 .set PE_SFR + 0Bh ; Port 10 Selection 0
+P10SEL1 .set PE_SFR + 0Dh ; Port 10 Selection 1
+P10SELC .set PE_SFR + 17h ; Port 10 Complement Selection
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : RTC_C REGISTERS
+; ----------------------------------------------------------------------
+RTCCTL0_L .set RTC_C_SFR + 00h
+RTCCTL0_H .set RTC_C_SFR + 01h
+RTCCTL1 .set RTC_C_SFR + 02h
+RTCCTL3 .set RTC_C_SFR + 03h
+RTCOCAL .set RTC_C_SFR + 04h
+RTCTCMP .set RTC_C_SFR + 06h
+RTCPS0CTL .set RTC_C_SFR + 08h
+RTCPS1CTL .set RTC_C_SFR + 0Ah
+RTCPS .set RTC_C_SFR + 0Ch
+RTCIV .set RTC_C_SFR + 0Eh
+RTCSEC .set RTC_C_SFR + 10h
+RTCMIN .set RTC_C_SFR + 11h
+RTCHOUR .set RTC_C_SFR + 12h
+RTCDOW .set RTC_C_SFR + 13h
+RTCDAY .set RTC_C_SFR + 14h
+RTCMON .set RTC_C_SFR + 15h
+RTCYEAR .set RTC_C_SFR + 16h
+
+RTCHOLD .set 40h
+RTCRDY .set 10h
+
+
+ .ENDIF ; MSP430FR6989
+
+
+
+
+
+
+
+;=======================================================================
+; COMMON PARTS
+;=======================================================================
+
+UCSWRST .equ 1 ; eUSCI Software Reset
+UCTXIE .equ 2 ; eUSCI Transmit Interrupt Enable
+UCRXIE .equ 1 ; eUSCI Receive Interrupt Enable
+UCTXIFG .equ 2 ; eUSCI Transmit Interrupt Flag
+UCRXIFG .equ 1 ; eUSCI Receive Interrupt Flag
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : LOCK PMM_LOCKLPM5
+; ----------------------------------------------------------------------
+PMMCTL0 .set PMM_SFR
+PMMSWBOR .set 4
+
+PM5CTL0 .set PMM_SFR + 10h ; Power mode 5 control register 0
+LOCKLPM5 .set 1
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : WATCHDOG TIMER A
+; ----------------------------------------------------------------------
+
+WDTCTL .equ WDT_A_SFR + 00h ; Watchdog Timer Control */
+
+; WDTCTL Control Bits
+WDTPW .equ 5A00h
+WDTHOLD .equ 0080h ; WDT - Timer hold
+WDTCNTCL .equ 0008h ; WDT timer counter clear
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT1/2
+; ----------------------------------------------------------------------
+
+PAIN .equ PA_SFR + 00h ; Port A INput
+PAOUT .equ PA_SFR + 02h ; Port A OUTput
+PADIR .equ PA_SFR + 04h ; Port A DIRection
+PAREN .equ PA_SFR + 06h ; Port A Resistor ENable
+PASEL0 .equ PA_SFR + 0Ah ; Port A SELection 0
+PASEL1 .equ PA_SFR + 0Ch ; Port A SELection 1
+PASELC .equ PA_SFR + 16h ; Port A SELection Complement
+PAIES .equ PA_SFR + 18h ; Port A Interrupt Edge Select
+PAIE .equ PA_SFR + 1Ah ; Port A Interrupt Enable
+PAIFG .equ PA_SFR + 1Ch ; Port A Interrupt FlaG
+
+P1IN .equ PA_SFR + 00h ; Port 1 INput
+P1OUT .equ PA_SFR + 02h ; Port 1 OUTput
+P1DIR .equ PA_SFR + 04h ; Port 1 DIRection
+P1REN .equ PA_SFR + 06h ; Port 1 Resistor ENable
+P1SEL0 .equ PA_SFR + 0Ah ; Port 1 SELection 0
+P1SEL1 .equ PA_SFR + 0Ch ; Port 1 SELection 1
+P1SELC .equ PA_SFR + 16h ; Port 1 SELection Complement
+P1IES .equ PA_SFR + 18h ; Port 1 Interrupt Edge Select
+P1IE .equ PA_SFR + 1Ah ; Port 1 Interrupt Enable
+P1IFG .equ PA_SFR + 1Ch ; Port 1 Interrupt FlaG
+P1IV .equ PA_SFR + 0Eh ; Port 1 Interrupt Vector word
+
+P2IN .equ PA_SFR + 01h ; Port 2 INput
+P2OUT .equ PA_SFR + 03h ; Port 2 OUTput
+P2DIR .equ PA_SFR + 05h ; Port 2 DIRection
+P2REN .equ PA_SFR + 07h ; Port 2 Resistor ENable
+P2SEL0 .equ PA_SFR + 0Bh ; Port 2 SELection 0
+P2SEL1 .equ PA_SFR + 0Dh ; Port 2 SELection 1
+P2SELC .equ PA_SFR + 17h ; Port 2 SELection Complement
+P2IES .equ PA_SFR + 19h ; Port 2 Interrupt Edge Select
+P2IE .equ PA_SFR + 1Bh ; Port 2 Interrupt Enable
+P2IFG .equ PA_SFR + 1Dh ; Port 2 Interrupt FlaG
+P2IV .equ PA_SFR + 1Eh ; Port 2 Interrupt Vector word
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT3/4
+; ----------------------------------------------------------------------
+
+PBIN .equ PB_SFR + 00h ; Port B Input
+PBOUT .equ PB_SFR + 02h ; Port B Output 1/0 or pullup/pulldown resistor
+PBDIR .equ PB_SFR + 04h ; Port B Direction
+PBREN .equ PB_SFR + 06h ; Port B Resistor Enable
+PBSEL0 .equ PB_SFR + 0Ah ; Port B Selection 0
+PBSEL1 .equ PB_SFR + 0Ch ; Port B Selection 1
+PBSELC .equ PB_SFR + 16h ; Port B Complement Selection
+PBIES .equ PB_SFR + 18h ; Port B Interrupt Edge Select
+PBIE .equ PB_SFR + 1Ah ; Port B Interrupt Enable
+PBIFG .equ PB_SFR + 1Ch ; Port B Interrupt Flag
+
+P3IN .equ PB_SFR + 00h ; Port 3 Input */
+P3OUT .equ PB_SFR + 02h ; Port 3 Output
+P3DIR .equ PB_SFR + 04h ; Port 3 Direction
+P3REN .equ PB_SFR + 06h ; Port 3 Resistor Enable
+P3SEL0 .equ PB_SFR + 0Ah ; Port 3 Selection 0
+P3SEL1 .equ PB_SFR + 0Ch ; Port 3 Selection 1
+P3SELC .equ PB_SFR + 16h ; Port 3 Complement Selection
+P3IES .equ PB_SFR + 18h ; Port 3 Interrupt Edge Select
+P3IE .equ PB_SFR + 1Ah ; Port 3 Interrupt Enable
+P3IFG .equ PB_SFR + 1Ch ; Port 3 Interrupt Flag
+P3IV .equ PB_SFR + 0Eh ; Port 3 Interrupt Vector word
+
+P4IN .equ PB_SFR + 01h ; Port 4 Input */
+P4OUT .equ PB_SFR + 03h ; Port 4 Output
+P4DIR .equ PB_SFR + 05h ; Port 4 Direction
+P4REN .equ PB_SFR + 07h ; Port 4 Resistor Enable
+P4SEL0 .equ PB_SFR + 0Bh ; Port 4 Selection 0
+P4SEL1 .equ PB_SFR + 0Dh ; Port 4 Selection 1
+P4SELC .equ PB_SFR + 17h ; Port 4 Complement Selection
+P4IES .equ PB_SFR + 19h ; Port 4 Interrupt Edge Select
+P4IE .equ PB_SFR + 1Bh ; Port 4 Interrupt Enable
+P4IFG .equ PB_SFR + 1Dh ; Port 4 Interrupt Flag
+P4IV .equ PB_SFR + 1Eh ; Port 4 Interrupt Vector word
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORTJ
+; ----------------------------------------------------------------------
+
+PJIN .equ PJ_SFR + 00h ; Port J INput
+PJOUT .equ PJ_SFR + 02h ; Port J OUTput
+PJDIR .equ PJ_SFR + 04h ; Port J DIRection
+PJREN .equ PJ_SFR + 06h ; Port J Resistor ENable
+PJSEL0 .equ PJ_SFR + 0Ah ; Port 2 SELection 0
+PJSEL1 .equ PJ_SFR + 0Ch ; Port 2 SELection 1
+PJSELC .equ PJ_SFR + 16h ; Port 2 SELection Complement; PJ 5-0 usage
+
+; ----------------------------------------------------------------------
+; FRAM config
+; ----------------------------------------------------------------------
+FRCTL0 .set FRAM_SFR + 00h ; FRAM Controller Control 0
+FRCTL0_H .set FRAM_SFR + 01h ; FRAM Controller Control 0 high byte
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : CLOCK SYSTEM
+; ----------------------------------------------------------------------
+
+CSCTL0 .equ CS_SFR + 00h ; CS Control Register 0
+CSCTL0_H .equ CS_SFR + 01h ; CS Control Register 0 high byte
+CSCTL1 .equ CS_SFR + 02h ; CS Control Register 1
+CSCTL2 .equ CS_SFR + 04h ; CS Control Register 2
+CSCTL3 .equ CS_SFR + 06h ; CS Control Register 3
+
+; CSCTL0 Control Bits
+CSKEY .equ 0A5h ; CS Password
+; CSCTL1 Control Bits
+DCORSEL .equ 0040h
+DCOFSEL0 .equ 0002h ; DCO frequency select Bit: 0
+DCOFSEL1 .equ 0004h ; DCO frequency select Bit: 1
+DCOFSEL2 .equ 0008h ; DCO frequency select Bit: 2
+DCOFSEL3 .equ 000Ch ; DCO frequency select Bit: 21
+; CSCTL2 Control Bits
+SELA_LFXCLK .equ 0000h ; 0 : ACLK Source Select LFXCLK
+SELA_VLOCLK .equ 0100h ; 1 ACLK Source Select VLOCLK 10kHz
+SELS_DCOCLK .equ 0030h ; 3 : SMCLK Source Select DCOCLK
+SELM_DCOCLK .equ 0003h ; 3 : MCLK Source Select DCOCLK
+; CSCTL3 Control Bits
+DIVA_0 .equ 0000h ; ACLK Source Divider 0
+DIVS_0 .equ 0000h ; SMCLK Source Divider 0
+DIVM_0 .equ 0000h ; MCLK Source Divider 0
+DIVA_2 .equ 0100h ; ACLK Source Divider 0
+DIVS_2 .equ 0010h ; SMCLK Source Divider 0
+DIVM_2 .equ 0001h ; MCLK Source Divider 0
+DIVA_4 .equ 0200h ; ACLK Source Divider 0
+DIVS_4 .equ 0020h ; SMCLK Source Divider 0
+DIVM_4 .equ 0002h ; MCLK Source Divider 0
+DIVA_8 .equ 0300h ; ACLK Source Divider 0
+DIVS_8 .equ 0030h ; SMCLK Source Divider 0
+DIVM_8 .equ 0003h ; MCLK Source Divider 0
+DIVA_16 .equ 0400h ; ACLK Source Divider 0
+DIVS_16 .equ 0040h ; SMCLK Source Divider 0
+DIVM_16 .equ 0004h ; MCLK Source Divider 0
+DIVA_32 .equ 0500h ; ACLK Source Divider 0
+DIVS_32 .equ 0050h ; SMCLK Source Divider 0
+DIVM_32 .equ 0005h ; MCLK Source Divider 0
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : REF
+; ----------------------------------------------------------------------
+
+REFCTL equ REF_SFR + 00h ; REF Shared Reference control register 0
+
+; REFCTL0 Control Bits
+REFON equ 0001h ; REF Reference On
+REFTCOFF equ 0008h ; REF Temp.Sensor off
+
+; ----------------------------------------------------------------------
+; MPY_32
+; ----------------------------------------------------------------------
+
+MPY .equ MPY_SFR + 00h ; Multiply16 Unsigned/Operand 1 */
+MPYS .equ MPY_SFR + 02h ; Multiply16 signed/Operand 1
+MAC .equ MPY_SFR + 04h ; MultiplyAccumulate16 Unsigned/Operand 1 */
+MACS .equ MPY_SFR + 06h ; MultiplyAccumulate16 signed/Operand 1
+OP2 .equ MPY_SFR + 08h ; Operand2_16 */
+RESLO .equ MPY_SFR + 0Ah ; 16x16-bit result low - least significant word */
+RESHI .equ MPY_SFR + 0Ch ; 16x16-bit result high */
+SUMEXT .equ MPY_SFR + 0Eh ; 16x16-bit sum extension register
+MPY32L .equ MPY_SFR + 10h ; Multiply32 Unsigned/Operand 1
+MPY32H .equ MPY_SFR + 12h ; Multiply32 Unsigned/Operand 1
+MPYS32L .equ MPY_SFR + 14h ; Multiply32 signed/Operand 1
+MPYS32H .equ MPY_SFR + 16h ; Multiply32 signed/Operand 1
+MAC32L .equ MPY_SFR + 18h ; MultiplyAccumulate32 Unsigned/Operand 1
+MAC32H .equ MPY_SFR + 1Ah ; MultiplyAccumulate32 Unsigned/Operand 1
+MACS32L .equ MPY_SFR + 1Ch ; MultiplyAccumulate32 signed/Operand 1
+MACS32H .equ MPY_SFR + 1Eh ; MultiplyAccumulate32 signed/Operand 1
+OP2L .equ MPY_SFR + 20h ; Multiply32 Operand 2
+OP2H .equ MPY_SFR + 22h ; Multiply32 Operand 2
+RES0 .equ MPY_SFR + 24h ; 32x32-bit result 0 - least significant word */
+RES1 .equ MPY_SFR + 26h ; 32x32-bit result 1 */
+RES2 .equ MPY_SFR + 28h ; 32x32-bit result 2 */
+RES3 .equ MPY_SFR + 2Ah ; 32x32-bit result 3 */
+MPY32CTL0 .equ MPY_SFR + 2Ch ; MPY32 control register 0
+
+
+; ----------------------------------------------------------------------
+; eUSCI_A0
+; ----------------------------------------------------------------------
+
+ .IFDEF UCA0_UART
+TERMCTLW0 .equ eUSCI_A0_SFR + 00h ; eUSCI_A0 Control Word Register 0
+TERMBRW .equ eUSCI_A0_SFR + 06h ; eUSCI_A0 Baud Word Rate 0
+TERMMCTLW .equ eUSCI_A0_SFR + 08h ; eUSCI_A0 Modulation Control
+TERMRXBUF .equ eUSCI_A0_SFR + 0Ch ; eUSCI_A0 Receive Buffer
+TERMTXBUF .equ eUSCI_A0_SFR + 0Eh ; eUSCI_A0 Transmit Buffer
+TERMIE .equ eUSCI_A0_SFR + 1Ah ; eUSCI_A0 Interrupt Enable Register
+TERMIFG .equ eUSCI_A0_SFR + 1Ch ; eUSCI_A0 Interrupt Flags Register
+ .ENDIF ;UCA0_UART
+
+ .IFDEF UCA0_SD
+SD_CTLW0 .equ eUSCI_A0_SFR + 00h ; eUSCI_A0 Control Word Register 0
+SD_BRW .equ eUSCI_A0_SFR + 06h ; eUSCI_A0 Baud Word Rate 0
+SD_RXBUF .equ eUSCI_A0_SFR + 0Ch ; eUSCI_A0 Receive Buffer 8
+SD_TXBUF .equ eUSCI_A0_SFR + 0Eh ; eUSCI_A0 Transmit Buffer 8
+SD_IFG .equ eUSCI_A0_SFR + 1Ch ; eUSCI_A0 Interrupt Flags Register
+ .ENDIF ;UCA0_SD
+
+; ----------------------------------------------------------------------
+; eUSCI_A1
+; ----------------------------------------------------------------------
+
+ .IFDEF UCA1_UART
+TERMCTLW0 .equ eUSCI_A1_SFR + 00h ; eUSCI_A1 Control Word Register 0
+TERMBRW .equ eUSCI_A1_SFR + 06h ; eUSCI_A1 Baud Word Rate 0
+TERMMCTLW .equ eUSCI_A1_SFR + 08h ; eUSCI_A1 Modulation Control
+TERMRXBUF .equ eUSCI_A1_SFR + 0Ch ; eUSCI_A1 Receive Buffer
+TERMTXBUF .equ eUSCI_A1_SFR + 0Eh ; eUSCI_A1 Transmit Buffer
+TERMIE .equ eUSCI_A1_SFR + 1Ah ; eUSCI_A1 Interrupt Enable Register
+TERMIFG .equ eUSCI_A1_SFR + 1Ch ; eUSCI_A1 Interrupt Flags Register
+ .ENDIF ;UCA1_UART
+
+ .IFDEF UCA1_SD
+SD_CTLW0 .equ eUSCI_A1_SFR + 00h ; eUSCI_A1 Control Word Register 0
+SD_BRW .equ eUSCI_A1_SFR + 06h ; eUSCI_A1 Baud Word Rate 0
+SD_RXBUF .equ eUSCI_A1_SFR + 0Ch ; eUSCI_A1 Receive Buffer 8
+SD_TXBUF .equ eUSCI_A1_SFR + 0Eh ; eUSCI_A1 Transmit Buffer 8
+SD_IFG .equ eUSCI_A1_SFR + 1Ch ; eUSCI_A1 Interrupt Flags Register
+ .ENDIF ;UCA1_SD
+
+
+; ----------------------------------------------------------------------
+; eUSCI_B0
+; ----------------------------------------------------------------------
+ .IFDEF UCB0_SD
+SD_CTLW0 .equ eUSCI_B0_SFR + 00h ; eUSCI_B0 Control Word Register 0
+SD_BRW .equ eUSCI_B0_SFR + 06h ; eUSCI_B0 Baud Word Rate 0
+SD_RXBUF .equ eUSCI_B0_SFR + 0Ch ; eUSCI_B0 Receive Buffer 8
+SD_TXBUF .equ eUSCI_B0_SFR + 0Eh ; eUSCI_B0 Transmit Buffer 8
+SD_IFG .equ eUSCI_B0_SFR + 2Ch ; eUSCI_B0 Interrupt Flags Register
+ .ENDIF ;UCB0_SD
+
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : SYS REGISTERS
+; ----------------------------------------------------------------------
+
+SYSUNIV .equ SYS_SFR + 001Ah
+SYSSNIV .equ SYS_SFR + 001Ch
+SYSRSTIV .equ SYS_SFR + 001Eh
+
+; SYS Control Bits
+; ...
--- /dev/null
+\prog\MSP430Flasher\msp430flasher -m SBW2 -n MSP430fr6989 -v -w %1 -z [VCC=3000]
+exit
+
+tip : how to calculate MAIN program lenght ?
+
+open the prog.txt file with your editor, select MAIN section
+in status bar, keep the number of selected chars
+if lines are ended with CR+LF, substract the number of lines selected
+then divide by 3.
--- /dev/null
+
+:: usage: MSP430Read RAM|INFO|MAIN|BSL output
+
+set howtoread=%1
+set readfile=%2
+if c%1==c set howtoread=MAIN
+if c%2==c set readfile=DUMP
+
+A:\prog\MSP430Flasher\msp430flasher -m SBW2 -r [%readfile%_%howtoread%.hex,%howtoread%] -z [VCC=3000]
+A:\prog\srecord\srec_cat %readfile%_%howtoread%.HEX -intel -output %readfile%_%howtoread%.bin -Binary
+A:\prog\HxD\HxD.exe" %readfile%_%howtoread%.bin
\ No newline at end of file
--- /dev/null
+a:\prog\MSP430Flasher\msp430flasher -m SBW2 -z [RESET,VCC=3300]
\ No newline at end of file
--- /dev/null
+; -*- coding: utf-8 -*-
+
+; Fast Forth For Texas Instrument MSP430FR4133
+;
+; Copyright (C) <2016> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+; ======================================================================
+; INIT MSP-EXP430FR4133 board
+; ======================================================================
+
+; my USBtoUart :
+; http://www.ebay.fr/itm/CP2102-USB-UART-Board-mini-Data-Transfer-Convertor-Module-Development-Board-/251433941479
+
+; for sd card socket be carefull : pin CD must be present !
+; http://www.ebay.com/itm/2-PCS-SD-Card-Module-Slot-Socket-Reader-For-Arduino-MCU-/181211954262?pt=LH_DefaultDomain_0&hash=item2a3112fc56
+
+
+; J101 eZ-FET <-> target
+; -----------------------
+; P1 <-> P2 - NC
+; P3 <-> P4 - TEST - TEST
+; P5 <-> P6 - RST - RST
+; P7 <-> P8 - TX1 - P1.0 UCA0 TXD ---> RX UARTtoUSB module
+; P9 <->P10 - RX1 - P1.1 UCA0 RXD <--- TX UARTtoUSB module
+; P11<->P12 - CTS - P2.4
+; P13<->P14 - RTS - P2.3
+; P15<->P16 - VCC - 3V3
+; P17<->P18 - 5V
+; P19<->P20 - GND - VSS
+
+; Launchpad Header Left J1
+; ------------------------
+; P1 - 3V3
+; P2 - P8.1 ACLK/A9
+; P3 - P1.1 UCA0 RXD
+; P4 - P1.0 UCA0 TXD
+; P5 - P2.7
+; P6 - P8.0 SMCLK/A8
+; P7 - P5.1 UCB0 CLK
+; P8 - P2.5
+; P9 - P8.2 TA1CLK
+; P10- P8.3 TA1.2
+
+; Launchpad Header Right J2
+; -------------------------
+; P1 - GND
+; P2 - P1.7 TA0.1/TDO/A7
+; P3 - P1.6 TA0.2/TDI/TCLK/A6
+; P4 - P5.0 UCB0STE
+; P5 - RST
+; P6 - P5.2 UCB0SIMO/UCB0SDA
+; P7 - P5.3 UCB0SOMI/UCB0SCL
+; P8 - P1.3 UCA0STE/A3
+; P9 - P1.4 MCLK/TCK/A4
+; P10- P1.5 TA0CLK/TMS/A5
+
+; switch-keys:
+; S1 - P1.2
+; S2 - P2.6
+; S3 - RST
+
+; LEDS:
+; LED1 - P1.0/TXD
+; LED2 - P4.0
+
+; XTAL LF 32768 Hz
+; Y4 - P4.1 XIN
+; Y4 - P4.2 XOUT
+
+; LCD
+; L0 - P7.0
+; L1 - P7.1
+; L2 - P7.2
+; L3 - P7.3
+; L4 - P7.4
+; L5 - P7.5
+; L6 - P7.6
+; L7 - P7.7
+; L8 - P3.0
+; L9 - P3.1
+; L10 - P3.2
+; L11 - P3.3
+; L12 - P3.4
+; L13 - P3.5
+; L14 - P3.6
+; L15 - P3.7
+; L16 - P6.0
+; L17 - P6.1
+; L18 - P6.2
+; L19 - P6.3
+; L20 - P6.4
+; L21 - P6.5
+; L22 - P6.6
+; L23 - P6.7
+; L24 - P2.0
+; L25 - P2.1
+; L26 - P2.2
+; L36 - P5.4
+; L37 - P5.5
+; L38 - P5.6
+; L39 - P5.7
+
+
+
+
+
+
+; ===================================================================================
+; in case of 3.3V powered by UARTtoUSB bridge, open J13 straps {RST,TST,V+,5V} BEFORE
+; then wire VCC and GND of bridge onto J13 connector
+; ===================================================================================
+
+; ---------------------------------------------------
+; MSP - MSP-EXP430FR4133 LAUNCHPAD <--> OUTPUT WORLD
+; ---------------------------------------------------
+; P1.0 - LED1 red
+; P4.0 - LED2 green
+;
+; P1.2 - S1
+; P2.6 - S2
+; +-4k7-< DeepRST <-- GND
+; |
+; P1.0 - UCA0 TXD J101.8 --+-> RX UARTtoUSB bridge
+; P1.1 - UCA0 RXD J101.10 <---- TX UARTtoUSB bridge
+; P2.3 - RTS J101.14 ----> CTS UARTtoUSB bridge (if TERMINALCTSRTS option)
+; VCC - J101.16 <---- VCC (optional supply from UARTtoUSB bridge - WARNING ! 3.3V !)
+; GND - J101.20 <---> GND (optional supply from UARTtoUSB bridge)
+;
+; P2.7 - J1.5 <---- OUT IR_Receiver (1 TSOP32236)
+;
+; P4.1 - LFXI 32768Hz quartz
+; P4.2 - LFXO 32768Hz quartz
+;
+; P5.2 - UCB0 SDA/SIMO J2.6 <---> SDA I2C Slave
+; P5.3 - UCB0 SCL/SOMI J2.7 <---- SCL I2C Slave
+;
+; P5.1 - UCB0 CLK J1.7 ----> SD_CLK
+; P5.2 - UCB0 SDA/SIMO J2.6 ----> SD_SDI
+; P5.3 - UCB0 SCL/SOMI J2.7 <---- SD_SDO
+; P8.0 - J1.6 <---- SD_CD (Card Detect)
+; P8.1 - J1.2 ----> SD_CS (Card Select)
+;
+; P8.2 - Soft I2C_Master J1.9 ----> SDA software I2C Master
+; P8.3 - Soft I2C_Master J1.10 <---> SCL software I2C Master
+
+
+; ----------------------------------------------------------------------
+; INIT order : WDT, GPIOs, FRAM, Clock, UARTs...
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : LOCK PMM_LOCKLPM5
+; ----------------------------------------------------------------------
+
+; BIS #LOCKLPM5,&PM5CTL0 ; unlocked by WARM
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : WATCHDOG TIMER A
+; ----------------------------------------------------------------------
+
+; WDT code
+ MOV #WDTPW+WDTHOLD+WDTCNTCL,&WDTCTL ; stop WDT
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : I/O
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT1/2
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+
+; PORT1 usage
+
+; P1.0 - TX0 --> JP1 --> red LED1 --> GND
+; P1.1 - RX0
+
+Deep_RST_IN .equ P1IN ; TERMINAL TX pin as FORTH Deep_RST
+Deep_RST .equ 1 ; TX
+TERM_TXRX .equ 003h ; TX RX
+TERM_SEL .equ P1SEL0
+TERM_REN .equ P1REN
+
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #-1,&PAOUT ; OUT1 for all pins
+ BIS #-1,&PAREN ; all pins with pullup resistors
+
+ .IFDEF TERMINALCTSRTS
+HANDSHAKOUT .set P2OUT
+HANDSHAKIN .set P2IN
+RTS .set 8 ; P2.3 bit position
+CTS .set 10h ; P2.4 bit position
+; BIS.B #RTS,&HANDSHAKOUT
+ .ENDIF
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT3/4
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; P3 configuration :
+
+; P4 configuration :
+; P4.0 - LED2 green
+; P4.1 - LFXI 32768Hz quartz
+; P4.2 - LFXO 32768Hz quartz
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #00100h,&PBDIR ; all pins as inputs else P4.0
+ MOV #0FEFFh,&PBOUT ; OUT1 for all pins else P4
+ BIS #0FEFFh,&PBREN ; pullup for all pins resistors else P4.0
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT5/6
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #-1,&PCOUT ; all pins OUT1
+ BIS #-1,&PCREN ; all pins with pull resistors
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT7/8
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #-1,&PDOUT ; all pins OUT1
+ BIS #-1,&PDREN ; all pins with pull resistors
+
+; ----------------------------------------------------------------------
+; FRAM config
+; ----------------------------------------------------------------------
+
+ .IF FREQUENCY = 16
+ MOV.B #0A5h, &FRCTL0_H ; enable FRCTL0 access
+ MOV.B #10h, &FRCTL0 ; 1 waitstate @ 16 MHz
+ MOV.B #01h, &FRCTL0_H ; disable FRCTL0 access
+ .ENDIF
+
+; ----------------------------------------------------------------------
+; POWER ON RESET SYS config
+; ----------------------------------------------------------------------
+; SYS code
+; BIC #1,&SYSCFG0 ; enable write program in FRAM
+ MOV #0A500h,&SYSCFG0 ; enable write MAIN and INFO
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : CLOCK SYSTEM
+; ----------------------------------------------------------------------
+
+; CS code for EXP430FR4133
+
+; to measure REFO frequency, output ACLK on P8.1:
+; BIS.B #2,&P8SEL0
+; BIS.B #2,&P8DIR
+; result : REFO = ? kHz
+
+
+; ===================================================================
+; need to adjust FLLN (and DCO) for each device of MSP430fr2xxx family ?
+; (no problem with MSP430FR5xxx families without FLL).
+; ===================================================================
+
+ .IF FREQUENCY = 0.5
+
+ MOV #0D6h,&CSCTL0 ; preset DCO = 0xD6 (measured value @ 0x180 ; to measure, type 0x180 @ U.)
+
+ MOV #0001h,&CSCTL1 ; Set 1MHZ DCORSEL,disable DCOFTRIM,Modulation
+; ===================================== ; fCOCLKDIV = REFO x (FLLN+1)
+; MOV #100Dh,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO/2),set FLLN=0Dh
+ ; fCOCLKDIV = 32768 x (13+1) = 0.459 MHz ; measured : MHz
+; MOV #100Eh,&CSCTL2 ; Set FLLD=1 (DCOCLKCDIV=DCO/2),set FLLN=0Eh
+ ; fCOCLKDIV = 32768 x (14+1) = 0.491 MHz ; measured : MHz
+ MOV #100Fh,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=0Fh
+ ; fCOCLKDIV = 32768 x (15+1) = 0.524 MHz ; measured : MHz
+; =====================================
+ MOV #2,X
+
+ .ELSEIF FREQUENCY = 1
+
+ MOV #00B4h,&CSCTL0 ; preset DCO = 0xB4 (measured value @ 0x180 ; to measure, type HEX 0x180 ?)
+
+ MOV #0001h,&CSCTL1 ; Set 1MHZ DCORSEL,disable DCOFTRIM,Modulation
+; ===================================== ; fCOCLKDIV = REFO x (FLLN+1)
+; MOV #001Dh,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=1Dh
+ ; fCOCLKDIV = 32768 x (29+1) = 0.983 MHz ; measured : 0.989MHz
+ MOV #001Eh,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=1Eh
+ ; fCOCLKDIV = 32768 x (30+1) = 1.015 MHz ; measured : 1.013MHz
+; MOV #001Fh,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=1Fh
+ ; fCOCLKDIV = 32768 x (31+1) = 1.049 MHz ; measured : 1.046MHz
+; =====================================
+ MOV #4,X
+
+ .ELSEIF FREQUENCY = 2
+
+ MOV #00B4h,&CSCTL0 ; preset DCO = 0xB4 (measured value @ 0x180 ; to measure, type HEX 0x180 ?)
+
+ MOV #0003h,&CSCTL1 ; Set 2MHZ DCORSEL,disable DCOFTRIM,Modulation
+; ===================================== ; fCOCLKDIV = REFO x (FLLN+1)
+; MOV #003Bh,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=3Bh
+ ; fCOCLKDIV = 32768 x (59+1) = 1.996 MHz ; measured : MHz
+ MOV #003Ch,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=3Ch
+ ; fCOCLKDIV = 32768 x (60+1) = 1.998 MHz ; measured : MHz
+; MOV #003Dh,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=3Dh
+ ; fCOCLKDIV = 32768 x (61+1) = 2.031 MHz ; measured : MHz
+; =====================================
+ MOV #8,X
+
+ .ELSEIF FREQUENCY = 4
+
+ MOV #00D2h,&CSCTL0 ; preset DCO = 0xD2 (measured value @ 0x180)
+
+ MOV #0005h,&CSCTL1 ; Set 4MHZ DCORSEL,disable DCOFTRIM,Modulation
+; ===================================== ; fCOCLKDIV = REFO x (FLLN+1)
+; MOV #0078h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=78h
+ ; fCOCLKDIV = 32768 x (120+1) = 3.965 MHz ; measured : 3.96MHz
+
+ MOV #0079h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=79h
+ ; fCOCLKDIV = 32768 x (121+1) = 3.997 MHz ; measured : 3.99MHz
+
+; MOV #007Ah,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=7Ah
+ ; fCOCLKDIV = 32768 x (122+1) = 4.030 MHz ; measured : 4.020MHz
+; =====================================
+ MOV #16,X
+
+ .ELSEIF FREQUENCY = 8
+
+ MOV #00F2h,&CSCTL0 ; preset DCO = 0xF2 (measured value @ 0x180)
+
+ MOV #0007h,&CSCTL1 ; Set 8MHZ DCORSEL,disable DCOFTRIM,Modulation
+; ===================================== ; fCOCLKDIV = REFO x (FLLN+1)
+; MOV #00F2h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=F2h
+ ; fCOCLKDIV = 32768 x (242+1) = 7.963 MHz ; measured : 7.943MHz
+; MOV #00F3h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=F3h
+ ; fCOCLKDIV = 32768 x (243+1) = 7.995 MHz ; measured : 7.976MHz
+ MOV #00F4h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=F4h
+ ; fCOCLKDIV = 32768 x (244+1) = 8.028 MHz ; measured : 8.009MHz
+
+; MOV #00F5h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=F5h
+ ; fCOCLKDIV = 32768 x (245+1) = 8.061 MHz ; measured : 8.042MHz
+ ; works with cp2102 and pl2303TA
+; =====================================
+ MOV #32,X
+
+ .ELSEIF FREQUENCY = 16
+
+ MOV #0129h,&CSCTL0 ; preset DCO = 0x129 (measured value @ 0x180)
+
+ MOV #000Bh,&CSCTL1 ; Set 16MHZ DCORSEL,disable DCOFTRIM,Modulation
+; ===================================== ; fCOCLKDIV = REFO x (FLLN+1)
+; MOV #01E6h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=1E6h
+ ; fCOCLKDIV = 32768 x 486+1) = 15.958 MHz ; measured : 15.92MHz
+; MOV #01E7h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=1E7h
+ ; fCOCLKDIV = 32768 x 487+1) = 15.991 MHz ; measured : 15.95MHz
+; MOV #01E8h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=1E8h
+ ; fCOCLKDIV = 32768 x 488+1) = 16.023 MHz ; measured : 15.99MHz
+ MOV #01E9h,&CSCTL2 ; Set FLLD=0 (DCOCLKCDIV=DCO),set FLLN=1E9h
+ ; fCOCLKDIV = 32768 x 489+1) = 16.056 MHz ; measured : 16.02MHz
+; =====================================
+ MOV #64,X
+
+ .ELSEIF
+ .error "bad frequency setting, only 0.5,1,2,4,8,16 MHz"
+ .ENDIF
+
+ .IFDEF LF_XTAL
+; MOV #0000h,&CSCTL3 ; FLL select XT1, FLLREFDIV=0 (default value)
+ MOV #0000h,&CSCTL4 ; ACLOCK select XT1, MCLK & SMCLK select DCOCLKDIV
+ .ELSE
+ MOV #0010h,&CSCTL3 ; FLL select REFCLOCK, FLLREFDIV=0
+; MOV #0100h,&CSCTL4 ; ACLOCK select REFO, MCLK & SMCLK select DCOCLKDIV (default value)
+ .ENDIF
+
+
+ BIS &SYSRSTIV,&SAVE_SYSRSTIV; store volatile SYSRSTIV with preserving a pending request for DEEP_RST
+ CMP #2,&SAVE_SYSRSTIV ; POWER ON ?
+ JZ ClockWaitX ; yes : wait 600ms to stabilize power source
+ .word 0359h ; no : RRUM #1,X --> wait still 300 ms...
+ ; ...because FLL lock time = 280 ms
+
+ClockWaitX MOV #50000,Y ;
+ClockWaitY SUB #1,Y ; 3 cycles loop
+ JNZ ClockWaitY ; 50000x3 = 150000 cycles delay = 150ms @ 1MHz
+ SUB #1,X ;
+ JNZ ClockWaitX ;
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : RTC REGISTERS
+; ----------------------------------------------------------------------
+
+ .IFDEF LF_XTAL
+; LFXIN : P4.1, LFXOUT : P4.2
+ MOV #0600h,&PBSEL0 ; SEL0 for only P4.1,P4.2
+ .ENDIF
+
+
+
+
--- /dev/null
+@1800
+10 00 74 C8 80 3E 80 04 FD FF 18 00 9C DB 52 D4
+52 C8 60 C8 00 00 00 00
+@21AA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@C400
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 C4
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 C4 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 C4 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E C4 02 3E 52 00 0E 12 3E 4F 30 4D 8E C4
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 C4
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C C4 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 20 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 C4 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 C5
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 C4 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA C4 03 41 4E 44 3E FF 30 4D 7A C4 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E C5 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 C5 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E C5 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 C5 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 C4 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE C5 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 C5 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 C5 03 3E 49 4E 85 12 C2 21 10 C5
+04 42 41 53 45 00 85 12 DA 21 C0 C4 05 53 54 41
+54 45 85 12 B6 21 30 C6 02 42 4C 00 85 12 20 00
+F4 C5 03 55 4D 2A 2C 4F 0A 43 08 43 0B 43 19 43
+0E B9 02 24 08 5C 0B 6A 0C 5C 0A 6A 09 59 F8 2B
+8F 48 00 00 0E 4B 30 4D 94 C5 02 3C 23 00 B2 40
+AA 21 AA 21 30 4D 1E 15 0E 43 3D 40 20 00 0A 93
+04 20 0D 11 0A 4C 0C 43 09 43 0E 9B 01 28 0E 8B
+09 69 08 68 1D 83 07 30 0C 5C 0A 6A 0E 6E F5 2B
+0E 8B 12 D3 F5 3F 0A 4E 1D 17 30 41 48 C6 01 23
+1B 42 DA 21 2C 4F 0A 4E B0 12 86 C6 8F 49 00 00
+0E 48 7A 90 0A 00 02 28 3A 50 07 00 3A 50 30 00
+92 83 AA 21 18 42 AA 21 C8 4A 00 00 30 4D BE C6
+02 23 53 00 87 12 C0 C6 FA C6 2D 83 09 93 E0 23
+0E 93 DE 23 3D 41 30 4D F0 C6 02 23 3E 00 9F 42
+AA 21 00 00 3E 40 AA 21 2E 8F 30 4D 00 C6 04 48
+4F 4C 44 00 0A 4E 3E 4F DB 3F 3C C6 04 53 49 47
+4E 00 0E 93 3E 4F 3A 40 2D 00 D2 33 30 4D 52 C6
+03 55 44 2E 87 12 7E C6 F4 C6 0E C7 5A C9 22 C9
+2A C4 40 C7 02 55 2E 00 2F 83 8F 4E 00 00 0E 43
+F1 3F 3E B0 00 80 06 24 BF E3 00 00 3E E3 9F 53
+00 00 0E 63 30 4D DA C4 02 44 2E 00 87 12 7E C6
+6E C4 80 C4 62 C7 F4 C6 92 C4 32 C7 0E C7 5A C9
+22 C9 2A C4 52 C5 01 2E 3E B0 00 80 DD 27 2F 83
+3E 43 EC 3F 1E C7 04 48 45 52 45 00 2F 83 8F 4E
+00 00 1E 42 C4 21 30 4D 62 C5 05 41 4C 4C 4F 54
+82 5E C4 21 3E 4F 30 4D 0A C7 02 43 2C 00 1A 42
+C4 21 CA 4E 00 00 92 53 C4 21 3E 4F 30 4D 2F 83
+8F 4E 00 00 B0 12 52 C8 92 B3 1C 05 FD 27 1E 42
+0C 05 B0 12 60 C8 30 4D 30 40 DE C7 A6 C7 05 28
+4B 45 59 29 18 42 0C 05 EA 3F 12 C6 03 4B 45 59
+30 40 04 C8 BA C7 06 41 43 43 45 50 54 00 3C 40
+B2 C8 3B 40 7C C8 2D 15 0A 4E 2E 4F 0A 5E 3B 40
+0D 00 3C 40 20 00 3D 40 A6 C8 92 B3 1C 05 05 24
+18 42 0C 05 38 90 0A 00 04 20 21 53 39 40 6E C8
+4D 15 B2 40 11 00 0E 05 A2 B3 1C 05 FD 27 30 41
+B2 40 13 00 0E 05 A2 B3 1C 05 FD 27 30 41 12 D2
+0A 18 FD 3F 21 52 3A 17 58 42 0C 05 48 9B F0 27
+48 9C 06 2C 78 92 11 20 2E 9F 0F 24 1E 83 05 3C
+0E 9A 03 24 CE 48 00 00 1E 53 82 48 0E 05 A2 B3
+1C 05 FD 27 30 4D A8 C8 2D 83 92 B3 1C 05 FD 27
+E3 23 B2 40 18 00 0A 18 3E 8F 3D 41 30 4D FE C7
+06 28 45 4D 49 54 29 00 08 4E 3E 4F E6 3F 78 C7
+04 45 4D 49 54 00 30 40 C8 C8 D0 C8 04 45 43 48
+4F 00 B2 40 82 48 9A C8 30 4D 96 C7 06 4E 4F 45
+43 48 4F 00 B2 40 30 4D 9A C8 30 4D C0 C8 04 28
+43 52 29 00 2F 83 8F 4E 00 00 3E 40 0D 00 E3 3F
+CA C7 02 43 52 00 30 40 04 C9 2C C7 05 53 50 41
+43 45 2F 83 8F 4E 00 00 3E 40 20 00 D4 3F 1C C9
+06 53 50 41 43 45 53 00 0E 93 09 24 0D 12 3D 40
+44 C9 EF 3F 46 C9 2D 83 1E 83 EB 23 3D 41 3E 4F
+30 4D 54 C7 04 54 59 50 45 00 0E 93 95 24 2A 4F
+8F 5E 00 00 0E 4A 87 12 CA C5 02 C6 0A C5 D6 C8
+EC C5 6A C9 2A C4 2F 82 8F 4E 02 00 7E 4D 8F 4D
+00 00 0D 5E 1D B3 0D 63 30 4D 30 C9 82 53 22 00
+87 12 34 C4 76 C9 06 CC 34 C4 22 00 D0 C9 A0 C9
+3D 41 6E 4E 1E 83 82 5E C4 21 3E 4F 92 B3 C4 21
+A2 63 C4 21 30 4D EC C8 82 2E 22 00 87 12 90 C9
+34 C4 5A C9 06 CC 2A C4 00 00 04 57 4F 52 44 00
+3C 40 BE 21 39 4C 3A 4C 09 5A 3A 5C 28 4C 09 9A
+19 24 7E 9A FC 27 1A 83 3B 40 60 00 C8 4C 00 00
+09 9A 0C 24 7C 4A 4E 9C 09 24 18 53 4B 9C F6 2F
+7C 90 7B 00 F3 2F 7C 80 20 00 F0 3F 1A 82 C0 21
+82 4A C2 21 1E 42 C4 21 08 8E CE 48 00 00 30 4D
+00 00 04 46 49 4E 44 00 2F 83 0C 4E 65 4C 74 40
+80 00 3B 40 CA 21 3E 4B 0E 93 1E 24 58 4C 01 00
+78 F0 1E 00 0E 58 2E 53 1E 4E FE FF 0E 93 F3 27
+09 4E 78 49 48 C4 48 95 F7 23 0A 4C 1A 53 FA 99
+00 00 F2 23 58 83 FA 23 19 B3 09 63 0C 49 6A 4E
+1E 43 4A 93 01 30 2E 83 8F 4C 00 00 35 40 08 C4
+34 40 14 C4 30 4D 2F 53 2F 53 3E 4F 30 4D 26 C6
+07 3E 4E 55 4D 42 45 52 2C 4F 6C 4C 7C 80 30 00
+7C 90 0A 00 02 28 7C 80 07 00 1C 92 DA 21 25 2C
+2E 15 2F 83 9F 4F 04 00 00 00 1E 42 DA 21 3D 40
+C6 CA 30 40 56 C6 C8 CA 2F 12 9F 4F 06 00 00 00
+1E 42 DA 21 3D 40 DC CA 30 40 56 C6 DE CA 3E 51
+BF 51 00 00 0E 63 AF 4F 06 00 8F 4E 04 00 1D 17
+2F 53 9F 53 00 00 1E 83 CF 23 30 4D 03 12 0D 12
+12 12 DA 21 32 C0 00 02 6D 4E 0D 5E 0C 4E 7A 40
+2E 00 0D 9C 0A 28 7A 9C FC 23 32 D0 00 02 FC 4C
+FE FF 0D 9C FC 2F DE 83 00 00 3D 40 88 CB 3F 82
+8F 4E 06 00 8F 43 04 00 8F 43 02 00 0A 4E 7E 4A
+8F 4A 00 00 79 4A 79 90 2D 00 17 2C 79 80 24 00
+04 20 B2 40 10 00 DA 21 0A 3C 59 83 03 20 A2 43
+DA 21 05 3C 69 53 98 23 B2 40 0A 00 DA 21 8F 4A
+00 00 1E 83 79 4A 79 90 2D 00 8E 23 B1 43 04 00
+8F 4A 00 00 1E 83 88 3F 8A CB 2F 53 0E 93 2C 17
+82 4C DA 21 03 24 2F 52 0E F3 30 4D 8F 93 00 00
+15 20 32 B0 00 02 14 20 0E 93 05 24 1A 4F 02 00
+1A 83 0A 93 0B 38 2F 53 BF 4F 00 00 3E E3 05 20
+BF E3 00 00 9F 53 00 00 3E E3 30 4D 32 D0 00 02
+9F 4F 02 00 04 00 BF 4F 00 00 3E E3 F6 23 BF E3
+02 00 BF E3 00 00 9F 53 02 00 8F 63 00 00 3E E3
+30 4D DC C8 07 45 58 45 43 55 54 45 0A 4E 3E 4F
+00 4A 28 C5 01 2C 1A 42 C4 21 A2 53 C4 21 8A 4E
+00 00 3E 4F 30 4D 04 CC 87 4C 49 54 45 52 41 4C
+82 93 B6 21 16 24 32 B0 00 02 09 24 1A 42 C4 21
+A2 52 C4 21 BA 40 34 C4 00 00 BA 4F 02 00 1A 42
+C4 21 A2 52 C4 21 BA 40 34 C4 00 00 8A 4E 02 00
+3E 4F 30 4D 12 C9 05 43 4F 55 4E 54 2F 83 1E 53
+8F 4E 00 00 5E 4E FF FF 30 4D 82 4E BE 21 B2 4F
+C0 21 3E 4F 82 43 C2 21 87 12 4C C6 D0 C9 80 CC
+3D 40 8C CC D1 22 3D 41 3E 4F 30 4D 8E CC 0A 4E
+3E 4F 3D 40 A4 CC 32 27 3D 40 7A CC 1A E2 B6 21
+B2 27 AC 23 A6 CC 3E 4F 3D 40 7A CC B9 23 DE 53
+00 00 68 4E 08 5E F8 40 3F 00 00 00 3D 40 6C CE
+CD 3F F4 CB 08 45 56 41 4C 55 41 54 45 00 39 40
+BE 21 39 12 39 12 39 12 0D 12 B0 12 2A C4 6A CC
+E2 CC 3D 41 B2 41 C2 21 B2 41 C0 21 B2 41 BE 21
+30 4D 7A C5 04 51 55 49 54 00 31 40 E0 20 B2 40
+00 20 AC 21 82 43 B6 21 82 43 08 18 B0 12 2A C4
+76 C9 04 0D 6F 6B 20 00 5A C9 34 C4 38 21 44 C4
+34 C4 50 00 1E C8 22 C9 6A CC 34 C4 7E 20 CE C4
+B2 C5 76 C9 0D 73 74 61 63 6B 20 65 6D 70 74 79
+20 21 7E CD 34 C4 30 FF AC C7 B2 C5 76 C9 0B 46
+52 41 4D 20 66 75 6C 6C 20 21 7E CD 42 C6 F4 C4
+C0 C5 10 CD 76 C9 04 0D 20 20 20 00 BC C5 18 CD
+16 C8 05 41 42 4F 52 54 3F 40 80 20 BE 3F 8F 93
+02 00 81 26 B2 40 82 48 9A C8 B0 12 66 D2 82 43
+16 DB 82 43 22 DB 82 43 2E DB 82 43 5E DB 82 43
+6A DB 82 43 76 DB A2 B3 1C 05 FD 27 B2 40 11 00
+0E 05 92 C3 1C 05 38 40 A0 AA 39 42 19 83 FE 23
+18 83 FB 23 92 B3 1C 05 F4 23 87 12 76 C9 04 1B
+5B 37 6D 00 5A C9 5A C9 76 C9 04 1B 5B 30 6D 00
+5A C9 AE D1 F0 D1 F6 D1 78 CD 72 CD 86 41 42 4F
+52 54 22 00 87 12 90 C9 34 C4 7E CD 06 CC 2A C4
+22 CA 01 27 87 12 4C C6 D0 C9 28 CA C0 C5 12 CE
+2A C4 AE CC 7A C6 81 5C 92 42 BE 21 C2 21 30 4D
+87 12 AC C9 4C C6 D0 C9 2A CE 08 4E 7A 4E 5A D3
+5A 53 0A 58 19 42 C8 21 6E 4E 3E F0 1E 00 09 5E
+82 48 AE 21 82 49 B0 21 82 4A B2 21 2A 52 82 4A
+C4 21 3E 4F 3D 41 30 41 87 12 76 C9 0F 73 74 61
+63 6B 20 6D 69 73 6D 61 74 63 68 21 84 CD 82 9F
+B4 21 F2 23 18 42 AE 21 19 42 B0 21 A8 49 FE FF
+89 48 00 00 30 4D CA C9 08 56 41 52 49 41 42 4C
+45 00 B0 12 20 CE BA 40 86 12 FC FF EF 3F 56 CC
+08 43 4F 4E 53 54 41 4E 54 00 B0 12 20 CE BA 40
+85 12 FC FF 8A 4E FE FF 3E 4F E0 3F A0 CE 06 43
+52 45 41 54 45 00 B0 12 20 CE BA 40 85 12 FC FF
+8A 4A FE FF D3 3F C4 CC 05 44 4F 45 53 3E 1A 42
+B2 21 BA 40 84 12 00 00 8A 4D 02 00 3D 41 30 4D
+D8 CE 05 44 45 46 45 52 B0 12 20 CE BA 40 30 40
+FC FF BA 40 EE CE FE FF B9 3F 00 00 81 5B 82 43
+B6 21 30 4D 16 CE 01 5D B2 43 B6 21 30 4D 8C C9
+87 52 45 43 55 52 53 45 19 42 C4 21 99 42 B2 21
+00 00 A2 53 C4 21 30 4D 0C CF 01 3A B0 12 20 CE
+BA 40 87 12 FC FF A2 83 C4 21 B2 43 B6 21 82 4F
+B4 21 30 4D 3A CF 81 3B 82 93 B6 21 5D 27 87 12
+34 C4 2A C4 06 CC 6E CE 0E CF 2A C4 FE C8 09 49
+4D 4D 45 44 49 41 54 45 1A 42 AE 21 FA D0 80 00
+00 00 30 4D BE 4F 02 00 3E 4F 30 4D 6E CF 82 49
+53 00 87 12 42 C6 F4 C4 C0 C5 A6 CF B2 CF 34 C4
+84 CF 06 CC 2A C4 04 CE 84 CF 2A C4 56 CF 83 5B
+27 5D 87 12 04 CE 34 C4 34 C4 06 CC 06 CC 2A C4
+F4 CC 88 50 4F 53 54 50 4F 4E 45 00 87 12 4C C6
+D0 C9 28 CA 54 C4 C0 C5 12 CE 7E C5 C0 C5 EC CF
+34 C4 34 C4 06 CC 06 CC 34 C4 06 CC 06 CC 2A C4
+F2 CF 3A 4E 82 4A C6 21 2E 4E 82 4E C4 21 3D 40
+10 00 09 4A 08 49 29 83 18 48 FE FF 0E 98 FC 2B
+89 48 00 00 1D 83 F6 23 2A 4A 0A 93 F0 23 3E 4F
+3D 41 30 4D 8E CF 82 49 46 00 2F 83 8F 4E 00 00
+1E 42 C4 21 BE 40 C0 C5 00 00 A2 52 C4 21 2E 53
+30 4D F2 CE 84 45 4C 53 45 00 1A 42 C4 21 BA 40
+BC C5 00 00 2A 52 82 4A C4 21 8E 4A 00 00 2A 83
+0E 4A 30 4D 54 C9 84 54 48 45 4E 00 9E 42 C4 21
+00 00 3E 4F 30 4D BE CE 85 42 45 47 49 4E 30 40
+AC C7 66 D0 85 55 4E 54 49 4C 39 40 C0 C5 1A 42
+C4 21 A2 52 C4 21 8A 49 00 00 8A 4E 02 00 3E 4F
+30 4D EC CD 85 41 47 41 49 4E 39 40 BC C5 EF 3F
+88 CE 85 57 48 49 4C 45 87 12 2A D0 6E C4 2A C4
+20 CF 86 52 45 50 45 41 54 00 87 12 AA D0 6C D0
+2A C4 44 D0 82 44 4F 00 2F 83 8F 4E 00 00 1E 42
+C4 21 BE 40 CA C5 00 00 2E 53 82 4E C4 21 A2 53
+AC 21 1A 42 AC 21 8A 43 00 00 30 4D 18 CC 84 4C
+4F 4F 50 00 39 40 EC C5 1A 42 C4 21 A2 52 C4 21
+8A 49 00 00 8A 4E 02 00 1E 42 AC 21 A2 83 AC 21
+2E 4E 0E 93 04 24 9E 42 C4 21 00 00 F5 3F 3E 4F
+30 4D 0C C8 85 2B 4C 4F 4F 50 39 40 DA C5 E4 3F
+FE D0 85 4C 45 41 56 45 1A 42 C4 21 BA 40 FC C5
+00 00 BA 40 BC C5 02 00 B2 50 06 00 C4 21 A2 53
+AC 21 2A 52 19 42 AC 21 89 4A 00 00 30 4D 42 D1
+04 4D 4F 56 45 00 0A 4E 38 4F 39 4F 3E 4F 0A 93
+11 24 08 99 0F 24 06 2C F8 49 00 00 18 53 1A 83
+FB 23 30 4D 08 5A 09 5A 19 83 18 83 E8 49 00 00
+1A 83 FA 23 30 4D 34 C4 CA 21 FC C4 2A C4 84 12
+A6 D1 86 D4 6E D4 D4 D0 02 CE 56 D4 34 D1 70 D1
+B8 C9 14 D2 48 D2 84 D0 08 D3 48 C5 AE CF 16 CF
+90 CA 00 00 3A 40 0C 00 39 40 CA 21 38 40 CC 21
+D9 3F 3A 40 0E 00 39 40 CC 21 38 40 CA 21 CC 3F
+82 43 CC 21 30 4D 92 42 CA 21 C8 21 30 4D C2 CF
+09 50 57 52 5F 53 54 41 54 45 84 12 F0 CF 52 D4
+9C DB 00 D2 08 50 57 52 5F 48 45 52 45 00 92 42
+C4 21 10 D2 92 42 C6 21 0E D2 EF 3F C2 D0 09 52
+53 54 5F 53 54 41 54 45 92 42 0C 18 10 D2 92 42
+0E 18 0E D2 E2 3F 2E D2 08 52 53 54 5F 48 45 52
+45 00 92 42 C4 21 0C 18 92 42 C6 21 0E 18 DF 3F
+B2 40 AE D2 10 D3 B2 40 C8 C8 D8 C8 B2 40 04 C9
+18 C9 B2 40 04 C8 12 C8 30 41 B2 D0 04 57 49 50
+45 00 39 40 80 FF B9 43 00 00 29 53 39 90 E2 FF
+FA 23 B0 12 60 D2 B2 40 9C DB C4 21 B2 40 52 D4
+C6 21 D7 3F 26 D0 06 28 57 41 52 4D 29 00 1E 42
+08 18 87 12 76 C9 05 0D 1B 5B 37 6D 5A C9 98 C7
+76 C9 27 20 46 61 73 74 46 6F 72 74 68 20 56 31
+36 30 20 31 36 4D 48 7A 20 28 43 29 20 4A 2E 4D
+2E 54 68 6F 6F 72 65 6E 73 20 5A C9 34 C4 30 FF
+AC C7 2A C5 58 C7 76 C9 0B 62 79 74 65 73 20 66
+72 65 65 20 8A CD 7C D2 04 57 41 52 4D 00 30 40
+AE D2 78 D0 04 43 4F 4C 44 00 B2 40 04 A5 20 01
+B2 40 88 5A CC 01 B2 43 02 02 B2 D3 06 02 B2 40
+00 01 24 02 B2 40 FF FE 22 02 B2 D0 FF FE 26 02
+B2 43 42 02 B2 D3 46 02 B2 43 62 02 B2 D3 66 02
+F2 40 A5 00 A1 01 F2 40 10 00 A0 01 D2 43 A1 01
+B2 40 00 A5 60 01 B2 40 29 01 80 01 B2 40 0B 00
+82 01 B2 40 E9 01 84 01 39 40 40 00 82 43 88 01
+92 D2 5E 01 08 18 A2 93 08 18 01 24 59 03 38 40
+50 C3 18 83 FE 23 19 83 FA 23 B2 40 00 06 2A 02
+3A 40 20 D3 39 40 E2 FF 89 4A 00 00 29 53 FC 23
+92 42 02 18 EC FF B2 40 18 00 0A 18 31 40 E0 20
+3F 40 80 20 37 40 00 C4 36 40 B4 C4 35 40 08 C4
+34 40 14 C4 B2 40 0A 00 DA 21 B2 43 DC 21 92 C3
+30 01 18 42 08 18 D2 B3 00 02 04 20 38 E3 18 53
+82 48 08 18 B2 40 81 00 00 05 B2 42 06 05 B2 40
+A1 F7 08 05 F2 D0 03 00 0A 02 92 C3 00 05 92 D3
+1A 05 3D 40 2C D4 18 42 08 18 38 90 0A 00 31 27
+38 90 16 00 2E 2F 28 93 07 23 EF 26 0E D3 84 12
+A6 D1 7A DA 26 DB 2E DA 7A DB F4 D9 AE DA F8 D6
+00 00 EA D9 9A DA 4C DA 8A DA 08 D8 00 00 00 00
+8C DB D2 D1 A6 D2 85 48 49 32 4C 4F 87 12 AC C7
+3E D0 06 CC 0E CF D4 D1 2E D4 2A C4 14 D3 04 43
+4F 44 45 00 B0 12 20 CE A2 82 C4 21 87 12 4E CF
+BC C5 66 D4 A4 D0 03 41 53 4D 92 42 C8 21 B8 21
+B2 40 32 D4 C8 21 EE 3F 00 00 07 45 4E 44 43 4F
+44 45 87 12 E2 D1 6E CE 2A C4 9A D4 06 45 4E 44
+41 53 4D 00 92 42 B8 21 C8 21 F3 3F 00 00 05 43
+4F 4C 4F 4E 1A 42 C4 21 BA 40 87 12 00 00 A2 53
+C4 21 B2 43 B6 21 30 40 E2 D1 00 00 05 4C 4F 32
+48 49 1A 42 C4 21 BA 40 B0 12 00 00 BA 40 2A C4
+02 00 A2 52 C4 21 ED 3F 38 40 BE 21 39 48 2A 48
+09 5A 1A 52 C2 21 09 9A 03 24 7E 9A FC 27 1A 83
+0E 4A 2A 88 82 4A C2 21 30 4D B0 12 2A C4 D0 C9
+28 CA 72 C5 C0 C5 30 D5 FC CA C0 C5 12 CE 52 D5
+32 D5 29 4E 39 90 86 12 02 20 2E 53 30 41 39 90
+85 12 03 20 1E 4E 02 00 30 41 39 90 84 12 01 20
+2E 52 30 41 19 42 C4 21 A2 53 C4 21 89 4E 00 00
+3E 40 29 00 12 12 C2 21 92 53 C2 21 B0 12 2A C4
+D0 C9 FC CA C0 C5 84 D5 7A D5 21 53 3E 90 10 00
+BB 2D 30 41 86 D5 B2 41 C2 21 22 D3 30 41 87 12
+4C C6 F8 D4 96 D5 82 43 BC 21 92 42 C4 21 BA 21
+A2 53 C4 21 0A 4E 3E 4F FA 90 23 00 00 00 34 20
+92 53 C2 21 B0 12 1A D5 0E 93 04 20 B2 40 00 03
+BC 21 27 3C 1E 93 04 20 B2 40 10 03 BC 21 21 3C
+2E 93 04 20 B2 40 20 03 BC 21 1B 3C 2E 92 04 20
+B2 40 20 02 BC 21 15 3C 3E 92 04 20 B2 40 30 02
+BC 21 0F 3C 3E 93 04 20 B2 40 30 03 BC 21 09 3C
+B2 40 30 00 BC 21 19 42 C4 21 A2 53 C4 21 89 4E
+00 00 3E 4F 3D 41 30 4D FA 90 26 00 00 00 08 20
+B2 40 10 02 BC 21 92 53 C2 21 30 12 06 D6 75 3F
+FA 90 40 00 00 00 1A 20 B2 40 20 00 BC 21 92 53
+C2 21 B0 12 64 D5 0E 20 B2 50 10 00 BC 21 3E 40
+2B 00 B0 12 64 D5 32 24 92 92 BE 21 C2 21 02 24
+92 53 C2 21 8E 10 82 5E BC 21 D3 3F B0 12 64 D5
+F9 23 B2 50 10 00 BC 21 3E 40 28 00 B0 12 1A D5
+30 12 56 D6 67 3F 87 12 4C C6 F8 D4 8E D6 FE 90
+26 00 00 00 3E 40 20 00 04 20 B2 50 82 00 BC 21
+C2 3F B0 12 64 D5 DF 23 B2 50 80 00 BC 21 3E 40
+28 00 B0 12 1A D5 B0 12 54 D5 D5 23 3D 40 12 CE
+30 4D 00 00 04 52 45 54 49 00 87 12 34 C4 00 13
+06 CC 2A C4 34 C4 2C 00 8E D5 86 D6 DE D6 2E 4E
+1E D2 BC 21 19 42 BA 21 92 3F DC D4 03 4D 4F 56
+84 12 D4 D6 00 40 EC D6 05 4D 4F 56 2E 42 84 12
+D4 D6 40 40 00 00 03 41 44 44 84 12 D4 D6 00 50
+06 D7 05 41 44 44 2E 42 84 12 D4 D6 40 50 12 D7
+04 41 44 44 43 00 84 12 D4 D6 00 60 20 D7 06 41
+44 44 43 2E 42 00 84 12 D4 D6 40 60 C4 D6 04 53
+55 42 43 00 84 12 D4 D6 00 70 3E D7 06 53 55 42
+43 2E 42 00 84 12 D4 D6 40 70 4C D7 03 53 55 42
+84 12 D4 D6 00 80 5C D7 05 53 55 42 2E 42 84 12
+D4 D6 40 80 BE D4 03 43 4D 50 84 12 D4 D6 00 90
+76 D7 05 43 4D 50 2E 42 84 12 D4 D6 40 90 AC D4
+04 44 41 44 44 00 84 12 D4 D6 00 A0 90 D7 06 44
+41 44 44 2E 42 00 84 12 D4 D6 40 A0 82 D7 03 42
+49 54 84 12 D4 D6 00 B0 AE D7 05 42 49 54 2E 42
+84 12 D4 D6 40 B0 BA D7 03 42 49 43 84 12 D4 D6
+00 C0 C8 D7 05 42 49 43 2E 42 84 12 D4 D6 40 C0
+D4 D7 03 42 49 53 84 12 D4 D6 00 D0 E2 D7 05 42
+49 53 2E 42 84 12 D4 D6 40 D0 00 00 03 58 4F 52
+84 12 D4 D6 00 E0 FC D7 05 58 4F 52 2E 42 84 12
+D4 D6 40 E0 2E D7 03 41 4E 44 84 12 D4 D6 00 F0
+16 D8 05 41 4E 44 2E 42 84 12 D4 D6 40 F0 4C C6
+8E D5 34 D8 1A 42 BC 21 B2 F0 70 00 BC 21 8A 10
+3A F0 0F 00 82 DA BC 21 4A 3F 68 D7 03 52 52 43
+84 12 2E D8 00 10 4C D8 05 52 52 43 2E 42 84 12
+2E D8 40 10 58 D8 04 53 57 50 42 00 84 12 2E D8
+80 10 66 D8 03 52 52 41 84 12 2E D8 00 11 74 D8
+05 52 52 41 2E 42 84 12 2E D8 40 11 80 D8 03 53
+58 54 84 12 2E D8 80 11 00 00 04 50 55 53 48 00
+84 12 2E D8 00 12 9A D8 06 50 55 53 48 2E 42 00
+84 12 2E D8 40 12 EE D7 04 43 41 4C 4C 00 84 12
+2E D8 80 12 34 C4 2C 00 8E D5 86 D6 CE D8 59 42
+BC 21 5A 42 BD 21 82 4A BC 21 BE 90 00 15 00 00
+02 20 0A 89 02 3C 09 8A 0A 49 3A 90 10 00 03 2C
+5A 0E A8 3F 1A 53 0E 4A 87 12 98 C7 76 C9 0D 6F
+75 74 20 6F 66 20 62 6F 75 6E 64 73 84 CD A8 D8
+05 50 55 53 48 4D 84 12 C4 D8 00 15 10 D9 04 50
+4F 50 4D 00 84 12 C4 D8 00 17 4C C6 F8 D4 30 D9
+82 43 BC 21 92 42 C4 21 BA 21 A2 53 C4 21 92 53
+C2 21 3E 40 2C 00 B0 12 2A C4 D0 C9 FC CA C0 C5
+12 CE 86 D6 56 D9 0A 4E 3E 4F 1A 83 2A 92 CA 2F
+8A 10 5A 06 6F 3F 8E D8 04 52 52 43 4D 00 84 12
+2A D9 50 00 68 D9 04 52 52 41 4D 00 84 12 2A D9
+50 01 76 D9 04 52 4C 41 4D 00 84 12 2A D9 50 02
+84 D9 04 52 52 55 4D 00 84 12 2A D9 50 03 85 12
+00 3C 92 D9 03 53 3E 3D 85 12 00 38 A4 D9 02 53
+3C 00 85 12 00 34 1E D9 03 30 3E 3D 85 12 00 30
+B8 D9 02 30 3C 00 85 12 00 30 00 00 02 55 3C 00
+85 12 00 2C CC D9 03 55 3E 3D 85 12 00 28 C2 D9
+03 30 3C 3E 85 12 00 24 E0 D9 02 30 3D 00 85 12
+00 20 00 00 02 49 46 00 1A 42 C4 21 8A 4E 00 00
+A2 53 C4 21 0E 4A 30 4D D6 D9 04 54 48 45 4E 00
+1A 42 C4 21 08 4E 3E 4F 09 48 29 53 0A 89 0A 11
+3A 90 00 02 68 2F 88 DA 00 00 30 4D 9E D7 04 45
+4C 53 45 00 1A 42 C4 21 BA 40 00 3C 00 00 A2 53
+C4 21 2F 83 8F 4A 00 00 E3 3F 0A DA 05 55 4E 54
+49 4C 3A 4F 08 4E 3E 4F 19 42 C4 21 2A 83 0A 89
+0A 11 3A 90 00 FE 47 3B 3A F0 FF 03 08 DA 89 48
+00 00 A2 53 C4 21 30 4D 22 D8 05 41 47 41 49 4E
+87 12 9E D9 52 DA 2A C4 00 00 05 57 48 49 4C 45
+87 12 F8 D9 6E C4 2A C4 AE D9 06 52 45 50 45 41
+54 00 87 12 9E D9 52 DA 10 DA 2A C4 00 00 03 4A
+4D 50 87 12 04 CE 9E D9 52 DA 2A C4 3E B0 00 10
+03 20 3E E0 00 04 30 4D 3E 90 00 34 06 28 03 24
+3E 40 00 34 30 4D 3E 40 00 38 30 4D 00 00 04 3F
+4A 4D 50 00 87 12 BC DA 04 CE 6E C4 52 DA 2A C4
+F2 DA 3D 41 08 4E 3E 4F 2A 48 0A 93 04 20 98 42
+C4 21 00 00 30 4D 88 43 00 00 A4 3F B8 D8 03 42
+57 31 84 12 F0 DA 00 00 0E DB 03 42 57 32 84 12
+F0 DA 00 00 1A DB 03 42 57 33 84 12 F0 DA 00 00
+32 DB 3D 41 1A 42 C4 21 28 4E 08 93 08 20 BA 4F
+00 00 A2 53 C4 21 8E 4A 00 00 3E 4F 30 4D 8E 43
+00 00 61 3F 00 00 03 46 57 31 84 12 30 DB 00 00
+56 DB 03 46 57 32 84 12 30 DB 00 00 62 DB 03 46
+57 33 84 12 30 DB 00 00 6E DB 04 47 4F 54 4F 00
+87 12 9E D9 04 CE FC CB 2A C4 DE DA 05 3F 47 4F
+54 4F 87 12 BC DA 04 CE FC CB 2A C4
+@FFE2
+20 D3 20 D3 20 D3 20 D3 20 D3 74 C8 20 D3 20 D3
+20 D3 20 D3 20 D3 20 D3 20 D3 20 D3 20 D3
+q
--- /dev/null
+@1800
+10 00 74 C8 80 3E 30 75 FD FF 18 00 9E DB 54 D4
+52 C8 60 C8 00 00 00 00
+@21AA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@C400
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 C4
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 C4 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 C4 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E C4 02 3E 52 00 0E 12 3E 4F 30 4D 8E C4
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 C4
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C C4 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 20 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 C4 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 C5
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 C4 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA C4 03 41 4E 44 3E FF 30 4D 7A C4 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E C5 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 C5 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E C5 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 C5 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 C4 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE C5 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 C5 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 C5 03 3E 49 4E 85 12 C2 21 10 C5
+04 42 41 53 45 00 85 12 DA 21 C0 C4 05 53 54 41
+54 45 85 12 B6 21 30 C6 02 42 4C 00 85 12 20 00
+F4 C5 03 55 4D 2A 2C 4F 0A 43 08 43 0B 43 19 43
+0E B9 02 24 08 5C 0B 6A 0C 5C 0A 6A 09 59 F8 2B
+8F 48 00 00 0E 4B 30 4D 94 C5 02 3C 23 00 B2 40
+AA 21 AA 21 30 4D 1E 15 0E 43 3D 40 20 00 0A 93
+04 20 0D 11 0A 4C 0C 43 09 43 0E 9B 01 28 0E 8B
+09 69 08 68 1D 83 07 30 0C 5C 0A 6A 0E 6E F5 2B
+0E 8B 12 D3 F5 3F 0A 4E 1D 17 30 41 48 C6 01 23
+1B 42 DA 21 2C 4F 0A 4E B0 12 86 C6 8F 49 00 00
+0E 48 7A 90 0A 00 02 28 3A 50 07 00 3A 50 30 00
+92 83 AA 21 18 42 AA 21 C8 4A 00 00 30 4D BE C6
+02 23 53 00 87 12 C0 C6 FA C6 2D 83 09 93 E0 23
+0E 93 DE 23 3D 41 30 4D F0 C6 02 23 3E 00 9F 42
+AA 21 00 00 3E 40 AA 21 2E 8F 30 4D 00 C6 04 48
+4F 4C 44 00 0A 4E 3E 4F DB 3F 3C C6 04 53 49 47
+4E 00 0E 93 3E 4F 3A 40 2D 00 D2 33 30 4D 52 C6
+03 55 44 2E 87 12 7E C6 F4 C6 0E C7 5A C9 22 C9
+2A C4 40 C7 02 55 2E 00 2F 83 8F 4E 00 00 0E 43
+F1 3F 3E B0 00 80 06 24 BF E3 00 00 3E E3 9F 53
+00 00 0E 63 30 4D DA C4 02 44 2E 00 87 12 7E C6
+6E C4 80 C4 62 C7 F4 C6 92 C4 32 C7 0E C7 5A C9
+22 C9 2A C4 52 C5 01 2E 3E B0 00 80 DD 27 2F 83
+3E 43 EC 3F 1E C7 04 48 45 52 45 00 2F 83 8F 4E
+00 00 1E 42 C4 21 30 4D 62 C5 05 41 4C 4C 4F 54
+82 5E C4 21 3E 4F 30 4D 0A C7 02 43 2C 00 1A 42
+C4 21 CA 4E 00 00 92 53 C4 21 3E 4F 30 4D 2F 83
+8F 4E 00 00 B0 12 52 C8 92 B3 1C 05 FD 27 1E 42
+0C 05 B0 12 60 C8 30 4D 30 40 DE C7 A6 C7 05 28
+4B 45 59 29 18 42 0C 05 EA 3F 12 C6 03 4B 45 59
+30 40 04 C8 BA C7 06 41 43 43 45 50 54 00 3C 40
+B2 C8 3B 40 7C C8 2D 15 0A 4E 2E 4F 0A 5E 3B 40
+0D 00 3C 40 20 00 3D 40 A6 C8 92 B3 1C 05 05 24
+18 42 0C 05 38 90 0A 00 04 20 21 53 39 40 6E C8
+4D 15 B2 40 11 00 0E 05 A2 B3 1C 05 FD 27 30 41
+B2 40 13 00 0E 05 A2 B3 1C 05 FD 27 30 41 12 D2
+0A 18 FD 3F 21 52 3A 17 58 42 0C 05 48 9B F0 27
+48 9C 06 2C 78 92 11 20 2E 9F 0F 24 1E 83 05 3C
+0E 9A 03 24 CE 48 00 00 1E 53 82 48 0E 05 A2 B3
+1C 05 FD 27 30 4D A8 C8 2D 83 92 B3 1C 05 FD 27
+E3 23 B2 40 18 00 0A 18 3E 8F 3D 41 30 4D FE C7
+06 28 45 4D 49 54 29 00 08 4E 3E 4F E6 3F 78 C7
+04 45 4D 49 54 00 30 40 C8 C8 D0 C8 04 45 43 48
+4F 00 B2 40 82 48 9A C8 30 4D 96 C7 06 4E 4F 45
+43 48 4F 00 B2 40 30 4D 9A C8 30 4D C0 C8 04 28
+43 52 29 00 2F 83 8F 4E 00 00 3E 40 0D 00 E3 3F
+CA C7 02 43 52 00 30 40 04 C9 2C C7 05 53 50 41
+43 45 2F 83 8F 4E 00 00 3E 40 20 00 D4 3F 1C C9
+06 53 50 41 43 45 53 00 0E 93 09 24 0D 12 3D 40
+44 C9 EF 3F 46 C9 2D 83 1E 83 EB 23 3D 41 3E 4F
+30 4D 54 C7 04 54 59 50 45 00 0E 93 95 24 2A 4F
+8F 5E 00 00 0E 4A 87 12 CA C5 02 C6 0A C5 D6 C8
+EC C5 6A C9 2A C4 2F 82 8F 4E 02 00 7E 4D 8F 4D
+00 00 0D 5E 1D B3 0D 63 30 4D 30 C9 82 53 22 00
+87 12 34 C4 76 C9 06 CC 34 C4 22 00 D0 C9 A0 C9
+3D 41 6E 4E 1E 83 82 5E C4 21 3E 4F 92 B3 C4 21
+A2 63 C4 21 30 4D EC C8 82 2E 22 00 87 12 90 C9
+34 C4 5A C9 06 CC 2A C4 00 00 04 57 4F 52 44 00
+3C 40 BE 21 39 4C 3A 4C 09 5A 3A 5C 28 4C 09 9A
+19 24 7E 9A FC 27 1A 83 3B 40 60 00 C8 4C 00 00
+09 9A 0C 24 7C 4A 4E 9C 09 24 18 53 4B 9C F6 2F
+7C 90 7B 00 F3 2F 7C 80 20 00 F0 3F 1A 82 C0 21
+82 4A C2 21 1E 42 C4 21 08 8E CE 48 00 00 30 4D
+00 00 04 46 49 4E 44 00 2F 83 0C 4E 65 4C 74 40
+80 00 3B 40 CA 21 3E 4B 0E 93 1E 24 58 4C 01 00
+78 F0 1E 00 0E 58 2E 53 1E 4E FE FF 0E 93 F3 27
+09 4E 78 49 48 C4 48 95 F7 23 0A 4C 1A 53 FA 99
+00 00 F2 23 58 83 FA 23 19 B3 09 63 0C 49 6A 4E
+1E 43 4A 93 01 30 2E 83 8F 4C 00 00 35 40 08 C4
+34 40 14 C4 30 4D 2F 53 2F 53 3E 4F 30 4D 26 C6
+07 3E 4E 55 4D 42 45 52 2C 4F 6C 4C 7C 80 30 00
+7C 90 0A 00 02 28 7C 80 07 00 1C 92 DA 21 25 2C
+2E 15 2F 83 9F 4F 04 00 00 00 1E 42 DA 21 3D 40
+C6 CA 30 40 56 C6 C8 CA 2F 12 9F 4F 06 00 00 00
+1E 42 DA 21 3D 40 DC CA 30 40 56 C6 DE CA 3E 51
+BF 51 00 00 0E 63 AF 4F 06 00 8F 4E 04 00 1D 17
+2F 53 9F 53 00 00 1E 83 CF 23 30 4D 03 12 0D 12
+12 12 DA 21 32 C0 00 02 6D 4E 0D 5E 0C 4E 7A 40
+2E 00 0D 9C 0A 28 7A 9C FC 23 32 D0 00 02 FC 4C
+FE FF 0D 9C FC 2F DE 83 00 00 3D 40 88 CB 3F 82
+8F 4E 06 00 8F 43 04 00 8F 43 02 00 0A 4E 7E 4A
+8F 4A 00 00 79 4A 79 90 2D 00 17 2C 79 80 24 00
+04 20 B2 40 10 00 DA 21 0A 3C 59 83 03 20 A2 43
+DA 21 05 3C 69 53 98 23 B2 40 0A 00 DA 21 8F 4A
+00 00 1E 83 79 4A 79 90 2D 00 8E 23 B1 43 04 00
+8F 4A 00 00 1E 83 88 3F 8A CB 2F 53 0E 93 2C 17
+82 4C DA 21 03 24 2F 52 0E F3 30 4D 8F 93 00 00
+15 20 32 B0 00 02 14 20 0E 93 05 24 1A 4F 02 00
+1A 83 0A 93 0B 38 2F 53 BF 4F 00 00 3E E3 05 20
+BF E3 00 00 9F 53 00 00 3E E3 30 4D 32 D0 00 02
+9F 4F 02 00 04 00 BF 4F 00 00 3E E3 F6 23 BF E3
+02 00 BF E3 00 00 9F 53 02 00 8F 63 00 00 3E E3
+30 4D DC C8 07 45 58 45 43 55 54 45 0A 4E 3E 4F
+00 4A 28 C5 01 2C 1A 42 C4 21 A2 53 C4 21 8A 4E
+00 00 3E 4F 30 4D 04 CC 87 4C 49 54 45 52 41 4C
+82 93 B6 21 16 24 32 B0 00 02 09 24 1A 42 C4 21
+A2 52 C4 21 BA 40 34 C4 00 00 BA 4F 02 00 1A 42
+C4 21 A2 52 C4 21 BA 40 34 C4 00 00 8A 4E 02 00
+3E 4F 30 4D 12 C9 05 43 4F 55 4E 54 2F 83 1E 53
+8F 4E 00 00 5E 4E FF FF 30 4D 82 4E BE 21 B2 4F
+C0 21 3E 4F 82 43 C2 21 87 12 4C C6 D0 C9 80 CC
+3D 40 8C CC D1 22 3D 41 3E 4F 30 4D 8E CC 0A 4E
+3E 4F 3D 40 A4 CC 32 27 3D 40 7A CC 1A E2 B6 21
+B2 27 AC 23 A6 CC 3E 4F 3D 40 7A CC B9 23 DE 53
+00 00 68 4E 08 5E F8 40 3F 00 00 00 3D 40 6C CE
+CD 3F F4 CB 08 45 56 41 4C 55 41 54 45 00 39 40
+BE 21 39 12 39 12 39 12 0D 12 B0 12 2A C4 6A CC
+E2 CC 3D 41 B2 41 C2 21 B2 41 C0 21 B2 41 BE 21
+30 4D 7A C5 04 51 55 49 54 00 31 40 E0 20 B2 40
+00 20 AC 21 82 43 B6 21 82 43 08 18 B0 12 2A C4
+76 C9 04 0D 6F 6B 20 00 5A C9 34 C4 38 21 44 C4
+34 C4 50 00 1E C8 22 C9 6A CC 34 C4 7E 20 CE C4
+B2 C5 76 C9 0D 73 74 61 63 6B 20 65 6D 70 74 79
+20 21 7E CD 34 C4 30 FF AC C7 B2 C5 76 C9 0B 46
+52 41 4D 20 66 75 6C 6C 20 21 7E CD 42 C6 F4 C4
+C0 C5 10 CD 76 C9 04 0D 20 20 20 00 BC C5 18 CD
+16 C8 05 41 42 4F 52 54 3F 40 80 20 BE 3F 8F 93
+02 00 81 26 B2 40 82 48 9A C8 B0 12 66 D2 82 43
+18 DB 82 43 24 DB 82 43 30 DB 82 43 60 DB 82 43
+6C DB 82 43 78 DB A2 B3 1C 05 FD 27 B2 40 11 00
+0E 05 92 C3 1C 05 38 40 A0 AA 39 42 19 83 FE 23
+18 83 FB 23 92 B3 1C 05 F4 23 87 12 76 C9 04 1B
+5B 37 6D 00 5A C9 5A C9 76 C9 04 1B 5B 30 6D 00
+5A C9 AE D1 F0 D1 F6 D1 78 CD 72 CD 86 41 42 4F
+52 54 22 00 87 12 90 C9 34 C4 7E CD 06 CC 2A C4
+22 CA 01 27 87 12 4C C6 D0 C9 28 CA C0 C5 12 CE
+2A C4 AE CC 7A C6 81 5C 92 42 BE 21 C2 21 30 4D
+87 12 AC C9 4C C6 D0 C9 2A CE 08 4E 7A 4E 5A D3
+5A 53 0A 58 19 42 C8 21 6E 4E 3E F0 1E 00 09 5E
+82 48 AE 21 82 49 B0 21 82 4A B2 21 2A 52 82 4A
+C4 21 3E 4F 3D 41 30 41 87 12 76 C9 0F 73 74 61
+63 6B 20 6D 69 73 6D 61 74 63 68 21 84 CD 82 9F
+B4 21 F2 23 18 42 AE 21 19 42 B0 21 A8 49 FE FF
+89 48 00 00 30 4D CA C9 08 56 41 52 49 41 42 4C
+45 00 B0 12 20 CE BA 40 86 12 FC FF EF 3F 56 CC
+08 43 4F 4E 53 54 41 4E 54 00 B0 12 20 CE BA 40
+85 12 FC FF 8A 4E FE FF 3E 4F E0 3F A0 CE 06 43
+52 45 41 54 45 00 B0 12 20 CE BA 40 85 12 FC FF
+8A 4A FE FF D3 3F C4 CC 05 44 4F 45 53 3E 1A 42
+B2 21 BA 40 84 12 00 00 8A 4D 02 00 3D 41 30 4D
+D8 CE 05 44 45 46 45 52 B0 12 20 CE BA 40 30 40
+FC FF BA 40 EE CE FE FF B9 3F 00 00 81 5B 82 43
+B6 21 30 4D 16 CE 01 5D B2 43 B6 21 30 4D 8C C9
+87 52 45 43 55 52 53 45 19 42 C4 21 99 42 B2 21
+00 00 A2 53 C4 21 30 4D 0C CF 01 3A B0 12 20 CE
+BA 40 87 12 FC FF A2 83 C4 21 B2 43 B6 21 82 4F
+B4 21 30 4D 3A CF 81 3B 82 93 B6 21 5D 27 87 12
+34 C4 2A C4 06 CC 6E CE 0E CF 2A C4 FE C8 09 49
+4D 4D 45 44 49 41 54 45 1A 42 AE 21 FA D0 80 00
+00 00 30 4D BE 4F 02 00 3E 4F 30 4D 6E CF 82 49
+53 00 87 12 42 C6 F4 C4 C0 C5 A6 CF B2 CF 34 C4
+84 CF 06 CC 2A C4 04 CE 84 CF 2A C4 56 CF 83 5B
+27 5D 87 12 04 CE 34 C4 34 C4 06 CC 06 CC 2A C4
+F4 CC 88 50 4F 53 54 50 4F 4E 45 00 87 12 4C C6
+D0 C9 28 CA 54 C4 C0 C5 12 CE 7E C5 C0 C5 EC CF
+34 C4 34 C4 06 CC 06 CC 34 C4 06 CC 06 CC 2A C4
+F2 CF 3A 4E 82 4A C6 21 2E 4E 82 4E C4 21 3D 40
+10 00 09 4A 08 49 29 83 18 48 FE FF 0E 98 FC 2B
+89 48 00 00 1D 83 F6 23 2A 4A 0A 93 F0 23 3E 4F
+3D 41 30 4D 8E CF 82 49 46 00 2F 83 8F 4E 00 00
+1E 42 C4 21 BE 40 C0 C5 00 00 A2 52 C4 21 2E 53
+30 4D F2 CE 84 45 4C 53 45 00 1A 42 C4 21 BA 40
+BC C5 00 00 2A 52 82 4A C4 21 8E 4A 00 00 2A 83
+0E 4A 30 4D 54 C9 84 54 48 45 4E 00 9E 42 C4 21
+00 00 3E 4F 30 4D BE CE 85 42 45 47 49 4E 30 40
+AC C7 66 D0 85 55 4E 54 49 4C 39 40 C0 C5 1A 42
+C4 21 A2 52 C4 21 8A 49 00 00 8A 4E 02 00 3E 4F
+30 4D EC CD 85 41 47 41 49 4E 39 40 BC C5 EF 3F
+88 CE 85 57 48 49 4C 45 87 12 2A D0 6E C4 2A C4
+20 CF 86 52 45 50 45 41 54 00 87 12 AA D0 6C D0
+2A C4 44 D0 82 44 4F 00 2F 83 8F 4E 00 00 1E 42
+C4 21 BE 40 CA C5 00 00 2E 53 82 4E C4 21 A2 53
+AC 21 1A 42 AC 21 8A 43 00 00 30 4D 18 CC 84 4C
+4F 4F 50 00 39 40 EC C5 1A 42 C4 21 A2 52 C4 21
+8A 49 00 00 8A 4E 02 00 1E 42 AC 21 A2 83 AC 21
+2E 4E 0E 93 04 24 9E 42 C4 21 00 00 F5 3F 3E 4F
+30 4D 0C C8 85 2B 4C 4F 4F 50 39 40 DA C5 E4 3F
+FE D0 85 4C 45 41 56 45 1A 42 C4 21 BA 40 FC C5
+00 00 BA 40 BC C5 02 00 B2 50 06 00 C4 21 A2 53
+AC 21 2A 52 19 42 AC 21 89 4A 00 00 30 4D 42 D1
+04 4D 4F 56 45 00 0A 4E 38 4F 39 4F 3E 4F 0A 93
+11 24 08 99 0F 24 06 2C F8 49 00 00 18 53 1A 83
+FB 23 30 4D 08 5A 09 5A 19 83 18 83 E8 49 00 00
+1A 83 FA 23 30 4D 34 C4 CA 21 FC C4 2A C4 84 12
+A6 D1 88 D4 70 D4 D4 D0 02 CE 58 D4 34 D1 70 D1
+B8 C9 14 D2 48 D2 84 D0 08 D3 48 C5 AE CF 16 CF
+90 CA 00 00 3A 40 0C 00 39 40 CA 21 38 40 CC 21
+D9 3F 3A 40 0E 00 39 40 CC 21 38 40 CA 21 CC 3F
+82 43 CC 21 30 4D 92 42 CA 21 C8 21 30 4D C2 CF
+09 50 57 52 5F 53 54 41 54 45 84 12 F0 CF 54 D4
+9E DB 00 D2 08 50 57 52 5F 48 45 52 45 00 92 42
+C4 21 10 D2 92 42 C6 21 0E D2 EF 3F C2 D0 09 52
+53 54 5F 53 54 41 54 45 92 42 0C 18 10 D2 92 42
+0E 18 0E D2 E2 3F 2E D2 08 52 53 54 5F 48 45 52
+45 00 92 42 C4 21 0C 18 92 42 C6 21 0E 18 DF 3F
+B2 40 AE D2 10 D3 B2 40 C8 C8 D8 C8 B2 40 04 C9
+18 C9 B2 40 04 C8 12 C8 30 41 B2 D0 04 57 49 50
+45 00 39 40 80 FF B9 43 00 00 29 53 39 90 E2 FF
+FA 23 B0 12 60 D2 B2 40 9E DB C4 21 B2 40 54 D4
+C6 21 D7 3F 26 D0 06 28 57 41 52 4D 29 00 1E 42
+08 18 87 12 76 C9 05 0D 1B 5B 37 6D 5A C9 98 C7
+76 C9 27 20 46 61 73 74 46 6F 72 74 68 20 56 31
+36 30 20 31 36 4D 48 7A 20 28 43 29 20 4A 2E 4D
+2E 54 68 6F 6F 72 65 6E 73 20 5A C9 34 C4 30 FF
+AC C7 2A C5 58 C7 76 C9 0B 62 79 74 65 73 20 66
+72 65 65 20 8A CD 7C D2 04 57 41 52 4D 00 30 40
+AE D2 78 D0 04 43 4F 4C 44 00 B2 40 04 A5 20 01
+B2 40 88 5A CC 01 B2 43 02 02 B2 D3 06 02 B2 40
+00 01 24 02 B2 40 FF FE 22 02 B2 D0 FF FE 26 02
+B2 43 42 02 B2 D3 46 02 B2 43 62 02 B2 D3 66 02
+F2 40 A5 00 A1 01 F2 40 10 00 A0 01 D2 43 A1 01
+B2 40 00 A5 60 01 B2 40 29 01 80 01 B2 40 0B 00
+82 01 B2 40 E9 01 84 01 39 40 40 00 82 43 88 01
+92 D2 5E 01 08 18 A2 93 08 18 01 24 59 03 38 40
+50 C3 18 83 FE 23 19 83 FA 23 B2 40 00 06 2A 02
+3A 40 20 D3 39 40 E2 FF 89 4A 00 00 29 53 FC 23
+92 42 02 18 EC FF B2 40 18 00 0A 18 31 40 E0 20
+3F 40 80 20 37 40 00 C4 36 40 B4 C4 35 40 08 C4
+34 40 14 C4 B2 40 0A 00 DA 21 B2 43 DC 21 92 C3
+30 01 18 42 08 18 D2 B3 00 02 04 20 38 E3 18 53
+82 48 08 18 B2 40 81 00 00 05 B2 40 05 00 06 05
+B2 40 00 49 08 05 F2 D0 03 00 0A 02 92 C3 00 05
+92 D3 1A 05 3D 40 2E D4 18 42 08 18 38 90 0A 00
+30 27 38 90 16 00 2D 2F 28 93 06 23 EE 26 0E D3
+84 12 A6 D1 7C DA 28 DB 30 DA 7C DB F6 D9 B0 DA
+FA D6 00 00 EC D9 9C DA 4E DA 8C DA 0A D8 00 00
+00 00 8E DB D2 D1 A6 D2 85 48 49 32 4C 4F 87 12
+AC C7 3E D0 06 CC 0E CF D4 D1 30 D4 2A C4 14 D3
+04 43 4F 44 45 00 B0 12 20 CE A2 82 C4 21 87 12
+4E CF BC C5 68 D4 A4 D0 03 41 53 4D 92 42 C8 21
+B8 21 B2 40 34 D4 C8 21 EE 3F 00 00 07 45 4E 44
+43 4F 44 45 87 12 E2 D1 6E CE 2A C4 9C D4 06 45
+4E 44 41 53 4D 00 92 42 B8 21 C8 21 F3 3F 00 00
+05 43 4F 4C 4F 4E 1A 42 C4 21 BA 40 87 12 00 00
+A2 53 C4 21 B2 43 B6 21 30 40 E2 D1 00 00 05 4C
+4F 32 48 49 1A 42 C4 21 BA 40 B0 12 00 00 BA 40
+2A C4 02 00 A2 52 C4 21 ED 3F 38 40 BE 21 39 48
+2A 48 09 5A 1A 52 C2 21 09 9A 03 24 7E 9A FC 27
+1A 83 0E 4A 2A 88 82 4A C2 21 30 4D B0 12 2A C4
+D0 C9 28 CA 72 C5 C0 C5 32 D5 FC CA C0 C5 12 CE
+54 D5 34 D5 29 4E 39 90 86 12 02 20 2E 53 30 41
+39 90 85 12 03 20 1E 4E 02 00 30 41 39 90 84 12
+01 20 2E 52 30 41 19 42 C4 21 A2 53 C4 21 89 4E
+00 00 3E 40 29 00 12 12 C2 21 92 53 C2 21 B0 12
+2A C4 D0 C9 FC CA C0 C5 86 D5 7C D5 21 53 3E 90
+10 00 BB 2D 30 41 88 D5 B2 41 C2 21 22 D3 30 41
+87 12 4C C6 FA D4 98 D5 82 43 BC 21 92 42 C4 21
+BA 21 A2 53 C4 21 0A 4E 3E 4F FA 90 23 00 00 00
+34 20 92 53 C2 21 B0 12 1C D5 0E 93 04 20 B2 40
+00 03 BC 21 27 3C 1E 93 04 20 B2 40 10 03 BC 21
+21 3C 2E 93 04 20 B2 40 20 03 BC 21 1B 3C 2E 92
+04 20 B2 40 20 02 BC 21 15 3C 3E 92 04 20 B2 40
+30 02 BC 21 0F 3C 3E 93 04 20 B2 40 30 03 BC 21
+09 3C B2 40 30 00 BC 21 19 42 C4 21 A2 53 C4 21
+89 4E 00 00 3E 4F 3D 41 30 4D FA 90 26 00 00 00
+08 20 B2 40 10 02 BC 21 92 53 C2 21 30 12 08 D6
+75 3F FA 90 40 00 00 00 1A 20 B2 40 20 00 BC 21
+92 53 C2 21 B0 12 66 D5 0E 20 B2 50 10 00 BC 21
+3E 40 2B 00 B0 12 66 D5 32 24 92 92 BE 21 C2 21
+02 24 92 53 C2 21 8E 10 82 5E BC 21 D3 3F B0 12
+66 D5 F9 23 B2 50 10 00 BC 21 3E 40 28 00 B0 12
+1C D5 30 12 58 D6 67 3F 87 12 4C C6 FA D4 90 D6
+FE 90 26 00 00 00 3E 40 20 00 04 20 B2 50 82 00
+BC 21 C2 3F B0 12 66 D5 DF 23 B2 50 80 00 BC 21
+3E 40 28 00 B0 12 1C D5 B0 12 56 D5 D5 23 3D 40
+12 CE 30 4D 00 00 04 52 45 54 49 00 87 12 34 C4
+00 13 06 CC 2A C4 34 C4 2C 00 90 D5 88 D6 E0 D6
+2E 4E 1E D2 BC 21 19 42 BA 21 92 3F DE D4 03 4D
+4F 56 84 12 D6 D6 00 40 EE D6 05 4D 4F 56 2E 42
+84 12 D6 D6 40 40 00 00 03 41 44 44 84 12 D6 D6
+00 50 08 D7 05 41 44 44 2E 42 84 12 D6 D6 40 50
+14 D7 04 41 44 44 43 00 84 12 D6 D6 00 60 22 D7
+06 41 44 44 43 2E 42 00 84 12 D6 D6 40 60 C6 D6
+04 53 55 42 43 00 84 12 D6 D6 00 70 40 D7 06 53
+55 42 43 2E 42 00 84 12 D6 D6 40 70 4E D7 03 53
+55 42 84 12 D6 D6 00 80 5E D7 05 53 55 42 2E 42
+84 12 D6 D6 40 80 C0 D4 03 43 4D 50 84 12 D6 D6
+00 90 78 D7 05 43 4D 50 2E 42 84 12 D6 D6 40 90
+AE D4 04 44 41 44 44 00 84 12 D6 D6 00 A0 92 D7
+06 44 41 44 44 2E 42 00 84 12 D6 D6 40 A0 84 D7
+03 42 49 54 84 12 D6 D6 00 B0 B0 D7 05 42 49 54
+2E 42 84 12 D6 D6 40 B0 BC D7 03 42 49 43 84 12
+D6 D6 00 C0 CA D7 05 42 49 43 2E 42 84 12 D6 D6
+40 C0 D6 D7 03 42 49 53 84 12 D6 D6 00 D0 E4 D7
+05 42 49 53 2E 42 84 12 D6 D6 40 D0 00 00 03 58
+4F 52 84 12 D6 D6 00 E0 FE D7 05 58 4F 52 2E 42
+84 12 D6 D6 40 E0 30 D7 03 41 4E 44 84 12 D6 D6
+00 F0 18 D8 05 41 4E 44 2E 42 84 12 D6 D6 40 F0
+4C C6 90 D5 36 D8 1A 42 BC 21 B2 F0 70 00 BC 21
+8A 10 3A F0 0F 00 82 DA BC 21 4A 3F 6A D7 03 52
+52 43 84 12 30 D8 00 10 4E D8 05 52 52 43 2E 42
+84 12 30 D8 40 10 5A D8 04 53 57 50 42 00 84 12
+30 D8 80 10 68 D8 03 52 52 41 84 12 30 D8 00 11
+76 D8 05 52 52 41 2E 42 84 12 30 D8 40 11 82 D8
+03 53 58 54 84 12 30 D8 80 11 00 00 04 50 55 53
+48 00 84 12 30 D8 00 12 9C D8 06 50 55 53 48 2E
+42 00 84 12 30 D8 40 12 F0 D7 04 43 41 4C 4C 00
+84 12 30 D8 80 12 34 C4 2C 00 90 D5 88 D6 D0 D8
+59 42 BC 21 5A 42 BD 21 82 4A BC 21 BE 90 00 15
+00 00 02 20 0A 89 02 3C 09 8A 0A 49 3A 90 10 00
+03 2C 5A 0E A8 3F 1A 53 0E 4A 87 12 98 C7 76 C9
+0D 6F 75 74 20 6F 66 20 62 6F 75 6E 64 73 84 CD
+AA D8 05 50 55 53 48 4D 84 12 C6 D8 00 15 12 D9
+04 50 4F 50 4D 00 84 12 C6 D8 00 17 4C C6 FA D4
+32 D9 82 43 BC 21 92 42 C4 21 BA 21 A2 53 C4 21
+92 53 C2 21 3E 40 2C 00 B0 12 2A C4 D0 C9 FC CA
+C0 C5 12 CE 88 D6 58 D9 0A 4E 3E 4F 1A 83 2A 92
+CA 2F 8A 10 5A 06 6F 3F 90 D8 04 52 52 43 4D 00
+84 12 2C D9 50 00 6A D9 04 52 52 41 4D 00 84 12
+2C D9 50 01 78 D9 04 52 4C 41 4D 00 84 12 2C D9
+50 02 86 D9 04 52 52 55 4D 00 84 12 2C D9 50 03
+85 12 00 3C 94 D9 03 53 3E 3D 85 12 00 38 A6 D9
+02 53 3C 00 85 12 00 34 20 D9 03 30 3E 3D 85 12
+00 30 BA D9 02 30 3C 00 85 12 00 30 00 00 02 55
+3C 00 85 12 00 2C CE D9 03 55 3E 3D 85 12 00 28
+C4 D9 03 30 3C 3E 85 12 00 24 E2 D9 02 30 3D 00
+85 12 00 20 00 00 02 49 46 00 1A 42 C4 21 8A 4E
+00 00 A2 53 C4 21 0E 4A 30 4D D8 D9 04 54 48 45
+4E 00 1A 42 C4 21 08 4E 3E 4F 09 48 29 53 0A 89
+0A 11 3A 90 00 02 68 2F 88 DA 00 00 30 4D A0 D7
+04 45 4C 53 45 00 1A 42 C4 21 BA 40 00 3C 00 00
+A2 53 C4 21 2F 83 8F 4A 00 00 E3 3F 0C DA 05 55
+4E 54 49 4C 3A 4F 08 4E 3E 4F 19 42 C4 21 2A 83
+0A 89 0A 11 3A 90 00 FE 47 3B 3A F0 FF 03 08 DA
+89 48 00 00 A2 53 C4 21 30 4D 24 D8 05 41 47 41
+49 4E 87 12 A0 D9 54 DA 2A C4 00 00 05 57 48 49
+4C 45 87 12 FA D9 6E C4 2A C4 B0 D9 06 52 45 50
+45 41 54 00 87 12 A0 D9 54 DA 12 DA 2A C4 00 00
+03 4A 4D 50 87 12 04 CE A0 D9 54 DA 2A C4 3E B0
+00 10 03 20 3E E0 00 04 30 4D 3E 90 00 34 06 28
+03 24 3E 40 00 34 30 4D 3E 40 00 38 30 4D 00 00
+04 3F 4A 4D 50 00 87 12 BE DA 04 CE 6E C4 54 DA
+2A C4 F4 DA 3D 41 08 4E 3E 4F 2A 48 0A 93 04 20
+98 42 C4 21 00 00 30 4D 88 43 00 00 A4 3F BA D8
+03 42 57 31 84 12 F2 DA 00 00 10 DB 03 42 57 32
+84 12 F2 DA 00 00 1C DB 03 42 57 33 84 12 F2 DA
+00 00 34 DB 3D 41 1A 42 C4 21 28 4E 08 93 08 20
+BA 4F 00 00 A2 53 C4 21 8E 4A 00 00 3E 4F 30 4D
+8E 43 00 00 61 3F 00 00 03 46 57 31 84 12 32 DB
+00 00 58 DB 03 46 57 32 84 12 32 DB 00 00 64 DB
+03 46 57 33 84 12 32 DB 00 00 70 DB 04 47 4F 54
+4F 00 87 12 A0 D9 04 CE FC CB 2A C4 E0 DA 05 3F
+47 4F 54 4F 87 12 BE DA 04 CE FC CB 2A C4
+@FFE2
+20 D3 20 D3 20 D3 20 D3 20 D3 74 C8 20 D3 20 D3
+20 D3 20 D3 20 D3 20 D3 20 D3 20 D3 20 D3
+q
--- /dev/null
+@1800
+10 00 68 C8 F4 01 80 04 FD FF 18 00 7C DB 32 D4
+52 C8 5A C8 00 00 00 00
+@21AA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@C400
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 C4
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 C4 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 C4 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E C4 02 3E 52 00 0E 12 3E 4F 30 4D 8E C4
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 C4
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C C4 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 20 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 C4 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 C5
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 C4 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA C4 03 41 4E 44 3E FF 30 4D 7A C4 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E C5 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 C5 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E C5 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 C5 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 C4 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE C5 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 C5 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 C5 03 3E 49 4E 85 12 C2 21 10 C5
+04 42 41 53 45 00 85 12 DA 21 C0 C4 05 53 54 41
+54 45 85 12 B6 21 30 C6 02 42 4C 00 85 12 20 00
+F4 C5 03 55 4D 2A 2C 4F 0A 43 08 43 0B 43 19 43
+0E B9 02 24 08 5C 0B 6A 0C 5C 0A 6A 09 59 F8 2B
+8F 48 00 00 0E 4B 30 4D 94 C5 02 3C 23 00 B2 40
+AA 21 AA 21 30 4D 1E 15 0E 43 3D 40 20 00 0A 93
+04 20 0D 11 0A 4C 0C 43 09 43 0E 9B 01 28 0E 8B
+09 69 08 68 1D 83 07 30 0C 5C 0A 6A 0E 6E F5 2B
+0E 8B 12 D3 F5 3F 0A 4E 1D 17 30 41 48 C6 01 23
+1B 42 DA 21 2C 4F 0A 4E B0 12 86 C6 8F 49 00 00
+0E 48 7A 90 0A 00 02 28 3A 50 07 00 3A 50 30 00
+92 83 AA 21 18 42 AA 21 C8 4A 00 00 30 4D BE C6
+02 23 53 00 87 12 C0 C6 FA C6 2D 83 09 93 E0 23
+0E 93 DE 23 3D 41 30 4D F0 C6 02 23 3E 00 9F 42
+AA 21 00 00 3E 40 AA 21 2E 8F 30 4D 00 C6 04 48
+4F 4C 44 00 0A 4E 3E 4F DB 3F 3C C6 04 53 49 47
+4E 00 0E 93 3E 4F 3A 40 2D 00 D2 33 30 4D 52 C6
+03 55 44 2E 87 12 7E C6 F4 C6 0E C7 4E C9 16 C9
+2A C4 40 C7 02 55 2E 00 2F 83 8F 4E 00 00 0E 43
+F1 3F 3E B0 00 80 06 24 BF E3 00 00 3E E3 9F 53
+00 00 0E 63 30 4D DA C4 02 44 2E 00 87 12 7E C6
+6E C4 80 C4 62 C7 F4 C6 92 C4 32 C7 0E C7 4E C9
+16 C9 2A C4 52 C5 01 2E 3E B0 00 80 DD 27 2F 83
+3E 43 EC 3F 1E C7 04 48 45 52 45 00 2F 83 8F 4E
+00 00 1E 42 C4 21 30 4D 62 C5 05 41 4C 4C 4F 54
+82 5E C4 21 3E 4F 30 4D 0A C7 02 43 2C 00 1A 42
+C4 21 CA 4E 00 00 92 53 C4 21 3E 4F 30 4D 2F 83
+8F 4E 00 00 B0 12 52 C8 92 B3 1C 05 FD 27 1E 42
+0C 05 B0 12 5A C8 30 4D 30 40 DE C7 A6 C7 05 28
+4B 45 59 29 18 42 0C 05 EA 3F 12 C6 03 4B 45 59
+30 40 04 C8 BA C7 06 41 43 43 45 50 54 00 3C 40
+A0 C8 3B 40 70 C8 2D 15 0A 4E 2E 4F 0A 5E 3B 40
+0D 00 3C 40 20 00 3D 40 94 C8 92 B3 1C 05 05 24
+18 42 0C 05 38 90 0A 00 04 20 21 53 39 40 62 C8
+4D 15 B2 40 11 00 0E 05 30 41 B2 40 13 00 0E 05
+30 41 12 D2 0A 18 FD 3F 21 52 3A 17 58 42 0C 05
+48 9B F3 27 48 9C 06 2C 78 92 0E 20 2E 9F 0C 24
+1E 83 05 3C 0E 9A 03 24 CE 48 00 00 1E 53 82 48
+0E 05 30 4D 96 C8 2D 83 92 B3 1C 05 FD 27 E6 23
+B2 40 18 00 0A 18 3E 8F 3D 41 30 4D FE C7 06 28
+45 4D 49 54 29 00 08 4E 3E 4F A2 B3 1C 05 FD 27
+E6 3F 78 C7 04 45 4D 49 54 00 30 40 B6 C8 C4 C8
+04 45 43 48 4F 00 B2 40 82 48 8E C8 30 4D 96 C7
+06 4E 4F 45 43 48 4F 00 B2 40 30 4D 8E C8 30 4D
+AE C8 04 28 43 52 29 00 2F 83 8F 4E 00 00 3E 40
+0D 00 E3 3F CA C7 02 43 52 00 30 40 F8 C8 2C C7
+05 53 50 41 43 45 2F 83 8F 4E 00 00 3E 40 20 00
+D4 3F 10 C9 06 53 50 41 43 45 53 00 0E 93 09 24
+0D 12 3D 40 38 C9 EF 3F 3A C9 2D 83 1E 83 EB 23
+3D 41 3E 4F 30 4D 54 C7 04 54 59 50 45 00 0E 93
+95 24 2A 4F 8F 5E 00 00 0E 4A 87 12 CA C5 02 C6
+0A C5 CA C8 EC C5 5E C9 2A C4 2F 82 8F 4E 02 00
+7E 4D 8F 4D 00 00 0D 5E 1D B3 0D 63 30 4D 24 C9
+82 53 22 00 87 12 34 C4 6A C9 FA CB 34 C4 22 00
+C4 C9 94 C9 3D 41 6E 4E 1E 83 82 5E C4 21 3E 4F
+92 B3 C4 21 A2 63 C4 21 30 4D E0 C8 82 2E 22 00
+87 12 84 C9 34 C4 4E C9 FA CB 2A C4 00 00 04 57
+4F 52 44 00 3C 40 BE 21 39 4C 3A 4C 09 5A 3A 5C
+28 4C 09 9A 19 24 7E 9A FC 27 1A 83 3B 40 60 00
+C8 4C 00 00 09 9A 0C 24 7C 4A 4E 9C 09 24 18 53
+4B 9C F6 2F 7C 90 7B 00 F3 2F 7C 80 20 00 F0 3F
+1A 82 C0 21 82 4A C2 21 1E 42 C4 21 08 8E CE 48
+00 00 30 4D 00 00 04 46 49 4E 44 00 2F 83 0C 4E
+65 4C 74 40 80 00 3B 40 CA 21 3E 4B 0E 93 1E 24
+58 4C 01 00 78 F0 1E 00 0E 58 2E 53 1E 4E FE FF
+0E 93 F3 27 09 4E 78 49 48 C4 48 95 F7 23 0A 4C
+1A 53 FA 99 00 00 F2 23 58 83 FA 23 19 B3 09 63
+0C 49 6A 4E 1E 43 4A 93 01 30 2E 83 8F 4C 00 00
+35 40 08 C4 34 40 14 C4 30 4D 2F 53 2F 53 3E 4F
+30 4D 26 C6 07 3E 4E 55 4D 42 45 52 2C 4F 6C 4C
+7C 80 30 00 7C 90 0A 00 02 28 7C 80 07 00 1C 92
+DA 21 25 2C 2E 15 2F 83 9F 4F 04 00 00 00 1E 42
+DA 21 3D 40 BA CA 30 40 56 C6 BC CA 2F 12 9F 4F
+06 00 00 00 1E 42 DA 21 3D 40 D0 CA 30 40 56 C6
+D2 CA 3E 51 BF 51 00 00 0E 63 AF 4F 06 00 8F 4E
+04 00 1D 17 2F 53 9F 53 00 00 1E 83 CF 23 30 4D
+03 12 0D 12 12 12 DA 21 32 C0 00 02 6D 4E 0D 5E
+0C 4E 7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23 32 D0
+00 02 FC 4C FE FF 0D 9C FC 2F DE 83 00 00 3D 40
+7C CB 3F 82 8F 4E 06 00 8F 43 04 00 8F 43 02 00
+0A 4E 7E 4A 8F 4A 00 00 79 4A 79 90 2D 00 17 2C
+79 80 24 00 04 20 B2 40 10 00 DA 21 0A 3C 59 83
+03 20 A2 43 DA 21 05 3C 69 53 98 23 B2 40 0A 00
+DA 21 8F 4A 00 00 1E 83 79 4A 79 90 2D 00 8E 23
+B1 43 04 00 8F 4A 00 00 1E 83 88 3F 7E CB 2F 53
+0E 93 2C 17 82 4C DA 21 03 24 2F 52 0E F3 30 4D
+8F 93 00 00 15 20 32 B0 00 02 14 20 0E 93 05 24
+1A 4F 02 00 1A 83 0A 93 0B 38 2F 53 BF 4F 00 00
+3E E3 05 20 BF E3 00 00 9F 53 00 00 3E E3 30 4D
+32 D0 00 02 9F 4F 02 00 04 00 BF 4F 00 00 3E E3
+F6 23 BF E3 02 00 BF E3 00 00 9F 53 02 00 8F 63
+00 00 3E E3 30 4D D0 C8 07 45 58 45 43 55 54 45
+0A 4E 3E 4F 00 4A 28 C5 01 2C 1A 42 C4 21 A2 53
+C4 21 8A 4E 00 00 3E 4F 30 4D F8 CB 87 4C 49 54
+45 52 41 4C 82 93 B6 21 16 24 32 B0 00 02 09 24
+1A 42 C4 21 A2 52 C4 21 BA 40 34 C4 00 00 BA 4F
+02 00 1A 42 C4 21 A2 52 C4 21 BA 40 34 C4 00 00
+8A 4E 02 00 3E 4F 30 4D 06 C9 05 43 4F 55 4E 54
+2F 83 1E 53 8F 4E 00 00 5E 4E FF FF 30 4D 82 4E
+BE 21 B2 4F C0 21 3E 4F 82 43 C2 21 87 12 4C C6
+C4 C9 74 CC 3D 40 80 CC D1 22 3D 41 3E 4F 30 4D
+82 CC 0A 4E 3E 4F 3D 40 98 CC 32 27 3D 40 6E CC
+1A E2 B6 21 B2 27 AC 23 9A CC 3E 4F 3D 40 6E CC
+B9 23 DE 53 00 00 68 4E 08 5E F8 40 3F 00 00 00
+3D 40 60 CE CD 3F E8 CB 08 45 56 41 4C 55 41 54
+45 00 39 40 BE 21 39 12 39 12 39 12 0D 12 B0 12
+2A C4 5E CC D6 CC 3D 41 B2 41 C2 21 B2 41 C0 21
+B2 41 BE 21 30 4D 7A C5 04 51 55 49 54 00 31 40
+E0 20 B2 40 00 20 AC 21 82 43 B6 21 82 43 08 18
+B0 12 2A C4 6A C9 04 0D 6F 6B 20 00 4E C9 34 C4
+38 21 44 C4 34 C4 50 00 1E C8 16 C9 5E CC 34 C4
+7E 20 CE C4 B2 C5 6A C9 0D 73 74 61 63 6B 20 65
+6D 70 74 79 20 21 72 CD 34 C4 30 FF AC C7 B2 C5
+6A C9 0B 46 52 41 4D 20 66 75 6C 6C 20 21 72 CD
+42 C6 F4 C4 C0 C5 04 CD 6A C9 04 0D 20 20 20 00
+BC C5 0C CD 16 C8 05 41 42 4F 52 54 3F 40 80 20
+BE 3F 8F 93 02 00 81 26 B2 40 82 48 8E C8 B0 12
+5A D2 82 43 F6 DA 82 43 02 DB 82 43 0E DB 82 43
+3E DB 82 43 4A DB 82 43 56 DB A2 B3 1C 05 FD 27
+B2 40 11 00 0E 05 92 C3 1C 05 38 40 55 05 39 42
+19 83 FE 23 18 83 FB 23 92 B3 1C 05 F4 23 87 12
+6A C9 04 1B 5B 37 6D 00 4E C9 4E C9 6A C9 04 1B
+5B 30 6D 00 4E C9 A2 D1 E4 D1 EA D1 6C CD 66 CD
+86 41 42 4F 52 54 22 00 87 12 84 C9 34 C4 72 CD
+FA CB 2A C4 16 CA 01 27 87 12 4C C6 C4 C9 1C CA
+C0 C5 06 CE 2A C4 A2 CC 7A C6 81 5C 92 42 BE 21
+C2 21 30 4D 87 12 A0 C9 4C C6 C4 C9 1E CE 08 4E
+7A 4E 5A D3 5A 53 0A 58 19 42 C8 21 6E 4E 3E F0
+1E 00 09 5E 82 48 AE 21 82 49 B0 21 82 4A B2 21
+2A 52 82 4A C4 21 3E 4F 3D 41 30 41 87 12 6A C9
+0F 73 74 61 63 6B 20 6D 69 73 6D 61 74 63 68 21
+78 CD 82 9F B4 21 F2 23 18 42 AE 21 19 42 B0 21
+A8 49 FE FF 89 48 00 00 30 4D BE C9 08 56 41 52
+49 41 42 4C 45 00 B0 12 14 CE BA 40 86 12 FC FF
+EF 3F 4A CC 08 43 4F 4E 53 54 41 4E 54 00 B0 12
+14 CE BA 40 85 12 FC FF 8A 4E FE FF 3E 4F E0 3F
+94 CE 06 43 52 45 41 54 45 00 B0 12 14 CE BA 40
+85 12 FC FF 8A 4A FE FF D3 3F B8 CC 05 44 4F 45
+53 3E 1A 42 B2 21 BA 40 84 12 00 00 8A 4D 02 00
+3D 41 30 4D CC CE 05 44 45 46 45 52 B0 12 14 CE
+BA 40 30 40 FC FF BA 40 E2 CE FE FF B9 3F 00 00
+81 5B 82 43 B6 21 30 4D 0A CE 01 5D B2 43 B6 21
+30 4D 80 C9 87 52 45 43 55 52 53 45 19 42 C4 21
+99 42 B2 21 00 00 A2 53 C4 21 30 4D 00 CF 01 3A
+B0 12 14 CE BA 40 87 12 FC FF A2 83 C4 21 B2 43
+B6 21 82 4F B4 21 30 4D 2E CF 81 3B 82 93 B6 21
+5D 27 87 12 34 C4 2A C4 FA CB 62 CE 02 CF 2A C4
+F2 C8 09 49 4D 4D 45 44 49 41 54 45 1A 42 AE 21
+FA D0 80 00 00 00 30 4D BE 4F 02 00 3E 4F 30 4D
+62 CF 82 49 53 00 87 12 42 C6 F4 C4 C0 C5 9A CF
+A6 CF 34 C4 78 CF FA CB 2A C4 F8 CD 78 CF 2A C4
+4A CF 83 5B 27 5D 87 12 F8 CD 34 C4 34 C4 FA CB
+FA CB 2A C4 E8 CC 88 50 4F 53 54 50 4F 4E 45 00
+87 12 4C C6 C4 C9 1C CA 54 C4 C0 C5 06 CE 7E C5
+C0 C5 E0 CF 34 C4 34 C4 FA CB FA CB 34 C4 FA CB
+FA CB 2A C4 E6 CF 3A 4E 82 4A C6 21 2E 4E 82 4E
+C4 21 3D 40 10 00 09 4A 08 49 29 83 18 48 FE FF
+0E 98 FC 2B 89 48 00 00 1D 83 F6 23 2A 4A 0A 93
+F0 23 3E 4F 3D 41 30 4D 82 CF 82 49 46 00 2F 83
+8F 4E 00 00 1E 42 C4 21 BE 40 C0 C5 00 00 A2 52
+C4 21 2E 53 30 4D E6 CE 84 45 4C 53 45 00 1A 42
+C4 21 BA 40 BC C5 00 00 2A 52 82 4A C4 21 8E 4A
+00 00 2A 83 0E 4A 30 4D 48 C9 84 54 48 45 4E 00
+9E 42 C4 21 00 00 3E 4F 30 4D B2 CE 85 42 45 47
+49 4E 30 40 AC C7 5A D0 85 55 4E 54 49 4C 39 40
+C0 C5 1A 42 C4 21 A2 52 C4 21 8A 49 00 00 8A 4E
+02 00 3E 4F 30 4D E0 CD 85 41 47 41 49 4E 39 40
+BC C5 EF 3F 7C CE 85 57 48 49 4C 45 87 12 1E D0
+6E C4 2A C4 14 CF 86 52 45 50 45 41 54 00 87 12
+9E D0 60 D0 2A C4 38 D0 82 44 4F 00 2F 83 8F 4E
+00 00 1E 42 C4 21 BE 40 CA C5 00 00 2E 53 82 4E
+C4 21 A2 53 AC 21 1A 42 AC 21 8A 43 00 00 30 4D
+0C CC 84 4C 4F 4F 50 00 39 40 EC C5 1A 42 C4 21
+A2 52 C4 21 8A 49 00 00 8A 4E 02 00 1E 42 AC 21
+A2 83 AC 21 2E 4E 0E 93 04 24 9E 42 C4 21 00 00
+F5 3F 3E 4F 30 4D 0C C8 85 2B 4C 4F 4F 50 39 40
+DA C5 E4 3F F2 D0 85 4C 45 41 56 45 1A 42 C4 21
+BA 40 FC C5 00 00 BA 40 BC C5 02 00 B2 50 06 00
+C4 21 A2 53 AC 21 2A 52 19 42 AC 21 89 4A 00 00
+30 4D 36 D1 04 4D 4F 56 45 00 0A 4E 38 4F 39 4F
+3E 4F 0A 93 11 24 08 99 0F 24 06 2C F8 49 00 00
+18 53 1A 83 FB 23 30 4D 08 5A 09 5A 19 83 18 83
+E8 49 00 00 1A 83 FA 23 30 4D 34 C4 CA 21 FC C4
+2A C4 84 12 9A D1 66 D4 4E D4 C8 D0 F6 CD 36 D4
+28 D1 64 D1 AC C9 08 D2 3C D2 78 D0 FC D2 48 C5
+A2 CF 0A CF 84 CA 00 00 3A 40 0C 00 39 40 CA 21
+38 40 CC 21 D9 3F 3A 40 0E 00 39 40 CC 21 38 40
+CA 21 CC 3F 82 43 CC 21 30 4D 92 42 CA 21 C8 21
+30 4D B6 CF 09 50 57 52 5F 53 54 41 54 45 84 12
+E4 CF 32 D4 7C DB F4 D1 08 50 57 52 5F 48 45 52
+45 00 92 42 C4 21 04 D2 92 42 C6 21 02 D2 EF 3F
+B6 D0 09 52 53 54 5F 53 54 41 54 45 92 42 0C 18
+04 D2 92 42 0E 18 02 D2 E2 3F 22 D2 08 52 53 54
+5F 48 45 52 45 00 92 42 C4 21 0C 18 92 42 C6 21
+0E 18 DF 3F B2 40 A2 D2 04 D3 B2 40 B6 C8 CC C8
+B2 40 F8 C8 0C C9 B2 40 04 C8 12 C8 30 41 A6 D0
+04 57 49 50 45 00 39 40 80 FF B9 43 00 00 29 53
+39 90 E2 FF FA 23 B0 12 54 D2 B2 40 7C DB C4 21
+B2 40 32 D4 C6 21 D7 3F 1A D0 06 28 57 41 52 4D
+29 00 1E 42 08 18 87 12 6A C9 05 0D 1B 5B 37 6D
+4E C9 98 C7 6A C9 27 20 46 61 73 74 46 6F 72 74
+68 20 56 31 36 30 20 2E 35 4D 48 7A 20 28 43 29
+20 4A 2E 4D 2E 54 68 6F 6F 72 65 6E 73 20 4E C9
+34 C4 30 FF AC C7 2A C5 58 C7 6A C9 0B 62 79 74
+65 73 20 66 72 65 65 20 7E CD 70 D2 04 57 41 52
+4D 00 30 40 A2 D2 6C D0 04 43 4F 4C 44 00 B2 40
+04 A5 20 01 B2 40 88 5A CC 01 B2 43 02 02 B2 D3
+06 02 B2 40 00 01 24 02 B2 40 FF FE 22 02 B2 D0
+FF FE 26 02 B2 43 42 02 B2 D3 46 02 B2 43 62 02
+B2 D3 66 02 B2 40 00 A5 60 01 B2 40 D6 00 80 01
+92 43 82 01 B2 40 0F 10 84 01 29 43 82 43 88 01
+92 D2 5E 01 08 18 A2 93 08 18 01 24 59 03 38 40
+50 C3 18 83 FE 23 19 83 FA 23 B2 40 00 06 2A 02
+3A 40 14 D3 39 40 E2 FF 89 4A 00 00 29 53 FC 23
+92 42 02 18 EC FF B2 40 18 00 0A 18 31 40 E0 20
+3F 40 80 20 37 40 00 C4 36 40 B4 C4 35 40 08 C4
+34 40 14 C4 B2 40 0A 00 DA 21 B2 43 DC 21 92 C3
+30 01 18 42 08 18 D2 B3 00 02 04 20 38 E3 18 53
+82 48 08 18 B2 40 81 00 00 05 A2 42 06 05 B2 40
+00 49 08 05 F2 D0 03 00 0A 02 92 C3 00 05 92 D3
+1A 05 3D 40 0C D4 18 42 08 18 38 90 0A 00 3B 27
+38 90 16 00 38 2F 28 93 11 23 F9 26 02 D3 84 12
+9A D1 5A DA 06 DB 0E DA 5A DB D4 D9 8E DA D8 D6
+00 00 CA D9 7A DA 2C DA 6A DA E8 D7 00 00 00 00
+6C DB C6 D1 9A D2 85 48 49 32 4C 4F 87 12 AC C7
+32 D0 FA CB 02 CF C8 D1 0E D4 2A C4 08 D3 04 43
+4F 44 45 00 B0 12 14 CE A2 82 C4 21 87 12 42 CF
+BC C5 46 D4 98 D0 03 41 53 4D 92 42 C8 21 B8 21
+B2 40 12 D4 C8 21 EE 3F 00 00 07 45 4E 44 43 4F
+44 45 87 12 D6 D1 62 CE 2A C4 7A D4 06 45 4E 44
+41 53 4D 00 92 42 B8 21 C8 21 F3 3F 00 00 05 43
+4F 4C 4F 4E 1A 42 C4 21 BA 40 87 12 00 00 A2 53
+C4 21 B2 43 B6 21 30 40 D6 D1 00 00 05 4C 4F 32
+48 49 1A 42 C4 21 BA 40 B0 12 00 00 BA 40 2A C4
+02 00 A2 52 C4 21 ED 3F 38 40 BE 21 39 48 2A 48
+09 5A 1A 52 C2 21 09 9A 03 24 7E 9A FC 27 1A 83
+0E 4A 2A 88 82 4A C2 21 30 4D B0 12 2A C4 C4 C9
+1C CA 72 C5 C0 C5 10 D5 F0 CA C0 C5 06 CE 32 D5
+12 D5 29 4E 39 90 86 12 02 20 2E 53 30 41 39 90
+85 12 03 20 1E 4E 02 00 30 41 39 90 84 12 01 20
+2E 52 30 41 19 42 C4 21 A2 53 C4 21 89 4E 00 00
+3E 40 29 00 12 12 C2 21 92 53 C2 21 B0 12 2A C4
+C4 C9 F0 CA C0 C5 64 D5 5A D5 21 53 3E 90 10 00
+BB 2D 30 41 66 D5 B2 41 C2 21 22 D3 30 41 87 12
+4C C6 D8 D4 76 D5 82 43 BC 21 92 42 C4 21 BA 21
+A2 53 C4 21 0A 4E 3E 4F FA 90 23 00 00 00 34 20
+92 53 C2 21 B0 12 FA D4 0E 93 04 20 B2 40 00 03
+BC 21 27 3C 1E 93 04 20 B2 40 10 03 BC 21 21 3C
+2E 93 04 20 B2 40 20 03 BC 21 1B 3C 2E 92 04 20
+B2 40 20 02 BC 21 15 3C 3E 92 04 20 B2 40 30 02
+BC 21 0F 3C 3E 93 04 20 B2 40 30 03 BC 21 09 3C
+B2 40 30 00 BC 21 19 42 C4 21 A2 53 C4 21 89 4E
+00 00 3E 4F 3D 41 30 4D FA 90 26 00 00 00 08 20
+B2 40 10 02 BC 21 92 53 C2 21 30 12 E6 D5 75 3F
+FA 90 40 00 00 00 1A 20 B2 40 20 00 BC 21 92 53
+C2 21 B0 12 44 D5 0E 20 B2 50 10 00 BC 21 3E 40
+2B 00 B0 12 44 D5 32 24 92 92 BE 21 C2 21 02 24
+92 53 C2 21 8E 10 82 5E BC 21 D3 3F B0 12 44 D5
+F9 23 B2 50 10 00 BC 21 3E 40 28 00 B0 12 FA D4
+30 12 36 D6 67 3F 87 12 4C C6 D8 D4 6E D6 FE 90
+26 00 00 00 3E 40 20 00 04 20 B2 50 82 00 BC 21
+C2 3F B0 12 44 D5 DF 23 B2 50 80 00 BC 21 3E 40
+28 00 B0 12 FA D4 B0 12 34 D5 D5 23 3D 40 06 CE
+30 4D 00 00 04 52 45 54 49 00 87 12 34 C4 00 13
+FA CB 2A C4 34 C4 2C 00 6E D5 66 D6 BE D6 2E 4E
+1E D2 BC 21 19 42 BA 21 92 3F BC D4 03 4D 4F 56
+84 12 B4 D6 00 40 CC D6 05 4D 4F 56 2E 42 84 12
+B4 D6 40 40 00 00 03 41 44 44 84 12 B4 D6 00 50
+E6 D6 05 41 44 44 2E 42 84 12 B4 D6 40 50 F2 D6
+04 41 44 44 43 00 84 12 B4 D6 00 60 00 D7 06 41
+44 44 43 2E 42 00 84 12 B4 D6 40 60 A4 D6 04 53
+55 42 43 00 84 12 B4 D6 00 70 1E D7 06 53 55 42
+43 2E 42 00 84 12 B4 D6 40 70 2C D7 03 53 55 42
+84 12 B4 D6 00 80 3C D7 05 53 55 42 2E 42 84 12
+B4 D6 40 80 9E D4 03 43 4D 50 84 12 B4 D6 00 90
+56 D7 05 43 4D 50 2E 42 84 12 B4 D6 40 90 8C D4
+04 44 41 44 44 00 84 12 B4 D6 00 A0 70 D7 06 44
+41 44 44 2E 42 00 84 12 B4 D6 40 A0 62 D7 03 42
+49 54 84 12 B4 D6 00 B0 8E D7 05 42 49 54 2E 42
+84 12 B4 D6 40 B0 9A D7 03 42 49 43 84 12 B4 D6
+00 C0 A8 D7 05 42 49 43 2E 42 84 12 B4 D6 40 C0
+B4 D7 03 42 49 53 84 12 B4 D6 00 D0 C2 D7 05 42
+49 53 2E 42 84 12 B4 D6 40 D0 00 00 03 58 4F 52
+84 12 B4 D6 00 E0 DC D7 05 58 4F 52 2E 42 84 12
+B4 D6 40 E0 0E D7 03 41 4E 44 84 12 B4 D6 00 F0
+F6 D7 05 41 4E 44 2E 42 84 12 B4 D6 40 F0 4C C6
+6E D5 14 D8 1A 42 BC 21 B2 F0 70 00 BC 21 8A 10
+3A F0 0F 00 82 DA BC 21 4A 3F 48 D7 03 52 52 43
+84 12 0E D8 00 10 2C D8 05 52 52 43 2E 42 84 12
+0E D8 40 10 38 D8 04 53 57 50 42 00 84 12 0E D8
+80 10 46 D8 03 52 52 41 84 12 0E D8 00 11 54 D8
+05 52 52 41 2E 42 84 12 0E D8 40 11 60 D8 03 53
+58 54 84 12 0E D8 80 11 00 00 04 50 55 53 48 00
+84 12 0E D8 00 12 7A D8 06 50 55 53 48 2E 42 00
+84 12 0E D8 40 12 CE D7 04 43 41 4C 4C 00 84 12
+0E D8 80 12 34 C4 2C 00 6E D5 66 D6 AE D8 59 42
+BC 21 5A 42 BD 21 82 4A BC 21 BE 90 00 15 00 00
+02 20 0A 89 02 3C 09 8A 0A 49 3A 90 10 00 03 2C
+5A 0E A8 3F 1A 53 0E 4A 87 12 98 C7 6A C9 0D 6F
+75 74 20 6F 66 20 62 6F 75 6E 64 73 78 CD 88 D8
+05 50 55 53 48 4D 84 12 A4 D8 00 15 F0 D8 04 50
+4F 50 4D 00 84 12 A4 D8 00 17 4C C6 D8 D4 10 D9
+82 43 BC 21 92 42 C4 21 BA 21 A2 53 C4 21 92 53
+C2 21 3E 40 2C 00 B0 12 2A C4 C4 C9 F0 CA C0 C5
+06 CE 66 D6 36 D9 0A 4E 3E 4F 1A 83 2A 92 CA 2F
+8A 10 5A 06 6F 3F 6E D8 04 52 52 43 4D 00 84 12
+0A D9 50 00 48 D9 04 52 52 41 4D 00 84 12 0A D9
+50 01 56 D9 04 52 4C 41 4D 00 84 12 0A D9 50 02
+64 D9 04 52 52 55 4D 00 84 12 0A D9 50 03 85 12
+00 3C 72 D9 03 53 3E 3D 85 12 00 38 84 D9 02 53
+3C 00 85 12 00 34 FE D8 03 30 3E 3D 85 12 00 30
+98 D9 02 30 3C 00 85 12 00 30 00 00 02 55 3C 00
+85 12 00 2C AC D9 03 55 3E 3D 85 12 00 28 A2 D9
+03 30 3C 3E 85 12 00 24 C0 D9 02 30 3D 00 85 12
+00 20 00 00 02 49 46 00 1A 42 C4 21 8A 4E 00 00
+A2 53 C4 21 0E 4A 30 4D B6 D9 04 54 48 45 4E 00
+1A 42 C4 21 08 4E 3E 4F 09 48 29 53 0A 89 0A 11
+3A 90 00 02 68 2F 88 DA 00 00 30 4D 7E D7 04 45
+4C 53 45 00 1A 42 C4 21 BA 40 00 3C 00 00 A2 53
+C4 21 2F 83 8F 4A 00 00 E3 3F EA D9 05 55 4E 54
+49 4C 3A 4F 08 4E 3E 4F 19 42 C4 21 2A 83 0A 89
+0A 11 3A 90 00 FE 47 3B 3A F0 FF 03 08 DA 89 48
+00 00 A2 53 C4 21 30 4D 02 D8 05 41 47 41 49 4E
+87 12 7E D9 32 DA 2A C4 00 00 05 57 48 49 4C 45
+87 12 D8 D9 6E C4 2A C4 8E D9 06 52 45 50 45 41
+54 00 87 12 7E D9 32 DA F0 D9 2A C4 00 00 03 4A
+4D 50 87 12 F8 CD 7E D9 32 DA 2A C4 3E B0 00 10
+03 20 3E E0 00 04 30 4D 3E 90 00 34 06 28 03 24
+3E 40 00 34 30 4D 3E 40 00 38 30 4D 00 00 04 3F
+4A 4D 50 00 87 12 9C DA F8 CD 6E C4 32 DA 2A C4
+D2 DA 3D 41 08 4E 3E 4F 2A 48 0A 93 04 20 98 42
+C4 21 00 00 30 4D 88 43 00 00 A4 3F 98 D8 03 42
+57 31 84 12 D0 DA 00 00 EE DA 03 42 57 32 84 12
+D0 DA 00 00 FA DA 03 42 57 33 84 12 D0 DA 00 00
+12 DB 3D 41 1A 42 C4 21 28 4E 08 93 08 20 BA 4F
+00 00 A2 53 C4 21 8E 4A 00 00 3E 4F 30 4D 8E 43
+00 00 61 3F 00 00 03 46 57 31 84 12 10 DB 00 00
+36 DB 03 46 57 32 84 12 10 DB 00 00 42 DB 03 46
+57 33 84 12 10 DB 00 00 4E DB 04 47 4F 54 4F 00
+87 12 7E D9 F8 CD F0 CB 2A C4 BE DA 05 3F 47 4F
+54 4F 87 12 9C DA F8 CD F0 CB 2A C4
+@FFE2
+14 D3 14 D3 14 D3 14 D3 14 D3 68 C8 14 D3 14 D3
+14 D3 14 D3 14 D3 14 D3 14 D3 14 D3 14 D3
+q
--- /dev/null
+@1800
+10 00 74 C8 80 3E 00 24 FD FF 18 00 9E DB 54 D4
+52 C8 60 C8 00 00 00 00
+@21AA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@C400
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 C4
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 C4 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 C4 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E C4 02 3E 52 00 0E 12 3E 4F 30 4D 8E C4
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 C4
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C C4 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 20 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 C4 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 C5
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 C4 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA C4 03 41 4E 44 3E FF 30 4D 7A C4 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E C5 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 C5 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E C5 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 C5 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 C4 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE C5 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 C5 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 C5 03 3E 49 4E 85 12 C2 21 10 C5
+04 42 41 53 45 00 85 12 DA 21 C0 C4 05 53 54 41
+54 45 85 12 B6 21 30 C6 02 42 4C 00 85 12 20 00
+F4 C5 03 55 4D 2A 2C 4F 0A 43 08 43 0B 43 19 43
+0E B9 02 24 08 5C 0B 6A 0C 5C 0A 6A 09 59 F8 2B
+8F 48 00 00 0E 4B 30 4D 94 C5 02 3C 23 00 B2 40
+AA 21 AA 21 30 4D 1E 15 0E 43 3D 40 20 00 0A 93
+04 20 0D 11 0A 4C 0C 43 09 43 0E 9B 01 28 0E 8B
+09 69 08 68 1D 83 07 30 0C 5C 0A 6A 0E 6E F5 2B
+0E 8B 12 D3 F5 3F 0A 4E 1D 17 30 41 48 C6 01 23
+1B 42 DA 21 2C 4F 0A 4E B0 12 86 C6 8F 49 00 00
+0E 48 7A 90 0A 00 02 28 3A 50 07 00 3A 50 30 00
+92 83 AA 21 18 42 AA 21 C8 4A 00 00 30 4D BE C6
+02 23 53 00 87 12 C0 C6 FA C6 2D 83 09 93 E0 23
+0E 93 DE 23 3D 41 30 4D F0 C6 02 23 3E 00 9F 42
+AA 21 00 00 3E 40 AA 21 2E 8F 30 4D 00 C6 04 48
+4F 4C 44 00 0A 4E 3E 4F DB 3F 3C C6 04 53 49 47
+4E 00 0E 93 3E 4F 3A 40 2D 00 D2 33 30 4D 52 C6
+03 55 44 2E 87 12 7E C6 F4 C6 0E C7 5A C9 22 C9
+2A C4 40 C7 02 55 2E 00 2F 83 8F 4E 00 00 0E 43
+F1 3F 3E B0 00 80 06 24 BF E3 00 00 3E E3 9F 53
+00 00 0E 63 30 4D DA C4 02 44 2E 00 87 12 7E C6
+6E C4 80 C4 62 C7 F4 C6 92 C4 32 C7 0E C7 5A C9
+22 C9 2A C4 52 C5 01 2E 3E B0 00 80 DD 27 2F 83
+3E 43 EC 3F 1E C7 04 48 45 52 45 00 2F 83 8F 4E
+00 00 1E 42 C4 21 30 4D 62 C5 05 41 4C 4C 4F 54
+82 5E C4 21 3E 4F 30 4D 0A C7 02 43 2C 00 1A 42
+C4 21 CA 4E 00 00 92 53 C4 21 3E 4F 30 4D 2F 83
+8F 4E 00 00 B0 12 52 C8 92 B3 1C 05 FD 27 1E 42
+0C 05 B0 12 60 C8 30 4D 30 40 DE C7 A6 C7 05 28
+4B 45 59 29 18 42 0C 05 EA 3F 12 C6 03 4B 45 59
+30 40 04 C8 BA C7 06 41 43 43 45 50 54 00 3C 40
+B2 C8 3B 40 7C C8 2D 15 0A 4E 2E 4F 0A 5E 3B 40
+0D 00 3C 40 20 00 3D 40 A6 C8 92 B3 1C 05 05 24
+18 42 0C 05 38 90 0A 00 04 20 21 53 39 40 6E C8
+4D 15 B2 40 11 00 0E 05 A2 B3 1C 05 FD 27 30 41
+B2 40 13 00 0E 05 A2 B3 1C 05 FD 27 30 41 12 D2
+0A 18 FD 3F 21 52 3A 17 58 42 0C 05 48 9B F0 27
+48 9C 06 2C 78 92 11 20 2E 9F 0F 24 1E 83 05 3C
+0E 9A 03 24 CE 48 00 00 1E 53 82 48 0E 05 A2 B3
+1C 05 FD 27 30 4D A8 C8 2D 83 92 B3 1C 05 FD 27
+E3 23 B2 40 18 00 0A 18 3E 8F 3D 41 30 4D FE C7
+06 28 45 4D 49 54 29 00 08 4E 3E 4F E6 3F 78 C7
+04 45 4D 49 54 00 30 40 C8 C8 D0 C8 04 45 43 48
+4F 00 B2 40 82 48 9A C8 30 4D 96 C7 06 4E 4F 45
+43 48 4F 00 B2 40 30 4D 9A C8 30 4D C0 C8 04 28
+43 52 29 00 2F 83 8F 4E 00 00 3E 40 0D 00 E3 3F
+CA C7 02 43 52 00 30 40 04 C9 2C C7 05 53 50 41
+43 45 2F 83 8F 4E 00 00 3E 40 20 00 D4 3F 1C C9
+06 53 50 41 43 45 53 00 0E 93 09 24 0D 12 3D 40
+44 C9 EF 3F 46 C9 2D 83 1E 83 EB 23 3D 41 3E 4F
+30 4D 54 C7 04 54 59 50 45 00 0E 93 95 24 2A 4F
+8F 5E 00 00 0E 4A 87 12 CA C5 02 C6 0A C5 D6 C8
+EC C5 6A C9 2A C4 2F 82 8F 4E 02 00 7E 4D 8F 4D
+00 00 0D 5E 1D B3 0D 63 30 4D 30 C9 82 53 22 00
+87 12 34 C4 76 C9 06 CC 34 C4 22 00 D0 C9 A0 C9
+3D 41 6E 4E 1E 83 82 5E C4 21 3E 4F 92 B3 C4 21
+A2 63 C4 21 30 4D EC C8 82 2E 22 00 87 12 90 C9
+34 C4 5A C9 06 CC 2A C4 00 00 04 57 4F 52 44 00
+3C 40 BE 21 39 4C 3A 4C 09 5A 3A 5C 28 4C 09 9A
+19 24 7E 9A FC 27 1A 83 3B 40 60 00 C8 4C 00 00
+09 9A 0C 24 7C 4A 4E 9C 09 24 18 53 4B 9C F6 2F
+7C 90 7B 00 F3 2F 7C 80 20 00 F0 3F 1A 82 C0 21
+82 4A C2 21 1E 42 C4 21 08 8E CE 48 00 00 30 4D
+00 00 04 46 49 4E 44 00 2F 83 0C 4E 65 4C 74 40
+80 00 3B 40 CA 21 3E 4B 0E 93 1E 24 58 4C 01 00
+78 F0 1E 00 0E 58 2E 53 1E 4E FE FF 0E 93 F3 27
+09 4E 78 49 48 C4 48 95 F7 23 0A 4C 1A 53 FA 99
+00 00 F2 23 58 83 FA 23 19 B3 09 63 0C 49 6A 4E
+1E 43 4A 93 01 30 2E 83 8F 4C 00 00 35 40 08 C4
+34 40 14 C4 30 4D 2F 53 2F 53 3E 4F 30 4D 26 C6
+07 3E 4E 55 4D 42 45 52 2C 4F 6C 4C 7C 80 30 00
+7C 90 0A 00 02 28 7C 80 07 00 1C 92 DA 21 25 2C
+2E 15 2F 83 9F 4F 04 00 00 00 1E 42 DA 21 3D 40
+C6 CA 30 40 56 C6 C8 CA 2F 12 9F 4F 06 00 00 00
+1E 42 DA 21 3D 40 DC CA 30 40 56 C6 DE CA 3E 51
+BF 51 00 00 0E 63 AF 4F 06 00 8F 4E 04 00 1D 17
+2F 53 9F 53 00 00 1E 83 CF 23 30 4D 03 12 0D 12
+12 12 DA 21 32 C0 00 02 6D 4E 0D 5E 0C 4E 7A 40
+2E 00 0D 9C 0A 28 7A 9C FC 23 32 D0 00 02 FC 4C
+FE FF 0D 9C FC 2F DE 83 00 00 3D 40 88 CB 3F 82
+8F 4E 06 00 8F 43 04 00 8F 43 02 00 0A 4E 7E 4A
+8F 4A 00 00 79 4A 79 90 2D 00 17 2C 79 80 24 00
+04 20 B2 40 10 00 DA 21 0A 3C 59 83 03 20 A2 43
+DA 21 05 3C 69 53 98 23 B2 40 0A 00 DA 21 8F 4A
+00 00 1E 83 79 4A 79 90 2D 00 8E 23 B1 43 04 00
+8F 4A 00 00 1E 83 88 3F 8A CB 2F 53 0E 93 2C 17
+82 4C DA 21 03 24 2F 52 0E F3 30 4D 8F 93 00 00
+15 20 32 B0 00 02 14 20 0E 93 05 24 1A 4F 02 00
+1A 83 0A 93 0B 38 2F 53 BF 4F 00 00 3E E3 05 20
+BF E3 00 00 9F 53 00 00 3E E3 30 4D 32 D0 00 02
+9F 4F 02 00 04 00 BF 4F 00 00 3E E3 F6 23 BF E3
+02 00 BF E3 00 00 9F 53 02 00 8F 63 00 00 3E E3
+30 4D DC C8 07 45 58 45 43 55 54 45 0A 4E 3E 4F
+00 4A 28 C5 01 2C 1A 42 C4 21 A2 53 C4 21 8A 4E
+00 00 3E 4F 30 4D 04 CC 87 4C 49 54 45 52 41 4C
+82 93 B6 21 16 24 32 B0 00 02 09 24 1A 42 C4 21
+A2 52 C4 21 BA 40 34 C4 00 00 BA 4F 02 00 1A 42
+C4 21 A2 52 C4 21 BA 40 34 C4 00 00 8A 4E 02 00
+3E 4F 30 4D 12 C9 05 43 4F 55 4E 54 2F 83 1E 53
+8F 4E 00 00 5E 4E FF FF 30 4D 82 4E BE 21 B2 4F
+C0 21 3E 4F 82 43 C2 21 87 12 4C C6 D0 C9 80 CC
+3D 40 8C CC D1 22 3D 41 3E 4F 30 4D 8E CC 0A 4E
+3E 4F 3D 40 A4 CC 32 27 3D 40 7A CC 1A E2 B6 21
+B2 27 AC 23 A6 CC 3E 4F 3D 40 7A CC B9 23 DE 53
+00 00 68 4E 08 5E F8 40 3F 00 00 00 3D 40 6C CE
+CD 3F F4 CB 08 45 56 41 4C 55 41 54 45 00 39 40
+BE 21 39 12 39 12 39 12 0D 12 B0 12 2A C4 6A CC
+E2 CC 3D 41 B2 41 C2 21 B2 41 C0 21 B2 41 BE 21
+30 4D 7A C5 04 51 55 49 54 00 31 40 E0 20 B2 40
+00 20 AC 21 82 43 B6 21 82 43 08 18 B0 12 2A C4
+76 C9 04 0D 6F 6B 20 00 5A C9 34 C4 38 21 44 C4
+34 C4 50 00 1E C8 22 C9 6A CC 34 C4 7E 20 CE C4
+B2 C5 76 C9 0D 73 74 61 63 6B 20 65 6D 70 74 79
+20 21 7E CD 34 C4 30 FF AC C7 B2 C5 76 C9 0B 46
+52 41 4D 20 66 75 6C 6C 20 21 7E CD 42 C6 F4 C4
+C0 C5 10 CD 76 C9 04 0D 20 20 20 00 BC C5 18 CD
+16 C8 05 41 42 4F 52 54 3F 40 80 20 BE 3F 8F 93
+02 00 81 26 B2 40 82 48 9A C8 B0 12 66 D2 82 43
+18 DB 82 43 24 DB 82 43 30 DB 82 43 60 DB 82 43
+6C DB 82 43 78 DB A2 B3 1C 05 FD 27 B2 40 11 00
+0E 05 92 C3 1C 05 38 40 A0 AA 39 42 19 83 FE 23
+18 83 FB 23 92 B3 1C 05 F4 23 87 12 76 C9 04 1B
+5B 37 6D 00 5A C9 5A C9 76 C9 04 1B 5B 30 6D 00
+5A C9 AE D1 F0 D1 F6 D1 78 CD 72 CD 86 41 42 4F
+52 54 22 00 87 12 90 C9 34 C4 7E CD 06 CC 2A C4
+22 CA 01 27 87 12 4C C6 D0 C9 28 CA C0 C5 12 CE
+2A C4 AE CC 7A C6 81 5C 92 42 BE 21 C2 21 30 4D
+87 12 AC C9 4C C6 D0 C9 2A CE 08 4E 7A 4E 5A D3
+5A 53 0A 58 19 42 C8 21 6E 4E 3E F0 1E 00 09 5E
+82 48 AE 21 82 49 B0 21 82 4A B2 21 2A 52 82 4A
+C4 21 3E 4F 3D 41 30 41 87 12 76 C9 0F 73 74 61
+63 6B 20 6D 69 73 6D 61 74 63 68 21 84 CD 82 9F
+B4 21 F2 23 18 42 AE 21 19 42 B0 21 A8 49 FE FF
+89 48 00 00 30 4D CA C9 08 56 41 52 49 41 42 4C
+45 00 B0 12 20 CE BA 40 86 12 FC FF EF 3F 56 CC
+08 43 4F 4E 53 54 41 4E 54 00 B0 12 20 CE BA 40
+85 12 FC FF 8A 4E FE FF 3E 4F E0 3F A0 CE 06 43
+52 45 41 54 45 00 B0 12 20 CE BA 40 85 12 FC FF
+8A 4A FE FF D3 3F C4 CC 05 44 4F 45 53 3E 1A 42
+B2 21 BA 40 84 12 00 00 8A 4D 02 00 3D 41 30 4D
+D8 CE 05 44 45 46 45 52 B0 12 20 CE BA 40 30 40
+FC FF BA 40 EE CE FE FF B9 3F 00 00 81 5B 82 43
+B6 21 30 4D 16 CE 01 5D B2 43 B6 21 30 4D 8C C9
+87 52 45 43 55 52 53 45 19 42 C4 21 99 42 B2 21
+00 00 A2 53 C4 21 30 4D 0C CF 01 3A B0 12 20 CE
+BA 40 87 12 FC FF A2 83 C4 21 B2 43 B6 21 82 4F
+B4 21 30 4D 3A CF 81 3B 82 93 B6 21 5D 27 87 12
+34 C4 2A C4 06 CC 6E CE 0E CF 2A C4 FE C8 09 49
+4D 4D 45 44 49 41 54 45 1A 42 AE 21 FA D0 80 00
+00 00 30 4D BE 4F 02 00 3E 4F 30 4D 6E CF 82 49
+53 00 87 12 42 C6 F4 C4 C0 C5 A6 CF B2 CF 34 C4
+84 CF 06 CC 2A C4 04 CE 84 CF 2A C4 56 CF 83 5B
+27 5D 87 12 04 CE 34 C4 34 C4 06 CC 06 CC 2A C4
+F4 CC 88 50 4F 53 54 50 4F 4E 45 00 87 12 4C C6
+D0 C9 28 CA 54 C4 C0 C5 12 CE 7E C5 C0 C5 EC CF
+34 C4 34 C4 06 CC 06 CC 34 C4 06 CC 06 CC 2A C4
+F2 CF 3A 4E 82 4A C6 21 2E 4E 82 4E C4 21 3D 40
+10 00 09 4A 08 49 29 83 18 48 FE FF 0E 98 FC 2B
+89 48 00 00 1D 83 F6 23 2A 4A 0A 93 F0 23 3E 4F
+3D 41 30 4D 8E CF 82 49 46 00 2F 83 8F 4E 00 00
+1E 42 C4 21 BE 40 C0 C5 00 00 A2 52 C4 21 2E 53
+30 4D F2 CE 84 45 4C 53 45 00 1A 42 C4 21 BA 40
+BC C5 00 00 2A 52 82 4A C4 21 8E 4A 00 00 2A 83
+0E 4A 30 4D 54 C9 84 54 48 45 4E 00 9E 42 C4 21
+00 00 3E 4F 30 4D BE CE 85 42 45 47 49 4E 30 40
+AC C7 66 D0 85 55 4E 54 49 4C 39 40 C0 C5 1A 42
+C4 21 A2 52 C4 21 8A 49 00 00 8A 4E 02 00 3E 4F
+30 4D EC CD 85 41 47 41 49 4E 39 40 BC C5 EF 3F
+88 CE 85 57 48 49 4C 45 87 12 2A D0 6E C4 2A C4
+20 CF 86 52 45 50 45 41 54 00 87 12 AA D0 6C D0
+2A C4 44 D0 82 44 4F 00 2F 83 8F 4E 00 00 1E 42
+C4 21 BE 40 CA C5 00 00 2E 53 82 4E C4 21 A2 53
+AC 21 1A 42 AC 21 8A 43 00 00 30 4D 18 CC 84 4C
+4F 4F 50 00 39 40 EC C5 1A 42 C4 21 A2 52 C4 21
+8A 49 00 00 8A 4E 02 00 1E 42 AC 21 A2 83 AC 21
+2E 4E 0E 93 04 24 9E 42 C4 21 00 00 F5 3F 3E 4F
+30 4D 0C C8 85 2B 4C 4F 4F 50 39 40 DA C5 E4 3F
+FE D0 85 4C 45 41 56 45 1A 42 C4 21 BA 40 FC C5
+00 00 BA 40 BC C5 02 00 B2 50 06 00 C4 21 A2 53
+AC 21 2A 52 19 42 AC 21 89 4A 00 00 30 4D 42 D1
+04 4D 4F 56 45 00 0A 4E 38 4F 39 4F 3E 4F 0A 93
+11 24 08 99 0F 24 06 2C F8 49 00 00 18 53 1A 83
+FB 23 30 4D 08 5A 09 5A 19 83 18 83 E8 49 00 00
+1A 83 FA 23 30 4D 34 C4 CA 21 FC C4 2A C4 84 12
+A6 D1 88 D4 70 D4 D4 D0 02 CE 58 D4 34 D1 70 D1
+B8 C9 14 D2 48 D2 84 D0 08 D3 48 C5 AE CF 16 CF
+90 CA 00 00 3A 40 0C 00 39 40 CA 21 38 40 CC 21
+D9 3F 3A 40 0E 00 39 40 CC 21 38 40 CA 21 CC 3F
+82 43 CC 21 30 4D 92 42 CA 21 C8 21 30 4D C2 CF
+09 50 57 52 5F 53 54 41 54 45 84 12 F0 CF 54 D4
+9E DB 00 D2 08 50 57 52 5F 48 45 52 45 00 92 42
+C4 21 10 D2 92 42 C6 21 0E D2 EF 3F C2 D0 09 52
+53 54 5F 53 54 41 54 45 92 42 0C 18 10 D2 92 42
+0E 18 0E D2 E2 3F 2E D2 08 52 53 54 5F 48 45 52
+45 00 92 42 C4 21 0C 18 92 42 C6 21 0E 18 DF 3F
+B2 40 AE D2 10 D3 B2 40 C8 C8 D8 C8 B2 40 04 C9
+18 C9 B2 40 04 C8 12 C8 30 41 B2 D0 04 57 49 50
+45 00 39 40 80 FF B9 43 00 00 29 53 39 90 E2 FF
+FA 23 B0 12 60 D2 B2 40 9E DB C4 21 B2 40 54 D4
+C6 21 D7 3F 26 D0 06 28 57 41 52 4D 29 00 1E 42
+08 18 87 12 76 C9 05 0D 1B 5B 37 6D 5A C9 98 C7
+76 C9 27 20 46 61 73 74 46 6F 72 74 68 20 56 31
+36 30 20 31 36 4D 48 7A 20 28 43 29 20 4A 2E 4D
+2E 54 68 6F 6F 72 65 6E 73 20 5A C9 34 C4 30 FF
+AC C7 2A C5 58 C7 76 C9 0B 62 79 74 65 73 20 66
+72 65 65 20 8A CD 7C D2 04 57 41 52 4D 00 30 40
+AE D2 78 D0 04 43 4F 4C 44 00 B2 40 04 A5 20 01
+B2 40 88 5A CC 01 B2 43 02 02 B2 D3 06 02 B2 40
+00 01 24 02 B2 40 FF FE 22 02 B2 D0 FF FE 26 02
+B2 43 42 02 B2 D3 46 02 B2 43 62 02 B2 D3 66 02
+F2 40 A5 00 A1 01 F2 40 10 00 A0 01 D2 43 A1 01
+B2 40 00 A5 60 01 B2 40 29 01 80 01 B2 40 0B 00
+82 01 B2 40 E9 01 84 01 39 40 40 00 82 43 88 01
+92 D2 5E 01 08 18 A2 93 08 18 01 24 59 03 38 40
+50 C3 18 83 FE 23 19 83 FA 23 B2 40 00 06 2A 02
+3A 40 20 D3 39 40 E2 FF 89 4A 00 00 29 53 FC 23
+92 42 02 18 EC FF B2 40 18 00 0A 18 31 40 E0 20
+3F 40 80 20 37 40 00 C4 36 40 B4 C4 35 40 08 C4
+34 40 14 C4 B2 40 0A 00 DA 21 B2 43 DC 21 92 C3
+30 01 18 42 08 18 D2 B3 00 02 04 20 38 E3 18 53
+82 48 08 18 B2 40 81 00 00 05 B2 40 11 00 06 05
+B2 40 00 4A 08 05 F2 D0 03 00 0A 02 92 C3 00 05
+92 D3 1A 05 3D 40 2E D4 18 42 08 18 38 90 0A 00
+30 27 38 90 16 00 2D 2F 28 93 06 23 EE 26 0E D3
+84 12 A6 D1 7C DA 28 DB 30 DA 7C DB F6 D9 B0 DA
+FA D6 00 00 EC D9 9C DA 4E DA 8C DA 0A D8 00 00
+00 00 8E DB D2 D1 A6 D2 85 48 49 32 4C 4F 87 12
+AC C7 3E D0 06 CC 0E CF D4 D1 30 D4 2A C4 14 D3
+04 43 4F 44 45 00 B0 12 20 CE A2 82 C4 21 87 12
+4E CF BC C5 68 D4 A4 D0 03 41 53 4D 92 42 C8 21
+B8 21 B2 40 34 D4 C8 21 EE 3F 00 00 07 45 4E 44
+43 4F 44 45 87 12 E2 D1 6E CE 2A C4 9C D4 06 45
+4E 44 41 53 4D 00 92 42 B8 21 C8 21 F3 3F 00 00
+05 43 4F 4C 4F 4E 1A 42 C4 21 BA 40 87 12 00 00
+A2 53 C4 21 B2 43 B6 21 30 40 E2 D1 00 00 05 4C
+4F 32 48 49 1A 42 C4 21 BA 40 B0 12 00 00 BA 40
+2A C4 02 00 A2 52 C4 21 ED 3F 38 40 BE 21 39 48
+2A 48 09 5A 1A 52 C2 21 09 9A 03 24 7E 9A FC 27
+1A 83 0E 4A 2A 88 82 4A C2 21 30 4D B0 12 2A C4
+D0 C9 28 CA 72 C5 C0 C5 32 D5 FC CA C0 C5 12 CE
+54 D5 34 D5 29 4E 39 90 86 12 02 20 2E 53 30 41
+39 90 85 12 03 20 1E 4E 02 00 30 41 39 90 84 12
+01 20 2E 52 30 41 19 42 C4 21 A2 53 C4 21 89 4E
+00 00 3E 40 29 00 12 12 C2 21 92 53 C2 21 B0 12
+2A C4 D0 C9 FC CA C0 C5 86 D5 7C D5 21 53 3E 90
+10 00 BB 2D 30 41 88 D5 B2 41 C2 21 22 D3 30 41
+87 12 4C C6 FA D4 98 D5 82 43 BC 21 92 42 C4 21
+BA 21 A2 53 C4 21 0A 4E 3E 4F FA 90 23 00 00 00
+34 20 92 53 C2 21 B0 12 1C D5 0E 93 04 20 B2 40
+00 03 BC 21 27 3C 1E 93 04 20 B2 40 10 03 BC 21
+21 3C 2E 93 04 20 B2 40 20 03 BC 21 1B 3C 2E 92
+04 20 B2 40 20 02 BC 21 15 3C 3E 92 04 20 B2 40
+30 02 BC 21 0F 3C 3E 93 04 20 B2 40 30 03 BC 21
+09 3C B2 40 30 00 BC 21 19 42 C4 21 A2 53 C4 21
+89 4E 00 00 3E 4F 3D 41 30 4D FA 90 26 00 00 00
+08 20 B2 40 10 02 BC 21 92 53 C2 21 30 12 08 D6
+75 3F FA 90 40 00 00 00 1A 20 B2 40 20 00 BC 21
+92 53 C2 21 B0 12 66 D5 0E 20 B2 50 10 00 BC 21
+3E 40 2B 00 B0 12 66 D5 32 24 92 92 BE 21 C2 21
+02 24 92 53 C2 21 8E 10 82 5E BC 21 D3 3F B0 12
+66 D5 F9 23 B2 50 10 00 BC 21 3E 40 28 00 B0 12
+1C D5 30 12 58 D6 67 3F 87 12 4C C6 FA D4 90 D6
+FE 90 26 00 00 00 3E 40 20 00 04 20 B2 50 82 00
+BC 21 C2 3F B0 12 66 D5 DF 23 B2 50 80 00 BC 21
+3E 40 28 00 B0 12 1C D5 B0 12 56 D5 D5 23 3D 40
+12 CE 30 4D 00 00 04 52 45 54 49 00 87 12 34 C4
+00 13 06 CC 2A C4 34 C4 2C 00 90 D5 88 D6 E0 D6
+2E 4E 1E D2 BC 21 19 42 BA 21 92 3F DE D4 03 4D
+4F 56 84 12 D6 D6 00 40 EE D6 05 4D 4F 56 2E 42
+84 12 D6 D6 40 40 00 00 03 41 44 44 84 12 D6 D6
+00 50 08 D7 05 41 44 44 2E 42 84 12 D6 D6 40 50
+14 D7 04 41 44 44 43 00 84 12 D6 D6 00 60 22 D7
+06 41 44 44 43 2E 42 00 84 12 D6 D6 40 60 C6 D6
+04 53 55 42 43 00 84 12 D6 D6 00 70 40 D7 06 53
+55 42 43 2E 42 00 84 12 D6 D6 40 70 4E D7 03 53
+55 42 84 12 D6 D6 00 80 5E D7 05 53 55 42 2E 42
+84 12 D6 D6 40 80 C0 D4 03 43 4D 50 84 12 D6 D6
+00 90 78 D7 05 43 4D 50 2E 42 84 12 D6 D6 40 90
+AE D4 04 44 41 44 44 00 84 12 D6 D6 00 A0 92 D7
+06 44 41 44 44 2E 42 00 84 12 D6 D6 40 A0 84 D7
+03 42 49 54 84 12 D6 D6 00 B0 B0 D7 05 42 49 54
+2E 42 84 12 D6 D6 40 B0 BC D7 03 42 49 43 84 12
+D6 D6 00 C0 CA D7 05 42 49 43 2E 42 84 12 D6 D6
+40 C0 D6 D7 03 42 49 53 84 12 D6 D6 00 D0 E4 D7
+05 42 49 53 2E 42 84 12 D6 D6 40 D0 00 00 03 58
+4F 52 84 12 D6 D6 00 E0 FE D7 05 58 4F 52 2E 42
+84 12 D6 D6 40 E0 30 D7 03 41 4E 44 84 12 D6 D6
+00 F0 18 D8 05 41 4E 44 2E 42 84 12 D6 D6 40 F0
+4C C6 90 D5 36 D8 1A 42 BC 21 B2 F0 70 00 BC 21
+8A 10 3A F0 0F 00 82 DA BC 21 4A 3F 6A D7 03 52
+52 43 84 12 30 D8 00 10 4E D8 05 52 52 43 2E 42
+84 12 30 D8 40 10 5A D8 04 53 57 50 42 00 84 12
+30 D8 80 10 68 D8 03 52 52 41 84 12 30 D8 00 11
+76 D8 05 52 52 41 2E 42 84 12 30 D8 40 11 82 D8
+03 53 58 54 84 12 30 D8 80 11 00 00 04 50 55 53
+48 00 84 12 30 D8 00 12 9C D8 06 50 55 53 48 2E
+42 00 84 12 30 D8 40 12 F0 D7 04 43 41 4C 4C 00
+84 12 30 D8 80 12 34 C4 2C 00 90 D5 88 D6 D0 D8
+59 42 BC 21 5A 42 BD 21 82 4A BC 21 BE 90 00 15
+00 00 02 20 0A 89 02 3C 09 8A 0A 49 3A 90 10 00
+03 2C 5A 0E A8 3F 1A 53 0E 4A 87 12 98 C7 76 C9
+0D 6F 75 74 20 6F 66 20 62 6F 75 6E 64 73 84 CD
+AA D8 05 50 55 53 48 4D 84 12 C6 D8 00 15 12 D9
+04 50 4F 50 4D 00 84 12 C6 D8 00 17 4C C6 FA D4
+32 D9 82 43 BC 21 92 42 C4 21 BA 21 A2 53 C4 21
+92 53 C2 21 3E 40 2C 00 B0 12 2A C4 D0 C9 FC CA
+C0 C5 12 CE 88 D6 58 D9 0A 4E 3E 4F 1A 83 2A 92
+CA 2F 8A 10 5A 06 6F 3F 90 D8 04 52 52 43 4D 00
+84 12 2C D9 50 00 6A D9 04 52 52 41 4D 00 84 12
+2C D9 50 01 78 D9 04 52 4C 41 4D 00 84 12 2C D9
+50 02 86 D9 04 52 52 55 4D 00 84 12 2C D9 50 03
+85 12 00 3C 94 D9 03 53 3E 3D 85 12 00 38 A6 D9
+02 53 3C 00 85 12 00 34 20 D9 03 30 3E 3D 85 12
+00 30 BA D9 02 30 3C 00 85 12 00 30 00 00 02 55
+3C 00 85 12 00 2C CE D9 03 55 3E 3D 85 12 00 28
+C4 D9 03 30 3C 3E 85 12 00 24 E2 D9 02 30 3D 00
+85 12 00 20 00 00 02 49 46 00 1A 42 C4 21 8A 4E
+00 00 A2 53 C4 21 0E 4A 30 4D D8 D9 04 54 48 45
+4E 00 1A 42 C4 21 08 4E 3E 4F 09 48 29 53 0A 89
+0A 11 3A 90 00 02 68 2F 88 DA 00 00 30 4D A0 D7
+04 45 4C 53 45 00 1A 42 C4 21 BA 40 00 3C 00 00
+A2 53 C4 21 2F 83 8F 4A 00 00 E3 3F 0C DA 05 55
+4E 54 49 4C 3A 4F 08 4E 3E 4F 19 42 C4 21 2A 83
+0A 89 0A 11 3A 90 00 FE 47 3B 3A F0 FF 03 08 DA
+89 48 00 00 A2 53 C4 21 30 4D 24 D8 05 41 47 41
+49 4E 87 12 A0 D9 54 DA 2A C4 00 00 05 57 48 49
+4C 45 87 12 FA D9 6E C4 2A C4 B0 D9 06 52 45 50
+45 41 54 00 87 12 A0 D9 54 DA 12 DA 2A C4 00 00
+03 4A 4D 50 87 12 04 CE A0 D9 54 DA 2A C4 3E B0
+00 10 03 20 3E E0 00 04 30 4D 3E 90 00 34 06 28
+03 24 3E 40 00 34 30 4D 3E 40 00 38 30 4D 00 00
+04 3F 4A 4D 50 00 87 12 BE DA 04 CE 6E C4 54 DA
+2A C4 F4 DA 3D 41 08 4E 3E 4F 2A 48 0A 93 04 20
+98 42 C4 21 00 00 30 4D 88 43 00 00 A4 3F BA D8
+03 42 57 31 84 12 F2 DA 00 00 10 DB 03 42 57 32
+84 12 F2 DA 00 00 1C DB 03 42 57 33 84 12 F2 DA
+00 00 34 DB 3D 41 1A 42 C4 21 28 4E 08 93 08 20
+BA 4F 00 00 A2 53 C4 21 8E 4A 00 00 3E 4F 30 4D
+8E 43 00 00 61 3F 00 00 03 46 57 31 84 12 32 DB
+00 00 58 DB 03 46 57 32 84 12 32 DB 00 00 64 DB
+03 46 57 33 84 12 32 DB 00 00 70 DB 04 47 4F 54
+4F 00 87 12 A0 D9 04 CE FC CB 2A C4 E0 DA 05 3F
+47 4F 54 4F 87 12 BE DA 04 CE FC CB 2A C4
+@FFE2
+20 D3 20 D3 20 D3 20 D3 20 D3 74 C8 20 D3 20 D3
+20 D3 20 D3 20 D3 20 D3 20 D3 20 D3 20 D3
+q
--- /dev/null
+\prog\MSP430Flasher\msp430flasher -m SBW2 -n MSP430fr4133 -v -w %1 -z [VCC=3000]
+exit
+
+tip : how to calculate MAIN program lenght ?
+
+open the prog.txt file with your editor, select MAIN section
+in status bar, keep the number of selected chars
+if lines are ended with CR+LF, substract the number of lines selected
+then divide by 3.
--- /dev/null
+; -*- coding: utf-8 -*-
+
+; Fast Forth For Texas Instrument MSP430FR5739
+; Tested on MSP-EXP430FR5739 launchpad
+;
+; Copyright (C) <2014> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+; ----------------------------------------------------------------------
+; MSP_EXP430FR739.inc
+; ----------------------------------------------------------------------
+; ----------------------------------------------------------------------
+; MSP430FR57xx BOOTSTRAP
+; ----------------------------------------------------------------------
+; BSL for MSP430FR573x devices
+; BSL Version 00.04.31.71
+; RAM erased 0x1C00-0x1FFF
+; Buffer size for Core Commands : 260 bytes
+; Notable Information
+; 1. TX and RX pins are noted in the device data sheet
+; 2. A mass erase command or incorrect password triggers a BSL reset.
+; This resets the BSL state to the default settings (9600 baud, password locked)
+; Known Bugs
+; 1. The baud rate of 115k cannot be ensured across all clock, voltage, and temperature variations
+; ----------------------------------------------------------------------
+; ======================================================================
+; INIT MSP-EXP430FR5739 board
+; ======================================================================
+
+; J3 (5xjumper), silkscreen printing:
+; "TEST" - FR5739 pin19 = TEST
+; "RST" - FR5739 pin20 = RST
+; "RXD" - FR5739 pin22 = P2.1 == UCA0RXD --> UCA0RXDBUF
+; "TXD" - FR5739 pin21 = P2.0 == UCA0TXD <-- UCA0TXDBUf
+; "VCC" - + upper side
+
+; 8x blue LEDs in a row. (portpinX->---resistor---LED---GND)
+; PJ.0 - LED1
+; PJ.1 - LED2
+; PJ.2 - LED3
+; PJ.3 - LED4
+; P3.4 - LED5
+; P3.5 - LED6
+; P3.6 - LED7
+; P3.7 - LED8
+
+; I/O pins on SV1:
+; P1.0 - SV1.1
+; P1.1 - SV1.2
+; P1.2 - SV1.3
+; P3.0 - SV1.4
+; P3.1 - SV1.5
+; P3.2 - SV1.6
+; P3.3 - SV1.7
+; P1.3 - SV1.8
+; P1.4 - SV1.9
+; P1.5 - SV1.10
+; P4.0 - SV1.11
+; GND - SV1.12
+
+; I/O pins on SV2:
+; P1.7 - SV2.1
+; P1.6 - SV2.2
+; P3.7 - SV2.3
+; P3.6 - SV2.4
+; P3.5 - SV2.5
+; P3.4 - SV2.6
+; P2.2 - SV2.7
+; P2.1 - SV2.8
+; P2.6 - SV2.9
+; P2.5 - SV2.10
+; P2.0 - SV2.11
+; VCC - SV2.12
+
+; I/O pins on RF:
+; GND - RF.1
+; VCC - RF.2
+; P2.0 - RF.3
+; P1.0 - RF.4
+; P2.6 - RF.5
+; P1.1 - RF.6
+; P2.5 - RF.7
+; P1.2 - RF.8
+; P2.7 - RF.9
+; P2.3 - RF.10
+; P4.0 - RF.11
+; GND - RF.12
+; P4.1 - RF.13
+; P2.4 - RF.14
+; P1.7 - RF.15
+; P2.2 - RF.16
+; P1.3 - RF.17
+; P1.6 - RF.18
+
+; Accelerometer:
+; P2.7 - VS
+; P3.0 - XOUT
+; P3.1 - YOUT
+; P3.2 - ZOUT
+
+; LDR and NTC:
+; P2.7 - VS
+; P3.3 - LDR
+; P1.4 - NTC
+
+; RST - reset
+
+; ======================================================================
+; MSP-EXP430FR5739 LAUNCHPAD <--> OUTPUT WORLD
+; ======================================================================
+;
+; P4.0 - Switch S1 <--- LCD contrast + (finger :-)
+; P4.1 - Switch S2 <--- LCD contrast - (finger :-)
+;
+; GND <-------+---0V0----------> 1 LCD_Vss
+; VCC >------ | --3V6-----+----> 2 LCD_Vdd
+; | |
+; |___ 470n ---
+; ^ | ---
+; / \ BAT54 |
+; --- |
+; 100n | 2k2 |
+; P1.5 - UCB0 CLK TB0.2 SV1.10 >---||--+--^/\/\/v--+----> 3 LCD_Vo (=0V6 without modulation)
+; P3.4 - SV2.6 -------------------------> 4 LCD_RS
+; P3.5 - SV2.5 -------------------------> 5 LCD_R/W
+; P3.6 - SV2.4 -------------------------> 6 LCD_EN
+; P1.0 - SV1.1 <------------------------> 11 LCD_DB4
+; P1.1 - SV1.2 <------------------------> 12 LCD_DB5
+; P1.2 - SV1.3 <------------------------> 13 LCD_DB5
+; P1.3 - SV1.8 <------------------------> 14 LCD_DB7
+;
+; PJ.4 - LFXI 32768Hz quartz
+; PJ.5 - LFXO 32768Hz quartz
+; PJ.6 - HFXI
+; PJ.7 - HFXO
+; +--4k7-< DeepRST <-- GND
+; |
+; P2.0 - UCA0 TXD SV2.11 --+-> RX UARTtoUSB bridge
+; P2.1 - UCA0 RXD SV2.8 <---- TX UARTtoUSB bridge
+; VCC - <---- VCC (optional supply from UARTtoUSB bridge - WARNING ! 3.3V !)
+; GND - <---> GND (optional supply from UARTtoUSB bridge)
+;
+; VCC - RF.2
+; VSS - RF.1
+; P2.2 - RF.16 <---- CD SD_CardAdapter (Card Detect)
+; P2.3 - RF.10 ----> CS SD_CardAdapter (Card Select)
+; P2.4 - UCA1 CLK RF.14 ----> CLK SD_CardAdapter (SCK)
+; P2.5 - UCA1 TXD/SIMO RF.7 ----> SDI SD_CardAdapter (MOSI)
+; P2.6 - UCA1 RXD/SOMI RF.5 <---- SDO SD_CardAdapter (MISO)
+;
+; P2.7 - RF.9 <---- OUT IR_Receiver (1 TSOP32236)
+;
+; P1.7 - UCB0 SCL/SOMI SV2.1 <---> SCL I2C MASTER/SLAVE
+; P1.6 - UCB0 SDA/SIMO SV2.2 <---> SDA I2C MASTER/SLAVE
+
+
+; Clocks:
+; 8 MHz DCO intern
+
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : LOCK I/O as high impedance state
+; ----------------------------------------------------------------------
+
+ BIS #LOCKLPM5,&PM5CTL0 ; unlocked by WARM
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : WATCHDOG TIMER A
+; ----------------------------------------------------------------------
+
+; WDT code
+ MOV #WDTPW+WDTHOLD+WDTCNTCL,&WDTCTL ; stop WDT
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION PAIN=PORT2:PORT1
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT 1 usage
+; P1.4 is used as analog input from NTC voltage divider ==> switch to ADC to disable digital input
+ BIS.B #10h,&P1SELC
+
+
+Deep_RST_IN .equ P2IN ; TERMINAL TX pin as FORTH Deep_RST
+Deep_RST .equ 1 ; P2.0
+TERM_TXRX .equ 003h
+TERM_SEL .equ P2SEL1
+TERM_REN .equ P2REN
+
+; P2.7 is used to power the accelerometer and NTC voltage divider ==> output low = OFF
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ BIS #08000h,&PADIR ; all pins as input else P2.7
+ MOV #07FFFh,&PAOUT ; all pins high else P2.7
+ BIS #07FFFh,&PAREN ; all pins with pull up resistors else P2.7
+
+ .IFDEF TERMINALCTSRTS
+;configure P2.2 as RTS output high
+RTS .equ 4
+HANDSHAKOUT .equ P2OUT
+HANDSHAKIN .equ P2IN
+ BIS.B #RTS,&HANDSHAKOUT
+ .ENDIF
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT3/4
+; ----------------------------------------------------------------------
+; PB = P4:P3
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; P3 FastForth usage
+; P3.0 to P3.2 are accelerometer analog outputs ==> switch to ADC to disable digital input
+ BIS.B #07h,&P3SELC
+
+; P3.4 to P3.7 are blues LEDs : set output low = OFF
+
+; P4 FastForth usage
+; P4.0 Switch S1 used for hard reset (WIPE+COLD)
+; P4.1 switch S2
+
+SWITCHIN .equ P4IN
+S1 .equ 1
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ BIS #000F0h,&PADIR ; all pins as input else blues LEDs
+ MOV #0FF0Fh,&PAOUT ; all pins high else blues LEDs
+ BIS #0FF0Fh,&PAREN ; all pins 1 with pull resistors else blues LEDs
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORTJ
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+
+; PJ FastForth usage
+; PJ.0 to PJ.3 are blues LEDs : set as output low = OFF
+
+; PORTx default wanted state : pins as input with pullup resistor else leds output low
+
+ BIS.B #00Fh,&PJDIR ; all pins as input else blues LEDs
+ MOV.B #0F0h,&PJOUT ; all pins high else blues LEDs
+ BIS.B #0F0h,&PJREN ; all pins 1 with pull resistors else blues LEDs
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : CLOCK SYSTEM
+; ----------------------------------------------------------------------
+
+; DCOCLK: Internal digitally controlled oscillator (DCO).
+
+; CS code for MSP430fr5739
+ MOV.B #CSKEY,&CSCTL0_H ; Unlock CS registers
+
+ .IF FREQUENCY = 0.5
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_16 + DIVM_16,&CSCTL3
+ MOV #4,X
+
+ .ELSEIF FREQUENCY = 1
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_8 + DIVM_8,&CSCTL3
+ MOV #8,X
+
+ .ELSEIF FREQUENCY = 2
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_4 + DIVM_4,&CSCTL3
+ MOV #16,X
+
+ .ELSEIF FREQUENCY = 4
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_2 + DIVM_2,&CSCTL3
+ MOV #32,X
+
+ .ELSEIF FREQUENCY = 8
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #64,X
+SMCLK .equ 8
+
+ .ELSEIF FREQUENCY = 16
+ MOV #DCORSEL,&CSCTL1 ; Set 16MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #128,X
+SMCLK .equ 16
+
+ .ELSEIF FREQUENCY = 24
+ MOV #DCORSEL+DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 24 MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #192,X
+SMCLK .equ 24
+
+ .ELSEIF
+ .error "bad frequency setting, only 0.5,1,2,4,8,16,24 MHz"
+ .ENDIF
+
+ .IFDEF LF_XTAL
+ MOV #SELA_LFXCLK+SELS_DCOCLK+SELM_DCOCLK,&CSCTL2
+ .ELSE
+ MOV #SELA_VLOCLK+SELS_DCOCLK+SELM_DCOCLK,&CSCTL2
+ .ENDIF
+ MOV.B #01h, &CSCTL0_H ; Lock CS Registers
+
+ BIS &SYSRSTIV,&SAVE_SYSRSTIV; store volatile SYSRSTIV preserving a pending request for DEEP_RST
+ CMP #2,&SAVE_SYSRSTIV ; POWER ON ?
+ JZ ClockWaitX ; yes
+ .word 0759h ; no RRUM #2,X --> wait only 125 ms
+ClockWaitX MOV #41666,Y ; wait 0.5s before starting after POWER ON
+ClockWaitY SUB #1,Y ;
+ JNZ ClockWaitY ; 41666x3 = 125000 cycles delay = 125ms @ 1MHz
+ SUB #1,X ; x 4 @ 1 MHZ
+ JNZ ClockWaitX ; time to stabilize power source ( 1s )
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : REF
+; ----------------------------------------------------------------------
+
+ BIS.W #REFTCOFF, &REFCTL ; Turn off temp.
+ BIC.W #REFON, &REFCTL
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : RTC REGISTERS
+; ----------------------------------------------------------------------
+ .IFDEF LF_XTAL
+; LFXIN : PJ.4, LFXOUT : PJ.5
+ BIS.B #010h,&PJSEL0 ; SEL0 for only LFXIN
+ BIC.B #RTCHOLD,&RTCCTL1 ; Clear RTCHOLD = start RTC_B
+ .ENDIF
+
--- /dev/null
+@1800
+10 00 4C C6 C0 5D 80 04 FD FF 18 00 60 D9 16 D2
+2A C6 38 C6 00 00 00 00
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@C200
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 C2
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 C2 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 C2 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E C2 02 3E 52 00 0E 12 3E 4F 30 4D 8E C2
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 C2
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C C2 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 C2 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 C3
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 C2 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA C2 03 41 4E 44 3E FF 30 4D 7A C2 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E C3 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 C3 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E C3 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 C3 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 C2 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE C3 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 C3 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 C3 03 3E 49 4E 85 12 C2 1D 10 C3
+04 42 41 53 45 00 85 12 DA 1D C0 C2 05 53 54 41
+54 45 85 12 B6 1D 30 C4 02 42 4C 00 85 12 20 00
+94 C3 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 C4 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E C4 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 C4 02 23 53 00 87 12 98 C4
+D2 C4 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 C4 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 C4 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C C4 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 C3 03 55 44 2E 87 12 56 C4
+CC C4 E6 C4 32 C7 FA C6 2A C2 18 C5 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA C2
+02 44 2E 00 87 12 56 C4 6E C2 80 C2 3A C5 CC C4
+92 C2 0A C5 E6 C4 32 C7 FA C6 2A C2 52 C3 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 C4 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 C3 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 C4 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A C6
+92 B3 DC 05 FD 27 1E 42 CC 05 B0 12 38 C6 30 4D
+30 40 B6 C5 7E C5 05 28 4B 45 59 29 18 42 CC 05
+EA 3F 12 C4 03 4B 45 59 30 40 DC C5 92 C5 06 41
+43 43 45 50 54 00 3C 40 8A C6 3B 40 54 C6 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+7E C6 92 B3 DC 05 05 24 18 42 CC 05 38 90 0A 00
+04 20 21 53 39 40 46 C6 4D 15 B2 40 11 00 CE 05
+A2 B3 DC 05 FD 27 30 41 B2 40 13 00 CE 05 A2 B3
+DC 05 FD 27 30 41 12 D2 0A 18 FD 3F 21 52 3A 17
+58 42 CC 05 48 9B F0 27 48 9C 06 2C 78 92 11 20
+2E 9F 0F 24 1E 83 05 3C 0E 9A 03 24 CE 48 00 00
+1E 53 82 48 CE 05 A2 B3 DC 05 FD 27 30 4D 80 C6
+2D 83 92 B3 DC 05 FD 27 E3 23 B2 40 18 00 0A 18
+3E 8F 3D 41 30 4D D6 C5 06 28 45 4D 49 54 29 00
+08 4E 3E 4F E6 3F 50 C5 04 45 4D 49 54 00 30 40
+A0 C6 A8 C6 04 45 43 48 4F 00 B2 40 82 48 72 C6
+30 4D 6E C5 06 4E 4F 45 43 48 4F 00 B2 40 30 4D
+72 C6 30 4D 98 C6 04 28 43 52 29 00 2F 83 8F 4E
+00 00 3E 40 0D 00 E3 3F A2 C5 02 43 52 00 30 40
+DC C6 04 C5 05 53 50 41 43 45 2F 83 8F 4E 00 00
+3E 40 20 00 D4 3F F4 C6 06 53 50 41 43 45 53 00
+0E 93 09 24 0D 12 3D 40 1C C7 EF 3F 1E C7 2D 83
+1E 83 EB 23 3D 41 3E 4F 30 4D 2C C5 04 54 59 50
+45 00 0E 93 95 24 2A 4F 8F 5E 00 00 0E 4A 87 12
+CA C3 02 C4 0A C3 AE C6 EC C3 42 C7 2A C2 2F 82
+8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E 1D B3 0D 63
+30 4D 08 C7 82 53 22 00 87 12 34 C2 4E C7 B0 C9
+34 C2 22 00 A8 C7 78 C7 3D 41 6E 4E 1E 83 82 5E
+C4 1D 3E 4F 92 B3 C4 1D A2 63 C4 1D 30 4D C4 C6
+82 2E 22 00 87 12 68 C7 34 C2 32 C7 B0 C9 2A C2
+00 00 04 57 4F 52 44 00 3C 40 BE 1D 39 4C 3A 4C
+09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A FC 27 1A 83
+3B 40 60 00 C8 4C 00 00 09 9A 0C 24 7C 4A 4E 9C
+09 24 18 53 4B 9C F6 2F 7C 90 7B 00 F3 2F 7C 80
+20 00 F0 3F 1A 82 C0 1D 82 4A C2 1D 1E 42 C4 1D
+08 8E CE 48 00 00 30 4D 00 00 04 46 49 4E 44 00
+2F 83 0C 4E 65 4C 74 40 80 00 3B 40 CA 1D 3E 4B
+0E 93 1E 24 58 4C 01 00 78 F0 1E 00 0E 58 2E 53
+1E 4E FE FF 0E 93 F3 27 09 4E 78 49 48 C4 48 95
+F7 23 0A 4C 1A 53 FA 99 00 00 F2 23 58 83 FA 23
+19 B3 09 63 0C 49 6A 4E 1E 43 4A 93 01 30 2E 83
+8F 4C 00 00 35 40 08 C2 34 40 14 C2 30 4D 2F 53
+2F 53 3E 4F 30 4D 26 C4 07 3E 4E 55 4D 42 45 52
+3C 4F 38 4F 29 4F 2F 82 1B 42 DA 1D 6A 4C 7A 80
+30 00 7A 90 0A 00 02 28 7A 80 07 00 0A 9B 13 2C
+82 49 D0 04 82 48 D2 04 82 4B C8 04 19 42 E4 04
+18 42 E6 04 09 5A 08 63 1C 53 1E 83 E7 23 8F 49
+04 00 8F 48 02 00 8F 4C 00 00 30 4D 03 12 0D 12
+1B 42 DA 1D 0B 12 32 C0 00 02 6D 4E 0D 5E 0C 4E
+7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23 32 D0 00 02
+FC 4C FE FF 0D 9C FC 2F DE 83 00 00 09 43 08 43
+3D 40 32 C9 3F 82 8F 4E 06 00 0C 4E 7E 4C 6A 4C
+7A 90 2D 00 10 2C 3B 40 10 00 7A 80 24 00 06 24
+2B 43 5A 83 03 24 3B 52 6A 53 B0 23 1C 53 1E 83
+6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83 B1 43 04 00
+A5 3F 34 C9 2F 53 0E 93 2C 17 82 4C DA 1D 03 24
+2F 52 0E F3 30 4D 8F 93 00 00 15 20 32 B0 00 02
+14 20 0E 93 05 24 1A 4F 02 00 1A 83 0A 93 0B 38
+2F 53 BF 4F 00 00 3E E3 05 20 BF E3 00 00 9F 53
+00 00 3E E3 30 4D 32 D0 00 02 9F 4F 02 00 04 00
+BF 4F 00 00 3E E3 F6 23 BF E3 02 00 BF E3 00 00
+9F 53 02 00 8F 63 00 00 3E E3 30 4D B4 C6 07 45
+58 45 43 55 54 45 0A 4E 3E 4F 00 4A 28 C3 01 2C
+1A 42 C4 1D A2 53 C4 1D 8A 4E 00 00 3E 4F 30 4D
+AE C9 87 4C 49 54 45 52 41 4C 82 93 B6 1D 16 24
+32 B0 00 02 09 24 1A 42 C4 1D A2 52 C4 1D BA 40
+34 C2 00 00 BA 4F 02 00 1A 42 C4 1D A2 52 C4 1D
+BA 40 34 C2 00 00 8A 4E 02 00 3E 4F 30 4D EA C6
+05 43 4F 55 4E 54 2F 83 1E 53 8F 4E 00 00 5E 4E
+FF FF 30 4D 82 4E BE 1D B2 4F C0 1D 3E 4F 82 43
+C2 1D 87 12 4C C4 A8 C7 2A CA 3D 40 36 CA E8 22
+3D 41 3E 4F 30 4D 38 CA 0A 4E 3E 4F 3D 40 4E CA
+3D 27 3D 40 24 CA 1A E2 B6 1D B2 27 AC 23 50 CA
+3E 4F 3D 40 24 CA B9 23 DE 53 00 00 68 4E 08 5E
+F8 40 3F 00 00 00 3D 40 16 CC CD 3F 9E C9 08 45
+56 41 4C 55 41 54 45 00 39 40 BE 1D 39 12 39 12
+39 12 0D 12 B0 12 2A C2 14 CA 8C CA 3D 41 B2 41
+C2 1D B2 41 C0 1D B2 41 BE 1D 30 4D 7A C3 04 51
+55 49 54 00 31 40 E0 1C B2 40 00 1C AC 1D 82 43
+B6 1D 82 43 08 18 B0 12 2A C2 4E C7 04 0D 6F 6B
+20 00 32 C7 34 C2 38 1D 44 C2 34 C2 50 00 F6 C5
+FA C6 14 CA 34 C2 7E 1C CE C2 B2 C3 4E C7 0D 73
+74 61 63 6B 20 65 6D 70 74 79 20 21 28 CB 34 C2
+30 FF 84 C5 B2 C3 4E C7 0B 46 52 41 4D 20 66 75
+6C 6C 20 21 28 CB 42 C4 F4 C2 C0 C3 BA CA 4E C7
+04 0D 20 20 20 00 BC C3 C2 CA EE C5 05 41 42 4F
+52 54 3F 40 80 1C BE 3F 8F 93 02 00 98 26 B2 40
+82 48 72 C6 B0 12 10 D0 82 43 DA D8 82 43 E6 D8
+82 43 F2 D8 82 43 22 D9 82 43 2E D9 82 43 3A D9
+A2 B3 DC 05 FD 27 B2 40 11 00 CE 05 92 C3 DC 05
+38 40 F0 FF 39 42 19 83 FE 23 18 83 FB 23 92 B3
+DC 05 F4 23 87 12 4E C7 04 1B 5B 37 6D 00 32 C7
+32 C7 4E C7 04 1B 5B 30 6D 00 32 C7 58 CF 9A CF
+A0 CF 22 CB 1C CB 86 41 42 4F 52 54 22 00 87 12
+68 C7 34 C2 28 CB B0 C9 2A C2 FA C7 01 27 87 12
+4C C4 A8 C7 00 C8 C0 C3 BC CB 2A C2 58 CA 52 C4
+81 5C 92 42 BE 1D C2 1D 30 4D 87 12 84 C7 4C C4
+A8 C7 D4 CB 08 4E 7A 4E 5A D3 5A 53 0A 58 19 42
+C8 1D 6E 4E 3E F0 1E 00 09 5E 82 48 AE 1D 82 49
+B0 1D 82 4A B2 1D 2A 52 82 4A C4 1D 3E 4F 3D 41
+30 41 87 12 4E C7 0F 73 74 61 63 6B 20 6D 69 73
+6D 61 74 63 68 21 2E CB 82 9F B4 1D F2 23 18 42
+AE 1D 19 42 B0 1D A8 49 FE FF 89 48 00 00 30 4D
+A2 C7 08 56 41 52 49 41 42 4C 45 00 B0 12 CA CB
+BA 40 86 12 FC FF EF 3F 00 CA 08 43 4F 4E 53 54
+41 4E 54 00 B0 12 CA CB BA 40 85 12 FC FF 8A 4E
+FE FF 3E 4F E0 3F 4A CC 06 43 52 45 41 54 45 00
+B0 12 CA CB BA 40 85 12 FC FF 8A 4A FE FF D3 3F
+6E CA 05 44 4F 45 53 3E 1A 42 B2 1D BA 40 84 12
+00 00 8A 4D 02 00 3D 41 30 4D 82 CC 05 44 45 46
+45 52 B0 12 CA CB BA 40 30 40 FC FF BA 40 98 CC
+FE FF B9 3F 00 00 81 5B 82 43 B6 1D 30 4D C0 CB
+01 5D B2 43 B6 1D 30 4D 64 C7 87 52 45 43 55 52
+53 45 19 42 C4 1D 99 42 B2 1D 00 00 A2 53 C4 1D
+30 4D B6 CC 01 3A B0 12 CA CB BA 40 87 12 FC FF
+A2 83 C4 1D B2 43 B6 1D 82 4F B4 1D 30 4D E4 CC
+81 3B 82 93 B6 1D 5D 27 87 12 34 C2 2A C2 B0 C9
+18 CC B8 CC 2A C2 D6 C6 09 49 4D 4D 45 44 49 41
+54 45 1A 42 AE 1D FA D0 80 00 00 00 30 4D BE 4F
+02 00 3E 4F 30 4D 18 CD 82 49 53 00 87 12 42 C4
+F4 C2 C0 C3 50 CD 5C CD 34 C2 2E CD B0 C9 2A C2
+AE CB 2E CD 2A C2 00 CD 83 5B 27 5D 87 12 AE CB
+34 C2 34 C2 B0 C9 B0 C9 2A C2 9E CA 88 50 4F 53
+54 50 4F 4E 45 00 87 12 4C C4 A8 C7 00 C8 54 C2
+C0 C3 BC CB 7E C3 C0 C3 96 CD 34 C2 34 C2 B0 C9
+B0 C9 34 C2 B0 C9 B0 C9 2A C2 9C CD 3A 4E 82 4A
+C6 1D 2E 4E 82 4E C4 1D 3D 40 10 00 09 4A 08 49
+29 83 18 48 FE FF 0E 98 FC 2B 89 48 00 00 1D 83
+F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41 30 4D 38 CD
+82 49 46 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40
+C0 C3 00 00 A2 52 C4 1D 2E 53 30 4D 9C CC 84 45
+4C 53 45 00 1A 42 C4 1D BA 40 BC C3 00 00 2A 52
+82 4A C4 1D 8E 4A 00 00 2A 83 0E 4A 30 4D 2C C7
+84 54 48 45 4E 00 9E 42 C4 1D 00 00 3E 4F 30 4D
+68 CC 85 42 45 47 49 4E 30 40 84 C5 10 CE 85 55
+4E 54 49 4C 39 40 C0 C3 1A 42 C4 1D A2 52 C4 1D
+8A 49 00 00 8A 4E 02 00 3E 4F 30 4D 96 CB 85 41
+47 41 49 4E 39 40 BC C3 EF 3F 32 CC 85 57 48 49
+4C 45 87 12 D4 CD 6E C2 2A C2 CA CC 86 52 45 50
+45 41 54 00 87 12 54 CE 16 CE 2A C2 EE CD 82 44
+4F 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40 CA C3
+00 00 2E 53 82 4E C4 1D A2 53 AC 1D 1A 42 AC 1D
+8A 43 00 00 30 4D C2 C9 84 4C 4F 4F 50 00 39 40
+EC C3 1A 42 C4 1D A2 52 C4 1D 8A 49 00 00 8A 4E
+02 00 1E 42 AC 1D A2 83 AC 1D 2E 4E 0E 93 04 24
+9E 42 C4 1D 00 00 F5 3F 3E 4F 30 4D E4 C5 85 2B
+4C 4F 4F 50 39 40 DA C3 E4 3F A8 CE 85 4C 45 41
+56 45 1A 42 C4 1D BA 40 FC C3 00 00 BA 40 BC C3
+02 00 B2 50 06 00 C4 1D A2 53 AC 1D 2A 52 19 42
+AC 1D 89 4A 00 00 30 4D EC CE 04 4D 4F 56 45 00
+0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24 08 99 0F 24
+06 2C F8 49 00 00 18 53 1A 83 FB 23 30 4D 08 5A
+09 5A 19 83 18 83 E8 49 00 00 1A 83 FA 23 30 4D
+34 C2 CA 1D FC C2 2A C2 84 12 50 CF 4A D2 32 D2
+7E CE AC CB 1A D2 DE CE 1A CF 90 C7 BE CF F2 CF
+2E CE B2 D0 48 C3 58 CD C0 CC 68 C8 00 00 3A 40
+0C 00 39 40 CA 1D 38 40 CC 1D D9 3F 3A 40 0E 00
+39 40 CC 1D 38 40 CA 1D CC 3F 82 43 CC 1D 30 4D
+92 42 CA 1D C8 1D 30 4D 6C CD 09 50 57 52 5F 53
+54 41 54 45 84 12 9A CD 16 D2 60 D9 AA CF 08 50
+57 52 5F 48 45 52 45 00 92 42 C4 1D BA CF 92 42
+C6 1D B8 CF EF 3F 6C CE 09 52 53 54 5F 53 54 41
+54 45 92 42 0C 18 BA CF 92 42 0E 18 B8 CF E2 3F
+D8 CF 08 52 53 54 5F 48 45 52 45 00 92 42 C4 1D
+0C 18 92 42 C6 1D 0E 18 DF 3F B2 40 58 D0 BA D0
+B2 40 A0 C6 B0 C6 B2 40 DC C6 F0 C6 B2 40 DC C5
+EA C5 30 41 5C CE 04 57 49 50 45 00 39 40 80 FF
+B9 43 00 00 29 53 39 90 CE FF FA 23 B0 12 0A D0
+B2 40 60 D9 C4 1D B2 40 16 D2 C6 1D D7 3F D0 CD
+06 28 57 41 52 4D 29 00 1E 42 08 18 87 12 4E C7
+05 0D 1B 5B 37 6D 32 C7 70 C5 4E C7 27 20 46 61
+73 74 46 6F 72 74 68 20 56 31 36 30 20 32 34 4D
+48 7A 20 28 43 29 20 4A 2E 4D 2E 54 68 6F 6F 72
+65 6E 73 20 32 C7 34 C2 30 FF 84 C5 2A C3 30 C5
+4E C7 0B 62 79 74 65 73 20 66 72 65 65 20 34 CB
+26 D0 04 57 41 52 4D 00 30 40 58 D0 22 CE 04 43
+4F 4C 44 00 B2 40 04 A5 20 01 92 D3 30 01 B2 40
+88 5A 5C 01 F2 D0 10 00 16 02 B2 D0 00 80 04 02
+B2 40 FF 7F 02 02 B2 D0 FF 7F 06 02 F2 D0 07 00
+36 02 B2 D0 F0 00 04 02 B2 40 0F FF 02 02 B2 D0
+0F FF 06 02 F2 D0 0F 00 24 03 F2 40 F0 00 22 03
+F2 D0 F0 00 26 03 F2 40 A5 00 61 01 B2 40 86 00
+62 01 82 43 66 01 39 40 C0 00 B2 40 33 00 64 01
+D2 43 61 01 92 D2 9E 01 08 18 A2 93 08 18 01 24
+59 07 38 40 C2 A2 18 83 FE 23 19 83 FA 23 B2 D2
+B0 01 92 C3 B0 01 F2 D0 10 00 2A 03 F2 C0 40 00
+A1 04 3A 40 CA D0 39 40 CE FF 89 4A 00 00 29 53
+FC 23 92 42 02 18 F0 FF B2 40 18 00 0A 18 31 40
+E0 1C 3F 40 80 1C 37 40 00 C2 36 40 B4 C2 35 40
+08 C2 34 40 14 C2 B2 40 0A 00 DA 1D B2 43 DC 1D
+92 C3 30 01 18 42 08 18 D2 B3 01 02 04 20 38 E3
+18 53 82 48 08 18 B2 40 81 00 C0 05 B2 40 0D 00
+C6 05 B2 40 01 49 C8 05 F2 D0 03 00 0D 02 92 C3
+C0 05 92 D3 DA 05 3D 40 F0 D1 18 42 08 18 38 90
+0A 00 24 27 38 90 16 00 21 2F 28 93 FA 22 E2 26
+B8 D0 84 12 50 CF 3E D8 EA D8 F2 D7 3E D9 B8 D7
+72 D8 BC D4 00 00 AE D7 5E D8 10 D8 4E D8 CC D5
+00 00 00 00 50 D9 7C CF 50 D0 85 48 49 32 4C 4F
+87 12 84 C5 E8 CD B0 C9 B8 CC 7E CF F2 D1 2A C2
+BE D0 04 43 4F 44 45 00 B0 12 CA CB A2 82 C4 1D
+87 12 F8 CC BC C3 2A D2 4E CE 03 41 53 4D 92 42
+C8 1D B8 1D B2 40 F6 D1 C8 1D EE 3F 00 00 07 45
+4E 44 43 4F 44 45 87 12 8C CF 18 CC 2A C2 5E D2
+06 45 4E 44 41 53 4D 00 92 42 B8 1D C8 1D F3 3F
+00 00 05 43 4F 4C 4F 4E 1A 42 C4 1D BA 40 87 12
+00 00 A2 53 C4 1D B2 43 B6 1D 30 40 8C CF 00 00
+05 4C 4F 32 48 49 1A 42 C4 1D BA 40 B0 12 00 00
+BA 40 2A C2 02 00 A2 52 C4 1D ED 3F 38 40 BE 1D
+39 48 2A 48 09 5A 1A 52 C2 1D 09 9A 03 24 7E 9A
+FC 27 1A 83 0E 4A 2A 88 82 4A C2 1D 30 4D B0 12
+2A C2 A8 C7 00 C8 72 C3 C0 C3 F4 D2 BC C8 C0 C3
+BC CB 16 D3 F6 D2 29 4E 39 90 86 12 02 20 2E 53
+30 41 39 90 85 12 03 20 1E 4E 02 00 30 41 39 90
+84 12 01 20 2E 52 30 41 19 42 C4 1D A2 53 C4 1D
+89 4E 00 00 3E 40 29 00 12 12 C2 1D 92 53 C2 1D
+B0 12 2A C2 A8 C7 BC C8 C0 C3 48 D3 3E D3 21 53
+3E 90 10 00 BB 2D 30 41 4A D3 B2 41 C2 1D 22 D3
+30 41 87 12 4C C4 BC D2 5A D3 82 43 BC 1D 92 42
+C4 1D BA 1D A2 53 C4 1D 0A 4E 3E 4F FA 90 23 00
+00 00 34 20 92 53 C2 1D B0 12 DE D2 0E 93 04 20
+B2 40 00 03 BC 1D 27 3C 1E 93 04 20 B2 40 10 03
+BC 1D 21 3C 2E 93 04 20 B2 40 20 03 BC 1D 1B 3C
+2E 92 04 20 B2 40 20 02 BC 1D 15 3C 3E 92 04 20
+B2 40 30 02 BC 1D 0F 3C 3E 93 04 20 B2 40 30 03
+BC 1D 09 3C B2 40 30 00 BC 1D 19 42 C4 1D A2 53
+C4 1D 89 4E 00 00 3E 4F 3D 41 30 4D FA 90 26 00
+00 00 08 20 B2 40 10 02 BC 1D 92 53 C2 1D 30 12
+CA D3 75 3F FA 90 40 00 00 00 1A 20 B2 40 20 00
+BC 1D 92 53 C2 1D B0 12 28 D3 0E 20 B2 50 10 00
+BC 1D 3E 40 2B 00 B0 12 28 D3 32 24 92 92 BE 1D
+C2 1D 02 24 92 53 C2 1D 8E 10 82 5E BC 1D D3 3F
+B0 12 28 D3 F9 23 B2 50 10 00 BC 1D 3E 40 28 00
+B0 12 DE D2 30 12 1A D4 67 3F 87 12 4C C4 BC D2
+52 D4 FE 90 26 00 00 00 3E 40 20 00 04 20 B2 50
+82 00 BC 1D C2 3F B0 12 28 D3 DF 23 B2 50 80 00
+BC 1D 3E 40 28 00 B0 12 DE D2 B0 12 18 D3 D5 23
+3D 40 BC CB 30 4D 00 00 04 52 45 54 49 00 87 12
+34 C2 00 13 B0 C9 2A C2 34 C2 2C 00 52 D3 4A D4
+A2 D4 2E 4E 1E D2 BC 1D 19 42 BA 1D 92 3F A0 D2
+03 4D 4F 56 84 12 98 D4 00 40 B0 D4 05 4D 4F 56
+2E 42 84 12 98 D4 40 40 00 00 03 41 44 44 84 12
+98 D4 00 50 CA D4 05 41 44 44 2E 42 84 12 98 D4
+40 50 D6 D4 04 41 44 44 43 00 84 12 98 D4 00 60
+E4 D4 06 41 44 44 43 2E 42 00 84 12 98 D4 40 60
+88 D4 04 53 55 42 43 00 84 12 98 D4 00 70 02 D5
+06 53 55 42 43 2E 42 00 84 12 98 D4 40 70 10 D5
+03 53 55 42 84 12 98 D4 00 80 20 D5 05 53 55 42
+2E 42 84 12 98 D4 40 80 82 D2 03 43 4D 50 84 12
+98 D4 00 90 3A D5 05 43 4D 50 2E 42 84 12 98 D4
+40 90 70 D2 04 44 41 44 44 00 84 12 98 D4 00 A0
+54 D5 06 44 41 44 44 2E 42 00 84 12 98 D4 40 A0
+46 D5 03 42 49 54 84 12 98 D4 00 B0 72 D5 05 42
+49 54 2E 42 84 12 98 D4 40 B0 7E D5 03 42 49 43
+84 12 98 D4 00 C0 8C D5 05 42 49 43 2E 42 84 12
+98 D4 40 C0 98 D5 03 42 49 53 84 12 98 D4 00 D0
+A6 D5 05 42 49 53 2E 42 84 12 98 D4 40 D0 00 00
+03 58 4F 52 84 12 98 D4 00 E0 C0 D5 05 58 4F 52
+2E 42 84 12 98 D4 40 E0 F2 D4 03 41 4E 44 84 12
+98 D4 00 F0 DA D5 05 41 4E 44 2E 42 84 12 98 D4
+40 F0 4C C4 52 D3 F8 D5 1A 42 BC 1D B2 F0 70 00
+BC 1D 8A 10 3A F0 0F 00 82 DA BC 1D 4A 3F 2C D5
+03 52 52 43 84 12 F2 D5 00 10 10 D6 05 52 52 43
+2E 42 84 12 F2 D5 40 10 1C D6 04 53 57 50 42 00
+84 12 F2 D5 80 10 2A D6 03 52 52 41 84 12 F2 D5
+00 11 38 D6 05 52 52 41 2E 42 84 12 F2 D5 40 11
+44 D6 03 53 58 54 84 12 F2 D5 80 11 00 00 04 50
+55 53 48 00 84 12 F2 D5 00 12 5E D6 06 50 55 53
+48 2E 42 00 84 12 F2 D5 40 12 B2 D5 04 43 41 4C
+4C 00 84 12 F2 D5 80 12 34 C2 2C 00 52 D3 4A D4
+92 D6 59 42 BC 1D 5A 42 BD 1D 82 4A BC 1D BE 90
+00 15 00 00 02 20 0A 89 02 3C 09 8A 0A 49 3A 90
+10 00 03 2C 5A 0E A8 3F 1A 53 0E 4A 87 12 70 C5
+4E C7 0D 6F 75 74 20 6F 66 20 62 6F 75 6E 64 73
+2E CB 6C D6 05 50 55 53 48 4D 84 12 88 D6 00 15
+D4 D6 04 50 4F 50 4D 00 84 12 88 D6 00 17 4C C4
+BC D2 F4 D6 82 43 BC 1D 92 42 C4 1D BA 1D A2 53
+C4 1D 92 53 C2 1D 3E 40 2C 00 B0 12 2A C2 A8 C7
+BC C8 C0 C3 BC CB 4A D4 1A D7 0A 4E 3E 4F 1A 83
+2A 92 CA 2F 8A 10 5A 06 6F 3F 52 D6 04 52 52 43
+4D 00 84 12 EE D6 50 00 2C D7 04 52 52 41 4D 00
+84 12 EE D6 50 01 3A D7 04 52 4C 41 4D 00 84 12
+EE D6 50 02 48 D7 04 52 52 55 4D 00 84 12 EE D6
+50 03 85 12 00 3C 56 D7 03 53 3E 3D 85 12 00 38
+68 D7 02 53 3C 00 85 12 00 34 E2 D6 03 30 3E 3D
+85 12 00 30 7C D7 02 30 3C 00 85 12 00 30 00 00
+02 55 3C 00 85 12 00 2C 90 D7 03 55 3E 3D 85 12
+00 28 86 D7 03 30 3C 3E 85 12 00 24 A4 D7 02 30
+3D 00 85 12 00 20 00 00 02 49 46 00 1A 42 C4 1D
+8A 4E 00 00 A2 53 C4 1D 0E 4A 30 4D 9A D7 04 54
+48 45 4E 00 1A 42 C4 1D 08 4E 3E 4F 09 48 29 53
+0A 89 0A 11 3A 90 00 02 68 2F 88 DA 00 00 30 4D
+62 D5 04 45 4C 53 45 00 1A 42 C4 1D BA 40 00 3C
+00 00 A2 53 C4 1D 2F 83 8F 4A 00 00 E3 3F CE D7
+05 55 4E 54 49 4C 3A 4F 08 4E 3E 4F 19 42 C4 1D
+2A 83 0A 89 0A 11 3A 90 00 FE 47 3B 3A F0 FF 03
+08 DA 89 48 00 00 A2 53 C4 1D 30 4D E6 D5 05 41
+47 41 49 4E 87 12 62 D7 16 D8 2A C2 00 00 05 57
+48 49 4C 45 87 12 BC D7 6E C2 2A C2 72 D7 06 52
+45 50 45 41 54 00 87 12 62 D7 16 D8 D4 D7 2A C2
+00 00 03 4A 4D 50 87 12 AE CB 62 D7 16 D8 2A C2
+3E B0 00 10 03 20 3E E0 00 04 30 4D 3E 90 00 34
+06 28 03 24 3E 40 00 34 30 4D 3E 40 00 38 30 4D
+00 00 04 3F 4A 4D 50 00 87 12 80 D8 AE CB 6E C2
+16 D8 2A C2 B6 D8 3D 41 08 4E 3E 4F 2A 48 0A 93
+04 20 98 42 C4 1D 00 00 30 4D 88 43 00 00 A4 3F
+7C D6 03 42 57 31 84 12 B4 D8 00 00 D2 D8 03 42
+57 32 84 12 B4 D8 00 00 DE D8 03 42 57 33 84 12
+B4 D8 00 00 F6 D8 3D 41 1A 42 C4 1D 28 4E 08 93
+08 20 BA 4F 00 00 A2 53 C4 1D 8E 4A 00 00 3E 4F
+30 4D 8E 43 00 00 61 3F 00 00 03 46 57 31 84 12
+F4 D8 00 00 1A D9 03 46 57 32 84 12 F4 D8 00 00
+26 D9 03 46 57 33 84 12 F4 D8 00 00 32 D9 04 47
+4F 54 4F 00 87 12 62 D7 AE CB A6 C9 2A C2 A2 D8
+05 3F 47 4F 54 4F 87 12 80 D8 AE CB A6 C9 2A C2
+@FFCE
+CA D0 CA D0 CA D0 CA D0 CA D0 CA D0 CA D0 CA D0
+CA D0 CA D0 CA D0 CA D0 CA D0 CA D0 CA D0 CA D0
+CA D0 4C C6 CA D0 CA D0 CA D0 CA D0 CA D0 CA D0
+CA D0
+q
--- /dev/null
+@1800
+10 00 4C C6 C0 5D 30 75 FD FF 18 00 5C D9 12 D2
+2A C6 38 C6 00 00 00 00
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@C200
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 C2
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 C2 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 C2 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E C2 02 3E 52 00 0E 12 3E 4F 30 4D 8E C2
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 C2
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C C2 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 C2 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 C3
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 C2 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA C2 03 41 4E 44 3E FF 30 4D 7A C2 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E C3 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 C3 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E C3 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 C3 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 C2 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE C3 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 C3 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 C3 03 3E 49 4E 85 12 C2 1D 10 C3
+04 42 41 53 45 00 85 12 DA 1D C0 C2 05 53 54 41
+54 45 85 12 B6 1D 30 C4 02 42 4C 00 85 12 20 00
+94 C3 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 C4 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E C4 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 C4 02 23 53 00 87 12 98 C4
+D2 C4 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 C4 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 C4 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C C4 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 C3 03 55 44 2E 87 12 56 C4
+CC C4 E6 C4 32 C7 FA C6 2A C2 18 C5 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA C2
+02 44 2E 00 87 12 56 C4 6E C2 80 C2 3A C5 CC C4
+92 C2 0A C5 E6 C4 32 C7 FA C6 2A C2 52 C3 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 C4 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 C3 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 C4 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A C6
+92 B3 DC 05 FD 27 1E 42 CC 05 B0 12 38 C6 30 4D
+30 40 B6 C5 7E C5 05 28 4B 45 59 29 18 42 CC 05
+EA 3F 12 C4 03 4B 45 59 30 40 DC C5 92 C5 06 41
+43 43 45 50 54 00 3C 40 8A C6 3B 40 54 C6 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+7E C6 92 B3 DC 05 05 24 18 42 CC 05 38 90 0A 00
+04 20 21 53 39 40 46 C6 4D 15 B2 40 11 00 CE 05
+A2 B3 DC 05 FD 27 30 41 B2 40 13 00 CE 05 A2 B3
+DC 05 FD 27 30 41 12 D2 0A 18 FD 3F 21 52 3A 17
+58 42 CC 05 48 9B F0 27 48 9C 06 2C 78 92 11 20
+2E 9F 0F 24 1E 83 05 3C 0E 9A 03 24 CE 48 00 00
+1E 53 82 48 CE 05 A2 B3 DC 05 FD 27 30 4D 80 C6
+2D 83 92 B3 DC 05 FD 27 E3 23 B2 40 18 00 0A 18
+3E 8F 3D 41 30 4D D6 C5 06 28 45 4D 49 54 29 00
+08 4E 3E 4F E6 3F 50 C5 04 45 4D 49 54 00 30 40
+A0 C6 A8 C6 04 45 43 48 4F 00 B2 40 82 48 72 C6
+30 4D 6E C5 06 4E 4F 45 43 48 4F 00 B2 40 30 4D
+72 C6 30 4D 98 C6 04 28 43 52 29 00 2F 83 8F 4E
+00 00 3E 40 0D 00 E3 3F A2 C5 02 43 52 00 30 40
+DC C6 04 C5 05 53 50 41 43 45 2F 83 8F 4E 00 00
+3E 40 20 00 D4 3F F4 C6 06 53 50 41 43 45 53 00
+0E 93 09 24 0D 12 3D 40 1C C7 EF 3F 1E C7 2D 83
+1E 83 EB 23 3D 41 3E 4F 30 4D 2C C5 04 54 59 50
+45 00 0E 93 95 24 2A 4F 8F 5E 00 00 0E 4A 87 12
+CA C3 02 C4 0A C3 AE C6 EC C3 42 C7 2A C2 2F 82
+8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E 1D B3 0D 63
+30 4D 08 C7 82 53 22 00 87 12 34 C2 4E C7 B0 C9
+34 C2 22 00 A8 C7 78 C7 3D 41 6E 4E 1E 83 82 5E
+C4 1D 3E 4F 92 B3 C4 1D A2 63 C4 1D 30 4D C4 C6
+82 2E 22 00 87 12 68 C7 34 C2 32 C7 B0 C9 2A C2
+00 00 04 57 4F 52 44 00 3C 40 BE 1D 39 4C 3A 4C
+09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A FC 27 1A 83
+3B 40 60 00 C8 4C 00 00 09 9A 0C 24 7C 4A 4E 9C
+09 24 18 53 4B 9C F6 2F 7C 90 7B 00 F3 2F 7C 80
+20 00 F0 3F 1A 82 C0 1D 82 4A C2 1D 1E 42 C4 1D
+08 8E CE 48 00 00 30 4D 00 00 04 46 49 4E 44 00
+2F 83 0C 4E 65 4C 74 40 80 00 3B 40 CA 1D 3E 4B
+0E 93 1E 24 58 4C 01 00 78 F0 1E 00 0E 58 2E 53
+1E 4E FE FF 0E 93 F3 27 09 4E 78 49 48 C4 48 95
+F7 23 0A 4C 1A 53 FA 99 00 00 F2 23 58 83 FA 23
+19 B3 09 63 0C 49 6A 4E 1E 43 4A 93 01 30 2E 83
+8F 4C 00 00 35 40 08 C2 34 40 14 C2 30 4D 2F 53
+2F 53 3E 4F 30 4D 26 C4 07 3E 4E 55 4D 42 45 52
+3C 4F 38 4F 29 4F 2F 82 1B 42 DA 1D 6A 4C 7A 80
+30 00 7A 90 0A 00 02 28 7A 80 07 00 0A 9B 13 2C
+82 49 D0 04 82 48 D2 04 82 4B C8 04 19 42 E4 04
+18 42 E6 04 09 5A 08 63 1C 53 1E 83 E7 23 8F 49
+04 00 8F 48 02 00 8F 4C 00 00 30 4D 03 12 0D 12
+1B 42 DA 1D 0B 12 32 C0 00 02 6D 4E 0D 5E 0C 4E
+7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23 32 D0 00 02
+FC 4C FE FF 0D 9C FC 2F DE 83 00 00 09 43 08 43
+3D 40 32 C9 3F 82 8F 4E 06 00 0C 4E 7E 4C 6A 4C
+7A 90 2D 00 10 2C 3B 40 10 00 7A 80 24 00 06 24
+2B 43 5A 83 03 24 3B 52 6A 53 B0 23 1C 53 1E 83
+6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83 B1 43 04 00
+A5 3F 34 C9 2F 53 0E 93 2C 17 82 4C DA 1D 03 24
+2F 52 0E F3 30 4D 8F 93 00 00 15 20 32 B0 00 02
+14 20 0E 93 05 24 1A 4F 02 00 1A 83 0A 93 0B 38
+2F 53 BF 4F 00 00 3E E3 05 20 BF E3 00 00 9F 53
+00 00 3E E3 30 4D 32 D0 00 02 9F 4F 02 00 04 00
+BF 4F 00 00 3E E3 F6 23 BF E3 02 00 BF E3 00 00
+9F 53 02 00 8F 63 00 00 3E E3 30 4D B4 C6 07 45
+58 45 43 55 54 45 0A 4E 3E 4F 00 4A 28 C3 01 2C
+1A 42 C4 1D A2 53 C4 1D 8A 4E 00 00 3E 4F 30 4D
+AE C9 87 4C 49 54 45 52 41 4C 82 93 B6 1D 16 24
+32 B0 00 02 09 24 1A 42 C4 1D A2 52 C4 1D BA 40
+34 C2 00 00 BA 4F 02 00 1A 42 C4 1D A2 52 C4 1D
+BA 40 34 C2 00 00 8A 4E 02 00 3E 4F 30 4D EA C6
+05 43 4F 55 4E 54 2F 83 1E 53 8F 4E 00 00 5E 4E
+FF FF 30 4D 82 4E BE 1D B2 4F C0 1D 3E 4F 82 43
+C2 1D 87 12 4C C4 A8 C7 2A CA 3D 40 36 CA E8 22
+3D 41 3E 4F 30 4D 38 CA 0A 4E 3E 4F 3D 40 4E CA
+3D 27 3D 40 24 CA 1A E2 B6 1D B2 27 AC 23 50 CA
+3E 4F 3D 40 24 CA B9 23 DE 53 00 00 68 4E 08 5E
+F8 40 3F 00 00 00 3D 40 16 CC CD 3F 9E C9 08 45
+56 41 4C 55 41 54 45 00 39 40 BE 1D 39 12 39 12
+39 12 0D 12 B0 12 2A C2 14 CA 8C CA 3D 41 B2 41
+C2 1D B2 41 C0 1D B2 41 BE 1D 30 4D 7A C3 04 51
+55 49 54 00 31 40 E0 1C B2 40 00 1C AC 1D 82 43
+B6 1D 82 43 08 18 B0 12 2A C2 4E C7 04 0D 6F 6B
+20 00 32 C7 34 C2 38 1D 44 C2 34 C2 50 00 F6 C5
+FA C6 14 CA 34 C2 7E 1C CE C2 B2 C3 4E C7 0D 73
+74 61 63 6B 20 65 6D 70 74 79 20 21 28 CB 34 C2
+30 FF 84 C5 B2 C3 4E C7 0B 46 52 41 4D 20 66 75
+6C 6C 20 21 28 CB 42 C4 F4 C2 C0 C3 BA CA 4E C7
+04 0D 20 20 20 00 BC C3 C2 CA EE C5 05 41 42 4F
+52 54 3F 40 80 1C BE 3F 8F 93 02 00 98 26 B2 40
+82 48 72 C6 B0 12 10 D0 82 43 D6 D8 82 43 E2 D8
+82 43 EE D8 82 43 1E D9 82 43 2A D9 82 43 36 D9
+A2 B3 DC 05 FD 27 B2 40 11 00 CE 05 92 C3 DC 05
+38 40 F0 FF 39 42 19 83 FE 23 18 83 FB 23 92 B3
+DC 05 F4 23 87 12 4E C7 04 1B 5B 37 6D 00 32 C7
+32 C7 4E C7 04 1B 5B 30 6D 00 32 C7 58 CF 9A CF
+A0 CF 22 CB 1C CB 86 41 42 4F 52 54 22 00 87 12
+68 C7 34 C2 28 CB B0 C9 2A C2 FA C7 01 27 87 12
+4C C4 A8 C7 00 C8 C0 C3 BC CB 2A C2 58 CA 52 C4
+81 5C 92 42 BE 1D C2 1D 30 4D 87 12 84 C7 4C C4
+A8 C7 D4 CB 08 4E 7A 4E 5A D3 5A 53 0A 58 19 42
+C8 1D 6E 4E 3E F0 1E 00 09 5E 82 48 AE 1D 82 49
+B0 1D 82 4A B2 1D 2A 52 82 4A C4 1D 3E 4F 3D 41
+30 41 87 12 4E C7 0F 73 74 61 63 6B 20 6D 69 73
+6D 61 74 63 68 21 2E CB 82 9F B4 1D F2 23 18 42
+AE 1D 19 42 B0 1D A8 49 FE FF 89 48 00 00 30 4D
+A2 C7 08 56 41 52 49 41 42 4C 45 00 B0 12 CA CB
+BA 40 86 12 FC FF EF 3F 00 CA 08 43 4F 4E 53 54
+41 4E 54 00 B0 12 CA CB BA 40 85 12 FC FF 8A 4E
+FE FF 3E 4F E0 3F 4A CC 06 43 52 45 41 54 45 00
+B0 12 CA CB BA 40 85 12 FC FF 8A 4A FE FF D3 3F
+6E CA 05 44 4F 45 53 3E 1A 42 B2 1D BA 40 84 12
+00 00 8A 4D 02 00 3D 41 30 4D 82 CC 05 44 45 46
+45 52 B0 12 CA CB BA 40 30 40 FC FF BA 40 98 CC
+FE FF B9 3F 00 00 81 5B 82 43 B6 1D 30 4D C0 CB
+01 5D B2 43 B6 1D 30 4D 64 C7 87 52 45 43 55 52
+53 45 19 42 C4 1D 99 42 B2 1D 00 00 A2 53 C4 1D
+30 4D B6 CC 01 3A B0 12 CA CB BA 40 87 12 FC FF
+A2 83 C4 1D B2 43 B6 1D 82 4F B4 1D 30 4D E4 CC
+81 3B 82 93 B6 1D 5D 27 87 12 34 C2 2A C2 B0 C9
+18 CC B8 CC 2A C2 D6 C6 09 49 4D 4D 45 44 49 41
+54 45 1A 42 AE 1D FA D0 80 00 00 00 30 4D BE 4F
+02 00 3E 4F 30 4D 18 CD 82 49 53 00 87 12 42 C4
+F4 C2 C0 C3 50 CD 5C CD 34 C2 2E CD B0 C9 2A C2
+AE CB 2E CD 2A C2 00 CD 83 5B 27 5D 87 12 AE CB
+34 C2 34 C2 B0 C9 B0 C9 2A C2 9E CA 88 50 4F 53
+54 50 4F 4E 45 00 87 12 4C C4 A8 C7 00 C8 54 C2
+C0 C3 BC CB 7E C3 C0 C3 96 CD 34 C2 34 C2 B0 C9
+B0 C9 34 C2 B0 C9 B0 C9 2A C2 9C CD 3A 4E 82 4A
+C6 1D 2E 4E 82 4E C4 1D 3D 40 10 00 09 4A 08 49
+29 83 18 48 FE FF 0E 98 FC 2B 89 48 00 00 1D 83
+F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41 30 4D 38 CD
+82 49 46 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40
+C0 C3 00 00 A2 52 C4 1D 2E 53 30 4D 9C CC 84 45
+4C 53 45 00 1A 42 C4 1D BA 40 BC C3 00 00 2A 52
+82 4A C4 1D 8E 4A 00 00 2A 83 0E 4A 30 4D 2C C7
+84 54 48 45 4E 00 9E 42 C4 1D 00 00 3E 4F 30 4D
+68 CC 85 42 45 47 49 4E 30 40 84 C5 10 CE 85 55
+4E 54 49 4C 39 40 C0 C3 1A 42 C4 1D A2 52 C4 1D
+8A 49 00 00 8A 4E 02 00 3E 4F 30 4D 96 CB 85 41
+47 41 49 4E 39 40 BC C3 EF 3F 32 CC 85 57 48 49
+4C 45 87 12 D4 CD 6E C2 2A C2 CA CC 86 52 45 50
+45 41 54 00 87 12 54 CE 16 CE 2A C2 EE CD 82 44
+4F 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40 CA C3
+00 00 2E 53 82 4E C4 1D A2 53 AC 1D 1A 42 AC 1D
+8A 43 00 00 30 4D C2 C9 84 4C 4F 4F 50 00 39 40
+EC C3 1A 42 C4 1D A2 52 C4 1D 8A 49 00 00 8A 4E
+02 00 1E 42 AC 1D A2 83 AC 1D 2E 4E 0E 93 04 24
+9E 42 C4 1D 00 00 F5 3F 3E 4F 30 4D E4 C5 85 2B
+4C 4F 4F 50 39 40 DA C3 E4 3F A8 CE 85 4C 45 41
+56 45 1A 42 C4 1D BA 40 FC C3 00 00 BA 40 BC C3
+02 00 B2 50 06 00 C4 1D A2 53 AC 1D 2A 52 19 42
+AC 1D 89 4A 00 00 30 4D EC CE 04 4D 4F 56 45 00
+0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24 08 99 0F 24
+06 2C F8 49 00 00 18 53 1A 83 FB 23 30 4D 08 5A
+09 5A 19 83 18 83 E8 49 00 00 1A 83 FA 23 30 4D
+34 C2 CA 1D FC C2 2A C2 84 12 50 CF 46 D2 2E D2
+7E CE AC CB 16 D2 DE CE 1A CF 90 C7 BE CF F2 CF
+2E CE B2 D0 48 C3 58 CD C0 CC 68 C8 00 00 3A 40
+0C 00 39 40 CA 1D 38 40 CC 1D D9 3F 3A 40 0E 00
+39 40 CC 1D 38 40 CA 1D CC 3F 82 43 CC 1D 30 4D
+92 42 CA 1D C8 1D 30 4D 6C CD 09 50 57 52 5F 53
+54 41 54 45 84 12 9A CD 12 D2 5C D9 AA CF 08 50
+57 52 5F 48 45 52 45 00 92 42 C4 1D BA CF 92 42
+C6 1D B8 CF EF 3F 6C CE 09 52 53 54 5F 53 54 41
+54 45 92 42 0C 18 BA CF 92 42 0E 18 B8 CF E2 3F
+D8 CF 08 52 53 54 5F 48 45 52 45 00 92 42 C4 1D
+0C 18 92 42 C6 1D 0E 18 DF 3F B2 40 58 D0 BA D0
+B2 40 A0 C6 B0 C6 B2 40 DC C6 F0 C6 B2 40 DC C5
+EA C5 30 41 5C CE 04 57 49 50 45 00 39 40 80 FF
+B9 43 00 00 29 53 39 90 CE FF FA 23 B0 12 0A D0
+B2 40 5C D9 C4 1D B2 40 12 D2 C6 1D D7 3F D0 CD
+06 28 57 41 52 4D 29 00 1E 42 08 18 87 12 4E C7
+05 0D 1B 5B 37 6D 32 C7 70 C5 4E C7 27 20 46 61
+73 74 46 6F 72 74 68 20 56 31 36 30 20 32 34 4D
+48 7A 20 28 43 29 20 4A 2E 4D 2E 54 68 6F 6F 72
+65 6E 73 20 32 C7 34 C2 30 FF 84 C5 2A C3 30 C5
+4E C7 0B 62 79 74 65 73 20 66 72 65 65 20 34 CB
+26 D0 04 57 41 52 4D 00 30 40 58 D0 22 CE 04 43
+4F 4C 44 00 B2 40 04 A5 20 01 92 D3 30 01 B2 40
+88 5A 5C 01 F2 D0 10 00 16 02 B2 D0 00 80 04 02
+B2 40 FF 7F 02 02 B2 D0 FF 7F 06 02 F2 D0 07 00
+36 02 B2 D0 F0 00 04 02 B2 40 0F FF 02 02 B2 D0
+0F FF 06 02 F2 D0 0F 00 24 03 F2 40 F0 00 22 03
+F2 D0 F0 00 26 03 F2 40 A5 00 61 01 B2 40 86 00
+62 01 82 43 66 01 39 40 C0 00 B2 40 33 00 64 01
+D2 43 61 01 92 D2 9E 01 08 18 A2 93 08 18 01 24
+59 07 38 40 C2 A2 18 83 FE 23 19 83 FA 23 B2 D2
+B0 01 92 C3 B0 01 F2 D0 10 00 2A 03 F2 C0 40 00
+A1 04 3A 40 CA D0 39 40 CE FF 89 4A 00 00 29 53
+FC 23 92 42 02 18 F0 FF B2 40 18 00 0A 18 31 40
+E0 1C 3F 40 80 1C 37 40 00 C2 36 40 B4 C2 35 40
+08 C2 34 40 14 C2 B2 40 0A 00 DA 1D B2 43 DC 1D
+92 C3 30 01 18 42 08 18 D2 B3 01 02 04 20 38 E3
+18 53 82 48 08 18 B2 40 81 00 C0 05 B2 42 C6 05
+82 43 C8 05 F2 D0 03 00 0D 02 92 C3 C0 05 92 D3
+DA 05 3D 40 EC D1 18 42 08 18 38 90 0A 00 26 27
+38 90 16 00 23 2F 28 93 FC 22 E4 26 B8 D0 84 12
+50 CF 3A D8 E6 D8 EE D7 3A D9 B4 D7 6E D8 B8 D4
+00 00 AA D7 5A D8 0C D8 4A D8 C8 D5 00 00 00 00
+4C D9 7C CF 50 D0 85 48 49 32 4C 4F 87 12 84 C5
+E8 CD B0 C9 B8 CC 7E CF EE D1 2A C2 BE D0 04 43
+4F 44 45 00 B0 12 CA CB A2 82 C4 1D 87 12 F8 CC
+BC C3 26 D2 4E CE 03 41 53 4D 92 42 C8 1D B8 1D
+B2 40 F2 D1 C8 1D EE 3F 00 00 07 45 4E 44 43 4F
+44 45 87 12 8C CF 18 CC 2A C2 5A D2 06 45 4E 44
+41 53 4D 00 92 42 B8 1D C8 1D F3 3F 00 00 05 43
+4F 4C 4F 4E 1A 42 C4 1D BA 40 87 12 00 00 A2 53
+C4 1D B2 43 B6 1D 30 40 8C CF 00 00 05 4C 4F 32
+48 49 1A 42 C4 1D BA 40 B0 12 00 00 BA 40 2A C2
+02 00 A2 52 C4 1D ED 3F 38 40 BE 1D 39 48 2A 48
+09 5A 1A 52 C2 1D 09 9A 03 24 7E 9A FC 27 1A 83
+0E 4A 2A 88 82 4A C2 1D 30 4D B0 12 2A C2 A8 C7
+00 C8 72 C3 C0 C3 F0 D2 BC C8 C0 C3 BC CB 12 D3
+F2 D2 29 4E 39 90 86 12 02 20 2E 53 30 41 39 90
+85 12 03 20 1E 4E 02 00 30 41 39 90 84 12 01 20
+2E 52 30 41 19 42 C4 1D A2 53 C4 1D 89 4E 00 00
+3E 40 29 00 12 12 C2 1D 92 53 C2 1D B0 12 2A C2
+A8 C7 BC C8 C0 C3 44 D3 3A D3 21 53 3E 90 10 00
+BB 2D 30 41 46 D3 B2 41 C2 1D 22 D3 30 41 87 12
+4C C4 B8 D2 56 D3 82 43 BC 1D 92 42 C4 1D BA 1D
+A2 53 C4 1D 0A 4E 3E 4F FA 90 23 00 00 00 34 20
+92 53 C2 1D B0 12 DA D2 0E 93 04 20 B2 40 00 03
+BC 1D 27 3C 1E 93 04 20 B2 40 10 03 BC 1D 21 3C
+2E 93 04 20 B2 40 20 03 BC 1D 1B 3C 2E 92 04 20
+B2 40 20 02 BC 1D 15 3C 3E 92 04 20 B2 40 30 02
+BC 1D 0F 3C 3E 93 04 20 B2 40 30 03 BC 1D 09 3C
+B2 40 30 00 BC 1D 19 42 C4 1D A2 53 C4 1D 89 4E
+00 00 3E 4F 3D 41 30 4D FA 90 26 00 00 00 08 20
+B2 40 10 02 BC 1D 92 53 C2 1D 30 12 C6 D3 75 3F
+FA 90 40 00 00 00 1A 20 B2 40 20 00 BC 1D 92 53
+C2 1D B0 12 24 D3 0E 20 B2 50 10 00 BC 1D 3E 40
+2B 00 B0 12 24 D3 32 24 92 92 BE 1D C2 1D 02 24
+92 53 C2 1D 8E 10 82 5E BC 1D D3 3F B0 12 24 D3
+F9 23 B2 50 10 00 BC 1D 3E 40 28 00 B0 12 DA D2
+30 12 16 D4 67 3F 87 12 4C C4 B8 D2 4E D4 FE 90
+26 00 00 00 3E 40 20 00 04 20 B2 50 82 00 BC 1D
+C2 3F B0 12 24 D3 DF 23 B2 50 80 00 BC 1D 3E 40
+28 00 B0 12 DA D2 B0 12 14 D3 D5 23 3D 40 BC CB
+30 4D 00 00 04 52 45 54 49 00 87 12 34 C2 00 13
+B0 C9 2A C2 34 C2 2C 00 4E D3 46 D4 9E D4 2E 4E
+1E D2 BC 1D 19 42 BA 1D 92 3F 9C D2 03 4D 4F 56
+84 12 94 D4 00 40 AC D4 05 4D 4F 56 2E 42 84 12
+94 D4 40 40 00 00 03 41 44 44 84 12 94 D4 00 50
+C6 D4 05 41 44 44 2E 42 84 12 94 D4 40 50 D2 D4
+04 41 44 44 43 00 84 12 94 D4 00 60 E0 D4 06 41
+44 44 43 2E 42 00 84 12 94 D4 40 60 84 D4 04 53
+55 42 43 00 84 12 94 D4 00 70 FE D4 06 53 55 42
+43 2E 42 00 84 12 94 D4 40 70 0C D5 03 53 55 42
+84 12 94 D4 00 80 1C D5 05 53 55 42 2E 42 84 12
+94 D4 40 80 7E D2 03 43 4D 50 84 12 94 D4 00 90
+36 D5 05 43 4D 50 2E 42 84 12 94 D4 40 90 6C D2
+04 44 41 44 44 00 84 12 94 D4 00 A0 50 D5 06 44
+41 44 44 2E 42 00 84 12 94 D4 40 A0 42 D5 03 42
+49 54 84 12 94 D4 00 B0 6E D5 05 42 49 54 2E 42
+84 12 94 D4 40 B0 7A D5 03 42 49 43 84 12 94 D4
+00 C0 88 D5 05 42 49 43 2E 42 84 12 94 D4 40 C0
+94 D5 03 42 49 53 84 12 94 D4 00 D0 A2 D5 05 42
+49 53 2E 42 84 12 94 D4 40 D0 00 00 03 58 4F 52
+84 12 94 D4 00 E0 BC D5 05 58 4F 52 2E 42 84 12
+94 D4 40 E0 EE D4 03 41 4E 44 84 12 94 D4 00 F0
+D6 D5 05 41 4E 44 2E 42 84 12 94 D4 40 F0 4C C4
+4E D3 F4 D5 1A 42 BC 1D B2 F0 70 00 BC 1D 8A 10
+3A F0 0F 00 82 DA BC 1D 4A 3F 28 D5 03 52 52 43
+84 12 EE D5 00 10 0C D6 05 52 52 43 2E 42 84 12
+EE D5 40 10 18 D6 04 53 57 50 42 00 84 12 EE D5
+80 10 26 D6 03 52 52 41 84 12 EE D5 00 11 34 D6
+05 52 52 41 2E 42 84 12 EE D5 40 11 40 D6 03 53
+58 54 84 12 EE D5 80 11 00 00 04 50 55 53 48 00
+84 12 EE D5 00 12 5A D6 06 50 55 53 48 2E 42 00
+84 12 EE D5 40 12 AE D5 04 43 41 4C 4C 00 84 12
+EE D5 80 12 34 C2 2C 00 4E D3 46 D4 8E D6 59 42
+BC 1D 5A 42 BD 1D 82 4A BC 1D BE 90 00 15 00 00
+02 20 0A 89 02 3C 09 8A 0A 49 3A 90 10 00 03 2C
+5A 0E A8 3F 1A 53 0E 4A 87 12 70 C5 4E C7 0D 6F
+75 74 20 6F 66 20 62 6F 75 6E 64 73 2E CB 68 D6
+05 50 55 53 48 4D 84 12 84 D6 00 15 D0 D6 04 50
+4F 50 4D 00 84 12 84 D6 00 17 4C C4 B8 D2 F0 D6
+82 43 BC 1D 92 42 C4 1D BA 1D A2 53 C4 1D 92 53
+C2 1D 3E 40 2C 00 B0 12 2A C2 A8 C7 BC C8 C0 C3
+BC CB 46 D4 16 D7 0A 4E 3E 4F 1A 83 2A 92 CA 2F
+8A 10 5A 06 6F 3F 4E D6 04 52 52 43 4D 00 84 12
+EA D6 50 00 28 D7 04 52 52 41 4D 00 84 12 EA D6
+50 01 36 D7 04 52 4C 41 4D 00 84 12 EA D6 50 02
+44 D7 04 52 52 55 4D 00 84 12 EA D6 50 03 85 12
+00 3C 52 D7 03 53 3E 3D 85 12 00 38 64 D7 02 53
+3C 00 85 12 00 34 DE D6 03 30 3E 3D 85 12 00 30
+78 D7 02 30 3C 00 85 12 00 30 00 00 02 55 3C 00
+85 12 00 2C 8C D7 03 55 3E 3D 85 12 00 28 82 D7
+03 30 3C 3E 85 12 00 24 A0 D7 02 30 3D 00 85 12
+00 20 00 00 02 49 46 00 1A 42 C4 1D 8A 4E 00 00
+A2 53 C4 1D 0E 4A 30 4D 96 D7 04 54 48 45 4E 00
+1A 42 C4 1D 08 4E 3E 4F 09 48 29 53 0A 89 0A 11
+3A 90 00 02 68 2F 88 DA 00 00 30 4D 5E D5 04 45
+4C 53 45 00 1A 42 C4 1D BA 40 00 3C 00 00 A2 53
+C4 1D 2F 83 8F 4A 00 00 E3 3F CA D7 05 55 4E 54
+49 4C 3A 4F 08 4E 3E 4F 19 42 C4 1D 2A 83 0A 89
+0A 11 3A 90 00 FE 47 3B 3A F0 FF 03 08 DA 89 48
+00 00 A2 53 C4 1D 30 4D E2 D5 05 41 47 41 49 4E
+87 12 5E D7 12 D8 2A C2 00 00 05 57 48 49 4C 45
+87 12 B8 D7 6E C2 2A C2 6E D7 06 52 45 50 45 41
+54 00 87 12 5E D7 12 D8 D0 D7 2A C2 00 00 03 4A
+4D 50 87 12 AE CB 5E D7 12 D8 2A C2 3E B0 00 10
+03 20 3E E0 00 04 30 4D 3E 90 00 34 06 28 03 24
+3E 40 00 34 30 4D 3E 40 00 38 30 4D 00 00 04 3F
+4A 4D 50 00 87 12 7C D8 AE CB 6E C2 12 D8 2A C2
+B2 D8 3D 41 08 4E 3E 4F 2A 48 0A 93 04 20 98 42
+C4 1D 00 00 30 4D 88 43 00 00 A4 3F 78 D6 03 42
+57 31 84 12 B0 D8 00 00 CE D8 03 42 57 32 84 12
+B0 D8 00 00 DA D8 03 42 57 33 84 12 B0 D8 00 00
+F2 D8 3D 41 1A 42 C4 1D 28 4E 08 93 08 20 BA 4F
+00 00 A2 53 C4 1D 8E 4A 00 00 3E 4F 30 4D 8E 43
+00 00 61 3F 00 00 03 46 57 31 84 12 F0 D8 00 00
+16 D9 03 46 57 32 84 12 F0 D8 00 00 22 D9 03 46
+57 33 84 12 F0 D8 00 00 2E D9 04 47 4F 54 4F 00
+87 12 5E D7 AE CB A6 C9 2A C2 9E D8 05 3F 47 4F
+54 4F 87 12 7C D8 AE CB A6 C9 2A C2
+@FFCE
+CA D0 CA D0 CA D0 CA D0 CA D0 CA D0 CA D0 CA D0
+CA D0 CA D0 CA D0 CA D0 CA D0 CA D0 CA D0 CA D0
+CA D0 4C C6 CA D0 CA D0 CA D0 CA D0 CA D0 CA D0
+CA D0
+q
--- /dev/null
+@1800
+10 00 40 C6 F4 01 80 04 FD FF 18 00 4C D9 02 D2
+2A C6 32 C6 00 00 00 00
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@C200
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 C2
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 C2 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 C2 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E C2 02 3E 52 00 0E 12 3E 4F 30 4D 8E C2
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 C2
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C C2 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 C2 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 C3
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 C2 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA C2 03 41 4E 44 3E FF 30 4D 7A C2 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E C3 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 C3 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E C3 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 C3 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 C2 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE C3 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 C3 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 C3 03 3E 49 4E 85 12 C2 1D 10 C3
+04 42 41 53 45 00 85 12 DA 1D C0 C2 05 53 54 41
+54 45 85 12 B6 1D 30 C4 02 42 4C 00 85 12 20 00
+94 C3 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 C4 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E C4 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 C4 02 23 53 00 87 12 98 C4
+D2 C4 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 C4 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 C4 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C C4 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 C3 03 55 44 2E 87 12 56 C4
+CC C4 E6 C4 26 C7 EE C6 2A C2 18 C5 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA C2
+02 44 2E 00 87 12 56 C4 6E C2 80 C2 3A C5 CC C4
+92 C2 0A C5 E6 C4 26 C7 EE C6 2A C2 52 C3 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 C4 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 C3 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 C4 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A C6
+92 B3 DC 05 FD 27 1E 42 CC 05 B0 12 32 C6 30 4D
+30 40 B6 C5 7E C5 05 28 4B 45 59 29 18 42 CC 05
+EA 3F 12 C4 03 4B 45 59 30 40 DC C5 92 C5 06 41
+43 43 45 50 54 00 3C 40 78 C6 3B 40 48 C6 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+6C C6 92 B3 DC 05 05 24 18 42 CC 05 38 90 0A 00
+04 20 21 53 39 40 3A C6 4D 15 B2 40 11 00 CE 05
+30 41 B2 40 13 00 CE 05 30 41 12 D2 0A 18 FD 3F
+21 52 3A 17 58 42 CC 05 48 9B F3 27 48 9C 06 2C
+78 92 0E 20 2E 9F 0C 24 1E 83 05 3C 0E 9A 03 24
+CE 48 00 00 1E 53 82 48 CE 05 30 4D 6E C6 2D 83
+92 B3 DC 05 FD 27 E6 23 B2 40 18 00 0A 18 3E 8F
+3D 41 30 4D D6 C5 06 28 45 4D 49 54 29 00 08 4E
+3E 4F A2 B3 DC 05 FD 27 E6 3F 50 C5 04 45 4D 49
+54 00 30 40 8E C6 9C C6 04 45 43 48 4F 00 B2 40
+82 48 66 C6 30 4D 6E C5 06 4E 4F 45 43 48 4F 00
+B2 40 30 4D 66 C6 30 4D 86 C6 04 28 43 52 29 00
+2F 83 8F 4E 00 00 3E 40 0D 00 E3 3F A2 C5 02 43
+52 00 30 40 D0 C6 04 C5 05 53 50 41 43 45 2F 83
+8F 4E 00 00 3E 40 20 00 D4 3F E8 C6 06 53 50 41
+43 45 53 00 0E 93 09 24 0D 12 3D 40 10 C7 EF 3F
+12 C7 2D 83 1E 83 EB 23 3D 41 3E 4F 30 4D 2C C5
+04 54 59 50 45 00 0E 93 95 24 2A 4F 8F 5E 00 00
+0E 4A 87 12 CA C3 02 C4 0A C3 A2 C6 EC C3 36 C7
+2A C2 2F 82 8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E
+1D B3 0D 63 30 4D FC C6 82 53 22 00 87 12 34 C2
+42 C7 A4 C9 34 C2 22 00 9C C7 6C C7 3D 41 6E 4E
+1E 83 82 5E C4 1D 3E 4F 92 B3 C4 1D A2 63 C4 1D
+30 4D B8 C6 82 2E 22 00 87 12 5C C7 34 C2 26 C7
+A4 C9 2A C2 00 00 04 57 4F 52 44 00 3C 40 BE 1D
+39 4C 3A 4C 09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A
+FC 27 1A 83 3B 40 60 00 C8 4C 00 00 09 9A 0C 24
+7C 4A 4E 9C 09 24 18 53 4B 9C F6 2F 7C 90 7B 00
+F3 2F 7C 80 20 00 F0 3F 1A 82 C0 1D 82 4A C2 1D
+1E 42 C4 1D 08 8E CE 48 00 00 30 4D 00 00 04 46
+49 4E 44 00 2F 83 0C 4E 65 4C 74 40 80 00 3B 40
+CA 1D 3E 4B 0E 93 1E 24 58 4C 01 00 78 F0 1E 00
+0E 58 2E 53 1E 4E FE FF 0E 93 F3 27 09 4E 78 49
+48 C4 48 95 F7 23 0A 4C 1A 53 FA 99 00 00 F2 23
+58 83 FA 23 19 B3 09 63 0C 49 6A 4E 1E 43 4A 93
+01 30 2E 83 8F 4C 00 00 35 40 08 C2 34 40 14 C2
+30 4D 2F 53 2F 53 3E 4F 30 4D 26 C4 07 3E 4E 55
+4D 42 45 52 3C 4F 38 4F 29 4F 2F 82 1B 42 DA 1D
+6A 4C 7A 80 30 00 7A 90 0A 00 02 28 7A 80 07 00
+0A 9B 13 2C 82 49 D0 04 82 48 D2 04 82 4B C8 04
+19 42 E4 04 18 42 E6 04 09 5A 08 63 1C 53 1E 83
+E7 23 8F 49 04 00 8F 48 02 00 8F 4C 00 00 30 4D
+03 12 0D 12 1B 42 DA 1D 0B 12 32 C0 00 02 6D 4E
+0D 5E 0C 4E 7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23
+32 D0 00 02 FC 4C FE FF 0D 9C FC 2F DE 83 00 00
+09 43 08 43 3D 40 26 C9 3F 82 8F 4E 06 00 0C 4E
+7E 4C 6A 4C 7A 90 2D 00 10 2C 3B 40 10 00 7A 80
+24 00 06 24 2B 43 5A 83 03 24 3B 52 6A 53 B0 23
+1C 53 1E 83 6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83
+B1 43 04 00 A5 3F 28 C9 2F 53 0E 93 2C 17 82 4C
+DA 1D 03 24 2F 52 0E F3 30 4D 8F 93 00 00 15 20
+32 B0 00 02 14 20 0E 93 05 24 1A 4F 02 00 1A 83
+0A 93 0B 38 2F 53 BF 4F 00 00 3E E3 05 20 BF E3
+00 00 9F 53 00 00 3E E3 30 4D 32 D0 00 02 9F 4F
+02 00 04 00 BF 4F 00 00 3E E3 F6 23 BF E3 02 00
+BF E3 00 00 9F 53 02 00 8F 63 00 00 3E E3 30 4D
+A8 C6 07 45 58 45 43 55 54 45 0A 4E 3E 4F 00 4A
+28 C3 01 2C 1A 42 C4 1D A2 53 C4 1D 8A 4E 00 00
+3E 4F 30 4D A2 C9 87 4C 49 54 45 52 41 4C 82 93
+B6 1D 16 24 32 B0 00 02 09 24 1A 42 C4 1D A2 52
+C4 1D BA 40 34 C2 00 00 BA 4F 02 00 1A 42 C4 1D
+A2 52 C4 1D BA 40 34 C2 00 00 8A 4E 02 00 3E 4F
+30 4D DE C6 05 43 4F 55 4E 54 2F 83 1E 53 8F 4E
+00 00 5E 4E FF FF 30 4D 82 4E BE 1D B2 4F C0 1D
+3E 4F 82 43 C2 1D 87 12 4C C4 9C C7 1E CA 3D 40
+2A CA E8 22 3D 41 3E 4F 30 4D 2C CA 0A 4E 3E 4F
+3D 40 42 CA 3D 27 3D 40 18 CA 1A E2 B6 1D B2 27
+AC 23 44 CA 3E 4F 3D 40 18 CA B9 23 DE 53 00 00
+68 4E 08 5E F8 40 3F 00 00 00 3D 40 0A CC CD 3F
+92 C9 08 45 56 41 4C 55 41 54 45 00 39 40 BE 1D
+39 12 39 12 39 12 0D 12 B0 12 2A C2 08 CA 80 CA
+3D 41 B2 41 C2 1D B2 41 C0 1D B2 41 BE 1D 30 4D
+7A C3 04 51 55 49 54 00 31 40 E0 1C B2 40 00 1C
+AC 1D 82 43 B6 1D 82 43 08 18 B0 12 2A C2 42 C7
+04 0D 6F 6B 20 00 26 C7 34 C2 38 1D 44 C2 34 C2
+50 00 F6 C5 EE C6 08 CA 34 C2 7E 1C CE C2 B2 C3
+42 C7 0D 73 74 61 63 6B 20 65 6D 70 74 79 20 21
+1C CB 34 C2 30 FF 84 C5 B2 C3 42 C7 0B 46 52 41
+4D 20 66 75 6C 6C 20 21 1C CB 42 C4 F4 C2 C0 C3
+AE CA 42 C7 04 0D 20 20 20 00 BC C3 B6 CA EE C5
+05 41 42 4F 52 54 3F 40 80 1C BE 3F 8F 93 02 00
+98 26 B2 40 82 48 66 C6 B0 12 04 D0 82 43 C6 D8
+82 43 D2 D8 82 43 DE D8 82 43 0E D9 82 43 1A D9
+82 43 26 D9 A2 B3 DC 05 FD 27 B2 40 11 00 CE 05
+92 C3 DC 05 38 40 55 05 39 42 19 83 FE 23 18 83
+FB 23 92 B3 DC 05 F4 23 87 12 42 C7 04 1B 5B 37
+6D 00 26 C7 26 C7 42 C7 04 1B 5B 30 6D 00 26 C7
+4C CF 8E CF 94 CF 16 CB 10 CB 86 41 42 4F 52 54
+22 00 87 12 5C C7 34 C2 1C CB A4 C9 2A C2 EE C7
+01 27 87 12 4C C4 9C C7 F4 C7 C0 C3 B0 CB 2A C2
+4C CA 52 C4 81 5C 92 42 BE 1D C2 1D 30 4D 87 12
+78 C7 4C C4 9C C7 C8 CB 08 4E 7A 4E 5A D3 5A 53
+0A 58 19 42 C8 1D 6E 4E 3E F0 1E 00 09 5E 82 48
+AE 1D 82 49 B0 1D 82 4A B2 1D 2A 52 82 4A C4 1D
+3E 4F 3D 41 30 41 87 12 42 C7 0F 73 74 61 63 6B
+20 6D 69 73 6D 61 74 63 68 21 22 CB 82 9F B4 1D
+F2 23 18 42 AE 1D 19 42 B0 1D A8 49 FE FF 89 48
+00 00 30 4D 96 C7 08 56 41 52 49 41 42 4C 45 00
+B0 12 BE CB BA 40 86 12 FC FF EF 3F F4 C9 08 43
+4F 4E 53 54 41 4E 54 00 B0 12 BE CB BA 40 85 12
+FC FF 8A 4E FE FF 3E 4F E0 3F 3E CC 06 43 52 45
+41 54 45 00 B0 12 BE CB BA 40 85 12 FC FF 8A 4A
+FE FF D3 3F 62 CA 05 44 4F 45 53 3E 1A 42 B2 1D
+BA 40 84 12 00 00 8A 4D 02 00 3D 41 30 4D 76 CC
+05 44 45 46 45 52 B0 12 BE CB BA 40 30 40 FC FF
+BA 40 8C CC FE FF B9 3F 00 00 81 5B 82 43 B6 1D
+30 4D B4 CB 01 5D B2 43 B6 1D 30 4D 58 C7 87 52
+45 43 55 52 53 45 19 42 C4 1D 99 42 B2 1D 00 00
+A2 53 C4 1D 30 4D AA CC 01 3A B0 12 BE CB BA 40
+87 12 FC FF A2 83 C4 1D B2 43 B6 1D 82 4F B4 1D
+30 4D D8 CC 81 3B 82 93 B6 1D 5D 27 87 12 34 C2
+2A C2 A4 C9 0C CC AC CC 2A C2 CA C6 09 49 4D 4D
+45 44 49 41 54 45 1A 42 AE 1D FA D0 80 00 00 00
+30 4D BE 4F 02 00 3E 4F 30 4D 0C CD 82 49 53 00
+87 12 42 C4 F4 C2 C0 C3 44 CD 50 CD 34 C2 22 CD
+A4 C9 2A C2 A2 CB 22 CD 2A C2 F4 CC 83 5B 27 5D
+87 12 A2 CB 34 C2 34 C2 A4 C9 A4 C9 2A C2 92 CA
+88 50 4F 53 54 50 4F 4E 45 00 87 12 4C C4 9C C7
+F4 C7 54 C2 C0 C3 B0 CB 7E C3 C0 C3 8A CD 34 C2
+34 C2 A4 C9 A4 C9 34 C2 A4 C9 A4 C9 2A C2 90 CD
+3A 4E 82 4A C6 1D 2E 4E 82 4E C4 1D 3D 40 10 00
+09 4A 08 49 29 83 18 48 FE FF 0E 98 FC 2B 89 48
+00 00 1D 83 F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41
+30 4D 2C CD 82 49 46 00 2F 83 8F 4E 00 00 1E 42
+C4 1D BE 40 C0 C3 00 00 A2 52 C4 1D 2E 53 30 4D
+90 CC 84 45 4C 53 45 00 1A 42 C4 1D BA 40 BC C3
+00 00 2A 52 82 4A C4 1D 8E 4A 00 00 2A 83 0E 4A
+30 4D 20 C7 84 54 48 45 4E 00 9E 42 C4 1D 00 00
+3E 4F 30 4D 5C CC 85 42 45 47 49 4E 30 40 84 C5
+04 CE 85 55 4E 54 49 4C 39 40 C0 C3 1A 42 C4 1D
+A2 52 C4 1D 8A 49 00 00 8A 4E 02 00 3E 4F 30 4D
+8A CB 85 41 47 41 49 4E 39 40 BC C3 EF 3F 26 CC
+85 57 48 49 4C 45 87 12 C8 CD 6E C2 2A C2 BE CC
+86 52 45 50 45 41 54 00 87 12 48 CE 0A CE 2A C2
+E2 CD 82 44 4F 00 2F 83 8F 4E 00 00 1E 42 C4 1D
+BE 40 CA C3 00 00 2E 53 82 4E C4 1D A2 53 AC 1D
+1A 42 AC 1D 8A 43 00 00 30 4D B6 C9 84 4C 4F 4F
+50 00 39 40 EC C3 1A 42 C4 1D A2 52 C4 1D 8A 49
+00 00 8A 4E 02 00 1E 42 AC 1D A2 83 AC 1D 2E 4E
+0E 93 04 24 9E 42 C4 1D 00 00 F5 3F 3E 4F 30 4D
+E4 C5 85 2B 4C 4F 4F 50 39 40 DA C3 E4 3F 9C CE
+85 4C 45 41 56 45 1A 42 C4 1D BA 40 FC C3 00 00
+BA 40 BC C3 02 00 B2 50 06 00 C4 1D A2 53 AC 1D
+2A 52 19 42 AC 1D 89 4A 00 00 30 4D E0 CE 04 4D
+4F 56 45 00 0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24
+08 99 0F 24 06 2C F8 49 00 00 18 53 1A 83 FB 23
+30 4D 08 5A 09 5A 19 83 18 83 E8 49 00 00 1A 83
+FA 23 30 4D 34 C2 CA 1D FC C2 2A C2 84 12 44 CF
+36 D2 1E D2 72 CE A0 CB 06 D2 D2 CE 0E CF 84 C7
+B2 CF E6 CF 22 CE A6 D0 48 C3 4C CD B4 CC 5C C8
+00 00 3A 40 0C 00 39 40 CA 1D 38 40 CC 1D D9 3F
+3A 40 0E 00 39 40 CC 1D 38 40 CA 1D CC 3F 82 43
+CC 1D 30 4D 92 42 CA 1D C8 1D 30 4D 60 CD 09 50
+57 52 5F 53 54 41 54 45 84 12 8E CD 02 D2 4C D9
+9E CF 08 50 57 52 5F 48 45 52 45 00 92 42 C4 1D
+AE CF 92 42 C6 1D AC CF EF 3F 60 CE 09 52 53 54
+5F 53 54 41 54 45 92 42 0C 18 AE CF 92 42 0E 18
+AC CF E2 3F CC CF 08 52 53 54 5F 48 45 52 45 00
+92 42 C4 1D 0C 18 92 42 C6 1D 0E 18 DF 3F B2 40
+4C D0 AE D0 B2 40 8E C6 A4 C6 B2 40 D0 C6 E4 C6
+B2 40 DC C5 EA C5 30 41 50 CE 04 57 49 50 45 00
+39 40 80 FF B9 43 00 00 29 53 39 90 CE FF FA 23
+B0 12 FE CF B2 40 4C D9 C4 1D B2 40 02 D2 C6 1D
+D7 3F C4 CD 06 28 57 41 52 4D 29 00 1E 42 08 18
+87 12 42 C7 05 0D 1B 5B 37 6D 26 C7 70 C5 42 C7
+27 20 46 61 73 74 46 6F 72 74 68 20 56 31 36 30
+20 2E 35 4D 48 7A 20 28 43 29 20 4A 2E 4D 2E 54
+68 6F 6F 72 65 6E 73 20 26 C7 34 C2 30 FF 84 C5
+2A C3 30 C5 42 C7 0B 62 79 74 65 73 20 66 72 65
+65 20 28 CB 1A D0 04 57 41 52 4D 00 30 40 4C D0
+16 CE 04 43 4F 4C 44 00 B2 40 04 A5 20 01 92 D3
+30 01 B2 40 88 5A 5C 01 F2 D0 10 00 16 02 B2 D0
+00 80 04 02 B2 40 FF 7F 02 02 B2 D0 FF 7F 06 02
+F2 D0 07 00 36 02 B2 D0 F0 00 04 02 B2 40 0F FF
+02 02 B2 D0 0F FF 06 02 F2 D0 0F 00 24 03 F2 40
+F0 00 22 03 F2 D0 F0 00 26 03 F2 40 A5 00 61 01
+B2 40 44 00 66 01 29 42 B2 40 33 00 64 01 D2 43
+61 01 92 D2 9E 01 08 18 A2 93 08 18 01 24 59 07
+38 40 C2 A2 18 83 FE 23 19 83 FA 23 B2 D2 B0 01
+92 C3 B0 01 F2 D0 10 00 2A 03 F2 C0 40 00 A1 04
+3A 40 BE D0 39 40 CE FF 89 4A 00 00 29 53 FC 23
+92 42 02 18 F0 FF B2 40 18 00 0A 18 31 40 E0 1C
+3F 40 80 1C 37 40 00 C2 36 40 B4 C2 35 40 08 C2
+34 40 14 C2 B2 40 0A 00 DA 1D B2 43 DC 1D 92 C3
+30 01 18 42 08 18 D2 B3 01 02 04 20 38 E3 18 53
+82 48 08 18 B2 40 81 00 C0 05 A2 42 C6 05 B2 40
+00 49 C8 05 F2 D0 03 00 0D 02 92 C3 C0 05 92 D3
+DA 05 3D 40 DC D1 18 42 08 18 38 90 0A 00 28 27
+38 90 16 00 25 2F 28 93 FE 22 E6 26 AC D0 84 12
+44 CF 2A D8 D6 D8 DE D7 2A D9 A4 D7 5E D8 A8 D4
+00 00 9A D7 4A D8 FC D7 3A D8 B8 D5 00 00 00 00
+3C D9 70 CF 44 D0 85 48 49 32 4C 4F 87 12 84 C5
+DC CD A4 C9 AC CC 72 CF DE D1 2A C2 B2 D0 04 43
+4F 44 45 00 B0 12 BE CB A2 82 C4 1D 87 12 EC CC
+BC C3 16 D2 42 CE 03 41 53 4D 92 42 C8 1D B8 1D
+B2 40 E2 D1 C8 1D EE 3F 00 00 07 45 4E 44 43 4F
+44 45 87 12 80 CF 0C CC 2A C2 4A D2 06 45 4E 44
+41 53 4D 00 92 42 B8 1D C8 1D F3 3F 00 00 05 43
+4F 4C 4F 4E 1A 42 C4 1D BA 40 87 12 00 00 A2 53
+C4 1D B2 43 B6 1D 30 40 80 CF 00 00 05 4C 4F 32
+48 49 1A 42 C4 1D BA 40 B0 12 00 00 BA 40 2A C2
+02 00 A2 52 C4 1D ED 3F 38 40 BE 1D 39 48 2A 48
+09 5A 1A 52 C2 1D 09 9A 03 24 7E 9A FC 27 1A 83
+0E 4A 2A 88 82 4A C2 1D 30 4D B0 12 2A C2 9C C7
+F4 C7 72 C3 C0 C3 E0 D2 B0 C8 C0 C3 B0 CB 02 D3
+E2 D2 29 4E 39 90 86 12 02 20 2E 53 30 41 39 90
+85 12 03 20 1E 4E 02 00 30 41 39 90 84 12 01 20
+2E 52 30 41 19 42 C4 1D A2 53 C4 1D 89 4E 00 00
+3E 40 29 00 12 12 C2 1D 92 53 C2 1D B0 12 2A C2
+9C C7 B0 C8 C0 C3 34 D3 2A D3 21 53 3E 90 10 00
+BB 2D 30 41 36 D3 B2 41 C2 1D 22 D3 30 41 87 12
+4C C4 A8 D2 46 D3 82 43 BC 1D 92 42 C4 1D BA 1D
+A2 53 C4 1D 0A 4E 3E 4F FA 90 23 00 00 00 34 20
+92 53 C2 1D B0 12 CA D2 0E 93 04 20 B2 40 00 03
+BC 1D 27 3C 1E 93 04 20 B2 40 10 03 BC 1D 21 3C
+2E 93 04 20 B2 40 20 03 BC 1D 1B 3C 2E 92 04 20
+B2 40 20 02 BC 1D 15 3C 3E 92 04 20 B2 40 30 02
+BC 1D 0F 3C 3E 93 04 20 B2 40 30 03 BC 1D 09 3C
+B2 40 30 00 BC 1D 19 42 C4 1D A2 53 C4 1D 89 4E
+00 00 3E 4F 3D 41 30 4D FA 90 26 00 00 00 08 20
+B2 40 10 02 BC 1D 92 53 C2 1D 30 12 B6 D3 75 3F
+FA 90 40 00 00 00 1A 20 B2 40 20 00 BC 1D 92 53
+C2 1D B0 12 14 D3 0E 20 B2 50 10 00 BC 1D 3E 40
+2B 00 B0 12 14 D3 32 24 92 92 BE 1D C2 1D 02 24
+92 53 C2 1D 8E 10 82 5E BC 1D D3 3F B0 12 14 D3
+F9 23 B2 50 10 00 BC 1D 3E 40 28 00 B0 12 CA D2
+30 12 06 D4 67 3F 87 12 4C C4 A8 D2 3E D4 FE 90
+26 00 00 00 3E 40 20 00 04 20 B2 50 82 00 BC 1D
+C2 3F B0 12 14 D3 DF 23 B2 50 80 00 BC 1D 3E 40
+28 00 B0 12 CA D2 B0 12 04 D3 D5 23 3D 40 B0 CB
+30 4D 00 00 04 52 45 54 49 00 87 12 34 C2 00 13
+A4 C9 2A C2 34 C2 2C 00 3E D3 36 D4 8E D4 2E 4E
+1E D2 BC 1D 19 42 BA 1D 92 3F 8C D2 03 4D 4F 56
+84 12 84 D4 00 40 9C D4 05 4D 4F 56 2E 42 84 12
+84 D4 40 40 00 00 03 41 44 44 84 12 84 D4 00 50
+B6 D4 05 41 44 44 2E 42 84 12 84 D4 40 50 C2 D4
+04 41 44 44 43 00 84 12 84 D4 00 60 D0 D4 06 41
+44 44 43 2E 42 00 84 12 84 D4 40 60 74 D4 04 53
+55 42 43 00 84 12 84 D4 00 70 EE D4 06 53 55 42
+43 2E 42 00 84 12 84 D4 40 70 FC D4 03 53 55 42
+84 12 84 D4 00 80 0C D5 05 53 55 42 2E 42 84 12
+84 D4 40 80 6E D2 03 43 4D 50 84 12 84 D4 00 90
+26 D5 05 43 4D 50 2E 42 84 12 84 D4 40 90 5C D2
+04 44 41 44 44 00 84 12 84 D4 00 A0 40 D5 06 44
+41 44 44 2E 42 00 84 12 84 D4 40 A0 32 D5 03 42
+49 54 84 12 84 D4 00 B0 5E D5 05 42 49 54 2E 42
+84 12 84 D4 40 B0 6A D5 03 42 49 43 84 12 84 D4
+00 C0 78 D5 05 42 49 43 2E 42 84 12 84 D4 40 C0
+84 D5 03 42 49 53 84 12 84 D4 00 D0 92 D5 05 42
+49 53 2E 42 84 12 84 D4 40 D0 00 00 03 58 4F 52
+84 12 84 D4 00 E0 AC D5 05 58 4F 52 2E 42 84 12
+84 D4 40 E0 DE D4 03 41 4E 44 84 12 84 D4 00 F0
+C6 D5 05 41 4E 44 2E 42 84 12 84 D4 40 F0 4C C4
+3E D3 E4 D5 1A 42 BC 1D B2 F0 70 00 BC 1D 8A 10
+3A F0 0F 00 82 DA BC 1D 4A 3F 18 D5 03 52 52 43
+84 12 DE D5 00 10 FC D5 05 52 52 43 2E 42 84 12
+DE D5 40 10 08 D6 04 53 57 50 42 00 84 12 DE D5
+80 10 16 D6 03 52 52 41 84 12 DE D5 00 11 24 D6
+05 52 52 41 2E 42 84 12 DE D5 40 11 30 D6 03 53
+58 54 84 12 DE D5 80 11 00 00 04 50 55 53 48 00
+84 12 DE D5 00 12 4A D6 06 50 55 53 48 2E 42 00
+84 12 DE D5 40 12 9E D5 04 43 41 4C 4C 00 84 12
+DE D5 80 12 34 C2 2C 00 3E D3 36 D4 7E D6 59 42
+BC 1D 5A 42 BD 1D 82 4A BC 1D BE 90 00 15 00 00
+02 20 0A 89 02 3C 09 8A 0A 49 3A 90 10 00 03 2C
+5A 0E A8 3F 1A 53 0E 4A 87 12 70 C5 42 C7 0D 6F
+75 74 20 6F 66 20 62 6F 75 6E 64 73 22 CB 58 D6
+05 50 55 53 48 4D 84 12 74 D6 00 15 C0 D6 04 50
+4F 50 4D 00 84 12 74 D6 00 17 4C C4 A8 D2 E0 D6
+82 43 BC 1D 92 42 C4 1D BA 1D A2 53 C4 1D 92 53
+C2 1D 3E 40 2C 00 B0 12 2A C2 9C C7 B0 C8 C0 C3
+B0 CB 36 D4 06 D7 0A 4E 3E 4F 1A 83 2A 92 CA 2F
+8A 10 5A 06 6F 3F 3E D6 04 52 52 43 4D 00 84 12
+DA D6 50 00 18 D7 04 52 52 41 4D 00 84 12 DA D6
+50 01 26 D7 04 52 4C 41 4D 00 84 12 DA D6 50 02
+34 D7 04 52 52 55 4D 00 84 12 DA D6 50 03 85 12
+00 3C 42 D7 03 53 3E 3D 85 12 00 38 54 D7 02 53
+3C 00 85 12 00 34 CE D6 03 30 3E 3D 85 12 00 30
+68 D7 02 30 3C 00 85 12 00 30 00 00 02 55 3C 00
+85 12 00 2C 7C D7 03 55 3E 3D 85 12 00 28 72 D7
+03 30 3C 3E 85 12 00 24 90 D7 02 30 3D 00 85 12
+00 20 00 00 02 49 46 00 1A 42 C4 1D 8A 4E 00 00
+A2 53 C4 1D 0E 4A 30 4D 86 D7 04 54 48 45 4E 00
+1A 42 C4 1D 08 4E 3E 4F 09 48 29 53 0A 89 0A 11
+3A 90 00 02 68 2F 88 DA 00 00 30 4D 4E D5 04 45
+4C 53 45 00 1A 42 C4 1D BA 40 00 3C 00 00 A2 53
+C4 1D 2F 83 8F 4A 00 00 E3 3F BA D7 05 55 4E 54
+49 4C 3A 4F 08 4E 3E 4F 19 42 C4 1D 2A 83 0A 89
+0A 11 3A 90 00 FE 47 3B 3A F0 FF 03 08 DA 89 48
+00 00 A2 53 C4 1D 30 4D D2 D5 05 41 47 41 49 4E
+87 12 4E D7 02 D8 2A C2 00 00 05 57 48 49 4C 45
+87 12 A8 D7 6E C2 2A C2 5E D7 06 52 45 50 45 41
+54 00 87 12 4E D7 02 D8 C0 D7 2A C2 00 00 03 4A
+4D 50 87 12 A2 CB 4E D7 02 D8 2A C2 3E B0 00 10
+03 20 3E E0 00 04 30 4D 3E 90 00 34 06 28 03 24
+3E 40 00 34 30 4D 3E 40 00 38 30 4D 00 00 04 3F
+4A 4D 50 00 87 12 6C D8 A2 CB 6E C2 02 D8 2A C2
+A2 D8 3D 41 08 4E 3E 4F 2A 48 0A 93 04 20 98 42
+C4 1D 00 00 30 4D 88 43 00 00 A4 3F 68 D6 03 42
+57 31 84 12 A0 D8 00 00 BE D8 03 42 57 32 84 12
+A0 D8 00 00 CA D8 03 42 57 33 84 12 A0 D8 00 00
+E2 D8 3D 41 1A 42 C4 1D 28 4E 08 93 08 20 BA 4F
+00 00 A2 53 C4 1D 8E 4A 00 00 3E 4F 30 4D 8E 43
+00 00 61 3F 00 00 03 46 57 31 84 12 E0 D8 00 00
+06 D9 03 46 57 32 84 12 E0 D8 00 00 12 D9 03 46
+57 33 84 12 E0 D8 00 00 1E D9 04 47 4F 54 4F 00
+87 12 4E D7 A2 CB 9A C9 2A C2 8E D8 05 3F 47 4F
+54 4F 87 12 6C D8 A2 CB 9A C9 2A C2
+@FFCE
+BE D0 BE D0 BE D0 BE D0 BE D0 BE D0 BE D0 BE D0
+BE D0 BE D0 BE D0 BE D0 BE D0 BE D0 BE D0 BE D0
+BE D0 40 C6 BE D0 BE D0 BE D0 BE D0 BE D0 BE D0
+BE D0
+q
--- /dev/null
+@1800
+10 00 40 C6 C0 5D 60 EA FD FF 18 00 50 D9 06 D2
+2A C6 32 C6 00 00 00 00
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@C200
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 C2
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 C2 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 C2 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E C2 02 3E 52 00 0E 12 3E 4F 30 4D 8E C2
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 C2
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C C2 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 C2 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 C3
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 C2 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA C2 03 41 4E 44 3E FF 30 4D 7A C2 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E C3 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 C3 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E C3 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 C3 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 C2 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE C3 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 C3 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 C3 03 3E 49 4E 85 12 C2 1D 10 C3
+04 42 41 53 45 00 85 12 DA 1D C0 C2 05 53 54 41
+54 45 85 12 B6 1D 30 C4 02 42 4C 00 85 12 20 00
+94 C3 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 C4 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E C4 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 C4 02 23 53 00 87 12 98 C4
+D2 C4 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 C4 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 C4 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C C4 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 C3 03 55 44 2E 87 12 56 C4
+CC C4 E6 C4 26 C7 EE C6 2A C2 18 C5 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA C2
+02 44 2E 00 87 12 56 C4 6E C2 80 C2 3A C5 CC C4
+92 C2 0A C5 E6 C4 26 C7 EE C6 2A C2 52 C3 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 C4 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 C3 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 C4 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A C6
+92 B3 DC 05 FD 27 1E 42 CC 05 B0 12 32 C6 30 4D
+30 40 B6 C5 7E C5 05 28 4B 45 59 29 18 42 CC 05
+EA 3F 12 C4 03 4B 45 59 30 40 DC C5 92 C5 06 41
+43 43 45 50 54 00 3C 40 78 C6 3B 40 48 C6 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+6C C6 92 B3 DC 05 05 24 18 42 CC 05 38 90 0A 00
+04 20 21 53 39 40 3A C6 4D 15 B2 40 11 00 CE 05
+30 41 B2 40 13 00 CE 05 30 41 12 D2 0A 18 FD 3F
+21 52 3A 17 58 42 CC 05 48 9B F3 27 48 9C 06 2C
+78 92 0E 20 2E 9F 0C 24 1E 83 05 3C 0E 9A 03 24
+CE 48 00 00 1E 53 82 48 CE 05 30 4D 6E C6 2D 83
+92 B3 DC 05 FD 27 E6 23 B2 40 18 00 0A 18 3E 8F
+3D 41 30 4D D6 C5 06 28 45 4D 49 54 29 00 08 4E
+3E 4F A2 B3 DC 05 FD 27 E6 3F 50 C5 04 45 4D 49
+54 00 30 40 8E C6 9C C6 04 45 43 48 4F 00 B2 40
+82 48 66 C6 30 4D 6E C5 06 4E 4F 45 43 48 4F 00
+B2 40 30 4D 66 C6 30 4D 86 C6 04 28 43 52 29 00
+2F 83 8F 4E 00 00 3E 40 0D 00 E3 3F A2 C5 02 43
+52 00 30 40 D0 C6 04 C5 05 53 50 41 43 45 2F 83
+8F 4E 00 00 3E 40 20 00 D4 3F E8 C6 06 53 50 41
+43 45 53 00 0E 93 09 24 0D 12 3D 40 10 C7 EF 3F
+12 C7 2D 83 1E 83 EB 23 3D 41 3E 4F 30 4D 2C C5
+04 54 59 50 45 00 0E 93 95 24 2A 4F 8F 5E 00 00
+0E 4A 87 12 CA C3 02 C4 0A C3 A2 C6 EC C3 36 C7
+2A C2 2F 82 8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E
+1D B3 0D 63 30 4D FC C6 82 53 22 00 87 12 34 C2
+42 C7 A4 C9 34 C2 22 00 9C C7 6C C7 3D 41 6E 4E
+1E 83 82 5E C4 1D 3E 4F 92 B3 C4 1D A2 63 C4 1D
+30 4D B8 C6 82 2E 22 00 87 12 5C C7 34 C2 26 C7
+A4 C9 2A C2 00 00 04 57 4F 52 44 00 3C 40 BE 1D
+39 4C 3A 4C 09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A
+FC 27 1A 83 3B 40 60 00 C8 4C 00 00 09 9A 0C 24
+7C 4A 4E 9C 09 24 18 53 4B 9C F6 2F 7C 90 7B 00
+F3 2F 7C 80 20 00 F0 3F 1A 82 C0 1D 82 4A C2 1D
+1E 42 C4 1D 08 8E CE 48 00 00 30 4D 00 00 04 46
+49 4E 44 00 2F 83 0C 4E 65 4C 74 40 80 00 3B 40
+CA 1D 3E 4B 0E 93 1E 24 58 4C 01 00 78 F0 1E 00
+0E 58 2E 53 1E 4E FE FF 0E 93 F3 27 09 4E 78 49
+48 C4 48 95 F7 23 0A 4C 1A 53 FA 99 00 00 F2 23
+58 83 FA 23 19 B3 09 63 0C 49 6A 4E 1E 43 4A 93
+01 30 2E 83 8F 4C 00 00 35 40 08 C2 34 40 14 C2
+30 4D 2F 53 2F 53 3E 4F 30 4D 26 C4 07 3E 4E 55
+4D 42 45 52 3C 4F 38 4F 29 4F 2F 82 1B 42 DA 1D
+6A 4C 7A 80 30 00 7A 90 0A 00 02 28 7A 80 07 00
+0A 9B 13 2C 82 49 D0 04 82 48 D2 04 82 4B C8 04
+19 42 E4 04 18 42 E6 04 09 5A 08 63 1C 53 1E 83
+E7 23 8F 49 04 00 8F 48 02 00 8F 4C 00 00 30 4D
+03 12 0D 12 1B 42 DA 1D 0B 12 32 C0 00 02 6D 4E
+0D 5E 0C 4E 7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23
+32 D0 00 02 FC 4C FE FF 0D 9C FC 2F DE 83 00 00
+09 43 08 43 3D 40 26 C9 3F 82 8F 4E 06 00 0C 4E
+7E 4C 6A 4C 7A 90 2D 00 10 2C 3B 40 10 00 7A 80
+24 00 06 24 2B 43 5A 83 03 24 3B 52 6A 53 B0 23
+1C 53 1E 83 6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83
+B1 43 04 00 A5 3F 28 C9 2F 53 0E 93 2C 17 82 4C
+DA 1D 03 24 2F 52 0E F3 30 4D 8F 93 00 00 15 20
+32 B0 00 02 14 20 0E 93 05 24 1A 4F 02 00 1A 83
+0A 93 0B 38 2F 53 BF 4F 00 00 3E E3 05 20 BF E3
+00 00 9F 53 00 00 3E E3 30 4D 32 D0 00 02 9F 4F
+02 00 04 00 BF 4F 00 00 3E E3 F6 23 BF E3 02 00
+BF E3 00 00 9F 53 02 00 8F 63 00 00 3E E3 30 4D
+A8 C6 07 45 58 45 43 55 54 45 0A 4E 3E 4F 00 4A
+28 C3 01 2C 1A 42 C4 1D A2 53 C4 1D 8A 4E 00 00
+3E 4F 30 4D A2 C9 87 4C 49 54 45 52 41 4C 82 93
+B6 1D 16 24 32 B0 00 02 09 24 1A 42 C4 1D A2 52
+C4 1D BA 40 34 C2 00 00 BA 4F 02 00 1A 42 C4 1D
+A2 52 C4 1D BA 40 34 C2 00 00 8A 4E 02 00 3E 4F
+30 4D DE C6 05 43 4F 55 4E 54 2F 83 1E 53 8F 4E
+00 00 5E 4E FF FF 30 4D 82 4E BE 1D B2 4F C0 1D
+3E 4F 82 43 C2 1D 87 12 4C C4 9C C7 1E CA 3D 40
+2A CA E8 22 3D 41 3E 4F 30 4D 2C CA 0A 4E 3E 4F
+3D 40 42 CA 3D 27 3D 40 18 CA 1A E2 B6 1D B2 27
+AC 23 44 CA 3E 4F 3D 40 18 CA B9 23 DE 53 00 00
+68 4E 08 5E F8 40 3F 00 00 00 3D 40 0A CC CD 3F
+92 C9 08 45 56 41 4C 55 41 54 45 00 39 40 BE 1D
+39 12 39 12 39 12 0D 12 B0 12 2A C2 08 CA 80 CA
+3D 41 B2 41 C2 1D B2 41 C0 1D B2 41 BE 1D 30 4D
+7A C3 04 51 55 49 54 00 31 40 E0 1C B2 40 00 1C
+AC 1D 82 43 B6 1D 82 43 08 18 B0 12 2A C2 42 C7
+04 0D 6F 6B 20 00 26 C7 34 C2 38 1D 44 C2 34 C2
+50 00 F6 C5 EE C6 08 CA 34 C2 7E 1C CE C2 B2 C3
+42 C7 0D 73 74 61 63 6B 20 65 6D 70 74 79 20 21
+1C CB 34 C2 30 FF 84 C5 B2 C3 42 C7 0B 46 52 41
+4D 20 66 75 6C 6C 20 21 1C CB 42 C4 F4 C2 C0 C3
+AE CA 42 C7 04 0D 20 20 20 00 BC C3 B6 CA EE C5
+05 41 42 4F 52 54 3F 40 80 1C BE 3F 8F 93 02 00
+98 26 B2 40 82 48 66 C6 B0 12 04 D0 82 43 CA D8
+82 43 D6 D8 82 43 E2 D8 82 43 12 D9 82 43 1E D9
+82 43 2A D9 A2 B3 DC 05 FD 27 B2 40 11 00 CE 05
+92 C3 DC 05 38 40 F0 FF 39 42 19 83 FE 23 18 83
+FB 23 92 B3 DC 05 F4 23 87 12 42 C7 04 1B 5B 37
+6D 00 26 C7 26 C7 42 C7 04 1B 5B 30 6D 00 26 C7
+4C CF 8E CF 94 CF 16 CB 10 CB 86 41 42 4F 52 54
+22 00 87 12 5C C7 34 C2 1C CB A4 C9 2A C2 EE C7
+01 27 87 12 4C C4 9C C7 F4 C7 C0 C3 B0 CB 2A C2
+4C CA 52 C4 81 5C 92 42 BE 1D C2 1D 30 4D 87 12
+78 C7 4C C4 9C C7 C8 CB 08 4E 7A 4E 5A D3 5A 53
+0A 58 19 42 C8 1D 6E 4E 3E F0 1E 00 09 5E 82 48
+AE 1D 82 49 B0 1D 82 4A B2 1D 2A 52 82 4A C4 1D
+3E 4F 3D 41 30 41 87 12 42 C7 0F 73 74 61 63 6B
+20 6D 69 73 6D 61 74 63 68 21 22 CB 82 9F B4 1D
+F2 23 18 42 AE 1D 19 42 B0 1D A8 49 FE FF 89 48
+00 00 30 4D 96 C7 08 56 41 52 49 41 42 4C 45 00
+B0 12 BE CB BA 40 86 12 FC FF EF 3F F4 C9 08 43
+4F 4E 53 54 41 4E 54 00 B0 12 BE CB BA 40 85 12
+FC FF 8A 4E FE FF 3E 4F E0 3F 3E CC 06 43 52 45
+41 54 45 00 B0 12 BE CB BA 40 85 12 FC FF 8A 4A
+FE FF D3 3F 62 CA 05 44 4F 45 53 3E 1A 42 B2 1D
+BA 40 84 12 00 00 8A 4D 02 00 3D 41 30 4D 76 CC
+05 44 45 46 45 52 B0 12 BE CB BA 40 30 40 FC FF
+BA 40 8C CC FE FF B9 3F 00 00 81 5B 82 43 B6 1D
+30 4D B4 CB 01 5D B2 43 B6 1D 30 4D 58 C7 87 52
+45 43 55 52 53 45 19 42 C4 1D 99 42 B2 1D 00 00
+A2 53 C4 1D 30 4D AA CC 01 3A B0 12 BE CB BA 40
+87 12 FC FF A2 83 C4 1D B2 43 B6 1D 82 4F B4 1D
+30 4D D8 CC 81 3B 82 93 B6 1D 5D 27 87 12 34 C2
+2A C2 A4 C9 0C CC AC CC 2A C2 CA C6 09 49 4D 4D
+45 44 49 41 54 45 1A 42 AE 1D FA D0 80 00 00 00
+30 4D BE 4F 02 00 3E 4F 30 4D 0C CD 82 49 53 00
+87 12 42 C4 F4 C2 C0 C3 44 CD 50 CD 34 C2 22 CD
+A4 C9 2A C2 A2 CB 22 CD 2A C2 F4 CC 83 5B 27 5D
+87 12 A2 CB 34 C2 34 C2 A4 C9 A4 C9 2A C2 92 CA
+88 50 4F 53 54 50 4F 4E 45 00 87 12 4C C4 9C C7
+F4 C7 54 C2 C0 C3 B0 CB 7E C3 C0 C3 8A CD 34 C2
+34 C2 A4 C9 A4 C9 34 C2 A4 C9 A4 C9 2A C2 90 CD
+3A 4E 82 4A C6 1D 2E 4E 82 4E C4 1D 3D 40 10 00
+09 4A 08 49 29 83 18 48 FE FF 0E 98 FC 2B 89 48
+00 00 1D 83 F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41
+30 4D 2C CD 82 49 46 00 2F 83 8F 4E 00 00 1E 42
+C4 1D BE 40 C0 C3 00 00 A2 52 C4 1D 2E 53 30 4D
+90 CC 84 45 4C 53 45 00 1A 42 C4 1D BA 40 BC C3
+00 00 2A 52 82 4A C4 1D 8E 4A 00 00 2A 83 0E 4A
+30 4D 20 C7 84 54 48 45 4E 00 9E 42 C4 1D 00 00
+3E 4F 30 4D 5C CC 85 42 45 47 49 4E 30 40 84 C5
+04 CE 85 55 4E 54 49 4C 39 40 C0 C3 1A 42 C4 1D
+A2 52 C4 1D 8A 49 00 00 8A 4E 02 00 3E 4F 30 4D
+8A CB 85 41 47 41 49 4E 39 40 BC C3 EF 3F 26 CC
+85 57 48 49 4C 45 87 12 C8 CD 6E C2 2A C2 BE CC
+86 52 45 50 45 41 54 00 87 12 48 CE 0A CE 2A C2
+E2 CD 82 44 4F 00 2F 83 8F 4E 00 00 1E 42 C4 1D
+BE 40 CA C3 00 00 2E 53 82 4E C4 1D A2 53 AC 1D
+1A 42 AC 1D 8A 43 00 00 30 4D B6 C9 84 4C 4F 4F
+50 00 39 40 EC C3 1A 42 C4 1D A2 52 C4 1D 8A 49
+00 00 8A 4E 02 00 1E 42 AC 1D A2 83 AC 1D 2E 4E
+0E 93 04 24 9E 42 C4 1D 00 00 F5 3F 3E 4F 30 4D
+E4 C5 85 2B 4C 4F 4F 50 39 40 DA C3 E4 3F 9C CE
+85 4C 45 41 56 45 1A 42 C4 1D BA 40 FC C3 00 00
+BA 40 BC C3 02 00 B2 50 06 00 C4 1D A2 53 AC 1D
+2A 52 19 42 AC 1D 89 4A 00 00 30 4D E0 CE 04 4D
+4F 56 45 00 0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24
+08 99 0F 24 06 2C F8 49 00 00 18 53 1A 83 FB 23
+30 4D 08 5A 09 5A 19 83 18 83 E8 49 00 00 1A 83
+FA 23 30 4D 34 C2 CA 1D FC C2 2A C2 84 12 44 CF
+3A D2 22 D2 72 CE A0 CB 0A D2 D2 CE 0E CF 84 C7
+B2 CF E6 CF 22 CE A6 D0 48 C3 4C CD B4 CC 5C C8
+00 00 3A 40 0C 00 39 40 CA 1D 38 40 CC 1D D9 3F
+3A 40 0E 00 39 40 CC 1D 38 40 CA 1D CC 3F 82 43
+CC 1D 30 4D 92 42 CA 1D C8 1D 30 4D 60 CD 09 50
+57 52 5F 53 54 41 54 45 84 12 8E CD 06 D2 50 D9
+9E CF 08 50 57 52 5F 48 45 52 45 00 92 42 C4 1D
+AE CF 92 42 C6 1D AC CF EF 3F 60 CE 09 52 53 54
+5F 53 54 41 54 45 92 42 0C 18 AE CF 92 42 0E 18
+AC CF E2 3F CC CF 08 52 53 54 5F 48 45 52 45 00
+92 42 C4 1D 0C 18 92 42 C6 1D 0E 18 DF 3F B2 40
+4C D0 AE D0 B2 40 8E C6 A4 C6 B2 40 D0 C6 E4 C6
+B2 40 DC C5 EA C5 30 41 50 CE 04 57 49 50 45 00
+39 40 80 FF B9 43 00 00 29 53 39 90 CE FF FA 23
+B0 12 FE CF B2 40 50 D9 C4 1D B2 40 06 D2 C6 1D
+D7 3F C4 CD 06 28 57 41 52 4D 29 00 1E 42 08 18
+87 12 42 C7 05 0D 1B 5B 37 6D 26 C7 70 C5 42 C7
+27 20 46 61 73 74 46 6F 72 74 68 20 56 31 36 30
+20 32 34 4D 48 7A 20 28 43 29 20 4A 2E 4D 2E 54
+68 6F 6F 72 65 6E 73 20 26 C7 34 C2 30 FF 84 C5
+2A C3 30 C5 42 C7 0B 62 79 74 65 73 20 66 72 65
+65 20 28 CB 1A D0 04 57 41 52 4D 00 30 40 4C D0
+16 CE 04 43 4F 4C 44 00 B2 40 04 A5 20 01 92 D3
+30 01 B2 40 88 5A 5C 01 F2 D0 10 00 16 02 B2 D0
+00 80 04 02 B2 40 FF 7F 02 02 B2 D0 FF 7F 06 02
+F2 D0 07 00 36 02 B2 D0 F0 00 04 02 B2 40 0F FF
+02 02 B2 D0 0F FF 06 02 F2 D0 0F 00 24 03 F2 40
+F0 00 22 03 F2 D0 F0 00 26 03 F2 40 A5 00 61 01
+B2 40 86 00 62 01 82 43 66 01 39 40 C0 00 B2 40
+33 00 64 01 D2 43 61 01 92 D2 9E 01 08 18 A2 93
+08 18 01 24 59 07 38 40 C2 A2 18 83 FE 23 19 83
+FA 23 B2 D2 B0 01 92 C3 B0 01 F2 D0 10 00 2A 03
+F2 C0 40 00 A1 04 3A 40 BE D0 39 40 CE FF 89 4A
+00 00 29 53 FC 23 92 42 02 18 F0 FF B2 40 18 00
+0A 18 31 40 E0 1C 3F 40 80 1C 37 40 00 C2 36 40
+B4 C2 35 40 08 C2 34 40 14 C2 B2 40 0A 00 DA 1D
+B2 43 DC 1D 92 C3 30 01 18 42 08 18 D2 B3 01 02
+04 20 38 E3 18 53 82 48 08 18 B2 40 81 00 C0 05
+A2 42 C6 05 82 43 C8 05 F2 D0 03 00 0D 02 92 C3
+C0 05 92 D3 DA 05 3D 40 E0 D1 18 42 08 18 38 90
+0A 00 26 27 38 90 16 00 23 2F 28 93 FC 22 E4 26
+AC D0 84 12 44 CF 2E D8 DA D8 E2 D7 2E D9 A8 D7
+62 D8 AC D4 00 00 9E D7 4E D8 00 D8 3E D8 BC D5
+00 00 00 00 40 D9 70 CF 44 D0 85 48 49 32 4C 4F
+87 12 84 C5 DC CD A4 C9 AC CC 72 CF E2 D1 2A C2
+B2 D0 04 43 4F 44 45 00 B0 12 BE CB A2 82 C4 1D
+87 12 EC CC BC C3 1A D2 42 CE 03 41 53 4D 92 42
+C8 1D B8 1D B2 40 E6 D1 C8 1D EE 3F 00 00 07 45
+4E 44 43 4F 44 45 87 12 80 CF 0C CC 2A C2 4E D2
+06 45 4E 44 41 53 4D 00 92 42 B8 1D C8 1D F3 3F
+00 00 05 43 4F 4C 4F 4E 1A 42 C4 1D BA 40 87 12
+00 00 A2 53 C4 1D B2 43 B6 1D 30 40 80 CF 00 00
+05 4C 4F 32 48 49 1A 42 C4 1D BA 40 B0 12 00 00
+BA 40 2A C2 02 00 A2 52 C4 1D ED 3F 38 40 BE 1D
+39 48 2A 48 09 5A 1A 52 C2 1D 09 9A 03 24 7E 9A
+FC 27 1A 83 0E 4A 2A 88 82 4A C2 1D 30 4D B0 12
+2A C2 9C C7 F4 C7 72 C3 C0 C3 E4 D2 B0 C8 C0 C3
+B0 CB 06 D3 E6 D2 29 4E 39 90 86 12 02 20 2E 53
+30 41 39 90 85 12 03 20 1E 4E 02 00 30 41 39 90
+84 12 01 20 2E 52 30 41 19 42 C4 1D A2 53 C4 1D
+89 4E 00 00 3E 40 29 00 12 12 C2 1D 92 53 C2 1D
+B0 12 2A C2 9C C7 B0 C8 C0 C3 38 D3 2E D3 21 53
+3E 90 10 00 BB 2D 30 41 3A D3 B2 41 C2 1D 22 D3
+30 41 87 12 4C C4 AC D2 4A D3 82 43 BC 1D 92 42
+C4 1D BA 1D A2 53 C4 1D 0A 4E 3E 4F FA 90 23 00
+00 00 34 20 92 53 C2 1D B0 12 CE D2 0E 93 04 20
+B2 40 00 03 BC 1D 27 3C 1E 93 04 20 B2 40 10 03
+BC 1D 21 3C 2E 93 04 20 B2 40 20 03 BC 1D 1B 3C
+2E 92 04 20 B2 40 20 02 BC 1D 15 3C 3E 92 04 20
+B2 40 30 02 BC 1D 0F 3C 3E 93 04 20 B2 40 30 03
+BC 1D 09 3C B2 40 30 00 BC 1D 19 42 C4 1D A2 53
+C4 1D 89 4E 00 00 3E 4F 3D 41 30 4D FA 90 26 00
+00 00 08 20 B2 40 10 02 BC 1D 92 53 C2 1D 30 12
+BA D3 75 3F FA 90 40 00 00 00 1A 20 B2 40 20 00
+BC 1D 92 53 C2 1D B0 12 18 D3 0E 20 B2 50 10 00
+BC 1D 3E 40 2B 00 B0 12 18 D3 32 24 92 92 BE 1D
+C2 1D 02 24 92 53 C2 1D 8E 10 82 5E BC 1D D3 3F
+B0 12 18 D3 F9 23 B2 50 10 00 BC 1D 3E 40 28 00
+B0 12 CE D2 30 12 0A D4 67 3F 87 12 4C C4 AC D2
+42 D4 FE 90 26 00 00 00 3E 40 20 00 04 20 B2 50
+82 00 BC 1D C2 3F B0 12 18 D3 DF 23 B2 50 80 00
+BC 1D 3E 40 28 00 B0 12 CE D2 B0 12 08 D3 D5 23
+3D 40 B0 CB 30 4D 00 00 04 52 45 54 49 00 87 12
+34 C2 00 13 A4 C9 2A C2 34 C2 2C 00 42 D3 3A D4
+92 D4 2E 4E 1E D2 BC 1D 19 42 BA 1D 92 3F 90 D2
+03 4D 4F 56 84 12 88 D4 00 40 A0 D4 05 4D 4F 56
+2E 42 84 12 88 D4 40 40 00 00 03 41 44 44 84 12
+88 D4 00 50 BA D4 05 41 44 44 2E 42 84 12 88 D4
+40 50 C6 D4 04 41 44 44 43 00 84 12 88 D4 00 60
+D4 D4 06 41 44 44 43 2E 42 00 84 12 88 D4 40 60
+78 D4 04 53 55 42 43 00 84 12 88 D4 00 70 F2 D4
+06 53 55 42 43 2E 42 00 84 12 88 D4 40 70 00 D5
+03 53 55 42 84 12 88 D4 00 80 10 D5 05 53 55 42
+2E 42 84 12 88 D4 40 80 72 D2 03 43 4D 50 84 12
+88 D4 00 90 2A D5 05 43 4D 50 2E 42 84 12 88 D4
+40 90 60 D2 04 44 41 44 44 00 84 12 88 D4 00 A0
+44 D5 06 44 41 44 44 2E 42 00 84 12 88 D4 40 A0
+36 D5 03 42 49 54 84 12 88 D4 00 B0 62 D5 05 42
+49 54 2E 42 84 12 88 D4 40 B0 6E D5 03 42 49 43
+84 12 88 D4 00 C0 7C D5 05 42 49 43 2E 42 84 12
+88 D4 40 C0 88 D5 03 42 49 53 84 12 88 D4 00 D0
+96 D5 05 42 49 53 2E 42 84 12 88 D4 40 D0 00 00
+03 58 4F 52 84 12 88 D4 00 E0 B0 D5 05 58 4F 52
+2E 42 84 12 88 D4 40 E0 E2 D4 03 41 4E 44 84 12
+88 D4 00 F0 CA D5 05 41 4E 44 2E 42 84 12 88 D4
+40 F0 4C C4 42 D3 E8 D5 1A 42 BC 1D B2 F0 70 00
+BC 1D 8A 10 3A F0 0F 00 82 DA BC 1D 4A 3F 1C D5
+03 52 52 43 84 12 E2 D5 00 10 00 D6 05 52 52 43
+2E 42 84 12 E2 D5 40 10 0C D6 04 53 57 50 42 00
+84 12 E2 D5 80 10 1A D6 03 52 52 41 84 12 E2 D5
+00 11 28 D6 05 52 52 41 2E 42 84 12 E2 D5 40 11
+34 D6 03 53 58 54 84 12 E2 D5 80 11 00 00 04 50
+55 53 48 00 84 12 E2 D5 00 12 4E D6 06 50 55 53
+48 2E 42 00 84 12 E2 D5 40 12 A2 D5 04 43 41 4C
+4C 00 84 12 E2 D5 80 12 34 C2 2C 00 42 D3 3A D4
+82 D6 59 42 BC 1D 5A 42 BD 1D 82 4A BC 1D BE 90
+00 15 00 00 02 20 0A 89 02 3C 09 8A 0A 49 3A 90
+10 00 03 2C 5A 0E A8 3F 1A 53 0E 4A 87 12 70 C5
+42 C7 0D 6F 75 74 20 6F 66 20 62 6F 75 6E 64 73
+22 CB 5C D6 05 50 55 53 48 4D 84 12 78 D6 00 15
+C4 D6 04 50 4F 50 4D 00 84 12 78 D6 00 17 4C C4
+AC D2 E4 D6 82 43 BC 1D 92 42 C4 1D BA 1D A2 53
+C4 1D 92 53 C2 1D 3E 40 2C 00 B0 12 2A C2 9C C7
+B0 C8 C0 C3 B0 CB 3A D4 0A D7 0A 4E 3E 4F 1A 83
+2A 92 CA 2F 8A 10 5A 06 6F 3F 42 D6 04 52 52 43
+4D 00 84 12 DE D6 50 00 1C D7 04 52 52 41 4D 00
+84 12 DE D6 50 01 2A D7 04 52 4C 41 4D 00 84 12
+DE D6 50 02 38 D7 04 52 52 55 4D 00 84 12 DE D6
+50 03 85 12 00 3C 46 D7 03 53 3E 3D 85 12 00 38
+58 D7 02 53 3C 00 85 12 00 34 D2 D6 03 30 3E 3D
+85 12 00 30 6C D7 02 30 3C 00 85 12 00 30 00 00
+02 55 3C 00 85 12 00 2C 80 D7 03 55 3E 3D 85 12
+00 28 76 D7 03 30 3C 3E 85 12 00 24 94 D7 02 30
+3D 00 85 12 00 20 00 00 02 49 46 00 1A 42 C4 1D
+8A 4E 00 00 A2 53 C4 1D 0E 4A 30 4D 8A D7 04 54
+48 45 4E 00 1A 42 C4 1D 08 4E 3E 4F 09 48 29 53
+0A 89 0A 11 3A 90 00 02 68 2F 88 DA 00 00 30 4D
+52 D5 04 45 4C 53 45 00 1A 42 C4 1D BA 40 00 3C
+00 00 A2 53 C4 1D 2F 83 8F 4A 00 00 E3 3F BE D7
+05 55 4E 54 49 4C 3A 4F 08 4E 3E 4F 19 42 C4 1D
+2A 83 0A 89 0A 11 3A 90 00 FE 47 3B 3A F0 FF 03
+08 DA 89 48 00 00 A2 53 C4 1D 30 4D D6 D5 05 41
+47 41 49 4E 87 12 52 D7 06 D8 2A C2 00 00 05 57
+48 49 4C 45 87 12 AC D7 6E C2 2A C2 62 D7 06 52
+45 50 45 41 54 00 87 12 52 D7 06 D8 C4 D7 2A C2
+00 00 03 4A 4D 50 87 12 A2 CB 52 D7 06 D8 2A C2
+3E B0 00 10 03 20 3E E0 00 04 30 4D 3E 90 00 34
+06 28 03 24 3E 40 00 34 30 4D 3E 40 00 38 30 4D
+00 00 04 3F 4A 4D 50 00 87 12 70 D8 A2 CB 6E C2
+06 D8 2A C2 A6 D8 3D 41 08 4E 3E 4F 2A 48 0A 93
+04 20 98 42 C4 1D 00 00 30 4D 88 43 00 00 A4 3F
+6C D6 03 42 57 31 84 12 A4 D8 00 00 C2 D8 03 42
+57 32 84 12 A4 D8 00 00 CE D8 03 42 57 33 84 12
+A4 D8 00 00 E6 D8 3D 41 1A 42 C4 1D 28 4E 08 93
+08 20 BA 4F 00 00 A2 53 C4 1D 8E 4A 00 00 3E 4F
+30 4D 8E 43 00 00 61 3F 00 00 03 46 57 31 84 12
+E4 D8 00 00 0A D9 03 46 57 32 84 12 E4 D8 00 00
+16 D9 03 46 57 33 84 12 E4 D8 00 00 22 D9 04 47
+4F 54 4F 00 87 12 52 D7 A2 CB 9A C9 2A C2 92 D8
+05 3F 47 4F 54 4F 87 12 70 D8 A2 CB 9A C9 2A C2
+@FFCE
+BE D0 BE D0 BE D0 BE D0 BE D0 BE D0 BE D0 BE D0
+BE D0 BE D0 BE D0 BE D0 BE D0 BE D0 BE D0 BE D0
+BE D0 40 C6 BE D0 BE D0 BE D0 BE D0 BE D0 BE D0
+BE D0
+q
--- /dev/null
+@1800
+10 00 4C C6 C0 5D 00 24 FD FF 18 00 5E D9 14 D2
+2A C6 38 C6 00 00 00 00
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@C200
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 C2
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 C2 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 C2 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E C2 02 3E 52 00 0E 12 3E 4F 30 4D 8E C2
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 C2
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C C2 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 C2 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 C3
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 C2 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA C2 03 41 4E 44 3E FF 30 4D 7A C2 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E C3 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 C3 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E C3 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 C3 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 C2 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE C3 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 C3 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 C3 03 3E 49 4E 85 12 C2 1D 10 C3
+04 42 41 53 45 00 85 12 DA 1D C0 C2 05 53 54 41
+54 45 85 12 B6 1D 30 C4 02 42 4C 00 85 12 20 00
+94 C3 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 C4 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E C4 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 C4 02 23 53 00 87 12 98 C4
+D2 C4 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 C4 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 C4 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C C4 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 C3 03 55 44 2E 87 12 56 C4
+CC C4 E6 C4 32 C7 FA C6 2A C2 18 C5 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA C2
+02 44 2E 00 87 12 56 C4 6E C2 80 C2 3A C5 CC C4
+92 C2 0A C5 E6 C4 32 C7 FA C6 2A C2 52 C3 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 C4 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 C3 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 C4 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A C6
+92 B3 DC 05 FD 27 1E 42 CC 05 B0 12 38 C6 30 4D
+30 40 B6 C5 7E C5 05 28 4B 45 59 29 18 42 CC 05
+EA 3F 12 C4 03 4B 45 59 30 40 DC C5 92 C5 06 41
+43 43 45 50 54 00 3C 40 8A C6 3B 40 54 C6 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+7E C6 92 B3 DC 05 05 24 18 42 CC 05 38 90 0A 00
+04 20 21 53 39 40 46 C6 4D 15 B2 40 11 00 CE 05
+A2 B3 DC 05 FD 27 30 41 B2 40 13 00 CE 05 A2 B3
+DC 05 FD 27 30 41 12 D2 0A 18 FD 3F 21 52 3A 17
+58 42 CC 05 48 9B F0 27 48 9C 06 2C 78 92 11 20
+2E 9F 0F 24 1E 83 05 3C 0E 9A 03 24 CE 48 00 00
+1E 53 82 48 CE 05 A2 B3 DC 05 FD 27 30 4D 80 C6
+2D 83 92 B3 DC 05 FD 27 E3 23 B2 40 18 00 0A 18
+3E 8F 3D 41 30 4D D6 C5 06 28 45 4D 49 54 29 00
+08 4E 3E 4F E6 3F 50 C5 04 45 4D 49 54 00 30 40
+A0 C6 A8 C6 04 45 43 48 4F 00 B2 40 82 48 72 C6
+30 4D 6E C5 06 4E 4F 45 43 48 4F 00 B2 40 30 4D
+72 C6 30 4D 98 C6 04 28 43 52 29 00 2F 83 8F 4E
+00 00 3E 40 0D 00 E3 3F A2 C5 02 43 52 00 30 40
+DC C6 04 C5 05 53 50 41 43 45 2F 83 8F 4E 00 00
+3E 40 20 00 D4 3F F4 C6 06 53 50 41 43 45 53 00
+0E 93 09 24 0D 12 3D 40 1C C7 EF 3F 1E C7 2D 83
+1E 83 EB 23 3D 41 3E 4F 30 4D 2C C5 04 54 59 50
+45 00 0E 93 95 24 2A 4F 8F 5E 00 00 0E 4A 87 12
+CA C3 02 C4 0A C3 AE C6 EC C3 42 C7 2A C2 2F 82
+8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E 1D B3 0D 63
+30 4D 08 C7 82 53 22 00 87 12 34 C2 4E C7 B0 C9
+34 C2 22 00 A8 C7 78 C7 3D 41 6E 4E 1E 83 82 5E
+C4 1D 3E 4F 92 B3 C4 1D A2 63 C4 1D 30 4D C4 C6
+82 2E 22 00 87 12 68 C7 34 C2 32 C7 B0 C9 2A C2
+00 00 04 57 4F 52 44 00 3C 40 BE 1D 39 4C 3A 4C
+09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A FC 27 1A 83
+3B 40 60 00 C8 4C 00 00 09 9A 0C 24 7C 4A 4E 9C
+09 24 18 53 4B 9C F6 2F 7C 90 7B 00 F3 2F 7C 80
+20 00 F0 3F 1A 82 C0 1D 82 4A C2 1D 1E 42 C4 1D
+08 8E CE 48 00 00 30 4D 00 00 04 46 49 4E 44 00
+2F 83 0C 4E 65 4C 74 40 80 00 3B 40 CA 1D 3E 4B
+0E 93 1E 24 58 4C 01 00 78 F0 1E 00 0E 58 2E 53
+1E 4E FE FF 0E 93 F3 27 09 4E 78 49 48 C4 48 95
+F7 23 0A 4C 1A 53 FA 99 00 00 F2 23 58 83 FA 23
+19 B3 09 63 0C 49 6A 4E 1E 43 4A 93 01 30 2E 83
+8F 4C 00 00 35 40 08 C2 34 40 14 C2 30 4D 2F 53
+2F 53 3E 4F 30 4D 26 C4 07 3E 4E 55 4D 42 45 52
+3C 4F 38 4F 29 4F 2F 82 1B 42 DA 1D 6A 4C 7A 80
+30 00 7A 90 0A 00 02 28 7A 80 07 00 0A 9B 13 2C
+82 49 D0 04 82 48 D2 04 82 4B C8 04 19 42 E4 04
+18 42 E6 04 09 5A 08 63 1C 53 1E 83 E7 23 8F 49
+04 00 8F 48 02 00 8F 4C 00 00 30 4D 03 12 0D 12
+1B 42 DA 1D 0B 12 32 C0 00 02 6D 4E 0D 5E 0C 4E
+7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23 32 D0 00 02
+FC 4C FE FF 0D 9C FC 2F DE 83 00 00 09 43 08 43
+3D 40 32 C9 3F 82 8F 4E 06 00 0C 4E 7E 4C 6A 4C
+7A 90 2D 00 10 2C 3B 40 10 00 7A 80 24 00 06 24
+2B 43 5A 83 03 24 3B 52 6A 53 B0 23 1C 53 1E 83
+6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83 B1 43 04 00
+A5 3F 34 C9 2F 53 0E 93 2C 17 82 4C DA 1D 03 24
+2F 52 0E F3 30 4D 8F 93 00 00 15 20 32 B0 00 02
+14 20 0E 93 05 24 1A 4F 02 00 1A 83 0A 93 0B 38
+2F 53 BF 4F 00 00 3E E3 05 20 BF E3 00 00 9F 53
+00 00 3E E3 30 4D 32 D0 00 02 9F 4F 02 00 04 00
+BF 4F 00 00 3E E3 F6 23 BF E3 02 00 BF E3 00 00
+9F 53 02 00 8F 63 00 00 3E E3 30 4D B4 C6 07 45
+58 45 43 55 54 45 0A 4E 3E 4F 00 4A 28 C3 01 2C
+1A 42 C4 1D A2 53 C4 1D 8A 4E 00 00 3E 4F 30 4D
+AE C9 87 4C 49 54 45 52 41 4C 82 93 B6 1D 16 24
+32 B0 00 02 09 24 1A 42 C4 1D A2 52 C4 1D BA 40
+34 C2 00 00 BA 4F 02 00 1A 42 C4 1D A2 52 C4 1D
+BA 40 34 C2 00 00 8A 4E 02 00 3E 4F 30 4D EA C6
+05 43 4F 55 4E 54 2F 83 1E 53 8F 4E 00 00 5E 4E
+FF FF 30 4D 82 4E BE 1D B2 4F C0 1D 3E 4F 82 43
+C2 1D 87 12 4C C4 A8 C7 2A CA 3D 40 36 CA E8 22
+3D 41 3E 4F 30 4D 38 CA 0A 4E 3E 4F 3D 40 4E CA
+3D 27 3D 40 24 CA 1A E2 B6 1D B2 27 AC 23 50 CA
+3E 4F 3D 40 24 CA B9 23 DE 53 00 00 68 4E 08 5E
+F8 40 3F 00 00 00 3D 40 16 CC CD 3F 9E C9 08 45
+56 41 4C 55 41 54 45 00 39 40 BE 1D 39 12 39 12
+39 12 0D 12 B0 12 2A C2 14 CA 8C CA 3D 41 B2 41
+C2 1D B2 41 C0 1D B2 41 BE 1D 30 4D 7A C3 04 51
+55 49 54 00 31 40 E0 1C B2 40 00 1C AC 1D 82 43
+B6 1D 82 43 08 18 B0 12 2A C2 4E C7 04 0D 6F 6B
+20 00 32 C7 34 C2 38 1D 44 C2 34 C2 50 00 F6 C5
+FA C6 14 CA 34 C2 7E 1C CE C2 B2 C3 4E C7 0D 73
+74 61 63 6B 20 65 6D 70 74 79 20 21 28 CB 34 C2
+30 FF 84 C5 B2 C3 4E C7 0B 46 52 41 4D 20 66 75
+6C 6C 20 21 28 CB 42 C4 F4 C2 C0 C3 BA CA 4E C7
+04 0D 20 20 20 00 BC C3 C2 CA EE C5 05 41 42 4F
+52 54 3F 40 80 1C BE 3F 8F 93 02 00 98 26 B2 40
+82 48 72 C6 B0 12 10 D0 82 43 D8 D8 82 43 E4 D8
+82 43 F0 D8 82 43 20 D9 82 43 2C D9 82 43 38 D9
+A2 B3 DC 05 FD 27 B2 40 11 00 CE 05 92 C3 DC 05
+38 40 F0 FF 39 42 19 83 FE 23 18 83 FB 23 92 B3
+DC 05 F4 23 87 12 4E C7 04 1B 5B 37 6D 00 32 C7
+32 C7 4E C7 04 1B 5B 30 6D 00 32 C7 58 CF 9A CF
+A0 CF 22 CB 1C CB 86 41 42 4F 52 54 22 00 87 12
+68 C7 34 C2 28 CB B0 C9 2A C2 FA C7 01 27 87 12
+4C C4 A8 C7 00 C8 C0 C3 BC CB 2A C2 58 CA 52 C4
+81 5C 92 42 BE 1D C2 1D 30 4D 87 12 84 C7 4C C4
+A8 C7 D4 CB 08 4E 7A 4E 5A D3 5A 53 0A 58 19 42
+C8 1D 6E 4E 3E F0 1E 00 09 5E 82 48 AE 1D 82 49
+B0 1D 82 4A B2 1D 2A 52 82 4A C4 1D 3E 4F 3D 41
+30 41 87 12 4E C7 0F 73 74 61 63 6B 20 6D 69 73
+6D 61 74 63 68 21 2E CB 82 9F B4 1D F2 23 18 42
+AE 1D 19 42 B0 1D A8 49 FE FF 89 48 00 00 30 4D
+A2 C7 08 56 41 52 49 41 42 4C 45 00 B0 12 CA CB
+BA 40 86 12 FC FF EF 3F 00 CA 08 43 4F 4E 53 54
+41 4E 54 00 B0 12 CA CB BA 40 85 12 FC FF 8A 4E
+FE FF 3E 4F E0 3F 4A CC 06 43 52 45 41 54 45 00
+B0 12 CA CB BA 40 85 12 FC FF 8A 4A FE FF D3 3F
+6E CA 05 44 4F 45 53 3E 1A 42 B2 1D BA 40 84 12
+00 00 8A 4D 02 00 3D 41 30 4D 82 CC 05 44 45 46
+45 52 B0 12 CA CB BA 40 30 40 FC FF BA 40 98 CC
+FE FF B9 3F 00 00 81 5B 82 43 B6 1D 30 4D C0 CB
+01 5D B2 43 B6 1D 30 4D 64 C7 87 52 45 43 55 52
+53 45 19 42 C4 1D 99 42 B2 1D 00 00 A2 53 C4 1D
+30 4D B6 CC 01 3A B0 12 CA CB BA 40 87 12 FC FF
+A2 83 C4 1D B2 43 B6 1D 82 4F B4 1D 30 4D E4 CC
+81 3B 82 93 B6 1D 5D 27 87 12 34 C2 2A C2 B0 C9
+18 CC B8 CC 2A C2 D6 C6 09 49 4D 4D 45 44 49 41
+54 45 1A 42 AE 1D FA D0 80 00 00 00 30 4D BE 4F
+02 00 3E 4F 30 4D 18 CD 82 49 53 00 87 12 42 C4
+F4 C2 C0 C3 50 CD 5C CD 34 C2 2E CD B0 C9 2A C2
+AE CB 2E CD 2A C2 00 CD 83 5B 27 5D 87 12 AE CB
+34 C2 34 C2 B0 C9 B0 C9 2A C2 9E CA 88 50 4F 53
+54 50 4F 4E 45 00 87 12 4C C4 A8 C7 00 C8 54 C2
+C0 C3 BC CB 7E C3 C0 C3 96 CD 34 C2 34 C2 B0 C9
+B0 C9 34 C2 B0 C9 B0 C9 2A C2 9C CD 3A 4E 82 4A
+C6 1D 2E 4E 82 4E C4 1D 3D 40 10 00 09 4A 08 49
+29 83 18 48 FE FF 0E 98 FC 2B 89 48 00 00 1D 83
+F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41 30 4D 38 CD
+82 49 46 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40
+C0 C3 00 00 A2 52 C4 1D 2E 53 30 4D 9C CC 84 45
+4C 53 45 00 1A 42 C4 1D BA 40 BC C3 00 00 2A 52
+82 4A C4 1D 8E 4A 00 00 2A 83 0E 4A 30 4D 2C C7
+84 54 48 45 4E 00 9E 42 C4 1D 00 00 3E 4F 30 4D
+68 CC 85 42 45 47 49 4E 30 40 84 C5 10 CE 85 55
+4E 54 49 4C 39 40 C0 C3 1A 42 C4 1D A2 52 C4 1D
+8A 49 00 00 8A 4E 02 00 3E 4F 30 4D 96 CB 85 41
+47 41 49 4E 39 40 BC C3 EF 3F 32 CC 85 57 48 49
+4C 45 87 12 D4 CD 6E C2 2A C2 CA CC 86 52 45 50
+45 41 54 00 87 12 54 CE 16 CE 2A C2 EE CD 82 44
+4F 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40 CA C3
+00 00 2E 53 82 4E C4 1D A2 53 AC 1D 1A 42 AC 1D
+8A 43 00 00 30 4D C2 C9 84 4C 4F 4F 50 00 39 40
+EC C3 1A 42 C4 1D A2 52 C4 1D 8A 49 00 00 8A 4E
+02 00 1E 42 AC 1D A2 83 AC 1D 2E 4E 0E 93 04 24
+9E 42 C4 1D 00 00 F5 3F 3E 4F 30 4D E4 C5 85 2B
+4C 4F 4F 50 39 40 DA C3 E4 3F A8 CE 85 4C 45 41
+56 45 1A 42 C4 1D BA 40 FC C3 00 00 BA 40 BC C3
+02 00 B2 50 06 00 C4 1D A2 53 AC 1D 2A 52 19 42
+AC 1D 89 4A 00 00 30 4D EC CE 04 4D 4F 56 45 00
+0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24 08 99 0F 24
+06 2C F8 49 00 00 18 53 1A 83 FB 23 30 4D 08 5A
+09 5A 19 83 18 83 E8 49 00 00 1A 83 FA 23 30 4D
+34 C2 CA 1D FC C2 2A C2 84 12 50 CF 48 D2 30 D2
+7E CE AC CB 18 D2 DE CE 1A CF 90 C7 BE CF F2 CF
+2E CE B2 D0 48 C3 58 CD C0 CC 68 C8 00 00 3A 40
+0C 00 39 40 CA 1D 38 40 CC 1D D9 3F 3A 40 0E 00
+39 40 CC 1D 38 40 CA 1D CC 3F 82 43 CC 1D 30 4D
+92 42 CA 1D C8 1D 30 4D 6C CD 09 50 57 52 5F 53
+54 41 54 45 84 12 9A CD 14 D2 5E D9 AA CF 08 50
+57 52 5F 48 45 52 45 00 92 42 C4 1D BA CF 92 42
+C6 1D B8 CF EF 3F 6C CE 09 52 53 54 5F 53 54 41
+54 45 92 42 0C 18 BA CF 92 42 0E 18 B8 CF E2 3F
+D8 CF 08 52 53 54 5F 48 45 52 45 00 92 42 C4 1D
+0C 18 92 42 C6 1D 0E 18 DF 3F B2 40 58 D0 BA D0
+B2 40 A0 C6 B0 C6 B2 40 DC C6 F0 C6 B2 40 DC C5
+EA C5 30 41 5C CE 04 57 49 50 45 00 39 40 80 FF
+B9 43 00 00 29 53 39 90 CE FF FA 23 B0 12 0A D0
+B2 40 5E D9 C4 1D B2 40 14 D2 C6 1D D7 3F D0 CD
+06 28 57 41 52 4D 29 00 1E 42 08 18 87 12 4E C7
+05 0D 1B 5B 37 6D 32 C7 70 C5 4E C7 27 20 46 61
+73 74 46 6F 72 74 68 20 56 31 36 30 20 32 34 4D
+48 7A 20 28 43 29 20 4A 2E 4D 2E 54 68 6F 6F 72
+65 6E 73 20 32 C7 34 C2 30 FF 84 C5 2A C3 30 C5
+4E C7 0B 62 79 74 65 73 20 66 72 65 65 20 34 CB
+26 D0 04 57 41 52 4D 00 30 40 58 D0 22 CE 04 43
+4F 4C 44 00 B2 40 04 A5 20 01 92 D3 30 01 B2 40
+88 5A 5C 01 F2 D0 10 00 16 02 B2 D0 00 80 04 02
+B2 40 FF 7F 02 02 B2 D0 FF 7F 06 02 F2 D0 07 00
+36 02 B2 D0 F0 00 04 02 B2 40 0F FF 02 02 B2 D0
+0F FF 06 02 F2 D0 0F 00 24 03 F2 40 F0 00 22 03
+F2 D0 F0 00 26 03 F2 40 A5 00 61 01 B2 40 86 00
+62 01 82 43 66 01 39 40 C0 00 B2 40 33 00 64 01
+D2 43 61 01 92 D2 9E 01 08 18 A2 93 08 18 01 24
+59 07 38 40 C2 A2 18 83 FE 23 19 83 FA 23 B2 D2
+B0 01 92 C3 B0 01 F2 D0 10 00 2A 03 F2 C0 40 00
+A1 04 3A 40 CA D0 39 40 CE FF 89 4A 00 00 29 53
+FC 23 92 42 02 18 F0 FF B2 40 18 00 0A 18 31 40
+E0 1C 3F 40 80 1C 37 40 00 C2 36 40 B4 C2 35 40
+08 C2 34 40 14 C2 B2 40 0A 00 DA 1D B2 43 DC 1D
+92 C3 30 01 18 42 08 18 D2 B3 01 02 04 20 38 E3
+18 53 82 48 08 18 B2 40 81 00 C0 05 92 43 C6 05
+B2 40 A1 00 C8 05 F2 D0 03 00 0D 02 92 C3 C0 05
+92 D3 DA 05 3D 40 EE D1 18 42 08 18 38 90 0A 00
+25 27 38 90 16 00 22 2F 28 93 FB 22 E3 26 B8 D0
+84 12 50 CF 3C D8 E8 D8 F0 D7 3C D9 B6 D7 70 D8
+BA D4 00 00 AC D7 5C D8 0E D8 4C D8 CA D5 00 00
+00 00 4E D9 7C CF 50 D0 85 48 49 32 4C 4F 87 12
+84 C5 E8 CD B0 C9 B8 CC 7E CF F0 D1 2A C2 BE D0
+04 43 4F 44 45 00 B0 12 CA CB A2 82 C4 1D 87 12
+F8 CC BC C3 28 D2 4E CE 03 41 53 4D 92 42 C8 1D
+B8 1D B2 40 F4 D1 C8 1D EE 3F 00 00 07 45 4E 44
+43 4F 44 45 87 12 8C CF 18 CC 2A C2 5C D2 06 45
+4E 44 41 53 4D 00 92 42 B8 1D C8 1D F3 3F 00 00
+05 43 4F 4C 4F 4E 1A 42 C4 1D BA 40 87 12 00 00
+A2 53 C4 1D B2 43 B6 1D 30 40 8C CF 00 00 05 4C
+4F 32 48 49 1A 42 C4 1D BA 40 B0 12 00 00 BA 40
+2A C2 02 00 A2 52 C4 1D ED 3F 38 40 BE 1D 39 48
+2A 48 09 5A 1A 52 C2 1D 09 9A 03 24 7E 9A FC 27
+1A 83 0E 4A 2A 88 82 4A C2 1D 30 4D B0 12 2A C2
+A8 C7 00 C8 72 C3 C0 C3 F2 D2 BC C8 C0 C3 BC CB
+14 D3 F4 D2 29 4E 39 90 86 12 02 20 2E 53 30 41
+39 90 85 12 03 20 1E 4E 02 00 30 41 39 90 84 12
+01 20 2E 52 30 41 19 42 C4 1D A2 53 C4 1D 89 4E
+00 00 3E 40 29 00 12 12 C2 1D 92 53 C2 1D B0 12
+2A C2 A8 C7 BC C8 C0 C3 46 D3 3C D3 21 53 3E 90
+10 00 BB 2D 30 41 48 D3 B2 41 C2 1D 22 D3 30 41
+87 12 4C C4 BA D2 58 D3 82 43 BC 1D 92 42 C4 1D
+BA 1D A2 53 C4 1D 0A 4E 3E 4F FA 90 23 00 00 00
+34 20 92 53 C2 1D B0 12 DC D2 0E 93 04 20 B2 40
+00 03 BC 1D 27 3C 1E 93 04 20 B2 40 10 03 BC 1D
+21 3C 2E 93 04 20 B2 40 20 03 BC 1D 1B 3C 2E 92
+04 20 B2 40 20 02 BC 1D 15 3C 3E 92 04 20 B2 40
+30 02 BC 1D 0F 3C 3E 93 04 20 B2 40 30 03 BC 1D
+09 3C B2 40 30 00 BC 1D 19 42 C4 1D A2 53 C4 1D
+89 4E 00 00 3E 4F 3D 41 30 4D FA 90 26 00 00 00
+08 20 B2 40 10 02 BC 1D 92 53 C2 1D 30 12 C8 D3
+75 3F FA 90 40 00 00 00 1A 20 B2 40 20 00 BC 1D
+92 53 C2 1D B0 12 26 D3 0E 20 B2 50 10 00 BC 1D
+3E 40 2B 00 B0 12 26 D3 32 24 92 92 BE 1D C2 1D
+02 24 92 53 C2 1D 8E 10 82 5E BC 1D D3 3F B0 12
+26 D3 F9 23 B2 50 10 00 BC 1D 3E 40 28 00 B0 12
+DC D2 30 12 18 D4 67 3F 87 12 4C C4 BA D2 50 D4
+FE 90 26 00 00 00 3E 40 20 00 04 20 B2 50 82 00
+BC 1D C2 3F B0 12 26 D3 DF 23 B2 50 80 00 BC 1D
+3E 40 28 00 B0 12 DC D2 B0 12 16 D3 D5 23 3D 40
+BC CB 30 4D 00 00 04 52 45 54 49 00 87 12 34 C2
+00 13 B0 C9 2A C2 34 C2 2C 00 50 D3 48 D4 A0 D4
+2E 4E 1E D2 BC 1D 19 42 BA 1D 92 3F 9E D2 03 4D
+4F 56 84 12 96 D4 00 40 AE D4 05 4D 4F 56 2E 42
+84 12 96 D4 40 40 00 00 03 41 44 44 84 12 96 D4
+00 50 C8 D4 05 41 44 44 2E 42 84 12 96 D4 40 50
+D4 D4 04 41 44 44 43 00 84 12 96 D4 00 60 E2 D4
+06 41 44 44 43 2E 42 00 84 12 96 D4 40 60 86 D4
+04 53 55 42 43 00 84 12 96 D4 00 70 00 D5 06 53
+55 42 43 2E 42 00 84 12 96 D4 40 70 0E D5 03 53
+55 42 84 12 96 D4 00 80 1E D5 05 53 55 42 2E 42
+84 12 96 D4 40 80 80 D2 03 43 4D 50 84 12 96 D4
+00 90 38 D5 05 43 4D 50 2E 42 84 12 96 D4 40 90
+6E D2 04 44 41 44 44 00 84 12 96 D4 00 A0 52 D5
+06 44 41 44 44 2E 42 00 84 12 96 D4 40 A0 44 D5
+03 42 49 54 84 12 96 D4 00 B0 70 D5 05 42 49 54
+2E 42 84 12 96 D4 40 B0 7C D5 03 42 49 43 84 12
+96 D4 00 C0 8A D5 05 42 49 43 2E 42 84 12 96 D4
+40 C0 96 D5 03 42 49 53 84 12 96 D4 00 D0 A4 D5
+05 42 49 53 2E 42 84 12 96 D4 40 D0 00 00 03 58
+4F 52 84 12 96 D4 00 E0 BE D5 05 58 4F 52 2E 42
+84 12 96 D4 40 E0 F0 D4 03 41 4E 44 84 12 96 D4
+00 F0 D8 D5 05 41 4E 44 2E 42 84 12 96 D4 40 F0
+4C C4 50 D3 F6 D5 1A 42 BC 1D B2 F0 70 00 BC 1D
+8A 10 3A F0 0F 00 82 DA BC 1D 4A 3F 2A D5 03 52
+52 43 84 12 F0 D5 00 10 0E D6 05 52 52 43 2E 42
+84 12 F0 D5 40 10 1A D6 04 53 57 50 42 00 84 12
+F0 D5 80 10 28 D6 03 52 52 41 84 12 F0 D5 00 11
+36 D6 05 52 52 41 2E 42 84 12 F0 D5 40 11 42 D6
+03 53 58 54 84 12 F0 D5 80 11 00 00 04 50 55 53
+48 00 84 12 F0 D5 00 12 5C D6 06 50 55 53 48 2E
+42 00 84 12 F0 D5 40 12 B0 D5 04 43 41 4C 4C 00
+84 12 F0 D5 80 12 34 C2 2C 00 50 D3 48 D4 90 D6
+59 42 BC 1D 5A 42 BD 1D 82 4A BC 1D BE 90 00 15
+00 00 02 20 0A 89 02 3C 09 8A 0A 49 3A 90 10 00
+03 2C 5A 0E A8 3F 1A 53 0E 4A 87 12 70 C5 4E C7
+0D 6F 75 74 20 6F 66 20 62 6F 75 6E 64 73 2E CB
+6A D6 05 50 55 53 48 4D 84 12 86 D6 00 15 D2 D6
+04 50 4F 50 4D 00 84 12 86 D6 00 17 4C C4 BA D2
+F2 D6 82 43 BC 1D 92 42 C4 1D BA 1D A2 53 C4 1D
+92 53 C2 1D 3E 40 2C 00 B0 12 2A C2 A8 C7 BC C8
+C0 C3 BC CB 48 D4 18 D7 0A 4E 3E 4F 1A 83 2A 92
+CA 2F 8A 10 5A 06 6F 3F 50 D6 04 52 52 43 4D 00
+84 12 EC D6 50 00 2A D7 04 52 52 41 4D 00 84 12
+EC D6 50 01 38 D7 04 52 4C 41 4D 00 84 12 EC D6
+50 02 46 D7 04 52 52 55 4D 00 84 12 EC D6 50 03
+85 12 00 3C 54 D7 03 53 3E 3D 85 12 00 38 66 D7
+02 53 3C 00 85 12 00 34 E0 D6 03 30 3E 3D 85 12
+00 30 7A D7 02 30 3C 00 85 12 00 30 00 00 02 55
+3C 00 85 12 00 2C 8E D7 03 55 3E 3D 85 12 00 28
+84 D7 03 30 3C 3E 85 12 00 24 A2 D7 02 30 3D 00
+85 12 00 20 00 00 02 49 46 00 1A 42 C4 1D 8A 4E
+00 00 A2 53 C4 1D 0E 4A 30 4D 98 D7 04 54 48 45
+4E 00 1A 42 C4 1D 08 4E 3E 4F 09 48 29 53 0A 89
+0A 11 3A 90 00 02 68 2F 88 DA 00 00 30 4D 60 D5
+04 45 4C 53 45 00 1A 42 C4 1D BA 40 00 3C 00 00
+A2 53 C4 1D 2F 83 8F 4A 00 00 E3 3F CC D7 05 55
+4E 54 49 4C 3A 4F 08 4E 3E 4F 19 42 C4 1D 2A 83
+0A 89 0A 11 3A 90 00 FE 47 3B 3A F0 FF 03 08 DA
+89 48 00 00 A2 53 C4 1D 30 4D E4 D5 05 41 47 41
+49 4E 87 12 60 D7 14 D8 2A C2 00 00 05 57 48 49
+4C 45 87 12 BA D7 6E C2 2A C2 70 D7 06 52 45 50
+45 41 54 00 87 12 60 D7 14 D8 D2 D7 2A C2 00 00
+03 4A 4D 50 87 12 AE CB 60 D7 14 D8 2A C2 3E B0
+00 10 03 20 3E E0 00 04 30 4D 3E 90 00 34 06 28
+03 24 3E 40 00 34 30 4D 3E 40 00 38 30 4D 00 00
+04 3F 4A 4D 50 00 87 12 7E D8 AE CB 6E C2 14 D8
+2A C2 B4 D8 3D 41 08 4E 3E 4F 2A 48 0A 93 04 20
+98 42 C4 1D 00 00 30 4D 88 43 00 00 A4 3F 7A D6
+03 42 57 31 84 12 B2 D8 00 00 D0 D8 03 42 57 32
+84 12 B2 D8 00 00 DC D8 03 42 57 33 84 12 B2 D8
+00 00 F4 D8 3D 41 1A 42 C4 1D 28 4E 08 93 08 20
+BA 4F 00 00 A2 53 C4 1D 8E 4A 00 00 3E 4F 30 4D
+8E 43 00 00 61 3F 00 00 03 46 57 31 84 12 F2 D8
+00 00 18 D9 03 46 57 32 84 12 F2 D8 00 00 24 D9
+03 46 57 33 84 12 F2 D8 00 00 30 D9 04 47 4F 54
+4F 00 87 12 60 D7 AE CB A6 C9 2A C2 A0 D8 05 3F
+47 4F 54 4F 87 12 7E D8 AE CB A6 C9 2A C2
+@FFCE
+CA D0 CA D0 CA D0 CA D0 CA D0 CA D0 CA D0 CA D0
+CA D0 CA D0 CA D0 CA D0 CA D0 CA D0 CA D0 CA D0
+CA D0 4C C6 CA D0 CA D0 CA D0 CA D0 CA D0 CA D0
+CA D0
+q
--- /dev/null
+\prog\MSP430Flasher\msp430flasher -m SBW2 -n MSP430fr5739 -v -w %1 -z [VCC=3000]
+exit
+
+tip : how to calculate MAIN program lenght ?
+
+open the prog.txt file with your editor, select MAIN section
+in status bar, keep the number of selected chars
+if lines are ended with CR+LF, substract the number of lines selected
+then divide by 3.
--- /dev/null
+; -*- coding: utf-8 -*-
+; MSP-EXP430FR5969.inc
+
+; Fast Forth For Texas Instrument MSP430FR5969
+;
+; Copyright (C) <2014> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+
+; ======================================================================
+; INIT MSP-EXP430FR5969 board
+; ======================================================================
+
+;
+; J21 : external target
+; ---------------------
+; P1 - RX0 - P2.1
+; P2 - VCC
+; P3 - TEST - TEST
+; P4 - RST - RST
+; P5 - GND
+; P6 - TX0 - P2.0
+
+
+; J3: JTAG
+; --------
+; P1 - TDO - PJ.0
+; P2 - V_debug
+; P3 - TDI - PJ.1
+; P4 - V_ext
+; P5 - TMS - PJ.2
+; P6 - NC
+; P7 - TCK - PJ.3
+; P8 - TEST - TEST
+; P9 - GND
+; P10- CTS - P4.0
+; P11- RST - RESET
+; P12- TX0 - P2.0
+; P13- RTS - P4.1
+; P14- RX0 - P2.1
+
+
+; J13 eZ-FET <-> target
+; -----------------------
+; P1 <-> P2 - NC
+; P3 <-> P4 - TEST - TEST
+; P5 <-> P6 - RST - RST
+; P7 <-> P8 - TX0 - P2.0 ---> RX UARTtoUSB
+; P9 <->P10 - RX0 - P2.1 <--- TX UARTtoUSB
+; P11<->P12 - CTS - P4.0
+; P13<->P14 - RTS - P4.1
+; P15<->P16 - VCC - VDD
+; P17<->P18 - 5V
+; P19<->P20 - GND - VSS
+
+; Launchpad Header Left J4
+; ------------------------
+; P1 - VCC
+; P2 - P4.2
+; P3 - P2.6 UCA1 RX/SOMI ---> SD_SDO
+; P4 - P2.5 UCA1 TX/SIMO <--- SD_SDI
+; P5 - P4.3 ---> SD_SS
+; P6 - P2.4 UCA1 CLK ---> SD_CLK
+; P7 - P2.2 TB0.2 UCB0CLK
+; P8 - P3.4
+; P9 - P3.5
+; P10- P3.6
+
+; Launchpad Header Right J5
+; -------------------------
+; P11- P1.3
+; P12- P1.4
+; P13- P1.5
+; P14- P1.6 UCB0 SIMO/SDA
+; P15- P1.7 UCB0 SOMI/SCL
+; P16- RST
+; P17- NC
+; P18- P3.0
+; P19- P1.2
+; P20- GND
+
+
+; switch-keys:
+; S1 - P4.5
+; S2 - P1.1
+; S3 - RST
+
+; LEDS:
+; LED1 - J6 - P4.6
+; LED2 - P1.0
+
+; XTAL LF 32768 Hz
+; Y4 - PJ.4
+; Y4 - PJ.5
+
+; XTAL HF
+; Y1 - PJ.6
+; Y1 - PJ.7
+
+; Clocks:
+; 8 MHz DCO intern
+
+
+
+; ===================================================================================
+; in case of 3.3V powered by UARTtoUSB bridge, open J13 straps {RST,TST,V+,5V} BEFORE
+; ===================================================================================
+
+; -----------------------------------------------
+; MSP430FR5969 LAUNCHPAD <--> OUTPUT WORLD
+; -----------------------------------------------
+; P4.6 - J6 - LED1 red
+; P1.0 - LED2 green
+
+; P4.5 - Switch S1 <--- LCD contrast + (finger :-)
+; P1.1 - Switch S2 <--- LCD contrast - (finger ;-)
+
+; GND - J1.2 <-------+---0V0----------> 1 LCD_Vss
+; VCC - J1.3 >------ | --3V6-----+----> 2 LCD_Vdd
+; | |
+; |___ 470n ---
+; ^ | ---
+; / \ BAT54 |
+; --- |
+; 100n | 2k2 |
+; P2.2 - UCB0 CLK TB0.2 J4.7 >---||--+--^/\/\/v--+----> 3 LCD_Vo (=0V6 without modulation)
+; P3.4 - J4.8 -------------------------> 4 LCD_RS
+; P3.5 - J4.9 -------------------------> 5 LCD_R/W
+; P3.6 - J4.10 -------------------------> 6 LCD_EN0
+; PJ.0 - J3.1 <------------------------> 11 LCD_DB4
+; PJ.1 - J3.3 <------------------------> 12 LCD_DB5
+; PJ.2 - J3.5 <------------------------> 13 LCD_DB5
+; PJ.3 - J3.7 <------------------------> 14 LCD_DB7
+
+; +--4k7-< DeepRST <-- GND
+; |
+; P2.0 - UCA0 TXD J13.8 <-+-> RX UARTtoUSB bridge
+; P2.1 - UCA0 RXD J13.10 <---- TX UARTtoUSB bridge
+; P4.1 - RTS J13.14 ----> CTS UARTtoUSB bridge (optional hardware control flow)
+; VCC - J13.16 <---- VCC (optional supply from UARTtoUSB bridge - WARNING ! 3.3V !)
+; GND - J13.20 <---> GND (optional supply from UARTtoUSB bridge)
+
+; VCC - J11.1 ----> VCC SD_CardAdapter
+; GND - J12.3 <---> GND SD_CardAdapter
+; P2.4 - UCA1 CLK J4.6 ----> CLK SD_CardAdapter (SCK)
+; P4.3 - J4.5 ----> CS SD_CardAdapter (Card Select)
+; P2.5 - UCA1 TXD/SIMO J4.4 ----> SDI SD_CardAdapter (MOSI)
+; P2.6 - UCA1 RXD/SOMI J4.3 <---- SDO SD_CardAdapter (MISO)
+; P4.2 - J4.2 <---- CD SD_CardAdapter (Card Detect)
+
+; P4.0 - J3.10 <---- OUT IR_Receiver (1 TSOP32236)
+; VCC - J3.2 ----> VCC IR_Receiver (2 TSOP32236)
+; GND - J3.9 <---> GND IR_Receiver (3 TSOP32236)
+
+; P1.2 - J5.19 <---> SDA I2C SOFTWARE MASTER
+; P1.3 - J5.11 <---> SCL I2C SOFTWARE MASTER
+; P1.4 - TB0.1 J5.12 <---> free
+; P1.5 - UCA0 CLK TB0.2 J5.13 <---> free
+; P1.7 - UCB0 SCL/SOMI J5.14 ----> SCL I2C MASTER/SLAVE
+; P1.6 - UCB0 SDA/SIMO J5.15 <---> SDA I2C MASTER/SLAVE
+; P3.0 - J5.7 <---- free
+
+; PJ.4 - LFXI 32768Hz quartz
+; PJ.5 - LFXO 32768Hz quartz
+; PJ.6 - HFXI
+; PJ.7 - HFXO
+
+; P2.3 - NC
+; P2.7 - NC
+; P3.1 - NC
+; P3.2 - NC
+; P3.3 - NC
+; P3.7 - NC
+; P4.4 - NC
+; P4.7 - NC
+
+
+
+; ----------------------------------------------------------------------
+; INIT order : LOCK I/O, WDT, GPIOs, FRAM, Clock, UARTs
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : LOCK PMM_LOCKLPM5
+; ----------------------------------------------------------------------
+
+; BIS #LOCKLPM5,&PM5CTL0 ; unlocked by WARM
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : WATCHDOG TIMER A
+; ----------------------------------------------------------------------
+
+ MOV #WDTPW+WDTHOLD+WDTCNTCL,&WDTCTL ; stop WDT
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : I/O
+; ----------------------------------------------------------------------
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT1/2
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT1 usage
+; P1.0 - LED2 green output low
+; P1.1 - Switch S2 input with pullup resistor
+
+; PORT2 usage
+
+
+Deep_RST_IN .equ P2IN ; TERMINAL TX pin as FORTH Deep_RST
+Deep_RST .equ 1 ; P2.0
+TERM_TXRX .equ 003h
+TERM_SEL .equ P2SEL1
+TERM_REN .equ P2REN
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ BIS #1,&PADIR ; all pins 0 as input else P1.0 (LED2)
+ MOV #0FFFEh,&PAOUT ; all pins high else P1.0 (LED2)
+ SUB #2,&PAREN ; all pins 1 with pull resistors else P1.0 (LED2)
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT3/4
+; ----------------------------------------------------------------------
+; PB = P4:P3
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT3 usage
+
+; PORT4 usage
+; switch S1
+SWITCHIN .set P4IN ; port
+S1 .set 020h ; P4.5 bit position
+
+; P4.6 as LED1 output low
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #04000h,&PBDIR ; all pins as input else P4.6 (LED1)
+ MOV #0BFFFh,&PBOUT ; all pins output high else P4.6 (LED1)
+ BIS #0BFFFh,&PBREN ; all pins with pull resistors else P4.6 (LED1)
+
+ .IFDEF TERMINALCTSRTS
+;configure P4.1 as RTS output high
+RTS .equ 2
+HANDSHAKOUT .equ P4OUT
+HANDSHAKIN .equ P4IN
+ BIS.B #RTS,&HANDSHAKOUT
+ .ENDIF
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORTJ
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV.B #-1,&PJOUT ; pullup resistors
+ BIS.B #-1,&PJREN ; enable pullup/pulldown resistors
+
+; ----------------------------------------------------------------------
+; FRAM config
+; ----------------------------------------------------------------------
+
+ .IF FREQUENCY = 16
+ MOV.B #0A5h, &FRCTL0_H ; enable FRCTL0 access
+ MOV.B #10h, &FRCTL0 ; 1 waitstate @ 16 MHz
+ MOV.B #01h, &FRCTL0_H ; disable FRCTL0 access
+ .ENDIF
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : CLOCK SYSTEM
+; ----------------------------------------------------------------------
+
+; DCOCLK: Internal digitally controlled oscillator (DCO).
+; Startup clock system in max. DCO setting ~8MHz
+
+ MOV.B #CSKEY,&CSCTL0_H ; Unlock CS registers
+
+ .IF FREQUENCY = 0.5
+ MOV #0,&CSCTL1 ; Set 1MHZ DCO setting
+ MOV #DIVA_2 + DIVS_2 + DIVM_2,&CSCTL3 ; set all dividers as 2
+ MOV #4,X
+
+ .ELSEIF FREQUENCY = 1
+ MOV #0,&CSCTL1 ; Set 1MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #8,X
+
+ .ELSEIF FREQUENCY = 2
+ MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 4MHZ DCO setting
+ MOV #DIVA_0 + DIVS_2 + DIVM_2,&CSCTL3
+ MOV #16,X
+
+ .ELSEIF FREQUENCY = 4
+ MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 4MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #32,X
+
+ .ELSEIF FREQUENCY = 8
+; MOV #DCOFSEL2+DCOFSEL1,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #64,X
+
+ .ELSEIF FREQUENCY = 16
+ MOV #DCORSEL+DCOFSEL2,&CSCTL1 ; Set 16MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #128,X
+
+ .ELSEIF
+ .error "bad frequency setting, only 0.5,1,2,4,8,16 MHz"
+ .ENDIF
+
+ .IFDEF LF_XTAL
+ MOV #SELA_LFXCLK+SELS_DCOCLK+SELM_DCOCLK,&CSCTL2
+ .ELSE
+ MOV #SELA_VLOCLK+SELS_DCOCLK+SELM_DCOCLK,&CSCTL2
+ .ENDIF
+ MOV.B #01h, &CSCTL0_H ; Lock CS Registers
+
+ BIS &SYSRSTIV,&SAVE_SYSRSTIV; store volatile SYSRSTIV preserving a pending request for DEEP_RST
+ CMP #2,&SAVE_SYSRSTIV ; POWER ON ?
+ JZ ClockWaitX ; yes
+ .word 0759h ; no RRUM #2,X --> wait only 125 ms
+ClockWaitX MOV #41666,Y ; wait 0.5s before starting after POWER ON
+ClockWaitY SUB #1,Y ;
+ JNZ ClockWaitY ; 41666x3 = 125000 cycles delay = 125ms @ 1MHz
+ SUB #1,X ; x 4 @ 1 MHZ
+ JNZ ClockWaitX ; time to stabilize power source ( 1s )
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : REF
+; ----------------------------------------------------------------------
+
+ BIS #8, &REFCTL
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : RTC REGISTERS
+; ----------------------------------------------------------------------
+
+ .IFDEF LF_XTAL
+; LFXIN : PJ.4, LFXOUT : PJ.5
+ BIS.B #010h,&PJSEL0 ; SEL0 for only LFXIN
+ BIC.B #RTCHOLD,&RTCCTL1 ; Clear RTCHOLD = start RTC_B
+ .ENDIF
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : SYS REGISTERS
+; ----------------------------------------------------------------------
+
+; SYS code
+; see COLD word
+
--- /dev/null
+@1800
+10 00 4C 48 80 3E 80 04 FD FF 18 00 4C 5B 02 54
+2A 48 38 48 00 00 00 00
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@4400
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 44
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 44 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 44 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E 44 02 3E 52 00 0E 12 3E 4F 30 4D 8E 44
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 44
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C 44 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 44 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 45
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 44 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA 44 03 41 4E 44 3E FF 30 4D 7A 44 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E 45 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 45 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E 45 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 45 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 44 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE 45 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 45 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 45 03 3E 49 4E 85 12 C2 1D 10 45
+04 42 41 53 45 00 85 12 DA 1D C0 44 05 53 54 41
+54 45 85 12 B6 1D 30 46 02 42 4C 00 85 12 20 00
+94 45 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 46 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E 46 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 46 02 23 53 00 87 12 98 46
+D2 46 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 46 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 46 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C 46 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 45 03 55 44 2E 87 12 56 46
+CC 46 E6 46 32 49 FA 48 2A 44 18 47 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA 44
+02 44 2E 00 87 12 56 46 6E 44 80 44 3A 47 CC 46
+92 44 0A 47 E6 46 32 49 FA 48 2A 44 52 45 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 46 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 45 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 46 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A 48
+92 B3 DC 05 FD 27 1E 42 CC 05 B0 12 38 48 30 4D
+30 40 B6 47 7E 47 05 28 4B 45 59 29 18 42 CC 05
+EA 3F 12 46 03 4B 45 59 30 40 DC 47 92 47 06 41
+43 43 45 50 54 00 3C 40 8A 48 3B 40 54 48 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+7E 48 92 B3 DC 05 05 24 18 42 CC 05 38 90 0A 00
+04 20 21 53 39 40 46 48 4D 15 B2 40 11 00 CE 05
+A2 B3 DC 05 FD 27 30 41 B2 40 13 00 CE 05 A2 B3
+DC 05 FD 27 30 41 12 D2 0A 18 FD 3F 21 52 3A 17
+58 42 CC 05 48 9B F0 27 48 9C 06 2C 78 92 11 20
+2E 9F 0F 24 1E 83 05 3C 0E 9A 03 24 CE 48 00 00
+1E 53 82 48 CE 05 A2 B3 DC 05 FD 27 30 4D 80 48
+2D 83 92 B3 DC 05 FD 27 E3 23 B2 40 18 00 0A 18
+3E 8F 3D 41 30 4D D6 47 06 28 45 4D 49 54 29 00
+08 4E 3E 4F E6 3F 50 47 04 45 4D 49 54 00 30 40
+A0 48 A8 48 04 45 43 48 4F 00 B2 40 82 48 72 48
+30 4D 6E 47 06 4E 4F 45 43 48 4F 00 B2 40 30 4D
+72 48 30 4D 98 48 04 28 43 52 29 00 2F 83 8F 4E
+00 00 3E 40 0D 00 E3 3F A2 47 02 43 52 00 30 40
+DC 48 04 47 05 53 50 41 43 45 2F 83 8F 4E 00 00
+3E 40 20 00 D4 3F F4 48 06 53 50 41 43 45 53 00
+0E 93 09 24 0D 12 3D 40 1C 49 EF 3F 1E 49 2D 83
+1E 83 EB 23 3D 41 3E 4F 30 4D 2C 47 04 54 59 50
+45 00 0E 93 95 24 2A 4F 8F 5E 00 00 0E 4A 87 12
+CA 45 02 46 0A 45 AE 48 EC 45 42 49 2A 44 2F 82
+8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E 1D B3 0D 63
+30 4D 08 49 82 53 22 00 87 12 34 44 4E 49 B0 4B
+34 44 22 00 A8 49 78 49 3D 41 6E 4E 1E 83 82 5E
+C4 1D 3E 4F 92 B3 C4 1D A2 63 C4 1D 30 4D C4 48
+82 2E 22 00 87 12 68 49 34 44 32 49 B0 4B 2A 44
+00 00 04 57 4F 52 44 00 3C 40 BE 1D 39 4C 3A 4C
+09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A FC 27 1A 83
+3B 40 60 00 C8 4C 00 00 09 9A 0C 24 7C 4A 4E 9C
+09 24 18 53 4B 9C F6 2F 7C 90 7B 00 F3 2F 7C 80
+20 00 F0 3F 1A 82 C0 1D 82 4A C2 1D 1E 42 C4 1D
+08 8E CE 48 00 00 30 4D 00 00 04 46 49 4E 44 00
+2F 83 0C 4E 65 4C 74 40 80 00 3B 40 CA 1D 3E 4B
+0E 93 1E 24 58 4C 01 00 78 F0 1E 00 0E 58 2E 53
+1E 4E FE FF 0E 93 F3 27 09 4E 78 49 48 C4 48 95
+F7 23 0A 4C 1A 53 FA 99 00 00 F2 23 58 83 FA 23
+19 B3 09 63 0C 49 6A 4E 1E 43 4A 93 01 30 2E 83
+8F 4C 00 00 35 40 08 44 34 40 14 44 30 4D 2F 53
+2F 53 3E 4F 30 4D 26 46 07 3E 4E 55 4D 42 45 52
+3C 4F 38 4F 29 4F 2F 82 1B 42 DA 1D 6A 4C 7A 80
+30 00 7A 90 0A 00 02 28 7A 80 07 00 0A 9B 13 2C
+82 49 D0 04 82 48 D2 04 82 4B C8 04 19 42 E4 04
+18 42 E6 04 09 5A 08 63 1C 53 1E 83 E7 23 8F 49
+04 00 8F 48 02 00 8F 4C 00 00 30 4D 03 12 0D 12
+1B 42 DA 1D 0B 12 32 C0 00 02 6D 4E 0D 5E 0C 4E
+7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23 32 D0 00 02
+FC 4C FE FF 0D 9C FC 2F DE 83 00 00 09 43 08 43
+3D 40 32 4B 3F 82 8F 4E 06 00 0C 4E 7E 4C 6A 4C
+7A 90 2D 00 10 2C 3B 40 10 00 7A 80 24 00 06 24
+2B 43 5A 83 03 24 3B 52 6A 53 B0 23 1C 53 1E 83
+6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83 B1 43 04 00
+A5 3F 34 4B 2F 53 0E 93 2C 17 82 4C DA 1D 03 24
+2F 52 0E F3 30 4D 8F 93 00 00 15 20 32 B0 00 02
+14 20 0E 93 05 24 1A 4F 02 00 1A 83 0A 93 0B 38
+2F 53 BF 4F 00 00 3E E3 05 20 BF E3 00 00 9F 53
+00 00 3E E3 30 4D 32 D0 00 02 9F 4F 02 00 04 00
+BF 4F 00 00 3E E3 F6 23 BF E3 02 00 BF E3 00 00
+9F 53 02 00 8F 63 00 00 3E E3 30 4D B4 48 07 45
+58 45 43 55 54 45 0A 4E 3E 4F 00 4A 28 45 01 2C
+1A 42 C4 1D A2 53 C4 1D 8A 4E 00 00 3E 4F 30 4D
+AE 4B 87 4C 49 54 45 52 41 4C 82 93 B6 1D 16 24
+32 B0 00 02 09 24 1A 42 C4 1D A2 52 C4 1D BA 40
+34 44 00 00 BA 4F 02 00 1A 42 C4 1D A2 52 C4 1D
+BA 40 34 44 00 00 8A 4E 02 00 3E 4F 30 4D EA 48
+05 43 4F 55 4E 54 2F 83 1E 53 8F 4E 00 00 5E 4E
+FF FF 30 4D 82 4E BE 1D B2 4F C0 1D 3E 4F 82 43
+C2 1D 87 12 4C 46 A8 49 2A 4C 3D 40 36 4C E8 22
+3D 41 3E 4F 30 4D 38 4C 0A 4E 3E 4F 3D 40 4E 4C
+3D 27 3D 40 24 4C 1A E2 B6 1D B2 27 AC 23 50 4C
+3E 4F 3D 40 24 4C B9 23 DE 53 00 00 68 4E 08 5E
+F8 40 3F 00 00 00 3D 40 16 4E CD 3F 9E 4B 08 45
+56 41 4C 55 41 54 45 00 39 40 BE 1D 39 12 39 12
+39 12 0D 12 B0 12 2A 44 14 4C 8C 4C 3D 41 B2 41
+C2 1D B2 41 C0 1D B2 41 BE 1D 30 4D 7A 45 04 51
+55 49 54 00 31 40 E0 1C B2 40 00 1C AC 1D 82 43
+B6 1D 82 43 08 18 B0 12 2A 44 4E 49 04 0D 6F 6B
+20 00 32 49 34 44 38 1D 44 44 34 44 50 00 F6 47
+FA 48 14 4C 34 44 7E 1C CE 44 B2 45 4E 49 0D 73
+74 61 63 6B 20 65 6D 70 74 79 20 21 28 4D 34 44
+30 FF 84 47 B2 45 4E 49 0B 46 52 41 4D 20 66 75
+6C 6C 20 21 28 4D 42 46 F4 44 C0 45 BA 4C 4E 49
+04 0D 20 20 20 00 BC 45 C2 4C EE 47 05 41 42 4F
+52 54 3F 40 80 1C BE 3F 8F 93 02 00 98 26 B2 40
+82 48 72 48 B0 12 10 52 82 43 C6 5A 82 43 D2 5A
+82 43 DE 5A 82 43 0E 5B 82 43 1A 5B 82 43 26 5B
+A2 B3 DC 05 FD 27 B2 40 11 00 CE 05 92 C3 DC 05
+38 40 A0 AA 39 42 19 83 FE 23 18 83 FB 23 92 B3
+DC 05 F4 23 87 12 4E 49 04 1B 5B 37 6D 00 32 49
+32 49 4E 49 04 1B 5B 30 6D 00 32 49 58 51 9A 51
+A0 51 22 4D 1C 4D 86 41 42 4F 52 54 22 00 87 12
+68 49 34 44 28 4D B0 4B 2A 44 FA 49 01 27 87 12
+4C 46 A8 49 00 4A C0 45 BC 4D 2A 44 58 4C 52 46
+81 5C 92 42 BE 1D C2 1D 30 4D 87 12 84 49 4C 46
+A8 49 D4 4D 08 4E 7A 4E 5A D3 5A 53 0A 58 19 42
+C8 1D 6E 4E 3E F0 1E 00 09 5E 82 48 AE 1D 82 49
+B0 1D 82 4A B2 1D 2A 52 82 4A C4 1D 3E 4F 3D 41
+30 41 87 12 4E 49 0F 73 74 61 63 6B 20 6D 69 73
+6D 61 74 63 68 21 2E 4D 82 9F B4 1D F2 23 18 42
+AE 1D 19 42 B0 1D A8 49 FE FF 89 48 00 00 30 4D
+A2 49 08 56 41 52 49 41 42 4C 45 00 B0 12 CA 4D
+BA 40 86 12 FC FF EF 3F 00 4C 08 43 4F 4E 53 54
+41 4E 54 00 B0 12 CA 4D BA 40 85 12 FC FF 8A 4E
+FE FF 3E 4F E0 3F 4A 4E 06 43 52 45 41 54 45 00
+B0 12 CA 4D BA 40 85 12 FC FF 8A 4A FE FF D3 3F
+6E 4C 05 44 4F 45 53 3E 1A 42 B2 1D BA 40 84 12
+00 00 8A 4D 02 00 3D 41 30 4D 82 4E 05 44 45 46
+45 52 B0 12 CA 4D BA 40 30 40 FC FF BA 40 98 4E
+FE FF B9 3F 00 00 81 5B 82 43 B6 1D 30 4D C0 4D
+01 5D B2 43 B6 1D 30 4D 64 49 87 52 45 43 55 52
+53 45 19 42 C4 1D 99 42 B2 1D 00 00 A2 53 C4 1D
+30 4D B6 4E 01 3A B0 12 CA 4D BA 40 87 12 FC FF
+A2 83 C4 1D B2 43 B6 1D 82 4F B4 1D 30 4D E4 4E
+81 3B 82 93 B6 1D 5D 27 87 12 34 44 2A 44 B0 4B
+18 4E B8 4E 2A 44 D6 48 09 49 4D 4D 45 44 49 41
+54 45 1A 42 AE 1D FA D0 80 00 00 00 30 4D BE 4F
+02 00 3E 4F 30 4D 18 4F 82 49 53 00 87 12 42 46
+F4 44 C0 45 50 4F 5C 4F 34 44 2E 4F B0 4B 2A 44
+AE 4D 2E 4F 2A 44 00 4F 83 5B 27 5D 87 12 AE 4D
+34 44 34 44 B0 4B B0 4B 2A 44 9E 4C 88 50 4F 53
+54 50 4F 4E 45 00 87 12 4C 46 A8 49 00 4A 54 44
+C0 45 BC 4D 7E 45 C0 45 96 4F 34 44 34 44 B0 4B
+B0 4B 34 44 B0 4B B0 4B 2A 44 9C 4F 3A 4E 82 4A
+C6 1D 2E 4E 82 4E C4 1D 3D 40 10 00 09 4A 08 49
+29 83 18 48 FE FF 0E 98 FC 2B 89 48 00 00 1D 83
+F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41 30 4D 38 4F
+82 49 46 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40
+C0 45 00 00 A2 52 C4 1D 2E 53 30 4D 9C 4E 84 45
+4C 53 45 00 1A 42 C4 1D BA 40 BC 45 00 00 2A 52
+82 4A C4 1D 8E 4A 00 00 2A 83 0E 4A 30 4D 2C 49
+84 54 48 45 4E 00 9E 42 C4 1D 00 00 3E 4F 30 4D
+68 4E 85 42 45 47 49 4E 30 40 84 47 10 50 85 55
+4E 54 49 4C 39 40 C0 45 1A 42 C4 1D A2 52 C4 1D
+8A 49 00 00 8A 4E 02 00 3E 4F 30 4D 96 4D 85 41
+47 41 49 4E 39 40 BC 45 EF 3F 32 4E 85 57 48 49
+4C 45 87 12 D4 4F 6E 44 2A 44 CA 4E 86 52 45 50
+45 41 54 00 87 12 54 50 16 50 2A 44 EE 4F 82 44
+4F 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40 CA 45
+00 00 2E 53 82 4E C4 1D A2 53 AC 1D 1A 42 AC 1D
+8A 43 00 00 30 4D C2 4B 84 4C 4F 4F 50 00 39 40
+EC 45 1A 42 C4 1D A2 52 C4 1D 8A 49 00 00 8A 4E
+02 00 1E 42 AC 1D A2 83 AC 1D 2E 4E 0E 93 04 24
+9E 42 C4 1D 00 00 F5 3F 3E 4F 30 4D E4 47 85 2B
+4C 4F 4F 50 39 40 DA 45 E4 3F A8 50 85 4C 45 41
+56 45 1A 42 C4 1D BA 40 FC 45 00 00 BA 40 BC 45
+02 00 B2 50 06 00 C4 1D A2 53 AC 1D 2A 52 19 42
+AC 1D 89 4A 00 00 30 4D EC 50 04 4D 4F 56 45 00
+0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24 08 99 0F 24
+06 2C F8 49 00 00 18 53 1A 83 FB 23 30 4D 08 5A
+09 5A 19 83 18 83 E8 49 00 00 1A 83 FA 23 30 4D
+34 44 CA 1D FC 44 2A 44 84 12 50 51 36 54 1E 54
+7E 50 AC 4D 06 54 DE 50 1A 51 90 49 BE 51 F2 51
+2E 50 B2 52 48 45 58 4F C0 4E 68 4A 00 00 3A 40
+0C 00 39 40 CA 1D 38 40 CC 1D D9 3F 3A 40 0E 00
+39 40 CC 1D 38 40 CA 1D CC 3F 82 43 CC 1D 30 4D
+92 42 CA 1D C8 1D 30 4D 6C 4F 09 50 57 52 5F 53
+54 41 54 45 84 12 9A 4F 02 54 4C 5B AA 51 08 50
+57 52 5F 48 45 52 45 00 92 42 C4 1D BA 51 92 42
+C6 1D B8 51 EF 3F 6C 50 09 52 53 54 5F 53 54 41
+54 45 92 42 0C 18 BA 51 92 42 0E 18 B8 51 E2 3F
+D8 51 08 52 53 54 5F 48 45 52 45 00 92 42 C4 1D
+0C 18 92 42 C6 1D 0E 18 DF 3F B2 40 58 52 BA 52
+B2 40 A0 48 B0 48 B2 40 DC 48 F0 48 B2 40 DC 47
+EA 47 30 41 5C 50 04 57 49 50 45 00 39 40 80 FF
+B9 43 00 00 29 53 39 90 CC FF FA 23 B0 12 0A 52
+B2 40 4C 5B C4 1D B2 40 02 54 C6 1D D7 3F D0 4F
+06 28 57 41 52 4D 29 00 1E 42 08 18 87 12 4E 49
+05 0D 1B 5B 37 6D 32 49 70 47 4E 49 27 20 46 61
+73 74 46 6F 72 74 68 20 56 31 36 30 20 31 36 4D
+48 7A 20 28 43 29 20 4A 2E 4D 2E 54 68 6F 6F 72
+65 6E 73 20 32 49 34 44 30 FF 84 47 2A 45 30 47
+4E 49 0B 62 79 74 65 73 20 66 72 65 65 20 34 4D
+26 52 04 57 41 52 4D 00 30 40 58 52 22 50 04 43
+4F 4C 44 00 B2 40 04 A5 20 01 B2 40 88 5A 5C 01
+92 D3 04 02 B2 40 FE FF 02 02 A2 83 06 02 B2 40
+00 40 24 02 B2 40 FF BF 22 02 B2 D0 FF BF 26 02
+F2 43 22 03 F2 D3 26 03 F2 40 A5 00 41 01 F2 40
+10 00 40 01 D2 43 41 01 F2 40 A5 00 61 01 B2 40
+48 00 62 01 82 43 66 01 39 40 80 00 B2 40 33 00
+64 01 D2 43 61 01 92 D2 9E 01 08 18 A2 93 08 18
+01 24 59 07 38 40 C2 A2 18 83 FE 23 19 83 FA 23
+B2 D2 B0 01 F2 D0 10 00 2A 03 F2 C0 40 00 A1 04
+3A 40 CA 52 39 40 CC FF 89 4A 00 00 29 53 FC 23
+92 42 02 18 F0 FF B2 40 18 00 0A 18 31 40 E0 1C
+3F 40 80 1C 37 40 00 44 36 40 B4 44 35 40 08 44
+34 40 14 44 B2 40 0A 00 DA 1D B2 43 DC 1D 92 C3
+30 01 18 42 08 18 D2 B3 01 02 04 20 38 E3 18 53
+82 48 08 18 B2 40 81 00 C0 05 B2 42 C6 05 B2 40
+A1 F7 C8 05 F2 D0 03 00 0D 02 92 C3 C0 05 92 D3
+DA 05 3D 40 DC 53 18 42 08 18 38 90 0A 00 2E 27
+38 90 16 00 2B 2F 28 93 04 23 EC 26 B8 52 84 12
+50 51 2A 5A D6 5A DE 59 2A 5B A4 59 5E 5A A8 56
+00 00 9A 59 4A 5A FC 59 3A 5A B8 57 00 00 00 00
+3C 5B 7C 51 50 52 85 48 49 32 4C 4F 87 12 84 47
+E8 4F B0 4B B8 4E 7E 51 DE 53 2A 44 BE 52 04 43
+4F 44 45 00 B0 12 CA 4D A2 82 C4 1D 87 12 F8 4E
+BC 45 16 54 4E 50 03 41 53 4D 92 42 C8 1D B8 1D
+B2 40 E2 53 C8 1D EE 3F 00 00 07 45 4E 44 43 4F
+44 45 87 12 8C 51 18 4E 2A 44 4A 54 06 45 4E 44
+41 53 4D 00 92 42 B8 1D C8 1D F3 3F 00 00 05 43
+4F 4C 4F 4E 1A 42 C4 1D BA 40 87 12 00 00 A2 53
+C4 1D B2 43 B6 1D 30 40 8C 51 00 00 05 4C 4F 32
+48 49 1A 42 C4 1D BA 40 B0 12 00 00 BA 40 2A 44
+02 00 A2 52 C4 1D ED 3F 38 40 BE 1D 39 48 2A 48
+09 5A 1A 52 C2 1D 09 9A 03 24 7E 9A FC 27 1A 83
+0E 4A 2A 88 82 4A C2 1D 30 4D B0 12 2A 44 A8 49
+00 4A 72 45 C0 45 E0 54 BC 4A C0 45 BC 4D 02 55
+E2 54 29 4E 39 90 86 12 02 20 2E 53 30 41 39 90
+85 12 03 20 1E 4E 02 00 30 41 39 90 84 12 01 20
+2E 52 30 41 19 42 C4 1D A2 53 C4 1D 89 4E 00 00
+3E 40 29 00 12 12 C2 1D 92 53 C2 1D B0 12 2A 44
+A8 49 BC 4A C0 45 34 55 2A 55 21 53 3E 90 10 00
+BB 2D 30 41 36 55 B2 41 C2 1D 22 D3 30 41 87 12
+4C 46 A8 54 46 55 82 43 BC 1D 92 42 C4 1D BA 1D
+A2 53 C4 1D 0A 4E 3E 4F FA 90 23 00 00 00 34 20
+92 53 C2 1D B0 12 CA 54 0E 93 04 20 B2 40 00 03
+BC 1D 27 3C 1E 93 04 20 B2 40 10 03 BC 1D 21 3C
+2E 93 04 20 B2 40 20 03 BC 1D 1B 3C 2E 92 04 20
+B2 40 20 02 BC 1D 15 3C 3E 92 04 20 B2 40 30 02
+BC 1D 0F 3C 3E 93 04 20 B2 40 30 03 BC 1D 09 3C
+B2 40 30 00 BC 1D 19 42 C4 1D A2 53 C4 1D 89 4E
+00 00 3E 4F 3D 41 30 4D FA 90 26 00 00 00 08 20
+B2 40 10 02 BC 1D 92 53 C2 1D 30 12 B6 55 75 3F
+FA 90 40 00 00 00 1A 20 B2 40 20 00 BC 1D 92 53
+C2 1D B0 12 14 55 0E 20 B2 50 10 00 BC 1D 3E 40
+2B 00 B0 12 14 55 32 24 92 92 BE 1D C2 1D 02 24
+92 53 C2 1D 8E 10 82 5E BC 1D D3 3F B0 12 14 55
+F9 23 B2 50 10 00 BC 1D 3E 40 28 00 B0 12 CA 54
+30 12 06 56 67 3F 87 12 4C 46 A8 54 3E 56 FE 90
+26 00 00 00 3E 40 20 00 04 20 B2 50 82 00 BC 1D
+C2 3F B0 12 14 55 DF 23 B2 50 80 00 BC 1D 3E 40
+28 00 B0 12 CA 54 B0 12 04 55 D5 23 3D 40 BC 4D
+30 4D 00 00 04 52 45 54 49 00 87 12 34 44 00 13
+B0 4B 2A 44 34 44 2C 00 3E 55 36 56 8E 56 2E 4E
+1E D2 BC 1D 19 42 BA 1D 92 3F 8C 54 03 4D 4F 56
+84 12 84 56 00 40 9C 56 05 4D 4F 56 2E 42 84 12
+84 56 40 40 00 00 03 41 44 44 84 12 84 56 00 50
+B6 56 05 41 44 44 2E 42 84 12 84 56 40 50 C2 56
+04 41 44 44 43 00 84 12 84 56 00 60 D0 56 06 41
+44 44 43 2E 42 00 84 12 84 56 40 60 74 56 04 53
+55 42 43 00 84 12 84 56 00 70 EE 56 06 53 55 42
+43 2E 42 00 84 12 84 56 40 70 FC 56 03 53 55 42
+84 12 84 56 00 80 0C 57 05 53 55 42 2E 42 84 12
+84 56 40 80 6E 54 03 43 4D 50 84 12 84 56 00 90
+26 57 05 43 4D 50 2E 42 84 12 84 56 40 90 5C 54
+04 44 41 44 44 00 84 12 84 56 00 A0 40 57 06 44
+41 44 44 2E 42 00 84 12 84 56 40 A0 32 57 03 42
+49 54 84 12 84 56 00 B0 5E 57 05 42 49 54 2E 42
+84 12 84 56 40 B0 6A 57 03 42 49 43 84 12 84 56
+00 C0 78 57 05 42 49 43 2E 42 84 12 84 56 40 C0
+84 57 03 42 49 53 84 12 84 56 00 D0 92 57 05 42
+49 53 2E 42 84 12 84 56 40 D0 00 00 03 58 4F 52
+84 12 84 56 00 E0 AC 57 05 58 4F 52 2E 42 84 12
+84 56 40 E0 DE 56 03 41 4E 44 84 12 84 56 00 F0
+C6 57 05 41 4E 44 2E 42 84 12 84 56 40 F0 4C 46
+3E 55 E4 57 1A 42 BC 1D B2 F0 70 00 BC 1D 8A 10
+3A F0 0F 00 82 DA BC 1D 4A 3F 18 57 03 52 52 43
+84 12 DE 57 00 10 FC 57 05 52 52 43 2E 42 84 12
+DE 57 40 10 08 58 04 53 57 50 42 00 84 12 DE 57
+80 10 16 58 03 52 52 41 84 12 DE 57 00 11 24 58
+05 52 52 41 2E 42 84 12 DE 57 40 11 30 58 03 53
+58 54 84 12 DE 57 80 11 00 00 04 50 55 53 48 00
+84 12 DE 57 00 12 4A 58 06 50 55 53 48 2E 42 00
+84 12 DE 57 40 12 9E 57 04 43 41 4C 4C 00 84 12
+DE 57 80 12 34 44 2C 00 3E 55 36 56 7E 58 59 42
+BC 1D 5A 42 BD 1D 82 4A BC 1D BE 90 00 15 00 00
+02 20 0A 89 02 3C 09 8A 0A 49 3A 90 10 00 03 2C
+5A 0E A8 3F 1A 53 0E 4A 87 12 70 47 4E 49 0D 6F
+75 74 20 6F 66 20 62 6F 75 6E 64 73 2E 4D 58 58
+05 50 55 53 48 4D 84 12 74 58 00 15 C0 58 04 50
+4F 50 4D 00 84 12 74 58 00 17 4C 46 A8 54 E0 58
+82 43 BC 1D 92 42 C4 1D BA 1D A2 53 C4 1D 92 53
+C2 1D 3E 40 2C 00 B0 12 2A 44 A8 49 BC 4A C0 45
+BC 4D 36 56 06 59 0A 4E 3E 4F 1A 83 2A 92 CA 2F
+8A 10 5A 06 6F 3F 3E 58 04 52 52 43 4D 00 84 12
+DA 58 50 00 18 59 04 52 52 41 4D 00 84 12 DA 58
+50 01 26 59 04 52 4C 41 4D 00 84 12 DA 58 50 02
+34 59 04 52 52 55 4D 00 84 12 DA 58 50 03 85 12
+00 3C 42 59 03 53 3E 3D 85 12 00 38 54 59 02 53
+3C 00 85 12 00 34 CE 58 03 30 3E 3D 85 12 00 30
+68 59 02 30 3C 00 85 12 00 30 00 00 02 55 3C 00
+85 12 00 2C 7C 59 03 55 3E 3D 85 12 00 28 72 59
+03 30 3C 3E 85 12 00 24 90 59 02 30 3D 00 85 12
+00 20 00 00 02 49 46 00 1A 42 C4 1D 8A 4E 00 00
+A2 53 C4 1D 0E 4A 30 4D 86 59 04 54 48 45 4E 00
+1A 42 C4 1D 08 4E 3E 4F 09 48 29 53 0A 89 0A 11
+3A 90 00 02 68 2F 88 DA 00 00 30 4D 4E 57 04 45
+4C 53 45 00 1A 42 C4 1D BA 40 00 3C 00 00 A2 53
+C4 1D 2F 83 8F 4A 00 00 E3 3F BA 59 05 55 4E 54
+49 4C 3A 4F 08 4E 3E 4F 19 42 C4 1D 2A 83 0A 89
+0A 11 3A 90 00 FE 47 3B 3A F0 FF 03 08 DA 89 48
+00 00 A2 53 C4 1D 30 4D D2 57 05 41 47 41 49 4E
+87 12 4E 59 02 5A 2A 44 00 00 05 57 48 49 4C 45
+87 12 A8 59 6E 44 2A 44 5E 59 06 52 45 50 45 41
+54 00 87 12 4E 59 02 5A C0 59 2A 44 00 00 03 4A
+4D 50 87 12 AE 4D 4E 59 02 5A 2A 44 3E B0 00 10
+03 20 3E E0 00 04 30 4D 3E 90 00 34 06 28 03 24
+3E 40 00 34 30 4D 3E 40 00 38 30 4D 00 00 04 3F
+4A 4D 50 00 87 12 6C 5A AE 4D 6E 44 02 5A 2A 44
+A2 5A 3D 41 08 4E 3E 4F 2A 48 0A 93 04 20 98 42
+C4 1D 00 00 30 4D 88 43 00 00 A4 3F 68 58 03 42
+57 31 84 12 A0 5A 00 00 BE 5A 03 42 57 32 84 12
+A0 5A 00 00 CA 5A 03 42 57 33 84 12 A0 5A 00 00
+E2 5A 3D 41 1A 42 C4 1D 28 4E 08 93 08 20 BA 4F
+00 00 A2 53 C4 1D 8E 4A 00 00 3E 4F 30 4D 8E 43
+00 00 61 3F 00 00 03 46 57 31 84 12 E0 5A 00 00
+06 5B 03 46 57 32 84 12 E0 5A 00 00 12 5B 03 46
+57 33 84 12 E0 5A 00 00 1E 5B 04 47 4F 54 4F 00
+87 12 4E 59 AE 4D A6 4B 2A 44 8E 5A 05 3F 47 4F
+54 4F 87 12 6C 5A AE 4D A6 4B 2A 44
+@FFCC
+CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52
+CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52
+CA 52 CA 52 4C 48 CA 52 CA 52 CA 52 CA 52 CA 52
+CA 52 CA 52
+q
--- /dev/null
+@1800
+10 00 4C 48 80 3E 30 75 FD FF 18 00 4E 5B 04 54
+2A 48 38 48 00 00 00 00
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@4400
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 44
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 44 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 44 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E 44 02 3E 52 00 0E 12 3E 4F 30 4D 8E 44
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 44
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C 44 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 44 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 45
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 44 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA 44 03 41 4E 44 3E FF 30 4D 7A 44 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E 45 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 45 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E 45 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 45 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 44 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE 45 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 45 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 45 03 3E 49 4E 85 12 C2 1D 10 45
+04 42 41 53 45 00 85 12 DA 1D C0 44 05 53 54 41
+54 45 85 12 B6 1D 30 46 02 42 4C 00 85 12 20 00
+94 45 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 46 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E 46 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 46 02 23 53 00 87 12 98 46
+D2 46 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 46 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 46 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C 46 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 45 03 55 44 2E 87 12 56 46
+CC 46 E6 46 32 49 FA 48 2A 44 18 47 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA 44
+02 44 2E 00 87 12 56 46 6E 44 80 44 3A 47 CC 46
+92 44 0A 47 E6 46 32 49 FA 48 2A 44 52 45 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 46 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 45 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 46 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A 48
+92 B3 DC 05 FD 27 1E 42 CC 05 B0 12 38 48 30 4D
+30 40 B6 47 7E 47 05 28 4B 45 59 29 18 42 CC 05
+EA 3F 12 46 03 4B 45 59 30 40 DC 47 92 47 06 41
+43 43 45 50 54 00 3C 40 8A 48 3B 40 54 48 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+7E 48 92 B3 DC 05 05 24 18 42 CC 05 38 90 0A 00
+04 20 21 53 39 40 46 48 4D 15 B2 40 11 00 CE 05
+A2 B3 DC 05 FD 27 30 41 B2 40 13 00 CE 05 A2 B3
+DC 05 FD 27 30 41 12 D2 0A 18 FD 3F 21 52 3A 17
+58 42 CC 05 48 9B F0 27 48 9C 06 2C 78 92 11 20
+2E 9F 0F 24 1E 83 05 3C 0E 9A 03 24 CE 48 00 00
+1E 53 82 48 CE 05 A2 B3 DC 05 FD 27 30 4D 80 48
+2D 83 92 B3 DC 05 FD 27 E3 23 B2 40 18 00 0A 18
+3E 8F 3D 41 30 4D D6 47 06 28 45 4D 49 54 29 00
+08 4E 3E 4F E6 3F 50 47 04 45 4D 49 54 00 30 40
+A0 48 A8 48 04 45 43 48 4F 00 B2 40 82 48 72 48
+30 4D 6E 47 06 4E 4F 45 43 48 4F 00 B2 40 30 4D
+72 48 30 4D 98 48 04 28 43 52 29 00 2F 83 8F 4E
+00 00 3E 40 0D 00 E3 3F A2 47 02 43 52 00 30 40
+DC 48 04 47 05 53 50 41 43 45 2F 83 8F 4E 00 00
+3E 40 20 00 D4 3F F4 48 06 53 50 41 43 45 53 00
+0E 93 09 24 0D 12 3D 40 1C 49 EF 3F 1E 49 2D 83
+1E 83 EB 23 3D 41 3E 4F 30 4D 2C 47 04 54 59 50
+45 00 0E 93 95 24 2A 4F 8F 5E 00 00 0E 4A 87 12
+CA 45 02 46 0A 45 AE 48 EC 45 42 49 2A 44 2F 82
+8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E 1D B3 0D 63
+30 4D 08 49 82 53 22 00 87 12 34 44 4E 49 B0 4B
+34 44 22 00 A8 49 78 49 3D 41 6E 4E 1E 83 82 5E
+C4 1D 3E 4F 92 B3 C4 1D A2 63 C4 1D 30 4D C4 48
+82 2E 22 00 87 12 68 49 34 44 32 49 B0 4B 2A 44
+00 00 04 57 4F 52 44 00 3C 40 BE 1D 39 4C 3A 4C
+09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A FC 27 1A 83
+3B 40 60 00 C8 4C 00 00 09 9A 0C 24 7C 4A 4E 9C
+09 24 18 53 4B 9C F6 2F 7C 90 7B 00 F3 2F 7C 80
+20 00 F0 3F 1A 82 C0 1D 82 4A C2 1D 1E 42 C4 1D
+08 8E CE 48 00 00 30 4D 00 00 04 46 49 4E 44 00
+2F 83 0C 4E 65 4C 74 40 80 00 3B 40 CA 1D 3E 4B
+0E 93 1E 24 58 4C 01 00 78 F0 1E 00 0E 58 2E 53
+1E 4E FE FF 0E 93 F3 27 09 4E 78 49 48 C4 48 95
+F7 23 0A 4C 1A 53 FA 99 00 00 F2 23 58 83 FA 23
+19 B3 09 63 0C 49 6A 4E 1E 43 4A 93 01 30 2E 83
+8F 4C 00 00 35 40 08 44 34 40 14 44 30 4D 2F 53
+2F 53 3E 4F 30 4D 26 46 07 3E 4E 55 4D 42 45 52
+3C 4F 38 4F 29 4F 2F 82 1B 42 DA 1D 6A 4C 7A 80
+30 00 7A 90 0A 00 02 28 7A 80 07 00 0A 9B 13 2C
+82 49 D0 04 82 48 D2 04 82 4B C8 04 19 42 E4 04
+18 42 E6 04 09 5A 08 63 1C 53 1E 83 E7 23 8F 49
+04 00 8F 48 02 00 8F 4C 00 00 30 4D 03 12 0D 12
+1B 42 DA 1D 0B 12 32 C0 00 02 6D 4E 0D 5E 0C 4E
+7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23 32 D0 00 02
+FC 4C FE FF 0D 9C FC 2F DE 83 00 00 09 43 08 43
+3D 40 32 4B 3F 82 8F 4E 06 00 0C 4E 7E 4C 6A 4C
+7A 90 2D 00 10 2C 3B 40 10 00 7A 80 24 00 06 24
+2B 43 5A 83 03 24 3B 52 6A 53 B0 23 1C 53 1E 83
+6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83 B1 43 04 00
+A5 3F 34 4B 2F 53 0E 93 2C 17 82 4C DA 1D 03 24
+2F 52 0E F3 30 4D 8F 93 00 00 15 20 32 B0 00 02
+14 20 0E 93 05 24 1A 4F 02 00 1A 83 0A 93 0B 38
+2F 53 BF 4F 00 00 3E E3 05 20 BF E3 00 00 9F 53
+00 00 3E E3 30 4D 32 D0 00 02 9F 4F 02 00 04 00
+BF 4F 00 00 3E E3 F6 23 BF E3 02 00 BF E3 00 00
+9F 53 02 00 8F 63 00 00 3E E3 30 4D B4 48 07 45
+58 45 43 55 54 45 0A 4E 3E 4F 00 4A 28 45 01 2C
+1A 42 C4 1D A2 53 C4 1D 8A 4E 00 00 3E 4F 30 4D
+AE 4B 87 4C 49 54 45 52 41 4C 82 93 B6 1D 16 24
+32 B0 00 02 09 24 1A 42 C4 1D A2 52 C4 1D BA 40
+34 44 00 00 BA 4F 02 00 1A 42 C4 1D A2 52 C4 1D
+BA 40 34 44 00 00 8A 4E 02 00 3E 4F 30 4D EA 48
+05 43 4F 55 4E 54 2F 83 1E 53 8F 4E 00 00 5E 4E
+FF FF 30 4D 82 4E BE 1D B2 4F C0 1D 3E 4F 82 43
+C2 1D 87 12 4C 46 A8 49 2A 4C 3D 40 36 4C E8 22
+3D 41 3E 4F 30 4D 38 4C 0A 4E 3E 4F 3D 40 4E 4C
+3D 27 3D 40 24 4C 1A E2 B6 1D B2 27 AC 23 50 4C
+3E 4F 3D 40 24 4C B9 23 DE 53 00 00 68 4E 08 5E
+F8 40 3F 00 00 00 3D 40 16 4E CD 3F 9E 4B 08 45
+56 41 4C 55 41 54 45 00 39 40 BE 1D 39 12 39 12
+39 12 0D 12 B0 12 2A 44 14 4C 8C 4C 3D 41 B2 41
+C2 1D B2 41 C0 1D B2 41 BE 1D 30 4D 7A 45 04 51
+55 49 54 00 31 40 E0 1C B2 40 00 1C AC 1D 82 43
+B6 1D 82 43 08 18 B0 12 2A 44 4E 49 04 0D 6F 6B
+20 00 32 49 34 44 38 1D 44 44 34 44 50 00 F6 47
+FA 48 14 4C 34 44 7E 1C CE 44 B2 45 4E 49 0D 73
+74 61 63 6B 20 65 6D 70 74 79 20 21 28 4D 34 44
+30 FF 84 47 B2 45 4E 49 0B 46 52 41 4D 20 66 75
+6C 6C 20 21 28 4D 42 46 F4 44 C0 45 BA 4C 4E 49
+04 0D 20 20 20 00 BC 45 C2 4C EE 47 05 41 42 4F
+52 54 3F 40 80 1C BE 3F 8F 93 02 00 98 26 B2 40
+82 48 72 48 B0 12 10 52 82 43 C8 5A 82 43 D4 5A
+82 43 E0 5A 82 43 10 5B 82 43 1C 5B 82 43 28 5B
+A2 B3 DC 05 FD 27 B2 40 11 00 CE 05 92 C3 DC 05
+38 40 A0 AA 39 42 19 83 FE 23 18 83 FB 23 92 B3
+DC 05 F4 23 87 12 4E 49 04 1B 5B 37 6D 00 32 49
+32 49 4E 49 04 1B 5B 30 6D 00 32 49 58 51 9A 51
+A0 51 22 4D 1C 4D 86 41 42 4F 52 54 22 00 87 12
+68 49 34 44 28 4D B0 4B 2A 44 FA 49 01 27 87 12
+4C 46 A8 49 00 4A C0 45 BC 4D 2A 44 58 4C 52 46
+81 5C 92 42 BE 1D C2 1D 30 4D 87 12 84 49 4C 46
+A8 49 D4 4D 08 4E 7A 4E 5A D3 5A 53 0A 58 19 42
+C8 1D 6E 4E 3E F0 1E 00 09 5E 82 48 AE 1D 82 49
+B0 1D 82 4A B2 1D 2A 52 82 4A C4 1D 3E 4F 3D 41
+30 41 87 12 4E 49 0F 73 74 61 63 6B 20 6D 69 73
+6D 61 74 63 68 21 2E 4D 82 9F B4 1D F2 23 18 42
+AE 1D 19 42 B0 1D A8 49 FE FF 89 48 00 00 30 4D
+A2 49 08 56 41 52 49 41 42 4C 45 00 B0 12 CA 4D
+BA 40 86 12 FC FF EF 3F 00 4C 08 43 4F 4E 53 54
+41 4E 54 00 B0 12 CA 4D BA 40 85 12 FC FF 8A 4E
+FE FF 3E 4F E0 3F 4A 4E 06 43 52 45 41 54 45 00
+B0 12 CA 4D BA 40 85 12 FC FF 8A 4A FE FF D3 3F
+6E 4C 05 44 4F 45 53 3E 1A 42 B2 1D BA 40 84 12
+00 00 8A 4D 02 00 3D 41 30 4D 82 4E 05 44 45 46
+45 52 B0 12 CA 4D BA 40 30 40 FC FF BA 40 98 4E
+FE FF B9 3F 00 00 81 5B 82 43 B6 1D 30 4D C0 4D
+01 5D B2 43 B6 1D 30 4D 64 49 87 52 45 43 55 52
+53 45 19 42 C4 1D 99 42 B2 1D 00 00 A2 53 C4 1D
+30 4D B6 4E 01 3A B0 12 CA 4D BA 40 87 12 FC FF
+A2 83 C4 1D B2 43 B6 1D 82 4F B4 1D 30 4D E4 4E
+81 3B 82 93 B6 1D 5D 27 87 12 34 44 2A 44 B0 4B
+18 4E B8 4E 2A 44 D6 48 09 49 4D 4D 45 44 49 41
+54 45 1A 42 AE 1D FA D0 80 00 00 00 30 4D BE 4F
+02 00 3E 4F 30 4D 18 4F 82 49 53 00 87 12 42 46
+F4 44 C0 45 50 4F 5C 4F 34 44 2E 4F B0 4B 2A 44
+AE 4D 2E 4F 2A 44 00 4F 83 5B 27 5D 87 12 AE 4D
+34 44 34 44 B0 4B B0 4B 2A 44 9E 4C 88 50 4F 53
+54 50 4F 4E 45 00 87 12 4C 46 A8 49 00 4A 54 44
+C0 45 BC 4D 7E 45 C0 45 96 4F 34 44 34 44 B0 4B
+B0 4B 34 44 B0 4B B0 4B 2A 44 9C 4F 3A 4E 82 4A
+C6 1D 2E 4E 82 4E C4 1D 3D 40 10 00 09 4A 08 49
+29 83 18 48 FE FF 0E 98 FC 2B 89 48 00 00 1D 83
+F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41 30 4D 38 4F
+82 49 46 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40
+C0 45 00 00 A2 52 C4 1D 2E 53 30 4D 9C 4E 84 45
+4C 53 45 00 1A 42 C4 1D BA 40 BC 45 00 00 2A 52
+82 4A C4 1D 8E 4A 00 00 2A 83 0E 4A 30 4D 2C 49
+84 54 48 45 4E 00 9E 42 C4 1D 00 00 3E 4F 30 4D
+68 4E 85 42 45 47 49 4E 30 40 84 47 10 50 85 55
+4E 54 49 4C 39 40 C0 45 1A 42 C4 1D A2 52 C4 1D
+8A 49 00 00 8A 4E 02 00 3E 4F 30 4D 96 4D 85 41
+47 41 49 4E 39 40 BC 45 EF 3F 32 4E 85 57 48 49
+4C 45 87 12 D4 4F 6E 44 2A 44 CA 4E 86 52 45 50
+45 41 54 00 87 12 54 50 16 50 2A 44 EE 4F 82 44
+4F 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40 CA 45
+00 00 2E 53 82 4E C4 1D A2 53 AC 1D 1A 42 AC 1D
+8A 43 00 00 30 4D C2 4B 84 4C 4F 4F 50 00 39 40
+EC 45 1A 42 C4 1D A2 52 C4 1D 8A 49 00 00 8A 4E
+02 00 1E 42 AC 1D A2 83 AC 1D 2E 4E 0E 93 04 24
+9E 42 C4 1D 00 00 F5 3F 3E 4F 30 4D E4 47 85 2B
+4C 4F 4F 50 39 40 DA 45 E4 3F A8 50 85 4C 45 41
+56 45 1A 42 C4 1D BA 40 FC 45 00 00 BA 40 BC 45
+02 00 B2 50 06 00 C4 1D A2 53 AC 1D 2A 52 19 42
+AC 1D 89 4A 00 00 30 4D EC 50 04 4D 4F 56 45 00
+0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24 08 99 0F 24
+06 2C F8 49 00 00 18 53 1A 83 FB 23 30 4D 08 5A
+09 5A 19 83 18 83 E8 49 00 00 1A 83 FA 23 30 4D
+34 44 CA 1D FC 44 2A 44 84 12 50 51 38 54 20 54
+7E 50 AC 4D 08 54 DE 50 1A 51 90 49 BE 51 F2 51
+2E 50 B2 52 48 45 58 4F C0 4E 68 4A 00 00 3A 40
+0C 00 39 40 CA 1D 38 40 CC 1D D9 3F 3A 40 0E 00
+39 40 CC 1D 38 40 CA 1D CC 3F 82 43 CC 1D 30 4D
+92 42 CA 1D C8 1D 30 4D 6C 4F 09 50 57 52 5F 53
+54 41 54 45 84 12 9A 4F 04 54 4E 5B AA 51 08 50
+57 52 5F 48 45 52 45 00 92 42 C4 1D BA 51 92 42
+C6 1D B8 51 EF 3F 6C 50 09 52 53 54 5F 53 54 41
+54 45 92 42 0C 18 BA 51 92 42 0E 18 B8 51 E2 3F
+D8 51 08 52 53 54 5F 48 45 52 45 00 92 42 C4 1D
+0C 18 92 42 C6 1D 0E 18 DF 3F B2 40 58 52 BA 52
+B2 40 A0 48 B0 48 B2 40 DC 48 F0 48 B2 40 DC 47
+EA 47 30 41 5C 50 04 57 49 50 45 00 39 40 80 FF
+B9 43 00 00 29 53 39 90 CC FF FA 23 B0 12 0A 52
+B2 40 4E 5B C4 1D B2 40 04 54 C6 1D D7 3F D0 4F
+06 28 57 41 52 4D 29 00 1E 42 08 18 87 12 4E 49
+05 0D 1B 5B 37 6D 32 49 70 47 4E 49 27 20 46 61
+73 74 46 6F 72 74 68 20 56 31 36 30 20 31 36 4D
+48 7A 20 28 43 29 20 4A 2E 4D 2E 54 68 6F 6F 72
+65 6E 73 20 32 49 34 44 30 FF 84 47 2A 45 30 47
+4E 49 0B 62 79 74 65 73 20 66 72 65 65 20 34 4D
+26 52 04 57 41 52 4D 00 30 40 58 52 22 50 04 43
+4F 4C 44 00 B2 40 04 A5 20 01 B2 40 88 5A 5C 01
+92 D3 04 02 B2 40 FE FF 02 02 A2 83 06 02 B2 40
+00 40 24 02 B2 40 FF BF 22 02 B2 D0 FF BF 26 02
+F2 43 22 03 F2 D3 26 03 F2 40 A5 00 41 01 F2 40
+10 00 40 01 D2 43 41 01 F2 40 A5 00 61 01 B2 40
+48 00 62 01 82 43 66 01 39 40 80 00 B2 40 33 00
+64 01 D2 43 61 01 92 D2 9E 01 08 18 A2 93 08 18
+01 24 59 07 38 40 C2 A2 18 83 FE 23 19 83 FA 23
+B2 D2 B0 01 F2 D0 10 00 2A 03 F2 C0 40 00 A1 04
+3A 40 CA 52 39 40 CC FF 89 4A 00 00 29 53 FC 23
+92 42 02 18 F0 FF B2 40 18 00 0A 18 31 40 E0 1C
+3F 40 80 1C 37 40 00 44 36 40 B4 44 35 40 08 44
+34 40 14 44 B2 40 0A 00 DA 1D B2 43 DC 1D 92 C3
+30 01 18 42 08 18 D2 B3 01 02 04 20 38 E3 18 53
+82 48 08 18 B2 40 81 00 C0 05 B2 40 05 00 C6 05
+B2 40 00 49 C8 05 F2 D0 03 00 0D 02 92 C3 C0 05
+92 D3 DA 05 3D 40 DE 53 18 42 08 18 38 90 0A 00
+2D 27 38 90 16 00 2A 2F 28 93 03 23 EB 26 B8 52
+84 12 50 51 2C 5A D8 5A E0 59 2C 5B A6 59 60 5A
+AA 56 00 00 9C 59 4C 5A FE 59 3C 5A BA 57 00 00
+00 00 3E 5B 7C 51 50 52 85 48 49 32 4C 4F 87 12
+84 47 E8 4F B0 4B B8 4E 7E 51 E0 53 2A 44 BE 52
+04 43 4F 44 45 00 B0 12 CA 4D A2 82 C4 1D 87 12
+F8 4E BC 45 18 54 4E 50 03 41 53 4D 92 42 C8 1D
+B8 1D B2 40 E4 53 C8 1D EE 3F 00 00 07 45 4E 44
+43 4F 44 45 87 12 8C 51 18 4E 2A 44 4C 54 06 45
+4E 44 41 53 4D 00 92 42 B8 1D C8 1D F3 3F 00 00
+05 43 4F 4C 4F 4E 1A 42 C4 1D BA 40 87 12 00 00
+A2 53 C4 1D B2 43 B6 1D 30 40 8C 51 00 00 05 4C
+4F 32 48 49 1A 42 C4 1D BA 40 B0 12 00 00 BA 40
+2A 44 02 00 A2 52 C4 1D ED 3F 38 40 BE 1D 39 48
+2A 48 09 5A 1A 52 C2 1D 09 9A 03 24 7E 9A FC 27
+1A 83 0E 4A 2A 88 82 4A C2 1D 30 4D B0 12 2A 44
+A8 49 00 4A 72 45 C0 45 E2 54 BC 4A C0 45 BC 4D
+04 55 E4 54 29 4E 39 90 86 12 02 20 2E 53 30 41
+39 90 85 12 03 20 1E 4E 02 00 30 41 39 90 84 12
+01 20 2E 52 30 41 19 42 C4 1D A2 53 C4 1D 89 4E
+00 00 3E 40 29 00 12 12 C2 1D 92 53 C2 1D B0 12
+2A 44 A8 49 BC 4A C0 45 36 55 2C 55 21 53 3E 90
+10 00 BB 2D 30 41 38 55 B2 41 C2 1D 22 D3 30 41
+87 12 4C 46 AA 54 48 55 82 43 BC 1D 92 42 C4 1D
+BA 1D A2 53 C4 1D 0A 4E 3E 4F FA 90 23 00 00 00
+34 20 92 53 C2 1D B0 12 CC 54 0E 93 04 20 B2 40
+00 03 BC 1D 27 3C 1E 93 04 20 B2 40 10 03 BC 1D
+21 3C 2E 93 04 20 B2 40 20 03 BC 1D 1B 3C 2E 92
+04 20 B2 40 20 02 BC 1D 15 3C 3E 92 04 20 B2 40
+30 02 BC 1D 0F 3C 3E 93 04 20 B2 40 30 03 BC 1D
+09 3C B2 40 30 00 BC 1D 19 42 C4 1D A2 53 C4 1D
+89 4E 00 00 3E 4F 3D 41 30 4D FA 90 26 00 00 00
+08 20 B2 40 10 02 BC 1D 92 53 C2 1D 30 12 B8 55
+75 3F FA 90 40 00 00 00 1A 20 B2 40 20 00 BC 1D
+92 53 C2 1D B0 12 16 55 0E 20 B2 50 10 00 BC 1D
+3E 40 2B 00 B0 12 16 55 32 24 92 92 BE 1D C2 1D
+02 24 92 53 C2 1D 8E 10 82 5E BC 1D D3 3F B0 12
+16 55 F9 23 B2 50 10 00 BC 1D 3E 40 28 00 B0 12
+CC 54 30 12 08 56 67 3F 87 12 4C 46 AA 54 40 56
+FE 90 26 00 00 00 3E 40 20 00 04 20 B2 50 82 00
+BC 1D C2 3F B0 12 16 55 DF 23 B2 50 80 00 BC 1D
+3E 40 28 00 B0 12 CC 54 B0 12 06 55 D5 23 3D 40
+BC 4D 30 4D 00 00 04 52 45 54 49 00 87 12 34 44
+00 13 B0 4B 2A 44 34 44 2C 00 40 55 38 56 90 56
+2E 4E 1E D2 BC 1D 19 42 BA 1D 92 3F 8E 54 03 4D
+4F 56 84 12 86 56 00 40 9E 56 05 4D 4F 56 2E 42
+84 12 86 56 40 40 00 00 03 41 44 44 84 12 86 56
+00 50 B8 56 05 41 44 44 2E 42 84 12 86 56 40 50
+C4 56 04 41 44 44 43 00 84 12 86 56 00 60 D2 56
+06 41 44 44 43 2E 42 00 84 12 86 56 40 60 76 56
+04 53 55 42 43 00 84 12 86 56 00 70 F0 56 06 53
+55 42 43 2E 42 00 84 12 86 56 40 70 FE 56 03 53
+55 42 84 12 86 56 00 80 0E 57 05 53 55 42 2E 42
+84 12 86 56 40 80 70 54 03 43 4D 50 84 12 86 56
+00 90 28 57 05 43 4D 50 2E 42 84 12 86 56 40 90
+5E 54 04 44 41 44 44 00 84 12 86 56 00 A0 42 57
+06 44 41 44 44 2E 42 00 84 12 86 56 40 A0 34 57
+03 42 49 54 84 12 86 56 00 B0 60 57 05 42 49 54
+2E 42 84 12 86 56 40 B0 6C 57 03 42 49 43 84 12
+86 56 00 C0 7A 57 05 42 49 43 2E 42 84 12 86 56
+40 C0 86 57 03 42 49 53 84 12 86 56 00 D0 94 57
+05 42 49 53 2E 42 84 12 86 56 40 D0 00 00 03 58
+4F 52 84 12 86 56 00 E0 AE 57 05 58 4F 52 2E 42
+84 12 86 56 40 E0 E0 56 03 41 4E 44 84 12 86 56
+00 F0 C8 57 05 41 4E 44 2E 42 84 12 86 56 40 F0
+4C 46 40 55 E6 57 1A 42 BC 1D B2 F0 70 00 BC 1D
+8A 10 3A F0 0F 00 82 DA BC 1D 4A 3F 1A 57 03 52
+52 43 84 12 E0 57 00 10 FE 57 05 52 52 43 2E 42
+84 12 E0 57 40 10 0A 58 04 53 57 50 42 00 84 12
+E0 57 80 10 18 58 03 52 52 41 84 12 E0 57 00 11
+26 58 05 52 52 41 2E 42 84 12 E0 57 40 11 32 58
+03 53 58 54 84 12 E0 57 80 11 00 00 04 50 55 53
+48 00 84 12 E0 57 00 12 4C 58 06 50 55 53 48 2E
+42 00 84 12 E0 57 40 12 A0 57 04 43 41 4C 4C 00
+84 12 E0 57 80 12 34 44 2C 00 40 55 38 56 80 58
+59 42 BC 1D 5A 42 BD 1D 82 4A BC 1D BE 90 00 15
+00 00 02 20 0A 89 02 3C 09 8A 0A 49 3A 90 10 00
+03 2C 5A 0E A8 3F 1A 53 0E 4A 87 12 70 47 4E 49
+0D 6F 75 74 20 6F 66 20 62 6F 75 6E 64 73 2E 4D
+5A 58 05 50 55 53 48 4D 84 12 76 58 00 15 C2 58
+04 50 4F 50 4D 00 84 12 76 58 00 17 4C 46 AA 54
+E2 58 82 43 BC 1D 92 42 C4 1D BA 1D A2 53 C4 1D
+92 53 C2 1D 3E 40 2C 00 B0 12 2A 44 A8 49 BC 4A
+C0 45 BC 4D 38 56 08 59 0A 4E 3E 4F 1A 83 2A 92
+CA 2F 8A 10 5A 06 6F 3F 40 58 04 52 52 43 4D 00
+84 12 DC 58 50 00 1A 59 04 52 52 41 4D 00 84 12
+DC 58 50 01 28 59 04 52 4C 41 4D 00 84 12 DC 58
+50 02 36 59 04 52 52 55 4D 00 84 12 DC 58 50 03
+85 12 00 3C 44 59 03 53 3E 3D 85 12 00 38 56 59
+02 53 3C 00 85 12 00 34 D0 58 03 30 3E 3D 85 12
+00 30 6A 59 02 30 3C 00 85 12 00 30 00 00 02 55
+3C 00 85 12 00 2C 7E 59 03 55 3E 3D 85 12 00 28
+74 59 03 30 3C 3E 85 12 00 24 92 59 02 30 3D 00
+85 12 00 20 00 00 02 49 46 00 1A 42 C4 1D 8A 4E
+00 00 A2 53 C4 1D 0E 4A 30 4D 88 59 04 54 48 45
+4E 00 1A 42 C4 1D 08 4E 3E 4F 09 48 29 53 0A 89
+0A 11 3A 90 00 02 68 2F 88 DA 00 00 30 4D 50 57
+04 45 4C 53 45 00 1A 42 C4 1D BA 40 00 3C 00 00
+A2 53 C4 1D 2F 83 8F 4A 00 00 E3 3F BC 59 05 55
+4E 54 49 4C 3A 4F 08 4E 3E 4F 19 42 C4 1D 2A 83
+0A 89 0A 11 3A 90 00 FE 47 3B 3A F0 FF 03 08 DA
+89 48 00 00 A2 53 C4 1D 30 4D D4 57 05 41 47 41
+49 4E 87 12 50 59 04 5A 2A 44 00 00 05 57 48 49
+4C 45 87 12 AA 59 6E 44 2A 44 60 59 06 52 45 50
+45 41 54 00 87 12 50 59 04 5A C2 59 2A 44 00 00
+03 4A 4D 50 87 12 AE 4D 50 59 04 5A 2A 44 3E B0
+00 10 03 20 3E E0 00 04 30 4D 3E 90 00 34 06 28
+03 24 3E 40 00 34 30 4D 3E 40 00 38 30 4D 00 00
+04 3F 4A 4D 50 00 87 12 6E 5A AE 4D 6E 44 04 5A
+2A 44 A4 5A 3D 41 08 4E 3E 4F 2A 48 0A 93 04 20
+98 42 C4 1D 00 00 30 4D 88 43 00 00 A4 3F 6A 58
+03 42 57 31 84 12 A2 5A 00 00 C0 5A 03 42 57 32
+84 12 A2 5A 00 00 CC 5A 03 42 57 33 84 12 A2 5A
+00 00 E4 5A 3D 41 1A 42 C4 1D 28 4E 08 93 08 20
+BA 4F 00 00 A2 53 C4 1D 8E 4A 00 00 3E 4F 30 4D
+8E 43 00 00 61 3F 00 00 03 46 57 31 84 12 E2 5A
+00 00 08 5B 03 46 57 32 84 12 E2 5A 00 00 14 5B
+03 46 57 33 84 12 E2 5A 00 00 20 5B 04 47 4F 54
+4F 00 87 12 50 59 AE 4D A6 4B 2A 44 90 5A 05 3F
+47 4F 54 4F 87 12 6E 5A AE 4D A6 4B 2A 44
+@FFCC
+CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52
+CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52
+CA 52 CA 52 4C 48 CA 52 CA 52 CA 52 CA 52 CA 52
+CA 52 CA 52
+q
--- /dev/null
+@1800
+10 00 40 48 F4 01 80 04 FD FF 18 00 2E 5B E4 53
+2A 48 32 48 00 00 00 00
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@4400
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 44
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 44 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 44 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E 44 02 3E 52 00 0E 12 3E 4F 30 4D 8E 44
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 44
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C 44 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 44 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 45
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 44 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA 44 03 41 4E 44 3E FF 30 4D 7A 44 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E 45 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 45 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E 45 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 45 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 44 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE 45 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 45 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 45 03 3E 49 4E 85 12 C2 1D 10 45
+04 42 41 53 45 00 85 12 DA 1D C0 44 05 53 54 41
+54 45 85 12 B6 1D 30 46 02 42 4C 00 85 12 20 00
+94 45 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 46 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E 46 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 46 02 23 53 00 87 12 98 46
+D2 46 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 46 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 46 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C 46 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 45 03 55 44 2E 87 12 56 46
+CC 46 E6 46 26 49 EE 48 2A 44 18 47 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA 44
+02 44 2E 00 87 12 56 46 6E 44 80 44 3A 47 CC 46
+92 44 0A 47 E6 46 26 49 EE 48 2A 44 52 45 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 46 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 45 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 46 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A 48
+92 B3 DC 05 FD 27 1E 42 CC 05 B0 12 32 48 30 4D
+30 40 B6 47 7E 47 05 28 4B 45 59 29 18 42 CC 05
+EA 3F 12 46 03 4B 45 59 30 40 DC 47 92 47 06 41
+43 43 45 50 54 00 3C 40 78 48 3B 40 48 48 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+6C 48 92 B3 DC 05 05 24 18 42 CC 05 38 90 0A 00
+04 20 21 53 39 40 3A 48 4D 15 B2 40 11 00 CE 05
+30 41 B2 40 13 00 CE 05 30 41 12 D2 0A 18 FD 3F
+21 52 3A 17 58 42 CC 05 48 9B F3 27 48 9C 06 2C
+78 92 0E 20 2E 9F 0C 24 1E 83 05 3C 0E 9A 03 24
+CE 48 00 00 1E 53 82 48 CE 05 30 4D 6E 48 2D 83
+92 B3 DC 05 FD 27 E6 23 B2 40 18 00 0A 18 3E 8F
+3D 41 30 4D D6 47 06 28 45 4D 49 54 29 00 08 4E
+3E 4F A2 B3 DC 05 FD 27 E6 3F 50 47 04 45 4D 49
+54 00 30 40 8E 48 9C 48 04 45 43 48 4F 00 B2 40
+82 48 66 48 30 4D 6E 47 06 4E 4F 45 43 48 4F 00
+B2 40 30 4D 66 48 30 4D 86 48 04 28 43 52 29 00
+2F 83 8F 4E 00 00 3E 40 0D 00 E3 3F A2 47 02 43
+52 00 30 40 D0 48 04 47 05 53 50 41 43 45 2F 83
+8F 4E 00 00 3E 40 20 00 D4 3F E8 48 06 53 50 41
+43 45 53 00 0E 93 09 24 0D 12 3D 40 10 49 EF 3F
+12 49 2D 83 1E 83 EB 23 3D 41 3E 4F 30 4D 2C 47
+04 54 59 50 45 00 0E 93 95 24 2A 4F 8F 5E 00 00
+0E 4A 87 12 CA 45 02 46 0A 45 A2 48 EC 45 36 49
+2A 44 2F 82 8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E
+1D B3 0D 63 30 4D FC 48 82 53 22 00 87 12 34 44
+42 49 A4 4B 34 44 22 00 9C 49 6C 49 3D 41 6E 4E
+1E 83 82 5E C4 1D 3E 4F 92 B3 C4 1D A2 63 C4 1D
+30 4D B8 48 82 2E 22 00 87 12 5C 49 34 44 26 49
+A4 4B 2A 44 00 00 04 57 4F 52 44 00 3C 40 BE 1D
+39 4C 3A 4C 09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A
+FC 27 1A 83 3B 40 60 00 C8 4C 00 00 09 9A 0C 24
+7C 4A 4E 9C 09 24 18 53 4B 9C F6 2F 7C 90 7B 00
+F3 2F 7C 80 20 00 F0 3F 1A 82 C0 1D 82 4A C2 1D
+1E 42 C4 1D 08 8E CE 48 00 00 30 4D 00 00 04 46
+49 4E 44 00 2F 83 0C 4E 65 4C 74 40 80 00 3B 40
+CA 1D 3E 4B 0E 93 1E 24 58 4C 01 00 78 F0 1E 00
+0E 58 2E 53 1E 4E FE FF 0E 93 F3 27 09 4E 78 49
+48 C4 48 95 F7 23 0A 4C 1A 53 FA 99 00 00 F2 23
+58 83 FA 23 19 B3 09 63 0C 49 6A 4E 1E 43 4A 93
+01 30 2E 83 8F 4C 00 00 35 40 08 44 34 40 14 44
+30 4D 2F 53 2F 53 3E 4F 30 4D 26 46 07 3E 4E 55
+4D 42 45 52 3C 4F 38 4F 29 4F 2F 82 1B 42 DA 1D
+6A 4C 7A 80 30 00 7A 90 0A 00 02 28 7A 80 07 00
+0A 9B 13 2C 82 49 D0 04 82 48 D2 04 82 4B C8 04
+19 42 E4 04 18 42 E6 04 09 5A 08 63 1C 53 1E 83
+E7 23 8F 49 04 00 8F 48 02 00 8F 4C 00 00 30 4D
+03 12 0D 12 1B 42 DA 1D 0B 12 32 C0 00 02 6D 4E
+0D 5E 0C 4E 7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23
+32 D0 00 02 FC 4C FE FF 0D 9C FC 2F DE 83 00 00
+09 43 08 43 3D 40 26 4B 3F 82 8F 4E 06 00 0C 4E
+7E 4C 6A 4C 7A 90 2D 00 10 2C 3B 40 10 00 7A 80
+24 00 06 24 2B 43 5A 83 03 24 3B 52 6A 53 B0 23
+1C 53 1E 83 6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83
+B1 43 04 00 A5 3F 28 4B 2F 53 0E 93 2C 17 82 4C
+DA 1D 03 24 2F 52 0E F3 30 4D 8F 93 00 00 15 20
+32 B0 00 02 14 20 0E 93 05 24 1A 4F 02 00 1A 83
+0A 93 0B 38 2F 53 BF 4F 00 00 3E E3 05 20 BF E3
+00 00 9F 53 00 00 3E E3 30 4D 32 D0 00 02 9F 4F
+02 00 04 00 BF 4F 00 00 3E E3 F6 23 BF E3 02 00
+BF E3 00 00 9F 53 02 00 8F 63 00 00 3E E3 30 4D
+A8 48 07 45 58 45 43 55 54 45 0A 4E 3E 4F 00 4A
+28 45 01 2C 1A 42 C4 1D A2 53 C4 1D 8A 4E 00 00
+3E 4F 30 4D A2 4B 87 4C 49 54 45 52 41 4C 82 93
+B6 1D 16 24 32 B0 00 02 09 24 1A 42 C4 1D A2 52
+C4 1D BA 40 34 44 00 00 BA 4F 02 00 1A 42 C4 1D
+A2 52 C4 1D BA 40 34 44 00 00 8A 4E 02 00 3E 4F
+30 4D DE 48 05 43 4F 55 4E 54 2F 83 1E 53 8F 4E
+00 00 5E 4E FF FF 30 4D 82 4E BE 1D B2 4F C0 1D
+3E 4F 82 43 C2 1D 87 12 4C 46 9C 49 1E 4C 3D 40
+2A 4C E8 22 3D 41 3E 4F 30 4D 2C 4C 0A 4E 3E 4F
+3D 40 42 4C 3D 27 3D 40 18 4C 1A E2 B6 1D B2 27
+AC 23 44 4C 3E 4F 3D 40 18 4C B9 23 DE 53 00 00
+68 4E 08 5E F8 40 3F 00 00 00 3D 40 0A 4E CD 3F
+92 4B 08 45 56 41 4C 55 41 54 45 00 39 40 BE 1D
+39 12 39 12 39 12 0D 12 B0 12 2A 44 08 4C 80 4C
+3D 41 B2 41 C2 1D B2 41 C0 1D B2 41 BE 1D 30 4D
+7A 45 04 51 55 49 54 00 31 40 E0 1C B2 40 00 1C
+AC 1D 82 43 B6 1D 82 43 08 18 B0 12 2A 44 42 49
+04 0D 6F 6B 20 00 26 49 34 44 38 1D 44 44 34 44
+50 00 F6 47 EE 48 08 4C 34 44 7E 1C CE 44 B2 45
+42 49 0D 73 74 61 63 6B 20 65 6D 70 74 79 20 21
+1C 4D 34 44 30 FF 84 47 B2 45 42 49 0B 46 52 41
+4D 20 66 75 6C 6C 20 21 1C 4D 42 46 F4 44 C0 45
+AE 4C 42 49 04 0D 20 20 20 00 BC 45 B6 4C EE 47
+05 41 42 4F 52 54 3F 40 80 1C BE 3F 8F 93 02 00
+98 26 B2 40 82 48 66 48 B0 12 04 52 82 43 A8 5A
+82 43 B4 5A 82 43 C0 5A 82 43 F0 5A 82 43 FC 5A
+82 43 08 5B A2 B3 DC 05 FD 27 B2 40 11 00 CE 05
+92 C3 DC 05 38 40 55 05 39 42 19 83 FE 23 18 83
+FB 23 92 B3 DC 05 F4 23 87 12 42 49 04 1B 5B 37
+6D 00 26 49 26 49 42 49 04 1B 5B 30 6D 00 26 49
+4C 51 8E 51 94 51 16 4D 10 4D 86 41 42 4F 52 54
+22 00 87 12 5C 49 34 44 1C 4D A4 4B 2A 44 EE 49
+01 27 87 12 4C 46 9C 49 F4 49 C0 45 B0 4D 2A 44
+4C 4C 52 46 81 5C 92 42 BE 1D C2 1D 30 4D 87 12
+78 49 4C 46 9C 49 C8 4D 08 4E 7A 4E 5A D3 5A 53
+0A 58 19 42 C8 1D 6E 4E 3E F0 1E 00 09 5E 82 48
+AE 1D 82 49 B0 1D 82 4A B2 1D 2A 52 82 4A C4 1D
+3E 4F 3D 41 30 41 87 12 42 49 0F 73 74 61 63 6B
+20 6D 69 73 6D 61 74 63 68 21 22 4D 82 9F B4 1D
+F2 23 18 42 AE 1D 19 42 B0 1D A8 49 FE FF 89 48
+00 00 30 4D 96 49 08 56 41 52 49 41 42 4C 45 00
+B0 12 BE 4D BA 40 86 12 FC FF EF 3F F4 4B 08 43
+4F 4E 53 54 41 4E 54 00 B0 12 BE 4D BA 40 85 12
+FC FF 8A 4E FE FF 3E 4F E0 3F 3E 4E 06 43 52 45
+41 54 45 00 B0 12 BE 4D BA 40 85 12 FC FF 8A 4A
+FE FF D3 3F 62 4C 05 44 4F 45 53 3E 1A 42 B2 1D
+BA 40 84 12 00 00 8A 4D 02 00 3D 41 30 4D 76 4E
+05 44 45 46 45 52 B0 12 BE 4D BA 40 30 40 FC FF
+BA 40 8C 4E FE FF B9 3F 00 00 81 5B 82 43 B6 1D
+30 4D B4 4D 01 5D B2 43 B6 1D 30 4D 58 49 87 52
+45 43 55 52 53 45 19 42 C4 1D 99 42 B2 1D 00 00
+A2 53 C4 1D 30 4D AA 4E 01 3A B0 12 BE 4D BA 40
+87 12 FC FF A2 83 C4 1D B2 43 B6 1D 82 4F B4 1D
+30 4D D8 4E 81 3B 82 93 B6 1D 5D 27 87 12 34 44
+2A 44 A4 4B 0C 4E AC 4E 2A 44 CA 48 09 49 4D 4D
+45 44 49 41 54 45 1A 42 AE 1D FA D0 80 00 00 00
+30 4D BE 4F 02 00 3E 4F 30 4D 0C 4F 82 49 53 00
+87 12 42 46 F4 44 C0 45 44 4F 50 4F 34 44 22 4F
+A4 4B 2A 44 A2 4D 22 4F 2A 44 F4 4E 83 5B 27 5D
+87 12 A2 4D 34 44 34 44 A4 4B A4 4B 2A 44 92 4C
+88 50 4F 53 54 50 4F 4E 45 00 87 12 4C 46 9C 49
+F4 49 54 44 C0 45 B0 4D 7E 45 C0 45 8A 4F 34 44
+34 44 A4 4B A4 4B 34 44 A4 4B A4 4B 2A 44 90 4F
+3A 4E 82 4A C6 1D 2E 4E 82 4E C4 1D 3D 40 10 00
+09 4A 08 49 29 83 18 48 FE FF 0E 98 FC 2B 89 48
+00 00 1D 83 F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41
+30 4D 2C 4F 82 49 46 00 2F 83 8F 4E 00 00 1E 42
+C4 1D BE 40 C0 45 00 00 A2 52 C4 1D 2E 53 30 4D
+90 4E 84 45 4C 53 45 00 1A 42 C4 1D BA 40 BC 45
+00 00 2A 52 82 4A C4 1D 8E 4A 00 00 2A 83 0E 4A
+30 4D 20 49 84 54 48 45 4E 00 9E 42 C4 1D 00 00
+3E 4F 30 4D 5C 4E 85 42 45 47 49 4E 30 40 84 47
+04 50 85 55 4E 54 49 4C 39 40 C0 45 1A 42 C4 1D
+A2 52 C4 1D 8A 49 00 00 8A 4E 02 00 3E 4F 30 4D
+8A 4D 85 41 47 41 49 4E 39 40 BC 45 EF 3F 26 4E
+85 57 48 49 4C 45 87 12 C8 4F 6E 44 2A 44 BE 4E
+86 52 45 50 45 41 54 00 87 12 48 50 0A 50 2A 44
+E2 4F 82 44 4F 00 2F 83 8F 4E 00 00 1E 42 C4 1D
+BE 40 CA 45 00 00 2E 53 82 4E C4 1D A2 53 AC 1D
+1A 42 AC 1D 8A 43 00 00 30 4D B6 4B 84 4C 4F 4F
+50 00 39 40 EC 45 1A 42 C4 1D A2 52 C4 1D 8A 49
+00 00 8A 4E 02 00 1E 42 AC 1D A2 83 AC 1D 2E 4E
+0E 93 04 24 9E 42 C4 1D 00 00 F5 3F 3E 4F 30 4D
+E4 47 85 2B 4C 4F 4F 50 39 40 DA 45 E4 3F 9C 50
+85 4C 45 41 56 45 1A 42 C4 1D BA 40 FC 45 00 00
+BA 40 BC 45 02 00 B2 50 06 00 C4 1D A2 53 AC 1D
+2A 52 19 42 AC 1D 89 4A 00 00 30 4D E0 50 04 4D
+4F 56 45 00 0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24
+08 99 0F 24 06 2C F8 49 00 00 18 53 1A 83 FB 23
+30 4D 08 5A 09 5A 19 83 18 83 E8 49 00 00 1A 83
+FA 23 30 4D 34 44 CA 1D FC 44 2A 44 84 12 44 51
+18 54 00 54 72 50 A0 4D E8 53 D2 50 0E 51 84 49
+B2 51 E6 51 22 50 A6 52 48 45 4C 4F B4 4E 5C 4A
+00 00 3A 40 0C 00 39 40 CA 1D 38 40 CC 1D D9 3F
+3A 40 0E 00 39 40 CC 1D 38 40 CA 1D CC 3F 82 43
+CC 1D 30 4D 92 42 CA 1D C8 1D 30 4D 60 4F 09 50
+57 52 5F 53 54 41 54 45 84 12 8E 4F E4 53 2E 5B
+9E 51 08 50 57 52 5F 48 45 52 45 00 92 42 C4 1D
+AE 51 92 42 C6 1D AC 51 EF 3F 60 50 09 52 53 54
+5F 53 54 41 54 45 92 42 0C 18 AE 51 92 42 0E 18
+AC 51 E2 3F CC 51 08 52 53 54 5F 48 45 52 45 00
+92 42 C4 1D 0C 18 92 42 C6 1D 0E 18 DF 3F B2 40
+4C 52 AE 52 B2 40 8E 48 A4 48 B2 40 D0 48 E4 48
+B2 40 DC 47 EA 47 30 41 50 50 04 57 49 50 45 00
+39 40 80 FF B9 43 00 00 29 53 39 90 CC FF FA 23
+B0 12 FE 51 B2 40 2E 5B C4 1D B2 40 E4 53 C6 1D
+D7 3F C4 4F 06 28 57 41 52 4D 29 00 1E 42 08 18
+87 12 42 49 05 0D 1B 5B 37 6D 26 49 70 47 42 49
+27 20 46 61 73 74 46 6F 72 74 68 20 56 31 36 30
+20 2E 35 4D 48 7A 20 28 43 29 20 4A 2E 4D 2E 54
+68 6F 6F 72 65 6E 73 20 26 49 34 44 30 FF 84 47
+2A 45 30 47 42 49 0B 62 79 74 65 73 20 66 72 65
+65 20 28 4D 1A 52 04 57 41 52 4D 00 30 40 4C 52
+16 50 04 43 4F 4C 44 00 B2 40 04 A5 20 01 B2 40
+88 5A 5C 01 92 D3 04 02 B2 40 FE FF 02 02 A2 83
+06 02 B2 40 00 40 24 02 B2 40 FF BF 22 02 B2 D0
+FF BF 26 02 F2 43 22 03 F2 D3 26 03 F2 40 A5 00
+61 01 82 43 62 01 B2 40 11 01 66 01 29 42 B2 40
+33 00 64 01 D2 43 61 01 92 D2 9E 01 08 18 A2 93
+08 18 01 24 59 07 38 40 C2 A2 18 83 FE 23 19 83
+FA 23 B2 D2 B0 01 F2 D0 10 00 2A 03 F2 C0 40 00
+A1 04 3A 40 BE 52 39 40 CC FF 89 4A 00 00 29 53
+FC 23 92 42 02 18 F0 FF B2 40 18 00 0A 18 31 40
+E0 1C 3F 40 80 1C 37 40 00 44 36 40 B4 44 35 40
+08 44 34 40 14 44 B2 40 0A 00 DA 1D B2 43 DC 1D
+92 C3 30 01 18 42 08 18 D2 B3 01 02 04 20 38 E3
+18 53 82 48 08 18 B2 40 81 00 C0 05 A2 42 C6 05
+B2 40 00 49 C8 05 F2 D0 03 00 0D 02 92 C3 C0 05
+92 D3 DA 05 3D 40 BE 53 18 42 08 18 38 90 0A 00
+37 27 38 90 16 00 34 2F 28 93 0D 23 F5 26 AC 52
+84 12 44 51 0C 5A B8 5A C0 59 0C 5B 86 59 40 5A
+8A 56 00 00 7C 59 2C 5A DE 59 1C 5A 9A 57 00 00
+00 00 1E 5B 70 51 44 52 85 48 49 32 4C 4F 87 12
+84 47 DC 4F A4 4B AC 4E 72 51 C0 53 2A 44 B2 52
+04 43 4F 44 45 00 B0 12 BE 4D A2 82 C4 1D 87 12
+EC 4E BC 45 F8 53 42 50 03 41 53 4D 92 42 C8 1D
+B8 1D B2 40 C4 53 C8 1D EE 3F 00 00 07 45 4E 44
+43 4F 44 45 87 12 80 51 0C 4E 2A 44 2C 54 06 45
+4E 44 41 53 4D 00 92 42 B8 1D C8 1D F3 3F 00 00
+05 43 4F 4C 4F 4E 1A 42 C4 1D BA 40 87 12 00 00
+A2 53 C4 1D B2 43 B6 1D 30 40 80 51 00 00 05 4C
+4F 32 48 49 1A 42 C4 1D BA 40 B0 12 00 00 BA 40
+2A 44 02 00 A2 52 C4 1D ED 3F 38 40 BE 1D 39 48
+2A 48 09 5A 1A 52 C2 1D 09 9A 03 24 7E 9A FC 27
+1A 83 0E 4A 2A 88 82 4A C2 1D 30 4D B0 12 2A 44
+9C 49 F4 49 72 45 C0 45 C2 54 B0 4A C0 45 B0 4D
+E4 54 C4 54 29 4E 39 90 86 12 02 20 2E 53 30 41
+39 90 85 12 03 20 1E 4E 02 00 30 41 39 90 84 12
+01 20 2E 52 30 41 19 42 C4 1D A2 53 C4 1D 89 4E
+00 00 3E 40 29 00 12 12 C2 1D 92 53 C2 1D B0 12
+2A 44 9C 49 B0 4A C0 45 16 55 0C 55 21 53 3E 90
+10 00 BB 2D 30 41 18 55 B2 41 C2 1D 22 D3 30 41
+87 12 4C 46 8A 54 28 55 82 43 BC 1D 92 42 C4 1D
+BA 1D A2 53 C4 1D 0A 4E 3E 4F FA 90 23 00 00 00
+34 20 92 53 C2 1D B0 12 AC 54 0E 93 04 20 B2 40
+00 03 BC 1D 27 3C 1E 93 04 20 B2 40 10 03 BC 1D
+21 3C 2E 93 04 20 B2 40 20 03 BC 1D 1B 3C 2E 92
+04 20 B2 40 20 02 BC 1D 15 3C 3E 92 04 20 B2 40
+30 02 BC 1D 0F 3C 3E 93 04 20 B2 40 30 03 BC 1D
+09 3C B2 40 30 00 BC 1D 19 42 C4 1D A2 53 C4 1D
+89 4E 00 00 3E 4F 3D 41 30 4D FA 90 26 00 00 00
+08 20 B2 40 10 02 BC 1D 92 53 C2 1D 30 12 98 55
+75 3F FA 90 40 00 00 00 1A 20 B2 40 20 00 BC 1D
+92 53 C2 1D B0 12 F6 54 0E 20 B2 50 10 00 BC 1D
+3E 40 2B 00 B0 12 F6 54 32 24 92 92 BE 1D C2 1D
+02 24 92 53 C2 1D 8E 10 82 5E BC 1D D3 3F B0 12
+F6 54 F9 23 B2 50 10 00 BC 1D 3E 40 28 00 B0 12
+AC 54 30 12 E8 55 67 3F 87 12 4C 46 8A 54 20 56
+FE 90 26 00 00 00 3E 40 20 00 04 20 B2 50 82 00
+BC 1D C2 3F B0 12 F6 54 DF 23 B2 50 80 00 BC 1D
+3E 40 28 00 B0 12 AC 54 B0 12 E6 54 D5 23 3D 40
+B0 4D 30 4D 00 00 04 52 45 54 49 00 87 12 34 44
+00 13 A4 4B 2A 44 34 44 2C 00 20 55 18 56 70 56
+2E 4E 1E D2 BC 1D 19 42 BA 1D 92 3F 6E 54 03 4D
+4F 56 84 12 66 56 00 40 7E 56 05 4D 4F 56 2E 42
+84 12 66 56 40 40 00 00 03 41 44 44 84 12 66 56
+00 50 98 56 05 41 44 44 2E 42 84 12 66 56 40 50
+A4 56 04 41 44 44 43 00 84 12 66 56 00 60 B2 56
+06 41 44 44 43 2E 42 00 84 12 66 56 40 60 56 56
+04 53 55 42 43 00 84 12 66 56 00 70 D0 56 06 53
+55 42 43 2E 42 00 84 12 66 56 40 70 DE 56 03 53
+55 42 84 12 66 56 00 80 EE 56 05 53 55 42 2E 42
+84 12 66 56 40 80 50 54 03 43 4D 50 84 12 66 56
+00 90 08 57 05 43 4D 50 2E 42 84 12 66 56 40 90
+3E 54 04 44 41 44 44 00 84 12 66 56 00 A0 22 57
+06 44 41 44 44 2E 42 00 84 12 66 56 40 A0 14 57
+03 42 49 54 84 12 66 56 00 B0 40 57 05 42 49 54
+2E 42 84 12 66 56 40 B0 4C 57 03 42 49 43 84 12
+66 56 00 C0 5A 57 05 42 49 43 2E 42 84 12 66 56
+40 C0 66 57 03 42 49 53 84 12 66 56 00 D0 74 57
+05 42 49 53 2E 42 84 12 66 56 40 D0 00 00 03 58
+4F 52 84 12 66 56 00 E0 8E 57 05 58 4F 52 2E 42
+84 12 66 56 40 E0 C0 56 03 41 4E 44 84 12 66 56
+00 F0 A8 57 05 41 4E 44 2E 42 84 12 66 56 40 F0
+4C 46 20 55 C6 57 1A 42 BC 1D B2 F0 70 00 BC 1D
+8A 10 3A F0 0F 00 82 DA BC 1D 4A 3F FA 56 03 52
+52 43 84 12 C0 57 00 10 DE 57 05 52 52 43 2E 42
+84 12 C0 57 40 10 EA 57 04 53 57 50 42 00 84 12
+C0 57 80 10 F8 57 03 52 52 41 84 12 C0 57 00 11
+06 58 05 52 52 41 2E 42 84 12 C0 57 40 11 12 58
+03 53 58 54 84 12 C0 57 80 11 00 00 04 50 55 53
+48 00 84 12 C0 57 00 12 2C 58 06 50 55 53 48 2E
+42 00 84 12 C0 57 40 12 80 57 04 43 41 4C 4C 00
+84 12 C0 57 80 12 34 44 2C 00 20 55 18 56 60 58
+59 42 BC 1D 5A 42 BD 1D 82 4A BC 1D BE 90 00 15
+00 00 02 20 0A 89 02 3C 09 8A 0A 49 3A 90 10 00
+03 2C 5A 0E A8 3F 1A 53 0E 4A 87 12 70 47 42 49
+0D 6F 75 74 20 6F 66 20 62 6F 75 6E 64 73 22 4D
+3A 58 05 50 55 53 48 4D 84 12 56 58 00 15 A2 58
+04 50 4F 50 4D 00 84 12 56 58 00 17 4C 46 8A 54
+C2 58 82 43 BC 1D 92 42 C4 1D BA 1D A2 53 C4 1D
+92 53 C2 1D 3E 40 2C 00 B0 12 2A 44 9C 49 B0 4A
+C0 45 B0 4D 18 56 E8 58 0A 4E 3E 4F 1A 83 2A 92
+CA 2F 8A 10 5A 06 6F 3F 20 58 04 52 52 43 4D 00
+84 12 BC 58 50 00 FA 58 04 52 52 41 4D 00 84 12
+BC 58 50 01 08 59 04 52 4C 41 4D 00 84 12 BC 58
+50 02 16 59 04 52 52 55 4D 00 84 12 BC 58 50 03
+85 12 00 3C 24 59 03 53 3E 3D 85 12 00 38 36 59
+02 53 3C 00 85 12 00 34 B0 58 03 30 3E 3D 85 12
+00 30 4A 59 02 30 3C 00 85 12 00 30 00 00 02 55
+3C 00 85 12 00 2C 5E 59 03 55 3E 3D 85 12 00 28
+54 59 03 30 3C 3E 85 12 00 24 72 59 02 30 3D 00
+85 12 00 20 00 00 02 49 46 00 1A 42 C4 1D 8A 4E
+00 00 A2 53 C4 1D 0E 4A 30 4D 68 59 04 54 48 45
+4E 00 1A 42 C4 1D 08 4E 3E 4F 09 48 29 53 0A 89
+0A 11 3A 90 00 02 68 2F 88 DA 00 00 30 4D 30 57
+04 45 4C 53 45 00 1A 42 C4 1D BA 40 00 3C 00 00
+A2 53 C4 1D 2F 83 8F 4A 00 00 E3 3F 9C 59 05 55
+4E 54 49 4C 3A 4F 08 4E 3E 4F 19 42 C4 1D 2A 83
+0A 89 0A 11 3A 90 00 FE 47 3B 3A F0 FF 03 08 DA
+89 48 00 00 A2 53 C4 1D 30 4D B4 57 05 41 47 41
+49 4E 87 12 30 59 E4 59 2A 44 00 00 05 57 48 49
+4C 45 87 12 8A 59 6E 44 2A 44 40 59 06 52 45 50
+45 41 54 00 87 12 30 59 E4 59 A2 59 2A 44 00 00
+03 4A 4D 50 87 12 A2 4D 30 59 E4 59 2A 44 3E B0
+00 10 03 20 3E E0 00 04 30 4D 3E 90 00 34 06 28
+03 24 3E 40 00 34 30 4D 3E 40 00 38 30 4D 00 00
+04 3F 4A 4D 50 00 87 12 4E 5A A2 4D 6E 44 E4 59
+2A 44 84 5A 3D 41 08 4E 3E 4F 2A 48 0A 93 04 20
+98 42 C4 1D 00 00 30 4D 88 43 00 00 A4 3F 4A 58
+03 42 57 31 84 12 82 5A 00 00 A0 5A 03 42 57 32
+84 12 82 5A 00 00 AC 5A 03 42 57 33 84 12 82 5A
+00 00 C4 5A 3D 41 1A 42 C4 1D 28 4E 08 93 08 20
+BA 4F 00 00 A2 53 C4 1D 8E 4A 00 00 3E 4F 30 4D
+8E 43 00 00 61 3F 00 00 03 46 57 31 84 12 C2 5A
+00 00 E8 5A 03 46 57 32 84 12 C2 5A 00 00 F4 5A
+03 46 57 33 84 12 C2 5A 00 00 00 5B 04 47 4F 54
+4F 00 87 12 30 59 A2 4D 9A 4B 2A 44 70 5A 05 3F
+47 4F 54 4F 87 12 4E 5A A2 4D 9A 4B 2A 44
+@FFCC
+BE 52 BE 52 BE 52 BE 52 BE 52 BE 52 BE 52 BE 52
+BE 52 BE 52 BE 52 BE 52 BE 52 BE 52 BE 52 BE 52
+BE 52 BE 52 40 48 BE 52 BE 52 BE 52 BE 52 BE 52
+BE 52 BE 52
+q
--- /dev/null
+@1800
+10 00 4C 48 80 3E 00 24 FD FF 18 00 4E 5B 04 54
+2A 48 38 48 00 00 00 00
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@4400
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 44
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 44 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 44 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E 44 02 3E 52 00 0E 12 3E 4F 30 4D 8E 44
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 44
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C 44 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 44 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 45
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 44 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA 44 03 41 4E 44 3E FF 30 4D 7A 44 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E 45 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 45 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E 45 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 45 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 44 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE 45 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 45 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 45 03 3E 49 4E 85 12 C2 1D 10 45
+04 42 41 53 45 00 85 12 DA 1D C0 44 05 53 54 41
+54 45 85 12 B6 1D 30 46 02 42 4C 00 85 12 20 00
+94 45 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 46 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E 46 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 46 02 23 53 00 87 12 98 46
+D2 46 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 46 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 46 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C 46 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 45 03 55 44 2E 87 12 56 46
+CC 46 E6 46 32 49 FA 48 2A 44 18 47 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA 44
+02 44 2E 00 87 12 56 46 6E 44 80 44 3A 47 CC 46
+92 44 0A 47 E6 46 32 49 FA 48 2A 44 52 45 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 46 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 45 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 46 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A 48
+92 B3 DC 05 FD 27 1E 42 CC 05 B0 12 38 48 30 4D
+30 40 B6 47 7E 47 05 28 4B 45 59 29 18 42 CC 05
+EA 3F 12 46 03 4B 45 59 30 40 DC 47 92 47 06 41
+43 43 45 50 54 00 3C 40 8A 48 3B 40 54 48 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+7E 48 92 B3 DC 05 05 24 18 42 CC 05 38 90 0A 00
+04 20 21 53 39 40 46 48 4D 15 B2 40 11 00 CE 05
+A2 B3 DC 05 FD 27 30 41 B2 40 13 00 CE 05 A2 B3
+DC 05 FD 27 30 41 12 D2 0A 18 FD 3F 21 52 3A 17
+58 42 CC 05 48 9B F0 27 48 9C 06 2C 78 92 11 20
+2E 9F 0F 24 1E 83 05 3C 0E 9A 03 24 CE 48 00 00
+1E 53 82 48 CE 05 A2 B3 DC 05 FD 27 30 4D 80 48
+2D 83 92 B3 DC 05 FD 27 E3 23 B2 40 18 00 0A 18
+3E 8F 3D 41 30 4D D6 47 06 28 45 4D 49 54 29 00
+08 4E 3E 4F E6 3F 50 47 04 45 4D 49 54 00 30 40
+A0 48 A8 48 04 45 43 48 4F 00 B2 40 82 48 72 48
+30 4D 6E 47 06 4E 4F 45 43 48 4F 00 B2 40 30 4D
+72 48 30 4D 98 48 04 28 43 52 29 00 2F 83 8F 4E
+00 00 3E 40 0D 00 E3 3F A2 47 02 43 52 00 30 40
+DC 48 04 47 05 53 50 41 43 45 2F 83 8F 4E 00 00
+3E 40 20 00 D4 3F F4 48 06 53 50 41 43 45 53 00
+0E 93 09 24 0D 12 3D 40 1C 49 EF 3F 1E 49 2D 83
+1E 83 EB 23 3D 41 3E 4F 30 4D 2C 47 04 54 59 50
+45 00 0E 93 95 24 2A 4F 8F 5E 00 00 0E 4A 87 12
+CA 45 02 46 0A 45 AE 48 EC 45 42 49 2A 44 2F 82
+8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E 1D B3 0D 63
+30 4D 08 49 82 53 22 00 87 12 34 44 4E 49 B0 4B
+34 44 22 00 A8 49 78 49 3D 41 6E 4E 1E 83 82 5E
+C4 1D 3E 4F 92 B3 C4 1D A2 63 C4 1D 30 4D C4 48
+82 2E 22 00 87 12 68 49 34 44 32 49 B0 4B 2A 44
+00 00 04 57 4F 52 44 00 3C 40 BE 1D 39 4C 3A 4C
+09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A FC 27 1A 83
+3B 40 60 00 C8 4C 00 00 09 9A 0C 24 7C 4A 4E 9C
+09 24 18 53 4B 9C F6 2F 7C 90 7B 00 F3 2F 7C 80
+20 00 F0 3F 1A 82 C0 1D 82 4A C2 1D 1E 42 C4 1D
+08 8E CE 48 00 00 30 4D 00 00 04 46 49 4E 44 00
+2F 83 0C 4E 65 4C 74 40 80 00 3B 40 CA 1D 3E 4B
+0E 93 1E 24 58 4C 01 00 78 F0 1E 00 0E 58 2E 53
+1E 4E FE FF 0E 93 F3 27 09 4E 78 49 48 C4 48 95
+F7 23 0A 4C 1A 53 FA 99 00 00 F2 23 58 83 FA 23
+19 B3 09 63 0C 49 6A 4E 1E 43 4A 93 01 30 2E 83
+8F 4C 00 00 35 40 08 44 34 40 14 44 30 4D 2F 53
+2F 53 3E 4F 30 4D 26 46 07 3E 4E 55 4D 42 45 52
+3C 4F 38 4F 29 4F 2F 82 1B 42 DA 1D 6A 4C 7A 80
+30 00 7A 90 0A 00 02 28 7A 80 07 00 0A 9B 13 2C
+82 49 D0 04 82 48 D2 04 82 4B C8 04 19 42 E4 04
+18 42 E6 04 09 5A 08 63 1C 53 1E 83 E7 23 8F 49
+04 00 8F 48 02 00 8F 4C 00 00 30 4D 03 12 0D 12
+1B 42 DA 1D 0B 12 32 C0 00 02 6D 4E 0D 5E 0C 4E
+7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23 32 D0 00 02
+FC 4C FE FF 0D 9C FC 2F DE 83 00 00 09 43 08 43
+3D 40 32 4B 3F 82 8F 4E 06 00 0C 4E 7E 4C 6A 4C
+7A 90 2D 00 10 2C 3B 40 10 00 7A 80 24 00 06 24
+2B 43 5A 83 03 24 3B 52 6A 53 B0 23 1C 53 1E 83
+6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83 B1 43 04 00
+A5 3F 34 4B 2F 53 0E 93 2C 17 82 4C DA 1D 03 24
+2F 52 0E F3 30 4D 8F 93 00 00 15 20 32 B0 00 02
+14 20 0E 93 05 24 1A 4F 02 00 1A 83 0A 93 0B 38
+2F 53 BF 4F 00 00 3E E3 05 20 BF E3 00 00 9F 53
+00 00 3E E3 30 4D 32 D0 00 02 9F 4F 02 00 04 00
+BF 4F 00 00 3E E3 F6 23 BF E3 02 00 BF E3 00 00
+9F 53 02 00 8F 63 00 00 3E E3 30 4D B4 48 07 45
+58 45 43 55 54 45 0A 4E 3E 4F 00 4A 28 45 01 2C
+1A 42 C4 1D A2 53 C4 1D 8A 4E 00 00 3E 4F 30 4D
+AE 4B 87 4C 49 54 45 52 41 4C 82 93 B6 1D 16 24
+32 B0 00 02 09 24 1A 42 C4 1D A2 52 C4 1D BA 40
+34 44 00 00 BA 4F 02 00 1A 42 C4 1D A2 52 C4 1D
+BA 40 34 44 00 00 8A 4E 02 00 3E 4F 30 4D EA 48
+05 43 4F 55 4E 54 2F 83 1E 53 8F 4E 00 00 5E 4E
+FF FF 30 4D 82 4E BE 1D B2 4F C0 1D 3E 4F 82 43
+C2 1D 87 12 4C 46 A8 49 2A 4C 3D 40 36 4C E8 22
+3D 41 3E 4F 30 4D 38 4C 0A 4E 3E 4F 3D 40 4E 4C
+3D 27 3D 40 24 4C 1A E2 B6 1D B2 27 AC 23 50 4C
+3E 4F 3D 40 24 4C B9 23 DE 53 00 00 68 4E 08 5E
+F8 40 3F 00 00 00 3D 40 16 4E CD 3F 9E 4B 08 45
+56 41 4C 55 41 54 45 00 39 40 BE 1D 39 12 39 12
+39 12 0D 12 B0 12 2A 44 14 4C 8C 4C 3D 41 B2 41
+C2 1D B2 41 C0 1D B2 41 BE 1D 30 4D 7A 45 04 51
+55 49 54 00 31 40 E0 1C B2 40 00 1C AC 1D 82 43
+B6 1D 82 43 08 18 B0 12 2A 44 4E 49 04 0D 6F 6B
+20 00 32 49 34 44 38 1D 44 44 34 44 50 00 F6 47
+FA 48 14 4C 34 44 7E 1C CE 44 B2 45 4E 49 0D 73
+74 61 63 6B 20 65 6D 70 74 79 20 21 28 4D 34 44
+30 FF 84 47 B2 45 4E 49 0B 46 52 41 4D 20 66 75
+6C 6C 20 21 28 4D 42 46 F4 44 C0 45 BA 4C 4E 49
+04 0D 20 20 20 00 BC 45 C2 4C EE 47 05 41 42 4F
+52 54 3F 40 80 1C BE 3F 8F 93 02 00 98 26 B2 40
+82 48 72 48 B0 12 10 52 82 43 C8 5A 82 43 D4 5A
+82 43 E0 5A 82 43 10 5B 82 43 1C 5B 82 43 28 5B
+A2 B3 DC 05 FD 27 B2 40 11 00 CE 05 92 C3 DC 05
+38 40 A0 AA 39 42 19 83 FE 23 18 83 FB 23 92 B3
+DC 05 F4 23 87 12 4E 49 04 1B 5B 37 6D 00 32 49
+32 49 4E 49 04 1B 5B 30 6D 00 32 49 58 51 9A 51
+A0 51 22 4D 1C 4D 86 41 42 4F 52 54 22 00 87 12
+68 49 34 44 28 4D B0 4B 2A 44 FA 49 01 27 87 12
+4C 46 A8 49 00 4A C0 45 BC 4D 2A 44 58 4C 52 46
+81 5C 92 42 BE 1D C2 1D 30 4D 87 12 84 49 4C 46
+A8 49 D4 4D 08 4E 7A 4E 5A D3 5A 53 0A 58 19 42
+C8 1D 6E 4E 3E F0 1E 00 09 5E 82 48 AE 1D 82 49
+B0 1D 82 4A B2 1D 2A 52 82 4A C4 1D 3E 4F 3D 41
+30 41 87 12 4E 49 0F 73 74 61 63 6B 20 6D 69 73
+6D 61 74 63 68 21 2E 4D 82 9F B4 1D F2 23 18 42
+AE 1D 19 42 B0 1D A8 49 FE FF 89 48 00 00 30 4D
+A2 49 08 56 41 52 49 41 42 4C 45 00 B0 12 CA 4D
+BA 40 86 12 FC FF EF 3F 00 4C 08 43 4F 4E 53 54
+41 4E 54 00 B0 12 CA 4D BA 40 85 12 FC FF 8A 4E
+FE FF 3E 4F E0 3F 4A 4E 06 43 52 45 41 54 45 00
+B0 12 CA 4D BA 40 85 12 FC FF 8A 4A FE FF D3 3F
+6E 4C 05 44 4F 45 53 3E 1A 42 B2 1D BA 40 84 12
+00 00 8A 4D 02 00 3D 41 30 4D 82 4E 05 44 45 46
+45 52 B0 12 CA 4D BA 40 30 40 FC FF BA 40 98 4E
+FE FF B9 3F 00 00 81 5B 82 43 B6 1D 30 4D C0 4D
+01 5D B2 43 B6 1D 30 4D 64 49 87 52 45 43 55 52
+53 45 19 42 C4 1D 99 42 B2 1D 00 00 A2 53 C4 1D
+30 4D B6 4E 01 3A B0 12 CA 4D BA 40 87 12 FC FF
+A2 83 C4 1D B2 43 B6 1D 82 4F B4 1D 30 4D E4 4E
+81 3B 82 93 B6 1D 5D 27 87 12 34 44 2A 44 B0 4B
+18 4E B8 4E 2A 44 D6 48 09 49 4D 4D 45 44 49 41
+54 45 1A 42 AE 1D FA D0 80 00 00 00 30 4D BE 4F
+02 00 3E 4F 30 4D 18 4F 82 49 53 00 87 12 42 46
+F4 44 C0 45 50 4F 5C 4F 34 44 2E 4F B0 4B 2A 44
+AE 4D 2E 4F 2A 44 00 4F 83 5B 27 5D 87 12 AE 4D
+34 44 34 44 B0 4B B0 4B 2A 44 9E 4C 88 50 4F 53
+54 50 4F 4E 45 00 87 12 4C 46 A8 49 00 4A 54 44
+C0 45 BC 4D 7E 45 C0 45 96 4F 34 44 34 44 B0 4B
+B0 4B 34 44 B0 4B B0 4B 2A 44 9C 4F 3A 4E 82 4A
+C6 1D 2E 4E 82 4E C4 1D 3D 40 10 00 09 4A 08 49
+29 83 18 48 FE FF 0E 98 FC 2B 89 48 00 00 1D 83
+F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41 30 4D 38 4F
+82 49 46 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40
+C0 45 00 00 A2 52 C4 1D 2E 53 30 4D 9C 4E 84 45
+4C 53 45 00 1A 42 C4 1D BA 40 BC 45 00 00 2A 52
+82 4A C4 1D 8E 4A 00 00 2A 83 0E 4A 30 4D 2C 49
+84 54 48 45 4E 00 9E 42 C4 1D 00 00 3E 4F 30 4D
+68 4E 85 42 45 47 49 4E 30 40 84 47 10 50 85 55
+4E 54 49 4C 39 40 C0 45 1A 42 C4 1D A2 52 C4 1D
+8A 49 00 00 8A 4E 02 00 3E 4F 30 4D 96 4D 85 41
+47 41 49 4E 39 40 BC 45 EF 3F 32 4E 85 57 48 49
+4C 45 87 12 D4 4F 6E 44 2A 44 CA 4E 86 52 45 50
+45 41 54 00 87 12 54 50 16 50 2A 44 EE 4F 82 44
+4F 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40 CA 45
+00 00 2E 53 82 4E C4 1D A2 53 AC 1D 1A 42 AC 1D
+8A 43 00 00 30 4D C2 4B 84 4C 4F 4F 50 00 39 40
+EC 45 1A 42 C4 1D A2 52 C4 1D 8A 49 00 00 8A 4E
+02 00 1E 42 AC 1D A2 83 AC 1D 2E 4E 0E 93 04 24
+9E 42 C4 1D 00 00 F5 3F 3E 4F 30 4D E4 47 85 2B
+4C 4F 4F 50 39 40 DA 45 E4 3F A8 50 85 4C 45 41
+56 45 1A 42 C4 1D BA 40 FC 45 00 00 BA 40 BC 45
+02 00 B2 50 06 00 C4 1D A2 53 AC 1D 2A 52 19 42
+AC 1D 89 4A 00 00 30 4D EC 50 04 4D 4F 56 45 00
+0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24 08 99 0F 24
+06 2C F8 49 00 00 18 53 1A 83 FB 23 30 4D 08 5A
+09 5A 19 83 18 83 E8 49 00 00 1A 83 FA 23 30 4D
+34 44 CA 1D FC 44 2A 44 84 12 50 51 38 54 20 54
+7E 50 AC 4D 08 54 DE 50 1A 51 90 49 BE 51 F2 51
+2E 50 B2 52 48 45 58 4F C0 4E 68 4A 00 00 3A 40
+0C 00 39 40 CA 1D 38 40 CC 1D D9 3F 3A 40 0E 00
+39 40 CC 1D 38 40 CA 1D CC 3F 82 43 CC 1D 30 4D
+92 42 CA 1D C8 1D 30 4D 6C 4F 09 50 57 52 5F 53
+54 41 54 45 84 12 9A 4F 04 54 4E 5B AA 51 08 50
+57 52 5F 48 45 52 45 00 92 42 C4 1D BA 51 92 42
+C6 1D B8 51 EF 3F 6C 50 09 52 53 54 5F 53 54 41
+54 45 92 42 0C 18 BA 51 92 42 0E 18 B8 51 E2 3F
+D8 51 08 52 53 54 5F 48 45 52 45 00 92 42 C4 1D
+0C 18 92 42 C6 1D 0E 18 DF 3F B2 40 58 52 BA 52
+B2 40 A0 48 B0 48 B2 40 DC 48 F0 48 B2 40 DC 47
+EA 47 30 41 5C 50 04 57 49 50 45 00 39 40 80 FF
+B9 43 00 00 29 53 39 90 CC FF FA 23 B0 12 0A 52
+B2 40 4E 5B C4 1D B2 40 04 54 C6 1D D7 3F D0 4F
+06 28 57 41 52 4D 29 00 1E 42 08 18 87 12 4E 49
+05 0D 1B 5B 37 6D 32 49 70 47 4E 49 27 20 46 61
+73 74 46 6F 72 74 68 20 56 31 36 30 20 31 36 4D
+48 7A 20 28 43 29 20 4A 2E 4D 2E 54 68 6F 6F 72
+65 6E 73 20 32 49 34 44 30 FF 84 47 2A 45 30 47
+4E 49 0B 62 79 74 65 73 20 66 72 65 65 20 34 4D
+26 52 04 57 41 52 4D 00 30 40 58 52 22 50 04 43
+4F 4C 44 00 B2 40 04 A5 20 01 B2 40 88 5A 5C 01
+92 D3 04 02 B2 40 FE FF 02 02 A2 83 06 02 B2 40
+00 40 24 02 B2 40 FF BF 22 02 B2 D0 FF BF 26 02
+F2 43 22 03 F2 D3 26 03 F2 40 A5 00 41 01 F2 40
+10 00 40 01 D2 43 41 01 F2 40 A5 00 61 01 B2 40
+48 00 62 01 82 43 66 01 39 40 80 00 B2 40 33 00
+64 01 D2 43 61 01 92 D2 9E 01 08 18 A2 93 08 18
+01 24 59 07 38 40 C2 A2 18 83 FE 23 19 83 FA 23
+B2 D2 B0 01 F2 D0 10 00 2A 03 F2 C0 40 00 A1 04
+3A 40 CA 52 39 40 CC FF 89 4A 00 00 29 53 FC 23
+92 42 02 18 F0 FF B2 40 18 00 0A 18 31 40 E0 1C
+3F 40 80 1C 37 40 00 44 36 40 B4 44 35 40 08 44
+34 40 14 44 B2 40 0A 00 DA 1D B2 43 DC 1D 92 C3
+30 01 18 42 08 18 D2 B3 01 02 04 20 38 E3 18 53
+82 48 08 18 B2 40 81 00 C0 05 B2 40 11 00 C6 05
+B2 40 00 4A C8 05 F2 D0 03 00 0D 02 92 C3 C0 05
+92 D3 DA 05 3D 40 DE 53 18 42 08 18 38 90 0A 00
+2D 27 38 90 16 00 2A 2F 28 93 03 23 EB 26 B8 52
+84 12 50 51 2C 5A D8 5A E0 59 2C 5B A6 59 60 5A
+AA 56 00 00 9C 59 4C 5A FE 59 3C 5A BA 57 00 00
+00 00 3E 5B 7C 51 50 52 85 48 49 32 4C 4F 87 12
+84 47 E8 4F B0 4B B8 4E 7E 51 E0 53 2A 44 BE 52
+04 43 4F 44 45 00 B0 12 CA 4D A2 82 C4 1D 87 12
+F8 4E BC 45 18 54 4E 50 03 41 53 4D 92 42 C8 1D
+B8 1D B2 40 E4 53 C8 1D EE 3F 00 00 07 45 4E 44
+43 4F 44 45 87 12 8C 51 18 4E 2A 44 4C 54 06 45
+4E 44 41 53 4D 00 92 42 B8 1D C8 1D F3 3F 00 00
+05 43 4F 4C 4F 4E 1A 42 C4 1D BA 40 87 12 00 00
+A2 53 C4 1D B2 43 B6 1D 30 40 8C 51 00 00 05 4C
+4F 32 48 49 1A 42 C4 1D BA 40 B0 12 00 00 BA 40
+2A 44 02 00 A2 52 C4 1D ED 3F 38 40 BE 1D 39 48
+2A 48 09 5A 1A 52 C2 1D 09 9A 03 24 7E 9A FC 27
+1A 83 0E 4A 2A 88 82 4A C2 1D 30 4D B0 12 2A 44
+A8 49 00 4A 72 45 C0 45 E2 54 BC 4A C0 45 BC 4D
+04 55 E4 54 29 4E 39 90 86 12 02 20 2E 53 30 41
+39 90 85 12 03 20 1E 4E 02 00 30 41 39 90 84 12
+01 20 2E 52 30 41 19 42 C4 1D A2 53 C4 1D 89 4E
+00 00 3E 40 29 00 12 12 C2 1D 92 53 C2 1D B0 12
+2A 44 A8 49 BC 4A C0 45 36 55 2C 55 21 53 3E 90
+10 00 BB 2D 30 41 38 55 B2 41 C2 1D 22 D3 30 41
+87 12 4C 46 AA 54 48 55 82 43 BC 1D 92 42 C4 1D
+BA 1D A2 53 C4 1D 0A 4E 3E 4F FA 90 23 00 00 00
+34 20 92 53 C2 1D B0 12 CC 54 0E 93 04 20 B2 40
+00 03 BC 1D 27 3C 1E 93 04 20 B2 40 10 03 BC 1D
+21 3C 2E 93 04 20 B2 40 20 03 BC 1D 1B 3C 2E 92
+04 20 B2 40 20 02 BC 1D 15 3C 3E 92 04 20 B2 40
+30 02 BC 1D 0F 3C 3E 93 04 20 B2 40 30 03 BC 1D
+09 3C B2 40 30 00 BC 1D 19 42 C4 1D A2 53 C4 1D
+89 4E 00 00 3E 4F 3D 41 30 4D FA 90 26 00 00 00
+08 20 B2 40 10 02 BC 1D 92 53 C2 1D 30 12 B8 55
+75 3F FA 90 40 00 00 00 1A 20 B2 40 20 00 BC 1D
+92 53 C2 1D B0 12 16 55 0E 20 B2 50 10 00 BC 1D
+3E 40 2B 00 B0 12 16 55 32 24 92 92 BE 1D C2 1D
+02 24 92 53 C2 1D 8E 10 82 5E BC 1D D3 3F B0 12
+16 55 F9 23 B2 50 10 00 BC 1D 3E 40 28 00 B0 12
+CC 54 30 12 08 56 67 3F 87 12 4C 46 AA 54 40 56
+FE 90 26 00 00 00 3E 40 20 00 04 20 B2 50 82 00
+BC 1D C2 3F B0 12 16 55 DF 23 B2 50 80 00 BC 1D
+3E 40 28 00 B0 12 CC 54 B0 12 06 55 D5 23 3D 40
+BC 4D 30 4D 00 00 04 52 45 54 49 00 87 12 34 44
+00 13 B0 4B 2A 44 34 44 2C 00 40 55 38 56 90 56
+2E 4E 1E D2 BC 1D 19 42 BA 1D 92 3F 8E 54 03 4D
+4F 56 84 12 86 56 00 40 9E 56 05 4D 4F 56 2E 42
+84 12 86 56 40 40 00 00 03 41 44 44 84 12 86 56
+00 50 B8 56 05 41 44 44 2E 42 84 12 86 56 40 50
+C4 56 04 41 44 44 43 00 84 12 86 56 00 60 D2 56
+06 41 44 44 43 2E 42 00 84 12 86 56 40 60 76 56
+04 53 55 42 43 00 84 12 86 56 00 70 F0 56 06 53
+55 42 43 2E 42 00 84 12 86 56 40 70 FE 56 03 53
+55 42 84 12 86 56 00 80 0E 57 05 53 55 42 2E 42
+84 12 86 56 40 80 70 54 03 43 4D 50 84 12 86 56
+00 90 28 57 05 43 4D 50 2E 42 84 12 86 56 40 90
+5E 54 04 44 41 44 44 00 84 12 86 56 00 A0 42 57
+06 44 41 44 44 2E 42 00 84 12 86 56 40 A0 34 57
+03 42 49 54 84 12 86 56 00 B0 60 57 05 42 49 54
+2E 42 84 12 86 56 40 B0 6C 57 03 42 49 43 84 12
+86 56 00 C0 7A 57 05 42 49 43 2E 42 84 12 86 56
+40 C0 86 57 03 42 49 53 84 12 86 56 00 D0 94 57
+05 42 49 53 2E 42 84 12 86 56 40 D0 00 00 03 58
+4F 52 84 12 86 56 00 E0 AE 57 05 58 4F 52 2E 42
+84 12 86 56 40 E0 E0 56 03 41 4E 44 84 12 86 56
+00 F0 C8 57 05 41 4E 44 2E 42 84 12 86 56 40 F0
+4C 46 40 55 E6 57 1A 42 BC 1D B2 F0 70 00 BC 1D
+8A 10 3A F0 0F 00 82 DA BC 1D 4A 3F 1A 57 03 52
+52 43 84 12 E0 57 00 10 FE 57 05 52 52 43 2E 42
+84 12 E0 57 40 10 0A 58 04 53 57 50 42 00 84 12
+E0 57 80 10 18 58 03 52 52 41 84 12 E0 57 00 11
+26 58 05 52 52 41 2E 42 84 12 E0 57 40 11 32 58
+03 53 58 54 84 12 E0 57 80 11 00 00 04 50 55 53
+48 00 84 12 E0 57 00 12 4C 58 06 50 55 53 48 2E
+42 00 84 12 E0 57 40 12 A0 57 04 43 41 4C 4C 00
+84 12 E0 57 80 12 34 44 2C 00 40 55 38 56 80 58
+59 42 BC 1D 5A 42 BD 1D 82 4A BC 1D BE 90 00 15
+00 00 02 20 0A 89 02 3C 09 8A 0A 49 3A 90 10 00
+03 2C 5A 0E A8 3F 1A 53 0E 4A 87 12 70 47 4E 49
+0D 6F 75 74 20 6F 66 20 62 6F 75 6E 64 73 2E 4D
+5A 58 05 50 55 53 48 4D 84 12 76 58 00 15 C2 58
+04 50 4F 50 4D 00 84 12 76 58 00 17 4C 46 AA 54
+E2 58 82 43 BC 1D 92 42 C4 1D BA 1D A2 53 C4 1D
+92 53 C2 1D 3E 40 2C 00 B0 12 2A 44 A8 49 BC 4A
+C0 45 BC 4D 38 56 08 59 0A 4E 3E 4F 1A 83 2A 92
+CA 2F 8A 10 5A 06 6F 3F 40 58 04 52 52 43 4D 00
+84 12 DC 58 50 00 1A 59 04 52 52 41 4D 00 84 12
+DC 58 50 01 28 59 04 52 4C 41 4D 00 84 12 DC 58
+50 02 36 59 04 52 52 55 4D 00 84 12 DC 58 50 03
+85 12 00 3C 44 59 03 53 3E 3D 85 12 00 38 56 59
+02 53 3C 00 85 12 00 34 D0 58 03 30 3E 3D 85 12
+00 30 6A 59 02 30 3C 00 85 12 00 30 00 00 02 55
+3C 00 85 12 00 2C 7E 59 03 55 3E 3D 85 12 00 28
+74 59 03 30 3C 3E 85 12 00 24 92 59 02 30 3D 00
+85 12 00 20 00 00 02 49 46 00 1A 42 C4 1D 8A 4E
+00 00 A2 53 C4 1D 0E 4A 30 4D 88 59 04 54 48 45
+4E 00 1A 42 C4 1D 08 4E 3E 4F 09 48 29 53 0A 89
+0A 11 3A 90 00 02 68 2F 88 DA 00 00 30 4D 50 57
+04 45 4C 53 45 00 1A 42 C4 1D BA 40 00 3C 00 00
+A2 53 C4 1D 2F 83 8F 4A 00 00 E3 3F BC 59 05 55
+4E 54 49 4C 3A 4F 08 4E 3E 4F 19 42 C4 1D 2A 83
+0A 89 0A 11 3A 90 00 FE 47 3B 3A F0 FF 03 08 DA
+89 48 00 00 A2 53 C4 1D 30 4D D4 57 05 41 47 41
+49 4E 87 12 50 59 04 5A 2A 44 00 00 05 57 48 49
+4C 45 87 12 AA 59 6E 44 2A 44 60 59 06 52 45 50
+45 41 54 00 87 12 50 59 04 5A C2 59 2A 44 00 00
+03 4A 4D 50 87 12 AE 4D 50 59 04 5A 2A 44 3E B0
+00 10 03 20 3E E0 00 04 30 4D 3E 90 00 34 06 28
+03 24 3E 40 00 34 30 4D 3E 40 00 38 30 4D 00 00
+04 3F 4A 4D 50 00 87 12 6E 5A AE 4D 6E 44 04 5A
+2A 44 A4 5A 3D 41 08 4E 3E 4F 2A 48 0A 93 04 20
+98 42 C4 1D 00 00 30 4D 88 43 00 00 A4 3F 6A 58
+03 42 57 31 84 12 A2 5A 00 00 C0 5A 03 42 57 32
+84 12 A2 5A 00 00 CC 5A 03 42 57 33 84 12 A2 5A
+00 00 E4 5A 3D 41 1A 42 C4 1D 28 4E 08 93 08 20
+BA 4F 00 00 A2 53 C4 1D 8E 4A 00 00 3E 4F 30 4D
+8E 43 00 00 61 3F 00 00 03 46 57 31 84 12 E2 5A
+00 00 08 5B 03 46 57 32 84 12 E2 5A 00 00 14 5B
+03 46 57 33 84 12 E2 5A 00 00 20 5B 04 47 4F 54
+4F 00 87 12 50 59 AE 4D A6 4B 2A 44 90 5A 05 3F
+47 4F 54 4F 87 12 6E 5A AE 4D A6 4B 2A 44
+@FFCC
+CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52
+CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52
+CA 52 CA 52 4C 48 CA 52 CA 52 CA 52 CA 52 CA 52
+CA 52 CA 52
+q
--- /dev/null
+\prog\MSP430Flasher\msp430flasher -m SBW2 -n MSP430fr5969 -v -w %1 -z [VCC=3000]
+exit
+
+tip : how to calculate MAIN program lenght ?
+
+open the prog.txt file with your editor, select MAIN section
+in status bar, keep the number of selected chars
+if lines are ended with CR+LF, substract the number of lines selected
+then divide by 3.
--- /dev/null
+; -*- coding: utf-8 -*-
+; MSP_EXP430FR5994.inc
+
+; Fast Forth For Texas Instrument MSP430FR5994
+;
+; Copyright (C) <2014> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+; ======================================================================
+; MSP_EXP430FR5994 board
+; ======================================================================
+;
+; J101 Target <---> eZ-FET
+; GND 14-13 GND
+; +5V 12-11
+; 3V3 10-9
+; P2.1 UCA0_RX 8-7 <---- TX UARTtoUSB bridge
+; +--4k7-< DeepRST <-- GND
+; |
+; P2.0 UCA0_TX 6-5 <-+-> RX UARTtoUSB bridge
+; /RST 4-3
+; TEST 2-1
+;
+;
+; P5.6 - sw1 <--- LCD contrast + (finger :-)
+; P5.5 - sw2 <--- LCD contrast - (finger ;-)
+; RST - sw3
+;
+; P1.0 - led1 red
+; P1.1 - led2 green
+;
+; J1 - left ext.
+; 3v3
+; P1.2/TA1.1/TA0CLK/COUT/A2/C2 <--- OUT IR_Receiver (1 TSOP32236)
+; P6.1/UCA3RXD/UCA3SOMI -------------------------> 4 LCD_RS
+; P6.0/UCA3TXD/UCA3SIMO -------------------------> 5 LCD_R/W
+; P6.2/UCA3CLK -------------------------> 6 LCD_EN0
+; P1.3/TA1.2/UCB0STE/A3/C3
+; P5.2/UCB1CLK/TA4CLK
+; P6.3/UCA3STE
+; P7.1/UCB2SOMI/UCB2SCL ---> SCL I2C MASTER/SLAVE
+; P7.0/UCB2SIMO/UCB2SDA <--> SDA I2C MASTER/SLAVE
+;
+; J3 - left int.
+; 5V
+; GND
+; P3.0/A12/C12 <------------------------> 11 LCD_DB4
+; P3.1/A13/C13 <------------------------> 12 LCD_DB5
+; P3.2/A14/C14 <------------------------> 13 LCD_DB5
+; P3.3/A15/C15 <------------------------> 14 LCD_DB7
+; P1.4/TB0.1/UCA0STE/A4/C4
+; P1.5/TB0.2/UCA0CLK/A5/C5 >---||--+--^/\/\/v--+----> 3 LCD_Vo (=0V6 without modulation)
+; P4.7
+; P8.0
+;
+; J4 - right int.
+; P3.7/TB0.6
+; P3.6/TB0.5
+; P3.5/TB0.4/COUT
+; P3.4/TB0.3/SMCLK
+; P7.3/UCB2STE/TA4.1 RTS ----> CTS UARTtoUSB bridge (optional hardware control flow)
+; P2.6/TB0.1/UCA1RXD/UCA1SOMI
+; P2.5/TB0.0/UCA1TXD/UCA1SIMO
+; P4.3/A11
+; P4.2/A10
+; P4.1/A9
+;
+; J2 - right ext.
+; GND
+; P5.7/UCA2STE/TA4.1/MCLK
+; P4.4/TB0.5
+; P5.3/UCB1STE
+; /RST
+; P5.0/UCB1SIMO/UCB1SDA
+; P5.1/UCB1SOMI/UCB1SCL
+; P8.3
+; P8.2 <--> SDA I2C SOFTWARE MASTER
+; P8.1 <--> SCL I2C SOFTWARE MASTER
+;
+; SD_CARD
+; P7.2/UCB2CLK <--- SD_CD
+; P1.6/TB0.3/UCB0SIMO/UCB0SDA/TA0.0 ---> SD_MOSI
+; P1.7/TB0.4/UCB0SOMI/UCB0SCL/TA1.0 <--- SD_MISO
+; P4.0/A8 ---> SD_CS
+; P2.2/TB0.2/UCB0CLK ---> SD_CLK
+;
+; XTAL LF 32768 Hz
+; PJ.4/LFXIN
+; PJ.5/LFXOUT
+;
+; XTAL HF
+; PJ.6/HFXIN
+; PJ.7/HFXOUT
+
+
+; -----------------------------------------------
+; LCD config
+; -----------------------------------------------
+
+; <-------+---0V0----------> 1 LCD_Vss
+; >------ | --3V6-----+----> 2 LCD_Vdd
+; | |
+; |___ 470n ---
+; ^ | ---
+; / \ BAT54 |
+; --- |
+; 100n | 2k2 |
+; TB0.2 >---||--+--^/\/\/v--+----> 3 LCD_Vo (=0V6 without modulation)
+; -------------------------> 4 LCD_RS
+; -------------------------> 5 LCD_R/W
+; -------------------------> 6 LCD_EN0
+; <------------------------> 11 LCD_DB4
+; <------------------------> 12 LCD_DB5
+; <------------------------> 13 LCD_DB5
+; <------------------------> 14 LCD_DB7
+
+
+
+; ----------------------------------------------------------------------
+; INIT order : LOCK I/O, WDT, GPIOs, FRAM, Clock, UARTs
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : LOCK PMM_LOCKLPM5
+; ----------------------------------------------------------------------
+
+; BIS #LOCKLPM5,&PM5CTL0 ; unlocked by WARM
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : WATCHDOG TIMER A
+; ----------------------------------------------------------------------
+
+ MOV #WDTPW+WDTHOLD+WDTCNTCL,&WDTCTL ; stop WDT
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : I/O
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT1/2
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT1 FastForth usage
+; P1.0 - led1 red
+; P1.1 - led2 green
+
+; PORT2 FastForth usage
+
+Deep_RST_IN .equ P2IN ; TERMINAL TX pin as FORTH Deep_RST
+Deep_RST .equ 1 ; P2.0 = TX
+TERM_TXRX .equ 003h ; P2.1 = RX
+TERM_SEL .equ P2SEL1
+TERM_REN .equ P2REN
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ BIS #3,&PADIR ; all pins 0 as input else LEDs
+ MOV #0FFFCh,&PAOUT ; all pins high else LEDs
+ BIC #3,&PAREN ; all pins 1 with pull resistors else LEDs
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT3/4
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT3 FastForth usage
+
+; PORT4 FastForth usage
+
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #-1,&PBOUT ; all pins output pull up resistors
+ BIS #-1,&PBREN ; all pins with pull resistors
+
+ .IFDEF TERMINALCTSRTS
+;configure P4.1 as RTS output high
+RTS .equ 2
+HANDSHAKOUT .equ P4OUT
+HANDSHAKIN .equ P4IN
+ BIS.B #RTS,&HANDSHAKOUT
+ .ENDIF
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT5/6
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT5 FastForth usage
+; P5.6 Switch S1 used for hard reset (WIPE+COLD)
+; P5.5 Switch S2
+SWITCHIN .set P5IN ; port
+s1 .set 020h ; P5.5 bit position
+
+; PORT6 FastForth usage
+
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #-1,&PCOUT ; all pins output high
+ BIS #-1,&PCREN ; all pins with pull resistors
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT7/8
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT7 FastForth usage
+
+; PORT8 FastForth usage
+
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #-1,&PDOUT ; all pins output high
+ BIS #-1,&PDREN ; all pins with pull resistors
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORTJ
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORTJ FastForth usage
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV.B #-1,&PJREN ; enable pullup/pulldown resistors
+ BIS.B #-1,&PJOUT ; pullup resistors
+
+
+; ----------------------------------------------------------------------
+; FRAM config
+; ----------------------------------------------------------------------
+
+ .IF FREQUENCY = 16
+ MOV.B #0A5h, &FRCTL0_H ; enable FRCTL0 access
+ MOV.B #10h, &FRCTL0 ; 1 waitstate @ 16 MHz
+ MOV.B #01h, &FRCTL0_H ; disable FRCTL0 access
+ .ENDIF
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : CLOCK SYSTEM
+; ----------------------------------------------------------------------
+
+; DCOCLK: Internal digitally controlled oscillator (DCO).
+; Startup clock system in max. DCO setting ~8MHz
+
+
+; CS code for MSP430FR5969
+ MOV.B #CSKEY,&CSCTL0_H ; Unlock CS registers
+
+ .IF FREQUENCY = 0.5
+ MOV #0,&CSCTL1 ; Set 1MHZ DCO setting
+ MOV #DIVA_2 + DIVS_2 + DIVM_2,&CSCTL3 ; set all dividers as 2
+ MOV #4,X
+
+ .ELSEIF FREQUENCY = 1
+ MOV #0,&CSCTL1 ; Set 1MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #8,X
+
+ .ELSEIF FREQUENCY = 2
+ MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 4MHZ DCO setting
+ MOV #DIVA_0 + DIVS_2 + DIVM_2,&CSCTL3
+ MOV #16,X
+
+ .ELSEIF FREQUENCY = 4
+ MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 4MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #32,X
+
+ .ELSEIF FREQUENCY = 8
+; MOV #DCOFSEL2+DCOFSEL1,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #64,X
+
+ .ELSEIF FREQUENCY = 16
+ MOV #DCORSEL+DCOFSEL2,&CSCTL1 ; Set 16MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #128,X
+
+ .ELSEIF
+ .error "bad frequency setting, only 0.5,1,2,4,8,16 MHz"
+ .ENDIF
+
+ .IFDEF LF_XTAL
+ MOV #SELA_LFXCLK+SELS_DCOCLK+SELM_DCOCLK,&CSCTL2
+ .ELSE
+ MOV #SELA_VLOCLK+SELS_DCOCLK+SELM_DCOCLK,&CSCTL2
+ .ENDIF
+ MOV.B #01h, &CSCTL0_H ; Lock CS Registers
+
+ BIS &SYSRSTIV,&SAVE_SYSRSTIV; store volatile SYSRSTIV preserving a pending request for DEEP_RST
+ CMP #2,&SAVE_SYSRSTIV ; POWER ON ?
+ JZ ClockWaitX ; yes
+ .word 0759h ; no RRUM #2,X --> wait only 125 ms
+ClockWaitX MOV #41666,Y ; wait 0.5s before starting after POWER ON
+ClockWaitY SUB #1,Y ;
+ JNZ ClockWaitY ; 41666x3 = 125000 cycles delay = 125ms @ 1MHz
+ SUB #1,X ; x 4 @ 1 MHZ
+ JNZ ClockWaitX ; time to stabilize power source ( 1s )
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : REF
+; ----------------------------------------------------------------------
+
+ MOV #8, &REFCTL
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : RTC REGISTERS
+; ----------------------------------------------------------------------
+
+ .IFDEF LF_XTAL
+; LFXIN : PJ.4, LFXOUT : PJ.5
+ BIS.B #010h,&PJSEL0 ; SEL0 for only LFXIN
+ BIC.B #RTCHOLD,&RTCCTL1 ; Clear RTCHOLD = start RTC_B
+ .ENDIF
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : SYS REGISTERS
+; ----------------------------------------------------------------------
+
+; SYS code
+; see COLD word
+
--- /dev/null
+@1800
+10 00 4C 44 80 3E 80 04 FD FF 18 00 56 57 0C 50
+2A 44 38 44 00 00 00 00
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@4000
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 40
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 40 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 40 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E 40 02 3E 52 00 0E 12 3E 4F 30 4D 8E 40
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 40
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C 40 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 40 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 41
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 40 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA 40 03 41 4E 44 3E FF 30 4D 7A 40 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E 41 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 41 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E 41 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 41 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 40 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE 41 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 41 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 41 03 3E 49 4E 85 12 C2 1D 10 41
+04 42 41 53 45 00 85 12 DA 1D C0 40 05 53 54 41
+54 45 85 12 B6 1D 30 42 02 42 4C 00 85 12 20 00
+94 41 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 42 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E 42 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 42 02 23 53 00 87 12 98 42
+D2 42 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 42 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 42 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C 42 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 41 03 55 44 2E 87 12 56 42
+CC 42 E6 42 32 45 FA 44 2A 40 18 43 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA 40
+02 44 2E 00 87 12 56 42 6E 40 80 40 3A 43 CC 42
+92 40 0A 43 E6 42 32 45 FA 44 2A 40 52 41 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 42 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 41 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 42 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A 44
+92 B3 DC 05 FD 27 1E 42 CC 05 B0 12 38 44 30 4D
+30 40 B6 43 7E 43 05 28 4B 45 59 29 18 42 CC 05
+EA 3F 12 42 03 4B 45 59 30 40 DC 43 92 43 06 41
+43 43 45 50 54 00 3C 40 8A 44 3B 40 54 44 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+7E 44 92 B3 DC 05 05 24 18 42 CC 05 38 90 0A 00
+04 20 21 53 39 40 46 44 4D 15 B2 40 11 00 CE 05
+A2 B3 DC 05 FD 27 30 41 B2 40 13 00 CE 05 A2 B3
+DC 05 FD 27 30 41 12 D2 0A 18 FD 3F 21 52 3A 17
+58 42 CC 05 48 9B F0 27 48 9C 06 2C 78 92 11 20
+2E 9F 0F 24 1E 83 05 3C 0E 9A 03 24 CE 48 00 00
+1E 53 82 48 CE 05 A2 B3 DC 05 FD 27 30 4D 80 44
+2D 83 92 B3 DC 05 FD 27 E3 23 B2 40 18 00 0A 18
+3E 8F 3D 41 30 4D D6 43 06 28 45 4D 49 54 29 00
+08 4E 3E 4F E6 3F 50 43 04 45 4D 49 54 00 30 40
+A0 44 A8 44 04 45 43 48 4F 00 B2 40 82 48 72 44
+30 4D 6E 43 06 4E 4F 45 43 48 4F 00 B2 40 30 4D
+72 44 30 4D 98 44 04 28 43 52 29 00 2F 83 8F 4E
+00 00 3E 40 0D 00 E3 3F A2 43 02 43 52 00 30 40
+DC 44 04 43 05 53 50 41 43 45 2F 83 8F 4E 00 00
+3E 40 20 00 D4 3F F4 44 06 53 50 41 43 45 53 00
+0E 93 09 24 0D 12 3D 40 1C 45 EF 3F 1E 45 2D 83
+1E 83 EB 23 3D 41 3E 4F 30 4D 2C 43 04 54 59 50
+45 00 0E 93 95 24 2A 4F 8F 5E 00 00 0E 4A 87 12
+CA 41 02 42 0A 41 AE 44 EC 41 42 45 2A 40 2F 82
+8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E 1D B3 0D 63
+30 4D 08 45 82 53 22 00 87 12 34 40 4E 45 B0 47
+34 40 22 00 A8 45 78 45 3D 41 6E 4E 1E 83 82 5E
+C4 1D 3E 4F 92 B3 C4 1D A2 63 C4 1D 30 4D C4 44
+82 2E 22 00 87 12 68 45 34 40 32 45 B0 47 2A 40
+00 00 04 57 4F 52 44 00 3C 40 BE 1D 39 4C 3A 4C
+09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A FC 27 1A 83
+3B 40 60 00 C8 4C 00 00 09 9A 0C 24 7C 4A 4E 9C
+09 24 18 53 4B 9C F6 2F 7C 90 7B 00 F3 2F 7C 80
+20 00 F0 3F 1A 82 C0 1D 82 4A C2 1D 1E 42 C4 1D
+08 8E CE 48 00 00 30 4D 00 00 04 46 49 4E 44 00
+2F 83 0C 4E 65 4C 74 40 80 00 3B 40 CA 1D 3E 4B
+0E 93 1E 24 58 4C 01 00 78 F0 1E 00 0E 58 2E 53
+1E 4E FE FF 0E 93 F3 27 09 4E 78 49 48 C4 48 95
+F7 23 0A 4C 1A 53 FA 99 00 00 F2 23 58 83 FA 23
+19 B3 09 63 0C 49 6A 4E 1E 43 4A 93 01 30 2E 83
+8F 4C 00 00 35 40 08 40 34 40 14 40 30 4D 2F 53
+2F 53 3E 4F 30 4D 26 42 07 3E 4E 55 4D 42 45 52
+3C 4F 38 4F 29 4F 2F 82 1B 42 DA 1D 6A 4C 7A 80
+30 00 7A 90 0A 00 02 28 7A 80 07 00 0A 9B 13 2C
+82 49 D0 04 82 48 D2 04 82 4B C8 04 19 42 E4 04
+18 42 E6 04 09 5A 08 63 1C 53 1E 83 E7 23 8F 49
+04 00 8F 48 02 00 8F 4C 00 00 30 4D 03 12 0D 12
+1B 42 DA 1D 0B 12 32 C0 00 02 6D 4E 0D 5E 0C 4E
+7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23 32 D0 00 02
+FC 4C FE FF 0D 9C FC 2F DE 83 00 00 09 43 08 43
+3D 40 32 47 3F 82 8F 4E 06 00 0C 4E 7E 4C 6A 4C
+7A 90 2D 00 10 2C 3B 40 10 00 7A 80 24 00 06 24
+2B 43 5A 83 03 24 3B 52 6A 53 B0 23 1C 53 1E 83
+6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83 B1 43 04 00
+A5 3F 34 47 2F 53 0E 93 2C 17 82 4C DA 1D 03 24
+2F 52 0E F3 30 4D 8F 93 00 00 15 20 32 B0 00 02
+14 20 0E 93 05 24 1A 4F 02 00 1A 83 0A 93 0B 38
+2F 53 BF 4F 00 00 3E E3 05 20 BF E3 00 00 9F 53
+00 00 3E E3 30 4D 32 D0 00 02 9F 4F 02 00 04 00
+BF 4F 00 00 3E E3 F6 23 BF E3 02 00 BF E3 00 00
+9F 53 02 00 8F 63 00 00 3E E3 30 4D B4 44 07 45
+58 45 43 55 54 45 0A 4E 3E 4F 00 4A 28 41 01 2C
+1A 42 C4 1D A2 53 C4 1D 8A 4E 00 00 3E 4F 30 4D
+AE 47 87 4C 49 54 45 52 41 4C 82 93 B6 1D 16 24
+32 B0 00 02 09 24 1A 42 C4 1D A2 52 C4 1D BA 40
+34 40 00 00 BA 4F 02 00 1A 42 C4 1D A2 52 C4 1D
+BA 40 34 40 00 00 8A 4E 02 00 3E 4F 30 4D EA 44
+05 43 4F 55 4E 54 2F 83 1E 53 8F 4E 00 00 5E 4E
+FF FF 30 4D 82 4E BE 1D B2 4F C0 1D 3E 4F 82 43
+C2 1D 87 12 4C 42 A8 45 2A 48 3D 40 36 48 E8 22
+3D 41 3E 4F 30 4D 38 48 0A 4E 3E 4F 3D 40 4E 48
+3D 27 3D 40 24 48 1A E2 B6 1D B2 27 AC 23 50 48
+3E 4F 3D 40 24 48 B9 23 DE 53 00 00 68 4E 08 5E
+F8 40 3F 00 00 00 3D 40 16 4A CD 3F 9E 47 08 45
+56 41 4C 55 41 54 45 00 39 40 BE 1D 39 12 39 12
+39 12 0D 12 B0 12 2A 40 14 48 8C 48 3D 41 B2 41
+C2 1D B2 41 C0 1D B2 41 BE 1D 30 4D 7A 41 04 51
+55 49 54 00 31 40 E0 1C B2 40 00 1C AC 1D 82 43
+B6 1D 82 43 08 18 B0 12 2A 40 4E 45 04 0D 6F 6B
+20 00 32 45 34 40 38 1D 44 40 34 40 50 00 F6 43
+FA 44 14 48 34 40 7E 1C CE 40 B2 41 4E 45 0D 73
+74 61 63 6B 20 65 6D 70 74 79 20 21 28 49 34 40
+30 FF 84 43 B2 41 4E 45 0B 46 52 41 4D 20 66 75
+6C 6C 20 21 28 49 42 42 F4 40 C0 41 BA 48 4E 45
+04 0D 20 20 20 00 BC 41 C2 48 EE 43 05 41 42 4F
+52 54 3F 40 80 1C BE 3F 8F 93 02 00 98 26 B2 40
+82 48 72 44 B0 12 10 4E 82 43 D0 56 82 43 DC 56
+82 43 E8 56 82 43 18 57 82 43 24 57 82 43 30 57
+A2 B3 DC 05 FD 27 B2 40 11 00 CE 05 92 C3 DC 05
+38 40 A0 AA 39 42 19 83 FE 23 18 83 FB 23 92 B3
+DC 05 F4 23 87 12 4E 45 04 1B 5B 37 6D 00 32 45
+32 45 4E 45 04 1B 5B 30 6D 00 32 45 58 4D 9A 4D
+A0 4D 22 49 1C 49 86 41 42 4F 52 54 22 00 87 12
+68 45 34 40 28 49 B0 47 2A 40 FA 45 01 27 87 12
+4C 42 A8 45 00 46 C0 41 BC 49 2A 40 58 48 52 42
+81 5C 92 42 BE 1D C2 1D 30 4D 87 12 84 45 4C 42
+A8 45 D4 49 08 4E 7A 4E 5A D3 5A 53 0A 58 19 42
+C8 1D 6E 4E 3E F0 1E 00 09 5E 82 48 AE 1D 82 49
+B0 1D 82 4A B2 1D 2A 52 82 4A C4 1D 3E 4F 3D 41
+30 41 87 12 4E 45 0F 73 74 61 63 6B 20 6D 69 73
+6D 61 74 63 68 21 2E 49 82 9F B4 1D F2 23 18 42
+AE 1D 19 42 B0 1D A8 49 FE FF 89 48 00 00 30 4D
+A2 45 08 56 41 52 49 41 42 4C 45 00 B0 12 CA 49
+BA 40 86 12 FC FF EF 3F 00 48 08 43 4F 4E 53 54
+41 4E 54 00 B0 12 CA 49 BA 40 85 12 FC FF 8A 4E
+FE FF 3E 4F E0 3F 4A 4A 06 43 52 45 41 54 45 00
+B0 12 CA 49 BA 40 85 12 FC FF 8A 4A FE FF D3 3F
+6E 48 05 44 4F 45 53 3E 1A 42 B2 1D BA 40 84 12
+00 00 8A 4D 02 00 3D 41 30 4D 82 4A 05 44 45 46
+45 52 B0 12 CA 49 BA 40 30 40 FC FF BA 40 98 4A
+FE FF B9 3F 00 00 81 5B 82 43 B6 1D 30 4D C0 49
+01 5D B2 43 B6 1D 30 4D 64 45 87 52 45 43 55 52
+53 45 19 42 C4 1D 99 42 B2 1D 00 00 A2 53 C4 1D
+30 4D B6 4A 01 3A B0 12 CA 49 BA 40 87 12 FC FF
+A2 83 C4 1D B2 43 B6 1D 82 4F B4 1D 30 4D E4 4A
+81 3B 82 93 B6 1D 5D 27 87 12 34 40 2A 40 B0 47
+18 4A B8 4A 2A 40 D6 44 09 49 4D 4D 45 44 49 41
+54 45 1A 42 AE 1D FA D0 80 00 00 00 30 4D BE 4F
+02 00 3E 4F 30 4D 18 4B 82 49 53 00 87 12 42 42
+F4 40 C0 41 50 4B 5C 4B 34 40 2E 4B B0 47 2A 40
+AE 49 2E 4B 2A 40 00 4B 83 5B 27 5D 87 12 AE 49
+34 40 34 40 B0 47 B0 47 2A 40 9E 48 88 50 4F 53
+54 50 4F 4E 45 00 87 12 4C 42 A8 45 00 46 54 40
+C0 41 BC 49 7E 41 C0 41 96 4B 34 40 34 40 B0 47
+B0 47 34 40 B0 47 B0 47 2A 40 9C 4B 3A 4E 82 4A
+C6 1D 2E 4E 82 4E C4 1D 3D 40 10 00 09 4A 08 49
+29 83 18 48 FE FF 0E 98 FC 2B 89 48 00 00 1D 83
+F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41 30 4D 38 4B
+82 49 46 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40
+C0 41 00 00 A2 52 C4 1D 2E 53 30 4D 9C 4A 84 45
+4C 53 45 00 1A 42 C4 1D BA 40 BC 41 00 00 2A 52
+82 4A C4 1D 8E 4A 00 00 2A 83 0E 4A 30 4D 2C 45
+84 54 48 45 4E 00 9E 42 C4 1D 00 00 3E 4F 30 4D
+68 4A 85 42 45 47 49 4E 30 40 84 43 10 4C 85 55
+4E 54 49 4C 39 40 C0 41 1A 42 C4 1D A2 52 C4 1D
+8A 49 00 00 8A 4E 02 00 3E 4F 30 4D 96 49 85 41
+47 41 49 4E 39 40 BC 41 EF 3F 32 4A 85 57 48 49
+4C 45 87 12 D4 4B 6E 40 2A 40 CA 4A 86 52 45 50
+45 41 54 00 87 12 54 4C 16 4C 2A 40 EE 4B 82 44
+4F 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40 CA 41
+00 00 2E 53 82 4E C4 1D A2 53 AC 1D 1A 42 AC 1D
+8A 43 00 00 30 4D C2 47 84 4C 4F 4F 50 00 39 40
+EC 41 1A 42 C4 1D A2 52 C4 1D 8A 49 00 00 8A 4E
+02 00 1E 42 AC 1D A2 83 AC 1D 2E 4E 0E 93 04 24
+9E 42 C4 1D 00 00 F5 3F 3E 4F 30 4D E4 43 85 2B
+4C 4F 4F 50 39 40 DA 41 E4 3F A8 4C 85 4C 45 41
+56 45 1A 42 C4 1D BA 40 FC 41 00 00 BA 40 BC 41
+02 00 B2 50 06 00 C4 1D A2 53 AC 1D 2A 52 19 42
+AC 1D 89 4A 00 00 30 4D EC 4C 04 4D 4F 56 45 00
+0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24 08 99 0F 24
+06 2C F8 49 00 00 18 53 1A 83 FB 23 30 4D 08 5A
+09 5A 19 83 18 83 E8 49 00 00 1A 83 FA 23 30 4D
+34 40 CA 1D FC 40 2A 40 84 12 50 4D 40 50 28 50
+7E 4C AC 49 10 50 DE 4C 1A 4D 90 45 BE 4D F2 4D
+2E 4C B2 4E 48 41 58 4B C0 4A 68 46 00 00 3A 40
+0C 00 39 40 CA 1D 38 40 CC 1D D9 3F 3A 40 0E 00
+39 40 CC 1D 38 40 CA 1D CC 3F 82 43 CC 1D 30 4D
+92 42 CA 1D C8 1D 30 4D 6C 4B 09 50 57 52 5F 53
+54 41 54 45 84 12 9A 4B 0C 50 56 57 AA 4D 08 50
+57 52 5F 48 45 52 45 00 92 42 C4 1D BA 4D 92 42
+C6 1D B8 4D EF 3F 6C 4C 09 52 53 54 5F 53 54 41
+54 45 92 42 0C 18 BA 4D 92 42 0E 18 B8 4D E2 3F
+D8 4D 08 52 53 54 5F 48 45 52 45 00 92 42 C4 1D
+0C 18 92 42 C6 1D 0E 18 DF 3F B2 40 58 4E BA 4E
+B2 40 A0 44 B0 44 B2 40 DC 44 F0 44 B2 40 DC 43
+EA 43 30 41 5C 4C 04 57 49 50 45 00 39 40 80 FF
+B9 43 00 00 29 53 39 90 B4 FF FA 23 B0 12 0A 4E
+B2 40 56 57 C4 1D B2 40 0C 50 C6 1D D7 3F D0 4B
+06 28 57 41 52 4D 29 00 1E 42 08 18 87 12 4E 45
+05 0D 1B 5B 37 6D 32 45 70 43 4E 45 27 20 46 61
+73 74 46 6F 72 74 68 20 56 31 36 30 20 31 36 4D
+48 7A 20 28 43 29 20 4A 2E 4D 2E 54 68 6F 6F 72
+65 6E 73 20 32 45 34 40 30 FF 84 43 2A 41 30 43
+4E 45 0B 62 79 74 65 73 20 66 72 65 65 20 34 49
+26 4E 04 57 41 52 4D 00 30 40 58 4E 22 4C 04 43
+4F 4C 44 00 B2 40 04 A5 20 01 B2 40 88 5A 5C 01
+B2 D0 03 00 04 02 B2 40 FC FF 02 02 B2 C0 03 00
+06 02 B2 43 22 02 B2 D3 26 02 B2 43 42 02 B2 D3
+46 02 B2 43 62 02 B2 D3 66 02 F2 43 26 03 F2 D3
+22 03 F2 40 A5 00 41 01 F2 40 10 00 40 01 D2 43
+41 01 F2 40 A5 00 61 01 B2 40 48 00 62 01 82 43
+66 01 39 40 80 00 B2 40 33 00 64 01 D2 43 61 01
+92 D2 9E 01 08 18 A2 93 08 18 01 24 59 07 38 40
+C2 A2 18 83 FE 23 19 83 FA 23 B2 42 B0 01 F2 D0
+10 00 2A 03 F2 C0 40 00 A2 04 3A 40 CA 4E 39 40
+B4 FF 89 4A 00 00 29 53 FC 23 92 42 02 18 F0 FF
+B2 40 18 00 0A 18 31 40 E0 1C 3F 40 80 1C 37 40
+00 40 36 40 B4 40 35 40 08 40 34 40 14 40 B2 40
+0A 00 DA 1D B2 43 DC 1D 92 C3 30 01 18 42 08 18
+D2 B3 01 02 04 20 38 E3 18 53 82 48 08 18 B2 40
+81 00 C0 05 B2 42 C6 05 B2 40 A1 F7 C8 05 F2 D0
+03 00 0D 02 92 C3 C0 05 92 D3 DA 05 3D 40 E6 4F
+18 42 08 18 38 90 0A 00 29 27 38 90 16 00 26 2F
+28 93 FF 22 E7 26 B8 4E 84 12 50 4D 34 56 E0 56
+E8 55 34 57 AE 55 68 56 B2 52 00 00 A4 55 54 56
+06 56 44 56 C2 53 00 00 00 00 46 57 7C 4D 50 4E
+85 48 49 32 4C 4F 87 12 84 43 E8 4B B0 47 B8 4A
+7E 4D E8 4F 2A 40 BE 4E 04 43 4F 44 45 00 B0 12
+CA 49 A2 82 C4 1D 87 12 F8 4A BC 41 20 50 4E 4C
+03 41 53 4D 92 42 C8 1D B8 1D B2 40 EC 4F C8 1D
+EE 3F 00 00 07 45 4E 44 43 4F 44 45 87 12 8C 4D
+18 4A 2A 40 54 50 06 45 4E 44 41 53 4D 00 92 42
+B8 1D C8 1D F3 3F 00 00 05 43 4F 4C 4F 4E 1A 42
+C4 1D BA 40 87 12 00 00 A2 53 C4 1D B2 43 B6 1D
+30 40 8C 4D 00 00 05 4C 4F 32 48 49 1A 42 C4 1D
+BA 40 B0 12 00 00 BA 40 2A 40 02 00 A2 52 C4 1D
+ED 3F 38 40 BE 1D 39 48 2A 48 09 5A 1A 52 C2 1D
+09 9A 03 24 7E 9A FC 27 1A 83 0E 4A 2A 88 82 4A
+C2 1D 30 4D B0 12 2A 40 A8 45 00 46 72 41 C0 41
+EA 50 BC 46 C0 41 BC 49 0C 51 EC 50 29 4E 39 90
+86 12 02 20 2E 53 30 41 39 90 85 12 03 20 1E 4E
+02 00 30 41 39 90 84 12 01 20 2E 52 30 41 19 42
+C4 1D A2 53 C4 1D 89 4E 00 00 3E 40 29 00 12 12
+C2 1D 92 53 C2 1D B0 12 2A 40 A8 45 BC 46 C0 41
+3E 51 34 51 21 53 3E 90 10 00 BB 2D 30 41 40 51
+B2 41 C2 1D 22 D3 30 41 87 12 4C 42 B2 50 50 51
+82 43 BC 1D 92 42 C4 1D BA 1D A2 53 C4 1D 0A 4E
+3E 4F FA 90 23 00 00 00 34 20 92 53 C2 1D B0 12
+D4 50 0E 93 04 20 B2 40 00 03 BC 1D 27 3C 1E 93
+04 20 B2 40 10 03 BC 1D 21 3C 2E 93 04 20 B2 40
+20 03 BC 1D 1B 3C 2E 92 04 20 B2 40 20 02 BC 1D
+15 3C 3E 92 04 20 B2 40 30 02 BC 1D 0F 3C 3E 93
+04 20 B2 40 30 03 BC 1D 09 3C B2 40 30 00 BC 1D
+19 42 C4 1D A2 53 C4 1D 89 4E 00 00 3E 4F 3D 41
+30 4D FA 90 26 00 00 00 08 20 B2 40 10 02 BC 1D
+92 53 C2 1D 30 12 C0 51 75 3F FA 90 40 00 00 00
+1A 20 B2 40 20 00 BC 1D 92 53 C2 1D B0 12 1E 51
+0E 20 B2 50 10 00 BC 1D 3E 40 2B 00 B0 12 1E 51
+32 24 92 92 BE 1D C2 1D 02 24 92 53 C2 1D 8E 10
+82 5E BC 1D D3 3F B0 12 1E 51 F9 23 B2 50 10 00
+BC 1D 3E 40 28 00 B0 12 D4 50 30 12 10 52 67 3F
+87 12 4C 42 B2 50 48 52 FE 90 26 00 00 00 3E 40
+20 00 04 20 B2 50 82 00 BC 1D C2 3F B0 12 1E 51
+DF 23 B2 50 80 00 BC 1D 3E 40 28 00 B0 12 D4 50
+B0 12 0E 51 D5 23 3D 40 BC 49 30 4D 00 00 04 52
+45 54 49 00 87 12 34 40 00 13 B0 47 2A 40 34 40
+2C 00 48 51 40 52 98 52 2E 4E 1E D2 BC 1D 19 42
+BA 1D 92 3F 96 50 03 4D 4F 56 84 12 8E 52 00 40
+A6 52 05 4D 4F 56 2E 42 84 12 8E 52 40 40 00 00
+03 41 44 44 84 12 8E 52 00 50 C0 52 05 41 44 44
+2E 42 84 12 8E 52 40 50 CC 52 04 41 44 44 43 00
+84 12 8E 52 00 60 DA 52 06 41 44 44 43 2E 42 00
+84 12 8E 52 40 60 7E 52 04 53 55 42 43 00 84 12
+8E 52 00 70 F8 52 06 53 55 42 43 2E 42 00 84 12
+8E 52 40 70 06 53 03 53 55 42 84 12 8E 52 00 80
+16 53 05 53 55 42 2E 42 84 12 8E 52 40 80 78 50
+03 43 4D 50 84 12 8E 52 00 90 30 53 05 43 4D 50
+2E 42 84 12 8E 52 40 90 66 50 04 44 41 44 44 00
+84 12 8E 52 00 A0 4A 53 06 44 41 44 44 2E 42 00
+84 12 8E 52 40 A0 3C 53 03 42 49 54 84 12 8E 52
+00 B0 68 53 05 42 49 54 2E 42 84 12 8E 52 40 B0
+74 53 03 42 49 43 84 12 8E 52 00 C0 82 53 05 42
+49 43 2E 42 84 12 8E 52 40 C0 8E 53 03 42 49 53
+84 12 8E 52 00 D0 9C 53 05 42 49 53 2E 42 84 12
+8E 52 40 D0 00 00 03 58 4F 52 84 12 8E 52 00 E0
+B6 53 05 58 4F 52 2E 42 84 12 8E 52 40 E0 E8 52
+03 41 4E 44 84 12 8E 52 00 F0 D0 53 05 41 4E 44
+2E 42 84 12 8E 52 40 F0 4C 42 48 51 EE 53 1A 42
+BC 1D B2 F0 70 00 BC 1D 8A 10 3A F0 0F 00 82 DA
+BC 1D 4A 3F 22 53 03 52 52 43 84 12 E8 53 00 10
+06 54 05 52 52 43 2E 42 84 12 E8 53 40 10 12 54
+04 53 57 50 42 00 84 12 E8 53 80 10 20 54 03 52
+52 41 84 12 E8 53 00 11 2E 54 05 52 52 41 2E 42
+84 12 E8 53 40 11 3A 54 03 53 58 54 84 12 E8 53
+80 11 00 00 04 50 55 53 48 00 84 12 E8 53 00 12
+54 54 06 50 55 53 48 2E 42 00 84 12 E8 53 40 12
+A8 53 04 43 41 4C 4C 00 84 12 E8 53 80 12 34 40
+2C 00 48 51 40 52 88 54 59 42 BC 1D 5A 42 BD 1D
+82 4A BC 1D BE 90 00 15 00 00 02 20 0A 89 02 3C
+09 8A 0A 49 3A 90 10 00 03 2C 5A 0E A8 3F 1A 53
+0E 4A 87 12 70 43 4E 45 0D 6F 75 74 20 6F 66 20
+62 6F 75 6E 64 73 2E 49 62 54 05 50 55 53 48 4D
+84 12 7E 54 00 15 CA 54 04 50 4F 50 4D 00 84 12
+7E 54 00 17 4C 42 B2 50 EA 54 82 43 BC 1D 92 42
+C4 1D BA 1D A2 53 C4 1D 92 53 C2 1D 3E 40 2C 00
+B0 12 2A 40 A8 45 BC 46 C0 41 BC 49 40 52 10 55
+0A 4E 3E 4F 1A 83 2A 92 CA 2F 8A 10 5A 06 6F 3F
+48 54 04 52 52 43 4D 00 84 12 E4 54 50 00 22 55
+04 52 52 41 4D 00 84 12 E4 54 50 01 30 55 04 52
+4C 41 4D 00 84 12 E4 54 50 02 3E 55 04 52 52 55
+4D 00 84 12 E4 54 50 03 85 12 00 3C 4C 55 03 53
+3E 3D 85 12 00 38 5E 55 02 53 3C 00 85 12 00 34
+D8 54 03 30 3E 3D 85 12 00 30 72 55 02 30 3C 00
+85 12 00 30 00 00 02 55 3C 00 85 12 00 2C 86 55
+03 55 3E 3D 85 12 00 28 7C 55 03 30 3C 3E 85 12
+00 24 9A 55 02 30 3D 00 85 12 00 20 00 00 02 49
+46 00 1A 42 C4 1D 8A 4E 00 00 A2 53 C4 1D 0E 4A
+30 4D 90 55 04 54 48 45 4E 00 1A 42 C4 1D 08 4E
+3E 4F 09 48 29 53 0A 89 0A 11 3A 90 00 02 68 2F
+88 DA 00 00 30 4D 58 53 04 45 4C 53 45 00 1A 42
+C4 1D BA 40 00 3C 00 00 A2 53 C4 1D 2F 83 8F 4A
+00 00 E3 3F C4 55 05 55 4E 54 49 4C 3A 4F 08 4E
+3E 4F 19 42 C4 1D 2A 83 0A 89 0A 11 3A 90 00 FE
+47 3B 3A F0 FF 03 08 DA 89 48 00 00 A2 53 C4 1D
+30 4D DC 53 05 41 47 41 49 4E 87 12 58 55 0C 56
+2A 40 00 00 05 57 48 49 4C 45 87 12 B2 55 6E 40
+2A 40 68 55 06 52 45 50 45 41 54 00 87 12 58 55
+0C 56 CA 55 2A 40 00 00 03 4A 4D 50 87 12 AE 49
+58 55 0C 56 2A 40 3E B0 00 10 03 20 3E E0 00 04
+30 4D 3E 90 00 34 06 28 03 24 3E 40 00 34 30 4D
+3E 40 00 38 30 4D 00 00 04 3F 4A 4D 50 00 87 12
+76 56 AE 49 6E 40 0C 56 2A 40 AC 56 3D 41 08 4E
+3E 4F 2A 48 0A 93 04 20 98 42 C4 1D 00 00 30 4D
+88 43 00 00 A4 3F 72 54 03 42 57 31 84 12 AA 56
+00 00 C8 56 03 42 57 32 84 12 AA 56 00 00 D4 56
+03 42 57 33 84 12 AA 56 00 00 EC 56 3D 41 1A 42
+C4 1D 28 4E 08 93 08 20 BA 4F 00 00 A2 53 C4 1D
+8E 4A 00 00 3E 4F 30 4D 8E 43 00 00 61 3F 00 00
+03 46 57 31 84 12 EA 56 00 00 10 57 03 46 57 32
+84 12 EA 56 00 00 1C 57 03 46 57 33 84 12 EA 56
+00 00 28 57 04 47 4F 54 4F 00 87 12 58 55 AE 49
+A6 47 2A 40 98 56 05 3F 47 4F 54 4F 87 12 76 56
+AE 49 A6 47 2A 40
+@FFB4
+CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E
+CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E
+CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E
+CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E 4C 44 CA 4E
+CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E
+q
--- /dev/null
+@1800
+10 00 C8 44 80 3E 80 04 FD FF 18 00 E4 62 EC 51
+A6 44 B4 44 E6 59 24 5A
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@2000
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+@4000
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 40
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 40 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 40 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E 40 02 3E 52 00 0E 12 3E 4F 30 4D 8E 40
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 40
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C 40 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 40 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 41
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 40 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA 40 03 41 4E 44 3E FF 30 4D 7A 40 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E 41 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 41 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E 41 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 41 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 40 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE 41 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 41 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 41 03 3E 49 4E 85 12 C2 1D 10 41
+04 42 41 53 45 00 85 12 DA 1D C0 40 05 53 54 41
+54 45 85 12 B6 1D 30 42 02 42 4C 00 85 12 20 00
+94 41 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 42 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E 42 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 42 02 23 53 00 87 12 98 42
+D2 42 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 42 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 42 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C 42 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 41 03 55 44 2E 87 12 56 42
+CC 42 E6 42 AE 45 76 45 2A 40 18 43 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA 40
+02 44 2E 00 87 12 56 42 6E 40 80 40 3A 43 CC 42
+92 40 0A 43 E6 42 AE 45 76 45 2A 40 52 41 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 42 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 41 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 42 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 A6 44
+92 B3 DC 05 FD 27 1E 42 CC 05 B0 12 B4 44 30 4D
+30 40 B6 43 7E 43 05 28 4B 45 59 29 18 42 CC 05
+EA 3F 12 42 03 4B 45 59 30 40 DC 43 0D 12 3D 40
+12 44 1B 42 36 20 9B 42 1E 20 16 00 3A 40 00 21
+8F 4A 02 00 BF 40 50 00 00 00 0E 43 19 42 1E 20
+02 3C 14 44 2D 83 19 92 20 20 16 2C 58 49 00 1E
+19 53 78 90 20 00 08 2C 78 90 0A 00 F4 23 82 49
+1E 20 2F 53 3D 41 30 4D 8F 9E 00 00 58 24 CA 48
+00 00 1A 53 1E 53 53 3C 0A 12 B0 12 50 5B 3A 41
+82 93 20 20 DB 23 ED 3F 92 43 06 41 43 43 45 50
+54 00 30 40 72 44 D6 43 08 28 41 43 43 45 50 54
+29 00 3C 40 06 45 3B 40 D0 44 2D 15 0A 4E 2E 4F
+0A 5E 3B 40 0D 00 3C 40 20 00 3D 40 FA 44 92 B3
+DC 05 05 24 18 42 CC 05 38 90 0A 00 04 20 21 53
+39 40 C2 44 4D 15 B2 40 11 00 CE 05 A2 B3 DC 05
+FD 27 30 41 B2 40 13 00 CE 05 A2 B3 DC 05 FD 27
+30 41 12 D2 0A 18 FD 3F 21 52 3A 17 58 42 CC 05
+48 9B F0 27 48 9C 06 2C 78 92 11 20 2E 9F 0F 24
+1E 83 05 3C 0E 9A 03 24 CE 48 00 00 1E 53 82 48
+CE 05 A2 B3 DC 05 FD 27 30 4D FC 44 2D 83 92 B3
+DC 05 FD 27 E3 23 B2 40 18 00 0A 18 3E 8F 3D 41
+30 4D 68 44 06 28 45 4D 49 54 29 00 08 4E 3E 4F
+E6 3F 50 43 04 45 4D 49 54 00 30 40 1C 45 24 45
+04 45 43 48 4F 00 B2 40 82 48 EE 44 30 4D 6E 43
+06 4E 4F 45 43 48 4F 00 B2 40 30 4D EE 44 30 4D
+14 45 04 28 43 52 29 00 2F 83 8F 4E 00 00 3E 40
+0D 00 E3 3F A2 43 02 43 52 00 30 40 58 45 04 43
+05 53 50 41 43 45 2F 83 8F 4E 00 00 3E 40 20 00
+D4 3F 70 45 06 53 50 41 43 45 53 00 0E 93 09 24
+0D 12 3D 40 98 45 EF 3F 9A 45 2D 83 1E 83 EB 23
+3D 41 3E 4F 30 4D 2C 43 04 54 59 50 45 00 0E 93
+95 24 2A 4F 8F 5E 00 00 0E 4A 87 12 CA 41 02 42
+0A 41 2A 45 EC 41 BE 45 2A 40 2F 82 8F 4E 02 00
+7E 4D 8F 4D 00 00 0D 5E 1D B3 0D 63 30 4D 84 45
+82 53 22 00 87 12 34 40 CA 45 2C 48 34 40 22 00
+24 46 F4 45 3D 41 6E 4E 1E 83 82 5E C4 1D 3E 4F
+92 B3 C4 1D A2 63 C4 1D 30 4D 40 45 82 2E 22 00
+87 12 E4 45 34 40 AE 45 2C 48 2A 40 00 00 04 57
+4F 52 44 00 3C 40 BE 1D 39 4C 3A 4C 09 5A 3A 5C
+28 4C 09 9A 19 24 7E 9A FC 27 1A 83 3B 40 60 00
+C8 4C 00 00 09 9A 0C 24 7C 4A 4E 9C 09 24 18 53
+4B 9C F6 2F 7C 90 7B 00 F3 2F 7C 80 20 00 F0 3F
+1A 82 C0 1D 82 4A C2 1D 1E 42 C4 1D 08 8E CE 48
+00 00 30 4D 00 00 04 46 49 4E 44 00 2F 83 0C 4E
+65 4C 74 40 80 00 3B 40 CA 1D 3E 4B 0E 93 1E 24
+58 4C 01 00 78 F0 1E 00 0E 58 2E 53 1E 4E FE FF
+0E 93 F3 27 09 4E 78 49 48 C4 48 95 F7 23 0A 4C
+1A 53 FA 99 00 00 F2 23 58 83 FA 23 19 B3 09 63
+0C 49 6A 4E 1E 43 4A 93 01 30 2E 83 8F 4C 00 00
+35 40 08 40 34 40 14 40 30 4D 2F 53 2F 53 3E 4F
+30 4D 26 42 07 3E 4E 55 4D 42 45 52 3C 4F 38 4F
+29 4F 2F 82 1B 42 DA 1D 6A 4C 7A 80 30 00 7A 90
+0A 00 02 28 7A 80 07 00 0A 9B 13 2C 82 49 D0 04
+82 48 D2 04 82 4B C8 04 19 42 E4 04 18 42 E6 04
+09 5A 08 63 1C 53 1E 83 E7 23 8F 49 04 00 8F 48
+02 00 8F 4C 00 00 30 4D 03 12 0D 12 1B 42 DA 1D
+0B 12 32 C0 00 02 6D 4E 0D 5E 0C 4E 7A 40 2E 00
+0D 9C 0A 28 7A 9C FC 23 32 D0 00 02 FC 4C FE FF
+0D 9C FC 2F DE 83 00 00 09 43 08 43 3D 40 AE 47
+3F 82 8F 4E 06 00 0C 4E 7E 4C 6A 4C 7A 90 2D 00
+10 2C 3B 40 10 00 7A 80 24 00 06 24 2B 43 5A 83
+03 24 3B 52 6A 53 B0 23 1C 53 1E 83 6A 4C 7A 90
+2D 00 AA 23 1C 53 1E 83 B1 43 04 00 A5 3F B0 47
+2F 53 0E 93 2C 17 82 4C DA 1D 03 24 2F 52 0E F3
+30 4D 8F 93 00 00 15 20 32 B0 00 02 14 20 0E 93
+05 24 1A 4F 02 00 1A 83 0A 93 0B 38 2F 53 BF 4F
+00 00 3E E3 05 20 BF E3 00 00 9F 53 00 00 3E E3
+30 4D 32 D0 00 02 9F 4F 02 00 04 00 BF 4F 00 00
+3E E3 F6 23 BF E3 02 00 BF E3 00 00 9F 53 02 00
+8F 63 00 00 3E E3 30 4D 30 45 07 45 58 45 43 55
+54 45 0A 4E 3E 4F 00 4A 28 41 01 2C 1A 42 C4 1D
+A2 53 C4 1D 8A 4E 00 00 3E 4F 30 4D 2A 48 87 4C
+49 54 45 52 41 4C 82 93 B6 1D 16 24 32 B0 00 02
+09 24 1A 42 C4 1D A2 52 C4 1D BA 40 34 40 00 00
+BA 4F 02 00 1A 42 C4 1D A2 52 C4 1D BA 40 34 40
+00 00 8A 4E 02 00 3E 4F 30 4D 66 45 05 43 4F 55
+4E 54 2F 83 1E 53 8F 4E 00 00 5E 4E FF FF 30 4D
+82 4E BE 1D B2 4F C0 1D 3E 4F 82 43 C2 1D 87 12
+4C 42 24 46 A6 48 3D 40 B2 48 E8 22 3D 41 3E 4F
+30 4D B4 48 0A 4E 3E 4F 3D 40 CA 48 3D 27 3D 40
+A0 48 1A E2 B6 1D B2 27 AC 23 CC 48 3E 4F 3D 40
+A0 48 B9 23 DE 53 00 00 68 4E 08 5E F8 40 3F 00
+00 00 3D 40 A2 4A CD 3F 1A 48 08 45 56 41 4C 55
+41 54 45 00 39 40 BE 1D 39 12 39 12 39 12 0D 12
+B0 12 2A 40 90 48 08 49 3D 41 B2 41 C2 1D B2 41
+C0 1D B2 41 BE 1D 30 4D 7A 41 04 51 55 49 54 00
+31 40 E0 1C B2 40 00 1C AC 1D 82 43 B6 1D 82 43
+08 18 B0 12 2A 40 CA 45 04 0D 6F 6B 20 00 AE 45
+34 40 38 1D 44 40 34 40 50 00 62 44 76 45 90 48
+34 40 7E 1C CE 40 B2 41 CA 45 0D 73 74 61 63 6B
+20 65 6D 70 74 79 20 21 A4 49 34 40 30 FF 84 43
+B2 41 CA 45 0B 46 52 41 4D 20 66 75 6C 6C 20 21
+A4 49 42 42 F4 40 C0 41 36 49 CA 45 04 0D 20 20
+20 00 BC 41 3E 49 5A 44 05 41 42 4F 52 54 3F 40
+80 1C BE 3F 8F 93 02 00 98 26 B2 40 82 48 EE 44
+1B 42 36 20 0B 93 04 24 CB 43 02 00 2B 4B FA 3F
+B0 12 9C 4E 82 43 B0 58 82 43 BC 58 82 43 C8 58
+82 43 F8 58 82 43 04 59 82 43 10 59 A2 B3 DC 05
+FD 27 B2 40 11 00 CE 05 92 C3 DC 05 38 40 A0 AA
+39 42 19 83 FE 23 18 83 FB 23 92 B3 DC 05 F4 23
+87 12 CA 45 04 1B 5B 37 6D 00 AE 45 AE 45 CA 45
+04 1B 5B 30 6D 00 AE 45 E4 4D 26 4E 2C 4E 9E 49
+98 49 86 41 42 4F 52 54 22 00 87 12 E4 45 34 40
+A4 49 2C 48 2A 40 76 46 01 27 87 12 4C 42 24 46
+7C 46 C0 41 48 4A 2A 40 D4 48 52 42 81 5C 92 42
+BE 1D C2 1D 30 4D 87 12 00 46 4C 42 24 46 60 4A
+08 4E 7A 4E 5A D3 5A 53 0A 58 19 42 C8 1D 6E 4E
+3E F0 1E 00 09 5E 82 48 AE 1D 82 49 B0 1D 82 4A
+B2 1D 2A 52 82 4A C4 1D 3E 4F 3D 41 30 41 87 12
+CA 45 0F 73 74 61 63 6B 20 6D 69 73 6D 61 74 63
+68 21 AA 49 82 9F B4 1D F2 23 18 42 AE 1D 19 42
+B0 1D A8 49 FE FF 89 48 00 00 30 4D 1E 46 08 56
+41 52 49 41 42 4C 45 00 B0 12 56 4A BA 40 86 12
+FC FF EF 3F 7C 48 08 43 4F 4E 53 54 41 4E 54 00
+B0 12 56 4A BA 40 85 12 FC FF 8A 4E FE FF 3E 4F
+E0 3F D6 4A 06 43 52 45 41 54 45 00 B0 12 56 4A
+BA 40 85 12 FC FF 8A 4A FE FF D3 3F EA 48 05 44
+4F 45 53 3E 1A 42 B2 1D BA 40 84 12 00 00 8A 4D
+02 00 3D 41 30 4D 0E 4B 05 44 45 46 45 52 B0 12
+56 4A BA 40 30 40 FC FF BA 40 24 4B FE FF B9 3F
+00 00 81 5B 82 43 B6 1D 30 4D 4C 4A 01 5D B2 43
+B6 1D 30 4D E0 45 87 52 45 43 55 52 53 45 19 42
+C4 1D 99 42 B2 1D 00 00 A2 53 C4 1D 30 4D 42 4B
+01 3A B0 12 56 4A BA 40 87 12 FC FF A2 83 C4 1D
+B2 43 B6 1D 82 4F B4 1D 30 4D 70 4B 81 3B 82 93
+B6 1D 5D 27 87 12 34 40 2A 40 2C 48 A4 4A 44 4B
+2A 40 52 45 09 49 4D 4D 45 44 49 41 54 45 1A 42
+AE 1D FA D0 80 00 00 00 30 4D BE 4F 02 00 3E 4F
+30 4D A4 4B 82 49 53 00 87 12 42 42 F4 40 C0 41
+DC 4B E8 4B 34 40 BA 4B 2C 48 2A 40 3A 4A BA 4B
+2A 40 8C 4B 83 5B 27 5D 87 12 3A 4A 34 40 34 40
+2C 48 2C 48 2A 40 1A 49 88 50 4F 53 54 50 4F 4E
+45 00 87 12 4C 42 24 46 7C 46 54 40 C0 41 48 4A
+7E 41 C0 41 22 4C 34 40 34 40 2C 48 2C 48 34 40
+2C 48 2C 48 2A 40 28 4C 3A 4E 82 4A C6 1D 2E 4E
+82 4E C4 1D 3D 40 10 00 09 4A 08 49 29 83 18 48
+FE FF 0E 98 FC 2B 89 48 00 00 1D 83 F6 23 2A 4A
+0A 93 F0 23 3E 4F 3D 41 30 4D C4 4B 82 49 46 00
+2F 83 8F 4E 00 00 1E 42 C4 1D BE 40 C0 41 00 00
+A2 52 C4 1D 2E 53 30 4D 28 4B 84 45 4C 53 45 00
+1A 42 C4 1D BA 40 BC 41 00 00 2A 52 82 4A C4 1D
+8E 4A 00 00 2A 83 0E 4A 30 4D A8 45 84 54 48 45
+4E 00 9E 42 C4 1D 00 00 3E 4F 30 4D F4 4A 85 42
+45 47 49 4E 30 40 84 43 9C 4C 85 55 4E 54 49 4C
+39 40 C0 41 1A 42 C4 1D A2 52 C4 1D 8A 49 00 00
+8A 4E 02 00 3E 4F 30 4D 22 4A 85 41 47 41 49 4E
+39 40 BC 41 EF 3F BE 4A 85 57 48 49 4C 45 87 12
+60 4C 6E 40 2A 40 56 4B 86 52 45 50 45 41 54 00
+87 12 E0 4C A2 4C 2A 40 7A 4C 82 44 4F 00 2F 83
+8F 4E 00 00 1E 42 C4 1D BE 40 CA 41 00 00 2E 53
+82 4E C4 1D A2 53 AC 1D 1A 42 AC 1D 8A 43 00 00
+30 4D 3E 48 84 4C 4F 4F 50 00 39 40 EC 41 1A 42
+C4 1D A2 52 C4 1D 8A 49 00 00 8A 4E 02 00 1E 42
+AC 1D A2 83 AC 1D 2E 4E 0E 93 04 24 9E 42 C4 1D
+00 00 F5 3F 3E 4F 30 4D E4 43 85 2B 4C 4F 4F 50
+39 40 DA 41 E4 3F 34 4D 85 4C 45 41 56 45 1A 42
+C4 1D BA 40 FC 41 00 00 BA 40 BC 41 02 00 B2 50
+06 00 C4 1D A2 53 AC 1D 2A 52 19 42 AC 1D 89 4A
+00 00 30 4D 78 4D 04 4D 4F 56 45 00 0A 4E 38 4F
+39 4F 3E 4F 0A 93 11 24 08 99 0F 24 06 2C F8 49
+00 00 18 53 1A 83 FB 23 30 4D 08 5A 09 5A 19 83
+18 83 E8 49 00 00 1A 83 FA 23 30 4D 34 40 CA 1D
+FC 40 2A 40 84 12 DC 4D 20 52 04 5D F8 5C 38 4A
+F0 51 6A 4D 12 5D 0C 46 4A 4E 96 61 7E 62 88 61
+48 41 E4 4B 4C 4B E4 46 00 00 3A 40 0C 00 39 40
+CA 1D 38 40 CC 1D D9 3F 3A 40 0E 00 39 40 CC 1D
+38 40 CA 1D CC 3F 82 43 CC 1D 30 4D 92 42 CA 1D
+C8 1D 30 4D F8 4B 09 50 57 52 5F 53 54 41 54 45
+84 12 26 4C EC 51 E4 62 36 4E 08 50 57 52 5F 48
+45 52 45 00 92 42 C4 1D 46 4E 92 42 C6 1D 44 4E
+EF 3F F8 4C 09 52 53 54 5F 53 54 41 54 45 92 42
+0C 18 46 4E 92 42 0E 18 44 4E E2 3F 64 4E 08 52
+53 54 5F 48 45 52 45 00 92 42 C4 1D 0C 18 92 42
+C6 1D 0E 18 DF 3F B2 40 EA 4E 4C 4F B2 40 1C 45
+2C 45 B2 40 58 45 6C 45 B2 40 DC 43 EA 43 B2 40
+72 44 64 44 30 41 E8 4C 04 57 49 50 45 00 39 40
+80 FF B9 43 00 00 29 53 39 90 B4 FF FA 23 B0 12
+96 4E B2 40 E4 62 C4 1D B2 40 EC 51 C6 1D D4 3F
+5C 4C 06 28 57 41 52 4D 29 00 1E 42 08 18 87 12
+CA 45 05 0D 1B 5B 37 6D AE 45 70 43 CA 45 27 20
+46 61 73 74 46 6F 72 74 68 20 56 31 36 30 20 31
+36 4D 48 7A 20 28 43 29 20 4A 2E 4D 2E 54 68 6F
+6F 72 65 6E 73 20 AE 45 34 40 30 FF 84 43 2A 41
+30 43 CA 45 0B 62 79 74 65 73 20 66 72 65 65 20
+C0 49 B8 4E 04 57 41 52 4D 00 30 40 EA 4E AE 4C
+04 43 4F 4C 44 00 B2 40 04 A5 20 01 B2 40 88 5A
+5C 01 B2 D0 03 00 04 02 B2 40 FC FF 02 02 B2 C0
+03 00 06 02 B2 43 22 02 B2 D3 26 02 B2 43 42 02
+B2 D3 46 02 B2 43 62 02 B2 D3 66 02 F2 43 26 03
+F2 D3 22 03 F2 40 A5 00 41 01 F2 40 10 00 40 01
+D2 43 41 01 F2 40 A5 00 61 01 B2 40 48 00 62 01
+82 43 66 01 39 40 80 00 B2 40 33 00 64 01 D2 43
+61 01 92 D2 9E 01 08 18 A2 93 08 18 01 24 59 07
+38 40 C2 A2 18 83 FE 23 19 83 FA 23 B2 42 B0 01
+F2 D0 10 00 2A 03 F2 C0 40 00 A2 04 3A 40 5C 4F
+39 40 B4 FF 89 4A 00 00 29 53 FC 23 92 42 02 18
+F0 FF B2 40 18 00 0A 18 31 40 E0 1C 3F 40 80 1C
+37 40 00 40 36 40 B4 40 35 40 08 40 34 40 14 40
+B2 40 0A 00 DA 1D B2 43 DC 1D 92 C3 30 01 18 42
+08 18 D2 B3 01 02 04 20 38 E3 18 53 82 48 08 18
+B2 40 81 00 C0 05 B2 42 C6 05 B2 40 A1 F7 C8 05
+F2 D0 03 00 0D 02 92 C3 C0 05 92 D3 DA 05 3D 40
+78 50 18 42 08 18 38 90 0A 00 29 27 38 90 16 00
+26 2F 28 93 FC 22 E4 26 7A 50 E2 B2 60 02 65 23
+B2 40 81 A9 40 06 B2 40 30 00 46 06 D2 D3 25 02
+B2 D0 C0 04 0C 02 B2 C0 C0 04 06 02 92 C3 40 06
+39 40 00 20 89 43 00 00 29 53 39 90 54 21 FA 23
+39 42 B0 12 BE 59 D2 C3 23 02 2C 42 B2 40 95 00
+14 20 B2 40 00 40 18 20 1A 43 B0 12 82 59 02 24
+30 40 5C 5A B0 12 BC 59 7A 93 FC 23 3C 42 B2 40
+87 AA 14 20 92 43 16 20 B2 40 00 48 18 20 1A 43
+B0 12 82 59 29 42 B0 12 BE 59 92 43 14 20 82 43
+16 20 78 43 0C 5C B2 40 00 77 18 20 1A 43 B0 12
+82 59 B2 40 40 69 18 20 B0 12 78 59 03 24 58 83
+F2 23 D6 3F 0C 5C A2 43 16 20 B2 40 00 50 18 20
+B0 12 78 59 CD 23 92 D3 40 06 82 43 46 06 92 C3
+40 06 0C 5C B0 12 E4 59 38 40 00 1E 92 48 C6 01
+04 20 92 48 C8 01 06 20 5A 48 C2 01 92 43 02 20
+7A 80 06 00 0B 24 7A 82 09 24 A2 43 02 20 6A 53
+05 24 5A 53 03 24 7A 50 0B 00 AA 23 B0 12 E4 59
+D2 48 0D 00 12 20 19 48 0E 00 82 49 08 20 1A 48
+16 00 0A 93 02 20 1A 48 24 00 82 4A 0A 20 09 5A
+82 49 0C 20 09 5A A2 93 02 20 04 24 82 49 0E 20
+39 50 20 00 19 82 12 20 19 82 12 20 82 49 10 20
+92 42 02 20 2E 20 C1 3E 84 12 DC 4D 14 58 C0 58
+C8 57 14 59 8E 57 48 58 92 54 00 00 84 57 34 58
+E6 57 24 58 A2 55 00 00 00 00 26 59 08 4E E2 4E
+85 48 49 32 4C 4F 87 12 84 43 74 4C 2C 48 44 4B
+0A 4E C8 51 2A 40 50 4F 04 43 4F 44 45 00 B0 12
+56 4A A2 82 C4 1D 87 12 84 4B BC 41 00 52 DA 4C
+03 41 53 4D 92 42 C8 1D B8 1D B2 40 CC 51 C8 1D
+EE 3F 00 00 07 45 4E 44 43 4F 44 45 87 12 18 4E
+A4 4A 2A 40 34 52 06 45 4E 44 41 53 4D 00 92 42
+B8 1D C8 1D F3 3F 00 00 05 43 4F 4C 4F 4E 1A 42
+C4 1D BA 40 87 12 00 00 A2 53 C4 1D B2 43 B6 1D
+30 40 18 4E 00 00 05 4C 4F 32 48 49 1A 42 C4 1D
+BA 40 B0 12 00 00 BA 40 2A 40 02 00 A2 52 C4 1D
+ED 3F 38 40 BE 1D 39 48 2A 48 09 5A 1A 52 C2 1D
+09 9A 03 24 7E 9A FC 27 1A 83 0E 4A 2A 88 82 4A
+C2 1D 30 4D B0 12 2A 40 24 46 7C 46 72 41 C0 41
+CA 52 38 47 C0 41 48 4A EC 52 CC 52 29 4E 39 90
+86 12 02 20 2E 53 30 41 39 90 85 12 03 20 1E 4E
+02 00 30 41 39 90 84 12 01 20 2E 52 30 41 19 42
+C4 1D A2 53 C4 1D 89 4E 00 00 3E 40 29 00 12 12
+C2 1D 92 53 C2 1D B0 12 2A 40 24 46 38 47 C0 41
+1E 53 14 53 21 53 3E 90 10 00 BB 2D 30 41 20 53
+B2 41 C2 1D 22 D3 30 41 87 12 4C 42 92 52 30 53
+82 43 BC 1D 92 42 C4 1D BA 1D A2 53 C4 1D 0A 4E
+3E 4F FA 90 23 00 00 00 34 20 92 53 C2 1D B0 12
+B4 52 0E 93 04 20 B2 40 00 03 BC 1D 27 3C 1E 93
+04 20 B2 40 10 03 BC 1D 21 3C 2E 93 04 20 B2 40
+20 03 BC 1D 1B 3C 2E 92 04 20 B2 40 20 02 BC 1D
+15 3C 3E 92 04 20 B2 40 30 02 BC 1D 0F 3C 3E 93
+04 20 B2 40 30 03 BC 1D 09 3C B2 40 30 00 BC 1D
+19 42 C4 1D A2 53 C4 1D 89 4E 00 00 3E 4F 3D 41
+30 4D FA 90 26 00 00 00 08 20 B2 40 10 02 BC 1D
+92 53 C2 1D 30 12 A0 53 75 3F FA 90 40 00 00 00
+1A 20 B2 40 20 00 BC 1D 92 53 C2 1D B0 12 FE 52
+0E 20 B2 50 10 00 BC 1D 3E 40 2B 00 B0 12 FE 52
+32 24 92 92 BE 1D C2 1D 02 24 92 53 C2 1D 8E 10
+82 5E BC 1D D3 3F B0 12 FE 52 F9 23 B2 50 10 00
+BC 1D 3E 40 28 00 B0 12 B4 52 30 12 F0 53 67 3F
+87 12 4C 42 92 52 28 54 FE 90 26 00 00 00 3E 40
+20 00 04 20 B2 50 82 00 BC 1D C2 3F B0 12 FE 52
+DF 23 B2 50 80 00 BC 1D 3E 40 28 00 B0 12 B4 52
+B0 12 EE 52 D5 23 3D 40 48 4A 30 4D 00 00 04 52
+45 54 49 00 87 12 34 40 00 13 2C 48 2A 40 34 40
+2C 00 28 53 20 54 78 54 2E 4E 1E D2 BC 1D 19 42
+BA 1D 92 3F 76 52 03 4D 4F 56 84 12 6E 54 00 40
+86 54 05 4D 4F 56 2E 42 84 12 6E 54 40 40 00 00
+03 41 44 44 84 12 6E 54 00 50 A0 54 05 41 44 44
+2E 42 84 12 6E 54 40 50 AC 54 04 41 44 44 43 00
+84 12 6E 54 00 60 BA 54 06 41 44 44 43 2E 42 00
+84 12 6E 54 40 60 5E 54 04 53 55 42 43 00 84 12
+6E 54 00 70 D8 54 06 53 55 42 43 2E 42 00 84 12
+6E 54 40 70 E6 54 03 53 55 42 84 12 6E 54 00 80
+F6 54 05 53 55 42 2E 42 84 12 6E 54 40 80 58 52
+03 43 4D 50 84 12 6E 54 00 90 10 55 05 43 4D 50
+2E 42 84 12 6E 54 40 90 46 52 04 44 41 44 44 00
+84 12 6E 54 00 A0 2A 55 06 44 41 44 44 2E 42 00
+84 12 6E 54 40 A0 1C 55 03 42 49 54 84 12 6E 54
+00 B0 48 55 05 42 49 54 2E 42 84 12 6E 54 40 B0
+54 55 03 42 49 43 84 12 6E 54 00 C0 62 55 05 42
+49 43 2E 42 84 12 6E 54 40 C0 6E 55 03 42 49 53
+84 12 6E 54 00 D0 7C 55 05 42 49 53 2E 42 84 12
+6E 54 40 D0 00 00 03 58 4F 52 84 12 6E 54 00 E0
+96 55 05 58 4F 52 2E 42 84 12 6E 54 40 E0 C8 54
+03 41 4E 44 84 12 6E 54 00 F0 B0 55 05 41 4E 44
+2E 42 84 12 6E 54 40 F0 4C 42 28 53 CE 55 1A 42
+BC 1D B2 F0 70 00 BC 1D 8A 10 3A F0 0F 00 82 DA
+BC 1D 4A 3F 02 55 03 52 52 43 84 12 C8 55 00 10
+E6 55 05 52 52 43 2E 42 84 12 C8 55 40 10 F2 55
+04 53 57 50 42 00 84 12 C8 55 80 10 00 56 03 52
+52 41 84 12 C8 55 00 11 0E 56 05 52 52 41 2E 42
+84 12 C8 55 40 11 1A 56 03 53 58 54 84 12 C8 55
+80 11 00 00 04 50 55 53 48 00 84 12 C8 55 00 12
+34 56 06 50 55 53 48 2E 42 00 84 12 C8 55 40 12
+88 55 04 43 41 4C 4C 00 84 12 C8 55 80 12 34 40
+2C 00 28 53 20 54 68 56 59 42 BC 1D 5A 42 BD 1D
+82 4A BC 1D BE 90 00 15 00 00 02 20 0A 89 02 3C
+09 8A 0A 49 3A 90 10 00 03 2C 5A 0E A8 3F 1A 53
+0E 4A 87 12 70 43 CA 45 0D 6F 75 74 20 6F 66 20
+62 6F 75 6E 64 73 AA 49 42 56 05 50 55 53 48 4D
+84 12 5E 56 00 15 AA 56 04 50 4F 50 4D 00 84 12
+5E 56 00 17 4C 42 92 52 CA 56 82 43 BC 1D 92 42
+C4 1D BA 1D A2 53 C4 1D 92 53 C2 1D 3E 40 2C 00
+B0 12 2A 40 24 46 38 47 C0 41 48 4A 20 54 F0 56
+0A 4E 3E 4F 1A 83 2A 92 CA 2F 8A 10 5A 06 6F 3F
+28 56 04 52 52 43 4D 00 84 12 C4 56 50 00 02 57
+04 52 52 41 4D 00 84 12 C4 56 50 01 10 57 04 52
+4C 41 4D 00 84 12 C4 56 50 02 1E 57 04 52 52 55
+4D 00 84 12 C4 56 50 03 85 12 00 3C 2C 57 03 53
+3E 3D 85 12 00 38 3E 57 02 53 3C 00 85 12 00 34
+B8 56 03 30 3E 3D 85 12 00 30 52 57 02 30 3C 00
+85 12 00 30 00 00 02 55 3C 00 85 12 00 2C 66 57
+03 55 3E 3D 85 12 00 28 5C 57 03 30 3C 3E 85 12
+00 24 7A 57 02 30 3D 00 85 12 00 20 00 00 02 49
+46 00 1A 42 C4 1D 8A 4E 00 00 A2 53 C4 1D 0E 4A
+30 4D 70 57 04 54 48 45 4E 00 1A 42 C4 1D 08 4E
+3E 4F 09 48 29 53 0A 89 0A 11 3A 90 00 02 68 2F
+88 DA 00 00 30 4D 38 55 04 45 4C 53 45 00 1A 42
+C4 1D BA 40 00 3C 00 00 A2 53 C4 1D 2F 83 8F 4A
+00 00 E3 3F A4 57 05 55 4E 54 49 4C 3A 4F 08 4E
+3E 4F 19 42 C4 1D 2A 83 0A 89 0A 11 3A 90 00 FE
+47 3B 3A F0 FF 03 08 DA 89 48 00 00 A2 53 C4 1D
+30 4D BC 55 05 41 47 41 49 4E 87 12 38 57 EC 57
+2A 40 00 00 05 57 48 49 4C 45 87 12 92 57 6E 40
+2A 40 48 57 06 52 45 50 45 41 54 00 87 12 38 57
+EC 57 AA 57 2A 40 00 00 03 4A 4D 50 87 12 3A 4A
+38 57 EC 57 2A 40 3E B0 00 10 03 20 3E E0 00 04
+30 4D 3E 90 00 34 06 28 03 24 3E 40 00 34 30 4D
+3E 40 00 38 30 4D 00 00 04 3F 4A 4D 50 00 87 12
+56 58 3A 4A 6E 40 EC 57 2A 40 8C 58 3D 41 08 4E
+3E 4F 2A 48 0A 93 04 20 98 42 C4 1D 00 00 30 4D
+88 43 00 00 A4 3F 52 56 03 42 57 31 84 12 8A 58
+00 00 A8 58 03 42 57 32 84 12 8A 58 00 00 B4 58
+03 42 57 33 84 12 8A 58 00 00 CC 58 3D 41 1A 42
+C4 1D 28 4E 08 93 08 20 BA 4F 00 00 A2 53 C4 1D
+8E 4A 00 00 3E 4F 30 4D 8E 43 00 00 61 3F 00 00
+03 46 57 31 84 12 CA 58 00 00 F0 58 03 46 57 32
+84 12 CA 58 00 00 FC 58 03 46 57 33 84 12 CA 58
+00 00 08 59 04 47 4F 54 4F 00 87 12 38 57 3A 4A
+22 48 2A 40 78 58 05 3F 47 4F 54 4F 87 12 56 58
+3A 4A 22 48 2A 40 D2 C3 23 02 E2 B2 60 02 02 24
+30 40 56 4F 1A 52 04 20 19 62 06 20 92 43 14 20
+A2 93 02 20 07 24 0A 5A 49 69 82 4A 16 20 C2 49
+18 20 0A 3C C2 4A 15 20 8A 10 C2 4A 16 20 C2 49
+17 20 89 10 C2 49 18 20 B0 12 BC 59 7A 93 FC 23
+0A 43 39 40 05 00 D2 49 14 20 4E 06 82 93 46 06
+05 24 92 B3 6C 06 FD 27 C2 93 4C 06 59 83 F3 2F
+19 83 0B 30 F2 43 4E 06 82 93 46 06 03 24 92 B3
+6C 06 FD 27 5A 92 4C 06 F3 23 30 41 19 43 3A 43
+8A 10 C2 4A 4E 06 82 93 46 06 05 24 92 B3 6C 06
+FD 27 C2 93 4C 06 19 83 F3 23 5A 42 4C 06 30 41
+1A 52 08 20 09 43 1C D3 F2 40 51 00 19 20 B0 12
+36 59 34 20 B0 12 BC 59 7A 90 FE FF FB 23 F2 43
+4E 06 00 40 19 53 39 90 00 02 D9 42 4C 06 FF 1D
+F6 23 29 43 B0 12 BE 59 3C C0 03 00 D2 D3 23 02
+30 41 09 43 2C D3 F0 40 58 00 EF C5 B0 12 36 59
+15 20 3A 40 FE FF 29 43 B0 12 C0 59 D2 49 00 1E
+4E 06 03 43 19 53 39 90 00 02 F8 23 39 40 03 00
+B0 12 BE 59 7A C0 E1 00 6A 92 DE 27 D2 D3 23 02
+8C 10 1C 52 4C 06 87 12 CA 45 0B 3C 20 53 44 20
+45 72 72 6F 72 21 78 5A 2F 82 8F 4E 02 00 9F 42
+DA 1D 00 00 B2 40 10 00 DA 1D 0E 4C B0 12 2A 40
+30 43 36 42 FC 40 AA 49 39 4F 18 42 C4 1D 4A 4E
+0E 48 C8 4A 00 00 18 53 30 40 BE 4D 92 4B 0E 00
+22 20 92 4B 10 00 24 20 5A 42 23 20 58 42 22 20
+A2 93 02 20 02 24 08 58 30 41 59 42 24 20 89 10
+0A 59 88 10 08 58 0A 6A 88 10 08 58 30 41 82 43
+1C 20 92 42 0E 20 1A 20 92 93 22 20 03 20 C2 93
+24 20 EA 27 92 42 10 20 E4 04 82 43 E6 04 92 42
+22 20 D8 04 92 42 24 20 DA 04 92 42 12 20 C8 04
+92 42 E4 04 1A 20 92 42 E6 04 1C 20 30 41 92 4B
+0E 00 22 20 92 4B 10 00 24 20 B0 12 DE 5A 5A 4B
+03 00 82 5A 1A 20 82 63 1C 20 30 41 09 93 C4 27
+F8 90 20 00 00 1E C0 23 18 53 19 83 F9 23 30 41
+1B 42 36 20 82 43 1E 20 B2 90 00 02 20 20 9A 20
+BB 80 00 02 12 00 8B 73 14 00 DB 53 03 00 DB 92
+12 20 03 00 11 28 CB 43 03 00 B0 12 AC 5A B0 12
+E0 59 8B 43 10 00 9B 48 00 1E 0E 00 92 93 02 20
+03 24 9B 48 02 1E 10 00 B2 40 00 02 20 20 8B 93
+14 00 0B 20 92 9B 12 00 1E 20 74 2C BB 90 00 02
+12 00 03 2C 92 4B 12 00 20 20 B0 12 1E 5B 1A 42
+1A 20 19 42 1C 20 0F 3F 3C 42 3B 40 40 20 09 43
+CB 93 02 00 10 24 9B 92 24 20 0C 00 04 20 9B 92
+22 20 0A 00 07 24 09 4B 3B 50 18 00 3B 90 00 21
+EF 23 0C 5C 30 41 0C 43 82 4B 36 20 8B 49 00 00
+4A 93 07 34 49 93 05 24 C9 93 02 00 02 34 5A 59
+02 00 CB 4A 02 00 CB 43 03 00 9B 42 1A 20 04 00
+9B 42 1C 20 06 00 18 42 32 20 8B 48 08 00 9B 48
+1A 1E 0A 00 9B 48 14 1E 0C 00 9B 48 1A 1E 0E 00
+9B 48 14 1E 10 00 9B 48 1C 1E 12 00 9B 48 1E 1E
+14 00 82 43 1E 20 6A 93 62 27 CC 37 8B 43 16 00
+7A 93 05 24 99 37 99 52 C2 1D 16 00 95 3F 92 42
+BE 1D 38 20 92 82 C2 1D 38 20 92 42 C0 1D 3A 20
+92 52 C2 1D 3A 20 B2 40 EC 43 64 44 92 42 BE 1D
+C2 1D 82 3F 1B 42 36 20 82 43 20 20 0B 93 AA 27
+EB 93 02 00 04 20 B0 12 0A 61 B0 12 D2 60 5A 4B
+02 00 CB 43 02 00 2B 4B 82 4B 36 20 5A 53 05 24
+99 37 92 4B 16 00 1E 20 67 3F 1E 42 38 20 9F 42
+3A 20 02 00 B2 40 72 44 64 44 8C 3F 7E 4E 85 52
+45 41 44 22 5A 43 19 3C 44 4F 86 57 52 49 54 45
+22 00 6A 43 12 3C 0A 4D 84 44 45 4C 22 00 6A 42
+0C 3C 08 52 05 43 4C 4F 53 45 B0 12 94 5C 30 4D
+A6 4D 85 4C 4F 41 44 22 7A 43 2F 83 8F 4E 00 00
+0E 4A 82 93 B6 1D 0D 24 87 12 34 40 34 40 2C 48
+2C 48 E4 45 34 40 98 5A 2C 48 34 40 4E 5D 2C 48
+2A 40 87 12 34 40 22 00 24 46 4C 5D 3D 41 2F 83
+78 4E 08 5E C8 43 00 00 1C 43 92 42 2E 20 22 20
+92 42 30 20 24 20 CE 93 00 00 96 24 FE 90 3A 00
+01 00 01 20 2E 53 FE 90 5C 00 00 00 09 20 1E 53
+92 42 02 20 22 20 82 43 24 20 CE 93 00 00 76 24
+82 4E 34 20 B0 12 DE 5A BF 40 20 00 00 00 A2 93
+02 20 04 24 92 92 22 20 02 20 03 24 9F 42 12 20
+00 00 B0 12 BE 5B 2C 43 0A 43 08 4A 58 0E 08 58
+82 48 32 20 C8 93 00 1E 67 24 39 42 F8 9E 00 1E
+04 20 18 53 19 83 FA 23 1E 53 FE 90 2E 00 FF FF
+1B 24 39 50 03 00 B0 12 3C 5B 07 20 FE 90 5C 00
+FF FF 2C 24 CE 93 FF FF 29 24 1E 42 34 20 1A 53
+3A 90 10 00 DA 23 92 53 1A 20 82 63 1C 20 9F 83
+00 00 CF 23 2C 42 40 3C FE 90 2E 00 FE FF ED 27
+B0 12 3C 5B EA 23 39 40 03 00 F8 9E 00 1E 04 20
+18 53 19 83 FA 23 0A 3C CE 93 FF FF DE 23 FE 90
+5C 00 FF FF DA 23 B0 12 3C 5B D7 23 18 42 32 20
+92 48 1A 1E 22 20 92 48 14 1E 24 20 F8 B0 10 00
+0B 1E 16 24 82 93 24 20 06 20 82 93 22 20 03 20
+92 42 02 20 22 20 CE 93 FF FF 87 23 92 42 22 20
+2E 20 92 42 24 20 30 20 2F 52 3E 4F 3D 41 30 4D
+1A 4F 02 00 B0 12 C8 5B 2F 53 3A 4F 3E 4F 7A 93
+15 20 0C 93 04 20 B2 40 30 4D EE 44 30 4D 87 12
+CA 45 0B 3C 20 4F 70 65 6E 45 72 72 6F 72 36 45
+84 43 82 48 AE 45 76 45 BC 41 76 5A 1A 93 B5 20
+0C 93 ED 23 30 4D DE 5C 04 52 45 41 44 00 2F 83
+8F 4E 00 00 1E 42 36 20 B0 12 50 5B 1E 82 36 20
+30 4D 2C 43 12 12 2C 20 18 42 02 20 08 58 2A 41
+82 9A 0A 20 A0 24 B0 12 E0 59 09 43 28 93 03 24
+89 93 02 1E 03 20 89 93 00 1E 07 24 09 58 39 90
+00 02 F4 23 91 53 00 00 EA 3F 0C 43 6A 41 B9 43
+00 1E 28 93 0F 24 B9 40 FF 0F 02 1E 09 11 8A 10
+09 5A 5A 41 01 00 0A 11 09 10 82 4A 28 20 82 49
+26 20 07 3C 09 11 C2 49 26 20 C2 4A 27 20 82 43
+28 20 3A 41 82 4A 2C 20 30 41 0A 12 1A 52 08 20
+B0 12 22 5A 3A 41 1A 52 0C 20 30 40 22 5A F2 B0
+40 00 A2 04 29 20 F2 B0 10 00 A2 04 FC 27 5A 42
+B0 04 4A 11 59 42 B4 04 F2 40 20 00 C0 04 D2 42
+B1 04 C8 04 1A 52 E4 04 D2 42 B5 04 C8 04 19 52
+E4 04 D2 42 B2 04 C0 04 B2 40 00 08 C8 04 1A 52
+E4 04 92 42 B6 04 C0 04 B2 80 BC 07 C0 04 B2 40
+00 02 C8 04 19 52 E4 04 30 41 22 2A 2B 2C 2F 3A
+3B 3C 3D 3E 3F 5B 5C 5D 7C 2E 29 92 06 38 39 80
+03 00 B0 12 28 60 39 40 03 00 7A 4B C8 4A 00 1E
+0A 93 12 24 0D 12 3D 40 0F 00 3C 40 DA 5F 7A 9C
+F4 27 1D 83 FC 23 3D 41 6A 9C E7 27 3A 80 21 00
+EC 3B 18 53 19 83 E9 23 09 93 06 24 F8 40 20 00
+00 1E 18 53 19 83 FA 23 30 41 2A 93 E4 20 2C 93
+0D 24 0C 93 BA 24 87 12 CA 45 0C 3C 20 57 72 69
+74 65 45 72 72 6F 72 00 BC 41 BE 5E B0 12 F2 5E
+92 42 26 20 22 20 92 42 28 20 24 20 B0 12 6A 5F
+B0 12 BE 5B 18 42 32 20 F8 40 20 00 0B 1E B0 12
+7E 5F 88 43 0C 1E 88 4A 0E 1E 88 49 10 1E 88 49
+12 1E 98 42 24 20 14 1E 98 42 22 20 1A 1E 88 43
+1C 1E 88 43 1E 1E 1C 43 1B 42 34 20 CB 93 00 00
+CA 27 FB 90 2E 00 00 00 C6 27 39 40 0B 00 B0 12
+FA 5F B0 12 14 61 2A 43 B0 12 C8 5B 0C 93 BB 23
+30 4D 1A 4B 04 00 19 4B 06 00 B0 12 E6 59 B0 12
+7E 5F 18 4B 08 00 88 49 12 1E 88 4A 16 1E 88 49
+18 1E 98 4B 12 00 1C 1E 98 4B 14 00 1E 1E 1A 4B
+04 00 19 4B 06 00 30 40 24 5A 9B 52 1E 20 12 00
+8B 63 14 00 1A 42 1A 20 19 42 1C 20 30 40 24 5A
+B2 40 00 02 1E 20 1B 42 36 20 B0 12 0A 61 82 43
+1E 20 DB 53 03 00 DB 92 12 20 03 00 22 20 CB 43
+03 00 B0 12 AC 5A 08 12 0A 12 B0 12 F2 5E 2A 91
+05 24 B0 12 6A 5F 2A 41 B0 12 E0 59 3A 41 38 41
+98 42 26 20 00 1E 92 93 02 20 03 24 98 42 28 20
+02 1E B0 12 6A 5F 9B 42 26 20 0E 00 9B 42 28 20
+10 00 30 40 1E 5B EA 5C 05 57 52 49 54 45 B0 12
+20 61 30 4D D8 5E 07 53 44 5F 45 4D 49 54 B2 90
+00 02 1E 20 02 28 B0 12 20 61 18 42 1E 20 C8 4E
+00 1E 92 53 1E 20 3E 4F 30 4D 58 4B 13 00 5C 4B
+14 00 8C 10 0C 58 5A 4B 15 00 0A 11 0C 10 18 4B
+12 00 BB C0 FF 01 12 00 38 F0 FF 01 82 48 1E 20
+5B 42 12 20 B0 12 5E 42 1B 42 36 20 CB 4A 03 00
+19 5B 0A 00 18 6B 0C 00 8B 49 0E 00 8B 48 10 00
+B0 12 BA 5B 30 4D 0C 93 38 20 38 90 E0 01 03 2C
+C8 93 20 1E 02 24 7C 40 E5 00 C8 4C 00 1E B0 12
+14 61 B0 12 B8 5A 82 4A 2C 20 0B 4A B0 12 E0 59
+1A 48 00 1E 88 43 00 1E 92 93 02 20 09 24 19 48
+02 1E 88 43 02 1E 39 F0 FF 0F 39 90 FF 0F 02 20
+3A 93 0E 24 82 4A 22 20 82 49 24 20 B0 12 B8 5A
+0B 9A E6 27 0A 12 0A 4B B0 12 6A 5F 3A 41 DD 3F
+0A 4B B0 12 6A 5F B0 12 94 5C 30 4D BA 4C 08 54
+45 52 4D 32 53 44 22 00 87 12 FE 5C 84 43 90 62
+21 53 2F 83 AF 43 00 00 3D 40 A0 62 30 40 4E 5D
+A2 62 92 C3 DC 05 08 43 B0 12 A6 44 92 B3 DC 05
+FD 27 59 42 CC 05 69 92 0D 24 C8 49 00 1E 18 53
+38 90 FF 01 04 24 F2 2B B0 12 20 61 EC 3F B0 12
+B4 44 EC 3F B0 12 B4 44 82 48 1E 20 B0 12 94 5C
+3D 41 30 4D
+@FFB4
+5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F
+5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F
+5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F
+5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F C8 44 5C 4F
+5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F
+q
--- /dev/null
+@1800
+10 00 4C 44 80 3E 30 75 FD FF 18 00 58 57 0E 50
+2A 44 38 44 00 00 00 00
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@4000
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 40
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 40 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 40 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E 40 02 3E 52 00 0E 12 3E 4F 30 4D 8E 40
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 40
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C 40 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 40 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 41
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 40 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA 40 03 41 4E 44 3E FF 30 4D 7A 40 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E 41 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 41 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E 41 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 41 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 40 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE 41 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 41 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 41 03 3E 49 4E 85 12 C2 1D 10 41
+04 42 41 53 45 00 85 12 DA 1D C0 40 05 53 54 41
+54 45 85 12 B6 1D 30 42 02 42 4C 00 85 12 20 00
+94 41 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 42 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E 42 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 42 02 23 53 00 87 12 98 42
+D2 42 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 42 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 42 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C 42 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 41 03 55 44 2E 87 12 56 42
+CC 42 E6 42 32 45 FA 44 2A 40 18 43 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA 40
+02 44 2E 00 87 12 56 42 6E 40 80 40 3A 43 CC 42
+92 40 0A 43 E6 42 32 45 FA 44 2A 40 52 41 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 42 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 41 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 42 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A 44
+92 B3 DC 05 FD 27 1E 42 CC 05 B0 12 38 44 30 4D
+30 40 B6 43 7E 43 05 28 4B 45 59 29 18 42 CC 05
+EA 3F 12 42 03 4B 45 59 30 40 DC 43 92 43 06 41
+43 43 45 50 54 00 3C 40 8A 44 3B 40 54 44 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+7E 44 92 B3 DC 05 05 24 18 42 CC 05 38 90 0A 00
+04 20 21 53 39 40 46 44 4D 15 B2 40 11 00 CE 05
+A2 B3 DC 05 FD 27 30 41 B2 40 13 00 CE 05 A2 B3
+DC 05 FD 27 30 41 12 D2 0A 18 FD 3F 21 52 3A 17
+58 42 CC 05 48 9B F0 27 48 9C 06 2C 78 92 11 20
+2E 9F 0F 24 1E 83 05 3C 0E 9A 03 24 CE 48 00 00
+1E 53 82 48 CE 05 A2 B3 DC 05 FD 27 30 4D 80 44
+2D 83 92 B3 DC 05 FD 27 E3 23 B2 40 18 00 0A 18
+3E 8F 3D 41 30 4D D6 43 06 28 45 4D 49 54 29 00
+08 4E 3E 4F E6 3F 50 43 04 45 4D 49 54 00 30 40
+A0 44 A8 44 04 45 43 48 4F 00 B2 40 82 48 72 44
+30 4D 6E 43 06 4E 4F 45 43 48 4F 00 B2 40 30 4D
+72 44 30 4D 98 44 04 28 43 52 29 00 2F 83 8F 4E
+00 00 3E 40 0D 00 E3 3F A2 43 02 43 52 00 30 40
+DC 44 04 43 05 53 50 41 43 45 2F 83 8F 4E 00 00
+3E 40 20 00 D4 3F F4 44 06 53 50 41 43 45 53 00
+0E 93 09 24 0D 12 3D 40 1C 45 EF 3F 1E 45 2D 83
+1E 83 EB 23 3D 41 3E 4F 30 4D 2C 43 04 54 59 50
+45 00 0E 93 95 24 2A 4F 8F 5E 00 00 0E 4A 87 12
+CA 41 02 42 0A 41 AE 44 EC 41 42 45 2A 40 2F 82
+8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E 1D B3 0D 63
+30 4D 08 45 82 53 22 00 87 12 34 40 4E 45 B0 47
+34 40 22 00 A8 45 78 45 3D 41 6E 4E 1E 83 82 5E
+C4 1D 3E 4F 92 B3 C4 1D A2 63 C4 1D 30 4D C4 44
+82 2E 22 00 87 12 68 45 34 40 32 45 B0 47 2A 40
+00 00 04 57 4F 52 44 00 3C 40 BE 1D 39 4C 3A 4C
+09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A FC 27 1A 83
+3B 40 60 00 C8 4C 00 00 09 9A 0C 24 7C 4A 4E 9C
+09 24 18 53 4B 9C F6 2F 7C 90 7B 00 F3 2F 7C 80
+20 00 F0 3F 1A 82 C0 1D 82 4A C2 1D 1E 42 C4 1D
+08 8E CE 48 00 00 30 4D 00 00 04 46 49 4E 44 00
+2F 83 0C 4E 65 4C 74 40 80 00 3B 40 CA 1D 3E 4B
+0E 93 1E 24 58 4C 01 00 78 F0 1E 00 0E 58 2E 53
+1E 4E FE FF 0E 93 F3 27 09 4E 78 49 48 C4 48 95
+F7 23 0A 4C 1A 53 FA 99 00 00 F2 23 58 83 FA 23
+19 B3 09 63 0C 49 6A 4E 1E 43 4A 93 01 30 2E 83
+8F 4C 00 00 35 40 08 40 34 40 14 40 30 4D 2F 53
+2F 53 3E 4F 30 4D 26 42 07 3E 4E 55 4D 42 45 52
+3C 4F 38 4F 29 4F 2F 82 1B 42 DA 1D 6A 4C 7A 80
+30 00 7A 90 0A 00 02 28 7A 80 07 00 0A 9B 13 2C
+82 49 D0 04 82 48 D2 04 82 4B C8 04 19 42 E4 04
+18 42 E6 04 09 5A 08 63 1C 53 1E 83 E7 23 8F 49
+04 00 8F 48 02 00 8F 4C 00 00 30 4D 03 12 0D 12
+1B 42 DA 1D 0B 12 32 C0 00 02 6D 4E 0D 5E 0C 4E
+7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23 32 D0 00 02
+FC 4C FE FF 0D 9C FC 2F DE 83 00 00 09 43 08 43
+3D 40 32 47 3F 82 8F 4E 06 00 0C 4E 7E 4C 6A 4C
+7A 90 2D 00 10 2C 3B 40 10 00 7A 80 24 00 06 24
+2B 43 5A 83 03 24 3B 52 6A 53 B0 23 1C 53 1E 83
+6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83 B1 43 04 00
+A5 3F 34 47 2F 53 0E 93 2C 17 82 4C DA 1D 03 24
+2F 52 0E F3 30 4D 8F 93 00 00 15 20 32 B0 00 02
+14 20 0E 93 05 24 1A 4F 02 00 1A 83 0A 93 0B 38
+2F 53 BF 4F 00 00 3E E3 05 20 BF E3 00 00 9F 53
+00 00 3E E3 30 4D 32 D0 00 02 9F 4F 02 00 04 00
+BF 4F 00 00 3E E3 F6 23 BF E3 02 00 BF E3 00 00
+9F 53 02 00 8F 63 00 00 3E E3 30 4D B4 44 07 45
+58 45 43 55 54 45 0A 4E 3E 4F 00 4A 28 41 01 2C
+1A 42 C4 1D A2 53 C4 1D 8A 4E 00 00 3E 4F 30 4D
+AE 47 87 4C 49 54 45 52 41 4C 82 93 B6 1D 16 24
+32 B0 00 02 09 24 1A 42 C4 1D A2 52 C4 1D BA 40
+34 40 00 00 BA 4F 02 00 1A 42 C4 1D A2 52 C4 1D
+BA 40 34 40 00 00 8A 4E 02 00 3E 4F 30 4D EA 44
+05 43 4F 55 4E 54 2F 83 1E 53 8F 4E 00 00 5E 4E
+FF FF 30 4D 82 4E BE 1D B2 4F C0 1D 3E 4F 82 43
+C2 1D 87 12 4C 42 A8 45 2A 48 3D 40 36 48 E8 22
+3D 41 3E 4F 30 4D 38 48 0A 4E 3E 4F 3D 40 4E 48
+3D 27 3D 40 24 48 1A E2 B6 1D B2 27 AC 23 50 48
+3E 4F 3D 40 24 48 B9 23 DE 53 00 00 68 4E 08 5E
+F8 40 3F 00 00 00 3D 40 16 4A CD 3F 9E 47 08 45
+56 41 4C 55 41 54 45 00 39 40 BE 1D 39 12 39 12
+39 12 0D 12 B0 12 2A 40 14 48 8C 48 3D 41 B2 41
+C2 1D B2 41 C0 1D B2 41 BE 1D 30 4D 7A 41 04 51
+55 49 54 00 31 40 E0 1C B2 40 00 1C AC 1D 82 43
+B6 1D 82 43 08 18 B0 12 2A 40 4E 45 04 0D 6F 6B
+20 00 32 45 34 40 38 1D 44 40 34 40 50 00 F6 43
+FA 44 14 48 34 40 7E 1C CE 40 B2 41 4E 45 0D 73
+74 61 63 6B 20 65 6D 70 74 79 20 21 28 49 34 40
+30 FF 84 43 B2 41 4E 45 0B 46 52 41 4D 20 66 75
+6C 6C 20 21 28 49 42 42 F4 40 C0 41 BA 48 4E 45
+04 0D 20 20 20 00 BC 41 C2 48 EE 43 05 41 42 4F
+52 54 3F 40 80 1C BE 3F 8F 93 02 00 98 26 B2 40
+82 48 72 44 B0 12 10 4E 82 43 D2 56 82 43 DE 56
+82 43 EA 56 82 43 1A 57 82 43 26 57 82 43 32 57
+A2 B3 DC 05 FD 27 B2 40 11 00 CE 05 92 C3 DC 05
+38 40 A0 AA 39 42 19 83 FE 23 18 83 FB 23 92 B3
+DC 05 F4 23 87 12 4E 45 04 1B 5B 37 6D 00 32 45
+32 45 4E 45 04 1B 5B 30 6D 00 32 45 58 4D 9A 4D
+A0 4D 22 49 1C 49 86 41 42 4F 52 54 22 00 87 12
+68 45 34 40 28 49 B0 47 2A 40 FA 45 01 27 87 12
+4C 42 A8 45 00 46 C0 41 BC 49 2A 40 58 48 52 42
+81 5C 92 42 BE 1D C2 1D 30 4D 87 12 84 45 4C 42
+A8 45 D4 49 08 4E 7A 4E 5A D3 5A 53 0A 58 19 42
+C8 1D 6E 4E 3E F0 1E 00 09 5E 82 48 AE 1D 82 49
+B0 1D 82 4A B2 1D 2A 52 82 4A C4 1D 3E 4F 3D 41
+30 41 87 12 4E 45 0F 73 74 61 63 6B 20 6D 69 73
+6D 61 74 63 68 21 2E 49 82 9F B4 1D F2 23 18 42
+AE 1D 19 42 B0 1D A8 49 FE FF 89 48 00 00 30 4D
+A2 45 08 56 41 52 49 41 42 4C 45 00 B0 12 CA 49
+BA 40 86 12 FC FF EF 3F 00 48 08 43 4F 4E 53 54
+41 4E 54 00 B0 12 CA 49 BA 40 85 12 FC FF 8A 4E
+FE FF 3E 4F E0 3F 4A 4A 06 43 52 45 41 54 45 00
+B0 12 CA 49 BA 40 85 12 FC FF 8A 4A FE FF D3 3F
+6E 48 05 44 4F 45 53 3E 1A 42 B2 1D BA 40 84 12
+00 00 8A 4D 02 00 3D 41 30 4D 82 4A 05 44 45 46
+45 52 B0 12 CA 49 BA 40 30 40 FC FF BA 40 98 4A
+FE FF B9 3F 00 00 81 5B 82 43 B6 1D 30 4D C0 49
+01 5D B2 43 B6 1D 30 4D 64 45 87 52 45 43 55 52
+53 45 19 42 C4 1D 99 42 B2 1D 00 00 A2 53 C4 1D
+30 4D B6 4A 01 3A B0 12 CA 49 BA 40 87 12 FC FF
+A2 83 C4 1D B2 43 B6 1D 82 4F B4 1D 30 4D E4 4A
+81 3B 82 93 B6 1D 5D 27 87 12 34 40 2A 40 B0 47
+18 4A B8 4A 2A 40 D6 44 09 49 4D 4D 45 44 49 41
+54 45 1A 42 AE 1D FA D0 80 00 00 00 30 4D BE 4F
+02 00 3E 4F 30 4D 18 4B 82 49 53 00 87 12 42 42
+F4 40 C0 41 50 4B 5C 4B 34 40 2E 4B B0 47 2A 40
+AE 49 2E 4B 2A 40 00 4B 83 5B 27 5D 87 12 AE 49
+34 40 34 40 B0 47 B0 47 2A 40 9E 48 88 50 4F 53
+54 50 4F 4E 45 00 87 12 4C 42 A8 45 00 46 54 40
+C0 41 BC 49 7E 41 C0 41 96 4B 34 40 34 40 B0 47
+B0 47 34 40 B0 47 B0 47 2A 40 9C 4B 3A 4E 82 4A
+C6 1D 2E 4E 82 4E C4 1D 3D 40 10 00 09 4A 08 49
+29 83 18 48 FE FF 0E 98 FC 2B 89 48 00 00 1D 83
+F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41 30 4D 38 4B
+82 49 46 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40
+C0 41 00 00 A2 52 C4 1D 2E 53 30 4D 9C 4A 84 45
+4C 53 45 00 1A 42 C4 1D BA 40 BC 41 00 00 2A 52
+82 4A C4 1D 8E 4A 00 00 2A 83 0E 4A 30 4D 2C 45
+84 54 48 45 4E 00 9E 42 C4 1D 00 00 3E 4F 30 4D
+68 4A 85 42 45 47 49 4E 30 40 84 43 10 4C 85 55
+4E 54 49 4C 39 40 C0 41 1A 42 C4 1D A2 52 C4 1D
+8A 49 00 00 8A 4E 02 00 3E 4F 30 4D 96 49 85 41
+47 41 49 4E 39 40 BC 41 EF 3F 32 4A 85 57 48 49
+4C 45 87 12 D4 4B 6E 40 2A 40 CA 4A 86 52 45 50
+45 41 54 00 87 12 54 4C 16 4C 2A 40 EE 4B 82 44
+4F 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40 CA 41
+00 00 2E 53 82 4E C4 1D A2 53 AC 1D 1A 42 AC 1D
+8A 43 00 00 30 4D C2 47 84 4C 4F 4F 50 00 39 40
+EC 41 1A 42 C4 1D A2 52 C4 1D 8A 49 00 00 8A 4E
+02 00 1E 42 AC 1D A2 83 AC 1D 2E 4E 0E 93 04 24
+9E 42 C4 1D 00 00 F5 3F 3E 4F 30 4D E4 43 85 2B
+4C 4F 4F 50 39 40 DA 41 E4 3F A8 4C 85 4C 45 41
+56 45 1A 42 C4 1D BA 40 FC 41 00 00 BA 40 BC 41
+02 00 B2 50 06 00 C4 1D A2 53 AC 1D 2A 52 19 42
+AC 1D 89 4A 00 00 30 4D EC 4C 04 4D 4F 56 45 00
+0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24 08 99 0F 24
+06 2C F8 49 00 00 18 53 1A 83 FB 23 30 4D 08 5A
+09 5A 19 83 18 83 E8 49 00 00 1A 83 FA 23 30 4D
+34 40 CA 1D FC 40 2A 40 84 12 50 4D 42 50 2A 50
+7E 4C AC 49 12 50 DE 4C 1A 4D 90 45 BE 4D F2 4D
+2E 4C B2 4E 48 41 58 4B C0 4A 68 46 00 00 3A 40
+0C 00 39 40 CA 1D 38 40 CC 1D D9 3F 3A 40 0E 00
+39 40 CC 1D 38 40 CA 1D CC 3F 82 43 CC 1D 30 4D
+92 42 CA 1D C8 1D 30 4D 6C 4B 09 50 57 52 5F 53
+54 41 54 45 84 12 9A 4B 0E 50 58 57 AA 4D 08 50
+57 52 5F 48 45 52 45 00 92 42 C4 1D BA 4D 92 42
+C6 1D B8 4D EF 3F 6C 4C 09 52 53 54 5F 53 54 41
+54 45 92 42 0C 18 BA 4D 92 42 0E 18 B8 4D E2 3F
+D8 4D 08 52 53 54 5F 48 45 52 45 00 92 42 C4 1D
+0C 18 92 42 C6 1D 0E 18 DF 3F B2 40 58 4E BA 4E
+B2 40 A0 44 B0 44 B2 40 DC 44 F0 44 B2 40 DC 43
+EA 43 30 41 5C 4C 04 57 49 50 45 00 39 40 80 FF
+B9 43 00 00 29 53 39 90 B4 FF FA 23 B0 12 0A 4E
+B2 40 58 57 C4 1D B2 40 0E 50 C6 1D D7 3F D0 4B
+06 28 57 41 52 4D 29 00 1E 42 08 18 87 12 4E 45
+05 0D 1B 5B 37 6D 32 45 70 43 4E 45 27 20 46 61
+73 74 46 6F 72 74 68 20 56 31 36 30 20 31 36 4D
+48 7A 20 28 43 29 20 4A 2E 4D 2E 54 68 6F 6F 72
+65 6E 73 20 32 45 34 40 30 FF 84 43 2A 41 30 43
+4E 45 0B 62 79 74 65 73 20 66 72 65 65 20 34 49
+26 4E 04 57 41 52 4D 00 30 40 58 4E 22 4C 04 43
+4F 4C 44 00 B2 40 04 A5 20 01 B2 40 88 5A 5C 01
+B2 D0 03 00 04 02 B2 40 FC FF 02 02 B2 C0 03 00
+06 02 B2 43 22 02 B2 D3 26 02 B2 43 42 02 B2 D3
+46 02 B2 43 62 02 B2 D3 66 02 F2 43 26 03 F2 D3
+22 03 F2 40 A5 00 41 01 F2 40 10 00 40 01 D2 43
+41 01 F2 40 A5 00 61 01 B2 40 48 00 62 01 82 43
+66 01 39 40 80 00 B2 40 33 00 64 01 D2 43 61 01
+92 D2 9E 01 08 18 A2 93 08 18 01 24 59 07 38 40
+C2 A2 18 83 FE 23 19 83 FA 23 B2 42 B0 01 F2 D0
+10 00 2A 03 F2 C0 40 00 A2 04 3A 40 CA 4E 39 40
+B4 FF 89 4A 00 00 29 53 FC 23 92 42 02 18 F0 FF
+B2 40 18 00 0A 18 31 40 E0 1C 3F 40 80 1C 37 40
+00 40 36 40 B4 40 35 40 08 40 34 40 14 40 B2 40
+0A 00 DA 1D B2 43 DC 1D 92 C3 30 01 18 42 08 18
+D2 B3 01 02 04 20 38 E3 18 53 82 48 08 18 B2 40
+81 00 C0 05 B2 40 05 00 C6 05 B2 40 00 49 C8 05
+F2 D0 03 00 0D 02 92 C3 C0 05 92 D3 DA 05 3D 40
+E8 4F 18 42 08 18 38 90 0A 00 28 27 38 90 16 00
+25 2F 28 93 FE 22 E6 26 B8 4E 84 12 50 4D 36 56
+E2 56 EA 55 36 57 B0 55 6A 56 B4 52 00 00 A6 55
+56 56 08 56 46 56 C4 53 00 00 00 00 48 57 7C 4D
+50 4E 85 48 49 32 4C 4F 87 12 84 43 E8 4B B0 47
+B8 4A 7E 4D EA 4F 2A 40 BE 4E 04 43 4F 44 45 00
+B0 12 CA 49 A2 82 C4 1D 87 12 F8 4A BC 41 22 50
+4E 4C 03 41 53 4D 92 42 C8 1D B8 1D B2 40 EE 4F
+C8 1D EE 3F 00 00 07 45 4E 44 43 4F 44 45 87 12
+8C 4D 18 4A 2A 40 56 50 06 45 4E 44 41 53 4D 00
+92 42 B8 1D C8 1D F3 3F 00 00 05 43 4F 4C 4F 4E
+1A 42 C4 1D BA 40 87 12 00 00 A2 53 C4 1D B2 43
+B6 1D 30 40 8C 4D 00 00 05 4C 4F 32 48 49 1A 42
+C4 1D BA 40 B0 12 00 00 BA 40 2A 40 02 00 A2 52
+C4 1D ED 3F 38 40 BE 1D 39 48 2A 48 09 5A 1A 52
+C2 1D 09 9A 03 24 7E 9A FC 27 1A 83 0E 4A 2A 88
+82 4A C2 1D 30 4D B0 12 2A 40 A8 45 00 46 72 41
+C0 41 EC 50 BC 46 C0 41 BC 49 0E 51 EE 50 29 4E
+39 90 86 12 02 20 2E 53 30 41 39 90 85 12 03 20
+1E 4E 02 00 30 41 39 90 84 12 01 20 2E 52 30 41
+19 42 C4 1D A2 53 C4 1D 89 4E 00 00 3E 40 29 00
+12 12 C2 1D 92 53 C2 1D B0 12 2A 40 A8 45 BC 46
+C0 41 40 51 36 51 21 53 3E 90 10 00 BB 2D 30 41
+42 51 B2 41 C2 1D 22 D3 30 41 87 12 4C 42 B4 50
+52 51 82 43 BC 1D 92 42 C4 1D BA 1D A2 53 C4 1D
+0A 4E 3E 4F FA 90 23 00 00 00 34 20 92 53 C2 1D
+B0 12 D6 50 0E 93 04 20 B2 40 00 03 BC 1D 27 3C
+1E 93 04 20 B2 40 10 03 BC 1D 21 3C 2E 93 04 20
+B2 40 20 03 BC 1D 1B 3C 2E 92 04 20 B2 40 20 02
+BC 1D 15 3C 3E 92 04 20 B2 40 30 02 BC 1D 0F 3C
+3E 93 04 20 B2 40 30 03 BC 1D 09 3C B2 40 30 00
+BC 1D 19 42 C4 1D A2 53 C4 1D 89 4E 00 00 3E 4F
+3D 41 30 4D FA 90 26 00 00 00 08 20 B2 40 10 02
+BC 1D 92 53 C2 1D 30 12 C2 51 75 3F FA 90 40 00
+00 00 1A 20 B2 40 20 00 BC 1D 92 53 C2 1D B0 12
+20 51 0E 20 B2 50 10 00 BC 1D 3E 40 2B 00 B0 12
+20 51 32 24 92 92 BE 1D C2 1D 02 24 92 53 C2 1D
+8E 10 82 5E BC 1D D3 3F B0 12 20 51 F9 23 B2 50
+10 00 BC 1D 3E 40 28 00 B0 12 D6 50 30 12 12 52
+67 3F 87 12 4C 42 B4 50 4A 52 FE 90 26 00 00 00
+3E 40 20 00 04 20 B2 50 82 00 BC 1D C2 3F B0 12
+20 51 DF 23 B2 50 80 00 BC 1D 3E 40 28 00 B0 12
+D6 50 B0 12 10 51 D5 23 3D 40 BC 49 30 4D 00 00
+04 52 45 54 49 00 87 12 34 40 00 13 B0 47 2A 40
+34 40 2C 00 4A 51 42 52 9A 52 2E 4E 1E D2 BC 1D
+19 42 BA 1D 92 3F 98 50 03 4D 4F 56 84 12 90 52
+00 40 A8 52 05 4D 4F 56 2E 42 84 12 90 52 40 40
+00 00 03 41 44 44 84 12 90 52 00 50 C2 52 05 41
+44 44 2E 42 84 12 90 52 40 50 CE 52 04 41 44 44
+43 00 84 12 90 52 00 60 DC 52 06 41 44 44 43 2E
+42 00 84 12 90 52 40 60 80 52 04 53 55 42 43 00
+84 12 90 52 00 70 FA 52 06 53 55 42 43 2E 42 00
+84 12 90 52 40 70 08 53 03 53 55 42 84 12 90 52
+00 80 18 53 05 53 55 42 2E 42 84 12 90 52 40 80
+7A 50 03 43 4D 50 84 12 90 52 00 90 32 53 05 43
+4D 50 2E 42 84 12 90 52 40 90 68 50 04 44 41 44
+44 00 84 12 90 52 00 A0 4C 53 06 44 41 44 44 2E
+42 00 84 12 90 52 40 A0 3E 53 03 42 49 54 84 12
+90 52 00 B0 6A 53 05 42 49 54 2E 42 84 12 90 52
+40 B0 76 53 03 42 49 43 84 12 90 52 00 C0 84 53
+05 42 49 43 2E 42 84 12 90 52 40 C0 90 53 03 42
+49 53 84 12 90 52 00 D0 9E 53 05 42 49 53 2E 42
+84 12 90 52 40 D0 00 00 03 58 4F 52 84 12 90 52
+00 E0 B8 53 05 58 4F 52 2E 42 84 12 90 52 40 E0
+EA 52 03 41 4E 44 84 12 90 52 00 F0 D2 53 05 41
+4E 44 2E 42 84 12 90 52 40 F0 4C 42 4A 51 F0 53
+1A 42 BC 1D B2 F0 70 00 BC 1D 8A 10 3A F0 0F 00
+82 DA BC 1D 4A 3F 24 53 03 52 52 43 84 12 EA 53
+00 10 08 54 05 52 52 43 2E 42 84 12 EA 53 40 10
+14 54 04 53 57 50 42 00 84 12 EA 53 80 10 22 54
+03 52 52 41 84 12 EA 53 00 11 30 54 05 52 52 41
+2E 42 84 12 EA 53 40 11 3C 54 03 53 58 54 84 12
+EA 53 80 11 00 00 04 50 55 53 48 00 84 12 EA 53
+00 12 56 54 06 50 55 53 48 2E 42 00 84 12 EA 53
+40 12 AA 53 04 43 41 4C 4C 00 84 12 EA 53 80 12
+34 40 2C 00 4A 51 42 52 8A 54 59 42 BC 1D 5A 42
+BD 1D 82 4A BC 1D BE 90 00 15 00 00 02 20 0A 89
+02 3C 09 8A 0A 49 3A 90 10 00 03 2C 5A 0E A8 3F
+1A 53 0E 4A 87 12 70 43 4E 45 0D 6F 75 74 20 6F
+66 20 62 6F 75 6E 64 73 2E 49 64 54 05 50 55 53
+48 4D 84 12 80 54 00 15 CC 54 04 50 4F 50 4D 00
+84 12 80 54 00 17 4C 42 B4 50 EC 54 82 43 BC 1D
+92 42 C4 1D BA 1D A2 53 C4 1D 92 53 C2 1D 3E 40
+2C 00 B0 12 2A 40 A8 45 BC 46 C0 41 BC 49 42 52
+12 55 0A 4E 3E 4F 1A 83 2A 92 CA 2F 8A 10 5A 06
+6F 3F 4A 54 04 52 52 43 4D 00 84 12 E6 54 50 00
+24 55 04 52 52 41 4D 00 84 12 E6 54 50 01 32 55
+04 52 4C 41 4D 00 84 12 E6 54 50 02 40 55 04 52
+52 55 4D 00 84 12 E6 54 50 03 85 12 00 3C 4E 55
+03 53 3E 3D 85 12 00 38 60 55 02 53 3C 00 85 12
+00 34 DA 54 03 30 3E 3D 85 12 00 30 74 55 02 30
+3C 00 85 12 00 30 00 00 02 55 3C 00 85 12 00 2C
+88 55 03 55 3E 3D 85 12 00 28 7E 55 03 30 3C 3E
+85 12 00 24 9C 55 02 30 3D 00 85 12 00 20 00 00
+02 49 46 00 1A 42 C4 1D 8A 4E 00 00 A2 53 C4 1D
+0E 4A 30 4D 92 55 04 54 48 45 4E 00 1A 42 C4 1D
+08 4E 3E 4F 09 48 29 53 0A 89 0A 11 3A 90 00 02
+68 2F 88 DA 00 00 30 4D 5A 53 04 45 4C 53 45 00
+1A 42 C4 1D BA 40 00 3C 00 00 A2 53 C4 1D 2F 83
+8F 4A 00 00 E3 3F C6 55 05 55 4E 54 49 4C 3A 4F
+08 4E 3E 4F 19 42 C4 1D 2A 83 0A 89 0A 11 3A 90
+00 FE 47 3B 3A F0 FF 03 08 DA 89 48 00 00 A2 53
+C4 1D 30 4D DE 53 05 41 47 41 49 4E 87 12 5A 55
+0E 56 2A 40 00 00 05 57 48 49 4C 45 87 12 B4 55
+6E 40 2A 40 6A 55 06 52 45 50 45 41 54 00 87 12
+5A 55 0E 56 CC 55 2A 40 00 00 03 4A 4D 50 87 12
+AE 49 5A 55 0E 56 2A 40 3E B0 00 10 03 20 3E E0
+00 04 30 4D 3E 90 00 34 06 28 03 24 3E 40 00 34
+30 4D 3E 40 00 38 30 4D 00 00 04 3F 4A 4D 50 00
+87 12 78 56 AE 49 6E 40 0E 56 2A 40 AE 56 3D 41
+08 4E 3E 4F 2A 48 0A 93 04 20 98 42 C4 1D 00 00
+30 4D 88 43 00 00 A4 3F 74 54 03 42 57 31 84 12
+AC 56 00 00 CA 56 03 42 57 32 84 12 AC 56 00 00
+D6 56 03 42 57 33 84 12 AC 56 00 00 EE 56 3D 41
+1A 42 C4 1D 28 4E 08 93 08 20 BA 4F 00 00 A2 53
+C4 1D 8E 4A 00 00 3E 4F 30 4D 8E 43 00 00 61 3F
+00 00 03 46 57 31 84 12 EC 56 00 00 12 57 03 46
+57 32 84 12 EC 56 00 00 1E 57 03 46 57 33 84 12
+EC 56 00 00 2A 57 04 47 4F 54 4F 00 87 12 5A 55
+AE 49 A6 47 2A 40 9A 56 05 3F 47 4F 54 4F 87 12
+78 56 AE 49 A6 47 2A 40
+@FFB4
+CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E
+CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E
+CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E
+CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E 4C 44 CA 4E
+CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E
+q
--- /dev/null
+@1800
+10 00 C8 44 80 3E 30 75 FD FF 18 00 E6 62 EE 51
+A6 44 B4 44 E8 59 26 5A
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@2000
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+@4000
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 40
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 40 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 40 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E 40 02 3E 52 00 0E 12 3E 4F 30 4D 8E 40
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 40
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C 40 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 40 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 41
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 40 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA 40 03 41 4E 44 3E FF 30 4D 7A 40 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E 41 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 41 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E 41 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 41 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 40 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE 41 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 41 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 41 03 3E 49 4E 85 12 C2 1D 10 41
+04 42 41 53 45 00 85 12 DA 1D C0 40 05 53 54 41
+54 45 85 12 B6 1D 30 42 02 42 4C 00 85 12 20 00
+94 41 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 42 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E 42 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 42 02 23 53 00 87 12 98 42
+D2 42 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 42 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 42 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C 42 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 41 03 55 44 2E 87 12 56 42
+CC 42 E6 42 AE 45 76 45 2A 40 18 43 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA 40
+02 44 2E 00 87 12 56 42 6E 40 80 40 3A 43 CC 42
+92 40 0A 43 E6 42 AE 45 76 45 2A 40 52 41 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 42 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 41 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 42 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 A6 44
+92 B3 DC 05 FD 27 1E 42 CC 05 B0 12 B4 44 30 4D
+30 40 B6 43 7E 43 05 28 4B 45 59 29 18 42 CC 05
+EA 3F 12 42 03 4B 45 59 30 40 DC 43 0D 12 3D 40
+12 44 1B 42 36 20 9B 42 1E 20 16 00 3A 40 00 21
+8F 4A 02 00 BF 40 50 00 00 00 0E 43 19 42 1E 20
+02 3C 14 44 2D 83 19 92 20 20 16 2C 58 49 00 1E
+19 53 78 90 20 00 08 2C 78 90 0A 00 F4 23 82 49
+1E 20 2F 53 3D 41 30 4D 8F 9E 00 00 58 24 CA 48
+00 00 1A 53 1E 53 53 3C 0A 12 B0 12 52 5B 3A 41
+82 93 20 20 DB 23 ED 3F 92 43 06 41 43 43 45 50
+54 00 30 40 72 44 D6 43 08 28 41 43 43 45 50 54
+29 00 3C 40 06 45 3B 40 D0 44 2D 15 0A 4E 2E 4F
+0A 5E 3B 40 0D 00 3C 40 20 00 3D 40 FA 44 92 B3
+DC 05 05 24 18 42 CC 05 38 90 0A 00 04 20 21 53
+39 40 C2 44 4D 15 B2 40 11 00 CE 05 A2 B3 DC 05
+FD 27 30 41 B2 40 13 00 CE 05 A2 B3 DC 05 FD 27
+30 41 12 D2 0A 18 FD 3F 21 52 3A 17 58 42 CC 05
+48 9B F0 27 48 9C 06 2C 78 92 11 20 2E 9F 0F 24
+1E 83 05 3C 0E 9A 03 24 CE 48 00 00 1E 53 82 48
+CE 05 A2 B3 DC 05 FD 27 30 4D FC 44 2D 83 92 B3
+DC 05 FD 27 E3 23 B2 40 18 00 0A 18 3E 8F 3D 41
+30 4D 68 44 06 28 45 4D 49 54 29 00 08 4E 3E 4F
+E6 3F 50 43 04 45 4D 49 54 00 30 40 1C 45 24 45
+04 45 43 48 4F 00 B2 40 82 48 EE 44 30 4D 6E 43
+06 4E 4F 45 43 48 4F 00 B2 40 30 4D EE 44 30 4D
+14 45 04 28 43 52 29 00 2F 83 8F 4E 00 00 3E 40
+0D 00 E3 3F A2 43 02 43 52 00 30 40 58 45 04 43
+05 53 50 41 43 45 2F 83 8F 4E 00 00 3E 40 20 00
+D4 3F 70 45 06 53 50 41 43 45 53 00 0E 93 09 24
+0D 12 3D 40 98 45 EF 3F 9A 45 2D 83 1E 83 EB 23
+3D 41 3E 4F 30 4D 2C 43 04 54 59 50 45 00 0E 93
+95 24 2A 4F 8F 5E 00 00 0E 4A 87 12 CA 41 02 42
+0A 41 2A 45 EC 41 BE 45 2A 40 2F 82 8F 4E 02 00
+7E 4D 8F 4D 00 00 0D 5E 1D B3 0D 63 30 4D 84 45
+82 53 22 00 87 12 34 40 CA 45 2C 48 34 40 22 00
+24 46 F4 45 3D 41 6E 4E 1E 83 82 5E C4 1D 3E 4F
+92 B3 C4 1D A2 63 C4 1D 30 4D 40 45 82 2E 22 00
+87 12 E4 45 34 40 AE 45 2C 48 2A 40 00 00 04 57
+4F 52 44 00 3C 40 BE 1D 39 4C 3A 4C 09 5A 3A 5C
+28 4C 09 9A 19 24 7E 9A FC 27 1A 83 3B 40 60 00
+C8 4C 00 00 09 9A 0C 24 7C 4A 4E 9C 09 24 18 53
+4B 9C F6 2F 7C 90 7B 00 F3 2F 7C 80 20 00 F0 3F
+1A 82 C0 1D 82 4A C2 1D 1E 42 C4 1D 08 8E CE 48
+00 00 30 4D 00 00 04 46 49 4E 44 00 2F 83 0C 4E
+65 4C 74 40 80 00 3B 40 CA 1D 3E 4B 0E 93 1E 24
+58 4C 01 00 78 F0 1E 00 0E 58 2E 53 1E 4E FE FF
+0E 93 F3 27 09 4E 78 49 48 C4 48 95 F7 23 0A 4C
+1A 53 FA 99 00 00 F2 23 58 83 FA 23 19 B3 09 63
+0C 49 6A 4E 1E 43 4A 93 01 30 2E 83 8F 4C 00 00
+35 40 08 40 34 40 14 40 30 4D 2F 53 2F 53 3E 4F
+30 4D 26 42 07 3E 4E 55 4D 42 45 52 3C 4F 38 4F
+29 4F 2F 82 1B 42 DA 1D 6A 4C 7A 80 30 00 7A 90
+0A 00 02 28 7A 80 07 00 0A 9B 13 2C 82 49 D0 04
+82 48 D2 04 82 4B C8 04 19 42 E4 04 18 42 E6 04
+09 5A 08 63 1C 53 1E 83 E7 23 8F 49 04 00 8F 48
+02 00 8F 4C 00 00 30 4D 03 12 0D 12 1B 42 DA 1D
+0B 12 32 C0 00 02 6D 4E 0D 5E 0C 4E 7A 40 2E 00
+0D 9C 0A 28 7A 9C FC 23 32 D0 00 02 FC 4C FE FF
+0D 9C FC 2F DE 83 00 00 09 43 08 43 3D 40 AE 47
+3F 82 8F 4E 06 00 0C 4E 7E 4C 6A 4C 7A 90 2D 00
+10 2C 3B 40 10 00 7A 80 24 00 06 24 2B 43 5A 83
+03 24 3B 52 6A 53 B0 23 1C 53 1E 83 6A 4C 7A 90
+2D 00 AA 23 1C 53 1E 83 B1 43 04 00 A5 3F B0 47
+2F 53 0E 93 2C 17 82 4C DA 1D 03 24 2F 52 0E F3
+30 4D 8F 93 00 00 15 20 32 B0 00 02 14 20 0E 93
+05 24 1A 4F 02 00 1A 83 0A 93 0B 38 2F 53 BF 4F
+00 00 3E E3 05 20 BF E3 00 00 9F 53 00 00 3E E3
+30 4D 32 D0 00 02 9F 4F 02 00 04 00 BF 4F 00 00
+3E E3 F6 23 BF E3 02 00 BF E3 00 00 9F 53 02 00
+8F 63 00 00 3E E3 30 4D 30 45 07 45 58 45 43 55
+54 45 0A 4E 3E 4F 00 4A 28 41 01 2C 1A 42 C4 1D
+A2 53 C4 1D 8A 4E 00 00 3E 4F 30 4D 2A 48 87 4C
+49 54 45 52 41 4C 82 93 B6 1D 16 24 32 B0 00 02
+09 24 1A 42 C4 1D A2 52 C4 1D BA 40 34 40 00 00
+BA 4F 02 00 1A 42 C4 1D A2 52 C4 1D BA 40 34 40
+00 00 8A 4E 02 00 3E 4F 30 4D 66 45 05 43 4F 55
+4E 54 2F 83 1E 53 8F 4E 00 00 5E 4E FF FF 30 4D
+82 4E BE 1D B2 4F C0 1D 3E 4F 82 43 C2 1D 87 12
+4C 42 24 46 A6 48 3D 40 B2 48 E8 22 3D 41 3E 4F
+30 4D B4 48 0A 4E 3E 4F 3D 40 CA 48 3D 27 3D 40
+A0 48 1A E2 B6 1D B2 27 AC 23 CC 48 3E 4F 3D 40
+A0 48 B9 23 DE 53 00 00 68 4E 08 5E F8 40 3F 00
+00 00 3D 40 A2 4A CD 3F 1A 48 08 45 56 41 4C 55
+41 54 45 00 39 40 BE 1D 39 12 39 12 39 12 0D 12
+B0 12 2A 40 90 48 08 49 3D 41 B2 41 C2 1D B2 41
+C0 1D B2 41 BE 1D 30 4D 7A 41 04 51 55 49 54 00
+31 40 E0 1C B2 40 00 1C AC 1D 82 43 B6 1D 82 43
+08 18 B0 12 2A 40 CA 45 04 0D 6F 6B 20 00 AE 45
+34 40 38 1D 44 40 34 40 50 00 62 44 76 45 90 48
+34 40 7E 1C CE 40 B2 41 CA 45 0D 73 74 61 63 6B
+20 65 6D 70 74 79 20 21 A4 49 34 40 30 FF 84 43
+B2 41 CA 45 0B 46 52 41 4D 20 66 75 6C 6C 20 21
+A4 49 42 42 F4 40 C0 41 36 49 CA 45 04 0D 20 20
+20 00 BC 41 3E 49 5A 44 05 41 42 4F 52 54 3F 40
+80 1C BE 3F 8F 93 02 00 98 26 B2 40 82 48 EE 44
+1B 42 36 20 0B 93 04 24 CB 43 02 00 2B 4B FA 3F
+B0 12 9C 4E 82 43 B2 58 82 43 BE 58 82 43 CA 58
+82 43 FA 58 82 43 06 59 82 43 12 59 A2 B3 DC 05
+FD 27 B2 40 11 00 CE 05 92 C3 DC 05 38 40 A0 AA
+39 42 19 83 FE 23 18 83 FB 23 92 B3 DC 05 F4 23
+87 12 CA 45 04 1B 5B 37 6D 00 AE 45 AE 45 CA 45
+04 1B 5B 30 6D 00 AE 45 E4 4D 26 4E 2C 4E 9E 49
+98 49 86 41 42 4F 52 54 22 00 87 12 E4 45 34 40
+A4 49 2C 48 2A 40 76 46 01 27 87 12 4C 42 24 46
+7C 46 C0 41 48 4A 2A 40 D4 48 52 42 81 5C 92 42
+BE 1D C2 1D 30 4D 87 12 00 46 4C 42 24 46 60 4A
+08 4E 7A 4E 5A D3 5A 53 0A 58 19 42 C8 1D 6E 4E
+3E F0 1E 00 09 5E 82 48 AE 1D 82 49 B0 1D 82 4A
+B2 1D 2A 52 82 4A C4 1D 3E 4F 3D 41 30 41 87 12
+CA 45 0F 73 74 61 63 6B 20 6D 69 73 6D 61 74 63
+68 21 AA 49 82 9F B4 1D F2 23 18 42 AE 1D 19 42
+B0 1D A8 49 FE FF 89 48 00 00 30 4D 1E 46 08 56
+41 52 49 41 42 4C 45 00 B0 12 56 4A BA 40 86 12
+FC FF EF 3F 7C 48 08 43 4F 4E 53 54 41 4E 54 00
+B0 12 56 4A BA 40 85 12 FC FF 8A 4E FE FF 3E 4F
+E0 3F D6 4A 06 43 52 45 41 54 45 00 B0 12 56 4A
+BA 40 85 12 FC FF 8A 4A FE FF D3 3F EA 48 05 44
+4F 45 53 3E 1A 42 B2 1D BA 40 84 12 00 00 8A 4D
+02 00 3D 41 30 4D 0E 4B 05 44 45 46 45 52 B0 12
+56 4A BA 40 30 40 FC FF BA 40 24 4B FE FF B9 3F
+00 00 81 5B 82 43 B6 1D 30 4D 4C 4A 01 5D B2 43
+B6 1D 30 4D E0 45 87 52 45 43 55 52 53 45 19 42
+C4 1D 99 42 B2 1D 00 00 A2 53 C4 1D 30 4D 42 4B
+01 3A B0 12 56 4A BA 40 87 12 FC FF A2 83 C4 1D
+B2 43 B6 1D 82 4F B4 1D 30 4D 70 4B 81 3B 82 93
+B6 1D 5D 27 87 12 34 40 2A 40 2C 48 A4 4A 44 4B
+2A 40 52 45 09 49 4D 4D 45 44 49 41 54 45 1A 42
+AE 1D FA D0 80 00 00 00 30 4D BE 4F 02 00 3E 4F
+30 4D A4 4B 82 49 53 00 87 12 42 42 F4 40 C0 41
+DC 4B E8 4B 34 40 BA 4B 2C 48 2A 40 3A 4A BA 4B
+2A 40 8C 4B 83 5B 27 5D 87 12 3A 4A 34 40 34 40
+2C 48 2C 48 2A 40 1A 49 88 50 4F 53 54 50 4F 4E
+45 00 87 12 4C 42 24 46 7C 46 54 40 C0 41 48 4A
+7E 41 C0 41 22 4C 34 40 34 40 2C 48 2C 48 34 40
+2C 48 2C 48 2A 40 28 4C 3A 4E 82 4A C6 1D 2E 4E
+82 4E C4 1D 3D 40 10 00 09 4A 08 49 29 83 18 48
+FE FF 0E 98 FC 2B 89 48 00 00 1D 83 F6 23 2A 4A
+0A 93 F0 23 3E 4F 3D 41 30 4D C4 4B 82 49 46 00
+2F 83 8F 4E 00 00 1E 42 C4 1D BE 40 C0 41 00 00
+A2 52 C4 1D 2E 53 30 4D 28 4B 84 45 4C 53 45 00
+1A 42 C4 1D BA 40 BC 41 00 00 2A 52 82 4A C4 1D
+8E 4A 00 00 2A 83 0E 4A 30 4D A8 45 84 54 48 45
+4E 00 9E 42 C4 1D 00 00 3E 4F 30 4D F4 4A 85 42
+45 47 49 4E 30 40 84 43 9C 4C 85 55 4E 54 49 4C
+39 40 C0 41 1A 42 C4 1D A2 52 C4 1D 8A 49 00 00
+8A 4E 02 00 3E 4F 30 4D 22 4A 85 41 47 41 49 4E
+39 40 BC 41 EF 3F BE 4A 85 57 48 49 4C 45 87 12
+60 4C 6E 40 2A 40 56 4B 86 52 45 50 45 41 54 00
+87 12 E0 4C A2 4C 2A 40 7A 4C 82 44 4F 00 2F 83
+8F 4E 00 00 1E 42 C4 1D BE 40 CA 41 00 00 2E 53
+82 4E C4 1D A2 53 AC 1D 1A 42 AC 1D 8A 43 00 00
+30 4D 3E 48 84 4C 4F 4F 50 00 39 40 EC 41 1A 42
+C4 1D A2 52 C4 1D 8A 49 00 00 8A 4E 02 00 1E 42
+AC 1D A2 83 AC 1D 2E 4E 0E 93 04 24 9E 42 C4 1D
+00 00 F5 3F 3E 4F 30 4D E4 43 85 2B 4C 4F 4F 50
+39 40 DA 41 E4 3F 34 4D 85 4C 45 41 56 45 1A 42
+C4 1D BA 40 FC 41 00 00 BA 40 BC 41 02 00 B2 50
+06 00 C4 1D A2 53 AC 1D 2A 52 19 42 AC 1D 89 4A
+00 00 30 4D 78 4D 04 4D 4F 56 45 00 0A 4E 38 4F
+39 4F 3E 4F 0A 93 11 24 08 99 0F 24 06 2C F8 49
+00 00 18 53 1A 83 FB 23 30 4D 08 5A 09 5A 19 83
+18 83 E8 49 00 00 1A 83 FA 23 30 4D 34 40 CA 1D
+FC 40 2A 40 84 12 DC 4D 22 52 06 5D FA 5C 38 4A
+F2 51 6A 4D 14 5D 0C 46 4A 4E 98 61 80 62 8A 61
+48 41 E4 4B 4C 4B E4 46 00 00 3A 40 0C 00 39 40
+CA 1D 38 40 CC 1D D9 3F 3A 40 0E 00 39 40 CC 1D
+38 40 CA 1D CC 3F 82 43 CC 1D 30 4D 92 42 CA 1D
+C8 1D 30 4D F8 4B 09 50 57 52 5F 53 54 41 54 45
+84 12 26 4C EE 51 E6 62 36 4E 08 50 57 52 5F 48
+45 52 45 00 92 42 C4 1D 46 4E 92 42 C6 1D 44 4E
+EF 3F F8 4C 09 52 53 54 5F 53 54 41 54 45 92 42
+0C 18 46 4E 92 42 0E 18 44 4E E2 3F 64 4E 08 52
+53 54 5F 48 45 52 45 00 92 42 C4 1D 0C 18 92 42
+C6 1D 0E 18 DF 3F B2 40 EA 4E 4C 4F B2 40 1C 45
+2C 45 B2 40 58 45 6C 45 B2 40 DC 43 EA 43 B2 40
+72 44 64 44 30 41 E8 4C 04 57 49 50 45 00 39 40
+80 FF B9 43 00 00 29 53 39 90 B4 FF FA 23 B0 12
+96 4E B2 40 E6 62 C4 1D B2 40 EE 51 C6 1D D4 3F
+5C 4C 06 28 57 41 52 4D 29 00 1E 42 08 18 87 12
+CA 45 05 0D 1B 5B 37 6D AE 45 70 43 CA 45 27 20
+46 61 73 74 46 6F 72 74 68 20 56 31 36 30 20 31
+36 4D 48 7A 20 28 43 29 20 4A 2E 4D 2E 54 68 6F
+6F 72 65 6E 73 20 AE 45 34 40 30 FF 84 43 2A 41
+30 43 CA 45 0B 62 79 74 65 73 20 66 72 65 65 20
+C0 49 B8 4E 04 57 41 52 4D 00 30 40 EA 4E AE 4C
+04 43 4F 4C 44 00 B2 40 04 A5 20 01 B2 40 88 5A
+5C 01 B2 D0 03 00 04 02 B2 40 FC FF 02 02 B2 C0
+03 00 06 02 B2 43 22 02 B2 D3 26 02 B2 43 42 02
+B2 D3 46 02 B2 43 62 02 B2 D3 66 02 F2 43 26 03
+F2 D3 22 03 F2 40 A5 00 41 01 F2 40 10 00 40 01
+D2 43 41 01 F2 40 A5 00 61 01 B2 40 48 00 62 01
+82 43 66 01 39 40 80 00 B2 40 33 00 64 01 D2 43
+61 01 92 D2 9E 01 08 18 A2 93 08 18 01 24 59 07
+38 40 C2 A2 18 83 FE 23 19 83 FA 23 B2 42 B0 01
+F2 D0 10 00 2A 03 F2 C0 40 00 A2 04 3A 40 5C 4F
+39 40 B4 FF 89 4A 00 00 29 53 FC 23 92 42 02 18
+F0 FF B2 40 18 00 0A 18 31 40 E0 1C 3F 40 80 1C
+37 40 00 40 36 40 B4 40 35 40 08 40 34 40 14 40
+B2 40 0A 00 DA 1D B2 43 DC 1D 92 C3 30 01 18 42
+08 18 D2 B3 01 02 04 20 38 E3 18 53 82 48 08 18
+B2 40 81 00 C0 05 B2 40 05 00 C6 05 B2 40 00 49
+C8 05 F2 D0 03 00 0D 02 92 C3 C0 05 92 D3 DA 05
+3D 40 7A 50 18 42 08 18 38 90 0A 00 28 27 38 90
+16 00 25 2F 28 93 FB 22 E3 26 7C 50 E2 B2 60 02
+64 23 B2 40 81 A9 40 06 B2 40 30 00 46 06 D2 D3
+25 02 B2 D0 C0 04 0C 02 B2 C0 C0 04 06 02 92 C3
+40 06 39 40 00 20 89 43 00 00 29 53 39 90 54 21
+FA 23 39 42 B0 12 C0 59 D2 C3 23 02 2C 42 B2 40
+95 00 14 20 B2 40 00 40 18 20 1A 43 B0 12 84 59
+02 24 30 40 5E 5A B0 12 BE 59 7A 93 FC 23 3C 42
+B2 40 87 AA 14 20 92 43 16 20 B2 40 00 48 18 20
+1A 43 B0 12 84 59 29 42 B0 12 C0 59 92 43 14 20
+82 43 16 20 78 43 0C 5C B2 40 00 77 18 20 1A 43
+B0 12 84 59 B2 40 40 69 18 20 B0 12 7A 59 03 24
+58 83 F2 23 D6 3F 0C 5C A2 43 16 20 B2 40 00 50
+18 20 B0 12 7A 59 CD 23 92 D3 40 06 82 43 46 06
+92 C3 40 06 0C 5C B0 12 E6 59 38 40 00 1E 92 48
+C6 01 04 20 92 48 C8 01 06 20 5A 48 C2 01 92 43
+02 20 7A 80 06 00 0B 24 7A 82 09 24 A2 43 02 20
+6A 53 05 24 5A 53 03 24 7A 50 0B 00 AA 23 B0 12
+E6 59 D2 48 0D 00 12 20 19 48 0E 00 82 49 08 20
+1A 48 16 00 0A 93 02 20 1A 48 24 00 82 4A 0A 20
+09 5A 82 49 0C 20 09 5A A2 93 02 20 04 24 82 49
+0E 20 39 50 20 00 19 82 12 20 19 82 12 20 82 49
+10 20 92 42 02 20 2E 20 C0 3E 84 12 DC 4D 16 58
+C2 58 CA 57 16 59 90 57 4A 58 94 54 00 00 86 57
+36 58 E8 57 26 58 A4 55 00 00 00 00 28 59 08 4E
+E2 4E 85 48 49 32 4C 4F 87 12 84 43 74 4C 2C 48
+44 4B 0A 4E CA 51 2A 40 50 4F 04 43 4F 44 45 00
+B0 12 56 4A A2 82 C4 1D 87 12 84 4B BC 41 02 52
+DA 4C 03 41 53 4D 92 42 C8 1D B8 1D B2 40 CE 51
+C8 1D EE 3F 00 00 07 45 4E 44 43 4F 44 45 87 12
+18 4E A4 4A 2A 40 36 52 06 45 4E 44 41 53 4D 00
+92 42 B8 1D C8 1D F3 3F 00 00 05 43 4F 4C 4F 4E
+1A 42 C4 1D BA 40 87 12 00 00 A2 53 C4 1D B2 43
+B6 1D 30 40 18 4E 00 00 05 4C 4F 32 48 49 1A 42
+C4 1D BA 40 B0 12 00 00 BA 40 2A 40 02 00 A2 52
+C4 1D ED 3F 38 40 BE 1D 39 48 2A 48 09 5A 1A 52
+C2 1D 09 9A 03 24 7E 9A FC 27 1A 83 0E 4A 2A 88
+82 4A C2 1D 30 4D B0 12 2A 40 24 46 7C 46 72 41
+C0 41 CC 52 38 47 C0 41 48 4A EE 52 CE 52 29 4E
+39 90 86 12 02 20 2E 53 30 41 39 90 85 12 03 20
+1E 4E 02 00 30 41 39 90 84 12 01 20 2E 52 30 41
+19 42 C4 1D A2 53 C4 1D 89 4E 00 00 3E 40 29 00
+12 12 C2 1D 92 53 C2 1D B0 12 2A 40 24 46 38 47
+C0 41 20 53 16 53 21 53 3E 90 10 00 BB 2D 30 41
+22 53 B2 41 C2 1D 22 D3 30 41 87 12 4C 42 94 52
+32 53 82 43 BC 1D 92 42 C4 1D BA 1D A2 53 C4 1D
+0A 4E 3E 4F FA 90 23 00 00 00 34 20 92 53 C2 1D
+B0 12 B6 52 0E 93 04 20 B2 40 00 03 BC 1D 27 3C
+1E 93 04 20 B2 40 10 03 BC 1D 21 3C 2E 93 04 20
+B2 40 20 03 BC 1D 1B 3C 2E 92 04 20 B2 40 20 02
+BC 1D 15 3C 3E 92 04 20 B2 40 30 02 BC 1D 0F 3C
+3E 93 04 20 B2 40 30 03 BC 1D 09 3C B2 40 30 00
+BC 1D 19 42 C4 1D A2 53 C4 1D 89 4E 00 00 3E 4F
+3D 41 30 4D FA 90 26 00 00 00 08 20 B2 40 10 02
+BC 1D 92 53 C2 1D 30 12 A2 53 75 3F FA 90 40 00
+00 00 1A 20 B2 40 20 00 BC 1D 92 53 C2 1D B0 12
+00 53 0E 20 B2 50 10 00 BC 1D 3E 40 2B 00 B0 12
+00 53 32 24 92 92 BE 1D C2 1D 02 24 92 53 C2 1D
+8E 10 82 5E BC 1D D3 3F B0 12 00 53 F9 23 B2 50
+10 00 BC 1D 3E 40 28 00 B0 12 B6 52 30 12 F2 53
+67 3F 87 12 4C 42 94 52 2A 54 FE 90 26 00 00 00
+3E 40 20 00 04 20 B2 50 82 00 BC 1D C2 3F B0 12
+00 53 DF 23 B2 50 80 00 BC 1D 3E 40 28 00 B0 12
+B6 52 B0 12 F0 52 D5 23 3D 40 48 4A 30 4D 00 00
+04 52 45 54 49 00 87 12 34 40 00 13 2C 48 2A 40
+34 40 2C 00 2A 53 22 54 7A 54 2E 4E 1E D2 BC 1D
+19 42 BA 1D 92 3F 78 52 03 4D 4F 56 84 12 70 54
+00 40 88 54 05 4D 4F 56 2E 42 84 12 70 54 40 40
+00 00 03 41 44 44 84 12 70 54 00 50 A2 54 05 41
+44 44 2E 42 84 12 70 54 40 50 AE 54 04 41 44 44
+43 00 84 12 70 54 00 60 BC 54 06 41 44 44 43 2E
+42 00 84 12 70 54 40 60 60 54 04 53 55 42 43 00
+84 12 70 54 00 70 DA 54 06 53 55 42 43 2E 42 00
+84 12 70 54 40 70 E8 54 03 53 55 42 84 12 70 54
+00 80 F8 54 05 53 55 42 2E 42 84 12 70 54 40 80
+5A 52 03 43 4D 50 84 12 70 54 00 90 12 55 05 43
+4D 50 2E 42 84 12 70 54 40 90 48 52 04 44 41 44
+44 00 84 12 70 54 00 A0 2C 55 06 44 41 44 44 2E
+42 00 84 12 70 54 40 A0 1E 55 03 42 49 54 84 12
+70 54 00 B0 4A 55 05 42 49 54 2E 42 84 12 70 54
+40 B0 56 55 03 42 49 43 84 12 70 54 00 C0 64 55
+05 42 49 43 2E 42 84 12 70 54 40 C0 70 55 03 42
+49 53 84 12 70 54 00 D0 7E 55 05 42 49 53 2E 42
+84 12 70 54 40 D0 00 00 03 58 4F 52 84 12 70 54
+00 E0 98 55 05 58 4F 52 2E 42 84 12 70 54 40 E0
+CA 54 03 41 4E 44 84 12 70 54 00 F0 B2 55 05 41
+4E 44 2E 42 84 12 70 54 40 F0 4C 42 2A 53 D0 55
+1A 42 BC 1D B2 F0 70 00 BC 1D 8A 10 3A F0 0F 00
+82 DA BC 1D 4A 3F 04 55 03 52 52 43 84 12 CA 55
+00 10 E8 55 05 52 52 43 2E 42 84 12 CA 55 40 10
+F4 55 04 53 57 50 42 00 84 12 CA 55 80 10 02 56
+03 52 52 41 84 12 CA 55 00 11 10 56 05 52 52 41
+2E 42 84 12 CA 55 40 11 1C 56 03 53 58 54 84 12
+CA 55 80 11 00 00 04 50 55 53 48 00 84 12 CA 55
+00 12 36 56 06 50 55 53 48 2E 42 00 84 12 CA 55
+40 12 8A 55 04 43 41 4C 4C 00 84 12 CA 55 80 12
+34 40 2C 00 2A 53 22 54 6A 56 59 42 BC 1D 5A 42
+BD 1D 82 4A BC 1D BE 90 00 15 00 00 02 20 0A 89
+02 3C 09 8A 0A 49 3A 90 10 00 03 2C 5A 0E A8 3F
+1A 53 0E 4A 87 12 70 43 CA 45 0D 6F 75 74 20 6F
+66 20 62 6F 75 6E 64 73 AA 49 44 56 05 50 55 53
+48 4D 84 12 60 56 00 15 AC 56 04 50 4F 50 4D 00
+84 12 60 56 00 17 4C 42 94 52 CC 56 82 43 BC 1D
+92 42 C4 1D BA 1D A2 53 C4 1D 92 53 C2 1D 3E 40
+2C 00 B0 12 2A 40 24 46 38 47 C0 41 48 4A 22 54
+F2 56 0A 4E 3E 4F 1A 83 2A 92 CA 2F 8A 10 5A 06
+6F 3F 2A 56 04 52 52 43 4D 00 84 12 C6 56 50 00
+04 57 04 52 52 41 4D 00 84 12 C6 56 50 01 12 57
+04 52 4C 41 4D 00 84 12 C6 56 50 02 20 57 04 52
+52 55 4D 00 84 12 C6 56 50 03 85 12 00 3C 2E 57
+03 53 3E 3D 85 12 00 38 40 57 02 53 3C 00 85 12
+00 34 BA 56 03 30 3E 3D 85 12 00 30 54 57 02 30
+3C 00 85 12 00 30 00 00 02 55 3C 00 85 12 00 2C
+68 57 03 55 3E 3D 85 12 00 28 5E 57 03 30 3C 3E
+85 12 00 24 7C 57 02 30 3D 00 85 12 00 20 00 00
+02 49 46 00 1A 42 C4 1D 8A 4E 00 00 A2 53 C4 1D
+0E 4A 30 4D 72 57 04 54 48 45 4E 00 1A 42 C4 1D
+08 4E 3E 4F 09 48 29 53 0A 89 0A 11 3A 90 00 02
+68 2F 88 DA 00 00 30 4D 3A 55 04 45 4C 53 45 00
+1A 42 C4 1D BA 40 00 3C 00 00 A2 53 C4 1D 2F 83
+8F 4A 00 00 E3 3F A6 57 05 55 4E 54 49 4C 3A 4F
+08 4E 3E 4F 19 42 C4 1D 2A 83 0A 89 0A 11 3A 90
+00 FE 47 3B 3A F0 FF 03 08 DA 89 48 00 00 A2 53
+C4 1D 30 4D BE 55 05 41 47 41 49 4E 87 12 3A 57
+EE 57 2A 40 00 00 05 57 48 49 4C 45 87 12 94 57
+6E 40 2A 40 4A 57 06 52 45 50 45 41 54 00 87 12
+3A 57 EE 57 AC 57 2A 40 00 00 03 4A 4D 50 87 12
+3A 4A 3A 57 EE 57 2A 40 3E B0 00 10 03 20 3E E0
+00 04 30 4D 3E 90 00 34 06 28 03 24 3E 40 00 34
+30 4D 3E 40 00 38 30 4D 00 00 04 3F 4A 4D 50 00
+87 12 58 58 3A 4A 6E 40 EE 57 2A 40 8E 58 3D 41
+08 4E 3E 4F 2A 48 0A 93 04 20 98 42 C4 1D 00 00
+30 4D 88 43 00 00 A4 3F 54 56 03 42 57 31 84 12
+8C 58 00 00 AA 58 03 42 57 32 84 12 8C 58 00 00
+B6 58 03 42 57 33 84 12 8C 58 00 00 CE 58 3D 41
+1A 42 C4 1D 28 4E 08 93 08 20 BA 4F 00 00 A2 53
+C4 1D 8E 4A 00 00 3E 4F 30 4D 8E 43 00 00 61 3F
+00 00 03 46 57 31 84 12 CC 58 00 00 F2 58 03 46
+57 32 84 12 CC 58 00 00 FE 58 03 46 57 33 84 12
+CC 58 00 00 0A 59 04 47 4F 54 4F 00 87 12 3A 57
+3A 4A 22 48 2A 40 7A 58 05 3F 47 4F 54 4F 87 12
+58 58 3A 4A 22 48 2A 40 D2 C3 23 02 E2 B2 60 02
+02 24 30 40 56 4F 1A 52 04 20 19 62 06 20 92 43
+14 20 A2 93 02 20 07 24 0A 5A 49 69 82 4A 16 20
+C2 49 18 20 0A 3C C2 4A 15 20 8A 10 C2 4A 16 20
+C2 49 17 20 89 10 C2 49 18 20 B0 12 BE 59 7A 93
+FC 23 0A 43 39 40 05 00 D2 49 14 20 4E 06 82 93
+46 06 05 24 92 B3 6C 06 FD 27 C2 93 4C 06 59 83
+F3 2F 19 83 0B 30 F2 43 4E 06 82 93 46 06 03 24
+92 B3 6C 06 FD 27 5A 92 4C 06 F3 23 30 41 19 43
+3A 43 8A 10 C2 4A 4E 06 82 93 46 06 05 24 92 B3
+6C 06 FD 27 C2 93 4C 06 19 83 F3 23 5A 42 4C 06
+30 41 1A 52 08 20 09 43 1C D3 F2 40 51 00 19 20
+B0 12 38 59 34 20 B0 12 BE 59 7A 90 FE FF FB 23
+F2 43 4E 06 00 40 19 53 39 90 00 02 D9 42 4C 06
+FF 1D F6 23 29 43 B0 12 C0 59 3C C0 03 00 D2 D3
+23 02 30 41 09 43 2C D3 F0 40 58 00 ED C5 B0 12
+38 59 15 20 3A 40 FE FF 29 43 B0 12 C2 59 D2 49
+00 1E 4E 06 03 43 19 53 39 90 00 02 F8 23 39 40
+03 00 B0 12 C0 59 7A C0 E1 00 6A 92 DE 27 D2 D3
+23 02 8C 10 1C 52 4C 06 87 12 CA 45 0B 3C 20 53
+44 20 45 72 72 6F 72 21 7A 5A 2F 82 8F 4E 02 00
+9F 42 DA 1D 00 00 B2 40 10 00 DA 1D 0E 4C B0 12
+2A 40 30 43 36 42 FC 40 AA 49 39 4F 18 42 C4 1D
+4A 4E 0E 48 C8 4A 00 00 18 53 30 40 BE 4D 92 4B
+0E 00 22 20 92 4B 10 00 24 20 5A 42 23 20 58 42
+22 20 A2 93 02 20 02 24 08 58 30 41 59 42 24 20
+89 10 0A 59 88 10 08 58 0A 6A 88 10 08 58 30 41
+82 43 1C 20 92 42 0E 20 1A 20 92 93 22 20 03 20
+C2 93 24 20 EA 27 92 42 10 20 E4 04 82 43 E6 04
+92 42 22 20 D8 04 92 42 24 20 DA 04 92 42 12 20
+C8 04 92 42 E4 04 1A 20 92 42 E6 04 1C 20 30 41
+92 4B 0E 00 22 20 92 4B 10 00 24 20 B0 12 E0 5A
+5A 4B 03 00 82 5A 1A 20 82 63 1C 20 30 41 09 93
+C4 27 F8 90 20 00 00 1E C0 23 18 53 19 83 F9 23
+30 41 1B 42 36 20 82 43 1E 20 B2 90 00 02 20 20
+9A 20 BB 80 00 02 12 00 8B 73 14 00 DB 53 03 00
+DB 92 12 20 03 00 11 28 CB 43 03 00 B0 12 AE 5A
+B0 12 E2 59 8B 43 10 00 9B 48 00 1E 0E 00 92 93
+02 20 03 24 9B 48 02 1E 10 00 B2 40 00 02 20 20
+8B 93 14 00 0B 20 92 9B 12 00 1E 20 74 2C BB 90
+00 02 12 00 03 2C 92 4B 12 00 20 20 B0 12 20 5B
+1A 42 1A 20 19 42 1C 20 0F 3F 3C 42 3B 40 40 20
+09 43 CB 93 02 00 10 24 9B 92 24 20 0C 00 04 20
+9B 92 22 20 0A 00 07 24 09 4B 3B 50 18 00 3B 90
+00 21 EF 23 0C 5C 30 41 0C 43 82 4B 36 20 8B 49
+00 00 4A 93 07 34 49 93 05 24 C9 93 02 00 02 34
+5A 59 02 00 CB 4A 02 00 CB 43 03 00 9B 42 1A 20
+04 00 9B 42 1C 20 06 00 18 42 32 20 8B 48 08 00
+9B 48 1A 1E 0A 00 9B 48 14 1E 0C 00 9B 48 1A 1E
+0E 00 9B 48 14 1E 10 00 9B 48 1C 1E 12 00 9B 48
+1E 1E 14 00 82 43 1E 20 6A 93 62 27 CC 37 8B 43
+16 00 7A 93 05 24 99 37 99 52 C2 1D 16 00 95 3F
+92 42 BE 1D 38 20 92 82 C2 1D 38 20 92 42 C0 1D
+3A 20 92 52 C2 1D 3A 20 B2 40 EC 43 64 44 92 42
+BE 1D C2 1D 82 3F 1B 42 36 20 82 43 20 20 0B 93
+AA 27 EB 93 02 00 04 20 B0 12 0C 61 B0 12 D4 60
+5A 4B 02 00 CB 43 02 00 2B 4B 82 4B 36 20 5A 53
+05 24 99 37 92 4B 16 00 1E 20 67 3F 1E 42 38 20
+9F 42 3A 20 02 00 B2 40 72 44 64 44 8C 3F 7E 4E
+85 52 45 41 44 22 5A 43 19 3C 44 4F 86 57 52 49
+54 45 22 00 6A 43 12 3C 0A 4D 84 44 45 4C 22 00
+6A 42 0C 3C 0A 52 05 43 4C 4F 53 45 B0 12 96 5C
+30 4D A6 4D 85 4C 4F 41 44 22 7A 43 2F 83 8F 4E
+00 00 0E 4A 82 93 B6 1D 0D 24 87 12 34 40 34 40
+2C 48 2C 48 E4 45 34 40 9A 5A 2C 48 34 40 50 5D
+2C 48 2A 40 87 12 34 40 22 00 24 46 4E 5D 3D 41
+2F 83 78 4E 08 5E C8 43 00 00 1C 43 92 42 2E 20
+22 20 92 42 30 20 24 20 CE 93 00 00 96 24 FE 90
+3A 00 01 00 01 20 2E 53 FE 90 5C 00 00 00 09 20
+1E 53 92 42 02 20 22 20 82 43 24 20 CE 93 00 00
+76 24 82 4E 34 20 B0 12 E0 5A BF 40 20 00 00 00
+A2 93 02 20 04 24 92 92 22 20 02 20 03 24 9F 42
+12 20 00 00 B0 12 C0 5B 2C 43 0A 43 08 4A 58 0E
+08 58 82 48 32 20 C8 93 00 1E 67 24 39 42 F8 9E
+00 1E 04 20 18 53 19 83 FA 23 1E 53 FE 90 2E 00
+FF FF 1B 24 39 50 03 00 B0 12 3E 5B 07 20 FE 90
+5C 00 FF FF 2C 24 CE 93 FF FF 29 24 1E 42 34 20
+1A 53 3A 90 10 00 DA 23 92 53 1A 20 82 63 1C 20
+9F 83 00 00 CF 23 2C 42 40 3C FE 90 2E 00 FE FF
+ED 27 B0 12 3E 5B EA 23 39 40 03 00 F8 9E 00 1E
+04 20 18 53 19 83 FA 23 0A 3C CE 93 FF FF DE 23
+FE 90 5C 00 FF FF DA 23 B0 12 3E 5B D7 23 18 42
+32 20 92 48 1A 1E 22 20 92 48 14 1E 24 20 F8 B0
+10 00 0B 1E 16 24 82 93 24 20 06 20 82 93 22 20
+03 20 92 42 02 20 22 20 CE 93 FF FF 87 23 92 42
+22 20 2E 20 92 42 24 20 30 20 2F 52 3E 4F 3D 41
+30 4D 1A 4F 02 00 B0 12 CA 5B 2F 53 3A 4F 3E 4F
+7A 93 15 20 0C 93 04 20 B2 40 30 4D EE 44 30 4D
+87 12 CA 45 0B 3C 20 4F 70 65 6E 45 72 72 6F 72
+36 45 84 43 82 48 AE 45 76 45 BC 41 78 5A 1A 93
+B5 20 0C 93 ED 23 30 4D E0 5C 04 52 45 41 44 00
+2F 83 8F 4E 00 00 1E 42 36 20 B0 12 52 5B 1E 82
+36 20 30 4D 2C 43 12 12 2C 20 18 42 02 20 08 58
+2A 41 82 9A 0A 20 A0 24 B0 12 E2 59 09 43 28 93
+03 24 89 93 02 1E 03 20 89 93 00 1E 07 24 09 58
+39 90 00 02 F4 23 91 53 00 00 EA 3F 0C 43 6A 41
+B9 43 00 1E 28 93 0F 24 B9 40 FF 0F 02 1E 09 11
+8A 10 09 5A 5A 41 01 00 0A 11 09 10 82 4A 28 20
+82 49 26 20 07 3C 09 11 C2 49 26 20 C2 4A 27 20
+82 43 28 20 3A 41 82 4A 2C 20 30 41 0A 12 1A 52
+08 20 B0 12 24 5A 3A 41 1A 52 0C 20 30 40 24 5A
+F2 B0 40 00 A2 04 29 20 F2 B0 10 00 A2 04 FC 27
+5A 42 B0 04 4A 11 59 42 B4 04 F2 40 20 00 C0 04
+D2 42 B1 04 C8 04 1A 52 E4 04 D2 42 B5 04 C8 04
+19 52 E4 04 D2 42 B2 04 C0 04 B2 40 00 08 C8 04
+1A 52 E4 04 92 42 B6 04 C0 04 B2 80 BC 07 C0 04
+B2 40 00 02 C8 04 19 52 E4 04 30 41 22 2A 2B 2C
+2F 3A 3B 3C 3D 3E 3F 5B 5C 5D 7C 2E 29 92 06 38
+39 80 03 00 B0 12 2A 60 39 40 03 00 7A 4B C8 4A
+00 1E 0A 93 12 24 0D 12 3D 40 0F 00 3C 40 DC 5F
+7A 9C F4 27 1D 83 FC 23 3D 41 6A 9C E7 27 3A 80
+21 00 EC 3B 18 53 19 83 E9 23 09 93 06 24 F8 40
+20 00 00 1E 18 53 19 83 FA 23 30 41 2A 93 E4 20
+2C 93 0D 24 0C 93 BA 24 87 12 CA 45 0C 3C 20 57
+72 69 74 65 45 72 72 6F 72 00 BC 41 C0 5E B0 12
+F4 5E 92 42 26 20 22 20 92 42 28 20 24 20 B0 12
+6C 5F B0 12 C0 5B 18 42 32 20 F8 40 20 00 0B 1E
+B0 12 80 5F 88 43 0C 1E 88 4A 0E 1E 88 49 10 1E
+88 49 12 1E 98 42 24 20 14 1E 98 42 22 20 1A 1E
+88 43 1C 1E 88 43 1E 1E 1C 43 1B 42 34 20 CB 93
+00 00 CA 27 FB 90 2E 00 00 00 C6 27 39 40 0B 00
+B0 12 FC 5F B0 12 16 61 2A 43 B0 12 CA 5B 0C 93
+BB 23 30 4D 1A 4B 04 00 19 4B 06 00 B0 12 E8 59
+B0 12 80 5F 18 4B 08 00 88 49 12 1E 88 4A 16 1E
+88 49 18 1E 98 4B 12 00 1C 1E 98 4B 14 00 1E 1E
+1A 4B 04 00 19 4B 06 00 30 40 26 5A 9B 52 1E 20
+12 00 8B 63 14 00 1A 42 1A 20 19 42 1C 20 30 40
+26 5A B2 40 00 02 1E 20 1B 42 36 20 B0 12 0C 61
+82 43 1E 20 DB 53 03 00 DB 92 12 20 03 00 22 20
+CB 43 03 00 B0 12 AE 5A 08 12 0A 12 B0 12 F4 5E
+2A 91 05 24 B0 12 6C 5F 2A 41 B0 12 E2 59 3A 41
+38 41 98 42 26 20 00 1E 92 93 02 20 03 24 98 42
+28 20 02 1E B0 12 6C 5F 9B 42 26 20 0E 00 9B 42
+28 20 10 00 30 40 20 5B EC 5C 05 57 52 49 54 45
+B0 12 22 61 30 4D DA 5E 07 53 44 5F 45 4D 49 54
+B2 90 00 02 1E 20 02 28 B0 12 22 61 18 42 1E 20
+C8 4E 00 1E 92 53 1E 20 3E 4F 30 4D 58 4B 13 00
+5C 4B 14 00 8C 10 0C 58 5A 4B 15 00 0A 11 0C 10
+18 4B 12 00 BB C0 FF 01 12 00 38 F0 FF 01 82 48
+1E 20 5B 42 12 20 B0 12 5E 42 1B 42 36 20 CB 4A
+03 00 19 5B 0A 00 18 6B 0C 00 8B 49 0E 00 8B 48
+10 00 B0 12 BC 5B 30 4D 0C 93 38 20 38 90 E0 01
+03 2C C8 93 20 1E 02 24 7C 40 E5 00 C8 4C 00 1E
+B0 12 16 61 B0 12 BA 5A 82 4A 2C 20 0B 4A B0 12
+E2 59 1A 48 00 1E 88 43 00 1E 92 93 02 20 09 24
+19 48 02 1E 88 43 02 1E 39 F0 FF 0F 39 90 FF 0F
+02 20 3A 93 0E 24 82 4A 22 20 82 49 24 20 B0 12
+BA 5A 0B 9A E6 27 0A 12 0A 4B B0 12 6C 5F 3A 41
+DD 3F 0A 4B B0 12 6C 5F B0 12 96 5C 30 4D BA 4C
+08 54 45 52 4D 32 53 44 22 00 87 12 00 5D 84 43
+92 62 21 53 2F 83 AF 43 00 00 3D 40 A2 62 30 40
+50 5D A4 62 92 C3 DC 05 08 43 B0 12 A6 44 92 B3
+DC 05 FD 27 59 42 CC 05 69 92 0D 24 C8 49 00 1E
+18 53 38 90 FF 01 04 24 F2 2B B0 12 22 61 EC 3F
+B0 12 B4 44 EC 3F B0 12 B4 44 82 48 1E 20 B0 12
+96 5C 3D 41 30 4D
+@FFB4
+5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F
+5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F
+5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F
+5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F C8 44 5C 4F
+5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F
+q
--- /dev/null
+@1800
+10 00 40 44 F4 01 80 04 FD FF 18 00 38 57 EE 4F
+2A 44 32 44 00 00 00 00
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@4000
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 40
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 40 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 40 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E 40 02 3E 52 00 0E 12 3E 4F 30 4D 8E 40
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 40
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C 40 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 40 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 41
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 40 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA 40 03 41 4E 44 3E FF 30 4D 7A 40 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E 41 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 41 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E 41 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 41 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 40 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE 41 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 41 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 41 03 3E 49 4E 85 12 C2 1D 10 41
+04 42 41 53 45 00 85 12 DA 1D C0 40 05 53 54 41
+54 45 85 12 B6 1D 30 42 02 42 4C 00 85 12 20 00
+94 41 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 42 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E 42 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 42 02 23 53 00 87 12 98 42
+D2 42 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 42 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 42 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C 42 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 41 03 55 44 2E 87 12 56 42
+CC 42 E6 42 26 45 EE 44 2A 40 18 43 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA 40
+02 44 2E 00 87 12 56 42 6E 40 80 40 3A 43 CC 42
+92 40 0A 43 E6 42 26 45 EE 44 2A 40 52 41 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 42 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 41 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 42 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A 44
+92 B3 DC 05 FD 27 1E 42 CC 05 B0 12 32 44 30 4D
+30 40 B6 43 7E 43 05 28 4B 45 59 29 18 42 CC 05
+EA 3F 12 42 03 4B 45 59 30 40 DC 43 92 43 06 41
+43 43 45 50 54 00 3C 40 78 44 3B 40 48 44 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+6C 44 92 B3 DC 05 05 24 18 42 CC 05 38 90 0A 00
+04 20 21 53 39 40 3A 44 4D 15 B2 40 11 00 CE 05
+30 41 B2 40 13 00 CE 05 30 41 12 D2 0A 18 FD 3F
+21 52 3A 17 58 42 CC 05 48 9B F3 27 48 9C 06 2C
+78 92 0E 20 2E 9F 0C 24 1E 83 05 3C 0E 9A 03 24
+CE 48 00 00 1E 53 82 48 CE 05 30 4D 6E 44 2D 83
+92 B3 DC 05 FD 27 E6 23 B2 40 18 00 0A 18 3E 8F
+3D 41 30 4D D6 43 06 28 45 4D 49 54 29 00 08 4E
+3E 4F A2 B3 DC 05 FD 27 E6 3F 50 43 04 45 4D 49
+54 00 30 40 8E 44 9C 44 04 45 43 48 4F 00 B2 40
+82 48 66 44 30 4D 6E 43 06 4E 4F 45 43 48 4F 00
+B2 40 30 4D 66 44 30 4D 86 44 04 28 43 52 29 00
+2F 83 8F 4E 00 00 3E 40 0D 00 E3 3F A2 43 02 43
+52 00 30 40 D0 44 04 43 05 53 50 41 43 45 2F 83
+8F 4E 00 00 3E 40 20 00 D4 3F E8 44 06 53 50 41
+43 45 53 00 0E 93 09 24 0D 12 3D 40 10 45 EF 3F
+12 45 2D 83 1E 83 EB 23 3D 41 3E 4F 30 4D 2C 43
+04 54 59 50 45 00 0E 93 95 24 2A 4F 8F 5E 00 00
+0E 4A 87 12 CA 41 02 42 0A 41 A2 44 EC 41 36 45
+2A 40 2F 82 8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E
+1D B3 0D 63 30 4D FC 44 82 53 22 00 87 12 34 40
+42 45 A4 47 34 40 22 00 9C 45 6C 45 3D 41 6E 4E
+1E 83 82 5E C4 1D 3E 4F 92 B3 C4 1D A2 63 C4 1D
+30 4D B8 44 82 2E 22 00 87 12 5C 45 34 40 26 45
+A4 47 2A 40 00 00 04 57 4F 52 44 00 3C 40 BE 1D
+39 4C 3A 4C 09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A
+FC 27 1A 83 3B 40 60 00 C8 4C 00 00 09 9A 0C 24
+7C 4A 4E 9C 09 24 18 53 4B 9C F6 2F 7C 90 7B 00
+F3 2F 7C 80 20 00 F0 3F 1A 82 C0 1D 82 4A C2 1D
+1E 42 C4 1D 08 8E CE 48 00 00 30 4D 00 00 04 46
+49 4E 44 00 2F 83 0C 4E 65 4C 74 40 80 00 3B 40
+CA 1D 3E 4B 0E 93 1E 24 58 4C 01 00 78 F0 1E 00
+0E 58 2E 53 1E 4E FE FF 0E 93 F3 27 09 4E 78 49
+48 C4 48 95 F7 23 0A 4C 1A 53 FA 99 00 00 F2 23
+58 83 FA 23 19 B3 09 63 0C 49 6A 4E 1E 43 4A 93
+01 30 2E 83 8F 4C 00 00 35 40 08 40 34 40 14 40
+30 4D 2F 53 2F 53 3E 4F 30 4D 26 42 07 3E 4E 55
+4D 42 45 52 3C 4F 38 4F 29 4F 2F 82 1B 42 DA 1D
+6A 4C 7A 80 30 00 7A 90 0A 00 02 28 7A 80 07 00
+0A 9B 13 2C 82 49 D0 04 82 48 D2 04 82 4B C8 04
+19 42 E4 04 18 42 E6 04 09 5A 08 63 1C 53 1E 83
+E7 23 8F 49 04 00 8F 48 02 00 8F 4C 00 00 30 4D
+03 12 0D 12 1B 42 DA 1D 0B 12 32 C0 00 02 6D 4E
+0D 5E 0C 4E 7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23
+32 D0 00 02 FC 4C FE FF 0D 9C FC 2F DE 83 00 00
+09 43 08 43 3D 40 26 47 3F 82 8F 4E 06 00 0C 4E
+7E 4C 6A 4C 7A 90 2D 00 10 2C 3B 40 10 00 7A 80
+24 00 06 24 2B 43 5A 83 03 24 3B 52 6A 53 B0 23
+1C 53 1E 83 6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83
+B1 43 04 00 A5 3F 28 47 2F 53 0E 93 2C 17 82 4C
+DA 1D 03 24 2F 52 0E F3 30 4D 8F 93 00 00 15 20
+32 B0 00 02 14 20 0E 93 05 24 1A 4F 02 00 1A 83
+0A 93 0B 38 2F 53 BF 4F 00 00 3E E3 05 20 BF E3
+00 00 9F 53 00 00 3E E3 30 4D 32 D0 00 02 9F 4F
+02 00 04 00 BF 4F 00 00 3E E3 F6 23 BF E3 02 00
+BF E3 00 00 9F 53 02 00 8F 63 00 00 3E E3 30 4D
+A8 44 07 45 58 45 43 55 54 45 0A 4E 3E 4F 00 4A
+28 41 01 2C 1A 42 C4 1D A2 53 C4 1D 8A 4E 00 00
+3E 4F 30 4D A2 47 87 4C 49 54 45 52 41 4C 82 93
+B6 1D 16 24 32 B0 00 02 09 24 1A 42 C4 1D A2 52
+C4 1D BA 40 34 40 00 00 BA 4F 02 00 1A 42 C4 1D
+A2 52 C4 1D BA 40 34 40 00 00 8A 4E 02 00 3E 4F
+30 4D DE 44 05 43 4F 55 4E 54 2F 83 1E 53 8F 4E
+00 00 5E 4E FF FF 30 4D 82 4E BE 1D B2 4F C0 1D
+3E 4F 82 43 C2 1D 87 12 4C 42 9C 45 1E 48 3D 40
+2A 48 E8 22 3D 41 3E 4F 30 4D 2C 48 0A 4E 3E 4F
+3D 40 42 48 3D 27 3D 40 18 48 1A E2 B6 1D B2 27
+AC 23 44 48 3E 4F 3D 40 18 48 B9 23 DE 53 00 00
+68 4E 08 5E F8 40 3F 00 00 00 3D 40 0A 4A CD 3F
+92 47 08 45 56 41 4C 55 41 54 45 00 39 40 BE 1D
+39 12 39 12 39 12 0D 12 B0 12 2A 40 08 48 80 48
+3D 41 B2 41 C2 1D B2 41 C0 1D B2 41 BE 1D 30 4D
+7A 41 04 51 55 49 54 00 31 40 E0 1C B2 40 00 1C
+AC 1D 82 43 B6 1D 82 43 08 18 B0 12 2A 40 42 45
+04 0D 6F 6B 20 00 26 45 34 40 38 1D 44 40 34 40
+50 00 F6 43 EE 44 08 48 34 40 7E 1C CE 40 B2 41
+42 45 0D 73 74 61 63 6B 20 65 6D 70 74 79 20 21
+1C 49 34 40 30 FF 84 43 B2 41 42 45 0B 46 52 41
+4D 20 66 75 6C 6C 20 21 1C 49 42 42 F4 40 C0 41
+AE 48 42 45 04 0D 20 20 20 00 BC 41 B6 48 EE 43
+05 41 42 4F 52 54 3F 40 80 1C BE 3F 8F 93 02 00
+98 26 B2 40 82 48 66 44 B0 12 04 4E 82 43 B2 56
+82 43 BE 56 82 43 CA 56 82 43 FA 56 82 43 06 57
+82 43 12 57 A2 B3 DC 05 FD 27 B2 40 11 00 CE 05
+92 C3 DC 05 38 40 55 05 39 42 19 83 FE 23 18 83
+FB 23 92 B3 DC 05 F4 23 87 12 42 45 04 1B 5B 37
+6D 00 26 45 26 45 42 45 04 1B 5B 30 6D 00 26 45
+4C 4D 8E 4D 94 4D 16 49 10 49 86 41 42 4F 52 54
+22 00 87 12 5C 45 34 40 1C 49 A4 47 2A 40 EE 45
+01 27 87 12 4C 42 9C 45 F4 45 C0 41 B0 49 2A 40
+4C 48 52 42 81 5C 92 42 BE 1D C2 1D 30 4D 87 12
+78 45 4C 42 9C 45 C8 49 08 4E 7A 4E 5A D3 5A 53
+0A 58 19 42 C8 1D 6E 4E 3E F0 1E 00 09 5E 82 48
+AE 1D 82 49 B0 1D 82 4A B2 1D 2A 52 82 4A C4 1D
+3E 4F 3D 41 30 41 87 12 42 45 0F 73 74 61 63 6B
+20 6D 69 73 6D 61 74 63 68 21 22 49 82 9F B4 1D
+F2 23 18 42 AE 1D 19 42 B0 1D A8 49 FE FF 89 48
+00 00 30 4D 96 45 08 56 41 52 49 41 42 4C 45 00
+B0 12 BE 49 BA 40 86 12 FC FF EF 3F F4 47 08 43
+4F 4E 53 54 41 4E 54 00 B0 12 BE 49 BA 40 85 12
+FC FF 8A 4E FE FF 3E 4F E0 3F 3E 4A 06 43 52 45
+41 54 45 00 B0 12 BE 49 BA 40 85 12 FC FF 8A 4A
+FE FF D3 3F 62 48 05 44 4F 45 53 3E 1A 42 B2 1D
+BA 40 84 12 00 00 8A 4D 02 00 3D 41 30 4D 76 4A
+05 44 45 46 45 52 B0 12 BE 49 BA 40 30 40 FC FF
+BA 40 8C 4A FE FF B9 3F 00 00 81 5B 82 43 B6 1D
+30 4D B4 49 01 5D B2 43 B6 1D 30 4D 58 45 87 52
+45 43 55 52 53 45 19 42 C4 1D 99 42 B2 1D 00 00
+A2 53 C4 1D 30 4D AA 4A 01 3A B0 12 BE 49 BA 40
+87 12 FC FF A2 83 C4 1D B2 43 B6 1D 82 4F B4 1D
+30 4D D8 4A 81 3B 82 93 B6 1D 5D 27 87 12 34 40
+2A 40 A4 47 0C 4A AC 4A 2A 40 CA 44 09 49 4D 4D
+45 44 49 41 54 45 1A 42 AE 1D FA D0 80 00 00 00
+30 4D BE 4F 02 00 3E 4F 30 4D 0C 4B 82 49 53 00
+87 12 42 42 F4 40 C0 41 44 4B 50 4B 34 40 22 4B
+A4 47 2A 40 A2 49 22 4B 2A 40 F4 4A 83 5B 27 5D
+87 12 A2 49 34 40 34 40 A4 47 A4 47 2A 40 92 48
+88 50 4F 53 54 50 4F 4E 45 00 87 12 4C 42 9C 45
+F4 45 54 40 C0 41 B0 49 7E 41 C0 41 8A 4B 34 40
+34 40 A4 47 A4 47 34 40 A4 47 A4 47 2A 40 90 4B
+3A 4E 82 4A C6 1D 2E 4E 82 4E C4 1D 3D 40 10 00
+09 4A 08 49 29 83 18 48 FE FF 0E 98 FC 2B 89 48
+00 00 1D 83 F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41
+30 4D 2C 4B 82 49 46 00 2F 83 8F 4E 00 00 1E 42
+C4 1D BE 40 C0 41 00 00 A2 52 C4 1D 2E 53 30 4D
+90 4A 84 45 4C 53 45 00 1A 42 C4 1D BA 40 BC 41
+00 00 2A 52 82 4A C4 1D 8E 4A 00 00 2A 83 0E 4A
+30 4D 20 45 84 54 48 45 4E 00 9E 42 C4 1D 00 00
+3E 4F 30 4D 5C 4A 85 42 45 47 49 4E 30 40 84 43
+04 4C 85 55 4E 54 49 4C 39 40 C0 41 1A 42 C4 1D
+A2 52 C4 1D 8A 49 00 00 8A 4E 02 00 3E 4F 30 4D
+8A 49 85 41 47 41 49 4E 39 40 BC 41 EF 3F 26 4A
+85 57 48 49 4C 45 87 12 C8 4B 6E 40 2A 40 BE 4A
+86 52 45 50 45 41 54 00 87 12 48 4C 0A 4C 2A 40
+E2 4B 82 44 4F 00 2F 83 8F 4E 00 00 1E 42 C4 1D
+BE 40 CA 41 00 00 2E 53 82 4E C4 1D A2 53 AC 1D
+1A 42 AC 1D 8A 43 00 00 30 4D B6 47 84 4C 4F 4F
+50 00 39 40 EC 41 1A 42 C4 1D A2 52 C4 1D 8A 49
+00 00 8A 4E 02 00 1E 42 AC 1D A2 83 AC 1D 2E 4E
+0E 93 04 24 9E 42 C4 1D 00 00 F5 3F 3E 4F 30 4D
+E4 43 85 2B 4C 4F 4F 50 39 40 DA 41 E4 3F 9C 4C
+85 4C 45 41 56 45 1A 42 C4 1D BA 40 FC 41 00 00
+BA 40 BC 41 02 00 B2 50 06 00 C4 1D A2 53 AC 1D
+2A 52 19 42 AC 1D 89 4A 00 00 30 4D E0 4C 04 4D
+4F 56 45 00 0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24
+08 99 0F 24 06 2C F8 49 00 00 18 53 1A 83 FB 23
+30 4D 08 5A 09 5A 19 83 18 83 E8 49 00 00 1A 83
+FA 23 30 4D 34 40 CA 1D FC 40 2A 40 84 12 44 4D
+22 50 0A 50 72 4C A0 49 F2 4F D2 4C 0E 4D 84 45
+B2 4D E6 4D 22 4C A6 4E 48 41 4C 4B B4 4A 5C 46
+00 00 3A 40 0C 00 39 40 CA 1D 38 40 CC 1D D9 3F
+3A 40 0E 00 39 40 CC 1D 38 40 CA 1D CC 3F 82 43
+CC 1D 30 4D 92 42 CA 1D C8 1D 30 4D 60 4B 09 50
+57 52 5F 53 54 41 54 45 84 12 8E 4B EE 4F 38 57
+9E 4D 08 50 57 52 5F 48 45 52 45 00 92 42 C4 1D
+AE 4D 92 42 C6 1D AC 4D EF 3F 60 4C 09 52 53 54
+5F 53 54 41 54 45 92 42 0C 18 AE 4D 92 42 0E 18
+AC 4D E2 3F CC 4D 08 52 53 54 5F 48 45 52 45 00
+92 42 C4 1D 0C 18 92 42 C6 1D 0E 18 DF 3F B2 40
+4C 4E AE 4E B2 40 8E 44 A4 44 B2 40 D0 44 E4 44
+B2 40 DC 43 EA 43 30 41 50 4C 04 57 49 50 45 00
+39 40 80 FF B9 43 00 00 29 53 39 90 B4 FF FA 23
+B0 12 FE 4D B2 40 38 57 C4 1D B2 40 EE 4F C6 1D
+D7 3F C4 4B 06 28 57 41 52 4D 29 00 1E 42 08 18
+87 12 42 45 05 0D 1B 5B 37 6D 26 45 70 43 42 45
+27 20 46 61 73 74 46 6F 72 74 68 20 56 31 36 30
+20 2E 35 4D 48 7A 20 28 43 29 20 4A 2E 4D 2E 54
+68 6F 6F 72 65 6E 73 20 26 45 34 40 30 FF 84 43
+2A 41 30 43 42 45 0B 62 79 74 65 73 20 66 72 65
+65 20 28 49 1A 4E 04 57 41 52 4D 00 30 40 4C 4E
+16 4C 04 43 4F 4C 44 00 B2 40 04 A5 20 01 B2 40
+88 5A 5C 01 B2 D0 03 00 04 02 B2 40 FC FF 02 02
+B2 C0 03 00 06 02 B2 43 22 02 B2 D3 26 02 B2 43
+42 02 B2 D3 46 02 B2 43 62 02 B2 D3 66 02 F2 43
+26 03 F2 D3 22 03 F2 40 A5 00 61 01 82 43 62 01
+B2 40 11 01 66 01 29 42 B2 40 33 00 64 01 D2 43
+61 01 92 D2 9E 01 08 18 A2 93 08 18 01 24 59 07
+38 40 C2 A2 18 83 FE 23 19 83 FA 23 B2 42 B0 01
+F2 D0 10 00 2A 03 F2 C0 40 00 A2 04 3A 40 BE 4E
+39 40 B4 FF 89 4A 00 00 29 53 FC 23 92 42 02 18
+F0 FF B2 40 18 00 0A 18 31 40 E0 1C 3F 40 80 1C
+37 40 00 40 36 40 B4 40 35 40 08 40 34 40 14 40
+B2 40 0A 00 DA 1D B2 43 DC 1D 92 C3 30 01 18 42
+08 18 D2 B3 01 02 04 20 38 E3 18 53 82 48 08 18
+B2 40 81 00 C0 05 A2 42 C6 05 B2 40 00 49 C8 05
+F2 D0 03 00 0D 02 92 C3 C0 05 92 D3 DA 05 3D 40
+C8 4F 18 42 08 18 38 90 0A 00 32 27 38 90 16 00
+2F 2F 28 93 08 23 F0 26 AC 4E 84 12 44 4D 16 56
+C2 56 CA 55 16 57 90 55 4A 56 94 52 00 00 86 55
+36 56 E8 55 26 56 A4 53 00 00 00 00 28 57 70 4D
+44 4E 85 48 49 32 4C 4F 87 12 84 43 DC 4B A4 47
+AC 4A 72 4D CA 4F 2A 40 B2 4E 04 43 4F 44 45 00
+B0 12 BE 49 A2 82 C4 1D 87 12 EC 4A BC 41 02 50
+42 4C 03 41 53 4D 92 42 C8 1D B8 1D B2 40 CE 4F
+C8 1D EE 3F 00 00 07 45 4E 44 43 4F 44 45 87 12
+80 4D 0C 4A 2A 40 36 50 06 45 4E 44 41 53 4D 00
+92 42 B8 1D C8 1D F3 3F 00 00 05 43 4F 4C 4F 4E
+1A 42 C4 1D BA 40 87 12 00 00 A2 53 C4 1D B2 43
+B6 1D 30 40 80 4D 00 00 05 4C 4F 32 48 49 1A 42
+C4 1D BA 40 B0 12 00 00 BA 40 2A 40 02 00 A2 52
+C4 1D ED 3F 38 40 BE 1D 39 48 2A 48 09 5A 1A 52
+C2 1D 09 9A 03 24 7E 9A FC 27 1A 83 0E 4A 2A 88
+82 4A C2 1D 30 4D B0 12 2A 40 9C 45 F4 45 72 41
+C0 41 CC 50 B0 46 C0 41 B0 49 EE 50 CE 50 29 4E
+39 90 86 12 02 20 2E 53 30 41 39 90 85 12 03 20
+1E 4E 02 00 30 41 39 90 84 12 01 20 2E 52 30 41
+19 42 C4 1D A2 53 C4 1D 89 4E 00 00 3E 40 29 00
+12 12 C2 1D 92 53 C2 1D B0 12 2A 40 9C 45 B0 46
+C0 41 20 51 16 51 21 53 3E 90 10 00 BB 2D 30 41
+22 51 B2 41 C2 1D 22 D3 30 41 87 12 4C 42 94 50
+32 51 82 43 BC 1D 92 42 C4 1D BA 1D A2 53 C4 1D
+0A 4E 3E 4F FA 90 23 00 00 00 34 20 92 53 C2 1D
+B0 12 B6 50 0E 93 04 20 B2 40 00 03 BC 1D 27 3C
+1E 93 04 20 B2 40 10 03 BC 1D 21 3C 2E 93 04 20
+B2 40 20 03 BC 1D 1B 3C 2E 92 04 20 B2 40 20 02
+BC 1D 15 3C 3E 92 04 20 B2 40 30 02 BC 1D 0F 3C
+3E 93 04 20 B2 40 30 03 BC 1D 09 3C B2 40 30 00
+BC 1D 19 42 C4 1D A2 53 C4 1D 89 4E 00 00 3E 4F
+3D 41 30 4D FA 90 26 00 00 00 08 20 B2 40 10 02
+BC 1D 92 53 C2 1D 30 12 A2 51 75 3F FA 90 40 00
+00 00 1A 20 B2 40 20 00 BC 1D 92 53 C2 1D B0 12
+00 51 0E 20 B2 50 10 00 BC 1D 3E 40 2B 00 B0 12
+00 51 32 24 92 92 BE 1D C2 1D 02 24 92 53 C2 1D
+8E 10 82 5E BC 1D D3 3F B0 12 00 51 F9 23 B2 50
+10 00 BC 1D 3E 40 28 00 B0 12 B6 50 30 12 F2 51
+67 3F 87 12 4C 42 94 50 2A 52 FE 90 26 00 00 00
+3E 40 20 00 04 20 B2 50 82 00 BC 1D C2 3F B0 12
+00 51 DF 23 B2 50 80 00 BC 1D 3E 40 28 00 B0 12
+B6 50 B0 12 F0 50 D5 23 3D 40 B0 49 30 4D 00 00
+04 52 45 54 49 00 87 12 34 40 00 13 A4 47 2A 40
+34 40 2C 00 2A 51 22 52 7A 52 2E 4E 1E D2 BC 1D
+19 42 BA 1D 92 3F 78 50 03 4D 4F 56 84 12 70 52
+00 40 88 52 05 4D 4F 56 2E 42 84 12 70 52 40 40
+00 00 03 41 44 44 84 12 70 52 00 50 A2 52 05 41
+44 44 2E 42 84 12 70 52 40 50 AE 52 04 41 44 44
+43 00 84 12 70 52 00 60 BC 52 06 41 44 44 43 2E
+42 00 84 12 70 52 40 60 60 52 04 53 55 42 43 00
+84 12 70 52 00 70 DA 52 06 53 55 42 43 2E 42 00
+84 12 70 52 40 70 E8 52 03 53 55 42 84 12 70 52
+00 80 F8 52 05 53 55 42 2E 42 84 12 70 52 40 80
+5A 50 03 43 4D 50 84 12 70 52 00 90 12 53 05 43
+4D 50 2E 42 84 12 70 52 40 90 48 50 04 44 41 44
+44 00 84 12 70 52 00 A0 2C 53 06 44 41 44 44 2E
+42 00 84 12 70 52 40 A0 1E 53 03 42 49 54 84 12
+70 52 00 B0 4A 53 05 42 49 54 2E 42 84 12 70 52
+40 B0 56 53 03 42 49 43 84 12 70 52 00 C0 64 53
+05 42 49 43 2E 42 84 12 70 52 40 C0 70 53 03 42
+49 53 84 12 70 52 00 D0 7E 53 05 42 49 53 2E 42
+84 12 70 52 40 D0 00 00 03 58 4F 52 84 12 70 52
+00 E0 98 53 05 58 4F 52 2E 42 84 12 70 52 40 E0
+CA 52 03 41 4E 44 84 12 70 52 00 F0 B2 53 05 41
+4E 44 2E 42 84 12 70 52 40 F0 4C 42 2A 51 D0 53
+1A 42 BC 1D B2 F0 70 00 BC 1D 8A 10 3A F0 0F 00
+82 DA BC 1D 4A 3F 04 53 03 52 52 43 84 12 CA 53
+00 10 E8 53 05 52 52 43 2E 42 84 12 CA 53 40 10
+F4 53 04 53 57 50 42 00 84 12 CA 53 80 10 02 54
+03 52 52 41 84 12 CA 53 00 11 10 54 05 52 52 41
+2E 42 84 12 CA 53 40 11 1C 54 03 53 58 54 84 12
+CA 53 80 11 00 00 04 50 55 53 48 00 84 12 CA 53
+00 12 36 54 06 50 55 53 48 2E 42 00 84 12 CA 53
+40 12 8A 53 04 43 41 4C 4C 00 84 12 CA 53 80 12
+34 40 2C 00 2A 51 22 52 6A 54 59 42 BC 1D 5A 42
+BD 1D 82 4A BC 1D BE 90 00 15 00 00 02 20 0A 89
+02 3C 09 8A 0A 49 3A 90 10 00 03 2C 5A 0E A8 3F
+1A 53 0E 4A 87 12 70 43 42 45 0D 6F 75 74 20 6F
+66 20 62 6F 75 6E 64 73 22 49 44 54 05 50 55 53
+48 4D 84 12 60 54 00 15 AC 54 04 50 4F 50 4D 00
+84 12 60 54 00 17 4C 42 94 50 CC 54 82 43 BC 1D
+92 42 C4 1D BA 1D A2 53 C4 1D 92 53 C2 1D 3E 40
+2C 00 B0 12 2A 40 9C 45 B0 46 C0 41 B0 49 22 52
+F2 54 0A 4E 3E 4F 1A 83 2A 92 CA 2F 8A 10 5A 06
+6F 3F 2A 54 04 52 52 43 4D 00 84 12 C6 54 50 00
+04 55 04 52 52 41 4D 00 84 12 C6 54 50 01 12 55
+04 52 4C 41 4D 00 84 12 C6 54 50 02 20 55 04 52
+52 55 4D 00 84 12 C6 54 50 03 85 12 00 3C 2E 55
+03 53 3E 3D 85 12 00 38 40 55 02 53 3C 00 85 12
+00 34 BA 54 03 30 3E 3D 85 12 00 30 54 55 02 30
+3C 00 85 12 00 30 00 00 02 55 3C 00 85 12 00 2C
+68 55 03 55 3E 3D 85 12 00 28 5E 55 03 30 3C 3E
+85 12 00 24 7C 55 02 30 3D 00 85 12 00 20 00 00
+02 49 46 00 1A 42 C4 1D 8A 4E 00 00 A2 53 C4 1D
+0E 4A 30 4D 72 55 04 54 48 45 4E 00 1A 42 C4 1D
+08 4E 3E 4F 09 48 29 53 0A 89 0A 11 3A 90 00 02
+68 2F 88 DA 00 00 30 4D 3A 53 04 45 4C 53 45 00
+1A 42 C4 1D BA 40 00 3C 00 00 A2 53 C4 1D 2F 83
+8F 4A 00 00 E3 3F A6 55 05 55 4E 54 49 4C 3A 4F
+08 4E 3E 4F 19 42 C4 1D 2A 83 0A 89 0A 11 3A 90
+00 FE 47 3B 3A F0 FF 03 08 DA 89 48 00 00 A2 53
+C4 1D 30 4D BE 53 05 41 47 41 49 4E 87 12 3A 55
+EE 55 2A 40 00 00 05 57 48 49 4C 45 87 12 94 55
+6E 40 2A 40 4A 55 06 52 45 50 45 41 54 00 87 12
+3A 55 EE 55 AC 55 2A 40 00 00 03 4A 4D 50 87 12
+A2 49 3A 55 EE 55 2A 40 3E B0 00 10 03 20 3E E0
+00 04 30 4D 3E 90 00 34 06 28 03 24 3E 40 00 34
+30 4D 3E 40 00 38 30 4D 00 00 04 3F 4A 4D 50 00
+87 12 58 56 A2 49 6E 40 EE 55 2A 40 8E 56 3D 41
+08 4E 3E 4F 2A 48 0A 93 04 20 98 42 C4 1D 00 00
+30 4D 88 43 00 00 A4 3F 54 54 03 42 57 31 84 12
+8C 56 00 00 AA 56 03 42 57 32 84 12 8C 56 00 00
+B6 56 03 42 57 33 84 12 8C 56 00 00 CE 56 3D 41
+1A 42 C4 1D 28 4E 08 93 08 20 BA 4F 00 00 A2 53
+C4 1D 8E 4A 00 00 3E 4F 30 4D 8E 43 00 00 61 3F
+00 00 03 46 57 31 84 12 CC 56 00 00 F2 56 03 46
+57 32 84 12 CC 56 00 00 FE 56 03 46 57 33 84 12
+CC 56 00 00 0A 57 04 47 4F 54 4F 00 87 12 3A 55
+A2 49 9A 47 2A 40 7A 56 05 3F 47 4F 54 4F 87 12
+58 56 A2 49 9A 47 2A 40
+@FFB4
+BE 4E BE 4E BE 4E BE 4E BE 4E BE 4E BE 4E BE 4E
+BE 4E BE 4E BE 4E BE 4E BE 4E BE 4E BE 4E BE 4E
+BE 4E BE 4E BE 4E BE 4E BE 4E BE 4E BE 4E BE 4E
+BE 4E BE 4E BE 4E BE 4E BE 4E BE 4E 40 44 BE 4E
+BE 4E BE 4E BE 4E BE 4E BE 4E BE 4E
+q
--- /dev/null
+@1800
+10 00 4C 44 80 3E 00 24 FD FF 18 00 58 57 0E 50
+2A 44 38 44 00 00 00 00
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@4000
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 40
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 40 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 40 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E 40 02 3E 52 00 0E 12 3E 4F 30 4D 8E 40
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 40
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C 40 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 40 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 41
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 40 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA 40 03 41 4E 44 3E FF 30 4D 7A 40 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E 41 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 41 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E 41 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 41 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 40 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE 41 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 41 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 41 03 3E 49 4E 85 12 C2 1D 10 41
+04 42 41 53 45 00 85 12 DA 1D C0 40 05 53 54 41
+54 45 85 12 B6 1D 30 42 02 42 4C 00 85 12 20 00
+94 41 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 42 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E 42 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 42 02 23 53 00 87 12 98 42
+D2 42 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 42 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 42 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C 42 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 41 03 55 44 2E 87 12 56 42
+CC 42 E6 42 32 45 FA 44 2A 40 18 43 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA 40
+02 44 2E 00 87 12 56 42 6E 40 80 40 3A 43 CC 42
+92 40 0A 43 E6 42 32 45 FA 44 2A 40 52 41 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 42 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 41 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 42 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A 44
+92 B3 DC 05 FD 27 1E 42 CC 05 B0 12 38 44 30 4D
+30 40 B6 43 7E 43 05 28 4B 45 59 29 18 42 CC 05
+EA 3F 12 42 03 4B 45 59 30 40 DC 43 92 43 06 41
+43 43 45 50 54 00 3C 40 8A 44 3B 40 54 44 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+7E 44 92 B3 DC 05 05 24 18 42 CC 05 38 90 0A 00
+04 20 21 53 39 40 46 44 4D 15 B2 40 11 00 CE 05
+A2 B3 DC 05 FD 27 30 41 B2 40 13 00 CE 05 A2 B3
+DC 05 FD 27 30 41 12 D2 0A 18 FD 3F 21 52 3A 17
+58 42 CC 05 48 9B F0 27 48 9C 06 2C 78 92 11 20
+2E 9F 0F 24 1E 83 05 3C 0E 9A 03 24 CE 48 00 00
+1E 53 82 48 CE 05 A2 B3 DC 05 FD 27 30 4D 80 44
+2D 83 92 B3 DC 05 FD 27 E3 23 B2 40 18 00 0A 18
+3E 8F 3D 41 30 4D D6 43 06 28 45 4D 49 54 29 00
+08 4E 3E 4F E6 3F 50 43 04 45 4D 49 54 00 30 40
+A0 44 A8 44 04 45 43 48 4F 00 B2 40 82 48 72 44
+30 4D 6E 43 06 4E 4F 45 43 48 4F 00 B2 40 30 4D
+72 44 30 4D 98 44 04 28 43 52 29 00 2F 83 8F 4E
+00 00 3E 40 0D 00 E3 3F A2 43 02 43 52 00 30 40
+DC 44 04 43 05 53 50 41 43 45 2F 83 8F 4E 00 00
+3E 40 20 00 D4 3F F4 44 06 53 50 41 43 45 53 00
+0E 93 09 24 0D 12 3D 40 1C 45 EF 3F 1E 45 2D 83
+1E 83 EB 23 3D 41 3E 4F 30 4D 2C 43 04 54 59 50
+45 00 0E 93 95 24 2A 4F 8F 5E 00 00 0E 4A 87 12
+CA 41 02 42 0A 41 AE 44 EC 41 42 45 2A 40 2F 82
+8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E 1D B3 0D 63
+30 4D 08 45 82 53 22 00 87 12 34 40 4E 45 B0 47
+34 40 22 00 A8 45 78 45 3D 41 6E 4E 1E 83 82 5E
+C4 1D 3E 4F 92 B3 C4 1D A2 63 C4 1D 30 4D C4 44
+82 2E 22 00 87 12 68 45 34 40 32 45 B0 47 2A 40
+00 00 04 57 4F 52 44 00 3C 40 BE 1D 39 4C 3A 4C
+09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A FC 27 1A 83
+3B 40 60 00 C8 4C 00 00 09 9A 0C 24 7C 4A 4E 9C
+09 24 18 53 4B 9C F6 2F 7C 90 7B 00 F3 2F 7C 80
+20 00 F0 3F 1A 82 C0 1D 82 4A C2 1D 1E 42 C4 1D
+08 8E CE 48 00 00 30 4D 00 00 04 46 49 4E 44 00
+2F 83 0C 4E 65 4C 74 40 80 00 3B 40 CA 1D 3E 4B
+0E 93 1E 24 58 4C 01 00 78 F0 1E 00 0E 58 2E 53
+1E 4E FE FF 0E 93 F3 27 09 4E 78 49 48 C4 48 95
+F7 23 0A 4C 1A 53 FA 99 00 00 F2 23 58 83 FA 23
+19 B3 09 63 0C 49 6A 4E 1E 43 4A 93 01 30 2E 83
+8F 4C 00 00 35 40 08 40 34 40 14 40 30 4D 2F 53
+2F 53 3E 4F 30 4D 26 42 07 3E 4E 55 4D 42 45 52
+3C 4F 38 4F 29 4F 2F 82 1B 42 DA 1D 6A 4C 7A 80
+30 00 7A 90 0A 00 02 28 7A 80 07 00 0A 9B 13 2C
+82 49 D0 04 82 48 D2 04 82 4B C8 04 19 42 E4 04
+18 42 E6 04 09 5A 08 63 1C 53 1E 83 E7 23 8F 49
+04 00 8F 48 02 00 8F 4C 00 00 30 4D 03 12 0D 12
+1B 42 DA 1D 0B 12 32 C0 00 02 6D 4E 0D 5E 0C 4E
+7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23 32 D0 00 02
+FC 4C FE FF 0D 9C FC 2F DE 83 00 00 09 43 08 43
+3D 40 32 47 3F 82 8F 4E 06 00 0C 4E 7E 4C 6A 4C
+7A 90 2D 00 10 2C 3B 40 10 00 7A 80 24 00 06 24
+2B 43 5A 83 03 24 3B 52 6A 53 B0 23 1C 53 1E 83
+6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83 B1 43 04 00
+A5 3F 34 47 2F 53 0E 93 2C 17 82 4C DA 1D 03 24
+2F 52 0E F3 30 4D 8F 93 00 00 15 20 32 B0 00 02
+14 20 0E 93 05 24 1A 4F 02 00 1A 83 0A 93 0B 38
+2F 53 BF 4F 00 00 3E E3 05 20 BF E3 00 00 9F 53
+00 00 3E E3 30 4D 32 D0 00 02 9F 4F 02 00 04 00
+BF 4F 00 00 3E E3 F6 23 BF E3 02 00 BF E3 00 00
+9F 53 02 00 8F 63 00 00 3E E3 30 4D B4 44 07 45
+58 45 43 55 54 45 0A 4E 3E 4F 00 4A 28 41 01 2C
+1A 42 C4 1D A2 53 C4 1D 8A 4E 00 00 3E 4F 30 4D
+AE 47 87 4C 49 54 45 52 41 4C 82 93 B6 1D 16 24
+32 B0 00 02 09 24 1A 42 C4 1D A2 52 C4 1D BA 40
+34 40 00 00 BA 4F 02 00 1A 42 C4 1D A2 52 C4 1D
+BA 40 34 40 00 00 8A 4E 02 00 3E 4F 30 4D EA 44
+05 43 4F 55 4E 54 2F 83 1E 53 8F 4E 00 00 5E 4E
+FF FF 30 4D 82 4E BE 1D B2 4F C0 1D 3E 4F 82 43
+C2 1D 87 12 4C 42 A8 45 2A 48 3D 40 36 48 E8 22
+3D 41 3E 4F 30 4D 38 48 0A 4E 3E 4F 3D 40 4E 48
+3D 27 3D 40 24 48 1A E2 B6 1D B2 27 AC 23 50 48
+3E 4F 3D 40 24 48 B9 23 DE 53 00 00 68 4E 08 5E
+F8 40 3F 00 00 00 3D 40 16 4A CD 3F 9E 47 08 45
+56 41 4C 55 41 54 45 00 39 40 BE 1D 39 12 39 12
+39 12 0D 12 B0 12 2A 40 14 48 8C 48 3D 41 B2 41
+C2 1D B2 41 C0 1D B2 41 BE 1D 30 4D 7A 41 04 51
+55 49 54 00 31 40 E0 1C B2 40 00 1C AC 1D 82 43
+B6 1D 82 43 08 18 B0 12 2A 40 4E 45 04 0D 6F 6B
+20 00 32 45 34 40 38 1D 44 40 34 40 50 00 F6 43
+FA 44 14 48 34 40 7E 1C CE 40 B2 41 4E 45 0D 73
+74 61 63 6B 20 65 6D 70 74 79 20 21 28 49 34 40
+30 FF 84 43 B2 41 4E 45 0B 46 52 41 4D 20 66 75
+6C 6C 20 21 28 49 42 42 F4 40 C0 41 BA 48 4E 45
+04 0D 20 20 20 00 BC 41 C2 48 EE 43 05 41 42 4F
+52 54 3F 40 80 1C BE 3F 8F 93 02 00 98 26 B2 40
+82 48 72 44 B0 12 10 4E 82 43 D2 56 82 43 DE 56
+82 43 EA 56 82 43 1A 57 82 43 26 57 82 43 32 57
+A2 B3 DC 05 FD 27 B2 40 11 00 CE 05 92 C3 DC 05
+38 40 A0 AA 39 42 19 83 FE 23 18 83 FB 23 92 B3
+DC 05 F4 23 87 12 4E 45 04 1B 5B 37 6D 00 32 45
+32 45 4E 45 04 1B 5B 30 6D 00 32 45 58 4D 9A 4D
+A0 4D 22 49 1C 49 86 41 42 4F 52 54 22 00 87 12
+68 45 34 40 28 49 B0 47 2A 40 FA 45 01 27 87 12
+4C 42 A8 45 00 46 C0 41 BC 49 2A 40 58 48 52 42
+81 5C 92 42 BE 1D C2 1D 30 4D 87 12 84 45 4C 42
+A8 45 D4 49 08 4E 7A 4E 5A D3 5A 53 0A 58 19 42
+C8 1D 6E 4E 3E F0 1E 00 09 5E 82 48 AE 1D 82 49
+B0 1D 82 4A B2 1D 2A 52 82 4A C4 1D 3E 4F 3D 41
+30 41 87 12 4E 45 0F 73 74 61 63 6B 20 6D 69 73
+6D 61 74 63 68 21 2E 49 82 9F B4 1D F2 23 18 42
+AE 1D 19 42 B0 1D A8 49 FE FF 89 48 00 00 30 4D
+A2 45 08 56 41 52 49 41 42 4C 45 00 B0 12 CA 49
+BA 40 86 12 FC FF EF 3F 00 48 08 43 4F 4E 53 54
+41 4E 54 00 B0 12 CA 49 BA 40 85 12 FC FF 8A 4E
+FE FF 3E 4F E0 3F 4A 4A 06 43 52 45 41 54 45 00
+B0 12 CA 49 BA 40 85 12 FC FF 8A 4A FE FF D3 3F
+6E 48 05 44 4F 45 53 3E 1A 42 B2 1D BA 40 84 12
+00 00 8A 4D 02 00 3D 41 30 4D 82 4A 05 44 45 46
+45 52 B0 12 CA 49 BA 40 30 40 FC FF BA 40 98 4A
+FE FF B9 3F 00 00 81 5B 82 43 B6 1D 30 4D C0 49
+01 5D B2 43 B6 1D 30 4D 64 45 87 52 45 43 55 52
+53 45 19 42 C4 1D 99 42 B2 1D 00 00 A2 53 C4 1D
+30 4D B6 4A 01 3A B0 12 CA 49 BA 40 87 12 FC FF
+A2 83 C4 1D B2 43 B6 1D 82 4F B4 1D 30 4D E4 4A
+81 3B 82 93 B6 1D 5D 27 87 12 34 40 2A 40 B0 47
+18 4A B8 4A 2A 40 D6 44 09 49 4D 4D 45 44 49 41
+54 45 1A 42 AE 1D FA D0 80 00 00 00 30 4D BE 4F
+02 00 3E 4F 30 4D 18 4B 82 49 53 00 87 12 42 42
+F4 40 C0 41 50 4B 5C 4B 34 40 2E 4B B0 47 2A 40
+AE 49 2E 4B 2A 40 00 4B 83 5B 27 5D 87 12 AE 49
+34 40 34 40 B0 47 B0 47 2A 40 9E 48 88 50 4F 53
+54 50 4F 4E 45 00 87 12 4C 42 A8 45 00 46 54 40
+C0 41 BC 49 7E 41 C0 41 96 4B 34 40 34 40 B0 47
+B0 47 34 40 B0 47 B0 47 2A 40 9C 4B 3A 4E 82 4A
+C6 1D 2E 4E 82 4E C4 1D 3D 40 10 00 09 4A 08 49
+29 83 18 48 FE FF 0E 98 FC 2B 89 48 00 00 1D 83
+F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41 30 4D 38 4B
+82 49 46 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40
+C0 41 00 00 A2 52 C4 1D 2E 53 30 4D 9C 4A 84 45
+4C 53 45 00 1A 42 C4 1D BA 40 BC 41 00 00 2A 52
+82 4A C4 1D 8E 4A 00 00 2A 83 0E 4A 30 4D 2C 45
+84 54 48 45 4E 00 9E 42 C4 1D 00 00 3E 4F 30 4D
+68 4A 85 42 45 47 49 4E 30 40 84 43 10 4C 85 55
+4E 54 49 4C 39 40 C0 41 1A 42 C4 1D A2 52 C4 1D
+8A 49 00 00 8A 4E 02 00 3E 4F 30 4D 96 49 85 41
+47 41 49 4E 39 40 BC 41 EF 3F 32 4A 85 57 48 49
+4C 45 87 12 D4 4B 6E 40 2A 40 CA 4A 86 52 45 50
+45 41 54 00 87 12 54 4C 16 4C 2A 40 EE 4B 82 44
+4F 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40 CA 41
+00 00 2E 53 82 4E C4 1D A2 53 AC 1D 1A 42 AC 1D
+8A 43 00 00 30 4D C2 47 84 4C 4F 4F 50 00 39 40
+EC 41 1A 42 C4 1D A2 52 C4 1D 8A 49 00 00 8A 4E
+02 00 1E 42 AC 1D A2 83 AC 1D 2E 4E 0E 93 04 24
+9E 42 C4 1D 00 00 F5 3F 3E 4F 30 4D E4 43 85 2B
+4C 4F 4F 50 39 40 DA 41 E4 3F A8 4C 85 4C 45 41
+56 45 1A 42 C4 1D BA 40 FC 41 00 00 BA 40 BC 41
+02 00 B2 50 06 00 C4 1D A2 53 AC 1D 2A 52 19 42
+AC 1D 89 4A 00 00 30 4D EC 4C 04 4D 4F 56 45 00
+0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24 08 99 0F 24
+06 2C F8 49 00 00 18 53 1A 83 FB 23 30 4D 08 5A
+09 5A 19 83 18 83 E8 49 00 00 1A 83 FA 23 30 4D
+34 40 CA 1D FC 40 2A 40 84 12 50 4D 42 50 2A 50
+7E 4C AC 49 12 50 DE 4C 1A 4D 90 45 BE 4D F2 4D
+2E 4C B2 4E 48 41 58 4B C0 4A 68 46 00 00 3A 40
+0C 00 39 40 CA 1D 38 40 CC 1D D9 3F 3A 40 0E 00
+39 40 CC 1D 38 40 CA 1D CC 3F 82 43 CC 1D 30 4D
+92 42 CA 1D C8 1D 30 4D 6C 4B 09 50 57 52 5F 53
+54 41 54 45 84 12 9A 4B 0E 50 58 57 AA 4D 08 50
+57 52 5F 48 45 52 45 00 92 42 C4 1D BA 4D 92 42
+C6 1D B8 4D EF 3F 6C 4C 09 52 53 54 5F 53 54 41
+54 45 92 42 0C 18 BA 4D 92 42 0E 18 B8 4D E2 3F
+D8 4D 08 52 53 54 5F 48 45 52 45 00 92 42 C4 1D
+0C 18 92 42 C6 1D 0E 18 DF 3F B2 40 58 4E BA 4E
+B2 40 A0 44 B0 44 B2 40 DC 44 F0 44 B2 40 DC 43
+EA 43 30 41 5C 4C 04 57 49 50 45 00 39 40 80 FF
+B9 43 00 00 29 53 39 90 B4 FF FA 23 B0 12 0A 4E
+B2 40 58 57 C4 1D B2 40 0E 50 C6 1D D7 3F D0 4B
+06 28 57 41 52 4D 29 00 1E 42 08 18 87 12 4E 45
+05 0D 1B 5B 37 6D 32 45 70 43 4E 45 27 20 46 61
+73 74 46 6F 72 74 68 20 56 31 36 30 20 31 36 4D
+48 7A 20 28 43 29 20 4A 2E 4D 2E 54 68 6F 6F 72
+65 6E 73 20 32 45 34 40 30 FF 84 43 2A 41 30 43
+4E 45 0B 62 79 74 65 73 20 66 72 65 65 20 34 49
+26 4E 04 57 41 52 4D 00 30 40 58 4E 22 4C 04 43
+4F 4C 44 00 B2 40 04 A5 20 01 B2 40 88 5A 5C 01
+B2 D0 03 00 04 02 B2 40 FC FF 02 02 B2 C0 03 00
+06 02 B2 43 22 02 B2 D3 26 02 B2 43 42 02 B2 D3
+46 02 B2 43 62 02 B2 D3 66 02 F2 43 26 03 F2 D3
+22 03 F2 40 A5 00 41 01 F2 40 10 00 40 01 D2 43
+41 01 F2 40 A5 00 61 01 B2 40 48 00 62 01 82 43
+66 01 39 40 80 00 B2 40 33 00 64 01 D2 43 61 01
+92 D2 9E 01 08 18 A2 93 08 18 01 24 59 07 38 40
+C2 A2 18 83 FE 23 19 83 FA 23 B2 42 B0 01 F2 D0
+10 00 2A 03 F2 C0 40 00 A2 04 3A 40 CA 4E 39 40
+B4 FF 89 4A 00 00 29 53 FC 23 92 42 02 18 F0 FF
+B2 40 18 00 0A 18 31 40 E0 1C 3F 40 80 1C 37 40
+00 40 36 40 B4 40 35 40 08 40 34 40 14 40 B2 40
+0A 00 DA 1D B2 43 DC 1D 92 C3 30 01 18 42 08 18
+D2 B3 01 02 04 20 38 E3 18 53 82 48 08 18 B2 40
+81 00 C0 05 B2 40 11 00 C6 05 B2 40 00 4A C8 05
+F2 D0 03 00 0D 02 92 C3 C0 05 92 D3 DA 05 3D 40
+E8 4F 18 42 08 18 38 90 0A 00 28 27 38 90 16 00
+25 2F 28 93 FE 22 E6 26 B8 4E 84 12 50 4D 36 56
+E2 56 EA 55 36 57 B0 55 6A 56 B4 52 00 00 A6 55
+56 56 08 56 46 56 C4 53 00 00 00 00 48 57 7C 4D
+50 4E 85 48 49 32 4C 4F 87 12 84 43 E8 4B B0 47
+B8 4A 7E 4D EA 4F 2A 40 BE 4E 04 43 4F 44 45 00
+B0 12 CA 49 A2 82 C4 1D 87 12 F8 4A BC 41 22 50
+4E 4C 03 41 53 4D 92 42 C8 1D B8 1D B2 40 EE 4F
+C8 1D EE 3F 00 00 07 45 4E 44 43 4F 44 45 87 12
+8C 4D 18 4A 2A 40 56 50 06 45 4E 44 41 53 4D 00
+92 42 B8 1D C8 1D F3 3F 00 00 05 43 4F 4C 4F 4E
+1A 42 C4 1D BA 40 87 12 00 00 A2 53 C4 1D B2 43
+B6 1D 30 40 8C 4D 00 00 05 4C 4F 32 48 49 1A 42
+C4 1D BA 40 B0 12 00 00 BA 40 2A 40 02 00 A2 52
+C4 1D ED 3F 38 40 BE 1D 39 48 2A 48 09 5A 1A 52
+C2 1D 09 9A 03 24 7E 9A FC 27 1A 83 0E 4A 2A 88
+82 4A C2 1D 30 4D B0 12 2A 40 A8 45 00 46 72 41
+C0 41 EC 50 BC 46 C0 41 BC 49 0E 51 EE 50 29 4E
+39 90 86 12 02 20 2E 53 30 41 39 90 85 12 03 20
+1E 4E 02 00 30 41 39 90 84 12 01 20 2E 52 30 41
+19 42 C4 1D A2 53 C4 1D 89 4E 00 00 3E 40 29 00
+12 12 C2 1D 92 53 C2 1D B0 12 2A 40 A8 45 BC 46
+C0 41 40 51 36 51 21 53 3E 90 10 00 BB 2D 30 41
+42 51 B2 41 C2 1D 22 D3 30 41 87 12 4C 42 B4 50
+52 51 82 43 BC 1D 92 42 C4 1D BA 1D A2 53 C4 1D
+0A 4E 3E 4F FA 90 23 00 00 00 34 20 92 53 C2 1D
+B0 12 D6 50 0E 93 04 20 B2 40 00 03 BC 1D 27 3C
+1E 93 04 20 B2 40 10 03 BC 1D 21 3C 2E 93 04 20
+B2 40 20 03 BC 1D 1B 3C 2E 92 04 20 B2 40 20 02
+BC 1D 15 3C 3E 92 04 20 B2 40 30 02 BC 1D 0F 3C
+3E 93 04 20 B2 40 30 03 BC 1D 09 3C B2 40 30 00
+BC 1D 19 42 C4 1D A2 53 C4 1D 89 4E 00 00 3E 4F
+3D 41 30 4D FA 90 26 00 00 00 08 20 B2 40 10 02
+BC 1D 92 53 C2 1D 30 12 C2 51 75 3F FA 90 40 00
+00 00 1A 20 B2 40 20 00 BC 1D 92 53 C2 1D B0 12
+20 51 0E 20 B2 50 10 00 BC 1D 3E 40 2B 00 B0 12
+20 51 32 24 92 92 BE 1D C2 1D 02 24 92 53 C2 1D
+8E 10 82 5E BC 1D D3 3F B0 12 20 51 F9 23 B2 50
+10 00 BC 1D 3E 40 28 00 B0 12 D6 50 30 12 12 52
+67 3F 87 12 4C 42 B4 50 4A 52 FE 90 26 00 00 00
+3E 40 20 00 04 20 B2 50 82 00 BC 1D C2 3F B0 12
+20 51 DF 23 B2 50 80 00 BC 1D 3E 40 28 00 B0 12
+D6 50 B0 12 10 51 D5 23 3D 40 BC 49 30 4D 00 00
+04 52 45 54 49 00 87 12 34 40 00 13 B0 47 2A 40
+34 40 2C 00 4A 51 42 52 9A 52 2E 4E 1E D2 BC 1D
+19 42 BA 1D 92 3F 98 50 03 4D 4F 56 84 12 90 52
+00 40 A8 52 05 4D 4F 56 2E 42 84 12 90 52 40 40
+00 00 03 41 44 44 84 12 90 52 00 50 C2 52 05 41
+44 44 2E 42 84 12 90 52 40 50 CE 52 04 41 44 44
+43 00 84 12 90 52 00 60 DC 52 06 41 44 44 43 2E
+42 00 84 12 90 52 40 60 80 52 04 53 55 42 43 00
+84 12 90 52 00 70 FA 52 06 53 55 42 43 2E 42 00
+84 12 90 52 40 70 08 53 03 53 55 42 84 12 90 52
+00 80 18 53 05 53 55 42 2E 42 84 12 90 52 40 80
+7A 50 03 43 4D 50 84 12 90 52 00 90 32 53 05 43
+4D 50 2E 42 84 12 90 52 40 90 68 50 04 44 41 44
+44 00 84 12 90 52 00 A0 4C 53 06 44 41 44 44 2E
+42 00 84 12 90 52 40 A0 3E 53 03 42 49 54 84 12
+90 52 00 B0 6A 53 05 42 49 54 2E 42 84 12 90 52
+40 B0 76 53 03 42 49 43 84 12 90 52 00 C0 84 53
+05 42 49 43 2E 42 84 12 90 52 40 C0 90 53 03 42
+49 53 84 12 90 52 00 D0 9E 53 05 42 49 53 2E 42
+84 12 90 52 40 D0 00 00 03 58 4F 52 84 12 90 52
+00 E0 B8 53 05 58 4F 52 2E 42 84 12 90 52 40 E0
+EA 52 03 41 4E 44 84 12 90 52 00 F0 D2 53 05 41
+4E 44 2E 42 84 12 90 52 40 F0 4C 42 4A 51 F0 53
+1A 42 BC 1D B2 F0 70 00 BC 1D 8A 10 3A F0 0F 00
+82 DA BC 1D 4A 3F 24 53 03 52 52 43 84 12 EA 53
+00 10 08 54 05 52 52 43 2E 42 84 12 EA 53 40 10
+14 54 04 53 57 50 42 00 84 12 EA 53 80 10 22 54
+03 52 52 41 84 12 EA 53 00 11 30 54 05 52 52 41
+2E 42 84 12 EA 53 40 11 3C 54 03 53 58 54 84 12
+EA 53 80 11 00 00 04 50 55 53 48 00 84 12 EA 53
+00 12 56 54 06 50 55 53 48 2E 42 00 84 12 EA 53
+40 12 AA 53 04 43 41 4C 4C 00 84 12 EA 53 80 12
+34 40 2C 00 4A 51 42 52 8A 54 59 42 BC 1D 5A 42
+BD 1D 82 4A BC 1D BE 90 00 15 00 00 02 20 0A 89
+02 3C 09 8A 0A 49 3A 90 10 00 03 2C 5A 0E A8 3F
+1A 53 0E 4A 87 12 70 43 4E 45 0D 6F 75 74 20 6F
+66 20 62 6F 75 6E 64 73 2E 49 64 54 05 50 55 53
+48 4D 84 12 80 54 00 15 CC 54 04 50 4F 50 4D 00
+84 12 80 54 00 17 4C 42 B4 50 EC 54 82 43 BC 1D
+92 42 C4 1D BA 1D A2 53 C4 1D 92 53 C2 1D 3E 40
+2C 00 B0 12 2A 40 A8 45 BC 46 C0 41 BC 49 42 52
+12 55 0A 4E 3E 4F 1A 83 2A 92 CA 2F 8A 10 5A 06
+6F 3F 4A 54 04 52 52 43 4D 00 84 12 E6 54 50 00
+24 55 04 52 52 41 4D 00 84 12 E6 54 50 01 32 55
+04 52 4C 41 4D 00 84 12 E6 54 50 02 40 55 04 52
+52 55 4D 00 84 12 E6 54 50 03 85 12 00 3C 4E 55
+03 53 3E 3D 85 12 00 38 60 55 02 53 3C 00 85 12
+00 34 DA 54 03 30 3E 3D 85 12 00 30 74 55 02 30
+3C 00 85 12 00 30 00 00 02 55 3C 00 85 12 00 2C
+88 55 03 55 3E 3D 85 12 00 28 7E 55 03 30 3C 3E
+85 12 00 24 9C 55 02 30 3D 00 85 12 00 20 00 00
+02 49 46 00 1A 42 C4 1D 8A 4E 00 00 A2 53 C4 1D
+0E 4A 30 4D 92 55 04 54 48 45 4E 00 1A 42 C4 1D
+08 4E 3E 4F 09 48 29 53 0A 89 0A 11 3A 90 00 02
+68 2F 88 DA 00 00 30 4D 5A 53 04 45 4C 53 45 00
+1A 42 C4 1D BA 40 00 3C 00 00 A2 53 C4 1D 2F 83
+8F 4A 00 00 E3 3F C6 55 05 55 4E 54 49 4C 3A 4F
+08 4E 3E 4F 19 42 C4 1D 2A 83 0A 89 0A 11 3A 90
+00 FE 47 3B 3A F0 FF 03 08 DA 89 48 00 00 A2 53
+C4 1D 30 4D DE 53 05 41 47 41 49 4E 87 12 5A 55
+0E 56 2A 40 00 00 05 57 48 49 4C 45 87 12 B4 55
+6E 40 2A 40 6A 55 06 52 45 50 45 41 54 00 87 12
+5A 55 0E 56 CC 55 2A 40 00 00 03 4A 4D 50 87 12
+AE 49 5A 55 0E 56 2A 40 3E B0 00 10 03 20 3E E0
+00 04 30 4D 3E 90 00 34 06 28 03 24 3E 40 00 34
+30 4D 3E 40 00 38 30 4D 00 00 04 3F 4A 4D 50 00
+87 12 78 56 AE 49 6E 40 0E 56 2A 40 AE 56 3D 41
+08 4E 3E 4F 2A 48 0A 93 04 20 98 42 C4 1D 00 00
+30 4D 88 43 00 00 A4 3F 74 54 03 42 57 31 84 12
+AC 56 00 00 CA 56 03 42 57 32 84 12 AC 56 00 00
+D6 56 03 42 57 33 84 12 AC 56 00 00 EE 56 3D 41
+1A 42 C4 1D 28 4E 08 93 08 20 BA 4F 00 00 A2 53
+C4 1D 8E 4A 00 00 3E 4F 30 4D 8E 43 00 00 61 3F
+00 00 03 46 57 31 84 12 EC 56 00 00 12 57 03 46
+57 32 84 12 EC 56 00 00 1E 57 03 46 57 33 84 12
+EC 56 00 00 2A 57 04 47 4F 54 4F 00 87 12 5A 55
+AE 49 A6 47 2A 40 9A 56 05 3F 47 4F 54 4F 87 12
+78 56 AE 49 A6 47 2A 40
+@FFB4
+CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E
+CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E
+CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E
+CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E 4C 44 CA 4E
+CA 4E CA 4E CA 4E CA 4E CA 4E CA 4E
+q
--- /dev/null
+@1800
+10 00 C8 44 80 3E 00 24 FD FF 18 00 E6 62 EE 51
+A6 44 B4 44 E8 59 26 5A
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@2000
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+@4000
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 40
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 40 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 40 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E 40 02 3E 52 00 0E 12 3E 4F 30 4D 8E 40
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 40
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C 40 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 40 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 41
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 40 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA 40 03 41 4E 44 3E FF 30 4D 7A 40 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E 41 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 41 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E 41 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 41 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 40 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE 41 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 41 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 41 03 3E 49 4E 85 12 C2 1D 10 41
+04 42 41 53 45 00 85 12 DA 1D C0 40 05 53 54 41
+54 45 85 12 B6 1D 30 42 02 42 4C 00 85 12 20 00
+94 41 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 42 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E 42 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 42 02 23 53 00 87 12 98 42
+D2 42 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 42 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 42 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C 42 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 41 03 55 44 2E 87 12 56 42
+CC 42 E6 42 AE 45 76 45 2A 40 18 43 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA 40
+02 44 2E 00 87 12 56 42 6E 40 80 40 3A 43 CC 42
+92 40 0A 43 E6 42 AE 45 76 45 2A 40 52 41 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 42 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 41 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 42 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 A6 44
+92 B3 DC 05 FD 27 1E 42 CC 05 B0 12 B4 44 30 4D
+30 40 B6 43 7E 43 05 28 4B 45 59 29 18 42 CC 05
+EA 3F 12 42 03 4B 45 59 30 40 DC 43 0D 12 3D 40
+12 44 1B 42 36 20 9B 42 1E 20 16 00 3A 40 00 21
+8F 4A 02 00 BF 40 50 00 00 00 0E 43 19 42 1E 20
+02 3C 14 44 2D 83 19 92 20 20 16 2C 58 49 00 1E
+19 53 78 90 20 00 08 2C 78 90 0A 00 F4 23 82 49
+1E 20 2F 53 3D 41 30 4D 8F 9E 00 00 58 24 CA 48
+00 00 1A 53 1E 53 53 3C 0A 12 B0 12 52 5B 3A 41
+82 93 20 20 DB 23 ED 3F 92 43 06 41 43 43 45 50
+54 00 30 40 72 44 D6 43 08 28 41 43 43 45 50 54
+29 00 3C 40 06 45 3B 40 D0 44 2D 15 0A 4E 2E 4F
+0A 5E 3B 40 0D 00 3C 40 20 00 3D 40 FA 44 92 B3
+DC 05 05 24 18 42 CC 05 38 90 0A 00 04 20 21 53
+39 40 C2 44 4D 15 B2 40 11 00 CE 05 A2 B3 DC 05
+FD 27 30 41 B2 40 13 00 CE 05 A2 B3 DC 05 FD 27
+30 41 12 D2 0A 18 FD 3F 21 52 3A 17 58 42 CC 05
+48 9B F0 27 48 9C 06 2C 78 92 11 20 2E 9F 0F 24
+1E 83 05 3C 0E 9A 03 24 CE 48 00 00 1E 53 82 48
+CE 05 A2 B3 DC 05 FD 27 30 4D FC 44 2D 83 92 B3
+DC 05 FD 27 E3 23 B2 40 18 00 0A 18 3E 8F 3D 41
+30 4D 68 44 06 28 45 4D 49 54 29 00 08 4E 3E 4F
+E6 3F 50 43 04 45 4D 49 54 00 30 40 1C 45 24 45
+04 45 43 48 4F 00 B2 40 82 48 EE 44 30 4D 6E 43
+06 4E 4F 45 43 48 4F 00 B2 40 30 4D EE 44 30 4D
+14 45 04 28 43 52 29 00 2F 83 8F 4E 00 00 3E 40
+0D 00 E3 3F A2 43 02 43 52 00 30 40 58 45 04 43
+05 53 50 41 43 45 2F 83 8F 4E 00 00 3E 40 20 00
+D4 3F 70 45 06 53 50 41 43 45 53 00 0E 93 09 24
+0D 12 3D 40 98 45 EF 3F 9A 45 2D 83 1E 83 EB 23
+3D 41 3E 4F 30 4D 2C 43 04 54 59 50 45 00 0E 93
+95 24 2A 4F 8F 5E 00 00 0E 4A 87 12 CA 41 02 42
+0A 41 2A 45 EC 41 BE 45 2A 40 2F 82 8F 4E 02 00
+7E 4D 8F 4D 00 00 0D 5E 1D B3 0D 63 30 4D 84 45
+82 53 22 00 87 12 34 40 CA 45 2C 48 34 40 22 00
+24 46 F4 45 3D 41 6E 4E 1E 83 82 5E C4 1D 3E 4F
+92 B3 C4 1D A2 63 C4 1D 30 4D 40 45 82 2E 22 00
+87 12 E4 45 34 40 AE 45 2C 48 2A 40 00 00 04 57
+4F 52 44 00 3C 40 BE 1D 39 4C 3A 4C 09 5A 3A 5C
+28 4C 09 9A 19 24 7E 9A FC 27 1A 83 3B 40 60 00
+C8 4C 00 00 09 9A 0C 24 7C 4A 4E 9C 09 24 18 53
+4B 9C F6 2F 7C 90 7B 00 F3 2F 7C 80 20 00 F0 3F
+1A 82 C0 1D 82 4A C2 1D 1E 42 C4 1D 08 8E CE 48
+00 00 30 4D 00 00 04 46 49 4E 44 00 2F 83 0C 4E
+65 4C 74 40 80 00 3B 40 CA 1D 3E 4B 0E 93 1E 24
+58 4C 01 00 78 F0 1E 00 0E 58 2E 53 1E 4E FE FF
+0E 93 F3 27 09 4E 78 49 48 C4 48 95 F7 23 0A 4C
+1A 53 FA 99 00 00 F2 23 58 83 FA 23 19 B3 09 63
+0C 49 6A 4E 1E 43 4A 93 01 30 2E 83 8F 4C 00 00
+35 40 08 40 34 40 14 40 30 4D 2F 53 2F 53 3E 4F
+30 4D 26 42 07 3E 4E 55 4D 42 45 52 3C 4F 38 4F
+29 4F 2F 82 1B 42 DA 1D 6A 4C 7A 80 30 00 7A 90
+0A 00 02 28 7A 80 07 00 0A 9B 13 2C 82 49 D0 04
+82 48 D2 04 82 4B C8 04 19 42 E4 04 18 42 E6 04
+09 5A 08 63 1C 53 1E 83 E7 23 8F 49 04 00 8F 48
+02 00 8F 4C 00 00 30 4D 03 12 0D 12 1B 42 DA 1D
+0B 12 32 C0 00 02 6D 4E 0D 5E 0C 4E 7A 40 2E 00
+0D 9C 0A 28 7A 9C FC 23 32 D0 00 02 FC 4C FE FF
+0D 9C FC 2F DE 83 00 00 09 43 08 43 3D 40 AE 47
+3F 82 8F 4E 06 00 0C 4E 7E 4C 6A 4C 7A 90 2D 00
+10 2C 3B 40 10 00 7A 80 24 00 06 24 2B 43 5A 83
+03 24 3B 52 6A 53 B0 23 1C 53 1E 83 6A 4C 7A 90
+2D 00 AA 23 1C 53 1E 83 B1 43 04 00 A5 3F B0 47
+2F 53 0E 93 2C 17 82 4C DA 1D 03 24 2F 52 0E F3
+30 4D 8F 93 00 00 15 20 32 B0 00 02 14 20 0E 93
+05 24 1A 4F 02 00 1A 83 0A 93 0B 38 2F 53 BF 4F
+00 00 3E E3 05 20 BF E3 00 00 9F 53 00 00 3E E3
+30 4D 32 D0 00 02 9F 4F 02 00 04 00 BF 4F 00 00
+3E E3 F6 23 BF E3 02 00 BF E3 00 00 9F 53 02 00
+8F 63 00 00 3E E3 30 4D 30 45 07 45 58 45 43 55
+54 45 0A 4E 3E 4F 00 4A 28 41 01 2C 1A 42 C4 1D
+A2 53 C4 1D 8A 4E 00 00 3E 4F 30 4D 2A 48 87 4C
+49 54 45 52 41 4C 82 93 B6 1D 16 24 32 B0 00 02
+09 24 1A 42 C4 1D A2 52 C4 1D BA 40 34 40 00 00
+BA 4F 02 00 1A 42 C4 1D A2 52 C4 1D BA 40 34 40
+00 00 8A 4E 02 00 3E 4F 30 4D 66 45 05 43 4F 55
+4E 54 2F 83 1E 53 8F 4E 00 00 5E 4E FF FF 30 4D
+82 4E BE 1D B2 4F C0 1D 3E 4F 82 43 C2 1D 87 12
+4C 42 24 46 A6 48 3D 40 B2 48 E8 22 3D 41 3E 4F
+30 4D B4 48 0A 4E 3E 4F 3D 40 CA 48 3D 27 3D 40
+A0 48 1A E2 B6 1D B2 27 AC 23 CC 48 3E 4F 3D 40
+A0 48 B9 23 DE 53 00 00 68 4E 08 5E F8 40 3F 00
+00 00 3D 40 A2 4A CD 3F 1A 48 08 45 56 41 4C 55
+41 54 45 00 39 40 BE 1D 39 12 39 12 39 12 0D 12
+B0 12 2A 40 90 48 08 49 3D 41 B2 41 C2 1D B2 41
+C0 1D B2 41 BE 1D 30 4D 7A 41 04 51 55 49 54 00
+31 40 E0 1C B2 40 00 1C AC 1D 82 43 B6 1D 82 43
+08 18 B0 12 2A 40 CA 45 04 0D 6F 6B 20 00 AE 45
+34 40 38 1D 44 40 34 40 50 00 62 44 76 45 90 48
+34 40 7E 1C CE 40 B2 41 CA 45 0D 73 74 61 63 6B
+20 65 6D 70 74 79 20 21 A4 49 34 40 30 FF 84 43
+B2 41 CA 45 0B 46 52 41 4D 20 66 75 6C 6C 20 21
+A4 49 42 42 F4 40 C0 41 36 49 CA 45 04 0D 20 20
+20 00 BC 41 3E 49 5A 44 05 41 42 4F 52 54 3F 40
+80 1C BE 3F 8F 93 02 00 98 26 B2 40 82 48 EE 44
+1B 42 36 20 0B 93 04 24 CB 43 02 00 2B 4B FA 3F
+B0 12 9C 4E 82 43 B2 58 82 43 BE 58 82 43 CA 58
+82 43 FA 58 82 43 06 59 82 43 12 59 A2 B3 DC 05
+FD 27 B2 40 11 00 CE 05 92 C3 DC 05 38 40 A0 AA
+39 42 19 83 FE 23 18 83 FB 23 92 B3 DC 05 F4 23
+87 12 CA 45 04 1B 5B 37 6D 00 AE 45 AE 45 CA 45
+04 1B 5B 30 6D 00 AE 45 E4 4D 26 4E 2C 4E 9E 49
+98 49 86 41 42 4F 52 54 22 00 87 12 E4 45 34 40
+A4 49 2C 48 2A 40 76 46 01 27 87 12 4C 42 24 46
+7C 46 C0 41 48 4A 2A 40 D4 48 52 42 81 5C 92 42
+BE 1D C2 1D 30 4D 87 12 00 46 4C 42 24 46 60 4A
+08 4E 7A 4E 5A D3 5A 53 0A 58 19 42 C8 1D 6E 4E
+3E F0 1E 00 09 5E 82 48 AE 1D 82 49 B0 1D 82 4A
+B2 1D 2A 52 82 4A C4 1D 3E 4F 3D 41 30 41 87 12
+CA 45 0F 73 74 61 63 6B 20 6D 69 73 6D 61 74 63
+68 21 AA 49 82 9F B4 1D F2 23 18 42 AE 1D 19 42
+B0 1D A8 49 FE FF 89 48 00 00 30 4D 1E 46 08 56
+41 52 49 41 42 4C 45 00 B0 12 56 4A BA 40 86 12
+FC FF EF 3F 7C 48 08 43 4F 4E 53 54 41 4E 54 00
+B0 12 56 4A BA 40 85 12 FC FF 8A 4E FE FF 3E 4F
+E0 3F D6 4A 06 43 52 45 41 54 45 00 B0 12 56 4A
+BA 40 85 12 FC FF 8A 4A FE FF D3 3F EA 48 05 44
+4F 45 53 3E 1A 42 B2 1D BA 40 84 12 00 00 8A 4D
+02 00 3D 41 30 4D 0E 4B 05 44 45 46 45 52 B0 12
+56 4A BA 40 30 40 FC FF BA 40 24 4B FE FF B9 3F
+00 00 81 5B 82 43 B6 1D 30 4D 4C 4A 01 5D B2 43
+B6 1D 30 4D E0 45 87 52 45 43 55 52 53 45 19 42
+C4 1D 99 42 B2 1D 00 00 A2 53 C4 1D 30 4D 42 4B
+01 3A B0 12 56 4A BA 40 87 12 FC FF A2 83 C4 1D
+B2 43 B6 1D 82 4F B4 1D 30 4D 70 4B 81 3B 82 93
+B6 1D 5D 27 87 12 34 40 2A 40 2C 48 A4 4A 44 4B
+2A 40 52 45 09 49 4D 4D 45 44 49 41 54 45 1A 42
+AE 1D FA D0 80 00 00 00 30 4D BE 4F 02 00 3E 4F
+30 4D A4 4B 82 49 53 00 87 12 42 42 F4 40 C0 41
+DC 4B E8 4B 34 40 BA 4B 2C 48 2A 40 3A 4A BA 4B
+2A 40 8C 4B 83 5B 27 5D 87 12 3A 4A 34 40 34 40
+2C 48 2C 48 2A 40 1A 49 88 50 4F 53 54 50 4F 4E
+45 00 87 12 4C 42 24 46 7C 46 54 40 C0 41 48 4A
+7E 41 C0 41 22 4C 34 40 34 40 2C 48 2C 48 34 40
+2C 48 2C 48 2A 40 28 4C 3A 4E 82 4A C6 1D 2E 4E
+82 4E C4 1D 3D 40 10 00 09 4A 08 49 29 83 18 48
+FE FF 0E 98 FC 2B 89 48 00 00 1D 83 F6 23 2A 4A
+0A 93 F0 23 3E 4F 3D 41 30 4D C4 4B 82 49 46 00
+2F 83 8F 4E 00 00 1E 42 C4 1D BE 40 C0 41 00 00
+A2 52 C4 1D 2E 53 30 4D 28 4B 84 45 4C 53 45 00
+1A 42 C4 1D BA 40 BC 41 00 00 2A 52 82 4A C4 1D
+8E 4A 00 00 2A 83 0E 4A 30 4D A8 45 84 54 48 45
+4E 00 9E 42 C4 1D 00 00 3E 4F 30 4D F4 4A 85 42
+45 47 49 4E 30 40 84 43 9C 4C 85 55 4E 54 49 4C
+39 40 C0 41 1A 42 C4 1D A2 52 C4 1D 8A 49 00 00
+8A 4E 02 00 3E 4F 30 4D 22 4A 85 41 47 41 49 4E
+39 40 BC 41 EF 3F BE 4A 85 57 48 49 4C 45 87 12
+60 4C 6E 40 2A 40 56 4B 86 52 45 50 45 41 54 00
+87 12 E0 4C A2 4C 2A 40 7A 4C 82 44 4F 00 2F 83
+8F 4E 00 00 1E 42 C4 1D BE 40 CA 41 00 00 2E 53
+82 4E C4 1D A2 53 AC 1D 1A 42 AC 1D 8A 43 00 00
+30 4D 3E 48 84 4C 4F 4F 50 00 39 40 EC 41 1A 42
+C4 1D A2 52 C4 1D 8A 49 00 00 8A 4E 02 00 1E 42
+AC 1D A2 83 AC 1D 2E 4E 0E 93 04 24 9E 42 C4 1D
+00 00 F5 3F 3E 4F 30 4D E4 43 85 2B 4C 4F 4F 50
+39 40 DA 41 E4 3F 34 4D 85 4C 45 41 56 45 1A 42
+C4 1D BA 40 FC 41 00 00 BA 40 BC 41 02 00 B2 50
+06 00 C4 1D A2 53 AC 1D 2A 52 19 42 AC 1D 89 4A
+00 00 30 4D 78 4D 04 4D 4F 56 45 00 0A 4E 38 4F
+39 4F 3E 4F 0A 93 11 24 08 99 0F 24 06 2C F8 49
+00 00 18 53 1A 83 FB 23 30 4D 08 5A 09 5A 19 83
+18 83 E8 49 00 00 1A 83 FA 23 30 4D 34 40 CA 1D
+FC 40 2A 40 84 12 DC 4D 22 52 06 5D FA 5C 38 4A
+F2 51 6A 4D 14 5D 0C 46 4A 4E 98 61 80 62 8A 61
+48 41 E4 4B 4C 4B E4 46 00 00 3A 40 0C 00 39 40
+CA 1D 38 40 CC 1D D9 3F 3A 40 0E 00 39 40 CC 1D
+38 40 CA 1D CC 3F 82 43 CC 1D 30 4D 92 42 CA 1D
+C8 1D 30 4D F8 4B 09 50 57 52 5F 53 54 41 54 45
+84 12 26 4C EE 51 E6 62 36 4E 08 50 57 52 5F 48
+45 52 45 00 92 42 C4 1D 46 4E 92 42 C6 1D 44 4E
+EF 3F F8 4C 09 52 53 54 5F 53 54 41 54 45 92 42
+0C 18 46 4E 92 42 0E 18 44 4E E2 3F 64 4E 08 52
+53 54 5F 48 45 52 45 00 92 42 C4 1D 0C 18 92 42
+C6 1D 0E 18 DF 3F B2 40 EA 4E 4C 4F B2 40 1C 45
+2C 45 B2 40 58 45 6C 45 B2 40 DC 43 EA 43 B2 40
+72 44 64 44 30 41 E8 4C 04 57 49 50 45 00 39 40
+80 FF B9 43 00 00 29 53 39 90 B4 FF FA 23 B0 12
+96 4E B2 40 E6 62 C4 1D B2 40 EE 51 C6 1D D4 3F
+5C 4C 06 28 57 41 52 4D 29 00 1E 42 08 18 87 12
+CA 45 05 0D 1B 5B 37 6D AE 45 70 43 CA 45 27 20
+46 61 73 74 46 6F 72 74 68 20 56 31 36 30 20 31
+36 4D 48 7A 20 28 43 29 20 4A 2E 4D 2E 54 68 6F
+6F 72 65 6E 73 20 AE 45 34 40 30 FF 84 43 2A 41
+30 43 CA 45 0B 62 79 74 65 73 20 66 72 65 65 20
+C0 49 B8 4E 04 57 41 52 4D 00 30 40 EA 4E AE 4C
+04 43 4F 4C 44 00 B2 40 04 A5 20 01 B2 40 88 5A
+5C 01 B2 D0 03 00 04 02 B2 40 FC FF 02 02 B2 C0
+03 00 06 02 B2 43 22 02 B2 D3 26 02 B2 43 42 02
+B2 D3 46 02 B2 43 62 02 B2 D3 66 02 F2 43 26 03
+F2 D3 22 03 F2 40 A5 00 41 01 F2 40 10 00 40 01
+D2 43 41 01 F2 40 A5 00 61 01 B2 40 48 00 62 01
+82 43 66 01 39 40 80 00 B2 40 33 00 64 01 D2 43
+61 01 92 D2 9E 01 08 18 A2 93 08 18 01 24 59 07
+38 40 C2 A2 18 83 FE 23 19 83 FA 23 B2 42 B0 01
+F2 D0 10 00 2A 03 F2 C0 40 00 A2 04 3A 40 5C 4F
+39 40 B4 FF 89 4A 00 00 29 53 FC 23 92 42 02 18
+F0 FF B2 40 18 00 0A 18 31 40 E0 1C 3F 40 80 1C
+37 40 00 40 36 40 B4 40 35 40 08 40 34 40 14 40
+B2 40 0A 00 DA 1D B2 43 DC 1D 92 C3 30 01 18 42
+08 18 D2 B3 01 02 04 20 38 E3 18 53 82 48 08 18
+B2 40 81 00 C0 05 B2 40 11 00 C6 05 B2 40 00 4A
+C8 05 F2 D0 03 00 0D 02 92 C3 C0 05 92 D3 DA 05
+3D 40 7A 50 18 42 08 18 38 90 0A 00 28 27 38 90
+16 00 25 2F 28 93 FB 22 E3 26 7C 50 E2 B2 60 02
+64 23 B2 40 81 A9 40 06 B2 40 30 00 46 06 D2 D3
+25 02 B2 D0 C0 04 0C 02 B2 C0 C0 04 06 02 92 C3
+40 06 39 40 00 20 89 43 00 00 29 53 39 90 54 21
+FA 23 39 42 B0 12 C0 59 D2 C3 23 02 2C 42 B2 40
+95 00 14 20 B2 40 00 40 18 20 1A 43 B0 12 84 59
+02 24 30 40 5E 5A B0 12 BE 59 7A 93 FC 23 3C 42
+B2 40 87 AA 14 20 92 43 16 20 B2 40 00 48 18 20
+1A 43 B0 12 84 59 29 42 B0 12 C0 59 92 43 14 20
+82 43 16 20 78 43 0C 5C B2 40 00 77 18 20 1A 43
+B0 12 84 59 B2 40 40 69 18 20 B0 12 7A 59 03 24
+58 83 F2 23 D6 3F 0C 5C A2 43 16 20 B2 40 00 50
+18 20 B0 12 7A 59 CD 23 92 D3 40 06 82 43 46 06
+92 C3 40 06 0C 5C B0 12 E6 59 38 40 00 1E 92 48
+C6 01 04 20 92 48 C8 01 06 20 5A 48 C2 01 92 43
+02 20 7A 80 06 00 0B 24 7A 82 09 24 A2 43 02 20
+6A 53 05 24 5A 53 03 24 7A 50 0B 00 AA 23 B0 12
+E6 59 D2 48 0D 00 12 20 19 48 0E 00 82 49 08 20
+1A 48 16 00 0A 93 02 20 1A 48 24 00 82 4A 0A 20
+09 5A 82 49 0C 20 09 5A A2 93 02 20 04 24 82 49
+0E 20 39 50 20 00 19 82 12 20 19 82 12 20 82 49
+10 20 92 42 02 20 2E 20 C0 3E 84 12 DC 4D 16 58
+C2 58 CA 57 16 59 90 57 4A 58 94 54 00 00 86 57
+36 58 E8 57 26 58 A4 55 00 00 00 00 28 59 08 4E
+E2 4E 85 48 49 32 4C 4F 87 12 84 43 74 4C 2C 48
+44 4B 0A 4E CA 51 2A 40 50 4F 04 43 4F 44 45 00
+B0 12 56 4A A2 82 C4 1D 87 12 84 4B BC 41 02 52
+DA 4C 03 41 53 4D 92 42 C8 1D B8 1D B2 40 CE 51
+C8 1D EE 3F 00 00 07 45 4E 44 43 4F 44 45 87 12
+18 4E A4 4A 2A 40 36 52 06 45 4E 44 41 53 4D 00
+92 42 B8 1D C8 1D F3 3F 00 00 05 43 4F 4C 4F 4E
+1A 42 C4 1D BA 40 87 12 00 00 A2 53 C4 1D B2 43
+B6 1D 30 40 18 4E 00 00 05 4C 4F 32 48 49 1A 42
+C4 1D BA 40 B0 12 00 00 BA 40 2A 40 02 00 A2 52
+C4 1D ED 3F 38 40 BE 1D 39 48 2A 48 09 5A 1A 52
+C2 1D 09 9A 03 24 7E 9A FC 27 1A 83 0E 4A 2A 88
+82 4A C2 1D 30 4D B0 12 2A 40 24 46 7C 46 72 41
+C0 41 CC 52 38 47 C0 41 48 4A EE 52 CE 52 29 4E
+39 90 86 12 02 20 2E 53 30 41 39 90 85 12 03 20
+1E 4E 02 00 30 41 39 90 84 12 01 20 2E 52 30 41
+19 42 C4 1D A2 53 C4 1D 89 4E 00 00 3E 40 29 00
+12 12 C2 1D 92 53 C2 1D B0 12 2A 40 24 46 38 47
+C0 41 20 53 16 53 21 53 3E 90 10 00 BB 2D 30 41
+22 53 B2 41 C2 1D 22 D3 30 41 87 12 4C 42 94 52
+32 53 82 43 BC 1D 92 42 C4 1D BA 1D A2 53 C4 1D
+0A 4E 3E 4F FA 90 23 00 00 00 34 20 92 53 C2 1D
+B0 12 B6 52 0E 93 04 20 B2 40 00 03 BC 1D 27 3C
+1E 93 04 20 B2 40 10 03 BC 1D 21 3C 2E 93 04 20
+B2 40 20 03 BC 1D 1B 3C 2E 92 04 20 B2 40 20 02
+BC 1D 15 3C 3E 92 04 20 B2 40 30 02 BC 1D 0F 3C
+3E 93 04 20 B2 40 30 03 BC 1D 09 3C B2 40 30 00
+BC 1D 19 42 C4 1D A2 53 C4 1D 89 4E 00 00 3E 4F
+3D 41 30 4D FA 90 26 00 00 00 08 20 B2 40 10 02
+BC 1D 92 53 C2 1D 30 12 A2 53 75 3F FA 90 40 00
+00 00 1A 20 B2 40 20 00 BC 1D 92 53 C2 1D B0 12
+00 53 0E 20 B2 50 10 00 BC 1D 3E 40 2B 00 B0 12
+00 53 32 24 92 92 BE 1D C2 1D 02 24 92 53 C2 1D
+8E 10 82 5E BC 1D D3 3F B0 12 00 53 F9 23 B2 50
+10 00 BC 1D 3E 40 28 00 B0 12 B6 52 30 12 F2 53
+67 3F 87 12 4C 42 94 52 2A 54 FE 90 26 00 00 00
+3E 40 20 00 04 20 B2 50 82 00 BC 1D C2 3F B0 12
+00 53 DF 23 B2 50 80 00 BC 1D 3E 40 28 00 B0 12
+B6 52 B0 12 F0 52 D5 23 3D 40 48 4A 30 4D 00 00
+04 52 45 54 49 00 87 12 34 40 00 13 2C 48 2A 40
+34 40 2C 00 2A 53 22 54 7A 54 2E 4E 1E D2 BC 1D
+19 42 BA 1D 92 3F 78 52 03 4D 4F 56 84 12 70 54
+00 40 88 54 05 4D 4F 56 2E 42 84 12 70 54 40 40
+00 00 03 41 44 44 84 12 70 54 00 50 A2 54 05 41
+44 44 2E 42 84 12 70 54 40 50 AE 54 04 41 44 44
+43 00 84 12 70 54 00 60 BC 54 06 41 44 44 43 2E
+42 00 84 12 70 54 40 60 60 54 04 53 55 42 43 00
+84 12 70 54 00 70 DA 54 06 53 55 42 43 2E 42 00
+84 12 70 54 40 70 E8 54 03 53 55 42 84 12 70 54
+00 80 F8 54 05 53 55 42 2E 42 84 12 70 54 40 80
+5A 52 03 43 4D 50 84 12 70 54 00 90 12 55 05 43
+4D 50 2E 42 84 12 70 54 40 90 48 52 04 44 41 44
+44 00 84 12 70 54 00 A0 2C 55 06 44 41 44 44 2E
+42 00 84 12 70 54 40 A0 1E 55 03 42 49 54 84 12
+70 54 00 B0 4A 55 05 42 49 54 2E 42 84 12 70 54
+40 B0 56 55 03 42 49 43 84 12 70 54 00 C0 64 55
+05 42 49 43 2E 42 84 12 70 54 40 C0 70 55 03 42
+49 53 84 12 70 54 00 D0 7E 55 05 42 49 53 2E 42
+84 12 70 54 40 D0 00 00 03 58 4F 52 84 12 70 54
+00 E0 98 55 05 58 4F 52 2E 42 84 12 70 54 40 E0
+CA 54 03 41 4E 44 84 12 70 54 00 F0 B2 55 05 41
+4E 44 2E 42 84 12 70 54 40 F0 4C 42 2A 53 D0 55
+1A 42 BC 1D B2 F0 70 00 BC 1D 8A 10 3A F0 0F 00
+82 DA BC 1D 4A 3F 04 55 03 52 52 43 84 12 CA 55
+00 10 E8 55 05 52 52 43 2E 42 84 12 CA 55 40 10
+F4 55 04 53 57 50 42 00 84 12 CA 55 80 10 02 56
+03 52 52 41 84 12 CA 55 00 11 10 56 05 52 52 41
+2E 42 84 12 CA 55 40 11 1C 56 03 53 58 54 84 12
+CA 55 80 11 00 00 04 50 55 53 48 00 84 12 CA 55
+00 12 36 56 06 50 55 53 48 2E 42 00 84 12 CA 55
+40 12 8A 55 04 43 41 4C 4C 00 84 12 CA 55 80 12
+34 40 2C 00 2A 53 22 54 6A 56 59 42 BC 1D 5A 42
+BD 1D 82 4A BC 1D BE 90 00 15 00 00 02 20 0A 89
+02 3C 09 8A 0A 49 3A 90 10 00 03 2C 5A 0E A8 3F
+1A 53 0E 4A 87 12 70 43 CA 45 0D 6F 75 74 20 6F
+66 20 62 6F 75 6E 64 73 AA 49 44 56 05 50 55 53
+48 4D 84 12 60 56 00 15 AC 56 04 50 4F 50 4D 00
+84 12 60 56 00 17 4C 42 94 52 CC 56 82 43 BC 1D
+92 42 C4 1D BA 1D A2 53 C4 1D 92 53 C2 1D 3E 40
+2C 00 B0 12 2A 40 24 46 38 47 C0 41 48 4A 22 54
+F2 56 0A 4E 3E 4F 1A 83 2A 92 CA 2F 8A 10 5A 06
+6F 3F 2A 56 04 52 52 43 4D 00 84 12 C6 56 50 00
+04 57 04 52 52 41 4D 00 84 12 C6 56 50 01 12 57
+04 52 4C 41 4D 00 84 12 C6 56 50 02 20 57 04 52
+52 55 4D 00 84 12 C6 56 50 03 85 12 00 3C 2E 57
+03 53 3E 3D 85 12 00 38 40 57 02 53 3C 00 85 12
+00 34 BA 56 03 30 3E 3D 85 12 00 30 54 57 02 30
+3C 00 85 12 00 30 00 00 02 55 3C 00 85 12 00 2C
+68 57 03 55 3E 3D 85 12 00 28 5E 57 03 30 3C 3E
+85 12 00 24 7C 57 02 30 3D 00 85 12 00 20 00 00
+02 49 46 00 1A 42 C4 1D 8A 4E 00 00 A2 53 C4 1D
+0E 4A 30 4D 72 57 04 54 48 45 4E 00 1A 42 C4 1D
+08 4E 3E 4F 09 48 29 53 0A 89 0A 11 3A 90 00 02
+68 2F 88 DA 00 00 30 4D 3A 55 04 45 4C 53 45 00
+1A 42 C4 1D BA 40 00 3C 00 00 A2 53 C4 1D 2F 83
+8F 4A 00 00 E3 3F A6 57 05 55 4E 54 49 4C 3A 4F
+08 4E 3E 4F 19 42 C4 1D 2A 83 0A 89 0A 11 3A 90
+00 FE 47 3B 3A F0 FF 03 08 DA 89 48 00 00 A2 53
+C4 1D 30 4D BE 55 05 41 47 41 49 4E 87 12 3A 57
+EE 57 2A 40 00 00 05 57 48 49 4C 45 87 12 94 57
+6E 40 2A 40 4A 57 06 52 45 50 45 41 54 00 87 12
+3A 57 EE 57 AC 57 2A 40 00 00 03 4A 4D 50 87 12
+3A 4A 3A 57 EE 57 2A 40 3E B0 00 10 03 20 3E E0
+00 04 30 4D 3E 90 00 34 06 28 03 24 3E 40 00 34
+30 4D 3E 40 00 38 30 4D 00 00 04 3F 4A 4D 50 00
+87 12 58 58 3A 4A 6E 40 EE 57 2A 40 8E 58 3D 41
+08 4E 3E 4F 2A 48 0A 93 04 20 98 42 C4 1D 00 00
+30 4D 88 43 00 00 A4 3F 54 56 03 42 57 31 84 12
+8C 58 00 00 AA 58 03 42 57 32 84 12 8C 58 00 00
+B6 58 03 42 57 33 84 12 8C 58 00 00 CE 58 3D 41
+1A 42 C4 1D 28 4E 08 93 08 20 BA 4F 00 00 A2 53
+C4 1D 8E 4A 00 00 3E 4F 30 4D 8E 43 00 00 61 3F
+00 00 03 46 57 31 84 12 CC 58 00 00 F2 58 03 46
+57 32 84 12 CC 58 00 00 FE 58 03 46 57 33 84 12
+CC 58 00 00 0A 59 04 47 4F 54 4F 00 87 12 3A 57
+3A 4A 22 48 2A 40 7A 58 05 3F 47 4F 54 4F 87 12
+58 58 3A 4A 22 48 2A 40 D2 C3 23 02 E2 B2 60 02
+02 24 30 40 56 4F 1A 52 04 20 19 62 06 20 92 43
+14 20 A2 93 02 20 07 24 0A 5A 49 69 82 4A 16 20
+C2 49 18 20 0A 3C C2 4A 15 20 8A 10 C2 4A 16 20
+C2 49 17 20 89 10 C2 49 18 20 B0 12 BE 59 7A 93
+FC 23 0A 43 39 40 05 00 D2 49 14 20 4E 06 82 93
+46 06 05 24 92 B3 6C 06 FD 27 C2 93 4C 06 59 83
+F3 2F 19 83 0B 30 F2 43 4E 06 82 93 46 06 03 24
+92 B3 6C 06 FD 27 5A 92 4C 06 F3 23 30 41 19 43
+3A 43 8A 10 C2 4A 4E 06 82 93 46 06 05 24 92 B3
+6C 06 FD 27 C2 93 4C 06 19 83 F3 23 5A 42 4C 06
+30 41 1A 52 08 20 09 43 1C D3 F2 40 51 00 19 20
+B0 12 38 59 34 20 B0 12 BE 59 7A 90 FE FF FB 23
+F2 43 4E 06 00 40 19 53 39 90 00 02 D9 42 4C 06
+FF 1D F6 23 29 43 B0 12 C0 59 3C C0 03 00 D2 D3
+23 02 30 41 09 43 2C D3 F0 40 58 00 ED C5 B0 12
+38 59 15 20 3A 40 FE FF 29 43 B0 12 C2 59 D2 49
+00 1E 4E 06 03 43 19 53 39 90 00 02 F8 23 39 40
+03 00 B0 12 C0 59 7A C0 E1 00 6A 92 DE 27 D2 D3
+23 02 8C 10 1C 52 4C 06 87 12 CA 45 0B 3C 20 53
+44 20 45 72 72 6F 72 21 7A 5A 2F 82 8F 4E 02 00
+9F 42 DA 1D 00 00 B2 40 10 00 DA 1D 0E 4C B0 12
+2A 40 30 43 36 42 FC 40 AA 49 39 4F 18 42 C4 1D
+4A 4E 0E 48 C8 4A 00 00 18 53 30 40 BE 4D 92 4B
+0E 00 22 20 92 4B 10 00 24 20 5A 42 23 20 58 42
+22 20 A2 93 02 20 02 24 08 58 30 41 59 42 24 20
+89 10 0A 59 88 10 08 58 0A 6A 88 10 08 58 30 41
+82 43 1C 20 92 42 0E 20 1A 20 92 93 22 20 03 20
+C2 93 24 20 EA 27 92 42 10 20 E4 04 82 43 E6 04
+92 42 22 20 D8 04 92 42 24 20 DA 04 92 42 12 20
+C8 04 92 42 E4 04 1A 20 92 42 E6 04 1C 20 30 41
+92 4B 0E 00 22 20 92 4B 10 00 24 20 B0 12 E0 5A
+5A 4B 03 00 82 5A 1A 20 82 63 1C 20 30 41 09 93
+C4 27 F8 90 20 00 00 1E C0 23 18 53 19 83 F9 23
+30 41 1B 42 36 20 82 43 1E 20 B2 90 00 02 20 20
+9A 20 BB 80 00 02 12 00 8B 73 14 00 DB 53 03 00
+DB 92 12 20 03 00 11 28 CB 43 03 00 B0 12 AE 5A
+B0 12 E2 59 8B 43 10 00 9B 48 00 1E 0E 00 92 93
+02 20 03 24 9B 48 02 1E 10 00 B2 40 00 02 20 20
+8B 93 14 00 0B 20 92 9B 12 00 1E 20 74 2C BB 90
+00 02 12 00 03 2C 92 4B 12 00 20 20 B0 12 20 5B
+1A 42 1A 20 19 42 1C 20 0F 3F 3C 42 3B 40 40 20
+09 43 CB 93 02 00 10 24 9B 92 24 20 0C 00 04 20
+9B 92 22 20 0A 00 07 24 09 4B 3B 50 18 00 3B 90
+00 21 EF 23 0C 5C 30 41 0C 43 82 4B 36 20 8B 49
+00 00 4A 93 07 34 49 93 05 24 C9 93 02 00 02 34
+5A 59 02 00 CB 4A 02 00 CB 43 03 00 9B 42 1A 20
+04 00 9B 42 1C 20 06 00 18 42 32 20 8B 48 08 00
+9B 48 1A 1E 0A 00 9B 48 14 1E 0C 00 9B 48 1A 1E
+0E 00 9B 48 14 1E 10 00 9B 48 1C 1E 12 00 9B 48
+1E 1E 14 00 82 43 1E 20 6A 93 62 27 CC 37 8B 43
+16 00 7A 93 05 24 99 37 99 52 C2 1D 16 00 95 3F
+92 42 BE 1D 38 20 92 82 C2 1D 38 20 92 42 C0 1D
+3A 20 92 52 C2 1D 3A 20 B2 40 EC 43 64 44 92 42
+BE 1D C2 1D 82 3F 1B 42 36 20 82 43 20 20 0B 93
+AA 27 EB 93 02 00 04 20 B0 12 0C 61 B0 12 D4 60
+5A 4B 02 00 CB 43 02 00 2B 4B 82 4B 36 20 5A 53
+05 24 99 37 92 4B 16 00 1E 20 67 3F 1E 42 38 20
+9F 42 3A 20 02 00 B2 40 72 44 64 44 8C 3F 7E 4E
+85 52 45 41 44 22 5A 43 19 3C 44 4F 86 57 52 49
+54 45 22 00 6A 43 12 3C 0A 4D 84 44 45 4C 22 00
+6A 42 0C 3C 0A 52 05 43 4C 4F 53 45 B0 12 96 5C
+30 4D A6 4D 85 4C 4F 41 44 22 7A 43 2F 83 8F 4E
+00 00 0E 4A 82 93 B6 1D 0D 24 87 12 34 40 34 40
+2C 48 2C 48 E4 45 34 40 9A 5A 2C 48 34 40 50 5D
+2C 48 2A 40 87 12 34 40 22 00 24 46 4E 5D 3D 41
+2F 83 78 4E 08 5E C8 43 00 00 1C 43 92 42 2E 20
+22 20 92 42 30 20 24 20 CE 93 00 00 96 24 FE 90
+3A 00 01 00 01 20 2E 53 FE 90 5C 00 00 00 09 20
+1E 53 92 42 02 20 22 20 82 43 24 20 CE 93 00 00
+76 24 82 4E 34 20 B0 12 E0 5A BF 40 20 00 00 00
+A2 93 02 20 04 24 92 92 22 20 02 20 03 24 9F 42
+12 20 00 00 B0 12 C0 5B 2C 43 0A 43 08 4A 58 0E
+08 58 82 48 32 20 C8 93 00 1E 67 24 39 42 F8 9E
+00 1E 04 20 18 53 19 83 FA 23 1E 53 FE 90 2E 00
+FF FF 1B 24 39 50 03 00 B0 12 3E 5B 07 20 FE 90
+5C 00 FF FF 2C 24 CE 93 FF FF 29 24 1E 42 34 20
+1A 53 3A 90 10 00 DA 23 92 53 1A 20 82 63 1C 20
+9F 83 00 00 CF 23 2C 42 40 3C FE 90 2E 00 FE FF
+ED 27 B0 12 3E 5B EA 23 39 40 03 00 F8 9E 00 1E
+04 20 18 53 19 83 FA 23 0A 3C CE 93 FF FF DE 23
+FE 90 5C 00 FF FF DA 23 B0 12 3E 5B D7 23 18 42
+32 20 92 48 1A 1E 22 20 92 48 14 1E 24 20 F8 B0
+10 00 0B 1E 16 24 82 93 24 20 06 20 82 93 22 20
+03 20 92 42 02 20 22 20 CE 93 FF FF 87 23 92 42
+22 20 2E 20 92 42 24 20 30 20 2F 52 3E 4F 3D 41
+30 4D 1A 4F 02 00 B0 12 CA 5B 2F 53 3A 4F 3E 4F
+7A 93 15 20 0C 93 04 20 B2 40 30 4D EE 44 30 4D
+87 12 CA 45 0B 3C 20 4F 70 65 6E 45 72 72 6F 72
+36 45 84 43 82 48 AE 45 76 45 BC 41 78 5A 1A 93
+B5 20 0C 93 ED 23 30 4D E0 5C 04 52 45 41 44 00
+2F 83 8F 4E 00 00 1E 42 36 20 B0 12 52 5B 1E 82
+36 20 30 4D 2C 43 12 12 2C 20 18 42 02 20 08 58
+2A 41 82 9A 0A 20 A0 24 B0 12 E2 59 09 43 28 93
+03 24 89 93 02 1E 03 20 89 93 00 1E 07 24 09 58
+39 90 00 02 F4 23 91 53 00 00 EA 3F 0C 43 6A 41
+B9 43 00 1E 28 93 0F 24 B9 40 FF 0F 02 1E 09 11
+8A 10 09 5A 5A 41 01 00 0A 11 09 10 82 4A 28 20
+82 49 26 20 07 3C 09 11 C2 49 26 20 C2 4A 27 20
+82 43 28 20 3A 41 82 4A 2C 20 30 41 0A 12 1A 52
+08 20 B0 12 24 5A 3A 41 1A 52 0C 20 30 40 24 5A
+F2 B0 40 00 A2 04 29 20 F2 B0 10 00 A2 04 FC 27
+5A 42 B0 04 4A 11 59 42 B4 04 F2 40 20 00 C0 04
+D2 42 B1 04 C8 04 1A 52 E4 04 D2 42 B5 04 C8 04
+19 52 E4 04 D2 42 B2 04 C0 04 B2 40 00 08 C8 04
+1A 52 E4 04 92 42 B6 04 C0 04 B2 80 BC 07 C0 04
+B2 40 00 02 C8 04 19 52 E4 04 30 41 22 2A 2B 2C
+2F 3A 3B 3C 3D 3E 3F 5B 5C 5D 7C 2E 29 92 06 38
+39 80 03 00 B0 12 2A 60 39 40 03 00 7A 4B C8 4A
+00 1E 0A 93 12 24 0D 12 3D 40 0F 00 3C 40 DC 5F
+7A 9C F4 27 1D 83 FC 23 3D 41 6A 9C E7 27 3A 80
+21 00 EC 3B 18 53 19 83 E9 23 09 93 06 24 F8 40
+20 00 00 1E 18 53 19 83 FA 23 30 41 2A 93 E4 20
+2C 93 0D 24 0C 93 BA 24 87 12 CA 45 0C 3C 20 57
+72 69 74 65 45 72 72 6F 72 00 BC 41 C0 5E B0 12
+F4 5E 92 42 26 20 22 20 92 42 28 20 24 20 B0 12
+6C 5F B0 12 C0 5B 18 42 32 20 F8 40 20 00 0B 1E
+B0 12 80 5F 88 43 0C 1E 88 4A 0E 1E 88 49 10 1E
+88 49 12 1E 98 42 24 20 14 1E 98 42 22 20 1A 1E
+88 43 1C 1E 88 43 1E 1E 1C 43 1B 42 34 20 CB 93
+00 00 CA 27 FB 90 2E 00 00 00 C6 27 39 40 0B 00
+B0 12 FC 5F B0 12 16 61 2A 43 B0 12 CA 5B 0C 93
+BB 23 30 4D 1A 4B 04 00 19 4B 06 00 B0 12 E8 59
+B0 12 80 5F 18 4B 08 00 88 49 12 1E 88 4A 16 1E
+88 49 18 1E 98 4B 12 00 1C 1E 98 4B 14 00 1E 1E
+1A 4B 04 00 19 4B 06 00 30 40 26 5A 9B 52 1E 20
+12 00 8B 63 14 00 1A 42 1A 20 19 42 1C 20 30 40
+26 5A B2 40 00 02 1E 20 1B 42 36 20 B0 12 0C 61
+82 43 1E 20 DB 53 03 00 DB 92 12 20 03 00 22 20
+CB 43 03 00 B0 12 AE 5A 08 12 0A 12 B0 12 F4 5E
+2A 91 05 24 B0 12 6C 5F 2A 41 B0 12 E2 59 3A 41
+38 41 98 42 26 20 00 1E 92 93 02 20 03 24 98 42
+28 20 02 1E B0 12 6C 5F 9B 42 26 20 0E 00 9B 42
+28 20 10 00 30 40 20 5B EC 5C 05 57 52 49 54 45
+B0 12 22 61 30 4D DA 5E 07 53 44 5F 45 4D 49 54
+B2 90 00 02 1E 20 02 28 B0 12 22 61 18 42 1E 20
+C8 4E 00 1E 92 53 1E 20 3E 4F 30 4D 58 4B 13 00
+5C 4B 14 00 8C 10 0C 58 5A 4B 15 00 0A 11 0C 10
+18 4B 12 00 BB C0 FF 01 12 00 38 F0 FF 01 82 48
+1E 20 5B 42 12 20 B0 12 5E 42 1B 42 36 20 CB 4A
+03 00 19 5B 0A 00 18 6B 0C 00 8B 49 0E 00 8B 48
+10 00 B0 12 BC 5B 30 4D 0C 93 38 20 38 90 E0 01
+03 2C C8 93 20 1E 02 24 7C 40 E5 00 C8 4C 00 1E
+B0 12 16 61 B0 12 BA 5A 82 4A 2C 20 0B 4A B0 12
+E2 59 1A 48 00 1E 88 43 00 1E 92 93 02 20 09 24
+19 48 02 1E 88 43 02 1E 39 F0 FF 0F 39 90 FF 0F
+02 20 3A 93 0E 24 82 4A 22 20 82 49 24 20 B0 12
+BA 5A 0B 9A E6 27 0A 12 0A 4B B0 12 6C 5F 3A 41
+DD 3F 0A 4B B0 12 6C 5F B0 12 96 5C 30 4D BA 4C
+08 54 45 52 4D 32 53 44 22 00 87 12 00 5D 84 43
+92 62 21 53 2F 83 AF 43 00 00 3D 40 A2 62 30 40
+50 5D A4 62 92 C3 DC 05 08 43 B0 12 A6 44 92 B3
+DC 05 FD 27 59 42 CC 05 69 92 0D 24 C8 49 00 1E
+18 53 38 90 FF 01 04 24 F2 2B B0 12 22 61 EC 3F
+B0 12 B4 44 EC 3F B0 12 B4 44 82 48 1E 20 B0 12
+96 5C 3D 41 30 4D
+@FFB4
+5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F
+5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F
+5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F
+5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F C8 44 5C 4F
+5C 4F 5C 4F 5C 4F 5C 4F 5C 4F 5C 4F
+q
--- /dev/null
+\prog\MSP430Flasher\msp430flasher -m SBW2 -n MSP430fr5994 -v -w %1 -z [VCC=3000]
+exit
+
+tip : how to calculate MAIN program lenght ?
+
+open the prog.txt file with your editor, select MAIN section
+in status bar, keep the number of selected chars
+if lines are ended with CR+LF, substract the number of lines selected
+then divide by 3.
--- /dev/null
+; -*- coding: utf-8 -*-
+
+; Fast Forth For Texas Instrument MSP430FR6989
+;
+; Copyright (C) <2014> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+; ======================================================================
+; INIT MSP-EXP430FR6989 board
+; ======================================================================
+
+; my USBtoUart :
+; http://www.ebay.fr/itm/CP2102-USB-UART-Board-mini-Data-Transfer-Convertor-Module-Development-Board-/251433941479
+
+; for sd card socket be carefull : pin CD must be present !
+; http://www.ebay.com/itm/2-PCS-SD-Card-Module-Slot-Socket-Reader-For-Arduino-MCU-/181211954262?pt=LH_DefaultDomain_0&hash=item2a3112fc56
+
+
+; J101 eZ-FET <-> target
+; -----------------------
+; P1 <-> P2 - NC
+; P3 <-> P4 - TEST - TEST
+; P5 <-> P6 - RST - RST
+; P7 <-> P8 - TX1 - P3.4 UCA1 TXD ---> RX UARTtoUSB module
+; P9 <->P10 - RX1 - P3.5 UCA1 RXD <--- TX UARTtoUSB module
+; P11<->P12 - CTS - P3.1
+; P13<->P14 - RTS - P3.0
+; P15<->P16 - VCC - 3V3
+; P17<->P18 - 5V
+; P19<->P20 - GND - VSS
+
+; Launchpad Header Left J1
+; ------------------------
+; P1 - 3V3
+; P2 - P9.2 ESICH2
+; P3 - P4.3 UCA0 RXD
+; P4 - P4.2 UCA0 TXD
+; P5 - P3.2 UCB1 SCL
+; P6 - P9.3 ESICH3
+; P7 - P1.4 UCB0 CLK
+; P8 - P2.0 TB0.6
+; P9 - P4.1 UCB1 SCL
+; P10- P4.0 UCB1 SDA
+
+; Launchpad Header Left J3
+; ------------------------
+; P21 - 5V0
+; P22 - GND
+; P23 - P8.4 A7
+; P24 - P8.5 A6
+; P25 - P8.6 A5
+; P26 - P8.7 A4
+; P27 - P9.0 A8
+; P28 - P9.1 A9
+; P29 - P9.5 A13
+; P30 - P9.6 A14
+
+; Launchpad Header Right J2
+; -------------------------
+; P20- GND
+; P19- P2.1 TB0.5
+; P18- P1.5 TA0.0 UCA0 CLK
+; P17- P9.4 ESIC10
+; P16- RST
+; P15- P1.6 UCB0 SDA
+; P14- P1.7 UCB0 SCL
+; P13- P2.5 TB0.4
+; P12- P2.4 TB0.3
+; P11- P4.7 TA1.2 UCB1 SOMI/SCL
+
+; Launchpad Header Right J4
+; -------------------------
+; P40- P2.7 TB0.6
+; P39- P2.6 TB0.5
+; P38- P3.3 TA1.1
+; P37- P3.6 TB0.2
+; P36- P3.7 TB0.3
+; P35- P2.2 UCA0 CLK
+; P34- P1.3 TA1.2
+; P33- P3.0 UCB1 CLK
+; P32- P3.1 UCB1 SIMO/SDA
+; P31- P2.3
+
+
+; switch-keys:
+; S1 - P1.1
+; S2 - P1.2
+; S3 - RST
+
+; LEDS:
+; LED1 - J7 - P1.0
+; LED2 - J8 - P9.7
+
+; XTAL LF 32768 Hz
+; Y4 - PJ.4
+; Y4 - PJ.5
+
+; LCD
+; 1 - P8.3
+; 2 - P8.2
+; 3 - P8.1
+; 4 - P8.0
+; 5 - P5.6
+; 6 - P5.5
+; 7 - P5.4
+; 8 - P7.1
+; 9 - P4.6
+; 10 - P4.5
+; 11 - P4.4
+; 12 - P5.7
+; 13 - P5.2
+; 14 - P5.1
+; 15 - P5.8
+; 16 - P10.2
+; 17 - P10.1
+; 18 - P7.6
+; 19 - P7.5
+; 20 - P6.7
+; 21 - P6.6
+; 22 - P6.5
+; 23 - P6.4
+; 24 - P6.3
+; 25 - NC
+; 26 - NC
+; 27 - NC
+; 28 - NC
+; 29 - NC
+; 30 - NC
+; 31 - NC
+; 32 - P10.0
+; 33 - P7.7
+; 34 - P5.3
+; 35 - P7.3
+; 36 - P7.2
+; 37 - P7.1
+; 38 - P7.0
+
+
+; Clocks:
+; 8 MHz DCO intern
+
+
+
+; ===================================================================================
+; in case of 3.3V powered by UARTtoUSB bridge, open J13 straps {RST,TST,V+,5V} BEFORE
+; then wire VCC and GND of bridge onto J13 connector
+; ===================================================================================
+
+; ---------------------------------------------------
+; MSP - MSP-EXP430FR6989 LAUNCHPAD <--> OUTPUT WORLD
+; ---------------------------------------------------
+; P1.0 - LED1 red
+; P9.7 - LED2 green
+
+; P1.1 - Switch S1 <--- LCD contrast + (finger :-)
+; P1.2 - Switch S2 <--- LCD contrast - (finger ;-)
+
+; note : ESI1.1 = lowest left pin
+; note : ESI1.2 is not connected to 3.3V
+; GND/ESIVSS - ESI1.3 <-------+---0V0----------> 1 LCD_Vss
+; VCC/ESIVCC - ESI1.4 >------ | --3V3-----+----> 2 LCD_Vdd
+; | |
+; |___ 470n ---
+; ^ | ---
+; / \ BAT54 |
+; --- |
+; 100n | 2k2 |
+; P3.6 - UCA1 CLK TB0.2 J4.37 >---||--+--^/\/\/v--+----> 3 LCD_Vo (=0V6 without modulation)
+; P9.0/ESICH0 - ESI1.14 <------------------------> 11 LCD_DB4
+; P9.1/ESICH1 - ESI1.13 <------------------------> 12 LCD_DB5
+; P9.2/ESICH2 - ESI1.12 <------------------------> 13 LCD_DB5
+; P9.3/ESICH3 - ESI1.11 <------------------------> 14 LCD_DB7
+; P9.4/ESICI0 - ESI1.10 -------------------------> 4 LCD_RS
+; P9.5/ESICI1 - ESI1.9 -------------------------> 5 LCD_R/W
+; P9.6/ESICI2 - ESI1.8 -------------------------> 6 LCD_EN
+
+; +--4k7-< DeepRST <-- GND
+; |
+; P3.4 - UCA1 TXD J101.8 <-+-> RX UARTtoUSB bridge
+; P3.5 - UCA1 RXD J101.10 <---- TX UARTtoUSB bridge
+; P3.0 - RTS J101.14 ----> CTS UARTtoUSB bridge (optional hardware control flow)
+; VCC - J101.16 <---- VCC (optional supply from UARTtoUSB bridge - WARNING ! 3.3V !)
+; GND - J101.20 <---> GND (optional supply from UARTtoUSB bridge)
+
+; VCC - J1.1 ----> VCC SD_CardAdapter
+; GND - J2.20 <---> GND SD_CardAdapter
+; P2.2 - UCA0 CLK J4.35 ----> CLK SD_CardAdapter (SCK)
+; P2.6 - J4.39 ----> CS SD_CardAdapter (Card Select)
+; P2.0 - UCA0 TXD/SIMO J1.8 ----> SDI SD_CardAdapter (MOSI)
+; P2.1 - UCA0 RXD/SOMI J2.19 <---- SDO SD_CardAdapter (MISO)
+; P2.7 - J4.40 <---- CD SD_CardAdapter (Card Detect)
+
+; P4.0 - J1.10 <---- OUT IR_Receiver (1 TSOP32236)
+; VCC - J6.1 ----> VCC IR_Receiver (2 TSOP32236)
+; GND - J6.2 <---> GND IR_Receiver (3 TSOP32236)
+
+; P1.3 - J4.34 <---> SDA software I2C Master
+; P1.5 - J2.18 ----> SCL software I2C Master
+
+; P1.4 -UCB0 CLK TA1.0 J1.7 <---> free
+
+; P1.6 -UCB0 SDA/SIMO J2.15 <---> SDA hardware I2C Master or Slave
+; P1.7 -UCB0 SCL/SOMI J2.14 ----> SCL hardware I2C Master or Slave
+
+; P3.0 -UCB1 CLK J4.33 ----> free (if UARTtoUSB with software control flow)
+; P3.1 -UCB1 SDA/SIMO J4.32 <---> free
+; P3.2 -UCB1 SCL/SOMI J1.5 ----> free
+; P3.3 - TA1.1 J1.5 <---> free
+
+; PJ.4 - LFXI 32768Hz quartz
+; PJ.5 - LFXO 32768Hz quartz
+; PJ.6 - HFXI
+; PJ.7 - HFXO
+
+
+; ----------------------------------------------------------------------
+; INIT order : WDT, GPIOs, FRAM, Clock, UARTs...
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : LOCK PMM_LOCKLPM5
+; ----------------------------------------------------------------------
+
+; BIS #LOCKLPM5,&PM5CTL0 ; unlocked by WARM
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : WATCHDOG TIMER A
+; ----------------------------------------------------------------------
+
+ MOV #WDTPW+WDTHOLD+WDTCNTCL,&WDTCTL ; stop WDT
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : I/O
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT1/2
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT1 usage
+; P1.0 - LED1 red output low
+; P1.1 - Switch S1
+; P1.2 - Switch S2
+SWITCHIN .set P1IN ; port
+S1 .set 2 ; P1.1 bit position
+
+; PORT2 usage
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #1,&PADIR ; all pins as input else P1.0
+ MOV #-2,&PAOUT ; all pins with pullup resistors else P1.0 output low
+ SUB #2,&PAREN ; all pins with pull resistors else P1.0
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT3/4
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT3 usage
+; P3.0 = RTS
+; P3.1 = CTS
+; P3.4 = TX1
+; P3.5 = RX1
+
+Deep_RST_IN .equ P3IN ; TERMINAL TX pin as FORTH Deep_RST
+Deep_RST .equ 10h ; P3.4 = TX
+TERM_TXRX .equ 30h ; P3.5 = RX
+TERM_SEL .equ P3SEL0
+TERM_REN .equ P3REN
+
+; PORT4 usage
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #-1,&PBOUT ; all pins 1
+ BIS #-1,&PBREN ; all pins with pull resistors
+
+ .IFDEF TERMINALCTSRTS
+CTS .equ 1 ; P3.0 bit position
+RTS .equ 2 ; P3.1 bit position
+HANDSHAKOUT .equ P3OUT
+HANDSHAKIN .equ P3IN
+ BIS.B #RTS,&HANDSHAKOUT ; set RTS output high
+ .ENDIF
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT5/6
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT5 usage
+
+; PORT6 usage
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #-1,&PCOUT ; all pins 1
+ BIS #-1,&PCREN ; all pins with pull resistors
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT7/8
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT7 usage
+
+; PORT8 usage
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #-1,&PDOUT ; all pins 1
+ BIS #-1,&PDREN ; all pins with pull resistors
+
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT9/10
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT9 usage
+; P9.7 Green LED2 as output low
+
+; PORT10 usage
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #00080h,&PEDIR ; all pins as input else P9.7
+ MOV #0FF7Fh,&PEOUT ; all pins high else P9.7
+ BIS #0FF7Fh,&PEREN ; all pins with pull resistors else P9.7
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORTJ
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORTJ usage
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV.B #-1,&PJOUT ; pullup resistors
+ BIS.B #-1,&PJREN ; enable pullup/pulldown resistors
+
+; ----------------------------------------------------------------------
+; FRAM config
+; ----------------------------------------------------------------------
+
+ .IF FREQUENCY = 16
+ MOV.B #0A5h, &FRCTL0_H ; enable FRCTL0 access
+ MOV.B #10h, &FRCTL0 ; 1 waitstate @ 16 MHz
+ MOV.B #01h, &FRCTL0_H ; disable FRCTL0 access
+ .ENDIF
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : CLOCK SYSTEM
+; ----------------------------------------------------------------------
+
+; DCOCLK: Internal digitally controlled oscillator (DCO).
+; Startup clock system in max. DCO setting ~8MHz
+; This value is closer to 10MHz on untrimmed parts
+
+ MOV.B #CSKEY,&CSCTL0_H ; Unlock CS registers
+
+ .IF FREQUENCY = 0.5
+ MOV #0,&CSCTL1 ; Set 1MHZ DCO setting
+ MOV #DIVA_2 + DIVS_2 + DIVM_2,&CSCTL3 ; set all dividers as 2
+ MOV #4,X
+
+ .ELSEIF FREQUENCY = 1
+ MOV #0,&CSCTL1 ; Set 1MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #8,X
+
+ .ELSEIF FREQUENCY = 2
+ MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 4MHZ DCO setting
+ MOV #DIVA_0 + DIVS_2 + DIVM_2,&CSCTL3
+ MOV #16,X
+
+ .ELSEIF FREQUENCY = 4
+ MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 4MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #32,X
+
+ .ELSEIF FREQUENCY = 8
+; MOV #DCOFSEL2+DCOFSEL1,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #64,X
+
+ .ELSEIF FREQUENCY = 16
+ MOV #DCORSEL+DCOFSEL2,&CSCTL1 ; Set 16MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #128,X
+
+ .ELSEIF
+ .error "bad frequency setting, only 0.5,1,2,4,8,16 MHz"
+ .ENDIF
+
+ .IFDEF LF_XTAL
+ MOV #SELA_LFXCLK+SELS_DCOCLK+SELM_DCOCLK,&CSCTL2
+ .ELSE
+ MOV #SELA_VLOCLK+SELS_DCOCLK+SELM_DCOCLK,&CSCTL2
+ .ENDIF
+ MOV.B #01h, &CSCTL0_H ; Lock CS Registers
+
+ BIS &SYSRSTIV,&SAVE_SYSRSTIV; store volatile SYSRSTIV preserving a pending request for DEEP_RST
+ CMP #2,&SAVE_SYSRSTIV ; POWER ON ?
+ JZ ClockWaitX ; yes
+ .word 0759h ; no RRUM #2,X --> wait only 125 ms
+ClockWaitX MOV #41666,Y ; wait 0.5s before starting after POWER ON
+ClockWaitY SUB #1,Y ;
+ JNZ ClockWaitY ; 41666x3 = 125000 cycles delay = 125ms @ 1MHz
+ SUB #1,X ; x 4 @ 1 MHZ
+ JNZ ClockWaitX ; time to stabilize power source ( 1s )
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : REF
+; ----------------------------------------------------------------------
+
+ MOV #REFTCOFF, &REFCTL
+
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : RTC_C REGISTERS
+; ----------------------------------------------------------------------
+
+ .IFDEF LF_XTAL
+; LFXIN : PJ.4, LFXOUT : PJ.5
+ BIS.B #010h,&PJSEL0 ; SEL0 for only LXIN
+ BIC.B #RTCHOLD,&RTCCTL1 ; Clear RTCHOLD = start RTC_B
+ .ENDIF
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : SYS REGISTERS
+; ----------------------------------------------------------------------
+
+; SYS code
+; see COLD word
+
+
--- /dev/null
+@1800
+10 00 4C 48 80 3E 80 04 FD FF 18 00 66 5B 1C 54
+2A 48 38 48 00 00 00 00
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@4400
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 44
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 44 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 44 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E 44 02 3E 52 00 0E 12 3E 4F 30 4D 8E 44
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 44
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C 44 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 44 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 45
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 44 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA 44 03 41 4E 44 3E FF 30 4D 7A 44 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E 45 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 45 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E 45 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 45 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 44 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE 45 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 45 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 45 03 3E 49 4E 85 12 C2 1D 10 45
+04 42 41 53 45 00 85 12 DA 1D C0 44 05 53 54 41
+54 45 85 12 B6 1D 30 46 02 42 4C 00 85 12 20 00
+94 45 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 46 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E 46 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 46 02 23 53 00 87 12 98 46
+D2 46 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 46 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 46 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C 46 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 45 03 55 44 2E 87 12 56 46
+CC 46 E6 46 32 49 FA 48 2A 44 18 47 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA 44
+02 44 2E 00 87 12 56 46 6E 44 80 44 3A 47 CC 46
+92 44 0A 47 E6 46 32 49 FA 48 2A 44 52 45 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 46 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 45 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 46 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A 48
+92 B3 FC 05 FD 27 1E 42 EC 05 B0 12 38 48 30 4D
+30 40 B6 47 7E 47 05 28 4B 45 59 29 18 42 EC 05
+EA 3F 12 46 03 4B 45 59 30 40 DC 47 92 47 06 41
+43 43 45 50 54 00 3C 40 8A 48 3B 40 54 48 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+7E 48 92 B3 FC 05 05 24 18 42 EC 05 38 90 0A 00
+04 20 21 53 39 40 46 48 4D 15 B2 40 11 00 EE 05
+A2 B3 FC 05 FD 27 30 41 B2 40 13 00 EE 05 A2 B3
+FC 05 FD 27 30 41 12 D2 0A 18 FD 3F 21 52 3A 17
+58 42 EC 05 48 9B F0 27 48 9C 06 2C 78 92 11 20
+2E 9F 0F 24 1E 83 05 3C 0E 9A 03 24 CE 48 00 00
+1E 53 82 48 EE 05 A2 B3 FC 05 FD 27 30 4D 80 48
+2D 83 92 B3 FC 05 FD 27 E3 23 B2 40 18 00 0A 18
+3E 8F 3D 41 30 4D D6 47 06 28 45 4D 49 54 29 00
+08 4E 3E 4F E6 3F 50 47 04 45 4D 49 54 00 30 40
+A0 48 A8 48 04 45 43 48 4F 00 B2 40 82 48 72 48
+30 4D 6E 47 06 4E 4F 45 43 48 4F 00 B2 40 30 4D
+72 48 30 4D 98 48 04 28 43 52 29 00 2F 83 8F 4E
+00 00 3E 40 0D 00 E3 3F A2 47 02 43 52 00 30 40
+DC 48 04 47 05 53 50 41 43 45 2F 83 8F 4E 00 00
+3E 40 20 00 D4 3F F4 48 06 53 50 41 43 45 53 00
+0E 93 09 24 0D 12 3D 40 1C 49 EF 3F 1E 49 2D 83
+1E 83 EB 23 3D 41 3E 4F 30 4D 2C 47 04 54 59 50
+45 00 0E 93 95 24 2A 4F 8F 5E 00 00 0E 4A 87 12
+CA 45 02 46 0A 45 AE 48 EC 45 42 49 2A 44 2F 82
+8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E 1D B3 0D 63
+30 4D 08 49 82 53 22 00 87 12 34 44 4E 49 B0 4B
+34 44 22 00 A8 49 78 49 3D 41 6E 4E 1E 83 82 5E
+C4 1D 3E 4F 92 B3 C4 1D A2 63 C4 1D 30 4D C4 48
+82 2E 22 00 87 12 68 49 34 44 32 49 B0 4B 2A 44
+00 00 04 57 4F 52 44 00 3C 40 BE 1D 39 4C 3A 4C
+09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A FC 27 1A 83
+3B 40 60 00 C8 4C 00 00 09 9A 0C 24 7C 4A 4E 9C
+09 24 18 53 4B 9C F6 2F 7C 90 7B 00 F3 2F 7C 80
+20 00 F0 3F 1A 82 C0 1D 82 4A C2 1D 1E 42 C4 1D
+08 8E CE 48 00 00 30 4D 00 00 04 46 49 4E 44 00
+2F 83 0C 4E 65 4C 74 40 80 00 3B 40 CA 1D 3E 4B
+0E 93 1E 24 58 4C 01 00 78 F0 1E 00 0E 58 2E 53
+1E 4E FE FF 0E 93 F3 27 09 4E 78 49 48 C4 48 95
+F7 23 0A 4C 1A 53 FA 99 00 00 F2 23 58 83 FA 23
+19 B3 09 63 0C 49 6A 4E 1E 43 4A 93 01 30 2E 83
+8F 4C 00 00 35 40 08 44 34 40 14 44 30 4D 2F 53
+2F 53 3E 4F 30 4D 26 46 07 3E 4E 55 4D 42 45 52
+3C 4F 38 4F 29 4F 2F 82 1B 42 DA 1D 6A 4C 7A 80
+30 00 7A 90 0A 00 02 28 7A 80 07 00 0A 9B 13 2C
+82 49 D0 04 82 48 D2 04 82 4B C8 04 19 42 E4 04
+18 42 E6 04 09 5A 08 63 1C 53 1E 83 E7 23 8F 49
+04 00 8F 48 02 00 8F 4C 00 00 30 4D 03 12 0D 12
+1B 42 DA 1D 0B 12 32 C0 00 02 6D 4E 0D 5E 0C 4E
+7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23 32 D0 00 02
+FC 4C FE FF 0D 9C FC 2F DE 83 00 00 09 43 08 43
+3D 40 32 4B 3F 82 8F 4E 06 00 0C 4E 7E 4C 6A 4C
+7A 90 2D 00 10 2C 3B 40 10 00 7A 80 24 00 06 24
+2B 43 5A 83 03 24 3B 52 6A 53 B0 23 1C 53 1E 83
+6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83 B1 43 04 00
+A5 3F 34 4B 2F 53 0E 93 2C 17 82 4C DA 1D 03 24
+2F 52 0E F3 30 4D 8F 93 00 00 15 20 32 B0 00 02
+14 20 0E 93 05 24 1A 4F 02 00 1A 83 0A 93 0B 38
+2F 53 BF 4F 00 00 3E E3 05 20 BF E3 00 00 9F 53
+00 00 3E E3 30 4D 32 D0 00 02 9F 4F 02 00 04 00
+BF 4F 00 00 3E E3 F6 23 BF E3 02 00 BF E3 00 00
+9F 53 02 00 8F 63 00 00 3E E3 30 4D B4 48 07 45
+58 45 43 55 54 45 0A 4E 3E 4F 00 4A 28 45 01 2C
+1A 42 C4 1D A2 53 C4 1D 8A 4E 00 00 3E 4F 30 4D
+AE 4B 87 4C 49 54 45 52 41 4C 82 93 B6 1D 16 24
+32 B0 00 02 09 24 1A 42 C4 1D A2 52 C4 1D BA 40
+34 44 00 00 BA 4F 02 00 1A 42 C4 1D A2 52 C4 1D
+BA 40 34 44 00 00 8A 4E 02 00 3E 4F 30 4D EA 48
+05 43 4F 55 4E 54 2F 83 1E 53 8F 4E 00 00 5E 4E
+FF FF 30 4D 82 4E BE 1D B2 4F C0 1D 3E 4F 82 43
+C2 1D 87 12 4C 46 A8 49 2A 4C 3D 40 36 4C E8 22
+3D 41 3E 4F 30 4D 38 4C 0A 4E 3E 4F 3D 40 4E 4C
+3D 27 3D 40 24 4C 1A E2 B6 1D B2 27 AC 23 50 4C
+3E 4F 3D 40 24 4C B9 23 DE 53 00 00 68 4E 08 5E
+F8 40 3F 00 00 00 3D 40 16 4E CD 3F 9E 4B 08 45
+56 41 4C 55 41 54 45 00 39 40 BE 1D 39 12 39 12
+39 12 0D 12 B0 12 2A 44 14 4C 8C 4C 3D 41 B2 41
+C2 1D B2 41 C0 1D B2 41 BE 1D 30 4D 7A 45 04 51
+55 49 54 00 31 40 E0 1C B2 40 00 1C AC 1D 82 43
+B6 1D 82 43 08 18 B0 12 2A 44 4E 49 04 0D 6F 6B
+20 00 32 49 34 44 38 1D 44 44 34 44 50 00 F6 47
+FA 48 14 4C 34 44 7E 1C CE 44 B2 45 4E 49 0D 73
+74 61 63 6B 20 65 6D 70 74 79 20 21 28 4D 34 44
+30 FF 84 47 B2 45 4E 49 0B 46 52 41 4D 20 66 75
+6C 6C 20 21 28 4D 42 46 F4 44 C0 45 BA 4C 4E 49
+04 0D 20 20 20 00 BC 45 C2 4C EE 47 05 41 42 4F
+52 54 3F 40 80 1C BE 3F 8F 93 02 00 98 26 B2 40
+82 48 72 48 B0 12 10 52 82 43 E0 5A 82 43 EC 5A
+82 43 F8 5A 82 43 28 5B 82 43 34 5B 82 43 40 5B
+A2 B3 FC 05 FD 27 B2 40 11 00 EE 05 92 C3 FC 05
+38 40 A0 AA 39 42 19 83 FE 23 18 83 FB 23 92 B3
+FC 05 F4 23 87 12 4E 49 04 1B 5B 37 6D 00 32 49
+32 49 4E 49 04 1B 5B 30 6D 00 32 49 58 51 9A 51
+A0 51 22 4D 1C 4D 86 41 42 4F 52 54 22 00 87 12
+68 49 34 44 28 4D B0 4B 2A 44 FA 49 01 27 87 12
+4C 46 A8 49 00 4A C0 45 BC 4D 2A 44 58 4C 52 46
+81 5C 92 42 BE 1D C2 1D 30 4D 87 12 84 49 4C 46
+A8 49 D4 4D 08 4E 7A 4E 5A D3 5A 53 0A 58 19 42
+C8 1D 6E 4E 3E F0 1E 00 09 5E 82 48 AE 1D 82 49
+B0 1D 82 4A B2 1D 2A 52 82 4A C4 1D 3E 4F 3D 41
+30 41 87 12 4E 49 0F 73 74 61 63 6B 20 6D 69 73
+6D 61 74 63 68 21 2E 4D 82 9F B4 1D F2 23 18 42
+AE 1D 19 42 B0 1D A8 49 FE FF 89 48 00 00 30 4D
+A2 49 08 56 41 52 49 41 42 4C 45 00 B0 12 CA 4D
+BA 40 86 12 FC FF EF 3F 00 4C 08 43 4F 4E 53 54
+41 4E 54 00 B0 12 CA 4D BA 40 85 12 FC FF 8A 4E
+FE FF 3E 4F E0 3F 4A 4E 06 43 52 45 41 54 45 00
+B0 12 CA 4D BA 40 85 12 FC FF 8A 4A FE FF D3 3F
+6E 4C 05 44 4F 45 53 3E 1A 42 B2 1D BA 40 84 12
+00 00 8A 4D 02 00 3D 41 30 4D 82 4E 05 44 45 46
+45 52 B0 12 CA 4D BA 40 30 40 FC FF BA 40 98 4E
+FE FF B9 3F 00 00 81 5B 82 43 B6 1D 30 4D C0 4D
+01 5D B2 43 B6 1D 30 4D 64 49 87 52 45 43 55 52
+53 45 19 42 C4 1D 99 42 B2 1D 00 00 A2 53 C4 1D
+30 4D B6 4E 01 3A B0 12 CA 4D BA 40 87 12 FC FF
+A2 83 C4 1D B2 43 B6 1D 82 4F B4 1D 30 4D E4 4E
+81 3B 82 93 B6 1D 5D 27 87 12 34 44 2A 44 B0 4B
+18 4E B8 4E 2A 44 D6 48 09 49 4D 4D 45 44 49 41
+54 45 1A 42 AE 1D FA D0 80 00 00 00 30 4D BE 4F
+02 00 3E 4F 30 4D 18 4F 82 49 53 00 87 12 42 46
+F4 44 C0 45 50 4F 5C 4F 34 44 2E 4F B0 4B 2A 44
+AE 4D 2E 4F 2A 44 00 4F 83 5B 27 5D 87 12 AE 4D
+34 44 34 44 B0 4B B0 4B 2A 44 9E 4C 88 50 4F 53
+54 50 4F 4E 45 00 87 12 4C 46 A8 49 00 4A 54 44
+C0 45 BC 4D 7E 45 C0 45 96 4F 34 44 34 44 B0 4B
+B0 4B 34 44 B0 4B B0 4B 2A 44 9C 4F 3A 4E 82 4A
+C6 1D 2E 4E 82 4E C4 1D 3D 40 10 00 09 4A 08 49
+29 83 18 48 FE FF 0E 98 FC 2B 89 48 00 00 1D 83
+F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41 30 4D 38 4F
+82 49 46 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40
+C0 45 00 00 A2 52 C4 1D 2E 53 30 4D 9C 4E 84 45
+4C 53 45 00 1A 42 C4 1D BA 40 BC 45 00 00 2A 52
+82 4A C4 1D 8E 4A 00 00 2A 83 0E 4A 30 4D 2C 49
+84 54 48 45 4E 00 9E 42 C4 1D 00 00 3E 4F 30 4D
+68 4E 85 42 45 47 49 4E 30 40 84 47 10 50 85 55
+4E 54 49 4C 39 40 C0 45 1A 42 C4 1D A2 52 C4 1D
+8A 49 00 00 8A 4E 02 00 3E 4F 30 4D 96 4D 85 41
+47 41 49 4E 39 40 BC 45 EF 3F 32 4E 85 57 48 49
+4C 45 87 12 D4 4F 6E 44 2A 44 CA 4E 86 52 45 50
+45 41 54 00 87 12 54 50 16 50 2A 44 EE 4F 82 44
+4F 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40 CA 45
+00 00 2E 53 82 4E C4 1D A2 53 AC 1D 1A 42 AC 1D
+8A 43 00 00 30 4D C2 4B 84 4C 4F 4F 50 00 39 40
+EC 45 1A 42 C4 1D A2 52 C4 1D 8A 49 00 00 8A 4E
+02 00 1E 42 AC 1D A2 83 AC 1D 2E 4E 0E 93 04 24
+9E 42 C4 1D 00 00 F5 3F 3E 4F 30 4D E4 47 85 2B
+4C 4F 4F 50 39 40 DA 45 E4 3F A8 50 85 4C 45 41
+56 45 1A 42 C4 1D BA 40 FC 45 00 00 BA 40 BC 45
+02 00 B2 50 06 00 C4 1D A2 53 AC 1D 2A 52 19 42
+AC 1D 89 4A 00 00 30 4D EC 50 04 4D 4F 56 45 00
+0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24 08 99 0F 24
+06 2C F8 49 00 00 18 53 1A 83 FB 23 30 4D 08 5A
+09 5A 19 83 18 83 E8 49 00 00 1A 83 FA 23 30 4D
+34 44 CA 1D FC 44 2A 44 84 12 50 51 50 54 38 54
+7E 50 AC 4D 20 54 DE 50 1A 51 90 49 BE 51 F2 51
+2E 50 B2 52 48 45 58 4F C0 4E 68 4A 00 00 3A 40
+0C 00 39 40 CA 1D 38 40 CC 1D D9 3F 3A 40 0E 00
+39 40 CC 1D 38 40 CA 1D CC 3F 82 43 CC 1D 30 4D
+92 42 CA 1D C8 1D 30 4D 6C 4F 09 50 57 52 5F 53
+54 41 54 45 84 12 9A 4F 1C 54 66 5B AA 51 08 50
+57 52 5F 48 45 52 45 00 92 42 C4 1D BA 51 92 42
+C6 1D B8 51 EF 3F 6C 50 09 52 53 54 5F 53 54 41
+54 45 92 42 0C 18 BA 51 92 42 0E 18 B8 51 E2 3F
+D8 51 08 52 53 54 5F 48 45 52 45 00 92 42 C4 1D
+0C 18 92 42 C6 1D 0E 18 DF 3F B2 40 58 52 BA 52
+B2 40 A0 48 B0 48 B2 40 DC 48 F0 48 B2 40 DC 47
+EA 47 30 41 5C 50 04 57 49 50 45 00 39 40 80 FF
+B9 43 00 00 29 53 39 90 C6 FF FA 23 B0 12 0A 52
+B2 40 66 5B C4 1D B2 40 1C 54 C6 1D D7 3F D0 4F
+06 28 57 41 52 4D 29 00 1E 42 08 18 87 12 4E 49
+05 0D 1B 5B 37 6D 32 49 70 47 4E 49 27 20 46 61
+73 74 46 6F 72 74 68 20 56 31 36 30 20 31 36 4D
+48 7A 20 28 43 29 20 4A 2E 4D 2E 54 68 6F 6F 72
+65 6E 73 20 32 49 34 44 30 FF 84 47 2A 45 30 47
+4E 49 0B 62 79 74 65 73 20 66 72 65 65 20 34 4D
+26 52 04 57 41 52 4D 00 30 40 58 52 22 50 04 43
+4F 4C 44 00 B2 40 04 A5 20 01 B2 40 88 5A 5C 01
+92 43 04 02 B2 40 FE FF 02 02 A2 83 06 02 B2 43
+22 02 B2 D3 26 02 B2 43 42 02 B2 D3 46 02 B2 43
+62 02 B2 D3 66 02 B2 40 80 00 84 02 B2 40 7F FF
+82 02 B2 D0 7F FF 86 02 F2 43 22 03 F2 D3 26 03
+F2 40 A5 00 41 01 F2 40 10 00 40 01 D2 43 41 01
+F2 40 A5 00 61 01 B2 40 48 00 62 01 82 43 66 01
+39 40 80 00 B2 40 33 00 64 01 D2 43 61 01 92 D2
+9E 01 08 18 A2 93 08 18 01 24 59 07 38 40 C2 A2
+18 83 FE 23 19 83 FA 23 B2 42 B0 01 F2 D0 10 00
+2A 03 F2 C0 40 00 A2 04 3A 40 CA 52 39 40 C6 FF
+89 4A 00 00 29 53 FC 23 92 42 02 18 E4 FF B2 40
+18 00 0A 18 31 40 E0 1C 3F 40 80 1C 37 40 00 44
+36 40 B4 44 35 40 08 44 34 40 14 44 B2 40 0A 00
+DA 1D B2 43 DC 1D 92 C3 30 01 18 42 08 18 F2 B0
+10 00 20 02 04 20 38 E3 18 53 82 48 08 18 B2 40
+81 00 E0 05 B2 42 E6 05 B2 40 A1 F7 E8 05 F2 D0
+30 00 2A 02 92 C3 E0 05 92 D3 FA 05 3D 40 F6 53
+18 42 08 18 38 90 0A 00 21 27 38 90 16 00 1E 2F
+28 93 F7 22 DF 26 B8 52 84 12 50 51 44 5A F0 5A
+F8 59 44 5B BE 59 78 5A C2 56 00 00 B4 59 64 5A
+16 5A 54 5A D2 57 00 00 00 00 56 5B 7C 51 50 52
+85 48 49 32 4C 4F 87 12 84 47 E8 4F B0 4B B8 4E
+7E 51 F8 53 2A 44 BE 52 04 43 4F 44 45 00 B0 12
+CA 4D A2 82 C4 1D 87 12 F8 4E BC 45 30 54 4E 50
+03 41 53 4D 92 42 C8 1D B8 1D B2 40 FC 53 C8 1D
+EE 3F 00 00 07 45 4E 44 43 4F 44 45 87 12 8C 51
+18 4E 2A 44 64 54 06 45 4E 44 41 53 4D 00 92 42
+B8 1D C8 1D F3 3F 00 00 05 43 4F 4C 4F 4E 1A 42
+C4 1D BA 40 87 12 00 00 A2 53 C4 1D B2 43 B6 1D
+30 40 8C 51 00 00 05 4C 4F 32 48 49 1A 42 C4 1D
+BA 40 B0 12 00 00 BA 40 2A 44 02 00 A2 52 C4 1D
+ED 3F 38 40 BE 1D 39 48 2A 48 09 5A 1A 52 C2 1D
+09 9A 03 24 7E 9A FC 27 1A 83 0E 4A 2A 88 82 4A
+C2 1D 30 4D B0 12 2A 44 A8 49 00 4A 72 45 C0 45
+FA 54 BC 4A C0 45 BC 4D 1C 55 FC 54 29 4E 39 90
+86 12 02 20 2E 53 30 41 39 90 85 12 03 20 1E 4E
+02 00 30 41 39 90 84 12 01 20 2E 52 30 41 19 42
+C4 1D A2 53 C4 1D 89 4E 00 00 3E 40 29 00 12 12
+C2 1D 92 53 C2 1D B0 12 2A 44 A8 49 BC 4A C0 45
+4E 55 44 55 21 53 3E 90 10 00 BB 2D 30 41 50 55
+B2 41 C2 1D 22 D3 30 41 87 12 4C 46 C2 54 60 55
+82 43 BC 1D 92 42 C4 1D BA 1D A2 53 C4 1D 0A 4E
+3E 4F FA 90 23 00 00 00 34 20 92 53 C2 1D B0 12
+E4 54 0E 93 04 20 B2 40 00 03 BC 1D 27 3C 1E 93
+04 20 B2 40 10 03 BC 1D 21 3C 2E 93 04 20 B2 40
+20 03 BC 1D 1B 3C 2E 92 04 20 B2 40 20 02 BC 1D
+15 3C 3E 92 04 20 B2 40 30 02 BC 1D 0F 3C 3E 93
+04 20 B2 40 30 03 BC 1D 09 3C B2 40 30 00 BC 1D
+19 42 C4 1D A2 53 C4 1D 89 4E 00 00 3E 4F 3D 41
+30 4D FA 90 26 00 00 00 08 20 B2 40 10 02 BC 1D
+92 53 C2 1D 30 12 D0 55 75 3F FA 90 40 00 00 00
+1A 20 B2 40 20 00 BC 1D 92 53 C2 1D B0 12 2E 55
+0E 20 B2 50 10 00 BC 1D 3E 40 2B 00 B0 12 2E 55
+32 24 92 92 BE 1D C2 1D 02 24 92 53 C2 1D 8E 10
+82 5E BC 1D D3 3F B0 12 2E 55 F9 23 B2 50 10 00
+BC 1D 3E 40 28 00 B0 12 E4 54 30 12 20 56 67 3F
+87 12 4C 46 C2 54 58 56 FE 90 26 00 00 00 3E 40
+20 00 04 20 B2 50 82 00 BC 1D C2 3F B0 12 2E 55
+DF 23 B2 50 80 00 BC 1D 3E 40 28 00 B0 12 E4 54
+B0 12 1E 55 D5 23 3D 40 BC 4D 30 4D 00 00 04 52
+45 54 49 00 87 12 34 44 00 13 B0 4B 2A 44 34 44
+2C 00 58 55 50 56 A8 56 2E 4E 1E D2 BC 1D 19 42
+BA 1D 92 3F A6 54 03 4D 4F 56 84 12 9E 56 00 40
+B6 56 05 4D 4F 56 2E 42 84 12 9E 56 40 40 00 00
+03 41 44 44 84 12 9E 56 00 50 D0 56 05 41 44 44
+2E 42 84 12 9E 56 40 50 DC 56 04 41 44 44 43 00
+84 12 9E 56 00 60 EA 56 06 41 44 44 43 2E 42 00
+84 12 9E 56 40 60 8E 56 04 53 55 42 43 00 84 12
+9E 56 00 70 08 57 06 53 55 42 43 2E 42 00 84 12
+9E 56 40 70 16 57 03 53 55 42 84 12 9E 56 00 80
+26 57 05 53 55 42 2E 42 84 12 9E 56 40 80 88 54
+03 43 4D 50 84 12 9E 56 00 90 40 57 05 43 4D 50
+2E 42 84 12 9E 56 40 90 76 54 04 44 41 44 44 00
+84 12 9E 56 00 A0 5A 57 06 44 41 44 44 2E 42 00
+84 12 9E 56 40 A0 4C 57 03 42 49 54 84 12 9E 56
+00 B0 78 57 05 42 49 54 2E 42 84 12 9E 56 40 B0
+84 57 03 42 49 43 84 12 9E 56 00 C0 92 57 05 42
+49 43 2E 42 84 12 9E 56 40 C0 9E 57 03 42 49 53
+84 12 9E 56 00 D0 AC 57 05 42 49 53 2E 42 84 12
+9E 56 40 D0 00 00 03 58 4F 52 84 12 9E 56 00 E0
+C6 57 05 58 4F 52 2E 42 84 12 9E 56 40 E0 F8 56
+03 41 4E 44 84 12 9E 56 00 F0 E0 57 05 41 4E 44
+2E 42 84 12 9E 56 40 F0 4C 46 58 55 FE 57 1A 42
+BC 1D B2 F0 70 00 BC 1D 8A 10 3A F0 0F 00 82 DA
+BC 1D 4A 3F 32 57 03 52 52 43 84 12 F8 57 00 10
+16 58 05 52 52 43 2E 42 84 12 F8 57 40 10 22 58
+04 53 57 50 42 00 84 12 F8 57 80 10 30 58 03 52
+52 41 84 12 F8 57 00 11 3E 58 05 52 52 41 2E 42
+84 12 F8 57 40 11 4A 58 03 53 58 54 84 12 F8 57
+80 11 00 00 04 50 55 53 48 00 84 12 F8 57 00 12
+64 58 06 50 55 53 48 2E 42 00 84 12 F8 57 40 12
+B8 57 04 43 41 4C 4C 00 84 12 F8 57 80 12 34 44
+2C 00 58 55 50 56 98 58 59 42 BC 1D 5A 42 BD 1D
+82 4A BC 1D BE 90 00 15 00 00 02 20 0A 89 02 3C
+09 8A 0A 49 3A 90 10 00 03 2C 5A 0E A8 3F 1A 53
+0E 4A 87 12 70 47 4E 49 0D 6F 75 74 20 6F 66 20
+62 6F 75 6E 64 73 2E 4D 72 58 05 50 55 53 48 4D
+84 12 8E 58 00 15 DA 58 04 50 4F 50 4D 00 84 12
+8E 58 00 17 4C 46 C2 54 FA 58 82 43 BC 1D 92 42
+C4 1D BA 1D A2 53 C4 1D 92 53 C2 1D 3E 40 2C 00
+B0 12 2A 44 A8 49 BC 4A C0 45 BC 4D 50 56 20 59
+0A 4E 3E 4F 1A 83 2A 92 CA 2F 8A 10 5A 06 6F 3F
+58 58 04 52 52 43 4D 00 84 12 F4 58 50 00 32 59
+04 52 52 41 4D 00 84 12 F4 58 50 01 40 59 04 52
+4C 41 4D 00 84 12 F4 58 50 02 4E 59 04 52 52 55
+4D 00 84 12 F4 58 50 03 85 12 00 3C 5C 59 03 53
+3E 3D 85 12 00 38 6E 59 02 53 3C 00 85 12 00 34
+E8 58 03 30 3E 3D 85 12 00 30 82 59 02 30 3C 00
+85 12 00 30 00 00 02 55 3C 00 85 12 00 2C 96 59
+03 55 3E 3D 85 12 00 28 8C 59 03 30 3C 3E 85 12
+00 24 AA 59 02 30 3D 00 85 12 00 20 00 00 02 49
+46 00 1A 42 C4 1D 8A 4E 00 00 A2 53 C4 1D 0E 4A
+30 4D A0 59 04 54 48 45 4E 00 1A 42 C4 1D 08 4E
+3E 4F 09 48 29 53 0A 89 0A 11 3A 90 00 02 68 2F
+88 DA 00 00 30 4D 68 57 04 45 4C 53 45 00 1A 42
+C4 1D BA 40 00 3C 00 00 A2 53 C4 1D 2F 83 8F 4A
+00 00 E3 3F D4 59 05 55 4E 54 49 4C 3A 4F 08 4E
+3E 4F 19 42 C4 1D 2A 83 0A 89 0A 11 3A 90 00 FE
+47 3B 3A F0 FF 03 08 DA 89 48 00 00 A2 53 C4 1D
+30 4D EC 57 05 41 47 41 49 4E 87 12 68 59 1C 5A
+2A 44 00 00 05 57 48 49 4C 45 87 12 C2 59 6E 44
+2A 44 78 59 06 52 45 50 45 41 54 00 87 12 68 59
+1C 5A DA 59 2A 44 00 00 03 4A 4D 50 87 12 AE 4D
+68 59 1C 5A 2A 44 3E B0 00 10 03 20 3E E0 00 04
+30 4D 3E 90 00 34 06 28 03 24 3E 40 00 34 30 4D
+3E 40 00 38 30 4D 00 00 04 3F 4A 4D 50 00 87 12
+86 5A AE 4D 6E 44 1C 5A 2A 44 BC 5A 3D 41 08 4E
+3E 4F 2A 48 0A 93 04 20 98 42 C4 1D 00 00 30 4D
+88 43 00 00 A4 3F 82 58 03 42 57 31 84 12 BA 5A
+00 00 D8 5A 03 42 57 32 84 12 BA 5A 00 00 E4 5A
+03 42 57 33 84 12 BA 5A 00 00 FC 5A 3D 41 1A 42
+C4 1D 28 4E 08 93 08 20 BA 4F 00 00 A2 53 C4 1D
+8E 4A 00 00 3E 4F 30 4D 8E 43 00 00 61 3F 00 00
+03 46 57 31 84 12 FA 5A 00 00 20 5B 03 46 57 32
+84 12 FA 5A 00 00 2C 5B 03 46 57 33 84 12 FA 5A
+00 00 38 5B 04 47 4F 54 4F 00 87 12 68 59 AE 4D
+A6 4B 2A 44 A8 5A 05 3F 47 4F 54 4F 87 12 86 5A
+AE 4D A6 4B 2A 44
+@FFC6
+CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52
+CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 4C 48
+CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52
+CA 52 CA 52 CA 52 CA 52 CA 52
+q
--- /dev/null
+@1800
+10 00 4C 48 80 3E 30 75 FD FF 18 00 68 5B 1E 54
+2A 48 38 48 00 00 00 00
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@4400
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 44
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 44 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 44 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E 44 02 3E 52 00 0E 12 3E 4F 30 4D 8E 44
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 44
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C 44 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 44 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 45
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 44 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA 44 03 41 4E 44 3E FF 30 4D 7A 44 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E 45 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 45 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E 45 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 45 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 44 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE 45 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 45 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 45 03 3E 49 4E 85 12 C2 1D 10 45
+04 42 41 53 45 00 85 12 DA 1D C0 44 05 53 54 41
+54 45 85 12 B6 1D 30 46 02 42 4C 00 85 12 20 00
+94 45 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 46 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E 46 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 46 02 23 53 00 87 12 98 46
+D2 46 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 46 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 46 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C 46 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 45 03 55 44 2E 87 12 56 46
+CC 46 E6 46 32 49 FA 48 2A 44 18 47 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA 44
+02 44 2E 00 87 12 56 46 6E 44 80 44 3A 47 CC 46
+92 44 0A 47 E6 46 32 49 FA 48 2A 44 52 45 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 46 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 45 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 46 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A 48
+92 B3 FC 05 FD 27 1E 42 EC 05 B0 12 38 48 30 4D
+30 40 B6 47 7E 47 05 28 4B 45 59 29 18 42 EC 05
+EA 3F 12 46 03 4B 45 59 30 40 DC 47 92 47 06 41
+43 43 45 50 54 00 3C 40 8A 48 3B 40 54 48 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+7E 48 92 B3 FC 05 05 24 18 42 EC 05 38 90 0A 00
+04 20 21 53 39 40 46 48 4D 15 B2 40 11 00 EE 05
+A2 B3 FC 05 FD 27 30 41 B2 40 13 00 EE 05 A2 B3
+FC 05 FD 27 30 41 12 D2 0A 18 FD 3F 21 52 3A 17
+58 42 EC 05 48 9B F0 27 48 9C 06 2C 78 92 11 20
+2E 9F 0F 24 1E 83 05 3C 0E 9A 03 24 CE 48 00 00
+1E 53 82 48 EE 05 A2 B3 FC 05 FD 27 30 4D 80 48
+2D 83 92 B3 FC 05 FD 27 E3 23 B2 40 18 00 0A 18
+3E 8F 3D 41 30 4D D6 47 06 28 45 4D 49 54 29 00
+08 4E 3E 4F E6 3F 50 47 04 45 4D 49 54 00 30 40
+A0 48 A8 48 04 45 43 48 4F 00 B2 40 82 48 72 48
+30 4D 6E 47 06 4E 4F 45 43 48 4F 00 B2 40 30 4D
+72 48 30 4D 98 48 04 28 43 52 29 00 2F 83 8F 4E
+00 00 3E 40 0D 00 E3 3F A2 47 02 43 52 00 30 40
+DC 48 04 47 05 53 50 41 43 45 2F 83 8F 4E 00 00
+3E 40 20 00 D4 3F F4 48 06 53 50 41 43 45 53 00
+0E 93 09 24 0D 12 3D 40 1C 49 EF 3F 1E 49 2D 83
+1E 83 EB 23 3D 41 3E 4F 30 4D 2C 47 04 54 59 50
+45 00 0E 93 95 24 2A 4F 8F 5E 00 00 0E 4A 87 12
+CA 45 02 46 0A 45 AE 48 EC 45 42 49 2A 44 2F 82
+8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E 1D B3 0D 63
+30 4D 08 49 82 53 22 00 87 12 34 44 4E 49 B0 4B
+34 44 22 00 A8 49 78 49 3D 41 6E 4E 1E 83 82 5E
+C4 1D 3E 4F 92 B3 C4 1D A2 63 C4 1D 30 4D C4 48
+82 2E 22 00 87 12 68 49 34 44 32 49 B0 4B 2A 44
+00 00 04 57 4F 52 44 00 3C 40 BE 1D 39 4C 3A 4C
+09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A FC 27 1A 83
+3B 40 60 00 C8 4C 00 00 09 9A 0C 24 7C 4A 4E 9C
+09 24 18 53 4B 9C F6 2F 7C 90 7B 00 F3 2F 7C 80
+20 00 F0 3F 1A 82 C0 1D 82 4A C2 1D 1E 42 C4 1D
+08 8E CE 48 00 00 30 4D 00 00 04 46 49 4E 44 00
+2F 83 0C 4E 65 4C 74 40 80 00 3B 40 CA 1D 3E 4B
+0E 93 1E 24 58 4C 01 00 78 F0 1E 00 0E 58 2E 53
+1E 4E FE FF 0E 93 F3 27 09 4E 78 49 48 C4 48 95
+F7 23 0A 4C 1A 53 FA 99 00 00 F2 23 58 83 FA 23
+19 B3 09 63 0C 49 6A 4E 1E 43 4A 93 01 30 2E 83
+8F 4C 00 00 35 40 08 44 34 40 14 44 30 4D 2F 53
+2F 53 3E 4F 30 4D 26 46 07 3E 4E 55 4D 42 45 52
+3C 4F 38 4F 29 4F 2F 82 1B 42 DA 1D 6A 4C 7A 80
+30 00 7A 90 0A 00 02 28 7A 80 07 00 0A 9B 13 2C
+82 49 D0 04 82 48 D2 04 82 4B C8 04 19 42 E4 04
+18 42 E6 04 09 5A 08 63 1C 53 1E 83 E7 23 8F 49
+04 00 8F 48 02 00 8F 4C 00 00 30 4D 03 12 0D 12
+1B 42 DA 1D 0B 12 32 C0 00 02 6D 4E 0D 5E 0C 4E
+7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23 32 D0 00 02
+FC 4C FE FF 0D 9C FC 2F DE 83 00 00 09 43 08 43
+3D 40 32 4B 3F 82 8F 4E 06 00 0C 4E 7E 4C 6A 4C
+7A 90 2D 00 10 2C 3B 40 10 00 7A 80 24 00 06 24
+2B 43 5A 83 03 24 3B 52 6A 53 B0 23 1C 53 1E 83
+6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83 B1 43 04 00
+A5 3F 34 4B 2F 53 0E 93 2C 17 82 4C DA 1D 03 24
+2F 52 0E F3 30 4D 8F 93 00 00 15 20 32 B0 00 02
+14 20 0E 93 05 24 1A 4F 02 00 1A 83 0A 93 0B 38
+2F 53 BF 4F 00 00 3E E3 05 20 BF E3 00 00 9F 53
+00 00 3E E3 30 4D 32 D0 00 02 9F 4F 02 00 04 00
+BF 4F 00 00 3E E3 F6 23 BF E3 02 00 BF E3 00 00
+9F 53 02 00 8F 63 00 00 3E E3 30 4D B4 48 07 45
+58 45 43 55 54 45 0A 4E 3E 4F 00 4A 28 45 01 2C
+1A 42 C4 1D A2 53 C4 1D 8A 4E 00 00 3E 4F 30 4D
+AE 4B 87 4C 49 54 45 52 41 4C 82 93 B6 1D 16 24
+32 B0 00 02 09 24 1A 42 C4 1D A2 52 C4 1D BA 40
+34 44 00 00 BA 4F 02 00 1A 42 C4 1D A2 52 C4 1D
+BA 40 34 44 00 00 8A 4E 02 00 3E 4F 30 4D EA 48
+05 43 4F 55 4E 54 2F 83 1E 53 8F 4E 00 00 5E 4E
+FF FF 30 4D 82 4E BE 1D B2 4F C0 1D 3E 4F 82 43
+C2 1D 87 12 4C 46 A8 49 2A 4C 3D 40 36 4C E8 22
+3D 41 3E 4F 30 4D 38 4C 0A 4E 3E 4F 3D 40 4E 4C
+3D 27 3D 40 24 4C 1A E2 B6 1D B2 27 AC 23 50 4C
+3E 4F 3D 40 24 4C B9 23 DE 53 00 00 68 4E 08 5E
+F8 40 3F 00 00 00 3D 40 16 4E CD 3F 9E 4B 08 45
+56 41 4C 55 41 54 45 00 39 40 BE 1D 39 12 39 12
+39 12 0D 12 B0 12 2A 44 14 4C 8C 4C 3D 41 B2 41
+C2 1D B2 41 C0 1D B2 41 BE 1D 30 4D 7A 45 04 51
+55 49 54 00 31 40 E0 1C B2 40 00 1C AC 1D 82 43
+B6 1D 82 43 08 18 B0 12 2A 44 4E 49 04 0D 6F 6B
+20 00 32 49 34 44 38 1D 44 44 34 44 50 00 F6 47
+FA 48 14 4C 34 44 7E 1C CE 44 B2 45 4E 49 0D 73
+74 61 63 6B 20 65 6D 70 74 79 20 21 28 4D 34 44
+30 FF 84 47 B2 45 4E 49 0B 46 52 41 4D 20 66 75
+6C 6C 20 21 28 4D 42 46 F4 44 C0 45 BA 4C 4E 49
+04 0D 20 20 20 00 BC 45 C2 4C EE 47 05 41 42 4F
+52 54 3F 40 80 1C BE 3F 8F 93 02 00 98 26 B2 40
+82 48 72 48 B0 12 10 52 82 43 E2 5A 82 43 EE 5A
+82 43 FA 5A 82 43 2A 5B 82 43 36 5B 82 43 42 5B
+A2 B3 FC 05 FD 27 B2 40 11 00 EE 05 92 C3 FC 05
+38 40 A0 AA 39 42 19 83 FE 23 18 83 FB 23 92 B3
+FC 05 F4 23 87 12 4E 49 04 1B 5B 37 6D 00 32 49
+32 49 4E 49 04 1B 5B 30 6D 00 32 49 58 51 9A 51
+A0 51 22 4D 1C 4D 86 41 42 4F 52 54 22 00 87 12
+68 49 34 44 28 4D B0 4B 2A 44 FA 49 01 27 87 12
+4C 46 A8 49 00 4A C0 45 BC 4D 2A 44 58 4C 52 46
+81 5C 92 42 BE 1D C2 1D 30 4D 87 12 84 49 4C 46
+A8 49 D4 4D 08 4E 7A 4E 5A D3 5A 53 0A 58 19 42
+C8 1D 6E 4E 3E F0 1E 00 09 5E 82 48 AE 1D 82 49
+B0 1D 82 4A B2 1D 2A 52 82 4A C4 1D 3E 4F 3D 41
+30 41 87 12 4E 49 0F 73 74 61 63 6B 20 6D 69 73
+6D 61 74 63 68 21 2E 4D 82 9F B4 1D F2 23 18 42
+AE 1D 19 42 B0 1D A8 49 FE FF 89 48 00 00 30 4D
+A2 49 08 56 41 52 49 41 42 4C 45 00 B0 12 CA 4D
+BA 40 86 12 FC FF EF 3F 00 4C 08 43 4F 4E 53 54
+41 4E 54 00 B0 12 CA 4D BA 40 85 12 FC FF 8A 4E
+FE FF 3E 4F E0 3F 4A 4E 06 43 52 45 41 54 45 00
+B0 12 CA 4D BA 40 85 12 FC FF 8A 4A FE FF D3 3F
+6E 4C 05 44 4F 45 53 3E 1A 42 B2 1D BA 40 84 12
+00 00 8A 4D 02 00 3D 41 30 4D 82 4E 05 44 45 46
+45 52 B0 12 CA 4D BA 40 30 40 FC FF BA 40 98 4E
+FE FF B9 3F 00 00 81 5B 82 43 B6 1D 30 4D C0 4D
+01 5D B2 43 B6 1D 30 4D 64 49 87 52 45 43 55 52
+53 45 19 42 C4 1D 99 42 B2 1D 00 00 A2 53 C4 1D
+30 4D B6 4E 01 3A B0 12 CA 4D BA 40 87 12 FC FF
+A2 83 C4 1D B2 43 B6 1D 82 4F B4 1D 30 4D E4 4E
+81 3B 82 93 B6 1D 5D 27 87 12 34 44 2A 44 B0 4B
+18 4E B8 4E 2A 44 D6 48 09 49 4D 4D 45 44 49 41
+54 45 1A 42 AE 1D FA D0 80 00 00 00 30 4D BE 4F
+02 00 3E 4F 30 4D 18 4F 82 49 53 00 87 12 42 46
+F4 44 C0 45 50 4F 5C 4F 34 44 2E 4F B0 4B 2A 44
+AE 4D 2E 4F 2A 44 00 4F 83 5B 27 5D 87 12 AE 4D
+34 44 34 44 B0 4B B0 4B 2A 44 9E 4C 88 50 4F 53
+54 50 4F 4E 45 00 87 12 4C 46 A8 49 00 4A 54 44
+C0 45 BC 4D 7E 45 C0 45 96 4F 34 44 34 44 B0 4B
+B0 4B 34 44 B0 4B B0 4B 2A 44 9C 4F 3A 4E 82 4A
+C6 1D 2E 4E 82 4E C4 1D 3D 40 10 00 09 4A 08 49
+29 83 18 48 FE FF 0E 98 FC 2B 89 48 00 00 1D 83
+F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41 30 4D 38 4F
+82 49 46 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40
+C0 45 00 00 A2 52 C4 1D 2E 53 30 4D 9C 4E 84 45
+4C 53 45 00 1A 42 C4 1D BA 40 BC 45 00 00 2A 52
+82 4A C4 1D 8E 4A 00 00 2A 83 0E 4A 30 4D 2C 49
+84 54 48 45 4E 00 9E 42 C4 1D 00 00 3E 4F 30 4D
+68 4E 85 42 45 47 49 4E 30 40 84 47 10 50 85 55
+4E 54 49 4C 39 40 C0 45 1A 42 C4 1D A2 52 C4 1D
+8A 49 00 00 8A 4E 02 00 3E 4F 30 4D 96 4D 85 41
+47 41 49 4E 39 40 BC 45 EF 3F 32 4E 85 57 48 49
+4C 45 87 12 D4 4F 6E 44 2A 44 CA 4E 86 52 45 50
+45 41 54 00 87 12 54 50 16 50 2A 44 EE 4F 82 44
+4F 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40 CA 45
+00 00 2E 53 82 4E C4 1D A2 53 AC 1D 1A 42 AC 1D
+8A 43 00 00 30 4D C2 4B 84 4C 4F 4F 50 00 39 40
+EC 45 1A 42 C4 1D A2 52 C4 1D 8A 49 00 00 8A 4E
+02 00 1E 42 AC 1D A2 83 AC 1D 2E 4E 0E 93 04 24
+9E 42 C4 1D 00 00 F5 3F 3E 4F 30 4D E4 47 85 2B
+4C 4F 4F 50 39 40 DA 45 E4 3F A8 50 85 4C 45 41
+56 45 1A 42 C4 1D BA 40 FC 45 00 00 BA 40 BC 45
+02 00 B2 50 06 00 C4 1D A2 53 AC 1D 2A 52 19 42
+AC 1D 89 4A 00 00 30 4D EC 50 04 4D 4F 56 45 00
+0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24 08 99 0F 24
+06 2C F8 49 00 00 18 53 1A 83 FB 23 30 4D 08 5A
+09 5A 19 83 18 83 E8 49 00 00 1A 83 FA 23 30 4D
+34 44 CA 1D FC 44 2A 44 84 12 50 51 52 54 3A 54
+7E 50 AC 4D 22 54 DE 50 1A 51 90 49 BE 51 F2 51
+2E 50 B2 52 48 45 58 4F C0 4E 68 4A 00 00 3A 40
+0C 00 39 40 CA 1D 38 40 CC 1D D9 3F 3A 40 0E 00
+39 40 CC 1D 38 40 CA 1D CC 3F 82 43 CC 1D 30 4D
+92 42 CA 1D C8 1D 30 4D 6C 4F 09 50 57 52 5F 53
+54 41 54 45 84 12 9A 4F 1E 54 68 5B AA 51 08 50
+57 52 5F 48 45 52 45 00 92 42 C4 1D BA 51 92 42
+C6 1D B8 51 EF 3F 6C 50 09 52 53 54 5F 53 54 41
+54 45 92 42 0C 18 BA 51 92 42 0E 18 B8 51 E2 3F
+D8 51 08 52 53 54 5F 48 45 52 45 00 92 42 C4 1D
+0C 18 92 42 C6 1D 0E 18 DF 3F B2 40 58 52 BA 52
+B2 40 A0 48 B0 48 B2 40 DC 48 F0 48 B2 40 DC 47
+EA 47 30 41 5C 50 04 57 49 50 45 00 39 40 80 FF
+B9 43 00 00 29 53 39 90 C6 FF FA 23 B0 12 0A 52
+B2 40 68 5B C4 1D B2 40 1E 54 C6 1D D7 3F D0 4F
+06 28 57 41 52 4D 29 00 1E 42 08 18 87 12 4E 49
+05 0D 1B 5B 37 6D 32 49 70 47 4E 49 27 20 46 61
+73 74 46 6F 72 74 68 20 56 31 36 30 20 31 36 4D
+48 7A 20 28 43 29 20 4A 2E 4D 2E 54 68 6F 6F 72
+65 6E 73 20 32 49 34 44 30 FF 84 47 2A 45 30 47
+4E 49 0B 62 79 74 65 73 20 66 72 65 65 20 34 4D
+26 52 04 57 41 52 4D 00 30 40 58 52 22 50 04 43
+4F 4C 44 00 B2 40 04 A5 20 01 B2 40 88 5A 5C 01
+92 43 04 02 B2 40 FE FF 02 02 A2 83 06 02 B2 43
+22 02 B2 D3 26 02 B2 43 42 02 B2 D3 46 02 B2 43
+62 02 B2 D3 66 02 B2 40 80 00 84 02 B2 40 7F FF
+82 02 B2 D0 7F FF 86 02 F2 43 22 03 F2 D3 26 03
+F2 40 A5 00 41 01 F2 40 10 00 40 01 D2 43 41 01
+F2 40 A5 00 61 01 B2 40 48 00 62 01 82 43 66 01
+39 40 80 00 B2 40 33 00 64 01 D2 43 61 01 92 D2
+9E 01 08 18 A2 93 08 18 01 24 59 07 38 40 C2 A2
+18 83 FE 23 19 83 FA 23 B2 42 B0 01 F2 D0 10 00
+2A 03 F2 C0 40 00 A2 04 3A 40 CA 52 39 40 C6 FF
+89 4A 00 00 29 53 FC 23 92 42 02 18 E4 FF B2 40
+18 00 0A 18 31 40 E0 1C 3F 40 80 1C 37 40 00 44
+36 40 B4 44 35 40 08 44 34 40 14 44 B2 40 0A 00
+DA 1D B2 43 DC 1D 92 C3 30 01 18 42 08 18 F2 B0
+10 00 20 02 04 20 38 E3 18 53 82 48 08 18 B2 40
+81 00 E0 05 B2 40 05 00 E6 05 B2 40 00 49 E8 05
+F2 D0 30 00 2A 02 92 C3 E0 05 92 D3 FA 05 3D 40
+F8 53 18 42 08 18 38 90 0A 00 20 27 38 90 16 00
+1D 2F 28 93 F6 22 DE 26 B8 52 84 12 50 51 46 5A
+F2 5A FA 59 46 5B C0 59 7A 5A C4 56 00 00 B6 59
+66 5A 18 5A 56 5A D4 57 00 00 00 00 58 5B 7C 51
+50 52 85 48 49 32 4C 4F 87 12 84 47 E8 4F B0 4B
+B8 4E 7E 51 FA 53 2A 44 BE 52 04 43 4F 44 45 00
+B0 12 CA 4D A2 82 C4 1D 87 12 F8 4E BC 45 32 54
+4E 50 03 41 53 4D 92 42 C8 1D B8 1D B2 40 FE 53
+C8 1D EE 3F 00 00 07 45 4E 44 43 4F 44 45 87 12
+8C 51 18 4E 2A 44 66 54 06 45 4E 44 41 53 4D 00
+92 42 B8 1D C8 1D F3 3F 00 00 05 43 4F 4C 4F 4E
+1A 42 C4 1D BA 40 87 12 00 00 A2 53 C4 1D B2 43
+B6 1D 30 40 8C 51 00 00 05 4C 4F 32 48 49 1A 42
+C4 1D BA 40 B0 12 00 00 BA 40 2A 44 02 00 A2 52
+C4 1D ED 3F 38 40 BE 1D 39 48 2A 48 09 5A 1A 52
+C2 1D 09 9A 03 24 7E 9A FC 27 1A 83 0E 4A 2A 88
+82 4A C2 1D 30 4D B0 12 2A 44 A8 49 00 4A 72 45
+C0 45 FC 54 BC 4A C0 45 BC 4D 1E 55 FE 54 29 4E
+39 90 86 12 02 20 2E 53 30 41 39 90 85 12 03 20
+1E 4E 02 00 30 41 39 90 84 12 01 20 2E 52 30 41
+19 42 C4 1D A2 53 C4 1D 89 4E 00 00 3E 40 29 00
+12 12 C2 1D 92 53 C2 1D B0 12 2A 44 A8 49 BC 4A
+C0 45 50 55 46 55 21 53 3E 90 10 00 BB 2D 30 41
+52 55 B2 41 C2 1D 22 D3 30 41 87 12 4C 46 C4 54
+62 55 82 43 BC 1D 92 42 C4 1D BA 1D A2 53 C4 1D
+0A 4E 3E 4F FA 90 23 00 00 00 34 20 92 53 C2 1D
+B0 12 E6 54 0E 93 04 20 B2 40 00 03 BC 1D 27 3C
+1E 93 04 20 B2 40 10 03 BC 1D 21 3C 2E 93 04 20
+B2 40 20 03 BC 1D 1B 3C 2E 92 04 20 B2 40 20 02
+BC 1D 15 3C 3E 92 04 20 B2 40 30 02 BC 1D 0F 3C
+3E 93 04 20 B2 40 30 03 BC 1D 09 3C B2 40 30 00
+BC 1D 19 42 C4 1D A2 53 C4 1D 89 4E 00 00 3E 4F
+3D 41 30 4D FA 90 26 00 00 00 08 20 B2 40 10 02
+BC 1D 92 53 C2 1D 30 12 D2 55 75 3F FA 90 40 00
+00 00 1A 20 B2 40 20 00 BC 1D 92 53 C2 1D B0 12
+30 55 0E 20 B2 50 10 00 BC 1D 3E 40 2B 00 B0 12
+30 55 32 24 92 92 BE 1D C2 1D 02 24 92 53 C2 1D
+8E 10 82 5E BC 1D D3 3F B0 12 30 55 F9 23 B2 50
+10 00 BC 1D 3E 40 28 00 B0 12 E6 54 30 12 22 56
+67 3F 87 12 4C 46 C4 54 5A 56 FE 90 26 00 00 00
+3E 40 20 00 04 20 B2 50 82 00 BC 1D C2 3F B0 12
+30 55 DF 23 B2 50 80 00 BC 1D 3E 40 28 00 B0 12
+E6 54 B0 12 20 55 D5 23 3D 40 BC 4D 30 4D 00 00
+04 52 45 54 49 00 87 12 34 44 00 13 B0 4B 2A 44
+34 44 2C 00 5A 55 52 56 AA 56 2E 4E 1E D2 BC 1D
+19 42 BA 1D 92 3F A8 54 03 4D 4F 56 84 12 A0 56
+00 40 B8 56 05 4D 4F 56 2E 42 84 12 A0 56 40 40
+00 00 03 41 44 44 84 12 A0 56 00 50 D2 56 05 41
+44 44 2E 42 84 12 A0 56 40 50 DE 56 04 41 44 44
+43 00 84 12 A0 56 00 60 EC 56 06 41 44 44 43 2E
+42 00 84 12 A0 56 40 60 90 56 04 53 55 42 43 00
+84 12 A0 56 00 70 0A 57 06 53 55 42 43 2E 42 00
+84 12 A0 56 40 70 18 57 03 53 55 42 84 12 A0 56
+00 80 28 57 05 53 55 42 2E 42 84 12 A0 56 40 80
+8A 54 03 43 4D 50 84 12 A0 56 00 90 42 57 05 43
+4D 50 2E 42 84 12 A0 56 40 90 78 54 04 44 41 44
+44 00 84 12 A0 56 00 A0 5C 57 06 44 41 44 44 2E
+42 00 84 12 A0 56 40 A0 4E 57 03 42 49 54 84 12
+A0 56 00 B0 7A 57 05 42 49 54 2E 42 84 12 A0 56
+40 B0 86 57 03 42 49 43 84 12 A0 56 00 C0 94 57
+05 42 49 43 2E 42 84 12 A0 56 40 C0 A0 57 03 42
+49 53 84 12 A0 56 00 D0 AE 57 05 42 49 53 2E 42
+84 12 A0 56 40 D0 00 00 03 58 4F 52 84 12 A0 56
+00 E0 C8 57 05 58 4F 52 2E 42 84 12 A0 56 40 E0
+FA 56 03 41 4E 44 84 12 A0 56 00 F0 E2 57 05 41
+4E 44 2E 42 84 12 A0 56 40 F0 4C 46 5A 55 00 58
+1A 42 BC 1D B2 F0 70 00 BC 1D 8A 10 3A F0 0F 00
+82 DA BC 1D 4A 3F 34 57 03 52 52 43 84 12 FA 57
+00 10 18 58 05 52 52 43 2E 42 84 12 FA 57 40 10
+24 58 04 53 57 50 42 00 84 12 FA 57 80 10 32 58
+03 52 52 41 84 12 FA 57 00 11 40 58 05 52 52 41
+2E 42 84 12 FA 57 40 11 4C 58 03 53 58 54 84 12
+FA 57 80 11 00 00 04 50 55 53 48 00 84 12 FA 57
+00 12 66 58 06 50 55 53 48 2E 42 00 84 12 FA 57
+40 12 BA 57 04 43 41 4C 4C 00 84 12 FA 57 80 12
+34 44 2C 00 5A 55 52 56 9A 58 59 42 BC 1D 5A 42
+BD 1D 82 4A BC 1D BE 90 00 15 00 00 02 20 0A 89
+02 3C 09 8A 0A 49 3A 90 10 00 03 2C 5A 0E A8 3F
+1A 53 0E 4A 87 12 70 47 4E 49 0D 6F 75 74 20 6F
+66 20 62 6F 75 6E 64 73 2E 4D 74 58 05 50 55 53
+48 4D 84 12 90 58 00 15 DC 58 04 50 4F 50 4D 00
+84 12 90 58 00 17 4C 46 C4 54 FC 58 82 43 BC 1D
+92 42 C4 1D BA 1D A2 53 C4 1D 92 53 C2 1D 3E 40
+2C 00 B0 12 2A 44 A8 49 BC 4A C0 45 BC 4D 52 56
+22 59 0A 4E 3E 4F 1A 83 2A 92 CA 2F 8A 10 5A 06
+6F 3F 5A 58 04 52 52 43 4D 00 84 12 F6 58 50 00
+34 59 04 52 52 41 4D 00 84 12 F6 58 50 01 42 59
+04 52 4C 41 4D 00 84 12 F6 58 50 02 50 59 04 52
+52 55 4D 00 84 12 F6 58 50 03 85 12 00 3C 5E 59
+03 53 3E 3D 85 12 00 38 70 59 02 53 3C 00 85 12
+00 34 EA 58 03 30 3E 3D 85 12 00 30 84 59 02 30
+3C 00 85 12 00 30 00 00 02 55 3C 00 85 12 00 2C
+98 59 03 55 3E 3D 85 12 00 28 8E 59 03 30 3C 3E
+85 12 00 24 AC 59 02 30 3D 00 85 12 00 20 00 00
+02 49 46 00 1A 42 C4 1D 8A 4E 00 00 A2 53 C4 1D
+0E 4A 30 4D A2 59 04 54 48 45 4E 00 1A 42 C4 1D
+08 4E 3E 4F 09 48 29 53 0A 89 0A 11 3A 90 00 02
+68 2F 88 DA 00 00 30 4D 6A 57 04 45 4C 53 45 00
+1A 42 C4 1D BA 40 00 3C 00 00 A2 53 C4 1D 2F 83
+8F 4A 00 00 E3 3F D6 59 05 55 4E 54 49 4C 3A 4F
+08 4E 3E 4F 19 42 C4 1D 2A 83 0A 89 0A 11 3A 90
+00 FE 47 3B 3A F0 FF 03 08 DA 89 48 00 00 A2 53
+C4 1D 30 4D EE 57 05 41 47 41 49 4E 87 12 6A 59
+1E 5A 2A 44 00 00 05 57 48 49 4C 45 87 12 C4 59
+6E 44 2A 44 7A 59 06 52 45 50 45 41 54 00 87 12
+6A 59 1E 5A DC 59 2A 44 00 00 03 4A 4D 50 87 12
+AE 4D 6A 59 1E 5A 2A 44 3E B0 00 10 03 20 3E E0
+00 04 30 4D 3E 90 00 34 06 28 03 24 3E 40 00 34
+30 4D 3E 40 00 38 30 4D 00 00 04 3F 4A 4D 50 00
+87 12 88 5A AE 4D 6E 44 1E 5A 2A 44 BE 5A 3D 41
+08 4E 3E 4F 2A 48 0A 93 04 20 98 42 C4 1D 00 00
+30 4D 88 43 00 00 A4 3F 84 58 03 42 57 31 84 12
+BC 5A 00 00 DA 5A 03 42 57 32 84 12 BC 5A 00 00
+E6 5A 03 42 57 33 84 12 BC 5A 00 00 FE 5A 3D 41
+1A 42 C4 1D 28 4E 08 93 08 20 BA 4F 00 00 A2 53
+C4 1D 8E 4A 00 00 3E 4F 30 4D 8E 43 00 00 61 3F
+00 00 03 46 57 31 84 12 FC 5A 00 00 22 5B 03 46
+57 32 84 12 FC 5A 00 00 2E 5B 03 46 57 33 84 12
+FC 5A 00 00 3A 5B 04 47 4F 54 4F 00 87 12 6A 59
+AE 4D A6 4B 2A 44 AA 5A 05 3F 47 4F 54 4F 87 12
+88 5A AE 4D A6 4B 2A 44
+@FFC6
+CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52
+CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 4C 48
+CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52
+CA 52 CA 52 CA 52 CA 52 CA 52
+q
--- /dev/null
+@1800
+10 00 40 48 F4 01 80 04 FD FF 18 00 48 5B FE 53
+2A 48 32 48 00 00 00 00
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@4400
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 44
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 44 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 44 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E 44 02 3E 52 00 0E 12 3E 4F 30 4D 8E 44
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 44
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C 44 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 44 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 45
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 44 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA 44 03 41 4E 44 3E FF 30 4D 7A 44 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E 45 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 45 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E 45 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 45 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 44 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE 45 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 45 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 45 03 3E 49 4E 85 12 C2 1D 10 45
+04 42 41 53 45 00 85 12 DA 1D C0 44 05 53 54 41
+54 45 85 12 B6 1D 30 46 02 42 4C 00 85 12 20 00
+94 45 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 46 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E 46 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 46 02 23 53 00 87 12 98 46
+D2 46 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 46 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 46 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C 46 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 45 03 55 44 2E 87 12 56 46
+CC 46 E6 46 26 49 EE 48 2A 44 18 47 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA 44
+02 44 2E 00 87 12 56 46 6E 44 80 44 3A 47 CC 46
+92 44 0A 47 E6 46 26 49 EE 48 2A 44 52 45 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 46 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 45 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 46 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A 48
+92 B3 FC 05 FD 27 1E 42 EC 05 B0 12 32 48 30 4D
+30 40 B6 47 7E 47 05 28 4B 45 59 29 18 42 EC 05
+EA 3F 12 46 03 4B 45 59 30 40 DC 47 92 47 06 41
+43 43 45 50 54 00 3C 40 78 48 3B 40 48 48 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+6C 48 92 B3 FC 05 05 24 18 42 EC 05 38 90 0A 00
+04 20 21 53 39 40 3A 48 4D 15 B2 40 11 00 EE 05
+30 41 B2 40 13 00 EE 05 30 41 12 D2 0A 18 FD 3F
+21 52 3A 17 58 42 EC 05 48 9B F3 27 48 9C 06 2C
+78 92 0E 20 2E 9F 0C 24 1E 83 05 3C 0E 9A 03 24
+CE 48 00 00 1E 53 82 48 EE 05 30 4D 6E 48 2D 83
+92 B3 FC 05 FD 27 E6 23 B2 40 18 00 0A 18 3E 8F
+3D 41 30 4D D6 47 06 28 45 4D 49 54 29 00 08 4E
+3E 4F A2 B3 FC 05 FD 27 E6 3F 50 47 04 45 4D 49
+54 00 30 40 8E 48 9C 48 04 45 43 48 4F 00 B2 40
+82 48 66 48 30 4D 6E 47 06 4E 4F 45 43 48 4F 00
+B2 40 30 4D 66 48 30 4D 86 48 04 28 43 52 29 00
+2F 83 8F 4E 00 00 3E 40 0D 00 E3 3F A2 47 02 43
+52 00 30 40 D0 48 04 47 05 53 50 41 43 45 2F 83
+8F 4E 00 00 3E 40 20 00 D4 3F E8 48 06 53 50 41
+43 45 53 00 0E 93 09 24 0D 12 3D 40 10 49 EF 3F
+12 49 2D 83 1E 83 EB 23 3D 41 3E 4F 30 4D 2C 47
+04 54 59 50 45 00 0E 93 95 24 2A 4F 8F 5E 00 00
+0E 4A 87 12 CA 45 02 46 0A 45 A2 48 EC 45 36 49
+2A 44 2F 82 8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E
+1D B3 0D 63 30 4D FC 48 82 53 22 00 87 12 34 44
+42 49 A4 4B 34 44 22 00 9C 49 6C 49 3D 41 6E 4E
+1E 83 82 5E C4 1D 3E 4F 92 B3 C4 1D A2 63 C4 1D
+30 4D B8 48 82 2E 22 00 87 12 5C 49 34 44 26 49
+A4 4B 2A 44 00 00 04 57 4F 52 44 00 3C 40 BE 1D
+39 4C 3A 4C 09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A
+FC 27 1A 83 3B 40 60 00 C8 4C 00 00 09 9A 0C 24
+7C 4A 4E 9C 09 24 18 53 4B 9C F6 2F 7C 90 7B 00
+F3 2F 7C 80 20 00 F0 3F 1A 82 C0 1D 82 4A C2 1D
+1E 42 C4 1D 08 8E CE 48 00 00 30 4D 00 00 04 46
+49 4E 44 00 2F 83 0C 4E 65 4C 74 40 80 00 3B 40
+CA 1D 3E 4B 0E 93 1E 24 58 4C 01 00 78 F0 1E 00
+0E 58 2E 53 1E 4E FE FF 0E 93 F3 27 09 4E 78 49
+48 C4 48 95 F7 23 0A 4C 1A 53 FA 99 00 00 F2 23
+58 83 FA 23 19 B3 09 63 0C 49 6A 4E 1E 43 4A 93
+01 30 2E 83 8F 4C 00 00 35 40 08 44 34 40 14 44
+30 4D 2F 53 2F 53 3E 4F 30 4D 26 46 07 3E 4E 55
+4D 42 45 52 3C 4F 38 4F 29 4F 2F 82 1B 42 DA 1D
+6A 4C 7A 80 30 00 7A 90 0A 00 02 28 7A 80 07 00
+0A 9B 13 2C 82 49 D0 04 82 48 D2 04 82 4B C8 04
+19 42 E4 04 18 42 E6 04 09 5A 08 63 1C 53 1E 83
+E7 23 8F 49 04 00 8F 48 02 00 8F 4C 00 00 30 4D
+03 12 0D 12 1B 42 DA 1D 0B 12 32 C0 00 02 6D 4E
+0D 5E 0C 4E 7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23
+32 D0 00 02 FC 4C FE FF 0D 9C FC 2F DE 83 00 00
+09 43 08 43 3D 40 26 4B 3F 82 8F 4E 06 00 0C 4E
+7E 4C 6A 4C 7A 90 2D 00 10 2C 3B 40 10 00 7A 80
+24 00 06 24 2B 43 5A 83 03 24 3B 52 6A 53 B0 23
+1C 53 1E 83 6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83
+B1 43 04 00 A5 3F 28 4B 2F 53 0E 93 2C 17 82 4C
+DA 1D 03 24 2F 52 0E F3 30 4D 8F 93 00 00 15 20
+32 B0 00 02 14 20 0E 93 05 24 1A 4F 02 00 1A 83
+0A 93 0B 38 2F 53 BF 4F 00 00 3E E3 05 20 BF E3
+00 00 9F 53 00 00 3E E3 30 4D 32 D0 00 02 9F 4F
+02 00 04 00 BF 4F 00 00 3E E3 F6 23 BF E3 02 00
+BF E3 00 00 9F 53 02 00 8F 63 00 00 3E E3 30 4D
+A8 48 07 45 58 45 43 55 54 45 0A 4E 3E 4F 00 4A
+28 45 01 2C 1A 42 C4 1D A2 53 C4 1D 8A 4E 00 00
+3E 4F 30 4D A2 4B 87 4C 49 54 45 52 41 4C 82 93
+B6 1D 16 24 32 B0 00 02 09 24 1A 42 C4 1D A2 52
+C4 1D BA 40 34 44 00 00 BA 4F 02 00 1A 42 C4 1D
+A2 52 C4 1D BA 40 34 44 00 00 8A 4E 02 00 3E 4F
+30 4D DE 48 05 43 4F 55 4E 54 2F 83 1E 53 8F 4E
+00 00 5E 4E FF FF 30 4D 82 4E BE 1D B2 4F C0 1D
+3E 4F 82 43 C2 1D 87 12 4C 46 9C 49 1E 4C 3D 40
+2A 4C E8 22 3D 41 3E 4F 30 4D 2C 4C 0A 4E 3E 4F
+3D 40 42 4C 3D 27 3D 40 18 4C 1A E2 B6 1D B2 27
+AC 23 44 4C 3E 4F 3D 40 18 4C B9 23 DE 53 00 00
+68 4E 08 5E F8 40 3F 00 00 00 3D 40 0A 4E CD 3F
+92 4B 08 45 56 41 4C 55 41 54 45 00 39 40 BE 1D
+39 12 39 12 39 12 0D 12 B0 12 2A 44 08 4C 80 4C
+3D 41 B2 41 C2 1D B2 41 C0 1D B2 41 BE 1D 30 4D
+7A 45 04 51 55 49 54 00 31 40 E0 1C B2 40 00 1C
+AC 1D 82 43 B6 1D 82 43 08 18 B0 12 2A 44 42 49
+04 0D 6F 6B 20 00 26 49 34 44 38 1D 44 44 34 44
+50 00 F6 47 EE 48 08 4C 34 44 7E 1C CE 44 B2 45
+42 49 0D 73 74 61 63 6B 20 65 6D 70 74 79 20 21
+1C 4D 34 44 30 FF 84 47 B2 45 42 49 0B 46 52 41
+4D 20 66 75 6C 6C 20 21 1C 4D 42 46 F4 44 C0 45
+AE 4C 42 49 04 0D 20 20 20 00 BC 45 B6 4C EE 47
+05 41 42 4F 52 54 3F 40 80 1C BE 3F 8F 93 02 00
+98 26 B2 40 82 48 66 48 B0 12 04 52 82 43 C2 5A
+82 43 CE 5A 82 43 DA 5A 82 43 0A 5B 82 43 16 5B
+82 43 22 5B A2 B3 FC 05 FD 27 B2 40 11 00 EE 05
+92 C3 FC 05 38 40 55 05 39 42 19 83 FE 23 18 83
+FB 23 92 B3 FC 05 F4 23 87 12 42 49 04 1B 5B 37
+6D 00 26 49 26 49 42 49 04 1B 5B 30 6D 00 26 49
+4C 51 8E 51 94 51 16 4D 10 4D 86 41 42 4F 52 54
+22 00 87 12 5C 49 34 44 1C 4D A4 4B 2A 44 EE 49
+01 27 87 12 4C 46 9C 49 F4 49 C0 45 B0 4D 2A 44
+4C 4C 52 46 81 5C 92 42 BE 1D C2 1D 30 4D 87 12
+78 49 4C 46 9C 49 C8 4D 08 4E 7A 4E 5A D3 5A 53
+0A 58 19 42 C8 1D 6E 4E 3E F0 1E 00 09 5E 82 48
+AE 1D 82 49 B0 1D 82 4A B2 1D 2A 52 82 4A C4 1D
+3E 4F 3D 41 30 41 87 12 42 49 0F 73 74 61 63 6B
+20 6D 69 73 6D 61 74 63 68 21 22 4D 82 9F B4 1D
+F2 23 18 42 AE 1D 19 42 B0 1D A8 49 FE FF 89 48
+00 00 30 4D 96 49 08 56 41 52 49 41 42 4C 45 00
+B0 12 BE 4D BA 40 86 12 FC FF EF 3F F4 4B 08 43
+4F 4E 53 54 41 4E 54 00 B0 12 BE 4D BA 40 85 12
+FC FF 8A 4E FE FF 3E 4F E0 3F 3E 4E 06 43 52 45
+41 54 45 00 B0 12 BE 4D BA 40 85 12 FC FF 8A 4A
+FE FF D3 3F 62 4C 05 44 4F 45 53 3E 1A 42 B2 1D
+BA 40 84 12 00 00 8A 4D 02 00 3D 41 30 4D 76 4E
+05 44 45 46 45 52 B0 12 BE 4D BA 40 30 40 FC FF
+BA 40 8C 4E FE FF B9 3F 00 00 81 5B 82 43 B6 1D
+30 4D B4 4D 01 5D B2 43 B6 1D 30 4D 58 49 87 52
+45 43 55 52 53 45 19 42 C4 1D 99 42 B2 1D 00 00
+A2 53 C4 1D 30 4D AA 4E 01 3A B0 12 BE 4D BA 40
+87 12 FC FF A2 83 C4 1D B2 43 B6 1D 82 4F B4 1D
+30 4D D8 4E 81 3B 82 93 B6 1D 5D 27 87 12 34 44
+2A 44 A4 4B 0C 4E AC 4E 2A 44 CA 48 09 49 4D 4D
+45 44 49 41 54 45 1A 42 AE 1D FA D0 80 00 00 00
+30 4D BE 4F 02 00 3E 4F 30 4D 0C 4F 82 49 53 00
+87 12 42 46 F4 44 C0 45 44 4F 50 4F 34 44 22 4F
+A4 4B 2A 44 A2 4D 22 4F 2A 44 F4 4E 83 5B 27 5D
+87 12 A2 4D 34 44 34 44 A4 4B A4 4B 2A 44 92 4C
+88 50 4F 53 54 50 4F 4E 45 00 87 12 4C 46 9C 49
+F4 49 54 44 C0 45 B0 4D 7E 45 C0 45 8A 4F 34 44
+34 44 A4 4B A4 4B 34 44 A4 4B A4 4B 2A 44 90 4F
+3A 4E 82 4A C6 1D 2E 4E 82 4E C4 1D 3D 40 10 00
+09 4A 08 49 29 83 18 48 FE FF 0E 98 FC 2B 89 48
+00 00 1D 83 F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41
+30 4D 2C 4F 82 49 46 00 2F 83 8F 4E 00 00 1E 42
+C4 1D BE 40 C0 45 00 00 A2 52 C4 1D 2E 53 30 4D
+90 4E 84 45 4C 53 45 00 1A 42 C4 1D BA 40 BC 45
+00 00 2A 52 82 4A C4 1D 8E 4A 00 00 2A 83 0E 4A
+30 4D 20 49 84 54 48 45 4E 00 9E 42 C4 1D 00 00
+3E 4F 30 4D 5C 4E 85 42 45 47 49 4E 30 40 84 47
+04 50 85 55 4E 54 49 4C 39 40 C0 45 1A 42 C4 1D
+A2 52 C4 1D 8A 49 00 00 8A 4E 02 00 3E 4F 30 4D
+8A 4D 85 41 47 41 49 4E 39 40 BC 45 EF 3F 26 4E
+85 57 48 49 4C 45 87 12 C8 4F 6E 44 2A 44 BE 4E
+86 52 45 50 45 41 54 00 87 12 48 50 0A 50 2A 44
+E2 4F 82 44 4F 00 2F 83 8F 4E 00 00 1E 42 C4 1D
+BE 40 CA 45 00 00 2E 53 82 4E C4 1D A2 53 AC 1D
+1A 42 AC 1D 8A 43 00 00 30 4D B6 4B 84 4C 4F 4F
+50 00 39 40 EC 45 1A 42 C4 1D A2 52 C4 1D 8A 49
+00 00 8A 4E 02 00 1E 42 AC 1D A2 83 AC 1D 2E 4E
+0E 93 04 24 9E 42 C4 1D 00 00 F5 3F 3E 4F 30 4D
+E4 47 85 2B 4C 4F 4F 50 39 40 DA 45 E4 3F 9C 50
+85 4C 45 41 56 45 1A 42 C4 1D BA 40 FC 45 00 00
+BA 40 BC 45 02 00 B2 50 06 00 C4 1D A2 53 AC 1D
+2A 52 19 42 AC 1D 89 4A 00 00 30 4D E0 50 04 4D
+4F 56 45 00 0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24
+08 99 0F 24 06 2C F8 49 00 00 18 53 1A 83 FB 23
+30 4D 08 5A 09 5A 19 83 18 83 E8 49 00 00 1A 83
+FA 23 30 4D 34 44 CA 1D FC 44 2A 44 84 12 44 51
+32 54 1A 54 72 50 A0 4D 02 54 D2 50 0E 51 84 49
+B2 51 E6 51 22 50 A6 52 48 45 4C 4F B4 4E 5C 4A
+00 00 3A 40 0C 00 39 40 CA 1D 38 40 CC 1D D9 3F
+3A 40 0E 00 39 40 CC 1D 38 40 CA 1D CC 3F 82 43
+CC 1D 30 4D 92 42 CA 1D C8 1D 30 4D 60 4F 09 50
+57 52 5F 53 54 41 54 45 84 12 8E 4F FE 53 48 5B
+9E 51 08 50 57 52 5F 48 45 52 45 00 92 42 C4 1D
+AE 51 92 42 C6 1D AC 51 EF 3F 60 50 09 52 53 54
+5F 53 54 41 54 45 92 42 0C 18 AE 51 92 42 0E 18
+AC 51 E2 3F CC 51 08 52 53 54 5F 48 45 52 45 00
+92 42 C4 1D 0C 18 92 42 C6 1D 0E 18 DF 3F B2 40
+4C 52 AE 52 B2 40 8E 48 A4 48 B2 40 D0 48 E4 48
+B2 40 DC 47 EA 47 30 41 50 50 04 57 49 50 45 00
+39 40 80 FF B9 43 00 00 29 53 39 90 C6 FF FA 23
+B0 12 FE 51 B2 40 48 5B C4 1D B2 40 FE 53 C6 1D
+D7 3F C4 4F 06 28 57 41 52 4D 29 00 1E 42 08 18
+87 12 42 49 05 0D 1B 5B 37 6D 26 49 70 47 42 49
+27 20 46 61 73 74 46 6F 72 74 68 20 56 31 36 30
+20 2E 35 4D 48 7A 20 28 43 29 20 4A 2E 4D 2E 54
+68 6F 6F 72 65 6E 73 20 26 49 34 44 30 FF 84 47
+2A 45 30 47 42 49 0B 62 79 74 65 73 20 66 72 65
+65 20 28 4D 1A 52 04 57 41 52 4D 00 30 40 4C 52
+16 50 04 43 4F 4C 44 00 B2 40 04 A5 20 01 B2 40
+88 5A 5C 01 92 43 04 02 B2 40 FE FF 02 02 A2 83
+06 02 B2 43 22 02 B2 D3 26 02 B2 43 42 02 B2 D3
+46 02 B2 43 62 02 B2 D3 66 02 B2 40 80 00 84 02
+B2 40 7F FF 82 02 B2 D0 7F FF 86 02 F2 43 22 03
+F2 D3 26 03 F2 40 A5 00 61 01 82 43 62 01 B2 40
+11 01 66 01 29 42 B2 40 33 00 64 01 D2 43 61 01
+92 D2 9E 01 08 18 A2 93 08 18 01 24 59 07 38 40
+C2 A2 18 83 FE 23 19 83 FA 23 B2 42 B0 01 F2 D0
+10 00 2A 03 F2 C0 40 00 A2 04 3A 40 BE 52 39 40
+C6 FF 89 4A 00 00 29 53 FC 23 92 42 02 18 E4 FF
+B2 40 18 00 0A 18 31 40 E0 1C 3F 40 80 1C 37 40
+00 44 36 40 B4 44 35 40 08 44 34 40 14 44 B2 40
+0A 00 DA 1D B2 43 DC 1D 92 C3 30 01 18 42 08 18
+F2 B0 10 00 20 02 04 20 38 E3 18 53 82 48 08 18
+B2 40 81 00 E0 05 A2 42 E6 05 B2 40 00 49 E8 05
+F2 D0 30 00 2A 02 92 C3 E0 05 92 D3 FA 05 3D 40
+D8 53 18 42 08 18 38 90 0A 00 2A 27 38 90 16 00
+27 2F 28 93 00 23 E8 26 AC 52 84 12 44 51 26 5A
+D2 5A DA 59 26 5B A0 59 5A 5A A4 56 00 00 96 59
+46 5A F8 59 36 5A B4 57 00 00 00 00 38 5B 70 51
+44 52 85 48 49 32 4C 4F 87 12 84 47 DC 4F A4 4B
+AC 4E 72 51 DA 53 2A 44 B2 52 04 43 4F 44 45 00
+B0 12 BE 4D A2 82 C4 1D 87 12 EC 4E BC 45 12 54
+42 50 03 41 53 4D 92 42 C8 1D B8 1D B2 40 DE 53
+C8 1D EE 3F 00 00 07 45 4E 44 43 4F 44 45 87 12
+80 51 0C 4E 2A 44 46 54 06 45 4E 44 41 53 4D 00
+92 42 B8 1D C8 1D F3 3F 00 00 05 43 4F 4C 4F 4E
+1A 42 C4 1D BA 40 87 12 00 00 A2 53 C4 1D B2 43
+B6 1D 30 40 80 51 00 00 05 4C 4F 32 48 49 1A 42
+C4 1D BA 40 B0 12 00 00 BA 40 2A 44 02 00 A2 52
+C4 1D ED 3F 38 40 BE 1D 39 48 2A 48 09 5A 1A 52
+C2 1D 09 9A 03 24 7E 9A FC 27 1A 83 0E 4A 2A 88
+82 4A C2 1D 30 4D B0 12 2A 44 9C 49 F4 49 72 45
+C0 45 DC 54 B0 4A C0 45 B0 4D FE 54 DE 54 29 4E
+39 90 86 12 02 20 2E 53 30 41 39 90 85 12 03 20
+1E 4E 02 00 30 41 39 90 84 12 01 20 2E 52 30 41
+19 42 C4 1D A2 53 C4 1D 89 4E 00 00 3E 40 29 00
+12 12 C2 1D 92 53 C2 1D B0 12 2A 44 9C 49 B0 4A
+C0 45 30 55 26 55 21 53 3E 90 10 00 BB 2D 30 41
+32 55 B2 41 C2 1D 22 D3 30 41 87 12 4C 46 A4 54
+42 55 82 43 BC 1D 92 42 C4 1D BA 1D A2 53 C4 1D
+0A 4E 3E 4F FA 90 23 00 00 00 34 20 92 53 C2 1D
+B0 12 C6 54 0E 93 04 20 B2 40 00 03 BC 1D 27 3C
+1E 93 04 20 B2 40 10 03 BC 1D 21 3C 2E 93 04 20
+B2 40 20 03 BC 1D 1B 3C 2E 92 04 20 B2 40 20 02
+BC 1D 15 3C 3E 92 04 20 B2 40 30 02 BC 1D 0F 3C
+3E 93 04 20 B2 40 30 03 BC 1D 09 3C B2 40 30 00
+BC 1D 19 42 C4 1D A2 53 C4 1D 89 4E 00 00 3E 4F
+3D 41 30 4D FA 90 26 00 00 00 08 20 B2 40 10 02
+BC 1D 92 53 C2 1D 30 12 B2 55 75 3F FA 90 40 00
+00 00 1A 20 B2 40 20 00 BC 1D 92 53 C2 1D B0 12
+10 55 0E 20 B2 50 10 00 BC 1D 3E 40 2B 00 B0 12
+10 55 32 24 92 92 BE 1D C2 1D 02 24 92 53 C2 1D
+8E 10 82 5E BC 1D D3 3F B0 12 10 55 F9 23 B2 50
+10 00 BC 1D 3E 40 28 00 B0 12 C6 54 30 12 02 56
+67 3F 87 12 4C 46 A4 54 3A 56 FE 90 26 00 00 00
+3E 40 20 00 04 20 B2 50 82 00 BC 1D C2 3F B0 12
+10 55 DF 23 B2 50 80 00 BC 1D 3E 40 28 00 B0 12
+C6 54 B0 12 00 55 D5 23 3D 40 B0 4D 30 4D 00 00
+04 52 45 54 49 00 87 12 34 44 00 13 A4 4B 2A 44
+34 44 2C 00 3A 55 32 56 8A 56 2E 4E 1E D2 BC 1D
+19 42 BA 1D 92 3F 88 54 03 4D 4F 56 84 12 80 56
+00 40 98 56 05 4D 4F 56 2E 42 84 12 80 56 40 40
+00 00 03 41 44 44 84 12 80 56 00 50 B2 56 05 41
+44 44 2E 42 84 12 80 56 40 50 BE 56 04 41 44 44
+43 00 84 12 80 56 00 60 CC 56 06 41 44 44 43 2E
+42 00 84 12 80 56 40 60 70 56 04 53 55 42 43 00
+84 12 80 56 00 70 EA 56 06 53 55 42 43 2E 42 00
+84 12 80 56 40 70 F8 56 03 53 55 42 84 12 80 56
+00 80 08 57 05 53 55 42 2E 42 84 12 80 56 40 80
+6A 54 03 43 4D 50 84 12 80 56 00 90 22 57 05 43
+4D 50 2E 42 84 12 80 56 40 90 58 54 04 44 41 44
+44 00 84 12 80 56 00 A0 3C 57 06 44 41 44 44 2E
+42 00 84 12 80 56 40 A0 2E 57 03 42 49 54 84 12
+80 56 00 B0 5A 57 05 42 49 54 2E 42 84 12 80 56
+40 B0 66 57 03 42 49 43 84 12 80 56 00 C0 74 57
+05 42 49 43 2E 42 84 12 80 56 40 C0 80 57 03 42
+49 53 84 12 80 56 00 D0 8E 57 05 42 49 53 2E 42
+84 12 80 56 40 D0 00 00 03 58 4F 52 84 12 80 56
+00 E0 A8 57 05 58 4F 52 2E 42 84 12 80 56 40 E0
+DA 56 03 41 4E 44 84 12 80 56 00 F0 C2 57 05 41
+4E 44 2E 42 84 12 80 56 40 F0 4C 46 3A 55 E0 57
+1A 42 BC 1D B2 F0 70 00 BC 1D 8A 10 3A F0 0F 00
+82 DA BC 1D 4A 3F 14 57 03 52 52 43 84 12 DA 57
+00 10 F8 57 05 52 52 43 2E 42 84 12 DA 57 40 10
+04 58 04 53 57 50 42 00 84 12 DA 57 80 10 12 58
+03 52 52 41 84 12 DA 57 00 11 20 58 05 52 52 41
+2E 42 84 12 DA 57 40 11 2C 58 03 53 58 54 84 12
+DA 57 80 11 00 00 04 50 55 53 48 00 84 12 DA 57
+00 12 46 58 06 50 55 53 48 2E 42 00 84 12 DA 57
+40 12 9A 57 04 43 41 4C 4C 00 84 12 DA 57 80 12
+34 44 2C 00 3A 55 32 56 7A 58 59 42 BC 1D 5A 42
+BD 1D 82 4A BC 1D BE 90 00 15 00 00 02 20 0A 89
+02 3C 09 8A 0A 49 3A 90 10 00 03 2C 5A 0E A8 3F
+1A 53 0E 4A 87 12 70 47 42 49 0D 6F 75 74 20 6F
+66 20 62 6F 75 6E 64 73 22 4D 54 58 05 50 55 53
+48 4D 84 12 70 58 00 15 BC 58 04 50 4F 50 4D 00
+84 12 70 58 00 17 4C 46 A4 54 DC 58 82 43 BC 1D
+92 42 C4 1D BA 1D A2 53 C4 1D 92 53 C2 1D 3E 40
+2C 00 B0 12 2A 44 9C 49 B0 4A C0 45 B0 4D 32 56
+02 59 0A 4E 3E 4F 1A 83 2A 92 CA 2F 8A 10 5A 06
+6F 3F 3A 58 04 52 52 43 4D 00 84 12 D6 58 50 00
+14 59 04 52 52 41 4D 00 84 12 D6 58 50 01 22 59
+04 52 4C 41 4D 00 84 12 D6 58 50 02 30 59 04 52
+52 55 4D 00 84 12 D6 58 50 03 85 12 00 3C 3E 59
+03 53 3E 3D 85 12 00 38 50 59 02 53 3C 00 85 12
+00 34 CA 58 03 30 3E 3D 85 12 00 30 64 59 02 30
+3C 00 85 12 00 30 00 00 02 55 3C 00 85 12 00 2C
+78 59 03 55 3E 3D 85 12 00 28 6E 59 03 30 3C 3E
+85 12 00 24 8C 59 02 30 3D 00 85 12 00 20 00 00
+02 49 46 00 1A 42 C4 1D 8A 4E 00 00 A2 53 C4 1D
+0E 4A 30 4D 82 59 04 54 48 45 4E 00 1A 42 C4 1D
+08 4E 3E 4F 09 48 29 53 0A 89 0A 11 3A 90 00 02
+68 2F 88 DA 00 00 30 4D 4A 57 04 45 4C 53 45 00
+1A 42 C4 1D BA 40 00 3C 00 00 A2 53 C4 1D 2F 83
+8F 4A 00 00 E3 3F B6 59 05 55 4E 54 49 4C 3A 4F
+08 4E 3E 4F 19 42 C4 1D 2A 83 0A 89 0A 11 3A 90
+00 FE 47 3B 3A F0 FF 03 08 DA 89 48 00 00 A2 53
+C4 1D 30 4D CE 57 05 41 47 41 49 4E 87 12 4A 59
+FE 59 2A 44 00 00 05 57 48 49 4C 45 87 12 A4 59
+6E 44 2A 44 5A 59 06 52 45 50 45 41 54 00 87 12
+4A 59 FE 59 BC 59 2A 44 00 00 03 4A 4D 50 87 12
+A2 4D 4A 59 FE 59 2A 44 3E B0 00 10 03 20 3E E0
+00 04 30 4D 3E 90 00 34 06 28 03 24 3E 40 00 34
+30 4D 3E 40 00 38 30 4D 00 00 04 3F 4A 4D 50 00
+87 12 68 5A A2 4D 6E 44 FE 59 2A 44 9E 5A 3D 41
+08 4E 3E 4F 2A 48 0A 93 04 20 98 42 C4 1D 00 00
+30 4D 88 43 00 00 A4 3F 64 58 03 42 57 31 84 12
+9C 5A 00 00 BA 5A 03 42 57 32 84 12 9C 5A 00 00
+C6 5A 03 42 57 33 84 12 9C 5A 00 00 DE 5A 3D 41
+1A 42 C4 1D 28 4E 08 93 08 20 BA 4F 00 00 A2 53
+C4 1D 8E 4A 00 00 3E 4F 30 4D 8E 43 00 00 61 3F
+00 00 03 46 57 31 84 12 DC 5A 00 00 02 5B 03 46
+57 32 84 12 DC 5A 00 00 0E 5B 03 46 57 33 84 12
+DC 5A 00 00 1A 5B 04 47 4F 54 4F 00 87 12 4A 59
+A2 4D 9A 4B 2A 44 8A 5A 05 3F 47 4F 54 4F 87 12
+68 5A A2 4D 9A 4B 2A 44
+@FFC6
+BE 52 BE 52 BE 52 BE 52 BE 52 BE 52 BE 52 BE 52
+BE 52 BE 52 BE 52 BE 52 BE 52 BE 52 BE 52 40 48
+BE 52 BE 52 BE 52 BE 52 BE 52 BE 52 BE 52 BE 52
+BE 52 BE 52 BE 52 BE 52 BE 52
+q
--- /dev/null
+@1800
+10 00 4C 48 80 3E 00 24 FD FF 18 00 68 5B 1E 54
+2A 48 38 48 00 00 00 00
+@1DAA
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00
+@4400
+3A 41 0D 12 0D 4A 30 4D 2F 83 8F 4E 00 00 3E 41
+2E 4E 30 4D 2F 83 8F 4E 00 00 3E 41 0D 12 3D 4E
+30 4D 00 00 04 45 58 49 54 00 3D 41 30 4D 00 00
+03 4C 49 54 2F 83 8F 4E 00 00 3E 4D 30 4D 24 44
+03 44 55 50 2F 83 8F 4E 00 00 30 4D 00 00 04 3F
+44 55 50 00 0E 93 F6 23 30 4D 40 44 04 44 52 4F
+50 00 3E 4F 30 4D 00 00 04 53 57 41 50 00 2A 4F
+8F 4E 00 00 0E 4A 30 4D 00 00 04 4F 56 45 52 00
+2F 83 8F 4E 00 00 1E 4F 02 00 30 4D 68 44 03 52
+4F 54 2A 4F 8F 4E 00 00 1E 4F 02 00 8F 4A 02 00
+30 4D 4E 44 02 3E 52 00 0E 12 3E 4F 30 4D 8E 44
+02 52 3E 00 2F 83 8F 4E 00 00 3E 41 30 4D B0 44
+02 52 40 00 2F 83 8F 4E 00 00 2E 41 30 4D 8F 4E
+FE FF 0E 4F 2F 83 30 4D 5C 44 05 44 45 50 54 48
+8F 4E FE FF 3E 40 80 1C 0E 8F 2F 83 0E 11 30 4D
+00 00 01 40 2E 4E 30 4D F2 44 01 21 BE 4F 00 00
+3E 4F 30 4D 00 00 02 43 40 00 6E 4E 30 4D 06 45
+02 43 21 00 3A 4F CE 4A 00 00 3E 4F 30 4D 00 00
+01 2B 3E 5F 30 4D 30 44 01 2D 3A 4F 0A 8E 0E 4A
+30 4D FA 44 03 41 4E 44 3E FF 30 4D 7A 44 02 4F
+52 00 3E DF 30 4D 00 00 03 58 4F 52 3E EF 30 4D
+3E 45 06 4E 45 47 41 54 45 00 3E E3 1E 53 30 4D
+34 45 03 41 42 53 0E 93 F8 33 30 4D 00 00 02 30
+3D 00 1E 83 0E 7E 30 4D 6E 45 02 30 3C 00 0E 5E
+0E 7E 3E E3 30 4D 00 00 01 3D 3E 8F 07 20 3E 43
+30 4D 88 45 01 3C 3A 4F 0A 8E F9 3B 0E 43 30 4D
+A4 44 01 3E 3E 8F F3 3B 0E 43 30 4D 00 00 02 55
+3C 00 3A 4F 0A 8E EB 2B 0E 43 30 4D 2D 4D 30 4D
+0E 93 3E 4F FB 27 2D 53 30 4D 39 40 00 80 39 8F
+08 4E 3E 4F 08 59 19 15 30 4D 81 5E 00 00 3E 4F
+32 B0 00 01 EB 27 2D 53 21 52 30 4D 91 53 00 00
+F7 3F AE 45 06 55 4E 4C 4F 4F 50 00 F5 3F 00 00
+01 49 2F 83 8F 4E 00 00 2E 41 1E 81 02 00 30 4D
+20 45 01 4A 2F 83 8F 4E 00 00 1E 41 04 00 1E 81
+06 00 30 4D A2 45 03 3E 49 4E 85 12 C2 1D 10 45
+04 42 41 53 45 00 85 12 DA 1D C0 44 05 53 54 41
+54 45 85 12 B6 1D 30 46 02 42 4C 00 85 12 20 00
+94 45 02 3C 23 00 B2 40 AA 1D AA 1D 30 4D 1E 15
+0E 43 3D 40 20 00 0A 93 04 20 0D 11 0A 4C 0C 43
+09 43 0E 9B 01 28 0E 8B 09 69 08 68 1D 83 07 30
+0C 5C 0A 6A 0E 6E F5 2B 0E 8B 12 D3 F5 3F 0A 4E
+1D 17 30 41 48 46 01 23 1B 42 DA 1D 2C 4F 0A 4E
+B0 12 5E 46 8F 49 00 00 0E 48 7A 90 0A 00 02 28
+3A 50 07 00 3A 50 30 00 92 83 AA 1D 18 42 AA 1D
+C8 4A 00 00 30 4D 96 46 02 23 53 00 87 12 98 46
+D2 46 2D 83 09 93 E0 23 0E 93 DE 23 3D 41 30 4D
+C8 46 02 23 3E 00 9F 42 AA 1D 00 00 3E 40 AA 1D
+2E 8F 30 4D 00 46 04 48 4F 4C 44 00 0A 4E 3E 4F
+DB 3F 3C 46 04 53 49 47 4E 00 0E 93 3E 4F 3A 40
+2D 00 D2 33 30 4D F4 45 03 55 44 2E 87 12 56 46
+CC 46 E6 46 32 49 FA 48 2A 44 18 47 02 55 2E 00
+2F 83 8F 4E 00 00 0E 43 F1 3F 3E B0 00 80 06 24
+BF E3 00 00 3E E3 9F 53 00 00 0E 63 30 4D DA 44
+02 44 2E 00 87 12 56 46 6E 44 80 44 3A 47 CC 46
+92 44 0A 47 E6 46 32 49 FA 48 2A 44 52 45 01 2E
+3E B0 00 80 DD 27 2F 83 3E 43 EC 3F F6 46 04 48
+45 52 45 00 2F 83 8F 4E 00 00 1E 42 C4 1D 30 4D
+62 45 05 41 4C 4C 4F 54 82 5E C4 1D 3E 4F 30 4D
+E2 46 02 43 2C 00 1A 42 C4 1D CA 4E 00 00 92 53
+C4 1D 3E 4F 30 4D 2F 83 8F 4E 00 00 B0 12 2A 48
+92 B3 FC 05 FD 27 1E 42 EC 05 B0 12 38 48 30 4D
+30 40 B6 47 7E 47 05 28 4B 45 59 29 18 42 EC 05
+EA 3F 12 46 03 4B 45 59 30 40 DC 47 92 47 06 41
+43 43 45 50 54 00 3C 40 8A 48 3B 40 54 48 2D 15
+0A 4E 2E 4F 0A 5E 3B 40 0D 00 3C 40 20 00 3D 40
+7E 48 92 B3 FC 05 05 24 18 42 EC 05 38 90 0A 00
+04 20 21 53 39 40 46 48 4D 15 B2 40 11 00 EE 05
+A2 B3 FC 05 FD 27 30 41 B2 40 13 00 EE 05 A2 B3
+FC 05 FD 27 30 41 12 D2 0A 18 FD 3F 21 52 3A 17
+58 42 EC 05 48 9B F0 27 48 9C 06 2C 78 92 11 20
+2E 9F 0F 24 1E 83 05 3C 0E 9A 03 24 CE 48 00 00
+1E 53 82 48 EE 05 A2 B3 FC 05 FD 27 30 4D 80 48
+2D 83 92 B3 FC 05 FD 27 E3 23 B2 40 18 00 0A 18
+3E 8F 3D 41 30 4D D6 47 06 28 45 4D 49 54 29 00
+08 4E 3E 4F E6 3F 50 47 04 45 4D 49 54 00 30 40
+A0 48 A8 48 04 45 43 48 4F 00 B2 40 82 48 72 48
+30 4D 6E 47 06 4E 4F 45 43 48 4F 00 B2 40 30 4D
+72 48 30 4D 98 48 04 28 43 52 29 00 2F 83 8F 4E
+00 00 3E 40 0D 00 E3 3F A2 47 02 43 52 00 30 40
+DC 48 04 47 05 53 50 41 43 45 2F 83 8F 4E 00 00
+3E 40 20 00 D4 3F F4 48 06 53 50 41 43 45 53 00
+0E 93 09 24 0D 12 3D 40 1C 49 EF 3F 1E 49 2D 83
+1E 83 EB 23 3D 41 3E 4F 30 4D 2C 47 04 54 59 50
+45 00 0E 93 95 24 2A 4F 8F 5E 00 00 0E 4A 87 12
+CA 45 02 46 0A 45 AE 48 EC 45 42 49 2A 44 2F 82
+8F 4E 02 00 7E 4D 8F 4D 00 00 0D 5E 1D B3 0D 63
+30 4D 08 49 82 53 22 00 87 12 34 44 4E 49 B0 4B
+34 44 22 00 A8 49 78 49 3D 41 6E 4E 1E 83 82 5E
+C4 1D 3E 4F 92 B3 C4 1D A2 63 C4 1D 30 4D C4 48
+82 2E 22 00 87 12 68 49 34 44 32 49 B0 4B 2A 44
+00 00 04 57 4F 52 44 00 3C 40 BE 1D 39 4C 3A 4C
+09 5A 3A 5C 28 4C 09 9A 19 24 7E 9A FC 27 1A 83
+3B 40 60 00 C8 4C 00 00 09 9A 0C 24 7C 4A 4E 9C
+09 24 18 53 4B 9C F6 2F 7C 90 7B 00 F3 2F 7C 80
+20 00 F0 3F 1A 82 C0 1D 82 4A C2 1D 1E 42 C4 1D
+08 8E CE 48 00 00 30 4D 00 00 04 46 49 4E 44 00
+2F 83 0C 4E 65 4C 74 40 80 00 3B 40 CA 1D 3E 4B
+0E 93 1E 24 58 4C 01 00 78 F0 1E 00 0E 58 2E 53
+1E 4E FE FF 0E 93 F3 27 09 4E 78 49 48 C4 48 95
+F7 23 0A 4C 1A 53 FA 99 00 00 F2 23 58 83 FA 23
+19 B3 09 63 0C 49 6A 4E 1E 43 4A 93 01 30 2E 83
+8F 4C 00 00 35 40 08 44 34 40 14 44 30 4D 2F 53
+2F 53 3E 4F 30 4D 26 46 07 3E 4E 55 4D 42 45 52
+3C 4F 38 4F 29 4F 2F 82 1B 42 DA 1D 6A 4C 7A 80
+30 00 7A 90 0A 00 02 28 7A 80 07 00 0A 9B 13 2C
+82 49 D0 04 82 48 D2 04 82 4B C8 04 19 42 E4 04
+18 42 E6 04 09 5A 08 63 1C 53 1E 83 E7 23 8F 49
+04 00 8F 48 02 00 8F 4C 00 00 30 4D 03 12 0D 12
+1B 42 DA 1D 0B 12 32 C0 00 02 6D 4E 0D 5E 0C 4E
+7A 40 2E 00 0D 9C 0A 28 7A 9C FC 23 32 D0 00 02
+FC 4C FE FF 0D 9C FC 2F DE 83 00 00 09 43 08 43
+3D 40 32 4B 3F 82 8F 4E 06 00 0C 4E 7E 4C 6A 4C
+7A 90 2D 00 10 2C 3B 40 10 00 7A 80 24 00 06 24
+2B 43 5A 83 03 24 3B 52 6A 53 B0 23 1C 53 1E 83
+6A 4C 7A 90 2D 00 AA 23 1C 53 1E 83 B1 43 04 00
+A5 3F 34 4B 2F 53 0E 93 2C 17 82 4C DA 1D 03 24
+2F 52 0E F3 30 4D 8F 93 00 00 15 20 32 B0 00 02
+14 20 0E 93 05 24 1A 4F 02 00 1A 83 0A 93 0B 38
+2F 53 BF 4F 00 00 3E E3 05 20 BF E3 00 00 9F 53
+00 00 3E E3 30 4D 32 D0 00 02 9F 4F 02 00 04 00
+BF 4F 00 00 3E E3 F6 23 BF E3 02 00 BF E3 00 00
+9F 53 02 00 8F 63 00 00 3E E3 30 4D B4 48 07 45
+58 45 43 55 54 45 0A 4E 3E 4F 00 4A 28 45 01 2C
+1A 42 C4 1D A2 53 C4 1D 8A 4E 00 00 3E 4F 30 4D
+AE 4B 87 4C 49 54 45 52 41 4C 82 93 B6 1D 16 24
+32 B0 00 02 09 24 1A 42 C4 1D A2 52 C4 1D BA 40
+34 44 00 00 BA 4F 02 00 1A 42 C4 1D A2 52 C4 1D
+BA 40 34 44 00 00 8A 4E 02 00 3E 4F 30 4D EA 48
+05 43 4F 55 4E 54 2F 83 1E 53 8F 4E 00 00 5E 4E
+FF FF 30 4D 82 4E BE 1D B2 4F C0 1D 3E 4F 82 43
+C2 1D 87 12 4C 46 A8 49 2A 4C 3D 40 36 4C E8 22
+3D 41 3E 4F 30 4D 38 4C 0A 4E 3E 4F 3D 40 4E 4C
+3D 27 3D 40 24 4C 1A E2 B6 1D B2 27 AC 23 50 4C
+3E 4F 3D 40 24 4C B9 23 DE 53 00 00 68 4E 08 5E
+F8 40 3F 00 00 00 3D 40 16 4E CD 3F 9E 4B 08 45
+56 41 4C 55 41 54 45 00 39 40 BE 1D 39 12 39 12
+39 12 0D 12 B0 12 2A 44 14 4C 8C 4C 3D 41 B2 41
+C2 1D B2 41 C0 1D B2 41 BE 1D 30 4D 7A 45 04 51
+55 49 54 00 31 40 E0 1C B2 40 00 1C AC 1D 82 43
+B6 1D 82 43 08 18 B0 12 2A 44 4E 49 04 0D 6F 6B
+20 00 32 49 34 44 38 1D 44 44 34 44 50 00 F6 47
+FA 48 14 4C 34 44 7E 1C CE 44 B2 45 4E 49 0D 73
+74 61 63 6B 20 65 6D 70 74 79 20 21 28 4D 34 44
+30 FF 84 47 B2 45 4E 49 0B 46 52 41 4D 20 66 75
+6C 6C 20 21 28 4D 42 46 F4 44 C0 45 BA 4C 4E 49
+04 0D 20 20 20 00 BC 45 C2 4C EE 47 05 41 42 4F
+52 54 3F 40 80 1C BE 3F 8F 93 02 00 98 26 B2 40
+82 48 72 48 B0 12 10 52 82 43 E2 5A 82 43 EE 5A
+82 43 FA 5A 82 43 2A 5B 82 43 36 5B 82 43 42 5B
+A2 B3 FC 05 FD 27 B2 40 11 00 EE 05 92 C3 FC 05
+38 40 A0 AA 39 42 19 83 FE 23 18 83 FB 23 92 B3
+FC 05 F4 23 87 12 4E 49 04 1B 5B 37 6D 00 32 49
+32 49 4E 49 04 1B 5B 30 6D 00 32 49 58 51 9A 51
+A0 51 22 4D 1C 4D 86 41 42 4F 52 54 22 00 87 12
+68 49 34 44 28 4D B0 4B 2A 44 FA 49 01 27 87 12
+4C 46 A8 49 00 4A C0 45 BC 4D 2A 44 58 4C 52 46
+81 5C 92 42 BE 1D C2 1D 30 4D 87 12 84 49 4C 46
+A8 49 D4 4D 08 4E 7A 4E 5A D3 5A 53 0A 58 19 42
+C8 1D 6E 4E 3E F0 1E 00 09 5E 82 48 AE 1D 82 49
+B0 1D 82 4A B2 1D 2A 52 82 4A C4 1D 3E 4F 3D 41
+30 41 87 12 4E 49 0F 73 74 61 63 6B 20 6D 69 73
+6D 61 74 63 68 21 2E 4D 82 9F B4 1D F2 23 18 42
+AE 1D 19 42 B0 1D A8 49 FE FF 89 48 00 00 30 4D
+A2 49 08 56 41 52 49 41 42 4C 45 00 B0 12 CA 4D
+BA 40 86 12 FC FF EF 3F 00 4C 08 43 4F 4E 53 54
+41 4E 54 00 B0 12 CA 4D BA 40 85 12 FC FF 8A 4E
+FE FF 3E 4F E0 3F 4A 4E 06 43 52 45 41 54 45 00
+B0 12 CA 4D BA 40 85 12 FC FF 8A 4A FE FF D3 3F
+6E 4C 05 44 4F 45 53 3E 1A 42 B2 1D BA 40 84 12
+00 00 8A 4D 02 00 3D 41 30 4D 82 4E 05 44 45 46
+45 52 B0 12 CA 4D BA 40 30 40 FC FF BA 40 98 4E
+FE FF B9 3F 00 00 81 5B 82 43 B6 1D 30 4D C0 4D
+01 5D B2 43 B6 1D 30 4D 64 49 87 52 45 43 55 52
+53 45 19 42 C4 1D 99 42 B2 1D 00 00 A2 53 C4 1D
+30 4D B6 4E 01 3A B0 12 CA 4D BA 40 87 12 FC FF
+A2 83 C4 1D B2 43 B6 1D 82 4F B4 1D 30 4D E4 4E
+81 3B 82 93 B6 1D 5D 27 87 12 34 44 2A 44 B0 4B
+18 4E B8 4E 2A 44 D6 48 09 49 4D 4D 45 44 49 41
+54 45 1A 42 AE 1D FA D0 80 00 00 00 30 4D BE 4F
+02 00 3E 4F 30 4D 18 4F 82 49 53 00 87 12 42 46
+F4 44 C0 45 50 4F 5C 4F 34 44 2E 4F B0 4B 2A 44
+AE 4D 2E 4F 2A 44 00 4F 83 5B 27 5D 87 12 AE 4D
+34 44 34 44 B0 4B B0 4B 2A 44 9E 4C 88 50 4F 53
+54 50 4F 4E 45 00 87 12 4C 46 A8 49 00 4A 54 44
+C0 45 BC 4D 7E 45 C0 45 96 4F 34 44 34 44 B0 4B
+B0 4B 34 44 B0 4B B0 4B 2A 44 9C 4F 3A 4E 82 4A
+C6 1D 2E 4E 82 4E C4 1D 3D 40 10 00 09 4A 08 49
+29 83 18 48 FE FF 0E 98 FC 2B 89 48 00 00 1D 83
+F6 23 2A 4A 0A 93 F0 23 3E 4F 3D 41 30 4D 38 4F
+82 49 46 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40
+C0 45 00 00 A2 52 C4 1D 2E 53 30 4D 9C 4E 84 45
+4C 53 45 00 1A 42 C4 1D BA 40 BC 45 00 00 2A 52
+82 4A C4 1D 8E 4A 00 00 2A 83 0E 4A 30 4D 2C 49
+84 54 48 45 4E 00 9E 42 C4 1D 00 00 3E 4F 30 4D
+68 4E 85 42 45 47 49 4E 30 40 84 47 10 50 85 55
+4E 54 49 4C 39 40 C0 45 1A 42 C4 1D A2 52 C4 1D
+8A 49 00 00 8A 4E 02 00 3E 4F 30 4D 96 4D 85 41
+47 41 49 4E 39 40 BC 45 EF 3F 32 4E 85 57 48 49
+4C 45 87 12 D4 4F 6E 44 2A 44 CA 4E 86 52 45 50
+45 41 54 00 87 12 54 50 16 50 2A 44 EE 4F 82 44
+4F 00 2F 83 8F 4E 00 00 1E 42 C4 1D BE 40 CA 45
+00 00 2E 53 82 4E C4 1D A2 53 AC 1D 1A 42 AC 1D
+8A 43 00 00 30 4D C2 4B 84 4C 4F 4F 50 00 39 40
+EC 45 1A 42 C4 1D A2 52 C4 1D 8A 49 00 00 8A 4E
+02 00 1E 42 AC 1D A2 83 AC 1D 2E 4E 0E 93 04 24
+9E 42 C4 1D 00 00 F5 3F 3E 4F 30 4D E4 47 85 2B
+4C 4F 4F 50 39 40 DA 45 E4 3F A8 50 85 4C 45 41
+56 45 1A 42 C4 1D BA 40 FC 45 00 00 BA 40 BC 45
+02 00 B2 50 06 00 C4 1D A2 53 AC 1D 2A 52 19 42
+AC 1D 89 4A 00 00 30 4D EC 50 04 4D 4F 56 45 00
+0A 4E 38 4F 39 4F 3E 4F 0A 93 11 24 08 99 0F 24
+06 2C F8 49 00 00 18 53 1A 83 FB 23 30 4D 08 5A
+09 5A 19 83 18 83 E8 49 00 00 1A 83 FA 23 30 4D
+34 44 CA 1D FC 44 2A 44 84 12 50 51 52 54 3A 54
+7E 50 AC 4D 22 54 DE 50 1A 51 90 49 BE 51 F2 51
+2E 50 B2 52 48 45 58 4F C0 4E 68 4A 00 00 3A 40
+0C 00 39 40 CA 1D 38 40 CC 1D D9 3F 3A 40 0E 00
+39 40 CC 1D 38 40 CA 1D CC 3F 82 43 CC 1D 30 4D
+92 42 CA 1D C8 1D 30 4D 6C 4F 09 50 57 52 5F 53
+54 41 54 45 84 12 9A 4F 1E 54 68 5B AA 51 08 50
+57 52 5F 48 45 52 45 00 92 42 C4 1D BA 51 92 42
+C6 1D B8 51 EF 3F 6C 50 09 52 53 54 5F 53 54 41
+54 45 92 42 0C 18 BA 51 92 42 0E 18 B8 51 E2 3F
+D8 51 08 52 53 54 5F 48 45 52 45 00 92 42 C4 1D
+0C 18 92 42 C6 1D 0E 18 DF 3F B2 40 58 52 BA 52
+B2 40 A0 48 B0 48 B2 40 DC 48 F0 48 B2 40 DC 47
+EA 47 30 41 5C 50 04 57 49 50 45 00 39 40 80 FF
+B9 43 00 00 29 53 39 90 C6 FF FA 23 B0 12 0A 52
+B2 40 68 5B C4 1D B2 40 1E 54 C6 1D D7 3F D0 4F
+06 28 57 41 52 4D 29 00 1E 42 08 18 87 12 4E 49
+05 0D 1B 5B 37 6D 32 49 70 47 4E 49 27 20 46 61
+73 74 46 6F 72 74 68 20 56 31 36 30 20 31 36 4D
+48 7A 20 28 43 29 20 4A 2E 4D 2E 54 68 6F 6F 72
+65 6E 73 20 32 49 34 44 30 FF 84 47 2A 45 30 47
+4E 49 0B 62 79 74 65 73 20 66 72 65 65 20 34 4D
+26 52 04 57 41 52 4D 00 30 40 58 52 22 50 04 43
+4F 4C 44 00 B2 40 04 A5 20 01 B2 40 88 5A 5C 01
+92 43 04 02 B2 40 FE FF 02 02 A2 83 06 02 B2 43
+22 02 B2 D3 26 02 B2 43 42 02 B2 D3 46 02 B2 43
+62 02 B2 D3 66 02 B2 40 80 00 84 02 B2 40 7F FF
+82 02 B2 D0 7F FF 86 02 F2 43 22 03 F2 D3 26 03
+F2 40 A5 00 41 01 F2 40 10 00 40 01 D2 43 41 01
+F2 40 A5 00 61 01 B2 40 48 00 62 01 82 43 66 01
+39 40 80 00 B2 40 33 00 64 01 D2 43 61 01 92 D2
+9E 01 08 18 A2 93 08 18 01 24 59 07 38 40 C2 A2
+18 83 FE 23 19 83 FA 23 B2 42 B0 01 F2 D0 10 00
+2A 03 F2 C0 40 00 A2 04 3A 40 CA 52 39 40 C6 FF
+89 4A 00 00 29 53 FC 23 92 42 02 18 E4 FF B2 40
+18 00 0A 18 31 40 E0 1C 3F 40 80 1C 37 40 00 44
+36 40 B4 44 35 40 08 44 34 40 14 44 B2 40 0A 00
+DA 1D B2 43 DC 1D 92 C3 30 01 18 42 08 18 F2 B0
+10 00 20 02 04 20 38 E3 18 53 82 48 08 18 B2 40
+81 00 E0 05 B2 40 11 00 E6 05 B2 40 00 4A E8 05
+F2 D0 30 00 2A 02 92 C3 E0 05 92 D3 FA 05 3D 40
+F8 53 18 42 08 18 38 90 0A 00 20 27 38 90 16 00
+1D 2F 28 93 F6 22 DE 26 B8 52 84 12 50 51 46 5A
+F2 5A FA 59 46 5B C0 59 7A 5A C4 56 00 00 B6 59
+66 5A 18 5A 56 5A D4 57 00 00 00 00 58 5B 7C 51
+50 52 85 48 49 32 4C 4F 87 12 84 47 E8 4F B0 4B
+B8 4E 7E 51 FA 53 2A 44 BE 52 04 43 4F 44 45 00
+B0 12 CA 4D A2 82 C4 1D 87 12 F8 4E BC 45 32 54
+4E 50 03 41 53 4D 92 42 C8 1D B8 1D B2 40 FE 53
+C8 1D EE 3F 00 00 07 45 4E 44 43 4F 44 45 87 12
+8C 51 18 4E 2A 44 66 54 06 45 4E 44 41 53 4D 00
+92 42 B8 1D C8 1D F3 3F 00 00 05 43 4F 4C 4F 4E
+1A 42 C4 1D BA 40 87 12 00 00 A2 53 C4 1D B2 43
+B6 1D 30 40 8C 51 00 00 05 4C 4F 32 48 49 1A 42
+C4 1D BA 40 B0 12 00 00 BA 40 2A 44 02 00 A2 52
+C4 1D ED 3F 38 40 BE 1D 39 48 2A 48 09 5A 1A 52
+C2 1D 09 9A 03 24 7E 9A FC 27 1A 83 0E 4A 2A 88
+82 4A C2 1D 30 4D B0 12 2A 44 A8 49 00 4A 72 45
+C0 45 FC 54 BC 4A C0 45 BC 4D 1E 55 FE 54 29 4E
+39 90 86 12 02 20 2E 53 30 41 39 90 85 12 03 20
+1E 4E 02 00 30 41 39 90 84 12 01 20 2E 52 30 41
+19 42 C4 1D A2 53 C4 1D 89 4E 00 00 3E 40 29 00
+12 12 C2 1D 92 53 C2 1D B0 12 2A 44 A8 49 BC 4A
+C0 45 50 55 46 55 21 53 3E 90 10 00 BB 2D 30 41
+52 55 B2 41 C2 1D 22 D3 30 41 87 12 4C 46 C4 54
+62 55 82 43 BC 1D 92 42 C4 1D BA 1D A2 53 C4 1D
+0A 4E 3E 4F FA 90 23 00 00 00 34 20 92 53 C2 1D
+B0 12 E6 54 0E 93 04 20 B2 40 00 03 BC 1D 27 3C
+1E 93 04 20 B2 40 10 03 BC 1D 21 3C 2E 93 04 20
+B2 40 20 03 BC 1D 1B 3C 2E 92 04 20 B2 40 20 02
+BC 1D 15 3C 3E 92 04 20 B2 40 30 02 BC 1D 0F 3C
+3E 93 04 20 B2 40 30 03 BC 1D 09 3C B2 40 30 00
+BC 1D 19 42 C4 1D A2 53 C4 1D 89 4E 00 00 3E 4F
+3D 41 30 4D FA 90 26 00 00 00 08 20 B2 40 10 02
+BC 1D 92 53 C2 1D 30 12 D2 55 75 3F FA 90 40 00
+00 00 1A 20 B2 40 20 00 BC 1D 92 53 C2 1D B0 12
+30 55 0E 20 B2 50 10 00 BC 1D 3E 40 2B 00 B0 12
+30 55 32 24 92 92 BE 1D C2 1D 02 24 92 53 C2 1D
+8E 10 82 5E BC 1D D3 3F B0 12 30 55 F9 23 B2 50
+10 00 BC 1D 3E 40 28 00 B0 12 E6 54 30 12 22 56
+67 3F 87 12 4C 46 C4 54 5A 56 FE 90 26 00 00 00
+3E 40 20 00 04 20 B2 50 82 00 BC 1D C2 3F B0 12
+30 55 DF 23 B2 50 80 00 BC 1D 3E 40 28 00 B0 12
+E6 54 B0 12 20 55 D5 23 3D 40 BC 4D 30 4D 00 00
+04 52 45 54 49 00 87 12 34 44 00 13 B0 4B 2A 44
+34 44 2C 00 5A 55 52 56 AA 56 2E 4E 1E D2 BC 1D
+19 42 BA 1D 92 3F A8 54 03 4D 4F 56 84 12 A0 56
+00 40 B8 56 05 4D 4F 56 2E 42 84 12 A0 56 40 40
+00 00 03 41 44 44 84 12 A0 56 00 50 D2 56 05 41
+44 44 2E 42 84 12 A0 56 40 50 DE 56 04 41 44 44
+43 00 84 12 A0 56 00 60 EC 56 06 41 44 44 43 2E
+42 00 84 12 A0 56 40 60 90 56 04 53 55 42 43 00
+84 12 A0 56 00 70 0A 57 06 53 55 42 43 2E 42 00
+84 12 A0 56 40 70 18 57 03 53 55 42 84 12 A0 56
+00 80 28 57 05 53 55 42 2E 42 84 12 A0 56 40 80
+8A 54 03 43 4D 50 84 12 A0 56 00 90 42 57 05 43
+4D 50 2E 42 84 12 A0 56 40 90 78 54 04 44 41 44
+44 00 84 12 A0 56 00 A0 5C 57 06 44 41 44 44 2E
+42 00 84 12 A0 56 40 A0 4E 57 03 42 49 54 84 12
+A0 56 00 B0 7A 57 05 42 49 54 2E 42 84 12 A0 56
+40 B0 86 57 03 42 49 43 84 12 A0 56 00 C0 94 57
+05 42 49 43 2E 42 84 12 A0 56 40 C0 A0 57 03 42
+49 53 84 12 A0 56 00 D0 AE 57 05 42 49 53 2E 42
+84 12 A0 56 40 D0 00 00 03 58 4F 52 84 12 A0 56
+00 E0 C8 57 05 58 4F 52 2E 42 84 12 A0 56 40 E0
+FA 56 03 41 4E 44 84 12 A0 56 00 F0 E2 57 05 41
+4E 44 2E 42 84 12 A0 56 40 F0 4C 46 5A 55 00 58
+1A 42 BC 1D B2 F0 70 00 BC 1D 8A 10 3A F0 0F 00
+82 DA BC 1D 4A 3F 34 57 03 52 52 43 84 12 FA 57
+00 10 18 58 05 52 52 43 2E 42 84 12 FA 57 40 10
+24 58 04 53 57 50 42 00 84 12 FA 57 80 10 32 58
+03 52 52 41 84 12 FA 57 00 11 40 58 05 52 52 41
+2E 42 84 12 FA 57 40 11 4C 58 03 53 58 54 84 12
+FA 57 80 11 00 00 04 50 55 53 48 00 84 12 FA 57
+00 12 66 58 06 50 55 53 48 2E 42 00 84 12 FA 57
+40 12 BA 57 04 43 41 4C 4C 00 84 12 FA 57 80 12
+34 44 2C 00 5A 55 52 56 9A 58 59 42 BC 1D 5A 42
+BD 1D 82 4A BC 1D BE 90 00 15 00 00 02 20 0A 89
+02 3C 09 8A 0A 49 3A 90 10 00 03 2C 5A 0E A8 3F
+1A 53 0E 4A 87 12 70 47 4E 49 0D 6F 75 74 20 6F
+66 20 62 6F 75 6E 64 73 2E 4D 74 58 05 50 55 53
+48 4D 84 12 90 58 00 15 DC 58 04 50 4F 50 4D 00
+84 12 90 58 00 17 4C 46 C4 54 FC 58 82 43 BC 1D
+92 42 C4 1D BA 1D A2 53 C4 1D 92 53 C2 1D 3E 40
+2C 00 B0 12 2A 44 A8 49 BC 4A C0 45 BC 4D 52 56
+22 59 0A 4E 3E 4F 1A 83 2A 92 CA 2F 8A 10 5A 06
+6F 3F 5A 58 04 52 52 43 4D 00 84 12 F6 58 50 00
+34 59 04 52 52 41 4D 00 84 12 F6 58 50 01 42 59
+04 52 4C 41 4D 00 84 12 F6 58 50 02 50 59 04 52
+52 55 4D 00 84 12 F6 58 50 03 85 12 00 3C 5E 59
+03 53 3E 3D 85 12 00 38 70 59 02 53 3C 00 85 12
+00 34 EA 58 03 30 3E 3D 85 12 00 30 84 59 02 30
+3C 00 85 12 00 30 00 00 02 55 3C 00 85 12 00 2C
+98 59 03 55 3E 3D 85 12 00 28 8E 59 03 30 3C 3E
+85 12 00 24 AC 59 02 30 3D 00 85 12 00 20 00 00
+02 49 46 00 1A 42 C4 1D 8A 4E 00 00 A2 53 C4 1D
+0E 4A 30 4D A2 59 04 54 48 45 4E 00 1A 42 C4 1D
+08 4E 3E 4F 09 48 29 53 0A 89 0A 11 3A 90 00 02
+68 2F 88 DA 00 00 30 4D 6A 57 04 45 4C 53 45 00
+1A 42 C4 1D BA 40 00 3C 00 00 A2 53 C4 1D 2F 83
+8F 4A 00 00 E3 3F D6 59 05 55 4E 54 49 4C 3A 4F
+08 4E 3E 4F 19 42 C4 1D 2A 83 0A 89 0A 11 3A 90
+00 FE 47 3B 3A F0 FF 03 08 DA 89 48 00 00 A2 53
+C4 1D 30 4D EE 57 05 41 47 41 49 4E 87 12 6A 59
+1E 5A 2A 44 00 00 05 57 48 49 4C 45 87 12 C4 59
+6E 44 2A 44 7A 59 06 52 45 50 45 41 54 00 87 12
+6A 59 1E 5A DC 59 2A 44 00 00 03 4A 4D 50 87 12
+AE 4D 6A 59 1E 5A 2A 44 3E B0 00 10 03 20 3E E0
+00 04 30 4D 3E 90 00 34 06 28 03 24 3E 40 00 34
+30 4D 3E 40 00 38 30 4D 00 00 04 3F 4A 4D 50 00
+87 12 88 5A AE 4D 6E 44 1E 5A 2A 44 BE 5A 3D 41
+08 4E 3E 4F 2A 48 0A 93 04 20 98 42 C4 1D 00 00
+30 4D 88 43 00 00 A4 3F 84 58 03 42 57 31 84 12
+BC 5A 00 00 DA 5A 03 42 57 32 84 12 BC 5A 00 00
+E6 5A 03 42 57 33 84 12 BC 5A 00 00 FE 5A 3D 41
+1A 42 C4 1D 28 4E 08 93 08 20 BA 4F 00 00 A2 53
+C4 1D 8E 4A 00 00 3E 4F 30 4D 8E 43 00 00 61 3F
+00 00 03 46 57 31 84 12 FC 5A 00 00 22 5B 03 46
+57 32 84 12 FC 5A 00 00 2E 5B 03 46 57 33 84 12
+FC 5A 00 00 3A 5B 04 47 4F 54 4F 00 87 12 6A 59
+AE 4D A6 4B 2A 44 AA 5A 05 3F 47 4F 54 4F 87 12
+88 5A AE 4D A6 4B 2A 44
+@FFC6
+CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52
+CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 4C 48
+CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52 CA 52
+CA 52 CA 52 CA 52 CA 52 CA 52
+q
--- /dev/null
+\prog\MSP430Flasher\msp430flasher -m SBW2 -n MSP430fr6989 -v -w %1 -z [VCC=3000]
+exit
+
+tip : how to calculate MAIN program lenght ?
+
+open the prog.txt file with your editor, select MAIN section
+in status bar, keep the number of selected chars
+if lines are ended with CR+LF, substract the number of lines selected
+then divide by 3.
--- /dev/null
+; -*- coding: utf-8 -*-
+; MY_MSP430FR5738.asm
+; config file for MY_MSP430FR5738 board
+;
+; Copyright (C) <2014> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+; ======================================================================
+; MY_MSP430FR5738 board
+; ======================================================================
+
+; MSP430FR5738 XTAL 32768 Hz
+; 1 --- PJ.4 --- LFXIN
+; 2 --- PJ.5 --- LFXOUT
+
+; MSP430FR5738 PROG 6PINS UART 4PINS
+; --- VCC <-> 2 "3v3" <-> 1 "3v3"
+; 20 --- P2.1 <-- 6 "RXD" <-- 2 "RXD"
+; +--4k7-< DeepRST <-- GND
+; |
+; 19 --- P2.0 <+> 1 "TXD" --> 3 "TXD"
+; --- VSS <-> 5 "GND" <-> 4 "GND"
+; 17 --- TEST --- 3 "TST"
+; 18 --- RST --- 4 "RST"
+
+; SWITCH PROG/UART
+; oriented to UART 4PINS
+
+; I2C 4PINS
+; 1 "3v3" <-> DVCC,AVCC
+; 2 "SCL" <-> pin23 = P1.7 == UCB0RXD --> UCB0RXDBUF
+; 3 "SDA" <-> pin22 = P1.6 == UCB0TXD <-- UCB0TXDBUf
+; 4 "GND" <-> DVSS,AVSS
+
+; P1
+; 1 <-> pin5 P1.0/TA0.1/DMAE0/RTCCLK/A0/CD0/VeREF-
+; 2 <-> pin6 P1.1/TA0.2/TA1CLK/CDOUT/A1/CD1/VeREF+
+; 3 <-> pin7 P1.2/TA1.1/TA0CLK/CDOUT/A2/CD2
+; 4 <-> pin8 P1.3/TA1.2/UCB0STE/A3/CD3
+; 5 <-> pin9 P1.4/TB0.1/UCA0STE/A4/CD4
+; 6 <-> pin10 P1.5/TB0.2/UCA0CLK/A5/CD5
+; 7 <-> pin22 P1.6/UCB0SIMO/UCB0SDA/TA0.0
+; 8 <-> pin23 P1.7/UCB0SOMI/UCB0SCL/TA1.0
+
+; P2
+; 1 <-> pin19 P2.0/UCA0TXD/UCA0SIMO/TB0CLK/ACLK
+; 2 <-> pin20 P2.1/UCA0RXD/UCA0SOMI/TB0.0
+; 3 <-> pin21 P2.2/UCB0CLK
+; 4 <-> pin27 P2.3/TA0.0/A6/CD10
+; 5 <-> pin28 P2.4/TA1.0/A7/CD11
+; 6 <-> pin15 P2.5/TB0.0
+; 7 <-> pin16 P2.6
+; 8 <-> "NC "
+
+; PJ
+; 1 <-> "3V3 "
+; 2 <-> "3V3 "
+; 3 <-> pin11 PJ.0/TDO/TB0OUTH/SMCLK/CD6
+; 4 <-> pin12 PJ.1/TDI/TCLK/MCLK/CD7
+; 5 <-> pin13 PJ.2/TMS/ACLK/CD8
+; 6 <-> pin14 PJ.3/TCK/CD9
+; 7 <-> "GND "
+; 8 <-> "GND "
+
+; XTAL 32768 Hz
+; PJ.4 <->XIN LF XTAL
+; PJ.5 <->XOUT LF XTAL
+
+; Vcc <------------------------- Vcc \
+; RST <------------------------> RST \ TI_PROGRM
+; TST <------------------------> TST / INTERFACE
+; Vss <------------------------> Gnd /
+
+; Vcc <------------------------- Vcc \
+; P2.0 TX0 ---------------------> RX \ UARTtoUSB
+; P2.1 RX0 <--------------------- TX / CP2102
+; Vss <------------------------> Gnd /
+
+; GND <-------+---0V0----------> 1 LCD_Vss
+; VCC <------ | --3V6-----+----> 2 LCD_Vdd
+; | |
+; |___ 470n ---
+; ^ | ---
+; / \ BAT54 |
+; --- |
+; 100n | 2k2 |
+; P1.5 >---||--+--^/\/\/v--+----> 3 LCD_Vo (=0V6 without modulation)
+; P1.4 >------------------------> 4 LCD_RS
+; P1.3 >------------------------> 5 LCD_R/W
+; P1.2 >------------------------> 6 LCD_EN
+
+; P1.1 >------------------------> 5 SCL I2C MASTER
+; P1.0 >------------------------> 6 SDA I2C MASTER | IR_RC5 receiver
+
+; PJ.0 <------------------------> 11 LCD_DB4
+; PJ.1 <------------------------> 12 LCD_DB5
+; PJ.2 <------------------------> 13 LCD_DB5
+; PJ.3 <------------------------> 14 LCD_DB7
+
+; P2.5 ---> S2 LCD contrast +
+; P2.6 ---> S1 LCD contrast - | HARD WIPE
+
+
+
+; VCC P1.1 ---> red SD_CardAdapter VCC
+; GND P1.2 <--> black SD_CardAdapter GND
+; P1.6/UCB0SIMO/UCB0SDA/TA0.0 P1.7 ---> grey SD_CardAdapter SDI (MOSI)
+; P1.7/UCB0SOMI/UCB0SCL/TA1.0 <--- purple SD_CardAdapter SDO (MISO)
+; P2.2/UCB0CLK ---> orange SD_CardAdapter CLK (SCK)
+; P2.3/TA0.0/A6/CD10 <--- violin SD_CardAdapter CD (Card Detect)
+; P2.4/TA1.0/A7/CD11 ---> brown SD_CardAdapter CS (Card Select)
+
+
+
+; Clocks:
+; 24 MHz DCO intern
+
+; ----------------------------------------------------------------------
+; INIT order : LOCK I/O, WDT, GPIOs, FRAM, Clock, UARTs
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : LOCK I/O as high impedance state
+; ----------------------------------------------------------------------
+
+ BIS #LOCKLPM5,&PM5CTL0 ; unlocked by WARM
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : WATCHDOG TIMER A
+; ----------------------------------------------------------------------
+
+; WDT code
+ MOV #WDTPW+WDTHOLD+WDTCNTCL,&WDTCTL ; stop WDT
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : I/O
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION PAIN=PORT2:PORT1
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT1 usage
+
+; PORT2 usage
+
+Deep_RST_IN .equ P2IN ; TERMINAL TX pin as FORTH Deep_RST
+Deep_RST .equ 1 ; P2.0 = TX
+TERM_TXRX .equ 003h ; P2.1 = RX
+TERM_SEL .equ P2SEL1
+TERM_REN .equ P2REN
+
+ .IFDEF TERMINALCTSRTS
+;configure P2.2 as RTS output high
+RTS .equ 4
+HANDSHAKOUT .equ P2OUT
+HANDSHAKIN .equ P2IN
+ BIS.B #RTS,&HANDSHAKOUT
+ .ENDIF
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #-1,&PAOUT ; all pins 1
+ BIS #-1,&PAREN ; all pins 1 with pull resistors
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORTJ
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORTJ usage
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV.B #-1,&PJOUT ; pullup resistors
+ BIS.B #-1,&PJREN ; enable pullup/pulldown resistors
+
+; ----------------------------------------------------------------------
+; FRAM config
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : CLOCK SYSTEM
+; ----------------------------------------------------------------------
+
+; DCOCLK: Internal digitally controlled oscillator (DCO).
+
+ MOV.B #CSKEY,&CSCTL0_H ; Unlock CS registers
+
+ .IF FREQUENCY = 0.5
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_16 + DIVM_16,&CSCTL3
+ MOV #4,X
+
+ .ELSEIF FREQUENCY = 1
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_8 + DIVM_8,&CSCTL3
+ MOV #8,X
+
+ .ELSEIF FREQUENCY = 2
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_4 + DIVM_4,&CSCTL3
+ MOV #16,X
+
+ .ELSEIF FREQUENCY = 4
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_2 + DIVM_2,&CSCTL3
+ MOV #32,X
+
+ .ELSEIF FREQUENCY = 8
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #64,X
+
+ .ELSEIF FREQUENCY = 16
+ MOV #DCORSEL,&CSCTL1 ; Set 16MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #128,X
+
+ .ELSEIF FREQUENCY = 24
+ MOV #DCORSEL+DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 24 MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #192,X
+
+ .ELSEIF
+ .error "bad frequency setting, only 0.5,1,2,4,8,16,24 MHz"
+ .ENDIF
+
+ .IFDEF LF_XTAL
+ MOV #SELA_LFXCLK+SELS_DCOCLK+SELM_DCOCLK,&CSCTL2
+ .ELSE
+ MOV #SELA_VLOCLK+SELS_DCOCLK+SELM_DCOCLK,&CSCTL2
+ .ENDIF
+ MOV.B #01h, &CSCTL0_H ; Lock CS Registers
+
+ BIS &SYSRSTIV,&SAVE_SYSRSTIV; store volatile SYSRSTIV preserving a pending request for DEEP_RST
+ CMP #2,&SAVE_SYSRSTIV ; POWER ON ?
+ JZ ClockWaitX ; yes
+ .word 0759h ; no RRUM #2,X --> wait only 125 ms
+ClockWaitX MOV #41666,Y ; wait 0.5s before starting after POWER ON
+ClockWaitY SUB #1,Y ;
+ JNZ ClockWaitY ; 41666x3 = 125000 cycles delay = 125ms @ 1MHz
+ SUB #1,X ; x 4 @ 1 MHZ
+ JNZ ClockWaitX ; time to stabilize power source ( 1s )
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : REF
+; ----------------------------------------------------------------------
+
+ MOV #8, &REFCTL
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : RTC REGISTERS
+; ----------------------------------------------------------------------
+
+ .IFDEF LF_XTAL
+; LF Xtal XIN : PJ.4, LF Xtal XOUT : PJ.5
+ BIS.B #010h,&PJSEL0 ; SEL0 for only XIN
+ BIC.B #RTCHOLD,&RTCCTL1 ; Clear RTCHOLD = start RTC_B
+ .ENDIF
+
--- /dev/null
+; -*- coding: utf-8 -*-
+; MY_MSP430FR5738_1.asm
+; config file for MY_MSP430FR5738 board
+;
+; Copyright (C) <2014> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+; ======================================================================
+; MY_MSP430FR5738_1 BOARD
+; ======================================================================
+;
+; MSP430FR5738 XTAL 32768 Hz
+; 1 --- PJ.4 --- LFXIN
+; 2 --- PJ.5 --- LFXOUT
+;
+; MSP430FR5738 PROG 6PINS ISOLATOR
+; --- VCC <-> 2 "3v3" >--------> Vdd1 1 [| SI |] 8 Vdd2 <---< 3v3 )
+; 20 --- P2.1 <-- 6 "RX0" <---4k7--< A1 2 [| 86 |] 7 B1 <---- TXD \ UART2USB
+; 19 --- P2.0 <-> 1 "TX0" <--+-----> A2 3 [| 22 |] 6 B2 >---> RXD / PL2303TA
+; --- VSS <-> 5 "GND" <- | ----> Gnd1 4 [| EC |] 5 Gnd2 <---> GND )
+; 17 --- TEST --- 3 "TST" |
+; 18 --- RST --- 4 "RST" |
+; +-4k7-< DeepRST <-- GND
+
+; DIP1 AVcc -- ferrite bead -- DVcc
+; DIP2 AVss -- ferrite bead -- DVss
+; DIP3 GND
+; DIP4 P2.4/TA1.0/A7/CD11
+; DIP5 P2.3/TA0.0/A6/CD10
+; DIP6 P1.7/UCB0SOMI/UCB0SCL/TA1.0
+; DIP7 P1.6/UCB0SIMO/UCB0SDA/TA0.0
+; DIP8 P2.2/UCB0CLK
+; DIP9 P2.6
+; DIP10 P2.5/TB0.0
+; DIP11 PJ.3/TCK/CD9
+; DIP12 PJ.2/TMS/ACLK/CD8
+; DIP13 PJ.1/TDI/TCLK/MCLK/CD7
+; DIP14 PJ.0/TDO/TB0OUTH/SMCLK/CD6
+; DIP15 P1.5/TB0.2/UCA0CLK/A5/CD5
+; DIP16 P1.4/TB0.1/UCA0STE/A4/CD4
+; DIP17 P1.3/TA1.2/UCB0STE/A3/CD3
+; DIP18 P1.2/TA1.1/TA0CLK/CDOUT/A2/CD2
+; DIP19 P1.1/TA0.2/TA1CLK/CDOUT/A1/CD1/VeREF+
+; DIP20 P1.0/TA0.1/DMAE0/RTCCLK/A0/CD0/VeREF-
+
+
+; CPU OUTPUT WORLD
+; --- ------------
+; GND <-------+---0V0----------> 1 LCD_Vss
+; VCC <------ | --3V6-----+----> 2 LCD_Vdd
+; | |
+; ___ 470n ---
+; ^ ---
+; / \ 1N4148 |
+; --- |
+; 100n | 2k2 |
+; P1.5 >---||--+--^/\/\/v--+----> 3 LCD_Vo (0V6 without modulation)
+; P1.4 >------------------------> 4 LCD_RS
+; P1.3 >------------------------> 5 LCD_R/W
+; P1.2 >------------------------> 6 LCD_EN
+;
+; PJ.0 <------------------------> 11 LCD_DB4
+; PJ.1 <------------------------> 12 LCD_DB5
+; PJ.2 <------------------------> 13 LCD_DB5
+; PJ.3 <------------------------> 14 LCD_DB7
+;
+; P2.5 <------------------------< S2 LCD contrast +
+; P2.6 <------------------------< S1 LCD contrast -
+;
+; P1.1 >------------------------> SCL I2C MASTER
+; P1.0 >------------------------> SDA I2C MASTER | IR_RC5 receiver
+;
+;
+;
+; VCC DIP1 ---> red SD_CardAdapter VCC
+; GND DIP2 <--> black SD_CardAdapter GND
+; P1.6/UCB0SIMO/UCB0SDA/TA0.0 DIP7 ---> grey SD_CardAdapter SDI (MOSI)
+; P1.7/UCB0SOMI/UCB0SCL/TA1.0 DIP6 <--- purple SD_CardAdapter SDO (MISO)
+; P2.2/UCB0CLK DIP8 ---> orange SD_CardAdapter CLK (SCK)
+; P2.3/TA0.0/A6/CD10 DIP5 <--- violin SD_CardAdapter CD (Card Detect)
+; P2.4/TA1.0/A7/CD11 DIP4 ---> brown SD_CardAdapter CS (Card Select)
+
+; Clocks:
+; 24 MHz DCO intern
+
+; ----------------------------------------------------------------------
+; INIT order : LOCK I/O, WDT, GPIOs, FRAM, Clock, UARTs
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : LOCK I/O as high impedance state
+; ----------------------------------------------------------------------
+
+ BIS #LOCKLPM5,&PM5CTL0 ; unlocked by WARM
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : WATCHDOG TIMER A
+; ----------------------------------------------------------------------
+
+; WDT code
+ MOV #WDTPW+WDTHOLD+WDTCNTCL,&WDTCTL ; stop WDT
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : I/O
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION PAIN=PORT2:PORT1
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT1 usage
+
+; PORT2 usage
+
+Deep_RST_IN .equ P2IN ; TERMINAL TX pin as FORTH Deep_RST
+Deep_RST .equ 1 ; P2.0 = TX
+TERM_TXRX .equ 003h ; P2.1 = RX
+TERM_SEL .equ P2SEL1
+TERM_REN .equ P2REN
+
+ .IFDEF TERMINALCTSRTS
+;configure P2.2 as RTS output high
+RTS .equ 4
+HANDSHAKOUT .equ P2OUT
+HANDSHAKIN .equ P2IN
+ BIS.B #RTS,&HANDSHAKOUT
+ .ENDIF
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #-1,&PAOUT ; all pins 1
+ BIS #-1,&PAREN ; all pins 1 with pull resistors
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORTJ
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORTJ usage
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV.B #-1,&PJOUT ; pullup resistors
+ BIS.B #-1,&PJREN ; enable pullup/pulldown resistors
+
+; ----------------------------------------------------------------------
+; FRAM config
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : CLOCK SYSTEM
+; ----------------------------------------------------------------------
+
+; DCOCLK: Internal digitally controlled oscillator (DCO).
+
+ MOV.B #CSKEY,&CSCTL0_H ; Unlock CS registers
+
+ .IF FREQUENCY = 0.5
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_16 + DIVM_16,&CSCTL3
+ MOV #4,X
+
+ .ELSEIF FREQUENCY = 1
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_8 + DIVM_8,&CSCTL3
+ MOV #8,X
+
+ .ELSEIF FREQUENCY = 2
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_4 + DIVM_4,&CSCTL3
+ MOV #16,X
+
+ .ELSEIF FREQUENCY = 4
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_2 + DIVM_2,&CSCTL3
+ MOV #32,X
+
+ .ELSEIF FREQUENCY = 8
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #64,X
+
+ .ELSEIF FREQUENCY = 16
+ MOV #DCORSEL,&CSCTL1 ; Set 16MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #128,X
+
+ .ELSEIF FREQUENCY = 24
+ MOV #DCORSEL+DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 24 MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #192,X
+
+ .ELSEIF
+ .error "bad frequency setting, only 0.5,1,2,4,8,16,24 MHz"
+ .ENDIF
+
+ .IFDEF LF_XTAL
+ MOV #SELA_LFXCLK+SELS_DCOCLK+SELM_DCOCLK,&CSCTL2
+ .ELSE
+ MOV #SELA_VLOCLK+SELS_DCOCLK+SELM_DCOCLK,&CSCTL2
+ .ENDIF
+ MOV.B #01h, &CSCTL0_H ; Lock CS Registers
+
+ BIS &SYSRSTIV,&SAVE_SYSRSTIV; store volatile SYSRSTIV preserving a pending request for DEEP_RST
+ CMP #2,&SAVE_SYSRSTIV ; POWER ON ?
+ JZ ClockWaitX ; yes
+ .word 0759h ; no RRUM #2,X --> wait only 125 ms
+ClockWaitX MOV #41666,Y ; wait 0.5s before starting after POWER ON
+ClockWaitY SUB #1,Y ;
+ JNZ ClockWaitY ; 41666x3 = 125000 cycles delay = 125ms @ 1MHz
+ SUB #1,X ; x 4 @ 1 MHZ
+ JNZ ClockWaitX ; time to stabilize power source ( 1s )
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : REF
+; ----------------------------------------------------------------------
+
+ MOV #8, &REFCTL
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : RTC REGISTERS
+; ----------------------------------------------------------------------
+
+ .IFDEF LF_XTAL
+; LF Xtal XIN : PJ.4, LF Xtal XOUT : PJ.5
+ BIS.B #010h,&PJSEL0 ; SEL0 for only XIN
+ BIC.B #RTCHOLD,&RTCCTL1 ; Clear RTCHOLD = start RTC_B
+ .ENDIF
+
--- /dev/null
+; -*- coding: utf-8 -*-
+; MY_MSP430FR5738_2.asm
+; config file for MY_MSP430FR5738 board
+;
+; Copyright (C) <2014> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+; ======================================================================
+; MY_MSP430FR5738_2 BOARD
+; ======================================================================
+;
+; MSP430FR5738 XTAL 32768 Hz
+; 1 --- PJ.4 --- LFXIN
+; 2 --- PJ.5 --- LFXOUT
+;
+; MSP430FR5738 PROG 6PINS ISOLATOR
+; --- VCC <-> 2 "3v3" >--------> Vdd1 1 [| SI |] 8 Vdd2 <---< 3v3 )
+; 20 --- P2.1 <-- 6 "RX0" <---4k7--< A1 2 [| 86 |] 7 B1 <---- TXD \ UART2USB
+; 19 --- P2.0 <-> 1 "TX0" <--+-----> A2 3 [| 22 |] 6 B2 >---> RXD / PL2303TA
+; --- VSS <-> 5 "GND" <- | ----> Gnd1 4 [| EC |] 5 Gnd2 <---> GND )
+; 17 --- TEST --- 3 "TST" |
+; 18 --- RST --- 4 "RST" |
+; +-4k7-< DeepRST <-- GND
+
+; DIP1 AVcc -- ferrite bead -- DVcc
+; DIP2 AVss -- ferrite bead -- DVss
+; DIP3 P2.4/TA1.0/A7/CD11
+; DIP4 P2.3/TA0.0/A6/CD10
+; DIP5 P1.7/UCB0SOMI/UCB0SCL/TA1.0
+; DIP6 P1.6/UCB0SIMO/UCB0SDA/TA0.0
+; DIP7 P2.2/UCB0CLK
+; DIP8 P2.6
+; DIP9 P2.5/TB0.0
+; DIP10 GND
+; DIP11 PJ.3/TCK/CD9
+; DIP12 PJ.2/TMS/ACLK/CD8
+; DIP13 PJ.1/TDI/TCLK/MCLK/CD7
+; DIP14 PJ.0/TDO/TB0OUTH/SMCLK/CD6
+; DIP15 P1.5/TB0.2/UCA0CLK/A5/CD5
+; DIP16 P1.4/TB0.1/UCA0STE/A4/CD4
+; DIP17 P1.3/TA1.2/UCB0STE/A3/CD3
+; DIP18 P1.2/TA1.1/TA0CLK/CDOUT/A2/CD2
+; DIP19 P1.1/TA0.2/TA1CLK/CDOUT/A1/CD1/VeREF+
+; DIP20 P1.0/TA0.1/DMAE0/RTCCLK/A0/CD0/VeREF-
+
+
+; CPU OUTPUT WORLD
+; --- ------------
+; GND <-------+---0V0----------> 1 LCD_Vss
+; VCC <------ | --3V6-----+----> 2 LCD_Vdd
+; | |
+; ___ 470n ---
+; ^ ---
+; / \ 1N4148 |
+; --- |
+; 100n | 2k2 |
+; P1.5 >---||--+--^/\/\/v--+----> 3 LCD_Vo (0V6 without modulation)
+; P1.4 >------------------------> 4 LCD_RS
+; P1.3 >------------------------> 5 LCD_R/W
+; P1.2 >------------------------> 6 LCD_EN
+;
+; PJ.0 <------------------------> 11 LCD_DB4
+; PJ.1 <------------------------> 12 LCD_DB5
+; PJ.2 <------------------------> 13 LCD_DB5
+; PJ.3 <------------------------> 14 LCD_DB7
+;
+; P2.5 <------------------------< S2 LCD contrast +
+; P2.6 <------------------------< S1 LCD contrast -
+;
+; P1.1 >------------------------> SCL I2C MASTER
+; P1.0 >------------------------> SDA I2C MASTER | IR_RC5 receiver
+;
+;
+;
+; VCC DIP1 ---> red SD_CardAdapter VCC
+; GND DIP2 <--> black SD_CardAdapter GND
+; P2.4/TA1.0/A7/CD11 DIP3 ---> brown SD_CardAdapter CS (Card Select)
+; P2.3/TA0.0/A6/CD10 DIP4 <--- violin SD_CardAdapter CD (Card Detect)
+; P1.7/UCB0SOMI/UCB0SCL/TA1.0 DIP5 <--- purple SD_CardAdapter SDO (MISO)
+; P1.6/UCB0SIMO/UCB0SDA/TA0.0 DIP6 ---> grey SD_CardAdapter SDI (MOSI)
+; P2.2/UCB0CLK DIP7 ---> orange SD_CardAdapter CLK (SCK)
+
+
+; Clocks:
+; 24 MHz DCO intern
+
+; ----------------------------------------------------------------------
+; INIT order : LOCK I/O, WDT, GPIOs, FRAM, Clock, UARTs
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : LOCK I/O as high impedance state
+; ----------------------------------------------------------------------
+
+ BIS #LOCKLPM5,&PM5CTL0 ; unlocked by WARM
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : WATCHDOG TIMER A
+; ----------------------------------------------------------------------
+
+; WDT code
+ MOV #WDTPW+WDTHOLD+WDTCNTCL,&WDTCTL ; stop WDT
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : I/O
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION PAIN=PORT2:PORT1
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT1 usage
+
+; PORT2 usage
+
+Deep_RST_IN .equ P2IN ; TERMINAL TX pin as FORTH Deep_RST
+Deep_RST .equ 1 ; P2.0 = TX
+TERM_TXRX .equ 003h ; P2.1 = RX
+TERM_SEL .equ P2SEL1
+TERM_REN .equ P2REN
+
+ .IFDEF TERMINALCTSRTS
+;configure P2.2 as RTS output high
+RTS .equ 4
+HANDSHAKOUT .equ P2OUT
+HANDSHAKIN .equ P2IN
+ BIS.B #RTS,&HANDSHAKOUT
+ .ENDIF
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #-1,&PAOUT ; all pins 1
+ BIS #-1,&PAREN ; all pins 1 with pull resistors
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORTJ
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORTJ usage
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV.B #-1,&PJOUT ; pullup resistors
+ BIS.B #-1,&PJREN ; enable pullup/pulldown resistors
+
+; ----------------------------------------------------------------------
+; FRAM config
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : CLOCK SYSTEM
+; ----------------------------------------------------------------------
+
+; DCOCLK: Internal digitally controlled oscillator (DCO).
+
+ MOV.B #CSKEY,&CSCTL0_H ; Unlock CS registers
+
+ .IF FREQUENCY = 0.5
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_16 + DIVM_16,&CSCTL3
+ MOV #4,X
+
+ .ELSEIF FREQUENCY = 1
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_8 + DIVM_8,&CSCTL3
+ MOV #8,X
+
+ .ELSEIF FREQUENCY = 2
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_4 + DIVM_4,&CSCTL3
+ MOV #16,X
+
+ .ELSEIF FREQUENCY = 4
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_2 + DIVM_2,&CSCTL3
+ MOV #32,X
+
+ .ELSEIF FREQUENCY = 8
+; MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #64,X
+
+ .ELSEIF FREQUENCY = 16
+ MOV #DCORSEL,&CSCTL1 ; Set 16MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #128,X
+
+ .ELSEIF FREQUENCY = 24
+ MOV #DCORSEL+DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 24 MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #192,X
+
+ .ELSEIF
+ .error "bad frequency setting, only 0.5,1,2,4,8,16,24 MHz"
+ .ENDIF
+
+ .IFDEF LF_XTAL
+ MOV #SELA_LFXCLK+SELS_DCOCLK+SELM_DCOCLK,&CSCTL2
+ .ELSE
+ MOV #SELA_VLOCLK+SELS_DCOCLK+SELM_DCOCLK,&CSCTL2
+ .ENDIF
+ MOV.B #01h, &CSCTL0_H ; Lock CS Registers
+
+ BIS &SYSRSTIV,&SAVE_SYSRSTIV; store volatile SYSRSTIV preserving a pending request for DEEP_RST
+ CMP #2,&SAVE_SYSRSTIV ; POWER ON ?
+ JZ ClockWaitX ; yes
+ .word 0759h ; no RRUM #2,X --> wait only 125 ms
+ClockWaitX MOV #41666,Y ; wait 0.5s before starting after POWER ON
+ClockWaitY SUB #1,Y ;
+ JNZ ClockWaitY ; 41666x3 = 125000 cycles delay = 125ms @ 1MHz
+ SUB #1,X ; x 4 @ 1 MHZ
+ JNZ ClockWaitX ; time to stabilize power source ( 1s )
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : REF
+; ----------------------------------------------------------------------
+
+ MOV #8, &REFCTL
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : RTC REGISTERS
+; ----------------------------------------------------------------------
+
+ .IFDEF LF_XTAL
+; LF Xtal XIN : PJ.4, LF Xtal XOUT : PJ.5
+ BIS.B #010h,&PJSEL0 ; SEL0 for only XIN
+ BIC.B #RTCHOLD,&RTCCTL1 ; Clear RTCHOLD = start RTC_B
+ .ENDIF
+
--- /dev/null
+; -*- coding: utf-8 -*-
+; MY_MSP430FR5948.asm
+
+; Fast Forth For Texas Instrument MSP430FR5739
+;
+; Copyright (C) <2014> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+; ======================================================================
+; MY_MSP430FR5948 : MSP430FR5948 TSSOP38 to DIP28 board MAP
+; may be remplaced by MSP430FR5939 TSSOP 38
+; with this first version, RX don't work via prog6pins when SI8622EC is present
+; ======================================================================
+
+; MSP430FR5948 XTAL 32768 Hz
+; 1 --- PJ.4 --- LFXIN
+; 2 --- PJ.5 --- LFXOUT
+
+; MSP430FR5948 PROG 6PINS ISOLATED UARTtoUSB bridge
+; --- VCC <-> 2 "3v3" --------> 1 Vdd1 <| SI |> Vdd2 8 <-- 3v3
+; 24 --- P2.1 <-- 6 "RX0" <----4k7- 2 A1 <| 86 |> B1 7 <-- TXD
+; 23 --- P2.0 <-> 1 "TX0" <--+----> 3 A2 <| 22 |> B2 6 --> RXD
+; --- VSS <-> 5 "GND" <- | ---> 4 Gnd1 <| EC |> Gnd2 5 <-- GND
+; 21 --- TEST --- 3 "TST" |
+; 22 --- RST --- 4 "RST" |
+; +-4k7- DeepRST <-- GND
+
+; MSP430FR5948 DIP28
+; 4,34 --- VCC --- 1 ; +
+; 3,33,38 --- VSS --- 2 ; -
+; 37 --- P2.4 --- 3 ; TA1.0/UCA1CLK/A7/C11
+; 36 --- P2.3 --- 4 ; TA0.0/UCA1STE/A6/C10
+; 5 ; GND
+; 31 --- P1.7 --- 6 ; TB0.4/UCB0SOMI/UCB0SCL/TA1.0
+; 30 --- P1.6 --- 7 ; TB0.3/UCB0SIMO/UCB0SDA/TA0.0
+; 29 --- P3.7 --- 8 ; TB0.6
+; 28 --- P3.6 --- 9 ; TB0.5
+; 27 --- P3.5 --- 10 ; TB0.4/COUT
+; 26 --- P3.4 --- 11 ; TB0.3/SMCLK
+; 20 --- P2.6 --- 12 ; TB0.1/UCA1RXD/UCA1SOMI
+; 25 --- P2.2 --- 13 ; TB0.2/UCB0CLK
+; 19 --- P2.5 --- 14 ; TB0.0/UCA1TXD/UCA1SIMO
+; 15 --- PJ.0 --- 15 ; TDO/TB0OUTH/SMCLK/SRSCG1/C6
+; 16 --- PJ.1 --- 16 ; TDI/TCLK/MCLK/SRSCG0/C7
+; 17 --- PJ.2 --- 17 ; TMS/ACLK/SROSCOFF/C8
+; 18 --- PJ.3 --- 18 ; TCK/SRCPUOFF/C9
+; 14 --- P1.5 --- 19 ; TB0.2/UCA0CLK/A5/C5
+; 13 --- P1.4 --- 20 ; TB0.1/UCA0STE/A4/C4
+; 12 --- P1.3 --- 21 ; TA1.2/UCB0STE/A3/C3
+; 10 --- P3.2 --- 22 ; A14/C14
+; 11 --- P3.3 --- 23 ; A15/C15
+; 9 --- P3.1 --- 24 ; A13/C13
+; 8 --- P3.0 --- 25 ; A12/C12
+; 5 --- P1.0 --- 26 ; TA0.1/DMAE0/RTCCLK/A0/C0/VREF-/VeREF-
+; 6 --- P1.1 --- 27 ; TA0.2/TA1CLK/COUT/A1/C1/VREF+/VeREF+
+; 7 --- P1.2 --- 28 ; TA1.1/TA0CLK/COUT/A2/C2
+
+
+; P1.0 - DIP.26
+; P1.1 - DIP.27
+; P1.2 - DIP.28 <------------------------> SDA I2C SOFTWARE MASTER
+; P1.3 - DIP.21 <------------------------> SCL I2C SOFTWARE MASTER
+; P1.4 - DIP.20
+; P1.5 - DIP.19
+; P1.6 - DIP.7 UCB0 SDA/SIMO <------------> SDA I2C MASTER/SLAVE
+; P1.7 - DIP.6 UCB0 SCL/SOMI <------------> SCL I2C MASTER/SLAVE
+;
+; SD_Card socket
+; VCC - -------------------------> VCC SD_CardAdapter
+; P2.2 - DIP.13 -------------------------> TB0.2 LCD_Vo
+; P2.3 - DIP.4 -------------------------> SD_CardAdapter CD (CardDetect)
+; P2.4 - DIP.3 UCA1/CLK ---------------> SD_CardAdapter SCK
+; P2.5 - DIP.14 UCA1/SIMO ---------------> SD_CardAdapter CMD/SDI (MOSI)
+; P2.6 - DIP.12 UCA1/SOMI <--------------- SD_CardAdapter DAT0/SDO (MISO)
+; P2.7 - -------------------------> SD_CardAdapter DAT3/CS (Card Select) (CD at power up)
+; VSS - <------------------------> GND SD_CardAdapter
+;
+;
+; P3.0 - DIP.25 -------------------------> 4 LCD_RS
+; P3.1 - DIP.24 -------------------------> 5 LCD_R/W
+; P3.2 - DIP.23 -------------------------> 6 LCD_EN
+; P3.3 - DIP.22 <------------------------- OUT IR_Receiver (1 TSOP32236)
+; P3.4 - DIP.11 -------------------------> sw1 (hard reset)
+; P3.5 - DIP.10 -------------------------> sw2
+; P3.6 - DIP.9
+; P3.7 - DIP.8
+;
+;
+; PJ.0 - DIP.15 <------------------------> 11 LCD_DB4
+; PJ.1 - DIP.16 <------------------------> 12 LCD_DB5
+; PJ.2 - DIP.17 <------------------------> 13 LCD_DB5
+; PJ.3 - DIP.18 <------------------------> 14 LCD_DB7
+;
+
+; Clocks:
+; 8 MHz DCO intern
+
+; ----------------------------------------------------------------------
+; INIT order : LOCK I/O, WDT, GPIOs, FRAM, Clock, UARTs
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : LOCK PMM_LOCKLPM5
+; ----------------------------------------------------------------------
+
+; BIS #LOCKLPM5,&PM5CTL0 ; unlocked by WARM
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : WATCHDOG TIMER A
+; ----------------------------------------------------------------------
+
+ MOV #WDTPW+WDTHOLD+WDTCNTCL,&WDTCTL ; stop WDT
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : I/O
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT1/2
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT1 usage
+
+; PORT2 usage
+
+Deep_RST_IN .equ P2IN ; TERMINAL TX pin as FORTH Deep_RST
+Deep_RST .equ 1 ; P2.0
+TERM_TXRX .equ 003h
+TERM_SEL .equ P2SEL1
+TERM_REN .equ P2REN
+
+ .IFDEF TERMINALCTSRTS
+ .error "CTS/RTS Control Flow not implemented"
+ .ENDIF
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #-1,&PAOUT ; OUT1
+ BIS #-1,&PAREN ; REN1 all pullup resistors
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT3/4
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT3 usage
+
+; PORT4 usage
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #-1,&PBOUT ; pullup
+ BIS #-1,&PBREN ; all pullup resistors
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORTJ
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PJ usage
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV.B #-1,&PJOUT ;
+ BIS.B #-1,&PJREN ; pullup resistors on unused pins
+
+; ----------------------------------------------------------------------
+; FRAM config
+; ----------------------------------------------------------------------
+
+ .IF FREQUENCY = 16
+ MOV.B #0A5h, &FRCTL0_H ; enable FRCTL0 access
+ MOV.B #10h, &FRCTL0 ; 1 waitstate @ 16 MHz
+ MOV.B #01h, &FRCTL0_H ; disable FRCTL0 access
+ .ENDIF
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : CLOCK SYSTEM
+; ----------------------------------------------------------------------
+
+; DCOCLK: Internal digitally controlled oscillator (DCO).
+; Startup clock system in max. DCO setting ~8MHz
+
+
+; CS code for MSP430FR5948
+ MOV.B #CSKEY,&CSCTL0_H ; Unlock CS registers
+
+ .IF FREQUENCY = 0.5
+ MOV #0,&CSCTL1 ; Set 1MHZ DCO setting
+ MOV #DIVA_2 + DIVS_2 + DIVM_2,&CSCTL3 ; set all dividers as 2
+ MOV #4,X
+
+ .ELSEIF FREQUENCY = 1
+ MOV #0,&CSCTL1 ; Set 1MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #8,X
+
+ .ELSEIF FREQUENCY = 2
+ MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 4MHZ DCO setting
+ MOV #DIVA_0 + DIVS_2 + DIVM_2,&CSCTL3
+ MOV #16,X
+
+ .ELSEIF FREQUENCY = 4
+ MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 4MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #32,X
+
+ .ELSEIF FREQUENCY = 8
+; MOV #DCOFSEL2+DCOFSEL1,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #64,X
+
+ .ELSEIF FREQUENCY = 16
+ MOV #DCORSEL+DCOFSEL2,&CSCTL1 ; Set 16MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #128,X
+
+ .ELSEIF
+ .error "bad frequency setting, only 0.5,1,2,4,8,16 MHz"
+ .ENDIF
+
+ .IFDEF LF_XTAL
+ MOV #SELA_LFXCLK+SELS_DCOCLK+SELM_DCOCLK,&CSCTL2
+ .ELSE
+ MOV #SELA_VLOCLK+SELS_DCOCLK+SELM_DCOCLK,&CSCTL2
+ .ENDIF
+ MOV.B #01h, &CSCTL0_H ; Lock CS Registers
+
+ BIS &SYSRSTIV,&SAVE_SYSRSTIV; store volatile SYSRSTIV preserving a pending request for DEEP_RST
+ CMP #2,&SAVE_SYSRSTIV ; POWER ON ?
+ JZ ClockWaitX ; yes
+ .word 0759h ; no RRUM #2,X --> wait only 125 ms
+ClockWaitX MOV #41666,Y ; wait 0.5s before starting after POWER ON
+ClockWaitY SUB #1,Y ;
+ JNZ ClockWaitY ; 41666x3 = 125000 cycles delay = 125ms @ 1MHz
+ SUB #1,X ; x 4 @ 1 MHZ
+ JNZ ClockWaitX ; time to stabilize power source ( 1s )
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : REF
+; ----------------------------------------------------------------------
+
+ MOV #8, &REFCTL
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : RTC REGISTERS
+; ----------------------------------------------------------------------
+
+ .IFDEF LF_XTAL
+; LF Xtal XIN : PJ.4, LF Xtal XOUT : PJ.5
+ BIS.B #010h,&PJSEL0 ; SEL0 for only XIN
+ BIC.B #RTCHOLD,&RTCCTL1 ; Clear RTCHOLD = start RTC_B
+ .ENDIF
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : SYS REGISTERS
+; ----------------------------------------------------------------------
+
+
+; SYS code
+; see COLD word
--- /dev/null
+; -*- coding: utf-8 -*-
+; MY_MSP430FR5948.asm
+
+; Fast Forth For Texas Instrument MSP430FR5739
+;
+; Copyright (C) <2014> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+; ======================================================================
+; MY_MSP430FR5948_1 : MSP430FR5948 TSSOP38 to DIP28 board MAP
+; may be remplaced by MSP430FR5939 TSSOP 38
+; Version 1 : added a 4k7 resistor on RX signal between Si8622EC and PROG6PINS
+; SD_CS and SD_CD are inverted
+; ======================================================================
+;
+; MSP430FR5948 XTAL 32768 Hz
+; 1 --- PJ.4 --- LFXIN
+; 2 --- PJ.5 --- LFXOUT
+;
+; MSP430FR5948 PROG 6PINS ISOLATED UARTtoUSB bridge
+; 34 --- DVCC <-> 2 "3v3" --------> 1 Vdd1 <| SI |> Vdd2 8 <-- 3v3
+; 24 --- P2.1 <-- 6 "RX0" <----4k7- 2 A1 <| 86 |> B1 7 <-- TXD
+; 23 --- P2.0 <-> 1 "TX0" <--+----> 3 A2 <| 22 |> B2 6 --> RXD
+; 33 --- DVSS <-> 5 "GND" <- | ---> 4 Gnd1 <| EC |> Gnd2 5 <-- GND
+; 21 --- TEST --- 3 "TST" |
+; 22 --- RST --- 4 "RST" |
+; +-4k7- DeepRST <-- GND
+;
+;
+; DIP28 1 --- 4 AVCC --- ferrite bead --- DVCC 34
+; DIP28 2 --- 3 AVSS --- ferrite bead --- DVSS 33
+;
+; MSP430FR5948 DIP28
+; 4, --- AVCC --- 1 ; +
+; 3,38 --- AVSS --- 2 ; -
+; 3 ; GND
+; 37 --- P2.4 --- 4 ; TA1.0/UCA1CLK/A7/C11
+; 36 --- P2.3 --- 5 ; TA0.0/UCA1STE/A6/C10
+; 30 --- P1.6 --- 6 ; TB0.3/UCB0SIMO/UCB0SDA/TA0.0
+; 31 --- P1.7 --- 7 ; TB0.4/UCB0SOMI/UCB0SCL/TA1.0
+; 29 --- P3.7 --- 8 ; TB0.6
+; 28 --- P3.6 --- 9 ; TB0.5
+; 27 --- P3.5 --- 10 ; TB0.4/COUT
+; 26 --- P3.4 --- 11 ; TB0.3/SMCLK
+; 20 --- P2.6 --- 12 ; TB0.1/UCA1RXD/UCA1SOMI
+; 25 --- P2.2 --- 13 ; TB0.2/UCB0CLK
+; 19 --- P2.5 --- 14 ; TB0.0/UCA1TXD/UCA1SIMO
+; 15 --- PJ.0 --- 15 ; TDO/TB0OUTH/SMCLK/SRSCG1/C6
+; 16 --- PJ.1 --- 16 ; TDI/TCLK/MCLK/SRSCG0/C7
+; 17 --- PJ.2 --- 17 ; TMS/ACLK/SROSCOFF/C8
+; 18 --- PJ.3 --- 18 ; TCK/SRCPUOFF/C9
+; 14 --- P1.5 --- 19 ; TB0.2/UCA0CLK/A5/C5
+; 13 --- P1.4 --- 20 ; TB0.1/UCA0STE/A4/C4
+; 12 --- P1.3 --- 21 ; TA1.2/UCB0STE/A3/C3
+; 10 --- P3.2 --- 22 ; A14/C14
+; 11 --- P3.3 --- 23 ; A15/C15
+; 9 --- P3.1 --- 24 ; A13/C13
+; 8 --- P3.0 --- 25 ; A12/C12
+; 5 --- P1.0 --- 26 ; TA0.1/DMAE0/RTCCLK/A0/C0/VREF-/VeREF-
+; 6 --- P1.1 --- 27 ; TA0.2/TA1CLK/COUT/A1/C1/VREF+/VeREF+
+; 7 --- P1.2 --- 28 ; TA1.1/TA0CLK/COUT/A2/C2
+;
+;
+; P1.0 - DIP.26
+; P1.1 - DIP.27
+; P1.2 - DIP.28 <------------------------> SDA I2C SOFTWARE MASTER
+; P1.3 - DIP.21 <------------------------> SCL I2C SOFTWARE MASTER
+; P1.4 - DIP.20
+; P1.5 - DIP.19
+; P1.6 - DIP.6 UCB0 SDA/SIMO <------------> SDA I2C MASTER/SLAVE
+; P1.7 - DIP.7 UCB0 SCL/SOMI <------------> SCL I2C MASTER/SLAVE
+;
+; SD_Card socket
+; VCC - -------------------------> VCC SD_CardAdapter
+; P2.2 - DIP.13 -------------------------> TB0.2 LCD_Vo
+; P2.3 - DIP.5 -------------------------> SD_CardAdapter DAT3/CS (Card Select) (CD at power up)
+; P2.4 - DIP.4 UCA1/CLK ---------------> SD_CardAdapter SCK
+; P2.5 - DIP.14 UCA1/SIMO ---------------> SD_CardAdapter CMD/SDI (MOSI)
+; P2.6 - DIP.12 UCA1/SOMI <--------------- SD_CardAdapter DAT0/SDO (MISO)
+; P2.7 - -------------------------> SD_CardAdapter CD (CardDetect)
+; VSS - <------------------------> GND SD_CardAdapter
+;
+;
+; P3.0 - DIP.25 -------------------------> 4 LCD_RS
+; P3.1 - DIP.24 -------------------------> 5 LCD_R/W
+; P3.2 - DIP.23 -------------------------> 6 LCD_EN
+; P3.3 - DIP.22 <------------------------- OUT IR_Receiver (1 TSOP32236)
+; P3.4 - DIP.11 -------------------------> sw1 (hard reset)
+; P3.5 - DIP.10 -------------------------> sw2
+; P3.6 - DIP.9
+; P3.7 - DIP.8
+;
+;
+; PJ.0 - DIP.15 <------------------------> 11 LCD_DB4
+; PJ.1 - DIP.16 <------------------------> 12 LCD_DB5
+; PJ.2 - DIP.17 <------------------------> 13 LCD_DB5
+; PJ.3 - DIP.18 <------------------------> 14 LCD_DB7
+
+; Clocks:
+; 8 MHz DCO intern
+
+; ----------------------------------------------------------------------
+; INIT order : LOCK I/O, WDT, GPIOs, FRAM, Clock, UARTs
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : LOCK PMM_LOCKLPM5
+; ----------------------------------------------------------------------
+
+; BIS #LOCKLPM5,&PM5CTL0 ; unlocked by WARM
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : WATCHDOG TIMER A
+; ----------------------------------------------------------------------
+
+ MOV #WDTPW+WDTHOLD+WDTCNTCL,&WDTCTL ; stop WDT
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : I/O
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT1/2
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT1 usage
+
+; PORT2 usage
+
+Deep_RST_IN .equ P2IN ; TERMINAL TX pin as FORTH Deep_RST
+Deep_RST .equ 1 ; P2.0
+TERM_TXRX .equ 003h
+TERM_SEL .equ P2SEL1
+TERM_REN .equ P2REN
+
+ .IFDEF TERMINALCTSRTS
+ .error "CTS/RTS Control Flow not implemented"
+ .ENDIF
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #-1,&PAOUT ; OUT1
+ BIS #-1,&PAREN ; REN1 all pullup resistors
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORT3/4
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PORT3 usage
+
+; PORT4 usage
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV #-1,&PBOUT ; pullup
+ BIS #-1,&PBREN ; all pullup resistors
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : PORTJ
+; ----------------------------------------------------------------------
+
+; reset state : Px{DIR,REN,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; Px{IN,OUT,IES} = ?
+
+; PJ usage
+
+; PORTx default wanted state : pins as input with pullup resistor
+
+ MOV.B #-1,&PJOUT ;
+ BIS.B #-1,&PJREN ; pullup resistors on unused pins
+
+; ----------------------------------------------------------------------
+; FRAM config
+; ----------------------------------------------------------------------
+
+ .IF FREQUENCY = 16
+ MOV.B #0A5h, &FRCTL0_H ; enable FRCTL0 access
+ MOV.B #10h, &FRCTL0 ; 1 waitstate @ 16 MHz
+ MOV.B #01h, &FRCTL0_H ; disable FRCTL0 access
+ .ENDIF
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : CLOCK SYSTEM
+; ----------------------------------------------------------------------
+
+; DCOCLK: Internal digitally controlled oscillator (DCO).
+; Startup clock system in max. DCO setting ~8MHz
+
+
+; CS code for MSP430FR5948
+ MOV.B #CSKEY,&CSCTL0_H ; Unlock CS registers
+
+ .IF FREQUENCY = 0.5
+ MOV #0,&CSCTL1 ; Set 1MHZ DCO setting
+ MOV #DIVA_2 + DIVS_2 + DIVM_2,&CSCTL3 ; set all dividers as 2
+ MOV #4,X
+
+ .ELSEIF FREQUENCY = 1
+ MOV #0,&CSCTL1 ; Set 1MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #8,X
+
+ .ELSEIF FREQUENCY = 2
+ MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 4MHZ DCO setting
+ MOV #DIVA_0 + DIVS_2 + DIVM_2,&CSCTL3
+ MOV #16,X
+
+ .ELSEIF FREQUENCY = 4
+ MOV #DCOFSEL1+DCOFSEL0,&CSCTL1 ; Set 4MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #32,X
+
+ .ELSEIF FREQUENCY = 8
+; MOV #DCOFSEL2+DCOFSEL1,&CSCTL1 ; Set 8MHZ DCO setting (default value)
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #64,X
+
+ .ELSEIF FREQUENCY = 16
+ MOV #DCORSEL+DCOFSEL2,&CSCTL1 ; Set 16MHZ DCO setting
+ MOV #DIVA_0 + DIVS_0 + DIVM_0,&CSCTL3 ; set all dividers as 0
+ MOV #128,X
+
+ .ELSEIF
+ .error "bad frequency setting, only 0.5,1,2,4,8,16 MHz"
+ .ENDIF
+
+ .IFDEF LF_XTAL
+ MOV #SELA_LFXCLK+SELS_DCOCLK+SELM_DCOCLK,&CSCTL2
+ .ELSE
+ MOV #SELA_VLOCLK+SELS_DCOCLK+SELM_DCOCLK,&CSCTL2
+ .ENDIF
+ MOV.B #01h, &CSCTL0_H ; Lock CS Registers
+
+ BIS &SYSRSTIV,&SAVE_SYSRSTIV; store volatile SYSRSTIV preserving a pending request for DEEP_RST
+ CMP #2,&SAVE_SYSRSTIV ; POWER ON ?
+ JZ ClockWaitX ; yes
+ .word 0759h ; no RRUM #2,X --> wait only 125 ms
+ClockWaitX MOV #41666,Y ; wait 0.5s before starting after POWER ON
+ClockWaitY SUB #1,Y ;
+ JNZ ClockWaitY ; 41666x3 = 125000 cycles delay = 125ms @ 1MHz
+ SUB #1,X ; x 4 @ 1 MHZ
+ JNZ ClockWaitX ; time to stabilize power source ( 1s )
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : REF
+; ----------------------------------------------------------------------
+
+ MOV #8, &REFCTL
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : RTC REGISTERS
+; ----------------------------------------------------------------------
+
+ .IFDEF LF_XTAL
+; LF Xtal XIN : PJ.4, LF Xtal XOUT : PJ.5
+ BIS.B #010h,&PJSEL0 ; SEL0 for only XIN
+ BIC.B #RTCHOLD,&RTCCTL1 ; Clear RTCHOLD = start RTC_B
+ .ENDIF
+
+; ----------------------------------------------------------------------
+; POWER ON RESET AND INITIALIZATION : SYS REGISTERS
+; ----------------------------------------------------------------------
+
+
+; SYS code
+; see COLD word
--- /dev/null
+Fast Forth For MSP430FRxxxx TI's devices
+========================================
+
+
+FAST FORTH is the Swiss Army knife you need for your MSP430FRxxxx.
+Usable with all the TI LaunchPads MSP430 FRAM and all MSP430FRxxxx, without moderation!
+
+ With its embedded assembler the size of FAST FORTH is < 6 kb, else: 4kb.
+ With SD_CARD file Load|Read|Write|Delete, plus a direct file transfer from PC to SD_CARD, its size is under 9Kb.
+ Excepted MSP430FR4133, because no hardware multiplier, works with SD CARD memories from 64MB to 64GB.
+ This enable to make a data logger with a small MSP430FR5738 QFN24 and its RTC and 24MHz SPI CLK.
+
+ Fully tested on MSP-EXP430FR5969, FR5994, FR6989, FR4133 launchpads and CHIPSTICKFR2433, at 0.5, 1, 2, 4, 8, 16 MHz,
+ plus 24MHz on a MSP430FR5738 module.
+
+ Files launchpad_3Mbd.txt are 16threads vocabularies 16MHz executables, with 3MBds, XON/XOFF terminal,
+ Launchpad_115200.txt files are same except 115200Bds for unlucky linux men without TERATERM.
+ For the launchpad MSP-EXP430FR5994 with SD_CARD, full version with SD_Card driver is available.
+ For others, you must before compile forthMSP430FR.asm with SD_CARD_LOADER and
+ SD_CARD_READ_WRITE switches turned ON (uncomment their line).
+
+ Once the Fast Forth binary is loaded into the target's FRAM memory, you add assembly code or FORTH code, or both,
+ by downloading source files that Fast Forth can interpret and compile. The download channel consists of the TERATERM program
+ on the PC side (the Fast Forth input terminal), and a USB-UART bridge (PL2303TA cable) that you connect between your PC
+ and your target.
+
+ Once your source files (files.f) in symbolic assembler are written,
+ the preprocessor GEMA translates them into Fast Forth source files (files.4th) ready to download, by
+ using .pat files (equivalent to the C files.h).
+ A set of .bat files is furnished to do this automatically. See it all in the MSP430-FORTH folder.
+
+ The download, interpretation and compilation of a file.4th is done at a throughput of 40/80/120 kbytes/sec
+ with a 8/16/24 MHz clock. Considering a ratio 5/1, that of the compiled code is 8/16/24 kbytes/sec.
+ To compare with the 8kbytes/s of the FlashPro-MSP programmer in SBW mode.
+
+ After downloading of complementary words in COMPxMPY.f, FastForth executes CORETEST.4th without errors
+ which ensures its compatibility with the FORTH ANS94 standard.
+ For MSP430FR4133 choose COMPSMPY.f, for all other COMPHMPY.f.
+
+ Notice that FAST FORTH interprets only SPACE as delimiter (not TAB), BACKSPACE, and CR+LF (not LF) as end of line.
+
+ Finally, if you use the scite editor you can do everything from its "tools" menu.
+
+What is new ?
+-------------
+
+ FAST FORTH V160, major version.
+
+ Accept SD_Card from 64 MB (FAT16) up to 64 GB (FAT32).
+ Note that Windows 10 no longer offers the FAT32 format for the highest sizes of SD_CARD memory.
+ So you must use an alternative to do, for example: https://www.partitionwizard.com.
+
+ Added an extension for 32 bits numbers and the words D. UD. to display them.
+ Typed numbers > 65535 or < -32768 are automatically processed as 32 bits numbers,
+ and to force a typed number of 16 bits to 32 bits, insert a decimal point.
+ Example : $-12 is processed as 16 bits negative number.
+ $-.12 or $-1.2 or $-12. are processed as 32 bits negative numbers.
+
+ in SD_TOOLS the word SECT_D (dump sector) use a 32 bits number.
+ added the word CLUST_D (dump first sector of a cluster). Usage (notice the point): number. CLUST_D
+
+
+ PREVIOUS versions
+
+ Added direct file.4th transfer of PC to target SD_CARD.
+ Measured speed: 90 kbytes/s at 3Mbauds and 16MHz target clock, with "HCI" SD CARD.
+ You can do it from scite editor (menu Tools) or by using specific bat files.
+ Double click on these to see how to do.
+
+ JTAG and BSL signatures (FF80h-FF88h) are protected against overwrite, typically during source file download.
+
+ added signed number prefixes $ (hex), % (bin) and # (decimal) to supersede current BASE.
+
+ Added words ASM and ENDASM to create assembler words that are not interpretable by FORTH
+ i.e. that are called by {CALL|INTERRUPT} and ended by {RET|RETI}. These so created words can be used only in ASSEMBLER context.
+
+ In the embedded assembler, added 3 backward BW1 BW2 BW3 and 3 forward FW1 FW2 FW3 jump labels to use with GOTO, ?GOTO.
+ These labels are for single use (one jump for one label).
+
+ you can compile up to 32 threads vocabularies ==> interpretation time is divided by sqrt(threads).
+
+ In root folder you can program files *.txt to any target by using drag and drop on their respective file.bat,
+ The same applies to MSP430-FORTH\source files .f and .4th to any target by using drag and drop.
+ Double click on these files.bat to see how to do.
+
+ Memory management :
+ Fast Forth defines 4 levels of programm memory :
+ WIPE that resets programm memory as txt file was,
+ RST_HERE / RST_STATE that set / reset the boundary of program protected against <reset>,
+ PWR_HERE / PWR_STATE that set / reset the boundary of program protected against power ON/OFF,
+ and nothing, i.e. volatile memory.
+
+ You can download source files with hardware or software control flow (i.e. without line or char delays) up to:
+ 134400 bds @ 500kHz
+ 268800 bds @ 1MHz
+ 614400 bds @ 2MHz
+ 1228800 bds @ 4MHz
+ 2457600 bds @ 8MHz
+ 3000000 bds @ 16MHZ
+ 6000000 bds @ 24MHz with MSP430FR57xx devices
+ See main file DTCforthMSP430FR5xxx.asm for the list of reliable baudrates.
+
+ FAST FORTH can be adjusted by selection of SWITCHES in the source file to reduce its size according
+ to your convenience. To do, comment/uncomment their line.
+
+ You can select mode LPM{0,1,2,3,4} in your application, depending of family, FR2xxx : LPM0,
+ FR57xx : LPM0 to 2, FR59xx : LPM0 to 4.
+
+ DEEP_RST (RESET + WIPE) can be hardware performed via the programmation interface (Vcc,RX,TX,RST,TEST,GND).
+
+
+Many thanks to Brad Rodriguez
+-----------------------------
+
+for his CamelForth which served me as a kind of canvas.
+
+Unlike CamelForth this FORTH is a "Direct Threaded Code", with an embedded assembler following the standard syntax,
+not the one used in the world Forth.
+
+Its core is fully compliant with the standard ANS.
+
+This is a FORTH optimized for the speed, especially in the interpreter mode, so that you can load an application program written in FORTH/Assembler faster than its binary via MSP430 Flasher.exe : everything can be done from your text editor, the preprocessor and a serial terminal.
+
+What's this and why?
+---
+
+I have first programmed atmel tiny devices.
+Particularly I2C master driver to have both I2C slave and I2C master on a ATtiny461.
+which means a lot of back and forth between the editor, assembler, the programmer and the test in situ.
+
+Previously I had programmed a FORTH on a Motorola 6809 and had been seduced by the possibility of sending a source file directly to the target using a serial terminal. Target which compiled and executed the program. At the time FORTH program lay in a battery backed RAM.
+
+The advent of chip MSP430 TEXAS INSTRUMENT with embedded FRAM gave me the idea to do it again : FAST FORTH was born.
+
+Today I dropped the ATMEL chips and proprietary interfaces, I program my applications in a mix 80%/20% of assembler/FORTH I then sent on MSP430FR5738 chips with embedded FAST FORTH.
+
+And that's the magic: After I finished editing (or modify) the source file, I press the "send" button in my text editor and I can test result on target in the second following. This is the whole point of an IDE reduced to its simplest form: a text editor, a cable, a target.
+
+
+Content
+-------
+
+With a size about 5.5 kb (enhanced version with vocabularies 16 threads), Fast Forth contains 111 words:
+
+ COLD WARM (WARM) WIPE RST_HERE RST_STATE PWR_HERE PWR_STATE
+ MOVE LEAVE +LOOP LOOP DO REPEAT WHILE AGAIN
+ UNTIL BEGIN THEN ELSE IF POSTPONE ['] IS
+ IMMEDIATE ; : RECURSE ] [ DEFER DOES>
+ CREATE CONSTANT VARIABLE \ ' ABORT" ABORT QUIT
+ EVALUATE COUNT LITERAL , EXECUTE >NUMBER FIND WORD
+ ." S" TYPE SPACES SPACE CR (CR) NOECHO
+ ECHO EMIT (EMIT) ACCEPT KEY (KEY) C, ALLOT
+ HERE . D. U. UD. SIGN HOLD #>
+ #S # <# BL STATE BASE >IN J
+ I UNLOOP U< > < = 0< 0=
+ ABS NEGATE XOR OR AND - + C!
+ C@ ! @ DEPTH R@ R> >R ROT
+ OVER SWAP DROP ?DUP DUP LIT EXIT
+
+...size that includes its embedded assembler of 73 words:
+
+ ?GOTO GOTO FW3 FW2 FW1 BW3 BW2 BW1
+ ?JMP JMP REPEAT WHILE AGAIN UNTIL ELSE THEN
+ IF 0= 0<> U>= U< 0< 0>= S<
+ S>= RRUM RLAM RRAM RRCM POPM PUSHM CALL
+ PUSH.B PUSH SXT RRA.B RRA SWPB RRC.B RRC
+ AND.B AND XOR.B XOR BIS.B BIS BIC.B BIC
+ BIT.B BIT DADD.B DADD CMP.B CMP SUB.B SUB
+ SUBC.B SUBC ADDC.B ADDC ADD.B ADD MOV.B MOV
+ RETI LO2HI COLON ENDASM ENDCODE ASM CODE HI2LO
+ ASSEMBLER
+
+...everything you need to program effectively in assembly or FORTH or mix, as you want. See examples in \MSP430-FORTH folder.
+
+VOCABULARY ADD-ON swith in forthMSP430.asm adds:
+
+ DEFINITIONS ONLY PREVIOUS ALSO FORTH VOCABULARY
+<<<<<<< HEAD
+
+SD\_CARD\_LOADER ADD-ON swith in forthMSP430.asm adds:
+
+=======
+
+SD\_CARD\_LOADER ADD-ON swith in forthMSP430.asm adds:
+
+>>>>>>> 4f83c2458a3d0b038b9a82e6290d4818d9ce3447
+ LOAD" (ACCEPT)
+
+SD\_CARD\_READ\_WRITE ADD-ON swith in forthMSP430.asm adds:
+
+ TERM2SD" SD_EMIT WRITE WRITE" READ READ" CLOSE DEL"
+
+external ANS\_COMPLEMENT in COMPHMPY.f or COMPSMPY.f adds:
+
+ >BODY SOURCE .( ( DECIMAL HEX FILL +!
+ [CHAR] CHAR CELL+ CELLS CHAR+ CHARS ALIGN ALIGNED
+ 2OVER 2SWAP 2DROP 2DUP 2! 2@ */ */MOD
+ MOD / /MOD * FM/MOD SM/REM UM/MOD M*
+ UM* S>D NIP 2/ 2* MIN MAX 1-
+ 1+ RSHIFT LSHIFT INVERT
+
+external SD\_TOOLS ADD-ON in SD\_TOOLS.f adds:
+
+ DIR_D FAT_D CLUST_D SECT_D DUMP U.R MIN
+ MAX WORDS .S SP@ ?
+
+
+Organize your gitlab copy of FastForth
+-------
+
+download zip of last version
+
+copy it to a subfolder, i.e. FastForth, created in your user folder
+
+right clic on it to share it with yourself.
+
+remember its shared name i.e. : //myPC/users/my/FastForth.
+
+in file explorer then right clic on root to connect a network drive, copy shared name in drive name and choose a free drive letter a:, b: ...
+
+Thus all relative paths will be linked to this drive, except the files.bat links in the folder \MSP430-forth.
+For all of them right clic select, select properties then check drive letter in target.
+
+WARNING! if you erase a file directly in this drive or in one of its subfolders, no trash, the file is lost!
+
+
+
+Minimal Software
+--
+
+If you are under WINDOWS :
+
+ First, you download the TI's programmer from TI : http://www.ti.com/tool/MSP430-FLASHER.
+ And the MSP430Drivers :
+ http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430_FET_Drivers/latest/index_FDS.html
+
+ The next tool is TERATERM.EXE : http://logmett.com/index.php?/products/teraterm.html.
+
+ As scite is my editor, this github repository is fully configured for scite users.
+ download the single file executable called sc1 (not the full download) :
+ http://www.scintilla.org/SciTEDownload.html, then save it as \prog\wscite\scite.exe.
+
+ download GEMA preprocessor : https://sourceforge.net/projects/gema/files/gema/gema-1.4-RC/
+
+ The MacroAssembler AS : http://john.ccac.rwth-aachen.de:8000/as/
+
+ and Srecord : http://srecord.sourceforge.net/download.html to convert HEX file to TI TXT files.
+
+ copy last 3 items onto their respective \prog subfolder.
+
+ ask windows to open .asm, .inc, lst, .map, .4th, .f files with scite.exe
+
+
+If you are linux or OS X men, sorry...
+
+
+Build the program file
+----------------------
+
+
+\forthMSP430FR.asm is the main file to compile FastForth. It calls :
+
+ - mspregister.mac that defines the TI symbolic instructions,
+ - TargetMap.inc that defines for each device the eUSCI used as Terminal
+ and then selects the declarations file family.map,
+ - ForthThreads.mac in case of multithread vocabularies,
+ - optionally, forthMSP430FR_SD.asm file(s) for SD_Card,
+ - optionally, forthMSP430FR_ASM.asm for assembler,
+ - TargetInit.asm that selects the target.asm,
+ - and then TERMINALBAUDRATE.asm.
+
+open it with scite
+
+uncomment the target as you want, i.e. MSP_EXP430fr5969
+
+choose frequency, baudrate, UART handshake.
+
+uncomment options switches as your convenience.
+
+save file.
+
+assemble (CTRL+0). A window asks you for 4 parameters:
+
+set device as first param, i.e. MSP430FR5969,
+
+set your target as 2th param, i.e. MSP_EXP430fr5969,
+
+then execute. the output is a target.txt file.
+
+
+
+Load Txt file (TI format) to target
+-----------------------------------
+
+ drag your target.txt file and drop it on TARGETprog.bat
+
+ or use scite internal command TOOLS:FET prog (CTRL+1).
+
+nota : programming the device use SBW2 interface, so UART0 is free for serial terminal use.
+
+If you want to program your own MSP430FRxxxx board, wire its pins TST, RST, 3V3 and GND to same pins of the launchpad, on eZ-FET side of the programming connector.
+
+
+
+Connect the FAST FORTH target to a serial terminal
+-------------------------------------------------
+
+you will need an USBtoUART cable with a PL2303TA or PL2303HXD device that allows XON/XOFF control flow :
+
+ http://www.google.com/search?q=PL2303TA
+ http://www.prolific.com.tw/UserFiles/files/PL2303_Prolific_DriverInstaller_v1_14_0.zip
+
+or USBtoUART bridge, with a CP2102 device that allows XON/XOFF control flow :
+
+ http://www.google.com/search?q=cp2102+module+3.3V
+ http://www.silabs.com/products/mcu/Pages/USBtoUARTBridgeVCPDrivers.aspx
+
+you must program CP2102 device to access 1382400 and 1843200 bds rates :
+
+ http://www.silabs.com/Support%20Documents/Software/install_USBXpress_SDK.exe
+ http://www.silabs.com/Support%20Documents/TechnicalDocs/an169.pdf
+
+or a USBtoUART bridge, with a FT232RL device for only hardware control flow:
+
+ http://www.google.com/search?q=FT232RL+module+3.3V
+ http://www.ftdichip.com/Drivers/CDM/CDM%20v2.12.00%20WHQL%20Certified.exe
+
+
+How to configure the connection ?
+-------------------------------
+
+1- the best ! Launchpad UARTn <--> USBtoUART bridge with cp2102|PL2303TA chipset <--> TERATERM
+
+ UARTn <--> CP2102 module | PL2303TA cable
+ TXn ---> RX
+ RXn <--- TX
+ (GND <--> GND)
+ WARNING! DON'T CONNECT 5V RED WIRE!
+
+ TeraTerm configuration : see DTCforthMSP430fr5xxx.asm
+
+If you plan to supply your target vith a PL2303 cable, open its box to weld red wire onto 3.3V pad.
+
+2- Launchpad UARTn <--> USBtoUART bridge with FT232RL chipset <--> TERATERM
+ WARNING! buy a FT232RL module with a switch 5V/3V3 and select 3V3.
+
+ UARTn <--> FT232RL module
+ TXn ---> RX
+ RXn <--- TX
+ RTS ---> CTS
+ (GND <--> GND)
+ WARNING! select 3V3 !
+ WARNING! DON'T CONNECT 5V !
+
+ TeraTerm configuration : see DTCforthMSP430fr5xxx.asm
+
+
+Send a source file to the FAST FORH target
+------------------
+
+Two .bat files are done in the folder \MSP430-FORTH that enable you to send any source file to any target.
+
+See how to in the file \MSP430-FORTH\send\_source\_file\_to\_target\_readme.txt. Or double click on .bat file
+
+you can also open any source file with scite, and do all via menu Tools.
+
+
+SD_Card Load, Read, Write and Delete
+=============================================
+
+First, hardware
+---------------
+
+If you have MSP-EXP430FR5994, nothing to do.
+
+For the choice of a SD card socket be carefull : pin CD (Card Detect) must be present !
+
+ http://www.ebay.com/itm/2-PCS-SD-Card-Module-Slot-Socket-Reader-For-Arduino-MCU-/181211954262?pt=LH_DefaultDomain_0&hash=item2a3112fc56
+
+
+the commands
+------------
+
+With the LOAD" pathame" command you load your source files from a SD_CARD memory in both execute and compile modes. Idem for READ", WRITE" and DEL" commands.
+
+See "SD_TESTS.f", a FORTH program done for example
+
+If you remove the SD memory card reader and then reset, all SD\_IO pins are available except SD_CD obviously.
+
+HowTo LOAD a sourcefile
+--------------
+
+ LOAD" path\filename.4th".
+
+The file is interpreted by FORTH in same manner than from the serial terminal.
+
+When EOF is reached, the file is automatically closed.
+
+A source file can _LOAD"_ an other source file, and so on in the limit of available handles (up to 8).
+
+HowTo READ a file
+--------------
+
+ READ" path\filename.ext".
+
+The first sector of this file is loaded in BUFFER.
+To read next sectors, use the command READ that loads the next sector in the buffer, and leaves on the stack a flag that is true when the EOF is reached.
+The file is automatically closed. See tstwords.4th for basic usage.
+
+The variable BufferLen keep the count of bytes to be read (0 to 512).
+
+If you want to anticipate the end, use the CLOSE command.
+
+HowTo WRITE a file
+---------------
+
+ WRITE" path\filename.ext".
+
+If the file does not exist, create it, else open it and set the write pointer at the end of the file, ready to append chars.
+
+See example of use in \MSP430-forth\SD_TEST.f.
+
+To overwrite an existing file: DEL" file" then WRITE" file".
+
+Use CLOSE to close the file.
+
+HowTo delete a file
+---------------
+
+ DEL" path\filename.ext". If the file is not found, do nothing, no error.
+
+HowTo change DIRectory
+---------------
+
+ READ" \misc". \misc becomes the current folder.
+ READ" ..\" parent folder becomes the current folder.
+ READ" \" Root becomes the current folder.
+
+Drive letters are always ignored.
+
+Downloading source file to SD_Card
+------------------------------------------
+
+to download a file.f/file.4th onto SD_CARD, use Send_file.f_to_SD_CARD_targe.bat/Send_file.4th_to_SD_CARD_targe.bat.
+any file.f will be preprocessed by gema before sending to SD_CARD as file.4th.
+
+Double click on one of this bat files to see how to do.
+
+
+I2C DRIVERS
+===========
+
+The I2C\_Soft\_Master driver with normal/fast mode allows you to add then use any couple of pins to drive a bus I2C :
+
+ - without use of eUSCI UCBx
+ - I2C\_Soft\_MultiMaster driver : same plus detection collision
+ - plus I2C\_Slave driver that uses the eUSCI UCBx hardware
+
+
+Other interesting specificities :
+=====
+
+Management of vocabularies (not ANSI). VOCABULARY, DEFINITIONS, ONLY, ALSO, PREVIOUS, CONTEXT, CURRENT, FORTH, ASSEMBLER.
+In fact, it's the operation of the assembler that requires the vocabularies management.
+
+Recognizing prefixed numbers %101011 (bin), $00FE (hex) and #220 (decimal).
+
+CAPS ON/OFF add on
+
+ECHO / NOECHO
+
+The words DEFER and IS are implemented. CR, EMIT, KEY and WARM are deferred words.
+
+Error messages are colored (reverse video on ANSI terminal).
+
+Assembly jumps are as FORTH one's : IF, ELSE, THEN, BEGIN, AGAIN, UNTIL, WHILE.
+Not canonical jumps are also available with JMP|?JMP to a defined word and GOTO|?GOTO to backward labels BW1 BW2 BW3 or forward labels FW1 FW2 FW3.
+These labels are one use.
+Switch within definitions between FORTH and Assembly contexts with words HI2LO and LO2HI. See examples in the TstWords.f file. This is perhaps the most interesting feature for development...
+
+
+The system is not responding ?
+======
+
+First, swich off then switch on. FORTH restarts as it was after the last PWR\_HERE command.
+
+If the system is not restarted, press <reset> button on the MSP-EXP430FR5xxx ; FORTH restarts as it was after the last RST_HERE command.
+
+If the system does not restart again, wire the TERMINAL TX pin to GND via 4k7 resistor then <reset> ; FORTH restarts as it is in the HEX file.
+Equivalent word : COLD + WIPE.
+
+Here is the FastForth init architecture :
+
+ case 0 : when you type WARM, FORTH interpreter is restarted, no program lost.
+ if ECHO is on, the WARM display is preceded by "0", else no display.
+
+ case 1 : Power ON ==> performs reset and the program beyond PWR_HERE is lost.
+ if ECHO is on, the WARM display is preceded by the SYSRSTIV value "2", else no display.
+
+ case 1.1 : when you type PWR_STATE ==> the program beyond PWR_HERE is lost.
+
+
+ case 2 : <reset> ==> performs reset and the program beyond RST_HERE is lost.
+ if ECHO is on, the WARM display is preceded by the SYSRSTIV value "4", else no display.
+
+ case 2.1 : when you type COLD (software reset) ==> same effects.
+ if ECHO is on, the WARM display is preceded by the SYSRSTIV value "6", else no display.
+
+ case 2.2 : when you type RST_STATE ==> the program beyond RST_HERE is lost.
+
+
+ case 3 : when you type WIPE ==> all programs donwloaded from the terminal or the SD_Card are lost.
+
+
+ case 4 : TERM_TX wired to GND via 4k7 during <reset> = DEEP_RST ===> performs reset, and all programs donwloaded from the terminal or the SD_Card are lost.
+ The WARM display is preceded by "-4".
+
+ case 4.1 : software reset on failure (SYSRSTIV = 0Ah | SYSRSTIV >= 16h) ===> same effects
+ The WARM display is preceded by the SYSRSTIV value.
+
+ case 4.2 : writing -1 in SAVE_SYSRSTIV before COLD = software DEEP_RST ===> same effects
+ The WARM display is preceded by "-1".
+
+
+If SD\_CARD extention and SD\_CARD memory with \BOOT.4TH included, the cases 1 to 4 start it after displaying of WARM message.
+
+
+EMBEDDED ASSEMBLER
+======
+
+With the preprocessor GEMA and the file MSP430FR\_FastForth.pat, the embedded assembler allows access to all system variables. See \\config\\gema\\MSP430FR\_FastForth.pat. You can also access to VARIABLE, CONSTANT or DOES type words in immediate (#), absolute (&) and indexed (Rx) assembly modes.
+
+Clearly, after the instruction "MOV &BASE,R6", R6 equals the contents of the FORTH variable "BASE", and after "MOV #BASE,R6" R6 contains its address.
+
+If you want to create a buffer of 8 bytes (4 words) :
+
+ CREATE BUFFER_OUT 8 ALLOT
+the access to this buffer is done by :
+
+ MOV #BUFFER_OUT,R8
+ MOV.B @R8,R9
+with R8 as org address of the buffer.
+
+Or by indexed addressing :
+
+ MOV.B BUFFER_OUT(R8),R9
+with R8 register as buffer pointer.
+
+see TESTASM.4th in \MSP430-FORTH folder.
+
+What is the interest of a very fast baud rate ?
+---------------------
+
+This seems obvious: you can edit a source program and then test it immediatly on the target: above, from my text editor, the download, compile and start are done in less than 1 sec.
+
+VOCABULARY ADD-ON
+====
+
+These words are not ANS94 compliant, they are those of F83 standard.
+
+For example, after loading SD_TOOLS add-on, you can type: ALSO ASSEMBLER WORDS PREVIOUS WORDS
+
+ With ALSO ASSEMBLER, the vocabulary ASSEMBLER is added to the search CONTEXT thus the ASSEMBLER words become visible
+
+ WORDS display the words of ASSEMBLER then those of FORTH,
+
+ PREVIOUS remove the vocabulary ASSEMBLER form the CONTEXT, and the ASSEMBLER words become hidden,
+
+ so the last WORDS display only FORTH words.
+
+In the forthMSP430FR_ASM.asm, see the FORTH word CODE that add ASSEMBLER to the search CONTEXT and the ASSEMBLER word ENDCODE
+ that remove ASSEMBLER from search CONTEXT. Thus, the assembler words can be used only between CODE and ENDCODE.
+
+The CONTEXT can grow up to 6 vocabularies by using the word ALSO.
+
+If you want add words to the assembler you must type: ALSO ASSEMBLER DEFINITIONS,
+The vocabulary ASSEMBLER is added to the search CONTEXT as previously but also becomes the CURRENT vocabulary in which the new words will be stored.
+
+Finally, FORTH ONLY DEFINITIONS limits the search CONTEXT to FORTH and the CURRENT vocabulary is FORTH.
+
+
--- /dev/null
+# SciTEDirectoriy.properties
+# For Windows, place in your directory project folder
+# Documentation at http://www.scintilla.org/SciTEDoc.html
+
+
+# Globals
+buffers.zorder.switching=1
+
+# Window sizes and visibility
+if PLAT_WIN
+ position.left=-1
+ position.top=0
+if PLAT_GTK
+ position.left=5
+ position.top=22
+position.width=1000
+position.height=768
+position.maximize=1
+#position.tile=1
+#full.screen.hides.menu=1
+minimize.to.tray=0
+split.vertical=1
+output.horizontal.size=400
+output.vertical.size=600
+output.initial.hide=1
+#horizontal.scrollbar=0
+#horizontal.scroll.width=10000
+#horizontal.scroll.width.tracking=0
+#output.horizontal.scrollbar=0
+#output.horizontal.scroll.width=10000
+#output.horizontal.scroll.width.tracking=0
+#output.scroll=0
+error.select.line=1
+#end.at.last.line=0
+tabbar.visible=1
+#tabbar.hide.one=1
+tabbar.multiline=0
+toolbar.visible=1
+#toolbar.detachable=1
+#toolbar.usestockicons=1
+#menubar.detachable=1
+#undo.redo.lazy=1
+statusbar.visible=1
+#fileselector.width=800
+#fileselector.height=600
+#fileselector.show.hidden=1
+magnification=0
+output.magnification=-4
+
+# Sizes and visibility in edit pane
+line.margin.visible=1
+line.margin.width=4
+margin.width=16
+fold.margin.width=0
+#fold.margin.colour=#00FF00
+#fold.margin.highlight.colour=#0000FF
+blank.margin.left=20
+#blank.margin.right=4
+buffered.draw=1
+#two.phase.draw=0
+use.palette=0
+
+
+#Element styles
+
+
+#view.eol=1
+#control.char.symbol=.
+caret.period=500
+view.whitespace=0
+view.indentation.whitespace=1
+view.indentation.guides=0
+view.indentation.examine=3
+highlight.indentation.guides=1
+caret.fore=#FF0000
+#caret.additional.blinks=0
+caret.width=3
+caret.line.back=#222222
+calltip.back=#FFF0FE
+edge.column=128
+edge.mode=1
+edge.colour=#C0DCC0
+braces.check=1
+braces.sloppy=1
+
+# black background
+selection.fore=#000000
+selection.alpha=256
+selection.back=#808080
+#selection.additional.fore=#0000A0
+#selection.additional.back=#000080
+#selection.additional.alpha=20
+#selection.multiple=0
+#selection.additional.typing=0
+#virtual.space=3
+#rectangular.selection.modifier=4
+#whitespace.fore=#FFFFFF
+#whitespace.back=#FFF0F0
+#error.marker.fore=#0000A0
+#error.marker.back=#DADAFF
+#bookmark.fore=#808000
+#bookmark.back=#FFFFA0
+#bookmark.alpha=
+#find.mark=#0000FF
+#highlight.current.word=1
+#highlight.current.word.by.style=1
+#highlight.current.word.colour=#00D040
+#indicators.alpha=63
+#indicators.under=1
+
+
+# Scripting
+ext.lua.startup.script=$(SciteUserHome)/SciTEStartup.lua
+ext.lua.auto.reload=1
+#ext.lua.reset=1
+
+
+# Checking
+are.you.sure=1
+#are.you.sure.for.build=1
+#save.all.for.build=1
+quit.on.close.last=1
+load.on.activate=1
+#save.on.deactivate=1
+are.you.sure.on.reload=1
+reload.preserves.undo=1
+#check.if.already.open=1
+#temp.files.sync.load=1
+default.file.ext=.txt
+#source.default.extensions=.h|.cxx|.bat
+title.full.path=1
+title.show.buffers=1
+pathbar.visible=1
+#save.recent=1
+#save.session=1
+#session.bookmarks=1
+#session.folds=1
+#save.position=1
+#open.dialog.in.file.directory=1
+#strip.trailing.spaces=1
+#ensure.final.line.end=1
+#ensure.consistent.line.ends=1
+#save.deletes.first=1
+#save.check.modified.time=1
+buffers=40
+buffers.zorder.switching=1
+#api.*.cxx=d:\api\w.api
+#import locale
+#locale.properties=locale.fr.properties
+#win95.death.delay=1000
+#translation.missing=***
+#read.only=1
+#max.file.size=1
+
+# Indentation
+tabsize=4
+indent.size=4
+use.tabs=0
+#indent.auto=1
+indent.automatic=0
+indent.opening=0
+indent.closing=0
+#tab.indents=0
+#backspace.unindents=0
+
+# Wrapping of long lines
+#wrap=1
+#wrap.style=2
+cache.layout=2
+#output.wrap=1
+#output.cache.layout=3
+#wrap.visual.flags=3
+#wrap.visual.flags.location=3
+#wrap.indent.mode=1
+#wrap.visual.startindent=4
+
+# Folding
+# enable folding, and show lines below when collapsed.
+fold=0
+fold.compact=0
+fold.flags=20
+fold.symbols=2
+#fold.highlight=1
+#fold.highlight.colour=#00C0C0
+#fold.on.open=1
+fold.comment=1
+fold.preprocessor=1
+
+# Find and Replace
+# Internal search always available with recursive capability so use in preference to external tool
+find.command=
+# findstr is available on recent versions of Windows including 2000
+if PLAT_WIN
+ find.command=findstr /n /s $(find.files) $(find.what)
+#find.input=$(find.what)
+if PLAT_GTK
+ find.command=grep --line-number "$(find.what)" $(find.files)
+#find.files=*.c *.cxx *.h
+find.files=*.*
+#find.in.files.close.on.find=0
+#find.in.dot=1
+#find.in.binary=1
+#find.close.on.find=0
+#find.replace.matchcase=1
+#find.replace.escapes=1
+#find.replace.regexp=1
+#find.replace.regexp.posix=1
+#find.replace.wrap=0
+#find.replacewith.focus=0
+#find.replace.advanced=1
+find.use.strip=0
+replace.use.strip=0
+#strip.button.height=24
+
+
+# Behaviour
+#eol.mode=LF
+#eol.auto=1
+clear.before.execute=0
+#vc.home.key=1
+#wrap.aware.home.end.keys=1
+#autocompleteword.automatic=1
+#autocomplete.choose.single=1
+caret.policy.xslop=1
+caret.policy.width=20
+caret.policy.xstrict=0
+caret.policy.xeven=0
+caret.policy.xjumps=0
+caret.policy.yslop=1
+caret.policy.lines=3
+caret.policy.ystrict=1
+caret.policy.yeven=1
+caret.policy.yjumps=0
+#visible.policy.strict=1
+#visible.policy.slop=1
+#visible.policy.lines=4
+#time.commands=1
+#caret.sticky=1
+properties.directory.enable=1
+
+# Status Bar
+statusbar.number=4
+statusbar.text.1=\
+li=$(LineNumber) co=$(ColumnNumber) $(OverType) ($(EOLMode)) $(FileAttr)
+statusbar.text.2=\
+$(BufferLength) chars in $(NbOfLines) lines. Sel: $(SelHeight) lines $(SelLength) chars.
+statusbar.text.3=\
+Now is: Date=$(CurrentDate) Time=$(CurrentTime)
+statusbar.text.4=\
+$(FileNameExt) : $(FileDate) \97 $(FileTime) | $(FileAttr)
+
+if PLAT_WIN
+ command.scite.help=C:\Program Files\SRWare Iron\iron.exe "C:\Program Files\SciTE\SciTEDoc.html"
+ command.scite.help.subsystem=2
+if PLAT_GTK
+ command.print.*=a2ps "$(FileNameExt)"
+ command.scite.help=netscape "file://$(SciteDefaultHome)/SciTEDoc.html"
+
+# Internationalisation
+# Japanese input code page 932 and ShiftJIS character set 128
+#code.page=932
+#character.set=128
+# Unicode
+#code.page=65001
+code.page=0
+#character.set=204
+# Required for Unicode to work on GTK+:
+#LC_CTYPE=en_US.UTF-8
+if PLAT_GTK
+ output.code.page=65001
+if PLAT_MAC
+ output.code.page=65001
+
+# Export
+#export.keep.ext=1
+export.html.wysiwyg=1
+#export.html.tabs=1
+#export.html.folding=1
+export.html.styleused=1
+export.html.title.fullpath=1
+#export.rtf.tabs=1
+#export.rtf.font.face=Arial
+#export.rtf.font.size=9
+#export.rtf.tabsize=8
+#export.rtf.wysiwyg=0
+#export.tex.title.fullpath=1
+# Magnification (added to default screen font size)
+export.pdf.magnification=0
+# Font: Courier, Helvetica or Times (Courier line-wraps)
+export.pdf.font=Courier
+# Page size (in points): width, height
+# E.g. Letter 612,792; A4 595,842; maximum 14400,14400
+export.pdf.pagesize=595,842
+# Margins (in points): left, right, top, bottom
+export.pdf.margins=56,28,28,28
+export.xml.collapse.spaces=1
+export.xml.collapse.lines=1
+
+# Define values for use in the imported properties files
+chars.alpha=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+chars.numeric=0123456789ABCDEFabcdefx
+chars.accented=\8a\9a\8c\9c\9fÿÀàÁáÂâÃãÄäÅåÆæÇçÈèÉéÊêËëÌìÍíÎîÏïÐðÑñÒòÓóÔôÕõÖØøÙùÚúÛûÜüÝýÞþßö
+# This is a better set for Russian:
+#chars.accented=ÀàÁáÂâÃãÄäÅ娸ÆæÇçÈèÉéÊêËëÌìÍíÎîÏïÐðÑñÒòÓóÔôÕõÖö×÷ØøÙùÚúÛûÜüÝýÞþßÿ
+
+# The open.filter setting is only used on Windows where the file selector has a menu of filters to apply
+# to the types of files seen when opening.
+# There is a limit (possibly 256 characters) to the length of a filter,
+# so not all source extensions can be in this setting.
+#*.idl;*.odl;*.rc;*.rc2;*.dlg;*.def;make*;*.mak;\
+#*.frm;*.cls;*.ctl;;*.pl;;*.iface;*.e;#*.rb;*.cgi;*.lua;\
+#source.files=*.asm;*.c;*.cc;*.f;*.ff;*.far;*.cpp;*.cxx;*.cs;*.h;*.hh;*.hxx;*.hpp;\
+source.files=*.asm;*.avr;*.tiny;*.mega;*.vb;*.vbs;*.bas;*.bat;*.ini;*.py;*.js;*.properties;*.vhd;*.vhdl
+
+# Each platform has a different idea of the most important filters
+if PLAT_WIN
+ all.files=All Files (*.*)|*.*|
+ top.filters=All Source|$(source.files)|$(all.files)
+if PLAT_GTK
+ all.files=All Files (*)|*|Hidden Files (.*)|.*|
+ top.filters=All Source|$(source.files)|$(all.files)
+# As OS X only greys out filtered files, show all as default
+if PLAT_MAC
+ all.files=All Files (*.*)|*.*|
+ top.filters=$(all.files)All Source|$(source.files)|
+
+open.filter=\
+$(top.filters)\
+#$(filter.ada)\
+$(filter.conf)\
+$(filter.asm)\
+#$(filter.asn1)\
+#$(filter.ave)\
+#$(filter.baan)\
+$(filter.bash)\
+#$(filter.caml)\
+#$(filter.cmake)\
+#$(filter.cpp)\
+#$(filter.ch)\
+$(filter.css)\
+#$(filter.d)\
+#$(filter.eiffel)\
+#$(filter.erlang)\
+#$(filter.fortran)\
+$(filter.forth)\
+#$(filter.gap)\
+#$(filter.hs)\
+#$(filter.idl)\
+#$(filter.inno)\
+$(filter.java)\
+$(filter.js)\
+#$(filter.kix)\
+#$(filter.lout)\
+$(filter.lua)\
+#$(filter.matlab)\
+#$(filter.metapost)\
+#$(filter.mmixal)\
+#$(filter.modula3)\
+#$(filter.nncrontab)\
+#$(filter.nsis)\
+#$(filter.opal)\
+#$(filter.pascal)\
+#$(filter.perl)\
+#$(filter.php)\
+#$(filter.pov)\
+#$(filter.powershell)\
+#$(filter.prg)\
+$(filter.properties)\
+$(filter.ps)\
+$(filter.python)\
+$(filter.r)\
+$(filter.ruby)\
+#$(filter.sql)\
+#$(filter.specman)\
+$(filter.tcl)\
+$(filter.tex)\
+$(filter.text)\
+$(filter.txt2tags)\
+$(filter.vb)\
+$(filter.web)\
+#$(filter.yaml)\
+$(filter.verilog)\
+$(filter.vhdl)
+
+#save.filter=$(open.filter)
+
+# Give symbolic names to the set of fonts used in the standard styles.
+if PLAT_WIN
+ font.base=font:Lucida Console,size:10
+ font.small=font:Lucida Console,size:10
+ font.comment=font:Lucida Console,size:10
+ font.code.comment.box=$(font.comment)
+ font.code.comment.line=$(font.comment)
+ font.code.comment.doc=$(font.comment)
+ font.code.comment.nested=$(font.comment)
+ font.text=font:Lucida Console,size:10
+ font.text.comment=font:Lucida Console,size:10
+ font.embedded.base=font:Lucida Console,size:10
+ font.embedded.comment=font:Lucida Console,size:10
+ font.monospace=font:Lucida Console,size:10
+ font.vbs=font:Lucida Sans Unicode,size:10
+if PLAT_GTK
+ font.base=font:lucidatypewriter,size:12
+ font.small=font:lucidatypewriter,size:10
+ font.comment=font:new century schoolbook,size:8
+ font.code.comment.box=$(font.comment)
+ font.code.comment.line=$(font.comment)
+ font.code.comment.doc=$(font.comment)
+ font.code.comment.nested=$(font.comment)
+ font.text=font:times,size:8
+ font.text.comment=font:lucidatypewriter,size:8
+ font.embedded.base=font:lucidatypewriter,size:8
+ font.embedded.comment=font:lucidatypewriter,size:8
+ font.monospace=font:courier,size:8
+ font.vbs=font:new century schoolbook,size:8
+if PLAT_MAC
+ font.base=font:Verdana,size:12
+ font.small=font:Verdana,size:10
+ font.comment=font:Georgia,size:13
+ font.code.comment.box=$(font.comment)
+ font.code.comment.line=$(font.comment)
+ font.code.comment.doc=$(font.comment)
+ font.code.comment.nested=$(font.comment)
+ font.text=font:Times New Roman,size:13
+ font.text.comment=font:Verdana,size:11
+ font.embedded.base=font:Verdana,size:11
+ font.embedded.comment=font:Comic Sans MS,size:10
+ font.monospace=font:Courier New,size:12
+ font.vbs=font:Lucida Sans Unicode,size:12
+ font.js=$(font.comment)
+
+# Old GTK+ font settings are faster but not antialiased
+ #~ font.base=font:lucidatypewriter,size:12
+ #~ font.small=font:lucidatypewriter,size:10
+ #~ font.comment=font:new century schoolbook,size:12
+ #~ font.code.comment.box=$(font.comment)
+ #~ font.code.comment.line=$(font.comment)
+ #~ font.code.comment.doc=$(font.comment)
+ #~ font.text=font:times,size:14
+ #~ font.text.comment=font:lucidatypewriter,size:10
+ #~ font.embedded.base=font:lucidatypewriter,size:12
+ #~ font.embedded.comment=font:lucidatypewriter,size:12
+ #~ font.monospace=font:courier,size:12
+ #~ font.vbs=font:new century schoolbook,size:12
+
+# Give symbolic names to the set of colours used in the standard styles.
+colour.code.comment.box=fore:#00FF00
+colour.code.comment.line=fore:#00FF00
+colour.code.comment.doc=fore:#3F703F
+colour.code.comment.nested=fore:#A0C0A0
+colour.text.comment=fore:#0000FF,back:#FFFFFF
+colour.other.comment=fore:#00FF00
+colour.embedded.comment=back:#E0EEFF
+colour.embedded.js=back:#F0F0FF
+colour.notused=back:#FF0000
+#couleur des nombres
+colour.number=fore:#FF00FF
+#couleur des instructions du langage
+colour.keyword=fore:#FF0000
+#couleur chaînes entre guillemets
+colour.string=fore:#00FFFF
+colour.char=fore:#7F7F7F
+colour.operator=fore:#00FF00
+colour.preproc=fore:#FF7F00
+colour.error=fore:#FFFF00,back:#FF0000
+
+# Global default styles for all languages
+# Default style, black background
+style.*.32=back:#000000,fore:#FFFFFF,font:Lucida Console,size:10
+# Line number
+style.*.33=back:#404040,$(font.base))
+# Brace highlight
+style.*.34=back:#222222,fore:#8080FF,bold
+# Brace incomplete highlight
+style.*.35=back:#222222,fore:#FF0000,bold
+# Control characters
+style.*.36=
+# Indentation guides
+style.*.37=fore:#C0C0C0,back:#FFFFFF
+
+# Printing - only works on Windows
+if PLAT_WIN
+ #print.colour.mode=1
+ print.magnification=-1
+ # Setup: left, right, top, bottom margins, in local units:
+ # hundredths of millimeters or thousandths of inches
+ print.margins=2000,1000,1000,1000
+ # Header/footer:
+ # && = &; &p = current page
+ # &f = file name; &F = full path
+ # &d = file date; &D = current date
+ # &t = file time; &T = full time
+ print.header.format=$(FileNameExt) \97 Printed on $(CurrentDate), $(CurrentTime) \97 Page $(CurrentPage)
+ print.footer.format=$(FilePath) \97 File date: $(FileDate) \97 File time: $(FileTime)
+ # Header/footer style
+ print.header.style=font:Arial,size:12,bold
+ print.footer.style=font:Arial Narrow,size:10,italics
+
+# Warnings - only works on Windows and needs to be pointed at files on machine
+#if PLAT_WIN
+# warning.findwrapped=100,E:\Windows\Media\SFX\Boing.wav
+# warning.notfound=0,Effect.wav
+# warning.wrongfile=0,Glass.wav
+# warning.executeok=0,Fanfare.wav
+# warning.executeko=100,GlassBreak.wav
+# warning.nootherbookmark=100,Boing2.wav
+
+# Define the Lexer menu,
+# Each item contains three parts: menu string | file extension | key
+# The only keys allowed currently are based on F-keys and alphabetic keys and look like
+# [Ctrl+][Shift+][Fn|a] such as F12 or Ctrl+Shift+D.
+# A '&' may be placed before a letter to be used as an accelerator. This does not work on GTK+.
+
+keyText=Shift+F11
+keyMake=Ctrl+Shift+F11
+keyHTML=F12
+keyXML=Shift+F12
+# On OS X, F11 is used by Expose, F12 by Dashbard
+if PLAT_MAC
+ keyText=Shift+F13
+ keyMake=Ctrl+Shift+F13
+ keyHTML=Ctrl+Shift+F14
+ keyXML=Shift+F14
+
+menu.language=\
+Text|txt|Shift+F11|\
+#Ada|ads||\
+#Apache Confi&g|conf||\
+Assembler|asm||\
+#ASN.1|asn1||\
+#Avenue|ave||\
+#Baan|bc||\
+&Batch|bat||\
+#Bullant|ant||\
+&C / C++|c||\
+#CMake|cmake||\
+C&#|cs||\
+#COBOL|cob||\
+#Csound|orc||\
+CSS|css||\
+D|d||\
+&Difference|diff||\
+#&Eiffel|e||\
+#Erlang|erl||\
+&Errorlist|err||\
+#FlagShip|prg||\
+Forth|forth||\
+#&Fortran|f90||\
+#Gap|g||\
+#Haskell|hs||\
+H&ypertext|html|F12|\
+#&InnoSetup|iss||\
+&Java|java||\
+Java&Script|js||\
+#&Kix|kix||\
+#Lisp|lisp||\
+#Lot|lot||\
+#Lout|lt||\
+#Lu&a|lua||\
+#Matlab|m.matlab||\
+&Makefile|mak|Ctrl+Shift+F11|\
+#MetaPost|mp||\
+#MMIXAL|mms||\
+#Modula-3|m3||\
+#&nnCron crontab|tab||\
+#NSIS|nsis||\
+#Objective Caml|ml||\
+#Octave|m.octave||\
+#Opal|impl||\
+#Pascal|pas||\
+Pe&rl|pl||\
+P&HP|php||\
+#P&LSQL|spec||\
+#P&ostScript|ps||\
+#P&OV-Ray SDL|pov||\
+#PowerShell|ps1||\
+#PowerPro|powerpro||\
+&Properties|properties||\
+Pytho&n|py||\
+#R|R||\
+#Reso&urce|rc||\
+Ruby|rb||\
+Shell|sh||\
+S&QL|sql||\
+#Specman|e||\
+&TCL|tcl||\
+TeX|tex||\
+#&txt2tags|t2t||\
+&VB|vb||\
+VBScr&ipt|vbs||\
+#Verilog|v||\
+#VHDL|vhd||\
+&XML|xml|$(keyXML)|\
+YAML|yaml||
+
+# User defined key commands
+user.shortcuts=\
+Ctrl+Shift+V|IDM_PASTEANDDOWN|\
+Ctrl+PageUp|IDM_PREVFILE|\
+Ctrl+PageDown|IDM_NEXTFILE|
+
+#KeypadPlus|IDM_EXPAND|\
+#KeypadMinus|IDM_BLOCK_COMMENT|
+
+#user.context.menu=\
+#||\
+#Next File|IDM_NEXTFILE|\
+#Prev File|IDM_PREVFILE|
+
+# Import all the language specific properties files
+#import abaqus
+#import ada
+#import asn1
+#import au3
+#import ave
+#import baan
+#import freebasic
+#import blitzbasic
+#import bullant
+#import caml
+import conf
+#import cobol
+import cpp
+#import cmake
+#import csound
+import css
+#import d
+#import eiffel
+#import erlang
+#import escript
+#import flagship
+#import fortran
+#import gap
+#import haskell
+import html
+#import inno
+#import kix
+import lisp
+#import lot
+#import lout
+import lua
+#import matlab
+#import metapost
+#import mmixal
+#import modula3
+#import nimrod
+#import nncrontab
+#import nsis
+#import opal
+import \config\scite\others
+#import pascal
+#import perl
+#import pov
+#import powerpro
+#import powershell
+import ps
+#import purebasic
+import python
+#import r
+#import rebol
+import ruby
+#import scriptol
+#import smalltalk
+#import spice
+#import sql
+#import specman
+#import tacl
+#import tal
+import tcl
+#import txt2tags
+import tex
+#import vb
+#import yaml
+#import verilog
+#import vhdl
+import \config\scite\AS_MSP430\asm
+import \config\scite\AS_MSP430\gema
+import \config\scite\AS_MSP430\forth
+import \config\scite\hex
+
+
+# Error list styles
+
+style.errorlist.32=fore:#B0B000,$(font.small)
+# Default
+style.errorlist.0=fore:#FFFFFF
+# Microsoft Error
+style.errorlist.3=fore:#0080FF
+# command or return status
+style.errorlist.4=fore:#FF00FF
+
+# Text matched with find in files and message part of GCC errors
+style.errorlist.21=fore:#FF0000
+
+
+
+
--- /dev/null
+
+; TERM alias eUSCI_Ax : select baudrate versus frequency
+ .IF FREQUENCY = 0.5
+ .SWITCH TERMINALBAUDRATE
+ .CASE 9600
+; Configure UART0 @ 19200 bauds / 1MHz
+; N=1000000/19200=52.0833... ==> UCOS16=1, UCBR0=int(N/16)=3, UCBRF0=int(frac(N/16)*16)=4, UCBRS0= fn(frac(N))=fn(0.0833)=0x02
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #3, &TERMBRW
+ MOV.W #0241h,&TERMMCTLW
+
+ .CASE 19200
+; Configure UART0 @ 38400 bauds / 1MHz
+; N=1000000/38400=26.04166... ==> UCOS16=1, UCBR0=int(N/16)=1, UCBRF0=int(frac(N/16)*16)=10, UCBRS0= fn(frac(N))=fn(0.04166)=0x00
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #1, &TERMBRW
+ MOV.W #00A1h, &TERMMCTLW
+
+ .CASE 31250 ; MIDI interface
+; Configure UART0 @ 31250 bauds / 500kHz
+; N=500000/31250=16 ==> UCOS16=0, UCBR0=int(N)=16, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0)=0
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #16, &TERMBRW
+ MOV.W #0000h,&TERMMCTLW
+
+ .CASE 38400 ; PL2303TA baudrate
+; Configure UART0 @ 38400 bauds / 500kHz
+; N=500000/38400=13.20833 ==> UCOS16=0, UCBR0=int(N)=13, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.20833)=0x11
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #13, &TERMBRW
+ MOV.W #1100h,&TERMMCTLW
+
+ .CASE 57600
+; Configure UART0 @ 115200 bauds / 1MHz
+; N=1000000/115200=8.68055... ==> UCOS16=0, UCBR0=int(N)=8, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.68055)=0xD6
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #8, &TERMBRW
+ MOV.W #0D600h,&TERMMCTLW
+
+ .CASE 100800 ; PL2303TA baudrate
+; Configure UART0 @ 201600 bauds / 1MHz
+; N=1000000/201600=4.955401 ==> UCOS16=0, UCBR0=int(N)=4, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.200396)=0xFE
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #4, &TERMBRW
+ MOV.W #0FE00h,&TERMMCTLW
+
+ .CASE 115200
+; Configure UART0 @ 230400 bauds / 1MHz
+; N=1000000/230400=4.34027... ==> UCOS16=0, UCBR0=int(N)=4, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.340277)=0x49
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #4, &TERMBRW
+ MOV.W #04900h,&TERMMCTLW
+
+ .CASE 134400 ; PL2303TA baudrate
+; Configure UART0 @ 268800 bauds / 1MHz
+; N=1000000/134400=3.72024 ==> UCOS16=0, UCBR0=int(N)=3, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.72024)=0xBB
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #3, &TERMBRW
+ MOV.W #0BB00h,&TERMMCTLW
+
+; .CASE 161280 ; PL2303TA baudrate
+;; Configure UART0 @ 161280 bauds / 500kHz
+;; N=500000/161280=3.100198 ==> UCOS16=0, UCBR0=int(N)=3, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.100198)=0x08
+;; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+; MOV #3, &TERMBRW
+; MOV.W #01100h,&TERMMCTLW
+
+ .ELSECASE
+ .error "UART0 / 500 kHz : baudrate not implemented"
+ .ENDCASE
+
+
+ .ELSEIF FREQUENCY = 1
+ .SWITCH TERMINALBAUDRATE
+ .CASE 9600
+; Configure UART0 @ 9600 bauds / 1MHz
+; N=1000000/9600=104.166... ==> UCOS16=1, UCBR0=int(N/16)=6, UCBRF0=int(frac(N/16)*16)=8, UCBRS0= fn(frac(N))=fn(0.1666)=0x20
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #6, &TERMBRW
+ MOV #2081h, &TERMMCTLW
+
+ .CASE 19200
+; Configure UART0 @ 19200 bauds / 1MHz
+; N=1000000/19200=52.0833... ==> UCOS16=1, UCBR0=int(N/16)=3, UCBRF0=int(frac(N/16)*16)=4, UCBRS0= fn(frac(N))=fn(0.0833)=0x02
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #3, &TERMBRW
+ MOV.W #0241h,&TERMMCTLW
+
+ .CASE 31250 ; MIDI interface
+; Configure UART0 @ 31250 bauds / 1MHz
+; N=1000000/31250=32 ==> UCOS16=1, UCBR0=int(N/16)=2, UCBRF0=int(frac(N/16)*16)=0, UCBRS0= fn(frac(N))=fn(0)=0
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #2, &TERMBRW
+ MOV.W #0001h,&TERMMCTLW
+
+ .CASE 38400
+; Configure UART0 @ 38400 bauds / 1MHz
+; N=1000000/38400=26.04166... ==> UCOS16=1, UCBR0=int(N/16)=1, UCBRF0=int(frac(N/16)*16)=10, UCBRS0= fn(frac(N))=fn(0.04166)=0x00
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #1, &TERMBRW
+ MOV.W #00A1h, &TERMMCTLW
+
+ .CASE 57600
+; Configure UART0 @ 57600 bauds / 1MHz
+; N=1000000/57600=17.301... ==> UCOS16=0, UCBR0=int(N)=17, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.301)=0x4A
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #17, &TERMBRW
+ MOV.W #04A00h,&TERMMCTLW
+
+ .CASE 100800 ; PL2303TA baudrate
+; Configure UART0 @ 100800 bauds / 1MHz
+; N=1000000/100800=9,920634 ==> UCOS16=0, UCBR0=int(N)=9, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.920634)=0xFD
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #9, &TERMBRW
+ MOV.W #0FD00h,&TERMMCTLW
+
+ .CASE 115200
+; Configure UART0 @ 115200 bauds / 1MHz
+; N=1000000/115200=8.68055... ==> UCOS16=0, UCBR0=int(N)=8, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.68055)=0xD6
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #8, &TERMBRW
+ MOV.W #0D600h,&TERMMCTLW
+
+ .CASE 134400 ; PL2303TA baudrate
+; Configure UART0 @ 134400 bauds / 1MHz
+; N=1000000/134400=7.440476 ==> UCOS16=0, UCBR0=int(N)=7, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.440476)=0x55
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #7, &TERMBRW
+ MOV.W #05500h,&TERMMCTLW
+
+ .CASE 161280 ; PL2303TA baudrate
+; Configure UART0 @ 161280 bauds / 1MHz
+; N=1000000/161280=6.200396 ==> UCOS16=0, UCBR0=int(N)=6, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.200396)=0x11
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #6, &TERMBRW
+ MOV.W #01100h,&TERMMCTLW
+
+ .CASE 201600 ; PL2303TA baudrate
+; Configure UART0 @ 201600 bauds / 1MHz
+; N=1000000/201600=4.955401 ==> UCOS16=0, UCBR0=int(N)=4, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.200396)=0xFE
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #4, &TERMBRW
+ MOV.W #0FE00h,&TERMMCTLW
+
+ .CASE 230400
+; Configure UART0 @ 230400 bauds / 1MHz
+; N=1000000/230400=4.34027... ==> UCOS16=0, UCBR0=int(N)=4, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.340277)=0x49
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #4, &TERMBRW
+ MOV.W #04900h,&TERMMCTLW
+
+ .CASE 250000 ; DMX interface
+; Configure UART0 @ 250000 bauds / 1MHz
+; N=1000000/250000=4 ==> UCOS16=0, UCBR0=int(N)=4, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0)=0
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #4, &TERMBRW
+ MOV.W #0000h,&TERMMCTLW
+
+ .CASE 268800 ; PL2303TA baudrate
+; Configure UART0 @ 268800 bauds / 1MHz
+; N=1000000/268800=3.72024 ==> UCOS16=0, UCBR0=int(N)=3, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.72024)=0xBB
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #3, &TERMBRW
+ MOV.W #0BB00h,&TERMMCTLW
+
+; .CASE 403200 ; PL2303TA baudrate
+;; Configure UART0 @ 403200 bauds / 1MHz
+;; N=1000000/403200=2.48016 ==> UCOS16=0, UCBR0=int(N)=2, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.48016)=0x55
+;; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+; MOV #2, &TERMBRW
+; MOV.W #05500h,&TERMMCTLW
+
+
+ .ELSECASE
+ .error "UART0 / 1 MHz : baudrate not implemented"
+ .ENDCASE
+
+ .ELSEIF FREQUENCY = 2
+ .SWITCH TERMINALBAUDRATE
+ .CASE 9600
+; Configure UART0 @ 19200 bauds / 4MHz
+; N=4000000/38400=208.333... ==> UCOS16=1, UCBR0=int(N/16)=13, UCBRF0=int(frac(N/16)*16)=0, UCBRS0= fn(frac(N))=fn(0.33333)=0x49
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #13, &TERMBRW
+ MOV.W #4901h, &TERMMCTLW
+
+ .CASE 19200
+; Configure UART0 @ 9600 bauds / 1MHz
+; N=1000000/9600=104.166... ==> UCOS16=1, UCBR0=int(N/16)=6, UCBRF0=int(frac(N/16)*16)=8, UCBRS0= fn(frac(N))=fn(0.1666)=0x20
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #6, &TERMBRW
+ MOV #2081h, &TERMMCTLW
+
+ .CASE 31250 ; MIDI interface
+; Configure UART0 @ 31250 bauds / 2MHz
+; N=2000000/31250=64 ==> UCOS16=1, UCBR0=int(N/16)=4, UCBRF0=int(frac(N/16)*16)=0, UCBRS0= fn(frac(N))=fn(0)=0
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #4, &TERMBRW
+ MOV.W #0001h,&TERMMCTLW
+
+ .CASE 38400
+; Configure UART0 @ 19200 bauds / 1MHz
+; N=1000000/19200=52.0833... ==> UCOS16=1, UCBR0=int(N/16)=3, UCBRF0=int(frac(N/16)*16)=4, UCBRS0= fn(frac(N))=fn(0.0833)=0x02
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #3, &TERMBRW
+ MOV.W #0241h,&TERMMCTLW
+
+ .CASE 57600
+; Configure UART0 @ 115200 bauds / 4MHz
+; N=8000000/230400=34.7222... ==> UCOS16=1, UCBR0=int(N/16)=2, UCBRF0=int(frac(N/16)*16)=2, UCBRS0= fn(frac(N))=fn(0.72222)=0xBB
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #2, &TERMBRW
+ MOV.W #0BB21h,&TERMMCTLW
+
+ .CASE 115200
+; Configure UART0 @ 57600 bauds / 1MHz
+; N=1000000/57600=17.301... ==> UCOS16=0, UCBR0=int(N)=17, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.301)=0x4A
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #17, &TERMBRW
+ MOV.W #04A00h,&TERMMCTLW
+
+ .CASE 230400
+; Configure UART0 @ 115200 bauds / 1MHz
+; N=1000000/115200=8.68055... ==> UCOS16=0, UCBR0=int(N)=8, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.68055)=0xD6
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #8, &TERMBRW
+ MOV.W #0D600h,&TERMMCTLW
+
+ .CASE 250000 ; DMX interface
+; Configure UART0 @ 250000 bauds / 2MHz
+; N=2000000/250000=8 ==> UCOS16=0, UCBR0=int(N)=8, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0)=0
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #8, &TERMBRW
+ MOV.W #0000h,&TERMMCTLW
+
+ .CASE 268800 ; PL2303TA baudrate
+; Configure UART0 @ 134400 bauds / 1MHz
+; N=1000000/134400=7.440476 ==> UCOS16=0, UCBR0=int(N)=7, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.440476)=0x55
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #7, &TERMBRW
+ MOV.W #05500h,&TERMMCTLW
+
+ .CASE 403200 ; PL2303TA baudrate
+; Configure UART0 @ 201600 bauds / 1MHz
+; N=1000000/201600=4.955401 ==> UCOS16=0, UCBR0=int(N)=4, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.200396)=0xFE
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #4, &TERMBRW
+ MOV.W #0FE00h,&TERMMCTLW
+
+ .CASE 460800 ; CP2102 baudrate (with programming)
+; Configure UART0 @ 921600 bauds / 4MHz
+; N = 4000000/460800 = 4.34027... ==> {UCOS16=0, UCBR1=int(N)=4, UCBRF1=dont_care=0 UCBRS1=fn(frac(N))=fn(0.34027)=0x49
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #4, &TERMBRW
+ MOV.W #04900h,&TERMMCTLW
+
+ .CASE 614400 ; PL2303TA baudrate
+; Configure UART0 @ 2457600 bauds / 8MHz
+; N = 8000000/2457600 = 3.25521... ==> {UCOS16=0, UCBR0=int(N)=3, UCBRF0=dont_care=0, UCBRS0=fn(frac(N))=fn(0.25521)=0x44
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #3, &TERMBRW
+ MOV.W #04400h,&TERMMCTLW
+
+; .CASE 806400 ; PL2303TA baudrate
+;; Configure UART0 @ 403200 bauds / 1MHz
+;; N=1000000/403200=2.48016 ==> UCOS16=0, UCBR0=int(N)=2, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.48016)=0x55
+;; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+; MOV #2, &TERMBRW
+; MOV.W #05500h,&TERMMCTLW
+
+
+ .ELSECASE
+ .error "UART0 / 2 MHz : baudrate not implemented"
+ .ENDCASE
+
+ .ELSEIF FREQUENCY = 4
+ .SWITCH TERMINALBAUDRATE
+ .CASE 9600
+; Configure UART0 @ 9600 bauds / 4MHz
+; N=4000000/19200=416.666... ==> UCOS16=1, UCBR0=int(N/16)=26, UCBRF0=int(frac(N/16)*16)=0, UCBRS0= fn(frac(N))=fn(0.66666)=0xD6
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #26, &TERMBRW
+ MOV.W #0D601h,&TERMMCTLW
+
+ .CASE 19200
+; Configure UART0 @ 19200 bauds / 4MHz
+; N=4000000/38400=208.333... ==> UCOS16=1, UCBR0=int(N/16)=13, UCBRF0=int(frac(N/16)*16)=0, UCBRS0= fn(frac(N))=fn(0.33333)=0x49
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #13, &TERMBRW
+ MOV.W #4901h, &TERMMCTLW
+
+ .CASE 31250 ; MIDI interface
+; Configure UART0 @ 31250 bauds / 4MHz
+; N=4000000/31250=128 ==> UCOS16=1, UCBR0=int(N/16)=8, UCBRF0=int(frac(N/16)*16)=0, UCBRS0= fn(frac(N))=fn(0)=0
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #8, &TERMBRW
+ MOV.W #0001h,&TERMMCTLW
+
+ .CASE 38400
+; Configure UART0 @ 38400 bauds / 4MHz
+; N=4000000/38400=104.1666... ==> UCOS16=1, UCBR0=int(N/16)=6, UCBRF0=int(frac(N/16)*16)=8, UCBRS0= fn(frac(N))=fn(0.16666)=0x20
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #6, &TERMBRW
+ MOV.W #02081h,&TERMMCTLW
+
+ .CASE 57600
+; Configure UART0 @ 57600 bauds / 4MHz
+; N=8000000/115200=69.444... ==> UCOS16=1, UCBR0=int(N/16)=4, UCBRF0=int(frac(N/16)*16)=5, UCBRS0= fn(frac(N))=fn(0.44444)=0x55
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #4, &TERMBRW
+ MOV.W #5551h, &TERMMCTLW
+
+ .CASE 115200
+; Configure UART0 @ 115200 bauds / 4MHz
+; N=8000000/230400=34.7222... ==> UCOS16=1, UCBR0=int(N/16)=2, UCBRF0=int(frac(N/16)*16)=2, UCBRS0= fn(frac(N))=fn(0.72222)=0xBB
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #2, &TERMBRW
+ MOV.W #0BB21h,&TERMMCTLW
+
+ .CASE 230400
+; Configure UART0 @ 230400 bauds / 4MHz
+; see table "Recommended Settings for Typical Crystals and Baudrates"
+ MOV #17, &TERMBRW
+ MOV.W #04A00h,&TERMMCTLW
+
+ .CASE 250000 ; DMX interface
+; Configure UART0 @ 250000 bauds / 4MHz
+; N=4000000/250000=16 ==> UCOS16=1, UCBR0=int(N/16)=1, UCBRF0=int(frac(N/16)*16)=0, UCBRS0= fn(frac(N))=fn(0)=0
+; TERMBRW=UCBR1, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #1, &TERMBRW
+ MOV.W #0001h, &TERMMCTLW
+
+ .CASE 460800
+; Configure UART0 @ 460800 bauds / 4MHz
+; N = 8000000/921600 = 8.680555... ==> {UCOS16=0, UCBR0=int(N)=8, UCBRF0=dont_care=0, UCBRS0=fn(frac(N))=fn(0.68055)=0xD6
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #8, &TERMBRW
+ MOV.W #0D600h,&TERMMCTLW
+
+ .CASE 806400 ; PL2303TA baudrate
+; Configure UART0 @ 201600 bauds / 1MHz
+; N=1000000/201600=4.955401 ==> UCOS16=0, UCBR0=int(N)=4, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.200396)=0xFE
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #4, &TERMBRW
+ MOV.W #0FE00h,&TERMMCTLW
+
+ .CASE 921600 ; CP2102 baudrate (with programming)
+; Configure UART0 @ 921600 bauds / 4MHz
+; N = 8000000/921600 = 4.34027... ==> {UCOS16=0, UCBR1=int(N)=4, UCBRF1=dont_care=0 UCBRS1=fn(frac(N))=fn(0.34027)=0x49
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #4, &TERMBRW
+ MOV.W #04900h,&TERMMCTLW
+
+ .CASE 1228800 ; PL2303TA baudrate
+; Configure UART0 @ 2457600 bauds / 8MHz
+; N = 8000000/1228800 = 3.25521... ==> {UCOS16=0, UCBR0=int(N)=3, UCBRF0=dont_care=0, UCBRS0=fn(frac(N))=fn(0.25521)=0x44
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #3, &TERMBRW
+ MOV.W #04400h,&TERMMCTLW
+
+
+ .ELSECASE
+ .error "UART0 / 4 MHz : baudrate not implemented"
+ .ENDCASE ; UART0 / 4 MHz baudrates
+
+
+ .ELSEIF FREQUENCY = 8
+ .SWITCH TERMINALBAUDRATE
+ .CASE 9600
+; Configure UART0 @ 9600 bauds / 8MHz
+; N=8000000/9600=833.333... ==> UCOS16=1, UCBR0=int(N/16)=52, UCBRF0=int(frac(N/16)*16)=1, UCBRS0= fn(frac(N))=fn(0.33333)=0x49
+ MOV #52, &TERMBRW
+ MOV #4911h, &TERMMCTLW
+
+ .CASE 19200
+; Configure UART0 @ 19200 bauds / 8MHz
+; N=8000000/19200=416.666... ==> UCOS16=1, UCBR0=int(N/16)=26, UCBRF0=int(frac(N/16)*16)=0, UCBRS0= fn(frac(N))=fn(0.66666)=0xD6
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #26, &TERMBRW
+ MOV.W #0D601h,&TERMMCTLW
+
+ .CASE 31250 ; MIDI interface
+; Configure UART0 @ 31250 bauds / 8MHz
+; N=8000000/31250=256 ==> UCOS16=1, UCBR0=int(N/16)=16, UCBRF0=int(frac(N/16)*16)=0, UCBRS0= fn(frac(N))=fn(0)=0
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #16, &TERMBRW
+ MOV.W #0001h,&TERMMCTLW
+
+ .CASE 38400
+; Configure UART0 @ 38400 bauds / 8MHz
+; N=8000000/38400=208.333... ==> UCOS16=1, UCBR0=int(N/16)=13, UCBRF0=int(frac(N/16)*16)=0, UCBRS0= fn(frac(N))=fn(0.33333)=0x49
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #13, &TERMBRW
+ MOV.W #4901h, &TERMMCTLW
+
+ .CASE 57600
+; Configure UART0 @ 57600 bauds / 8MHz
+; N=8000000/57600=138.888... ==> UCOS16=1, UCBR0=int(N/16)=8, UCBRF0=int(frac(N/16)*16)=10, UCBRS0= fn(frac(N))=fn(0.88888)=0xF7
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #8, &TERMBRW
+ MOV.W #0F7A1h,&TERMMCTLW
+
+ .CASE 115200
+; Configure UART0 @ 115200 bauds / 8MHz
+; N=8000000/115200=69.444... ==> UCOS16=1, UCBR0=int(N/16)=4, UCBRF0=int(frac(N/16)*16)=5, UCBRS0= fn(frac(N))=fn(0.44444)=0x55
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #4, &TERMBRW
+ MOV.W #5551h, &TERMMCTLW
+
+ .CASE 230400
+; Configure UART0 @ 230400 bauds / 8MHz
+; N=8000000/230400=34.7222... ==> UCOS16=1, UCBR0=int(N/16)=2, UCBRF0=int(frac(N/16)*16)=2, UCBRS0= fn(frac(N))=fn(0.72222)=0xBB
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #2, &TERMBRW
+ MOV.W #0BB21h,&TERMMCTLW
+
+ .CASE 250000 ; DMX interface
+; Configure UART0 @ 250000 bauds / 8MHz
+; N=8000000/250000=32 ==> UCOS16=1, UCBR0=int(N/16)=2, UCBRF0=int(frac(N/16)*16)=0, UCBRS0= fn(frac(N))=fn(0)=0
+; TERMBRW=UCBR1, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #2, &TERMBRW
+ MOV.W #0001h, &TERMMCTLW
+
+ .CASE 460800
+; Configure UART0 @ 460800 bauds / 8MHz
+; see table "Recommended Settings for Typical Crystals and Baudrates"
+ MOV #17, &TERMBRW
+ MOV.W #04A00h,&TERMMCTLW
+
+ .CASE 614400 ; PL2303TA baudrate
+; Configure UART0 @ 614400 bauds / 8MHz
+; N = 8000000/614400 = 13.02083... ==> {UCOS16=0, UCBR0=int(N)=13, UCBRF0=dont_care=0, UCBRS0=fn(frac(N))=fn(0.02083)=0x02
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #13, &TERMBRW
+ MOV.W #00200h,&TERMMCTLW
+
+ .CASE 806400 ; PL2303TA baudrate
+; Configure UART0 @ 100800 bauds / 1MHz
+; N=1000000/100800=9,920634 ==> UCOS16=0, UCBR0=int(N)=9, UCBRF0=dont_care=0, UCBRS0= fn(frac(N))=fn(0.920634)=0xFD
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #9, &TERMBRW
+ MOV.W #0FD00h,&TERMMCTLW
+
+ .CASE 921600
+; Configure UART0 @ 921600 bauds / 8MHz
+; N = 8000000/921600 = 8.680555... ==> {UCOS16=0, UCBR0=int(N)=8, UCBRF0=dont_care=0, UCBRS0=fn(frac(N))=fn(0.68055)=0xD6
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #8, &TERMBRW
+ MOV.W #0D600h,&TERMMCTLW
+
+ .CASE 1000000
+; Configure UART0 @ 2000000 bauds / 16MHz
+; N = 16000000/2000000 = 8 ==> {UCOS16=0, UCBR0=int(N)=8, UCBRF0=dont_care=0 UCBRS0=fn(frac(N))=fn(0.00000)=0x00
+ MOV #8 , &TERMBRW
+ MOV.W #00000h,&TERMMCTLW
+
+ .CASE 1228800 ; PL2303TA baudrate
+; Configure UART0 @ 1228800 bauds / 8MHz
+; N = 8000000/1228800 = 6.510416... ==> {UCOS16=0, UCBR0=int(N)=6, UCBRF0=dont_care=0, UCBRS0=fn(frac(N))=fn(0.510416)=0xAA
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #6, &TERMBRW
+ MOV.W #0AA00h,&TERMMCTLW
+
+ .CASE 1382400 ; CP2102 baudrate
+; Configure UART0 @ 1382400 bauds / 8MHz
+; N = 8000000/1382400 = 5.787037... ==> {UCOS16=0, UCBR0=int(N)=5, UCBRF0=dont_care=0 UCBRS0=fn(frac(N))=fn(0.787037)=0xED
+ MOV #5, &TERMBRW
+ MOV.W #0DD00h,&TERMMCTLW
+
+ .CASE 1843200 ; CP2102 baudrate (with programming)
+; Configure UART0 @ 1843200 bauds / 8MHz
+; N = 16000000/1843200 = 4.34027... ==> {UCOS16=0, UCBR1=int(N)=4, UCBRF1=dont_care=0 UCBRS1=fn(frac(N))=fn(0.34027)=0x49
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #4, &TERMBRW
+ MOV.W #04900h,&TERMMCTLW
+
+ .CASE 2457600 ; PL2303TA baudrate
+; Configure UART0 @ 2457600 bauds / 8MHz
+; N = 8000000/1228800 = 3.25521... ==> {UCOS16=0, UCBR0=int(N)=3, UCBRF0=dont_care=0, UCBRS0=fn(frac(N))=fn(0.25521)=0x44
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #3, &TERMBRW
+ MOV.W #04400h,&TERMMCTLW
+
+ .ELSECASE
+ .error "UART0 / 8 MHz : baudrate not implemented"
+ .ENDCASE ; UART0 / 8 MHz baudrates
+
+
+ .ELSEIF FREQUENCY = 16
+ .SWITCH TERMINALBAUDRATE
+ .CASE 9600
+; Configure UART0 @ 9600 bauds / 16MHz
+; N=16000000/9600=1666.666... ==> UCOS16=1, UCBR0=int(N/16)=104, UCBRF0=int(frac(N/16)*16)=2, UCBRS0= fn(frac(N))=fn(0.66666)=0xD6
+; TERMBRW=UCBR1, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #104, &TERMBRW
+ MOV #0D621h, &TERMMCTLW
+
+ .CASE 19200
+; Configure UART0 @ 19200 bauds / 16MHz
+; N=16000000/19200=833.333... ==> UCOS16=1, UCBR0=int(N/16)=52, UCBRF0=int(frac(N/16)*16)=1, UCBRS0= fn(frac(N))=fn(0.33333)=0x49
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #52, &TERMBRW
+ MOV #4911h, &TERMMCTLW
+
+ .CASE 31250 ; MIDI interface
+; Configure UART0 @ 31250 bauds / 8MHz
+; N=16000000/31250=512 ==> UCOS16=1, UCBR0=int(N/16)=32, UCBRF0=int(frac(N/16)*16)=0, UCBRS0= fn(frac(N))=fn(0)=0
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #32, &TERMBRW
+ MOV.W #0001h,&TERMMCTLW
+
+ .CASE 38400
+; Configure UART0 @ 38400 bauds / 16MHz
+; N=16000000/19200=416.666... ==> UCOS16=1, UCBR0=int(N/16)=26, UCBRF0=int(frac(N/16)*16)=0, UCBRS0= fn(frac(N))=fn(0.66666)=0xD6
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #26, &TERMBRW
+ MOV.W #0D601h,&TERMMCTLW
+
+ .CASE 57600
+; Configure UART0 @ 57600 bauds / 16MHz
+; N=16000000/57600=277.777... ==> UCOS16=1, UCBR0=int(N/16)=17, UCBRF0=int(frac(N/16)*16)=5, UCBRS0= fn(frac(N))=fn(0.77777)=0xDD
+; TERMBRW=UCBR1, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #17, &TERMBRW
+ MOV.W #0DD51h,&TERMMCTLW
+
+ .CASE 115200
+; Configure UART0 @ 115200 bauds / 16MHz
+; N=16000000/115200=138.888... ==> UCOS16=1, UCBR0=int(N/16)=8, UCBRF0=int(frac(N/16)*16)=10, UCBRS0= fn(frac(N))=fn(0.88888)=0xF7
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #8, &TERMBRW
+ MOV.W #0F7A1h,&TERMMCTLW
+
+ .CASE 230400
+; Configure UART0 @ 230400 bauds / 16MHz
+; N=16000000/230400=69.444... ==> UCOS16=1, UCBR0=int(N/16)=4, UCBRF0=int(frac(N/16)*16)=5, UCBRS0= fn(frac(N))=fn(0.44444)=0x55
+; TERMBRW=UCBR1, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #4, &TERMBRW
+ MOV.W #5551h, &TERMMCTLW
+
+ .CASE 250000 ; DMX interface
+; Configure UART0 @ 250000 bauds / 16MHz
+; N=16000000/250000=64 ==> UCOS16=1, UCBR0=int(N/16)=4, UCBRF0=int(frac(N/16)*16)=0, UCBRS0= fn(frac(N))=fn(0)=0
+; TERMBRW=UCBR1, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #4, &TERMBRW
+ MOV.W #0001h, &TERMMCTLW
+
+ .CASE 460800
+; Configure UART0 @ 460800 bauds / 16MHz
+; N=16000000/460800=34.7222... ==> UCOS16=1, UCBR0=int(N/16)=2, UCBRF0=int(frac(N/16)*16)=2, UCBRS0= fn(frac(N))=fn(0.72222)=0xBB
+; TERMBRW=UCBR1, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #2, &TERMBRW
+ MOV.W #0BB21h,&TERMMCTLW
+
+ .CASE 500000 ; CP2102 baudrate
+; Configure UART0 @ 500000 bauds / 16MHz
+; N = 16000000/500000 = 32 ==> {UCOS16=1, UCBR0=int(N/16)=2, UCBRF1=0 UCBRS0=fn(frac(N))=fn(0.00000)=0x00
+; TERMBRW=UCBR1, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+; MOV #2, &TERMBRW
+; MOV.W #00001h,&TERMMCTLW
+
+ .CASE 921600
+; Configure UART0 @ 921600 bauds / 16MHz
+; see "Configure UART1 @ 460800 bauds / 8MHz"
+ MOV #17, &TERMBRW
+ MOV.W #04A00h,&TERMMCTLW
+
+ .CASE 1000000
+; Configure UART0 @ 1000000 bauds / 16MHz
+; N = 16000000/1000000 = 16 ==> {UCOS16=1, UCBR0=int(N/16)=1, UCBRF0=0 UCBRS0=fn(frac(N))=fn(0.00000)=0x00
+; TERMBRW=UCBR1, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #1, &TERMBRW
+ MOV.W #00001h,&TERMMCTLW
+
+ .CASE 1228800 ; PL2303TA baudrate
+; Configure UART0 @ 614400 bauds / 8MHz
+; N = 8000000/614400 = 13.02083... ==> {UCOS16=0, UCBR0=int(N)=13, UCBRF0=dont_care=0, UCBRS0=fn(frac(N))=fn(0.02083)=0x02
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #13, &TERMBRW
+ MOV.W #00200h,&TERMMCTLW
+
+ .CASE 1382400 ; CP2102 baudrate (with programming)
+; Configure UART0 @ 1382400 bauds / 16MHz
+; N = 16000000/1382400 = 11.574074... ==> {UCOS16=0, UCBR0=int(N)=11, UCBRF0=dont_care=0 UCBRS0=fn(frac(N))=fn(0.68055)=0x6B
+ MOV #11, &TERMBRW
+ MOV.W #06B00h,&TERMMCTLW
+
+ .CASE 1843200 ; CP2102 baudrate (with programming)
+; Configure UART0 @ 1843200 bauds / 16MHz
+; N = 16000000/1843200 = 8.680555... ==> {UCOS16=0, UCBR1=int(N)=8, UCBRF1=dont_care=0 UCBRS1=fn(frac(N))=fn(0.68055)=0xD6
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #8, &TERMBRW
+ MOV.W #0D600h,&TERMMCTLW
+
+ .CASE 2000000
+; Configure UART0 @ 2000000 bauds / 16MHz
+; N = 16000000/2000000 = 8 ==> {UCOS16=0, UCBR0=int(N)=8, UCBRF0=dont_care=0 UCBRS0=fn(frac(N))=fn(0.00000)=0x00
+ MOV #8 , &TERMBRW
+ MOV.W #00000h,&TERMMCTLW
+
+ .CASE 2457600 ; PL2303TA baudrate
+; Configure UART0 @ 1228800 bauds / 8MHz
+; N = 8000000/1228800 = 6.510416... ==> {UCOS16=0, UCBR0=int(N)=6, UCBRF0=dont_care=0, UCBRS0=fn(frac(N))=fn(0.510416)=0xAA
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #6, &TERMBRW
+ MOV.W #0AA00h,&TERMMCTLW
+
+ .CASE 2764800
+; Configure UART0 @ 2764800 bauds / 16MHz
+; N = 16000000/2764800 = 5.787037... ==> {UCOS16=0, UCBR0=int(N)=5, UCBRF0=dont_care=0 UCBRS0=fn(frac(N))=fn(0.787037)=0xED
+ MOV #5, &TERMBRW
+ MOV.W #0DD00h,&TERMMCTLW
+
+ .CASE 3000000 ; PL2303TA baudrate
+; Configure UART0 @ 3000000 bauds / 16MHz
+; N = 16000000/3000000 = 5.333333... ==> {UCOS16=0, UCBR0=int(N)=5, UCBRF0=dont_care=0, UCBRS0=fn(frac(N))=fn(0.333333)=0x49
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #5, &TERMBRW
+ MOV.W #04900h,&TERMMCTLW
+
+ .ELSECASE
+ .error "UART0 / 16 MHz : baudrate not implemented"
+ .ENDCASE ; UART0 / 16 MHz baudrates
+
+ .ELSEIF FREQUENCY = 24
+ .SWITCH TERMINALBAUDRATE
+ .CASE 9600
+; Configure UART0 @ 9600 bauds / 24MHz
+; N=24000000/9600=2500 ==> UCOS16=1, UCBR0=int(N/16)=156, UCBRF0=int(frac(N/16)*16)=4, UCBRS0= fn(frac(N))=(fn(0))=0x00
+; TERMBRW=UCBR1, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #156, &TERMBRW
+ MOV #0041h, &TERMMCTLW
+
+ .CASE 19200
+; Configure UART0 @ 19200 bauds / 24MHz
+; N=24000000/19200=1250 ==> UCOS16=1, UCBR0=int(N/16)=78, UCBRF0=int(frac(N/16)*16)=2, UCBRS0= fn(frac(N))=fn(0)=0x00
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #78, &TERMBRW
+ MOV #0021h, &TERMMCTLW
+
+ .CASE 31250 ; MIDI interface
+; Configure UART0 @ 31250 bauds / 8MHz
+; N=24000000/31250=768 ==> UCOS16=1, UCBR0=int(N/16)=48, UCBRF0=int(frac(N/16)*16)=0, UCBRS0= fn(frac(N))=fn(0)=0
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #48, &TERMBRW
+ MOV.W #0001h,&TERMMCTLW
+
+ .CASE 38400
+; Configure UART0 @ 38400 bauds / 24MHz
+; N=24000000/19200=625 ==> UCOS16=1, UCBR0=int(N/16)=39, UCBRF0=int(frac(N/16)*16)=1, UCBRS0= fn(frac(N))=fn(0)=0x00
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #39, &TERMBRW
+ MOV.W #0011h,&TERMMCTLW
+
+ .CASE 57600
+; Configure UART0 @ 57600 bauds / 24MHz
+; N=24000000/57600=416.666... ==> UCOS16=1, UCBR0=int(N/16)=26, UCBRF0=int(frac(N/16)*16)=0, UCBRS0= fn(frac(N))=fn(0.666)=0xD6
+; TERMBRW=UCBR1, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #26, &TERMBRW
+ MOV.W #0D601h,&TERMMCTLW
+
+ .CASE 115200
+; Configure UART0 @ 115200 bauds / 24MHz
+; N=24000000/115200=208.333... ==> UCOS16=1, UCBR0=int(N/16)=13, UCBRF0=int(frac(N/16)*16)=0, UCBRS0= fn(frac(N))=fn(0.333)=0x49
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #13, &TERMBRW
+ MOV.W #04901h,&TERMMCTLW
+
+ .CASE 230400
+; Configure UART0 @ 230400 bauds / 24MHz
+; N=24000000/230400=104.1666... ==> UCOS16=1, UCBR0=int(N/16)=6, UCBRF0=int(frac(N/16)*16)=8, UCBRS0= fn(frac(N))=fn(0.1666)=0x20
+; TERMBRW=UCBR1, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #6, &TERMBRW
+ MOV.W #2081h, &TERMMCTLW
+
+ .CASE 250000 ; DMX interface
+; Configure UART0 @ 250000 bauds / 24MHz
+; N=24000000/250000=96 ==> UCOS16=1, UCBR0=int(N/16)=6, UCBRF0=int(frac(N/16)*16)=0, UCBRS0= fn(frac(N))=fn(0)=0
+; TERMBRW=UCBR1, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #6, &TERMBRW
+ MOV.W #0001h, &TERMMCTLW
+
+ .CASE 460800
+; Configure UART0 @ 460800 bauds / 24MHz
+; N=24000000/460800=52.08333... ==> UCOS16=1, UCBR0=int(N/16)=3, UCBRF0=int(frac(N/16)*16)=4, UCBRS0= fn(frac(N))=fn(0.0833)=0x02
+; TERMBRW=UCBR1, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #3, &TERMBRW
+ MOV.W #0241h,&TERMMCTLW
+
+ .CASE 500000 ; CP2102 baudrate
+; Configure UART0 @ 500000 bauds / 24MHz
+; N = 24000000/500000 = 48 ==> {UCOS16=1, UCBR0=int(N/16)=3, UCBRF0=int(frac(N/16)*16)=0 UCBRS0=fn(frac(N))=fn(0.00000)=0x00
+; TERMBRW=UCBR1, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+; MOV #3, &TERMBRW
+; MOV.W #0001h,&TERMMCTLW
+
+ .CASE 921600
+; Configure UART0 @ 921600 bauds / 24MHz
+; N = 24000000/921600 = 26.041666... ==> {UCOS16=1, UCBR0=int(N/16)=1, UCBRF0=int(frac(N/16)*16)=10 UCBRS0=fn(frac(N))=fn(0.0416)=0x00
+; TERMBRW=UCBR1, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #1, &TERMBRW
+ MOV.W #00A1h,&TERMMCTLW
+
+ .CASE 1000000
+; Configure UART0 @ 1000000 bauds / 24MHz
+; N = 24000000/1000000 = 24 ==> {UCOS16=1, UCBR0=int(N/16)=1, UCBRF0=int(frac(N/16)*16)=4, UCBRS0=fn(frac(N))=fn(0.000)=0x00
+; TERMBRW=UCBR1, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #1, &TERMBRW
+ MOV.W #0041h,&TERMMCTLW
+
+ .CASE 1382400
+; Configure UART0 @ 1382400 bauds / 24MHz
+; N = 24000000/1382400 = 17.36111... ==> {UCOS16=1, UCBR0=int(N/16)=1, UCBRF0=int(frac(N/16)*16)=1, UCBRS0=fn(frac(N))=fn(0.3611)=0x4A
+ MOV #1, &TERMBRW
+ MOV.W #04A11h,&TERMMCTLW
+
+ .CASE 1843200
+; Configure UART0 @ 1843200 bauds / 24MHz
+; N = 24000000/1843200 = 13.08203... {UCOS16=0, UCBR0=int(N)=13, UCBRF0=dont_care=0 UCBRS0=fn(frac(N))=fn(0.08203)=0x02
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #13, &TERMBRW
+ MOV.W #0200h,&TERMMCTLW
+
+ .CASE 2457600 ; PL2303TA baudrate
+; Configure UART0 @ 2457600 bauds / 24MHz
+; N = 24000000/2457600 = 9.765625... ==> {UCOS16=0, UCBR0=int(N)=9, UCBRF0=dont_care=0, UCBRS0=fn(frac(N))=fn(0.765625)=0xDD
+; TERMBRW=UCBR0, TERMMCTLW= (UCBRS0<<8)|(UCBRF0<<4)|UCOS16
+ MOV #9, &TERMBRW
+ MOV.W #0DD00h,&TERMMCTLW
+
+ .CASE 3000000 ; PL2303TA baudrate
+; Configure UART0 @ 3000000 bauds / 24MHz
+; N = 24000000/3000000 = 8 ==> {UCOS16=0, UCBR0=int(N)=8, UCBRF0=dont_care=0 UCBRS0=fn(frac(N))=fn(0.00000)=0x00
+ MOV #8, &TERMBRW
+ MOV.W #0000h,&TERMMCTLW
+
+ .CASE 6000000 ; PL2303TA baudrate
+; Configure UART0 @ 3000000 bauds / 24MHz
+; N = 24000000/3000000 = 4 ==> {UCOS16=0, UCBR0=int(N)=8, UCBRF0=dont_care=0 UCBRS0=fn(frac(N))=fn(0.00000)=0x00
+ MOV #4, &TERMBRW
+ MOV.W #0000h,&TERMMCTLW
+
+ .ELSECASE
+ .error "UART0 / 24 MHz : baudrate not implemented"
+ .ENDCASE ; UART0 / 24MHz baudrates
+
+ .ELSEIF
+ .error "UART0 frequency not implemented"
+ .ENDIF ; frequency
+
--- /dev/null
+; Targe.inc
+
+;-----------------------------------------------------------------------
+; DEVICE I/O, MEMORY, SFR, vectors and FORTH I/O declarations
+;-----------------------------------------------------------------------
+
+
+FRAM_FULL .equ SIGNATURES-50h ; set to protect JTAG and BSL signatures against overwrite.
+ ; notice that ALLOT memory space beyond SIGNATURES don't corrupt it,
+ ; so 80 bytes are sufficient considering what can be compiled in one line and WORD use.
+ ; good practice: one line reserved for each ALLOT command.
+
+
+
+
+ OUTRADIX 10
+ .warning "TERMINAL \{TERMINALBAUDRATE} bds"
+ .warning "frequency = \{FREQUENCY} MHz"
+
+
+ .IFDEF MSP_EXP430FR5739
+ .warning "Code for MSP_EXP430FR5739"
+DEVICE = "MSP430FR5739"
+LF_XTAL
+UCA0_UART
+UCB0_SD
+ .include "MSP430FR57xx.inc"
+ .ENDIF ; MSP_EXP430FR5739
+
+ .IFDEF MSP_EXP430FR5969
+ .warning "Code for MSP_EXP430FR5969"
+DEVICE = "MSP430FR5969"
+LF_XTAL
+UCA0_UART
+UCA1_SD
+ .include "MSP430FR5x6x.inc"
+ .ENDIF ; MSP_EXP430FR5969
+
+ .IFDEF MSP_EXP430FR5994
+ .warning "Code for MSP_EXP430FR5994"
+DEVICE = "MSP430FR5994"
+LF_XTAL
+UCA0_UART
+UCB0_SD
+ .include "MSP430FR5x6x.inc"
+ .ENDIF ; MSP_EXP430FR5994
+
+ .IFDEF MSP_EXP430FR6989
+ .warning "Code for MSP_EXP430FR6989"
+DEVICE = "MSP430FR6989"
+LF_XTAL
+UCA1_UART
+UCA0_SD
+ .INCLUDE "MSP430FR5x6x.inc"
+ .ENDIF ; MSP_EXP430FR6989
+
+ .IFDEF MSP_EXP430FR4133
+ .warning "Code for MSP_EXP430FR4133"
+DEVICE = "MSP430FR4133"
+LF_XTAL
+UCA0_UART
+UCB0_SD
+ .INCLUDE "MSP430FR2x4x.inc"
+ .ENDIF ; MSP_EXP430FR4133
+
+ .IFDEF CHIPSTICK_FR2433
+ .warning "Code for CHIPSTICK_FR2433"
+DEVICE = "MSP430FR2433"
+UCA0_UART
+UCB0_SD
+ .include "MSP430FR2x4x.inc"
+ .ENDIF ; CHIPSTICK_FR2433
+
+
+ .IFDEF MY_MSP430FR5738
+ .warning "Code for MY_MSP430FR5738"
+DEVICE = "MSP430FR5738"
+LF_XTAL
+UCA0_UART
+UCB0_SD
+ .include "MSP430FR57xx.inc"
+ .ENDIF ; MY_MSP430FR5738
+
+ .IFDEF MY_MSP430FR5734
+ .warning "Code for MY_MSP430FR5734"
+DEVICE = "MSP430FR5734"
+UCA0_UART
+ .include "MSP430FR57xx.inc"
+ .ENDIF ; MY_MSP430FR5734_1
+
+ .IFDEF MY_MSP430FR5738_1
+ .warning "Code for MY_MSP430FR5738_1"
+DEVICE = "MSP430FR5738"
+LF_XTAL
+UCA0_UART
+UCB0_SD
+ .include "MSP430FR57xx.inc"
+ .ENDIF ; MY_MSP430FR5738_1
+
+ .IFDEF MY_MSP430FR5948
+ .warning "Code for MY_MSP430FR5948"
+DEVICE = "MSP430FR5948"
+UCA0_UART
+UCA1_SD
+ .include "MSP430FR5x6x.inc"
+ .ENDIF ; MY_MSP430FR5948
+
+ .IFDEF MY_MSP430FR5948_1
+ .warning "Code for MY_MSP430FR5948_1"
+DEVICE = "MSP430FR5948"
+LF_XTAL
+UCA0_UART
+UCA1_SD
+ .include "MSP430FR5x6x.inc"
+ .ENDIF ; MY_MSP430FR5948_1
+
+ .IFDEF JMJ_BOX
+ .warning "Code for JMJ_BOX"
+DEVICE = "MSP430FR5738"
+UCA0_UART
+ .include "MSP430FR57xx.inc"
+ .ENDIF ; JMJ_BOX
+
+ .IFDEF PA8_PA_MSP430
+ .warning "Code for PA8_PA_MSP430"
+DEVICE = "MSP430FR5738"
+UCA0_UART
+ .include "MSP430FR57xx.inc"
+ .ENDIF ; PA8_PA_MSP430
+
+ .IFDEF PA_PA_MSP430
+ .warning "Code for PA_PA_MSP430"
+DEVICE = "MSP430FR5738"
+UCA0_UART
+ .include "MSP430FR57xx.inc"
+ .ENDIF ; PA_PA_MSP430
+
+ .IFDEF PA_Core_MSP430
+ .warning "Code for PA_Core_MSP430"
+DEVICE = "MSP430FR5948"
+UCA0_UART
+ .include "MSP430FR5x6x.inc"
+ .ENDIF ; PA_Core_MSP430
+
+ .IF (charfromstr(DEVICE,8) = '5') & (charfromstr(DEVICE,9) = '7')
+RAM_1K
+ .ENDIF
\ No newline at end of file
--- /dev/null
+; TargetInit.asm
+ .IFDEF MSP_EXP430FR5739
+ .include "MSP_EXP430FR5739.asm"
+ .ENDIF
+ .IFDEF MSP_EXP430FR5969
+ .include "MSP_EXP430FR5969.asm"
+ .ENDIF
+ .IFDEF MSP_EXP430FR5994
+ .include "MSP_EXP430FR5994.asm"
+ .ENDIF
+ .IFDEF MSP_EXP430FR6989
+ .INCLUDE "MSP_EXP430FR6989.asm"
+ .ENDIF
+ .IFDEF MSP_EXP430FR4133
+ .INCLUDE "MSP_EXP430FR4133.asm"
+ .ENDIF
+ .IFDEF CHIPSTICK_FR2433
+ .include "CHIPSTICK_FR2433.asm"
+ .ENDIF
+ .IFDEF MY_MSP430FR5734
+ .include "MY_MSP430FR5738.asm"
+ .ENDIF
+ .IFDEF MY_MSP430FR5738
+ .include "MY_MSP430FR5738.asm"
+ .ENDIF
+ .IFDEF MY_MSP430FR5738_1
+ .include "MY_MSP430FR5738_1.asm"
+ .ENDIF
+ .IFDEF MY_MSP430FR5738_2
+ .include "MY_MSP430FR5738_2.asm"
+ .ENDIF
+ .IFDEF MY_MSP430FR5948
+ .include "MY_MSP430FR5948.asm"
+ .ENDIF
+ .IFDEF MY_MSP430FR5948_1
+ .include "MY_MSP430FR5948_1.asm"
+ .ENDIF
+ .IFDEF JMJ_BOX
+ .include "JMJ_BOX.asm"
+ .ENDIF
+ .IFDEF PA8_PA_MSP430
+ .include "PA8_PA_MSP430.asm"
+ .ENDIF
+ .IFDEF PA_PA_MSP430
+ .include "PA_PA_MSP430.asm"
+ .ENDIF
+ .IFDEF PA_Core_MSP430
+ .include "PA_Core_MSP430.asm"
+ .ENDIF
--- /dev/null
+!FastForthREGtoTI.pat
+! ============================================
+! translate Forth registers to TI's ones
+! ============================================
+
+PC=R0
+RSP=R1
+SR=R2
+rDODOES=R4
+rDOCON=R5
+rDOVAR=R6
+rEXIT=R7
+rDOCOL=R7
+R=R7
+Y=R8
+X=R9
+W=R10
+T=R11
+S=R12
+IP=R13
+TOS=R14
+PSP=R15
+
+! forth words filter
+U\.R=U\.R
+R\>=R\>
+\>R=\>R
+S\>D=S\>D
+S\<=S\<
+S\>\==S\>\=
+\.S=\.S
+\#S=\#S
+S\"=S\"
+!_R=_R
+!_S=_S
+!_T=_T
+!_W=_W
+!_X=_X
+!_Y=_Y
--- /dev/null
+!MSP430FR2433.pat
+
+@define{@read{/config/gema/MSP430FR2x4x.pat}}
+
+! ----------------------------------------------
+! MSP430FR2433 MEMORY MAP
+! ----------------------------------------------
+! 0000-0FFF = peripherals (4 KB)
+! 1000-17FF = ROM bootstrap loader BSL1 (2k)
+! 1800-19FF = info B (FRAM 512 B)
+! 1A00-1A7F = TLV device descriptor info (FRAM 128 B)
+! 1A80-1FFF = unused
+! 2000-2FFF = RAM (4 KB)
+! 2800-C3FF = unused
+! C400-FF7F = code memory (FRAM 15232 B)
+! FF80-FFFF = interrupt vectors (FRAM 128 B)
+! FFC00-FFFFF = BSL2 (2k)
+! ----------------------------------------------
+!PAGESIZE .equ 512 ; MPU unit
+! ----------------------------------------------
+! BSL
+! ----------------------------------------------
+BSL1=\$1000!
+BSL2=\$FFC00!
+! ----------------------------------------------
+! FRAM ; INFO B, TLV
+! ----------------------------------------------
+INFOSTART =\$1800!
+INFOBSTART=\$1800!
+INFOBEND=\$19FF!
+INFOEND=\$19FF!
+TLVSTART=\$1A00! Device Descriptor Info (Tag-Lenght-Value)
+TLVEND=\$1A7F!
+! ----------------------------------------------
+! RAM
+! ----------------------------------------------
+RAMSTART=\$2000!
+RAMEND=\$2FFF!
+! ----------------------------------------------
+! FRAM
+! ----------------------------------------------
+PROGRAMSTART=\$C400! Code space start
+SIGNATURES=\$FF80! JTAG/BSL signatures
+JTAG_SIG1=\$FF80! if 0 (electronic fuse=0) enable JTAG/SBW ; reset by wipe and by S1+<reset>
+JTAG_SIG2=\$FF82! if JTAG_SIG <> |\$FFFFFFFF, \$00000000|, SBW and JTAG are locked
+BSL_SIG1=\$FF84!
+BSL_SIG2=\$FF86!
+JTAG_PASSWORD=\$FF88! 256 bits
+INTVECT=\$FFDA! FFDA-FFFF
+BSL_PASSWORD=\$FFE0! 256 bits
+! ----------------------------------------------
+
+
+P2_Vec=\$FFDA!
+P1_Vec=\$FFDC!
+ADC10_B_Vec=\$FFDE!
+eUSCI_B0_Vec=\$FFE0!
+eUSCI_A1_Vec=\$FFE2!
+eUSCI_A0_Vec=\$FFE4!
+WDT_Vec=\$FFE6!
+RTC_Vec=\$FFE8!
+TA3_x_Vec=\$FFEA!
+TA3_0_Vec=\$FFEC!
+TA2_x_Vec=\$FFEE!
+TA2_0_Vec=\$FFF0!
+TA1_x_Vec=\$FFF2!
+TA1_0_Vec=\$FFF4!
+TA0_x_Vec=\$FFF6!
+TA0_0_Vec=\$FFF8!
+U_NMI_Vec=\$FFFA!
+S_NMI_Vec=\$FFFC!
+RST_Vec=\$FFFE!
+
+
+TA0CTL=\$380! \ TA0 control
+TA0CCTL0=\$382! \ Capture/compare control 0
+TA0CCTL1=\$384! \ Capture/compare control 1
+TA0CCTL2=\$386! \ Capture/compare control 2
+TA0R=\$390! \ TA0 counter register
+TA0CCR0=\$392! \ Capture/compare register 0
+TA0CCR1=\$394! \ Capture/compare register 1
+TA0CCR2=\$396! \ Capture/compare register 2
+TA0EX0=\$3A0! \ TA0 expansion register 0
+TA0IV=\$3AE! \ TA0 interrupt vector
+
+TA1CTL=\$3C0! \ TA1 control
+TA1CCTL0=\$3C2! \ Capture/compare control 0
+TA1CCTL1=\$3C4! \ Capture/compare control 1
+TA1CCTL2=\$3C6! \ Capture/compare control 2
+TA1R=\$3D0! \ TA1 counter register
+TA1CCR0=\$3D2! \ Capture/compare register 0
+TA1CCR1=\$3D4! \ Capture/compare register 1
+TA1CCR2=\$3D6! \ Capture/compare register 2
+TA1EX0=\$3E0! \ TA1 expansion register 0
+TA1IV=\$3EE! \ TA1 interrupt vector
+
+TA2CTL=\$400! \ TA2 control
+TA2CCTL0=\$402! \ Capture/compare control 0
+TA2CCTL1=\$404! \ Capture/compare control 1
+TA2R=\$410! \ TA2 counter register
+TA2CCR0=\$412! \ Capture/compare register 0
+TA2CCR1=\$414! \ Capture/compare register 1
+TA2EX0=\$420! \ TA2 expansion register 0
+TA2IV=\$42E! \ TA2 interrupt vector
+
+TA3CTL=\$440! \ TA3 control
+TA3CCTL0=\$442! \ Capture/compare control 0
+TA3CCTL1=\$444! \ Capture/compare control 1
+TA3R=\$450! \ TA3 counter register
+TA3CCR0=\$452! \ Capture/compare register 0
+TA3CCR1=\$454! \ Capture/compare register 1
+TA3EX0=\$460! \ TA3 expansion register 0
+TA3IV=\$46E! \ TA3 interrupt vector
+
--- /dev/null
+!MSP430FR2633.pat
+
+@define{@read{/config/gema/MSP430FR2x4x.pat}}
+
+! ----------------------------------------------
+! MSP430FR2633 MEMORY MAP
+! ----------------------------------------------
+! 0000-0FFF = peripherals (4 KB)
+! 1000-17FF = ROM bootstrap loader BSL1 (4x512 B)
+! 1800-187F = info B (FRAM 128 B)
+! 1880-18FF = info A (FRAM 128 B)
+! 1900-19FF = N/A (mirrored into info A/B)
+! 1A00-1A7F = TLV device descriptor info (FRAM 128 B)
+! 2000-2FFF = RAM (4 KB)
+! 4000-6FFF = ROM captivate (12 k)
+! C400-FF7F = code memory (FRAM 15232 B)
+! FF80-FFFF = interrupt vectors (FRAM 127 B)
+! ----------------------------------------------
+INFOSTART=\$1800!
+INFOBSTART=\$1800!
+INFOBEND=\$19FF!
+INFOEND=\$19FF!
+TLVSTAT=\$1A00! Device Descriptor Info (Tag-Lenght-Value)
+TLVEND=\$1A7F!
+RAMSTART=\$2000!
+RAMEND=\$2FFF!
+PROGRAMSTART=\$C400! Code space start
+SIGNATURES=\$FF80! JTAG/BSL signatures
+JTAG_SIG1=\$FF80! if 0 (electronic fuse=0) enable JTAG/SBW; must be reset by wipe.
+JTAG_SIG2=\$FF82! if JTAG_SIG1=\$AAAA, length of password string @ JTAG_PASSWORD
+BSL_SIG1=\$FF84!
+BSL_SIG2=\$FF86!
+JTAG_PASSWORD=\$FF88! 256 bits
+INTVECT=\$FFD8! FFD8-FFFF
+BSL_PASSWORD=\$FFE0! 256 bits
+
+
+CAPTIVATE_Vec=\$FFD8!
+P2_Vec=\$FFDA!
+P1_Vec=\$FFDC!
+ADC10_B_Vec=\$FFDE!
+eUSCI_B0_Vec=\$FFE0!
+eUSCI_A1_Vec=\$FFE2!
+eUSCI_A0_Vec=\$FFE4!
+WDT_Vec=\$FFE6!
+RTC_Vec=\$FFE8!
+TA3_x_Vec=\$FFEA!
+TA3_0_Vec=\$FFEC!
+TA2_x_Vec=\$FFEE!
+TA2_0_Vec=\$FFF0!
+TA1_x_Vec=\$FFF2!
+TA1_0_Vec=\$FFF4!
+TA0_x_Vec=\$FFF6!
+TA0_0_Vec=\$FFF8!
+U_NMI_Vec=\$FFFA!
+S_NMI_Vec=\$FFFC!
+RST_Vec=\$FFFE!
+
--- /dev/null
+!MSP430FR2xxx.pat
+
+LPM4=\$F8!
+LPM3=\$D8!
+LPM0=\$18!
+
+
+SFRIE1=\$100! \ SFR enable register
+SFRIFG1=\$102! \ SFR flag register
+SFRRPCR=\$104! \ SFR reset pin control
+
+PMMCTL0=\$120! \ PMM Control 0
+PMMCTL1=\$122! \ PMM Control 0
+PMMCTL2=\$124! \ PMM Control 0
+PMMIFG=\$12A! \ PMM interrupt flags
+PM5CTL0=\$130! \ PM5 Control 0
+
+SYSCTL=\$140! \ System control
+SYSBSLC=\$142! \ Bootstrap loader configuration area
+SYSJMBC=\$146! \ JTAG mailbox control
+SYSJMBI0=\$148! \ JTAG mailbox input 0
+SYSJMBI1=\$14A! \ JTAG mailbox input 1
+SYSJMBO0=\$14C! \ JTAG mailbox output 0
+SYSJMBO1=\$14E! \ JTAG mailbox output 1
+SYSBERRIV=\$158! \ Bus Error vector generator
+SYSUNIV=\$15A! \ User NMI vector generator
+SYSSNIV=\$15C! \ System NMI vector generator
+SYSRSTIV=\$15E! \ Reset vector generator
+SYSCFG0=\$160! \ System configuration 0
+SYSCFG1=\$162! \ System configuration 1
+SYSCFG2=\$164! \ System configuration 2
+
+CSCTL0=\$180! \ CS control 0
+CSCTL1=\$182! \ CS control 1
+CSCTL2=\$184! \ CS control 2
+CSCTL3=\$186! \ CS control 3
+CSCTL4=\$188! \ CS control 4
+CSCTL5=\$18A! \ CS control 5
+CSCTL6=\$18C! \ CS control 6
+
+FRCTLCTL0=\$1A0! \ FRAM control 0
+GCCTL0=\$1A4! \ General control 0
+GCCTL1=\$1A6! \ General control 1
+
+CRC16DI=\$1C0! \ CRC data input
+CRCDIRB=\$1C2! \ CRC data input reverse byte
+CRCINIRES=\$1C4! \ CRC initialization and result
+CRCRESR=\$1C6! \ CRC result reverse byte
+
+WDTCTL=\$1CC! \ WDT control register
+
+
+PAIN=\$200!
+PAOUT=\$202!
+PADIR=\$204!
+PAREN=\$206!
+PASEL0=\$20A!
+PASEL1=\$20C!
+P1IV=\$20E!
+PASELC=\$216!
+PAIES=\$218!
+PAIE=\$21A!
+PAIFG=\$21C!
+P2IV=\$21E!
+
+P1IN=\$200!
+P1OUT=\$202!
+P1DIR=\$204!
+P1REN=\$206!
+P1SEL0=\$20A!
+P1SEL1=\$20C!
+P1SELC=\$216!
+P1IES=\$218!
+P1IE=\$21A!
+P1IFG=\$21C!
+
+P2IN=\$201!
+P2OUT=\$203!
+P2DIR=\$205!
+P2REN=\$207!
+P2SEL0=\$20B!
+P2SEL1=\$20D!
+P2SELC=\$217!
+P2IES=\$218!
+P2IE=\$21B!
+P2IFG=\$21D!
+
+P3IN=\$220!
+P3OUT=\$222!
+P3DIR=\$224!
+P3REN=\$226!
+P3SEL0=\$22A!
+P3SEL1=\$22C!
+
+
+RTCCTL=\$300! \ RTC control
+RTCIV=\$304! \ RTC interrupt vector word
+RTCMOD=\$308! \ RTC modulo
+RTCCNT=\$30C! \ RTC counter register
+
+MPY=\$4C0! \ 16-bit operand 1 \96 multiply
+MPYS=\$4C2! \ 16-bit operand 1 \96 signed multiply
+MAC=\$4C4! \ 16-bit operand 1 \96 multiply accumulate
+MACS=\$4C6! \ 16-bit operand 1 \96 signed multiply accumulate
+OP2=\$4C8! \ 16-bit operand 2
+RESLO=\$4CA! \ 16 × 16 result low word
+RESHI=\$4CC! \ 16 × 16 result high word
+SUMEXT=\$4CE! \ 16 × 16 sum extension register
+MPY32L=\$4D0! \ 32-bit operand 1 \96 multiply low word
+MPY32H=\$4D2! \ 32-bit operand 1 \96 multiply high word
+MPYS32L=\$4D4! \ 32-bit operand 1 \96 signed multiply low word
+MPYS32H=\$4D6! \ 32-bit operand 1 \96 signed multiply high word
+MAC32L=\$4D8! \ 32-bit operand 1 \96 multiply accumulate low word
+MAC32H=\$4DA! \ 32-bit operand 1 \96 multiply accumulate high word
+MACS32L=\$4DC! \ 32-bit operand 1 \96 signed multiply accumulate low word
+MACS32H=\$4DE! \ 32-bit operand 1 \96 signed multiply accumulate high word
+OP2L=\$4E0! \ 32-bit operand 2 \96 low word
+OP2H=\$4E2! \ 32-bit operand 2 \96 high word
+RES0=\$4E4! \ 32 × 32 result 0 \96 least significant word
+RES1=\$4E6! \ 32 × 32 result 1
+RES2=\$4E8! \ 32 × 32 result 2
+RES3=\$4EA! \ 32 × 32 result 3 \96 most significant word
+MPY32CTL0=\$4EC! \ MPY32 control register 0
+
+
+
+UCA0CTLW0=\$500! \ eUSCI_A control word 0
+UCA0CTLW1=\$502! \ eUSCI_A control word 1
+UCA0BRW=\$506!
+UCA0BR0=\$506! \ eUSCI_A baud rate 0
+UCA0BR1=\$507! \ eUSCI_A baud rate 1
+UCA0MCTLW=\$508! \ eUSCI_A modulation control
+UCA0STAT=\$50A! \ eUSCI_A status
+UCA0RXBUF=\$50C! \ eUSCI_A receive buffer
+UCA0TXBUF=\$50E! \ eUSCI_A transmit buffer
+UCA0ABCTL=\$510! \ eUSCI_A LIN control
+UCA0IRTCTL=\$512! \ eUSCI_A IrDA transmit control
+UCA0IRRCTL=\$513! \ eUSCI_A IrDA receive control
+UCA0IE=\$51A! \ eUSCI_A interrupt enable
+UCA0IFG=\$51C! \ eUSCI_A interrupt flags
+UCA0IV=\$51E! \ eUSCI_A interrupt vector word
+
+UCA1CTLW0=\$520! \ eUSCI_A control word 0
+UCA1CTLW1=\$522! \ eUSCI_A control word 1
+UCA1BRW=\$526!
+UCA1BR0=\$526! \ eUSCI_A baud rate 0
+UCA1BR1=\$527! \ eUSCI_A baud rate 1
+UCA1MCTLW=\$528! \ eUSCI_A modulation control
+UCA1STAT=\$52A! \ eUSCI_A status
+UCA1RXBUF=\$52C! \ eUSCI_A receive buffer
+UCA1TXBUF=\$52E! \ eUSCI_A transmit buffer
+UCA1ABCTL=\$530! \ eUSCI_A LIN control
+UCA1IRTCTL=\$532! \ eUSCI_A IrDA transmit control
+UCA1IRRCTL=\$533! \ eUSCI_A IrDA receive control
+UCA1IE=\$53A! \ eUSCI_A interrupt enable
+UCA1IFG=\$53C! \ eUSCI_A interrupt flags
+UCA1IV=\$53E! \ eUSCI_A interrupt vector word
+
+
+UCB0CTLW0=\$540! \ eUSCI_B control word 0
+UCB0CTLW1=\$542! \ eUSCI_B control word 1
+UCB0BRW=\$546!
+UCB0BR0=\$546! \ eUSCI_B bit rate 0
+UCB0BR1=\$547! \ eUSCI_B bit rate 1
+UCB0STATW=\$548! \ eUSCI_B status word
+UCBCNT0=\$549! \ eUSCI_B hardware count
+UCB0TBCNT=\$54A! \ eUSCI_B byte counter threshold
+UCB0RXBUF=\$54C! \ eUSCI_B receive buffer
+UCB0TXBUF=\$54E! \ eUSCI_B transmit buffer
+UCB0I2COA0=\$554! \ eUSCI_B I2C own address 0
+UCB0I2COA1=\$556! \ eUSCI_B I2C own address 1
+UCB0I2COA2=\$558! \ eUSCI_B I2C own address 2
+UCB0I2COA3=\$55A! \ eUSCI_B I2C own address 3
+UCB0ADDRX=\$55C! \ eUSCI_B received address
+UCB0ADDMASK=\$55E! \ eUSCI_B address mask
+UCB0I2CSA=\$560! \ eUSCI I2C slave address
+UCB0IE=\$56A! \ eUSCI interrupt enable
+UCB0IFG=\$56C! \ eUSCI interrupt flags
+UCB0IV=\$56E! \ eUSCI interrupt vector word
+
+UCTXACK=\$20!
+UCTR=\$10!
+
+LCDCTL0=\$600! \ LCD control register 0
+LCDCTL1=\$602! \ LCD control register 1
+LCDBLKCTL=\$604! \ LCD blink control register
+LCDMEMCTL=\$606! \ LCD memory control register
+LCDVCTL=\$608! \ LCD voltage control register
+LCDPCTL0=\$60A! \ LCD port control 0
+LCDPCTL1=\$60C! \ LCD port control 1
+LCDPCTL2=\$60E! \ LCD port control 2
+LCDCSS0=\$614! \ LCD COM/SEG select register
+LCDCSS1=\$616! \ LCD COM/SEG select register
+LCDCSS2=\$618! \ LCD COM/SEG select register
+LCDIV=\$61E! \ LCD interrupt vector
+LCDM0=\$620! \ LCD memory 0
+LCDM1=\$621! \ LCD memory 1
+LCDM2=\$622! \ LCD memory 2
+LCDM3=\$623! \ LCD memory 3
+LCDM4=\$624! \ LCD memory 4
+LCDM5=\$625! \ LCD memory 5
+LCDM6=\$626! \ LCD memory 6
+LCDM7=\$627! \ LCD memory 7
+LCDM8=\$628! \ LCD memory 8
+LCDM9=\$629! \ LCD memory 9
+LCDM10=\$62A! \ LCD memory 10
+LCDM11=\$62B! \ LCD memory 11
+LCDM12=\$62C! \ LCD memory 12
+LCDM13=\$62D! \ LCD memory 13
+LCDM14=\$62E! \ LCD memory 14
+LCDM15=\$62F! \ LCD memory 15
+LCDM16=\$630! \ LCD memory 16
+LCDM17=\$631! \ LCD memory 17
+LCDM18=\$632! \ LCD memory 18
+LCDM19=\$633! \ LCD memory 19
+LCDM20=\$634! \ LCD memory 20
+LCDM21=\$635! \ LCD memory 21
+LCDM22=\$636! \ LCD memory 22
+LCDM23=\$637! \ LCD memory 23
+LCDM24=\$638! \ LCD memory 24
+LCDM25=\$639! \ LCD memory 25
+LCDM26=\$63A! \ LCD memory 26
+LCDM27=\$63B! \ LCD memory 27
+LCDM28=\$63C! \ LCD memory 28
+LCDM29=\$63D! \ LCD memory 29
+LCDM30=\$63E! \ LCD memory 30
+LCDM31=\$63F! \ LCD memory 31
+LCDM32=\$640! \ LCD memory 32
+LCDM33=\$641! \ LCD memory 33
+LCDM34=\$642! \ LCD memory 34
+LCDM35=\$643! \ LCD memory 35
+LCDM36=\$644! \ LCD memory 36
+LCDM37=\$645! \ LCD memory 37
+LCDM38=\$646! \ LCD memory 38
+LCDM39=\$647! \ LCD memory 39
+LCDBM0=\$640! \ LCD blinking memory 0
+LCDBM1=\$641! \ LCD blinking memory 1
+LCDBM2=\$642! \ LCD blinking memory 2
+LCDBM3=\$643! \ LCD blinking memory 3
+LCDBM4=\$644! \ LCD blinking memory 4
+LCDBM5=\$645! \ LCD blinking memory 5
+LCDBM6=\$646! \ LCD blinking memory 6
+LCDBM7=\$647! \ LCD blinking memory 7
+LCDBM8=\$648! \ LCD blinking memory 8
+LCDBM9=\$649! \ LCD blinking memory 9
+LCDBM10=\$64A! \ LCD blinking memory 10
+LCDBM11=\$64B! \ LCD blinking memory 11
+LCDBM12=\$64C! \ LCD blinking memory 12
+LCDBM13=\$64D! \ LCD blinking memory 13
+LCDBM14=\$64E! \ LCD blinking memory 14
+LCDBM15=\$64F! \ LCD blinking memory 15
+LCDBM16=\$650! \ LCD blinking memory 16
+LCDBM17=\$651! \ LCD blinking memory 17
+LCDBM18=\$652! \ LCD blinking memory 18
+LCDBM19=\$653! \ LCD blinking memory 19
+
+
+BAKMEM0=\$660! \ Backup Memory 0
+BAKMEM1=\$662! \ Backup Memory 1
+BAKMEM2=\$664! \ Backup Memory 2
+BAKMEM3=\$666! \ Backup Memory 3
+BAKMEM4=\$668! \ Backup Memory 4
+BAKMEM5=\$66A! \ Backup Memory 5
+BAKMEM6=\$66C! \ Backup Memory 6
+BAKMEM7=\$66E! \ Backup Memory 7
+BAKMEM8=\$670! \ Backup Memory 8
+BAKMEM9=\$672! \ Backup Memory 9
+BAKMEM10=\$674! \ Backup Memory 10
+BAKMEM11=\$676! \ Backup Memory 11
+BAKMEM12=\$678! \ Backup Memory 12
+BAKMEM13=\$67A! \ Backup Memory 13
+BAKMEM14=\$67C! \ Backup Memory 14
+BAKMEM15=\$67E! \ Backup Memory 15
+
+
+ADC10CTL0=\$700! \ ADC10_B Control register 0
+ADC10CTL1=\$702! \ ADC10_B Control register 1
+ADC10CTL2=\$704! \ ADC10_B Control register 2
+ADC10LO=\$706! \ ADC10_B Window Comparator Low Threshold
+ADC10HI=\$708! \ ADC10_B Window Comparator High Threshold
+ADC10MCTL0=\$70A! \ ADC10_B Memory Control Register 0
+ADC10MEM0=\$712! \ ADC10_B Conversion Memory Register
+ADC10IE=\$71A! \ ADC10_B Interrupt Enable
+ADC10IFG=\$71C! \ ADC10_B Interrupt Flags
+ADC10IV=\$71E! \ ADC10_B Interrupt Vector Word
+
+ADCON=\$10!
+ADCSTART=\$03!
+
--- /dev/null
+!MSP430FR2x4x_FastForth.pat
+
+! ===========================================================
+! MSP430FR2xxx and FR4xxx DEVICES HAVE SPECIFIC RAM ADDRESSES
+! ===========================================================
+
+
+! ================================================
+! SR bits : only SR(11:0) are PUSHed by interrupts
+! ================================================
+\#C=\#1! = SR(0) Carry flag
+\#Z=\#2! = SR(1) Zero flag
+\#N=\#4! = SR(2) Negative flag
+GIE=8! = SR(3) Enable Int
+CPUOFF=\$10! = SR(4) CPUOFF
+OSCOFF=\$20! = SR(5) OSCOFF
+SCG0=\$40! = SR(6) SCG0
+SCG1=\$80! = SR(7) SCG1
+V=\$100! = SR(8) oVerflow flag
+UF1=\$200! = SR(9) User Flag 1 used by ?NUMBER --> INTERPRET --> LITERAL to process double numbers, else free for use.
+UF2=\$400! = SR(10) User Flag 2
+UF3=\$800! = SR(11) User Flag 3
+
+C\@=C\@
+C\!=C\!
+C\,=C\,
+
+! ============================================
+! PORTx, Reg bits :
+! ============================================
+BIT0=1!
+BIT1=2!
+BIT2=4!
+BIT3=8!
+BIT4=\$10!
+BIT5=\$20!
+BIT6=\$40!
+BIT7=\$80!
+BIT8=\$100!
+BIT9=\$200!
+BIT10=\$400!
+BIT11=\$800!
+BIT12=\$1000!
+BIT13=\$2000!
+BIT14=\$4000!
+BIT15=\$8000!
+
+! ============================================
+! symbolic codes :
+! ============================================
+RET=MOV \@R1+,R0!
+NOP=MOV 0,R3! \ one word one cycle
+NOP2=\$3C00 ,! \ compile JMP 0: one word two cycles
+NOP3=MOV R0,R0! \ one word three cycles
+NEXT=MOV \@R13+,R0!
+
+
+
+! You can check the addresses below by comparing their values in DTCforthMSP430FRxxxx.lst
+! those addresses are usable with the symbolic assembler
+
+! ============================================
+! FastForth INFO(DCBA) memory map (256 bytes):
+! ============================================
+
+! ----------------------
+! KERNEL CONSTANTS
+! ----------------------
+INI_THREAD=\$1800! .word THREADS
+TERMINAL_INT=\$1802! .word TERMINAL_INT
+FREQ_KHZ=\$1804! .word FREQUENCY*1000
+HECTOBAUDS=\$1806! .word TERMINALBAUDRATE/100
+! ----------------------
+! SAVED VARIABLES
+! ----------------------
+SAVE_SYSRSTIV=\$1808! to enable SYSRSTIV read
+LPM_MODE=\$180A! LPM0+GIE is the default mode
+INIDP=\$180C! define RST_STATE, init by wipe
+INIVOC=\$180E! define RST_STATE, init by wipe
+
+XON=\$1810!
+XOFF=\$1812!
+
+ReadSectorWX=\$1814! call with W = SectorLO X = SectorHI
+WriteSectorWX=\$1816! call with W = SectorLO X = SectorHI
+
+
+! ============================================
+! FastForth RAM memory map (>= 1k):
+! ============================================
+LSATCK=\$2000! \ leave stack, grow up
+PSTACK=\$2080! \ parameter stack, grow down
+RSTACK=\$20E0! \ Return stack, grow down
+PAD=\$20E2! \ user scratch pad buffer, grow up
+TIB=\$2138! \ Terminal input buffer, grow up
+BASE_HOLD=\$21AA! \ BASE HOLD area, grow down
+
+! ----------------------
+! NOT SAVED VARIABLES
+! ----------------------
+
+HP=\$21AA! HOLD ptr
+LEAVEPTR=\$21AC! Leave-stack pointer, init by QUIT
+
+LAST_NFA=\$21AE!
+LAST_THREAD=\$21B0!
+LAST_CFA=\$21B2!
+LAST_CSP=\$21B4!
+
+STATE=\$21B6! Interpreter state
+
+ASM_CURRENT=\$21B8! preserve CURRENT when create assembler words
+OPCODE=\$21BA! OPCODE adr
+ASMTYPE=\$21BC! keep the opcode complement
+
+SOURCE_LEN=\$21BE! len of input stream
+SOURCE_ADR=\$21C0! adr of input stream
+\>IN=\$21C2! >IN
+DP=\$21C4! dictionary ptr
+LASTVOC=\$21C6! keep VOC-LINK
+CURRENT=\$21C8! CURRENT dictionnary ptr
+CONTEXT=\$21CA! CONTEXT dictionnary space (8 CELLS)
+
+BASE=\$21DA! numeric base, must be defined before first reset !
+CAPS=\$21DC! CAPS ON/OFF flag, must be set to -1 before first reset !
+
+
+BUFFER=\$2200! \ SD_Card buffer
+BUFEND=\$2400!
+
+! ---------------------------------------
+! FAT16 FileSystemInfos
+! ---------------------------------------
+FATtype=\$2402!
+BS_FirstSectorL=\$2404!
+BS_FirstSectorH=\$2406!
+OrgFAT1=\$2408!
+FATSize=\$240A!
+OrgFAT2=\$240C!
+OrgRootDir=\$240E!
+OrgClusters=\$2410! Sector of Cluster 0
+SecPerClus=\$2412!
+
+! ---------------------------------------
+! SD command
+! ---------------------------------------
+SD_CMD_FRM=\$2414! 6 bytes SD_CMDx inverted frame \${CRC,ll,LL,hh,HH,CMD}
+SD_CMD_FRM0=\$2414! CRC:ll word access
+SD_CMD_FRM1=\$2415! ll byte access
+SD_CMD_FRM2=\$2416! LL:hh word access
+SD_CMD_FRM3=\$2417! hh byte access
+SD_CMD_FRM4=\$2418! HH:CMD word access
+SD_CMD_FRM5=\$2419! CMD byte access
+SectorL=\$241A! 2 words
+SectorH=\$241C!
+
+! ---------------------------------------
+! BUFFER management
+! ---------------------------------------
+BufferPtr=\$241E!
+BufferLen=\$2420!
+
+! ---------------------------------------
+! FAT entry
+! ---------------------------------------
+ClusterL=\$2422! 16 bits wide (FAT16)
+ClusterH=\$2424! 16 bits wide (FAT16)
+NewClusterL=\$2426! 16 bits wide (FAT16)
+NewClusterH=\$2428! 16 bits wide (FAT16)
+FATsector=\$242A! not used
+CurFATsector=\$242C!
+
+! ---------------------------------------
+! DIR entry
+! ---------------------------------------
+DIRclusterL=\$242E! contains the Cluster of current directory ; 1 if FAT16 root directory
+DIRclusterH=\$2430! contains the Cluster of current directory ; 1 if FAT16 root directory
+EntryOfst=\$2432!
+pathname=\$2434! address of pathname string
+
+! ---------------------------------------
+! Handle Pointer
+! ---------------------------------------
+CurrentHdl=\$2436! contains the address of the last opened file structure, or 0
+
+! ---------------------------------------
+! Load file operation
+! ---------------------------------------
+SAVEtsLEN=\$2438! of previous ACCEPT
+SAVEtsPTR=\$243A! of previous ACCEPT
+MemSectorL=\$243C! double word current Sector of previous LOAD"ed file
+MemSectorH=\$243E!
+
+! ---------------------------------------
+! Handle structure
+! ---------------------------------------
+! three handle tokens :
+! token = 0 : free handle
+! token = 1 : file to read
+! token = 2 : file updated (write)
+! token =-1 : LOAD"ed file (source file)
+
+! offset values
+HDLW_PrevHDL=0! previous handle ; used by LOAD"
+HDLB_Token=2! token
+HDLB_ClustOfst=3! Current sector offset in current cluster (Byte)
+HDLL_DIRsect=4! Dir SectorL (Long)
+HDLH_DIRsect=6!
+HDLW_DIRofst=8! BUFFER offset of Dir entry
+HDLL_FirstClus=10! File First ClusterLo (identify the file)
+HDLH_FirstClus=12! File First ClusterHi (byte)
+HDLL_CurClust=14! Current ClusterLo
+HDLH_CurClust=16! Current ClusterHi (T as 3Th byte)
+HDLL_CurSize=18! written size / not yet read size (Long)
+HDLH_CurSize=20! written size / not yet read size (Long)
+HDLW_BUFofst=22! BUFFER offset ; used by LOAD" and by WRITE"
+
+HandleMax=8!
+HandleLenght=24!
+
+!OpenedFirstFile ; "openedFile" structure
+FirstHandle=\$2440!
+HandleOutOfBound=\$2500!
+
+SDIB=\$2500!
\ No newline at end of file
--- /dev/null
+!MSP430FR4133.pat
+
+@define{@read{/config/gema/MSP430FR2x4x.pat}}
+
+! ----------------------------------------------
+! MSP430FR5739 MEMORY MAP
+! ----------------------------------------------
+! 0000-0FFF = peripherals (4 KB)
+! 1000-17FF = ROM bootstrap loader BSL0..3 (4x512 B)
+! 1800-187F = info B (FRAM 128 B)
+! 1880-18FF = info A (FRAM 128 B)
+! 1900-19FF = N/A (mirrored into info A/B)
+! 1A00-1A7F = TLV device descriptor info (FRAM 128 B)
+! 1A80-1BFF = unused (385 B)
+! 1C00-1FFF = RAM (1 KB)
+! 2000-C1FF = unused (41472 B)
+! C400-FF7F = code memory (FRAM 15232 B)
+! FF80-FFFF = interrupt vectors (FRAM 127 B)
+! ----------------------------------------------
+INFOSTART=\$1800!
+INFOBSTART=\$1800!
+INFOBEND=\$19FF!
+INFOEND=\$19FF!
+TLVSTAT=\$1A00! Device Descriptor Info (Tag-Lenght-Value)
+TLVEND=\$1A7F!
+RAMSTART=\$2000!
+RAMEND=\$27FF!
+PROGRAMSTART=\$C400! Code space start
+SIGNATURES=\$FF80! JTAG/BSL signatures
+JTAG_SIG1=\$FF80! if 0 (electronic fuse=0) enable JTAG/SBW; must be reset by wipe.
+JTAG_SIG2=\$FF82! if JTAG_SIG1=\$AAAA, length of password string @ JTAG_PASSWORD
+BSL_SIG1=\$FF84!
+BSL_SIG2=\$FF86!
+JTAG_PASSWORD=\$FF88! 256 bits
+INTVECT=\$FFE2! FFE2-FFFF
+BSL_PASSWORD=\$FFE0! 256 bits
+
+
+LCD_Vec=\$FFE2!
+P2_Vec=\$FFE4!
+P1_Vec=\$FFE6!
+ADC10_B_Vec=\$FFE8!
+eUSCI_B0_Vec=\$FFEA!
+eUSCI_A0_Vec=\$FFEC!
+WDT_Vec=\$FFEE!
+RTC_Vec=\$FFF0!
+TA1_x_Vec=\$FFF2!
+TA1_0_Vec=\$FFF4!
+TA0_x_Vec=\$FFF6!
+TA0_0_Vec=\$FFF8!
+U_NMI_Vec=\$FFFA!
+S_NMI_Vec=\$FFFC!
+RST_Vec=\$FFFE!
+
+TA0CTL=\$300! \ TA0 control
+TA0CCTL0=\$302! \ Capture/compare control 0
+TA0CCTL1=\$304! \ Capture/compare control 1
+TA0CCTL2=\$306! \ Capture/compare control 2
+TA0R=\$310! \ TA0 counter register
+TA0CCR0=\$312! \ Capture/compare register 0
+TA0CCR1=\$314! \ Capture/compare register 1
+TA0CCR2=\$316! \ Capture/compare register 2
+TA0EX0=\$320! \ TA0 expansion register 0
+TA0IV=\$32E! \ TA0 interrupt vector
+
+TA1CTL=\$340! \ TA1 control
+TA1CCTL0=\$342! \ Capture/compare control 0
+TA1CCTL1=\$344! \ Capture/compare control 1
+TA1CCTL2=\$346! \ Capture/compare control 2
+TA1R=\$350! \ TA1 counter register
+TA1CCR0=\$352! \ Capture/compare register 0
+TA1CCR1=\$354! \ Capture/compare register 1
+TA1CCR2=\$356! \ Capture/compare register 2
+TA1EX0=\$360! \ TA1 expansion register 0
+TA1IV=\$36E! \ TA1 interrupt vector
+
--- /dev/null
+!MSP430fr5738.pat
+
+@define{@read{/config/gema/MSP430FR57xx.pat}}
+
+
+! ----------------------------------------------
+! MSP430FR5738 MEMORY MAP
+! ----------------------------------------------
+! 0000-0FFF = peripherals (4 KB)
+! 1000-17FF = ROM bootstrap loader BSL0..3 (4x512 B)
+! 1800-187F = info B (FRAM 128 B)
+! 1880-18FF = info A (FRAM 128 B)
+! 1900-19FF = N/A (mirrored into info A/B)
+! 1A00-1A7F = TLV device descriptor info (FRAM 128 B)
+! 1A80-1BFF = unused (385 B)
+! 1C00-1FFF = RAM (1 KB)
+! 2000-C1FF = unused (41472 B)
+! C200-FF7F = code memory (FRAM 15743 B)
+! FF80-FFFF = interrupt vectors (FRAM 127 B)
+! ----------------------------------------------
+INFOSTART=\$1800!
+INFOBSTART=\$1800!
+INFOBEND=\$187F!
+INFOASTART=\$1880!
+INFOAEND=\$18FF!
+TLVSTAT=\$1A00! Device Descriptor Info (Tag-Lenght-Value)
+TLVEND=\$1A7F!
+RAMSTART=\$1C00!
+RAMEND=\$1FFF!
+PROGRAMSTART=\$C200! Code space start
+SIGNATURES=\$FF80! JTAG/BSL signatures
+JTAG_SIG1=\$FF80! if 0 (electronic fuse=0) enable JTAG/SBW; must be reset by wipe.
+JTAG_SIG2=\$FF82! if JTAG_SIG1=\$AAAA, length of password string @ JTAG_PASSWORD
+BSL_SIG1=\$FF84!
+BSL_SIG2=\$FF86!
+JTAG_PASSWORD=\$FF88! 256 bits
+INTVECT=\$FFCE! FFCE-FFFF
+BSL_PASSWORD=\$FFE0! 256 bits
+
+
+RTC_Vec=\$FFCE!
+P4_Vec=\$FFD0!
+P3_Vec=\$FFD2!
+TB2_x_Vec=\$FFD4!
+TB2_0_Vec=\$FFD6!
+P2_Vec=\$FFD8!
+TB1_x_Vec=\$FFDA!
+TB1_0_Vec=\$FFDC!
+P1_Vec=\$FFDE!
+TA1_x_Vec=\$FFE0!
+TA1_0_Vec=\$FFE2!
+DMA_Vec=\$FFE4!
+!eUSCI_A1_Vec=\$FFE6!
+TA0_x_Vec=\$FFE8!
+TA0_0_Vec=\$FFEA!
+ADC10_B_Vec=\$FFEC!
+eUSCI_B0_Vec=\$FFEE!
+eUSCI_A0_Vec=\$FFF0!
+TERM_Vec=\$FFF0!
+WDT_Vec=\$FFF2!
+TB0_x_Vec=\$FFF4!
+TB0_0_Vec=\$FFF6!
+COMP_D_Vec=\$FFF8!
+USER_NMI_Vec=\$FFFA!
+SYS_NMI_Vec=\$FFFC!
+RST_Vec=\$FFFE!
+
--- /dev/null
+!MSP430fr5739.pat
+
+@define{@read{/config/gema/MSP430FR57xx.pat}}
+
+
+! ----------------------------------------------
+! MSP430FR5739 MEMORY MAP
+! ----------------------------------------------
+! 0000-0FFF = peripherals (4 KB)
+! 1000-17FF = ROM bootstrap loader BSL0..3 (4x512 B)
+! 1800-187F = info B (FRAM 128 B)
+! 1880-18FF = info A (FRAM 128 B)
+! 1900-19FF = N/A (mirrored into info A/B)
+! 1A00-1A7F = TLV device descriptor info (FRAM 128 B)
+! 1A80-1BFF = unused (385 B)
+! 1C00-1FFF = RAM (1 KB)
+! 2000-C1FF = unused (41472 B)
+! C200-FF7F = code memory (FRAM 15743 B)
+! FF80-FFFF = interrupt vectors (FRAM 127 B)
+! ----------------------------------------------
+INFOSTART=\$1800!
+INFOBSTART=\$1800!
+INFOBEND=\$187F!
+INFOASTART=\$1880!
+INFOAEND=\$18FF!
+TLVSTAT=\$1A00! Device Descriptor Info (Tag-Lenght-Value)
+TLVEND=\$1A7F!
+RAMSTART=\$1C00!
+RAMEND=\$1FFF!
+PROGRAMSTART=\$C200! Code space start
+SIGNATURES=\$FF80! JTAG/BSL signatures
+JTAG_SIG1=\$FF80! if 0 (electronic fuse=0) enable JTAG/SBW; must be reset by wipe.
+JTAG_SIG2=\$FF82! if JTAG_SIG1=\$AAAA, length of password string @ JTAG_PASSWORD
+BSL_SIG1=\$FF84!
+BSL_SIG2=\$FF86!
+JTAG_PASSWORD=\$FF88! 256 bits
+INTVECT=\$FFCE! FFCE-FFFF
+BSL_PASSWORD=\$FFE0! 256 bits
+
+
+RTC_Vec=\$FFCE!
+P4_Vec=\$FFD0!
+P3_Vec=\$FFD2!
+TB2_x_Vec=\$FFD4!
+TB2_0_Vec=\$FFD6!
+P2_Vec=\$FFD8!
+TB1_x_Vec=\$FFDA!
+TB1_0_Vec=\$FFDC!
+P1_Vec=\$FFDE!
+TA1_x_Vec=\$FFE0!
+TA1_0_Vec=\$FFE2!
+DMA_Vec=\$FFE4!
+eUSCI_A1_Vec=\$FFE6!
+TA0_x_Vec=\$FFE8!
+TA0_0_Vec=\$FFEA!
+ADC10_B_Vec=\$FFEC!
+eUSCI_B0_Vec=\$FFEE!
+eUSCI_A0_Vec=\$FFF0!
+WDT_Vec=\$FFF2!
+TB0_x_Vec=\$FFF4!
+TB0_0_Vec=\$FFF6!
+COMP_D_Vec=\$FFF8!
+U_NMI_Vec=\$FFFA!
+S_NMI_Vec=\$FFFC!
+RST_Vec=\$FFFE!
+
--- /dev/null
+!MSP430fr57xx.pat
+
+\#LPM4,=\#\$F8,!
+\#LPM3,=\#\$D8,!
+\#LPM2,=\#\$98,!
+\#LPM1,=\#\$58,!
+\#LPM0,=\#\$18,!
+
+
+
+SFRIE1=\$100! \ SFR enable register
+SFRIFG1=\$102! \ SFR flag register
+SFRRPCR=\$104! \ SFR reset pin control
+
+PMMCTL0=\$120! \ PMM Control 0
+PMMIFG=\$12A! \ PMM interrupt flags
+PM5CTL0=\$130! \ PM5 Control 0
+
+FRCTLCTL0=\$140! \ FRAM control 0
+GCCTL0=\$144! \ General control 0
+GCCTL1=\$146! \ General control 1
+
+CRC16DI=\$150! \ CRC data input
+CRCDIRB=\$152! \ CRC data input reverse byte
+CRCINIRES=\$154! \ CRC initialization and result
+CRCRESR=\$156! \ CRC result reverse byte
+
+WDTCTL=\$15C! \ WDT control register
+
+CSCTL0=\$160! \ CS control 0
+CSCTL0_H=\$161! \
+CSCTL1=\$162! \ CS control 1
+CSCTL2=\$164! \ CS control 2
+CSCTL3=\$166! \ CS control 3
+CSCTL4=\$168! \ CS control 4
+CSCTL5=\$16A! \ CS control 5
+CSCTL6=\$16C! \ CS control 6
+
+SYSCTL=\$180! \ System control
+SYSJMBC=\$186! \ JTAG mailbox control
+SYSJMBI0=\$188! \ JTAG mailbox input 0
+SYSJMBI1=\$18A! \ JTAG mailbox input 1
+SYSJMBO0=\$18C! \ JTAG mailbox output 0
+SYSJMBO1=\$18E! \ JTAG mailbox output 1
+SYSBERRIV=\$198! \ Bus Error vector generator
+SYSUNIV=\$19A! \ User NMI vector generator
+SYSSNIV=\$19C! \ System NMI vector generator
+SYSRSTIV=\$19E! \ Reset vector generator
+
+REFCTL=\$1b0! \ Shared reference control
+
+PAIN=\$200!
+PAOUT=\$202!
+PADIR=\$204!
+PAREN=\$206!
+PASEL0=\$20A!
+PASEL1=\$20C!
+P1IV=\$20E!
+PASELC=\$216!
+PAIES=\$218!
+PAIE=\$21A!
+PAIFG=\$21C!
+P2IV=\$21E!
+
+P1IN=\$200!
+P1OUT=\$202!
+P1DIR=\$204!
+P1REN=\$206!
+P1SEL0=\$20A!
+P1SEL1=\$20C!
+P1SELC=\$216!
+P1IES=\$218!
+P1IE=\$21A!
+P1IFG=\$21C!
+
+P2IN=\$201!
+P2OUT=\$203!
+P2DIR=\$205!
+P2REN=\$207!
+P2SEL0=\$20B!
+P2SEL1=\$20D!
+P2SELC=\$217!
+P2IES=\$218!
+P2IE=\$21B!
+P2IFG=\$21D!
+
+PBIN=\$220!
+PBOUT=\$222!
+PBDIR=\$224!
+PBREN=\$226!
+PBSEL0=\$22A!
+PBSEL1=\$22C!
+P3IV=\$22E!
+PBSELC=\$236!
+PBIES=\$238!
+PBIE=\$23A!
+PBIFG=\$23C!
+P4IV=\$23E!
+
+P3IN=\$220!
+P3OUT=\$222!
+P3DIR=\$224!
+P3REN=\$226!
+P3SEL0=\$22A!
+P3SEL1=\$22C!
+P3SELC=\$236!
+P3IES=\$238!
+P3IE=\$23A!
+P3IFG=\$23C!
+
+P4IN=\$221!
+P4OUT=\$223!
+P4DIR=\$225!
+P4REN=\$227!
+P4SEL0=\$22B!
+P4SEL1=\$22D!
+P4SELC=\$237!
+P4IES=\$238!
+P4IE=\$23B!
+P4IFG=\$23D!
+
+PJIN=\$320!
+PJOUT=\$322!
+PJDIR=\$324!
+PJREN=\$326!
+PJSEL0=\$32A!
+PJSEL1=\$32C!
+PJSELC=\$336!
+
+TA0CTL=\$340! \ TA0 control
+TA0CCTL0=\$342! \ Capture/compare control 0
+TA0CCTL1=\$344! \ Capture/compare control 1
+TA0CCTL2=\$346! \ Capture/compare control 2
+TA0R=\$350! \ TA0 counter register
+TA0CCR0=\$352! \ Capture/compare register 0
+TA0CCR1=\$354! \ Capture/compare register 1
+TA0CCR2=\$356! \ Capture/compare register 2
+TA0EX0=\$360! \ TA0 expansion register 0
+TA0IV=\$36E! \ TA0 interrupt vector
+
+TA1CTL=\$380! \ TA1 control
+TA1CCTL0=\$382! \ Capture/compare control 0
+TA1CCTL1=\$384! \ Capture/compare control 1
+TA1CCTL2=\$386! \ Capture/compare control 2
+TA1R=\$390! \ TA1 counter register
+TA1CCR0=\$392! \ Capture/compare register 0
+TA1CCR1=\$394! \ Capture/compare register 1
+TA1CCR2=\$396! \ Capture/compare register 2
+TA1EX0=\$3A0! \ TA1 expansion register 0
+TA1IV=\$3AE! \ TA1 interrupt vector
+
+TB0CTL=\$3C0! \ TB0 control
+TB0CCTL0=\$3C2! \ Capture/compare control 0
+TB0CCTL1=\$3C4! \ Capture/compare control 1
+TB0CCTL2=\$3C6! \ Capture/compare control 2
+TB0R=\$3D0! \ TB0 counter register
+TB0CCR0=\$3D2! \ Capture/compare register 0
+TB0CCR1=\$3D4! \ Capture/compare register 1
+TB0CCR2=\$3D6! \ Capture/compare register 2
+TB0EX0=\$3E0! \ TB0 expansion register 0
+TB0IV=\$3EE! \ TB0 interrupt vector
+
+TB1CTL=\$400! \ TB1 control
+TB1CCTL0=\$402! \ Capture/compare control 0
+TB1CCTL1=\$404! \ Capture/compare control 1
+TB1CCTL2=\$406! \ Capture/compare control 2
+TB1R=\$410! \ TB1 counter register
+TB1CCR0=\$412! \ Capture/compare register 0
+TB1CCR1=\$414! \ Capture/compare register 1
+TB1CCR2=\$416! \ Capture/compare register 2
+TB1EX0=\$420! \ TB1 expansion register 0
+TB1IV=\$42E! \ TB1 interrupt vector
+
+TB2CTL=\$440! \ TB2 control
+TB2CCTL0=\$442! \ Capture/compare control 0
+TB2CCTL1=\$444! \ Capture/compare control 1
+TB2CCTL2=\$446! \ Capture/compare control 2
+TB2R=\$450! \ TB2 counter register
+TB2CCR0=\$452! \ Capture/compare register 0
+TB2CCR1=\$454! \ Capture/compare register 1
+TB2CCR2=\$456! \ Capture/compare register 2
+TB2EX0=\$460! \ TB2 expansion register 0
+TB2IV=\$46E! \ TB2 interrupt vector
+
+RTCCTL0=\$4A0! \ RTC control 0
+RTCCTL1=\$4A1! \ RTC control 1
+RTCCTL2=\$4A2! \ RTC control 2
+RTCCTL3=\$4A3! \ RTC control 3
+RTCPS0CTL=\$4A8! \ RTC prescaler 0 control
+RTCPS1CTL=\$4AA! \ RTC prescaler 1 control
+RTCPS0=\$4AC! \ RTC prescaler 0
+RTCPS1=\$4AD! \ RTC prescaler 1
+RTCIV=\$4AE! \ RTC interrupt vector word
+RTCSEC=\$4B0! \ RTC seconds, RTC counter register 1 RTCSEC,
+RTCMIN=\$4B1! \ RTC minutes, RTC counter register 2 RTCMIN,
+RTCHOUR=\$4B2! \ RTC hours, RTC counter register 3 RTCHOUR,
+RTCDOW=\$4B3! \ RTC day of week, RTC counter register 4 RTCDOW,
+RTCDAY=\$4B4! \ RTC days
+RTCMON=\$4B5! \ RTC month
+RTCYEAR=\$4B6!
+RTCYEARL=\$4B6! \ RTC year low
+RTCYEARH=\$4B7! \ RTC year high
+RTCAMIN=\$4B8! \ RTC alarm minutes
+RTCAHOUR=\$4B9! \ RTC alarm hours
+RTCADOW=\$4BA! \ RTC alarm day of week
+RTCADAY=\$4BB! \ RTC alarm days
+BIN2BCD=\$4BC! \ Binary-to-BCD conversion register
+BCD2BIN=\$4BE! \ BCD-to-binary conversion register
+RTCHOLD=\$40!
+
+MPY=\$4C0! \ 16-bit operand 1 \96 multiply
+MPYS=\$4C2! \ 16-bit operand 1 \96 signed multiply
+MAC=\$4C4! \ 16-bit operand 1 \96 multiply accumulate
+MACS=\$4C6! \ 16-bit operand 1 \96 signed multiply accumulate
+OP2=\$4C8! \ 16-bit operand 2
+RESLO=\$4CA! \ 16 × 16 result low word
+RESHI=\$4CC! \ 16 × 16 result high word
+SUMEXT=\$4CE! \ 16 × 16 sum extension register
+MPY32L=\$4D0! \ 32-bit operand 1 \96 multiply low word
+MPY32H=\$4D2! \ 32-bit operand 1 \96 multiply high word
+MPYS32L=\$4D4! \ 32-bit operand 1 \96 signed multiply low word
+MPYS32H=\$4D6! \ 32-bit operand 1 \96 signed multiply high word
+MAC32L=\$4D8! \ 32-bit operand 1 \96 multiply accumulate low word
+MAC32H=\$4DA! \ 32-bit operand 1 \96 multiply accumulate high word
+MACS32L=\$4DC! \ 32-bit operand 1 \96 signed multiply accumulate low word
+MACS32H=\$4DE! \ 32-bit operand 1 \96 signed multiply accumulate high word
+OP2L=\$4E0! \ 32-bit operand 2 \96 low word
+OP2H=\$4E2! \ 32-bit operand 2 \96 high word
+RES0=\$4E4! \ 32 × 32 result 0 \96 least significant word
+RES1=\$4E6! \ 32 × 32 result 1
+RES2=\$4E8! \ 32 × 32 result 2
+RES3=\$4EA! \ 32 × 32 result 3 \96 most significant word
+MPY32CTL0=\$4EC! \ MPY32 control register 0
+
+DMA0CTL=\$500! \ DMA channel 0 control
+DMA0SAL=\$502! \ DMA channel 0 source address low
+DMA0SAH=\$504! \ DMA channel 0 source address high
+DMA0DAL=\$506! \ DMA channel 0 destination address low
+DMA0DAH=\$508! \ DMA channel 0 destination address high
+DMA0SZ=\$50A! \ DMA channel 0 transfer size
+DMA1CTL=\$510! \ DMA channel 1 control
+DMA1SAL=\$512! \ DMA channel 1 source address low
+DMA1SAH=\$514! \ DMA channel 1 source address high
+DMA1DAL=\$516! \ DMA channel 1 destination address low
+DMA1DAH=\$518! \ DMA channel 1 destination address high
+DMA1SZ=\$51A! \ DMA channel 1 transfer size
+DMA2CTL=\$520! \ DMA channel 2 control
+DMA2SAL=\$522! \ DMA channel 2 source address low
+DMA2SAH=\$524! \ DMA channel 2 source address high
+DMA2DAL=\$526! \ DMA channel 2 destination address low
+DMA2DAH=\$528! \ DMA channel 2 destination address high
+DMA2SZ=\$52A! \ DMA channel 2 transfer size
+DMACTL0=\$530! \ DMA module control 0
+DMACTL1=\$532! \ DMA module control 1
+DMACTL2=\$534! \ DMA module control 2
+DMACTL3=\$536! \ DMA module control 3
+DMACTL4=\$538! \ DMA module control 4
+DMAIV=\$53A! \ DMA interrupt vector
+
+MPUCTL0=\$5A0! \ MPU control 0
+MPUCTL1=\$5A2! \ MPU control 1
+MPUSEG=\$5A4! \ MPU Segmentation Register
+MPUSAM=\$5A6! \ MPU access management
+
+UCA0CTLW0=\$5C0! \ eUSCI_A control word 0
+UCA0CTLW1=\$5C2! \ eUSCI_A control word 1
+UCA0BRW=\$5C6!
+UCA0BR0=\$5C6! \ eUSCI_A baud rate 0
+UCA0BR1=\$5C7! \ eUSCI_A baud rate 1
+UCA0MCTLW=\$5C8! \ eUSCI_A modulation control
+UCA0STAT=\$5CA! \ eUSCI_A status
+UCA0RXBUF=\$5CC! \ eUSCI_A receive buffer
+UCA0TXBUF=\$5CE! \ eUSCI_A transmit buffer
+UCA0ABCTL=\$5D0! \ eUSCI_A LIN control
+UCA0IRTCTL=\$5D2! \ eUSCI_A IrDA transmit control
+UCA0IRRCTL=\$5D3! \ eUSCI_A IrDA receive control
+UCA0IE=\$5DA! \ eUSCI_A interrupt enable
+UCA0IFG=\$5DC! \ eUSCI_A interrupt flags
+UCA0IV=\$5DE! \ eUSCI_A interrupt vector word
+
+UCA1CTLW0=\$5E0! \ eUSCI_A control word 0
+UCA1CTLW1=\$5E2! \ eUSCI_A control word 1
+UCA1BRW=\$5E6!
+UCA1BR0=\$5E6! \ eUSCI_A baud rate 0
+UCA1BR1=\$5E7! \ eUSCI_A baud rate 1
+UCA1MCTLW=\$5E8! \ eUSCI_A modulation control
+UCA1STAT=\$5EA! \ eUSCI_A status
+UCA1RXBUF=\$5EC! \ eUSCI_A receive buffer
+UCA1TXBUF=\$5EE! \ eUSCI_A transmit buffer
+UCA1ABCTL=\$5F0! \ eUSCI_A LIN control
+UCA1IRTCTL=\$5F2! \ eUSCI_A IrDA transmit control
+UCA1IRRCTL=\$5F3! \ eUSCI_A IrDA receive control
+UCA1IE=\$5FA! \ eUSCI_A interrupt enable
+UCA1IFG=\$5FC! \ eUSCI_A interrupt flags
+UCA1IV=\$5FE! \ eUSCI_A interrupt vector word
+
+UCB0CTLW0=\$640! \ eUSCI_B control word 0
+UCB0CTLW1=\$642! \ eUSCI_B control word 1
+UCB0BRW=\$646!
+UCB0BR0=\$646! \ eUSCI_B bit rate 0
+UCB0BR1=\$647! \ eUSCI_B bit rate 1
+UCB0STATW=\$648! \ eUSCI_B status word
+UCBCNT0=\$649! \ eUSCI_B hardware count
+UCB0TBCNT=\$64A! \ eUSCI_B byte counter threshold
+UCB0RXBUF=\$64C! \ eUSCI_B receive buffer
+UCB0TXBUF=\$64E! \ eUSCI_B transmit buffer
+UCB0I2COA0=\$654! \ eUSCI_B I2C own address 0
+UCB0I2COA1=\$656! \ eUSCI_B I2C own address 1
+UCB0I2COA2=\$658! \ eUSCI_B I2C own address 2
+UCB0I2COA3=\$65A! \ eUSCI_B I2C own address 3
+UCB0ADDRX=\$65C! \ eUSCI_B received address
+UCB0ADDMASK=\$65E! \ eUSCI_B address mask
+UCB0I2CSA=\$660! \ eUSCI I2C slave address
+UCB0IE=\$66A! \ eUSCI interrupt enable
+UCB0IFG=\$66C! \ eUSCI interrupt flags
+UCB0IV=\$66E! \ eUSCI interrupt vector word
+
+\#UCTXACK,=\#\$20,!
+\#UCTR,=\#\$10,!
+
+ADC10CTL0=\$700! \ ADC10_B Control register 0
+ADC10CTL1=\$702! \ ADC10_B Control register 1
+ADC10CTL2=\$704! \ ADC10_B Control register 2
+ADC10LO=\$706! \ ADC10_B Window Comparator Low Threshold
+ADC10HI=\$708! \ ADC10_B Window Comparator High Threshold
+ADC10MCTL0=\$70A! \ ADC10_B Memory Control Register 0
+ADC10MEM0=\$712! \ ADC10_B Conversion Memory Register
+ADC10IE=\$71A! \ ADC10_B Interrupt Enable
+ADC10IFG=\$71C! \ ADC10_B Interrupt Flags
+ADC10IV=\$71E! \ ADC10_B Interrupt Vector Word
+
+\#ADCON,=\#\$10,!
+\#ADCSTART,=\#\$03,!
+
+CDCTL0=\$8C0! \ Comparator_D control register 0
+CDCTL1=\$8C2! \ Comparator_D control register 1
+CDCTL2=\$8C4! \ Comparator_D control register 2
+CDCTL3=\$8C6! \ Comparator_D control register 3
+CDINT=\$8CC! \ Comparator_D interrupt register
+CDIV=\$8CE! \ Comparator_D interrupt vector word
--- /dev/null
+!MSP430FR57xx_FastForth.pat
+
+! =================================================
+! MSP430FR57xx DEVICES HAVE SPECIFIC RAM ADDRESSES!
+! =================================================
+
+
+! ============================================
+! SR bits :
+! ============================================
+\#C=\#1! = SR(0) Carry flag
+\#Z=\#2! = SR(1) Zero flag
+\#N=\#4! = SR(2) Negative flag
+GIE=8! = SR(3) Enable Int
+CPUOFF=\$10! = SR(4) CPUOFF
+OSCOFF=\$20! = SR(5) OSCOFF
+SCG0=\$40! = SR(6) SCG0
+SCG1=\$80! = SR(7) SCG1
+V=\$100! = SR(8) oVerflow flag
+UF1=\$200! = SR(9) User Flag 1 used by ?NUMBER --> INTERPRET --> LITERAL to process double numbers, else free for use.
+UF2=\$400! = SR(10) User Flag 2
+UF3=\$800! = SR(11) User Flag 3
+
+C\@=C\@
+C\!=C\!
+C\,=C\,
+
+! ============================================
+! PORTx, Reg bits :
+! ============================================
+BIT0=1!
+BIT1=2!
+BIT2=4!
+BIT3=8!
+BIT4=\$10!
+BIT5=\$20!
+BIT6=\$40!
+BIT7=\$80!
+BIT8=\$100!
+BIT9=\$200!
+BIT10=\$400!
+BIT11=\$800!
+BIT12=\$1000!
+BIT13=\$2000!
+BIT14=\$4000!
+BIT15=\$8000!
+
+! ============================================
+! symbolic codes :
+! ============================================
+RET=MOV \@R1+,R0!
+NOP=MOV 0,R3! \ one word one cycle
+NOP2=\$3C00 ,! \ compile JMP 0: one word two cycles
+NOP3=MOV R0,R0! \ one word three cycles
+NEXT=MOV \@R13+,R0!
+
+
+
+! You can check the addresses below by comparing their values in DTCforthMSP430FRxxxx.lst
+! those addresses are usable with the symbolic assembler
+
+! ============================================
+! FastForth INFO(DCBA) memory map (256 bytes):
+! ============================================
+
+! ----------------------
+! KERNEL CONSTANTS
+! ----------------------
+INI_THREAD=\$1800! .word THREADS
+TERMINAL_INT=\$1802! .word TERMINAL_INT
+FREQ_KHZ=\$1804! .word FREQUENCY*1000
+HECTOBAUDS=\$1806! .word TERMINALBAUDRATE/100
+! ----------------------
+! SAVED VARIABLES
+! ----------------------
+SAVE_SYSRSTIV=\$1808! to enable SYSRSTIV read
+LPM_MODE=\$180A! LPM0+GIE is the default mode
+INIDP=\$180C! define RST_STATE, init by wipe
+INIVOC=\$180E! define RST_STATE, init by wipe
+
+XON=\$1810!
+XOFF=\$1812!
+
+ReadSectorWX=\$1814! call with W = SectorLO X = SectorHI
+WriteSectorWX=\$1816! call with W = SectorLO X = SectorHI
+
+
+! ---------------------------------------
+! FAT16 FileSystemInfos
+! ---------------------------------------
+FATtype=\$181A!
+BS_FirstSectorL=\$181C!
+BS_FirstSectorH=\$181E!
+OrgFAT1=\$1820!
+FATSize=\$1822!
+OrgFAT2=\$1824!
+OrgRootDir=\$1826!
+OrgClusters=\$1828! Sector of Cluster 0
+SecPerClus=\$182A!
+
+! ---------------------------------------
+! SD command
+! ---------------------------------------
+SD_CMD_FRM=\$182C! 6 bytes SD_CMDx inverted frame \${CRC,ll,LL,hh,HH,CMD}
+SD_CMD_FRM0=\$182C! CRC:ll word access
+SD_CMD_FRM1=\$182D! ll byte access
+SD_CMD_FRM2=\$182E! LL:hh word access
+SD_CMD_FRM3=\$182F! hh byte access
+SD_CMD_FRM4=\$1830! HH:CMD word access
+SD_CMD_FRM5=\$1831! CMD byte access
+SectorL=\$1832! 2 words
+SectorH=\$1834!
+
+! ---------------------------------------
+! BUFFER management
+! ---------------------------------------
+BufferPtr=\$1836!
+BufferLen=\$1838!
+
+! ---------------------------------------
+! FAT entry
+! ---------------------------------------
+ClusterL=\$183A! 16 bits wide (FAT16)
+ClusterH=\$183C! 16 bits wide (FAT16)
+NewClusterL=\$183E! 16 bits wide (FAT16)
+NewClusterH=\$1840! 16 bits wide (FAT16)
+FATsector=\$1842! not used
+CurFATsector=\$1844!
+
+! ---------------------------------------
+! DIR entry
+! ---------------------------------------
+DIRclusterL=\$1846! contains the Cluster of current directory ; 1 if FAT16 root directory
+DIRclusterH=\$1848! contains the Cluster of current directory ; 1 if FAT16 root directory
+EntryOfst=\$184A!
+pathname=\$184C! address of pathname string
+
+! ---------------------------------------
+! Handle Pointer
+! ---------------------------------------
+CurrentHdl=\$184E! contains the address of the last opened file structure, or 0
+
+! ---------------------------------------
+! Load file operation
+! ---------------------------------------
+SAVEtsLEN=\$1850! of previous ACCEPT
+SAVEtsPTR=\$1852! of previous ACCEPT
+MemSectorL=\$1854! double word current Sector of previous LOAD"ed file
+MemSectorH=\$1856!
+
+! ---------------------------------------
+! Handle structure
+! ---------------------------------------
+! three handle tokens :
+! token = 0 : free handle
+! token = 1 : file to read
+! token = 2 : file updated (write)
+! token =-1 : LOAD"ed file (source file)
+
+! offset values
+HDLW_PrevHDL=0! previous handle ; used by LOAD"
+HDLB_Token=2! token
+HDLB_ClustOfst=3! Current sector offset in current cluster (Byte)
+HDLL_DIRsect=4! Dir SectorL (Long)
+HDLH_DIRsect=6!
+HDLW_DIRofst=8! BUFFER offset of Dir entry
+HDLL_FirstClus=10! File First ClusterLo (identify the file)
+HDLH_FirstClus=12! File First ClusterHi (byte)
+HDLL_CurClust=14! Current ClusterLo
+HDLH_CurClust=16! Current ClusterHi (T as 3Th byte)
+HDLL_CurSize=18! written size / not yet read size (Long)
+HDLH_CurSize=20! written size / not yet read size (Long)
+HDLW_BUFofst=22! BUFFER offset ; used by LOAD" and by WRITE"
+
+HandleMax=7!
+HandleLenght=24!
+
+!OpenedFirstFile ; "openedFile" structure
+FirstHandle=\$1858!
+HandleOutOfBound=\$1900!
+
+
+
+! ============================================
+! FastForth RAM memory map (= 1k):
+! ============================================
+LSATCK=\$1C00! \ leave stack, grow up
+PSTACK=\$1C80! \ parameter stack, grow down
+RSTACK=\$1CE0! \ Return stack, grow down
+PAD=\$1CE2! \ user scratch pad buffer, grow up
+TIB=\$1D38! \ Terminal input buffer, grow up
+BASE_HOLD=\$1DAA! \ BASE HOLD area, grow down
+
+! ----------------------
+! NOT SAVED VARIABLES
+! ----------------------
+
+HP=\$1DAA! HOLD ptr
+LEAVEPTR=\$1DAC! Leave-stack pointer, init by QUIT
+
+LAST_NFA=\$1DAE!
+LAST_THREAD=\$1DB0!
+LAST_CFA=\$1DB2!
+LAST_CSP=\$1DB4!
+
+STATE=\$1DB6! Interpreter state
+
+ASM_CURRENT=\$1DB8! preserve CURRENT when create assembler words
+OPCODE=\$1DBA! OPCODE adr
+ASMTYPE=\$1DBC! keep the opcode complement
+
+SOURCE_LEN=\$1DBE! len of input stream
+SOURCE_ADR=\$1DC0! adr of input stream
+\>IN=\$1DC2! >IN
+DP=\$1DC4! dictionary ptr
+LASTVOC=\$1DC6! keep VOC-LINK
+CURRENT=\$1DC8! CURRENT dictionnary ptr
+CONTEXT=\$1DCA! CONTEXT dictionnary space (8 CELLS)
+
+BASE=\$1DDA! numeric base, must be defined before first reset !
+CAPS=\$1DDC! CAPS ON/OFF flag, must be set to -1 before first reset !
+
+
+BUFFER=\$1E00! \ SD_Card buffer
+BUFEND=\$2000!
+
--- /dev/null
+!MSP430fr5948.pat
+
+@define{@read{/config/gema/MSP430FR5x6x.pat}}
+
+! ----------------------------------------------
+! MSP430fr5948 MEMORY MAP
+! ----------------------------------------------
+! 0000-0FFF = peripherals (4 KB)
+! 1000-17FF = ROM bootstrap loader BSL0..3 (4x512 B)
+! 1800-187F = info D (FRAM 128 B)
+! 1880-18FF = info C (FRAM 128 B)
+! 1900-197F = info B (FRAM 128 B)
+! 1980-19FF = info A (FRAM 128 B)
+! 1A00-1A7F = TLV device descriptor info (FRAM 128 B)
+! 1A80-1BFF = unused (385 B)
+! 1C00-23FF = RAM (2 KB)
+! 2000-C1FF = unused (41472 B)
+! C200-FF7F = code memory (FRAM 15743 B)
+! FF80-FFFF = interrupt vectors (FRAM 127 B)
+! ----------------------------------------------
+INFOSTART=\$1800!
+INFODSTART=\$1800!
+INFODEND=\$187F!
+INFOCSTART=\$1880!
+INFOCEND=\$18FF!
+INFOBSTART=\$1900!
+INFOBEND=\$197F!
+INFOASTART=\$1980!
+INFOAEND=\$19FF!
+INFOEND=\$19FF!
+TLVSTAT=\$1A00! Device Descriptor Info (Tag-Lenght-Value)
+TLVEND=\$1A7F!
+RAMSTART=\$1C00!
+RAMEND=\$23FF!
+PROGRAMSTART=\$4400! Code space start
+SIGNATURES=\$FF80! JTAG/BSL signatures
+JTAG_SIG1=\$FF80! if 0 (electronic fuse=0) enable JTAG/SBW; must be reset by wipe.
+JTAG_SIG2=\$FF82! if JTAG_SIG1=\$AAAA, length of password string @ JTAG_PASSWORD
+BSL_SIG1=\$FF84!
+BSL_SIG2=\$FF86!
+JTAG_PASSWORD=\$FF88! 256 bits
+INTVECT=\$FFCC! FFCC-FFFF
+BSL_PASSWORD=\$FFE0! 256 bits
+
+
+AES_Vec=\$FFCC!
+RTC_Vec=\$FFCE!
+P4_Vec=\$FFD0!
+P3_Vec=\$FFD2!
+TB2_x_Vec=\$FFD4!
+TB2_0_Vec=\$FFD6!
+P2_Vec=\$FFD8!
+TB1_x_Vec=\$FFDA!
+TB1_0_Vec=\$FFDC!
+P1_Vec=\$FFDE!
+TA1_x_Vec=\$FFE0!
+TA1_0_Vec=\$FFE2!
+DMA_Vec=\$FFE4!
+eUSCI_A1_Vec=\$FFE6!
+TA0_x_Vec=\$FFE8!
+TA0_0_Vec=\$FFEA!
+ADC10_B_Vec=\$FFEC!
+eUSCI_B0_Vec=\$FFEE!
+eUSCI_A0_Vec=\$FFF0!
+WDT_Vec=\$FFF2!
+TB0_x_Vec=\$FFF4!
+TB0_0_Vec=\$FFF6!
+COMP_D_Vec=\$FFF8!
+U_NMI_Vec=\$FFFA!
+S_NMI_Vec=\$FFFC!
+RST_Vec=\$FFFE!
+
--- /dev/null
+!MSP430fr5969.pat
+
+@define{@read{/config/gema/MSP430FR5x6x.pat}}
+
+
+! ----------------------------------------------
+! MSP430FR5969 MEMORY MAP
+! ----------------------------------------------
+! 0000-0FFF = peripherals (4 KB)
+! 1000-17FF = ROM bootstrap loader BSL0..3 (4x512 B)
+! 1800-187F = FRAM info D (128 B)
+! 1880-18FF = FRAM info C (128 B)
+! 1900-197F = FRAM info B (128 B)
+! 1980-19FF = FRAM info A (128 B)
+! 1A00-1AFF = TLV device descriptor info (FRAM 256 B)
+! 1B00-1BFF = unused (256 B)
+! 1C00-23FF = RAM (2 KB)
+! 4400-FF7F = code memory (FRAM 47 kB)
+! FF80-FFFF = interrupt vectors (FRAM 127 B)
+! ----------------------------------------------
+INFOSTART=\$1800!
+INFODSTART=\$1800!
+INFODEND=\$187F!
+INFOCSTART=\$1880!
+INFOCEND=\$18FF!
+INFOBSTART=\$1900!
+INFOBEND=\$197F!
+INFOASTART=\$1980!
+INFOAEND=\$19FF!
+TLVSTAT=\$1A00! Device Descriptor Info (Tag-Lenght-Value)
+TLVEND=\$1AFF!
+RAMSTART=\$1C00!
+RAMEND=\$23FF!
+PROGRAMSTART=\$4400! Code space start
+SIGNATURES=\$FF80! JTAG/BSL signatures
+JTAG_SIG1=\$FF80! if 0 (electronic fuse=0) enable JTAG/SBW; must be reset by wipe.
+JTAG_SIG2=\$FF82! if JTAG_SIG1=\$AAAA, length of password string @ JTAG_PASSWORD
+BSL_SIG1=\$FF84!
+BSL_SIG2=\$FF86!
+JTAG_PASSWORD=\$FF88! 256 bits
+INTVECT=\$FFCC! FFCC-FFFF
+BSL_PASSWORD=\$FFE0! 256 bits
+
+AES_Vec=\$FFCC!
+RTC_Vec=\$FFCE!
+P4_Vec=\$FFD0!
+P3_Vec=\$FFD2!
+TA3_x_Vec=\$FFD4!
+TA3_0_Vec=\$FFD6!
+P2_Vec=\$FFD8!
+TA2_x_Vec=\$FFDA!
+TA2_0_Vec=\$FFDC!
+P1_Vec=\$FFDE!
+TA1_x_Vec=\$FFE0!
+TA1_0_Vec=\$FFE2!
+DMA_Vec=\$FFE4!
+eUSCI_A1_Vec=\$FFE6!
+TA0_x_Vec=\$FFE8!
+TA0_0_Vec=\$FFEA!
+ADC12_B_Vec=\$FFEC!
+eUSCI_B0_Vec=\$FFEE!
+eUSCI_A0_Vec=\$FFF0!
+WDT_Vec=\$FFF2!
+TB0_x_Vec=\$FFF4!
+TB0_0_Vec=\$FFF6!
+COMP_D_Vec=\$FFF8!
+U_NMI_Vec=\$FFFA!
+S_NMI_Vec=\$FFFC!
+RST_Vec=\$FFFE!
+
--- /dev/null
+!MSP430fr5994.pat
+
+@define{@read{/config/gema/MSP430FR5x6x.pat}}
+
+
+! ----------------------------------------------
+! MSP430FR5994 MEMORY MAP
+! ----------------------------------------------
+! 000A-001F = tiny RAM
+! 0020-0FFF = peripherals (4 KB)
+! 1000-17FF = ROM bootstrap loader BSL0..3 (4x512 B)
+! 1800-187F = FRAM info D (128 B)
+! 1880-18FF = FRAM info C (128 B)
+! 1900-197F = FRAM info B (128 B)
+! 1980-19FF = FRAM info A (128 B)
+! 1A00-1AFF = FRAM TLV device descriptor info (256 B)
+! 1B00-1BFF = unused (256 B)
+! 1C00-2BFF = RAM (4KB)
+! 2C00-3BFF = sharedRAM (4kB)
+! 4400-FF7F = FRAM code memory (FRAM) (MSP430FR59x8/9)
+! 8000-FF7F = FRAM code memory (FRAM) (MSP430FR59x7/8/9)
+! FF80-FFFF = FRAM interrupt vectors and signatures (FRAM)
+
+! ----------------------------------------------
+! PAGESIZE .equ 512 ; MPU unit
+! ----------------------------------------------
+! BSL
+! ----------------------------------------------
+BSL=\$1000!
+! ----------------------------------------------
+! FRAM ; INFO B, A, TLV
+! ----------------------------------------------
+INFOSTART=\$1800!
+INFODSTART=\$1800!
+INFODEND=\$187F!
+INFOCSTART=\$1880!
+INFOCEND=\$18FF!
+INFOBSTART=\$1900!
+INFOBEND=\$197F!
+INFOASTART=\$1980!
+INFOAEND=\$19FF!
+INFOEND=\$19FF!
+TLVSTART=\$1A00! Device Descriptor Info (Tag-Lenght-Value)
+TLVEND=\$1AFF!
+! ----------------------------------------------
+! RAM
+! ----------------------------------------------
+TinyRAM=\$0A!
+TinyRAMEnd=\$1F!
+RAMSTART=\$1C00!
+RAMEND=\$2BFF!
+SharedRAMSTART=\$2C00!
+SharedRAMEND=\$3BFF!
+! ----------------------------------------------
+! FRAM
+! ----------------------------------------------
+PROGRAMSTART=\$4000! Code space start
+!FRAMEND=\$43FFF! 256 k FRAM
+SIGNATURES=\$FF80! JTAG/BSL signatures
+JTAG_SIG1=\$FF80! if 0, enable JTAG/SBW
+JTAG_SIG2=\$FF82! if JTAG_SIG1=\$AAAA, length of password string @ JTAG_PASSWORD
+BSL_SIG1=\$FF84!
+BSL_SIG2=\$FF86!
+JTAG_PASSWORD=\$FF88! 256 bits max
+IPE_SIG_VALID=\$FF88! one word
+IPE_STR_PTR_SRC=\$FF8A! one word
+INTVECT=\$FFB4! FFB4-FFFF
+BSL_PASSWORD=\$FFE0! 256 bits
+
+
+LEA_Vec=\$FFB4!
+P8_Vec=\$FFB6!
+P7_Vec=\$FFB8!
+eUSCI_B3_Vec=\$FFBA!
+eUSCI_B2_Vec=\$FFBC!
+eUSCI_B1_Vec=\$FFBE!
+eUSCI_A3_Vec=\$FFC0!
+eUSCI_A2_Vec=\$FFC2!
+P6_Vec=\$FFC4!
+P5_Vec=\$FFC6!
+TA4_x_Vec=\$FFC8!
+TA4_0_Vec=\$FFCA!
+AES_Vec=\$FFCC!
+RTC_C_Vec=\$FFCE!
+P4_Vec=\$FFD0!
+P3_Vec=\$FFD2!
+TA3_x_Vec=\$FFD4!
+TA3_0_Vec=\$FFD6!
+P2_Vec=\$FFD8!
+TA2_x_Vec=\$FFDA!
+TA2_0_Vec=\$FFDC!
+P1_Vec=\$FFDE!
+TA1_x_Vec=\$FFE0!
+TA1_0_Vec=\$FFE2!
+DMA_Vec=\$FFE4!
+eUSCI_A1_Vec=\$FFE6!
+TA0_x_Vec=\$FFE8!
+TA0_0_Vec=\$FFEA!
+ADC12_B_Vec=\$FFEC!
+eUSCI_B0_Vec=\$FFEE!
+eUSCI_A0_Vec=\$FFF0!
+WDT_Vec=\$FFF2!
+TB0_x_Vec=\$FFF4!
+TB0_0_Vec=\$FFF6!
+COMP_E_Vec=\$FFF8!
+U_NMI_Vec=\$FFFA!
+S_NMI_Vec=\$FFFC!
+RST_Vec=\$FFFE!
--- /dev/null
+!MSP430fr5x6x.pat
+
+LPM4=\$F8!
+LPM3=\$D8!
+LPM2=\$98!
+LPM1=\$58!
+LPM0=\$18!
+
+
+
+SFRIE1=\$100! \ SFR enable register
+SFRIFG1=\$102! \ SFR flag register
+SFRRPCR=\$104! \ SFR reset pin control
+
+PMMCTL0=\$120! \ PMM Control 0
+PMMIFG=\$12A! \ PMM interrupt flags
+PM5CTL0=\$130! \ PM5 Control 0
+
+FRCTLCTL0=\$140! \ FRAM control 0
+GCCTL0=\$144! \ General control 0
+GCCTL1=\$146! \ General control 1
+
+CRC16DI=\$150! \ CRC data input
+CRCDIRB=\$152! \ CRC data input reverse byte
+CRCINIRES=\$154! \ CRC initialization and result
+CRCRESR=\$156! \ CRC result reverse byte
+
+WDTCTL=\$15C! \ WDT control register
+
+CSCTL0=\$160! \ CS control 0
+CSCTL1=\$162! \ CS control 1
+CSCTL2=\$164! \ CS control 2
+CSCTL3=\$166! \ CS control 3
+CSCTL4=\$168! \ CS control 4
+CSCTL5=\$16A! \ CS control 5
+CSCTL6=\$16C! \ CS control 6
+
+SYSCTL=\$180! \ System control
+SYSJMBC=\$186! \ JTAG mailbox control
+SYSJMBI0=\$188! \ JTAG mailbox input 0
+SYSJMBI1=\$18A! \ JTAG mailbox input 1
+SYSJMBO0=\$18C! \ JTAG mailbox output 0
+SYSJMBO1=\$18E! \ JTAG mailbox output 1
+SYSUNIV=\$19A! \ User NMI vector generator
+SYSSNIV=\$19C! \ System NMI vector generator
+SYSRSTIV=\$19E! \ Reset vector generator
+
+REFCTL=\$1B0! \ Shared reference control
+
+PAIN=\$200!
+PAOUT=\$202!
+PADIR=\$204!
+PAREN=\$206!
+PASEL0=\$20A!
+PASEL1=\$20C!
+P1IV=\$20E!
+PASELC=\$216!
+PAIES=\$218!
+PAIE=\$21A!
+PAIFG=\$21C!
+P2IV=\$21E!
+
+P1IN=\$200!
+P1OUT=\$202!
+P1DIR=\$204!
+P1REN=\$206!
+P1SEL0=\$20A!
+P1SEL1=\$20C!
+P1SELC=\$216!
+P1IES=\$218!
+P1IE=\$21A!
+P1IFG=\$21C!
+
+P2IN=\$201!
+P2OUT=\$203!
+P2DIR=\$205!
+P2REN=\$207!
+P2SEL0=\$20B!
+P2SEL1=\$20D!
+P2SELC=\$217!
+P2IES=\$219!
+P2IE=\$21B!
+P2IFG=\$21D!
+
+PBIN=\$220!
+PBOUT=\$222!
+PBDIR=\$224!
+PBREN=\$226!
+PBSEL0=\$22A!
+PBSEL1=\$22C!
+P3IV=\$22E!
+PBSELC=\$236!
+PBIES=\$238!
+PBIE=\$23A!
+PBIFG=\$23C!
+P4IV=\$23E!
+
+P3IN=\$220!
+P3OUT=\$222!
+P3DIR=\$224!
+P3REN=\$226!
+P3SEL0=\$22A!
+P3SEL1=\$22C!
+P3SELC=\$236!
+P3IES=\$238!
+P3IE=\$23A!
+P3IFG=\$23C!
+
+P4IN=\$221!
+P4OUT=\$223!
+P4DIR=\$225!
+P4REN=\$227!
+P4SEL0=\$22B!
+P4SEL1=\$22D!
+P4SELC=\$237!
+P4IES=\$239!
+P4IE=\$23B!
+P4IFG=\$23D!
+
+PCIN=\$240!
+PCOUT=\$242!
+PCDIR=\$244!
+PCREN=\$246!
+PCSEL0=\$24A!
+PCSEL1=\$24C!
+P5IV=\$24E!
+PCSELC=\$256!
+PCIES=\$258!
+PCIE=\$25A!
+PCIFG=\$25C!
+P6IV=\$25E!
+
+P5IN=\$240!
+P5OUT=\$242!
+P5DIR=\$244!
+P5REN=\$246!
+P5SEL0=\$24A!
+P5SEL1=\$24C!
+P5SELC=\$256!
+P5IES=\$258!
+P5IE=\$25A!
+P5IFG=\$25C!
+
+P6IN=\$241!
+P6OUT=\$243!
+P6DIR=\$245!
+P6REN=\$247!
+P6SEL0=\$24B!
+P6SEL1=\$24D!
+P6SELC=\$257!
+P6IES=\$259!
+P6IE=\$25B!
+P6IFG=\$25D!
+
+PDIN=\$260!
+PDOUT=\$262!
+PDDIR=\$264!
+PDREN=\$266!
+PDSEL0=\$26A!
+PDSEL1=\$26C!
+P7IV=\$26E!
+PCSELC=\$276!
+PCIES=\$278!
+PCIE=\$27A!
+PCIFG=\$27C!
+P8IV=\$27E!
+
+P7IN=\$260!
+P7OUT=\$262!
+P7DIR=\$264!
+P7REN=\$266!
+P7SEL0=\$26A!
+P7SEL1=\$26C!
+P7SELC=\$276!
+P7IES=\$278!
+P7IE=\$27A!
+P7IFG=\$27C!
+
+P8IN=\$261!
+P8OUT=\$263!
+P8DIR=\$265!
+P8REN=\$267!
+P8SEL0=\$26B!
+P8SEL1=\$26D!
+P8SELC=\$277!
+P8IES=\$279!
+P8IE=\$27B!
+P8IFG=\$27D!
+
+PEIN=\$280!
+PEOUT=\$282!
+PEDIR=\$284!
+PEREN=\$286!
+PESEL0=\$28A!
+PESEL1=\$28C!
+P9IV=\$28E!
+PESELC=\$296!
+PEIES=\$298!
+PEIE=\$29A!
+PEIFG=\$29C!
+P10IV=\$29E!
+
+P9IN=\$280!
+P9OUT=\$282!
+P9DIR=\$284!
+P9REN=\$286!
+P9SEL0=\$28A!
+P9SEL1=\$28C!
+P9SELC=\$296!
+P9IES=\$298!
+P9IE=\$29A!
+P9IFG=\$29C!
+
+P10IN=\$281!
+P10OUT=\$283!
+P10DIR=\$285!
+P10REN=\$287!
+P10SEL0=\$28B!
+P10SEL1=\$28D!
+P10SELC=\$297!
+P10IES=\$299!
+P10IE=\$29B!
+P10IFG=\$29D!
+
+PJIN=\$320!
+PJOUT=\$322!
+PJDIR=\$324!
+PJREN=\$326!
+PJSEL0=\$32A!
+PJSEL1=\$32C!
+PJSELC=\$336!
+
+TA0CTL=\$340! \ TA0 control
+TA0CCTL0=\$342! \ Capture/compare control 0
+TA0CCTL1=\$344! \ Capture/compare control 1
+TA0CCTL2=\$346! \ Capture/compare control 2
+TA0R=\$350! \ TA0 counter register
+TA0CCR0=\$352! \ Capture/compare register 0
+TA0CCR1=\$354! \ Capture/compare register 1
+TA0CCR2=\$356! \ Capture/compare register 2
+TA0EX0=\$360! \ TA0 expansion register 0
+TA0IV=\$36E! \ TA0 interrupt vector
+
+TA1CTL=\$380! \ TA1 control
+TA1CCTL0=\$382! \ Capture/compare control 0
+TA1CCTL1=\$384! \ Capture/compare control 1
+TA1CCTL2=\$386! \ Capture/compare control 2
+TA1R=\$390! \ TA1 counter register
+TA1CCR0=\$392! \ Capture/compare register 0
+TA1CCR1=\$394! \ Capture/compare register 1
+TA1CCR2=\$396! \ Capture/compare register 2
+TA1EX0=\$3A0! \ TA1 expansion register 0
+TA1IV=\$3AE! \ TA1 interrupt vector
+
+TB0CTL=\$3C0! \ TB0 control
+TB0CCTL0=\$3C2! \ Capture/compare control 0
+TB0CCTL1=\$3C4! \ Capture/compare control 1
+TB0CCTL2=\$3C6! \ Capture/compare control 2
+TB0R=\$3D0! \ TB0 counter register
+TB0CCR0=\$3D2! \ Capture/compare register 0
+TB0CCR1=\$3D4! \ Capture/compare register 1
+TB0CCR2=\$3D6! \ Capture/compare register 2
+TB0EX0=\$3E0! \ TB0 expansion register 0
+TB0IV=\$3EE! \ TB0 interrupt vector
+
+TA2CTL=\$400! \ TA2 control
+TA2CCTL0=\$402! \ Capture/compare control 0
+TA2CCTL1=\$404! \ Capture/compare control 1
+TA2R=\$410! \ TA2 counter register
+TA2CCR0=\$412! \ Capture/compare register 0
+TA2CCR1=\$414! \ Capture/compare register 1
+TA2EX0=\$420! \ TA2 expansion register 0
+TA2IV=\$42E! \ TA2 interrupt vector
+
+CAPTIO0CTL=\$43E! \ Capacitive Touch IO 0 control
+
+TA3CTL=\$440! \ TA3 control
+TA3CCTL0=\$442! \ Capture/compare control 0
+TA3CCTL1=\$444! \ Capture/compare control 1
+TA3R=\$450! \ TA3 counter register
+TA3CCR0=\$452! \ Capture/compare register 0
+TA3CCR1=\$454! \ Capture/compare register 1
+TA3EX0=\$460! \ TA3 expansion register 0
+TA3IV=\$46E! \ TA3 interrupt vector
+
+CAPTIO1CTL=\$47E! \ Capacitive Touch IO 1 control
+
+! \ RTC_B / RTC_C
+RTCCTL0=\$4A0! \ RTC control 0 / RTCCTL0_L
+RTCCTL1=\$4A1! \ RTC control 1 / RTCCTL0_H
+RTCCTL2=\$4A2! \ RTC control 2 / RTCCTL1
+RTCCTL3=\$4A3! \ RTC control 3 / RTCCTL3
+RTCPS0CTL=\$4A8! \ RTC prescaler 0 control
+RTCPS1CTL=\$4AA! \ RTC prescaler 1 control
+RTCPS0=\$4AC! \ RTC prescaler 0
+RTCPS1=\$4AD! \ RTC prescaler 1
+RTCIV=\$4AE! \ RTC interrupt vector word
+RTCSEC=\$4B0! \ RTC seconds, RTC counter register 1 RTCSEC,
+RTCMIN=\$4B1! \ RTC minutes, RTC counter register 2 RTCMIN,
+RTCHOUR=\$4B2! \ RTC hours, RTC counter register 3 RTCHOUR,
+RTCDOW=\$4B3! \ RTC day of week, RTC counter register 4 RTCDOW,
+RTCDAY=\$4B4! \ RTC days
+RTCMON=\$4B5! \ RTC month
+RTCYEAR=\$4B6!
+RTCYEARL=\$4B6! \ RTC year low
+RTCYEARH=\$4B7! \ RTC year high
+RTCAMIN=\$4B8! \ RTC alarm minutes
+RTCAHOUR=\$4B9! \ RTC alarm hours
+RTCADOW=\$4BA! \ RTC alarm day of week
+RTCADAY=\$4BB! \ RTC alarm days
+BIN2BCD=\$4BC! \ Binary-to-BCD conversion register
+BCD2BIN=\$4BE! \ BCD-to-binary conversion register
+RTCHOLD=\$40!
+
+MPY=\$4C0! \ 16-bit operand 1 \96 multiply
+MPYS=\$4C2! \ 16-bit operand 1 \96 signed multiply
+MAC=\$4C4! \ 16-bit operand 1 \96 multiply accumulate
+MACS=\$4C6! \ 16-bit operand 1 \96 signed multiply accumulate
+OP2=\$4C8! \ 16-bit operand 2
+RESLO=\$4CA! \ 16 × 16 result low word
+RESHI=\$4CC! \ 16 × 16 result high word
+SUMEXT=\$4CE! \ 16 × 16 sum extension register
+MPY32L=\$4D0! \ 32-bit operand 1 \96 multiply low word
+MPY32H=\$4D2! \ 32-bit operand 1 \96 multiply high word
+MPYS32L=\$4D4! \ 32-bit operand 1 \96 signed multiply low word
+MPYS32H=\$4D6! \ 32-bit operand 1 \96 signed multiply high word
+MAC32L=\$4D8! \ 32-bit operand 1 \96 multiply accumulate low word
+MAC32H=\$4DA! \ 32-bit operand 1 \96 multiply accumulate high word
+MACS32L=\$4DC! \ 32-bit operand 1 \96 signed multiply accumulate low word
+MACS32H=\$4DE! \ 32-bit operand 1 \96 signed multiply accumulate high word
+OP2L=\$4E0! \ 32-bit operand 2 \96 low word
+OP2H=\$4E2! \ 32-bit operand 2 \96 high word
+RES0=\$4E4! \ 32 × 32 result 0 \96 least significant word
+RES1=\$4E6! \ 32 × 32 result 1
+RES2=\$4E8! \ 32 × 32 result 2
+RES3=\$4EA! \ 32 × 32 result 3 \96 most significant word
+MPY32CTL0=\$4EC! \ MPY32 control register 0
+
+DMA0CTL=\$510! \ DMA channel 0 control
+DMA0SAL=\$512! \ DMA channel 0 source address low
+DMA0SAH=\$514! \ DMA channel 0 source address high
+DMA0DAL=\$516! \ DMA channel 0 destination address low
+DMA0DAH=\$518! \ DMA channel 0 destination address high
+DMA0SZ=\$51A! \ DMA channel 0 transfer size
+DMA1CTL=\$520! \ DMA channel 1 control
+DMA1SAL=\$522! \ DMA channel 1 source address low
+DMA1SAH=\$524! \ DMA channel 1 source address high
+DMA1DAL=\$526! \ DMA channel 1 destination address low
+DMA1DAH=\$528! \ DMA channel 1 destination address high
+DMA1SZ=\$52A! \ DMA channel 1 transfer size
+DMA2CTL=\$530! \ DMA channel 2 control
+DMA2SAL=\$532! \ DMA channel 2 source address low
+DMA2SAH=\$534! \ DMA channel 2 source address high
+DMA2DAL=\$536! \ DMA channel 2 destination address low
+DMA2DAH=\$538! \ DMA channel 2 destination address high
+DMA2SZ=\$53A! \ DMA channel 2 transfer size
+DMA2CTL=\$540! \ DMA channel 3 control
+DMA2SAL=\$542! \ DMA channel 3 source address low
+DMA2SAH=\$544! \ DMA channel 3 source address high
+DMA2DAL=\$546! \ DMA channel 3 destination address low
+DMA2DAH=\$548! \ DMA channel 3 destination address high
+DMA2SZ=\$54A! \ DMA channel 3 transfer size
+DMA2CTL=\$550! \ DMA channel 4 control
+DMA2SAL=\$552! \ DMA channel 4 source address low
+DMA2SAH=\$554! \ DMA channel 4 source address high
+DMA2DAL=\$556! \ DMA channel 4 destination address low
+DMA2DAH=\$558! \ DMA channel 4 destination address high
+DMA2SZ=\$55A! \ DMA channel 4 transfer size
+DMA2CTL=\$560! \ DMA channel 5 control
+DMA2SAL=\$562! \ DMA channel 5 source address low
+DMA2SAH=\$564! \ DMA channel 5 source address high
+DMA2DAL=\$566! \ DMA channel 5 destination address low
+DMA2DAH=\$568! \ DMA channel 5 destination address high
+DMA2SZ=\$56A! \ DMA channel 5 transfer size
+DMACTL0=\$500! \ DMA module control 0
+DMACTL1=\$502! \ DMA module control 1
+DMACTL2=\$504! \ DMA module control 2
+DMACTL3=\$506! \ DMA module control 3
+DMACTL4=\$508! \ DMA module control 4
+DMAIV=\$50A! \ DMA interrupt vector
+
+MPUCTL0=\$5A0! \ MPU control 0
+MPUCTL1=\$5A2! \ MPU control 1
+MPUSEG=\$5A4! \ MPU Segmentation Register
+MPUSAM=\$5A6! \ MPU access management
+MPUIPC0=\$5AA! \ MPU IP control 0
+MPUIPSEGB2=\$5AC! \ MPU IP Encapsulation Segment Border 2
+MPUIPSEGB1=\$5AE! \ MPU IP Encapsulation Segment Border 1
+
+UCA0CTLW0=\$5C0! \ eUSCI_A control word 0
+UCA0CTLW1=\$5C2! \ eUSCI_A control word 1
+UCA0BRW=\$5C6!
+UCA0BR0=\$5C6! \ eUSCI_A baud rate 0
+UCA0BR1=\$5C7! \ eUSCI_A baud rate 1
+UCA0MCTLW=\$5C8! \ eUSCI_A modulation control
+UCA0STAT=\$5CA! \ eUSCI_A status
+UCA0RXBUF=\$5CC! \ eUSCI_A receive buffer
+UCA0TXBUF=\$5CE! \ eUSCI_A transmit buffer
+UCA0ABCTL=\$5D0! \ eUSCI_A LIN control
+UCA0IRTCTL=\$5D2! \ eUSCI_A IrDA transmit control
+UCA0IRRCTL=\$5D3! \ eUSCI_A IrDA receive control
+UCA0IE=\$5DA! \ eUSCI_A interrupt enable
+UCA0IFG=\$5DC! \ eUSCI_A interrupt flags
+UCA0IV=\$5DE! \ eUSCI_A interrupt vector word
+
+UCA1CTLW0=\$5E0! \ eUSCI_A control word 0
+UCA1CTLW1=\$5E2! \ eUSCI_A control word 1
+UCA1BRW=\$5E6!
+UCA1BR0=\$5E6! \ eUSCI_A baud rate 0
+UCA1BR1=\$5E7! \ eUSCI_A baud rate 1
+UCA1MCTLW=\$5E8! \ eUSCI_A modulation control
+UCA1STAT=\$5EA! \ eUSCI_A status
+UCA1RXBUF=\$5EC! \ eUSCI_A receive buffer
+UCA1TXBUF=\$5EE! \ eUSCI_A transmit buffer
+UCA1ABCTL=\$5F0! \ eUSCI_A LIN control
+UCA1IRTCTL=\$5F2! \ eUSCI_A IrDA transmit control
+UCA1IRRCTL=\$5F3! \ eUSCI_A IrDA receive control
+UCA1IE=\$5FA! \ eUSCI_A interrupt enable
+UCA1IFG=\$5FC! \ eUSCI_A interrupt flags
+UCA1IV=\$5FE! \ eUSCI_A interrupt vector word
+
+UCA2CTLW0=\$600! \ eUSCI_A control word 0
+UCA2CTLW1=\$602! \ eUSCI_A control word 1
+UCA2BRW=\$606!
+UCA2BR0=\$606! \ eUSCI_A baud rate 0
+UCA2BR1=\$607! \ eUSCI_A baud rate 1
+UCA2MCTLW=\$608! \ eUSCI_A modulation control
+UCA2STAT=\$60A! \ eUSCI_A status
+UCA2RXBUF=\$60C! \ eUSCI_A receive buffer
+UCA2TXBUF=\$60E! \ eUSCI_A transmit buffer
+UCA2ABCTL=\$610! \ eUSCI_A LIN control
+UCA2IRTCTL=\$612! \ eUSCI_A IrDA transmit control
+UCA2IRRCTL=\$613! \ eUSCI_A IrDA receive control
+UCA2IE=\$61A! \ eUSCI_A interrupt enable
+UCA2IFG=\$61C! \ eUSCI_A interrupt flags
+UCA2IV=\$61E! \ eUSCI_A interrupt vector word
+
+UCA3CTLW0=\$620! \ eUSCI_A control word 0
+UCA3CTLW1=\$622! \ eUSCI_A control word 1
+UCA3BRW=\$626!
+UCA3BR0=\$626! \ eUSCI_A baud rate 0
+UCA3BR1=\$627! \ eUSCI_A baud rate 1
+UCA3MCTLW=\$628! \ eUSCI_A modulation control
+UCA3STAT=\$62A! \ eUSCI_A status
+UCA3RXBUF=\$62C! \ eUSCI_A receive buffer
+UCA3TXBUF=\$62E! \ eUSCI_A transmit buffer
+UCA3ABCTL=\$630! \ eUSCI_A LIN control
+UCA3IRTCTL=\$632! \ eUSCI_A IrDA transmit control
+UCA3IRRCTL=\$633! \ eUSCI_A IrDA receive control
+UCA3IE=\$63A! \ eUSCI_A interrupt enable
+UCA3IFG=\$63C! \ eUSCI_A interrupt flags
+UCA3IV=\$63E! \ eUSCI_A interrupt vector word
+
+UCB0CTLW0=\$640! \ eUSCI_B control word 0
+UCB0CTLW1=\$642! \ eUSCI_B control word 1
+UCB0BRW=\$646!
+UCB0BR0=\$646! \ eUSCI_B bit rate 0
+UCB0BR1=\$647! \ eUSCI_B bit rate 1
+UCB0STATW=\$648! \ eUSCI_B status word
+UCBCNT0=\$649! \ eUSCI_B hardware count
+UCB0TBCNT=\$64A! \ eUSCI_B byte counter threshold
+UCB0RXBUF=\$64C! \ eUSCI_B receive buffer
+UCB0TXBUF=\$64E! \ eUSCI_B transmit buffer
+UCB0I2COA0=\$654! \ eUSCI_B I2C own address 0
+UCB0I2COA1=\$656! \ eUSCI_B I2C own address 1
+UCB0I2COA2=\$658! \ eUSCI_B I2C own address 2
+UCB0I2COA3=\$65A! \ eUSCI_B I2C own address 3
+UCB0ADDRX=\$65C! \ eUSCI_B received address
+UCB0ADDMASK=\$65E! \ eUSCI_B address mask
+UCB0I2CSA=\$660! \ eUSCI I2C slave address
+UCB0IE=\$66A! \ eUSCI interrupt enable
+UCB0IFG=\$66C! \ eUSCI interrupt flags
+UCB0IV=\$66E! \ eUSCI interrupt vector word
+
+UCB1CTLW0=\$680! \ eUSCI_B control word 0
+UCB1CTLW1=\$682! \ eUSCI_B control word 1
+UCB1BRW=\$686!
+UCB1BR0=\$686! \ eUSCI_B bit rate 0
+UCB1BR1=\$687! \ eUSCI_B bit rate 1
+UCB1STATW=\$688! \ eUSCI_B status word
+UCB1NT0=\$689! \ eUSCI_B hardware count
+UCB1TBCNT=\$68A! \ eUSCI_B byte counter threshold
+UCB1RXBUF=\$68C! \ eUSCI_B receive buffer
+UCB1TXBUF=\$68E! \ eUSCI_B transmit buffer
+UCB1I2COA0=\$694! \ eUSCI_B I2C own address 0
+UCB1I2COA1=\$696! \ eUSCI_B I2C own address 1
+UCB1I2COA2=\$698! \ eUSCI_B I2C own address 2
+UCB1I2COA3=\$69A! \ eUSCI_B I2C own address 3
+UCB1ADDRX=\$69C! \ eUSCI_B received address
+UCB1ADDMASK=\$69E! \ eUSCI_B address mask
+UCB1I2CSA=\$6A0! \ eUSCI I2C slave address
+UCB1IE=\$6AA! \ eUSCI interrupt enable
+UCB1IFG=\$6AC! \ eUSCI interrupt flags
+UCB1IV=\$6AE! \ eUSCI interrupt vector word
+
+UCB2CTLW0=\$6C0! \ eUSCI_B control word 0
+UCB2CTLW1=\$6C2! \ eUSCI_B control word 1
+UCB2BRW=\$6C6!
+UCB2BR0=\$6C6! \ eUSCI_B bit rate 0
+UCB2BR1=\$6C7! \ eUSCI_B bit rate 1
+UCB2STATW=\$6C8! \ eUSCI_B status word
+UCB2NT0=\$6C9! \ eUSCI_B hardware count
+UCB2TBCNT=\$6CA! \ eUSCI_B byte counter threshold
+UCB2RXBUF=\$6CC! \ eUSCI_B receive buffer
+UCB2TXBUF=\$6CE! \ eUSCI_B transmit buffer
+UCB2I2COA0=\$6D4! \ eUSCI_B I2C own address 0
+UCB2I2COA1=\$6D6! \ eUSCI_B I2C own address 1
+UCB2I2COA2=\$6D8! \ eUSCI_B I2C own address 2
+UCB2I2COA3=\$6DA! \ eUSCI_B I2C own address 3
+UCB2ADDRX=\$6DC! \ eUSCI_B received address
+UCB2ADDMASK=\$6DE! \ eUSCI_B address mask
+UCB2I2CSA=\$6E0! \ eUSCI I2C slave address
+UCB2IE=\$6EA! \ eUSCI interrupt enable
+UCB2IFG=\$6EC! \ eUSCI interrupt flags
+UCB2IV=\$6EE! \ eUSCI interrupt vector word
+
+UCB3CTLW0=\$700! \ eUSCI_B control word 0
+UCB3CTLW1=\$702! \ eUSCI_B control word 1
+UCB3BRW=\$706!
+UCB3BR0=\$706! \ eUSCI_B bit rate 0
+UCB3BR1=\$707! \ eUSCI_B bit rate 1
+UCB3STATW=\$708! \ eUSCI_B status word
+UCB3NT0=\$709! \ eUSCI_B hardware count
+UCB3TBCNT=\$70A! \ eUSCI_B byte counter threshold
+UCB3RXBUF=\$70C! \ eUSCI_B receive buffer
+UCB3TXBUF=\$70E! \ eUSCI_B transmit buffer
+UCB3I2COA0=\$714! \ eUSCI_B I2C own address 0
+UCB3I2COA1=\$716! \ eUSCI_B I2C own address 1
+UCB3I2COA2=\$718! \ eUSCI_B I2C own address 2
+UCB3I2COA3=\$71A! \ eUSCI_B I2C own address 3
+UCB3ADDRX=\$71C! \ eUSCI_B received address
+UCB3ADDMASK=\$71E! \ eUSCI_B address mask
+UCB3I2CSA=\$720! \ eUSCI I2C slave address
+UCB3IE=\$72A! \ eUSCI interrupt enable
+UCB3IFG=\$72C! \ eUSCI interrupt flags
+UCB3IV=\$72E! \ eUSCI interrupt vector word
+
+UCTXACK=\$20!
+UCTR=\$10!
+
+TA4CTL=\$7C0! \ TA4 control
+TA4CCTL0=\$7C2! \ Capture/compare control 0
+TA4CCTL1=\$7C4! \ Capture/compare control 1
+TA4R=\$7D0! \ TA4 counter register
+TA4CCR0=\$7D2! \ Capture/compare register 0
+TA4CCR1=\$7D4! \ Capture/compare register 1
+TA4EX0=\$7E0! \ TA4 expansion register 0
+TA4IV=\$7EE! \ TA4 interrupt vector
+
+
+
+
+
+
+
+ADC12CTL0=\$800! \ ADC12_B Control 0
+ADC12CTL1=\$802! \ ADC12_B Control 1
+ADC12CTL2=\$804! \ ADC12_B Control 2
+ADC12CTL3=\$806! \ ADC12_B Control 3
+ADC12LO=\$808! \ ADC12_B Window Comparator Low Threshold Register
+ADC12HI=\$80A! \ ADC12_B Window Comparator High Threshold Register
+ADC12IFGR0=\$80C! \ ADC12_B Interrupt Flag Register 0
+ADC12IFGR1=\$80E! \ ADC12_B Interrupt Flag Register 1
+ADC12IFGR2=\$810! \ ADC12_B Interrupt Flag Register 2
+ADC12IER0=\$812! \ ADC12_B Interrupt Enable Register 0
+ADC12IER1=\$814! \ ADC12_B Interrupt Enable Register 1
+ADC12IER2=\$816! \ ADC12_B Interrupt Enable Register 2
+ADC12IV=\$818! \ ADC12_B Interrupt Vector
+ADC12MCTL0=\$820! \ ADC12_B Memory Control 0
+ADC12MCTL1=\$822! \ ADC12_B Memory Control 1
+ADC12MCTL2=\$824! \ ADC12_B Memory Control 2
+ADC12MCTL3=\$826! \ ADC12_B Memory Control 3
+ADC12MCTL4=\$828! \ ADC12_B Memory Control 4
+ADC12MCTL5=\$82A! \ ADC12_B Memory Control 5
+ADC12MCTL6=\$82C! \ ADC12_B Memory Control 6
+ADC12MCTL7=\$82E! \ ADC12_B Memory Control 7
+ADC12MCTL8=\$830! \ ADC12_B Memory Control 8
+ADC12MCTL9=\$832! \ ADC12_B Memory Control 9
+ADC12MCTL10=\$834! \ ADC12_B Memory Control 10
+ADC12MCTL11=\$836! \ ADC12_B Memory Control 11
+ADC12MCTL12=\$838! \ ADC12_B Memory Control 12
+ADC12MCTL13=\$83A! \ ADC12_B Memory Control 13
+ADC12MCTL14=\$83C! \ ADC12_B Memory Control 14
+ADC12MCTL15=\$83E! \ ADC12_B Memory Control 15
+ADC12MCTL16=\$840! \ ADC12_B Memory Control 16
+ADC12MCTL17=\$842! \ ADC12_B Memory Control 17
+ADC12MCTL18=\$844! \ ADC12_B Memory Control 18
+ADC12MCTL19=\$846! \ ADC12_B Memory Control 19
+ADC12MCTL20=\$848! \ ADC12_B Memory Control 20
+ADC12MCTL21=\$84A! \ ADC12_B Memory Control 21
+ADC12MCTL22=\$84C! \ ADC12_B Memory Control 22
+ADC12MCTL23=\$84E! \ ADC12_B Memory Control 23
+ADC12MCTL24=\$850! \ ADC12_B Memory Control 24
+ADC12MCTL25=\$852! \ ADC12_B Memory Control 25
+ADC12MCTL26=\$854! \ ADC12_B Memory Control 26
+ADC12MCTL27=\$856! \ ADC12_B Memory Control 27
+ADC12MCTL28=\$858! \ ADC12_B Memory Control 28
+ADC12MCTL29=\$85A! \ ADC12_B Memory Control 29
+ADC12MCTL30=\$85C! \ ADC12_B Memory Control 30
+ADC12MCTL31=\$85E! \ ADC12_B Memory Control 31
+ADC12MEM0=\$860! \ ADC12_B Memory 0
+ADC12MEM1=\$862! \ ADC12_B Memory 1
+ADC12MEM2=\$864! \ ADC12_B Memory 2
+ADC12MEM3=\$866! \ ADC12_B Memory 3
+ADC12MEM4=\$868! \ ADC12_B Memory 4
+ADC12MEM5=\$86A! \ ADC12_B Memory 5
+ADC12MEM6=\$86C! \ ADC12_B Memory 6
+ADC12MEM7=\$86E! \ ADC12_B Memory 7
+ADC12MEM8=\$870! \ ADC12_B Memory 8
+ADC12MEM9=\$872! \ ADC12_B Memory 9
+ADC12MEM10=\$874! \ ADC12_B Memory 10
+ADC12MEM11=\$876! \ ADC12_B Memory 11
+ADC12MEM12=\$878! \ ADC12_B Memory 12
+ADC12MEM13=\$87A! \ ADC12_B Memory 13
+ADC12MEM14=\$87C! \ ADC12_B Memory 14
+ADC12MEM15=\$87E! \ ADC12_B Memory 15
+ADC12MEM16=\$880! \ ADC12_B Memory 16
+ADC12MEM17=\$882! \ ADC12_B Memory 17
+ADC12MEM18=\$884! \ ADC12_B Memory 18
+ADC12MEM19=\$886! \ ADC12_B Memory 19
+ADC12MEM20=\$888! \ ADC12_B Memory 20
+ADC12MEM21=\$88A! \ ADC12_B Memory 21
+ADC12MEM22=\$88C! \ ADC12_B Memory 22
+ADC12MEM23=\$88E! \ ADC12_B Memory 23
+ADC12MEM24=\$890! \ ADC12_B Memory 24
+ADC12MEM25=\$892! \ ADC12_B Memory 25
+ADC12MEM26=\$894! \ ADC12_B Memory 26
+ADC12MEM27=\$896! \ ADC12_B Memory 27
+ADC12MEM28=\$898! \ ADC12_B Memory 28
+ADC12MEM29=\$89A! \ ADC12_B Memory 29
+ADC12MEM30=\$89C! \ ADC12_B Memory 30
+ADC12MEM31=\$89E! \ ADC12_B Memory 31
+
+
+CDCTL0=\$8C0! \ Comparator_E control register 0
+CDCTL1=\$8C2! \ Comparator_E control register 1
+CDCTL2=\$8C4! \ Comparator_E control register 2
+CDCTL3=\$8C6! \ Comparator_E control register 3
+CDINT=\$8CC! \ Comparator_E interrupt register
+CDIV=\$8CE! \ Comparator_E interrupt vector word
+
+CRC32DIW0=\$980! \ CRC32 data input
+CRC32DIRBW0=\$986! \ CRC32 data input reverse
+CRC32INIRESW0=\$988! \ CRC32 initialization and result word 0
+CRC32INIRESW1=\$98A! \ CRC32 initialization and result word 1
+CRC32RESRW1=\$98! \ CRC32 result reverse word 1
+CRC32RESRW1=\$98E! \ CRC32 result reverse word 0
+CRC16DIW0=\$990! \ CRC16 data input
+CRC16DIRBW0=\$996! \ CRC16 data input reverse
+CRC16INIRESW0=\$99! \ CRC16 initialization and result word 0
+CRC16RESRW1=\$99E! \ CRC16 result reverse word 0
+
+
+AESACTL0=\$9C0! \ AES accelerator control register 0
+AESASTAT=\$9C4! \ AES accelerator status register
+AESAKEY=\$9C6! \ AES accelerator key register
+AESADIN=\$9C8! \ AES accelerator data in register
+AESADOUT=\$9CA! \ AES accelerator data out register
+AESAXDIN=\$9CC! \ AES accelerator XORed data in register
+AESAXIN =\$9CE! \ AES accelerator XORed data in register (no trigger)
+
+
+LCDCCTL0=\$A00! \ LCD_C control register 0
+LCDCCTL1=\$A02! \ LCD_C control register 1
+LCDCBLKCTL=\$A04! \ LCD_C blinking control register
+LCDCMEMCTL=\$A06! \ LCD_C memory control register
+LCDCVCTL=\$A08! \ LCD_C voltage control register
+LCDCPCTL0=\$A0A! \ LCD_C port control 0
+LCDCPCTL1=\$A0C! \ LCD_C port control 1
+LCDCPCTL2=\$A0E! \ LCD_C port control 2
+LCDCCPCTL=\$A12! \ LCD_C charge pump ctrl register
+LCDCIV=\$A1E! \ LCD_C interrupt vector
+LCDM1=\$A20! \ LCD_C memory 1
+LCDM2=\$A21! \ LCD_C memory 2
+LCDM3=\$A22! \ LCD_C memory 3
+LCDM4=\$A23! \ LCD_C memory 4
+LCDM5=\$A24! \ LCD_C memory 5
+LCDM6=\$A25! \ LCD_C memory 6
+LCDM7=\$A26! \ LCD_C memory 7
+LCDM8=\$A27! \ LCD_C memory 8
+LCDM9=\$A28! \ LCD_C memory 9
+LCDM10=\$A29! \ LCD_C memory 10
+LCDM11=\$A2A! \ LCD_C memory 11
+LCDM12=\$A2B! \ LCD_C memory 12
+LCDM13=\$A2C! \ LCD_C memory 13
+LCDM14=\$A2D! \ LCD_C memory 14
+LCDM15=\$A2E! \ LCD_C memory 15
+LCDM16=\$A2F! \ LCD_C memory 16
+LCDM17=\$A30! \ LCD_C memory 17
+LCDM18=\$A31! \ LCD_C memory 18
+LCDM19=\$A32! \ LCD_C memory 19
+LCDM20=\$A33! \ LCD_C memory 20
+LCDM21=\$A34! \ LCD_C memory 21
+LCDM22=\$A35! \ LCD_C memory 22
+LCDM23=\$A36! \ LCD_C memory 23
+LCDM24=\$A37! \ LCD_C memory 24
+LCDM25=\$A38! \ LCD_C memory 25
+LCDM26=\$A39! \ LCD_C memory 26
+LCDM27=\$A3A! \ LCD_C memory 27
+LCDM28=\$A3B! \ LCD_C memory 28
+LCDM29=\$A3C! \ LCD_C memory 29
+LCDM30=\$A3D! \ LCD_C memory 30
+LCDM31=\$A3E! \ LCD_C memory 31
+LCDM32=\$A3F! \ LCD_C memory 32
+LCDM33=\$A40! \ LCD_C memory 33
+LCDM34=\$A41! \ LCD_C memory 34
+LCDM35=\$A42! \ LCD_C memory 35
+LCDM36=\$A43! \ LCD_C memory 36
+LCDM37=\$A44! \ LCD_C memory 37
+LCDM38=\$A45! \ LCD_C memory 38
+LCDM39=\$A46! \ LCD_C memory 39
+LCDM40=\$A47! \ LCD_C memory 40
+LCDM41=\$A48! \ LCD_C memory 41
+LCDM42=\$A49! \ LCD_C memory 42
+LCDM43=\$A4A! \ LCD_C memory 43
+LCDBM1=\$A40! \ LCD_C blinking memory 1
+LCDBM2=\$A41! \ LCD_C blinking memory 2
+LCDBM3=\$A42! \ LCD_C blinking memory 3
+LCDBM4=\$A43! \ LCD_C blinking memory 4
+LCDBM5=\$A44! \ LCD_C blinking memory 5
+LCDBM6=\$A45! \ LCD_C blinking memory 6
+LCDBM7=\$A46! \ LCD_C blinking memory 7
+LCDBM8=\$A47! \ LCD_C blinking memory 8
+LCDBM9=\$A48! \ LCD_C blinking memory 9
+LCDBM10=\$A49! \ LCD_C blinking memory 10
+LCDBM11=\$A4A! \ LCD_C blinking memory 11
+LCDBM12=\$A4B! \ LCD_C blinking memory 12
+LCDBM13=\$A4C! \ LCD_C blinking memory 13
+LCDBM14=\$A4D! \ LCD_C blinking memory 14
+LCDBM15=\$A4E! \ LCD_C blinking memory 15
+LCDBM16=\$A4F! \ LCD_C blinking memory 16
+LCDBM17=\$A50! \ LCD_C blinking memory 17
+LCDBM18=\$A51! \ LCD_C blinking memory 18
+LCDBM19=\$A52! \ LCD_C blinking memory 19
+LCDBM20=\$A53! \ LCD_C blinking memory 20
+LCDBM21=\$A54! \ LCD_C blinking memory 21
+LCDBM22=\$A55! \ LCD_C blinking memory 22
+
+
+LEASCCAP=\$A80! \ LEASC capability
+LEASCCNF0=\$A84! \ Configuration 0
+LEASCCNF1=\$A88! \ Configuration 1
+LEASCCNF2=\$A8C! \ Configuration 2
+LEASCMB=\$A90! \ Memory bottom
+LEASCMT=\$A94! \ Memory top
+LEASCCMA=\$A98! \ Code memory access
+LEASCCMCTL=\$A9C! \ Code memory control
+LEASSCMDSTAT=\$AA8! \ LEA command status
+LEASCS1STAT=\$AAC! \ LEA source 1 status
+LEASCS0STAT=\$AB0! \ LEA source 0 status
+LEASCDSTSTAT=\$AB4! \ LEA result status
+LEASCPMCTL=\$AC0! \ Control
+LEASCPMDST=\$AC4! \ Result
+LEASCPMS1=\$AC8! \ Source 1
+LEASCPMS0=\$ACC! \ Source 0
+LEASCPMCB=\$AD0! \ Command buffer
+LEASCIFGSET=\$AF0! \ Interrupt flag and set
+LEASCIE=\$AF4! \ Interrupt enable
+LEASCIFG=\$AF8! \ Interrupt flag and clr
+LEASCIV=\$AFC! \ Interrupt vector
+
+
+ESIDEBUG1=\$D00! \ ESI debug register 1
+ESIDEBUG2=\$D02! \ ESI debug register 2
+ESIDEBUG3=\$D04! \ ESI debug register 3
+ESIDEBUG4=\$D06! \ ESI debug register 4
+ESIDEBUG5=\$D08! \ ESI debug register 5
+ESICNT0=\$D10! \ ESI PSM counter 0
+ESICNT1=\$D12! \ ESI PSM counter 1
+ESICNT2=\$D14! \ ESI PSM counter 2
+ESICNT3=\$D16! \ ESI oscillator counter register
+ESIIV=\$D1A! \ ESI interrupt vector
+ESIINT1=\$D1C! \ ESI interrupt register 1
+ESIINT2=\$D1E! \ ESI interrupt register 2
+ESIAFE=\$D20! \ ESI AFE control register
+ESIPPU=\$D22! \ ESI PPU control register
+ESITSM=\$D24! \ ESI TSM control register
+ESIPSM=\$D26! \ ESI PSM control register
+ESIOSC=\$D28! \ ESI oscillator control register
+ESICTL=\$D2A! \ ESI control register
+ESITHR1=\$D2C! \ ESI PSM counter threshold register 1
+ESITHR2=\$D2E! \ ESI PSM counter threshold register 2
+ESIADMEM1=\$D30! \ ESI A/D conversion memory 1
+ESIADMEM2=\$D32! \ ESI A/D conversion memory 2
+ESIADMEM3=\$D34! \ ESI A/D conversion memory 3
+ESIADMEM4=\$D36! \ ESI A/D conversion memory 4
+ESIDAC1R0=\$D40! \ ESI DAC1 register 0
+ESIDAC1R1=\$D42! \ ESI DAC1 register 1
+ESIDAC1R2=\$D44! \ ESI DAC1 register 2
+ESIDAC1R3=\$D46! \ ESI DAC1 register 3
+ESIDAC1R4=\$D48! \ ESI DAC1 register 4
+ESIDAC1R5=\$D4A! \ ESI DAC1 register 5
+ESIDAC1R6=\$D4C! \ ESI DAC1 register 6
+ESIDAC1R7=\$D4E! \ ESI DAC1 register 7
+ESIDAC2R0=\$D50! \ ESI DAC2 register 0
+ESIDAC2R1=\$D52! \ ESI DAC2 register 1
+ESIDAC2R2=\$D54! \ ESI DAC2 register 2
+ESIDAC2R3=\$D56! \ ESI DAC2 register 3
+ESIDAC2R4=\$D58! \ ESI DAC2 register 4
+ESIDAC2R5=\$D5A! \ ESI DAC2 register 5
+ESIDAC2R6=\$D5C! \ ESI DAC2 register 6
+ESIDAC2R7=\$D5E! \ ESI DAC2 register 7
+ESITSM0=\$D60! \ ESI TSM 0
+ESITSM1=\$D62! \ ESI TSM 1
+ESITSM2=\$D64! \ ESI TSM 2
+ESITSM3=\$D66! \ ESI TSM 3
+ESITSM4=\$D68! \ ESI TSM 4
+ESITSM5=\$D6A! \ ESI TSM 5
+ESITSM6=\$D6C! \ ESI TSM 6
+ESITSM7=\$D6E! \ ESI TSM 7
+ESITSM8=\$D70! \ ESI TSM 8
+ESITSM9=\$D72! \ ESI TSM 9
+ESITSM10=\$D74! \ ESI TSM 10
+ESITSM11=\$D76! \ ESI TSM 11
+ESITSM12=\$D78! \ ESI TSM 12
+ESITSM13=\$D7A! \ ESI TSM 13
+ESITSM14=\$D7C! \ ESI TSM 14
+ESITSM15=\$D7E! \ ESI TSM 15
+ESITSM16=\$D80! \ ESI TSM 16
+ESITSM17=\$D82! \ ESI TSM 17
+ESITSM18=\$D84! \ ESI TSM 18
+ESITSM19=\$D86! \ ESI TSM 19
+ESITSM20=\$D88! \ ESI TSM 20
+ESITSM21=\$D8A! \ ESI TSM 21
+ESITSM22=\$D8C! \ ESI TSM 22
+ESITSM23=\$D8E! \ ESI TSM 23
+ESITSM24=\$D90! \ ESI TSM 24
+ESITSM25=\$D92! \ ESI TSM 25
+ESITSM26=\$D94! \ ESI TSM 26
+ESITSM27=\$D96! \ ESI TSM 27
+ESITSM28=\$D98! \ ESI TSM 28
+ESITSM29=\$D9A! \ ESI TSM 29
+ESITSM30=\$D9C! \ ESI TSM 30
+ESITSM31=\$D9E! \ ESI TSM 31
+
+
+ESI_RAM=\$E00!
\ No newline at end of file
--- /dev/null
+!MSP430FR5x6x_FastForth.pat
+
+! =================================================
+! MSP430FR5x6x DEVICES HAVE SPECIFIC RAM ADDRESSES!
+! =================================================
+
+
+! ============================================
+! SR bits :
+! ============================================
+\#C=\#1! = SR(0) Carry flag
+\#Z=\#2! = SR(1) Zero flag
+\#N=\#4! = SR(2) Negative flag
+GIE=8! = SR(3) Enable Int
+CPUOFF=\$10! = SR(4) CPUOFF
+OSCOFF=\$20! = SR(5) OSCOFF
+SCG0=\$40! = SR(6) SCG0
+SCG1=\$80! = SR(7) SCG1
+V=\$100! = SR(8) oVerflow flag
+UF1=\$200! = SR(9) User Flag 1 used by ?NUMBER --> INTERPRET --> LITERAL to process double numbers, else free for use.
+UF2=\$400! = SR(10) User Flag 2
+UF3=\$800! = SR(11) User Flag 3
+
+C\@=C\@
+C\!=C\!
+C\,=C\,
+
+! ============================================
+! PORTx, Reg bits :
+! ============================================
+BIT0=1!
+BIT1=2!
+BIT2=4!
+BIT3=8!
+BIT4=\$10!
+BIT5=\$20!
+BIT6=\$40!
+BIT7=\$80!
+BIT8=\$100!
+BIT9=\$200!
+BIT10=\$400!
+BIT11=\$800!
+BIT12=\$1000!
+BIT13=\$2000!
+BIT14=\$4000!
+BIT15=\$8000!
+
+! ============================================
+! symbolic codes :
+! ============================================
+RET=MOV \@R1+,R0!
+NOP=MOV 0,R3! \ one word one cycle
+NOP2=\$3C00 ,! \ compile JMP 0: one word two cycles
+NOP3=MOV R0,R0! \ one word three cycles
+NEXT=MOV \@R13+,R0!
+
+
+
+! You can check the addresses below by comparing their values in DTCforthMSP430FRxxxx.lst
+! those addresses are usable with the symbolic assembler
+
+! ============================================
+! FastForth INFO(DCBA) memory map (256 bytes):
+! ============================================
+
+! ----------------------
+! KERNEL CONSTANTS
+! ----------------------
+INI_THREAD=\$1800! .word THREADS
+TERMINAL_INT=\$1802! .word TERMINAL_INT
+FREQ_KHZ=\$1804! .word FREQUENCY*1000
+HECTOBAUDS=\$1806! .word TERMINALBAUDRATE/100
+! ----------------------
+! SAVED VARIABLES
+! ----------------------
+SAVE_SYSRSTIV=\$1808! to enable SYSRSTIV read
+LPM_MODE=\$180A! LPM0+GIE is the default mode
+INIDP=\$180C! define RST_STATE, init by wipe
+INIVOC=\$180E! define RST_STATE, init by wipe
+
+XON=\$1810!
+XOFF=\$1812!
+
+ReadSectorWX=\$1814! call with W = SectorLO X = SectorHI
+WriteSectorWX=\$1816! call with W = SectorLO X = SectorHI
+
+
+! ============================================
+! FastForth RAM memory map (>= 2k):
+! ============================================
+LSATCK=\$1C00! \ leave stack, grow up
+PSTACK=\$1C80! \ parameter stack, grow down
+RSTACK=\$1CE0! \ Return stack, grow down
+PAD=\$1CE2! \ user scratch pad buffer, grow up
+TIB=\$1D38! \ Terminal input buffer, grow up
+BASE_HOLD=\$1DAA! \ BASE HOLD area, grow down
+
+! ----------------------
+! NOT SAVED VARIABLES
+! ----------------------
+
+HP=\$1DAA! HOLD ptr
+LEAVEPTR=\$1DAC! Leave-stack pointer, init by QUIT
+
+LAST_NFA=\$1DAE!
+LAST_THREAD=\$1DB0!
+LAST_CFA=\$1DB2!
+LAST_CSP=\$1DB4!
+
+STATE=\$1DB6! Interpreter state
+
+ASM_CURRENT=\$1DB8! preserve CURRENT when create assembler words
+OPCODE=\$1DBA! OPCODE adr
+ASMTYPE=\$1DBC! keep the opcode complement
+
+SOURCE_LEN=\$1DBE! len of input stream
+SOURCE_ADR=\$1DC0! adr of input stream
+\>IN=\$1DC2! >IN
+DP=\$1DC4! dictionary ptr
+LASTVOC=\$1DC6! keep VOC-LINK
+CURRENT=\$1DC8! CURRENT dictionnary ptr
+CONTEXT=\$1DCA! CONTEXT dictionnary space (8 CELLS)
+
+BASE=\$1DDA! numeric base, must be defined before first reset !
+CAPS=\$1DDC! CAPS ON/OFF flag, must be set to -1 before first reset !
+
+
+BUFFER=\$1E00! \ SD_Card buffer
+BUFEND=\$2000!
+
+! ---------------------------------------
+! FAT16 FileSystemInfos
+! ---------------------------------------
+FATtype=\$2002!
+BS_FirstSectorL=\$2004!
+BS_FirstSectorH=\$2006!
+OrgFAT1=\$2008!
+FATSize=\$200A!
+OrgFAT2=\$200C!
+OrgRootDir=\$200E!
+OrgClusters=\$2010! Sector of Cluster 0
+SecPerClus=\$2012!
+
+! ---------------------------------------
+! SD command
+! ---------------------------------------
+SD_CMD_FRM=\$2014! 6 bytes SD_CMDx inverted frame \${CRC,ll,LL,hh,HH,CMD}
+SD_CMD_FRM0=\$2014! CRC:ll word access
+SD_CMD_FRM1=\$2015! ll byte access
+SD_CMD_FRM2=\$2016! LL:hh word access
+SD_CMD_FRM3=\$2017! hh byte access
+SD_CMD_FRM4=\$2018! HH:CMD word access
+SD_CMD_FRM5=\$2019! CMD byte access
+SectorL=\$201A! 2 words
+SectorH=\$201C!
+
+! ---------------------------------------
+! BUFFER management
+! ---------------------------------------
+BufferPtr=\$201E!
+BufferLen=\$2020!
+
+! ---------------------------------------
+! FAT entry
+! ---------------------------------------
+ClusterL=\$2022! 16 bits wide (FAT16)
+ClusterH=\$2024! 16 bits wide (FAT16)
+NewClusterL=\$2026! 16 bits wide (FAT16)
+NewClusterH=\$2028! 16 bits wide (FAT16)
+FATsector=\$202A! not used
+CurFATsector=\$202C!
+
+! ---------------------------------------
+! DIR entry
+! ---------------------------------------
+DIRclusterL=\$202E! contains the Cluster of current directory ; 1 if FAT16 root directory
+DIRclusterH=\$2030! contains the Cluster of current directory ; 1 if FAT16 root directory
+EntryOfst=\$2032!
+pathname=\$2034! address of pathname string
+
+! ---------------------------------------
+! Handle Pointer
+! ---------------------------------------
+CurrentHdl=\$2036! contains the address of the last opened file structure, or 0
+
+! ---------------------------------------
+! Load file operation
+! ---------------------------------------
+SAVEtsLEN=\$2038! of previous ACCEPT
+SAVEtsPTR=\$203A! of previous ACCEPT
+MemSectorL=\$203C! double word current Sector of previous LOAD"ed file
+MemSectorH=\$203E!
+
+! ---------------------------------------
+! Handle structure
+! ---------------------------------------
+! three handle tokens :
+! token = 0 : free handle
+! token = 1 : file to read
+! token = 2 : file updated (write)
+! token =-1 : LOAD"ed file (source file)
+
+! offset values
+HDLW_PrevHDL=0! previous handle ; used by LOAD"
+HDLB_Token=2! token
+HDLB_ClustOfst=3! Current sector offset in current cluster (Byte)
+HDLL_DIRsect=4! Dir SectorL (Long)
+HDLH_DIRsect=6!
+HDLW_DIRofst=8! BUFFER offset of Dir entry
+HDLL_FirstClus=10! File First ClusterLo (identify the file)
+HDLH_FirstClus=12! File First ClusterHi (byte)
+HDLL_CurClust=14! Current ClusterLo
+HDLH_CurClust=16! Current ClusterHi (T as 3Th byte)
+HDLL_CurSize=18! written size / not yet read size (Long)
+HDLH_CurSize=20! written size / not yet read size (Long)
+HDLW_BUFofst=22! BUFFER offset ; used by LOAD" and by WRITE"
+
+HandleMax=8!
+HandleLenght=24!
+
+!OpenedFirstFile ; "openedFile" structure
+FirstHandle=\$2040!
+HandleOutOfBound=\$2100!
+
+SDIB=\$2100!
\ No newline at end of file
--- /dev/null
+!MSP430fr6989.pat
+
+@define{@read{/config/gema/MSP430FR5x6x.pat}}
+
+
+! ----------------------------------------------
+! MSP430FR6989 MEMORY MAP
+! ----------------------------------------------
+! 0000-0005 = reserved ROM
+! 0006-001F = tiny RAM 26 bytes
+! 0020-0FFF = peripherals (4 KB)
+! 1000-17FF = ROM bootstrap loader BSL0..3 (4x512 B)
+! 1800-187F = FRAM info D (128 B)
+! 1880-18FF = FRAM info C (128 B)
+! 1900-197F = FRAM info B (128 B)
+! 1980-19FF = FRAM info A (128 B)
+! 1A00-1AFF = TLV device descriptor info (FRAM 256 B)
+! 1B00-1BFF = ROM boot memory
+! 1C00-23FF = RAM (2 KB)
+! 2000-C1FF = unused (41472 B)
+! C200-FF7F = code memory (FRAM 15743 B)
+! FF80-FFFF = interrupt vectors (FRAM 127 B)
+! ----------------------------------------------
+INFOSTART=\$1800!
+INFODSTART=\$1800!
+INFODEND=\$187F!
+INFOCSTART=\$1880!
+INFOCEND=\$18FF!
+INFOBSTART=\$1900!
+INFOBEND=\$197F!
+INFOASTART=\$1980!
+INFOAEND=\$19FF!
+TLVSTAT=\$1A00! Device Descriptor Info (Tag-Lenght-Value)
+TLVEND=\$1AFF!
+RAMSTART=\$1C00!
+RAMEND=\$23FF!
+PROGRAMSTART=\$4400! Code space start
+SIGNATURES=\$FF80! JTAG/BSL signatures
+JTAG_SIG1=\$FF80! if 0 (electronic fuse=0) enable JTAG/SBW; must be reset by wipe.
+JTAG_SIG2=\$FF82! if JTAG_SIG1=\$AAAA, length of password string @ JTAG_PASSWORD
+BSL_SIG1=\$FF84!
+BSL_SIG2=\$FF86!
+JTAG_PASSWORD=\$FF88! 256 bits
+INTVECT=\$FFC6! FFCE-FFFF
+BSL_PASSWORD=\$FFE0! 256 bits
+
+
+AES_Vec=\$FFC6!
+RTC_Vec=\$FFC8!
+LCD_Vec=\$FFCA!
+P4_Vec=\$FFCC!
+P3_Vec=\$FFCE!
+TA3_x_Vec=\$FFD0!
+TA3_0_Vec=\$FFD2!
+P2_Vec=\$FFD4!
+TA2_x_Vec=\$FFD6!
+TA2_0_Vec=\$FFD8!
+P1_Vec=\$FFDA!
+TA1_x_Vec=\$FFDC!
+TA1_0_Vec=\$FFDE!
+DMA_Vec=\$FFE0!
+eUSCI_B1_Vec=\$FFE2!
+eUSCI_A1_Vec=\$FFE4!
+TA0_x_Vec=\$FFE6!
+TA0_0_Vec=\$FFE8!
+ADC12_B_Vec=\$FFEA!
+eUSCI_B0_Vec=\$FFEC!
+eUSCI_A0_Vec=\$FFEE!
+ESI_Vec=\$FFF0!
+WDT_Vec=\$FFF2!
+TB0_x_Vec=\$FFF4!
+TB0_0_Vec=\$FFF6!
+COMP_E_Vec=\$FFF8!
+U_NMI_Vec=\$FFFA!
+S_NMI_Vec=\$FFFC!
+RST_Vec=\$FFFE!
+
--- /dev/null
+
+! remove comments
+\\*\n=! remove line beginning with \
+\s\\*\n=\n
+
+! remove some lines...
+\n=\N
--- /dev/null
+# SciTEDirectoriy.properties
+# For Windows, place in your directory project folder
+# Documentation at http://www.scintilla.org/SciTEDoc.html
+
+
+# Globals
+buffers.zorder.switching=1
+
+# Window sizes and visibility
+if PLAT_WIN
+ position.left=-1
+ position.top=0
+if PLAT_GTK
+ position.left=5
+ position.top=22
+position.width=1000
+position.height=768
+position.maximize=1
+#position.tile=1
+#full.screen.hides.menu=1
+minimize.to.tray=0
+split.vertical=1
+output.horizontal.size=400
+output.vertical.size=600
+output.initial.hide=1
+#horizontal.scrollbar=0
+#horizontal.scroll.width=10000
+#horizontal.scroll.width.tracking=0
+#output.horizontal.scrollbar=0
+#output.horizontal.scroll.width=10000
+#output.horizontal.scroll.width.tracking=0
+#output.scroll=0
+error.select.line=1
+#end.at.last.line=0
+tabbar.visible=1
+#tabbar.hide.one=1
+tabbar.multiline=0
+toolbar.visible=1
+#toolbar.detachable=1
+#toolbar.usestockicons=1
+#menubar.detachable=1
+#undo.redo.lazy=1
+statusbar.visible=1
+#fileselector.width=800
+#fileselector.height=600
+#fileselector.show.hidden=1
+magnification=0
+output.magnification=-4
+
+# Sizes and visibility in edit pane
+line.margin.visible=1
+line.margin.width=4
+margin.width=16
+fold.margin.width=0
+#fold.margin.colour=#00FF00
+#fold.margin.highlight.colour=#0000FF
+blank.margin.left=20
+#blank.margin.right=4
+buffered.draw=1
+#two.phase.draw=0
+use.palette=0
+
+
+#Element styles
+
+
+#view.eol=1
+#control.char.symbol=.
+caret.period=500
+view.whitespace=0
+view.indentation.whitespace=1
+view.indentation.guides=0
+view.indentation.examine=3
+highlight.indentation.guides=1
+caret.fore=#FF0000
+#caret.additional.blinks=0
+caret.width=3
+caret.line.back=#222222
+calltip.back=#FFF0FE
+edge.column=128
+edge.mode=1
+edge.colour=#C0DCC0
+braces.check=1
+braces.sloppy=1
+
+# black background
+selection.fore=#000000
+selection.alpha=256
+selection.back=#808080
+#selection.additional.fore=#0000A0
+#selection.additional.back=#000080
+#selection.additional.alpha=20
+#selection.multiple=0
+#selection.additional.typing=0
+#virtual.space=3
+#rectangular.selection.modifier=4
+#whitespace.fore=#FFFFFF
+#whitespace.back=#FFF0F0
+#error.marker.fore=#0000A0
+#error.marker.back=#DADAFF
+#bookmark.fore=#808000
+#bookmark.back=#FFFFA0
+#bookmark.alpha=
+#find.mark=#0000FF
+#highlight.current.word=1
+#highlight.current.word.by.style=1
+#highlight.current.word.colour=#00D040
+#indicators.alpha=63
+#indicators.under=1
+
+
+# Scripting
+ext.lua.startup.script=$(SciteUserHome)/SciTEStartup.lua
+ext.lua.auto.reload=1
+#ext.lua.reset=1
+
+
+# Checking
+are.you.sure=1
+#are.you.sure.for.build=1
+#save.all.for.build=1
+quit.on.close.last=1
+load.on.activate=1
+#save.on.deactivate=1
+are.you.sure.on.reload=1
+reload.preserves.undo=1
+#check.if.already.open=1
+#temp.files.sync.load=1
+default.file.ext=.txt
+#source.default.extensions=.h|.cxx|.bat
+title.full.path=1
+title.show.buffers=1
+pathbar.visible=1
+#save.recent=1
+#save.session=1
+#session.bookmarks=1
+#session.folds=1
+#save.position=1
+#open.dialog.in.file.directory=1
+#strip.trailing.spaces=1
+#ensure.final.line.end=1
+#ensure.consistent.line.ends=1
+#save.deletes.first=1
+#save.check.modified.time=1
+buffers=40
+buffers.zorder.switching=1
+#api.*.cxx=d:\api\w.api
+#import locale
+#locale.properties=locale.fr.properties
+#win95.death.delay=1000
+#translation.missing=***
+#read.only=1
+#max.file.size=1
+
+# Indentation
+tabsize=4
+indent.size=4
+use.tabs=0
+#indent.auto=1
+indent.automatic=0
+indent.opening=0
+indent.closing=0
+#tab.indents=0
+#backspace.unindents=0
+
+# Wrapping of long lines
+#wrap=1
+#wrap.style=2
+cache.layout=2
+#output.wrap=1
+#output.cache.layout=3
+#wrap.visual.flags=3
+#wrap.visual.flags.location=3
+#wrap.indent.mode=1
+#wrap.visual.startindent=4
+
+# Folding
+# enable folding, and show lines below when collapsed.
+fold=0
+fold.compact=0
+fold.flags=20
+fold.symbols=2
+#fold.highlight=1
+#fold.highlight.colour=#00C0C0
+#fold.on.open=1
+fold.comment=1
+fold.preprocessor=1
+
+# Find and Replace
+# Internal search always available with recursive capability so use in preference to external tool
+find.command=
+# findstr is available on recent versions of Windows including 2000
+if PLAT_WIN
+ find.command=findstr /n /s $(find.files) $(find.what)
+#find.input=$(find.what)
+if PLAT_GTK
+ find.command=grep --line-number "$(find.what)" $(find.files)
+#find.files=*.c *.cxx *.h
+find.files=*.*
+#find.in.files.close.on.find=0
+#find.in.dot=1
+#find.in.binary=1
+#find.close.on.find=0
+#find.replace.matchcase=1
+#find.replace.escapes=1
+#find.replace.regexp=1
+#find.replace.regexp.posix=1
+#find.replace.wrap=0
+#find.replacewith.focus=0
+#find.replace.advanced=1
+find.use.strip=0
+replace.use.strip=0
+#strip.button.height=24
+
+
+# Behaviour
+#eol.mode=LF
+#eol.auto=1
+clear.before.execute=0
+#vc.home.key=1
+#wrap.aware.home.end.keys=1
+#autocompleteword.automatic=1
+#autocomplete.choose.single=1
+caret.policy.xslop=1
+caret.policy.width=20
+caret.policy.xstrict=0
+caret.policy.xeven=0
+caret.policy.xjumps=0
+caret.policy.yslop=1
+caret.policy.lines=3
+caret.policy.ystrict=1
+caret.policy.yeven=1
+caret.policy.yjumps=0
+#visible.policy.strict=1
+#visible.policy.slop=1
+#visible.policy.lines=4
+#time.commands=1
+#caret.sticky=1
+properties.directory.enable=1
+
+# Status Bar
+statusbar.number=4
+statusbar.text.1=\
+li=$(LineNumber) co=$(ColumnNumber) $(OverType) ($(EOLMode)) $(FileAttr)
+statusbar.text.2=\
+$(BufferLength) chars in $(NbOfLines) lines. Sel: $(SelLength) chars.
+statusbar.text.3=\
+Now is: Date=$(CurrentDate) Time=$(CurrentTime)
+statusbar.text.4=\
+$(FileNameExt) : $(FileDate) \97 $(FileTime) | $(FileAttr)
+
+if PLAT_WIN
+ command.scite.help=C:\Program Files\SRWare Iron\iron.exe "C:\Program Files\SciTE\SciTEDoc.html"
+ command.scite.help.subsystem=2
+if PLAT_GTK
+ command.print.*=a2ps "$(FileNameExt)"
+ command.scite.help=netscape "file://$(SciteDefaultHome)/SciTEDoc.html"
+
+# Internationalisation
+# Japanese input code page 932 and ShiftJIS character set 128
+#code.page=932
+#character.set=128
+# Unicode
+#code.page=65001
+code.page=0
+#character.set=204
+# Required for Unicode to work on GTK+:
+#LC_CTYPE=en_US.UTF-8
+if PLAT_GTK
+ output.code.page=65001
+if PLAT_MAC
+ output.code.page=65001
+
+# Export
+#export.keep.ext=1
+export.html.wysiwyg=1
+#export.html.tabs=1
+#export.html.folding=1
+export.html.styleused=1
+export.html.title.fullpath=1
+#export.rtf.tabs=1
+#export.rtf.font.face=Arial
+#export.rtf.font.size=9
+#export.rtf.tabsize=8
+#export.rtf.wysiwyg=0
+#export.tex.title.fullpath=1
+# Magnification (added to default screen font size)
+export.pdf.magnification=0
+# Font: Courier, Helvetica or Times (Courier line-wraps)
+export.pdf.font=Courier
+# Page size (in points): width, height
+# E.g. Letter 612,792; A4 595,842; maximum 14400,14400
+export.pdf.pagesize=595,842
+# Margins (in points): left, right, top, bottom
+export.pdf.margins=56,28,28,28
+export.xml.collapse.spaces=1
+export.xml.collapse.lines=1
+
+# Define values for use in the imported properties files
+chars.alpha=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ?
+chars.numeric=0123456789abcdef
+chars.accented=\8a\9a\8c\9c\9fÿÀàÁáÂâÃãÄäÅåÆæÇçÈèÉéÊêËëÌìÍíÎîÏïÐðÑñÒòÓóÔôÕõÖØøÙùÚúÛûÜüÝýÞþßö
+# This is a better set for Russian:
+#chars.accented=ÀàÁáÂâÃãÄäÅ娸ÆæÇçÈèÉéÊêËëÌìÍíÎîÏïÐðÑñÒòÓóÔôÕõÖö×÷ØøÙùÚúÛûÜüÝýÞþßÿ
+
+# The open.filter setting is only used on Windows where the file selector has a menu of filters to apply
+# to the types of files seen when opening.
+# There is a limit (possibly 256 characters) to the length of a filter,
+# so not all source extensions can be in this setting.
+#*.idl;*.odl;*.rc;*.rc2;*.dlg;*.def;make*;*.mak;\
+#*.frm;*.cls;*.ctl;;*.pl;;*.iface;*.e;#*.rb;*.cgi;*.lua;\
+#source.files=*.asm;*.c;*.cc;*.f;*.ff;*.far;*.cpp;*.cxx;*.cs;*.h;*.hh;*.hxx;*.hpp;\
+source.files=*.asm;*.avr;*.tiny;*.mega;*.vb;*.vbs;*.bas;*.bat;*.ini;*.py;*.js;*.properties;*.vhd;*.vhdl
+
+# Each platform has a different idea of the most important filters
+if PLAT_WIN
+ all.files=All Files (*.*)|*.*|
+ top.filters=All Source|$(source.files)|$(all.files)
+if PLAT_GTK
+ all.files=All Files (*)|*|Hidden Files (.*)|.*|
+ top.filters=All Source|$(source.files)|$(all.files)
+# As OS X only greys out filtered files, show all as default
+if PLAT_MAC
+ all.files=All Files (*.*)|*.*|
+ top.filters=$(all.files)All Source|$(source.files)|
+
+open.filter=\
+$(top.filters)\
+#$(filter.ada)\
+$(filter.conf)\
+$(filter.asm)\
+#$(filter.asn1)\
+#$(filter.ave)\
+#$(filter.baan)\
+$(filter.bash)\
+#$(filter.caml)\
+#$(filter.cmake)\
+#$(filter.cpp)\
+#$(filter.ch)\
+$(filter.css)\
+#$(filter.d)\
+#$(filter.eiffel)\
+#$(filter.erlang)\
+#$(filter.fortran)\
+$(filter.forth)\
+#$(filter.gap)\
+#$(filter.hs)\
+#$(filter.idl)\
+#$(filter.inno)\
+$(filter.java)\
+$(filter.js)\
+#$(filter.kix)\
+#$(filter.lout)\
+$(filter.lua)\
+#$(filter.matlab)\
+#$(filter.metapost)\
+#$(filter.mmixal)\
+#$(filter.modula3)\
+#$(filter.nncrontab)\
+#$(filter.nsis)\
+#$(filter.opal)\
+#$(filter.pascal)\
+#$(filter.perl)\
+#$(filter.php)\
+#$(filter.pov)\
+#$(filter.powershell)\
+#$(filter.prg)\
+$(filter.properties)\
+$(filter.ps)\
+$(filter.python)\
+$(filter.r)\
+$(filter.ruby)\
+#$(filter.sql)\
+#$(filter.specman)\
+$(filter.tcl)\
+$(filter.tex)\
+$(filter.text)\
+$(filter.txt2tags)\
+$(filter.vb)\
+$(filter.web)\
+#$(filter.yaml)\
+$(filter.verilog)\
+$(filter.vhdl)
+
+#save.filter=$(open.filter)
+
+# Give symbolic names to the set of fonts used in the standard styles.
+if PLAT_WIN
+ font.base=font:Lucida Console,size:10
+ font.small=font:Lucida Console,size:10
+ font.comment=font:Lucida Console,size:10
+ font.code.comment.box=$(font.comment)
+ font.code.comment.line=$(font.comment)
+ font.code.comment.doc=$(font.comment)
+ font.code.comment.nested=$(font.comment)
+ font.text=font:Lucida Console,size:10
+ font.text.comment=font:Lucida Console,size:10
+ font.embedded.base=font:Lucida Console,size:10
+ font.embedded.comment=font:Lucida Console,size:10
+ font.monospace=font:Lucida Console,size:10
+ font.vbs=font:Lucida Sans Unicode,size:10
+if PLAT_GTK
+ font.base=font:lucidatypewriter,size:12
+ font.small=font:lucidatypewriter,size:10
+ font.comment=font:new century schoolbook,size:8
+ font.code.comment.box=$(font.comment)
+ font.code.comment.line=$(font.comment)
+ font.code.comment.doc=$(font.comment)
+ font.code.comment.nested=$(font.comment)
+ font.text=font:times,size:8
+ font.text.comment=font:lucidatypewriter,size:8
+ font.embedded.base=font:lucidatypewriter,size:8
+ font.embedded.comment=font:lucidatypewriter,size:8
+ font.monospace=font:courier,size:8
+ font.vbs=font:new century schoolbook,size:8
+if PLAT_MAC
+ font.base=font:Verdana,size:12
+ font.small=font:Verdana,size:10
+ font.comment=font:Georgia,size:13
+ font.code.comment.box=$(font.comment)
+ font.code.comment.line=$(font.comment)
+ font.code.comment.doc=$(font.comment)
+ font.code.comment.nested=$(font.comment)
+ font.text=font:Times New Roman,size:13
+ font.text.comment=font:Verdana,size:11
+ font.embedded.base=font:Verdana,size:11
+ font.embedded.comment=font:Comic Sans MS,size:10
+ font.monospace=font:Courier New,size:12
+ font.vbs=font:Lucida Sans Unicode,size:12
+ font.js=$(font.comment)
+
+# Old GTK+ font settings are faster but not antialiased
+ #~ font.base=font:lucidatypewriter,size:12
+ #~ font.small=font:lucidatypewriter,size:10
+ #~ font.comment=font:new century schoolbook,size:12
+ #~ font.code.comment.box=$(font.comment)
+ #~ font.code.comment.line=$(font.comment)
+ #~ font.code.comment.doc=$(font.comment)
+ #~ font.text=font:times,size:14
+ #~ font.text.comment=font:lucidatypewriter,size:10
+ #~ font.embedded.base=font:lucidatypewriter,size:12
+ #~ font.embedded.comment=font:lucidatypewriter,size:12
+ #~ font.monospace=font:courier,size:12
+ #~ font.vbs=font:new century schoolbook,size:12
+
+# Give symbolic names to the set of colours used in the standard styles.
+colour.code.comment.box=fore:#00FF00
+colour.code.comment.line=fore:#00FF00
+colour.code.comment.doc=fore:#3F703F
+colour.code.comment.nested=fore:#A0C0A0
+colour.text.comment=fore:#0000FF,back:#FFFFFF
+colour.other.comment=fore:#00FF00
+colour.embedded.comment=back:#E0EEFF
+colour.embedded.js=back:#F0F0FF
+colour.notused=back:#FF0000
+#couleur des nombres
+colour.number=fore:#FF00FF
+#couleur des instructions du langage
+colour.keyword=fore:#FF0000
+#couleur chaînes entre guillemets
+colour.string=fore:#00FFFF
+colour.char=fore:#7F7F7F
+colour.operator=fore:#00FF00
+colour.preproc=fore:#FF7F00
+colour.error=fore:#FFFF00,back:#FF0000
+
+# Global default styles for all languages
+# Default style, black background
+style.*.32=back:#000000,fore:#FFFFFF,font:Lucida Console,size:10
+# Line number
+style.*.33=back:#404040,$(font.base))
+# Brace highlight
+style.*.34=back:#222222,fore:#8080FF,bold
+# Brace incomplete highlight
+style.*.35=back:#222222,fore:#FF0000,bold
+# Control characters
+style.*.36=
+# Indentation guides
+style.*.37=fore:#C0C0C0,back:#FFFFFF
+
+# Printing - only works on Windows
+if PLAT_WIN
+ #print.colour.mode=1
+ print.magnification=-1
+ # Setup: left, right, top, bottom margins, in local units:
+ # hundredths of millimeters or thousandths of inches
+ print.margins=2000,1000,1000,1000
+ # Header/footer:
+ # && = &; &p = current page
+ # &f = file name; &F = full path
+ # &d = file date; &D = current date
+ # &t = file time; &T = full time
+ print.header.format=$(FileNameExt) \97 Printed on $(CurrentDate), $(CurrentTime) \97 Page $(CurrentPage)
+ print.footer.format=$(FilePath) \97 File date: $(FileDate) \97 File time: $(FileTime)
+ # Header/footer style
+ print.header.style=font:Arial,size:12,bold
+ print.footer.style=font:Arial Narrow,size:10,italics
+
+# Warnings - only works on Windows and needs to be pointed at files on machine
+#if PLAT_WIN
+# warning.findwrapped=100,E:\Windows\Media\SFX\Boing.wav
+# warning.notfound=0,Effect.wav
+# warning.wrongfile=0,Glass.wav
+# warning.executeok=0,Fanfare.wav
+# warning.executeko=100,GlassBreak.wav
+# warning.nootherbookmark=100,Boing2.wav
+
+# Define the Lexer menu,
+# Each item contains three parts: menu string | file extension | key
+# The only keys allowed currently are based on F-keys and alphabetic keys and look like
+# [Ctrl+][Shift+][Fn|a] such as F12 or Ctrl+Shift+D.
+# A '&' may be placed before a letter to be used as an accelerator. This does not work on GTK+.
+
+keyText=Shift+F11
+keyMake=Ctrl+Shift+F11
+keyHTML=F12
+keyXML=Shift+F12
+# On OS X, F11 is used by Expose, F12 by Dashbard
+if PLAT_MAC
+ keyText=Shift+F13
+ keyMake=Ctrl+Shift+F13
+ keyHTML=Ctrl+Shift+F14
+ keyXML=Shift+F14
+
+menu.language=\
+Text|txt|Shift+F11|\
+#Ada|ads||\
+#Apache Confi&g|conf||\
+Assembler|asm||\
+#ASN.1|asn1||\
+#Avenue|ave||\
+#Baan|bc||\
+&Batch|bat||\
+#Bullant|ant||\
+&C / C++|c||\
+#CMake|cmake||\
+C&#|cs||\
+#COBOL|cob||\
+#Csound|orc||\
+CSS|css||\
+D|d||\
+&Difference|diff||\
+#&Eiffel|e||\
+#Erlang|erl||\
+&Errorlist|err||\
+#FlagShip|prg||\
+Forth|forth||\
+#&Fortran|f90||\
+#Gap|g||\
+#Haskell|hs||\
+H&ypertext|html|F12|\
+#&InnoSetup|iss||\
+&Java|java||\
+Java&Script|js||\
+#&Kix|kix||\
+#Lisp|lisp||\
+#Lot|lot||\
+#Lout|lt||\
+#Lu&a|lua||\
+#Matlab|m.matlab||\
+&Makefile|mak|Ctrl+Shift+F11|\
+#MetaPost|mp||\
+#MMIXAL|mms||\
+#Modula-3|m3||\
+#&nnCron crontab|tab||\
+#NSIS|nsis||\
+#Objective Caml|ml||\
+#Octave|m.octave||\
+#Opal|impl||\
+#Pascal|pas||\
+Pe&rl|pl||\
+P&HP|php||\
+#P&LSQL|spec||\
+#P&ostScript|ps||\
+#P&OV-Ray SDL|pov||\
+#PowerShell|ps1||\
+#PowerPro|powerpro||\
+&Properties|properties||\
+Pytho&n|py||\
+#R|R||\
+#Reso&urce|rc||\
+Ruby|rb||\
+Shell|sh||\
+S&QL|sql||\
+#Specman|e||\
+&TCL|tcl||\
+TeX|tex||\
+#&txt2tags|t2t||\
+&VB|vb||\
+VBScr&ipt|vbs||\
+#Verilog|v||\
+#VHDL|vhd||\
+&XML|xml|$(keyXML)|\
+YAML|yaml||
+
+# User defined key commands
+user.shortcuts=\
+Ctrl+Shift+V|IDM_PASTEANDDOWN|\
+Ctrl+PageUp|IDM_PREVFILE|\
+Ctrl+PageDown|IDM_NEXTFILE|
+
+#KeypadPlus|IDM_EXPAND|\
+#KeypadMinus|IDM_BLOCK_COMMENT|
+
+#user.context.menu=\
+#||\
+#Next File|IDM_NEXTFILE|\
+#Prev File|IDM_PREVFILE|
+
+# Import all the language specific properties files
+#import abaqus
+#import ada
+#import asn1
+#import au3
+#import ave
+#import baan
+#import freebasic
+#import blitzbasic
+#import bullant
+#import caml
+import conf
+#import cobol
+import cpp
+#import cmake
+#import csound
+import css
+#import d
+#import eiffel
+#import erlang
+#import escript
+#import flagship
+import \config\scite\AS_MSP430\forth
+#import fortran
+#import gap
+#import haskell
+import html
+#import inno
+#import kix
+import lisp
+#import lot
+#import lout
+import lua
+#import matlab
+#import metapost
+#import mmixal
+#import modula3
+#import nimrod
+#import nncrontab
+#import nsis
+#import opal
+import \config\scite\others
+#import pascal
+#import perl
+#import pov
+#import powerpro
+#import powershell
+import ps
+#import purebasic
+import python
+#import r
+#import rebol
+import ruby
+#import scriptol
+#import smalltalk
+#import spice
+#import sql
+#import specman
+#import tacl
+#import tal
+import tcl
+#import txt2tags
+import tex
+#import vb
+#import yaml
+#import verilog
+#import vhdl
+import \config\scite\AS_MSP430\asm
+import \config\scite\AS_MSP430\gema
+
+
+# Error list styles
+
+style.errorlist.32=fore:#B0B000,$(font.small)
+# Default
+style.errorlist.0=fore:#FFFFFF
+# Microsoft Error
+style.errorlist.3=fore:#0080FF
+# command or return status
+style.errorlist.4=fore:#FF00FF
+
+# Text matched with find in files and message part of GCC errors
+style.errorlist.21=fore:#FF0000
+
+
+
+
--- /dev/null
+!tiREGtoFastForth.pat
+! ============================================
+! translate MSP430 registers to FORTH's ones
+! ============================================
+
+R15=PSP
+R14=TOS
+R13=IP
+R12=S
+R11=T
+R10=W
+R9=X
+R8=Y
+R7=rEXIT
+R6=rDOVAR
+R5=rDOCON
+R4=rDODOES
+R2=SR
+R1=RSP
+R0=PC
--- /dev/null
+@ECHO OFF
+if not exist %~dpn1.hex goto eof
+if exist %2 goto eof
+a:\prog\srecord\srec_cat %~dpn1.hex -intel -output %~dpn1.txt -ti-txt
+:eof
+exit
+
+rem %1 is the target device, example: MSP430FR5969
\ No newline at end of file
--- /dev/null
+connect param3
+sendln ' $0A BASE ! STOP' ; blanks are to pass LPMx wake up time...
+
+inputbox 'Send a File' 'Select File : ' param2
+
+showtt 0
+sendln 'NOECHO' ; by default
+sendfile inputstr 0
+showtt 1
+
+end
+; param1 = this macro
+; param2 = file to send
+; param3 = "/C"
--- /dev/null
+
+; param1 = this macro filename
+; param2 = pathname of file to write in SD_CARD
+; param3 = /C = default COM saved in TERATERM.INI with all its parameters.
+
+basename fname param2 ; fname = file.ext of param2
+strinsert fname 1 '\' ; fname = \file.ext, to force absolute path
+
+testlink
+if result=0 connect param3
+
+sendln ' $0A BASE ! ECHO STOP' ; blanks are added to pass LPMx wake up time...
+
+inputbox 'here you can add a path to the file: ' 'Send a File to SD_CARD target' fname
+
+sendln 'TERM2SD" ' inputstr '"' ; send to FastForth the command TERM2SD" \file.ext" ...with optionnal path added in inputbox
+
+sendfile param2 0 ; binary flag = 0 to send text file
+
+sendln #4 ; send ETX to ask FastForth to close file
+
+showtt 0
+
+; end
\ No newline at end of file
--- /dev/null
+
+; param1 = this macro filename
+; param2 = pathname of the bat file
+; param3 = /C = default COM saved in TERATERM.INI with all its parameters.
+
+timeout=0 ; 0 s
+mtimeout=100 ; + 100 ms = 100 ms
+noname = '\'
+connect param3
+
+; blanks are added to pass LPMx wake up time...
+sendln ' $0A BASE ! ECHO STOP'
+
+
+; first input box to define file to be read
+inputbox 'select SD_CARD file to be read:' 'SD_CARD file' '\'
+
+strcompare inputstr noname
+if result=0 then
+goto end
+endif
+
+fileorg = inputstr
+namedst = inputstr
+
+strremove namedst 1 1
+dirdst = param2 ; disdst = path of bat file
+makepath filedst dirdst namedst ; filedst = pathname of file selected in windows 2
+
+
+; 2th input box to define destination file with param1 path
+inputbox 'select destination file:' 'destination file' filedst
+
+filecreate filehandle inputstr
+
+;setsync 1 ; enter synchronous mode
+
+; send to FastForth the command TERM2SD" \file.ext"...
+; ...with optionnal path added in first inputbox
+sendln 'SD2TERM" ' fileorg '"'
+
+recvln ; keep sendln 'SD2TERM" ' fileorg '"'
+recvln ; keep FastForth response
+
+:start
+
+recvln ; receive one line
+
+if result=0 then ; case of timeout
+ fileclose filehandle
+ goto end
+endif
+
+filewriteln filehandle inputstr ; write it to output file
+
+send #17 ; send XON
+
+goto start
+
+:end
+
+;setsync 0 ; enter asynchronous mode
+
+showtt 1
+
+closett
+end
\ No newline at end of file
--- /dev/null
+@ECHO OFF
+if not exist %~dpn1%.4th goto error
+if exist %2 goto error
+taskkill /F /IM ttermpro.exe 1> NULL 2>&1
+@"C:\Program Files\teraterm\ttpmacro.exe" /V %~d0\config\scite\AS_MSP430\SendtoSD.ttl %~dpn1%.4th /C 1> NULL 2>&1
+if ERRORLEVEL 1 goto nextcmd
+exit
+
+:nextcmd
+del null
+@"C:\Program Files (x86)\teraterm\ttpmacro.exe" /V %~d0\config\scite\AS_MSP430\SendtoSD.ttl %~dpn1%.4th /C
+exit
+
+:error
+
+@start %~d0\config\scite\AS_MSP430\error4thtoSDCARD.bat
+exit
+
+rem %~d0% is the drive of bat file
+rem %~dpn1%.4th is the file to send described as drive\path\name.4th of param %1
+rem %~d1 is the drive of param %1
--- /dev/null
+@ECHO OFF
+if not exist %~dpn1%.4th goto error
+if exist %2 goto error
+taskkill /F /IM ttermpro.exe 1> NULL 2>&1
+@"C:\Program Files\teraterm\ttpmacro.exe" /V %~d1\config\scite\AS_MSP430\SendFile.ttl %~dpn1%.4th /C 1> NULL 2>&1
+if ERRORLEVEL 1 goto nextcmd
+exit
+
+:nextcmd
+del null
+@"C:\Program Files (x86)\teraterm\ttpmacro.exe" /V %~d1\config\scite\AS_MSP430\SendFile.ttl %~dpn1%.4th /C
+:eof
+exit
+
+:error
+
+@start %~d1\config\scite\AS_MSP430\error4th.bat
+exit
+
+
+
+rem %~dpn1%.4th is the file to send described as drive\path\name.4th of param %1
+rem %~d1 is the drive of param %1
+
+
+
+
--- /dev/null
+# Define SciTE settings for MACROASSEMBLER AS for MSP430
+
+
+
+file.patterns.asm=*.asm;*.inc;*.map
+
+# add '*.inc;*.asm;' to 'source.files' variable in 'SciTEGlobal.properties'
+# if you want to include these file patterns into default source file list
+
+lexer.$(file.patterns.asm)=asm
+
+*language.asm=ASM|asm||
+
+*source.patterns.asm=$(file.patterns.asm);
+
+filter.asm=asm files (asm inc)|$(file.patterns.asm)|
+
+*filter.asm=$(filter.asm)
+
+word.characters.$(file.patterns.asm)=$(chars.alpha)$(chars.numeric)_
+
+comment.block.asm=\ ~
+#comment.block.at.line.start.asm=0
+comment.box.start.asm=\
+comment.box.middle.asm=\
+comment.box.end.asm=\
+comment.stream.start.asm=(
+comment.stream.end.asm=)
+
+# asm styles
+
+#MSP430_instructions
+keywords.$(file.patterns.asm)=adc adc.b adc.w add add.b add.w addc addc.b addc.w and and.b and.w \
+ bic bic.b bic.w bis bis.b bis.w bit bit.b bit.w br branch call clrc clrn clrz dint eint \
+ clr clr.b clr.w cmp cmp.b cmp.w dadc dadc.b dadc.w dadd dadd.b dadd.w dec dec.b dec.w decd decd.b decd.w \
+ inc inc.b inc.w incd incd.b incd.w inv inv.b inv.w mov mov.b mov.w pop pop.b pop.w push push.b push.w \
+ jc jhs je jeq jz jge jl jmp jn jnc jlo jne jnz nop nop2 nop3 nop4 nop5 nop6 nop7 ret reti setc setn setz swpb sxt \
+ rla rla.b rla.w rlc rlc.b rlc.w rra rra.b rra.w rrc rrc.b rrc.w sbc sbc.b sbc.w sub sub.b sub.w \
+ subc subc.b subc.w sbb sbb.b sbb.w tst tst.b tst.w xor xor.b xor.w \
+ pushm popm rlam rram rrcm rrum
+
+##preprocessor
+#keywords2.$(file.patterns.asm)=#define #elif #else #endif #error\
+ ##if #ifdef #ifndef #include #message #pragma #undef #warning
+
+# MACROASSEMBLER AS directives
+keywords3.$(file.patterns.asm)=.align .cpu .byte .word .endm .endmacro \
+ .equ .include .macro .org .reg .set .ifdef .ifndef .if .elseif .else .endif \
+ .switch .case .elsecase .endcase \
+ .warning .error
+
+# my macros
+keywords4.$(file.patterns.asm)=NEXT DOALIAS DEST
+
+
+
+
+
+
+
+# Default
+style.asm.32=$(font.base)
+# whitespace
+style.asm.0=$(font.base)
+
+# Comment stream
+style.asm.1=$(colour.code.comment.line)
+#style.asm.1=fore:#00FF00,$(font.comment)
+
+# Number
+#style.asm.2=$(colour.number)
+style.asm.2=fore:#FF0000
+
+# String
+#style.asm.3=$(colour.string)
+style.asm.3=fore:#00FFFF
+
+# Operator (= - / * , etc.)
+style.asm.4=fore:#00FFFF
+
+# Identifier (text)
+style.asm.5=fore:#FFFFFF
+
+# CPU instruction ( add, adc, adiw, etc.)
+style.asm.6=$(colour.keyword)
+
+# preprocessor (#define #elif #else, etc.)
+style.asm.7=fore:#FFFF00
+
+# directives (.byte .cseg etc.)
+style.asm.8=fore:#FFFF00
+
+# assembler Directive
+style.asm.9=fore:#FF00ff
+
+# my macros
+style.asm.9=fore:#00FFff
+
+
+# Comment block (GNU as /*...*/ syntax, unimplemented)
+# style.asm.11=$(colour.code.comment.box),$(font.code.comment.box)
+# Character/String (single quote) (also character prefix in GNU as)
+style.asm.12=$(colour.char)
+# End of line where string is not closed
+#style.asm.13=fore:#000000,back:#E0C0E0,eolfilled
+style.asm.13=fore:#FFFFFF,back:#000000
+
+
+# the star at the start of this command line is to display the parameters box
+# write the name of the device in the first parameter; example : MSP430fr5969
+# write the name of the target in the 2th parameter; example : MSP_EXP430fr5969
+
+command.name.0.*.asm=Assembler 1:[device] 2:[target]
+command.0.*.asm=*\config\scite\AS_MSP430\build.bat $(FileNameExt) $(2)$(3)
+
+command.name.1.*.asm=FET Prog 1:[device] 2:[target]
+command.1.*.asm=*\config\scite\AS_MSP430\prog.bat $(1) $(2)$(3).txt
+
+
+
+
+
+
+
+
--- /dev/null
+@ECHO OFF
+\prog\MacroAssemblerAS\bin\asw -L -i \projets\msp430 %1 -o %2.p
+\prog\MacroAssemblerAS\bin\p2hex %2.p -r 0x0000-0xffff
+\prog\srecord\srec_cat %2.hex -intel -output %2.txt -ti-txt
+del %2.p
+del %2.hex
+exit
+
+rem %1 is the target device, example: MSP430FR5969
+rem %2 is the target, example: MSP_EXP430FR5969
\ No newline at end of file
--- /dev/null
+@ECHO OFF
+if not exist %~dpn1.f goto error
+if not exist %~dpn2.pat goto error
+if exist %3 goto error
+@%~d1\prog\gema\gema.exe -nobackup -line -t -f %~dpn2.pat %~dpn1.f %~dpn1.4th
+exit
+
+:error
+
+@start %~d1\config\scite\AS_MSP430\errorfto4th.bat
+exit
+
+
+
+exit
+%~dpn1.f is the symbolic source file described as drive\path\name.f of first arg (%1)
+%~dpn2.pat is the pattern file for preprocessor gema.exe described as drive\path\name.pat of 2th arg (%2)
+%~dpn1.4th is the source file ready to send to the target
+%~d1 is the drive of arg %1
--- /dev/null
+
+@echo how to download a file.4th to your target
+@echo -----------------------------------------
+@echo I presume you are connected to your fastforth target via input terminal TERATERM.EXE
+@echo drag and drop your file.4th onto Send_file.4th_to_target.bat
+
+@pause
+exit
+
--- /dev/null
+
+@echo how to copy a file.4th to the SD_CARD target
+@echo --------------------------------------------
+@echo I presume you are connected via TERATERM.EXE to your fastforth target with its SD_CARD extensions,
+@echo and a formatted FAT 16 SD_CARD is in it's slot...
+@echo drag and drop your file.4th onto Send_File.4th_to_SD_CARD_target.bat
+
+@pause
+exit
+
--- /dev/null
+
+@echo how to download a generic file.f to your target
+@echo -----------------------------------------------
+@echo I presume you are connected to your fastforth target via input terminal TERATERM.EXE
+@echo 1- clic on your file.f,
+@echo 2- ctrl clic on your selected target.pat file, for example MSP_EXP430FR5994.pat
+@echo 3- then drag and drop your file.f onto Send_File.f_to_SD_CARD_target.bat
+@echo the generic file.f is sent so to the preprocessor gema.exe which products a specific file.4th
+@echo which is itself loaded by FastForth onto target
+
+@pause
+exit
--- /dev/null
+
+@echo how to convert a generic file.f to a file.4th specific to a target
+@echo ------------------------------------------------------------------
+@echo I presume you are connected to your fastforth target via input terminal TERATERM.EXE
+@echo 1- clic on a file.f,
+@echo 2- ctrl clic on your selected target.pat file, for example MSP_EXP430FR5994.pat
+@echo 3- clic selected file.f then drag and drop it on to Convert_file.f_to_file.4th.bat
+@echo the generic file.f is sent so to the preprocessor gema.exe which products specific the file.4th
+@pause
+exit
--- /dev/null
+
+
+@echo how to copy a generic file.f to your SD_CARD target
+@echo ---------------------------------------------------
+@echo I presume you are connected via TERATERM.EXE to your fastforth target with its SD_CARD extensions,
+@echo and a formatted FAT 16 SD_CARD is in it's slot...
+@echo 1- clic on your file.f,
+@echo 2- ctrl clic on your selected target.pat file, for example MSP_EXP430FR5994.pat
+@echo 3- then drag and drop your file.f onto Send_File.f_to_SD_CARD_target.bat
+@echo the generic file.f is sent so to the preprocessor gema.exe which products a specific file.4th
+@echo which is itself copied onto SD_CARD target
+
+@pause
+exit
+
--- /dev/null
+
+
+@echo how to receive a file from target SD_CARD
+@echo -----------------------------------------
+@echo I presume you are connected via TERATERM.EXE to your fastforth target with its SD_CARD extensions,
+@echo and a formatted FAT 16 SD_CARD is in it's slot...
+@echo 1- drag and drop any file.f/.4th of your destination folder onto Receive_file_from_SD_CARD_target.bat
+@echo this defines path for 2th window below
+@echo 2- in the first window opened by TERATERM select the SD_CARD file you want upload
+@echo 3- in the 2th window, change if necessary filename to be written on your PC.
+@echo 4- wait for TERATERM window blinking (at 15kb/s, this may do a long time): it's done.
+
+@pause
+exit
+
--- /dev/null
+# Define SciTE settings for Forth files
+
+# These patterns conflict with fortran.properties and nncrontab.properties
+# so disable these other properties files if you want to use forth.
+file.patterns.forth=*.f;*.4th
+
+# add '*.tab;*.spf;' to 'source.files' variable in 'SciTEGlobal.properties'
+# if you want to include these file patterns into default source file list
+
+lexer.$(file.patterns.forth)=forth
+
+*language.forth=Forth|forth||
+
+
+
+filter.forth=Forth files (4th f)|$(file.patterns.forth)|
+
+*filter.forth=$(filter.forth)
+
+
+word.characters.$(file.patterns.forth)=$(chars.alpha)$(chars.numeric)_
+
+comment.block.forth=\
+#comment.block.at.line.start.forth=0
+comment.stream.start.forth=(
+comment.stream.end.forth=)
+comment.box.start.forth=\
+comment.box.middle.forth=\
+comment.box.end.forth=\
+
+# Forth styles
+
+# control keywords Forth
+keywords.$(file.patterns.forth)=\
+again begin case do else endcase endof if loop +loop leave unloop of repeat then until while ?do \
+< > >= = <> 0<> 0= 0< <0 0>= u< u>= S< S>= jmp goto bw1 bw2 bw3 fw1 fw2 fw3
+
+# Keywords
+keywords2.$(file.patterns.forth)=\
+dup ?dup drop rot swap over @ ! 2@ 2! 2dup 2drop 2swap 2over nip r@ >r r> 2r@ 2>r 2r> \
+ sp@ sp! @ ! c@ c! s>d um/mod um* m* * fm/mod sm/rem rshift lshift invert 1+ 1- negate \
+ (cr) (EMIT) (accept) (warm) is lit warm depth /mod mod \
+ space spaces bl word char fill key? key abort abort" */ 2* 2/ /mod cell+ cells char+ \
+ chars move abs hex decimal hold <# # #s #> sign or \
+ count type . u. dump (.") >number ' immediate exit recurse here allot , \
+ c, branch 0branch ?branch ." align aligned create does> \
+ variable constant defer definitions forth forget only also previous literal \
+ source evaluate word interpret quit >body execute find state base \
+ immediate words accept emit cr type echo noecho min max true false \
+ char [char] postpone ['] rst_here rst_state wipe pwr_here pwr_state ( .( \
+ assembler
+
+# defwords
+keywords3.$(file.patterns.forth)=\
+code endcode : ; \
+lo2hi hi2lo colon asm endasm \
+
+# MSP430 assembly words & MSP430_instructions
+keywords4.$(file.patterns.forth)=\
+adc adc.b adc.w add add.b add.w addc addc.b addc.w and and.b and.w \
+ bic bic.b bic.w bis bis.b bis.w bit bit.b bit.w br branch call clrc clrn clrz dint eint \
+ clr clr.b clr.w cmp cmp.b cmp.w dadc dadc.b dadc.w dadd dadd.b dadd.w dec dec.b dec.w decd decd.b decd.w \
+ inc inc.b inc.w incd incd.b incd.w inv inv.b inv.w mov mov.b mov.w pop pop.b pop.w push push.b push.w \
+ jc jhs je jeq jz jge jl jmp jn jnc jlo jne jnz nop nop2 nop3 nop4 nop5 nop6 nop7 ret reti setc setn setz swpb sxt \
+ rla rla.b rla.w rlc rlc.b rlc.w rra rra.b rra.w rrc rrc.b rrc.w sbc sbc.b sbc.w sub sub.b sub.w \
+ subc subc.b subc.w sbb sbb.b sbb.w tst tst.b tst.w xor xor.b xor.w \
+ pushm popm rlam rram rrcm rrum \
+
+
+#keywords5.$(file.patterns.forth)= \
+#u v w x y ip tos pc rsp psp
+
+# string words
+keywords6.$(file.patterns.forth)=\
+s" z" " ." c"
+
+
+
+
+
+# Default
+style.forth.32=$(font.base)
+
+# whitespace (SCE_FORTH_DEFAULT)
+style.forth.0=$(font.base)
+
+# Comment (SCE_FORTH_COMMENT)
+style.forth.1=fore:#00FF00,$(font.comment)
+
+# ( ) comment (SCE_FORTH_COMMENT_ML)
+style.forth.2=fore:#00FF00,$(font.comment)
+
+# ML comment (SCE_FORTH_IDENTIFIER)
+style.forth.3=fore:#FFFFFF
+
+# control (keyword_FORTH_CONTROL)
+style.forth.4=fore:#007f7F
+
+# Keywords (keyword2_SCE_FORTH_KEYWORD)
+style.forth.5=fore:#FF0FF,$(font.base)
+
+# defwords (keyword3_SCE_FORTH_DEFWORD)
+style.forth.6=fore:#FFFF00,$(font.base)
+
+# preword1 (keyword4_SCE_msp430_assembly)
+style.forth.7=fore:#FF0000,$(font.base)
+
+# preword2 (keyword5_SCE_msp430_registers)
+style.forth.8=fore:#FFFF00,$(font.base)
+
+# number (SCE_FORTH_NUMBER)
+style.forth.9=fore:#007F7F,$(font.base)
+
+# Double quoted string (SCE_FORTH_STRING)
+style.forth.10=fore:#00FFFF,$(font.base)
+
+# locale
+style.forth.11=fore:#0000CC,$(font.base)
+
+#command.compile.*.f=spf.cmd $(FileNameExt)
+
+command.name.0.*.f=preprocess file.f with 2:[target].pat then send file.4th to [target]
+command.0.*.f=*\config\scite\AS_MSP430\send_file.f_to_target.bat $(FileDir)\$(FileName).f $(2)
+
+command.name.1.*.f=preprocess file.f with 2:[target].pat then send file.4th to [target] SD_CARD
+command.1.*.f=*\config\scite\AS_MSP430\send_file.f_to_SD_CARD_target.bat $(FileDir)\$(FileName).f $(2)
+
+command.name.2.*.f=convert FORTH registers to TI's ones
+command.2.*.f=\prog\gema\gema -line -t -f \config\gema\FastForthREGtoTI.pat $(FileNameExt) $(FileNameExt)
+
+command.name.3.*.f=convert TI registers to FORTH's ones
+command.3.*.f=\prog\gema\gema -line -t -f \config\gema\TiREGtoFastForth.pat $(FileNameExt) $(FileNameExt)
+
+command.name.4.*.f=preprocess file.f with 2:[target].pat to file.4th (for debug)
+command.4.*.f=*\config\scite\AS_MSP430\convert_file.f_to_file.4th.bat $(FileDir)\$(FileName).f $(2)
+
+command.name.0.*.4th=send file.4th to [target]
+command.0.*.4th=\config\scite\AS_MSP430\send_file.4th_to_target.bat $(FileDir)\$(FileName).4th
+
+command.name.1.*.4th=send file.4th to [target] SD_CARD
+command.1.*.4th=\config\scite\AS_MSP430\send_file.4th_to_SD_CARD_target.bat $(FileDir)\$(FileName).4th
+
+command.name.2.*.4th=convert TI registers to FORTH's ones
+command.2.*.4th=\prog\gema\gema -line -t -f \config\gema\TiREGtoFastForth.pat $(FileNameExt) $(FileNameExt)
+
+command.name.3.*.4th=convert FORTH registers to TI's ones
+command.3.*.4th=\prog\gema\gema -line -t -f \config\gema\FastForthREGtoTI.pat $(FileNameExt) $(FileNameExt)
+
--- /dev/null
+\prog\MSP430Flasher\msp430flasher -s -m SBW2 -n %1 -v -w %2 -z [RESET,VCC]
+exit
+
+rem -s : force update
+rem -m : select SBW2 mode
+rem -n %1 : device
+rem -v : verify device
+rem -w %2 : file to be flashed
+rem -z [] : end of flasher behaviour
\ No newline at end of file
--- /dev/null
+@ECHO OFF
+if not exist %~dpn1.f goto error
+if not exist %~dpn2.pat goto error
+if exist %3 goto error
+@%~d1\prog\gema\gema.exe -nobackup -line -t -f %~dpn2.pat %~dpn1.f %~dpn1.4th
+@taskkill /F /IM ttermpro.exe 1> NULL 2>&1
+@"C:\Program Files\teraterm\ttpmacro.exe" /V %~d1\config\scite\AS_MSP430\SendToSD.ttl %~dpn1.4th /C 1> NULL 2>&1
+if ERRORLEVEL 1 goto nextcmd
+exit
+
+:nextcmd
+del null
+@"C:\Program Files (x86)\teraterm\ttpmacro.exe" /V %~d1\config\scite\AS_MSP430\SendToSD.ttl %~dpn1.4th /C
+@del %~dpn1.4th
+:eof
+exit
+
+:error
+
+@start %~d1\config\scite\AS_MSP430\errorftoSDCARD.bat
+exit
+
+rem %~dpn1.f is the symbolic source file described as drive\path\name.f of first arg (%1)
+rem %~dpn2.pat is the pattern file for preprocessor gema.exe described as drive\path\name.pat of 2th arg (%2)
+rem %~dpn1.4th is the source file send to the target
+rem %~d1 is the drive of arg %1
+
--- /dev/null
+@ECHO OFF
+if not exist %~dpn1.f goto error
+if not exist %~dpn2.pat goto error
+if exist %3 goto error
+@%~d1\prog\gema\gema.exe -nobackup -line -t -f %~dpn2.pat %~dpn1.f %~dpn1.4th
+@taskkill /F /IM ttermpro.exe 1> NULL 2>&1
+@"C:\Program Files\teraterm\ttpmacro.exe" /V %~d1\config\scite\AS_MSP430\SendFile.ttl %~dpn1.4th /C 1> NULL 2>&1
+if ERRORLEVEL 1 goto nextcmd
+exit
+
+:nextcmd
+del null
+@"C:\Program Files (x86)\teraterm\ttpmacro.exe" /V %~d1\config\scite\AS_MSP430\SendFile.ttl %~dpn1.4th /C
+@del %~dpn1.4th
+:eof
+exit
+
+:error
+
+@start %~d1\config\scite\AS_MSP430\errorf.bat
+exit
+
+rem %~dpn1.f is the symbolic source file described as drive\path\name.f of first arg (%1)
+rem %~dpn2.pat is the pattern file for preprocessor gema.exe described as drive\path\name.pat of 2th arg (%2)
+rem %~dpn1.4th is the source file send to the target
+rem %~d1 is the drive of arg %1
+
--- /dev/null
+# SciTEDirectoriy.properties
+# For Windows, place in your directory project folder
+# Documentation at http://www.scintilla.org/SciTEDoc.html
+
+
+# Globals
+buffers.zorder.switching=1
+
+# Window sizes and visibility
+if PLAT_WIN
+ position.left=-1
+ position.top=0
+if PLAT_GTK
+ position.left=5
+ position.top=22
+position.width=1000
+position.height=768
+position.maximize=1
+#position.tile=1
+#full.screen.hides.menu=1
+minimize.to.tray=0
+split.vertical=1
+output.horizontal.size=400
+output.vertical.size=600
+output.initial.hide=1
+#horizontal.scrollbar=0
+#horizontal.scroll.width=10000
+#horizontal.scroll.width.tracking=0
+#output.horizontal.scrollbar=0
+#output.horizontal.scroll.width=10000
+#output.horizontal.scroll.width.tracking=0
+#output.scroll=0
+error.select.line=1
+#end.at.last.line=0
+tabbar.visible=1
+#tabbar.hide.one=1
+tabbar.multiline=0
+toolbar.visible=1
+#toolbar.detachable=1
+#toolbar.usestockicons=1
+#menubar.detachable=1
+#undo.redo.lazy=1
+statusbar.visible=1
+#fileselector.width=800
+#fileselector.height=600
+#fileselector.show.hidden=1
+magnification=0
+output.magnification=-4
+
+# Sizes and visibility in edit pane
+line.margin.visible=1
+line.margin.width=4
+margin.width=16
+fold.margin.width=0
+#fold.margin.colour=#00FF00
+#fold.margin.highlight.colour=#0000FF
+blank.margin.left=20
+#blank.margin.right=4
+buffered.draw=1
+#two.phase.draw=0
+use.palette=0
+
+
+#Element styles
+
+
+#view.eol=1
+#control.char.symbol=.
+caret.period=500
+view.whitespace=0
+view.indentation.whitespace=1
+view.indentation.guides=0
+view.indentation.examine=3
+highlight.indentation.guides=1
+caret.fore=#FF0000
+#caret.additional.blinks=0
+caret.width=3
+caret.line.back=#222222
+calltip.back=#FFF0FE
+edge.column=128
+edge.mode=1
+edge.colour=#C0DCC0
+braces.check=1
+braces.sloppy=1
+
+# black background
+selection.fore=#000000
+selection.alpha=256
+selection.back=#808080
+#selection.additional.fore=#0000A0
+#selection.additional.back=#000080
+#selection.additional.alpha=20
+#selection.multiple=0
+#selection.additional.typing=0
+#virtual.space=3
+#rectangular.selection.modifier=4
+#whitespace.fore=#FFFFFF
+#whitespace.back=#FFF0F0
+#error.marker.fore=#0000A0
+#error.marker.back=#DADAFF
+#bookmark.fore=#808000
+#bookmark.back=#FFFFA0
+#bookmark.alpha=
+#find.mark=#0000FF
+#highlight.current.word=1
+#highlight.current.word.by.style=1
+#highlight.current.word.colour=#00D040
+#indicators.alpha=63
+#indicators.under=1
+
+
+# Scripting
+ext.lua.startup.script=$(SciteUserHome)/SciTEStartup.lua
+ext.lua.auto.reload=1
+#ext.lua.reset=1
+
+
+# Checking
+are.you.sure=1
+#are.you.sure.for.build=1
+#save.all.for.build=1
+quit.on.close.last=1
+load.on.activate=1
+#save.on.deactivate=1
+are.you.sure.on.reload=1
+reload.preserves.undo=1
+#check.if.already.open=1
+#temp.files.sync.load=1
+default.file.ext=.txt
+#source.default.extensions=.h|.cxx|.bat
+title.full.path=1
+title.show.buffers=1
+pathbar.visible=1
+#save.recent=1
+#save.session=1
+#session.bookmarks=1
+#session.folds=1
+#save.position=1
+#open.dialog.in.file.directory=1
+#strip.trailing.spaces=1
+#ensure.final.line.end=1
+#ensure.consistent.line.ends=1
+#save.deletes.first=1
+#save.check.modified.time=1
+buffers=40
+buffers.zorder.switching=1
+#api.*.cxx=d:\api\w.api
+#import locale
+#locale.properties=locale.fr.properties
+#win95.death.delay=1000
+#translation.missing=***
+#read.only=1
+#max.file.size=1
+
+# Indentation
+tabsize=4
+indent.size=4
+use.tabs=0
+#indent.auto=1
+indent.automatic=0
+indent.opening=0
+indent.closing=0
+#tab.indents=0
+#backspace.unindents=0
+
+# Wrapping of long lines
+#wrap=1
+#wrap.style=2
+cache.layout=2
+#output.wrap=1
+#output.cache.layout=3
+#wrap.visual.flags=3
+#wrap.visual.flags.location=3
+#wrap.indent.mode=1
+#wrap.visual.startindent=4
+
+# Folding
+# enable folding, and show lines below when collapsed.
+fold=0
+fold.compact=0
+fold.flags=20
+fold.symbols=2
+#fold.highlight=1
+#fold.highlight.colour=#00C0C0
+#fold.on.open=1
+fold.comment=1
+fold.preprocessor=1
+
+# Find and Replace
+# Internal search always available with recursive capability so use in preference to external tool
+find.command=
+# findstr is available on recent versions of Windows including 2000
+if PLAT_WIN
+ find.command=findstr /n /s $(find.files) $(find.what)
+#find.input=$(find.what)
+if PLAT_GTK
+ find.command=grep --line-number "$(find.what)" $(find.files)
+#find.files=*.c *.cxx *.h
+find.files=*.*
+#find.in.files.close.on.find=0
+#find.in.dot=1
+#find.in.binary=1
+#find.close.on.find=0
+#find.replace.matchcase=1
+#find.replace.escapes=1
+#find.replace.regexp=1
+#find.replace.regexp.posix=1
+#find.replace.wrap=0
+#find.replacewith.focus=0
+#find.replace.advanced=1
+find.use.strip=0
+replace.use.strip=0
+#strip.button.height=24
+
+
+# Behaviour
+#eol.mode=LF
+#eol.auto=1
+clear.before.execute=0
+#vc.home.key=1
+#wrap.aware.home.end.keys=1
+#autocompleteword.automatic=1
+#autocomplete.choose.single=1
+caret.policy.xslop=1
+caret.policy.width=20
+caret.policy.xstrict=0
+caret.policy.xeven=0
+caret.policy.xjumps=0
+caret.policy.yslop=1
+caret.policy.lines=3
+caret.policy.ystrict=1
+caret.policy.yeven=1
+caret.policy.yjumps=0
+#visible.policy.strict=1
+#visible.policy.slop=1
+#visible.policy.lines=4
+#time.commands=1
+#caret.sticky=1
+properties.directory.enable=1
+
+# Status Bar
+statusbar.number=4
+statusbar.text.1=\
+li=$(LineNumber) co=$(ColumnNumber) $(OverType) ($(EOLMode)) $(FileAttr)
+statusbar.text.2=\
+$(BufferLength) chars in $(NbOfLines) lines. Sel: $(SelLength) chars.
+statusbar.text.3=\
+Now is: Date=$(CurrentDate) Time=$(CurrentTime)
+statusbar.text.4=\
+$(FileNameExt) : $(FileDate) \97 $(FileTime) | $(FileAttr)
+
+if PLAT_WIN
+ command.scite.help=C:\Program Files\SRWare Iron\iron.exe "C:\Program Files\SciTE\SciTEDoc.html"
+ command.scite.help.subsystem=2
+if PLAT_GTK
+ command.print.*=a2ps "$(FileNameExt)"
+ command.scite.help=netscape "file://$(SciteDefaultHome)/SciTEDoc.html"
+
+# Internationalisation
+# Japanese input code page 932 and ShiftJIS character set 128
+#code.page=932
+#character.set=128
+# Unicode
+#code.page=65001
+code.page=0
+#character.set=204
+# Required for Unicode to work on GTK+:
+#LC_CTYPE=en_US.UTF-8
+if PLAT_GTK
+ output.code.page=65001
+if PLAT_MAC
+ output.code.page=65001
+
+# Export
+#export.keep.ext=1
+export.html.wysiwyg=1
+#export.html.tabs=1
+#export.html.folding=1
+export.html.styleused=1
+export.html.title.fullpath=1
+#export.rtf.tabs=1
+#export.rtf.font.face=Arial
+#export.rtf.font.size=9
+#export.rtf.tabsize=8
+#export.rtf.wysiwyg=0
+#export.tex.title.fullpath=1
+# Magnification (added to default screen font size)
+export.pdf.magnification=0
+# Font: Courier, Helvetica or Times (Courier line-wraps)
+export.pdf.font=Courier
+# Page size (in points): width, height
+# E.g. Letter 612,792; A4 595,842; maximum 14400,14400
+export.pdf.pagesize=595,842
+# Margins (in points): left, right, top, bottom
+export.pdf.margins=56,28,28,28
+export.xml.collapse.spaces=1
+export.xml.collapse.lines=1
+
+# Define values for use in the imported properties files
+chars.alpha=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+chars.numeric=0123456789ABCDEFabcdefx
+chars.accented=\8a\9a\8c\9c\9fÿÀàÁáÂâÃãÄäÅåÆæÇçÈèÉéÊêËëÌìÍíÎîÏïÐðÑñÒòÓóÔôÕõÖØøÙùÚúÛûÜüÝýÞþßö
+# This is a better set for Russian:
+#chars.accented=ÀàÁáÂâÃãÄäÅ娸ÆæÇçÈèÉéÊêËëÌìÍíÎîÏïÐðÑñÒòÓóÔôÕõÖö×÷ØøÙùÚúÛûÜüÝýÞþßÿ
+
+# The open.filter setting is only used on Windows where the file selector has a menu of filters to apply
+# to the types of files seen when opening.
+# There is a limit (possibly 256 characters) to the length of a filter,
+# so not all source extensions can be in this setting.
+#*.idl;*.odl;*.rc;*.rc2;*.dlg;*.def;make*;*.mak;\
+#*.frm;*.cls;*.ctl;;*.pl;;*.iface;*.e;#*.rb;*.cgi;*.lua;\
+#source.files=*.asm;*.c;*.cc;*.f;*.ff;*.far;*.cpp;*.cxx;*.cs;*.h;*.hh;*.hxx;*.hpp;\
+source.files=*.asm;*.avr;*.tiny;*.mega;*.vb;*.vbs;*.bas;*.bat;*.ini;*.py;*.js;*.properties;*.vhd;*.vhdl
+
+# Each platform has a different idea of the most important filters
+if PLAT_WIN
+ all.files=All Files (*.*)|*.*|
+ top.filters=All Source|$(source.files)|$(all.files)
+if PLAT_GTK
+ all.files=All Files (*)|*|Hidden Files (.*)|.*|
+ top.filters=All Source|$(source.files)|$(all.files)
+# As OS X only greys out filtered files, show all as default
+if PLAT_MAC
+ all.files=All Files (*.*)|*.*|
+ top.filters=$(all.files)All Source|$(source.files)|
+
+open.filter=\
+$(top.filters)\
+#$(filter.ada)\
+$(filter.conf)\
+$(filter.asm)\
+#$(filter.asn1)\
+#$(filter.ave)\
+#$(filter.baan)\
+$(filter.bash)\
+#$(filter.caml)\
+#$(filter.cmake)\
+#$(filter.cpp)\
+#$(filter.ch)\
+$(filter.css)\
+#$(filter.d)\
+#$(filter.eiffel)\
+#$(filter.erlang)\
+#$(filter.fortran)\
+$(filter.forth)\
+#$(filter.gap)\
+#$(filter.hs)\
+#$(filter.idl)\
+#$(filter.inno)\
+$(filter.java)\
+$(filter.js)\
+#$(filter.kix)\
+#$(filter.lout)\
+$(filter.lua)\
+#$(filter.matlab)\
+#$(filter.metapost)\
+#$(filter.mmixal)\
+#$(filter.modula3)\
+#$(filter.nncrontab)\
+#$(filter.nsis)\
+#$(filter.opal)\
+#$(filter.pascal)\
+#$(filter.perl)\
+#$(filter.php)\
+#$(filter.pov)\
+#$(filter.powershell)\
+#$(filter.prg)\
+$(filter.properties)\
+$(filter.ps)\
+$(filter.python)\
+$(filter.r)\
+$(filter.ruby)\
+#$(filter.sql)\
+#$(filter.specman)\
+$(filter.tcl)\
+$(filter.tex)\
+$(filter.text)\
+$(filter.txt2tags)\
+$(filter.vb)\
+$(filter.web)\
+#$(filter.yaml)\
+$(filter.verilog)\
+$(filter.vhdl)
+
+#save.filter=$(open.filter)
+
+# Give symbolic names to the set of fonts used in the standard styles.
+if PLAT_WIN
+ font.base=font:Lucida Console,size:10
+ font.small=font:Lucida Console,size:10
+ font.comment=font:Lucida Console,size:10
+ font.code.comment.box=$(font.comment)
+ font.code.comment.line=$(font.comment)
+ font.code.comment.doc=$(font.comment)
+ font.code.comment.nested=$(font.comment)
+ font.text=font:Lucida Console,size:10
+ font.text.comment=font:Lucida Console,size:10
+ font.embedded.base=font:Lucida Console,size:10
+ font.embedded.comment=font:Lucida Console,size:10
+ font.monospace=font:Lucida Console,size:10
+ font.vbs=font:Lucida Sans Unicode,size:10
+if PLAT_GTK
+ font.base=font:lucidatypewriter,size:12
+ font.small=font:lucidatypewriter,size:10
+ font.comment=font:new century schoolbook,size:8
+ font.code.comment.box=$(font.comment)
+ font.code.comment.line=$(font.comment)
+ font.code.comment.doc=$(font.comment)
+ font.code.comment.nested=$(font.comment)
+ font.text=font:times,size:8
+ font.text.comment=font:lucidatypewriter,size:8
+ font.embedded.base=font:lucidatypewriter,size:8
+ font.embedded.comment=font:lucidatypewriter,size:8
+ font.monospace=font:courier,size:8
+ font.vbs=font:new century schoolbook,size:8
+if PLAT_MAC
+ font.base=font:Verdana,size:12
+ font.small=font:Verdana,size:10
+ font.comment=font:Georgia,size:13
+ font.code.comment.box=$(font.comment)
+ font.code.comment.line=$(font.comment)
+ font.code.comment.doc=$(font.comment)
+ font.code.comment.nested=$(font.comment)
+ font.text=font:Times New Roman,size:13
+ font.text.comment=font:Verdana,size:11
+ font.embedded.base=font:Verdana,size:11
+ font.embedded.comment=font:Comic Sans MS,size:10
+ font.monospace=font:Courier New,size:12
+ font.vbs=font:Lucida Sans Unicode,size:12
+ font.js=$(font.comment)
+
+# Old GTK+ font settings are faster but not antialiased
+ #~ font.base=font:lucidatypewriter,size:12
+ #~ font.small=font:lucidatypewriter,size:10
+ #~ font.comment=font:new century schoolbook,size:12
+ #~ font.code.comment.box=$(font.comment)
+ #~ font.code.comment.line=$(font.comment)
+ #~ font.code.comment.doc=$(font.comment)
+ #~ font.text=font:times,size:14
+ #~ font.text.comment=font:lucidatypewriter,size:10
+ #~ font.embedded.base=font:lucidatypewriter,size:12
+ #~ font.embedded.comment=font:lucidatypewriter,size:12
+ #~ font.monospace=font:courier,size:12
+ #~ font.vbs=font:new century schoolbook,size:12
+
+# Give symbolic names to the set of colours used in the standard styles.
+colour.code.comment.box=fore:#00FF00
+colour.code.comment.line=fore:#00FF00
+colour.code.comment.doc=fore:#3F703F
+colour.code.comment.nested=fore:#A0C0A0
+colour.text.comment=fore:#0000FF,back:#FFFFFF
+colour.other.comment=fore:#00FF00
+colour.embedded.comment=back:#E0EEFF
+colour.embedded.js=back:#F0F0FF
+colour.notused=back:#FF0000
+#couleur des nombres
+colour.number=fore:#FF00FF
+#couleur des instructions du langage
+colour.keyword=fore:#FF0000
+#couleur chaînes entre guillemets
+colour.string=fore:#00FFFF
+colour.char=fore:#7F7F7F
+colour.operator=fore:#00FF00
+colour.preproc=fore:#FF7F00
+colour.error=fore:#FFFF00,back:#FF0000
+
+# Global default styles for all languages
+# Default style, black background
+style.*.32=back:#000000,fore:#FFFFFF,font:Lucida Console,size:10
+# Line number
+style.*.33=back:#404040,$(font.base))
+# Brace highlight
+style.*.34=back:#222222,fore:#8080FF,bold
+# Brace incomplete highlight
+style.*.35=back:#222222,fore:#FF0000,bold
+# Control characters
+style.*.36=
+# Indentation guides
+style.*.37=fore:#C0C0C0,back:#FFFFFF
+
+# Printing - only works on Windows
+if PLAT_WIN
+ #print.colour.mode=1
+ print.magnification=-1
+ # Setup: left, right, top, bottom margins, in local units:
+ # hundredths of millimeters or thousandths of inches
+ print.margins=2000,1000,1000,1000
+ # Header/footer:
+ # && = &; &p = current page
+ # &f = file name; &F = full path
+ # &d = file date; &D = current date
+ # &t = file time; &T = full time
+ print.header.format=$(FileNameExt) \97 Printed on $(CurrentDate), $(CurrentTime) \97 Page $(CurrentPage)
+ print.footer.format=$(FilePath) \97 File date: $(FileDate) \97 File time: $(FileTime)
+ # Header/footer style
+ print.header.style=font:Arial,size:12,bold
+ print.footer.style=font:Arial Narrow,size:10,italics
+
+# Warnings - only works on Windows and needs to be pointed at files on machine
+#if PLAT_WIN
+# warning.findwrapped=100,E:\Windows\Media\SFX\Boing.wav
+# warning.notfound=0,Effect.wav
+# warning.wrongfile=0,Glass.wav
+# warning.executeok=0,Fanfare.wav
+# warning.executeko=100,GlassBreak.wav
+# warning.nootherbookmark=100,Boing2.wav
+
+# Define the Lexer menu,
+# Each item contains three parts: menu string | file extension | key
+# The only keys allowed currently are based on F-keys and alphabetic keys and look like
+# [Ctrl+][Shift+][Fn|a] such as F12 or Ctrl+Shift+D.
+# A '&' may be placed before a letter to be used as an accelerator. This does not work on GTK+.
+
+keyText=Shift+F11
+keyMake=Ctrl+Shift+F11
+keyHTML=F12
+keyXML=Shift+F12
+# On OS X, F11 is used by Expose, F12 by Dashbard
+if PLAT_MAC
+ keyText=Shift+F13
+ keyMake=Ctrl+Shift+F13
+ keyHTML=Ctrl+Shift+F14
+ keyXML=Shift+F14
+
+menu.language=\
+Text|txt|Shift+F11|\
+#Ada|ads||\
+#Apache Confi&g|conf||\
+Assembler|asm||\
+#ASN.1|asn1||\
+#Avenue|ave||\
+#Baan|bc||\
+&Batch|bat||\
+#Bullant|ant||\
+&C / C++|c||\
+#CMake|cmake||\
+C&#|cs||\
+#COBOL|cob||\
+#Csound|orc||\
+CSS|css||\
+D|d||\
+&Difference|diff||\
+#&Eiffel|e||\
+#Erlang|erl||\
+&Errorlist|err||\
+#FlagShip|prg||\
+Forth|forth||\
+#&Fortran|f90||\
+#Gap|g||\
+#Haskell|hs||\
+H&ypertext|html|F12|\
+#&InnoSetup|iss||\
+&Java|java||\
+Java&Script|js||\
+#&Kix|kix||\
+#Lisp|lisp||\
+#Lot|lot||\
+#Lout|lt||\
+#Lu&a|lua||\
+#Matlab|m.matlab||\
+&Makefile|mak|Ctrl+Shift+F11|\
+#MetaPost|mp||\
+#MMIXAL|mms||\
+#Modula-3|m3||\
+#&nnCron crontab|tab||\
+#NSIS|nsis||\
+#Objective Caml|ml||\
+#Octave|m.octave||\
+#Opal|impl||\
+#Pascal|pas||\
+Pe&rl|pl||\
+P&HP|php||\
+#P&LSQL|spec||\
+#P&ostScript|ps||\
+#P&OV-Ray SDL|pov||\
+#PowerShell|ps1||\
+#PowerPro|powerpro||\
+&Properties|properties||\
+Pytho&n|py||\
+#R|R||\
+#Reso&urce|rc||\
+Ruby|rb||\
+Shell|sh||\
+S&QL|sql||\
+#Specman|e||\
+&TCL|tcl||\
+TeX|tex||\
+#&txt2tags|t2t||\
+&VB|vb||\
+VBScr&ipt|vbs||\
+#Verilog|v||\
+#VHDL|vhd||\
+&XML|xml|$(keyXML)|\
+YAML|yaml||
+
+# User defined key commands
+user.shortcuts=\
+Ctrl+Shift+V|IDM_PASTEANDDOWN|\
+Ctrl+PageUp|IDM_PREVFILE|\
+Ctrl+PageDown|IDM_NEXTFILE|
+
+#KeypadPlus|IDM_EXPAND|\
+#KeypadMinus|IDM_BLOCK_COMMENT|
+
+#user.context.menu=\
+#||\
+#Next File|IDM_NEXTFILE|\
+#Prev File|IDM_PREVFILE|
+
+# Import all the language specific properties files
+#import abaqus
+#import ada
+#import asn1
+#import au3
+#import ave
+#import baan
+#import freebasic
+#import blitzbasic
+#import bullant
+#import caml
+import conf
+#import cobol
+import cpp
+#import cmake
+#import csound
+import css
+#import d
+#import eiffel
+#import erlang
+#import escript
+#import flagship
+import \config\scite\AS_MSP430\forth
+#import fortran
+#import gap
+#import haskell
+import html
+#import inno
+#import kix
+import lisp
+#import lot
+#import lout
+import lua
+#import matlab
+#import metapost
+#import mmixal
+#import modula3
+#import nimrod
+#import nncrontab
+#import nsis
+#import opal
+import \config\scite\others
+#import pascal
+#import perl
+#import pov
+#import powerpro
+#import powershell
+import ps
+#import purebasic
+import python
+#import r
+#import rebol
+import ruby
+#import scriptol
+#import smalltalk
+#import spice
+#import sql
+#import specman
+#import tacl
+#import tal
+import tcl
+#import txt2tags
+import tex
+#import vb
+#import yaml
+#import verilog
+#import vhdl
+import \config\scite\AS_MSP430\asm
+import \config\scite\hex
+
+
+# Error list styles
+
+style.errorlist.32=fore:#B0B000,$(font.small)
+# Default
+style.errorlist.0=fore:#FFFFFF
+# Microsoft Error
+style.errorlist.3=fore:#0080FF
+# command or return status
+style.errorlist.4=fore:#FF00FF
+
+# Text matched with find in files and message part of GCC errors
+style.errorlist.21=fore:#FF0000
+
+
+
+
--- /dev/null
+# Define SciTE settings for Motorola S-Record and Intel HEX files.
+
+file.patterns.srec=*.mot;*.srec
+file.patterns.ihex=*.hex
+file.patterns.tehex=*.tek
+
+filter.srec=S-Record (mot)|$(file.patterns.srec)|
+filter.ihex=Intel HEX (hex)|$(file.patterns.ihex)|
+filter.tehex=Tektronix extended HEX (tek)|$(file.patterns.tehex)|
+
+*filter.srec=$(filter.srec)
+*filter.ihex=$(filter.ihex)
+*filter.tehex=$(filter.tehex)
+
+lexer.$(file.patterns.srec)=srec
+lexer.$(file.patterns.ihex)=ihex
+lexer.$(file.patterns.tehex)=tehex
+
+*language.srecord=S-Record|mot||
+*language.intelhex=Intel HEX|hex||
+*language.tektronixhex=Tektronix extended HEX|tek||
+
+# Default
+style.srec.0=
+# Record start 'S'
+style.srec.1=$(style.srec.2)
+# Record type
+style.srec.2=fore:#7F0000
+# Record type unknown
+style.srec.3=$(style.srec.2),$(style.srec.10)
+# Byte count field: Correct byte count
+style.srec.4=fore:#7F7F00
+# Byte count field: Wrong byte count
+style.srec.5=$(colour.error)
+# Address field: No address
+style.srec.6=fore:#7F00FF
+# Address field: Data address
+style.srec.7=fore:#007FFF
+# Address field: Record count
+style.srec.8=$(style.srec.6)
+# Address field: Start address
+style.srec.9=$(style.srec.7)
+# Address field: Type unknown (this state does not contain any characters)
+style.srec.10=italics
+# .11 N/A
+# Data odd
+style.srec.12=bold
+# Data even
+style.srec.13=
+# Data field: Position unknown
+style.srec.14=$(style.srec.10)
+# Data field empty (this state does not contain any characters)
+style.srec.15=
+# Checksum field: Correct checksum
+style.srec.16=fore:#00BF00
+# Checksum field: Wrong checksum
+style.srec.17=$(colour.error)
+# Garbage data after the record
+style.srec.18=$(style.srec.10)
+
+# Same color scheme as above, comments when differing
+style.ihex.0=$(style.srec.0)
+# Record start ':'
+style.ihex.1=$(style.srec.1)
+style.ihex.2=$(style.srec.2)
+style.ihex.3=$(style.srec.3)
+style.ihex.4=$(style.srec.4)
+style.ihex.5=$(style.srec.5)
+style.ihex.6=$(style.srec.6)
+style.ihex.7=$(style.srec.7)
+# .8 N/A
+# Data field: Start address
+style.ihex.9=$(style.srec.9)
+# Address field: Type unknown (4 digits as usual)
+style.ihex.10=$(style.srec.10)
+# Data field: Extended address
+style.ihex.11=$(style.ihex.9)
+style.ihex.12=$(style.srec.12)
+style.ihex.13=$(style.srec.13)
+# Data field: Type unknown
+style.ihex.14=$(style.srec.14)
+style.ihex.15=$(style.srec.15)
+style.ihex.16=$(style.srec.16)
+style.ihex.17=$(style.srec.17)
+style.ihex.18=$(style.srec.18)
+
+# Same color scheme as above, comments when differing
+style.tehex.0=$(style.srec.0)
+# Record start '%'
+style.tehex.1=$(style.srec.1)
+style.tehex.2=$(style.srec.2)
+style.tehex.3=$(style.srec.3)
+style.tehex.4=$(style.srec.4)
+style.tehex.5=$(style.srec.5)
+# .6 N/A
+style.tehex.7=$(style.srec.7)
+# .8 N/A
+style.tehex.9=$(style.srec.9)
+# Address field: Type unknown (9 digits as usual)
+style.tehex.10=$(style.srec.10)
+# .11 N/A
+style.tehex.12=$(style.srec.12)
+style.tehex.13=$(style.srec.13)
+# .14 N/A
+# .15 N/A
+style.tehex.16=$(style.srec.16)
+style.tehex.17=$(style.srec.17)
+style.tehex.18=$(style.srec.18)
--- /dev/null
+# Define SciTE settings for other simple files.
+
+file.patterns.props=*.properties;*.session;*.ini;*.inf;*.url;*.cfg;*.cnf;*.aut
+file.patterns.text=*.txt;*.log;*.lst;*.doc;*.diz;*.nfo
+file.patterns.batch=*.bat;*.cmd;*.nt
+file.patterns.diff=*.diff;*.patch
+file.patterns.make=makefile;Makefile;*.mak;configure
+
+*source.patterns.props=$(file.patterns.props);
+*source.patterns.batch=$(file.patterns.batch);
+*source.patterns.diff=$(file.patterns.diff);
+*source.patterns.make=$(file.patterns.make);*.iface;
+
+filter.properties=Properties (ini inf reg url cfg cnf)|$(file.patterns.props)|
+filter.text=Text (txt log lst doc diz nfo)|$(file.patterns.text);make*|
+filter.batch=Batch (bat cmd nt)|$(file.patterns.batch)|
+filter.diff=Difference (diff patch)|$(file.patterns.diff)|
+
+*filter.properties=$(filter.properties)
+*filter.text=$(filter.text)
+
+lexer.$(file.patterns.props)=props
+lexer.$(file.patterns.batch)=batch
+lexer.*.err=errorlist
+lexer.$(file.patterns.make)=makefile
+lexer.*.iface=makefile
+lexer.$(file.patterns.diff)=diff
+
+*language.batch=&Batch|bat||
+*language.difference=&Difference|diff||
+*language.errorlist=&Errorlist|err||
+*language.properties=&Properties|properties||
+*language.makefile=&Makefile|mak|$(keyMake)|
+*language._text=Text|txt|$(keyText)|
+
+word.characters.$(file.patterns.text)=$(chars.alpha)$(chars.numeric)$(chars.accented)-'
+
+colour.other.operator=fore:#B06000
+
+# Properties styles
+
+# Default
+style.props.0=
+# Comment
+style.props.1=fore:#007F7F,$(font.comment)
+# Section
+style.props.2=$(colour.string),back:#E0F0F0,eolfilled
+# Assignment operator
+style.props.3=$(colour.other.operator)
+# Default value (@)
+style.props.4=$(colour.preproc)
+# Key
+style.props.5=
+# Matched Operators
+style.props.34=fore:#0000FF,notbold
+style.props.35=fore:#FF0000,notbold
+comment.block.props=#~
+preprocessor.symbol.$(file.patterns.make)=!
+preprocessor.start.$(file.patterns.make)=IF IFDEF IFNDEF
+preprocessor.middle.$(file.patterns.make)=ELSE ELSEIF ELSEIFDEF ELSEIFNDEF
+preprocessor.end.$(file.patterns.make)=ENDIF
+
+# Batch styles
+
+# List from http://www.easydos.com/dosindex.html and https://sourceforge.net/p/scintilla/bugs/1686/
+# I limit here the commands to those built in command.com, ie. I don't list external Dos commands
+# if [no] (test) (command) -- test is EXIST (filename) | (string1)==(string2) | ERRORLEVEL (number)
+# for %%(variable) IN (set) DO (command) -- variable is [a-zA-Z] -- eg for %%X in (*.txt) do type %%X
+# Also includes device names.
+keywordclass.batch=\
+assoc aux break call cd chcp chdir choice cls cmdextversion \
+color com1 com2 com3 com4 con copy ctty date defined \
+del dir do dpath echo else endlocal erase errorlevel exist \
+exit for ftype goto if in lpt1 lpt2 lpt3 lpt4 md mkdir move \
+not nul path pause popd prompt prn pushd rd rem ren \
+rename rmdir set setlocal shift start time title type ver \
+verify vol
+keywords.$(file.patterns.batch)=$(keywordclass.batch)
+
+# Optional list of external commands to highlight in style 5.
+# If not set all commands are highlighted in style 5.
+#keywords2.$(file.patterns.batch)=append attrib chkdsk comp diskcomp
+
+# Default
+style.batch.0=fore:#000000
+# Comment (rem or ::)
+style.batch.1=fore:#007F00,$(font.comment)
+# Keywords
+style.batch.2=$(colour.keyword),bold
+# Label (line beginning with ':')
+style.batch.3=$(colour.string),back:#606060,fore:#FFFF00,eolfilled
+# Hide command character ('@')
+style.batch.4=$(colour.preproc)
+# External commands
+style.batch.5=fore:#007090,$(font.monospace),bold
+# Variable: %%x (x is almost whatever, except space and %), %n (n in [0-9]), %EnvironmentVar%
+style.batch.6=fore:#800080
+# Operator: * ? < > |
+style.batch.7=fore:#000000
+
+comment.block.batch=REM ~
+
+# Makefile styles
+
+# Default
+style.makefile.0=fore:#000000
+# Comment: #
+style.makefile.1=$(colour.other.comment),$(font.code.comment.box)
+# Pre-processor or other comment: !
+style.makefile.2=$(colour.preproc)
+# Variable: $(x)
+style.makefile.3=fore:#000080
+# Operator
+style.makefile.4=$(colour.other.operator)
+# Target
+style.makefile.5=fore:#A00000
+# Error
+style.makefile.9=$(colour.error),eolfilled
+# Matched Operators
+style.makefile.34=fore:#0000FF,notbold
+style.makefile.35=fore:#FF0000,notbold
+
+comment.block.makefile=#~
+
+# Error list styles
+
+style.errorlist.32=fore:#B06000,$(font.small)
+# Default
+style.errorlist.0=fore:#000000
+# python Error
+style.errorlist.1=fore:#FF0000
+# gcc Error
+style.errorlist.2=fore:#800080
+# Microsoft Error
+style.errorlist.3=fore:#808000
+# command or return status
+style.errorlist.4=fore:#0000FF
+# Borland error and warning messages
+style.errorlist.5=fore:#B06000
+# perl error and warning messages
+style.errorlist.6=fore:#FF0000
+# .NET tracebacks
+style.errorlist.7=fore:#FF0000
+# Lua error and warning messages
+style.errorlist.8=fore:#FF0000
+# ctags
+style.errorlist.9=fore:#FF00FF
+# diff changed !
+style.errorlist.10=fore:#007F00
+# diff addition +
+style.errorlist.11=fore:#00007F
+# diff deletion -
+style.errorlist.12=fore:#007F7F
+# diff message ---
+style.errorlist.13=fore:#7F0000
+# PHP error
+style.errorlist.14=fore:#FF0000
+# Essential Lahey Fortran 90 error
+style.errorlist.15=fore:#FF0000
+# Intel Fortran Compiler error
+style.errorlist.16=fore:#FF0000
+# Intel Fortran Compiler v8.0 error/warning
+style.errorlist.17=fore:#FF0000
+# Absoft Pro Fortran 90/95 v8.2 error or warning
+style.errorlist.18=fore:#FF0000
+# HTML Tidy
+style.errorlist.19=fore:#FF0000
+# Java runtime stack trace
+style.errorlist.20=fore:#FF0000
+# Text matched with find in files and message part of GCC errors
+style.errorlist.21=fore:#000000
+# GCC showing include path to following error
+style.errorlist.22=fore:#800080
+# Escape sequence
+style.errorlist.23=fore:#000000,notvisible,back:#FFFFFF,$(error.background)
+# Escape sequence unknown
+style.errorlist.24=back:#FFE0A0
+# Ensures that spacing is not affected by line number styles
+style.errorlist.33=$(font.small)
+# Basic colours
+style.errorlist.40=fore:#000000,$(error.background)
+style.errorlist.41=fore:#800000,$(error.background)
+style.errorlist.42=fore:#008000,$(error.background)
+style.errorlist.43=fore:#808000,$(error.background)
+style.errorlist.44=fore:#000080,$(error.background)
+style.errorlist.45=fore:#800080,$(error.background)
+style.errorlist.46=fore:#008080,$(error.background)
+style.errorlist.47=fore:#A0A0A0,$(error.background)
+# Intense colours
+style.errorlist.48=fore:#000000,bold,$(error.background)
+style.errorlist.49=fore:#800000,bold,$(error.background)
+style.errorlist.50=fore:#008000,bold,$(error.background)
+style.errorlist.51=fore:#808000,bold,$(error.background)
+style.errorlist.52=fore:#000080,bold,$(error.background)
+style.errorlist.53=fore:#800080,bold,$(error.background)
+style.errorlist.54=fore:#008080,bold,$(error.background)
+style.errorlist.55=fore:#A0A0A0,bold,$(error.background)
+
+error.background=back:#FFF7E7,eolfilled
+
+lexer.errorlist.value.separate=1
+#lexer.errorlist.escape.sequences=1
+
+# Difference styles
+
+# Default
+style.diff.0=fore:#000000
+# Comment (part before "diff ..." or "--- ..." and , Only in ..., Binary file...)
+style.diff.1=fore:#007F00
+# Command (diff ...)
+style.diff.2=fore:#7F7F00
+# Source file (--- ...) and Destination file (+++ ...)
+style.diff.3=fore:#7F0000
+# Position setting (@@ ...)
+style.diff.4=fore:#7F007F
+# Line removal (-...)
+style.diff.5=fore:#007F7F
+# Line addition (+...)
+style.diff.6=fore:#00007F
+# Line change (!...)
+style.diff.7=fore:#7F7F7F
+
+command.build.makefile=make
+command.build.*.mak=make
+
+command.help.*.properties="file://$(SciteDefaultHome)/SciTEDoc.html#property-$(CurrentSelection)"
+command.help.subsystem.*.properties=2
+
+if PLAT_WIN
+ command.go.*.bat="$(FileNameExt)"
+ command.name.0.*.bat=Execute Selection
+ command.0.*.bat=$(CurrentSelection)
+ command.name.1.*.mak=nmake
+ command.1.*.mak=nmake -f $(FileNameExt)
--- /dev/null
+; -*- coding: utf-8 -*-
+; http://patorjk.com/software/taag/#p=display&f=Banner&t=Fast Forth
+
+; Fast Forth For Texas Instrument MSP430FRxxxx FRAM devices
+; Copyright (C) <2017> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+; ----------------------------------------------------------------------
+; assembled with MACROASSEMBLER AS (http://john.ccac.rwth-aachen.de:8000/as/)
+; ----------------------------------------------------------------------
+
+ .cpu MSP430
+ .include "mspregister.mac" ;
+; macexp off ; unrem to hide macro results
+
+;----------------------------------------------------------------------------------------------------------
+; Vingt fois sur le métier remettez votre ouvrage,
+; Polissez-le sans cesse, et le repolissez,
+; Ajoutez quelquefois, et souvent effacez.
+; Boileau, L'Art poétique
+;----------------------------------------------------------------------------------------------------------
+
+;==========================================================================================================
+; FAST FORTH challenge: time to load, interpret, compile and execute 31136 bytes source file "CORETEST.4th"
+;==========================================================================================================
+; Look at a FAST FORTH competitor @24MHZ, 115200 Bds without flow control, delay=50ms/line ==> result: 54s.
+;==========================================================================================================
+; FAST FORTH on a MSP430FR5738 @500kHz UART 115200 Bds, PL2303TA/HXD, download speed measured by TERATERM
+; real bytes rate without UART connexion : 11.36 kbytes/s ==> 113600 Bds instead of 115200 Bds expected
+; real bytes rate without echo (half duplex) : 3.19 kbytes/s ==> result: 9.75s.
+; process time @ 1MHz = 2/(1/3.19 - 1/11.36) = 8.86 kbytes/s of source file.
+;==========================================================================================================
+; test on a MSP430FR5738 @24MHz UART 6 Mbds via si8622EC-B-IS iso, 1m of cable, PL2303HXD, TERATERM, COREi7
+; download CORETESTx20.4th without UART connexion : 165 kbytes/s ==> 1.65 MBds instead of 6 MBds expected
+; without echo (half duplex), best of 10 downloads: 123.5 kbytes/s ==> result: 0.25s ==> 200 times faster!
+;----------------------------------------------------------------------------------------------------------
+
+;===============================================================================================
+;===============================================================================================
+; before assembling or programming you must set DEVICE in param1 and TARGET in param2 (SHIFT+F8)
+; according to the TARGET "switched" below
+; example : your TARGET = MSP_EXP430FR5969 (notice the underscore) ==> DEVICE = MSP430FR5969
+;===============================================================================================
+;===============================================================================================
+
+;-----------------------------------------------------------------------------------------------
+; TARGET configuration SWITCHES ; bytes values are measured for DTC=1, 8MHz 2457600 bds settings
+;-----------------------------------------------------------------------------------------------
+; TOTAL - SUM of (INFO+RAM +VECTORS) = MAIN PROG
+;MSP_EXP430FR5739 ; compile for MSP-EXP430FR5739 launchpad ; 4136 - 160 ( 24 + 86 + 50 ) = 3976 bytes
+MSP_EXP430FR5969 ; compile for MSP-EXP430FR5969 launchpad ; 4104 - 162 ( 24 + 86 + 52 ) = 3942 bytes
+;MSP_EXP430FR5994 ; compile for MSP-EXP430FR5994 launchpad ; 4138 - 186 ( 24 + 86 + 76 ) = 3952 bytes
+;MSP_EXP430FR6989 ; compile for MSP-EXP430FR6989 launchpad ; 4136 - 168 ( 24 + 86 + 58 ) = 3968 bytes
+;MSP_EXP430FR4133 ; compile for MSP-EXP430FR4133 launchpad ; 4168 - 140 ( 24 + 86 + 30 ) = 4028 bytes
+;CHIPSTICK_FR2433 ; compile for the "CHIPSTICK" of M. Ken BOAK ; 4070 - 148 ( 24 + 86 + 38 ) = 3932 bytes
+
+; choose DTC (Direct Threaded Code) model, if you don't know, choose 1
+DTC .equ 1 ; DTC model 1 : DOCOL = CALL rDOCOL 14 cycles 1 word shortest DTC model
+ ; DTC model 2 : DOCOL = PUSH IP, CALL rEXIT 13 cycles 2 words good compromize for mix FORTH/ASM code
+ ; DTC model 3 : inlined DOCOL 9 cycles 4 words fastest
+
+FREQUENCY .equ 16 ; fully tested at 0.5,1,2,4,8,16 (and 24 for MSP430FR57xx) MHz
+THREADS .equ 16 ; 1, 4, 8, 16, 32 search entries in dictionnary. 16 is an optimum: speed up to 8 the interpretation.
+ ; +40, +66, +90, +154 bytes
+
+TERMINALBAUDRATE .equ 3000000 ; choose value considering the frequency and the bridge uart/USB, see explanations below.
+TERMINALXONXOFF ;; to allow XON/XOFF flow control (PL2303TA/CP2102 devices)
+;TERMINALCTSRTS ; to allow Hardware flow control (FT232RL device)
+
+ .include "Target.inc" ; to define target config: I/O, memory, SFR, vectors, TERMINAL eUSCI, SD_Card eUSCI, LF_XTAL,
+
+;-----------------------------------------------------------------------
+; KERNEL ADD-ON SWITCHES ;
+;-----------------------------------------------------------------------
+MSP430ASSEMBLER ; + 1896 bytes : add embedded assembler with TI syntax; without, you can do all but all much more slowly...
+;SD_CARD_LOADER ; + 1776 bytes to LOAD source files from SD_card
+;SD_CARD_READ_WRITE ; + 1162 bytes to create, read, write, close and del files, + copy file from PC to SD_Card
+;VOCABULARY_SET ; + 108 bytes : add VOCABULARY FORTH ASSEMBLER ALSO PREVIOUS ONLY DEFINITIONS (FORTH83, not ANSI)
+;LOWERCASE ; + 30 bytes : enable to EMIT strings in lowercase.
+;BACKSPACE_ERASE ; + 24 bytes : replace BS by ERASE, for visual comfort
+
+;-------------------------------------------------------------------------------------------------
+; OPTIONAL KERNELL ADD-ON SWITCHES, because their source file can be downloaded later >----------------+
+;------------------------------------------------------------------------------------------------- |
+; v
+;UTILITY ; + 404 bytes : add .S WORDS U.R DUMP ? UTILITY.f
+;SD_TOOLS ; + 126 bytes for trivial DIR, FAT, CLUSTER and SECTOR view, needs UTILITY SD_TOOLS.f
+;ANS_CORE_COMPLIANT ; + 876 bytes : required to pass coretest.4th ; (includes items below) COMPxMPY.f (x = H or S)
+;ARITHMETIC ; + 358 bytes : add S>D M* SM/REM FM/MOD * /MOD / MOD */MOD /MOD */ ARITxMPY.f (x = H or S)
+;DOUBLE ; + 130 bytes : add 2@ 2! 2DUP 2SWAP 2OVER DOUBLE.f
+;ALIGNMENT ; + 24 bytes : add ALIGN ALIGNED ALIGN.f
+;PORTABILITY ; + 46 bytes : add CHARS CHAR+ CELLS CELL+ PORTABLE.f
+
+
+
+;=================================================================
+; XON/XOFF control flow configuration ; up to 285kBd/MHz with ECHO
+;=================================================================
+; notice: these specified baud rates perform downloads error free.
+
+; the cheapest and best : UARTtoUSB cable with Prolific PL2303TA (supply current = 8 mA) or PL2303HXD
+; ---------------------------------------------------------------------------------------------------
+; WARNING ! if you use it as supply for your target, open box before to weld red wire on 3v3 pad !
+; ---------------------------------------------------------------------------------------------------
+; 9600,19200,38400,57600,115200,134400 (500kHz)
+; + 161280,201600,230400,268800 (1MHz)
+; + 403200,460800,614400 (2MHz)
+; + 806400,921600,1228800 (4MHz)
+; + 2457600 (8MHz)
+; + 3000000 (16MHz)
+; + 6000000 (24MHz, MSP430FR57xx)
+
+
+; UARTtoUSB module with Silabs CP2102 (supply current = 20 mA)
+; ---------------------------------------------------------------------------------------------------
+; WARNING ! if you use it as supply for your target, connect VCC on the wire 3v3 !
+; ---------------------------------------------------------------------------------------------------
+; 9600,19200,38400,57600 (500kHz)
+; + 115200 (1MHz)
+; + 230400 (2MHz)
+; + 460800 (4MHz)
+; + 921600,1382400,1843200 (8MHz,16MHz,24MHz)
+; notice that you must program the CP2102 device to add speeds 1382400, 1843200 bds.
+
+; Launchpad --- UARTtoUSB device
+; RX <-- TX
+; TX --> RX
+; GND <-> GND
+
+; TERATERM config terminal : NewLine receive : AUTO,
+; NewLine transmit : CR+LF
+; Size : 128 chars x 49 lines (adjust lines to your display)
+
+; TERATERM config serial port : 9600 to 6000000 Bds,
+; 8bits, no parity, 1Stopbit,
+; XON/XOFF flow control,
+; delay = 0ms/line, 0ms/char
+
+; don't forget : save new TERATERM configuration !
+
+
+;=================================================================
+; Hardware control flow configuration with FT232RL device only
+;=================================================================
+
+; UARTtoUSB module with FTDI FT232RL
+;===============================================================================================
+; 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)
+
+; Launchpad UARTtoUSB device
+; RX <-- TX
+; TX --> RX
+; RTS --> CTS
+; GND <-> GND
+
+; notice that the control flow seems not necessary for TX
+
+; TERATERM config terminal : NewLine receive : AUTO,
+; NewLine transmit : CR+LF (so FT232RL can test its CTS line during transmit LF)
+; Size : 128 chars x 49 lines (adjust lines to your display)
+
+; TERATERM config serial port : 9600 to 921600 Bds,
+; 8bits, no parity, 1Stopbit,
+; Hardware flow control,
+; delay = 0ms/line, 0ms/char
+
+; don't forget : save new TERATERM configuration !
+
+
+
+; ----------------------------------------------------------------------
+; DTCforthMSP430FR5xxx Init vocabulary pointers:
+; ----------------------------------------------------------------------
+
+ .IF THREADS = 1
+
+voclink .set 0 ; init vocabulary links
+forthlink .set 0
+asmlink .set 0
+
+FORTHWORD .MACRO name
+ .word forthlink
+forthlink .set $
+ .byte STRLEN(name),name
+; .align 2
+ .ENDM
+
+FORTHWORDIMM .MACRO name
+ .word forthlink
+forthlink .set $
+ .byte STRLEN(name)+128,name
+; .align 2
+ .ENDM
+
+asmword .MACRO name
+ .word asmlink
+asmlink .set $
+ .byte STRLEN(name),name
+; .align 2
+ .ENDM
+
+ .ELSE
+ .include "ForthThreads.mac"
+ .ENDIF
+
+; ----------------------------------------------------------------------
+; DTCforthMSP430FR5xxx RAM memory map:
+; ----------------------------------------------------------------------
+
+; name words ; comment
+
+;LSTACK=L0 ; ----- 1C00
+ ; |
+LSTACK_SIZE .equ 16 ; | grows up
+ ; |
+ ; V
+ ;
+ ; ^
+ ; |
+PSTACK_SIZE .equ 48 ; | grows down
+ ; |
+;PSTACK=S0 ; ----- 1C80
+ ;
+ ; ^
+ ; |
+RSTACK_SIZE .equ 48 ; | grows down
+ ; |
+;RSTACK=R0 ; ---- 1CE0
+
+ ; aligned buffers only required for terminal tasks.
+
+; names bytes ; comments
+
+;PAD ; ----- 1CE2
+ ; |
+PAD_SIZE .equ 84 ; | grows up (ans spec. : PAD >= 84 chars)
+ ; |
+ ; v
+ ; ------1D36
+;TIB ; ----- 1D38
+ ; |
+TIB_SIZE .equ 80 ; | grows up (ans spec. : TIB >= 80 chars)
+ ; |
+ ; v
+ ; ^
+ ; |
+HOLD_SIZE .equ 34 ; | grows down (ans spec. : HOLD_SIZE >= (2*n) + 2 char, with n = 16 bits/cell
+ ; |
+;BASE_HOLD ; ----- 1DAA
+ ; |
+; variables systme ; | grows up
+ ; |
+ ; v
+;BUFFER ; ----- 1DDC
+;INPUT_BUFFER ; 512 bytes buffer
+ ; ----- 1FDC
+
+LSTACK .equ RAMSTART
+PSTACK .equ LSTACK+(LSTACK_SIZE*2)+(PSTACK_SIZE*2)
+RSTACK .equ PSTACK+(RSTACK_SIZE*2)
+PAD .equ RSTACK+2
+TIB .equ PAD+PAD_SIZE+2
+BASE_HOLD .equ TIB+TIB_SIZE+HOLD_SIZE
+
+
+; ----------------------------------
+; RAM VARIABLES initialised by RESET
+; ----------------------------------
+
+ .org BASE_HOLD
+
+HP .word 0 ; HOLD ptr
+LEAVEPTR .word 0 ; Leave-stack pointer
+LAST_NFA .word 0 ; NFA, VOC_PFA, LFA, CFA, CSP of last created word
+LAST_THREAD .word 0
+LAST_CFA .word 0
+LAST_CSP .word 0
+STATE .word 0 ; Interpreter state
+ASM_CURRENT .word 0 ; preserve CURRENT during create assembler words
+OPCODE .word 0 ; OPCODE adr
+ASMTYPE .word 0 ; keep the opcode complement
+SOURCE_LEN .word 0
+SOURCE_ADR .word 0 ; len, addr of input stream
+TOIN .word 0
+DDP .word 0
+LASTVOC .word 0 ; keep VOC-LINK
+CURRENT .word 0 ; CURRENT dictionnary ptr
+CONTEXT .word 0,0,0,0,0,0,0,0 ; CONTEXT dictionnary space (8 CELLS)
+BASE .word 0
+CAPS .word 0
+
+ .word 0,0,0,0,0,0,0,0 ; user free use
+ .word 0,0,0,0,0,0,0,0 ; user free use
+
+
+
+; ------------------------------
+; RAM SD_CARD BUFFER 2+512 bytes
+; ------------------------------
+
+ .word 0 ; to init BufferPtr down to -2 (to skip a CR, for example)
+BUFFER
+BUFEND .equ BUFFER + 200h
+
+; ----------------------------------------------------------------------
+; INFO(DCBA) >= 256 bytes memory map:
+; ----------------------------------------------------------------------
+
+ .org INFOSTART
+
+; --------------------------
+; FRAM INFO KERNEL CONSTANTS
+; --------------------------
+
+INI_THREAD .word THREADS ; used by ADDON_UTILITY.f
+INI_TERM .word TERMINAL_INT ; used by RESET
+ .IF FREQUENCY = 0.5
+FREQ_KHZ .word 500 ; user use
+ .ELSE
+FREQ_KHZ .word FREQUENCY*1000 ; user use
+ .ENDIF
+HECTOBAUDS .word TERMINALBAUDRATE/100 ; user use
+
+SAVE_SYSRSTIV .word -3 ; to perform DEEP_RST after FastForth compiling
+LPM_MODE .word CPUOFF+GIE ; LPM0 is the default mode
+INIDP .word ROMDICT ; define RST_STATE
+INIVOC .word lastvoclink ; define RST_STATE
+
+ .word XON ; user use
+ .word XOFF ; user use
+
+ .IFDEF SD_CARD_LOADER
+ .word ReadSectorWX ; used by ADDON_SD_TOOLS.f
+ .IFDEF SD_CARD_READ_WRITE
+ .word WriteSectorWX ; used by ADDON_SD_TOOLS.f
+ .ELSEIF
+ .word 0
+ .ENDIF ; SD_CARD_READ_WRITE
+ .ELSEIF
+ .word 0,0
+ .ENDIF ; SD_CARD_LOADER
+
+; ------------------------------
+; VARIABLES that could be in RAM
+; ------------------------------
+ .IFNDEF RAM_1K ; if RAM = 1K the variables below stay in FRAM
+ .org BUFEND ; else in RAM beyond BUFFER
+ .ENDIF
+
+ .IFDEF SD_CARD_LOADER
+
+SD_ORG_DATA
+ .word 0 ; guard word
+; ---------------------------------------
+; FAT16 FileSystemInfos
+; ---------------------------------------
+FATtype .word 0
+BS_FirstSectorL .word 0 ; init by SD_Init, used by RW_Sector_CMD
+BS_FirstSectorH .word 0 ; init by SD_Init, used by RW_Sector_CMD
+OrgFAT1 .word 0 ; init by SD_Init,
+FATSize .word 0 ; init by SD_Init,
+OrgFAT2 .word 0 ; init by SD_Init,
+OrgRootDIR .word 0 ; init by SD_Init, (FAT16 specific)
+OrgClusters .word 0 ; init by SD_Init, Sector of Cluster 0
+SecPerClus .word 0 ; init by SD_Init, byte size
+
+; ---------------------------------------
+; SD command
+; ---------------------------------------
+SD_CMD_FRM .byte 0,0,0,0,0,0 ; SD_CMDx inverted frame ${CRC7,ll,LL,hh,HH,CMD}
+SectorL .word 0
+SectorH .word 0
+
+; ---------------------------------------
+; BUFFER management
+; ---------------------------------------
+BufferPtr .word 0
+BufferLen .word 0
+
+; ---------------------------------------
+; FAT entry
+; ---------------------------------------
+ClusterL .word 0 ;
+ClusterH .word 0 ;
+NewClusterL .word 0 ;
+NewClusterH .word 0 ;
+FATsector .word 0 ; not used
+CurFATsector .word 0 ; current FATSector of last free cluster
+
+; ---------------------------------------
+; DIR entry
+; ---------------------------------------
+DIRClusterL .word 0 ; contains the Cluster of current directory ; = 1 as FAT16 root directory
+DIRClusterH .word 0 ; contains the Cluster of current directory ; = 1 as FAT16 root directory
+EntryOfst .word 0
+pathname .word 0 ; address of pathname string
+
+; ---------------------------------------
+; Handle Pointer
+; ---------------------------------------
+CurrentHdl .word 0 ; contains the address of the last opened file structure, or 0
+
+; ---------------------------------------
+; Load file operation
+; ---------------------------------------
+SAVEtsLEN .word 0 ; of previous ACCEPT
+SAVEtsPTR .word 0 ; of previous ACCEPT
+MemSectorL .word 0 ;
+MemSectorH .word 0 ;
+
+; ---------------------------------------
+; Handle structure
+; ---------------------------------------
+; three handle tokens :
+; HDLB_Token= 0 : free handle
+; = 1 : file to read
+; = 2 : file updated (write)
+; =-1 : LOAD"ed file (source file)
+
+; offset values
+HDLW_PrevHDL .equ 0 ; previous handle ; used by LOAD"
+HDLB_Token .equ 2 ; token
+HDLB_ClustOfst .equ 3 ; Current sector offset in current cluster (Byte)
+HDLL_DIRsect .equ 4 ; Dir SectorL
+HDLH_DIRsect .equ 6 ; Dir SectorH
+HDLW_DIRofst .equ 8 ; BUFFER offset of Dir entry
+HDLL_FirstClus .equ 10 ; File First ClusterLo (identify the file)
+HDLH_FirstClus .equ 12 ; File First ClusterHi (byte)
+HDLL_CurClust .equ 14 ; Current ClusterLo
+HDLH_CurClust .equ 16 ; Current ClusterHi
+HDLL_CurSize .equ 18 ; written size / not yet read size (Long)
+HDLH_CurSize .equ 20 ; written size / not yet read size (Long)
+HDLW_BUFofst .equ 22 ; BUFFER offset ; used by LOAD"
+
+
+ .IFDEF RAM_1K ; RAM_Size = 1k
+HandleMax .equ 7
+HandleLenght .equ 24
+
+;OpenedFirstFile ; structure "openedFile"
+FirstHandle .word 0,0,0,0,0,0,0,0,0,0,0,0
+ .word 0,0,0,0,0,0,0,0,0,0,0,0
+ .word 0,0,0,0,0,0,0,0,0,0,0,0
+ .word 0,0,0,0,0,0,0,0,0,0,0,0
+ .word 0,0,0,0,0,0,0,0,0,0,0,0
+ .word 0,0,0,0,0,0,0,0,0,0,0,0
+ .word 0,0,0,0,0,0,0,0,0,0,0,0
+HandleEnd
+
+ .ELSEIF ; RAM_Size >= 2k
+HandleMax .equ 8
+HandleLenght .equ 24
+
+;OpenedFirstFile ; structure "openedFile"
+FirstHandle .word 0,0,0,0,0,0,0,0,0,0,0,0
+ .word 0,0,0,0,0,0,0,0,0,0,0,0
+ .word 0,0,0,0,0,0,0,0,0,0,0,0
+ .word 0,0,0,0,0,0,0,0,0,0,0,0
+ .word 0,0,0,0,0,0,0,0,0,0,0,0
+ .word 0,0,0,0,0,0,0,0,0,0,0,0
+ .word 0,0,0,0,0,0,0,0,0,0,0,0
+ .word 0,0,0,0,0,0,0,0,0,0,0,0
+HandleEnd
+
+
+SDIB
+SDIB_SIZE .equ 84
+
+ .org SDIB+SDIB_SIZE
+
+ .ENDIF ; RAM_Size
+
+SD_END_DATA
+
+ .ENDIF ; SD_CARD_LOADER
+; ----------------------------------------------------------------------
+; DTCforthMSP430FR5xxx REGISTER USAGE
+; ----------------------------------------------------------------------
+
+ .SWITCH DTC
+ .CASE 1 ; DOCOL = CALL rDOCOL
+
+RSP .reg SP ; RSP = Return Stack Pointer (return stack)
+
+; DOxxx registers ; must be saved before use and restored after use
+rDODOES .reg r4
+rDOCON .reg r5
+rDOVAR .reg r6
+rDOCOL .reg R7
+
+; Scratch registers
+Y .reg R8
+X .reg R9
+W .reg R10
+T .reg R11
+S .reg R12
+
+; Forth virtual machine
+IP .reg R13 ; interpretative pointer
+TOS .reg R14 ; first PSP cell
+PSP .reg R15 ; PSP = Parameters Stack Pointer (stack data)
+
+ .CASE 2 ; DOCOL = PUSH IP + CALL rEXIT
+
+RSP .reg SP ; RSP = Return Stack Pointer (return stack)
+
+; DOxxx registers ; must be saved before use and restored after use
+rDODOES .reg r4
+rDOCON .reg r5
+rDOVAR .reg r6
+rEXIT .reg R7
+
+; Scratch registers
+Y .reg R8
+X .reg R9
+W .reg R10
+T .reg R11
+S .reg R12
+
+; Forth virtual machine
+IP .reg R13 ; interpretative pointer
+TOS .reg R14 ; first PSP cell
+PSP .reg R15 ; PSP = Parameters Stack Pointer (stack data)
+
+ .CASE 3 ; INLINED DOCOL
+
+RSP .reg SP ; RSP = Return Stack Pointer (return stack)
+
+; DOxxx registers ; must be saved before use and restored after use
+rDODOES .reg r4
+rDOCON .reg r5
+rDOVAR .reg r6
+
+; Scratch registers
+R .reg R7
+Y .reg R8
+X .reg R9
+W .reg R10
+T .reg R11
+S .reg R12
+
+; Forth virtual machine
+IP .reg R13 ; interpretative pointer
+TOS .reg R14 ; first PSP cell
+PSP .reg R15 ; PSP = Parameters Stack Pointer (stack data)
+
+ .ENDCASE ; DTC
+
+; ----------------------------------------------------------------------
+; DTCforthMSP430FR5xxx program (FRAM) memory
+; ----------------------------------------------------------------------
+
+ .org PROGRAMSTART
+
+; ----------------------------------------------------------------------
+; DEFINING EXECUTIVE WORDS - DTC model
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; very nice FAST FORTH added feature:
+; ----------------------------------------------------------------------
+; as IP is calculated from the PC value we can place the low to high level
+; switches "COLON" or "LO2HI" anywhere in a word, i.e. not only at its beginning.
+; ----------------------------------------------------------------------
+
+
+ .SWITCH DTC
+ .CASE 1 ; DOCOL = CALL rDOCOL
+
+mNEXT .MACRO ; return for low level words (written in assembler)
+ MOV @IP+,PC ; 4 fetch code address into PC, IP=PFA
+ .ENDM ; 4 cycles,1word = ITC -2cycles -1 word
+
+NEXT .equ 4D30h ; 4 MOV @IP+,PC
+
+FORTHtoASM .MACRO ; compiled by HI2LO
+ .word $+2 ; 0 cycle
+ .ENDM ; 0 cycle, 1 word
+
+ASMtoFORTH .MACRO ; compiled by LO2HI
+ CALL #EXIT ;
+ .ENDM ; 2 words, 10~
+
+DOCOL1 .equ 1287h ; 4 CALL R7 ; [R7] is set as xdocol by COLD
+
+mDOCOL .MACRO ; compiled by : and by colon
+ CALL R7 ;
+ .ENDM ; 14~ 1 word
+
+xdocol ; 4 for CALL rDOCOL
+ 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
+ ; 14 = ITC +4
+
+ .CASE 2 ; DOCOL = PUSH IP + CALL rEXIT
+
+mNEXT .MACRO
+ MOV @IP+,PC ; 4 fetch code address into PC, IP=PFA
+ .ENDM ; 4cycles,1word = ITC -2cycles -1 word
+
+NEXT .equ 4D30h ; 4 MOV @IP+,PC
+
+FORTHtoASM .MACRO ; compiled by HI2LO
+ .word $+2 ; 0 cycle
+ .ENDM ; 0 cycle, 1 word
+
+ASMtoFORTH .MACRO ; compiled by LO2HI
+ CALL rEXIT ; CALL EXIT
+ .ENDM ; 10 cycles, 1 word
+
+mDOCOL .MACRO ; compiled by : and by COLON
+ PUSH IP ; 3
+ CALL rEXIT ; 10 CALL EXIT
+ .ENDM ; 13 cycles (ITC+3), two words
+
+DOCOL1 .equ 120Dh ; 3 PUSH IP
+DOCOL2 .equ 1287h ; 4 CALL rEXIT ; [rEXIT] is set as EXIT by COLD
+
+ .CASE 3 ; inlined DOCOL
+
+mNEXT .MACRO ; return for low level words (written in assembler)
+ MOV @IP+,PC ; 4 fetch code address into PC, IP=PFA
+ .ENDM ; 4 cycles,1word = ITC -2cycles -1 word
+
+NEXT .equ 4D30h ; 4 MOV @IP+,PC
+
+FORTHtoASM .MACRO ; compiled by HI2LO
+ .word $+2 ; 0 cycle
+ .ENDM ; 0 cycle, 1 word
+
+ASMtoFORTH .MACRO ; compiled by LO2HI
+ MOV PC,IP ; 1
+ ADD #4,IP ; 1
+ MOV @IP+,PC ; 4 NEXT
+ .ENDM ; 6 cycles, 3 words
+
+mDOCOL .MACRO ; compiled by : and by COLON
+ PUSH IP ; 3
+ MOV PC,IP ; 1
+ ADD #4,IP ; 1
+ MOV @IP+,PC ; 4 NEXT
+ .ENDM ; 9 cycles (ITC -1), 4 words
+
+DOCOL1 .equ 120Dh ; 3 PUSH IP
+DOCOL2 .equ 400Dh ; 1 MOV PC,IP
+DOCOL3 .equ 522Dh ; 1 ADD #4,IP
+
+ .ENDCASE ; DTC
+
+; mDOVAR leave on parameter stack the PFA of a VARIABLE definition
+
+mDOVAR .MACRO ; compiled by VARIABLE
+ CALL rDOVAR ; CALL RFROM
+ .ENDM ; 14 cycles (ITC+4), 1 word
+
+DOVAR .equ 1286h ; 4 CALL rDOVAR ; [rDOVAR] is set as RFROM by COLD
+
+
+; mDOCON leave on parameter stack the [PFA] of a CONSTANT definition
+
+mDOCON .MACRO ; compiled by CONSTANT
+ CALL rDOCON ; CALL xdocon
+ .ENDM ; 16 cycles (ITC+4), 1 word
+
+DOCON .equ 1285h ; 4 CALL rDOCON ; [rDOCON] is set as xdocon by COLD
+
+xdocon ; -- constant ; 4 for CALL rDOCON
+ SUB #2,PSP ; 1 make room on stack
+ MOV TOS,0(PSP) ; 3 push first PSP cell
+ MOV @RSP+,TOS ; 2 TOS=CONSTANT address
+ MOV @TOS,TOS ; 2 TOS=CONSTANT
+ MOV @IP+,PC ; 4 execute next word
+ ; 16 = ITC (+4)
+
+; mDODOES leave on parameter stack the PFA of a CREATE definition
+
+mDODOES .MACRO ; compiled by DOES>
+ CALL rDODOES ; CALL xdodoes
+ .ENDM ; 19 cycles (ITC-2), 1 word
+
+DODOES .equ 1284h ; 4 CALL rDODOES ; [rDODOES] is set as xdodoes by COLD
+
+xdodoes ; -- a-addr ; 4 for CALL rDODOES
+ SUB #2,PSP ; 1
+ MOV TOS,0(PSP) ; 3 save TOS on parameters stack
+ MOV @RSP+,TOS ; 2 TOS = CFA address of master word, i.e. address of its first cell after DOES>
+ PUSH IP ; 3 save IP on return stack
+ MOV @TOS+,IP ; 2 IP = CFA of Master word, TOS = BODY of created word
+ MOV @IP+,PC ; 4 Execute Master word
+
+; ----------------------------------------------------------------------
+; INTERPRETER LOGIC
+; ----------------------------------------------------------------------
+
+;C EXIT -- exit a colon definition; CALL #EXIT performs ASMtoFORTH
+ FORTHWORD "EXIT"
+EXIT MOV @RSP+,IP ; 2 pop previous IP (or next PC) from return stack
+ MOV @IP+,PC ; 4 = NEXT
+ ; 6 = ITC - 2
+
+;Z lit -- x fetch inline literal to stack
+; This is the primitive compiled by LITERAL.
+ FORTHWORD "LIT"
+lit SUB #2,PSP ; 2 push old TOS..
+ MOV TOS,0(PSP) ; 3 ..onto stack
+ MOV @IP+,TOS ; 2 fetch new TOS value
+ MOV @IP+,PC ; 4 NEXT
+ ; 11 = ITC - 2
+
+; ----------------------------------------------------------------------
+; STACK OPERATIONS
+; ----------------------------------------------------------------------
+
+;C DUP x -- x x duplicate top of stack
+ FORTHWORD "DUP"
+DUP SUB #2,PSP ; 2 push old TOS..
+ MOV TOS,0(PSP) ; 3 ..onto stack
+ mNEXT ; 4
+
+;C ?DUP x -- 0 | x x DUP if nonzero
+ FORTHWORD "?DUP"
+QDUP CMP #0,TOS ; 2 test for TOS nonzero
+ JNZ DUP ; 2
+ mNEXT ; 4
+
+;C DROP x -- drop top of stack
+ FORTHWORD "DROP"
+DROP MOV @PSP+,TOS ; 2
+ mNEXT ; 4
+
+;C SWAP x1 x2 -- x2 x1 swap top two items
+ FORTHWORD "SWAP"
+SWAP MOV @PSP,W ; 2
+ MOV TOS,0(PSP) ; 3
+ MOV W,TOS ; 1
+ mNEXT ; 4
+
+;C OVER x1 x2 -- x1 x2 x1
+ FORTHWORD "OVER"
+OVER SUB #2,PSP ; 2 -- x1 x x2
+ MOV TOS,0(PSP) ; 3 -- x1 x2 x2
+ MOV 2(PSP),TOS ; 2 -- x1 x2 x1
+ mNEXT ; 4
+
+;C ROT x1 x2 x3 -- x2 x3 x1
+ FORTHWORD "ROT"
+ROT MOV @PSP,W ; 2 fetch x2
+ MOV TOS,0(PSP) ; 3 store x3
+ MOV 2(PSP),TOS ; 3 fetch x1
+ MOV W,2(PSP) ; 3 store x2
+ mNEXT ; 4
+
+;C >R x -- R: -- x push to return stack
+ FORTHWORD ">R"
+TOR PUSH TOS
+ MOV @PSP+,TOS
+ mNEXT
+
+;C R> -- x R: x -- pop from return stack ; CALL #RFROM performs DOVAR
+ FORTHWORD "R>"
+RFROM SUB #2,PSP ; 1
+ MOV TOS,0(PSP) ; 3
+ MOV @RSP+,TOS ; 2
+ mNEXT ; 4
+
+;C R@ -- x R: x -- x fetch from rtn stk
+ FORTHWORD "R@"
+RFETCH SUB #2,PSP
+ MOV TOS,0(PSP)
+ MOV @RSP,TOS
+ mNEXT
+
+;;Z SP@ -- a-addr get data stack pointer, must leave PSTACK value if stack empty
+; FORTHWORD "SP@"
+SPFETCH MOV TOS,-2(PSP) ;3
+ MOV PSP,TOS ;1
+ SUB #2,PSP ;1 post decrement stack...
+ mNEXT
+
+;C DEPTH -- +n number of items on stack, must leave 0 if stack empty
+ FORTHWORD "DEPTH"
+DEPTH: MOV TOS,-2(PSP)
+ MOV #PSTACK,TOS
+ SUB PSP,TOS ; PSP-S0--> TOS
+ SUB #2,PSP ; post decrement stack...
+ RRA TOS ; TOS/2 --> TOS
+ mNEXT
+
+; ----------------------------------------------------------------------
+; MEMORY OPERATIONS
+; ----------------------------------------------------------------------
+
+;C @ a-addr -- x fetch cell from memory
+ FORTHWORD "@"
+FETCH MOV @TOS,TOS
+ mNEXT
+
+
+;C ! x a-addr -- store cell in memory
+ FORTHWORD "!"
+STORE MOV @PSP+,0(TOS) ;4
+ MOV @PSP+,TOS ;2
+ mNEXT ;4
+
+;C C@ c-addr -- char fetch char from memory
+ FORTHWORD "C@"
+CFETCH MOV.B @TOS,TOS
+ mNEXT
+
+
+;C C! char c-addr -- store char in memory
+ FORTHWORD "C!"
+CSTORE MOV @PSP+,W ;2
+ MOV.B W,0(TOS) ;3
+ MOV @PSP+,TOS ;2
+ mNEXT
+
+; ----------------------------------------------------------------------
+; ARITHMETIC OPERATIONS
+; ----------------------------------------------------------------------
+
+;C + n1/u1 n2/u2 -- n3/u3 add n1+n2
+ FORTHWORD "+"
+PLUS ADD @PSP+,TOS
+ mNEXT
+
+;C - n1/u1 n2/u2 -- n3/u3 subtract n1-n2
+ FORTHWORD "-"
+MINUS MOV @PSP+,W ; 2
+ SUB TOS,W ; 1
+ MOV W,TOS ; 1
+ mNEXT
+
+;C AND x1 x2 -- x3 logical AND
+ FORTHWORD "AND"
+ANDD AND @PSP+,TOS
+ mNEXT
+
+;C OR x1 x2 -- x3 logical OR
+ FORTHWORD "OR"
+ORR BIS @PSP+,TOS
+ mNEXT
+
+;C XOR x1 x2 -- x3 logical XOR
+ FORTHWORD "XOR"
+XORR XOR @PSP+,TOS
+ mNEXT
+
+;C NEGATE x1 -- x2 two's complement
+ FORTHWORD "NEGATE"
+NEGATE XOR #-1,TOS
+ ADD #1,TOS
+ mNEXT
+
+;C ABS n1 -- +n2 absolute value
+ FORTHWORD "ABS"
+ABBS: CMP #0,TOS ; 1
+ JN NEGATE
+ mNEXT
+
+; ----------------------------------------------------------------------
+; COMPARAISON OPERATIONS
+; ----------------------------------------------------------------------
+
+;C 0= n/u -- flag return true if TOS=0
+ FORTHWORD "0="
+ZEROEQUAL SUB #1,TOS ; borrow (clear cy) if TOS was 0
+ SUBC TOS,TOS ; TOS=-1 if borrow was set
+ mNEXT
+
+;C 0< n -- flag true if TOS negative
+ FORTHWORD "0<"
+ZEROLESS ADD TOS,TOS ; set carry if TOS negative
+ SUBC TOS,TOS ; TOS=-1 if carry was clear
+ XOR #-1,TOS ; TOS=-1 if carry was set
+ mNEXT
+
+;C = x1 x2 -- flag test x1=x2
+ FORTHWORD "="
+EQUAL: SUB @PSP+,TOS ; 2
+ JNZ TOSFALSE ; 2 --> +4
+TOSTRUE: MOV #-1,TOS ; 2 (MOV @R3+,TOS)
+ mNEXT ; 4
+
+;C < n1 n2 -- flag test n1<n2, signed
+ FORTHWORD "<"
+LESS: MOV @PSP+,W ; 2 W=n1
+ SUB TOS,W ; 1 W=n1-n2 flags set
+ JL TOSTRUE ; 2
+TOSFALSE MOV #0,TOS ; 1
+ mNEXT ; 4
+
+;C > n1 n2 -- flag test n1>n2, signed
+ FORTHWORD ">"
+GREATER: SUB @PSP+,TOS ; 2 TOS=n2-n1
+ JL TOSTRUE ; 2
+ MOV #0,TOS ; 1
+ mNEXT ; 4
+
+;C U< u1 u2 -- flag test u1<u2, unsigned
+ FORTHWORD "U<"
+ULESS: MOV @PSP+,W ; 2
+ SUB TOS,W ; 1 u1-u2 in W, cy clear if borrow
+ JNC TOSTRUE ; 2
+ MOV #0,TOS ; 1
+ mNEXT ; 4
+
+; ----------------------------------------------------------------------
+; BRANCH and LOOP OPERATIONS
+; ----------------------------------------------------------------------
+
+;Z branch -- branch always
+; FORTHWORD "BRANCH"
+BRAN MOV @IP,IP ; 2
+ mNEXT ; 4
+
+;Z ?branch x -- branch if TOS = zero
+; FORTHWORD "?BRANCH"
+QBRAN CMP #0,TOS ; 1 test TOS value
+ MOV @PSP+,TOS ; 2 pop new TOS value (doesn't change flags)
+ JZ bran ; 2 if TOS was zero, take the branch = 11 cycles
+ ADD #2,IP ; 1 else skip the branch destination
+ mNEXT ; 4 ==> branch not taken = 10 cycles
+
+;Z (do) n1|u1 n2|u2 -- R: -- sys1 sys2 run-time code for DO
+; n1|u1=limit, n2|u2=index
+; FORTHWORD "(DO)"
+
+xdo MOV #8000h,X ;2 compute 8000h-limit "fudge factor"
+ SUB @PSP+,X ;2
+ MOV TOS,Y ;1 loop ctr = index+fudge
+ MOV @PSP+,TOS ;2 pop new TOS
+ ADD X,Y ;1
+ .word 01519h ;4 PUSHM X,Y, i.e. PUSHM LIMIT, INDEX
+ mNEXT ;4
+
+;Z (+loop) n -- R: sys1 sys2 -- | sys1 sys2
+; run-time code for +LOOP
+; Add n to the loop index. If loop terminates, clean up the
+; return stack and skip the branch. Else take the inline branch.
+; FORTHWORD "(+LOOP)"
+
+xploop ADD TOS,0(RSP) ;4 increment INDEX by TOS value
+ MOV @PSP+,TOS ;2 get new TOS, doesn't change flags
+xloopnext BIT #100h,SR ;2 is overflow bit set?
+ JZ bran ;2 no overflow = loop
+ ADD #2,IP ;1 overflow = loop done, skip branch ofs
+UNXLOOP ADD #4,RSP ;1 empty RSP
+ mNEXT ;4 16~ taken or not taken xloop/loop
+
+
+;Z (loop) R: sys1 sys2 -- | sys1 sys2
+; run-time code for LOOP
+; Add 1 to the loop index. If loop terminates, clean up the
+; return stack and skip the branch. Else take the inline branch.
+; Note that LOOP terminates when index=8000h.
+; FORTHWORD "(LOOP)"
+
+xloop ADD #1,0(RSP) ;4 increment INDEX
+ JMP xloopnext ;2
+
+;C UNLOOP -- R: sys1 sys2 -- drop loop parms
+ FORTHWORD "UNLOOP"
+UNLOOP JMP UNXLOOP
+
+;C I -- n R: sys1 sys2 -- sys1 sys2
+;C get the innermost loop index
+ FORTHWORD "I"
+II SUB #2,PSP ; make room in TOS
+ MOV TOS,0(PSP)
+ MOV @RSP,TOS ; index = loopctr - fudge
+ SUB 2(RSP),TOS
+ mNEXT
+
+;C J -- n R: 4*sys -- 4*sys
+;C get the second loop index
+ FORTHWORD "J"
+JJ SUB #2,PSP ; make room in TOS
+ MOV TOS,0(PSP)
+ MOV 4(RSP),TOS ; index = loopctr - fudge
+ SUB 6(RSP),TOS
+ mNEXT
+
+; ----------------------------------------------------------------------
+; SYSTEM VARIABLES & CONSTANTS
+; ----------------------------------------------------------------------
+
+;C >IN -- a-addr holds offset in input stream
+ FORTHWORD ">IN"
+FTOIN mDOCON
+ .word TOIN ; VARIABLE address in RAM space
+
+;C BASE -- a-addr holds conversion radix
+ FORTHWORD "BASE"
+FBASE mDOCON
+ .word BASE ; VARIABLE address in INFO space
+
+;C STATE -- a-addr holds compiler state
+ FORTHWORD "STATE"
+FSTATE mDOCON
+ .word STATE ; VARIABLE address in RAM space
+
+;C BL -- char an ASCII space
+ FORTHWORD "BL"
+FBLANK mDOCON
+ .word 32
+
+; ----------------------------------------------------------------------
+; MULTIPLY
+; ----------------------------------------------------------------------
+
+ .IFNDEF MPY ; if no hardware MPY
+
+; T.I. SIGNED MULTIPLY SUBROUTINE: U1 x U2 -> Ud
+
+;C UM* u1 u2 -- ud unsigned 16x16->32 mult.
+ FORTHWORD "UM*"
+UMSTAR MOV @PSP,S ; U1 = MULTIPLICANDlo
+ MOV #0,W ; 0 -> created MULTIPLICANDhi
+ MOV #0,Y ; 0 -> created RESULTlo
+ MOV #0,T ; 0 -> created RESULThi
+ MOV #1,X ; BIT TEST REGISTER
+UMSTARLOOP BIT X,TOS ;1 TEST ACTUAL BIT MULTIPLIER
+ JZ UMSTARNEXT ;2 IF 0: DO NOTHING
+ ADD S,Y ;1 IF 1: ADD MULTIPLICAND TO RESULT
+ ADDC W,T ;1
+UMSTARNEXT ADD S,S ;1 (RLA LSBs) MULTIPLICAND x 2
+ ADDC W,W ;1 (RLC MSBs)
+ ADD X,X ;1 (RLA) NEXT BIT TO TEST
+ JNC UMSTARLOOP ;2 IF BIT IN CARRY: FINISHED 10~ loop
+ MOV Y,0(PSP) ; low result on stack
+ MOV T,TOS ; high result in TOS
+ mNEXT
+
+ .ENDIF ; hardware MPY
+
+; ----------------------------------------------------------------------------------------
+; ANS complement OPTION that include ALIGNMENT, PORTABILITY, ARITHMETIC and DOUBLE options
+; ----------------------------------------------------------------------------------------
+ .IFDEF ANS_CORE_COMPLIANT
+ .include "ADDON\ANS_COMPLEMENT.asm"
+; ----------------------------------------------------------------------------------------
+
+ .ELSEIF
+
+; ----------------------------------------------------------------------
+; ALIGNMENT OPERATORS OPTION
+; ----------------------------------------------------------------------
+ .IFDEF ALIGNMENT ; included in ANS_COMPLEMENT
+ .include "ADDON\ALIGNMENT.asm"
+ .ENDIF ; ALIGNMENT
+; ----------------------------------------------------------------------
+; PORTABILITY OPERATORS OPTION
+; ----------------------------------------------------------------------
+ .IFDEF PORTABILITY
+ .include "ADDON\PORTABILITY.asm"
+ .ENDIF ; PORTABILITY
+; ----------------------------------------------------------------------
+; ARITHMETIC OPERATORS OPTION
+; ----------------------------------------------------------------------
+ .IFDEF ARITHMETIC ; included in ANS_COMPLEMENT
+ .include "ADDON\ARITHMETIC.asm"
+ .ENDIF ; ARITHMETIC
+; ----------------------------------------------------------------------
+; DOUBLE OPERATORS OPTION
+; ----------------------------------------------------------------------
+ .IFDEF DOUBLE ; included in ANS_COMPLEMENT
+ .include "ADDON\DOUBLE.asm"
+ .ENDIF ; DOUBLE
+
+; ----------------------------------------------------------------------------------------
+ .ENDIF ; ANS_COMPLEMENT
+; ----------------------------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; NUMERIC OUTPUT
+; ----------------------------------------------------------------------
+
+; Numeric conversion is done last digit first, so
+; the output buffer is built backwards in memory.
+
+;C <# -- begin numeric conversion (initialize Hold Pointer in PAD area)
+ FORTHWORD "<#"
+LESSNUM: MOV #BASE_HOLD,&HP
+ mNEXT
+
+; unsigned 32-BIT DIVIDEND : 16-BIT DIVISOR --> 32-BIT QUOTIENT, 16-BIT REMAINDER
+; DVDhi|DVDlo : DVR --> QUOThi|QUOTlo, REMAINDER
+; then REMAINDER is converted in ASCII char
+; about 2 times faster if ud1 < 65536 (it's the general case)
+
+; input registers :
+; T = DIVISOR
+; S = DVDlo
+; W = DVDhi
+; output registers :
+; W = remainder
+; X = QUOTlo
+; Y = QUOThi
+; saved registers :
+; IP = count
+; TOS = DVD48
+
+UDIVQ32 ; use S,T,W,X,Y
+ .word 151Eh ;4 PUSHM TOS,IP (1+1 push,TOS=Eh): save all no scratch registers before use
+ MOV #0,TOS ;1 TOS = DVD48 = 0
+ MOV #32,IP ;3 init loop count
+ CMP #0,W ;1 DVDhi <> 0 ?
+ JNZ MDIV1 ;2 yes
+ RRA IP ;1 no: loop count / 2
+ MOV S,W ;1 DVD = DVD<<16
+ MOV #0,S ;1
+ MOV #0,X ;1 QUOTlo = 0
+MDIV1: CMP T,TOS ;1 DVD48 > divisor ?
+ JNC MDIV2 ;2 U<
+ SUB T,TOS ;1 DVD48 - DVR
+MDIV2: ADDC X,X ;1 RLC quotLO
+ ADDC Y,Y ;1 RLC quotHI
+ SUB #1,IP ;1 Decrement loop counter
+ JN ENDMDIVIDE ;2 If 0< --> end
+ ADD S,S ;1 RLA DVDlo
+ ADDC W,W ;1 RLC DVDhi
+ ADDC TOS,TOS ;1 RLC DVD48
+ JNC MDIV1 ;2 14~ loop
+ SUB T,TOS ;1 DVD48 - DVR
+ BIS #1,SR ;1 SETC
+ JMP MDIV2 ;2 14~ loop
+ENDMDIVIDE MOV TOS,W ;1 DVD48 ==> W = remainder
+ .word 171Dh ;4 POPM IP, TOS
+ RET ;4 27 words
+
+
+;C # ud1lo:ud1hi -- ud2lo:ud2hi convert 1 digit of output
+ FORTHWORD "#"
+NUM MOV &BASE,T ;3 T = Divisor
+ MOV @PSP,S ;2 S = DVDlo
+ MOV TOS,W ;1 TOS ==> W = DVDhi
+ CALL #UDIVQ32 ;4 use S,T,W,X,Y
+ MOV X,0(PSP) ;3 QUOTlo in 0(PSP)
+ MOV Y,TOS ;1 QUOThi in TOS
+TODIGIT CMP.B #10,W ;2 W = REMAINDER
+ JLO TODIGIT1 ;2 U<
+ ADD #7,W ;2
+TODIGIT1 ADD #30h,W ;2
+HOLDW SUB #1,&HP ;3 store W=char --> -[HP]
+ MOV &HP,Y ;3
+ MOV.B W,0(Y) ;3
+ mNEXT ;4 23 words, about 290/490 cycles/char
+
+;C #S udlo:udhi -- udlo:udhi=0 convert remaining digits
+ FORTHWORD "#S"
+NUMS mDOCOL
+ .word NUM ;
+NUMS1 FORTHtoASM ;
+ SUB #2,IP ;1 define NUM return
+ CMP #0,X ;1 test udlo first
+ JNZ NUM ;2
+ CMP #0,TOS ;1 then udhi
+ JNZ NUM ;2
+NUMSEND MOV @RSP+,IP ;2
+ mNEXT ;4
+
+;C #> udlo:udhi=0 -- c-addr u end conversion, get string
+ FORTHWORD "#>"
+NUMGREATER: MOV &HP,0(PSP)
+ MOV #BASE_HOLD,TOS
+ SUB @PSP,TOS
+ mNEXT
+
+;C HOLD char -- add char to output string
+ FORTHWORD "HOLD"
+HOLD: MOV TOS,W ;1
+ MOV @PSP+,TOS ;2
+ JMP HOLDW ;15
+
+;C SIGN n -- add minus sign if n<0
+ FORTHWORD "SIGN"
+SIGN: CMP #0,TOS
+ MOV @PSP+,TOS
+ MOV #'-',W
+ JN HOLDW ; 0<
+ mNEXT
+
+;C UD. udlo udhi -- display ud (unsigned)
+ FORTHWORD "UD."
+UDDOT: mDOCOL
+ .word LESSNUM,NUMS,NUMGREATER,TYPE
+ .word SPACE,EXIT
+
+;C U. u -- display u (unsigned)
+ FORTHWORD "U."
+UDOT: SUB #2,PSP
+ MOV TOS,0(PSP)
+ MOV #0,TOS
+ JMP UDDOT
+
+;C DABS d1 -- |d1| absolute value
+; FORTHWORD "DABS"
+DABBS: BIT #8000h,TOS ; 1
+ JZ DABBSEND
+ XOR #-1,0(PSP)
+ XOR #-1,TOS
+ ADD #1,0(PSP)
+ ADDC #0,TOS
+DABBSEND mNEXT
+
+;C D. dlo dhi -- display d (signed)
+ FORTHWORD "D."
+DDOT: mDOCOL
+ .word LESSNUM,SWAP,OVER,DABBS,NUMS
+ .word ROT,SIGN,NUMGREATER,TYPE,SPACE,EXIT
+
+;C . n -- display n (signed)
+ FORTHWORD "."
+DOT: BIT #8000h,TOS
+ JZ UDOT
+ SUB #2,PSP
+ MOV #-1,TOS
+ JMP DDOT
+
+; ----------------------------------------------------------------------
+; DICTIONARY MANAGEMENT
+; ----------------------------------------------------------------------
+
+;C HERE -- addr returns dictionary ptr
+ FORTHWORD "HERE"
+HERE SUB #2,PSP
+ MOV TOS,0(PSP)
+ MOV &DDP,TOS
+ mNEXT
+
+;C ALLOT n -- allocate n bytes in dict
+ FORTHWORD "ALLOT"
+ALLOT ADD TOS,&DDP
+ MOV @PSP+,TOS
+ mNEXT
+
+;C C, char -- append char to dict
+ FORTHWORD "C,"
+CCOMMA MOV &DDP,W
+ MOV.B TOS,0(W)
+ ADD #1,&DDP
+ MOV @PSP+,TOS
+ mNEXT
+
+; ------------------------------------------------------------------------------
+; TERMINAL I/O, input part
+; ------------------------------------------------------------------------------
+
+;Z (KEY?) -- c get character from the terminal
+; FORTHWORD "(KEY?)"
+PARENKEYTST SUB #2,PSP ; 1 push old TOS..
+ MOV TOS,0(PSP) ; 4 ..onto stack
+ CALL #XON
+KEYLOOP BIT #UCRXIFG,&TERMIFG ; loop if bit0 = 0 in interupt flag register
+ JZ KEYLOOP ;
+ MOV &TERMRXBUF,TOS ;
+ CALL #XOFF ;
+ mNEXT
+
+;F KEY? -- c get character from input device ; deferred word
+; FORTHWORD "KEY?"
+KEYTST MOV #PARENKEYTST,PC
+
+
+;Z (KEY) -- c get character from the terminal
+ FORTHWORD "(KEY)"
+PARENKEY MOV &TERMRXBUF,Y ; empty buffer
+ JMP PARENKEYTST
+
+;C KEY -- c wait character from input device ; deferred word
+ FORTHWORD "KEY"
+KEY MOV #PARENKEY,PC
+
+; ----------------------------------------------------------------------
+; INTERPRETER INPUT, the kernel of kernel !
+; ----------------------------------------------------------------------
+
+ .IFDEF SD_CARD_LOADER ; ACCEPT becomes a DEFERred word
+
+ .include "forthMSP430FR_SD_ACCEPT.asm" ; that creates SD_ACCEPT and (SD_ACCEPT)
+
+ .ELSE ; ACCEPT is not a DEFERred word
+
+;C ACCEPT addr len -- len' get line at addr to interpret len' chars
+ FORTHWORD "ACCEPT"
+ACCEPT
+
+ .ENDIF
+
+; con speed of TERMINAL link, there are three bottlenecks :
+; 1- time to send XOFF/RTS_high on CR (CR+LF=EOL), first emergency.
+; 2- the char loop time,
+; 3- the time between sending XON/RTS_low and clearing UCRXIFG on first received char,
+; everything must be done to reduce these times, taking into account the necessity of switching to Standby (LPMx mode).
+; --------------------------------------;
+; (ACCEPT) part I: prepare TERMINAL_INT ;
+; --------------------------------------;
+ MOV #ENDACCEPT,S ;2 S = XOFF return
+ MOV #AKEYREAD1,T ;2 T = default XON return
+ .word 152Dh ;5 PUSHM IP,S,T, as IP ret, XOFF ret, XON ret
+ MOV TOS,W ;1 -- addr len
+ MOV @PSP,TOS ;2 -- org ptr )
+ ADD TOS,W ;1 -- org ptr W=Bound )
+ MOV #0Dh,T ;2 T = 'CR' to speed up char loop in part II > prepare stack and registers
+ MOV #20h,S ;2 S = 'BL' to speed up char loop in part II ) for TERMINAL_INT use
+ MOV #AYEMIT_RET,IP ;2 IP = return for YEMIT )
+ BIT #UCRXIFG,&TERMIFG ;3 RX_Int ?
+ JZ ACCEPTNEXT ;2 no : case of FORTH init or input terminal quiet
+ MOV &TERMRXBUF,Y ;3 yes: clear RX_Int
+ CMP #0Ah,Y ;2 received char = LF ? (end of downloading ?)
+ JNZ XON ;2 no : process char (first char of a new line).
+ACCEPTNEXT ADD #2,RSP ;1 nothing to do, remove previous XON return address,
+ MOV #LPMx_LOOP,X ;2 and set good XON return to force the shutdown in sleep mode
+ .word 154Dh ;7 PUSHM IP,S,T,W,X
+
+; ======================================;
+XON ;
+; ======================================;
+ .IFDEF TERMINALXONXOFF ;
+ MOV #17,&TERMTXBUF ;4 move char XON into TX_buf
+ .IF TERMINALBAUDRATE/FREQUENCY <230400
+XON_LOOP BIT #UCTXIFG,&TERMIFG ;3 wait the sending end of previous char, useless at high baudrates
+ JZ XON_LOOP ;2
+ .ENDIF
+ .ENDIF ;
+ .IFDEF TERMINALCTSRTS ;
+ BIC.B #RTS,&HANDSHAKOUT ;4 set RTS low
+ .ENDIF ;
+; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv;
+; starts first and 3th stopwatches ;
+; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;
+ RET ;4 to LPMx_LOOP or AKEYREAD1, ...or user defined
+; --------------------------------------;
+
+; ======================================;
+XOFF ; NOP11
+; ======================================;
+ .IFDEF TERMINALXONXOFF ;
+ MOV #19,&TERMTXBUF ;4 move XOFF char into TX_buf
+ .IF TERMINALBAUDRATE/FREQUENCY <230400
+XOFF_LOOP BIT #UCTXIFG,&TERMIFG ;3 wait the sending end of previous char, useless at high baudrates
+ JZ XOFF_LOOP ;2
+ .ENDIF
+ .ENDIF ;
+ .IFDEF TERMINALCTSRTS ;
+ BIS.B #RTS,&HANDSHAKOUT ;4 set RTS high
+ .ENDIF ;
+ RET ;4 to ENDACCEPT, ...or user defined
+; --------------------------------------;
+
+
+; ======================================;
+LPMx_LOOP ; XON RET address 1 ; NOP100
+; ======================================;
+ BIS &LPM_MODE,SR ;3 enter in LPMx sleep mode with GIE=1
+; --------------------------------------; default mode : LPM0.
+
+
+; ### # # ####### ####### ###### ###### # # ###### ####### ##### # # ####### ###### #######
+; # ## # # # # # # # # # # # # # # # # # # # #
+; # # # # # # # # # # # # # # # # # # # # # #
+; # # # # # ##### ###### ###### # # ###### # ##### ####### ##### ###### #####
+; # # # # # # # # # # # # # # # # # # # # #
+; # # ## # # # # # # # # # # # # # # # # # #
+; ### # # # ####### # # # # ##### # # ##### # # ####### # # #######
+
+
+; here, Fast FORTH sleeps, waiting any interrupt.
+; IP,S,T,W,X,Y registers (R13 to R8) are free for any interrupt routine...
+; ...and so PSP and RSP stacks with their rules of use.
+; remember : in any interrupt routine you must include : BIC #0xF8,0(RSP) before RETI
+; to force return to LPMx_LOOP.
+
+
+; ======================================;
+ JMP LPMx_LOOP ;2 and here is the return for any interrupts, else TERMINAL_INT :-)
+; ======================================;
+
+
+; **************************************;
+TERMINAL_INT ; <--- UCA0 RX interrupt vector, delayed by the LPMx wake up time
+; **************************************; if wake up time increases, max bauds rate decreases...
+; (ACCEPT) part II under interrupt ; Org Ptr -- len'
+; --------------------------------------;
+ ADD #4,RSP ;1 remove SR and PC from stack
+ .word 173Ah ;6 POPM W=bound,T=0Dh,S=20h,IP=AYEMIT_RET
+; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv;
+; starts the 2th stopwatch ;
+; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;
+AKEYREAD MOV.B &TERMRXBUF,Y ;3 read character into Y, UCRXIFG is cleared
+; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv;
+; stops the 3th stopwatch ; 3th bottleneck result : 17~ + LPMx wake_up time ( + 5~ XON loop if F/Bds<230400 )
+; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;
+AKEYREAD1 ; <--- XON RET address 2 ; first emergency: anticipate XOFF on CR as soon as possible
+ CMP.B T,Y ;1 char = CR ?
+ JZ XOFF ;2 then RET to ENDACCEPT
+; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv;+ 4
+; stops the first stopwatch ; first bottleneck, best case result: 24~ + LPMx wake_up time..
+; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^; ...or 11~ in case of empty line
+ CMP.B S,Y ;1 printable char ?
+ JHS ASTORETEST ;2 yes
+ CMP.B #8,Y ; char = BS ?
+ JNE WAITaKEY
+; --------------------------------------;
+; start of backspace ;
+; --------------------------------------;
+BACKSPACE CMP @PSP,TOS ; Ptr = Org ?
+ JZ WAITaKEY ; yes: do nothing
+ SUB #1,TOS ; no : dec Ptr
+; --------------------------------------;
+ .IFDEF BACKSPACE_ERASE
+ MOV #BS_NEXT,IP ;
+ JMP YEMIT ; send BS
+BS_NEXT FORTHtoASM ;
+ MOV #32,Y ; send SPACE to rub previous char
+ ADD #8,IP ; (BS_NEXT+2) + 8 = FORTHtoASM @ !
+ JMP YEMIT ;
+ FORTHtoASM ;
+ MOV.B #8,Y ;
+ MOV #AYEMIT_RET,IP ;
+ .ENDIF
+; --------------------------------------;
+ JMP YEMIT ; send BS
+; --------------------------------------;
+; end of backspace ;
+; --------------------------------------;
+ASTORETEST CMP W,TOS ; 1 Bound is reached ? (protect against big lines without CR, UNIX like)
+ JZ YEMIT ; 2 yes, send echo without store, then loopback
+ASTORE MOV.B Y,0(TOS) ; 3 no, store char @ Ptr before send echo, then loopback
+ ADD #1,TOS ; 1 increment Ptr
+YEMIT .word 4882h ; hi7/4~ lo:12/4~ send/send_not echo to terminal
+ .word TERMTXBUF ; 3 MOV Y,&TERMTXBUF
+ .IF TERMINALBAUDRATE/FREQUENCY <230400
+YEMIT1 BIT #UCTXIFG,&TERMIFG ; 3 wait the sending end of previous char, useless at high baudrates
+ JZ YEMIT1 ; 2
+ .ENDIF
+ mNEXT ; 4
+; --------------------------------------;
+AYEMIT_RET FORTHtoASM ; 0 YEMII NEXT address; NOP9
+ SUB #2,IP ; 1 set YEMIT NEXT address to AYEMIT_RET
+WAITaKEY BIT #UCRXIFG,&TERMIFG ; 3 new char in TERMRXBUF ?
+ JZ WAITaKEY ; 2 no
+ JNZ AKEYREAD ; 2 yes
+; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv;
+; stops the 2th stopwatch ; best case result: 31~/28~ (with/without echo) ==> 322/357 kBds/MHz
+; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;
+
+; --------------------------------------;
+ENDACCEPT ; <--- XOFF RET address
+; --------------------------------------;
+ MOV #LPM0+GIE,&LPM_MODE ; reset LPM_MODE to default mode LPM0
+DROPEXIT SUB @PSP+,TOS ; Org Ptr -- len'
+ MOV @RSP+,IP ; 2 and continue with INTERPRET with GIE=0.
+ ; So FORTH machine is protected against any interrupt...
+ mNEXT ; ...until next falling down to LPMx mode of (ACCEPT) part1,
+; **************************************; i.e. when the FORTH interpreter has no more to do.
+
+; ------------------------------------------------------------------------------
+; TERMINAL I/O, output part
+; ------------------------------------------------------------------------------
+
+
+;Z (EMIT) c -- output character (byte) to the terminal
+; hardware or software control on TX flow seems not necessary with UARTtoUSB bridges because
+; they stop TX when their RX buffer is full. So no problem when the terminal input is echoed to output.
+ FORTHWORD "(EMIT)"
+PARENEMIT MOV TOS,Y ; 1
+ MOV @PSP+,TOS ; 2
+ .IF TERMINALBAUDRATE/FREQUENCY >=230400
+YEMIT1 BIT #UCTXIFG,&TERMIFG ; 3 wait the sending end of previous char (usefull for low baudrates)
+ JZ YEMIT1 ; 2
+ .ENDIF
+ JMP YEMIT
+
+
+;C EMIT c -- output character to the output device ; deferred word
+ FORTHWORD "EMIT"
+EMIT MOV #PARENEMIT,PC ; 3
+
+
+;Z ECHO -- connect console output (default)
+ FORTHWORD "ECHO"
+ECHO MOV #4882h,&YEMIT ; 4882h = MOV Y,&<next_adr>
+ mNEXT
+
+;Z NOECHO -- disconnect console output
+ FORTHWORD "NOECHO"
+NOECHO MOV #NEXT,&YEMIT ; NEXT = 4030h = MOV @IP+,PC
+ mNEXT
+
+; (CR) -- send CR to the output terminal (via EMIT)
+ FORTHWORD "(CR)"
+PARENCR SUB #2,PSP
+ MOV TOS,0(PSP)
+ MOV #0Dh,TOS
+ JMP EMIT
+
+;C CR -- send CR to the output device
+ FORTHWORD "CR"
+CR MOV #PARENCR,PC
+
+
+;C SPACE -- output a space
+ FORTHWORD "SPACE"
+SPACE SUB #2,PSP
+ MOV TOS,0(PSP)
+ MOV #20h,TOS
+ JMP EMIT
+
+;C SPACES n -- output n spaces
+ FORTHWORD "SPACES"
+SPACES CMP #0,TOS
+ JZ SPACESEND
+ PUSH IP
+ MOV #SPACESNEXT,IP
+ JMP SPACE
+SPACESNEXT FORTHtoASM
+ SUB #2,IP
+ SUB #1,TOS
+ JNZ SPACE
+ MOV @RSP+,IP
+SPACESEND MOV @PSP+,TOS
+ mNEXT
+
+
+;C TYPE adr len -- type line to terminal
+ FORTHWORD "TYPE"
+TYPE CMP #0,TOS
+ JZ TWODROP
+ MOV @PSP,W
+ ADD TOS,0(PSP)
+ MOV W,TOS
+ mDOCOL
+ .word xdo
+TYPELOOP .word II,CFETCH,EMIT,xloop,TYPELOOP
+ .word EXIT
+
+
+; ------------------------------------------------------------------------------
+; STRINGS PROCESSING
+; ------------------------------------------------------------------------------
+
+;Z (S") -- addr u run-time code for S"
+; get address and length of string.
+XSQUOTE: SUB #4,PSP ; 1 -- x x TOS ; push old TOS on stack
+ MOV TOS,2(PSP) ; 3 -- TOS x x ; and reserve one cell on stack
+ MOV.B @IP+,TOS ; 2 -- x u ; u = lenght of string
+ MOV IP,0(PSP) ; 3 -- addr u
+ ADD TOS,IP ; 1 -- addr u IP=addr+u=addr(end_of_string)
+ BIT #1,IP ; 1 -- addr u IP=addr+u Carry set/clear if odd/even
+ ADDC #0,IP ; 1 -- addr u IP=addr+u aligned
+ mNEXT ; 4 16~
+
+;C S" -- compile in-line string
+ FORTHWORDIMM "S\34" ; immediate
+SQUOTE: mDOCOL
+ .word lit,XSQUOTE,COMMA
+ .word lit,'"',WORDD ; -- c-addr (= HERE)
+ FORTHtoASM
+ MOV @RSP+,IP
+ MOV.B @TOS,TOS ; -- u
+ SUB #1,TOS ; -1 byte
+ ADD TOS,&DDP
+ MOV @PSP+,TOS
+CELLPLUSALIGN
+ BIT #1,&DDP ;3
+ ADDC #2,&DDP ;4 +2 bytes
+ mNEXT
+
+ .IFDEF LOWERCASE
+
+ FORTHWORD "CAPS_ON"
+CAPS_ON MOV #-1,&CAPS ; state by default
+ mNEXT
+
+ FORTHWORD "CAPS_OFF"
+CAPS_OFF MOV #0,&CAPS
+ mNEXT
+
+;C ." -- compile string to print
+ FORTHWORDIMM ".\34" ; immediate
+DOTQUOTE: mDOCOL
+ .word CAPS_OFF
+ .word SQUOTE
+ .word CAPS_ON
+ .word lit,TYPE,COMMA,EXIT
+
+ .ELSE
+
+;C ." -- compile string to print
+ FORTHWORDIMM ".\34" ; immediate
+DOTQUOTE: mDOCOL
+ .word SQUOTE
+ .word lit,TYPE,COMMA,EXIT
+
+ .ENDIF ; LOWERCASE
+
+; ----------------------------------------------------------------------
+; INTERPRETER
+; ----------------------------------------------------------------------
+
+;C WORD char -- addr Z=1 if len=0
+; parse a word delimited by char ( and begining usually at [TIB])
+; "word" is capitalized
+; TOIN is the relative displacement into buffer
+; empty line = 25 cycles + 7 cycles by char
+ FORTHWORD "WORD"
+WORDD MOV #SOURCE_LEN,S ;2 -- separator
+ MOV @S+,X ;2 X = buf_len
+ MOV @S+,W ;2 W = buf_org
+ ADD W,X ;1 W = buf_org X = buf_org + buf_len = buf_end
+ ADD @S+,W ;2 W = buf_org + >IN = buf_ptr X = buf_end
+ MOV @S,Y ;2 -- separator W = buf_ptr X = buf_end Y = HERE, as dst_ptr
+SKIPCHARLOO CMP W,X ;1 buf_ptr = buf_end ?
+ JZ EOL_END ;2 -- separator if yes : End Of Line !
+ CMP.B @W+,TOS ;2 does char = separator ?
+ JZ SKIPCHARLOO ;2 -- separator if yes
+SCANWORD SUB #1,W ;1
+ MOV #96,T ;2 T = 96 = ascii(a)-1 (test value in register before SCANWORD loop)
+SCANWORDLOO ; -- separator 15/23 cycles loop for upper/lower case char... write words in upper case !
+ MOV.B S,0(Y) ;3 first time puts anything in dst word length, then put char @ dst.
+ CMP W,X ;1 buf_ptr = buf_end ?
+ JZ SCANWORDEND ;2 if yes
+ MOV.B @W+,S ;2
+ CMP.B S,TOS ;1 does char = separator ?
+ JZ SCANWORDEND ;2 if yes
+ ADD #1,Y ;1 increment dst just before test loop
+ CMP.B S,T ;1 char U< 'a' ? ('a'-1 U>= char) this condition is tested at each loop
+ JC SCANWORDLOO ;2 15~ upper case char loop
+ .IFDEF LOWERCASE ; enable lowercase strings
+QCAPS CMP #0,&CAPS ;3 CAPS is OFF ? (case available only for ABORT" ." .( )
+ JZ SCANWORDLOO ;2 yes
+ .ENDIF ; LOWERCASE ; here CAPS is ON (other cases)
+ CMP.B #123,S ;2 char U>= 'z'+1 ?
+ JC SCANWORDLOO ;2 if yes
+ SUB.B #32,S ;2 convert lowercase char to uppercase
+ JMP SCANWORDLOO ;2 28~ lower case char loop
+
+SCANWORDEND SUB &SOURCE_ADR,W ;3 -- separator W=buf_ptr - buf_org = new >IN (first char separator next)
+ MOV W,&TOIN ;3 update >IN
+EOL_END MOV &DDP,TOS ;3 -- c-addr
+ SUB TOS,Y ;1 Y=Word_Length
+ MOV.B Y,0(TOS) ;3
+ mNEXT ;4 -- c-addr 40 words Z=1 <==> lenght=0 <==> EOL
+
+
+;C FIND c-addr -- c-addr 0 if not found ; flag Z=1
+;C xt -1 if found ; flag Z=0
+;C xt 1 if immediate ; flag Z=0
+; compare WORD at c-addr (HERE) with each of words in each of listed vocabularies in CONTEXT
+; FIND to WORDLOOP : 14/20 cycles,
+; mismatch word loop: 13 cycles on len, +8 cycles on first char,
+; +10 cycles char loop,
+; VOCLOOP : 12/18 cycles,
+; WORDFOUND to end : 21 cycles.
+; note: with 16 threads vocabularies, FIND takes about 75% of CORETEST.4th processing time
+
+ FORTHWORD "FIND"
+FIND SUB #2,PSP ;1 -- ???? c-addr reserve one cell here, not at FINDEND because interacts with flag Z
+ MOV TOS,S ;1 S=c-addr
+ MOV.B @S,rDOCON ;2 R5= string count
+ MOV.B #80h,rDODOES ;2 R4= immediate mask
+ MOV #CONTEXT,T ;2
+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
+ .ELSECASE ; search thread add 6cycles 5words
+MAKETHREAD MOV.B 1(S),Y ;3 -- ???? VOC_PFA0 S=c-addr Y=CHAR0
+ AND.B #(THREADS-1)*2,Y ;2 -- ???? VOC_PFA0 Y=thread offset
+ ADD Y,TOS ;1 -- ???? VOC_PFAx
+ .ENDCASE
+ ADD #2,TOS ;1 -- ???? VOC_PFA+2
+WORDLOOP MOV -2(TOS),TOS ;3 -- ???? [VOC_PFA] [VOC_PFA] first, then [LFA]
+ CMP #0,TOS ;1 -- ???? NFA no more word in the thread ?
+ JZ VOCLOOP ;2 -- ???? NFA yes ==> search next voc in context
+ MOV TOS,X ;1
+ MOV.B @X+,Y ;2 TOS=NFA,X=NFA+1,Y=NFA_char
+ BIC.B rDODOES,Y ;1 hide Immediate bit
+LENCOMP CMP.B rDOCON,Y ;1 compare lenght
+ JNZ WORDLOOP ;2 -- ???? NFA 13~ word loop on lenght mismatch
+ MOV S,W ;1 W=c-addr
+CHARLOOP ADD #1,W ;1
+CHARCOMP CMP.B @X+,0(W) ;4 compare chars
+ JNZ WORDLOOP ;2 -- ???? NFA 21~ word loop on first char mismatch
+ SUB.B #1,Y ;1 decr count
+ JNZ CHARLOOP ;2 -- ???? NFA 10~ char loop
+WORDFOUND BIT #1,X ;1
+ ADDC #0,X ;1
+ MOV X,S ;1 S=aligned CFA
+ MOV.B @TOS,W ;2 -- ???? NFA W=NFA_first_char
+ MOV #1,TOS ;1 -- ???? 1 preset immediate flag
+ CMP.B #0,W ;1 W is negative if immediate flag
+ JN FINDEND ;2 -- ???? 1
+ SUB #2,TOS ;1 -- ???? -1
+FINDEND MOV S,0(PSP) ;3 not found: -- c-addr 0 flag Z=1
+ ; found: -- xt -1|+1 (not immediate|immediate) flag Z=0
+ MOV #xdocon,rDOCON ;2
+ MOV #xdodoes,rDODOES;2
+ mNEXT ;4 42/47 words
+
+
+
+THREEDROP ADD #2,PSP
+TWODROP ADD #2,PSP
+ MOV @PSP+,TOS
+ mNEXT
+
+;C convert a string to double number until count = 0 or until not convertible char
+;C >NUMBER ud1lo|ud1hi addr1 count1 -- ud2lo|ud2hi addr2 count2
+
+ .IFDEF MPY
+
+ FORTHWORD ">NUMBER" ; 23 cycles + 32/34 cycles DEC/HEX char loop
+TONUMBER MOV @PSP+,S ;2 S = adr
+ MOV @PSP+,Y ;2 Y = ud1hi
+ MOV @PSP,X ;2 X = ud1lo
+ SUB #4,PSP ;1
+ MOV &BASE,T ;3
+TONUMLOOP MOV.B @S,W ;2 -- ud1lo ud1hi adr count W=char
+DDIGITQ SUB.B #30h,W ;2 skip all chars < '0'
+ CMP.B #10,W ;2 char was > "9" ?
+ JLO DDIGITQNEXT ;2 no
+ SUB.B #7,W ;2 skip all chars between "9" and "A"
+DDIGITQNEXT CMP T,W ;1 digit-base
+ JHS TONUMEND ;2 -- ud1lo ud1hi adr count abort
+ MOV X,&MPY32L ;3 Load 1st operand (ud1lo)
+ MOV Y,&MPY32H ;3 Load 1st operand (ud1hi)
+ MOV T,&OP2 ;3 Load 2nd operand with BASE
+ MOV &RES0,X ;3 lo result in X (ud2lo)
+ MOV &RES1,Y ;3 hi result in Y (ud2hi)
+ ADD W,X ;1 ud2lo + digit
+ ADDC #0,Y ;1 ud2hi + carry
+ ADD #1,S ;1 -- ud1lo ud1hi adr count S=adr+1
+ SUB #1,TOS ;1 -- ud1lo ud1hi adr count-1
+ JNZ TONUMLOOP ;2 if count <>0
+ MOV X,4(PSP) ;3 -- ud2lo ud1hi adr count2
+ MOV Y,2(PSP) ;3 -- ud2lo ud2hi adr count2
+TONUMEND MOV S,0(PSP) ;3 -- ud2lo ud2hi addr2 count2
+ mNEXT ;4 38 words
+
+
+; convert a string to a signed number; FORTH 2012 prefixes $, %, # are recognized
+; 32 bits numbers are recognized
+; the decimal point is processed
+;Z ?NUMBER c-addr -- n -1 if convert ok ; flag Z=0
+;Z c-addr -- c-addr 0 if convert ko ; flag Z=1
+
+; FORTHWORD "?NUMBER"
+QNUMBER PUSH #0 ;3 -- c-addr
+ PUSH IP ;3
+ MOV &BASE,T ;3 T=BASE
+ PUSH T ;3 R-- sign IP base
+; ----------------------------------;
+; Added decimal point process ;
+; ----------------------------------;
+ BIC #UF1,SR ;2 reset flag UF1 used here as Decimal Point flag
+ MOV.B @TOS,IP ;2 IP = count of chars
+ ADD TOS,IP ;1 IP = end address
+ MOV TOS,S ;1 S = ptr
+ MOV.B #'.',W ;2 W = '.' = Decimal Point DP
+SearchDP CMP S,IP ;1 IP U< S ?
+ JLO SearchDPEND ;2
+ CMP.B @S+,W ;2 DP found ?
+ JNE SearchDP ;2 7~ loop by char
+DPfound BIS #UF1,SR ;2 DP found: set flag UF1
+DPrubLoop MOV.B @S+,-2(S) ;4 rub out decimal point
+ CMP S,IP ;1 and move left one all susbsequent chars
+ JHS DPrubLoop ;2 7~ loop by char
+ SUB.B #1,0(TOS) ;3 and decrement count of chars
+SearchDPEND ;
+; ----------------------------------;
+ MOV #0,X ;1 X=ud1lo
+ MOV #0,Y ;1 Y=ud1hi
+ MOV #QNUMNEXT,IP ;2 return from >NUMBER
+ SUB #8,PSP ;1 -- x x x x c-addr
+ MOV TOS,6(PSP) ;3 -- c-addr x x x c-addr
+ MOV TOS,S ;1 S=addrr
+ MOV.B @S+,TOS ;2 -- c-addr x x x cnt
+ MOV.B @S,W ;2 W=char
+ CMP.B #'-',W ;2
+ JHS QSIGN ;2 speed up for not prefixed numbers
+QHEXA MOV #16,T ;2 BASE = 16
+ SUB.B #'$',W ;2 = 0 ==> "$" : hex number ?
+ JZ PREFIXED ;2
+QBINARY MOV #2,T ;1 BASE = 2
+ SUB.B #1,W ;1 "%" - "$" - 1 = 0 ==> '%' : hex number ?
+ JZ PREFIXED ;2
+QDECIMAL ADD #8,T ;1 BASE = 10
+ ADD.B #2,W ;1 "#" - "%" + 2 = 0 ==> '#' : decimal number ?
+ JNZ TONUMLOOP ;2 then the conversion return will be ko
+PREFIXED ADD #1,S ;1 addr+1 to skip prefix
+ SUB #1,TOS ;1 -- c-addr x x x cnt-1
+ MOV.B @S,W ;2 W=2th char, S=adr
+ CMP.B #'-',W ;2
+QSIGN JNZ TONUMLOOP ;15 + 32/34 cycles DEC/HEX char loop
+QSIGNYES ADD #1,S ;1 addr+1 to skip "-"
+ SUB #1,TOS ;1 -- c-addr x x x cnt-1
+ MOV #-1,4(RSP) ;3 R-- sign IP BASE
+ JMP TONUMLOOP ;15 + 32/34 cycles DEC/HEX char loop
+; ----------------------------------;
+QNUMNEXT FORTHtoASM ; -- c-addr ud2lo ud2hi addr2 count2
+ ADD #2,PSP ;1
+ CMP #0,TOS ;1 -- c-addr ud2lo ud2hi cnt2 n=0 ? conversion is ok ?
+ .word 0172Ch ;4 -- c-addr ud2lo ud2hi sign POPM S,IP,TOS; TOS = sign flag = {-1;0}
+ MOV S,&BASE ;3
+ JZ QNUMOK ;2 -- c-addr ud2lo ud2hi sign conversion OK
+QNUMKO ADD #4,PSP ;1 -- c-addr sign
+ AND #0,TOS ;1 -- c-addr ff TOS=0 and Z=1 ==> conversion ko
+ mNEXT ;4
+
+;; ----------------------------------;
+;; process word conversion ;
+;; ----------------------------------;
+;QNUMOK ADD #2,PSP ; -- c-addr ud2lo sign
+; MOV @PSP+,0(PSP) ;4 -- |n| sign note : PSP is incremented before write back !!!
+; XOR #-1,TOS ;1 -- |n| inv(sign)
+; JNZ QNUMEND ;2 if jump : TOS=-1 and Z=0 ==> conversion ok
+;QNEGATE XOR #-1,0(PSP) ;3 -- n-1 ff else TOS=0
+; ADD #1,0(PSP) ;3 -- n ff
+; XOR #-1,TOS ;1 -- n tf TOS=-1 and Z=0 ==> conversion ok
+;QNUMEND mNEXT ;4
+;; ----------------------------------;
+
+; ----------------------------------;
+; Select word|double word conversion; -- c-addr ud2lo ud2hi sign
+; ----------------------------------;
+QNUMOK CMP #0,0(PSP) ;3 double number ?
+ JNZ PROCESSNUM2 ;2 process double numbers
+ BIT #UF1,SR ;2 decimal point added ?
+ JNZ PROCESSNUM3 ;2 process double numbers
+ CMP #0,TOS ; test sign
+ JZ PROCESSNUM ; if unsigned number < 65536
+ MOV 2(PSP),W ;
+ SUB #1,W ;
+ CMP #0,W ;
+ JL PROCESSNUM2 ; if number < -32768
+; ----------------------------------;
+; process word conversion ;
+; ----------------------------------;
+PROCESSNUM ADD #2,PSP ; -- c-addr ud2lo sign
+ MOV @PSP+,0(PSP) ;4 -- |n| sign note : PSP is incremented before write back !!!
+ XOR #-1,TOS ;1 -- |n| inv(sign)
+ JNZ QNUMEND ;2 if jump : TOS=-1 and Z=0 ==> conversion ok
+QNEGATE XOR #-1,0(PSP) ;3 -- n-1 ff else TOS=0
+ ADD #1,0(PSP) ;3 -- n ff
+ XOR #-1,TOS ;1 -- n tf TOS=-1 and Z=0 ==> conversion ok
+QNUMEND mNEXT ;4
+; ----------------------------------;
+; process double word conversion ;
+; ----------------------------------;
+PROCESSNUM2 BIS #UF1,SR ; set UF1 flag (SR(9)), for LITERAL use
+PROCESSNUM3 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 QNUMEND ;2 if jump : TOS=-1 and Z=0 ==> conversion ok
+Q2NEGATE XOR #-1,2(PSP) ;3 -- dlo-1 dhi-1 ff
+ XOR #-1,0(PSP) ;3 -- dlo-1 udhi ff
+ ADD #1,2(PSP) ;3 -- dlo dhi-1 ff
+ ADDC #0,0(PSP) ;3 -- dlo dhi ff
+ XOR #-1,TOS ;1 -- dlo dhi tf
+QNUM2END mNEXT ;4 105 words TOS=-1 and Z=0 ==> conversion ok
+; ----------------------------------;
+
+ .ELSE ; no hardware MPY
+
+ FORTHWORD ">NUMBER"
+TONUMBER MOV @PSP,S ; -- ud1lo ud1hi adr count
+ MOV.B @S,S ; -- ud1lo ud1hi adr count S=char
+DDIGITQ SUB.B #30h,S ;2 skip all chars < '0'
+ CMP.B #10,S ; char was > "9" ?
+ JLO DDIGITQNEXT ; -- ud1lo ud1hi adr count no
+ SUB.B #07h,S ; S=digit
+DDIGITQNEXT CMP &BASE,S ; -- ud1lo ud1hi adr count digit-base
+ JHS TONUMEND ; U>=
+UDSTAR .word 152Eh ; -- ud1lo ud1hi adr count PUSHM TOS,IP,S (2+1 push,TOS=Eh)
+ SUB #2,PSP ; -- ud1lo ud1hi adr x count
+ MOV 4(PSP),0(PSP) ; -- ud1lo ud1hi adr ud1hi count
+ MOV &BASE,TOS ; -- ud1lo ud1hi adr ud1hi u2=base
+ MOV #UMSTARNEXT1,IP ;
+UMSTAR1 MOV #UMSTAR,PC ; ud1hi * base ; UMSTAR use S,T,W,X,Y
+UMSTARNEXT1 FORTHtoASM ; -- ud1lo ud1hi adr ud3lo ud3hi
+ PUSH @PSP ; r-- count ud3lo
+ MOV 6(PSP),0(PSP) ; -- ud1lo ud1hi adr ud1lo ud3hi
+ MOV &BASE,TOS ; -- ud1lo ud1hi adr ud1lo u=base
+ MOV #UMSTARNEXT2,IP
+UMSTAR2 MOV #UMSTAR,PC ; ud1lo * base ; UMSTAR use S,T,W,X,Y, and S is free for use
+UMSTARNEXT2 FORTHtoASM ; -- ud1lo ud1hi adr ud2lo ud2hi r-- count IP digit ud3lo
+ ADD @RSP+,TOS ; -- ud1lo ud1hi adr ud2lo ud2hi r-- count IP digit add ud3lo to ud2hi
+MPLUS ADD @RSP+,0(PSP) ; -- ud1lo ud1hi adr ud2lo ud2hi Ud2lo + digit
+ ADDC #0,TOS ; -- ud1lo ud1hi adr ud2lo ud2hi ud2hi + carry
+ MOV @PSP,6(PSP) ; -- ud2lo ud1hi adr ud2lo ud2hi
+ MOV TOS,4(PSP) ; -- ud2lo ud2hi adr ud2lo ud2hi
+
+ .word 171Dh ; -- ud2lo ud2hi adr ud2lo count POPM IP,TOS (1+1 pop,IP=D)
+ ADD #2,PSP ; -- ud2lo ud2hi adr count
+ ADD #1,0(PSP) ; -- ud2lo ud2hi adr+1 count
+ SUB #1,TOS ; -- ud2lo ud2hi adr+1 count-1
+ JNZ TONUMBER
+TONUMEND mNEXT ; 52 words
+
+
+; convert a string to a signed number
+;Z ?NUMBER c-addr -- n -1 if convert ok ; flag Z=0
+;Z c-addr -- c-addr 0 if convert ko ; flag Z=1
+; FORTH 2012 prefixes $, %, # are recognized
+; FORTHWORD "?NUMBER"
+QNUMBER PUSH #0 ;3 -- c-addr
+ PUSH IP ;3
+ PUSH &BASE ;3 R-- sign IP base
+; ----------------------------------;
+; Added decimal point process ;
+; ----------------------------------;
+ BIC #UF1,SR ;2 reset flag UF1 used here as decimal point flag
+ MOV.B @TOS,IP ;2 IP = count of chars
+ ADD TOS,IP ;1 IP = end address
+ MOV TOS,S ;1 S = ptr
+ MOV.B #'.',W ;2 W = '.'
+SearchDP CMP S,IP ;1 IP U< S ?
+ JLO SearchDPEND ;2
+ CMP.B @S+,W ;2 DP found ?
+ JNE SearchDP ;2 7~ loop by char
+DPfound BIS #UF1,SR ;2 DP found: set flag UF1
+DPrubLoop MOV.B @S+,-2(S) ;4 rub out decimal point
+ CMP S,IP ;1 and move left one all susbsequent chars
+ JHS DPrubLoop ;2 7~ loop by char
+ SUB.B #1,0(TOS) ;3 and decrement count of chars
+SearchDPEND
+; ----------------------------------;
+ MOV #QNUMNEXT,IP ;2 return from >NUMBER
+ SUB #8,PSP ;1 -- x x x x c-addr
+ MOV TOS,6(PSP) ;3 -- c-addr x x x c-addr
+ MOV #0,4(PSP) ;3
+ MOV #0,2(PSP) ;3 -- c-addr ud x c-addr
+ MOV TOS,W ;1
+ MOV.B @W+,TOS ;2 -- c-addr ud x count
+ MOV W,0(PSP) ;3 -- c-addr ud adr count
+ MOV.B @W+,X ;2 X=char
+ CMP.B #'-',X ;2
+ JHS QSIGN ;2 speed up for not prefixed numbers
+QHEXA SUB.B #'$',X ;2 = 0 ==> "$" : hex number ?
+ JNZ QBINARY ;2 -- c-addr ud adr count other cases will cause error
+ MOV #16,&BASE ;4
+ JMP PREFIXED ;2
+QBINARY SUB.B #1,X ;1 "%" - "$" - 1 = 0 ==> '%' : hex number ?
+ JNZ QDECIMAL ;2
+ MOV #2,&BASE ;3
+ JMP PREFIXED ;2
+QDECIMAL ADD.B #2,X ;1 "#" - "%" + 2 = 0 ==> '#' : decimal number ?
+ JNZ TONUMBER ;2 that will perform a conversion error
+ MOV #10,&BASE ;4
+PREFIXED MOV W,0(PSP) ;3
+ SUB #1,TOS ;1 -- c-addr ud adr+1 count-1
+ MOV.B @W+,X ;2 X=2th char, W=adr
+ CMP.B #'-',X ;2
+QSIGN JNZ TONUMBER ;2
+ MOV #-1,4(RSP) ;3 R-- sign IP BASE
+ MOV W,0(PSP) ;3
+ SUB #1,TOS ;1 -- c-addr ud adr+1 count-1
+ JMP TONUMBER ;2
+; ----------------------------------;
+QNUMNEXT FORTHtoASM ; -- c-addr ud2lo ud2hi addr2 count2
+ ADD #2,PSP ;1
+ CMP #0,TOS ;1 -- c-addr ud2lo ud2hi cnt2 n=0 ? conversion is ok ?
+ .word 0172Ch ;4 -- c-addr ud2lo ud2hi sign POPM S,IP,TOS; TOS = sign flag = {-1;0}
+ MOV S,&BASE ;3
+ JZ QNUMOK ;2 -- c-addr ud2lo ud2hi sign conversion OK
+QNUMKO ADD #4,PSP ;1 -- c-addr sign
+ AND #0,TOS ;1 -- c-addr ff TOS=0 and Z=1 ==> conversion ko
+ mNEXT ;4
+
+;; ----------------------------------;
+;; process word conversion ;
+;; ----------------------------------;
+;QNUMOK ADD #2,PSP ; -- c-addr ud2lo sign
+; MOV @PSP+,0(PSP) ;4 -- |n| sign note : PSP is incremented before write back !!!
+; XOR #-1,TOS ;1 -- |n| inv(sign)
+; JNZ QNUMEND ;2 if jump : TOS=-1 and Z=0 ==> conversion ok
+;QNEGATE XOR #-1,0(PSP) ;3 -- n-1 ff else TOS=0
+; ADD #1,0(PSP) ;3 -- n ff
+; XOR #-1,TOS ;1 -- n tf TOS=-1 and Z=0 ==> conversion ok
+;QNUMEND mNEXT ;4
+;; ----------------------------------;
+
+; ----------------------------------;
+; Select word|double word conversion; -- c-addr ud2lo ud2hi sign
+; ----------------------------------;
+QNUMOK CMP #0,0(PSP) ;3 double number ?
+ JNZ PROCESSNUM2 ;2 process double numbers
+ BIT #UF1,SR ;2 decimal point added ?
+ JNZ PROCESSNUM3 ;2 process double numbers
+ CMP #0,TOS ; test sign
+ JZ PROCESSNUM ; if unsigned number < 65536
+ MOV 2(PSP),W ;
+ SUB #1,W ;
+ CMP #0,W ;
+ JL PROCESSNUM2 ; if number < -32768
+; ----------------------------------;
+; process word conversion ;
+; ----------------------------------;
+PROCESSNUM ADD #2,PSP ; -- c-addr ud2lo sign
+ MOV @PSP+,0(PSP) ;4 -- |n| sign note : PSP is incremented before write back !!!
+ XOR #-1,TOS ;1 -- |n| inv(sign)
+ JNZ QNUMEND ;2 if jump : TOS=-1 and Z=0 ==> conversion ok
+QNEGATE XOR #-1,0(PSP) ;3 -- n-1 ff else TOS=0
+ ADD #1,0(PSP) ;3 -- n ff
+ XOR #-1,TOS ;1 -- n tf TOS=-1 and Z=0 ==> conversion ok
+QNUMEND mNEXT ;4
+; ----------------------------------;
+; process double word conversion ;
+; ----------------------------------;
+PROCESSNUM2 BIS #UF1,SR ; set UF1 flag (SR(9)), case of number > word
+PROCESSNUM3 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 QNUMEND ;2 if jump : TOS=-1 and Z=0 ==> conversion ok
+Q2NEGATE XOR #-1,2(PSP) ;3 -- dlo-1 dhi-1 ff
+ XOR #-1,0(PSP) ;3 -- dlo-1 udhi ff
+ ADD #1,2(PSP) ;3 -- dlo dhi-1 ff
+ ADDC #0,0(PSP) ;3 -- dlo dhi ff
+ XOR #-1,TOS ;1 -- dlo dhi tf
+QNUM2END mNEXT ;4 105 words TOS=-1 and Z=0 ==> conversion ok
+; ----------------------------------;
+
+ .ENDIF ; MPY
+
+
+;C EXECUTE i*x xt -- j*x execute Forth word at 'xt'
+ FORTHWORD "EXECUTE"
+EXECUTE MOV TOS,W ; 1 put word address into W
+ MOV @PSP+,TOS ; 2 fetch new TOS
+ MOV W,PC ; 3 fetch code address into PC
+ ; 6 = ITC - 1
+
+;C , x -- append cell to dict
+ FORTHWORD ","
+COMMA MOV &DDP,W ;3
+ ADD #2,&DDP ;3
+ MOV TOS,0(W) ;3
+ MOV @PSP+,TOS ;2
+ mNEXT ;4 15~
+
+;C LITERAL (n|d) -- append single or double numeric literal if compiling state
+ FORTHWORDIMM "LITERAL" ; immediate
+LITERAL CMP #0,&STATE ;3
+ JZ LITERALEND ;2
+ BIT #UF1,SR ;2
+ JZ LITERAL1 ;2
+LITERAL2 MOV &DDP,W ;3
+ ADD #4,&DDP ;3
+ MOV #lit,0(W) ;4
+ MOV @PSP+,2(W) ;3
+LITERAL1 MOV &DDP,W ;3
+ ADD #4,&DDP ;3
+ MOV #lit,0(W) ;4
+ MOV TOS,2(W) ;3
+ MOV @PSP+,TOS ;2
+LITERALEND mNEXT ;4 24~
+
+;C COUNT c-addr1 -- adr len counted->adr/len
+ FORTHWORD "COUNT"
+COUNT: SUB #2,PSP ;1
+ ADD #1,TOS ;1
+ MOV TOS,0(PSP) ;3
+ MOV.B -1(TOS),TOS ;3
+ mNEXT ;4 15~
+
+;C INTERPRET i*x addr u -- j*x interpret given buffer
+; This is the common factor of EVALUATE and QUIT.
+; ref. dpANS-6, 3.4 The Forth Text Interpreter
+
+; FORTHWORD "INTERPRET" ; not used in FORTH 2012
+INTERPRET MOV TOS,&SOURCE_LEN ; -- addr u buffer lentgh ==> ticksource variable
+ MOV @PSP+,&SOURCE_ADR ; -- u buffer address ==> ticksource+2 variable
+ MOV @PSP+,TOS ; --
+ MOV #0,&TOIN ;
+ mDOCOL ;
+INTLOOP .word FBLANK,WORDD ; -- c-addr Z = End Of Line
+ FORTHtoASM ;
+ MOV #INTFINDNEXT,IP ;2 ddefine INTFINDNEXT as FIND return
+ JNZ FIND ;2 if EOL not reached
+ MOV @RSP+,IP ; --
+ MOV @PSP+,TOS ; -- else EOL is reached
+ mNEXT ; return to QUIT on EOL
+
+INTFINDNEXT FORTHtoASM ; -- c-addr fl Z = not found
+ MOV TOS,W ; W = flag =(-1|0|+1) as (normal|not_found|immediate)
+ MOV @PSP+,TOS ; -- c-addr
+ MOV #INTQNUMNEXT,IP ;2 define QNUMBER return
+ JZ QNUMBER ;2 c-addr -- if not found search a number
+ MOV #INTLOOP,IP ;2 define (EXECUTE | COMMA) return
+ XOR &STATE,W ;3
+ JZ COMMA ;2 c-addr -- if W xor STATE = 0 compile xt then loop back to INTLOOP
+ JNZ EXECUTE ;2 c-addr -- if W xor STATE <> 0 execute then loop back to INTLOOP
+
+INTQNUMNEXT FORTHtoASM ; -- n|c-addr fl Z = not a number
+ MOV @PSP+,TOS ;2
+ MOV #INTLOOP,IP ;2 -- n|c-addr define LITERAL return
+ JNZ LITERAL ;2 n -- execute LITERAL then loop back to INTLOOP
+NotFoundExe ADD.B #1,0(TOS) ;3 c-addr -- Not a Number : incr string count to add '?'
+ MOV.B @TOS,Y ;2
+ ADD TOS,Y ;1
+ MOV.B #'?',0(Y) ;5 add '?' to end of word
+ MOV #FQABORTYES,IP ;2 define COUNT return
+ JMP COUNT ;2 c-addr -- 44 words
+
+; EVALUATE \ i*x c-addr u -- j*x interpret string
+ FORTHWORD "EVALUATE"
+EVALUATE MOV #SOURCE_LEN,X
+ PUSH @X+
+ PUSH @X+
+ PUSH @X+
+ PUSH IP
+ ASMtoFORTH
+ .word INTERPRET
+ FORTHtoASM
+ MOV @RSP+,IP ;2
+ MOV @RSP+,&TOIN ;4
+ MOV @RSP+,&SOURCE_ADR ;4
+ MOV @RSP+,&SOURCE_LEN ;4
+ mNEXT
+
+;c QUIT -- interpret line by line the input stream
+ FORTHWORD "QUIT"
+QUIT MOV #RSTACK,RSP
+ MOV #LSTACK,&LEAVEPTR
+ MOV #0,&STATE
+
+ MOV #0,&SAVE_SYSRSTIV ;
+
+QUIT0 ASMtoFORTH
+QUIT1 .word XSQUOTE
+ .byte 4,13,"ok " ; CR + system prompt
+QUIT2 .word TYPE
+QUIT3 .word lit,TIB,DUP,lit,TIB_SIZE ; -- StringOrg StringOrg len
+ .word ACCEPT ; -- StringOrg len'
+ .word SPACE
+QUIT4 .word INTERPRET
+ .word lit,PSTACK-2,SPFETCH,ULESS
+ .word XSQUOTE
+ .byte 13,"stack empty !"
+ .word QABORT
+ .word lit,FRAM_FULL,HERE,ULESS
+ .word XSQUOTE
+ .byte 11,"FRAM full !"
+ .word QABORT
+ .word FSTATE,FETCH
+ .word QBRAN,QUIT1 ; case of interpretion state
+ .word XSQUOTE ; case of compilation state
+ .byte 4,13," " ; CR + 3 spaces
+ .word BRAN,QUIT2
+
+;C ABORT i*x -- R: j*x -- clear stack & QUIT
+ FORTHWORD "ABORT"
+ABORT: MOV #PSTACK,PSP
+ JMP QUIT
+
+RefillUSBtime .equ int(frequency*2730) ; 2730*frequency ==> word size max value @ 24 MHz
+
+;Z ?ABORT f c-addr u -- abort & print msg
+; FORTHWORD "?ABORT"
+QABORT CMP #0,2(PSP) ; -- f c-addr u flag test
+QABORTNO JZ THREEDROP
+
+QABORTYES MOV #4882h,&YEMIT ; restore default YEMIT = set ECHO
+ .IFDEF SD_CARD_LOADER ; close all handles
+ MOV &CurrentHdl,T
+QABORTCLOSE
+ CMP #0,T
+ JZ QABORTYESNOECHO
+ MOV.B #0,HDLB_Token(T)
+ MOV @T,T
+ JMP QABORTCLOSE
+ .ENDIF
+ ; -- c-addr u
+; ----------------------------------;
+QABORTYESNOECHO ; <== WARM jumps here, thus, if NOECHO, TERMINAL can be disconnected without freezing the app
+; ----------------------------------;
+ CALL #QAB_DEFER ; restore default deferred words ....else WARM.
+ .IFDEF MSP430ASSEMBLER ; reset all branch labels
+ MOV #0,&CLRBW1
+ MOV #0,&CLRBW2
+ MOV #0,&CLRBW3
+ MOV #0,&CLRFW1
+ MOV #0,&CLRFW2
+ MOV #0,&CLRFW3
+ .ENDIF
+
+
+; ----------------------------------;
+QABORTTERM ; wait the end of source file downloading
+; ----------------------------------;
+ .IFDEF TERMINALXONXOFF ;
+ BIT #UCTXIFG,&TERMIFG ; TX buffer empty ?
+ JZ QABORTTERM ; no
+ MOV #17,&TERMTXBUF ; yes move XON char into TX_buf
+ .ENDIF ;
+ .IFDEF TERMINALCTSRTS ;
+ BIC.B #RTS,&HANDSHAKOUT ; set /RTS low (connected to /CTS pin of UARTtoUSB bridge)
+ .ENDIF ;
+QABORTLOOP BIC #UCRXIFG,&TERMIFG ; reset TERMIFG(UCRXIFG)
+ MOV #RefillUSBtime,Y ; 2730*28 = 75 ms
+QABUSBLOOPJ ; 28~ loop : PL2303TA seems the slower USB device to refill its buffer.
+ MOV #8,X ; 1~
+QABUSBLOOPI ; 3~ loop
+ SUB #1,X ; 1~
+ JNZ QABUSBLOOPI ; 2~
+ SUB #1,Y ; 1~
+ JNZ QABUSBLOOPJ ; 2~
+ BIT #UCRXIFG,&TERMIFG ; 4 new char in TERMXBUF ?
+ JNZ QABORTLOOP ; 2 yes, the input stream (download source file) is still active
+
+; ----------------------------------;
+; Display WARM/ABORT message ;
+; ----------------------------------;
+ mDOCOL ; no, the input stream is quiet (end of download source file)
+ .word XSQUOTE ; -- c-addr u c-addr1 u1
+ .byte 4,1Bh,"[7m" ;
+ .word TYPE ; -- c-addr u set reverse video
+ .word TYPE ; -- type abort message
+ .word XSQUOTE ; -- c-addr2 u2
+ .byte 4,1Bh,"[0m" ;
+ .word TYPE ; -- set normal video
+ .word FORTH,ONLY ; to quit assembler and so to abort any ASSEMBLER definitions
+ .word DEFINITIONS ; reset CURRENT directory
+ .IFDEF LOWERCASE
+ .word CAPS_ON ;
+ .ENDIF
+ .word ABORT ;
+
+ .IFDEF LOWERCASE
+
+;C ABORT" i*x flag -- i*x R: j*x -- j*x flag=0
+;C i*x flag -- R: j*x -- flag<>0
+ FORTHWORDIMM "ABORT\34" ; immediate
+ABORTQUOTE mDOCOL
+ .word CAPS_OFF,SQUOTE,CAPS_ON
+ .word lit,QABORT,COMMA
+ .word EXIT
+
+ .ELSE
+
+;C ABORT" i*x flag -- i*x R: j*x -- j*x flag=0
+;C i*x flag -- R: j*x -- flag<>0
+ FORTHWORDIMM "ABORT\34" ; immediate
+ABORTQUOTE mDOCOL
+ .word SQUOTE
+ .word lit,QABORT,COMMA
+ .word EXIT
+
+ .ENDIF ; LOWERCASE
+
+
+;C ' -- xt find word in dictionary
+ FORTHWORD "'"
+TICK mDOCOL ; separator -- xt
+ .word FBLANK,WORDD,FIND ; Z=1 if not found
+ .word QBRAN,NotFound
+ .word EXIT
+NotFound .word NotFoundExe ; in INTERPRET
+
+; \ -- backslash
+; everything up to the end of the current line is a comment.
+ FORTHWORDIMM "\\" ; immediate
+BACKSLASH MOV &SOURCE_LEN,&TOIN ;
+ mNEXT
+
+; ----------------------------------------------------------------------
+; COMPILER
+; ----------------------------------------------------------------------
+
+; HEADER create an header for a new word. Max count of chars = 126
+; common code for VARIABLE, CONSTANT, CREATE, DEFER, :, CODE, ASM.
+; don't link created word in vocabulary.
+
+HEADER mDOCOL
+ .word CELLPLUSALIGN ; ALIGN then make room for LFA
+ .word FBLANK,WORDD ;
+ FORTHtoASM ; -- HERE HERE is the NFA of this new word
+ MOV TOS,Y ;
+ MOV.B @TOS+,W ; -- xxx W=Count_of_chars Y=NFA
+ BIS.B #1,W ; -- xxx W=count is always odd
+ ADD.B #1,W ; -- xxx W=add one byte for length
+ ADD Y,W ; -- xxx W=Aligned_CFA
+ MOV &CURRENT,X ; -- xxx X=VOC_BODY of CURRENT Y=NFA
+ .SWITCH THREADS
+ .CASE 1 ; nothing to do
+ .ELSECASE ; multithreading add 5~ 4words
+ MOV.B @TOS,TOS ; -- xxx TOS=first CHAR of new word
+ AND #(THREADS-1)*2,TOS ; -- xxx TOS= Thread offset
+ ADD TOS,X ; -- xxx TOS= Thread X=VOC_PFAx = thread x of VOC_PFA of CURRENT
+ .ENDCASE
+ MOV Y,&LAST_NFA ; -- xxx NFA --> LAST_NFA used by QREVEAL, IMMEDIATE
+ MOV X,&LAST_THREAD ; -- xxx VOC_PFAx --> LAST_THREAD used by QREVEAL
+ MOV W,&LAST_CFA ; -- xxx HERE=CFA --> LAST_CFA used by DOES>, RECURSE
+ ADD #4,W ; -- xxx by default make room for two words...
+ MOV W,&DDP ; -- xxx
+ MOV @PSP+,TOS ; --
+ MOV @RSP+,IP
+ MOV @RSP+,PC ; 23 words, W is the new DDP value )
+ ; X is LAST_THREAD > used by VARIABLE, CONSTANT, CREATE, DEFER and :
+ ; Y is NFA )
+
+BAD_CSP mDOCOL
+ .word XSQUOTE
+ .byte 15,"stack mismatch!"
+FQABORTYES .word QABORTYES
+
+;;Z ?REVEAL -- link last created word in vocabulary if no stack mismatch
+; FORTHWORD "REVEAL"
+QREVEAL CMP PSP,&LAST_CSP ; check actual SP with saved value by :
+ JNZ BAD_CSP ; if stack mismatch
+ MOV &LAST_NFA,Y ;
+ MOV &LAST_THREAD,X ;
+REVEAL MOV @X,-2(Y) ; [LAST_THREAD] --> LFA
+ MOV Y,0(X) ; LAST_NFA --> [LAST_THREAD]
+ mNEXT
+
+
+;C VARIABLE <name> -- define a Forth VARIABLE
+ FORTHWORD "VARIABLE"
+VARIABLE CALL #HEADER ; -- W = DDP = CFA + 2 words
+ MOV #DOVAR,-4(W)
+ JMP REVEAL
+
+;C CONSTANT <name> n -- define a Forth CONSTANT
+ FORTHWORD "CONSTANT"
+CONSTANT CALL #HEADER ; -- W = DDP
+ MOV #DOCON,-4(W) ; compile exec
+ MOV TOS,-2(W) ; compile TOS as constant
+ MOV @PSP+,TOS
+ JMP REVEAL
+
+;C CREATE <name> -- define a CONSTANT with its next address
+; Execution: ( -- a-addr ) ; a-addr is the address of name's data field
+; ; the execution semantics of name may be extended by using DOES>
+ FORTHWORD "CREATE"
+CREATE CALL #HEADER ; -- W = DDP
+ MOV #DOCON,-4(W) ;4 first CELL = DOCON
+ MOV W,-2(W) ;3 second CELL = HERE
+ JMP REVEAL
+
+;C DOES> -- set action for the latest CREATEd definition
+ FORTHWORD "DOES>"
+DOES MOV &LAST_CFA,W ; W = CFA of latest CREATEd word that becomes a master word
+ MOV #DODOES,0(W) ; remplace code of CFA (DOCON) by DODOES
+ MOV IP,2(W) ; remplace parameter of PFA (HERE) by the address after DOES> as execution address
+ MOV @RSP+,IP ; exit of the new created word
+NEXTADR mNEXT
+
+;X DEFER <name> -- ; create a word to be deferred
+ FORTHWORD "DEFER"
+ CALL #HEADER
+ MOV #4030h,-4(W) ;4 first CELL = MOV @PC+,PC = BR...
+ MOV #NEXTADR,-2(W) ;4 second CELL = address of mNEXT below : created word does nothing by default
+ JMP REVEAL
+
+;C [ -- enter interpretative state
+ FORTHWORDIMM "[" ; immediate
+LEFTBRACKET MOV #0,&STATE
+ mNEXT
+
+;C ] -- enter compiling state
+ FORTHWORD "]"
+RIGHTBRACKET MOV #-1,&STATE
+ mNEXT
+
+;C RECURSE -- recurse to current definition (compile current definition)
+ FORTHWORDIMM "RECURSE" ; immediate
+RECURSE MOV &DDP,X ;
+ MOV &LAST_CFA,0(X) ;
+ ADD #2,&DDP ;
+ mNEXT
+
+ .SWITCH DTC
+ .CASE 1
+
+;C : <name> -- begin a colon definition
+ FORTHWORD ":"
+ CALL #HEADER
+ MOV #DOCOL1,-4(W) ; compile CALL rDOCOL
+ SUB #2,&DDP
+
+ .CASE 2
+
+;C : <name> -- begin a colon definition
+ FORTHWORD ":"
+ CALL #HEADER
+ MOV #DOCOL1,-4(W) ; compile PUSH IP 3~
+ MOV #DOCOL2,-2(W) ; compile CALL rEXIT
+
+ .CASE 3 ; inlined DOCOL
+
+;C : <name> -- begin a colon definition
+ FORTHWORD ":"
+ CALL #HEADER
+ MOV #DOCOL1,-4(W) ; compile PUSH IP 3~
+ MOV #DOCOL2,-2(W) ; compile MOV PC,IP 1~
+ MOV #DOCOL3,0(W) ; compile ADD #4,IP 1~
+ MOV #NEXT,+2(W) ; compile MOV @IP+,PC 4~
+ ADD #4,&DDP
+
+ .ENDCASE ; DTC
+
+ MOV #-1,&STATE ; enter compiling state
+SAVE_PSP MOV PSP,&LAST_CSP ; save PSP for check compiling, used by QREVEAL
+ mNEXT
+
+;C ; -- end a colon definition
+ FORTHWORDIMM ";" ; immediate
+SEMICOLON CMP #0,&STATE ; interpret mode : semicolon becomes a comment separator
+ JZ BACKSLASH ; tip: ; it's transparent to the preprocessor, so semicolon comments are kept in file.4th
+ mDOCOL ; compile mode
+ .word lit,EXIT,COMMA
+ .word QREVEAL,LEFTBRACKET,EXIT
+
+;C IMMEDIATE -- make last definition immediate
+ FORTHWORD "IMMEDIATE"
+IMMEDIATE MOV &LAST_NFA,W
+ BIS.B #80h,0(W)
+ mNEXT
+
+;X DEFER! xt CFA_DEFER -- ; store xt to the address after DODEFER
+DEFERSTORE MOV @PSP+,2(TOS) ; -- CFA_DEFER xt --> [CFA_DEFER+2]
+ MOV @PSP+,TOS ; --
+ mNEXT
+
+;X IS <name> xt --
+; used as is :
+; DEFER DISPLAY create a "do nothing" definition (2 CELLS)
+; inline command : ' U. IS DISPLAY U. becomes the runtime of the word DISPLAY
+; or in a definition : ... ['] U. IS DISPLAY ...
+; KEY, EMIT, CR, ACCEPT and WARM are DEFERred words
+
+ FORTHWORDIMM "IS" ; immediate
+IS mDOCOL
+ .word FSTATE,FETCH
+ .word QBRAN,IS_EXEC
+IS_COMPILE .word BRACTICK ; find the word, compile its CFA as literal
+ .word lit,DEFERSTORE,COMMA ; compile DEFERSTORE
+ .word EXIT
+IS_EXEC .word TICK,DEFERSTORE ; find the word, leave its CFA on the stack and execute DEFERSTORE
+ .word EXIT
+
+;C ['] <name> -- find word & compile it as literal
+ FORTHWORDIMM "[']" ; immediate word, i.e. word executed also during compilation
+BRACTICK mDOCOL
+ .word TICK ; get xt of <name>
+ .word lit,lit,COMMA ; append LIT action
+ .word COMMA,EXIT ; append xt literal
+
+ FORTHWORDIMM "POSTPONE" ; immediate
+POSTPONE mDOCOL
+ .word FBLANK,WORDD,FIND,QDUP
+ .word QBRAN,NotFound
+ .word ZEROLESS ; immediate ?
+ .word QBRAN,POST1 ; yes
+ .word lit,lit,COMMA,COMMA
+ .word lit,COMMA
+POST1: .word COMMA,EXIT
+
+;; CORE EXT MARKER
+;;( "<spaces>name" -- )
+;;Skip leading space delimiters. Parse name delimited by a space. Create a definition for name
+;;with the execution semantics defined below.
+
+;;name Execution: ( -- )
+;;Restore all dictionary allocation and search order pointers to the state they had just prior to the
+;;definition of name. Remove the definition of name and all subsequent definitions. Restoration
+;;of any structures still existing that could refer to deleted definitions or deallocated data space is
+;;not necessarily provided. No other contextual information such as numeric base is affected
+
+; FORTHWORD "MARKER"
+; CALL #HEADER ;4
+; MOV #DODOES,-4(W) ;4 CFA = DODOES
+; MOV #MARKER_DOES,-2(W) ;4 PFA = MARKER_DOES
+; ADD #4,&DDP ;3
+; MOV &LASTVOC,0(W) ;5 [BODY] = VOCLINK to be restored
+; MOV Y,2(W) ;3 [BODY+2] = NFA
+; SUB #2,2(W) ;4 [BODY+2] = LFA = DP to be restored
+; JMP REVEAL ;2
+
+MARKER_DOES
+ .IFDEF VOCABULARY_SET
+ .word FORTH,ONLY,DEFINITIONS
+ .ENDIF
+ FORTHtoASM ; -- BODY IP is free
+ MOV @TOS+,W ; -- BODY+2 W= old VOCLINK =VLK
+ MOV W,&LASTVOC ; -- BODY+2 restore LASTVOC
+ MOV @TOS,TOS ; -- OLD_DP
+ MOV TOS,&DDP ; -- OLD_DP restore DP
+
+ .SWITCH THREADS
+
+ .CASE 1
+MARKALLVOC MOV W,Y ; -- OLD_DP W=VLK Y=VLK
+MRKWORDLOOP MOV -2(Y),Y ; -- OLD_DP W=VLK Y=NFA
+ CMP Y,TOS ; -- OLD_DP CMP = TOS-Y : OLD_DP-NFA
+ JNC MRKWORDLOOP ; loop back if TOS<Y : OLD_DP<NFA
+ MOV Y,-2(W) ; W=VLK X=THD Y=NFA refresh thread with good NFA
+ MOV @W,W ; -- OLD_DP W=[VLK] = next voclink
+ CMP #0,W ; -- OLD_DP W=[VLK] = next voclink end of vocs ?
+ JNZ MARKALLVOC ; -- OLD_DP W=VLK no : loopback
+
+ .ELSECASE ; multi threads
+
+MARKALLVOC MOV #THREADS,IP ; -- OLD_DP W=VLK
+ MOV W,X ; -- OLD_DP W=VLK X=VLK
+MRKTHRDLOOP MOV X,Y ; -- OLD_DP W=VLK X=VLK Y=VLK
+ SUB #2,X ; -- OLD_DP W=VLK X=THD (thread ((case-2)to0))
+MRKWORDLOOP MOV -2(Y),Y ; -- OLD_DP W=VLK Y=NFA
+ CMP Y,TOS ; -- OLD_DP CMP = TOS-Y : OLD_DP-NFA
+ JNC MRKWORDLOOP ; loop back if TOS<Y : OLD_DP<NFA
+MARKTHREAD MOV Y,0(X) ; W=VLK X=THD Y=NFA refresh thread with good NFA
+ SUB #1,IP ; -- OLD_DP W=VLK X=THD Y=NFA IP=CFT-1
+ JNZ MRKTHRDLOOP ; loopback to compare NFA in next thread (thread-1)
+ MOV @W,W ; -- OLD_DP W=[VLK] = next voclink
+ CMP #0,W ; -- OLD_DP W=[VLK] = next voclink end of vocs ?
+ JNZ MARKALLVOC ; -- OLD_DP W=VLK no : loopback
+
+ .ENDCASE ; THREADS ; -- HERE
+
+ MOV @PSP+,TOS ;
+ MOV @RSP+,IP ;
+ mNEXT ;
+; ----------------------------------;
+
+; ----------------------------------------------------------------------
+; CONTROL STRUCTURES
+; ----------------------------------------------------------------------
+; THEN and BEGIN compile nothing
+; DO compile one word
+; IF, ELSE, AGAIN, UNTIL, WHILE, REPEAT, LOOP & +LOOP compile two words
+; LEAVE compile three words
+
+;C IF -- IFadr initialize conditional forward branch
+ FORTHWORDIMM "IF" ; immediate
+IFF SUB #2,PSP ;
+ MOV TOS,0(PSP) ;
+ MOV &DDP,TOS ; -- HERE
+ MOV #QBRAN,0(TOS) ; -- HERE
+ ADD #4,&DDP ; compile two words
+CELLPLUS ADD #2,TOS ; -- HERE+2=IFadr
+ mNEXT
+
+;C ELSE IFadr -- ELSEadr resolve forward IF branch, leave ELSEadr on stack
+ FORTHWORDIMM "ELSE" ; immediate
+ELSS MOV &DDP,W
+ MOV #bran,0(W)
+ ADD #4,W ; W=HERE+4
+ MOV W,&DDP ; compile two words
+ MOV W,0(TOS) ; HERE+4 ==> [IFadr]
+ SUB #2,W ; HERE+2
+ MOV W,TOS ; -- ELSEadr
+ mNEXT
+
+;C THEN IFadr -- resolve forward branch
+ FORTHWORDIMM "THEN" ; immediate
+THEN MOV &DDP,0(TOS) ; -- IFadr
+ MOV @PSP+,TOS ; --
+ mNEXT
+
+;C BEGIN -- BEGINadr initialize backward branch
+ FORTHWORDIMM "BEGIN" ; immediate
+BEGIN MOV #HERE,PC ; BR HERE
+
+;C UNTIL BEGINadr -- resolve conditional backward branch
+ FORTHWORDIMM "UNTIL" ; immediate
+UNTIL MOV #qbran,X
+UNTIL1 MOV &DDP,W ; W = HERE
+ ADD #4,&DDP ; compile two words
+ MOV X,0(W) ; compile Bran or qbran at HERE
+ MOV TOS,2(W) ; compile bakcward adr at HERE+2
+ MOV @PSP+,TOS
+ mNEXT
+
+;X AGAIN BEGINadr -- resolve uncondionnal backward branch
+ FORTHWORDIMM "AGAIN" ; immediate
+AGAIN MOV #bran,X
+ JMP UNTIL1
+
+;C WHILE BEGINadr -- WHILEadr BEGINadr
+ FORTHWORDIMM "WHILE" ; immediate
+WHILE mDOCOL
+ .word IFF,SWAP,EXIT
+
+;C REPEAT WHILEadr BEGINadr -- resolve WHILE loop
+ FORTHWORDIMM "REPEAT" ; immediate
+REPEAT mDOCOL
+ .word AGAIN,THEN,EXIT
+
+;C DO -- DOadr L: -- 0
+ FORTHWORDIMM "DO" ; immediate
+DO SUB #2,PSP ;
+ MOV TOS,0(PSP) ;
+ MOV &DDP,TOS ; -- HERE
+ MOV #xdo,0(TOS)
+ ADD #2,TOS ; -- HERE+2
+ MOV TOS,&DDP ; compile one word
+ ADD #2,&LEAVEPTR ; -- HERE+2 LEAVEPTR+2
+ MOV &LEAVEPTR,W ;
+ MOV #0,0(W) ; -- HERE+2 L-- 0
+ mNEXT
+
+;C LOOP DOadr -- L-- 0 a1 a2 .. aN
+ FORTHWORDIMM "LOOP" ; immediate
+LOO MOV #xloop,X
+ENDLOOP MOV &DDP,W
+ ADD #4,&DDP ; compile two words
+ MOV X,0(W) ; xloop --> HERE
+ MOV TOS,2(W) ; DOadr --> HERE+2
+; resolve all "leave" adr
+LEAVELOOP MOV &LEAVEPTR,TOS ; -- Adr of first LeaveStack cell
+ SUB #2,&LEAVEPTR ; --
+ MOV @TOS,TOS ; -- first LeaveStack value
+ CMP #0,TOS ; -- = value left by DO ?
+ JZ ENDLOOPEND
+ MOV &DDP,0(TOS) ; move adr after loop as UNLOOP adr
+ JMP LEAVELOOP
+ENDLOOPEND MOV @PSP+,TOS
+ mNEXT
+
+;C +LOOP adrs -- L: 0 a1 a2 .. aN --
+ FORTHWORDIMM "+LOOP" ; immediate
+PLUSLOOP MOV #xploop,X
+ JMP ENDLOOP
+
+;C LEAVE -- L: -- adrs
+ FORTHWORDIMM "LEAVE" ; immediate
+LEAV MOV &DDP,W ; compile three words
+ MOV #UNLOOP,0(W) ; [HERE] = UNLOOP
+ MOV #BRAN,2(W) ; [HERE+2] = BRAN
+ ADD #6,&DDP ; [HERE+4] = take word for AfterLOOPadr
+ ADD #2,&LEAVEPTR
+ ADD #4,W
+ MOV &LEAVEPTR,X
+ MOV W,0(X) ; leave HERE+4 on LEAVEPTR stack
+ mNEXT
+
+;C MOVE addr1 addr2 u -- smart move
+; VERSION FOR 1 ADDRESS UNIT = 1 CHAR
+ FORTHWORD "MOVE"
+MOVE MOV TOS,W ; 1
+ MOV @PSP+,Y ; dest adrs
+ MOV @PSP+,X ; src adrs
+ MOV @PSP+,TOS ; pop new TOS
+ CMP #0,W
+ JZ MOVE_X
+ CMP X,Y ; Y-X ; dst - src
+ JZ MOVE_X ; already made !
+ JC MOVEUP ; U>= if dst > src
+MOVEDOWN: MOV.B @X+,0(Y) ; if X=src > Y=dst copy W bytes down
+ ADD #1,Y
+ SUB #1,W
+ JNZ MOVEDOWN
+ mNEXT
+MOVEUP ADD W,Y ; start at end
+ ADD W,X
+MOVUP1: SUB #1,X
+ SUB #1,Y
+ MOV.B @X,0(Y) ; if X=src < Y=dst copy W bytes up
+ SUB #1,W
+ JNZ MOVUP1
+MOVE_X: mNEXT
+
+
+; ----------------------------------------------------------------------
+; WORDS SET for VOCABULARY, not ANS compliant
+; ----------------------------------------------------------------------
+
+;X VOCABULARY -- create a vocabulary
+
+ .IFDEF VOCABULARY_SET
+
+ FORTHWORD "VOCABULARY"
+VOCABULARY mDOCOL
+ .word CREATE
+ .SWITCH THREADS
+ .CASE 1
+ .word lit,0,COMMA ; will keep the NFA of the last word of the future created vocabularies
+ .ELSECASE ; multithreading add 7 words
+ .word lit,THREADS,lit,0,xdo
+VOCABULOOP .word lit,0,COMMA
+ .word xloop,VOCABULOOP
+ .ENDCASE
+ .word HERE ; link via LASTVOC the future created vocabularies
+ .word LIT,LASTVOC,DUP
+ .word FETCH,COMMA ; compile [LASTVOC] to HERE+
+ .word STORE ; store (HERE - CELL) to LASTVOC
+ .word DOES ; compile CFA and PFA for the future defined vocabulary
+
+ .ENDIF ; VOCABULARY_SET
+
+VOCDOES .word LIT,CONTEXT,STORE
+ .word EXIT
+
+;X FORTH -- ; set FORTH the first context vocabulary; FORTH is and must be the first vocabulary
+ .IFDEF VOCABULARY_SET
+ FORTHWORD "FORTH"
+ .ENDIF ; VOCABULARY_SET
+FORTH mDODOES ; leave FORTH_BODY on the stack and run VOCDOES
+ .word VOCDOES
+FORTH_BODY .word lastforthword
+ .SWITCH THREADS
+ .CASE 2
+ .word lastforthword1
+ .CASE 4
+ .word lastforthword1
+ .word lastforthword2
+ .word lastforthword3
+ .CASE 8
+ .word lastforthword1
+ .word lastforthword2
+ .word lastforthword3
+ .word lastforthword4
+ .word lastforthword5
+ .word lastforthword6
+ .word lastforthword7
+ .CASE 16
+ .word lastforthword1
+ .word lastforthword2
+ .word lastforthword3
+ .word lastforthword4
+ .word lastforthword5
+ .word lastforthword6
+ .word lastforthword7
+ .word lastforthword8
+ .word lastforthword9
+ .word lastforthword10
+ .word lastforthword11
+ .word lastforthword12
+ .word lastforthword13
+ .word lastforthword14
+ .word lastforthword15
+ .CASE 32
+ .word lastforthword1
+ .word lastforthword2
+ .word lastforthword3
+ .word lastforthword4
+ .word lastforthword5
+ .word lastforthword6
+ .word lastforthword7
+ .word lastforthword8
+ .word lastforthword9
+ .word lastforthword10
+ .word lastforthword11
+ .word lastforthword12
+ .word lastforthword13
+ .word lastforthword14
+ .word lastforthword15
+ .word lastforthword16
+ .word lastforthword17
+ .word lastforthword18
+ .word lastforthword19
+ .word lastforthword20
+ .word lastforthword21
+ .word lastforthword22
+ .word lastforthword23
+ .word lastforthword24
+ .word lastforthword25
+ .word lastforthword26
+ .word lastforthword27
+ .word lastforthword28
+ .word lastforthword29
+ .word lastforthword30
+ .word lastforthword31
+
+ .ELSECASE
+ .ENDCASE
+ .word voclink
+voclink .set $-2
+
+;X ALSO -- make room to put a vocabulary as first in context
+ .IFDEF VOCABULARY_SET
+ FORTHWORD "ALSO"
+ .ENDIF ; VOCABULARY_SET
+ALSO MOV #12,W ; -- move up 6 words
+ MOV #CONTEXT,X ; X=src
+ MOV #CONTEXT+2,Y ; Y=dst
+ JMP MOVEUP ; src < dst
+
+;X PREVIOUS -- pop last vocabulary out of context
+ .IFDEF VOCABULARY_SET
+ FORTHWORD "PREVIOUS"
+ .ENDIF ; VOCABULARY_SET
+PREVIOUS MOV #14,W ; -- move down 7 words
+ MOV #CONTEXT+2,X ; X=src
+ MOV #CONTEXT,Y ; Y=dst
+ JMP MOVEDOWN ; src > dst
+
+;X ONLY -- cut context list to access only first vocabulary, ex.: FORTH ONLY
+ .IFDEF VOCABULARY_SET
+ FORTHWORD "ONLY"
+ .ENDIF ; VOCABULARY_SET
+ONLY MOV #0,&CONTEXT+2
+ mNEXT
+
+;X DEFINITIONS -- set last context vocabulary as entry for further defining words
+ .IFDEF VOCABULARY_SET
+ FORTHWORD "DEFINITIONS"
+ .ENDIF ; VOCABULARY_SET
+DEFINITIONS MOV &CONTEXT,&CURRENT
+ mNEXT
+
+; ----------------------------------------------------------------------
+; IMPROVED POWER ON RESET AND INITIALIZATION
+; ----------------------------------------------------------------------
+
+ FORTHWORD "PWR_STATE" ; set dictionary in same state as OFF/ON
+PWR_STATE mDODOES ; DOES part of MARKER : resets pointers DP, voclink and latest
+ .word MARKER_DOES ; execution vector of MARKER DOES
+MARKVOC .word lastvoclink ; as voclink value
+MARKDP .word ROMDICT ; as DP value
+
+ FORTHWORD "PWR_HERE" ; define dictionary bound for PWR_STATE
+PWR_HERE MOV &DDP,&MARKDP
+ MOV &LASTVOC,&MARKVOC
+ JMP PWR_STATE
+
+ FORTHWORD "RST_STATE" ; set dictionary in same state as <reset>
+RST_STATE MOV &INIDP,&MARKDP
+ MOV &INIVOC,&MARKVOC
+ JMP PWR_STATE
+
+ FORTHWORD "RST_HERE" ; define dictionary bound for RST_STATE
+RST_HERE MOV &DDP,&INIDP
+ MOV &LASTVOC,&INIVOC
+ JMP PWR_HERE ; and reset PWR_STATE same as RST_STATE
+
+
+WIPE_DEFER MOV #PARENWARM,&WARM+2
+QAB_DEFER MOV #PARENEMIT,&EMIT+2 ; always restore default console output
+ MOV #PARENCR,&CR+2 ; and CR to CR EMIT
+ MOV #PARENKEY,&KEY+2
+ .IFDEF SD_CARD_LOADER
+ MOV #PARENACCEPT,&ACCEPT+2 ; always restore default console input
+ .ENDIF
+ RET
+
+ FORTHWORD "WIPE" ; restore the program as it was in FastForth.hex file
+WIPE
+; reset JTAG and BSL signatures ; unlock JTAG, SBW and BSL
+ MOV #SIGNATURES,X
+SIGNLOOP MOV #-1,0(X) ; reset signature; WARNING ! DON'T CHANGE THIS IMMEDIATE VALUE !
+ ADD #2,X
+ CMP #INTVECT,X
+ JNZ SIGNLOOP
+
+; reset all FACTORY defered words to allow execution from SD_Card
+ CALL #WIPE_DEFER
+; reinit this factory values :
+ MOV #ROMDICT,&DDP
+ MOV #lastvoclink,&LASTVOC
+; then reinit RST_STATE and PWR_STATE
+ JMP RST_HERE
+
+
+; define FREQ used in WARM message (6)
+ .IF FREQUENCY = 0.5
+FREQ .set " .5MHz"
+ .ELSEIF FREQUENCY = 1
+FREQ .set " 1MHz"
+ .ELSEIF FREQUENCY = 2
+FREQ .set " 2MHz"
+ .ELSEIF FREQUENCY = 4
+FREQ .set " 4MHz"
+ .ELSEIF FREQUENCY = 8
+FREQ .set " 8MHz"
+ .ELSEIF FREQUENCY = 16
+FREQ .set " 16MHz"
+ .ELSEIF FREQUENCY = 24
+FREQ .set " 24MHz"
+ .ENDIF
+
+;Z (WARM) -- ; init some user variables,
+ ; print start message if ECHO is set,
+ ; then ABORT
+ FORTHWORD "(WARM)"
+PARENWARM
+ MOV &SAVE_SYSRSTIV,TOS ; to display it
+ mDOCOL
+ .word XSQUOTE ;
+ .byte 5,13,1Bh,"[7m" ; CR + cmd "reverse video"
+ .word TYPE ;
+ .word DOT ; display signed SAVE_SYSRSTIV
+ .word XSQUOTE
+ .byte 39," FastForth V160",FREQ," (C) J.M.Thoorens "
+ .word TYPE
+ .word LIT,FRAM_FULL,HERE,MINUS,UDOT
+ .word XSQUOTE ;
+ .byte 11,"bytes free ";
+ .word QABORTYESNOECHO ; NOECHO enables any app to execute COLD without terminal connexion !
+
+
+;Z WARM -- ; deferred word used to init your application
+ ; define this word: : START ...init app here... LIT RECURSE IS WARM (WARM) ;
+ FORTHWORD "WARM"
+WARM MOV #PARENWARM,PC
+
+;Z COLD -- performs a software reset
+ FORTHWORD "COLD"
+COLD MOV #0A500h+PMMSWBOR,&PMMCTL0
+
+; -------------------------------------------------------------------------
+; in addition to <reset>, DEEP_RST restores the program as it was in the FastForth.hex file and the electronic fuse so.
+; -------------------------------------------------------------------------
+RESET
+; -------------------------------------------------------------------------
+; case 1 : Power ON ==> RESET + the volatile program beyond PWR_HERE (not protected by PWR_STATE against POWER OFF) is lost
+; SYSRSTIV = 2
+
+; case 2 : <reset> ==> RESET + the program beyond RST_HERE (not protected by RST_STATE against reset) is lost
+; SYSRSTIV = 4
+; case 2.1 : software <reset> is performed by COLD.
+; SYSRSTIV = 6
+
+; case 3 : TERM_TX wired to GND via 4k7 + <reset> ===> DEEP_RST, works even if the electronic fuse is "blown" !
+; case 3.1 : (SYSRSTIV = 0Ah | SYSRSTIV >= 16h) ===> DEEP_RST on failure,
+; case 3.2 : writing -1 in SAVE_SYSRSTIV then COLD ===> software DEEP_RST (WARM displays "-1")
+; -------------------------------------------------------------------------
+
+; ------------------------------------------------------------------
+; RESET : Target Init, limited to FORTH usage : I/O, FRAM, RTC
+; ------------------------------------------------------------------
+
+ .include "TargetInit.asm" ; include for each target the init code
+
+; reset all interrupt vectors to RESET vector
+ MOV #RESET,W ; W = reset vector
+ MOV #INTVECT,X ; interrupt vectors base address
+RESETINT: MOV W,0(X)
+ ADD #2,X
+ JNZ RESETINT ; endloop when X = 0
+
+; reset default TERMINAL vector interrupt and LPM0 mode for terminal use
+ MOV &INI_TERM,&TERMVEC
+ MOV #CPUOFF+GIE,&LPM_MODE
+
+; -----------------------------------------------------------
+; RESET : INIT FORTH machine
+; -----------------------------------------------------------
+ MOV #RSTACK,SP ; init return stack
+ MOV #PSTACK,PSP ; init parameter stack
+ .SWITCH DTC
+ .CASE 1
+ MOV #xdocol,rDOCOL
+ .CASE 2
+ MOV #EXIT,rEXIT
+ .CASE 3 ; inlined DOCOL, do nothing here
+ .ENDCASE
+ MOV #RFROM,rDOVAR
+ MOV #xdocon,rDOCON
+ MOV #xdodoes,rDODOES
+
+ MOV #10,&BASE
+ MOV #-1,&CAPS
+
+; -----------------------------------------------------------
+; RESET : test TERM_TXD/Deep_RST before init TERM_UART I/O
+; -----------------------------------------------------------
+ BIC #LOCKLPM5,&PM5CTL0 ; activate all previous I/O settings before DEEP_RST test
+ MOV &SAVE_SYSRSTIV,Y ;
+ BIT.B #DEEP_RST,&Deep_RST_IN ; TERM TXD wired to GND via 4k7 resistor ?
+ JNZ TERM_INIT ; no
+ XOR #-1,Y ; yes : force DEEP_RST
+ ADD #1,Y ; to display SAVE_SYSRSTIV as negative value
+ MOV Y,&SAVE_SYSRSTIV
+
+; ----------------------------------------------------------------------
+; RESET : INIT TERM_UART
+; ----------------------------------------------------------------------
+TERM_INIT
+
+ MOV #0081h,&TERMCTLW0 ; Configure TERM_UART UCLK = SMCLK
+
+ .include "TERMINALBAUDRATE.asm" ; include code to configure baudrate
+
+ BIS.B #TERM_TXRX,&TERM_SEL ; Configure pins TXD & RXD for TERM_UART (PORTx_SEL0 xor PORTx_SEL1)
+ ; TERM_DIR is controlled by eUSCI_Ax module
+ BIC #UCSWRST,&TERMCTLW0 ; release from reset...
+ BIS #UCRXIE,&TERMIE ; ... then enable RX interrupt for wake up on terminal input
+
+; -----------------------------------------------------------
+; RESET : Select POWER_ON|<reset>|DEEP_RST
+; -----------------------------------------------------------
+
+SelectReset MOV #COLD_END,IP ; define return of WIPE,RST_STATE,PWR_STATE
+ MOV &SAVE_SYSRSTIV,Y;
+ CMP #0Ah,Y ; reset event = security violation BOR ???? not documented...
+ JZ WIPE ; Add WIPE to this reset to do DEEP_RST --------------
+ CMP #16h,Y ; reset event > software POR : failure or DEEP_RST request
+ JHS WIPE ; U>= ; Add WIPE to this reset to do DEEP_RST
+ CMP #2,Y ; reset event = Brownout ?
+ JNZ RST_STATE ; else execute RST_STATE
+ JZ PWR_STATE ; yes execute PWR_STATE
+
+; ----------------------------------------------------------------------
+; RESET : INIT SD_Card optionally
+; ----------------------------------------------------------------------
+COLD_END
+ .IFNDEF SD_CARD_LOADER ;
+ .word WARM ; the next step
+ .ELSE
+ FORTHtoASM
+ BIT.B #SD_CD,&SD_CDIN ; SD_memory in SD_Card module ?
+ JNZ WARM ; no
+ .include "forthMSP430FR_SD_INIT.asm";
+ JMP WARM
+ .ENDIF
+
+; ----------------------------------------------------------------------
+; ASSEMBLER OPTION
+; ----------------------------------------------------------------------
+ .IFDEF MSP430ASSEMBLER
+ .include "forthMSP430FR_ASM.asm"
+ .ENDIF
+
+; ----------------------------------------------------------------------
+; SD CARD FAT OPTIONS
+; ----------------------------------------------------------------------
+ .IFDEF SD_CARD_LOADER
+ .include "forthMSP430FR_SD_LowLvl.asm" ; SD primitives
+ .include "forthMSP430FR_SD_LOAD.asm" ; SD LOAD fonctions
+ .IFDEF SD_CARD_READ_WRITE
+ .include "forthMSP430FR_SD_RW.asm" ; SD Read/Write fonctions
+ .ENDIF
+ .ENDIF ; SD_CARD_LOADER
+
+; ----------------------------------------------------------------------
+; UTILITY WORDS OPTION
+; ----------------------------------------------------------------------
+ .IFDEF UTILITY
+ .include "ADDON\UTILITY.asm"
+ .ENDIF ; UTILITY
+
+;-----------------------------------------------------------------------
+; SD TOOLS
+;-----------------------------------------------------------------------
+ .IFDEF SD_TOOLS
+
+ .IFNDEF UTILITY
+ .include "ADDON\UTILITY.asm"
+ .ENDIF
+
+ .include "ADDON\SD_TOOLS.asm"
+ .ENDIF ; SD_READ_WRITE_TOOLS
+
+; -----------------------------------------------------------
+; IT'S FINISH : RESOLVE ASSEMBLY PTR
+; -----------------------------------------------------------
+ROMDICT ; init DDP
+lastvoclink .equ voclink
+lastforthword .equ forthlink
+lastasmword .equ asmlink
+
+ .IF THREADS <> 1
+
+lastforthword1 .equ forthlink1
+lastforthword2 .equ forthlink2
+lastforthword3 .equ forthlink3
+lastforthword4 .equ forthlink4
+lastforthword5 .equ forthlink5
+lastforthword6 .equ forthlink6
+lastforthword7 .equ forthlink7
+lastforthword8 .equ forthlink8
+lastforthword9 .equ forthlink9
+lastforthword10 .equ forthlink10
+lastforthword11 .equ forthlink11
+lastforthword12 .equ forthlink12
+lastforthword13 .equ forthlink13
+lastforthword14 .equ forthlink14
+lastforthword15 .equ forthlink15
+lastforthword16 .equ forthlink16
+lastforthword17 .equ forthlink17
+lastforthword18 .equ forthlink18
+lastforthword19 .equ forthlink19
+lastforthword20 .equ forthlink20
+lastforthword21 .equ forthlink21
+lastforthword22 .equ forthlink22
+lastforthword23 .equ forthlink23
+lastforthword24 .equ forthlink24
+lastforthword25 .equ forthlink25
+lastforthword26 .equ forthlink26
+lastforthword27 .equ forthlink27
+lastforthword28 .equ forthlink28
+lastforthword29 .equ forthlink29
+lastforthword30 .equ forthlink30
+lastforthword31 .equ forthlink31
+
+lastasmword1 .equ asmlink1
+lastasmword2 .equ asmlink2
+lastasmword3 .equ asmlink3
+lastasmword4 .equ asmlink4
+lastasmword5 .equ asmlink5
+lastasmword6 .equ asmlink6
+lastasmword7 .equ asmlink7
+lastasmword8 .equ asmlink8
+lastasmword9 .equ asmlink9
+lastasmword10 .equ asmlink10
+lastasmword11 .equ asmlink11
+lastasmword12 .equ asmlink12
+lastasmword13 .equ asmlink13
+lastasmword14 .equ asmlink14
+lastasmword15 .equ asmlink15
+lastasmword16 .equ asmlink16
+lastasmword17 .equ asmlink17
+lastasmword18 .equ asmlink18
+lastasmword19 .equ asmlink19
+lastasmword20 .equ asmlink20
+lastasmword21 .equ asmlink21
+lastasmword22 .equ asmlink22
+lastasmword23 .equ asmlink23
+lastasmword24 .equ asmlink24
+lastasmword25 .equ asmlink25
+lastasmword26 .equ asmlink26
+lastasmword27 .equ asmlink27
+lastasmword28 .equ asmlink28
+lastasmword29 .equ asmlink29
+lastasmword30 .equ asmlink30
+lastasmword31 .equ asmlink31
+
+ .ENDIF
--- /dev/null
+; -*- coding: utf-8 -*-
+; http://patorjk.com/software/taag/#p=display&f=Banner&t=Fast Forth
+
+; Fast Forth For Texas Instrument MSP430FRxxxx FRAM devices
+; Copyright (C) <2017> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+; ----------------------------------------------------------------------
+;forthMSP430FR_asm.asm
+; ----------------------------------------------------------------------
+
+; ----------------------------------------------------------------------
+; MOV(.B) #0, dst is coded as follow : MOV(.B) R3, dst ; 1 cycle, one word As=00 register mode
+; MOV(.B) #1, dst is coded as follow : MOV(.B) 0(R3), dst ; 2 cycles, one word AS=01 x(reg) mode
+; MOV(.B) #2, dst is coded as follow : MOV(.B) @R3, dst ; 2 cycles, one word AS=10 @reg mode
+; MOV(.B) #4, dst is coded as follow : MOV(.B) @R2, dst ; 2 cycles, one word AS=10 @reg mode
+; MOV(.B) #8, dst is coded as follow : MOV(.B) @R2+, dst ; 2 cycles, one word AS=11 @reg+ mode
+; MOV(.B) #-1,dst is coded as follow : MOV(.B) @R3+, dst ; 2 cycles, one word AS=11
+; MOV(.B) #xxxx,dst is coded a follow : MOV(.B) @PC+, dst ; 2 cycles, two words AS=11 @reg+ mode
+; MOV(.B) &EDE,&TON is coded as follow: MOV(.B) EDE(R2),TON(R2) ; (R2=0), three words AS=01, AD=1 x(reg) mode
+; ----------------------------------------------------------------------
+
+; PUSHM order : R15,R14,R13,R12,R11,R10, R9, R8, R7, R6, R5, R4 (TI's reg)
+; or : PSP,TOS, IP, S, T, W, X, Y, R7, R6, R5, R4 (FastForth reg)
+; example : PUSHM IP,Y or PUSHM R13,R8
+
+; POPM order : R4, R5, R6, R7, R8, R9,R10,R11,R12,R13,R14,R15 (TI's reg)
+; or : R4, R5, R6, R7, Y, X, W, T, S, IP,TOS,PSP (FastForth reg)
+; example : POPM Y,IP or POPM R8,R13
+
+; ----------------------------------------------------------------------
+; DTCforthMSP430FR5xxx ASSEMBLER : STRUCTURE
+; ----------------------------------------------------------------------
+
+;X ASSEMBLER -- ; set ASSEMBLER the first context vocabulary
+ .IFDEF VOCABULARY_SET
+ FORTHWORD "ASSEMBLER"
+ .ENDIF ; VOCABULARY_SET
+ASSEMBLER mDODOES ; leave ASSEMBLER_BODY on the stack and run VOCDOES
+ .word VOCDOES
+ASSEMBLER_BODY .word lastasmword ; here is the structure created by VOCABULARY
+ .SWITCH THREADS
+ .CASE 2
+ .word lastasmword1
+ .CASE 4
+ .word lastasmword1
+ .word lastasmword2
+ .word lastasmword3
+ .CASE 8
+ .word lastasmword1
+ .word lastasmword2
+ .word lastasmword3
+ .word lastasmword4
+ .word lastasmword5
+ .word lastasmword6
+ .word lastasmword7
+ .CASE 16
+ .word lastasmword1
+ .word lastasmword2
+ .word lastasmword3
+ .word lastasmword4
+ .word lastasmword5
+ .word lastasmword6
+ .word lastasmword7
+ .word lastasmword8
+ .word lastasmword9
+ .word lastasmword10
+ .word lastasmword11
+ .word lastasmword12
+ .word lastasmword13
+ .word lastasmword14
+ .word lastasmword15
+ .CASE 32
+ .word lastasmword1
+ .word lastasmword2
+ .word lastasmword3
+ .word lastasmword4
+ .word lastasmword5
+ .word lastasmword6
+ .word lastasmword7
+ .word lastasmword8
+ .word lastasmword9
+ .word lastasmword10
+ .word lastasmword11
+ .word lastasmword12
+ .word lastasmword13
+ .word lastasmword14
+ .word lastasmword15
+ .word lastasmword16
+ .word lastasmword17
+ .word lastasmword18
+ .word lastasmword19
+ .word lastasmword20
+ .word lastasmword21
+ .word lastasmword22
+ .word lastasmword23
+ .word lastasmword24
+ .word lastasmword25
+ .word lastasmword26
+ .word lastasmword27
+ .word lastasmword28
+ .word lastasmword29
+ .word lastasmword30
+ .word lastasmword31
+ .ELSECASE
+ .ENDCASE
+ .word voclink
+voclink .set $-2
+
+ FORTHWORDIMM "HI2LO" ; immediate, switch to low level, add ASSEMBLER context, set interpretation state
+ mDOCOL
+ .word HERE,CELLPLUS,COMMA
+ .word LEFTBRACKET
+HI2LONEXT .word ALSO,ASSEMBLER
+ .word EXIT
+
+ FORTHWORD "CODE" ;
+ASMCODE CALL #HEADER ; same as ":" ...
+ SUB #4,&DDP ; ...but compile nothing
+ mDOCOL
+ .word SAVE_PSP
+ .word BRAN,HI2LONEXT
+
+
+ FORTHWORD "ASM" ; used to define an assembler word which is not executable by FORTH interpreter
+ ; i.e. typically an assembler word called by CALL and ended by RET
+ ; ASM word is only accessible in ASSEMBLER CONTEXT
+ MOV &CURRENT,&ASM_CURRENT
+ MOV #ASSEMBLER_BODY,&CURRENT
+ JMP ASMCODE
+
+ asmword "ENDCODE" ; restore previous context and test PSP balancing
+ENDCODE mDOCOL
+ .word PREVIOUS,QREVEAL
+ .word EXIT
+
+ asmword "ENDASM" ; end of ASM word
+ MOV &ASM_CURRENT,&CURRENT
+ JMP ENDCODE
+
+
+ asmword "COLON" ; compile DOCOL, remove ASSEMBLER from CONTEXT, switch to compilation state
+ MOV &DDP,W
+
+ .SWITCH DTC
+ .CASE 1
+ MOV #DOCOL1,0(W) ; compile CALL xDOCOL
+ ADD #2,&DDP
+
+ .CASE 2
+ MOV #DOCOL1,0(W) ; compile PUSH IP
+COLON1 MOV #DOCOL2,2(W) ; compile CALL rEXIT
+ ADD #4,&DDP
+
+ .CASE 3 ; inlined DOCOL
+ MOV #DOCOL1,0(W) ; compile PUSH IP
+COLON1 MOV #DOCOL2,2(W) ; compile MOV PC,IP
+ MOV #DOCOL3,4(W) ; compile ADD #4,IP
+ MOV #NEXT,6(W) ; compile MOV @IP+,PC
+ ADD #8,&DDP ;
+ .ENDCASE ; DTC
+
+COLON2 MOV #-1,&STATE ; enter in compile state
+ MOV #PREVIOUS,PC ; restore previous state of CONTEXT
+
+
+ asmword "LO2HI" ; same as COLON but without saving IP
+ .SWITCH DTC
+ .CASE 1 ; compile 2 words
+ MOV &DDP,W
+ MOV #12B0h,0(W) ; compile CALL #EXIT, 2 words 4+6=10~
+ MOV #EXIT,2(W)
+ ADD #4,&DDP
+ JMP COLON2
+ .ELSECASE ; CASE 2 : compile 1 word, CASE 3 : compile 3 words
+ SUB #2,&DDP ; to skip PUSH IP
+ MOV &DDP,W
+ JMP COLON1
+ .ENDCASE
+
+;;Z SKIP char -- addr ; skip all occurring character 'char' in input stream
+; FORTHWORD "SKIP" ; used by assembler to parse input stream
+SKIP: MOV #SOURCE_LEN,Y ;
+ MOV @Y+,X ; -- char X=length
+ MOV @Y,W ; -- char X=length W=org
+ ADD W,X ; -- char X=End W=org
+ ADD &TOIN,W ; -- char X=End W=ptr
+SKIPLOOP: CMP W,X ; -- char ptr=End ?
+ JZ SKIPEND ; -- char yes
+ CMP.B @W+,TOS ; -- char does character match?
+ JZ SKIPLOOP ; -- char yes
+SKIPNEXT: SUB #1,W ; -- char
+SKIPEND: MOV W,TOS ; -- addr
+ SUB @Y,W ; -- addr W=Ptr-Org=Toin
+ MOV W,&TOIN ;
+ mNEXT
+
+; ----------------------------------------------------------------------
+; DTCforthMSP430FR5xxx ASSEMBLER : search argument "xxxx", IP is free
+; ----------------------------------------------------------------------
+
+; Search ARG of "#xxxx"<sep> ; <== PARAM10
+; Search ARG of "&xxxx"<sep> ; <== PARAM111
+; Search ARG of "xxxx(REG)"<sep> ; <== PARAM130
+; Search ARG of <sep>"xxxx(REG)" ; <== PARAM210
+SearchARG ASMtoFORTH ; -- separator search word first
+ .word WORDD,FIND ; -- c-addr
+ .word ZEROEQUAL
+ .word QBRAN,SearchARGW ; -- c-addr if found
+ .word QNUMBER ;
+ .word QBRAN,NotFound ; -- c-addr
+ .word AsmSrchEnd ; -- value end if number found
+SearchARGW FORTHtoASM ; -- xt
+ MOV @TOS,X
+QDOVAR CMP #DOVAR,X
+ JNZ QDOCON
+ ADD #2,TOS ; remplace CFA by PFA for VARIABLE words
+ MOV @RSP+,PC ; ret
+QDOCON CMP #DOCON,X
+ JNZ QDODOES
+ MOV 2(TOS),TOS ; remplace CFA by [PFA] for CONSTANT and CREATE words
+ MOV @RSP+,PC ; ret
+QDODOES CMP #DODOES,X
+ JNZ AsmSrchEnd
+ ADD #4,TOS ; leave BODY for DOES words (but don't execute !)
+AsmSrchEnd RET ;
+
+; ----------------------------------------------------------------------
+; DTCforthMSP430FR5xxx ASSEMBLER : search REG
+; ----------------------------------------------------------------------
+
+; STOre ARGument xxxx of "xxxx(REG)"<sep> ; <== PARAM130
+; STOre ARGument xxxx of <sep>"xxxx(REG)" ; <== PARAM210
+StoARGsearchREG
+ MOV &DDP,X
+ ADD #2,&DDP
+ MOV TOS,0(X) ; -- xxxx compile xxxx
+ MOV #')',TOS ; -- ")" prepare separator to search REG of "xxxx(REG)"
+
+; search REG of "xxxx(REG)"<sep> separator = ')' ;
+; search REG of <sep>"xxxx(REG)" separator = ')' ;
+; search REG of "@REG"<sep> separator = <sep>; <== PARAM120
+; search REG of "@REG+"<sep> separator = '+' ; <== PARAM121
+; search REG of "REG"<sep> separator = <sep>; <== PARAM13
+; search REG of <sep>"REG" separator = ' ' ; <== PARAM21
+
+SearchREG PUSH &TOIN ; -- separator save >IN
+ ADD #1,&TOIN ; skip "R"
+ ASMtoFORTH ; search xx of Rxx
+ .word WORDD,QNUMBER ;
+ .word QBRAN,notREG ; -- xxxx if number found
+ FORTHtoASM ; -- c-addr if number not found
+ ADD #2,RSP ; remove >IN
+ CMP #16,TOS ; -- 000R register > 15 ?
+ JHS BOUNDERROR ; yes : abort
+ MOV @RSP+,PC ; -- 000R Z=0 ==> found
+
+notREG FORTHtoASM ; -- c-addr
+ MOV @RSP+,&TOIN ; -- c-addr restore >IN
+ BIS #Z,SR ; Z=1 ==> not found
+ MOV @RSP+,PC ; -- c_addr
+
+; ----------------------------------------------------------------------
+; DTCforthMSP430FR5xxx ASSEMBLER : INTERPRET FIRST OPERAND
+; ----------------------------------------------------------------------
+
+; PARAM1 separator -- ; parse input buffer until separator and compute first operand of opcode
+ ; sep is comma or space.
+
+PARAM1 mDOCOL ; -- sep
+ .word FBLANK,SKIP ; -- sep c-addr
+ FORTHtoASM ; -- sep c-addr
+ MOV #0,&ASMTYPE ; -- sep c-addr reset ASMTYPE
+ MOV &DDP,&OPCODE ; -- sep c-addr HERE --> OPCODE (opcode is preset to its address !)
+ ADD #2,&DDP ; -- sep c-addr cell allot for opcode
+ MOV TOS,W ; -- sep c-addr W=c-addr
+ MOV @PSP+,TOS ; -- sep W=c-addr
+ CMP.B #'#',0(W) ; -- sep W=c-addr
+ JNE PARAM11
+
+; "#" found : case of "#xxxx"<sep>
+PARAM10 ADD #1,&TOIN ; -- sep skip # prefix
+ CALL #SearchARG ; -- xxxx abort if not found
+
+PARAM100 CMP #0,TOS ; -- xxxx = 0 ?
+ JNE PARAM101
+; case of "#0"<sep>
+ MOV #0300h,&ASMTYPE ; -- 0 example : MOV #0,dst <=> MOV R3,dst
+ JMP PARAMENDOF
+
+PARAM101 CMP #1,TOS ; -- xxxx = 1 ?
+ JNE PARAM102
+; case of "#1"<sep>
+ MOV #0310h,&ASMTYPE ; -- 1 example : MOV #1,dst <=> MOV 0(R3),dst
+ JMP PARAMENDOF
+
+PARAM102 CMP #2,TOS ; -- xxxx = 2 ?
+ JNE PARAM104
+; case of "#2"<sep>
+ MOV #0320h,&ASMTYPE ; -- 2 ASMTYPE = 0320h example : MOV #2, <=> MOV @R3,
+ JMP PARAMENDOF
+
+PARAM104 CMP #4,TOS ; -- xxxx = 4 ?
+ JNE PARAM108
+; case of "#4"<sep>
+ MOV #0220h,&ASMTYPE ; -- 4 ASMTYPE = 0220h example : MOV #4, <=> MOV @SR,
+ JMP PARAMENDOF
+
+PARAM108 CMP #8,TOS ; -- xxxx = 8 ?
+ JNE PARAM10M1
+; case of "#8"<sep>
+ MOV #0230h,&ASMTYPE ; -- 8 ASMTYPE = 0230h example : MOV #8, <=> MOV @SR+,
+ JMP PARAMENDOF
+
+PARAM10M1 CMP #-1,TOS ; -- xxxx = -1 ?
+ JNE PARAM1000
+; case of "#-1"<sep>
+ MOV #0330h,&ASMTYPE ; -- -1 ASMTYPE = 0330h example : XOR #-1 <=> XOR @R3+,
+ JMP PARAMENDOF
+
+; case of all others "#xxxx"<sep> ; -- xxxx
+PARAM1000 MOV #0030h,&ASMTYPE ; -- xxxx add immediate code type : @PC+,
+
+; case of "&xxxx"<sep> ; <== PARAM110
+; case of <sep>"&xxxx" ; <== PARAM20
+StoreArg MOV &DDP,X ; -- xxxx
+ ADD #2,&DDP ; cell allot for arg
+StoreTOS MOV TOS,0(X) ; compile arg
+
+; endcase of all "&xxxx" ;
+; endcase of all "#xxxx" ; <== PARAM101,102,104,108,10M1
+; endcase of all "REG"|"@REG"|"@REG+" ; <== PARAM124
+PARAMENDOF MOV @PSP+,TOS ; --
+ MOV @RSP+,IP
+ mNEXT ; --
+; ------------------------------------------
+
+PARAM11 CMP.B #'&',0(W) ; -- sep
+ JNE PARAM12
+
+; case of "&xxxx"<sep> ; -- sep search for "&xxxx,"
+PARAM110 MOV #0210h,&ASMTYPE ; -- sep set code type : xxxx(SR) with AS=0b01 ==> x210h (and SR=0 !)
+
+; case of "&xxxx"<sep>
+; case of <sep>"&xxxx" ; <== PARAM20
+PARAM111 ADD #1,&TOIN ; -- sep skip "&" prefix
+ PUSH #StoreArg ; prepare next ret : compile xxxx then ret
+ JMP SearchARG ; -- sep abort if not found
+; ------------------------------------------
+
+PARAM12 CMP.B #'@',0(W) ; -- sep
+ JNE PARAM13
+
+; case of "@REG"<sep>|"@REG+"<sep>
+PARAM120 MOV #0020h,&ASMTYPE ; -- sep init ASMTYPE with indirect code type : AS=0b10
+ ADD #1,&TOIN ; -- sep skip "@" prefix
+ CALL #SearchREG ; Z = not found
+ JNZ PARAM123 ; -- value REG of "@REG," found
+
+; case of "@REG+"<sep> ; -- c-addr "@REG"<sep> not found, search REG of "@REG+"
+PARAM121 ADD #0010h,&ASMTYPE ; change ASMTYPE from @REG to @REG+ type
+ MOV #'+',TOS ; -- "+" as WORD separator to find REG of "@REG+,"
+ CALL #SearchREG ; -- value|c-addr X = flag
+
+; case of "REG" of "@REG+"<sep>
+; case of "REG" of "xxxx(REG)"<sep> ; <== PARAM130
+PARAM122 JZ REGnotFound ; -- c-addr
+ CMP &SOURCE_LEN,&TOIN ; test OPCODE II parameter ending by REG+ or (REG) without comma,
+ JZ PARAM123 ; i.e. >IN = SOURCE_LEN : don't skip char CR !
+ ADD #1,&TOIN ; -- 000R skip "," ready for the second operand search
+
+; case of "REG" of "@REG+"<sep>
+; case of "REG" of "xxxx(REG)"<sep>
+; case of "REG" of "@REG"<sep> ; <== PARAM120
+; case of "REG" of "REG"<sep> ; <== PARAM13
+PARAM123 SWPB TOS ; 000R -- 0R00 swap bytes because it's not a dst REG typeI (not a 2 ops inst.)
+
+; case of "REG" of "@REG+"<sep> ; -- 0R00 (src REG typeI)
+; case of "REG" of "xxxx(REG)"<sep> ; -- 0R00 (src REG typeI or dst REG typeII)
+; case of "REG" of "@REG"<sep> ; -- 0R00 (src REG typeI)
+; case of "REG" of "REG"<sep> ; -- 0R00 (src REG typeI or dst REG typeII)
+; case of "REG" of <sep>"REG" ; -- 000R <== PARAM21 (dst REG typeI)
+; case of "REG" of <sep>"xxxx(REG)" ; -- 000R <== PARAM210 (dst REG typeI)
+PARAM124 ADD TOS,&ASMTYPE ; -- 0R00|000R
+ JMP PARAMENDOF
+; ------------------------------------------
+
+; case of "REG"<sep>|"xxxx(REG)"<sep> ; first, searg REG of "REG,"
+PARAM13 CALL #SearchREG ; -- sep save >IN for second parsing (case of "xxxx(REG),")
+ JNZ PARAM123 ; -- 000R REG of "REG," found, ASMTYPE=0
+
+; case of "xxxx(REG)"<sep> ; -- c-addr "REG," not found
+PARAM130 ADD #0010h,&ASMTYPE ; AS=0b01 for indexing address
+ MOV #'(',TOS ; -- "(" as WORD separator to find xxxx of "xxxx(REG),"
+ CALL #SearchARG ; -- xxxx aborted if not found
+ PUSH #PARAM122 ; prepare next ret : REG found or not found
+ JMP StoARGsearchREG ; compile xxxx and search REG of "(REG)"
+
+; ----------------------------------------------------------------------
+; DTCforthMSP430FR5xxx ASSEMBLER : INTERPRET 2th OPERAND
+; ----------------------------------------------------------------------
+
+; PARAM2 -- ; parse input buffer until BL and compute this 2th operand
+
+PARAM2 mDOCOL ;
+ .word FBLANK,SKIP ; skip space(s) between "arg1," and "arg2" if any
+ FORTHtoASM ; -- c-addr search for '&' of "&xxxx
+ CMP.B #'&',0(TOS) ;
+ MOV #20h,TOS ; -- " " as WORD separator to find xxxx of ",&xxxx"
+ JNE PARAM21 ; '&' not found
+
+; case of <sep>"&xxxx" ;
+PARAM20 ADD #0082h,&ASMTYPE ; change ASMTYPE : AD=1, dst = R2
+ JMP PARAM111 ; -- " "
+; ------------------------------------------
+
+; case of <sep>"REG"|<sep>"xxxx(REG) ; -- " " first, search REG of ",REG"
+PARAM21 CALL #SearchREG ;
+ JNZ PARAM124 ; -- 000R REG of ",REG" found
+
+; case of <sep>"xxxx(REG) ; -- c-addr REG not found
+PARAM210 ADD #0080h,&ASMTYPE ; set AD=1
+ MOV #'(',TOS ; -- "(" as WORD separator to find xxxx of ",xxxx(REG)"
+ CALL #SearchARG ; -- xxxx aborted if not found
+ CALL #StoARGsearchREG ; compile argument xxxx and search REG of "(REG)"
+ JNZ PARAM124 ; -- 000R REG of "(REG) found
+REGnotFound MOV #NotFound,IP ; -- c-addr abort
+ mNEXT
+
+
+; ----------------------------------------------------------------------
+; DTCforthMSP430FR5xxx ASSEMBLER: OPCODES TYPE 0 : zero operand f:-)
+; ----------------------------------------------------------------------
+ asmword "RETI"
+ mDOCOL
+ .word lit,1300h,COMMA,EXIT
+
+; ----------------------------------------------------------------------
+; DTCforthMSP430FR5xxx ASSEMBLER: OPCODES TYPE I : double operand
+; ----------------------------------------------------------------------
+; OPCODE(FEDC)
+; OPCODE(code) for TYPE I = 0bxxxx opcode I
+; OPCODE(BA98)
+; = 0bxxxx src register
+; OPCODE(7) AD (dst addr type)
+; = 0b0 register
+; = 0b1 x(Rn),&adr
+; OPCODE(6) size
+; OPCODE(B) for TYPE I or TYPE II = 0b0 word
+; = 0b1 byte
+; OPCODE(54) AS (src addr type)
+; OPCODE(AS) for TYPE I or OPCODE(AD) for TYPE II = 0b00 register
+; = 0b01 x(Rn),&adr
+; = 0b10 @Rn
+; = 0b11 @Rn+
+; OPCODE(3210)
+; OPCODE(dst) for TYPE I or TYPE II = 0bxxxx dst register
+; ----------------------------------------------------------------------
+
+; TYPE1DOES -- PFADOES search and compute PARAM1 & PARAM2 as src and dst operands then compile instruction
+TYPE1DOES ; -- PFADOES
+ .word lit,',' ; -- PFADOES "," char separator for PARAM1
+ .word PARAM1 ; -- PFADOES
+ .word PARAM2 ; -- PFADOES char separator (BL) included in PARAM2
+ FORTHtoASM ; -- PFADOES
+MAKEOPCODE MOV @TOS,TOS ; -- opcode part of instruction
+ BIS &ASMTYPE,TOS ; -- opcode opcode is complete
+ MOV &OPCODE,X ; -- opcode X= addr to compile opcode
+ JMP StoreTOS ; then EXIT
+
+ asmword "MOV"
+ mDODOES
+ .word TYPE1DOES,4000h
+
+ asmword "MOV.B"
+ mDODOES
+ .word TYPE1DOES,4040h
+
+ asmword "ADD"
+ mDODOES
+ .word TYPE1DOES,5000h
+
+ asmword "ADD.B"
+ mDODOES
+ .word TYPE1DOES,5040h
+
+ asmword "ADDC"
+ mDODOES
+ .word TYPE1DOES,6000h
+
+ asmword "ADDC.B"
+ mDODOES
+ .word TYPE1DOES,6040h
+
+ asmword "SUBC"
+ mDODOES
+ .word TYPE1DOES,7000h
+
+ asmword "SUBC.B"
+ mDODOES
+ .word TYPE1DOES,7040h
+
+ asmword "SUB"
+ mDODOES
+ .word TYPE1DOES,8000h
+
+ asmword "SUB.B"
+ mDODOES
+ .word TYPE1DOES,8040h
+
+ asmword "CMP"
+ mDODOES
+ .word TYPE1DOES,9000h
+
+ asmword "CMP.B"
+ mDODOES
+ .word TYPE1DOES,9040h
+
+ asmword "DADD"
+ mDODOES
+ .word TYPE1DOES,0A000h
+
+ asmword "DADD.B"
+ mDODOES
+ .word TYPE1DOES,0A040h
+
+ asmword "BIT"
+ mDODOES
+ .word TYPE1DOES,0B000h
+
+ asmword "BIT.B"
+ mDODOES
+ .word TYPE1DOES,0B040h
+
+ asmword "BIC"
+ mDODOES
+ .word TYPE1DOES,0C000h
+
+ asmword "BIC.B"
+ mDODOES
+ .word TYPE1DOES,0C040h
+
+ asmword "BIS"
+ mDODOES
+ .word TYPE1DOES,0D000h
+
+ asmword "BIS.B"
+ mDODOES
+ .word TYPE1DOES,0D040h
+
+ asmword "XOR"
+ mDODOES
+ .word TYPE1DOES,0E000h
+
+ asmword "XOR.B"
+ mDODOES
+ .word TYPE1DOES,0E040h
+
+ asmword "AND"
+ mDODOES
+ .word TYPE1DOES,0F000h
+
+ asmword "AND.B"
+ mDODOES
+ .word TYPE1DOES,0F040h
+
+; ----------------------------------------------------------------------
+; DTCforthMSP430FR5xxx ASSEMBLER, OPCODES TYPE II : single operand
+; ----------------------------------------------------------------------
+; OPCODE(FEDCBA987) opcodeII
+; OPCODE(code) for TYPE II = 0bxxxxxxxxx
+; OPCODE(6) size
+; OPCODE(B) for TYPE I or TYPE II = 0b0 word
+; = 0b1 byte
+; OPCODE(54) (dst addr type)
+; OPCODE(AS) for TYPE I or OPCODE(AD) for TYPE II = 0b00 register
+; = 0b01 x(Rn),&adr
+; = 0b10 @Rn
+; = 0b11 @Rn+
+; OPCODE(3210)
+; OPCODE(dst) for TYPE I or TYPE II = 0bxxxx dst register
+; ----------------------------------------------------------------------
+
+; TYPE2DOES -- PFADOES search and compute PARAM1 as dst operand then compile instruction
+TYPE2DOES ; -- PFADOES
+ .word FBLANK ; char separator for PARAM1
+ .word PARAM1
+ FORTHtoASM ; -- PFADOES
+ MOV &ASMTYPE,W ;
+ AND #0070h,&ASMTYPE ; keep B/W & AS infos in ASMTYPE
+ SWPB W ; (REG org --> REG dst)
+ AND #000Fh,W ; keep REG
+BIS_ASMTYPE BIS W,&ASMTYPE ; -- PFADOES add it in ASMTYPE
+ JMP MAKEOPCODE ; -- then end
+
+ asmword "RRC" ; Rotate Right through Carry ( word)
+ mDODOES
+ .word TYPE2DOES,1000h
+
+ asmword "RRC.B" ; Rotate Right through Carry ( byte)
+ mDODOES
+ .word TYPE2DOES,1040h
+
+ asmword "SWPB" ; Swap bytes
+ mDODOES
+ .word TYPE2DOES,1080h
+
+ asmword "RRA"
+ mDODOES
+ .word TYPE2DOES,1100h
+
+ asmword "RRA.B"
+ mDODOES
+ .word TYPE2DOES,1140h
+
+ asmword "SXT"
+ mDODOES
+ .word TYPE2DOES,1180h
+
+ asmword "PUSH"
+ mDODOES
+ .word TYPE2DOES,1200h
+
+ asmword "PUSH.B"
+ mDODOES
+ .word TYPE2DOES,1240h
+
+ asmword "CALL"
+ mDODOES
+ .word TYPE2DOES,1280h
+
+; ----------------------------------------------------------------------
+; DTCforthMSP430FR5xxx ASSEMBLER, OPCODES TYPE III : PUSHM POPM
+; ----------------------------------------------------------------------
+; syntax : PUSHM R13,R9 ; R-- R13 R12 R11 R10 R9 (first >= last)
+; POPM R9,R13 ; R-- (last >= first)
+; this syntax is more explicit than TI's one and can reuse typeI template
+
+; PUSHM order : R15,R14,R13,R12,R11,R10, R9, R8, R7, R6, R5, R4 (TI's reg)
+; or : PSP,TOS, IP, S, T, W, X, Y, R7, R6, R5, R4 (FastForth reg)
+; example : PUSHM IP,Y or PUSHM R13,R8
+
+; POPM order : R4, R5, R6, R7, R8, R9,R10,R11,R12,R13,R14,R15 (TI's reg)
+; or : R4, R5, R6, R7, Y, X, W, T, S, IP,TOS,PSP (FastForth reg)
+; example : POPM Y,IP or POPM R8,R13
+
+; TYPE3DOES -- PFADOES parse input stream to search :" REG, REG " as operands of PUSHM|POPM then compile instruction
+TYPE3DOES ; -- PFADOES
+ .word lit,',' ; -- PFADOES "," char separator for PARAM1
+ .word PARAM1 ; -- PFADOES ASMTYPE contains : 0x0S00 S=REGsrc
+ .word PARAM2 ; -- PFADOES ASMTYPE contains : 0x0S0D D=REGdst
+ FORTHtoASM ; -- PFADOES
+ MOV.B &ASMTYPE,X ; X=REGdst
+ MOV.B &ASMTYPE+1,W ; W=REGsrc
+ MOV W,&ASMTYPE ; ASMTYPE = 0x000S
+ CMP #1500h,0(TOS) ; -- PFADOES PUSHM ?
+ JNZ POPMCASEOF
+PUSHMCASEOF SUB X,W ; -- PFADOES PUSHM : REGsrc - REGdst = n-1
+ JMP TYPE3QERR
+POPMCASEOF SUB W,X ; -- PFADOES POPM : REGdst - REGsrc = n-1
+ MOV X,W
+TYPE3QERR CMP #16,W
+ JHS BOUNDERRORW ; -- PFADOES (u>=)
+ .word 0E5Ah ; RLAM #4,R10 --> RLAM #4,W
+ JMP BIS_ASMTYPE ; -- then end
+
+BOUNDERRWM1 ADD #1,W ; <== RRAM|RRUM|RRCM|RLAM error
+BOUNDERRORW MOV W,TOS ; <== PUSHM|POPM|ASM_branch error
+BOUNDERROR ; <== REG number error
+ mDOCOL ; -- n n = value out of bounds
+ .word DOT,XSQUOTE
+ .byte 13,"out of bounds"
+ .word QABORTYES
+
+ asmword "PUSHM"
+ASM_PUSHM mDODOES
+ .word TYPE3DOES,01500h
+
+ asmword "POPM"
+ASM_POPM mDODOES
+ .word TYPE3DOES,01700h
+
+; ----------------------------------------------------------------------
+; DTCforthMSP430FR5xxx ASSEMBLER, OPCODES TYPE IV : RLAM|RRAM|RRUM|RRCM
+; ----------------------------------------------------------------------
+
+; TYPE4DOES -- PFADOES parse input stream to search : " #N, REG " as operands of RLAM|RRAM|RRUM|RRCM
+TYPE4DOES ; -- PFADOES
+ .word FBLANK,SKIP ; skip spaces if any
+ FORTHtoASM ; -- PFADOES c-addr
+ MOV #0,&ASMTYPE ; init ASMTYPE=0
+ MOV &DDP,&OPCODE ; init OPCODE=DP
+ ADD #2,&DDP ; make room for opcode
+ ADD #1,&TOIN ; skip "#"
+ MOV #',',TOS ; -- PFADOES ","
+ ASMtoFORTH
+ .word WORDD,QNUMBER
+ .word QBRAN,NotFound
+ .word PARAM2 ; -- PFADOES 0x000N ASMTYPE = 0x000R
+ FORTHtoASM
+ MOV TOS,W ; -- PFADOES 0x000N W = 0x000N
+ MOV @PSP+,TOS ; -- PFADOES
+ SUB #1,W ; W = N floored to 0
+ CMP #4,W ;
+ JHS BOUNDERRWM1 ; JC=JHS (U>=)
+ SWPB W ; -- PFADOES W = N << 8
+ .word 065Ah ; RLAM #2,R10 W = N << 10
+ JMP BIS_ASMTYPE ; --
+
+ asmword "RRCM"
+ mDODOES
+ .word TYPE4DOES,0050h
+
+ asmword "RRAM"
+ mDODOES
+ .word TYPE4DOES,0150h
+
+ asmword "RLAM"
+ mDODOES
+ .word TYPE4DOES,0250h
+
+ asmword "RRUM"
+ mDODOES
+ .word TYPE4DOES,0350h
+
+; ----------------------------------------------------------------------
+; DTCforthMSP430FR5xxx ASSEMBLER, CONDITIONAL BRANCHS
+; ----------------------------------------------------------------------
+; ASSEMBLER FORTH OPCODE(FEDC)
+; OPCODE(code) for TYPE JNE,JNZ 0<>, <> = 0x20xx + (offset AND 3FF) ; branch if Z = 0
+; OPCODE(code) for TYPE JEQ,JZ 0=, = = 0x24xx + (offset AND 3FF) ; branch if Z = 1
+; OPCODE(code) for TYPE JNC,JLO U< = 0x28xx + (offset AND 3FF) ; branch if C = 0
+; OPCODE(code) for TYPE JC,JHS U>= = 0x2Cxx + (offset AND 3FF) ; branch if C = 1
+; OPCODE(code) for TYPE JN 0< = 0x30xx + (offset AND 3FF) ; branch if N = 1
+; OPCODE(code) for TYPE JGE >= = 0x34xx + (offset AND 3FF) ; branch if (N xor V) = 0
+; OPCODE(code) for TYPE JL < = 0x38xx + (offset AND 3FF) ; branch if (N xor V) = 1
+; OPCODE(code) for TYPE JMP = 0x3Cxx + (offset AND 3FF)
+
+CODE_JMP mDOCON ; branch always
+ .word 3C00h
+
+ asmword "S>=" ; if >= assertion
+ mDOCON
+ .word 3800h
+
+ asmword "S<" ; if < assertion
+ mDOCON
+ .word 3400h
+
+ asmword "0>=" ; if 0>= assertion ; use only with IF UNTIL WHILE !
+ mDOCON
+ .word 3000h
+
+ asmword "0<" ; jump if 0< ; use only with ?JMP ?GOTO !
+ mDOCON
+ .word 3000h
+
+ asmword "U<" ; if U< assertion
+ mDOCON
+ .word 2C00h
+
+ asmword "U>=" ; if U>= assertion
+ mDOCON
+ .word 2800h
+
+ asmword "0<>" ; if <>0 assertion
+ mDOCON
+ .word 2400h
+
+ asmword "0=" ; if =0 assertion
+ mDOCON
+ .word 2000h
+
+;ASM IF OPCODE -- @OPCODE1
+ asmword "IF"
+ASM_IF MOV &DDP,W
+ MOV TOS,0(W)
+ ADD #2,&DDP
+ MOV W,TOS
+ mNEXT
+
+;ASM THEN @OPCODE -- resolve forward branch
+ asmword "THEN"
+ASM_THEN MOV &DDP,W ; -- @OPCODE W=dst
+ MOV TOS,Y ; Y=@OPCODE
+ASM_THEN1 MOV @PSP+,TOS ; --
+ MOV Y,X ;
+ ADD #2,X ; -- Y=@OPCODE W=dst X=src+2
+ SUB X,W ; -- Y=@OPCODE W=dst-src+2=displacement*2 (bytes)
+ RRA W ; -- Y=@OPCODE W=displacement (words)
+ CMP #512,W
+ JC BOUNDERRORW ; (JHS) unsigned branch if u> 511
+ BIS W,0(Y) ; -- [@OPCODE]=OPCODE completed
+ mNEXT
+
+;C ELSE @OPCODE1 -- @OPCODE2 branch for IF..ELSE
+ asmword "ELSE"
+ASM_ELSE MOV &DDP,W ; -- W=HERE
+ MOV #3C00h,0(W) ; compile unconditionnal branch
+ ADD #2,&DDP ; -- DP+2
+ SUB #2,PSP
+ MOV W,0(PSP) ; -- dst
+ JMP ASM_THEN
+
+;C BEGIN -- @BEGIN same as FORTH counterpart
+
+;C UNTIL @BEGIN OPCODE -- resolve conditional backward branch
+ asmword "UNTIL"
+ASM_UNTIL MOV @PSP+,W ; -- OPCODE W=dst
+ASM_UNTIL1 MOV TOS,Y
+ MOV @PSP+,TOS ; --
+ MOV &DDP,X ; -- Y=OPCODE X=HERE W=dst
+ SUB #2,W ; -- Y=OPCODE X=HERE W=dst-2
+ SUB X,W ; -- Y=OPCODE X=src W=src-dst-2=displacement (bytes)
+ RRA W ; -- Y=OPCODE X=HERE W=displacement (words)
+ CMP #-512,W
+ JL BOUNDERRORW ; signed branch if < -512
+ AND #3FFh,W ; -- Y=OPCODE X=HERE W=troncated negative displacement (words)
+ BIS W,Y ; -- Y=OPCODE (completed)
+ MOV Y,0(X)
+ ADD #2,&DDP
+ mNEXT
+
+;X AGAIN @BEGIN -- uncond'l backward branch
+; unconditional backward branch
+ asmword "AGAIN"
+ASM_AGAIN mDOCOL ; -- @BEGIN
+ .word CODE_JMP ; -- @BEGIN opcode
+ .word ASM_UNTIL ; --
+ .word EXIT ; --
+
+;C WHILE @BEGIN OPCODE -- @WHILE @BEGIN
+ asmword "WHILE"
+ASM_WHILE mDOCOL ; -- @BEGIN OPCODE
+ .word ASM_IF ; -- @BEGIN @WHILE
+ .word SWAP ; -- @WHILE @BEGIN
+ .word EXIT
+
+;C REPEAT @WHILE @BEGIN -- resolve WHILE loop
+ asmword "REPEAT"
+ASM_REPEAT mDOCOL ; -- @WHILE @BEGIN
+ .word CODE_JMP ; -- @WHILE @BEGIN opcode
+ .word ASM_UNTIL ; -- @WHILE
+ .word ASM_THEN ; --
+ .word EXIT
+
+; ----------------------------------------------------------------
+; DTCforthMSP430FR5xxx ASSEMBLER : branch to a previous definition
+; ----------------------------------------------------------------
+
+;ASM JMP <word> ; -- unconditionnal branch to a previous definition
+ asmword "JMP"
+JUMP mDOCOL
+ .word TICK,CODE_JMP
+ .word ASM_UNTIL,EXIT
+
+
+; invert FORTH conditionnal branch FORTH_JMP_OPCODE -- LABEL_JMP_OPCODE
+INVJMP BIT #1000h,TOS ; 3xxxh case ?
+ JNZ INVJMP3xxxh ; yes
+INVJMP2xxxh XOR #0400h,TOS ; no: case of JNE/JNZ JEQ/JZ JNC/JLO JC/JHS
+ mNEXT
+INVJMP3xxxh CMP #3400h,TOS
+ JLO INVJMPEND ; case of 3000h, do nothing
+ JZ INVJMP3400h
+INVJMP3800h MOV #3400h,TOS ; not jump if >= --> jump if <
+ mNEXT
+INVJMP3400h MOV #3800h,TOS ; not jump if < --> jump if >=
+INVJMPEND mNEXT
+
+
+;ASM <cond> ?JMP <word> ; OPCODE -- conditionnal branch to a previous definition
+ asmword "?JMP"
+ mDOCOL
+ .word INVJMP,TICK,SWAP
+ .word ASM_UNTIL,EXIT
+
+; ------------------------------------------------------------------------------------------
+; DTCforthMSP430FR5xxx ASSEMBLER : branch up to 3 backward labels and up to 3 forward labels
+; ------------------------------------------------------------------------------------------
+; used for non canonical branchs, as BASIC language: "goto line x"
+; when a branch to label is resolved, it's ready for new use
+
+BACKWARDDOES ;
+ FORTHtoASM
+ MOV @RSP+,IP
+ MOV TOS,Y
+ MOV @PSP+,TOS
+ MOV @Y,W ; W = [PFA]
+ CMP #0,W ; W = 0 ?
+ JNZ BACKWUSE
+BACKWSET ; --
+ MOV &DDP,0(Y) ; [PFA] = @LABEL
+ mNEXT
+BACKWUSE ; -- OPCODE
+ MOV #0,0(Y) ; reset [PFA] for next use
+ JMP ASM_UNTIL1 ; resolve backward branch
+
+; backward label 1
+ asmword "BW1"
+ mdodoes
+ .word BACKWARDDOES
+CLRBW1 .word 0
+
+; backward label 2
+ asmword "BW2"
+ mdodoes
+ .word BACKWARDDOES
+CLRBW2 .word 0
+
+; backward label 3
+ asmword "BW3"
+ mdodoes
+ .word BACKWARDDOES
+CLRBW3 .word 0
+
+FORWARDDOES
+ FORTHtoASM
+ MOV @RSP+,IP
+ MOV &DDP,W ;
+ MOV @TOS,Y ; Y=@OPCODE
+ CMP #0,Y
+ JNZ FORWUSE
+FORWSET ; OPCODE PFA --
+ MOV @PSP+,0(W) ; -- PFA compile incomplete opcode
+ ADD #2,&DDP ;
+ MOV W,0(TOS) ; store @OPCODE into PFA
+ MOV @PSP+,TOS ; --
+ mNEXT
+FORWUSE ; PFA -- @OPCODE
+ MOV #0,0(TOS) ; reset PFA for next use
+ JMP ASM_THEN1 ; resolve forward branch
+
+
+; forward label 1
+ asmword "FW1"
+ mdodoes
+ .word FORWARDDOES
+CLRFW1 .word 0
+
+; forward label 2
+ asmword "FW2"
+ mdodoes
+ .word FORWARDDOES
+CLRFW2 .word 0
+
+; forward label 3
+ asmword "FW3"
+ mdodoes
+ .word FORWARDDOES
+CLRFW3 .word 0
+
+
+;ASM GOTO <label> -- unconditionnal branch to label
+ asmword "GOTO"
+ mDOCOL
+ .word CODE_JMP,TICK ; -- OPCODE PFA<label>
+ .word EXECUTE,EXIT
+
+;ASM <cond> ?GOTO <label> OPCODE -- conditionnal branch to label
+ asmword "?GOTO"
+ mDOCOL
+ .word INVJMP,TICK ; -- OPCODE PFA<label>
+ .word EXECUTE,EXIT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+; -*- coding: utf-8 -*-
+; http://patorjk.com/software/taag/#p=display&f=Banner&t=Fast Forth
+
+; Fast Forth For Texas Instrument MSP430FRxxxx FRAM devices
+; Copyright (C) <2017> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+;Z SD_ACCEPT addr addr len -- addr' len' get line to interpret from a SD Card file
+; note : addr = TIB, addr' = PAD
+; defered word ACCEPT is redirected here by the word LOAD"
+; sequentially move an input line ended by CRLF from BUFFER to PAD
+; if end of buffer is reached before CRLF, asks Read_HandledFile to fill buffer with next sector
+; then move the end of the line.
+; when all LOAD"ed files are read, redirects defered word ACCEPT to (ACCEPT) and restore interpret pointers.
+; see CloseHandleT.
+
+; used variables : BufferPtr, BufferLen
+
+; ----------------------------------;
+; FORTHWORD "SD_ACCEPT" ; TIB TIB len -- SDIB len'
+; ----------------------------------;
+SD_ACCEPT ; sequentially move from BUFFER to SDIB (or PAD) a line of chars delimited by CRLF
+; ----------------------------------;
+ PUSH IP ;
+ MOV #SDA_YEMIT_RET,IP ; set YEMIT return
+; ----------------------------------;
+StartNewLine ;
+; ----------------------------------;
+ MOV &CurrentHdl,T ; prepare link for any next LOAD"ed file...
+ MOV &BufferPtr,HDLW_BUFofst(T) ; ...see usage : HandleComplements
+ .IFDEF RAM_1K ; use PAD as SD Input Buffer because the lack of RAM
+ MOV #PAD,W ; W=dst
+ MOV W,2(PSP) ; -- PAD TIB max_chars_count
+ MOV #PAD_SIZE-4,0(PSP) ; -- StringOrg' len" len
+ .ELSEIF ; RAM >= 2k
+ MOV #SDIB,W ; W=dst
+ MOV W,2(PSP) ; -- SDIB TIB max_chars_count
+ MOV #SDIB_SIZE-4,0(PSP) ; -- StringOrg' len" len
+ .ENDIF
+ MOV #0,TOS ; -- StringOrg' len" Count
+; ----------------------------------;
+SDA_InitSrcAddr ; <== SDA_GetFileNextSector (if BufferLen<>0)
+; ----------------------------------;
+ MOV &BufferPtr,X ; X=src (buf_offset)
+ JMP SDA_ComputeChar ;
+; ----------------------------------;
+SDA_YEMIT_RET ;
+; ----------------------------------;
+ FORTHtoASM ;
+ SUB #2,IP ; 1 restore YEMIT return
+; ----------------------------------;
+SDA_ComputeChar ;
+; ----------------------------------;
+ CMP &BufferLen,X ; 3 BufferPtr >= BufferLen ?
+ JHS SDA_GetFileNextSector ; 2 yes
+ MOV.B BUFFER(X),Y ; 3 Y = char
+ ADD #1,X ; 1 increment input BufferPtr
+ CMP.B #32,Y ; 2 ascii printable char ?
+ JHS SDA_MoveChar ; 2 yes
+ CMP.B #10,Y ; control char = 'LF' ?
+ JNZ SDA_ComputeChar ; no
+; ----------------------------------;
+SDA_EndOfLine ;
+; ----------------------------------;
+ MOV X,&BufferPtr ; yes save BufferPtr for next line
+; MOV &CurrentHdl,T ; prepare link for case of this line ask to LOAD" a new file...
+; MOV X,HDLW_BUFofst(T) ; to handle update.
+; ----------------------------------;
+SDA_GoToInterpret ;
+; ----------------------------------;
+ ADD #2,PSP ; -- StringOrg' len'
+ MOV @RSP+,IP ;
+ MOV @IP+,PC ; ===> unique output
+; ----------------------------------;
+SDA_MoveChar ;
+; ----------------------------------;
+ CMP TOS,0(PSP) ; 3 count = max_chars_count ?
+ JZ YEMIT ; 2 yes, don't move char to dst
+ MOV.B Y,0(W) ; 3 move char to dst
+ ADD #1,W ; 1 increment dst addr
+ ADD #1,TOS ; 1 increment count of moved chars
+ JMP YEMIT ; 9/6~ send echo to terminal if ECHO, do nothing if NOECHO
+; ----------------------------------; 33/30~ char loop
+SDA_GetFileNextSector ;
+; ----------------------------------;
+ PUSH W ; save dst
+ CALL #Read_File ; STWXY use
+ MOV @RSP+,W ; restore dst
+ CMP #0,&BufferLen ; test if input buffer is empty (EOF)
+ JNZ SDA_InitSrcAddr ; no : loopback to end the line
+ JMP SDA_GoToInterpret ; yes, loopback to interpret the line, then on next SD_ACCEPT goto SDA_RestoreInputBuffer
+; ----------------------------------;
+
+
+;C ACCEPT addr addr len -- addr' len' get line at addr to interpret len' chars
+ FORTHWORD "ACCEPT"
+ACCEPT MOV #PARENACCEPT,PC
+
+;C (ACCEPT) addr addr len -- addr len' get len' (up to len) chars from terminal (TERATERM.EXE) via USBtoUART bridge
+ FORTHWORD "(ACCEPT)"
+PARENACCEPT
+
--- /dev/null
+; -*- coding: utf-8 -*-
+; forthMSP430FR_SD_INIT.asm
+
+; http://patorjk.com/software/taag/#p=display&f=Banner&t=Fast Forth
+
+; Fast Forth For Texas Instrument MSP430FRxxxx FRAM devices
+; Copyright (C) <2017> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+; ===========================================================
+; ABOUT INIT SD_CARD AND HOW TO SELECT FAT16/FAT32 FORMATTING
+; ===========================================================
+; FAT16/FAT32 selection is done via the ID of partition in EBP, because SD must be always FAT16 and SDHC must be always FAT32
+; So we assume that the SD_Card FAT16/FAT32 formatting was done well !
+
+
+; ===========================================================
+; 1- Init eUSCI dedicated to SD_Card SPI driver
+; ===========================================================
+
+ MOV #0A981h,&SD_CTLW0 ; UCxxCTL1 = CKPH, MSB, MST, SPI_3, SMCLK + UCSWRST
+ MOV #FREQUENCY*3,&SD_BRW ; UCxxBRW init SPI CLK = 333 kHz ( < 400 kHz) for SD_Card init
+
+
+ .IFDEF MSP_EXP430FR5739
+
+; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
+
+; P2.2 - RF.16 <--- CD SD_CardAdapter (Card Detect)
+SD_CD .equ 4
+SD_CDIN .equ P2IN
+; P2.3 - RF.10 ---> CS SD_CardAdapter (Card Select)
+SD_CS .equ 8
+SD_CSOUT .equ P2OUT
+ BIS.B #SD_CS,&P2DIR ; SD_CS output high
+
+; P2.4 - RF.14 UCA1 CLK ---> CLK SD_CardAdapter (SCK)
+; P2.5 - RF.7 UCA1 TXD/SIMO ---> SDI SD_CardAdapter (MOSI)
+; P2.6 - RF.5 UCA1 RXD/SOMI <--- SDO SD_CardAdapter (MISO)
+ BIS.B #070h,&P2SEL1 ; Configure UCA1 pins P2.4 as UCA1CLK, P2.5 as UCA1SIMO & P2.6 as UCA1SOMI
+ ; P2DIR.x is controlled by eUSCI_A0 module
+ BIC.B #070h,&P2REN ; disable pullup resistors for SIMO/SOMI/SCK pins
+
+ .ENDIF
+ .IFDEF MSP_EXP430FR5969
+
+; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
+
+; P4.2 <--- SD_CD (Card Detect)
+SD_CD .equ 4
+SD_CDIN .equ P4IN
+; P4.3 ---> SD_CS (Card Select)
+SD_CS .equ 8
+SD_CSOUT .equ P4OUT
+ BIS.B #SD_CS,&P4DIR ; SD_CS output high
+
+; P2.4 UCA1 CLK ---> SD_CLK
+; P2.5 UCA1 TX/SIMO ---> SD_SDI
+; P2.6 UCA1 RX/SOMI <--- SD_SDO
+ BIS.B #070h, &P2SEL1 ; Configure UCA1 pins P2.4 as UCA1CLK, P2.5 as UCA1SIMO & P2.6 as UCA1SOMI
+ ; P2DIR.x is controlled by eUSCI_A0 module
+ BIC.B #070h, &P2REN ; disable pullup resistors for SIMO/SOMI/SCK pins
+
+ .ENDIF
+ .IFDEF MSP_EXP430FR5994
+
+; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
+
+; P7.2/UCB2CLK - SD_CD (Card Detect)
+SD_CD .equ 4 ; P7.2
+SD_CDIN .equ P7IN
+; P4.0/A8 - SD_CS (Card Select)
+SD_CS .equ 1 ; P4.0
+SD_CSOUT .equ P4OUT
+ BIS.B #SD_CS,&P4DIR ; SD_CS output high
+
+; P2.2/TB0.2/UCB0CLK - SD_CLK
+; P1.6/TB0.3/UCB0SIMO/UCB0SDA/TA0.0 - SD_SDI
+; P1.7/TB0.4/UCB0SOMI/UCB0SCL/TA1.0 - SD_SDO
+ BIS #04C0h,&PASEL1 ; Configure UCB0 pins P1.6 as UCB0SIMO, P1.7 as UCB0SOMI& UCB0 pins P2.2 as UCB0CLK
+ ; PxDIR.x is controlled by eUSCI_A0 module
+ BIC #04C0h,&PAREN ; disable pullup resistors for SIMO/SOMI/SCK pins
+
+ .ENDIF
+ .IFDEF MSP_EXP430FR6989
+
+; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
+
+; P2.7 <--- SD_CD (Card Detect)
+SD_CD .equ 80h
+SD_CDIN .equ P2IN
+; P2.6 ---> SD_CS (Card Select)
+SD_CS .equ 40h
+SD_CSOUT .equ P2OUT
+ BIS.B #SD_CS,&P2DIR ; SD_CS output high
+
+; P2.2 UCA0 CLK ---> SD_CLK
+; P2.0 UCA0 TX/SIMO ---> SD_SDI
+; P2.2 UCA0 RX/SOMI <--- SD_SDO
+ BIS.B #007h,&P2SEL0 ; Configure UCA1 pins P2.2 as UCA0CLK, P2.0 as UCA0SIMO & P2.1 as UCA0SOMI
+ ; P2DIR.x is controlled by eUSCI_A0 module
+ BIC.B #007h,&P2REN ; disable pullup resistors for SIMO/SOMI/SCK pins
+
+ .ENDIF
+; .IFDEF MSP_EXP430FR4133
+;
+;; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
+;
+;; P8.0 <--- SD_CD (Card Detect)
+;SD_CD .equ 1
+;SD_CDIN .equ P8IN
+;; P8.1 ---> SD_CS (Card Select)
+;SD_CS .equ 2
+;SD_CSOUT .equ P8OUT
+; BIS.B #SD_CS,&P8DIR ; SD_CS output high
+;
+;; P5.1 UCB0 CLK ---> SD_CLK
+;; P5.2 UCB0 TX/SIMO ---> SD_SDI
+;; P5.3 UCB0 RX/SOMI <--- SD_SDO
+; BIS.B #00Eh,&P5SEL1 ; Configure UCB0 pins P5.1 as CLK, P5.2 as SIMO & P5.3 as SOMI
+; ; P2DIR.x is controlled by eUSCI_A0 module
+; BIC.B #00Eh,&P5REN ; disable pullup resistors for SIMO/SOMI/SCK pins
+;
+; .ENDIF
+ .IFDEF CHIPSTICK_FR2433
+
+; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
+
+; P2.3 <--- SD_CD (Card Detect)
+SD_CD .equ 8
+SD_CDIN .equ P2IN
+; P2.2 ---> SD_CS (Card Select)
+SD_CS .equ 4
+SD_CSOUT .equ P2OUT
+ BIS.B #SD_CS,&P2DIR ; SD_CS output high
+
+; P1.1 UCB0 CLK ---> SD_CLK
+; P1.2 UCB0 TX/SIMO ---> SD_SDI
+; P1.3 UCB0 RX/SOMI <--- SD_SDO
+ BIS.B #00Eh,&P1SEL0 ; Configure UCB0 pins P1.1 as CLK, P1.2 as SIMO & P1.3 as SOMI
+ ; P1DIR.x is controlled by eUSCI_B0 module
+ BIC.B #00Eh,&P1REN ; disable pullup resistors for SIMO/SOMI/SCK pins
+
+ .ENDIF
+ .IFDEF MY_MSP430FR5738
+
+; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
+
+; P2.3 as SD_CD
+SD_CD .equ 08h
+SD_CDIN .equ P2IN
+; P2.4 as SD_CS
+SD_CS .equ 10h
+SD_CSOUT .equ P2OUT
+ BIS.B #SD_CS,&P2DIR ; SD_CS output high
+
+; P2.2/UCB0CLK ---> SD_CardAdapter CLK (SCK) default value
+; P1.6/UCB0SIMO/UCB0SDA/TA0.0 ---> SD_CardAdapter SDI (MOSI) default value
+; P1.7/UCB0SOMI/UCB0SCL/TA1.0 <--- SD_CardAdapter SDO (MISO) default value
+ BIS #04C0h,&PASEL1 ; Configure UCB0 pins P2.2 as UCB0CLK, P1.6 as UCB0SIMO & P1.7 as UCB0SOMI
+ ; P2DIR.x is controlled by eUSCI_B0 module
+ BIC #04C0h,&PAREN ; disable pullup resistors for SIMO/SOMI/CLK pins
+
+ .ENDIF
+ .IFDEF MY_MSP430FR5738_1
+
+; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
+
+; P2.3 as SD_CD
+SD_CD .equ 08h
+SD_CDIN .equ P2IN
+; P2.4 as SD_CS
+SD_CS .equ 10h
+SD_CSOUT .equ P2OUT
+ BIS.B #SD_CS,&P2DIR ; SD_CS output high
+
+; P2.2/UCB0CLK ---> SD_CardAdapter CLK (SCK) default value
+; P1.6/UCB0SIMO/UCB0SDA/TA0.0 ---> SD_CardAdapter SDI (MOSI) default value
+; P1.7/UCB0SOMI/UCB0SCL/TA1.0 <--- SD_CardAdapter SDO (MISO) default value
+ BIS #04C0h,&PASEL1 ; Configure UCB0 pins P2.2 as UCB0CLK, P1.6 as UCB0SIMO & P1.7 as UCB0SOMI
+ ; P2DIR.x is controlled by eUSCI_B0 module
+ BIC #04C0h,&PAREN ; disable pullup resistors for SIMO/SOMI/CLK pins
+
+ .ENDIF
+ .IFDEF MY_MSP430FR5948
+
+; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
+
+; P2.3 <--- SD_CD (Card Detect)
+SD_CD .equ 08h
+SD_CDIN .equ P2IN
+; P2.7 ---> SD_CS (Card Select)
+SD_CS .equ 80h
+SD_CSOUT .equ P2OUT
+ BIS.B #SD_CS,&P2DIR ; SD_CS output high
+
+; P2.4 UCA1 CLK ---> SD_CLK
+; P2.5 UCA1 TX/SIMO ---> SD_SDI
+; P2.6 UCA1 RX/SOMI <--- SD_SDO
+ BIS.B #070h,&P2SEL1 ; Configure UCA1 pins P2.4 as UCA1CLK, P2.5 as UCA1SIMO & P2.6 as UCA1SOMI
+ ; P2DIR.x is controlled by eUSCI_A0 module
+ BIC.B #070h,&P2REN ; disable pullup resistors for SIMO/SOMI/SCK pins
+
+ .ENDIF
+ .IFDEF MY_MSP430FR5948_1 ; = new version of MY_MSP430FR5948
+
+; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
+
+; P2.7 ---> SD_CD (Card Detect)
+SD_CD .equ 80h
+SD_CDIN .equ P2IN
+; P2.3 <--- SD_CS (Card Select)
+SD_CS .equ 08h
+SD_CSOUT .equ P2OUT
+ BIS.B #SD_CS,&P2DIR ; SD_CS output high
+
+; P2.4 UCA1 CLK ---> SD_CLK
+; P2.5 UCA1 TX/SIMO ---> SD_SDI
+; P2.6 UCA1 RX/SOMI <--- SD_SDO
+ BIS.B #070h,&P2SEL1 ; Configure UCA1 pins P2.4 as UCA1CLK, P2.5 as UCA1SIMO & P2.6 as UCA1SOMI
+ ; P2DIR.x is controlled by eUSCI_A0 module
+ BIC.B #070h,&P2REN ; disable pullup resistors for SIMO/SOMI/SCK pins
+
+ .ENDIF
+
+ BIC #1,&SD_CTLW0 ; release eUSCI from reset
+
+; ===========================================================
+; 2- Init all SD_Card variables, handles and SDIB buffer to 0
+; ===========================================================
+
+InitSDdata
+ MOV #SD_ORG_DATA,X ;
+InitSDdataLoop ;
+ MOV #0,0(X) ;
+ ADD #2,X ;
+ CMP #SD_END_DATA,X ;
+ JNE InitSDdataLoop ;
+
+
+; ===========================================================
+; 3- Init SD_Card
+; ===========================================================
+
+SD_POWER_ON
+ MOV #8,X ; send 64 clk on SD_clk
+ CALL #SPI_X_GET ;
+ BIC.B #SD_CS,&SD_CSOUT ; set SD_CS output low to switch in SPI mode
+ MOV #4,S ; preset error 4R1
+SEND_CMD0 ; CMD0 : GO_IDLE_STATE
+ MOV #95h,&SD_CMD_FRM ; $(95 00 00 00 00 00)
+ MOV #4000h,&SD_CMD_FRM+4 ; $(95 00 00 00 00 40); send CMD0
+ MOV #1,W ; expected SPI_R1 response = 1 = idle state
+ CALL #sendCommand ;X
+ JZ INIT_CMD8 ; if idle state
+SD_INIT_ERROR ;
+ MOV #SD_CARD_ERROR,PC ; ReturnError = $04R1, case of defectuous card (or insufficient SD_POWER_ON clk)
+; ----------------------------------;
+INIT_CMD8 ; mandatory if SD_Card >= V2.x [11:8]supply voltage(VHS)
+; ----------------------------------;
+ CALL #SPI_GET ; (needed to pass SanDisk ultra 8GB "HC I")
+ CMP.B #-1,W ; FFh expected value <==> MISO = high level
+ JNE INIT_CMD8 ; loop back while yet busy
+; ----------------------------------;
+ MOV #8,S ; preset error 8R1 for CMD1
+ MOV #0AA87h,&SD_CMD_FRM ; $(87 AA ...) (CRC:CHECK PATTERN)
+ MOV #1,&SD_CMD_FRM+2 ; $(87 AA 01 00 ...) (CRC:CHECK PATTERN:VHS set as 2.7to3.6V:0)
+ MOV #4800h,&SD_CMD_FRM+4 ; $(87 AA 01 00 00 48)
+SEND_CMD8 ; CMD8 = SEND_IF_COND
+ MOV #1,W ; expected R1 response (first byte of SPI R7) = 01h : idle state
+ CALL #sendCommand ;
+; ----------------------------------;
+CMD8_NEXT ; time out occured with SD_Card V1.x and all MMC_card
+ MOV #4,X ;
+ CALL #SPI_X_GET ;WX skip end of SD_Card V2.x type R7 response (4 bytes)
+; ----------------------------------;
+ MOV #1,&SD_CMD_FRM ; $(01 00 ... set stop bit
+ MOV #0,&SD_CMD_FRM+2 ; $(01 00 00 00 ...
+; MOV.B #16,Y ; init 16 * ACMD41 repeats (power on fails with SanDisk ultra 8GB "HC I" and Transcend 2GB)
+; MOV.B #32,Y ; init 32 * ACMD41 repeats ==> ~400ms
+ MOV.B #-1,Y ; init 255 * ACMD41 repeats ==> 3 s
+; ----------------------------------;
+SEND_ACMD41 ; (CMD55+CMD41)
+; ----------------------------------;
+ ADD S,S ; preset error 10R1 for ACMD41
+SEND_CMD55 ; CMD55 = APP_CMD
+ MOV #7700h,&SD_CMD_FRM+4 ; $(01 00 00 00 00 77)
+ MOV #1,W ; expected R1 response = 1 : idle
+ CALL #sendCommand ;
+SEND_CMD41 ; CMD41 = APP OPERATING CONDITION
+ MOV #6940h,&SD_CMD_FRM+4 ; $(01 00 00 00 40 69) (30th bit = HCS = High Capacity Support request)
+ CALL #SDbusyLoop ; wait until busy (needed to pass SanDisk ultra 8GB "HC I") then send Command CMD41
+ JZ SetBLockLength ; if SD_Card ready (R1=0)
+ SUB.B #1,Y ; else decr time out delay
+ JNZ SEND_CMD55 ; then loop back while count of repeat not reached
+ JMP SD_INIT_ERROR ; ReturnError on time out : unusable card
+; ----------------------------------;
+setBLockLength ; set block = 512 bytes (buffer size), usefull for FAT16 SD Cards
+; ----------------------------------;
+ ADD S,S ; preset error $20 for CMD16
+SEND_CMD16 ; CMD16 = SET_BLOCKLEN
+ MOV #02h,&SD_CMD_FRM+2 ; $(01 00 02 00 ...)
+ MOV #5000h,&SD_CMD_FRM+4 ; $(01 00 02 00 00 50)
+ CALL #SDbusyLoop ; wait until busy then send CMD16
+ JNZ SD_INIT_ERROR ; if W = R1 <> 0, ReturnError = $20R1 ; send command ko
+; ----------------------------------;
+SetHighSpeed ; end of SD init ==> SD_CLK = SMCLK
+; ----------------------------------;
+ BIS #1,&SD_CTLW0 ; Software reset
+ MOV #0,&SD_BRW ; UCxxBRW = 0 ==> SPI_CLK = MCLK
+ BIC #1,&SD_CTLW0 ; release from reset
+; ----------------------------------;
+Read_EBP_FirstSector ; W=0, BS_FirstSectorHL=0
+; ----------------------------------;
+ ADD S,S ; preset error $40 ; SD card not FAT16/FAT32
+ CALL #readSectorW ; read physical first sector
+ MOV #BUFFER,Y ;
+ MOV 454(Y),&BS_FirstSectorL ;
+ MOV 456(Y),&BS_FirstSectorH ;
+ MOV.B 450(Y),W ; W = partition ID
+; ----------------------------------;
+TestPartitionID ;
+; ----------------------------------;
+ MOV #1,&FATtype ; preset FAT16
+FAT16_CHS_LBA_Test ;
+ SUB.B #6,W ; ID=06h Partition FAT16 using CHS & LBA ?
+ JZ Read_MBR_FirstSector ;
+FAT16_LBA_Test ;
+ SUB.B #8,W ; ID=0Eh Partition FAT16 using LBA ?
+ JZ Read_MBR_FirstSector ;
+; ----------------------------------;
+ MOV #2,&FATtype ; set FAT32
+FAT32_LBA_Test ;
+ ADD.B #2,W ; ID=0Ch Partition FAT32 using LBA ?
+ JZ Read_MBR_FirstSector ;
+FAT32_CHS_LBA_Test ;
+ ADD.B #1,W ; ID=0Bh Partition FAT32 using CHS & LBA ?
+ JZ Read_MBR_FirstSector ;
+ ADD.B #0Bh,W
+ JNZ SD_INIT_ERROR ; ReturnError = $40xx with xx = partition ID
+; ----------------------------------;
+Read_MBR_FirstSector ; W=0
+; ----------------------------------;
+ CALL #readSectorW ; ...with the good bytes/sectors (FAT16/FAT32) CMD17 frame !
+; ----------------------------------;
+FATxx_SetFileSystem ;
+; ----------------------------------;
+ MOV.B 13(Y),&SecPerClus ;
+ MOV 14(Y),X ;3 X = BPB_RsvdSecCnt
+ MOV X,&OrgFAT1 ;3 set OrgFAT1
+ MOV 22(Y),W ; W = BPB_FATsize
+ CMP #0,W ; BPB_FATsize = 0 ?
+ JNZ Set_FATsize ;
+ MOV 36(Y),W ; W = BPB_FATSz32
+Set_FATsize ;
+ MOV W,&FATSize ; limited to 16384 sectors....
+ ADD W,X ;
+ MOV X,&OrgFAT2 ; X = OrgFAT1 + FATsize = OrgFAT2
+ ADD W,X ; X = OrgFAT2 + FATsize = FAT16 OrgRootDir | FAT32 OrgDatas
+ CMP #2,&FATtype ; FAT32?
+ JZ FATxx_SetFileSystemNext ; yes
+FAT16_SetRootCluster ;
+ MOV X,&OrgRootDIR ; only FAT16 use, is a sector used by ComputeClusFrstSect
+ ADD #32,X ; OrgRootDir + RootDirSize = OrgDatas
+FATxx_SetFileSystemNext ;
+ SUB &SecPerClus,X ; OrgDatas - SecPerClus*2 = OrgClusters
+ SUB &SecPerClus,X ; no borrow expected
+ MOV X,&OrgClusters ; X = virtual cluster 0 address (clusters 0 and 1 don't exist)
+ MOV &FATtype,&DIRClusterL ; init DIRcluster as RootDIR
+; ----------------------------------;
+
+
--- /dev/null
+; -*- coding: utf-8 -*-
+; DTCforthMSP430FRxxxxSD_LOAD.asm
+
+; Tested with MSP-EXP430FR5969 launchpad
+; Copyright (C) <2017> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+;-----------------------------------------------------------------------
+; SD card OPEN, LOAD subroutines
+;-----------------------------------------------------------------------
+
+;Z S">HERE addr u -- HERE move in-line string to a counted string at HERE
+SQUOTE2HERE MOV @PSP+,X ; X = src
+ MOV &DDP,Y ; Y = dst = HERE
+ MOV.B TOS,W ; W = count
+ MOV Y,TOS ; -- HERE
+ MOV.B W,0(Y) ; count at HERE
+ ADD #1,Y ; inc dst
+ MOV #MOVEDOWN,PC ;
+
+
+
+; rules for registers use
+; S = error
+; T = CurrentHdl, pathname
+; W = SectorL, (RTC) TIME
+; X = SectorH, (RTC) DATE
+; Y = BufferPtr, (DIR) EntryOfst, FAToffset
+
+
+; ----------------------------------;
+HDLCurClusToFAT1sectWofstY ;WXY Input: HDL_CurCluster, Output: W=FATsector, Y=FAToffset, Cluster=HDL_CurCluster
+; ----------------------------------;
+ MOV HDLL_CurClust(T),&ClusterL ;
+ MOV HDLH_CurClust(T),&ClusterH ;
+; ----------------------------------;
+ClusterToFAT1sectWofstY ;WXY Input : Cluster ; Output: W = FATsector, Y = FAToffset
+; ----------------------------------;
+ MOV.B &ClusterL+1,W ;3 W = ClusterLoHI
+ MOV.B &ClusterL,Y ;3 Y = ClusterLoLo
+ CMP #2,&FATtype ;3 FAT32?
+ JZ ClusterToFAT32sector ;2 yes
+ ADD Y,Y ;1 Y = ClusterLoLo << 1
+OpenSubRET
+ RET
+
+
+; input : Cluster n, max = 7FFFFF ==> SDcard up to 256 GB
+; ClusterLoLo*4 = displacement in 512 bytes sector ==> FAToffset
+; ClusterHiLo&ClusterLoHi +C << 1 = relative FATsector + orgFAT1 ==> FATsector
+; ----------------------------------;
+ClusterToFAT32sector ; Input : Cluster ; Output: W=FATsector, Y=FAToffset
+; ----------------------------------;
+ MOV.B &ClusterH,X ; X = 0:ClusterHiLo
+ SWPB X ; X = ClusterHiLo:0
+ ADD X,W ; W = ClusterHiLo:ClusterLoHi
+; ----------------------------------;
+ SWPB Y ; Y = ClusterLoLo:0
+ ADD Y,Y ;1 Y = ClusterLoLo:0 * 2 + carry for FATsector
+ ADDC W,W ; W = ClusterHiLo:ClusterLoHi * 2 = ClusterHiLo:ClusterL / 128
+ SWPB Y
+ ADD Y,Y ; Y = 0:ClusterLoLo * 4
+ RET ;4
+; ----------------------------------;
+
+
+; use no registers
+; ----------------------------------; Input : Cluster
+ComputeClusFrstSect ; If Cluster = 1 ==> RootDirectory ==> SectorL = OrgRootDir
+; ----------------------------------; Output: SectorL of Cluster
+ MOV #0,&SectorH ;
+ MOV &OrgRootDir,&SectorL ;
+ CMP #1,&ClusterL ; clusterL = 1 ? (FAT16 specificity)
+ JNE CCFS_AllOtherCLuster ; no
+ CMP.B #0,&ClusterH ; clusterT = 0 ?
+ JZ OpenSubRET ; yes, sectorL for FAT16 OrgRootDIR is done
+CCFS_AllOtherCLuster ;
+ MOV &OrgClusters,&RES0 ; OrgClusters = sector of virtual cluster 0, word size
+ MOV #0,&RES1 ;
+ MOV &ClusterL,&MAC32L ;3
+ MOV &ClusterH,&MAC32H ;3
+ MOV &SecPerClus,&OP2 ;
+ MOV &RES0,&SectorL ;
+ MOV &RES1,&SectorH ;
+ RET ;
+; ----------------------------------;
+
+; ----------------------------------;
+ComputeHDLcurrentSector ;
+; ----------------------------------;
+ MOV HDLL_CurClust(T),&ClusterL;
+ MOV HDLH_CurClust(T),&ClusterH;
+ CALL #ComputeClusFrstSect ;
+ MOV.B HDLB_ClustOfst(T),W ;
+ ADD W,&SectorL ;
+ ADDC #0,&SectorH ;
+ RET ;
+; ----------------------------------;
+
+
+
+
+; ----------------------------------; input : X = countdown_of_spaces, Y = name pointer in buffer
+ParseEntryNameSpaces ;XY
+; ----------------------------------; output: Z flag, Y is set after the last space char
+ CMP #0,X ;
+ JZ OpenSubRET ;
+; ----------------------------------; input : X = countdown_of_spaces, Y = name pointer in buffer
+ParseEntryNameSpacesLoop ; here X must be > 0
+; ----------------------------------; output: Z flag, Y is set after the last space char
+ CMP.B #32,BUFFER(Y) ; SPACE ?
+ JNZ OpenSubRET ; no: RET
+ ADD #1,Y ;
+ SUB #1,X ;
+ JNZ ParseEntryNameSpacesLoop;
+ RET ;
+; ----------------------------------;
+
+
+; sequentially load in BUFFER bytsPerSec bytes of a file opened as read or as load
+; if previous bufferLen had a size < bytsPerSec, closes the file.
+; if new bufferLen have a size <= BufferPtr, closes the file.
+; reload previous LOADed file if exist.
+; HDLL_CurSize leaves the not yet read size
+; All used registers must be initialized.
+; ==================================;
+Read_File ; <== SD_ACCEPT, READ
+; ==================================;
+ MOV &CurrentHdl,T ;
+ MOV #0,&BufferPtr ; reset BufferPtr (the buffer is already read)
+ CMP #bytsPerSec,&BufferLen ;
+ JNZ CloseHandleT ; because this last and incomplete sector is already read
+ SUB #bytsPerSec,HDLL_CurSize(T) ; HDLL_CurSize is decremented of one sector lenght
+ SUBC #0,HDLH_CurSize(T) ;
+ ADD.B #1,HDLB_ClustOfst(T) ; current cluster offset is incremented
+ CMP.B &SecPerClus,HDLB_ClustOfst(T) ; Cluster Bound reached ?
+ JLO SetBufLenAndLoadCurSector ; no
+; ----------------------------------;
+;SearchNextCluster ; yes
+; ----------------------------------;
+ MOV.B #0,HDLB_ClustOfst(T) ; reset Current_Cluster sectors offset
+ CALL #HDLCurClusToFAT1sectWofstY;WXY Output: W=FATsector, Y=FAToffset, Cluster=HDL_CurCluster
+ CALL #ReadFAT1SectorW ;SWX (< 65536)
+ MOV #0,HDLH_CurClust(T) ;
+ MOV BUFFER(Y),HDLL_CurClust(T) ;
+ CMP #1,&FATtype ; FAT16?
+ JZ SetBufLenAndLoadCurSector ;
+ MOV BUFFER+2(Y),HDLH_CurClust(T);
+; ==================================;
+SetBufLenAndLoadCurSector ;WXY <== previous handle reLOAD
+; ==================================;
+;ComputeBufferLen ;
+; ----------------------------------;
+ MOV #bytsPerSec,&BufferLen ; preset BufferLen
+ CMP #0,HDLH_CurSize(T) ; CurSize > 65535 ?
+ JNZ LoadHDLcurrentSector ; yes
+ CMP HDLL_CurSize(T),&BufferPtr ; BufferPtr >= CurSize ? (BufferPtr = 0 or see RestorePreviousLoadedFileContext)
+ JHS CloseHandleT ; yes
+ CMP #bytsPerSec,HDLL_CurSize(T) ; CurSize >= 512 ?
+ JHS LoadHDLcurrentSector ; yes
+ MOV HDLL_CurSize(T),&BufferLen ; no: adjust BufferLen
+; ==================================;
+LoadHDLcurrentSector ; <=== OPEN_WRITE_APPEND
+; ==================================;
+ CALL #ComputeHDLcurrentSector ; use no registers
+; ==================================;
+ReadSector ;
+; ==================================;
+ MOV &SectorL,W ; Low
+ MOV &SectorH,X ; High
+ JMP ReadSectorWX ; then RET
+; ----------------------------------;
+
+
+; if first open_load token, save DefaultInputStream
+; if other open_load token, decrement token, save previous context
+
+; OPEN subroutine
+; Input : EntryOfst, Cluster = EntryOfst(HDLL_FirstClus())
+; init handle(HDLL_DIRsect,HDLW_DIRofst,HDLL_FirstClus,HDLL_CurClust,HDLL_CurSize)
+; Output: Cluster = first Cluster of file, X = CurrentHdl
+; ----------------------------------; input : Cluster, EntryOfst
+GetFreeHandle ;STWXY init handle(HDLL_DIRsect,HDLW_DIRofst,HDLL_FirstClus = HDLL_CurClust,HDLL_CurSize)
+; ----------------------------------; output : T = new CurrentHdl
+ MOV #8,S ; prepare file already open error
+ MOV #FirstHandle,T ;
+ MOV #0,X ; X = previous handle, init = 0
+; ----------------------------------;
+SearchHandleLoop ;
+; ----------------------------------;
+ CMP.B #0,HDLB_Token(T) ; free handle ?
+ JZ FreeHandleFound ; yes
+AlreadyOpenTest ; no
+ CMP &ClusterH,HDLH_FirstClus(T);
+ JNE SearchNextHandle ;
+ CMP &ClusterL,HDLL_FirstClus(T);
+ JZ InitHandleRET ; error 8: Already Open abort ===>
+SearchNextHandle ;
+ MOV T,X ; handle is occupied, keep it in X as previous handle
+ ADD #HandleLenght,T ;
+ CMP #HandleEnd,T ;
+ JNZ SearchHandleLoop ;
+; ----------------------------------;
+ ADD S,S ; 16 = no more handle error, abort ===>
+InitHandleRET ;
+ RET ;
+; ----------------------------------;
+FreeHandleFound ; T = new handle, X = previous handle
+; ----------------------------------;
+ MOV #0,S ; prepare HappyEnd
+ MOV T,&CurrentHdl ;
+ MOV X,HDLW_PrevHDL(T) ; link to previous handle
+; ----------------------------------;
+CheckCaseOfLoadFileToken ;
+; ----------------------------------;
+ CMP.B #0,W ; open_type is LOAD?
+ JGE InitHandle ; W>0, no
+ CMP.B #0,X ; existing previous handle?
+ JZ InitHandle ; no
+ CMP.B #0,HDLB_Token(X) ; previous token is negative? (open_load type)
+ JGE InitHandle ; no
+ ADD.B HDLB_Token(X),W ; LOAD token = previous LOAD token -1
+; ----------------------------------;
+InitHandle ;
+; ----------------------------------;
+ MOV.B W,HDLB_Token(T) ; marks handle as open type
+ MOV.B #0,HDLB_ClustOfst(T) ; clear ClustOfst
+ MOV &SectorL,HDLL_DIRsect(T); init handle DIRsectorL
+ MOV &SectorH,HDLH_DIRsect(T);
+ MOV &EntryOfst,Y ;
+ MOV Y,HDLW_DIRofst(T) ; init handle BUFFER offset of DIR entry
+ MOV BUFFER+26(Y),HDLL_FirstClus(T); init handle firstcluster of file (to identify file)
+ MOV BUFFER+20(Y),HDLH_FirstClus(T)
+ MOV BUFFER+26(Y),HDLL_CurClust(T) ; init handle CurrentCluster
+ MOV BUFFER+20(Y),HDLH_CurClust(T)
+ MOV BUFFER+28(Y),HDLL_CurSize(T); init handle LOW currentSizeL
+ MOV BUFFER+30(Y),HDLH_CurSize(T);
+ MOV #0,&BufferPtr ; reset BufferPtr all type of files
+ CMP.B #2,W ; is a WRITE file handle?
+ JZ ComputeHDLcurrentSector ; = 2, is a WRITE file
+ JGE InitHandleRET ; > 2, is a file to be deleted
+ MOV #0,HDLW_BUFofst(T) ; < 2, is a READ or a LOAD file
+; ----------------------------------;
+HandleComplements ;
+; ----------------------------------;
+ CMP.B #-1,W ; is the first loaded file?
+ JZ FirstLoadFileHandle ; = -1, is the first LOADed file
+ JGE SetBufLenAndLoadCurSector ; > -1, is a READ file
+ ADD &TOIN,HDLW_BUFofst(X) ; < -1, is not the first LOADed file: in previous handle, add interpret offset to Buffer offset
+ JMP SetBufLenAndLoadCurSector ; thus, the return to this previous LOADed file will be on next char after current LOAD" cmd.
+; ----------------------------------;
+FirstLoadFileHandle ;
+; ----------------------------------;
+ MOV &SOURCE_LEN,&SAVEtsLEN ;
+ SUB &TOIN,&SAVEtsLEN ; save remaining lenght
+ MOV &SOURCE_ADR,&SAVEtsPTR ;
+ ADD &TOIN,&SAVEtsPTR ; save new input org address
+ MOV #SD_ACCEPT,&ACCEPT+2 ; redirect ACCEPT to SD_ACCEPT
+ MOV &SOURCE_LEN,&TOIN ; to quit interpret (same as BACKSLASH)
+ JMP SetBufLenAndLoadCurSector ;
+;; ----------------------------------;
+;FirstLoadFileHandle ;
+;; ----------------------------------;
+; SUB &TOIN,&SOURCE_LEN ;
+; ADD &TOIN,&SOURCE_ADR ;
+; MOV #SD_ACCEPT,&ACCEPT+2 ; redirect ACCEPT to SD_ACCEPT
+; MOV &SOURCE_LEN,&TOIN ; to quit interpret (same as BACKSLASH)
+; JMP SetBufLenAndLoadCurSector ;
+; ----------------------------------;
+
+
+
+; If closed token = -1, restore DefaultInputStream
+; if closed token < -1, restore previous context
+; ==================================;
+CloseHandleT ; <== CLOSE, Read_File, TERM2SD", OPEN_DEL
+; ==================================;
+ MOV &CurrentHdl,T ;
+ MOV #0,&BufferLen ; to inform the user that file is closed
+ CMP #0,T ; no handle?
+ JZ InitHandleRET ; RET
+; ----------------------------------;
+ .IFDEF SD_CARD_READ_WRITE
+ CMP.B #2,HDLB_Token(T) ; updated file ?
+ JNZ CloseHandleHere ; no
+ CALL #WriteBuffer ;SWXY
+ CALL #OPWW_UpdateDirectory ;SWXY
+ .ENDIF
+; ----------------------------------;
+CloseHandleHere ;
+; ----------------------------------;
+ MOV.B HDLB_Token(T),W ; to test W=token below
+ MOV.B #0,HDLB_Token(T) ; close handle
+; ----------------------------------;
+ MOV @T,T ; T = previous handle
+ MOV T,&CurrentHdl ; becomes current handle
+; ----------------------------------;
+CheckCaseOfClosedLoadedFile ;
+; ----------------------------------;
+ ADD.B #1,W ;
+ JZ LastFileLoadClosed ; W=0, this closed LOADed file had not a paren
+ JGE InitHandleRET ; W>0, for READ, WRITE, DEL files
+; ----------------------------------;
+RestorePreviousLoadedFileContext ; W<0, this closed LOADed file had a paren
+; ----------------------------------;
+ MOV HDLW_BUFofst(T),&BufferPtr ; restore BufferPtr saved by SD_ACCEPT before interpreting LOAD cmd line
+ JMP SetBufLenAndLoadCurSector ;
+; ----------------------------------;
+LastFileLoadClosed ;
+; ----------------------------------;
+RestoreDefaultInputStream ; it was the first LOADed filre
+ MOV &SAVEtsLEN,TOS ; restore lenght
+ MOV &SAVEtsPTR,2(PSP) ; restore pointer for interpret
+ MOV #PARENACCEPT,&ACCEPT+2 ; restore (ACCEPT)
+ JMP InitHandleRET ; RET
+; ----------------------------------;
+;RestoreDefaultInputStream ; it was the first LOADed filre
+; MOV &SOURCE_LEN,TOS ; restore lenght
+; MOV &SOURCE_ADR,2(PSP) ; restore pointer for interpret
+; MOV #0,&TOIN ; reset interpret ptr
+; MOV #PARENACCEPT,&ACCEPT+2 ; restore (ACCEPT)
+; JMP InitHandleRET ; RET
+; ----------------------------------;
+
+
+ .IFDEF SD_CARD_READ_WRITE
+
+;-----------------------------------------------------------------------
+; SD_READ_WRITE FORTH words
+;-----------------------------------------------------------------------
+
+;Z READ" --
+; parse string until " is encountered, convert counted string in StringZ
+; then parse stringZ until char '0'.
+; media identifiers "A:", "B:" ... are ignored (only one SD_Card),
+; char "\" as first one initializes rootDir as SearchDir.
+; if file found, if not already open and if free handle...
+; ...open the file as read and return the handle in CurrentHdl.
+; then load first sector in buffer, bufferLen and bufferPtr are ready for read
+; currentHdl keep handle that is flagged as "read".
+
+; to read sequentially next sectors use READ word. A flag is returned : true if file is closed.
+; the last sector so is in buffer.
+
+; if pathname is a directory, change current directory.
+; if an error is encountered, no handle is set, error message is displayed.
+
+; READ" acts also as CD dos command :
+; - READ" a:\misc\" set a:\misc as current directory
+; - READ" a:\" reset current directory to root
+; - READ" ..\" change to parent directory
+
+; to close all files type : WARM (or COLD, RESET)
+
+; ----------------------------------;
+ FORTHWORDIMM "READ\34" ; immediate
+; ----------------------------------;
+READDQ
+ MOV.B #1,W ; W = OpenType
+ JMP Open_File ;
+; ----------------------------------;
+
+;Z WRITE" pathame" -- immediate
+; open or create the file designed by pathname.
+; an error occurs if the file is already opened.
+; the last sector of the file is loaded in buffer, and bufferPtr leave the address of the first free byte.
+; compile state : compile WRITE" pathname"
+; exec state : open or create entry selected by pathname
+; ----------------------------------;
+ FORTHWORDIMM "WRITE\34" ; immediate
+; ----------------------------------;
+WRITEDQ
+ MOV.B #2,W ; W = OpenType
+ JMP Open_File ;
+; ----------------------------------;
+
+
+;Z DEL" pathame" -- immediate
+; compile state : compile DEL" pathname"
+; exec state : DELETE entry selected by pathname
+
+; ----------------------------------;
+ FORTHWORDIMM "DEL\34" ; immediate
+; ----------------------------------;
+DELDQ
+ MOV.B #4,W ; W = OpenType
+ JMP Open_File ;
+; ----------------------------------;
+
+
+ .ENDIF ; SD_CARD_READ_WRITE
+
+;-----------------------------------------------------------------------
+; SD_CARD_LOADER FORTH word
+;-----------------------------------------------------------------------
+
+;Z CLOSE --
+; close current handle
+; ----------------------------------;
+ FORTHWORD "CLOSE" ;
+; ----------------------------------;
+ CALL #CloseHandleT ;
+ mNEXT ;
+; ----------------------------------;
+
+;Z LOAD" pathame" -- immediate
+; compile state : compile LOAD" pathname"
+; exec state : open a file from SD card via its pathname
+; see Open_File primitive for pathname conventions
+; the opened file becomes the new input stream for INTERPRET
+; this command is recursive, limited only by the count of free handles (up to 8)
+
+; LOAD" acts also as dos command "CD" :
+; - LOAD" \misc\" set a:\misc as current directory
+; - LOAD" \" reset current directory to root
+; - LOAD" ..\" change to parent directory
+
+; ----------------------------------;
+ FORTHWORDIMM "LOAD\34" ; immediate
+; ----------------------------------;
+ MOV.B #-1,W ; W = OpenType
+; ----------------------------------;
+
+
+; ======================================================================
+; OPEN FILE primitive
+; ======================================================================
+; Open_File --
+; primitive for LOAD" READ" CREATE" WRITE" DEL"
+; store OpenType on TOS,
+; compile state : compile OpenType, compile SQUOTE and the string of provided pathname
+; exec state : open a file from SD card via its pathname
+; convert counted string found at HERE in a StringZ then parse it
+; media identifiers "A:", "B:" ... are ignored (only one SD_Card),
+; char "\" as first one initializes rootDir as SearchDir.
+; if file found, if not already open and if free handle...
+; ...open the file as read and return the handle in CurrentHdl.
+; if the pathname is a directory, change current directory, no handle is set.
+; if an error is encountered, no handle is set, an error message is displayed.
+
+; ----------------------------------;
+Open_File ; --
+; ----------------------------------;
+ SUB #2,PSP ;
+ MOV TOS,0(PSP) ;
+ MOV W,TOS ; -- Open_type (0=LOAD", 1=READ", 2=WRITE", 4=DEL")
+ CMP #0,&STATE ;
+ JZ OPEN_EXEC ;
+OPEN_COMP ;
+ mDOCOL ; if compile state
+ .word lit,lit,COMMA,COMMA ; compile open_type as literal
+ .word SQUOTE ; compile string_exec + string
+ .word lit,SQUOTE2HERE,COMMA ; compile move in-line string to a counted string at HERE
+ .word lit,ParenOpen,COMMA ; compile (OPEN)
+ .word EXIT
+
+OPEN_EXEC ;
+ mDOCOL ; if exec state
+ .word lit,34,WORDD ; -- open_type HERE
+ FORTHtoASM ;
+ MOV @RSP+,IP ;
+; ----------------------------------;
+ParenOpen ; open_type HERE --
+; ----------------------------------;
+ SUB #2,PSP ; make room for DIRsector
+; ----------------------------------;
+OPN_CountedToStringZ ;
+; ----------------------------------;
+ MOV.B @TOS+,Y ; Y=count, TOS = HERE+1
+ ADD TOS,Y ; Y = end of counted string
+ MOV.B #0,0(Y) ; open_type address_of_stringZ --
+; ----------------------------------;
+OPN_PathName ;
+; ----------------------------------;
+ MOV #1,S ; error 1
+ MOV &DIRClusterL,&ClusterL ;
+ MOV &DIRclusterH,&ClusterH ;
+ CMP.B #0,0(TOS) ; first char = 0 ?
+ JZ OPN_NoPathName ; error 1 ===>
+ CMP.B #':',1(TOS) ; A: B: C: ... in pathname ?
+ JNZ OPN_AntiSlashStartTest ; no
+ ADD #2,TOS ; yes : skip drive because not used, only one SD_card
+OPN_AntiSlashStartTest ;
+ CMP.B #5Ch,0(TOS) ; "\" as first char ?
+ JNZ OPN_SearchDirSector ; no
+ ADD #1,TOS ; yes : skip '\' char
+ MOV &FATtype,&ClusterL ; FATtype = 1 as FAT16 RootDIR, FATtype = 2 = FAT32RootDIR
+ MOV #0,&ClusterH ;
+; ----------------------------------;
+OPN_EndOfDIRstringZtest ; <=== dir found in path
+; ----------------------------------;
+ CMP.B #0,0(TOS) ; End of pathname ?
+ JZ OPN_SetCurrentDIR ; yes
+; ----------------------------------;
+OPN_SearchDirSector ;
+; ----------------------------------;
+ MOV TOS,&Pathname ; save name addr
+ CALL #ComputeClusFrstSect ; output: SectorHL
+ MOV #32,0(PSP) ; preset countdown for FAT16 RootDIR sectors
+ CMP #2,&FATtype ; FAT32?
+ JZ OPN_SetDirSectors ; yes
+ CMP &ClusterL,&FATtype ; FAT16 AND RootDIR ?
+ JZ OPN_LoadSectorDir ; yes
+OPN_SetDirSectors ;
+ MOV &SecPerClus,0(PSP) ;
+; ----------------------------------;
+OPN_LoadSectorDir ; <=== Dir Sector loopback
+; ----------------------------------;
+ CALL #ReadSector ;SWX
+; ----------------------------------;
+ MOV #2,S ; prepare no such file error
+ MOV #0,W ; init entries count
+; ----------------------------------;
+OPN_SearchEntryInSector ; <=== DIR Entry loopback
+; ----------------------------------;
+ MOV W,Y ; 1
+ .word 0E58h ; 5 RLAM #4,Y --> * 16
+ ADD Y,Y ; 1 --> * 2
+ MOV Y,&EntryOfst ; EntryOfst points to first free entry
+ CMP.B #0,BUFFER(Y) ; free entry ? (end of entries in DIR)
+ JZ OPN_NoSuchFile ; error 2 NoSuchFile, used by create ===>
+ MOV #8,X ; count of chars in entry name
+OPN_CompareName8chars ;
+ CMP.B @TOS+,BUFFER(Y) ; compare Pathname(char) with DirEntry(char)
+ JNZ OPN_FirstCharMismatch ;
+ ADD #1,Y ;
+ SUB #1,X ;
+ JNZ OPN_CompareName8chars ; loopback if chars 1 to 7 of stringZ and DirEntry are equal
+ ADD #1,TOS ; 9th char of Pathname is always a dot
+; ----------------------------------;
+OPN_FirstCharMismatch ;
+ CMP.B #'.',-1(TOS) ; FirstNotEqualChar of Pathname = dot ?
+ JZ OPN_DotFound ;
+; ----------------------------------;
+OPN_DotNotFound ;
+; ----------------------------------;
+ ADD #3,X ; for next cases not equal chars of entry until 11 must be spaces
+ CALL #ParseEntryNameSpaces ; for X + 3 chars
+ JNZ OPN_EntryMismatch ; if a char entry <> space
+OPN_AntiSlashTest ;
+ CMP.B #5Ch,-1(TOS) ; FirstNotEqualChar of Pathname = "\" ?
+ JZ OPN_EntryFound ;
+OPN_EndOfStringZtest ;
+ CMP.B #0,-1(TOS) ; FirstNotEqualChar of Pathname = 0 ?
+ JZ OPN_EntryFound ;
+; ----------------------------------;
+OPN_EntryMismatch ;
+; ----------------------------------;
+ MOV &pathname,TOS ; reload Pathname
+ ADD #1,W ; inc entry
+ CMP #16,W ; 16 entry in a sector
+ JNZ OPN_SearchEntryInSector ; ===> loopback for search same sector next entry
+; ----------------------------------;
+ ADD #1,&SectorL ;
+ ADDC #0,&SectorH ;
+ SUB #1,0(PSP) ; dec count of Dir sectors
+ JNZ OPN_LoadSectorDir ; ===> loopback for next DIR sector
+; ----------------------------------;
+ MOV #4,S ;
+ JMP OPN_EndOfDIR ; error 4 ===>
+; ----------------------------------;
+
+; ----------------------------------;
+OPN_DotFound ; not equal chars of entry name until 8 must be spaces
+; ----------------------------------;
+ CMP.B #'.',-2(TOS) ; LastCharEqual = dot ?
+ JZ OPN_EntryMismatch ; case of first DIR entry = "." and Pathname = "..\"
+ CALL #ParseEntryNameSpaces ; parse X spaces, X{0,...,7}
+ JNZ OPN_EntryMismatch ; if a char entry <> space
+ MOV #3,X ;
+OPN_CompareExtChars ;
+ CMP.B @TOS+,BUFFER(Y) ; compare stringZ(char) with DirEntry(char)
+ JNZ OPN_ExtNotEqualChar ;
+ ADD #1,Y ;
+ SUB #1,X ;
+ JNZ OPN_CompareExtChars ; nothing to do if chars equal
+ JMP OPN_EntryFound ;
+OPN_ExtNotEqualChar ;
+ CMP.B #0,-1(TOS) ;
+ JNZ OPN_EntryMismatch ;
+ CMP.B #5Ch,-1(TOS) ; FirstNotEqualChar = "\" ?
+ JNZ OPN_EntryMismatch ;
+ CALL #ParseEntryNameSpaces ; parse X spaces, X{0,...,3}
+ JNZ OPN_EntryMismatch ; if a char entry <> space
+; ----------------------------------;
+OPN_EntryFound ; Y points on the file attribute (11th byte of entry)
+; ----------------------------------;
+ MOV &EntryOfst,Y ; reload DIRentry
+ MOV BUFFER+26(Y),&ClusterL ; first clusterL of file
+ MOV BUFFER+20(Y),&ClusterH ; first clusterT of file, always 0 if FAT16
+OPN_EntryFoundNext
+ BIT.B #10h,BUFFER+11(Y) ; test if Directory or File
+ JZ OPN_FileFound ;
+; ----------------------------------;
+OPN_DIRfound ; entry is a DIRECTORY
+; ----------------------------------;
+ CMP #0,&ClusterH ; case of ".." entry, when parent directory is root
+ JNZ OPN_DIRfoundNext ;
+ CMP #0,&ClusterL ; case of ".." entry, when parent directory is root
+ JNZ OPN_DIRfoundNext ;
+ MOV &FATtype,&ClusterL ; set cluster as RootDIR cluster
+OPN_DIRfoundNext ;
+ CMP.B #0,-1(TOS) ; FirstNotEqualChar = 0 ?
+ JNZ OPN_EndOfDIRstringZtest ; no : FirstNotEqualChar = "\"
+; ----------------------------------;
+OPN_SetCurrentDIR ; -- open_type DIRsector ptr
+; ----------------------------------;
+ MOV &ClusterL,&DIRClusterL ;
+ MOV &ClusterH,&DIRclusterH ;
+ ADD #4,PSP ; -- ptr
+ MOV @PSP+,TOS ; --
+ MOV @RSP+,IP ;
+ mNEXT ; happy end
+; ----------------------------------;
+OPN_FileFound ; -- open_type DIRsector ptr
+; ----------------------------------;
+ MOV 2(PSP),W
+ CALL #GetFreeHandle ;STWXY init handle(HDLL_DIRsect,HDLW_DIRofst,HDLL_FirstClus = HDLL_CurClust,HDLL_CurSize)
+; ----------------------------------; output : T = CurrentHdl*, S = ReturnError, Y = DIRentry offset
+OPN_NomoreHandle ; S = error 16
+OPN_alreadyOpen ; S = error 8
+OPN_EndOfDIR ; S = error 4
+OPN_NoSuchFile ; S = error 2
+OPN_NoPathName ; S = error 1
+ ADD #2,PSP ; -- open_type ptr
+ MOV @PSP+,W ; -- ptr W = open_type
+ MOV @PSP+,TOS ; --
+; ----------------------------------; then go to selected OpenType subroutine (OpenType = W register)
+
+
+; ======================================================================
+; LOAD" primitive as part of Open_File
+; input from open: S = OpenError, W = open_type, SectorHL = DIRsectorHL,
+; Buffer = [DIRsector], ClusterHL = FirstClusterHL
+; from open(GetFreeHandle): Y = DIRentry, T = CurrentHdl
+; output: nothing else abort on error
+; ======================================================================
+
+; ----------------------------------;
+ .IFDEF SD_CARD_READ_WRITE ;
+ CMP.B #-1,W ; open_type = LOAD"
+ JNZ OPEN_QREAD ; next step
+ .ENDIF ;
+; ----------------------------------; here W is free
+OPEN_LOAD ;
+; ----------------------------------;
+ CMP #0,S ; open file happy end ?
+ JNZ OPEN_Error ; no
+; ----------------------------------;
+ MOV #NEXT,&YEMIT ; set NOECHO, as does TERATERM before sending a file to the target.
+; ----------------------------------;
+ mNEXT
+; ----------------------------------;
+
+
+
+; ----------------------------------;
+OPEN_Error ; S= error
+; ----------------------------------;
+; Error 1 : PathNameNotFound ; S = error 1
+; Error 2 : NoSuchFile ; S = error 2
+; Error 4 : DIRisFull ; S = error 4
+; Error 8 : alreadyOpen ; S = error 8
+; Error 16 : NomoreHandle ; S = error 16
+; ----------------------------------;
+ mDOCOL ; set ECHO, type Pathname, type #error, type "< OpenError"; no return
+ .word XSQUOTE ;
+ .byte 11,"< OpenError" ;
+SD_ERROR
+ .word ECHO ;
+ .word HERE,COUNT,TYPE,SPACE ;
+ .word BRAN,SD_QABORTYES ; to insert S error as flag, no return
+; ----------------------------------;
+
+
+
+
+
+
+
--- /dev/null
+; -*- coding: utf-8 -*-
+; forthMSP430FR_SD_lowLvl.asm
+
+; Copyright (C) <2017> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+; =====================================================================
+; goal : accept 64 MB up to 64 GB SD_CARD
+; =====================================================================
+; thus FAT and RootClus logical sectors are word addressable.
+
+; FAT is a little endian structure.
+; CMD frame is sent as big endian.
+
+; we assume that SDSC Card (up to 2GB) is FAT16 with a byte addressing
+; and that SDHC Card (4GB up to 32GB) is FAT32 with a sector addressing (sector = 512 bytes)
+
+; ref. https://en.wikipedia.org/wiki/Extended_boot_record
+; ref. https://en.wikipedia.org/wiki/Partition_type
+
+; Formatage FA16 d'une SDSC Card 2GB
+; First sector of physical drive (sector 0) content :
+; ---------------------------------------------------
+; dec@| HEX@ = HEX decimal
+; 446 |0x1BE : partition table first record ==> logical drive 0
+; 446 |0x1CE : partition table 2th record ==> logical drive 1
+; 446 |0x1DE : partition table 3th record ==> logical drive 2
+; 446 |0x1EE : partition table 4th record ==> logical drive 3
+
+; partition record content :
+; ---------------------------------------------------
+; dec@|HEX@ = HEX decimal
+; 0 |0x00 = 0x00 : not bootable
+; 1 |0x01 = 02 0C 00 : Org Cylinder/Head/Sector offset (CHS-addressing) = not used
+; 4 |0x04 = 0x0E : type FAT16 using LBA addressing = 14 ==> FAT16
+; 5 |0x05 = ED 3F EE : End Cylinder/Head/Sector offset (CHS-addressing) = not used
+; 8 |0x08 = 00 20 00 00 : sector offset of logical drive = 8192
+; 12 |0x0C = 00 40 74 00 : sector size of logical drive = 7618560 sectors
+
+; 450 |0x04 = 0x0E : type FAT16 using LBA addressing = 14 ==> set FATtype = FAT16 with byte CMD addressing
+; 454 |0x1C6 = 89 00 : FirstSector (of logical drive 0) BS_FirstSector = 137
+
+
+; ref. https://www.compuphase.com/mbr_fat.htm#BOOTSECTOR
+
+; FirstSector of logical drive (sector 0) content :
+; -------------------------------------------------
+; dec@| HEX@ = HEX decimal
+; 11 | 0x0B = 00 02 : 512 bytes/sector BPB_BytsPerSec = 512
+; 13 | 0x0D = 40 : 64 sectors/cluster BPB_SecPerClus = 64
+; 14 | 0x0E = 01 00 : 2 reserved sectors BPB_RsvdSecCnt = 1
+; 16 | 0x10 = 02 : 2 FATs BPB_NumFATs = 2 (always 2)
+; 17 | 0x11 = 00 02 : 512 entries/directory BPB_RootEntCnt = 512
+; 19 | 0x13 = 00 00 : BPB_TotSec16 (if < 65535) BPB_TotSec16 = 0
+; 22 | 0x16 = EB 00 : 235 sectors/FAT (FAT16) BPB_FATSize = 235
+; 32 | 0x20 = 77 9F 3A 00 : 3841911 total sectors BPB_TotSec32 = 3841911
+; 54 | 0x36 = "FAT16" BS_FilSysType (not used)
+
+; all values below are evaluated in logical sectors
+; FAT1 = BPB_RsvdSecCnt = 1
+; FAT2 = BPB_RsvdSecCnt + BPB_FATSz32 = 1 + 235 = 236
+; OrgRootDirL = BPB_RsvdSecCnt + (BPB_FATSize * BPB_NumFATs) = 471
+; RootDirSize = BPB_RootEntCnt * 32 / BPB_BytsPerSec = 32 sectors
+; OrgDatas = OrgRootDir + RootDirSize = 503
+; OrgCluster = OrgRootDir - 2*BPB_SecPerClus = 375 (virtual value)
+; FirstSectorOfCluster(n) = OrgCluster + n*BPB_SecPerClus ==> cluster(3) = 705
+
+; ====================================================================================
+
+; Formatage FA32 d'une SDSC Card 8GB
+; First sector of physical drive (sector 0) content :
+; ---------------------------------------------------
+; dec@| HEX@ = HEX decimal
+; 446 |0x1BE : partition table first record ==> logical block 0
+; 446 |0x1CE : partition table 2th record ==> logical block 1
+; 446 |0x1DE : partition table 3th record ==> logical block 2
+; 446 |0x1EE : partition table 4th record ==> logical block 3
+
+; partition record content :
+; ---------------------------------------------------
+; dec@|HEX@ = HEX decimal
+; 0 |0x00 = 0x00 : not bootable
+; 1 |0x01 = 82 03 00 : Org CHS offset (Cylinder/Head/Sector) = not used
+; 4 |0x04 = 0x0C : type FAT32 using LBA addressing = 12 ==> set FATtype = FAT32 with sector CMD addressing
+; 5 |0x05 = 82 03 00 : End offset (Cylinder/Head/Sector offset) = not used
+; 8 |0x08 = 00 20 00 00 : sector offset of logical block = 8192
+; 12 |0x0C = 00 40 74 00 : sector size of logical block = 7618560
+
+; 454 |0x1C6 = 00 20 00 00 : FirstSector (of logical drive 0) BS_FirstSector = 8192
+
+;
+; FirstSector of logical block (sector 0) content :
+; -------------------------------------------------
+; dec@| HEX@ = HEX decimal
+; 11 | 0x0B = 00 02 : 512 bytes/sector BPB_BytsPerSec = 512
+; 13 | 0x0D = 08 : 8 sectors/cluster BPB_SecPerClus = 8
+; 14 | 0x0E = 20 00 : 32 reserved sectors BPB_RsvdSecCnt = 32
+; 16 | 0x10 = 02 : 2 FATs BPB_NumFATs = 2 (always 2)
+; 17 | 0x11 = 00 00 : 0 BPB_RootEntCnt = 0 (always 0 for FAT32)
+
+; 32 | 0x20 = 00 C0 EC 00 : BPB_TotSec32 BPB_TotSec32 = 15515648
+; 36 | 0x24 = 30 3B 00 00 : BPB_FATSz32 BPB_FATSz32 = 15152
+; 40 | 0x28 = 00 00 : BPB_ExtFlags BPB_ExtFlags
+; 44 | 0x2C = 02 00 00 00 : BPB_RootClus BPB_RootClus = 2
+; 48 | 0x30 = 01 00 : BPB_FSInfo BPB_FSInfo = 1
+; 50 | 0x33 = 06 00 : BPB_BkBootSec BPB_BkBootSec = 6
+; 82 | 0x52 = "FAT32" : BS_FilSysType BS_FilSysType (not used)
+
+
+; all values below are evaluated in sectors
+; FAT1 = BS_FirstSector + BPB_RsvdSecCnt = 8192 + 32 = 8224
+; FAT2 = BS_FirstSector + BPB_RsvdSecCnt + BPB_FATSz32 = 8192 + 32 + 15152 = 23376
+; OrgRootDirL = BS_FirstSector + BPB_RsvdSecCnt + (BPB_FATSz32 * BPB_NumFATs) = 8192 + 32 + 15152*2 = 38528
+; OrgCluster = OrgRootDir - 2*BPB_SecPerClus = 38512
+; RootDirSize = BPB_RootEntCnt * 32 / BPB_BytsPerSec = 0
+; OrgDatas = OrgRootDir + RootDirSize = 38512
+; FirstSectorOfCluster(n) = OrgCluster + n*BPB_SecPerClus ==> cluster(6) = 38560
+
+
+
+BytsPerSec .equ 512
+
+; all sectors are computed as logical, then physically translated at last time by RW_Sector_CMD
+
+; in SPI mode CRC is not required, but CMD frame must be ended with a stop bit
+; ==================================;
+RW_Sector_CMD ;WX <=== CMD17 or CMD24 (read or write Sector CMD)
+; ==================================;
+ BIC.B #SD_CS,&SD_CSOUT ; SD_CS low
+ BIT.B #SD_CD,&SD_CDIN ; memory card present ?
+ JZ ComputePhysicalSector ; yes
+ MOV #COLD,PC ; no: force COLD
+; ----------------------------------;
+ComputePhysicalSector ;
+; ----------------------------------;
+ ADD &BS_FirstSectorL,W ;3
+ ADDC &BS_FirstSectorH,X ;3
+; ----------------------------------;
+ MOV #1,&SD_CMD_FRM ;3 $(01 00 xx xx xx CMD) (set stop bit)
+ CMP #2,&FATtype ;3 FAT32 ?
+ JZ FAT32_CMD ;2 yes
+FAT16_CMD ; FAT16 : CMD17/24 byte address = Sector * BPB_BytsPerSec
+ ADD W,W ; shift left one SectorL
+ ADDC.B X,X ;
+ MOV W,&SD_CMD_FRM+2 ; $(01 00 ll LL xx CMD)
+ MOV.B X,&SD_CMD_FRM+4 ; $(01 00 ll LL hh CMD)
+ JMP SDbusyLoop
+FAT32_CMD ; FAT32 : CMD17/24 sector address
+ MOV.B W,&SD_CMD_FRM+1 ;3 $(01 ll xx xx xx CMD)
+ SWPB W ;1
+ MOV.B W,&SD_CMD_FRM+2 ;3 $(01 ll LL xx xx CMD)
+ MOV.B X,&SD_CMD_FRM+3 ;3 $(01 ll LL hh xx CMD)
+ SWPB X ;1
+ MOV.B X,&SD_CMD_FRM+4 ;3 $(01 ll LL hh HH CMD)
+; ==================================;
+SDbusyLoop ; <=== CMD41, CMD1, CMD16 (R1 expected response = 0 = ready)
+; ==================================;
+ CALL #SPI_GET ;
+ CMP.B #-1,W ; FFh expected value <==> MISO = 1 = not busy
+ JNE SDbusyLoop ; loop back while yet busy
+ MOV #0,W ; W = expected R1 response = ready = 0, for CMD41, CMD1, CMD16, CMD17, CMD24
+
+; ==================================;
+sendCommand ;X <=== CMD0, CMD8, CMD55 (W = R1 expected response = 1 = idle)
+; ==================================;
+ ; input : SD_CMD_FRM : {CRC,byte_l,byte_L,byte_h,byte_H,CMD}
+ ; W = expected return value
+ ; output W is unchanged, flag Z is positionned
+ ; reverts CMD bytes before send : $(CMD hh LL ll 00 CRC)
+ MOV #5,X ; X = SD_CMD_FRM index AND countdown
+; ----------------------------------;
+Send_CMD_PUT ; performs little endian --> big endian conversion
+; ----------------------------------;
+ MOV.B SD_CMD_FRM(X),&SD_TXBUF ;5
+ CMP #0,&SD_BRW ;3 full speed ?
+ JZ FullSpeedSend ;2 yes
+Send_CMD_Loop ; no: case of low speed during memCardInit
+ BIT #UCRXIFG,&SD_IFG ;3
+ JZ Send_CMD_Loop ;2
+ CMP.B #0,&SD_RXBUF ;3 to clear UCRXIFG
+FullSpeedSend ;
+; NOP ;0 NOPx adjusted to avoid SD error
+ SUB.B #1,X ;1
+ JHS Send_CMD_PUT ;2 U>= : don't skip SD_CMD_FRM(0) !
+
+ ; host must provide height clock cycles to complete operation
+ ; here X=255, so wait for CMD return expected value with PUT FFh 256 times
+
+; MOV #4,X ; to pass made in PRC SD_Card init
+; MOV #16,X ; to pass Transcend SD_Card init
+; MOV #32,X ; to pass Panasonic SD_Card init
+; MOV #64,X ; to pass SanDisk SD_Card init
+; MOV #1000,X ; max value
+; ----------------------------------;
+Wait_Command_Response ; expect W = return value during X = 255 delay time
+; ----------------------------------;
+ SUB #1,X ;1
+ JN SPI_WAIT_RET ;2 error on time out with SR(Z) = 0
+ MOV.B #-1,&SD_TXBUF ;3 PUT FFh
+ CMP #0,&SD_BRW ;3 full speed ?
+ JZ FullSpeedGET ;2 yes
+cardResp_Getloop ; no: case of low speed during memCardInit
+ BIT #UCRXIFG,&SD_IFG ;3
+ JZ cardResp_Getloop ;2
+FullSpeedGET ;
+; NOP2 ;2 NOPx adjusted to avoid SD_error
+ CMP.B &SD_RXBUF,W ;3 return value = ExpectedValue ?
+ JNZ Wait_Command_Response ;2
+SPI_WAIT_RET ; SR(Z) = 1 <==> Return value = expected value
+ RET ; expected value = W is unchanged
+; ----------------------------------;
+
+
+; SPI_GET and SPI_PUT are adjusted for SD_CLK = MCLK
+; PUT value must be a word or byte:byte because little endian to big endian conversion
+
+; ==================================;
+SPI_GET ; PUT(FFh)
+; ==================================; output : W = received byte, X = 0 always
+ MOV #1,X ;1
+; ==================================;
+SPI_X_GET ; PUT(FFh) X time
+; ==================================; output : W = last received byte, X = 0
+ MOV #-1,W ;1
+; ==================================;
+SPI_PUT ; PUT(W) X time
+; ==================================; output : W = last received byte, X = 0
+ SWPB W ;1
+ MOV.B W,&SD_TXBUF ;3 put W high byte then W low byte and so forth that performs little to big endian conversion
+ CMP #0,&SD_BRW ;3 full speed ?
+ JZ FullSpeedPut ;2
+SPI_PUTWAIT BIT #UCRXIFG,&SD_IFG ;3
+ JZ SPI_PUTWAIT ;2
+ CMP.B #0,&SD_RXBUF ;3 reset RX flag
+FullSpeedPut
+; NOP ;0 NOPx adjusted to avoid SD error
+ SUB #1,X ;1
+ JNZ SPI_PUT ;2
+SPI_PUT_END MOV.B &SD_RXBUF,W ;3
+ RET ;4
+; ----------------------------------;
+
+; ==================================;
+readFAT1SectorW ; read a FAT1 sector
+; ==================================;
+ ADD &OrgFAT1,W ;
+; ==================================;
+readSectorW ; read a logical sector up to 65535 (case of FAT1,FAT2,RootDIR)
+; ==================================;
+ MOV #0,X ;
+; ==================================;
+readSectorWX ; read a logical sector
+; ==================================;
+ BIS #1,S ; preset sd_read error
+ MOV.B #51h,&SD_CMD_FRM+5 ; CMD17 = READ_SINGLE_BLOCK
+ CALL #RW_Sector_CMD ; which performs logical sector to physical sector then little endian to big endian conversions
+ JNE SD_CARD_ERROR ; time out error if R1 <> 0
+; ----------------------------------;
+WaitFEhResponse ; wait SD_Card response FEh
+; ----------------------------------;
+ CALL #SPI_GET ;
+ CMP.B #-2,W ; FEh expected value
+ JNZ WaitFEhResponse ;
+; ----------------------------------;
+ReadSectorLoop ; 16 cycles loop read byte, starts with X = 0
+; ----------------------------------;
+ MOV.B #-1,&SD_TXBUF ; 3 put FF
+ NOP3 ; 3 NOPx adjusted to avoid read SD_error
+ ADD #1,X ; 1
+ CMP #BytsPerSec,X ; 2
+ MOV.B &SD_RXBUF,BUFFER-1(X) ; 5
+ JNZ ReadSectorLoop ; 2
+; ----------------------------------;
+ReadSkipCRC16 ; not used in SPI mode
+; ----------------------------------;
+ MOV #2,X ;
+ CALL #SPI_X_GET ;
+; ----------------------------------;
+ReadWriteHappyEnd ;
+; ----------------------------------;
+ BIC #3,S ; reset read and write errors
+ BIS.B #SD_CS,&SD_CSOUT ; SD_CS = high
+ RET ;
+; ----------------------------------;
+
+ .IFDEF SD_CARD_READ_WRITE
+
+; ==================================;
+WriteSectorW ; write a logical sector up to 65535 (FAT1,FAT2,RootDIR)
+; ==================================;
+ MOV #0,X ;
+; ==================================;
+WriteSectorWX ; write a logical sector
+; ==================================;
+ BIS #2,S ; preset sd_write error
+ MOV.B #058h,SD_CMD_FRM+5 ; CMD24 = WRITE_SINGLE_BLOCK
+ CALL #RW_Sector_CMD ; which performs logical sector to physical sector then little endian to big endian conversions
+ JNE SD_CARD_ERROR ; ReturnError = 2
+ MOV #0FFFEh,W ; PUT FFFEh as preamble requested for sector write
+ MOV #2,X ; to put 16 bits value
+ CALL #SPI_PUT ; which performs little endian to big endian conversion
+; ----------------------------------;
+WriteSectorLoop ; 11 cycles loop write, starts with X = 0
+; ----------------------------------;
+ MOV.B BUFFER(X),&SD_TXBUF ; 5
+ NOP ; 1 NOPx adjusted to avoid write SD_error
+ ADD #1,X ; 1
+ CMP #BytsPerSec,X ; 2
+ JNZ WriteSectorLoop ; 2
+; ----------------------------------;
+WriteSkipCRC16 ; not used in SPI mode
+; ----------------------------------;
+ MOV #3,X ; PUT 2 bytes to skip CRC16
+ CALL #SPI_X_GET ; + 1 byte to get data token in W
+; ----------------------------------;
+CheckWriteState ;
+; ----------------------------------;
+ BIC.B #0E1h,W ; apply mask for Data response
+ CMP.B #4,W ; data accepted
+ JZ ReadWriteHappyEnd ;
+; ----------------------------------;
+
+ .ENDIF ; SD_CARD_READ_WRITE
+
+; SD Error n°
+; High byte
+; 1 = CMD17 read error
+; 2 = CMD24 write error
+; 4 = CMD0 time out (GO_IDLE_STATE)
+; 8 = CMD1 time out (SEND_OP_COND), reserved for MMC_Card
+; 10 = ACMD41 time out (APP_SEND_OP_COND)
+; 20 = CMD16 time out (SET_BLOCKLEN)
+; 40 = not FAT16/FAT32 media, low byte = partition ID
+
+; low byte, if CMD R1 response : |0|7|6|5|4|3|2|1|
+; 1th bit = In Idle state
+; 2th bit = Erase reset
+; 3th bit = Illegal command
+; 4th bit = Command CRC error
+; 5th bit = erase sequence error
+; 6th bit = address error
+; 7th bit = parameter error
+
+; ----------------------------------;
+SD_CARD_ERROR ; <=== SD_INIT errors 4,8,10,20,40
+; ----------------------------------;
+ BIS.B #SD_CS,&SD_CSOUT ; SD_CS = high
+ SWPB S ; High Level error in High byte
+ ADD &SD_RXBUF,S ; add SPI(GET) return value to high level error
+ mDOCOL ;
+ .word XSQUOTE ;
+ .byte 11,"< SD Error!" ;
+; ----------------------------------;
+SD_QABORTYES ; <=== OPEN/READ and WRITE errors
+; ----------------------------------;
+ FORTHtoASM ;
+ SUB #4,PSP ;
+ MOV TOS,2(PSP) ;
+ MOV &BASE,0(PSP) ;
+ MOV #10h,&BASE ; select hex
+ MOV S,TOS ;
+ ASMtoFORTH ;
+ .word UDOT ;
+ .word FBASE,STORE ; restore base
+ .word QABORTYES ;
+; ----------------------------------;
+
--- /dev/null
+; -*- coding: utf-8 -*-
+; DTCforthMSP430FR5xxxSD_RW.asm
+
+; and only for FR5xxx and FR6xxx with RTC_B or RTC_C hardware if you want write file with date and time.
+
+; Tested with MSP-EXP430FR5969 launchpad
+; Copyright (C) <2015> <J.M. THOORENS>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+
+; ======================================================================
+; READ" primitive as part of OpenPathName
+; input from open: S = OpenError, W = open_type, SectorHL = DIRsectorHL,
+; Buffer = [DIRsector], ClusterHL = FirstClusterHL
+; from open(GetFreeHandle): Y = DIRentry, T = CurrentHdl
+; output: nothing else abort on error
+; ======================================================================
+
+; ----------------------------------;
+OPEN_QREAD ;
+ CMP #1,W ; open_type = READ" ?
+ JNZ OPEN_QWRITE ; no : goto next step
+; ----------------------------------;
+OPEN_READ ;
+; ----------------------------------;
+ CMP #0,S ; open file happy end ?
+ JNZ OPEN_Error ; no
+ mNEXT ;
+; ----------------------------------;
+
+;Z READ -- f
+; sequentially read a file opened by READ".
+; sectors are loaded in BUFFER and BufferLen leave the count of loaded bytes.
+; when the last sector of file is loaded in buffer, the handle is automatically closed and flag is true (<>0).
+
+; ----------------------------------;
+ FORTHWORD "READ" ; -- fl closed ?
+; ----------------------------------;
+READ
+ SUB #2,PSP ;
+ MOV TOS,0(PSP) ;
+ MOV &CurrentHdl,TOS ;
+ CALL #Read_File ;SWX
+ SUB &CurrentHdl,TOS ; -- fl if fl <>0 (if Z=0) handle is closed
+ mNEXT ;
+; ----------------------------------;
+
+
+;-----------------------------------------------------------------------
+; WRITE" (CREATE part) subroutines
+;-----------------------------------------------------------------------
+
+; parse all FAT sectors until free cluster is found
+; this NewCluster is marked as the end's one (-1)
+
+
+; input : CurFATsector
+; use SWX registers
+; output: W = new FATsector, BUFFER = [new FATsector], NewCluster
+; SectorL is unchanged, FATS are not updated.
+; S = 2 --> Disk FULL error
+; ----------------------------------;
+SearchNewCluster ; <== CREATE file, WRITE_File
+; ----------------------------------;
+ MOV #2,S ; preset disk full return error
+ PUSH &CurFATsector ; last known free cluster sector
+ MOV &FATtype,Y ;
+ ADD Y,Y ; Y = bytes size of Cluster number (2 or 4)
+; ----------------------------------;
+LoadFATsectorInBUF ; <== IncrementFATsector
+; ----------------------------------;
+ MOV @RSP,W ; W = FATsector
+ CMP W,&FATSize ;
+ JZ OPW_Error ; FATsector = FATSize ===> abort disk full
+ CALL #ReadFAT1SectorW ;SWX
+ MOV #0,X ; init FAToffset
+; ----------------------------------;
+SearchFreeClustInBUF ; <== SearchNextCluster
+; ----------------------------------;
+ CMP #2,Y ; FAT16 Cluster size ?
+ JZ ClusterLowWordTest ; yes
+ClusterHighWordTest ;
+ CMP #0,BUFFER+2(X) ; cluster address hi word = 0 ?
+ JNZ SearchNextNewCluster ;
+ClusterLowWordTest ;
+ CMP #0,BUFFER(X) ; Cluster address lo word = 0 ?
+ JZ GNC_FreeClusterFound ;
+SearchNextNewCluster ;
+ ADD Y,X ; increment BUFFER offset by size of Cluster address
+ CMP #BytsPerSec,X ;
+ JNE SearchFreeClustInBUF ; loopback while X < BytsPerSec
+IncrementFATsector ;
+ ADD #1,0(RSP) ; increment FATsector
+ JMP LoadFATsectorInBUF ; loopback
+; ----------------------------------;
+GNC_FreeClusterFound ; Y = cluster number low word in BUFFER = FATsector
+; ----------------------------------;
+ MOV #0,S ; clear error
+ MOV.B @RSP,W ; W = 0:FATsectorLo
+ MOV #-1,BUFFER(X) ; mark NewCluster low word as end cluster (0xFFFF) in BUFFER
+ CMP #2,Y ; Y = FAT16 size of Cluster number ?
+ JZ FAT16EntryToClusterNum ; yes
+ MOV #0FFFh,BUFFER+2(X) ; no: mark NewCluster high word as end cluster (0x0FFF) in BUFFER
+; ----------------------------------;
+FAT32EntryToClusterNum ; convert FAT32 cluster address to cluster number
+; ----------------------------------;
+ RRA X ; X = FATOffset>>1, FAToffset is byte size
+ SWPB W ; W = FATsectorLo:0
+ ADD W,X ; X = FATsectorLo:FATOffset>>1
+ MOV.B 1(RSP),W ; W = FATsectorHi
+ RRA W ; W = FATsectorHi>>1
+ RRC X ; X = (FATsectorLo:FAToffset>>1)>>1 = FATsectorLo>>1:FAToffset>>2
+ MOV W,&NewClusterH ; NewClusterH = FATsectorHi>>1
+ MOV X,&NewClusterL ; NewClusterL = FATsectorLo>>1:FAToffset>>2
+ JMP SearchNewClusterEnd ; max cluster = 7FFFFF ==> 1FFFFFFF sectors ==> 256 GB
+; ----------------------------------;
+FAT16EntryToClusterNum ; convert FAT16 address of Cluster in cluster number
+; ----------------------------------;
+ RRA X ; X = Offset>>1, offset is word < 256
+ MOV.B X,&NewClusterL ; X = NewCluster numberLO (byte)
+ MOV.B W,&NewClusterL+1 ; W = NewCluster numberHI (byte)
+ MOV #0,&NewClusterH ;
+; ----------------------------------;
+SearchNewClusterEnd ;
+; ----------------------------------;
+ MOV @RSP+,W ; W = FATsector
+ MOV W,&CurFATsector ; refresh CurrentFATsector
+ RET ;
+; ----------------------------------;
+
+
+; update FATs with BUFFER content.
+; input : FATsector, FAToffset, BUFFER = [FATsector]
+; use : SWX registers
+; ----------------------------------; else update FATsector of the old cluster
+UpdateFATsSectorW ;
+; ----------------------------------;
+ PUSH W ;
+ ADD &OrgFAT1,W ; update FAT#1
+ CALL #WriteSectorW ; SWX
+ MOV @RSP+,W ;
+ ADD &OrgFAT2,W ; update FAT#2
+ MOV #WriteSectorW,PC ; then ret
+; ----------------------------------;
+
+
+
+; FAT16/32 format for date and time in a DIR entry
+; create time : offset 0Dh = 0 to 200 centiseconds, not used.
+; offset 0Eh = 0bhhhhhmmmmmmsssss, with : s=seconds*2, m=minutes, h=hours
+; access time : offset 14h = always 0, not used as date
+; modified time : ofsset 16h = 0bhhhhhmmmmmmsssss, with : s=seconds*2, m=minutes, h=hours
+; dates : offset 10, 12, 18 = 0byyyyyyymmmmddddd, with : y=year-1980, m=month, d=day
+
+; ----------------------------------; input:
+GetYMDHMSforDIR ;X=date, W=TIME
+; ----------------------------------;
+ .IFDEF LF_XTAL ;
+ .IFNDEF RTC ; RTC_B or RTC_C select
+; ----------------------------------;
+ BIT.B #RTCHOLD,&RTCCTL1 ; rtc is running ?
+ JNZ SD_RW_RET ; no
+WaitRTC ; yes
+ BIT.B #RTCRDY,&RTCCTL1 ; rtc values are valid ?
+ JZ WaitRTC ; no
+ MOV.B &RTCSEC,W ; yes
+ RRA.B W ; 2 seconds accuracy time
+ MOV.B &RTCDAY,X ;
+ MOV.B #32,&MPY ; common MPY for minutes and months
+ MOV.B &RTCMIN,&OP2 ;
+ ADD &RES0,W ;
+ MOV.B &RTCMON,&OP2 ;
+ ADD &RES0,X ;
+ MOV.B &RTCHOUR,&MPY ;
+ MOV #2048,&OP2 ;
+ ADD &RES0,W ;
+ MOV &RTCYEAR,&MPY ;
+ SUB #1980,&MPY ;
+ MOV #512,&OP2 ;
+ ADD &RES0,X ;
+ .ELSEIF
+ MOV #0,X ; X=DATE
+ MOV #0,W ; W=TIME
+ .ENDIF
+ .ENDIF
+SD_RW_RET ;
+ RET ;
+; ----------------------------------;
+
+
+; when create filename, forbidden chars are skipped
+ForbiddenChars ; 15 forbidden chars + dot char table
+; " * + , / : ; < = > ? [ \ ] | .
+ .byte 34,42,43,44,47,58,59,60,61,62,63,91,92,93,124,46
+
+
+
+; ----------------------------------;
+OPWC_SkipDot ;
+; ----------------------------------;
+ CMP #4,X ;
+ JL FillDIRentryName ; X < 4 : no need spaces to complete name entry
+ SUB #3,X ;
+ CALL #OPWC_CompleteWithSpaces; complete name entry
+ MOV #3,X ;
+; ----------------------------------;
+
+; ----------------------------------;
+FillDIRentryName ;SWXY use
+; ----------------------------------;
+ MOV.B @T+,W ; W = char of pathname
+ MOV.B W,BUFFER(Y) ; to DIRentry
+ CMP #0,W ; end of stringZ ?
+ JZ OPWC_CompleteWithSpaces ;
+; ----------------------------------;
+SkipForbiddenChars ;
+; ----------------------------------;
+ PUSH IP ;3
+ MOV #15,IP ;2 forbidden chars count
+ MOV #ForbiddenChars,S ;2 here, S is free
+ForbiddenCharLoop ;
+ CMP.B @S+,W ;2
+ JZ FillDIRentryName ;2 skip forbidden char
+ SUB #1,IP ;1
+ JNZ ForbiddenCharLoop ;2
+ MOV @RSP+,IP ;2
+; ----------------------------------;
+ CMP.B @S,W ;1 46 (0x2E)
+ JZ OPWC_SkipDot ;2 skip '.'
+; ----------------------------------;
+ SUB #33,W ;
+ JL FillDIRentryName ; skip char =< SPACE char
+ ADD #1,Y ; increment DIRentry ptr
+ SUB #1,X ; decrement count of chars entry
+ JNZ FillDIRentryName ;
+; ----------------------------------;
+OPWC_CompleteWithSpaces ; 0 to n spaces !
+; ----------------------------------;
+ CMP #0,X ;
+ JZ OPWC_CWS_End ;
+; ----------------------------------;
+OPWC_CompleteWithSpaceloop ;
+; ----------------------------------;
+ MOV.B #32,BUFFER(Y) ; remplace dot by char space
+ ADD #1,Y ; increment DIRentry ptr in buffer
+ SUB #1,X ; dec countdown of chars space
+ JNZ OPWC_CompleteWithSpaceloop ;
+OPWC_CWS_End ;
+ RET ;
+; ----------------------------------;
+
+
+
+
+; ======================================================================
+; WRITE" primitive as part of OpenPathName
+; input from open: S = OpenError, W = open_type, SectorHL = DIRsectorHL,
+; Buffer = [DIRsector], ClusterHL = FirstClusterHL
+; from open(GetFreeHandle): Y = DIRentry, T = CurrentHdl
+; output: nothing else abort on error
+; error 1 : PathNameNotFound
+; error 2 : NoSuchFile
+; error 4 : DirectoryFull
+; error 8 : AlreadyOpen
+; error 16 : NomoreHandle
+; ======================================================================
+
+; ----------------------------------;
+OPEN_QWRITE ;
+ CMP #2,W ; open_type = WRITE" ?
+ JNZ OPEN_QDEL ; no : goto next step
+; ----------------------------------;
+; 1 try to open ; done
+; ----------------------------------;
+; 2 select error "no such file" ;
+; ----------------------------------;
+ CMP #2,S ; "no such file" error ?
+ JZ OPEN_WRITE_CREATE ; yes
+ CMP #0,S ; no open file error ?
+ JZ OPEN_WRITE_APPEND ; yes
+; ----------------------------------;
+; Write errors ;
+; ----------------------------------;
+OPWC_InvalidPathname ; S = 1
+OPWC_DiskFull ; S = 2
+OPWC_DirectoryFull ; S = 4
+OPWC_AlreadyOpen ; S = 8
+OPWC_NomoreHandle ; S = 16
+; ----------------------------------;
+OPW_Error ; set ECHO, type Pathname, type #error, type "< WriteError"; no return
+ mDOCOL ;
+ .word XSQUOTE ;
+ .byte 12,"< WriteError",0 ;
+ .word BRAN,SD_ERROR ;
+; ----------------------------------;
+
+
+; ======================================================================
+; WRITE" (CREATE part) primitive as part of OpenPathName
+; input from open: S = NoSuchFile, W = open_type, SectorHL = DIRsectorHL,
+; Buffer = [DIRsector], ClusterHL = FirstClusterHL
+; output: nothing else abort on error:
+; error 1 : InvalidPathname
+; error 2 : DiskFull
+; error 4 : DirectoryFull
+; error 8 : AlreadyOpen
+; error 16 : NomoreHandle
+; ======================================================================
+
+; ----------------------------------;
+OPEN_WRITE_CREATE ;
+; ----------------------------------;
+; 3 get free cluster ;
+; ----------------------------------; input: FATsector
+ CALL #SearchNewCluster ;SWXY output: W = new FATsector loaded in buffer,NewCluster
+ MOV &NewClusterL,&ClusterL ;
+ MOV &NewClusterH,&ClusterH ;
+ CALL #UpdateFATsSectorW ;SWX update FATs with buffer
+; ----------------------------------;
+ CALL #ReadSector ; reload DIRsector
+ MOV &EntryOfst,Y ; reload entry offset (first free entry in DIR)
+; ----------------------------------;
+; 4 init DIRentryAttributes ;
+; ----------------------------------;
+OPWC_SetEntryAttribute ; (cluster=DIRcluster!)
+ MOV.B #20h,BUFFER+11(Y) ; file attribute = file
+ CALL #GetYMDHMSforDIR ;WX X=DATE, W=TIME
+ MOV #0,BUFFER+12(Y) ; nt reserved = 0 and centiseconds are 0
+ MOV W,BUFFER+14(Y) ; time of creation
+ MOV X,BUFFER+16(Y) ; date of creation 20/08/2001
+ MOV X,BUFFER+18(Y) ; date of access 20/08/2001
+ MOV &ClusterH,BUFFER+20(Y) ; as first Cluster Hi
+ MOV &ClusterL,BUFFER+26(Y) ; as first cluster LO
+ MOV #0,BUFFER+28(Y) ; file lenghtLO = 0
+ MOV #0,BUFFER+30(Y) ; file lenghtHI = 0
+; ----------------------------------;
+; 5 create DIRentryName ;
+; ----------------------------------;
+ MOV #1,S ; preset pathname error
+ MOV &Pathname,T ; here, pathname is "xxxxxxxx.yyy" format
+ CMP.B #0,0(T) ; forbidden null string
+ JZ OPWC_InvalidPathname ; write error 1
+ CMP.B #'.',0(T) ; forbidden "." in first
+ JZ OPWC_InvalidPathname ; write error 1
+ MOV #11,X ; X=countdown of chars entry
+ CALL #FillDIRentryName ;STWXY
+; ----------------------------------;
+; 6 save DIRsector ;
+; ----------------------------------;
+ CALL #WriteSector ;SWX update DIRsector
+; ----------------------------------;
+; 7 Get free handle ;
+; ----------------------------------;
+ MOV #2,W ;
+ CALL #GetFreeHandle ; output : S = handle error, CurCluster and CurSector are set
+; ----------------------------------;
+ CMP #0,S ; no error ?
+ JNZ OPWC_NomoreHandle ; ==> abort with error 16
+ mNEXT ; --
+; ----------------------------------;
+
+;-----------------------------------------------------------------------
+; WRITE" subroutines
+;-----------------------------------------------------------------------
+
+; SectorL is unchanged
+; ----------------------------------;
+OPWW_UpdateDirectory ; <== CloseHandleT
+; ----------------------------------; Input : current Handle
+ MOV HDLL_DIRsect(T),W ;
+ MOV HDLH_DIRsect(T),X ;
+ CALL #readSectorWX ;SWX buffer = DIRsector
+ CALL #GetYMDHMSforDIR ; X=DATE, W=TIME
+ MOV HDLW_DIRofst(T),Y ; Y = DirEntryOffset
+ MOV X,BUFFER+18(Y) ; access date
+ MOV W,BUFFER+22(Y) ; modified time
+ MOV X,BUFFER+24(Y) ; modified date
+OPWW_UpdateEntryFileSize ;
+ MOV HDLL_CurSize(T),BUFFER+28(Y); save new filesize
+ MOV HDLH_CurSize(T),BUFFER+30(Y);
+ MOV HDLL_DIRsect(T),W ;
+ MOV HDLH_DIRsect(T),X ;
+ MOV #WriteSectorWX,PC ;SWX then RET
+; ----------------------------------;
+
+; this subroutine is called by Write_File and CloseHandleT
+; ==================================;
+WriteBuffer ;SWXY input: T = CurrentHDL
+; ==================================;
+ ADD &BufferPtr,HDLL_CurSize(T) ; update handle CurrentSizeL
+ ADDC #0,HDLH_CurSize(T) ;
+; ==================================;
+WriteSector ;SWX
+; ==================================;
+ MOV &SectorL,W ; Low
+ MOV &SectorH,X ; High
+ MOV #WriteSectorWX,PC ; ...then RET
+; ----------------------------------;
+
+
+
+; write sequentially the buffer in the post incremented SectorHL.
+; The first time, SectorHL is initialized by WRITE".
+; All used registers must be initialized.
+; ==================================;
+Write_File ; <== WRITE, SD_EMIT, TERM2SD"
+; ==================================;
+ MOV #BytsPerSec,&BufferPtr ; write always all the buffer
+ MOV &CurrentHdl,T ;
+ CALL #WriteBuffer ; write BUFFER and update Handle informations only for DIRentry update
+ MOV #0,&BufferPtr ; reset buffer pointer
+; ----------------------------------;
+PostIncrementSector ;
+; ----------------------------------;
+ ADD.B #1,HDLB_ClustOfst(T) ; increment current Cluster offset
+ CMP.B &SecPerClus,HDLB_ClustOfst(T) ; out of bound ?
+ JNZ Write_File_End ; no,
+; ----------------------------------;
+GetNewCluster ; input : T=CurrentHdl
+; ----------------------------------;
+ MOV.B #0,HDLB_ClustOfst(T) ; reset handle ClusterOffset
+ CALL #HDLCurClusToFAT1sectWofstY;WXY Output: W=FATsector, Y=FAToffset, Cluster=HDL_CurCluster
+ PUSH Y ; push current FAToffset
+ PUSH W ; push current FATsector
+ CALL #SearchNewCluster ;SWXY output: W = new FATsector loaded in buffer, NewCluster
+ CMP @RSP,W ; current and new clusters are in same FATsector?
+ JZ LinkClusters ; yes
+UpdateNewClusterFATs ;
+ CALL #UpdateFATsSectorW ;SWX no: UpdateFATsSectorW with buffer of new FATsector
+ MOV @RSP,W ; W = current FATsector
+ CALL #ReadFAT1SectorW ;SWX reload current FATsector in buffer to link clusters
+LinkClusters ;
+ MOV @RSP+,W ; W = current FATsector
+ MOV @RSP+,Y ; pop current FAToffset
+ MOV &NewClusterL,BUFFER(Y) ; store new cluster to current cluster address in current FATsector buffer
+ CMP #1,&FATtype ; FAT16?
+ JZ UpdatePreviousClusterFATs ; yes
+ MOV &NewClusterH,BUFFER+2(Y);
+UpdatePreviousClusterFATs ;
+ CALL #UpdateFATsSectorW ;SWX update FATS with current FATsector buffer
+UpdateHandleCurCluster ;
+ MOV &NewClusterL,HDLL_CurClust(T) ; update handle with new cluster
+ MOV &NewClusterH,HDLH_CurClust(T) ;
+; CALL #ComputeHDLcurrentSector ; set Cluster first Sector as next Sector to be written
+; MOV #OPWW_UpdateDirectory,PC ; update DIRentry to avoid cluster lost, then RET
+Write_File_End
+ MOV #ComputeHDLcurrentSector,PC ; set current Cluster Sector as next Sector to be written then RET
+; ----------------------------------;
+
+;Z WRITE --
+; sequentially write the BUFFER in a file opened by WRITE"
+; ----------------------------------;
+ FORTHWORD "WRITE" ;
+; ----------------------------------;
+ CALL #Write_File ;
+ mNEXT ;
+; ----------------------------------;
+
+;Z SD_EMIT c -- output char c to a SD_CARD file opened as write
+; ----------------------------------;
+ FORTHWORD "SD_EMIT" ;
+; ----------------------------------;
+SD_EMIT ;
+ CMP #BytsPerSec,&BufferPtr ; 4 file buffer is full ?
+ JLO SD_EmitNext ; 2
+ CALL #Write_File ; BufferPtr = 0
+SD_EmitNext ;
+ MOV &BufferPtr,Y ; Y
+ MOV.B TOS,BUFFER(Y) ; 3
+ ADD #1,&BufferPtr ; 4
+ MOV @PSP+,TOS ; 2
+ mNEXT ; 4
+; ----------------------------------; 19~ for SD_EMIT, 22~ for EMIT
+
+
+
+
+; ======================================================================
+; WRITE" (APPEND part) primitive as part of OpenPathName
+; input from open: S = OpenError, W = open_type, SectorHL = DIRsectorHL,
+; Buffer = [DIRsector], ClusterHL = FirstClusterHL
+; from open(GetFreeHandle): Y = DIRentry, T = CurrentHdl, BufferPtr=HDLW_BufOfst=0
+; output: nothing else abort on error
+; error 2 : DiskFull
+; ======================================================================
+
+; ----------------------------------;
+OPEN_WRITE_APPEND ;
+; ----------------------------------;
+; 1- open file ; done
+; ----------------------------------;
+; 2- compute missing Handle infos ;
+; ----------------------------------;
+; 2.1- Compute Sectors count ; Sectors = HDLL_CurSize/512
+; ----------------------------------;
+ MOV.B HDLL_CurSize+1(T),Y ; Y = 0:CurSizeLoHi
+ MOV.B HDLH_CurSize(T),S ; S = 0:CurSizeHiLo
+ SWPB S ; S = CurSizeHiLo:0
+ ADD Y,S ; S = CurSizeHiLo:CurSizeLoHi
+ MOV.B HDLH_CurSize+1(T),W ; W:S = CurSize / 256
+ RRA W ; W = Sectors number_High
+ RRC S ; S = Sectors number_Low
+; ----------------------------------;
+; 2.2- Compute Buffer offset ; tested with 4100 bytes and SecPerClus=8
+; ----------------------------------;
+ MOV HDLL_CurSize(T),Y ; Y = 1004
+ BIC #01FFh,HDLL_CurSize(T) ; substract 4 from HDLL_CurSize
+ AND #01FFh,Y ; Y = 4
+ MOV Y,&BufferPtr ; init Buffer Pointer with 4
+; ----------------------------------;
+ComputeClustersCount ; with W:S / T ==> quotient = Y:X, remainder = W
+; ----------------------------------;
+ MOV.B &SecPerClus,T ;3 T = DIVISOR = SecPerClus
+ CALL #UDIVQ32 ; unsigned division 32/16 ==> Q32,R16 i.e. W:S/T ==> Y:X,W use S,T,W,X,Y
+ MOV &CurrentHDL,T ;
+; ----------------------------------;
+; 2.3- Compute Cluster offset ;
+; ----------------------------------;
+ MOV.B W,HDLB_ClustOfst(T) ;3 update handle with W = R16 (remainder) = sectors offset in cluster
+; ----------------------------------;
+; 2.4- Compute last Cluster ; X = Q32lo = Clusters numberLO, Y = Q32hi = Clusters numberHI
+; ----------------------------------;
+ ADD HDLL_FirstClus(T),X ;
+ ADDC HDLH_FirstClus(T),Y ;
+ MOV X,HDLL_CurClust(T) ; update handle
+ MOV Y,HDLH_CurClust(T) ;
+; ----------------------------------;
+; 3- load last sector in BUFFER ;
+; ----------------------------------;
+ CALL #LoadHDLcurrentSector ;SWX
+ mNEXT ; --
+; ----------------------------------; BufferPtr leaves first free byte offset
+
+
+; ======================================================================
+; DEL" primitive as part of OpenPathName
+; All "DEL"eted clusters are freed
+; If next DIRentry in same sector is free, DIRentry is freed, else hidden.
+; input from open: S = OpenError, W = open_type, SectorHL = DIRsectorHL,
+; Buffer = [DIRsector], ClusterHL = FirstClusterHL
+; from open(GetFreeHandle): Y = DIRentry, T = CurrentHdl, BufferPtr=HDLW_BufOfst=0
+; output: nothing (no message if open error)
+; ======================================================================
+
+
+OPEN_QDEL ;
+; CMP #4,W ; open_type = DEL"
+; JNZ OPEN_8W ;
+; ----------------------------------;
+OPEN_DEL ;
+; ----------------------------------;
+; 1- open file ; done
+; ----------------------------------;
+ CMP #0,S ; open file happy end ?
+ JNE OPND_END ; no: don't send message
+; ----------------------------------;
+; 2- Delete DIR entry ; "delete" entry with 00h if next entry in same DIRsector is free, else "hide" entry with 05Eh
+; ----------------------------------;
+SelectFreeEntry ; nothing to do: S = 0 ready for free entry!
+; ----------------------------------;
+ CMP #BytsPerSec-32,Y ; Entry >= last entry in DIRsector ?
+ JHS SelectHideEntry ; yes: next DIR entry is out of sector
+ CMP.B #0,BUFFER+32(Y) ; no: next DIR entry in DIRsector is free?
+ JZ WriteDelEntry ; yes
+; ----------------------------------;
+SelectHideEntry ; no
+; ----------------------------------;
+ MOV.B #0E5h,S ;
+; ----------------------------------;
+WriteDelEntry
+; ----------------------------------;
+ MOV.B S,BUFFER(Y) ;
+ CALL #WriteSector ;SWX write SectorHL=DIRsector
+; ----------------------------------;
+; 3- free all file clusters ; Cluster = FirstCluster
+; ----------------------------------;
+ComputeClusterSectWofstY ;
+ CALL #ClusterToFAT1sectWofstY;WXY W = FATsector, Y=FAToffset
+ MOV W,&CurFATsector ; update CurrentFATsector
+; ----------------------------------;
+LoadFAT1sector
+; ----------------------------------;
+ MOV W,T ; T = W = current FATsector memory
+ CALL #ReadFAT1SectorW ;SWX
+; ----------------------------------;
+GetAndFreeClusterLo ;
+; ----------------------------------;
+ MOV BUFFER(Y),W ; get [clusterLO]
+ MOV #0,BUFFER(Y) ; free CLusterLO
+ClusterTestSelect ;
+ CMP #1,&FATtype ; FAT16 ?
+ JZ ClusterLoTest ; yes
+GetAndFreeClusterHi ;
+ MOV BUFFER+2(Y),X ; get [clusterHI]
+ MOV #0,BUFFER+2(Y) ; free CLusterHI
+ClusterHiTest
+ AND #00FFFh,X ; select 12 bits significant
+ CMP #00FFFh,X ; [ClusterHI] was = 0FFFh?
+ JNE SearchNextCluster2free ; no
+ClusterLoTest
+ CMP #-1,W ; [ClusterLO] was = FFFFh?
+ JZ EndOfFileClusters ; yes
+; ----------------------------------;
+SearchNextCluster2free
+; ----------------------------------;
+ MOV W,&ClusterL ;
+ MOV X,&ClusterH ;
+ CALL #ClusterToFAT1sectWofstY;WXY
+ CMP W,T ; new FATsector = current FATsector memory ?
+ JZ GetAndFreeClusterLo ; yes loop back
+ PUSH W ; no: save new FATsector...
+ MOV T,W ; ...before update current FATsector
+ CALL #UpdateFATsSectorW ;SWX
+ MOV @RSP+,W ; restore new current FATsector
+ JMP LoadFAT1sector ; loop back with Y = FAToffset
+; ----------------------------------;
+EndOfFileClusters ;
+; ----------------------------------;
+ MOV T,W ; T = W = current FATsector
+ CALL #UpdateFATsSectorW ;SWX
+; ----------------------------------;
+; 3- Close Handle ;
+; ----------------------------------;
+ CALL #CloseHandleT ;
+; ----------------------------------;
+OPND_End ;
+; ----------------------------------;
+ mNEXT
+
+
+
+; first TERATERM sends the command TERM2SD" file.ext" to FastForth which returns XOFF at the end of the line.
+; then when XON is sent below, TERATERM sends "file.ext" by slices of 512 bytes,
+; until it sends char ETX that closes the file on SD_CARD.
+
+ FORTHWORD "TERM2SD\34"
+ mDOCOL
+ .word DELDQ ; DEL file if already exist
+ .word HERE ;
+ FORTHtoASM ;
+ ADD #2,RSP ; pop IP of OPEN
+ SUB #2,PSP ;
+ MOV #2,0(PSP) ; -- open_type HERE open_type = open as write
+ MOV #TERM2SD,IP ; IP = ParenOpen return address
+ MOV #PARENOPEN,PC ; open_type HERE -- open as write the file whose HERE is the c-addr of pathname
+TERM2SD ;
+ FORTHtoASM ; T = CurrentHdl
+ BIC #UCRXIFG,&TERMIFG ; clean up RX buffer
+; ----------------------------------;
+T2S_GetSliceLoop ; tranfert by slices of 512 bytes terminal input to file on SD_CARD via BUFFER
+; ----------------------------------;
+ MOV #0,Y ;1 reset Y = BufferPtr
+ CALL #XON ; use no registers
+; ----------------------------------;
+T2S_FillBufferLoop ;
+; ----------------------------------;
+ BIT #UCRXIFG,&TERMIFG ;3 new char in TERMRXBUF ?
+ JZ T2S_FillBufferLoop ;2
+ MOV.B &TERMRXBUF,X ;3
+ CMP.B #4,X ;1 ETX sent by TERATERM ?
+ JZ T2S_END ;2 yes
+ MOV.B X,BUFFER(Y) ;3
+ ADD #1,Y ;1
+ CMP #BytsPerSec-1,Y ;2
+ JZ T2S_XOFF ;2 Y=511 send XOFF after RX 511th char
+ JLO T2S_FillBufferLoop ;2 Y<511 21 cycles char loop
+; ----------------------------------;
+T2S_WriteFile ;2 Y>511
+; ----------------------------------;
+ CALL #Write_File ;TSWXY write all the buffer
+ JMP T2S_GetSliceLoop ;2
+; ----------------------------------;
+T2S_XOFF ; 27 cycles between XON and XOFF
+; ----------------------------------;
+ CALL #XOFF ;4 use no registers
+ JMP T2S_FillBufferLoop ;2 loop back to get 512th char
+; ----------------------------------;
+T2S_END ;
+; ----------------------------------;
+ CALL #XOFF ;4 use no registers
+ MOV Y,&BufferPtr ;3
+ CALL #CloseHandleT ;4
+ MOV @RSP+,IP ;2
+ mNEXT ;4
+; ----------------------------------;
+
--- /dev/null
+
+
+ WHAT IS FAST FORTH FOR MSP430FR ?
+ HARDWARE to start
+ FAST FORTH IS IT AN IDE ?
+ HOW TO MIX ASSEMBLY and FORTH ?
+ WRITING RULES
+ ASSEMBLY WITHOUT LABEL ?
+ SYMBOLIC ASSEMBLER ? YES !
+ START YOUR PROJECT
+ Case of MSP430FR2xxx family (with FLL)
+ ANNEXE
+
+WHAT IS FAST FORTH FOR MSP430FRxxxx ?
+--
+
+FAST FORTH is a FORTH program written in MSP430 assembly and it runs on TI's LAUNCHPAD :
+MSP-EXP430FR5739, MSP-EXP430FR5969, MSP-EXP430FR6989... or any MSP430 FRAM device.
+
+Built-in assembler allows you to program an application using interruptions and LPMX modes.
+
+
+HARWARE TO START
+--
+
+ a TI launchpad, I prefer MSP-EXP430FR5969
+
+ an UARTtoUSB cable with a PL2303TA device (preferred device) :
+ Search :"PL2303TA"
+ RX and TX wires are 3.3V level.
+
+ BE CAREFULL ! if you plan to supply your MSP430FRxxxx device with the PL2303TA cable,
+ you MUST open it to weld the red wire (+) onto the 3.3V pad !!!
+ otherwise, cut it...
+
+
+ or UARTtoUSB bridge with CP2102 device :
+ search on ebay :"UART to USB CP2102"
+ verify the presence of a 3.3V pin before buy !
+
+
+If you want to test RC5toLCD.f :
+
+ a standard LCD DISPLAY 2x16 or 2x20 chars,
+ a VISHAY IR receiver TSOP32236 or equivalent plus an IR remote with RC5/RC6 Philips protocol,
+ a piece of PCB to wire the diode, resistor and two capacitors of the LCD_Vo booster.
+
+And to use the SD_Card extension :
+
+ http://www.ebay.com/itm/2-PCS-SD-Card-Module-Slot-Socket-Reader-For-Arduino-MCU-/181211954262?pt=LH_DefaultDomain_0&hash=item2a3112fc56
+
+ http://fr.aliexpress.com/item/Reading-and-writing-SD-Card-Module-Slot-Socket-Reader-For-Arduino-ARM-MCU-free-Shipping/32351128089.html?spm=2114.06010108.3.314.T5C4eQ&ws_ab_test=201407_5,201444_5,201409_3
+
+ http://fr.aliexpress.com/item/5V-3-3V-Compatible-Perfect-SD-Card-Module-Slot-Socket-Reader-For-ARM-MCU-Read/32223868267.html?isOrigTitle=true
+
+It is not wasteful.
+
+If you have MSP-EXP430FR994 launchpad, simply put a FAT16 formatted card in slot.
+
+I suggest you to wire constantly the RX0 TX0 pins of your LAUNCHPAD (RX1 TX1 pins for MSP-EXP430FR6989 launchpad) to a free USB socket on your PC via the cable UARTtoUSB PL2303TA.
+So you can drag and drop HEX file on MSP-EXP430FRxxxxprog.bat to regenerate FORTH kernel or download RC5toLCD.f without doing anything else...
+
+
+FAST FORTH IS IT AN IDE ?
+--
+
+YES, if you admit that you can program in FORTH / in assembler, not C... Look at "RC5toLCD.f".
+
+In fact, you have an IDE with two languages, one low level other high level, and it's easy to mix them.
+
+
+HOW TO MIX assembly and FORTH ?
+---
+
+FAST FORTH knows two kinds of words :
+
+ low level assembly words start with CODE <name> and end with ENDCODE.
+
+ high level FORTH words begin with : <name> and end with ;
+
+
+Examples
+
+ CODE ADD \ Assembly word, alias of word +
+ ADD @PSP+,TOS
+ MOV @IP+,PC
+ ENDCODE
+
+
+ : NOOP \ FORTH word, do nothing
+ DUP
+ DROP
+ ;
+
+
+
+To end a low level assembly word, the instruction MOV @IP+,PC jumps to the next FORTH word. This faster (4 cycles) and shorter (one word) instruction replaces the famous pair of assembly instructions : CALL #LABEL ... RET (4+4 cycles, 2+1 words). The register IP is the Interpretative Pointer.
+
+High level FORTH word starts with a boot code (13 cycles) that save the IP pointer, load it with the first address of a list of execution addresses, then perform a postincrement branch to this first address. The list ends with the address of another piece of code EXIT (6 cycles) that restores IP before the instruction MOV @IP+,PC.
+
+
+here, the compilation of low level word ADD :
+
+ preamble \ compiled by the word CODE
+ execution addr ADD @PSP+,TOS
+ MOV @IP+,PC \ instruction called NEXT
+
+and the one of the high level word NOOP :
+
+ preamble \ compiled by the word :
+ execution addr PUSH IP \ boot code compiled by the word :
+ CALL rEXIT \ boot code compiled by the word :
+ addr of DUP \ execution addr of DUP
+ addr of DROP \ execution addr of DROP
+ addr of EXIT \ execution addr of EXIT compiled by the word ;
+
+
+_A high level FORTH word is a list of execution addresses preceded by a boot code and ending with EXIT address._
+
+
+WRITING RULES
+--
+
+any low level FORTH words must be ended with the instruction MOV @IP+,PC (NEXT).
+
+ CODE TEST \ CODE starts a low level word
+ asm1 \ assembly instruction 1
+ asm2 \ assembly instruction 2
+ MOV @IP+,PC \ NEXT
+ ENDCODE \ end of low level word
+
+
+If you want to use the IP register, save it before and restore it before NEXT
+
+ CODE TEST1 \ CODE starts a low level word
+ asm1 \ assembly instructions
+ ...
+ PUSH IP \ save IP before use
+ MOV #1,IP \ assembly instruction that uses IP
+ ... \ assembly instructions
+ MOV @RSP+,IP \ restore IP
+ MOV @IP+,PC \ NEXT
+ ENDCODE \ end of low level word
+
+
+A little more complex, the case of mixing FORTH and assembly
+
+ : MIX_FORTH_ASM \ definition of a FORTH word starts with :
+ SWAP
+ DUP
+ HI2LO \ FORTH to assembler switch
+ asm1 \ assembly instruction
+ asm2 \ assembly instruction
+ ... \ you can freely use IP !
+ ... \ assembly instructions
+ MOV @RSP+,IP \ restore IP
+ MOV @IP+,PC \ NEXT
+ ENDCODE \ end of low level word
+
+If we see the code "MIX\_FORTH\_ASM" after compilation :
+
+ preamble \ compiled by :
+ exec@ PUSH IP \ compiled by : save IP
+ CALL rEXIT \ compiled by : and execute EXIT
+ addr \ execution addr of SWAP
+ addr \ execution addr of DUP
+ next addr \ addr of asm1, compiled by HI2LO
+ asm1 \ assembly instruction
+ asm2 \ assembly instruction
+ ... \ you can freely use IP !
+ ... \ assembly instructions
+ MOV @RSP+,IP \ restore IP saved by :
+ MOV @IP+,PC \ NEXT
+
+the instruction "CALL rEXIT" (CALL R7), have EXIT address as rEXIT content.
+
+
+going a step further :
+
+ CODE MIX_ASM_FORTH \ CODE starts a low level word
+ asm1 \ assembly instruction 1
+ asm2 \ assembly instruction 2
+ COLON \ starts high level
+ word1
+ word2
+ ; \ end of high level word
+
+
+If we see this code "MIX\_ASM\_FORTH" after compilation :
+
+ preamble \ compiled by CODE
+ exec@ asm1 \ assembly instruction 1
+ asm2 \ assembly instruction 2
+ PUSH IP \ compiled by COLON, save IP
+ CALL rEXIT \ compiled by COLON, CALL EXIT
+ addr1 \ of word1
+ addr2 \ of word2
+ addr of EXIT \ the word ; compiles EXIT that restores IP then executes MOV @IP+,PC
+
+
+EXIT is used twice !
+
+the first time, at the start of FORTH word, after save IP:
+
+ EXIT MOV @RSP+,IP \ 2 pop into IP next PC pushed on return stack by CALL rEXIT
+ MOV @IP+,PC \ 4 execute the routine pointed by the the address next "CALL rEXIT"
+
+then at the end of FORTH word :
+
+ EXIT MOV @RSP+,IP \ 2 pop old IP from return stack
+ MOV @IP+,PC \ 4 execute the routine pointed by the old IP
+
+
+A new step
+
+ : MIX_FORTH_ASM_FORTH \ definition of a FORTH word starts with :
+ word1
+ word2
+ ...
+ HI2LO \ FORTH to assembler switch
+ MOV #0,IP \ IP is free for use
+ asm1
+ ...
+ LO2HI \ assembler to FORTH switch
+ word3
+ word4
+ ; \ end of high level word
+
+the compiled result
+
+
+ preamble \ compiled by :
+ exec@ PUSH IP \ compiled by : save IP
+ CALL rEXIT \ compiled by : and move next PC from return stack into IP
+ addr1 \ of word1
+ addr2 \ of word2
+ ...
+ next addr \ compiled by HI2LO
+ MOV #0,IP \ IP is free for use
+ asm1 \ assembly instruction
+ ...
+ CALL rEXIT \ compiled by LO2HI (10 cycles switch)
+ addr3 \ of word3
+ addr4 \ of word4
+ addr5 \ of EXIT
+
+Still another step :
+
+ CODE MIX_ASM_FORTH_ASM \ CODE starts a low level word
+ asm1 \ assembly instruction
+ asm2 \ assembly instruction
+ COLON \ starts high level
+ word
+ ...
+ HI2LO \ FORTH to assembler switch
+ asm3 \ assembly instruction
+ asm4 \ assembly instruction
+ MOV @RSP+,IP \ restore IP
+ MOV @IP+,PC \ NEXT
+ ENDCODE \ end of low level word
+
+In fact, with FASTFORTH, the start of a word FORTH can be placed anywhere :
+
+ CODE MIX_ASM_FORTH_ASM_FORTH
+ asm
+ asm
+ ...
+ COLON \ starts high level
+ word
+ word
+ ...
+ HI2LO \ FORTH to assembler switch
+ asm
+ asm
+ ...
+ LO2HI \ assembler to FORTH switch
+ word
+ word
+ ...
+ ; \ end of high level word
+
+with the compiled result :
+
+ preamble \ compiled by CODE
+ exec@ asm
+ asm
+ PUSH IP \ compiled by COLON
+ CALL rEXIT \ compiled by COLON
+ addr
+ addr
+ next address \ compiled by HI2LO
+ asm
+ asm
+ CALL rEXIT \ compiled by LO2HI
+ addr
+ addr
+ EXIT addr \ that restores IP from return stack and then executes MOV @IP+,PC
+
+As we see, IP is saved only once, it's logical.
+
+
+ASSEMBLY WITHOUT LABEL ?
+---
+
+Yes ! the assembly syntax borrows FORTH's one for jumps :
+
+ CODE TEST_IF_THEN
+ CMP #1,R8 \ set Z,N,V, flags
+ 0= IF \ irritating, the "IF =" upside down, isn't it?
+ ADD R8,R9 \ true part of comparaison
+ THEN
+ ... \ the next
+ MOV @IP+,PC \ don't forget...
+ ENDCODE \ don't forget...
+
+and the complete version :
+
+ CODE TEST_IF_ELSE_THEN
+ CMP #1,R8 \ set Z,N,V, flags
+ 0= IF \
+ ADD R8,R9 \ true part of comparaison
+ ELSE
+ SUB R8,R9 \ false part of comparaison
+ THEN
+ ... \ following for the two branches
+ MOV @IP+,PC \ don't forget...
+ ENDCODE \ don't forget...
+
+test for loop back version BEGIN ... UNTIL
+
+ CODE TEST_BEGIN_UNTIL
+ MOV #8,R10
+ BEGIN
+ SUB #1,R10 \ set Z,N,V flags
+ 0= UNTIL \ loop back to BEGIN if flag Z is set
+ ...
+ MOV @IP+,PC
+ ENDCODE
+
+test for out of loop version BEGIN ... WHILE ... REPEAT
+
+ CODE TEST_BEGIN_WHILE_REPEAT
+ MOV #8,R10
+ BEGIN
+ SUB #1,R10 \ set Z,N,V flags
+ 0<> WHILE \ go to out of loop if X=0 (Z flag =1)
+ XOR #1,R9
+ REPEAT \ unconditionnal loop back to BEGIN
+ ... \ out of loop here
+ MOV @IP+,PC
+ ENDCODE
+
+infinite loop :
+
+ CODE TEST_BEGIN_AGAIN
+ BEGIN
+ ADD #1,R9
+ AGAIN \ unconditionnal loop back to BEGIN
+ ENDCODE
+
+to quit this infinite loop, press <reset>
+
+We can nest several conditional branches :
+
+ CODE TEST_NESTED_IF_ELSE
+ CMP #0,R10
+ 0= IF
+ CMP #0,R10
+ 0= IF
+ MOV #0,R11
+ ELSE
+ SUB #1,R11
+ THEN
+ ELSE
+ MOV #1,R11
+ THEN
+ MOV @IP+,PC
+ ENDCODE
+
+another nest :
+
+ CODE TEST_NESTED_BEGIN_AGAIN_IF
+ MOV #8,R9
+ BEGIN
+ CMP #-1,R9
+ 0= IF
+ MOV @IP+,PC \ out of test_NESTED_BEGIN_AGAIN_IF
+ THEN
+ SUB #1,R9
+ AGAIN
+ ENDCODE
+
+
+you can also MIX conditional branches with a mix of FORTH/assembly :
+
+ see TEST5 in the demo file \MSP430-FORTH\TESTASM.4TH
+
+
+...but not quite !
+---
+
+unconditionnal backward jump :
+
+ CODE UNCOND_BACKWARD
+ asm
+ asm
+ JMP TEST \ jump backward to the word TEST
+ ENDCODE
+
+conditionnal backward jump :
+
+ CODE COND_BACKWARD
+ asm
+ CMP #0,R8
+ S< ?JMP TEST \ jump backward to TEST if negative
+ asm
+ MOV @IP+,PC
+ ENDCODE
+
+FAST FORTH have one pass assembler, not able to make forward jump.
+
+In my (well written) apps I have never used forward jumps.
+
+I have added possibility of several "non canonical" jumps, up to 3 backward and up to 3 forward imbricated jumps to label :
+
+ \ C UM/MOD udlo|udhi u1 -- ur uq
+ CODE UM/MOD
+ MOV @PSP+,W \ 2 W = DIVIDENDhi
+ MOV @PSP,S \ 2 S = DIVIDENDlo
+ \ T.I. ROUTINE Section 5.1.5 of MSP430 Family Application Reports
+ MOV #0,Y \ 1 CLEAR RESULT
+ MOV #16,X \ 2 INITIALIZE LOOP COUNTER
+ BW1 CMP TOS,W \ 1
+ U< ?GOTO FW1 \ 2 if not carry
+ SUB TOS,W \ 1 if carry DIVIDENDhi-divisor
+ FW1 \ FW1 label is resolved therefore reusable
+ BW2 ADDC Y,Y \ 1 RLC quotient
+ U>= ?GOTO FW1 \ 2 if carry Error: result > 16 bits
+ SUB #1,X \ 1 Decrement loop counter
+ <0 ?GOTO FW2 \ 2 if 0< terminate w/o error
+ ADD S,S \ 1 RLA DIVIDENDlo
+ ADDC W,W \ 1 RLC DIVIDENDhi
+ U< ?GOTO BW1 \ 2 if not carry 14~ loop
+ SUB TOS,W \ 1 if carry DIVIDENDhi-divisor
+ BIS #1,SR \ 1 SETC
+ GOTO BW2 \ 2 14~ loop
+ FW2 BIC #1,SR \ 1 CLRC No error, C = 0
+ FW1 \ Error indication in C
+ \ END T.I. ROUTINE Section 5.1.5 of MSP430 Family Application Reports
+ MOV W,0(PSP) \ 3 remainder on stack
+ MOV Y,TOS \ 1 quotient in TOS
+ MOV @IP+,PC \ 4
+ ENDCODE
+
+
+SYMBOLIC ASSEMBLER ? YES !
+--
+
+I have discovered a little semantic preprocessor "GEMA",
+just like that FAST FORTH have its symbolic assembler !
+
+ \config\gema\MSP430FR_FastForth.pat contains variables FORTH for all devices
+ \config\gema\MSP430FR57xx.pat contains declarations for FR57 family
+ \config\gema\MSP430FR5x6x.pat ... for FR59/FR69 families
+ \config\gema\MSP430FR2x4x.pat ... for FR2/FR4 families.
+ \config\gema\DEVICE.pat contains memory map and vectors for a specified DEVICE
+ \MSP430-FORTH\LAUNCHPAD.pat is the I/O config file for specific LAUNCHPAD or application
+
+gema translates also FORTH registers in ASM registers (R0 to R15)
+
+If you have created a network drive from your local gitlab directory, it's easy :
+with scite editor open a file.f, then select in the menu "tools" the items "preprocess..."
+
+furnished examples : see \MSP430-FORTH\
+Enjoy !
+
+Try SD\_TESTS.f to build a SD\_Card test.
+
+
+START YOUR PROJECT
+--
+
+How to start your project ?
+
+First you create two files : project.f and test.f
+
+PROJECT.f :
+
+ ; ----------------------------------------------------
+ ; MSP430FR5969 MSP_EXP430FR5969 8MHZ 921600bds PROJECT
+ ; ----------------------------------------------------
+ WIPE \ restore the content of FastForth.hex file
+
+here you write your already tested routines :
+
+ CODE FIRST
+ ...
+ ENCODE
+
+ CODE TWO
+ ...
+ ENDCODE
+
+ : ONE
+ ...
+ ...
+ ;
+
+ : MORE
+ ...
+ ...
+ ;
+
+then finish with two master words : START and STOP
+
+ CODE START \ to init your app
+ ... \ assembly part
+
+ COLON
+ ... \ FORTH part
+
+ \ NOECHO \ uncomment if your app runs without terminal
+ LIT RECURSE IS WARM \ inserts START (so init app) in the FORTH init process
+ (WARM) \ then start app by continuing the FORTH init process
+ ;
+
+
+ CODE STOP \ to stop app and interrupts if any
+ MOV #WARM,R8
+ MOV #(WARM),2(R8) \ unlink START from FORTH init process
+ MOV #COLD,PC \ reset CPU that resets interrupt vectors
+ ENDCODE
+
+or in high level :
+
+ : STOP \ to stop app and interrupts if any
+ ['] (WARM) IS WARM \ remove START from FORTH init process
+ COLD \ reset CPU that resets interrupt vectors
+ ;FR
+
+
+ ; compiling is done
+ RST_HERE ; thus allowing to restart your app with <reset> or COLD !
+ START ; let's go!
+
+end of file
+
+
+Each time you download this project file in LAUNCHPAD, the word WIPE returns the dictionary set as it was in HEX file. And the word RST_HERE protects the PROJECT against <RESET\>.
+
+The word START allows to include app init into FORTH's one.
+The word STOP unlink app.
+
+Look at the file RC5toLCD.f to retrieve this structure.
+
+
+
+TEST.f :
+
+ \ ----------------------------------
+ \ MSP-EXP430FR5969_8MHZ_TEST.f
+ \ ----------------------------------
+ RST_STATE \ restore the state defined by PROJECT.f
+
+ here you write your routine to test
+
+ PWR_HERE \ test.f content is protected against POWER OFF, but volatile with <reset>
+
+
+
+Each time you download this test file, the word RST\_STATE returns the <RESET\> dictionary set (i.e. PROJECT). The word PWR\_HERE protects the test against POWER OFF. without the word PWR\_HERE, the test is lost when power down.
+
+let's go
+--
+
+With the TERATERM menu : send a file..., you download first your project.f file, then your test.f file that include the routine to test.
+
+If the test don't work, modify it in the test.f file, then reload it.
+
+When the routine "test" works as you want, you cut it in test.f file and copy it in project.f, then when you reload it, test is done !
+
+Good luck !
+
+
+
+Case of MSP430FR2xxx family (with FLL)
+---
+
+
+Difficult to donwload CORETEST.4th on CHIPSTICK @ 8MHz without error (tested with USBtoUART device = CP2102).
+
+To resolve, I was forced to speed the clock up to 8.29 MHz ! (see ChipStick_fr2433.inc)
+
+And there is no this problem @ 16MHz !
+
+Is a problem that affects this device only ?
+
+If you ever encounter the same difficulty, recompile + download CORETEST.4th several times by increasing each time by 2 the FLLN value until you reach the good compromising...
+...or use a MSP430FR5xxx device !
+
+
+ANNEXE
+--
+
+The embedded assembler don't recognize the (useless) TI's symbolic addressing mode: ADD.B EDE,TONI.
+
+REGISTERS correspondence
+
+ ASM TI FASTFORTH comment
+
+ R0 PC PC Program Counter
+ R1 SP RSP Return Stack Pointer
+ R2 SR/CG1 SR Status Register/Constant Generator 1
+ R3 CG2 Constant Generator 2
+ R4 R4 rDODOES contents address of xdodoes
+ R5 R5 rDOCON contents address of xdocon
+ R6 R6 rDOVAR contents address of RFROM
+ R7 R7 rEXIT contents address of EXIT
+ R8 R8 Y scratch register
+ R9 R9 X scratch register
+ R10 R10 W scratch register
+ R11 R11 T scratch register
+ R12 R12 S scratch register
+ R13 R13 IP Interpretation Pointer
+ R14 R14 TOS Top Of parameters Stack
+ R15 R15 PSP Parameters Stack Pointer
+
+ FASTFORTH registers must be preprocessed by gema.exe before sending to the embedded assembler.
+ (don't use R3 and use R2 only with register addressing mode).
+
+REGISTERS use
+
+ The FASTFORTH registers rDOCOL, rDOVAR, rDOCON and rDODOES must be preserved.
+ PUSHM R7,R4 before use and POPM R4,R7 after.
+
+ Under interrupt, the use of scratch registers and IP is free.
+ Else, only scratch registers.
+
+
+PARAMETERS STACK use
+
+ The register TOS (Top Of Stack) is the first cell of the Parameters stack.
+ The register PSP (Parameters Stack Pointer) points the second cell.
+
+ to push one cell on the PSP stack :
+
+ SUB #2,PSP \ insert a empty 2th cell
+ MOV TOS,0(PSP) \ mov first cell in this empty 2th cell
+ MOV <what you want>,TOS \ or MOV.B <what you want>,TOS ; i.e. in first cell
+ ...
+
+ to pop one cell from the PSP stack :
+
+ MOV @PSP+,TOS \ first cell is lost
+ ...
+
+
+RETURN STACK use
+
+ register RSP is the Return Stack Pointer (SP).
+
+ to push one cell on the RSP stack :
+
+ PUSH <what you want> \
+ ...
+
+ to pop one cell from the RSP stack :
+
+ MOV @RSP+,<where you want> \
+ ...
+
+ to push multiple registers on the RSP stack :
+
+ PUSHM Rx,Ry \ x > y
+ ...
+
+ to pop multiple registers from the RSP stack :
+
+ POPM Ry,Rx \ y < x
+ ...
+
+CPUx instructions PUSHM / POPM (my own syntax, not the TI's one, too bad :-)
+
+ PUSHM order : PSP,TOS, IP, S, T, W, X, Y, R7, R6, R5, R4
+
+ example : PUSHM IP,Y \ push IP, S, T, W, X, Y registers onto the stack RSP
+
+
+ POPM order : R4, R5, R6, R7, Y, X, W, T, S, IP,TOS,PSP
+
+ example : POPM Y,IP \ pop Y, X, W, T, S, IP registers from the stack RSP
+
+ error occurs if bad order (PUSHM Y,IP for example)
+
+
+CPUx instructions RRCM,RRAM,RLAM,RRUM
+
+ example : RRUM #3,R9 \ R9 register is Unsigned Right shifted by n=3
+
+ error occurs if 1 > n > 4
--- /dev/null
+ save
+ listing off ; kein Listing über diesen File
+
+;****************************************************************************
+;* *
+;* AS 1.41 - Datei REGMSP.INC von Alfred Arnold *
+;* *
+;* Sinn : enthält Makro- und Registerdefinitionen für den MSP430 *
+;* *
+;* letzte Änderungen : 2002-01-11 *
+;* 2010/2011/2012 erweitert von Matthias Koch *
+;* *
+;****************************************************************************
+
+ ifndef regmspinc ; verhindert Mehrfacheinbindung
+
+regmspinc equ 1
+
+ if (MOMCPUNAME<>"MSP430")
+ fatal "Falscher Prozessortyp eingestellt: nur MSP430 erlaubt!"
+ endif
+
+ if MOMPASS=1
+ message "MSP430-Register+Befehlsdefinitionen (C) 1996 Alfred Arnold"
+ endif
+
+; Definitions for Instructions, Macros and Ports.
+
+;----------------------------------------------------------------------------
+; Arithmetik
+
+adc macro op
+ addc.attribute #0,op
+ endm
+
+dadc macro op
+ dadd.attribute #0,op
+ endm
+
+dec macro op
+ sub.attribute #1,op
+ endm
+
+decd macro op
+ sub.attribute #2,op
+ endm
+
+inc macro op
+ add.attribute #1,op
+ endm
+
+incd macro op
+ add.attribute #2,op
+ endm
+
+sbc macro op
+ subc.attribute #0,op
+ endm
+
+;----------------------------------------------------------------------------
+; Logik
+
+inv macro op
+ xor.attribute #-1,op
+ endm
+
+rla macro op
+ add.attribute op,op
+ endm
+
+rlc macro op
+ addc.attribute op,op
+ endm
+
+;----------------------------------------------------------------------------
+; Daten bewegen ;-)
+
+clr macro op
+ mov.attribute #0,op
+ endm
+
+clrc macro
+ bic #1,sr
+ endm
+
+clrn macro
+ bic #4,sr
+ endm
+
+clrz macro
+ bic #2,sr
+ endm
+
+pop macro op ; Muss hier noch ein Atribut anbringen ! Kann auch Bytes zurückladen...
+ mov.attribute @sp+,op
+ endm
+
+setc macro
+ bis #1,sr
+ endm
+
+setn macro
+ bis #4,sr
+ endm
+
+setz macro
+ bis #2,sr
+ endm
+
+tst macro op
+ cmp.attribute #0,op
+ endm
+
+;----------------------------------------------------------------------------
+; Sprungbefehle
+
+br macro op
+ mov op,pc
+ endm
+
+dint macro
+ bic #8,sr
+ endm
+
+eint macro
+ bis #8,sr
+ endm
+
+nop macro
+ .word 04303h ; mov #0, r3
+ endm
+
+nop2 macro ; 1 Word, 2 Takte
+ jmp $+2
+ endm
+
+nop3 macro ; 1 Word, 3 Takte
+ MOV PC,PC
+ endm
+
+ret macro
+ mov @sp+,pc
+ endm
+
+jlo macro label ; unsigned
+ jnc label
+ endm
+
+jhs macro label ; unsigned
+ jc label
+ endm
+
+jeq macro label
+ jz label
+ endm
+
+; ================================================
+; Flags im Statusregister
+; ================================================
+; SR bits : only SR(11:0) are PUSHed by interrupts
+; ================================================
+C equ 0001h
+Z equ 0002h
+N equ 0004h
+V equ 0100h
+GIE equ 0008h
+CPUOFF equ 0010h
+OSCOFF equ 0020h
+SCG0 equ 0040h
+SCG1 equ 0080h
+UF1 equ 0200h ; = SR(9) User Flag 1 used by ?NUMBER --> INTERPRET --> LITERAL to process double numbers, else free for use.
+UF2 equ 0400h ; = SR(10) User Flag 2
+UF3 equ 0800h ; = SR(11) User Flag 3
+
+;----------------------------------------------------------------------------
+; Low-Power-Mode Bitmuster
+
+LPM0 equ CPUOFF
+LPM1 equ SCG0 + CPUOFF
+LPM2 equ SCG1 + CPUOFF
+LPM3 equ SCG1 + SCG0 + CPUOFF
+LPM4 equ SCG1 + SCG0 + OSCOFF + CPUOFF
+
+;----------------------------------------------------------------------------
+
+ endif ; von IFDEF...
+ restore ; wieder erlauben
+ listing on
--- /dev/null
+[InternetShortcut]
+URL=http://processors.wiki.ti.com/index.php/MSP430_Flasher_-_Command_Line_Programmer?DCMP=MSP430&HQS=Other+OT+msp430flasher
--- /dev/null
+[InternetShortcut]
+URL=http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPBSL_CustomBSL430/latest/index_FDS.html
--- /dev/null
+[InternetShortcut]
+URL=http://john.ccac.rwth-aachen.de:8000/as/
--- /dev/null
+[InternetShortcut]
+URL=http://john.ccac.rwth-aachen.de:8000/as/as_EN.html
--- /dev/null
+ save
+ listing off ; kein Listing \81ber diesen File
+
+;****************************************************************************
+;* *
+;* AS 1.41 - Datei REGMSP.INC *
+;* *
+;* Sinn : enth\84lt Makro- und Registerdefinitionen f\81r den MSP430 *
+;* *
+;* letzte \8enderungen : 2002-01-11 *
+;* *
+;****************************************************************************
+;* $Id: regmsp.inc,v 1.3 2008/01/02 22:32:21 alfred Exp $
+;****************************************************************************
+;* $Log: regmsp.inc,v $
+;* Revision 1.3 2008/01/02 22:32:21 alfred
+;* - better heap checking for DOS target
+;*
+;* Revision 1.2 2007/12/31 13:23:53 alfred
+;* - added some bit definitions
+;*
+;****************************************************************************
+
+ ifndef regmspinc ; verhindert Mehrfacheinbindung
+
+regmspinc equ 1
+
+ if (MOMCPUNAME<>"MSP430")
+ fatal "Falscher Prozessortyp eingestellt: nur MSP430 erlaubt!"
+ endif
+
+ if MOMPASS=1
+ message "MSP430-Register+Befehlsdefinitionen (C) 1996/2007 Alfred Arnold, Jose Da Silva"
+ endif
+
+;----------------------------------------------------------------------------
+; Arithmetik
+
+adc macro op
+ addc.attribute #0,op
+ endm
+
+dadc macro op
+ dadd.attribute #0,op
+ endm
+
+dec macro op
+ sub.attribute #1,op
+ endm
+
+decd macro op
+ sub.attribute #2,op
+ endm
+
+inc macro op
+ add.attribute #1,op
+ endm
+
+incd macro op
+ add.attribute #2,op
+ endm
+
+sbc macro op
+ subc.attribute #0,op
+ endm
+
+;----------------------------------------------------------------------------
+; Logik
+
+inv macro op
+ xor.attribute #-1,op
+ endm
+
+rla macro op
+ add.attribute op,op
+ endm
+
+rlc macro op
+ addc.attribute op,op
+ endm
+
+;----------------------------------------------------------------------------
+; Daten bewegen ;-)
+
+clr macro op
+ mov.attribute #0,op
+ endm
+
+clrc macro
+ bic #1,sr
+ endm
+
+clrn macro
+ bic #4,sr
+ endm
+
+clrz macro
+ bic #2,sr
+ endm
+
+pop macro op
+ mov @sp+,op
+ endm
+
+setc macro
+ bis #1,sr
+ endm
+
+setn macro
+ bis #4,sr
+ endm
+
+setz macro
+ bis #2,sr
+ endm
+
+tst macro op
+ cmp.attribute #0,op
+ endm
+
+;----------------------------------------------------------------------------
+; Sprungbefehle
+
+br macro op
+ mov op,pc
+ endm
+
+dint macro
+ bic #8,sr
+ endm
+
+eint macro
+ bis #8,sr
+ endm
+
+nop macro
+ .word 04303h ; den symbolischen Befehl w\81rde AS zur\81ckweisen
+ endm
+
+ret macro
+ mov @sp+,pc
+ endm
+
+jlo macro label
+ jnc label
+ endm
+
+jhs macro label
+ jc label
+ endm
+
+jeq macro label
+ jz label
+ endm
+
+;----------------------------------------------------------------------------
+; General Memory Layout
+; ----------------------
+;
+; 0000 - 000f : Special Function Registers
+; 0010 - 00ff : 8bit Peripheral Modules
+; 0100 - 01ff : 16bit Peripheral Modules
+; 0200 - .... : RAM Memory
+; .... - ffdf : Flash Memory
+; ffe0 - ffff : Interrupt Vector Table
+;
+;----------------------------------------------------------------------------
+
+;----------------------------------------------------------------------------
+;Status Register
+
+SCG1 equ 128 ; System Clock Generator 1. 1=turn_off_SMCLK
+SCG0 equ 64 ; System Clock Generator 0. 1=turn_off_DCO
+OSCOFF equ 32 ; Oscillator Off. 1=turn_off_LFXT1CLK
+CPUOFF equ 16 ; CPU Off. 1=turn_off_CPU (SR)
+GIE equ 8 ; General Interrupt Enable (SR)
+
+;----------------------------------------------------------------------------
+; Special Function Register of MSP430x1xx Family, Byte Access
+
+IE1 equ 000h ; Interrupt Enable
+ACCVIE equ 32 ; flash-access interrupt enable (IE1.5)
+NMIIE equ 16 ; NMI enable (IE1.4)
+OFIE equ 2 ; Osc-fault-interrupt enable (IE1.1)
+WDTIE equ 1 ; Watchdog interrupt enable (IE1.0)
+
+IFG1 equ 002h ; Interrupt Flag
+NMIIFG equ 16 ; set via !RST/NMI pin (IFG1.4)
+RSTIFG equ 8 ; External reset interrupt flag (IFG1.3)
+PORIFG equ 4 ; Power-on-reset interrupt flag (IFG1.2)
+OFIFG equ 2 ; flag on oscillator fault (IFG1.1)
+WDTIFG equ 1 ; watchdog or security key violation (IFG1.0)
+
+ME1 equ 004h ; Modul Enable
+
+;MSP43012xx devices only, only for MSP43012xx devices.
+
+IE2 equ 001h
+UTXIE0 equ 2 ; USART0 transmit int-enable bit (IE2.2)
+URXIE0 equ 1 ; USART0 receive int-enable bit (IE2.1)
+
+IFG2 equ 003h
+UTXIFG0 equ 2 ; USART0 and SPI transmit flag (IFG2.1)
+URXIFG0 equ 1 ; USART0 and SPI receive flag (IFG2.0)
+
+ME2 equ 005h
+UTXE0 equ 2 ; USART0 transmit enable bit (ME2.1)
+URXE0 equ 1 ; USART0 receive enable bit (ME2.0)
+USPIE0 equ 1 ; SPI transmit+receive enable (ME2.0)
+
+;----------------------------------------------------------------------------
+; Digital I/O, Byte Access
+
+P0IN equ 010h ; Leseregister (Pinzustand)
+P0OUT equ 011h ; Schreibregister (Latches)
+P0DIR equ 012h ; Richtungsregister
+P0IFG equ 013h ; Interrupt-Flags
+P0IES equ 014h ; Interrupf-Flankenwahl
+P0IE equ 015h ; Interrupt-Freigaben
+
+P3IN equ 018h ; Input Register
+P3OUT equ 019h ; Output Register
+P3DIR equ 01Ah ; Direction Register
+P3SEL equ 01Bh ; Function select
+
+P4IN equ 01Ch ; Input Register
+P4OUT equ 01Dh ; Output Register
+P4DIR equ 01Eh ; Direction Register
+P4SEL equ 01Fh ; Function select
+
+P1IN equ 020h ; Input Register
+P1OUT equ 021h ; Output Register
+P1DIR equ 022h ; Direction Register
+P1IFG equ 023h ; Interrupt Flags
+P1IES equ 024h ; Interrupt Edge select
+P1IE equ 025h ; Interrupt enable
+P1SEL equ 026h ; Function select
+
+P2IN equ 028h ; Input Register
+P2OUT equ 029h ; Output Register
+P2DIR equ 02Ah ; Direction Register
+P2IFG equ 02Bh ; Interrupt Flags
+P2IES equ 02Ch ; Interrupt Edge select
+P2IE equ 02Dh ; Interrupt enable
+P2SEL equ 02Eh ; Function select
+
+P5IN equ 030h ; Input Register
+P5OUT equ 031h ; Output Register
+P5DIR equ 032h ; Direction Register
+P5SEL equ 033h ; Function select
+
+P6IN equ 034h ; Input Register
+P6OUT equ 035h ; Output Register
+P6DIR equ 036h ; Direction Register
+P6SEL equ 037h ; Function select
+
+;----------------------------------------------------------------------------
+; LCD-Interface
+
+LCDCTL equ 030h ; Steuerung
+LCD_Start equ 031h ; Startadresse
+LCD_Stop equ 03fh ; Endadresse
+__TMP set 1 ; Einzeldefinitionen
+ rept 9
+LCD{"\{__TMP}"} equ 030h+__TMP
+__TMP set __TMP+1
+ endm
+ rept 6
+LCD1{"\{__TMP-10}"} equ 030h+__TMP
+__TMP set __TMP+1
+ endm
+;----------------------------------------------------------------------------
+; Timer
+
+BTCTL equ 040h ; Basis-Steuerregister Timer 1
+
+TCCTL equ 042h
+TCPLD equ 043h ; Vorladewert
+TCDAT equ 044h ; Z\84hlwert
+
+BTCNT1 equ 046h ; Z\84hlregister
+BTCNT2 equ 047h
+
+TPCTL equ 04Bh ; Timer/Port Steuerregister
+TPCNT1 equ 04Ch ; Z\84hlregister
+TPCNT2 equ 04Dh
+TPD equ 04Eh ; Datenregister
+TPE equ 04Fh ; Freigaberegister
+
+;----------------------------------------------------------------------------
+; Taktgenerator
+
+SCFI0 equ 050h ; Integrator
+SCFI1 equ 051h
+SCFQCTL equ 052h ; Multiplikator Quarzfrequenz
+CBCTL equ 053h ; Puffersteuerung
+
+;----------------------------------------------------------------------------
+; EPROM Control Register, Byte Access
+
+EPCTL equ 054h ; EPROM-Steuerung
+
+;----------------------------------------------------------------------------
+; Basic Clock Registers, Byte Access
+
+DCOCTL equ 056h
+DCO2 equ 128 ;DCO freq select, see RSELx (DCOCTL.7)
+DCO1 equ 64 ; (DCOCTL.6)
+DCO0 equ 32 ; (DCOCTL.5)
+MOD4 equ 16 ;Modulator selection (DCOCTL.4)
+MOD3 equ 8 ; (DCOCTL.3)
+MOD2 equ 4 ; (DCOCTL.2)
+MOD1 equ 2 ; (DCOCTL.1)
+MOD0 equ 1 ; (DCOCTL.0)
+
+BCSCTL1 equ 057h
+XT2OFF equ 128 ; XT2 off. Turn off XT2 oscil (BCSCTL1.7)
+XTS equ 64 ; LFXT1 mode. 0=LowFreq,1=HiFreq (BCSCTL1.6)
+DIVA1 equ 32 ; Divider for ACLK. (BCSCTL1.5)
+DIVA0 equ 16 ; 00=/1, 01=/2, 10=/4, 11=/8 (BCSCTL1.4)
+XT5V equ 8 ; Unused. Always reset to zero (BCSCTL1.3)
+RSEL2 equ 4 ; Resistor select. internal R (BCSCTL1.2)
+RSEL1 equ 2 ; lowest R=0 (BCSCTL1.1)
+RSEL0 equ 1 ; (BCSCTL1.0)
+RSEL_7 equ 7 ; (BCSCTL1.0-2)
+RSEL_6 equ 6 ; (BCSCTL1.0-2)
+RSEL_5 equ 5 ; (BCSCTL1.0-2)
+RSEL_4 equ 4 ; (BCSCTL1.0-2)
+RSEL_3 equ 3 ; (BCSCTL1.0-2)
+RSEL_2 equ 2 ; (BCSCTL1.0-2)
+RSEL_1 equ 1 ; (BCSCTL1.0-2)
+RSEL_0 equ 0 ; (BCSCTL1.0-2)
+
+BCSCTL2 equ 058h
+SELM_3 equ 128+64 ; Select MCLK. 11=LFXT1CLK (BCSCTL2.6.7)
+SELM_2 equ 128 ; MCLK 10=XT2CLK or LFXT1CLK (BCSCTL2.6.7)
+SELM_1 equ 64 ; Select MCLK. 01=DCOCLK (BCSCTL2.6.7)
+SELM_0 equ 0 ; Select MCLK. 00=DCOCLK (BCSCTL2.6.7)
+SELM1 equ 128 ; Select MCLK. 00=01=DCOCLK (BCSCTL2.7)
+SELM0 equ 64 ; 10=XT2CLK or LFXT1CLK=11 (BCSCTL2.6)
+DIVM1 equ 32 ; Divider for MCLK, (BCSCTL2.5)
+DIVM0 equ 16 ; 00=/1, 01=/2, 10=/4, 11=/8 (BCSCTL2.4)
+SELS equ 8 ; Select SMCLK 0=DCOCLK,1=XT2CLK (BCSCTL2.3)
+DIVS1 equ 4 ; Divider for SMCLK, (BCSCTL2.2)
+DIVS0 equ 2 ; 00=/1, 01=/2, 10=/4, 11=/8 (BCSCTL2.1)
+DCOR equ 1 ; DCO resistor. 0=intern,1=extn (BCSCTL2.0)
+
+;----------------------------------------------------------------------------
+; Comparator_A Registers, Byte Access
+
+CACTL1 equ 059h ; Comparator A control register 1
+CACTL2 equ 05Ah ; Comparator A control register 2
+CAPD equ 05Bh ; Comparator A port disable
+
+;----------------------------------------------------------------------------
+; PWM
+
+PWMCTL equ 058h ; Z\84hlwert
+PWMDTB equ 059h ; Pulsweite (Puffer)
+PWMDTR equ 05Ah ; Pulsweite
+PWMCNT equ 05Bh ; Steuerung
+
+;----------------------------------------------------------------------------
+; USART 0
+
+U0CTL equ 070h
+U0TCTL equ 071h
+U0RCTL equ 072h
+U0MCTL equ 073h
+U0BR0 equ 074h
+U0BR1 equ 075h
+U0RXBUF equ 076h
+U0TXBUF equ 077h
+
+;----------------------------------------------------------------------------
+; USART 1
+
+U1CTL equ 078h
+U1TCTL equ 079h
+U1RCTL equ 07Ah
+U1MCTL equ 07Bh
+U1BR0 equ 07Ch
+U1BR1 equ 07Dh
+U1RXBUF equ 07Eh
+U1TXBUF equ 07Fh
+
+;----------------------------------------------------------------------------
+; USART Register Bits
+
+FE equ 128 ; Framing error (low stop bit) (UxRCTL.7)
+PE equ 64 ; Parity error (PE=0 if PENA=0) (UxRCTL.6)
+OE equ 32 ; Overrun error (buffer overrun) (UxRCTL.5)
+BRK equ 16 ; Break detect flag (UxRCTL.4)
+URXEIE equ 8 ; Rec err chars sets URXIFG) (UxRCTL.3)
+URXWIE equ 4 ; Rec wakeup int-enable (URXIFG) (UxRCTL.2)
+RXWAKE equ 2 ; Rec wakeup flag (UxRCTL.1)
+RXERR equ 1 ; Rec error flag (FE,PE,OE,BRK) (UxRCTL.0)
+
+CKPL equ 64 ; Clock polarity 0=UCLKI=UCLK (UxTCTL.6)
+SSEL1 equ 32 ; Source 00=UCLKI, 01=ACLK (UxTCTL.5)
+SSEL0 equ 16 ; Source 10=SMCLKI, 11=SMCLK (UxTCTL.4)
+URXSE equ 8 ; Receive start-edge, 1=enabled (UxTCTL.3)
+TXWAKE equ 4 ; Transmitter wake, 0=data,1=adr (UxTCTL.2)
+TXEPT equ 1 ; Transmitter empty flag (UxTCTL.0)
+
+PENA equ 128 ; Parity enable, 1=enabled (UxCTL.7)
+PEV equ 64 ; Parity select, 1=even,0=odd (UxCTL.6)
+SPB equ 32 ; Stop bit, 0=1stop,1=2stop (UxCTL.5)
+CHAR equ 16 ; Char length, 0=7bit,1=8bit (UxCTL.4)
+LISTEN equ 8 ; Listen enable, 1=loopback->RX (UxCTL.3)
+SYNC equ 4 ; synch mode, 0=USART,1=SPI (UxCTL.2)
+MM equ 2 ; Multiprocessor, 1=use_protocol (UxCTL.1)
+SWRST equ 1 ; software reset, 1=held_reset (UxCTL.0)
+
+;----------------------------------------------------------------------------
+; ADC12 low bytes
+
+ADC12MCTL0 equ 080h
+ADC12MCTL1 equ 081h
+ADC12MCTL2 equ 082h
+ADC12MCTL3 equ 083h
+ADC12MCTL4 equ 084h
+ADC12MCTL5 equ 085h
+ADC12MCTL6 equ 086h
+ADC12MCTL7 equ 087h
+ADC12MCTL8 equ 088h
+ADC12MCTL9 equ 089h
+ADC12MCTL10 equ 08Ah
+ADC12MCTL11 equ 08Bh
+ADC12MCTL12 equ 08Ch
+ADC12MCTL13 equ 08Dh
+ADC12MCTL14 equ 08Eh
+ADC12MCTL15 equ 08Fh
+
+;----------------------------------------------------------------------------
+; LCD Registers
+
+LCDC equ 090h
+__TMP set 1 ; Einzeldefinitionen
+ rept 19
+LCDmemory{"\{__TMP}"} equ LCDC+__TMP
+__TMP set __TMP+1
+ endm
+
+;----------------------------------------------------------------------------
+; A/D-Wandler, Word Access
+
+AIN equ 0110h ; Eingaberegister
+AEN equ 0112h ; Eingabefreigaben
+ACTL equ 0114h ; Steuerung
+ADAT equ 0118h ; Daten
+
+;----------------------------------------------------------------------------
+; Timer_B Interrupt Vector, Word Access
+
+TBIV equ 011Eh
+
+;----------------------------------------------------------------------------
+; Watchdog/Timer, Word Access
+
+WDTCTL equ 0120h
+WDTHOLD equ 128 ; Watchdog timer hold. 1=stopped (WDTCTL.6)
+WDTNMIES equ 64 ; NMI edge select 0=rise,1=fall (WDTCTL.6)
+WDTNMI equ 32 ; NMI pin select, 0=!reset,1=NMI (WDTCTL.5)
+WDTTMSEL equ 16 ; mode select 0=watchdog,1=timer (WDTCTL.4)
+WDTCNTCL equ 8 ; Counter clear, 1=clear_counter (WDTCTL.3)
+WDTSSEL equ 4 ; Source select, 0=SMCLK,1=ACLK (WDTCTL.2)
+WDTIS1 equ 2 ; Watchdog timer interval select (WDTCTL.1)
+WDTIS0 equ 1 ; 00=32768,01=8192,10=512,11=64 (WDTCTL.0)
+
+;----------------------------------------------------------------------------
+; Timer_A Interrupt Vector, Word Access
+
+TAIV equ 012Eh
+
+;----------------------------------------------------------------------------
+; Flash Control, Word Access
+
+FCTL1 equ 0128h
+FCTL2 equ 012Ah
+FCTL3 equ 012Ch
+
+;----------------------------------------------------------------------------
+; Hardware Multiplier, Word Access
+
+MPY equ 0130h ; Multiply unsigned
+MPYS equ 0132h ; Multiply signed
+MAC equ 0134h ; MPY+ACC
+MACS equ 0136h ; MPYS+ACC
+OP2 equ 0138h ; Second Operand
+ResLo equ 013Ah ; Result low word
+ResHi equ 013Ch ; Result high word
+SumExt equ 013Eh ; Sum extend
+
+;----------------------------------------------------------------------------
+; ADC12 high bytes, Word Access
+
+ADC12MEM0 equ 0140h
+ADC12MEM1 equ 0142h
+ADC12MEM2 equ 0144h
+ADC12MEM3 equ 0146h
+ADC12MEM4 equ 0148h
+ADC12MEM5 equ 014Ah
+ADC12MEM6 equ 014Ch
+ADC12MEM7 equ 014Eh
+ADC12MEM8 equ 0150h
+ADC12MEM9 equ 0152h
+ADC12MEM10 equ 0154h
+ADC12MEM11 equ 0156h
+ADC12MEM12 equ 0158h
+ADC12MEM13 equ 015Ah
+ADC12MEM14 equ 015Ch
+ADC12MEM15 equ 015Eh
+
+;----------------------------------------------------------------------------
+; Timer_A Registers, Word Access
+
+TACTL equ 0160h
+CCTL0 equ 0162h
+CCTL1 equ 0164h
+CCTL2 equ 0166h
+CCTL3 equ 0168h
+CCTL4 equ 016Ah
+TAR equ 0170h
+CCR0 equ 0172h
+CCR1 equ 0174h
+CCR2 equ 0176h
+CCR3 equ 0178h
+CCR4 equ 017Ah
+
+;----------------------------------------------------------------------------
+; Timer_B Registers, Word Access
+
+TBCTL equ 0180h
+TBCCTL0 equ 0182h
+TBCCTL1 equ 0184h
+TBCCTL2 equ 0186h
+TBCCTL3 equ 0188h
+TBCCTL4 equ 018Ah
+TBCCTL5 equ 018Ch
+TBCCTL6 equ 018Eh
+TBR equ 0190h
+TBCCR0 equ 0192h
+TBCCR1 equ 0194h
+TBCCR2 equ 0196h
+TBCCR3 equ 0198h
+TBCCR4 equ 019Ah
+TBCCR5 equ 019Ch
+TBCCR6 equ 019Eh
+
+;----------------------------------------------------------------------------
+; ADC12 Registers, Byte and Word Access
+
+ADC12CTL0 equ 01A0h
+ADC12CTL1 equ 01A2h
+ADC12FG equ 01A4h
+ADC12IE equ 01A6h
+
+;----------------------------------------------------------------------------
+
+ endif ; von IFDEF...
+ restore ; wieder erlauben
--- /dev/null
+[InternetShortcut]
+URL=https://sourceforge.net/projects/srecord/
--- /dev/null
+[BG]
+; Use Eterm look-feel Background extension (on/off)
+BGEnable=off
+
+; Use AlphaBlend API (on/off)
+BGUseAlphaBlendAPI=on
+
+; Susie plugin path
+BGSPIPath=plugin
+
+; Fast window sizing/moving
+BGFastSizeMove=on
+
+; Flickerless window moving
+BGFlickerlessMove=on
+
+; If HideTitle=on and BGNoFrame=on, use window without frame
+; you can resize window with Alt + Shift + LeftDrag
+BGNoFrame=on
+
+; wildcard => random select
+BGThemeFile=theme\*.ini
+
+
+[Tera Term]
+; Tera Term version number
+Version=2.3
+
+; Language (English/Japanese/Russian/Korean/UTF-8)
+Language=English
+
+; User interface language file that includes message strings.
+; Tera Term uses built-in English message when the file or message is not found.
+UILanguageFile=lang\French.lng
+
+; Connecting timeout value(per seconds). No action if the value is zero.
+; Connecting socket could be canceled after the value timeout if the value is greater than zero.
+; The default value is zero(depends on Windows TCP/IP stack implementation).
+ConnectingTimeout=0
+
+; pasting string by clicking mouse right button disabled
+DisablePasteMouseRButton=off
+
+; pasting string by clicking mouse middle button disabled
+DisablePasteMouseMButton=on
+
+; confirm pasting string by clicking mouse right button
+ConfirmPasteMouseRButton=off
+
+; confirm changing clipboard string by clicking mouse right button
+ConfirmChangePaste=on
+ConfirmChangePasteCR=on
+PasteDialogSize=330,220
+ConfirmChangePasteStringFile=
+
+; Scroll out the current buffer when the clear screen does.
+ScrollWindowClearScreen=on
+
+; Reset scrollback on display activity
+AutoScrollOnlyInBottomLine=on
+
+; Starting the selection only by a left button.
+SelectOnlyByLButton=on
+
+; Duplicate session by Alt-D Accelerator key disabled
+DisableAcceleratorDuplicateSession=off
+
+; Send break by Alt-B Accelerator key disabled
+DisableAcceleratorSendBreak=off
+
+; Duplicate session Menu disabled
+DisableMenuDuplicateSession=off
+
+; New connection Menu disabled
+DisableMenuNewConnection=off
+
+; Send break Menu disabled
+DisableMenuSendBreak=off
+
+; ANSI color definition (in the case FullColor=on)
+; * UseTextColor should be off, or the background and foreground color of
+; VTColor are assigned to color-number 0 and 7 respectively, even if
+; they are specified in ANSIColor.
+; * ANSIColor is a set of 4 values that are color-number(0--15),
+; red-value(0--255), green-value(0--255) and blue-value(0--255).
+ANSIColor=0,0,0,0, 1,255,0,0, 2,0,255,0, 3,255,255,0, 4,128,128,255, 5,255,0,255, 6,0,255,255, 7,255,255,255, 8,64,64,64, 9,192,0,0, 10,0,192,0, 11,192,192,0, 12,64,64,192, 13,192,0,192, 14,0,192,192, 15,192,192,192
+; xterm
+; ANSIColor=0,0,0,0, 1,255,0,0, 2,0,255,0, 3,255,255,0, 4,92,92,255, 5,255,0,255, 6,0,255,255, 7,255,255,255, 8,127,127,127, 9,205,0,0, 10,0,205,0, 11,205,205,0, 12,0,0,238, 13,205,0,205, 14,0,205,205, 15,229,229,229
+; PuTTY
+;ANSIColor=0,0,0,0, 1,255,85,85, 2,85,255,85, 3,255,255,85, 4,85,85,255, 5,255,85,255, 6,85,255,255, 7,255,255,255, 8,85,85,85, 9,187,0,0, 10,0,187,0, 11,187,187,0, 12,0,0,187, 13,187,0,187, 14,0,187,187, 15,187,187,187
+; Tera Term Pro 2.3
+;ANSIColor=0,0,0,0, 1,255,0,0, 2,0,255,0, 3,255,255,0, 4,0,0,255, 5,255,0,255, 6,0,255,255, 7,255,255,255, 8,128,128,128, 9,128,0,0, 10,0,128,0, 11,128,128,0, 12,0,0,128, 13,128,0,128, 14,0,128,128, 15,192,192,192
+; Solarized (http://ethanschoonover.com/solarized)
+;ANSIColor=0,7,54,66, 1,203,75,22, 2,88,110,117, 3,101,123,131, 4,131,148,150, 5,108,113,196, 6,147,161,161, 7,253,246,227, 8,0,43,54, 9,220,50,47, 10,133,153,0, 11,181,137,0, 12,38,139,210, 13,211,54,130, 14,42,161,152, 15,238,232,213
+
+; Enable continued-line copy
+EnableContinuedLineCopy=on
+
+; Mouse cursor type (arrow/ibeam/cross/hand)
+MouseCursor=ibeam
+
+; Translucent window (0 - 255: transparency value)
+AlphaBlend=255
+
+; Cygwin install path
+CygwinDirectory=c:\cygwin
+
+; Viewlog Editor path
+ViewlogEditor=C:\Windows\notepad.exe
+
+; Locale for Unicode
+;Locale=chs
+Locale=english
+
+; CodePage for Unicode
+CodePage=1252
+
+; Background color of text uses background color of screen (on/off)
+UseNormalBGColor=on
+
+; Port type (serial/tcpip/namedpipe)
+Port=serial
+
+; Window positions
+VTPos=-2147483648,-2147483648
+TEKPos=-2147483648,-2147483648
+
+; Terminal size
+TerminalSize=128,49
+; Terminal size=window size (on/off)
+TermIsWin=off
+; Auto window resizing option (on/off)
+AutoWinResize=off
+
+; Convert a received new-line (CR) char to CR/CRLF/LF/AUTO
+CRReceive=CR
+; New-line code to be transmitted (CR/CRLF)
+CRSend=CR
+
+; Terminal ID
+TerminalID=VT100
+
+; Local echo (on/off)
+LocalEcho=off
+
+; Answerback
+Answerback=
+
+; Auto window switching (VT<->TEK; on/off)
+AutoWinSwitch=off
+
+; Kanji code to be received (SJIS/EUC/JIS)
+KanjiReceive=UTF-8
+; JIS Katakana code to be received (7/8)
+KatakanaReceive=8
+
+; Kanji code to be transmitted (SJIS/EUC/JIS)
+KanjiSend=UTF-8
+; JIS Katakana to be transmitted (7/8)
+KatakanaSend=8
+; Kanji-in sequence to be transmitted (@/B)
+KanjiIn=B
+; Kanji-out sequence to be transmitted (J/B)
+KanjiOut=B
+
+; Russian code set used in host
+RussHost=Windows
+; Russian code set used in PC
+RussClient=Windows
+
+; Window title
+Title=Tera Term
+
+; Cursor shape (block/vertical/horizontal)
+CursorShape=block
+
+; Hide title & menu bars and enable popup menu (on/off)
+HideTitle=off
+; Hide menu bar and enable popup menu (on/off)
+PopupMenu=off
+
+; Color mode (on/off)
+EnableANSIColor=on
+PcBoldColor=on
+Aixterm16Color=on
+Xterm256Color=on
+
+; Enable scroll buffer (on/off)
+EnableScrollBuff=on
+; Scroll buffer size
+ScrollBuffSize=10000
+
+; Text and background colors
+; for Normal characters
+VTColor=0,255,0,0,0,0
+; Solarized Dark
+;VTColor=131,148,150,0,43,54
+; Solarized Light
+;VTColor=101,123,131,253,246,227
+;
+; for Bold characters
+EnableBoldAttrColor=on
+VTBoldColor=255,255,0,0,0,0
+; Solarized Dark
+;VTBoldColor=147,161,161,7,54,66
+; Solarized Light
+;VTBoldColor=88,110,117,238,232,213
+;
+; for Blink characters
+EnableBlinkAttrColor=on
+VTBlinkColor=255,0,0,0,0,0
+; Solarized Dark
+;VTBlinkColor=133,153,0,0,43,54
+; Solarized Light
+;VTBlinkColor=133,153,0,253,246,227
+;
+; for Reverse characters
+EnableReverseAttrColor=on
+VTReverseColor=0,0,0,255,255,255
+; Solarized Dark
+;VTReverseColor=0,43,54,131,148,150
+;VTReverseColor=101,123,131,253,246,227
+; Solarized Light
+;VTReverseColor=253,246,227,101,123,131
+;VTReverseColor=131,148,150,0,43,54
+;
+; for URL(hyper link) text color
+EnableURLColor=on
+URLUnderline=on
+URLColor=0,255,255,0,0,0
+; Solarized Dark
+;URLColor=181,137,0,0,43,54
+; Solarized Light
+;URLColor=181,137,0,253,246,227
+;
+
+; Enable clickable URL
+EnableClickableUrl=on
+
+; Launched Browser
+; Firefox example
+; ClickableUrlBrowser=firefox
+; ClickableUrlBrowserArg=-new-tab
+; Opera example
+; ClickableUrlBrowser=opera
+; ClickableUrlBrowserArg=-newpage
+; IE example
+; ClickableUrlBrowser=iexplore
+; ClickableUrlBrowserArg=
+; Chrome example
+; ClickableUrlBrowser=chrome
+; ClickableUrlBrowserArg=
+ClickableUrlBrowser=
+ClickableUrlBrowserArg=
+
+
+; for TEK window
+TEKColor=0,0,0,255,255,255
+
+; TEK color emulation (on/off)
+TEKColorEmulation=off
+
+; Font
+VTFont=Courier New,0,-18,0
+; Bold style font (on/off)
+EnableBold=on
+; Font for TEK window
+TEKFont=Terminal,0,-8,255
+; Font quality(default/non-antialiased/antialiased/cleartype)
+FontQuality=default
+
+; Russian code set of the font
+RussFont=Windows
+
+; Backspace key (BS/DEL)
+BSKey=BS
+; transmit DEL by Delete key (on/off)
+DeleteKey=on
+
+; Russian code set used in the keyboard driver
+RussKeyb=Windows
+
+; Meta key (on/off/left/right)
+MetaKey=off
+
+; Meta key sets MSB (off/raw/text)
+Meta8Bit=off
+
+; Application keypad mode disabled.
+DisableAppKeypad=off
+
+; Application cursor mode disabled.
+DisableAppCursor=off
+
+; Serial port parameters
+; Port number
+ComPort=5
+; Baud rate
+BaudRate=921600
+; Parity (even/odd/none/mark/space)
+Parity=none
+; Data (7/8)
+DataBit=8
+; Stop (1/1.5/2)
+StopBit=1
+; Flow control (x/hard/none)
+FlowCtrl=x
+; Transmit delay per character (in msec)
+DelayPerChar=0
+; Transmit delay per line (in msec)
+DelayPerLine=0
+
+; TCP/IP parameters
+; TCP port#
+TCPPort=23
+; Telnet flag (on/off)
+Telnet=on
+; Telnet terminal type
+;TermType=vt100
+TermType=xterm
+
+; Auto window closing option (on/off)
+AutoWinClose=on
+; History list of hosts
+HistoryList=on
+
+; Binary flag for Send File (on/off)
+TransBin=off
+
+; without transfer dialog flag for Send File (on/off)
+FTHideDialog=off
+
+; Binary flag for Log (on/off)
+LogBinary=off
+; Log append (on/off)
+LogAppend=on
+; plain text flag for Log (on/off)
+LogTypePlainText=on
+; timestamp flag for Log (on/off)
+LogTimestamp=off
+; without transfer dialog flag for Log (on/off)
+LogHideDialog=off
+; Current all buffer included in first (on/off)
+LogIncludeScreenBuffer=off
+
+; Default Log file name. You can specify strftime format to here.
+LogDefaultName=teraterm.log
+; Default path to save the log file.
+LogDefaultPath=
+; Auto start logging with default log file name.
+LogAutoStart=off
+
+; === Log Rotate ===
+; Mode: 0(none), 1(size)
+LogRotate=0
+; Size
+LogRotateSize=0
+; Size type: 0(byte), 1(KB), 2(MB)
+LogRotateSizeType=0
+; Step: 0(none), >=1(count times)
+LogRotateStep=0
+
+; Deferred Log Write Mode (on/off)
+DeferredLogWriteMode=on
+
+
+; XMODEM option (checksum/crc/1k)
+XmodemOpt=checksum
+; Binary flag for XMODEM Receive and ZMODEM Send (on/off)
+XmodemBin=on
+
+; XMODEM receive command
+XmodemRcvCommand=
+
+; Default directory for file transfers
+FileDir=A:\projets\msp430\DTCforth
+
+; Filter for send file
+FileSendFilter=
+
+; SCP sending directory
+ScpSendDir=~/
+
+; Save Broadcast Command History
+BroadcastCommandHistory=on
+
+; Broadcast command enabling flag on the dialog window (on/off)
+AcceptBroadcast=on
+
+; Number of broadcast command history
+MaxBroadcatHistory=99
+
+;------ special options (see Tera Term help)
+
+; C1 (8-bit) control characters
+Accept8BitCtrl=on
+Send8BitCtrl=off
+
+; Accept remote-controlled window title changing (off/overwrite/ahead/last)
+AcceptTitleChangeRequest=overwrite
+
+; Wrong kanji-out ^[(H (Japanese only)
+AllowWrongSequence=off
+
+; Alternate screen buffer support
+AlternateScreenBuffer=on
+
+; Auto file renaming for downloading
+AutoFileRename=on
+
+; Auto text copying
+AutoTextCopy=on
+
+; Back wrap
+BackWrap=off
+
+; Beep by BEL (on/off/visual)
+Beep=on
+
+; Beep over-used
+BeepOverUsedTime=2
+BeepOverUsedCount=5
+BeepSuppressTime=5
+
+; Beep on connection & disconnection
+BeepOnConnect=off
+
+; B-Plus auto receive
+BPAuto=off
+
+; Escape all control characters in B-Plus
+BPEscCtl=off
+
+; B-Plus log
+BPLog=off
+
+; Clear serial port buffer when port opening
+ClearComBuffOnOpen=on
+
+; Clear screen when window is resized
+ClearOnResize=on
+
+; Clear screen after the connection is closed
+ClearScreenOnCloseConnection=off
+
+; Clipboard access from remote (on/off/read/write)
+ClipboardAccessFromRemote=off
+
+; "Disconnect?" warning
+ConfirmDisconnect=on
+
+; Control characters in kanji (Japanese only)
+CtrlInKanji=on
+
+; Confirm send a file when drag and drop
+ConfirmFileDragAndDrop=on
+
+; allow the sequences related to cursor control
+CursorCtrlSequence=off
+
+; Display all characters (debug mode)
+Debug=off
+
+; Delimters for word selection
+; (compatible with earlier versions of Tera Term)
+; DelimList=$20
+; DelimDBCS=off
+DelimList=$20!"#$24%&'()*+,:;<=>?@[\]^`{|}
+DelimDBCS=on
+
+; Disable mouse event tracking when Control-Key is pressed.
+DisableMouseTrackingByCtrl=on
+
+; Disable wheel to cursor translation when Control-Key is pressed.
+DisableWheelToCursorByCtrl=on
+
+; Line at a time mode
+EnableLineMode=on
+
+; Popup menu
+EnablePopupMenu=on
+
+; "Show menu bar" command
+EnableShowMenu=on
+
+; Enable the status line
+EnableStatusLine=on
+
+; Display "New Connection" dialog on startup
+HostDialogOnStartup=on
+
+; Enable IME / inline input (Japanese only)
+IME=on
+IMEInline=on
+
+IMERelatedCursor=off
+
+; Windows 7 jump list support
+JumpList=on
+
+; Join Split URL
+JoinSplitURL=off
+JoinSplitURLIgnoreEOLChar=\
+
+; Kermit log
+KmtLog=off
+; Kermit CAPAS: Ability to transmit and receive extended-length packets
+KmtLongPacket=off
+; Kermit CAPAS: Ability to accept "A" packets (file attributes)
+KmtFileAttr=off
+
+; Language selection
+LanguageSelection=on
+
+; Lock Terminal Unique ID
+LockTUID=on
+
+; Exclusive lock for log file
+LogLockExclusive=on
+
+; Max scroll buffer size
+MaxBuffSize=500000
+
+; Max serial port number
+MaxComPort=256
+
+; Max buffer size of OSC string
+MaxOSCBufferSize=4096
+
+; Mouse event tracking
+MouseEventTracking=on
+
+; Maximized window bug tweak
+MaximizedBugTweak=on
+
+; Nonblinking cursor
+NonblinkingCursor=off
+
+; Polygon cursor for KILLFOCUS
+KillFocusCursor=on
+
+; Delay for pass-thru printing (in secs)
+PassThruDelay=3
+
+; Direct pass-thru printing
+PassThruPort=
+
+; Delay for paste per each lines (in msec)
+PasteDelayPerLine=10
+
+; Allow the sequences related to printer control
+PrinterCtrlSequence=on
+
+; Printer font
+PrnFont=
+
+; Page margins for printing
+; (left, right, top and bottom in 1/100 inches)
+PrnMargin=50,50,50,50
+
+; Quick-VAN log
+QVLog=off
+
+; Quick-VAN window size
+QVWinSize=8
+
+; Russian code set of printer font
+RussPrint=Windows
+
+; Save VT Window position
+SaveVTWinPos=off
+
+; Max lines per one jump scroll
+ScrollThreshold=12
+
+; Scroll line count with mouse wheel button
+MouseWheelScrollLine=3
+
+; Text selection on window activation
+SelectOnActivate=on
+
+; Startup macro
+StartupMacro=
+
+; Strict Key Mapping
+StrictKeyMapping=off
+
+; Tab Stop Modify Sequence (on/off/combination of HTS,HTS7,HTS8,TBC,TBC0,TBC3)
+TabStopModifySequence=on
+
+; TEK mouse code
+TEKGINMouseCode=32
+
+; Telnet Auto Detection
+TelAutoDetect=on
+
+; Telnet binary option
+TelBin=off
+
+; Telnet auto echo
+TelEcho=off
+
+; Telnet log
+TelLog=off
+
+; Standard telnet port
+TelPort=23
+
+; Keep-Alive packet sending interval on telnet connection (per second, 0=disabled)
+TelKeepAliveInterval=300
+
+; Auto setup for non-telnet
+TCPLocalEcho=off
+TCPCRSend=
+
+; Terminal Unique ID
+TerminalUID=FFFFFFFF
+
+; Title format
+; format ID: 5(000101) <title> - <host/port> VT/TEK
+; format ID: 13(001101) <host/port> - <title> VT/TEK
+; format ID: 29(011101) <host:tcpport/port> - <title> VT/TEK
+; format ID: 45(101101) <host/port:baud> - <title> VT/TEK
+; format ID: 61(111101) <host:tcpport/port:baud> - <title> VT/TEK
+TitleFormat=61
+
+; Allow the sequences related to title report (accept/ignore/empty)
+TitleReportSequence=empty
+
+; Translate mouse wheel to cursor key when application cursor mode
+TranslateWheelToCursor=on
+
+; Unknown Unicode character handling
+UnknownUnicodeCharacterAsWide=off
+
+; Mapping of Unicode to DEC special character
+; The sum of following values:
+; 1 : Box drawings (U+2500-U+257F)
+; 2 : Bullet (U+2022)
+; Hyphenation point (U+2027)
+; Light shade (25%) (U+2591)
+; Medium shade (50%) (U+2592)
+; Dark shade (75%) (U+2593)
+; Black small square (U+25AA)
+; Black vertical rectangle (U+25AE)
+; Black verty small square (U+2B1D)
+; 4 : Middle dot (U+00B7)
+; One dot leader (U+2024)
+; Bullet operator (U+2219)
+UnicodeToDecSpMapping=3
+
+; White & black color conversion
+UseTextColor=off
+
+; VT Compatible Tab
+VTCompatTab=off
+
+; Space between characters (lines)
+VTFontSpace=0,0,0,0
+
+; Window Icon
+VTIcon=Default
+TEKIcon=Default
+
+; Scaling factors for printing (in pixels per inch)
+VTPPI=0,0
+TEKPPI=0,0
+
+; `wait4all' macro command
+Wait4allMacroCommand=off
+
+; allow the sequences related to window control
+WindowCtrlSequence=on
+
+; allow the sequences related to window report
+WindowReportSequence=on
+
+; [Window] menu
+WindowMenu=on
+
+; XMODEM log
+XmodemLog=off
+
+; YMODEM log
+YmodemLog=off
+
+; YMODEM receive command
+YmodemRcvCommand=
+
+; ZMODEM auto receive
+ZmodemAuto=off
+
+; ZMODEM parameters for sending
+ZmodemDataLen=1024
+ZmodemWinSize=32767
+
+; Escape all control characters in ZMODEM
+ZmodemEscCtl=off
+
+; ZMODEM log
+ZmodemLog=off
+
+; ZMODEM receive command
+ZmodemRcvCommand=rz
+
+;------ end of special options
+
+[TTSSH]
+; SSH enabled flag (1=enabled 0=disabled)
+Enabled=1
+
+; default login username (setup to authentication dialog)
+DefaultUserName=
+DefaultForwarding=
+
+; Cipher algorithm order
+; 2...DES(SSH1), 3...3DES(SSH1), 6...Blowfish(SSH1), 7...3DES-CBC,
+; 8...AES128-CBC, 9...AES192-CBC, :...AES256-CBC, ;...Blowfish-CBC,
+; <...AES128-CTR, =...AES192-CTR, >...AES256-CTR, ?...Arcfour,
+; @...Arcfour128, A...Arcfour256, B...CAST128-CBC, C...3DES-CTR,
+; D...Blowfish-CTR, E...CAST128-CTR, F...Camellia128-CBC,
+; G...Camellia192-CBC, H...Camellia256-CBC, I...Camellia128-CTR,
+; J...Camellia192-CTR, K...Camellia256-CTR
+; 0...Ciphers below this line are disabled.
+CipherOrder=K>H:J=G9I<F8C7D;A@?EB3062
+
+; KEX algorithm order(SSH2)
+; 0...diffie-hellman-group1-sha1
+; 1...diffie-hellman-group14-sha1
+; 2...diffie-hellman-group-exchange-sha1
+; 3...diffie-hellman-group-exchange-sha256
+; 4...ecdh-sha2-nistp256
+; 5...ecdh-sha2-nistp384
+; 6...ecdh-sha2-nistp521
+; 7...KEXs below this line are disabled.
+KexOrder=56743210
+
+; Host Key algorithm order(SSH2)
+; 2...RSA
+; 3...DSA
+; 4...ecdh-sha2-nistp256
+; 5...ecdh-sha2-nistp384
+; 6...ecdh-sha2-nistp521
+; 0...below this line are disabled.
+HostKeyOrder=456230
+
+; MAC algorithm order(SSH2)
+; 1...hmac-sha1
+; 2...hmac-md5
+; 3...hmac-sha1-96
+; 4...hmac-md5-96
+; 5...hmac-ripemd160@openssh.com
+; 6...hmac-sha2-256
+; 8...hmac-sha2-512
+; 0...below this line are disabled.
+MacOrder=86152034
+
+; Compression algorithm order(SSH2)
+; 1...none
+; 2...zlib
+; 3...zlib@openssh.com(Delayed Compression)
+; 0...below this line are disabled.
+CompOrder=3210
+; packet compression level (0=none)
+Compression=0
+
+
+KnownHostsFiles=ssh_known_hosts
+DefaultRhostsLocalUserName=
+DefaultRhostsHostPrivateKeyFile=
+DefaultRSAPrivateKeyFile=
+DefaultAuthMethod=3
+; Debug message logging level of `TTSSH.LOG'.
+; The default value is disabled(0).
+; LOG_LEVEL_FATAL 5
+; LOG_LEVEL_ERROR 10
+; LOG_LEVEL_URGENT 20
+; LOG_LEVEL_WARNING 30
+; LOG_LEVEL_VERBOSE 100
+; LOG_LEVEL_SSHDUMP 200
+LogLevel=0
+WriteBufferSize=2097152
+
+; SSH protocol version (1 or 2)
+ProtocolVersion=2
+
+; SSH heartbeat(keepalive): per second (0=disabled)
+HeartBeat=60
+
+; Remember password in memory (1=enabled 0=disabled)
+RememberPassword=1
+
+; Check supported auth methods with "none" method (1=enabled 0=disabled)
+CheckAuthListFirst=0
+
+; Enable connection to the server that has RSA key length less than 768 bit (1=enabled 0=disabled)
+EnableRsaShortKeyServer=0
+
+; SSH agent forwarding (pageant) (1=enabled 0=disabled)
+ForwardAgent=0
+
+; Confirm SSH agent forwarding (1=enabled 0=disabled)
+ForwardAgentConfirm=1
+
+; Verify host key by DNS (1=enabled 0=disabled)
+VerifyHostKeyDNS=0
+
+; SSH Icon
+SSHIcon=Default
+
+[TTProxy]
+ConnectionTimeout="10"
+SocksResolve="auto"
+TelnetHostnamePrompt=">> Host name: "
+TelnetUsernamePrompt="Username:"
+TelnetPasswordPrompt="Password:"
+TelnetConnectedMessage="-- Connected to "
+TelnetErrorMessage="!!!!!!!!"
+
+[TTXKanjiMenu]
+UseOneSetting=on
+
+[TTXttyrec]
+RecordStartSize=on
+
+[TTXRecurringCommand]
+Enable=off
+Command=
+Interval=300
+
+[Resize Menu]
+; 80x62
+;ResizeMenu1= 80, 24
+;
+; 120x52
+;ResizeMenu2=120, 52
+;
+; Width: no-change, Height: 52
+;ResizeMenu3= 0, 52
+;
+; Width: 80, Height: no-change
+;ResizeMenu4= 80, 0
+
+;------ Telnet host list
+; Max number of hosts is 200.
+; You can edit this list in the [Setup] TCP/IP dialog box.
+;[Hosts]
+; Host name
+;Host1=myhost.example.com
+; IPv4 address
+;Host2=192.0.2.1
+; IPv6 address
+;Host3=[2001:db8:1:2:8401:02ff:fe03:0405]
+; IPv6 address with interface number
+;Host4=[fe80::8401:02ff:fe03:0405%3]
+; Host name with option
+;Host5=myhost.example.com /F=myhost.ini
+; Host name with user, port and option
+;Host6=user@myhost.example.com:10022 /ssh
+; URL
+;Host7=ssh://user@myhost.example.com
+; COM1 port
+;Host8=/C=1
+; Replay a file
+;Host9=/R=readme.txt
+
+[Hosts]
+Host1=192.168.0.19/
+Host2=ssh://192.168.0.19/
+Host3=ssh://192.168.0.19
+Host4=myhost.example.com
+Host5=192.0.2.1
+Host6=[2001:db8:1:2:8401:2ff:fe03:405]
+Host7=[fe80::8401:2ff:fe03:405%3]
+Host8=myhost.example.com /F=myhost.ini
+Host9=user@myhost.example.com:10022 /ssh
+Host10=ssh://user@myhost.example.com
+Host11=/C=1 ;serial port
+Host12=\\.\pipe\vmware-serial-port ;Named pipe
+Host13=/R=readme.txt ;replay a file
--- /dev/null
+[InternetShortcut]
+URL=http://gema.sourceforge.net/new/index.shtml
--- /dev/null
+[InternetShortcut]
+URL=http://www.scintilla.org/SciTEDownload.html
--- /dev/null
+# Global initialisation file for SciTE
+# For Linux, place in $prefix/share/scite
+# For Windows, place in same directory as SciTE.EXE (or Sc1.EXE)
+# Documentation at http://www.scintilla.org/SciTEDoc.html
+
+# Globals
+
+# Window sizes and visibility
+if PLAT_WIN
+ position.left=0
+ position.top=0
+if PLAT_GTK
+ position.left=5
+ position.top=22
+position.width=576
+position.height=740
+position.maximize=1
+#position.tile=1
+#full.screen.hides.menu=1
+#minimize.to.tray=1
+split.vertical=1
+#output.horizontal.size=200
+#output.vertical.size=60
+#output.initial.hide=1
+#horizontal.scrollbar=0
+#horizontal.scroll.width=10000
+#horizontal.scroll.width.tracking=0
+#output.horizontal.scrollbar=0
+#output.horizontal.scroll.width=10000
+#output.horizontal.scroll.width.tracking=0
+#output.scroll=0
+#error.select.line=1
+#end.at.last.line=0
+tabbar.visible=1
+#tabbar.hide.one=1
+#tabbar.multiline=1
+toolbar.visible=1
+#toolbar.usestockicons=1
+#toolbar.large=1
+#menubar.detachable=1
+#undo.redo.lazy=1
+#statusbar.visible=1
+#fileselector.width=800
+#fileselector.height=600
+#fileselector.show.hidden=1
+#magnification=-1
+#output.magnification=-1
+
+# Sizes and visibility in edit pane
+#line.margin.visible=1
+line.margin.width=4
+margin.width=16
+#fold.margin.width=16
+#fold.margin.colour=#FF0000
+#fold.margin.highlight.colour=#0000FF
+#blank.margin.left=4
+#blank.margin.right=4
+buffered.draw=1
+#phases.draw=2
+if PLAT_WIN
+ technology=1
+#font.quality=3
+if PLAT_MAC
+ font.quality=3
+
+# Element styles
+#view.eol=1
+#control.char.symbol=.
+caret.period=500
+view.whitespace=0
+view.indentation.whitespace=1
+view.indentation.guides=1
+view.indentation.examine=3
+highlight.indentation.guides=1
+#caret.fore=#FF0000
+#caret.additional.blinks=0
+#caret.width=2
+#caret.line.back=#FFFED8
+caret.fore=#FF0000
+caret.width=3
+caret.line.back=#222222
+#caret.line.back.alpha=63
+edge.column=200
+edge.mode=0
+edge.colour=#C0DCC0
+braces.check=1
+braces.sloppy=1
+#selection.fore=#006000
+# DADADA used as background because it yields standard silver C0C0C0
+# on low colour displays and a reasonable light grey on higher bit depths
+if PLAT_WINNT
+# selection.alpha=32
+# selection.back=#000000
+selection.fore=#000000
+selection.alpha=256
+selection.back=#808080
+if PLAT_GTK
+ selection.alpha=30
+ selection.back=#000000
+if PLAT_MAC
+ selection.alpha=32
+ selection.back=#000000
+#selection.additional.fore=#0000A0
+#selection.additional.back=#000080
+#selection.additional.alpha=20
+#selection.rectangular.switch.mouse=1
+#selection.multiple=0
+#selection.additional.typing=0
+#virtual.space=3
+#rectangular.selection.modifier=4
+#whitespace.fore=#FF0000
+#whitespace.back=#FFF0F0
+#error.marker.fore=#0000A0
+#error.marker.back=#DADAFF
+#error.inline=1
+bookmark.fore=#BE0000
+#bookmark.back=#FFFFA0
+#bookmark.alpha=
+#find.mark=#0000FF
+#find.mark.indicator=style:compositionthick,colour:#FFB700,under
+#highlight.current.word=1
+#highlight.current.word.by.style=1
+#highlight.current.word.colour=#00D040
+#highlight.current.word.indicator=style:roundbox,colour:#0080FF,under,outlinealpha:140,fillalpha:80
+#indicators.alpha=63
+#indicators.under=1
+
+# Scripting
+ext.lua.startup.script=$(SciteUserHome)/SciTEStartup.lua
+ext.lua.auto.reload=1
+#ext.lua.reset=1
+
+# Checking
+are.you.sure=1
+#are.you.sure.for.build=1
+#save.all.for.build=1
+#quit.on.close.last=1
+#load.on.activate=1
+#save.on.deactivate=1
+#are.you.sure.on.reload=1
+#save.on.timer=20
+#reload.preserves.undo=1
+#check.if.already.open=1
+#temp.files.sync.load=1
+default.file.ext=.cxx
+#source.default.extensions=.h|.cxx|.bat
+#title.full.path=1
+#title.show.buffers=1
+#pathbar.visible=1
+#save.recent=1
+#save.session=1
+#session.bookmarks=1
+#session.folds=1
+#save.position=1
+#save.find=1
+#open.dialog.in.file.directory=1
+#strip.trailing.spaces=1
+#ensure.final.line.end=1
+#ensure.consistent.line.ends=1
+#save.deletes.first=1
+#save.check.modified.time=1
+buffers=40
+buffers.zorder.switching=1
+#api.*.cxx=d:\api\w.api
+locale.properties=locale.fr.properties
+#translation.missing=***
+#read.only=1
+#background.open.size=20000
+#background.save.size=20000
+if PLAT_GTK
+ background.save.size=10000000
+#max.file.size=1
+
+# Indentation
+tabsize=4
+indent.size=4
+use.tabs=0
+#indent.auto=1
+indent.automatic=1
+indent.opening=0
+indent.closing=0
+#tab.indents=0
+#backspace.unindents=0
+
+# Wrapping of long lines
+#wrap=1
+#wrap.style=2
+#cache.layout=3
+#output.wrap=1
+#output.cache.layout=3
+#wrap.visual.flags=3
+#wrap.visual.flags.location=3
+#wrap.indent.mode=1
+#wrap.visual.startindent=4
+
+# Folding
+# enable folding, and show lines below when collapsed.
+fold=1
+fold.compact=0
+fold.flags=16
+fold.symbols=1
+#fold.highlight=1
+#fold.highlight.colour=#00C0C0
+#fold.on.open=1
+fold.comment=1
+fold.preprocessor=1
+
+# Find and Replace
+# Internal search always available with recursive capability so use in preference to external tool
+find.command=
+# findstr is available on recent versions of Windows including 2000
+#if PLAT_WIN
+# find.command=findstr /n /s $(find.what) $(find.files)
+#find.input=$(find.what)
+#if PLAT_GTK
+# find.command=grep --line-number "$(find.what)" $(find.files)
+find.files=*.c *.cxx *.h
+#find.in.files.close.on.find=0
+#find.in.dot=1
+#find.in.binary=1
+#find.in.directory=
+#find.close.on.find=0
+#find.replace.matchcase=1
+#find.replace.escapes=1
+#find.replace.regexp=1
+#find.replace.regexp.posix=1
+#find.replace.wrap=0
+#find.replacewith.focus=0
+#find.replace.advanced=1
+find.use.strip=0
+#find.strip.incremental=1
+#find.indicator.incremental=style:compositionthick,colour:#FFB700,under
+replace.use.strip=0
+#replace.strip.incremental=1
+#strip.button.height=24
+
+# Behaviour
+#eol.mode=LF
+eol.auto=1
+clear.before.execute=0
+#vc.home.key=1
+#wrap.aware.home.end.keys=1
+#autocompleteword.automatic=1
+#autocomplete.choose.single=1
+#autocomplete.*.fillups=([
+#autocomplete.*.start.characters=.:
+caret.policy.xslop=1
+caret.policy.width=20
+caret.policy.xstrict=0
+caret.policy.xeven=0
+caret.policy.xjumps=0
+caret.policy.yslop=1
+caret.policy.lines=1
+caret.policy.ystrict=1
+caret.policy.yeven=1
+caret.policy.yjumps=0
+#visible.policy.strict=1
+#visible.policy.slop=1
+#visible.policy.lines=4
+#time.commands=1
+#caret.sticky=1
+properties.directory.enable=1
+
+# Status Bar
+statusbar.number=4
+statusbar.text.1=\
+li=$(LineNumber) co=$(ColumnNumber) $(OverType) ($(EOLMode)) $(FileAttr)
+statusbar.text.2=\
+$(BufferLength) chars in $(NbOfLines) lines. Sel: $(SelLength) chars.
+statusbar.text.3=\
+Now is: Date=$(CurrentDate) Time=$(CurrentTime)
+statusbar.text.4=\
+$(FileNameExt) : $(FileDate) - $(FileTime) | $(FileAttr)
+
+if PLAT_WIN
+ command.scite.help="file://$(SciteDefaultHome)\SciTEDoc.html"
+ command.scite.help.subsystem=2
+if PLAT_GTK
+ command.print.*=a2ps "$(FileNameExt)"
+ command.scite.help=xdg-open "file://$(SciteDefaultHome)/SciTEDoc.html"
+
+# Internationalisation
+# Japanese input code page 932 and ShiftJIS character set 128
+#code.page=932
+#character.set=128
+# Unicode
+#code.page=65001
+code.page=0
+#character.set=204
+#command.discover.properties=python /home/user/FileDetect.py "$(FilePath)"
+# Required for Unicode to work on GTK+:
+#LC_CTYPE=en_US.UTF-8
+if PLAT_GTK
+ output.code.page=65001
+if PLAT_MAC
+ output.code.page=65001
+
+# Export
+#export.keep.ext=1
+export.html.wysiwyg=1
+#export.html.tabs=1
+#export.html.folding=1
+export.html.styleused=1
+#export.html.title.fullpath=1
+#export.rtf.tabs=1
+#export.rtf.font.face=Arial
+#export.rtf.font.size=9
+#export.rtf.tabsize=8
+#export.rtf.wysiwyg=0
+#export.tex.title.fullpath=1
+# Magnification (added to default screen font size)
+export.pdf.magnification=0
+# Font: Courier, Helvetica or Times (Courier line-wraps)
+export.pdf.font=Helvetica
+# Page size (in points): width, height
+# E.g. Letter 612,792; A4 595,842; maximum 14400,14400
+export.pdf.pagesize=595,842
+# Margins (in points): left, right, top, bottom
+export.pdf.margins=72,72,72,72
+export.xml.collapse.spaces=1
+export.xml.collapse.lines=1
+
+# Define values for use in the imported properties files
+chars.alpha=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+chars.numeric=0123456789x
+chars.accented=\8a\9a\8c\9c\9fÿÀàÁáÂâÃãÄäÅåÆæÇçÈèÉéÊêËëÌìÍíÎîÏïÐðÑñÒòÓóÔôÕõÖØøÙùÚúÛûÜüÝýÞþßö
+# This is a better set for Russian:
+#chars.accented=ÀàÁáÂâÃãÄäÅ娸ÆæÇçÈèÉéÊêËëÌìÍíÎîÏïÐðÑñÒòÓóÔôÕõÖö×÷ØøÙùÚúÛûÜüÝýÞþßÿ
+
+# The open.filter setting is used in the file selector which has a menu of filters to apply
+# to the types of files seen when opening.
+# There is a limit (possibly 256 characters) to the length of a filter on Windows,
+# so not all source extensions can be in this setting.
+source.files=*.asm;*.f;*.inc;*.c;*.cc;*.cpp;*.cxx;*.cs;*.h;*.hh;*.hxx;*.hpp;\
+*.idl;*.odl;*.rc;*.rc2;*.dlg;*.def;\
+*.vb;*.vbs;*.bas;*.frm;*.cls;*.ctl;\
+*.java;*.js;*.py;*.pyw;*.pl;*.rb;*.cgi;*.lua;*.conf;\
+make*;*.mak;\
+*.properties;*.html;*.xml;*.iface;*.bat;*.e;*.m;*.mm;\
+*.sh;*.patch
+
+# Each platform has a different idea of the most important filters
+if PLAT_WIN
+ all.files=All Files (*.*)|*.*|
+ top.filters=All Source|$(source.files)|$(all.files)
+if PLAT_GTK
+ all.files=All Files (*)|*|Hidden Files (.*)|.*|
+ top.filters=All Source|$(source.files)|$(all.files)
+# As OS X only greys out filtered files, show all as default
+if PLAT_MAC
+ all.files=All Files (*.*)|*.*|
+ top.filters=$(all.files)All Source|$(source.files)|
+
+open.filter=\
+$(top.filters)\
+$(filter.ada)\
+$(filter.conf)\
+$(filter.asm)\
+$(filter.asn1)\
+$(filter.ave)\
+$(filter.baan)\
+$(filter.bash)\
+$(filter.caml)\
+$(filter.cmake)\
+$(filter.cpp)\
+#$(filter.ch)\
+$(filter.css)\
+$(filter.d)\
+$(filter.eiffel)\
+$(filter.erlang)\
+$(filter.fortran)\
+$(filter.gap)\
+#$(filter.hs)\
+$(filter.idl)\
+$(filter.inno)\
+$(filter.java)\
+$(filter.js)\
+$(filter.kix)\
+$(filter.lout)\
+$(filter.lua)\
+$(filter.matlab)\
+$(filter.metapost)\
+$(filter.mmixal)\
+#$(filter.modula3)\
+$(filter.nncrontab)\
+$(filter.nsis)\
+$(filter.opal)\
+$(filter.pascal)\
+$(filter.perl)\
+$(filter.php)\
+$(filter.pov)\
+$(filter.powershell)\
+$(filter.prg)\
+$(filter.properties)\
+$(filter.ps)\
+$(filter.python)\
+$(filter.r)\
+$(filter.ruby)\
+#$(filter.rust)\
+$(filter.sql)\
+$(filter.specman)\
+$(filter.tcl)\
+$(filter.tex)\
+$(filter.text)\
+$(filter.txt2tags)\
+$(filter.vb)\
+$(filter.web)\
+$(filter.yaml)\
+$(filter.verilog)\
+$(filter.vhdl)
+
+#save.filter=$(open.filter)
+
+# Give symbolic names to the set of fonts used in the standard styles.
+if PLAT_WIN
+ font.base=font:Lucida Console,size:10
+ font.small=font:Verdana,size:8
+ font.comment=font:Georgia,size:10.1
+ font.code.comment.box=$(font.comment)
+ font.code.comment.line=$(font.comment)
+ font.code.comment.doc=$(font.comment)
+ font.code.comment.nested=$(font.comment)
+ font.text=font:Times New Roman,size:11
+ font.text.comment=font:Verdana,size:9
+ font.embedded.base=font:Verdana,size:9
+ font.embedded.comment=font:Comic Sans MS,size:8
+ font.monospace=font:Consolas,size:8.9
+ font.vbs=font:Lucida Sans Unicode,size:10
+if PLAT_GTK
+ font.base=font:Bitstream Vera Sans,size:9
+ font.small=font:Bitstream Vera Sans,size:8
+ font.comment=font:Bitstream Vera Serif,size:9
+ font.code.comment.box=$(font.comment)
+ font.code.comment.line=$(font.comment)
+ font.code.comment.doc=$(font.comment)
+ font.code.comment.nested=$(font.comment)
+ font.text=font:Bitstream Charter,size:10
+ font.text.comment=font:Serif,size:9
+ font.embedded.base=font:Serif,size:9
+ font.embedded.comment=font:Serif,size:9
+ font.monospace=font:Bitstream Vera Sans Mono,size:9
+ font.vbs=font:Bitstream Vera Sans Mono,size:9
+if PLAT_MAC
+ font.base=font:Verdana,size:12
+ font.small=font:Verdana,size:10
+ font.comment=font:Georgia,size:13
+ font.code.comment.box=$(font.comment)
+ font.code.comment.line=$(font.comment)
+ font.code.comment.doc=$(font.comment)
+ font.code.comment.nested=$(font.comment)
+ font.text=font:Times New Roman,size:13
+ font.text.comment=font:Verdana,size:11
+ font.embedded.base=font:Verdana,size:11
+ font.embedded.comment=font:Comic Sans MS,size:10
+ font.monospace=font:Courier New,size:12
+ font.vbs=font:Lucida Sans Unicode,size:12
+font.js=$(font.comment)
+
+# Give symbolic names to the set of colours used in the standard styles.
+colour.code.comment.box=fore:#00FF00
+colour.code.comment.line=fore:#00FF00
+colour.code.comment.doc=fore:#3F703F
+colour.code.comment.nested=fore:#A0C0A0
+colour.text.comment=fore:#0000FF,back:#FFFFFF
+colour.other.comment=fore:#00FF00
+colour.embedded.comment=back:#E0EEFF
+colour.embedded.js=back:#F0F0FF
+colour.notused=back:#FF0000
+#couleur des nombres
+colour.number=fore:#FF00FF
+#couleur des instructions du langage
+colour.keyword=fore:#FF0000
+#couleur chaînes entre guillemets
+colour.string=fore:#00FFFF
+colour.char=fore:#7F7F7F
+colour.operator=fore:#00FF00
+colour.preproc=fore:#FF7F00
+colour.error=fore:#FFFF00,back:#FF0000
+
+
+# Global default styles for all languages
+# Default
+style.*.32=back:#000000,fore:#FFFFFF,$(font.base)
+# Line number
+style.*.33=back:#404040,$(font.base)
+# Brace highlight
+style.*.34=fore:#0000FF,bold
+# Brace incomplete highlight
+style.*.35=fore:#FF0000,bold
+# Control characters
+style.*.36=
+# Indentation guides
+style.*.37=fore:#C0C0C0,back:#FFFFFF
+
+# Printing
+#print.colour.mode=1
+print.magnification=-1
+# Windows-only setup: left, right, top, bottom margins, in local units:
+# hundredths of millimeters or thousandths of inches
+print.margins=1500,1000,1000,1500
+# Header/footer:
+print.header.format=$(FileNameExt) -- Printed on $(CurrentDate), $(CurrentTime) -- Page $(CurrentPage)
+print.footer.format=$(FilePath) -- File date: $(FileDate) -- File time: $(FileTime)
+# Header/footer style
+print.header.style=font:Arial,size:12,bold
+print.footer.style=font:Arial Narrow,size:10,italics
+
+# Warnings - only works on Windows and needs to be pointed at files on machine
+#if PLAT_WIN
+# warning.findwrapped=100,E:\Windows\Media\SFX\Boing.wav
+# warning.notfound=0,Effect.wav
+# warning.wrongfile=0,Glass.wav
+# warning.executeok=0,Fanfare.wav
+# warning.executeko=100,GlassBreak.wav
+# warning.nootherbookmark=100,Boing2.wav
+
+# Define the Lexer menu,
+# Each item contains three parts: menu string | file extension | key
+# The only keys allowed currently are based on F-keys and alphabetic keys and look like
+# [Ctrl+][Shift+][Fn|a] such as F12 or Ctrl+Shift+D.
+# A '&' may be placed before a letter to be used as an accelerator. This does not work on GTK+.
+
+keyText=Shift+F11
+keyMake=Ctrl+Shift+F11
+keyHTML=F12
+keyXML=Shift+F12
+# On OS X, F11 is used by Expose, F12 by Dashbard
+if PLAT_MAC
+ os.x.home.end.keys=1
+ keyText=Shift+F13
+ keyMake=Ctrl+Shift+F13
+ keyHTML=Ctrl+Shift+F14
+ keyXML=Shift+F14
+
+default.languages=\
+#FreeBasic|bas||\
+Text|txt|$(keyText)|\
+#Ada|ads||\
+#Apache Confi&g|conf||\
+Assembler|asm||\
+#ASN.1|mib||\
+#Avenue|ave||\
+#Baan|bc||\
+&Batch|bat||\
+#Bullant|ant||\
+&C / C++|c||\
+#CMake|cmake||\
+C&#|cs||\
+#COBOL|cob||\
+#Csound|orc||\
+CSS|css||\
+D|d||\
+&Difference|diff||\
+#&Eiffel|e||\
+#Erlang|erl||\
+&Errorlist|err||\
+#FlagShip|prg||\
+Forth|forth||\
+#&Fortran|f90||\
+#Gap|g||\
+#Haskell|hs||\
+H&ypertext|html|$(keyHTML)|\
+#&InnoSetup|iss||\
+&Java|java||\
+Java&Script|js||\
+#&Kix|kix||\
+Lisp|lisp||\
+#Lot|lot||\
+#Lout|lt||\
+Lu&a|lua||\
+Matlab|m.matlab||\
+&Makefile|mak|$(keyMake)|\
+#MetaPost|mp||\
+#MMIXAL|mms||\
+#Modula-3|m3||\
+#&nnCron crontab|tab||\
+#NSIS|nsis||\
+#Objective Caml|ml||\
+#Octave|m.octave||\
+#Opal|impl||\
+Pascal|pas||\
+Pe&rl|pl||\
+P&HP|php||\
+#P&LSQL|spec||\
+#P&ostScript|ps||\
+#P&OV-Ray SDL|pov||\
+#PowerShell|ps1||\
+#PowerPro|powerpro||\
+&Properties|properties||\
+Pytho&n|py||\
+#R|R||\
+#Reso&urce|rc||\
+Ruby|rb||\
+#Rust|rs||\
+Shell|sh||\
+S&QL|sql||\
+#Specman|e||\
+&TCL|tcl||\
+TeX|tex||\
+#&txt2tags|t2t||\
+&VB|vb||\
+VBScr&ipt|vbs||\
+#Verilog|v||\
+#VHDL|vhd||\
+#&XML|xml|$(keyXML)|\
+YAML|yaml||
+
+menu.language=$(default.languages)
+
+# User defined key commands
+user.shortcuts=\
+Ctrl+Shift+V|IDM_PASTEANDDOWN|\
+Ctrl+PageUp|IDM_PREVFILE|\
+Ctrl+PageDown|IDM_NEXTFILE|
+
+#KeypadPlus|IDM_EXPAND|\
+#KeypadMinus|IDM_BLOCK_COMMENT|
+
+#user.context.menu=\
+#||\
+#Next File|IDM_NEXTFILE|\
+#Prev File|IDM_PREVFILE|
+
+# To keep menus short, these .properties files are not loaded by default.
+imports.exclude=abaqus ada asl asm asn1 au3 avenue avs baan blitzbasic bullant \
+C C# cobol cmake csound css d ecl escript flagship fortran freebasic Hypertext gap haskell inno \
+kix latex lot lout metapost mmixal modula3 nimrod nncrontab nsis \
+opal oscript powerpro powershell purebasic r rebol rust \
+scriptol smalltalk sorcins spice specman \
+tacl tal txt2tags verilog vhdl XML
+# Newly removed: ave baan escript lot metapost mmixal
+# The set of imports allowed can be set with
+#imports.include=ave
+
+# Import all the language specific properties files in this directory
+
+
--- /dev/null
+Copyright (c) 2000-2008 Andre Burgaud (http://www.burgaud.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
--- /dev/null
+========================================================================
+Context Menu Extension for SciTE (Win32)
+Version: 1.4.0
+Date: 12/06/2008
+File Name: wscitecm.dll
+$Id: readme.txt 497 2008-12-07 03:17:37Z andre $
+========================================================================
+
+Overview
+--------
+wscitecm.dll is a companion for SciTE on Windows (32-bit and 64-bit). Installing wscitecm.dll creates a new command "Edit with SciTE" in the context menu of Windows Explorer. You can quickly open one or several selected files in Windows Explorer: right click on the selection and click on the command "Edit with SciTE". For a friendly installation, I recommend to use the SciTE setup provided by Bruce Dodson (http://gisdeveloper.tripod.com/scite.html) and to check the choice "Register shell extension" during the install process. The manual installation is described in the following sections.
+
+Uninstallation
+--------------
+To uninstall a version prior to 1.2:
+- Double click on the file wscitecm-remove.reg. This will clean-up the old registry keys. This script was provided by Bruce Dodson.
+
+To uninstall any version newer than 1.2:
+- In SciTE directory installation, type the command "regsvr32 /u wscitecm.dll".
+
+Installation
+------------
+1) Copy wscitecm.dll in SciTE directory. Refer to the paragraph unload the dll if you have the error: "Access is denied."
+2) In SciTE directory installation, type the command "regsvr32 wscitecm.dll". This will register the dll.
+
+If everything goes well, you should have "Edit with SciTE" when you right click on selected file(s) in Windows Explorer.
+
+Unload the dll
+--------------
+If you try to delete or override the dll file and you get the error "Access is denied.", the library is already loaded. There are several options to workaround this issue:
+
+Solution 1:
+- Close all the Windows Explorer instances open on your desktop and copy wsctecm.dll using the command line (Example: "C:/>cp wscitecm.dll <scite_directory>").
+
+Solution 2:
+- Reboot the computer and delete or override wscitecm.dll (with the command line) before starting Windows Explorer and using the context menu (right-click).
+
+Solution 3:
+- Open a command line window
+- Type CTRL+ALT+DEL to display the Windows Task Manager, display the Process tab and "kill" the explorer.exe process.
+- If Windows Exlorer does not restart automatically, start it manually from the command line window (c:/>explorer).
+- Delete or override wscitecm.dll before using the context menu (Example: "C:/>cp wscitecm.dll <scite_directory>").
+
+Build
+-----
+Until version 1.2.1, wscitecm was built with Visual C++ 6.0. Version 1.3.0 (32-bit and 64-bit) was built with Visual Studio 2005. A Makefile is provided with the sources: in the source directory, type "nmake". Ensure that all the environment variables and paths are set correctly. To do so, use the command file "VCVARS32.BAT" available in the bin directory of Visual C++ installation.
+
+History
+-------
+Version 1.4.0 (12/06/2008):
+- Fixed an issue with the manifest file introduced with VS 2005 compilation
+- Modified the GUID to avoid conflict with Notepad++ reusing wscitecm code with the same GUID
+
+Version 1.3.0 (05/26/2008):
+- Support for Vista 64-bit
+- Build with Visual Studio 2005
+- Fixed warnings related to string functions
+
+Version 1.2.1 (01/21/2003):
+- Released under MIT license and packaged with the source code
+
+Version 1.2:
+- Registration and unregistration of the Shell Extension included in the code
+- SciTE icon displayed in the context menu
+
+Version 1.x:
+- Initial version
+
+License
+-------
+MIT License
+Copyright 2002-2008 Andre Burgaud <andre@burgaud.com>
+See license.txt
\ No newline at end of file