This chapter presents the listing of the file fcc_c50.wft.
| 
   Last update:  | 
  
   7-February-1999  | 
 
| 
   State (estimation)  | 
  
   55%  | 
 
/* ===========================================================================
  fcc_c50.wft Oliver Singla
   Description: This file is the code for the forth cross-compiler                for the TI C50 DSP RMS320C50 evalation card).                The link between PC/DSK is a serial link                 (either COM1: or COM2:)            *************************            *** UNDER DEVELOPMENT ***            *************************   =========================================================================== */host
forget <fcc_c50>
: <fcc_c50> ;
/*
open_comm Initialize the serial port (speed, etc.) and save handle
close_comm Close serial port
reset_c50 Reset the C50 (if I understood weel, seems that DTR low means a C50 reset)
init_mon Sequence to perform after the reset of the C50 to initialize the monitor
read Read a byte from the serial line
write Write a byte to the serial line
send Send a byte to the monitor, then wait the echo from the monitor
sendw Send a 16-bits word to the monitor
receive Receive a byte from the monitor
receivew Receive a 16-bits word from the monitor
*/
$2BF0 const saved_acc
$2BF1 const saved_ar6
$2BF2 const saved_ar7
$2BB8 const userfunct_addr
int target_nameddef
int target_anodef
$0A00 const target_cp0
$1A00 const target_dp0
$2BD0 const target_s0   // Target stack baseint target_cp // Target current code pointer
int target_dp           // Target current data pointer// ********************************************
// *** COMMUNICATION WITH THE DSK MONITOR   ***// *** TROUGHT A RS-232 LINK                ***// ********************************************
\ Either COM1: or COM2: has been given before compiling this file
const SerialPort:
-1 iint serial
: handle
  serial @ ;: open_comm
  57600 NOPARITY 8 2 SerialPort: HFLOW SerialOpen serial ! ;: close_comm
  handle -1 <> IF handle SerialClose ENDIF   serial -1 ! ;: reset_c50
  0 handle SerialDtr 20 delay   1 handle SerialDtr 20 delay ;: read          ( --- b )  handle SerialIn ;: write         ( b --- )  handle SerialOut ;: send          ( b --- )  dup write read != " DSK no more ready!" ?"error ;: sendw         ( hilo --- )  split send send ;: receive       ( --- b )  0 write read ;: receivew      ( --- w )  receive receive swap join ;// Monitor operations
0 const DDM // Dump Data DSP -> PC
1 const DPM // Dump Program DSP -> PC
2 const DLD // Download Data PC -> DSP
3 const DLP     // Download Program PC -> DSP5 const EXE     // Execute: init_mon
  $80 write  read ESC != " DSK not ready!" ?"error ;: address>      ( w --- )  sendw ;: len>          ( w --- )  sendw ;: address+len>  ( w1 w2 --- )  swap address> len> ;// ********************************************
// *** COMMUNICATION WITH THE DSK MONITOR   ***// *** TROUGHT A RS-232 LINK ***
// ********************************************
: dm!           ( w a --- )DLD send 0 address+len>
  sendw ;: dm@           ( a --- w )DDM send 0 address+len>
  receivew ;: dm?           ( a --- )  dm@ h. ;: pm!           ( w a --- )DLP send 0 address+len>
  sendw ;: pm@           ( a --- w )DPM send 0 address+len>
  receivew ;: pm?           ( a --- )  pm@ h. ;: run           ( a --- )  userfunct_addr dm!  EXE send  $2BB0 sendw  $12 write read drop  reset_c50init_mon ;
// ********************************************
// *** FORTH CROSS-COMPILER                 ***// ********************************************
// Add a new word into the Program Memory target
: pm,                   ( w --- )  target_cp @ pm! target_cp incr ;: pm,,
  swap pm, pm, ;// ********************************************
// *** TMS320C50 CODE GENERATION            ***// ********************************************
: nop               $8B00 pm, ;: ret               $EF00 pm, ;: retd              $FF00 pm, ;: retd_neq          $FF08 pm, ;: reti              $BE38 pm, ;: idle              $BE22 pm, ;: sacl_*            $9080 pm, ;: sacl_*-           $9090 pm, ;: sacl_*+           $90A0 pm, ;: sacl_*,ar7 $908F pm, ;
: lacc_#i8          ( b --- )  $B9 join pm, ;: lacc_#i16         ( w --- )  $BF80 pm, pm, ;: subb              ( w --- )  $BF00 pm, pm, ;: lar_ar4,*         $0480 pm, ;: lar_ar5,*         $0580 pm, ;: lar_ar5,*-        $0590 pm, ;: lar_ar5,*+        $05A0 pm, ;: sar_ar4,*+        $84A0 pm, ;: sar_ar5,*+        $85A0 pm, ;: mar_*-            $8B90 pm, ;: mar_*+            $8BA0 pm, ;: mar_*,ar6         $8B8E pm, ;: mar_*,ar7         $8B8F pm, ;: mar_*-,ar6        $8B9E pm, ;: lacc_*            $1080 pm, ;: lacc_*+           $10A0 pm, ;: lacc_*+,ar7       $10AF pm, ;: lamm_ar4          $0814 pm, ;: lamm_ar5          $0815 pm, ;: lamm_ar6          $0816 pm, ;: lamm_ar7          $0817 pm, ;: neg               $BE02 pm, ;: add_*             $2080 pm, ;: add_#i8           ( b --- )  $B8 join pm, ;: add_#i16          ( w --- )  $BF90 pm, pm, ;: add_*,0,ar7       $208F pm, ;: sub_*             $3080 pm, ;: sub_#i8           ( b --- )  $BA join pm, ;: sub_#i16          ( w --- )  $BFA0 pm, pm, ;: sub_*,0,ar7       $308F pm, ;: subs_*            $6680 pm, ;: lt_*+             $73A0 pm, ;: mpy_*-            $5490 pm, ;: pac               $BE03 pm, ;: xc_2,gt           $F704 pm, ;: xc_2,neq          $F708 pm, ;: xc_2,lt           $F744 pm, ;: xc_2,eq           $F788 pm, ;: xc_2,geq          $F78C pm, ;: xc_2,leq          $F7CC pm, ;: setc_sxm          $BE47 pm, ;: bd ( w --- )
$7D80 pm, pm, ;
// ********************************************
// *** REMOVE PREVIOUS COMPILED LITERAL?    ***// *** Optimizer ***
// ********************************************
: ?short_lit        ( --- b f )  target_cp @ 2- dup dm@ $90A0 ==  swap 1+ dm@ split $B9 == rot AND ;: ?long_lit         ( --- f )  target_cp @ 3 - dup dm@ $90A0 ==  swap 1+ dm@ $BF80 == AND ;: ?lit              ( --- f )  target_nameddef @ NOT IF target_anodef ENDIF @  target_cp @ over - 2 >= IF ?short_lit under IF 1 ELSE 0 ENDIF ELSE false ENDIF  target_cp @ rot - 3 >= IF ?long_lit IF 2 ELSE 0 ENDIF ELSE false ENDIF  or ;: lit->             ( --- n )  ?short_lit not IF drop target_cp @ 1- dm@ 3 ELSE 2 ENDIF target_cp -! ;// ********************************************
// *** FORTH DEFINITIONS                    ***// *** Run-Time ***
// ********************************************
int ^2dup
: (2dup)
  sacl_*-  lar_ar5,*+  retd  mar_*+  sar_ar5,*+ ;int ^above
: (above)
  sacl_*-  mar_*-  lacc_*+  retd  mar_*+  mar_*+ ;int ^below
: (below)
  mar_*-  lar_ar5,*-  retd  sar_ar5,*+  sacl_* ;int ^rot
: (rot)
  mar_*-  lar_ar5,*-  lar_ar4,*  sar_ar5,*+  retd  sacl_*+  lamm_ar4 ;int ^-rot
: (-rot)
  mar_*-  lar_ar5,*-  lar_ar4,*  sacl_*+  retd  sar_ar4,*+  lamm_ar5 ;int ^tuck
: (tuck)
  mar_*-  lar_ar5,*  sacl_*+  retd  sar_ar5,*+  sacl_* ;;
int ^depth
: (depth)
  sacl_*+  lamm_ar7  retd  target_s0 1+ subb ;int ^swap
: (swap)
  mar_*-  lar_ar4,*  retd  sacl_*+  lamm_ar4 ;int ^lit==
: (lit==) // ( n1 n2 --- f ) x = n1-n2
  nopxc_2,neq // FALSE if (x >= 0) ie (n1-n2 >= 0) ie (n1 >= n2)
  0 lacc_#i8  ret  retd  $FFFF lacc_#i16 ;int ^==
: (==)              // ( n1 n2 --- f )  mar_*-sub_* // x=n2-n1
  nopxc_2,neq // FALSE if (x != 0) ie (n2-n1 != 0) ie (n1 != n2)
  0 lacc_#i8  ret  retd  $FFFF lacc_#i16 ;int ^lit!=
: (lit!=) // ( n1 n2 --- f ) x = n1-n2
  nopxc_2,eq // FALSE if (x >= 0) ie (n1-n2 >= 0) ie (n1 >= n2)
  0 lacc_#i8  ret  retd  $FFFF lacc_#i16 ;int ^!=
: (!=)              // ( n1 n2 --- f )  mar_*-sub_* // x=n2-n1
  nopxc_2,eq // FALSE if (x != 0) ie (n2-n1 != 0) ie (n1 != n2)
  0 lacc_#i8  ret  retd  $FFFF lacc_#i16 ;int ^lit<
: (lit<) // ( n1 n2 --- f ) x = n1-n2
  nopxc_2,geq // FALSE if (x >= 0) ie (n1-n2 >= 0) ie (n1 >= n2)
  0 lacc_#i8  ret  retd  $FFFF lacc_#i16 ;int ^<
: (<)               // ( n1 n2 --- f )  mar_*-sub_* // x=n2-n1
  nopxc_2,leq // FALSE if (x <= 0) ie (n2-n1 <= 0) ie (n1 >= n2)
  0 lacc_#i8  ret  retd  $FFFF lacc_#i16 ;int ^lit<=
: (lit<=) // ( n1 n2 --- f ) x = n1-n2
  nopxc_2,gt // FALSE if (x > 0) ie (n1-n2 > 0) ie (n1 > n2)
  0 lacc_#i8  ret  retd  $FFFF lacc_#i16 ;int ^<=
: (<=)              // ( n1 n2 --- f )  mar_*-sub_* // x=n2-n1
  nopxc_2,lt // FALSE if (x < 0) ie (n2-n1 < 0) ie (n1 > n2)
  0 lacc_#i8  ret  retd  $FFFF lacc_#i16 ;int ^lit>
: (lit>) // ( n1 n2 --- f ) x = n1-n2
  nopxc_2,leq // FALSE if (x <= 0) ie (n1-n2 <= 0) ie (n1 <= n2)
  0 lacc_#i8  ret  retd  $FFFF lacc_#i16 ;int ^>
: (>)               // ( n1 n2 --- f )  mar_*-sub_* // x=n2-n1
  nopxc_2,geq // FALSE if (x >= 0) ie (n2-n1 >= 0) ie (n1 <= n2)
  0 lacc_#i8  ret  retd  $FFFF lacc_#i16 ;int ^lit>=
: (lit>=) // ( n1 n2 --- f ) x = n1-n2
  nopxc_2,lt // FALSE if (x < 0) ie (n1-n2 < 0) ie (n1 < n2)
  0 lacc_#i8  ret  retd  $FFFF lacc_#i16 ;int ^>=
: (>=)              // ( n1 n2 --- f )  mar_*-sub_* // x=n2-n1
  nopxc_2,gt // FALSE if (x > 0) ie (n2-n1 > 0) ie (n1 < n2)
  0 lacc_#i8  ret  retd  $FFFF lacc_#i16 ;int ^+!
: (+!)          // ( n --- )  mar_*-,ar6  add_*  retd  sacl_*,ar7  lacc_* ;int ^-!
: (-!)          // ( n --- )  mar_*-,ar6  sub_*  retd  sacl_*,ar7  lacc_* ;int ^*
: (*)
  sacl_*-  lt_*+  retd  mpy_*-  pac ;: run_time
  target_cp @ ^2dup ! (2dup)   target_cp @ ^above ! (above)   target_cp @ ^below ! (below)  target_cp @ ^rot ! (rot)  target_cp @ ^-rot ! (-rot)  target_cp @ ^tuck ! (tuck)  target_cp @ ^depth ! (depth)  target_cp @ ^swap ! (swap)target_cp @ ^lit!= ! (lit!=) target_cp @ ^!= ! (!=)
target_cp @ ^lit== ! (lit==) target_cp @ ^== ! (==)
target_cp @ ^lit< ! (lit<) target_cp @ ^< ! (<)
target_cp @ ^lit<= ! (lit<=) target_cp @ ^<= ! (<=)
target_cp @ ^lit> ! (lit>) target_cp @ ^> ! (>)
target_cp @ ^lit>= ! (lit>=) target_cp @ ^>= ! (>=)
  target_cp @ ^+! ! (+!)  target_cp @ ^-! ! (-!)  target_cp @ ^* ! (*);
: (?runtime)        ( sz --- ) ( areg )  @ cr '$ emit h. 2 spaces type ;: ?runtime
  " 2DUP" ^2dup (?runtime)   " ABOVE" ^above (?runtime)   " BELOW" ^below (?runtime)  " ROT" ^rot (?runtime)  " -ROT" ^-rot (?runtime)  " TUCK" ^tuck (?runtime)  " DEPTH" ^depth (?runtime)  " SWAP" ^swap (?runtime)" lit!=" ^lit!= (?runtime) " !=" ^!= (?runtime)
" lit==" ^lit== (?runtime) " ==" ^== (?runtime)
" lit<" ^lit< (?runtime) " <" ^< (?runtime)
" lit<=" ^lit<= (?runtime) " <=" ^<= (?runtime)
" lit>" ^lit> (?runtime) " >" ^> (?runtime)
" lit>=" ^lit>= (?runtime) " >=" ^>= (?runtime)
  " +!" ^+! (?runtime)  " -!" ^-! (?runtime)  " *" ^* (?runtime);
: call:     ( areg )$7A80 @ pm,, ;
: calld:    ( areg )$7E80 @ pm,, ;
: (?call_runtime)
  over @ == IF      under true      R>   ENDIF drop ;: ?call_runtime     ( a --- z f )  ^2dup " 2DUP" (?call_runtime)  ^above " ABOVE" (?call_runtime)  ^below " BELOW" (?call_runtime)   ^rot " ROT" (?call_runtime)   ^-rot " -ROT" (?call_runtime)   ^tuck " TUCK" (?call_runtime)   ^depth " DEPTH" (?call_runtime)   ^swap " SWAP" (?call_runtime)^lit== " lit==" (?call_runtime) ^== " ==" (?call_runtime)
^lit!= " lit!=" (?call_runtime) ^!= " !=" (?call_runtime)
^lit< " lit<" (?call_runtime) ^< " <" (?call_runtime)
^lit<= " lit<=" (?call_runtime) ^<= " <=" (?call_runtime)
^lit> " lit>" (?call_runtime) ^> " >" (?call_runtime)
^lit>= " lit>=" (?call_runtime) ^>= " >=" (?call_runtime)
  ^+! " +!" (?call_runtime)   ^-! " -!" (?call_runtime)   ^* " *" (?call_runtime)   drop 0 false ;// ********************************************
// *** FORTH DEFINITIONS ***
// *** STACK OPERATIONS ***
// ********************************************
: `sp!
$BF0F target_s0 pm,, ; // lar ar7,#2BD0h
: sp! host? IF compile sp! ELSE `sp! ENDIF ; immediate
: depth host? IF compile depth ELSE ^depth call: ENDIF ; immediate
: `dup
  sacl_*+ ;: dup host? IF compile dup ELSE `dup ENDIF ; immediate
: 2dup host? IF compile 2dup ELSE ^2dup call: ENDIF ; immediate
: `over
  sacl_*-  lacc_*+  mar_*+ ;: over host? IF compile over ELSE `over ENDIF ; immediate
: above host? IF compile above ELSE ^above call: ENDIF ; immediate
' above alias pluck
: `drop
  mar_*-  lacc_* ;: drop host? IF compile drop ELSE `drop ENDIF ; immediate
: `under
  mar_*- ;: under host? IF compile under ELSE `under ENDIF ; immediate
' under alias nip
: below host? IF compile below ELSE ^below call: ENDIF ; immediate
: swap host? IF compile swap ELSE ^swap call: ENDIF ; immediate
: tuck host? IF compile tuck ELSE ^tuck call: ENDIF ; immediate
: rot host? IF compile rot ELSE ^rot call: ENDIF ; immediate
: -rot host? IF compile -rot ELSE ^-rot call: ENDIF ; immediate
// ********************************************
// *** FORTH DEFINITIONS                    ***// *** ARITHMETIC and LOGIC ***
// ********************************************
: `negate
  neg ;: negate host? IF compile negate ELSE `negate ENDIF ; immediate
: `+
  ?lit CASE1 OF // Optimization: short literal
lit-> add_#i8
        ENDOF2 OF // Optimization: long literal
            lit-> add_#i16        ENDOFmar_*- // No optimization
      add_*  ENDCASE drop ;: + host? IF compile + ELSE `+ ENDIF ; immediate
: `-
  mar_*-  sub_*  neg ;: - host? IF compile - ELSE `- ENDIF ; immediate
: * host? IF compile * ELSE ^* call: ENDIF ; immediate
: ==
  host? IF       compile ==  ELSE       ?lit CASE1 OF // Optimization: short literal
lit-> sub_#i8
^lit== call:
        ENDOF2 OF // Optimization: long literal
            lit-> ^lit== calld:
            sub_#i16        ENDOF^== call: // No optimization
      ENDCASE drop  ENDIF ; immediate' == alias =
: !=
  host? IF       compile !=  ELSE       ?lit CASE1 OF // Optimization: short literal
            lit-> sub_#i8^lit!= call:
        ENDOF2 OF // Optimization: long literal
            lit->^lit!= calld:
            sub_#i16        ENDOF^!= call: // No optimization
      ENDCASE drop  ENDIF ; immediate' != alias <>
: <    host? IF compile <
  ELSE       ?lit CASE1 OF // Optimization: short literal
            lit-> sub_#i8^lit< call:
        ENDOF2 OF // Optimization: long literal
            lit->            ^lit< calld:            sub_#i16        ENDOF^< call: // No optimization
      ENDCASE drop  ENDIF ; immediate: <=
  host? IF       compile <=  ELSE       ?lit CASE1 OF // Optimization: short literal
            lit-> sub_#i8^lit<= call:
        ENDOF2 OF // Optimization: long literal
            lit->            ^lit<= calld:            sub_#i16        ENDOF^<= call: // No optimization
      ENDCASE drop  ENDIF ; immediate: >
  host? IF       compile >  ELSE       ?lit CASE1 OF // Optimization: short literal
            lit-> sub_#i8            ^lit> call:        ENDOF2 OF // Optimization: long literal
            lit->            ^lit> calld:            sub_#i16        ENDOF^> call: // No optimization
      ENDCASE drop  ENDIF ; immediate: >=
  host? IF       compile >=  ELSE       ?lit CASE1 OF // Optimization: short literal
            lit-> sub_#i8            ^lit>= call:        ENDOF2 OF // Optimization: long literal
            lit->            ^lit>= calld:            sub_#i16        ENDOF^>= call: // No optimization
      ENDCASE drop  ENDIF ; immediate// ********************************************
// *** FORTH DEFINITIONS                    ***// *** MEMORY ***
// ********************************************
: `!
  mar_*-,ar6  sacl_*,ar7  lacc_* ;: ! host? IF compile ! ELSE `! ENDIF ; immediate
: `@
  sacl_*+  mar_*,ar6  lacc_*+,ar7 ;: @ host? IF compile @ ELSE `@ ENDIF ; immediate
: `A>
  sacl_*+  lamm_ar6 ;: A> host? IF compile A> ELSE `A> ENDIF ; immediate  : +! host? IF compile +! ELSE ^+! call: ENDIF ; immediate
: -! host? IF compile -! ELSE ^-! call: ENDIF ; immediate
// ********************************************
// *** CREATING WORDS                       ***// ********************************************
: !instr        ( a --- )  @ 0 DO      cellsize+ dup >A @ pm,  ENDDO drop ;\ ---------------------------------------------------------------------------
\ `int Compile-time: ( --- )
\ Run-time: ( --- ) AREG = addr
\ Usage: Creation of a variable into the target.
\  PFA of a Variable Definition:\ 0-3 type=5
\ 4-7 data address
\ 8-11 instruction compiled for the macro definition
\ ---------------------------------------------------------------------------
: `int
  build>0 , // Type
target_dp @ , // Data Address
                            // Instruction is: LAR AR6,#addr2 , // 2 words
      $BF0E ,      target_dp @ ,target_dp incr // 1 allot
      [compile] immediate  does>      target? IF2 cellsize * +A // skip Type, Link, Data Address
          A> !instr       ENDIF ;: int host? IF [compile] int ELSE [compile] `int ENDIF ; immediate
' int alias integer
' int alias variable
' int alias var
// List all defined variables (simple list)
: vlist
  cr -1 BEGIN      nextword      -rot over - 12 == IF          dup peek ' rt_does> == swap cellsize+ cellsize+ peek 'does> `int == && IF              swap type space          ELSE              under          ENDIF      ELSE          drop under      ENDIF      DUP -1 ==   UNTIL drop ; immediate0 iint last_colondef
: :
  host? IF      [compile] :  ELSE  build>1 , // Type
target_cp @ , // Code Address (start)
      dp @ last_colondef !0 , // Code address (end), will be resolved by ;
                            // Instruction is: CALL xx2 , // 2 words
$7A80 , // CALL
      target_cp @ dup ,      [compile] immediatetarget_nameddef ! // We create a named definition
  does>3 cellsize* +A // skip Type, Data Address
      A> !instr  ENDIF ; immediate: ;
  host? IF      [compile] ;  ELSEret // End the definition with a RET
      last_colondef @ IF          target_cp @ last_colondef @ >A !          last_colondef 0!      ENDIF  ENDIF ; immediate// ********************************************
// *** SOME TOOLS                           ***// ********************************************
1 const t_int
2 const t_:
: table
  build> does> ;table target_objects
'does> `int , t_int ,
'does> : , t_: ,
    0 , 0 ,: ?target_objects   ( n --- f )  target_objects BEGIN      @+ dup 0 == ?break      over over == ?break      @+ 2drop  AGAIN 2drop @ ;\ List all definitions created into the target
: `words
  cr -1 BEGIN      nextword      -rot over - 12 == IF          dup peek ' rt_does> == swap cellsize+ cellsize+ peek ?target_objects && IF              swap type space          ELSE              under          ENDIF      ELSE          drop underENDIF
      DUP -1 ==   UNTIL drop ;: words host? IF compile words ELSE `words ENDIF ; immediate
: which_def     ( a --- sz f )  -1 BEGIN      nextword      -rot over - 12 == IF          dup dup peek ' rt_does> == swap cellsize+ cellsize+ peek ?target_objects t_: == && IF              rot >R              cellsize+ peek cellsize+ peek above == R> swap IF                  under under true [compile] (;)              ELSE                  drop              ENDIF          ELSE              drop under          ENDIF      ELSE          drop under      ENDIF      DUP -1 ==   UNTIL drop false ;// **************************
// *** CONTROL STRUCTURES ***
// *** IF..[ELSE]..ENDIF  ***// **************************
: `exit
  ret ;: exit host? IF compile exit ELSE `exit ENDIF ; immediate
: `?exit
  $FF08 pm,  mar_*-  lacc_* ;: ?exit host? IF ELSE `?exit @ ENDIF ; immediate
: here host? IF compile here ELSE target_cp @ ENDIF ; immediate
: `(0branch)        ( a --- )  $F388 pm, pm,  mar_*-  lacc_* ;: `(1branch)        ( a --- )  $F308 pm, pm,  mar_*-  lacc_* ;: `(branch)         ( a --- )  $7980 pm, pm, ;: `!code            ( w a --- )  swap over + swap pm! ;: `create_control_stack
  build>       dup 2 * 2 + allot !+ 0 !  does> ;64 `create_control_stack `control_stack
: `dummy 1000 ;
: `>control     ( addr mark --- )  `control_stack @+ drop 1+! @+ 1- cellsize * 2 * A> + >A   swap !+ ! ;: `control>     ( --- addr mark )  `control_stack @+ drop 1-! @+ cellsize * 2 * A> + >A  @+ @ ;: `control      ( --- addr mark )  `control_stack @+ drop @+ 1- cellsize * 2 * A> + >A  @+ @ ;: `IF
  `dummy `(0branch)  target_cp @ 3 - 'IFFI `>control ; immediate: `if?              ( mark --- )  'IFFI == 0 == " IF not called before" ?"error ;: `ELSE
  `control> `if?  `dummy `(branch)  target_cp @ 1 - 'IFFI `>control  target_cp @ over - swap `!code ; immediate: `ENDIF
  `control> `if?   target_cp @ over - swap `!code ; immediate: IF host? IF [compile] IF ELSE [compile] `IF ENDIF ; immediate
: ELSE host? IF [compile] ELSE ELSE [compile] `ELSE ENDIF ; immediate
: ENDIF host? IF [compile] ENDIF ELSE [compile] `ENDIF ENDIF ; immediate
' ENDIF alias THEN
: `begin?           ( mark --- )  'BEGI != " BEGIN not called before" ?"error ;: `break?
  dup 'BREA == IF     drop target_cp @ swap pm!     `control>     myself  ENDIF ;: `begin_or_break?  ( addr mark --- )  under dup 'BEGI != swap dup 'BREA !=   swap 'WHIL != and and  " BREAK not allowed here" ?"error ;: `?break
  `control `begin_or_break?  target_cp @ 1+ 'BREA `>control  `dummy `(1branch) ; immediate: `?continue
  `control `begin_or_break?  `control drop `(1branch) ; immediate: `BEGIN
  target_cp @ 'BEGI `>control ; immediate: `AGAIN
  2 target_cp +!  `control>   `break? `begin?  2 target_cp -!  `(branch) ; immediate: `UNTIL
  4 target_cp +!  `control> `break? `begin?  4 target_cp -!  `(0branch) ; immediate: BEGIN host? IF [compile] BEGIN ELSE [compile] `BEGIN ENDIF ; immediate
: AGAIN host? IF [compile] AGAIN ELSE [compile] `AGAIN ENDIF ; immediate
: UNTIL host? IF [compile] UNTIL ELSE [compile] `UNTIL ENDIF ; immediate
: ?BREAK host? IF [compile] ?BREAK ELSE [compile] `?BREAK ENDIF ; immediate
: ?CONTINUE host? IF [compile] ?CONTINUE ELSE [compile] `?CONTINUE ENDIF ; immediate
/*
: ;
  target? IF      A> >R      `control_stack @+ drop @ 0 > " Control Structure not endded" ?"error      R> >A   ENDIF   [compile] ; ; immediate*/
// ********************************************
// *** PSEUDO-DECOMPILER                    ***// ********************************************
: (.)               ( n --- z )  A> >R base @ >R decimal <#S> R> base ! R> >A ;: (h.)              ( n --- z )  A> >R base @ >R hex <#S> R> base ! R> >A ;: (field1)          ( --- )  BEGIN space wherex 17 == UNTIL ;: (field2)          ( --- )  BEGIN space wherex 40 == UNTIL ;: (forth_decomp)    ( z --- )  (field2) type space ;: (call_decomp)     ( a --- )  (field2)   dup ?call_runtime IF       under type  ELSE      drop which_def IF type ELSE drop ENDIF  ENDIF ;: (instr)           ( z --- )  (field1) " : " type type ;: (instr+h2)        ( a z --- )  (field1) " : " type type h02. ;: (instr+h4)        ( a z --- )  (field1) " : " type type h04. ;int addr
: next              ( --- a )  addr @ 1+ target_cp @ U>= IF      -1  ELSE     addr @ 1+ pm@  ENDIF ;: next2             ( --- a )  addr @ 2 + target_cp @ U>= IF      -1  ELSE     addr @ 2 + pm@  ENDIF ;: next3             ( --- a )  addr @ 3 + target_cp @ U>= IF      -1  ELSE     addr @ 3 + pm@  ENDIF ;: handle_mar_*-
next $1080 == IF " DROP" (forth_decomp) exit ENDIF
next $10A0 == IF " UNDER" (forth_decomp) exit ENDIF
next $2080 == IF " +" (forth_decomp) exit ENDIF
  next $0590 == IF next2 $85A0 == IF next3 $9080 == IF " BELOW" (forth_decomp) exit ENDIF ENDIF ENDIF ;int [decomp]
: (decomp)          ( a --- )  1 [decomp] !  dup addr !  dup 1+ >R pm@ dup h04. space  CASE$0480 OF " LAR AR4,*-" (instr) ENDOF
$0580 OF " LAR AR5,*-" (instr) ENDOF
$0590 OF " LAR AR5,*-" (instr) ENDOF
$05A0 OF " LAR AR5,*+" (instr) ENDOF
$0814 OF " LAMM AR4" (instr) ENDOF
$0815 OF " LAMM AR5" (instr) ENDOF
$0816 OF " LAMM AR6" (instr) ENDOF
$0817 OF " LAMM AR7" (instr) ENDOF
$1080 OF " LACC *" (instr) ENDOF
$10A0 OF " LACC *+" (instr) ENDOF
$10AF OF " LACC *+,AR7" (instr) ENDOF
$2080 OF " ADD *" (instr) ENDOF
$208F OF " ADD *,0,AR7" (instr) ENDOF
$3080 OF " SUB *" (instr) ENDOF
$308F OF " SUB *,0,AR7" (instr) ENDOF
$5490 OF " MPY *-" (instr) ENDOF
$73A0 OF " LT *+" (instr) ENDOF
$7980 OF R pm@ dup h04. " B " (instr+h4) R pm@ (.) (forth_decomp) [decomp] incr ENDOF
$7A80 OF R pm@ dup h04. " CALL " (instr+h4) R pm@ (call_decomp) [decomp] incr ENDOF
      $7E80 OF R pm@ dup h04. " CALLD " (instr+h4) R pm@ (call_decomp) [decomp] incr ENDOF$84A0 OF " SAR AR4,*+" (instr) ENDOF
$85A0 OF " SAR AR5,*+" (instr) ENDOF
$8B8E OF " MAR *,AR6" (instr) ENDOF
$8B8F OF " MAR *,AR7" (instr) ENDOF
$8B90 OF " MAR *-" (instr) handle_mar_*- ENDOF
$8B9E OF " MAR *-,AR6" (instr) ENDOF
$8BA0 OF " MAR *+" (instr) ENDOF
$908F OF " SACL *,AR7" (instr) ENDOF
$9080 OF " SACL *" (instr) ENDOF
$9090 OF " SACL *-" (instr) ENDOF
$90A0 OF " SACL *+" (instr) " LIT" (forth_decomp) ENDOF
$BE02 OF " NEG" (instr) ENDOF
$BE03 OF " PAC" (instr) ENDOF
$BE22 OF " IDLE" (instr) ENDOF
$BE38 OF " RETI" (instr) ENDOF
$BE47 OF " SETC SXM" (instr) ENDOF
$BF80 OF R pm@ dup h04. " LACC #" (instr+h4) R pm@ (.) (forth_decomp) [decomp] incr ENDOF
$BF90 OF R pm@ dup h04. " ADD #" (instr+h4) R pm@ (.) (forth_decomp) " +" type [decomp] incr ENDOF
$BFA0 OF R pm@ dup h04. " SUB #" (instr+h4) R pm@ (.) (forth_decomp) " -" type [decomp] incr ENDOF
$BF0E OF R pm@ dup h04. " LAR AR6,#" (instr+h4) [decomp] incr ENDOF
$F704 OF " XC 2,GT" (instr) ENDOF
$F708 OF " XC 2,NEQ" (instr) ENDOF
$F744 OF " XC 2,LT" (instr) ENDOF
$F788 OF " XC 2,EQ" (instr) ENDOF
$F78C OF " XC 2,GEQ" (instr) ENDOF
$F7CC OF " XC 2,LEQ" (instr) ENDOF
$EF00 OF " RET" (instr) ENDOF
      $F308 OF R pm@ dup h04. " BCNDD " (instr+h4) R pm@ (.) (forth_decomp) [decomp] incr ENDOF      $F388 OF R pm@ dup h04. " BCNDD " (instr+h4) R pm@ (.) (forth_decomp) [decomp] incr ENDOF$FF00 OF " RETD" (instr) ENDOF
$FF08 OF " RETD NEQ" (instr) ENDOF
      dup split CASE$B8 OF over dup " ADD #" (instr+h2) dup (.) (forth_decomp) " +" type ENDOF
$B9 OF over dup " LACC #" (instr+h2) dup (.) (forth_decomp) ENDOF
$BA OF over dup " SUB #" (instr+h2) dup (.) (forth_decomp) " -" type ENDOF
      ENDCASE drop drop drop  ENDCASE drop R> drop ;: decomp
  target_cp @ target_anodef @ != IFtarget_cp @ target_anodef @ DO
          cr I h04. space " : " type          I (decomp)      [decomp] @ +ENDDO  ENDIF ;// ********************************************
// *** HOOK THE INTERPRET                   ***// ********************************************
: target_literal        ( n --- )  sacl_*+  dup 255 U<= IF lacc_#i8 ELSE lacc_#i16 ENDIF ;: .s
  host? IF      [compile] .s  ELSE      cr " Target Stack: " type      saved_ar7 dm@ target_s0 - dup 1 > IF          target_s0 + target_s0 1+ DO              I dm@               dup $8000 < IF . ELSE '- emit $10000 swap - . ENDIF              space          ENDDO          saved_acc dm@          dup $8000 < IF . ELSE '- emit $10000 swap - . ENDIF      ELSE0 > IF
              saved_acc dm@ .          ELSE             " empty" type          ENDIF      ENDIF  ENDIF ; immediate: target_infos
  cr " Code: $" type target_cp0 h04. " -$" type target_cp @ h04.  space " (used: " type target_cp @ target_cp0 - 5 .L  space " free: " type target_dp0 target_cp @ - 5 .L " )" type  cr " Data: $" type target_dp0 h04. " -$" type target_dp @ h04.  space " (used: " type target_dp @ target_dp0 - 5 .L  space " free: " type target_s0 target_dp @ - 5 .L " )" typecr " anodef: " type target_anodef @ h.
  target_nameddef @ IF      cr " nameddef: " type target_nameddef @ h.  ENDIF  [compile] .s  decomp ;: infos
  host? IF [compile] infos ELSE target_infos ENDIF ; immediate' infos alias ??
: target_ok
target_nameddef @ 0 == IF
      '{ emit      saved_ar7 dm@ target_s0 - <#S> type      " } " type  ENDIF ;: :
  [compile] :  target? IF      target_cp @ target_nameddef !   ENDIF ; immediate: `flush
  target? IF ret // Compile RET at the end of the code
      target_nameddef @ IF          target_cp @ target_anodef !          target_nameddef 0 !      ELSE          target_anodef @ run          target_anodef @ target_cp !      ENDIF  ENDIF ;: ;
  [compile] ;  target? IF `flush ENDIF ; immediate// ********************************************
// *** SOME MORE TOOLS                      ***// ********************************************
\ Show the type of the next target object
\ Example: integer xx what xx
: see
  [compile] 'nfa  dup not " Definition not found" ?"error   >R R >A @+ IF       cr " Is an alias of " type cellsize -A @+ 10 cellsize* + type  ENDIF   @+ IF      R> drop " 'C' definition" "error  ENDIF  cellsize +A @+ @+ over - 3 cellsize* != IF      R> drop " Not a target definition" "error  ENDIF  dup peek ' rt_does> != IF      R> drop " Not a target definition" "error  ENDIF  cr dup cellsize+ cellsize+ peek ?target_objects CASE      t_int OF" integer Addr=" type
          swap cellsize+ >A @ cellsize+ >A @ dup h04.(.) 2 spaces          dm@ " Value=" type h04.(.)      ENDOF      t_: OF" colon definition Start=$" type
          swap cellsize+ >A @ cellsize+ >A @+ @ over h. space          " End=$" type dup h. space           " len=" type dup above - .           swap DO               cr I h04. space " : " type              I (decomp)          [decomp] @ +ENDDO      ENDOF      " Not a target definition!" "error  ENDCASE drop  R> drop; immediate
: `.
  `flush  saved_ar7 dm@ target_s0 - 0 > IF      saved_acc dm@       dup $8000 < IF . ELSE '- emit $10000 swap - . ENDIF      `drop `flush  ELSE     " Stack empty!" type  ENDIF space ; immediate: . host? IF [compile] . ELSE [compile] `. ENDIF ; immediate
// ********************************************
// *** INITIALIZATION OF THE FORTH INTO THE ***
// *** C50 DSP (TARGET)                     ***// ********************************************
: do_call
  target_cp @target_cp $2BB0 ! // Target current code pointer
$BF0D saved_acc pm,, // lar ar5,#2BF0h
$8B8D pm, // mar *,ar5
$10A0 pm, // lacc *+
$06A0 pm, // lar ar6,*+
$07AF pm, // lar ar7,*+,ar7
  setc_sxm$7A80 $FFFF pm,, // call {routine}
$BF0D saved_acc pm,, // lar ar5,#2BF0h
$8B8D pm, // mar *,ar5
$90A0 pm, // sacl *+
$86A0 pm, // sar ar6,*+
$87A0 pm, // sar ar7,*+
idle // idle
  target_cp ! ;: initforth_c50
  [compile] target  target_cp @target_cp $2A00 ! // Target current code pointer
$BC00 pm, // ldp #0
  mar_*,ar7  setc_sxm$BF0F target_s0 pm,, // lar ar7,#2BD0h
$BF0E target_dp0 pm,, // lar ar6,#1A00h
ret // ret
  do_call  run_time  target_cp !  target_s0 saved_ar7 dm!   0 saved_ar6 dm!  $2A00 run  target_cp0 target_anodef !;
// Initialization of the forth cross-compiler
: init_fcc
  open_comm   reset_c50init_mon
target_cp0 target_cp ! // Target current code pointer
target_dp0 target_dp ! // Target current data pointer
  0 target_nameddef !initforth_c50 // Compile some code into the target (definitions not macros)
;
: target
  target  ' target_literal (literal) ! ' target_ok (ok) !
; immediate
' target alias tok
: host
  host  0 (literal) ! 0 (ok) !
; immediate
' host alias ok
: bye
  target? IF close_comm ENDIF  [compile] bye ; immediate// I'm too lazy to type that each time I compile this file...
init_fcc ;
target
// Include here your project
" /wfroth/ti_c50/test.c50" !curr_file
load