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 - 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
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 ...
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 )
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:
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
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......
...
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
@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
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.
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.
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
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
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
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
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
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.
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.
Comments
Yes I'm working on an IOT but not using EASYNET just EASYFILE for now.
Yes that weird character.
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.
Hmmm, yes, when I get to hook-up a unit I will test that sometime by tomorrow hopefully.
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
proplem
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 It was absolute fun then ..,
Today I wanted to improve this and fell about some minor things:
1. I find this is strange
2. I miss will EVAL$ return into Tachyon V4r4?
Hope you're fine, best regards
proplem
Best regards,
proplem
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:
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
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 ...
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$
Pleased you had a good time on Straddie. The whale population is booming now. So nice to see
Thanks a lot!
Here's the skeleton code that needs to be finished and tested:
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. Best regards,
proplem
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: 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......
Then I played a bit since I was expecting it could be even shortened more, since shifting a 0 did no harm, to
I discovered some interrestig behavior:
DEPTH is 0 but TOS has a value ... 1+, 2+, << do not care if the stack is empty, they do as expected.
also here - nothing is lost
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
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: We could instead code like this: Where the index defaults to zero and the step defaults to 1. Now to step in twos: Or to use a start index other than zero Or combine all:
To display all printable ASCII characters: vs the V4r4 method:
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.
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: Wouldn't that be more intuitive/useful ?
Of course everything should reverse if the loop is counting down:
Best regards,
proplem
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
That's nice and simple. Even I can understand this.
Perhaps to offer an alternative syntax/words along the lines of proplems suggestion
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
@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.
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)
TachyonV4r5.spin cannot compile.
Error occur line below;
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.