Shop OBEX P1 Docs P2 Docs Learn Events
Tachyon V4 "DAWN" - exploring new worlds - Page 18 — Parallax Forums

Tachyon V4 "DAWN" - exploring new worlds

1151618202130

Comments

  • proplem wrote: »
    Your are also on an iot5500 with EASYFILE and EASYNET?
    The "weirdness" is the weird character in my output or what?

    Yes I'm working on an IOT but not using EASYNET just EASYFILE for now.

    Yes that weird character.

  • I've been busy but bear in mind that if the dictionary has been moved to EEPROM via COMPACT that some of these reporting function won't find the name through conventional means. I am trying to make where the dictionary is transparent so CFA>NFA should be able to return with the buffered EEPROM name field address so that routines like .TASK will print "TIMER.TASK" instead junk.

    I've just been trying to get a clone tool working on V4.4 and it is doing something weird on BOOT where boot calls the cloner from an list of init vectors. But thanks for the feedback, it's these little things that need to be fixed.
  • Peter - did you see my wizpins problem some posts above and could you reproduce it?
  • proplem wrote: »
    Peter - did you see my wizpins problem some posts above and could you reproduce it?

    Hmmm, yes, when I get to hook-up a unit I will test that sometime by tomorrow hopefully.

  • caskazcaskaz Posts: 957
    edited 2017-06-26 13:17
    Hi.

    I try to measure Joystic-position by using counter mode.
    RCdecay(ctra) work well.
    But RCdecay1(ctrb) don't work.
    What is wrong?

    Sorry, It's solved.
    I had misunderstanding.
    B 8 CTRMODE VRB BPIN -> B 8 CTRMODE VRB APIN
    {
    P4 -----------------------
            |    open        |
            |     |          |
             ---->VRA(10k) Capacitance(0.01uF)
                  |          |
                 GND        GND
                 
    P5 -----------------------
            |    open        |
            |     |          |
             ---->VRB(10k)  Capacitance(0.01uF)
                  |          |
                 GND        GND
    }
    #P4 == VRA
    VRA MASK == mVRA
    #P5 == VRB
    VRB  MASK == mVRB
    
    : RCdecay
    \ $2000_0000 VRA OR CTRA COG!
    A 8 CTRMODE VRA APIN
    1 FRQA COG!
    
    BEGIN
         ON VRA PIN!
         #10 us
         0 PHSA COG!
         mVRA INPUTS
         #10 ms
         PHSA COG@ . CR
         
         KEY
    UNTIL
    ;
    
    
    : RCdecay1
    \ $2000_0000 VRB OR CTRA COG!
    B 8 CTRMODE VRB BPIN
    1 FRQB COG!
    
    BEGIN
         ON VRB PIN!
         #10 us
         0 PHSB COG!
         mVRB INPUTS
         #10 ms
         PHSB COG@ . CR
         
         KEY
    UNTIL
    ;
    
  • What is "IY" to be used for? Is it to have a reverting counter in parallel to the incrementing "I" ? And is this the intended output?'
    ( 0001 $549C  ok )   4 5 1 DOFOR I . CR LOOP
    4
    5
    6
    7
    8
    ( 0002 $549C  ok )   4 5 1 DOFOR IY . CR LOOP
    5
    4
    3
    2
    1
    
    Thanks,
    proplem
  • JoyStick works finely.
    TACHYON V4
                  
    IFDEF JoyStick
    @rest	org
    FORGET JoyStick
    }
    
    pub JoyStick        ." Joystick 2017/06/29 22:35:43 " ;
    
    @org W@	== @rest	--- remember
    
    {
    2017/06/29 22:35:37
    
    
    P4 -----------------------
            |    open        |
            |     |          |
             ---->VRy(10k) Capacitance(0.01uF)
                  |          |
                 GND        GND
                 
    P5 -----------------------
            |    open        |
            |     |          |
             ---->VRx(10k)  Capacitance(0.01uF)
                  |          |
                 GND        GND
    }
    \ =========================================================================== 
    \ Constants 
    \ =========================================================================== 
    #P4 == VRX
    VRX MASK == mVRX
    #7015 == Xmax
    #30 == Xmin
    
    #P5 == VRY
    VRY  MASK == mVRY
    #7151 == Ymax
    #10 == Ymin
    
    \ =========================================================================== 
    \ Variables 
    \ =========================================================================== 
    long Xcenter
    long Ycenter
    word Xdiv
    word Ydiv
    
    \ =========================================================================== 
    \ Main 
    \ =========================================================================== 
    
    \ Count PHSA after charging capacitance
    \ ( -- )
    : Xcount
    ON VRX PIN!
    #10 us
    0 PHSA COG!
    mVRX INPUTS
    #1 ms
    ;
    
    \ Count PHSB after charging capacitance
    \ ( -- )
    : Ycount
    ON VRY PIN!
    #10 us
    0 PHSB COG!
    mVRY INPUTS
    #1 ms
    ;
    
    : demo
    \ Initialize XY
    A 8 CTRMODE VRX APIN
    1 FRQA COG!
    B 8 CTRMODE VRY APIN
    1 FRQB COG!
    \ Measure center value
    #100 ms
    Xcount 
    PHSA COG@ #216 - Xcenter ! 
    Xmax Xcenter @ - #100 / Xdiv !
    Ycount
    PHSB COG@ #216 - Ycenter !
    Ymax Ycenter @ - #100 / Ydiv !
    
    BEGIN
         Xcount
         PHSA COG@ #216 - 
         Xcenter @ - \ . TAB
                     Xdiv @ / . TAB
         Ycount
         PHSB COG@ #216 - 
         Ycenter @ - \ . CR
                      Ydiv @ / . CR
         #100 ms
         KEY
    UNTIL
    ;
         
    
    END
    
    \ ?BACKUP
    
  • @Peter - it is so silent. I hope you're fine.
    Yesterday my little son (he is 7 years old) told me about school that they are doing "Lichtsprache" (light language) -- Ahh I recognized morse code. That's interesting and so I hacked a few lines into tachyon
    FORGET t_dit
    long t_dit
    long t_dah
    : t_dit@ t_dit @ ;
    : t_dah@ t_dah @ ;
    
    100 t_dit !
    t_dit @ 3 * t_dah !
    : K " dit " PRINT$ #14 HIGH t_dit@ ms #14 LOW t_dit@ ms ;
    : L " dah " PRINT$ #14 HIGH t_dah@ ms #14 LOW t_dit@ ms ;
    
    : _A 	K L ;
    : _B 	L K K K ;
    : _C 	L K L K ;
    : _D 	L K K ;
    : _E 	K ;
    : _F 	K K L K ;
    : _G 	L L K ;
    : _H 	K K K K ;
    : _I 	K K ;
    : _J 	K L L L ;
    : _K 	L K L ;
    : _L 	K L K K ;
    : _M 	L L ;
    : _N 	L K ;
    : _O 	L L L ;
    : _P 	K L L K ;
    : _Q 	L L K L ;
    : _R 	K L K ;
    : _S 	K K K ;
    : _T 	L ;
    : _U 	K K L ;
    : _V 	K K K L ;
    : _W 	K L L ;
    : _X 	L K K L ;
    : _Y 	L K L L ;
    : _Z 	L L K K ;
    
    It was absolute fun then ..,

    Today I wanted to improve this and fell about some minor things:
    1. I find this is strange
    ( 0001 $3D38  ok )   " Hello"                                                   
    ( 0002 $3D38  ok )   PRINT$                                                     
    #                                                                               
    ( 0003 $3D38  ok )   " Hello" PRINT$              
    Hello                              
    

    2. I miss
    " .VER" EVAL$
    
    will EVAL$ return into Tachyon V4r4?

    Hope you're fine, best regards
    proplem
  • Hi Peter - there is a problem with EVAL
    ( 0001 $55AA  ok )   .VER
      Propeller .:.:--TACHYON--:.:. Forth V4.4 DAWN 440170621.0930
    ( 0002 $55AA  ok )   " .VER" 0 STRING mycmd$
    ( 0003 $55B2  ok )   mycmd$ EVAL
    .VER 
    .VER 
    .VER 
    .VER 
    .VER 
    .VER 
    .VER  ??? 
    .VER
    
    AFAICS the source seems ok.
    Best regards,
    proplem
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-07-01 10:17
    proplem - " Hello" is compiled and leaves the address of the string on the stack for sure, but that same code space has not been permanently allocated and so it is lost on the next line. But if you happen to pad that previous line like this:
    ( 0009 $4520  ok )   " dummy string"  " hello"
    ( 0010 $4520  ok )   print$
    hello
    
    then it works because print$ (+exit) is compiled over the top of " dummy string" thereby corrupting it but not so the " hello" string. Anyway, just remember that practically everything is compiled but interactive one liners do not allot permanent code space, the code pointer is reset. I will see if we can do an EVAL$, it should be straightforward, maybe MJB would like to give it a go.

    btw - I did look at "wizpins" so I see there is a problem but I will get back to you soon on that.

    edit - it sure is fun. Maybe you can look at a method for allowing character output to be diverted to Morse so that you can send:
    MORSE ." Forth is fun" CON
    

    hint - create a table for all characters with perhaps 16-bits for each character to hold up to ten dot dash symbols at 2-bits each. Then have your Morse emit routine lookup that table and read out the dot dashes (00 = extra space, 01 = dot, 10 = dash, 11 = end)

    I spent a couple of days over at North Stradbroke Island having a break and photographing the humpback whale migration with my wife and friends, +wine+food+sun+fun+kangaroos+dolphins+turtles+wine+fun+sun
  • Peter - nice to hear you're fine and had a good time! Very well! Pictures are looking great ...
    Of course I'm already after a table controlled solution. As I have to arrange with my "personal reduced instruction set"
    I wanted to waste a lot more bytes instead of bits to implement it. That's why I was looking for EVAL($).
    There has been an EVAL$ in v3 I remember - I will search for it later as I found it useful. First I'll try your bit version ...
  • MJBMJB Posts: 1,235
    proplem wrote: »
    Peter - nice to hear you're fine and had a good time! Very well! Pictures are looking great ...
    Of course I'm already after a table controlled solution. As I have to arrange with my "personal reduced instruction set"
    I wanted to waste a lot more bytes instead of bits to implement it. That's why I was looking for EVAL($).
    There has been an EVAL$ in v3 I remember - I will search for it later as I found it useful. First I'll try your bit version ...
    Hi Proplem,

    I don't understand what exactly you need EVAL$ for - but first guess is - it is overkill ...

    but anyhow here a version from EXTEND-20160823
    for a very simple EVAL$
    
    ( 0004 $43AA  ok )   WORD evp PRIVATE
    ( 0005 $43AA  ok )   LONG evio PRIVATE
    ( 0006 $43AA  ok )   pri (EVAL)                  evp W@ C@ evp W++ DUP 0= IF DROP evio @ uemit ! $0D THEN ;
    ( 0007 $43C8  ok )   pub EVAL$ ( str -- )                evp W! uemit @ evio ! ' (EVAL) ukey W! NULLOUT ;
    ( 0008 $43DC  ok )   " .VER" EVAL$
    
      Propeller .:.:--TACHYON--:.:. Forth V4.4 DAWN 440170604.1130
    ( 0010 $43DC  ok )   .VER
      Propeller .:.:--TACHYON--:.:. Forth V4.4 DAWN 440170604.1130
    ( 0011 $43DC  ok )
    
    


  • Cluso99Cluso99 Posts: 18,066
    Peter,
    Pleased you had a good time on Straddie. The whale population is booming now. So nice to see :)
  • Hi @MJB
    MJB wrote: »
    Hi Proplem,

    I don't understand what exactly you need EVAL$ for - but first guess is - it is overkill ...

    but anyhow here a version from EXTEND-20160823
    for a very simple EVAL$
    
    ( 0004 $43AA  ok )   WORD evp PRIVATE
    ( 0005 $43AA  ok )   LONG evio PRIVATE
    ( 0006 $43AA  ok )   pri (EVAL)                  evp W@ C@ evp W++ DUP 0= IF DROP evio @ uemit ! $0D THEN ;
    ( 0007 $43C8  ok )   pub EVAL$ ( str -- )                evp W! uemit @ evio ! ' (EVAL) ukey W! NULLOUT ;
    ( 0008 $43DC  ok )   " .VER" EVAL$
    
      Propeller .:.:--TACHYON--:.:. Forth V4.4 DAWN 440170604.1130
    ( 0010 $43DC  ok )   .VER
      Propeller .:.:--TACHYON--:.:. Forth V4.4 DAWN 440170604.1130
    ( 0011 $43DC  ok )
    
    

    yes you are right it is overkill for morsing, but I used it some times and I like it.
    Thanks a lot!
  • proplem - Just to kick it off one way I might go about coding a Morse keyer in Tachyon is shown here. The main part is that we read a 16-bit number corresponding to the character from the lookup table. We then scan that code 8 times reading out 2-bit each time and deciding whether to dot or dash or pause or do nothing. We then generate an 800Hz audio tone for the dots and dashes and all we have to do to send Morse is to specify the pin and the data like this:
    4 MORSE PRINT" HELLO WORLD"
    

    Here's the skeleton code that needs to be finished and tested:
    TACHYON V4
    
    pub MORSE.fth	PRINT" Morse code keyer 170701-0000 " ;
    pri ..		DEPTH IF 2 <<  1+ ELSE 1 THEN ;
    pri __		DEPTH IF 2 << 2+ ELSE 2 THEN ;
    
    cbyte dotms	50 dotms C!
    cword pitch	800 pitch W!
    
    ---  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
    TABLE _morsew
    ( SP )	$3FFF ||
    ( ! )	__ .. __ .. __ __ || 0 || 0 || .. .. ..  __ .. .. __ ||
    
    ( 0 )	__ __ __ __ __ || .. __ __ __ __ || .. .. __ __ __ || .. .. .. __ __ || .. .. .. .. __ ||
    ( 5 )	.. .. .. .. .. || __ .. .. .. .. || __ __ .. .. .. || __ __ __ .. .. || __ __ __ __ .. ||
    
    ( $3A-$3F )
    
    ( @ )	.. __ __ .. __ .. ||
    
    ( A )	.. __ || __ .. .. .. || __ .. __ .. || __ .. .. || .. ||
    ( F )	.. .. __ .. || __ __ .. || .. .. .. .. ||
    ( dummy filler )
    0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||
    
    
    pri .DOT		1
    pri SOUND		dotms C@ * pitch W@ HZ ms MUTE dotms C@ ms ;
    pri .DASH		3 SOUND ;
    
    pri TAP:
    	SWITCH
    	1 CASE .DOT BREAK
    	2 CASE .DASH BREAK
    	3 CASE dotms C@ ms BREAK
    	;
    
    pub TAP	( ch -- )
    	$1F > 0EXIT
    	$20 - 2* _morse + W@ 8 FOR DUP 14 >> 3 AND TAP: 2 << NEXT DROP
    	MUTE dotms C@ 3 * ms
    	;
    
    pub MORSE ( pin -- )	A APIN 	' TAP uemit W! ;
    
    ( Usage: 4 MORSE PRINT" HELLO WORLD" CON )
    
    END
    
    
  • Hi there - here is the current state of the tachyon forth code powered morse code :-)
    Attention: This code is not ready for use! It's just for feedback of the more experienced.
    There is a complete table with binary coded dit dah and pause.
    Although Peter gave some advice I was already on the way and didn't want to restart again - which I did already because of the missing EVAL$.
    I have to stretch myself very much to do this simple task - and sometimes I ask myself wether I will success in learning forth. It is definitely hard. Although I see the potential of forth the one liners need as much time as complete pages in other programming languages I already used :-)
    I hope I will get more productive ... which will be hard again because I decided to learn bit fiddling with masks and moving them over the 16 bit word to detect dit dah and pause.
    FORGET K
    #14 pLED
    #15 pSOUND
    
    long t_dit
    long t_dah
    
    200 t_dit !
    t_dit @ 3 * t_dah !
    
    pub pk t_dit @ ms ; --- pause short
    pub pl t_dah @ ms ; --- pause long
    pub K " dit " PRINT$ pLED HIGH pk pLED LOW pk ;
    pub L " dah " PRINT$ pLED HIGH pl pLED LOW pk ;
    pub P " ___ " PRINT$ pl ;
    pub _S K K K P ;
    pub _I K K P ;
    pub _M L L P ;
    pub _O L L L P ;
    pub _N L K P ;
    
    \ _S _I _M _O _N
    
    ( 00 = extra space, 01 = dot, 10 = dash, 11 = end )
    
    TABLE mctbl --- table morse code
    \ Ziffern Ziffer Code
    'A' | 0 | ( A )   %0000_0000_0001_1011 ||
    'B' | 0 | ( B )   %0000_0010_0101_0111 ||
    'C' | 0 | ( C )   %0000_0010_0110_0111 ||
    'D' | 0 | ( D )   %0000_0000_1001_0111 ||
    'E' | 0 | ( E )   %0000_0000_0000_0111 ||
    'F' | 0 | ( F )   %0000_0001_0110_0111 ||
    'G' | 0 | ( G )   %0000_0000_1010_0111 ||
    'H' | 0 | ( H )   %0000_0001_0101_0111 ||
    'I' | 0 | ( I )   %0000_0000_0001_0111 ||
    'J' | 0 | ( J )   %0000_0001_1010_1011 ||
    'K' | 0 | ( K )   %0000_0000_1001_1011 ||
    'L' | 0 | ( L )   %0000_0001_1001_0111 ||
    'M' | 0 | ( M )   %0000_0000_0010_1011 ||
    'N' | 0 | ( N )   %0000_0000_0010_0111 ||
    'O' | 0 | ( O )   %0000_0000_1010_1011 ||
    'P' | 0 | ( P )   %0000_0001_1010_0111 ||
    'Q' | 0 | ( Q )   %0000_0010_1001_1011 ||
    'R' | 0 | ( R )   %0000_0000_0110_0111 ||
    'S' | 0 | ( S )   %0000_0000_0101_0111 ||
    'T' | 0 | ( T )   %0000_0000_0000_1011 ||
    'U' | 0 | ( U )   %0000_0000_0101_1011 ||
    'V' | 0 | ( V )   %0000_0001_0101_1011 ||
    'W' | 0 | ( W )   %0000_0000_0110_1011 ||
    'X' | 0 | ( X )   %0000_0010_0101_1011 ||
    'Y' | 0 | ( Y )   %0000_0010_0110_1011 ||
    'Z' | 0 | ( Z )   %0000_0010_1001_0111 ||
    '1' | 0 | ( 1 )   %0000_0110_1010_1011 ||
    '2' | 0 | ( 2 )   %0000_0101_1010_1011 ||
    '3' | 0 | ( 3 )   %0000_0101_0110_1011 ||
    '4' | 0 | ( 4 )   %0000_0101_0101_1011 ||
    '5' | 0 | ( 5 )   %0000_0101_0101_0111 ||
    '6' | 0 | ( 6 )   %0000_1001_0101_0111 ||
    '7' | 0 | ( 7 )   %0000_1010_0101_0111 ||
    '8' | 0 | ( 8 )   %0000_1010_1001_0111 ||
    '9' | 0 | ( 9 )   %0000_1010_1010_0111 ||
    '0' | 0 | ( 0 )   %0000_1010_1010_1011 ||
    '.' | 0 | ( AAA ) %0001_1001_1001_1011 ||
    ',' | 0 | ( MIM ) %0010_1001_0110_1011 ||
    ':' | 0 | ( OS )  %0010_1010_0101_0111 ||
    ';' | 0 | ( NNN ) %0010_0110_0110_0111 ||
    '?' | 0 | ( IMI ) %0001_0110_1001_0111 ||
    '-' | 0 | ( BA )  %0010_0101_0101_1011 ||
    '_' | 0 | ( UK )  %0001_0110_1001_1011 ||
    '(' | 0 | ( KN )  %0000_1001_1010_0111 ||
    ')' | 0 | ( KK )  %0010_0110_1001_1011 ||
    ''' | 0 | ( JN )  %0001_1010_1010_0111 ||
    '=' | 0 | ( BT )  %0000_1001_0101_1011 ||
    '+' | 0 | ( AR )  %0000_0110_0110_0111 ||
    '/' | 0 | ( DN )  %0000_1001_0110_0111 ||
    '@' | 0 | ( AC )  %0001_1010_0110_0111 ||
    0   | 0 |         0                 ||
    
    byte mctblmax --- max index of morse code table has to be calculated once
    pub MCTBLLEN ( -- idx ) --- set last index of MA table to maxtblalpha
    	mctbl BEGIN DUP @ 0 > WHILE 4+ REPEAT mctbl - 2 >> mctblmax C! ;
    
    MCTBLLEN
    
    pub @MC ( idx -- ) --- return Morse code at idx
    	4 * mctbl + @ ;
    
    pub .MC ( idx -- ) --- print morse code table
    	0 mctblmax C@ 1 DOFOR I @MC >B EMIT CR LOOP ;
    
    pub MCGET ( ch -- ) --- get morse code element from table
    	0 mctblmax C@ 1 DOFOR DUP I @MC >B = IF I @MC LEAVE THEN LOOP OVER DROP ;
    
    pub MCEMIT
    	DUP (EMIT) --- stdout
    	MCGET
    	16 ROR >W
    	. CR
    	( code to morse ) ;
    
    	\ .VER --- problem report version info
    	\ " .VER" 0 STRING mycmd$
    	\ mycmd$ EVAL    --- executings this hangs tachyon
    
    END
    
    Best regards,
    proplem
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-07-02 00:57
    Hi proplem - interesting you say that "one liners" are hard :) They are normally referred to as "quick and dirty" for a reason other than "hard" :)

    Good work so far but here are some hints with your code and to help you to "think Forth":

    * MCTBLLEN could be forgotten immediately after it is executed ( for that same reason it could be an immediate "one liner" rather than a definition

    * MCTBLLEN is also not really required if you test for zero as end of table and use BEGIN loops in MCGET instead

    * You could have two tables for scanning, one for valid 8-bit characters and one for 16-bit Morse - simplify building and using.
    If you use character table you can define it as a single string:
    pri mcchars " ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.,:;?-_()'=+/@" ;
    
    Then the index that matches the character is the index that you use to look up the 16-bit Morse code table.

    * @MC stack description has an error - effectively it is a fetch MC@ ( idx -- code )

    * It is not possible to use the simple EVAL$ method in redirected character output since it already uses that method itself.

    * If something seems too complicated then go away and have a wine. When you come you won't be able to do anything too complicated, so......
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-07-02 03:37
    I decided to finish that bit of Morse keyer demonstration code enough to do a video and actually demonstrate it. Here it is, in all its simplicity:


    TACHYON V4
    
    pub MORSE.fth	PRINT" Morse code keyer 170701-0000 " ;
    
    #P14	== *PIEZO
    #P15	== *EN
    
    pri ..		DEPTH IF 2 <<  1+ ELSE 1 THEN ;
    pri __		DEPTH IF 2 << 2+ ELSE 2 THEN ;
    
    cbyte dotms	50 dotms C!
    cword pitch	800 pitch W!
    
    !SP --- clear stack to use dot dash method of building table
    ---  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
    TABLE _morse
    ( SP )	$3FFF ||
    ( ! )	__ .. __ .. __ __ || 0 || 0 || .. .. ..  __ .. .. __ ||
    ( $25 )	 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||
    
    ( 0 )	__ __ __ __ __ || .. __ __ __ __ || .. .. __ __ __ || .. .. .. __ __ || .. .. .. .. __ ||
    ( 5 )	.. .. .. .. .. || __ .. .. .. .. || __ __ .. .. .. || __ __ __ .. .. || __ __ __ __ .. ||
    
    ( $3A-$3F )
    	 0 || 0 || 0 || 0 || 0 || 0 ||
    ( @ )	.. __ __ .. __ .. ||
    
    ( A )	.. __ || __ .. .. .. || __ .. __ .. || __ .. .. || .. ||
    ( F )	.. .. __ .. || __ __ .. || .. .. .. .. || .. .. || .. __ __ __ ||
    ( K )	__ .. __ || .. __ .. .. || __ __ || __ .. || __ __ __ ||
    ( P )	.. __ __ .. || __ __ .. __ || .. __ .. || .. .. .. || __ || .. .. __ ||
    ( V )	.. .. ..  __ || .. __ __ || __ .. .. __ || __ .. __ __ | __ __ .. .. ||
    
    
    pri .DOT		1
    pri SOUND		dotms C@ * pitch W@ HZ ms MUTE dotms C@ ms ;
    pri .DASH		3 SOUND ;
    
    pri TAP:
    	SWITCH
    	1 CASE .DOT BREAK
    	2 CASE .DASH BREAK
    	3 CASE dotms C@ ms BREAK
    	;
    
    pub TAP	( ch -- )
    	DUP $1F >
    	IF
    	$20 - 2* _morse + W@ 8 FOR DUP 14 >> 3 AND TAP: 2 << NEXT DROP
    	THEN
    	MUTE dotms C@ 3 * ms
    	;
    
    pub MORSE (  -- )	*EN HIGH *PIEZO A APIN 	' TAP uemit W! ;
    
    ( Usage: MORSE PRINT" HELLO WORLD" CON )
    
    END
    
    
  • MJBMJB Posts: 1,235
    ... ...
    ... 
    pri ..		DEPTH IF 2 <<  1+ ELSE 1 THEN ;
    pri __		DEPTH IF 2 << 2+ ELSE 2 THEN ;
    
    I hadn't seen the DEPTH operator befor and was guessing it gives the stack depth.
    Then I played a bit since I was expecting it could be even shortened more, since shifting a 0 did no harm, to
    pri ..		2 << 1+ ;
    pri __		2 << 2+  ;
    

    I discovered some interrestig behavior:

    DEPTH is 0 but TOS has a value ...
    ( 0030 $43AA  ok )   pri ..              2 << 1+ ;
    ( 0031 $43B2  ok )   ..
    ( 0032 $43B2  ok )   .S
     Data Stack (0)
    ( 0033 $43B2  ok )   .
    1
    ( 0034 $43B2  ok )   .. .. .. .S
     Data Stack (0)
    ( 0035 $43B2  ok )   .
    21
    ( 0036 $43B2  ok )   .. 1 .. 2 .. 3 .S
     Data Stack (3)
    $0000.0003 - 3
    $0000.0009 - 9
    $0000.0005 - 5
    ( 0037 $43B2  ok )   .
    3
    ( 0038 $43B2  ok )   .
    9
    ( 0039 $43B2  ok )   .
    5
    ( 0040 $43B2  ok )   .
    1
    ( 0041 $43B2  ok )   .
    0
    ( 0042 $43B2  ok )
    
    1+, 2+, << do not care if the stack is empty, they do as expected.
    also here - nothing is lost
    
    ( 0048 $43B2  ok )   .S
     Data Stack (0)
    ( 0049 $43B2  ok )   2+
    ( 0050 $43B2  ok )   .S
     Data Stack (0)
    ( 0051 $43B2  ok )   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
    ( 0052 $43B2  ok )   .S
     Data Stack (16)
    $0000.0010 - 16
    $0000.000F - 15
    $0000.000E - 14
    $0000.000D - 13
    $0000.000C - 12
    $0000.000B - 11
    $0000.000A - 10
    $0000.0009 - 9
    $0000.0008 - 8
    $0000.0007 - 7
    $0000.0006 - 6
    $0000.0005 - 5
    $0000.0004 - 4
    $0000.0003 - 3
    $0000.0002 - 2
    $0000.0001 - 1
    ( 0053 $43B2  ok )   . . . . . . . . . . . . . . . . . .  . .
    161514131211109876543212000
    ( 0054 $43B2  ok )
    
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-07-02 13:27
    @MJB - that was my Q&D version and I wanted to see if I could create the code table more visually. In the second version I just use binary with 01 for a dot and 11 for a dash while separating them with an underscore. So dot dot dash is written %01_01_11

    I also modified the way that we can use code variables such as cbyte, cword, and clong which are compiled in code space and backed up along with the code. It made sense to include a value that they are initialized to when creating the variable so now there is no need to go and write to it "manually".
    800 cword _pitch
    Creates a word variable in code space that is initialized to 800 and this value is locked into EEPROM. Only another BACKUP or write to EEPROM will permanently change it.

    In the process I also expanded string creation so that we can include a delimiter in the string. A delimiter is only valid if it is immediately followed by a space, tab, or CR.

    EDIT: latest version
    TACHYON V4
    
    pub MORSE.fth	PRINT" Morse code keyer 170702-0000 " ;
    { NOTES:
    Current version uses presettable cbyte/cword code variables - use EXTEND 170702-1440 or greater
    }
    
    --- my tone output - general version can specify pin when calling MORSE
    #P14	== *PIEZO
    #P15	== *EN
    
    --- setup preinitialized code space variables (170702)
    50 cbyte dotms
    800 cword _pitch
    
    
    TABLE _morse
    ( A )	%01_11			|| %11_01_01_01		|| %11_01_11_01		|| %11_01_01		||
    ( E )	%01			|| %01_01_11_01		|| %11_11_01		|| %01_01_01_01		||
    ( I )	%01_01			|| %01_11_11_11		|| %11_01_11		|| %01_11_01_01		||
    ( M )	%11_11			|| %11_01		|| %11_11_11		|| %01_11_11_01		||
    ( Q )	%11_11_01_11		|| %01_11_01		|| %01_01_01		|| %11			||
    ( U )	%01_01_11		|| %01_01_01_11		|| %01_11_11		|| %11_01_01_11		||
    ( Y )	%11_01_11_11		|| %11_11_01_01	||
    
    ( 1 )	%0111111111		|| %0101111111		|| %0101011111		|| %0101010111		||
    ( 5 )	%0101010101		|| %1101010101		|| %1111010101		|| %1111110101		||
    ( 9 )	%1111111101		|| %1111111111		||
    
    ( . )	%01_11_01_11_01_11	|| %11_11_01_01_11_11	|| %01_01_11_11_01_01	|| %01_11_11_11_11_01	||
    ( ! )	%11_01_11_01_11_11	|| %11_01_01_11_01	|| %11_01_11_11_01	|| %11_01_11_11_01_11	||
    ( & )	%01_11_01_01_01		|| %11_11_11_01_01_01	|| %11_01_11_01_11_01	|| %11_01_01_01_11	||
    ( + )	%01_11_01_11_01		|| %11_01_01_01_01_11	|| %01_01_11_11_01_11	|| %01_11_01_01_11_01	||
    ( $ )	%01_01_01_11_01_01_11	|| %01_11_11_01_11_01	||
    
    
    pri MC@ ( ch -- code )
    	" ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.,?'!/()&:;=+-_"$@" DUP ROT  ( str str ch )
    	OVER DUP LEN$ 1 DOFOR I C@ OVER = IF NIP I SWAP LEAVE THEN LOOP DROP
    	SWAP - 2* _morse + W@
    	;
    
    pri GAP			MUTE dotms C@ * ms ;
    pri TAP:		?DUP IF dotms C@ * _pitch W@ HZ ms 1 GAP THEN ;
    
    pub TAP	( ch -- )
    	DUP $20 >
    	IF
    	  --- convert lower case to upper case
    	  $7F AND DUP $5F > IF $20 - THEN
    	  --- index morse table and convert 2-bit codes to Morse taps
    	  MC@ 8 FOR DUP 14 >> 3 AND TAP: 2 << NEXT DROP 3
    	ELSE DROP 7
    	THEN
    	GAP
    	;
    
    ---			enable counter as tone - redirect output
    pub MORSE ( -- )	*EN HIGH *PIEZO A APIN 	' TAP uemit W! ;
    
    --- use this version for general use anbd specify pin
    \ pub MORSE ( pin -- )	A APIN 	' TAP uemit W! ;
    
    ( Usage: MORSE PRINT" HELLO WORLD" CON )
    
    
    --- The character speed is related to dot length in seconds by the following formula:
    --- Speed (WPM) = 2.4 * (Dots per second)
    pub WPM ( wpm -- )	1200 SWAP / dotms C! ;
    pub PITCH ( hz -- )	600 MAX 1000 MIN _pitch W! ;
    
    
    END
    
    [s][/s]
    
  • caskaz - sorry to get back to you so late, I think you were asking about IY, it is simply the loop counter which for DOFOR ( index cnt step -- ) always counts down to zero by ones. The loop count might be useful sometimes. Now that you have your joysticks working it would be nice to see them in action controlling something :)
  • DO LOOP rethink - again

    In V4r4 I introduced DOFOR to replace DO, ADO, and +LOOP but I am still not convinced and I feel that there is a better way still. What I want to do is to have the simplicity of the FOR NEXT loop but make it work the same as a DOFOR LOOP. This means that since FOR requires a count that we then need to specify both the start index and the step. By default these could be set to 0 and 1 respectively so that any 0 <cnt> 1 DOFOR LOOP could be replaced simply with <cnt> FOR NEXT. Internally the FOR NEXT would work just like DOFOR LOOP except it only ever expects a count parameter.

    So instead of coding:
    0 100 1 DOFOR CR I . SPACE I I * . LOOP
    
    We could instead code like this:
    100 FOR CR I . SPACE I I * . NEXT
    
    Where the index defaults to zero and the step defaults to 1. Now to step in twos:
    2 STEP 100 FOR CR I . SPACE I I * . NEXT
    
    Or to use a start index other than zero
    200 INDEX 100 FOR CR I . SPACE I I * . NEXT
    
    Or combine all:
    200 INDEX 2 STEP 100 FOR CR I . SPACE I I * . NEXT
    

    To display all printable ASCII characters:
    $20 INDEX 96 FOR I EMIT NEXT
    
    vs the V4r4 method:
    $20 96 1 DOFOR I EMIT LOOP
    

    If you have a simple FOR NEXT loop you can still access I as the current incrementing index.

    I don't want to throw another spanner in the works but I'd like your opinion as I think that most loops will become a lot simpler and more uniform.
  • MJBMJB Posts: 1,235
    DO LOOP rethink - again

    In V4r4 I introduced DOFOR to replace DO, ADO, and +LOOP but I am still not convinced and I feel that there is a better way still. What I want to do is to have the simplicity of the FOR NEXT loop but make it work the same as a DOFOR LOOP. This means that since FOR requires a count that we then need to specify both the start index and the step. By default these could be set to 0 and 1 respectively so that any 0 <cnt> 1 DOFOR LOOP could be replaced simply with <cnt> FOR NEXT. Internally the FOR NEXT would work just like DOFOR LOOP except it only ever expects a count parameter.

    So instead of coding:
    0 100 1 DOFOR CR I . SPACE I I * . LOOP
    
    We could instead code like this:
    100 FOR CR I . SPACE I I * . NEXT
    
    Where the index defaults to zero and the step defaults to 1. Now to step in twos:
    2 STEP 100 FOR CR I . SPACE I I * . NEXT
    
    Or to use a start index other than zero
    200 INDEX 100 FOR CR I . SPACE I I * . NEXT
    
    Or combine all:
    200 INDEX 2 STEP 100 FOR CR I . SPACE I I * . NEXT
    

    To display all printable ASCII characters:
    $20 INDEX 96 FOR I EMIT NEXT
    
    vs the V4r4 method:
    $20 96 1 DOFOR I EMIT LOOP
    

    If you have a simple FOR NEXT loop you can still access I as the current incrementing index.

    I don't want to throw another spanner in the works but I'd like your opinion as I think that most loops will become a lot simpler and more uniform.

    maybe you could use FROM intead of INDEX ??
    and DOFOR would still be there and a bit faster ?? than the verbose variant.
  • Peter - it was me who asked for IY - I still don't understand it see old post
    caskaz - sorry to get back to you so late, I think you were asking about IY, it is simply the loop counter which for DOFOR ( index cnt step -- ) always counts down to zero by ones. The loop count might be useful sometimes. Now that you have your joysticks working it would be nice to see them in action controlling something :)

    I would find it useful if "IY" always would be the opposite counting of "I" - the counting in the post above for me isn't intuitive.

    this is the current implementation:
    ( 0004 $5562  ok )   4 5 1 DOFOR I . SPACE IY . CR LOOP
    4 5
    5 4
    6 3
    7 2
    8 1
    
    Wouldn't that be more intuitive/useful ?
    ( 0004 $5562  ok )   4 5 1 DOFOR I . SPACE IY . CR LOOP
    4 4
    5 3
    6 2
    7 1
    8 0
    

    Of course everything should reverse if the loop is counting down:
    ( 0004 $5562  ok )   4 5 -1 DOFOR I . SPACE IY . CR LOOP
    4 0
    3 1
    2 2
    1 3
    0 4
    

    Best regards,
    proplem
  • Hi Peter - yes, DOFOR hasn't reached perfection yet. But you're after it.
    DO LOOP rethink - again

    In V4r4 I introduced DOFOR to replace DO, ADO, and +LOOP but I am still not convinced and I feel that there is a better way still. What I want to do is to have the simplicity of the FOR NEXT loop but make it work the same as a DOFOR LOOP.
    ...
    MJB said
    and DOFOR would still be there and a bit faster ?? than the verbose variant.
    which inspired me to conclude most of the loop constructions should be implemented in one and only one way. There should be different words to configure the loop a la
    5 FROM 2 STEP 8 TIMES ( looping code ) NEXT
    
    synonym
    5 8 2 DOFOR ( looping code ) LOOP ( / better NEXT )
    
    Additionally there could be an automatic word IFROM to access the start value within a loop and also an ITO to get the destination value.

    Maybe the other loop constructs could also be transformed. It would be great if someone could put them together in the Tachyon+ V4 google doc with all words regarding the loop topic as LEAVE, BEGIN, UNTIL, WHILE there should also be a CONT(INUE)/SKIP

    Best regards,
    proplem
  • Cluso99Cluso99 Posts: 18,066
    DO LOOP rethink - again

    In V4r4 I introduced DOFOR to replace DO, ADO, and +LOOP but I am still not convinced and I feel that there is a better way still. What I want to do is to have the simplicity of the FOR NEXT loop but make it work the same as a DOFOR LOOP. This means that since FOR requires a count that we then need to specify both the start index and the step. By default these could be set to 0 and 1 respectively so that any 0 <cnt> 1 DOFOR LOOP could be replaced simply with <cnt> FOR NEXT. Internally the FOR NEXT would work just like DOFOR LOOP except it only ever expects a count parameter.

    So instead of coding:
    0 100 1 DOFOR CR I . SPACE I I * . LOOP
    
    We could instead code like this:
    100 FOR CR I . SPACE I I * . NEXT
    
    Where the index defaults to zero and the step defaults to 1. Now to step in twos:
    2 STEP 100 FOR CR I . SPACE I I * . NEXT
    
    Or to use a start index other than zero
    200 INDEX 100 FOR CR I . SPACE I I * . NEXT
    
    Or combine all:
    200 INDEX 2 STEP 100 FOR CR I . SPACE I I * . NEXT
    

    To display all printable ASCII characters:
    $20 INDEX 96 FOR I EMIT NEXT
    
    vs the V4r4 method:
    $20 96 1 DOFOR I EMIT LOOP
    

    If you have a simple FOR NEXT loop you can still access I as the current incrementing index.

    I don't want to throw another spanner in the works but I'd like your opinion as I think that most loops will become a lot simpler and more uniform.
    Wow!
    That's nice and simple. Even I can understand this.

    Perhaps to offer an alternative syntax/words along the lines of proplems suggestion
    5 FROM 2 STEP 100 LOOPS .... NEXT
    
  • Cluso99Cluso99 Posts: 18,066
    Peter,
    Could you please update the first post with links to the docs and code please. Might be time to look at the docs again.
    No point in doing any P2 work since I cannot see the light at the end of the tunnel yet :(
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-07-04 04:20
    Let's see if I can respond to the correct person...
    @MJB - FROM was my first choice for index and it is still an option but in English at least it sounds strange to say "4 FROM" whereas "4 INDEX" is more neutral perhaps. But I know what you are saying.
    As for DOFOR I am still considering leaving it in there as long as I have spare cog memory but FOR will still stack 3 parameters just like DOFOR but the code is different.

    @Cluso99 - I must be doing something wrong if you can understand it :) Forth is supposed to be arcane and unreadable :)
    Try clicking the "Use the Forth" logo.

    @proplem - The DOFOR LOOP and FOR NEXT work much the same as a DJNZ instruction where you never get to see the count being zero in the loop unless you offset it. Is that what you are thinking? Normally the count isn't all the useful for loops, but the current index I is. I very rarely would use IY itself.

    The problem with an IFROM is that this value would have to be stacked and maintained in precious cog memory. The DOFOR uses 3 parameters already, to borrow my current terminology they are the INDEX, the STEP, and the FOR count. Since the INDEX parameter is incremented by STEP each loop the starting value would have to be maintained for an IFROM, the cost of which far outweighs any benefits gained.

    I have used TIMES as an alias for FOR at times simply for readability for people who are not familiar with Forth. We have several aliases in Tachyon such as THEN or ENDIF etc.
    Maybe the other loop constructs could also be transformed. It would be great if someone could put them together in the Tachyon+ V4 google doc with all words regarding the loop topic as LEAVE, BEGIN, UNTIL, WHILE there should also be a CONT(INUE)/SKIP
    Would you like to supply some samples of how code would use these constructs? There are times I use general BEGIN loops and other times counted DO/FOR loops, each with their own advantages although in Tachyon the counted loops are faster since they don't need the slower data stack to test for exit plus they have their own branch stack for instant branching.


    Further thoughts
    Although there are some instance where the full loop parameter specification is both slower and requires more bytes, overall the savings in many other areas makes up for it too. Anyway, the loop setup is only done once and what is important is that the looping itself is as fast as it can be. Tachyon already compiles FOR NEXT etc directly without going through the traditional (FOR) and (NEXT)+branch compilation steps that are otherwise necessary. In fact there are no markers at compile time to throw an error if structures are mismatched. There is a lot of flexibility there though.

    DONE (for now)
  • Hi Peter.

    TachyonV4r5.spin cannot compile.
    Error occur line below;
    setkey  word  _1,!,DUP,I,_SHL1,w+@keyactions+s,PLUS,WSTORE,LOOP,@DROPEX+t
    
  • caskaz wrote: »
    Hi Peter.

    TachyonV4r5.spin cannot compile.
    Error occur line below;
    setkey  word  _1,!,DUP,I,_SHL1,w+@keyactions+s,PLUS,WSTORE,LOOP,@DROPEX+t
    

    I meant to mark that folder, it is only for testing but I got caught up with work and need to get back to it. It will be my new FOR NEXT method version.

Sign In or Register to comment.