Well I guess I should rename */ to U*/ but do you need a signed */ or other operations? There are probably a few areas I need to check for correct naming and operation.
Re: Revising DO and +LOOP practice - replacing with DOFOR
Now that I've thrown DO and +LOOP into the trash even though they have never changed in all of Forth history, I find that I have a lot of code that has this practice of "end start" parameters locked into it. However I am testing this and even though it is "better" I still find that I'm getting my poor head around it. One of the main features of the new DOFOR LOOP method is that DOFOR takes a start parameter, a actual loop count, and a index increment that gets added to the start value each loop where normally this is simply the value of one.
DOFOR doesn't run any faster than the previous loops I had since I use a rather fast branch stack but you really notice the difference in speed when the old +LOOP method is used.
Here is the old method which times the loop for 1,000,000 (2000000/2) (80MHz)
( 0076 $4F0A ok ) 0 2000000 LAP ADO 2 +LOOP LAP .LAP
176000336 cycles at 80MHz = 2.200sec
So that is 2.2us/loop which is really slow.
The equivalent DOFOR code (at 96MHz)
( 1619 $42BA ok ) 0 1000000 2 LAP DOFOR LOOP LAP .LAP
48000432 cycles at 96MHz = 500.004ms
Now each loop executes at 500ns regardless of the loop increment and always executes times the loop count regardless of the increment value.
Since the loop count controls how times the DOFOR loop executes independently of the increment value it means we can do reverse loops which were very awkward with the conventional DO LOOP arrangement:
( 1641 $42BA ok ) $7F 96 -1 DOFOR I EMIT LOOP
~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$#"!
( 1642 $42BA ok )
This doesn't append very far with that EXIT as the first word?
.VER
Propeller .:.:--TACHYON--:.:. Forth V4.3 DAWN 430170514.0076
( 0019 $4198 ok ) .MODULES
MODULES LOADED:
3304: EASYFILE.fth SDHC card + FAT32 Virtual Memory Access File System Layer V1.2 170506-0000
1A40: EXTEND.fth Primary extensions to TACHYON+ kernel - 170427-2200
( 0020 $4198 ok )
pub APPEND ( eof -- fsptr )
EXIT
\ reimplement - DO NOT ASSUME eof = 0 as in LEN$
eof C!
FSECT@ DUP 0EXIT DROP --- exit with false if there is no file opened
APPEND.BLK ( -- relblk ) --- find the active block to use
8<< 2* sdbuf LEN$ BLKSIZ MIN + --- add in offset allowing for a full block as well
\ FILE@ FSIZE@ + OVER = IF DROP FALSE THEN
DUP fwrite !
;
V4.4 which introduced DOFOR in place of DO, ADO, and +LOOP seems to be working well. The only problem I've had so far is wrestling with some old code that complicated the stack to suit the old DO LOOP arrangement. After conversion it is not so complicated anymore. I wonder why Forth used this arrangement in the first place since I find that I almost invariably use the start index and count method but looping with +LOOP complicated this still.
Because the loop stack is a separate stack in COG memory it had been implemented as fixed position registers with brute force ripple moves for push and pop. However there is one extra element on the stack for each DOFOR now and the ripple move was becoming too unwieldy so I made it a hybrid stack with the top four elements as fixed registers much the same as the data stack is implemented. The top four elements are: index (I); count (IY); and increment with the next element being the previous index (J). A count of 0 for either FOR or DOFOR will terminate the loop after the first iteration rather than for over 4 billion times which I am pretty sure would not be the intention.
Also added is 16-bit literals since 15-bit were encoded as a single wordcode but anything was always encoded as three words (PUSH32,highword,lowword).
There are lots of little enhancements and I still have room left in the cog after all this to enhance it some more.
For fast I/O work there are the pin mask operators H L and F which will set pins High Low or Float (back to input) by reading a mask off the top of the stack without discarding. This is different from the P2 version that may have been used since the P2 version used PIN to set the mask internally whereas 4.4 just borrows the mask from the stack.
EASYFILE is also working well on 4.4 so I will fix the APPEND operation in this version first since I am testing it.
If you are still stuck with V3 just remember that even V4.0 is very old now and V4.4 is the goto version to use IMO. Wordcode being more compact and faster "overall" than bytecode, who woulda thunk it?
V4.4 which introduced DOFOR in place of DO, ADO, and +LOOP seems to be working well. ...
Hi Peter - congratulations ro the new minor version!
As I'm always curious to stay on the bleesing edge but I don't know if that is always welcome to you. You solved a few issues recently which took time on your side.
Additionaly it could be of advantage to branch v44 into a new folder.
Best regards,
Proplem
V4 is looking better every day but as an added measure I have introduced an auxiliary stack for those times when you need to push stuff out of the way. Traditionally the return stack was used but in my embedded 24/7 reliability view this should never ever be as this could lead to uncontrolled execution <crash!> if values other than return addresses are left there. So I have used the loop stack with >L and L> but this stack is limited in cog memory so hence the auxiliary stack using >A A> and A@ which should be used for shuffling and even temporary constants via A@.
The doNEXT address interpreter has been tweaked as well just to give some priority to calls to wordcode so they run a bit faster again. Just remember too that for fast I/O you can use H L and F to control outputs with sub-microsecond resolution, good enough even to bit-bash serial RGB LEDs or 1-wire etc.
A moment ago I was just fixing up some little bug I had introduced in the filesystem in creating files. Anyway I normally preallocate contiguous sectors when creating a file and so I specify the maximum file size with a number. Just to make it easier I created two small words KB and MB which are nothing more than a left shift operation but very useful. To create a 16MB file just:
16 MB mk NETLOG.TXT
or to ASCII wide dump the 1 KB of a file offset 1 MB from the start of the file:
1 MB 1 KB FS DUMPAW
( 0060 $4202 ok ) FOPEN WARPEACE.TXT
...opened at 0000.48C0 for 3226652
( 0061 $4202 ok ) 1 MB 1 KB FS DUMPAW
0010.0000: .down his back..."Why, this one seems..." he began, turning to the assistant..."And how we've been begging, your honor," said th
0010.0080: e old soldier, his jaw.quivering. "He's been dead since morning. After all we're men, not.dogs.".."I'll send someone at once. He
0010.0100: shall be taken away--taken away at once,".said the assistant hurriedly. "Let us go, your honor.".."Yes, yes, let us go," said R
0010.0180: ostov hastily, and lowering his eyes and.shrinking, he tried to pass unnoticed between the rows of reproachful.envious eyes that
0010.0200: were fixed upon him, and went out of the room......CHAPTER XVIII..Going along the corridor, the assistant led Rostov to the off
0010.0280: icers'.wards, consisting of three rooms, the doors of which stood open. There.were beds in these rooms and the sick and wounded
0010.0300: officers were lying or.sitting on them. Some were walking about the rooms in hospital dressing.gowns. The first person Rostov me
0010.0380: t in the officers' ward was a thin.little man with one arm, who was walking about the first room in a.nightcap and hospital dres
( 0062 $4202 ok ) 16 MB mk NETLOG.TXT
( 0063 $4202 ok ) ls-l
-rwxrwxrwx 1 502 500 65536 Aug 4 18:01 SCR.ROM
-rwxrwxrwx 1 502 500 1048576 Dec 2 15:56 SYSLOG.TXT
-rwxrwxrwx 1 502 500 3226652 Aug 30 07:27 WARPEACE.TXT
-rwxrwxrwx 1 502 500 1895 Apr 15 15:09 SEE-V4.FTH
-rwxrwxrwx 1 502 500 7229 Apr 26 23:24 LIFE.FTH
-rwxrwxrwx 1 502 500 18944 Mar 9 12:30 SPLAT-V4.FTH
-rwxrwxrwx 1 502 500 1048576 Jan 1 00:02 TEMP.TXT
-rwxrwxrwx 1 502 500 16777216 Jan 1 00:07 NETLOG.TXT
Hi @Peter - couldn't resist and tried v4r4
- DOFOR is looking good
- IoT5500 builds successful up to EASYFILE, EASYNET is not yet ready.
- separating the new version into a new folder is fine - thank you - maybe others with more Forth code will appreciate too
- EASYFILE: I tried to use a Transcend 16 GB micro SDHC without success. Should it work or is is there still a SANDISK dependency? It could be that mine is "mis-formatted" because of many trial end errors. I ask to be sure whether I should try to reformat it which can eat up spare tachyon time :-(
- COMPACT4r4.FTH should be renamed to COMPACT-v4r4.FTH :-)
Again thank you for sharing and holding up the Tachyon flag so high!
Hi @Peter - couldn't resist and tried v4r4
- DOFOR is looking good
- IoT5500 builds successful up to EASYFILE, EASYNET is not yet ready.
- separating the new version into a new folder is fine - thank you - maybe others with more Forth code will appreciate too
- EASYFILE: I tried to use a Transcend 16 GB micro SDHC without success. Should it work or is is there still a SANDISK dependency? It could be that mine is "mis-formatted" because of many trial end errors. I ask to be sure whether I should try to reformat it which can eat up spare tachyon time :-(
- COMPACT4r4.FTH should be renamed to COMPACT-v4r4.FTH :-)
Again thank you for sharing and holding up the Tachyon flag so high!
Best regards,
proplem
I'll get down to the bottom of why some cards don't work but it should be a very minor thing I'm sure, I have cards other than Sandisk that work. I'm doing quite a bit of work on EASYFILE in 4.4 at present,
I haven't quite gotten onto EASYNET yet but it should be straightforward enough.
Now that the files are in their own folders I can probably remove the version from the name and leave that information in the file itself.
V4.4 starts up in non-case sensitive mode although fast block mode load via TACHYON END is still always case sensitive. Use OFF ANYCASE to enforce case sensitivity.
I've been using 4.3 for my projects but with these improvements and stability testing I see I can easily start using 4.4. With an SD card in I can also fast load FL to a temporary or specified file which buffers everything into the file and then loads it automatically. If you want to update a text file on the card over the console you can SAVETEXT <myfile>, paste/send the text file as you would normally and use esc to finalize. This will also update the file size in the directory. Using FL or SAVETEXT without a filename will cause it to use TEMP.TXT.
Since the minimum cluster size is 32k bytes it doesn't matter if the file only had 4kB but the new text has 6kB etc. I like to preallocate at least 64kB though and there is no reason why you couldn't preallocate 1MB per file anyway, unless you have 8,000 of them. The cluster chain for a file is contiguous and the number of clusters allocated has to be scanned to determine the maximum but it is just as easy to preallocate anyway.
Here is a scan of clusters of sectors with sector address header where each * represents a cluster with data (non-zero) plus I've inserted labels for id.
Each line represents 4MB so it is interesting to see all that unused space after the MBR (really just partition info) and before the FAT tables, that's around 4MB you can hide files and config in.
PART
0000.0000 *...............................................................................................................................
BOOT FAT1
0000.2000 **..............................................................................................................................
FAT2
0000.4000 ............................................................................................................**..................
0000.6000 ................................................................................................................................
ROOT
0000.8000 .........................................................................................***************************************
0000.A000 ********************************************************************************************************************************
0000.C000 ********************************************************************************************************************************
0000.E000 ********************************************************************************************************************************
0001.0000 ****************************************************************************************************************************...*
0001.2000 ................................................................................................................................
0001.8000 .................................
( 0014 $441E ok ) @ROOT .LONG
0000.9646
( 0015 $441E ok ) @BOOT .LONG
0000.2000
( 0013 $441E ok ) DIR
SCR1.5
COMPACT .FTH .....a 0000.964E May 21 2017 15:23 3,156
LIFE .FTH .....a 0000.9656 May 22 2017 04:29 7,609
PTZ485 .FTH .....a 0000.9666 May 21 2017 01:00 875
SEE .FTH .....a 0000.966E May 19 2017 13:34 1,998
WARPEACE.TXT .....a 0000.9676 Aug 30 2015 07:27 3,226,652
SPLAT-V4.FTH .....a 0000.AF16 Mar 9 2017 12:30 18,944
LOVE .WAV .....a 0000.AF3E Feb 16 2015 08:06 14,630,692
POPCORN .WAV .....a 0001.1EDE Jun 17 2014 06:15 117,804
FRED .TXT .....a 0001.1FC6 Oct 13 2005 22:43 2,474
( 0014 $441E ok )
I did quite a lot of testing of various SD Cards. I found some quirks that were not completely explained from the flowchart of commands. With that code I didn't find any that I couldn't read/write to. Some of the cards I tried were cheapie eBay 8GB and 32GB cards.
I won't be back in Oz for 3 weeks. When I get back I will look up my notes as I don't think I have all the info on my laptop I have with me. IIRC I posted the info on a P2 thread, so I'll also look for that.
@D.P - Ahh, you saw that stub. Yes, I may get around to it tonight and put the scanning SDRD back in and all should be good again for 4.3.
Well if you are using 4.3 for production are you logging data? If so how since APPEND is still a stub.
I keep looking for the stub to be implemented.
[/quote]
I'm actually working on the 4.4 version, I started checking it the other day, so with all my file system work at present I will be able to sort it out. I didn't actually use APPEND for some of these files. It's easier sometimes to create a new file each time it starts up if the old file has already been used but I might make it a point right at the moment to get APPEND working ASAP as I had already started doing so in V4.3.
The last time I downloaded and built 4.4 (17 05 30) with easyfile and issued mount on a non sandisk card the system went into constant reboot mode. I then cycled power and the easyfile.fth module was gone. Hum, I will wait for another minor update and try again.
The last time I downloaded and built 4.4 (17 05 30) with easyfile and issued mount on a non sandisk card the system went into constant reboot mode. I then cycled power and the easyfile.fth module was gone. Hum, I will wait for another minor update and try again.
Wow! are you able to repeat that?
I am actively using V4.4 easyfile and some non Sandisk cards work but the worst that should happen is that they fail to mount, not wipe easyfile. There is no mechanism for that to happen so if it is repeatable then if you don't mind trying it out again and maybe copy your terminal screen from the initial compile to when it gets corrupted. I'd like to get to the bottom of this but is there any reason why you can't just the Ultras?
btw, that version number doesn't sound right, typo?
DAT { *** VERSION *** }
version long 440_170528
vertime word 1600
vername byte "4.4 DAWN" ' fixed 8 character version name
@D.P - The append operation has not been fully checked out, I know there is something more I need to look at. I'll see if I can fit half an hour in and fix it.
My old 4GB SD-HC is not properly handled (worked well with Tachyon before)
There is a known problem with "other" cards, SanDisk cards work well. Hoping for a update to EasyFile.fth that restores other cards to usable and also fixes APPEND. I'm still using V3 for "production".
I start to learn Tacyon.
I loaded TachyonV4.4.spin(Xtal:5MHz) to eeprom.
And loaded EXTEND-V4r4.fth.
I try to understand CHARLCD.fth because I don't know Tachyon manner at all.
I copy/paste it to TeraTerm.
But error occured.
Code-loading is wrong?
Propeller .:.:--TACHYON--:.:. Forth V4r4 DAWN 440170522.0000
MODULES LOADED:
1AC0: EXTEND.fth Primary extensions to TACHYON V4.4 kernel - 170521-0000
AUTORUN BOOT
FREQ = 80.0MHz
*** INITS ***
NO ROMS
*** I2C ***
A0 EEPROM
PPNET: &00.00.00.00 @2,000,000
CODE:$33B0 =12720 bytes NAME:$5B66 =6298 bytes DATA:$76E8 =216 bytes =10166 bytes free Data Stack (1)
$0000.76D8 - 30424
--------------------------------------------------------------------------------
( 0001 $33B0 ok ) TACHYON
Propeller .:.:--TACHYON--:.:. Forth V4r4 DAWN 440170522.0000
( 0131 $3474 ?? ) ??? in
?? at MASKS
( 0133 $3474 ?? ) ??? in
?? at 16>>
( 0176 $350E ?? ) ??? in 56789 at lcdlm
??? in 56789 at xpos
( 0178 $3512 ?? ) ??? in +,-./ at ypos
( 0179 $3512 ?? ) ??? in +,-./ at xpos
??? in 3528 ?? )
at ypos
( 0189 $3530 ?? ) ??? in
at xpos
( 0195 $353C ?? ) ??? in ・巐 﨟t ypos
( 0196 $353C ?? ) ??? in ・巐 﨟t ypos
??? in ・巐 﨟t ypos
( 0235 $358C ?? ) ??? in 烙痰邃繙 at ADO
( 0296 $3644 ?? ) ??? in 兎波品北 at bigptr
??? in 兎波品北 at bigptr
( 0301 $3652 ?? ) ??? in 杭纂従神 at BL
( 0306 $3660 ?? ) ??? in ⑭・渦 梶t bigptr
( 0307 $3660 ?? ) ??? in ⑭・渦 梶t ypos
( 0308 $3660 ?? ) ??? in ⑭・渦 梶t ypos
( 0309 $3660 ?? ) ??? in ⑭・渦 梶t xpos
( 0313 $367C ?? ) ??? in 、・ウ пt lch
( 0315 $367E ?? ) ??? in t lcdmode
( 0320 $367E ?? ) ??? in t xpos
( 0321 $367E ?? ) ??? in t xpos
( 0329 $36A4 ok ) ??? in
?? at BL
??? in
?? at xpos
( 0330 $36B2 ok ) ??? in at xpos
??? in at xpos
( 0334 $36CE ok ) ??? in QRSTU at dpy
( 0335 $36CE ?? ) ??? in GHIJK at dpy
( 0336 $36D6 ok ) ??? in =>?@AB at dpy
( 0337 $36DC ok ) ??? in 1234567 at dpy
( 0338 $36E2 ok ) ??? in '()*+ at dpy
??? in '()*+ at dpy
( 0339 $36EC ok ) ??? in t dpy
( 0344 $370C ok ) ??? in 邃繙艾 at lcdmode
( 0345 $3710 ok ) ??? in 忤掣桀毳 at lcdmode
( 0349 $372A ok ) ??? in ・⑭・ 堰t lcdlm
( 0358 $3738 ?? ) ??? in t dpy
( 0359 $3738 ?? ) ??? in t xpos
??? in t ypos
( 0360 $3738 ?? ) ??? in t lcdlm
??? in t lcdmode
( 0376 $3798 ?? ) ??? in }~ at lch
( 0378 $37BE ?? ) ??? in qrstuvwx at BL
??? in qrstuvwx at LOOKUP
( 0384 $37BE ?? ) ??? in qrstuvwx at LCDchar
??? in 12345678 at SP! ?
( 0528 $383E ok ) ???
End of source code, 0097 errors found Load time = 680578160 cycles at 80MHz = 8.507sec
Code bytes used = 1166
CODE:$383E =13886 bytes NAME:$5830 =7120 bytes DATA:$7714 =260 bytes =8178 bytes free Data Stack (0)
( 0529 $383E ok )
( 0530 $383E ok ) \
( 0531 $383E ok )
( 0532 $383E ok )
( 0001 $33B0 ok ) 1 0
( 0002 $33B0 ok ) .
0
( 0003 $33B0 ok ) .
1
( 0004 $33B0 ok ) .
30424
( 0005 $33B0 ok ) .
12844
( 0006 $33B0 ok ) .
0
( 0007 $33B0 ok ) .
0
Executed '.' under stack-empty, 30424 and 12844 ouput.
What is this [30424][12844]?
And more '.' , '0' output.
Why error ocurr?
( 0001 $33B0 ok ) LAP LAP LAP LAP LAP LAP LAP LAP LAP LAP LAP LAP LAP LAP .LAP
0 cycles at 80MHz = 0.000us
( 0001 $33B0 ok )
Why 0.000us?
This is abnormal?
@caskaz - good to see you are ok, we missed you from the forum for a while there.
I just made a copy of CHARLCD.FTH in the V4r4 folder and modified an ADO to the newer DOFOR format which simplifies the normal DO LOOP arrangement. Since it has a few tables in there it can sometimes require a bit more compile time so I slowed minicom down to 10ms line delay (no character delay) @921600 baud. TeraTerm works fine at this baud rate too.
( 1772 $3374 ok ) TACHYON V4
Propeller .:.:--TACHYON--:.:. Forth V4.4 DAWN 440170604.1130
( 0441 $37AE ok )
End of source code, 0000 errors found Load time = 546758448 cycles at 96MHz = 5.695sec
Code bytes used = 1082
CODE:$37AE =13742 bytes NAME:$580E =7154 bytes DATA:$76F4 =228 bytes =8288 bytes free Data Stack (0)
( 0442 $37AE ok )
( 0443 $37AE ok ) ?BACKUP
BACKUP /
( 0444 $37AE ok )
( 0445 $37AE ok ) ??
Propeller .:.:--TACHYON--:.:. Forth V4.4 DAWN 440170604.1130
MODULES LOADED:
3374: CHARLCD.fth Character LCD - 8-bit parallel interface V1.2 170607.0000
1A80: EXTEND.fth Primary extensions to TACHYON V4.4 kernel - 170521-0000
AUTORUN BOOT
FREQ = 96.0MHz CODE:$37AE =13742 bytes NAME:$580E =7154 bytes DATA:$76F4 =228 bytes =8288 bytes free Data Stack (0)
As regards stack operations you will not find any warnings on stack underflow as that only slows down any runtime system but there is protection built in so what you are seeing is simply the "top of stack" register since the top four items are maintained in fixed registers to suit the Prop's lack of indexed addressing. That's how a fetch from memory is something as simple as:
' @ ( addr -- long ) Fetch a long from hub memory
FETCH rdlong tos,tos
jmp unext
which is only one of the reasons why Tachyon is so fast. You can check the stacks at any time with a simple ^? (control key + ?) or zero the stack with ^S. Most Forths will automatically clear the stack on encountering an error but I Tachyon does not act so presumptuously, it's my data, don't touch it and certainly means we don't have to keep typing in the same stuff every time we get an error.
To measure how fast that operation is we take laps which capture the timing difference between the last two laps. Here we try it on @:
( 0466 $37AE ok ) 0 LAP @ LAP .LAP
48 cycles at 96MHz = 0.500us
( 0467 $37AE ok )
It doesn't matter how many laps we do beforehand:
( 0467 $37AE ok ) 0 LAP LAP LAP LAP @ LAP .LAP
48 cycles at 96MHz = 0.500us
and in fact LAP LAP is used by .LAP to calculate the lap overhead which is subtracted from the reading which is why LAP LAP .LAP will always report 0us.
LAP can be used in many situations but it is always important to LAP only that section that you are interested in, so say for instance you want to time a FOR NEXT loop you won't get an accurate overhead by reading one but if we do 1 million of them we can easily divide the reading from milliseconds to nanoseconds.
( 0469 $37AE ok ) 1,000,000 lap for next lap .lap
48000176 cycles at 96MHz = 500.001ms
I didn't want to add the 1,000,000 to the reading although we can't help including the overhead of FOR itself but each NEXT takes 500ns to count and loop. Notice too that in interactive mode lower case can also be used as can standard numeric separators too.
The !SP function is actually implemented as LMM code in hub since it doesn't have to be fast but it can't really be high level code since it would use the very stack it is trying to initialize.
When you print the top value it is read from the tos register which still holds 4 however the print operation itself uses the stack of course and the residual value is 0 which is dropped at the end but is still present in the tos register, hence the zero values thereafter.
Btw, DROP calls POPX where you can see it detects a depth of zero and skips popping the stack.
POPX mov X,tos ' copy old tos into X
tjz udepth,#POPX_ret ' do not allow ext stack to pop past bottom
sub udepth,#1 wz
mov tos,tos+1
mov tos+1,tos+2
mov tos+2,tos+3
sub stkpop,#1
sub stkpsh,dstinc
stkpop mov tos+3,datastk
@rest org simply restores the data memory that was used by CHARLCD if it already exists as is the case when this code is reloaded over an older version. When CHARLCD is compiled it will create a restore marker to data memory using "@org W@ == @rest" which reads the contents of the data pointer @org and assigns that value to the constant @reset.
Tachyon separates the dictionary and data space from code space so that the hub RAM can be utilized more effectively. V3 would mix data in with code which was not always a good thing since code could be corrupted by overwriting.
You can define your own LCD pins and hopefully if you do this before you load CHARLCD then it will detect this and not use its own default. If you change the default in CHARLCD itself rather than predefine them then you should rename it so that you know since CHARLCD could be upgraded anytime. Predefining these constants will allow you to load the current version of CHARLCD without having to maintain the patch. However I will probably update CHARLCD so that it can be loaded without having to specify pins beforehand in much the same way EASYFILE and EASYNET and other drivers now accept a parameter at runtime to specify the pins and settings to use. CHARLCD is intended to be used as an output device as if it were a remote serial display rather than have an application call the various internal methods. If you type in LCD from the console then all output will be redirected and handled correctly on the LCD display for instance.
Some traditional Forth words are replaced with more familiar symbols so that rather than CONSTANT I end up using == instead. One reason for this is readability as I have found over the years that the word itself tends to overshadow the value and name we are creating. Then there is the opposite also in traditional Forth such as the print number symbol . which seems to disappear into the source code and can easily be skipped over. Although I retain these traditional symbols I favor using PRINT instead of . just as I also favor using pub and pri and even pre instead of a plain : but then again that is also to convey information for the compiler so that all pri defined words have a tag set in the header so that a RECLAIM operation can remove those headers from the dictionary and reclaim memory.
There's a lot of very good reasons for why Tachyon does things differently just as there are very good reasons why the Propeller chip does things differently from traditional CPUs.
All strings in Tachyon are passed as an pointer to a null terminated string. They are defined simply as a leading quote as such:
" Hello World"
Here's how we use it:
( 0001 $33AA ok ) " Hello World" 16 DUMP
0000.33AC: 48 65 6C 6C 6F 20 57 6F 72 6C 64 00 10 80 8A 05 Hello World.....
( 0002 $33AA ok ) " Hello World" LEN$ .
11
( 0003 $33AA ok ) " Hello World" PRINT$
Hello World
( 0004 $33AA ok ) " Hello World" BUFFERS OVER LEN$ 1+ CMOVE
( 0005 $33AA ok ) BUFFERS 16 DUMP
0000.7800: 48 65 6C 6C 6F 20 57 6F 72 6C 64 00 00 00 00 00 Hello World.....
( 0006 $33AA ok ) BUFFERS PRINT$
Hello World
( 0007 $33AA ok ) BUFFERS 5 LEFT$ PRINT$
Hello
( 0015 $33AA ok ) " Hello World" $7E00 $!
( 0016 $33AA ok ) $7E00 PRINT$
Hello World
In those examples we are working interactively but strings are exactly the same whether compiled into a definition or typed in at the console. There are no special forms since Tachyon is always compiling, which is why you can run loops without putting them in a definition first. Strings may also be terminated by any byte with the msb bit as well.
This here may be the smallest hello world program, just one line that executes immediately.
( 0013 $33AA ok ) PRINT" Hello World"
Hello World
Btw, as you type in the console Tachyon will compile each word immediately upon a space or enter, and automatically execute the temporary compilation on an enter. There are some immediate words that execute as soon as you type them too of course.
Also, try WWORDS which prints out a formatted color-coded dictionary list otherwise you can always do the simpler WORDS or even hit ^W
.VARS will list all the variable and constants it tries to find.
lsi2c will list all I2C devices it finds etc.
Comments
No need for a hurry - thanks for the quick response
Now that I've thrown DO and +LOOP into the trash even though they have never changed in all of Forth history, I find that I have a lot of code that has this practice of "end start" parameters locked into it. However I am testing this and even though it is "better" I still find that I'm getting my poor head around it. One of the main features of the new DOFOR LOOP method is that DOFOR takes a start parameter, a actual loop count, and a index increment that gets added to the start value each loop where normally this is simply the value of one.
DOFOR doesn't run any faster than the previous loops I had since I use a rather fast branch stack but you really notice the difference in speed when the old +LOOP method is used.
Here is the old method which times the loop for 1,000,000 (2000000/2) (80MHz) So that is 2.2us/loop which is really slow.
The equivalent DOFOR code (at 96MHz) Now each loop executes at 500ns regardless of the loop increment and always executes times the loop count regardless of the increment value.
Since the loop count controls how times the DOFOR loop executes independently of the increment value it means we can do reverse loops which were very awkward with the conventional DO LOOP arrangement:
V4.4 which introduced DOFOR in place of DO, ADO, and +LOOP seems to be working well. The only problem I've had so far is wrestling with some old code that complicated the stack to suit the old DO LOOP arrangement. After conversion it is not so complicated anymore. I wonder why Forth used this arrangement in the first place since I find that I almost invariably use the start index and count method but looping with +LOOP complicated this still.
Because the loop stack is a separate stack in COG memory it had been implemented as fixed position registers with brute force ripple moves for push and pop. However there is one extra element on the stack for each DOFOR now and the ripple move was becoming too unwieldy so I made it a hybrid stack with the top four elements as fixed registers much the same as the data stack is implemented. The top four elements are: index (I); count (IY); and increment with the next element being the previous index (J). A count of 0 for either FOR or DOFOR will terminate the loop after the first iteration rather than for over 4 billion times which I am pretty sure would not be the intention.
Also added is 16-bit literals since 15-bit were encoded as a single wordcode but anything was always encoded as three words (PUSH32,highword,lowword).
There are lots of little enhancements and I still have room left in the cog after all this to enhance it some more.
For fast I/O work there are the pin mask operators H L and F which will set pins High Low or Float (back to input) by reading a mask off the top of the stack without discarding. This is different from the P2 version that may have been used since the P2 version used PIN to set the mask internally whereas 4.4 just borrows the mask from the stack.
EASYFILE is also working well on 4.4 so I will fix the APPEND operation in this version first since I am testing it.
If you are still stuck with V3 just remember that even V4.0 is very old now and V4.4 is the goto version to use IMO. Wordcode being more compact and faster "overall" than bytecode, who woulda thunk it?
As I'm always curious to stay on the bleesing edge but I don't know if that is always welcome to you. You solved a few issues recently which took time on your side.
Additionaly it could be of advantage to branch v44 into a new folder.
Best regards,
Proplem
The doNEXT address interpreter has been tweaked as well just to give some priority to calls to wordcode so they run a bit faster again. Just remember too that for fast I/O you can use H L and F to control outputs with sub-microsecond resolution, good enough even to bit-bash serial RGB LEDs or 1-wire etc.
A moment ago I was just fixing up some little bug I had introduced in the filesystem in creating files. Anyway I normally preallocate contiguous sectors when creating a file and so I specify the maximum file size with a number. Just to make it easier I created two small words KB and MB which are nothing more than a left shift operation but very useful. To create a 16MB file just:
16 MB mk NETLOG.TXT
or to ASCII wide dump the 1 KB of a file offset 1 MB from the start of the file:
1 MB 1 KB FS DUMPAW
- DOFOR is looking good
- IoT5500 builds successful up to EASYFILE, EASYNET is not yet ready.
- separating the new version into a new folder is fine - thank you - maybe others with more Forth code will appreciate too
- EASYFILE: I tried to use a Transcend 16 GB micro SDHC without success. Should it work or is is there still a SANDISK dependency? It could be that mine is "mis-formatted" because of many trial end errors. I ask to be sure whether I should try to reformat it which can eat up spare tachyon time :-(
- COMPACT4r4.FTH should be renamed to COMPACT-v4r4.FTH :-)
Again thank you for sharing and holding up the Tachyon flag so high!
Best regards,
proplem
I'll get down to the bottom of why some cards don't work but it should be a very minor thing I'm sure, I have cards other than Sandisk that work. I'm doing quite a bit of work on EASYFILE in 4.4 at present,
I haven't quite gotten onto EASYNET yet but it should be straightforward enough.
Now that the files are in their own folders I can probably remove the version from the name and leave that information in the file itself.
V4.4 starts up in non-case sensitive mode although fast block mode load via TACHYON END is still always case sensitive. Use OFF ANYCASE to enforce case sensitivity.
I've been using 4.3 for my projects but with these improvements and stability testing I see I can easily start using 4.4. With an SD card in I can also fast load FL to a temporary or specified file which buffers everything into the file and then loads it automatically. If you want to update a text file on the card over the console you can SAVETEXT <myfile>, paste/send the text file as you would normally and use esc to finalize. This will also update the file size in the directory. Using FL or SAVETEXT without a filename will cause it to use TEMP.TXT.
Since the minimum cluster size is 32k bytes it doesn't matter if the file only had 4kB but the new text has 6kB etc. I like to preallocate at least 64kB though and there is no reason why you couldn't preallocate 1MB per file anyway, unless you have 8,000 of them. The cluster chain for a file is contiguous and the number of clusters allocated has to be scanned to determine the maximum but it is just as easy to preallocate anyway.
Here is a scan of clusters of sectors with sector address header where each * represents a cluster with data (non-zero) plus I've inserted labels for id.
Each line represents 4MB so it is interesting to see all that unused space after the MBR (really just partition info) and before the FAT tables, that's around 4MB you can hide files and config in.
[/quote]
Well if you are using 4.3 for production are you logging data? If so how since APPEND is still a stub.
I keep looking for the stub to be implemented.
I won't be back in Oz for 3 weeks. When I get back I will look up my notes as I don't think I have all the info on my laptop I have with me. IIRC I posted the info on a P2 thread, so I'll also look for that.
Well if you are using 4.3 for production are you logging data? If so how since APPEND is still a stub.
I keep looking for the stub to be implemented.
[/quote]
I'm actually working on the 4.4 version, I started checking it the other day, so with all my file system work at present I will be able to sort it out. I didn't actually use APPEND for some of these files. It's easier sometimes to create a new file each time it starts up if the old file has already been used but I might make it a point right at the moment to get APPEND working ASAP as I had already started doing so in V4.3.
The last time I downloaded and built 4.4 (17 05 30) with easyfile and issued mount on a non sandisk card the system went into constant reboot mode. I then cycled power and the easyfile.fth module was gone. Hum, I will wait for another minor update and try again.
Wow! are you able to repeat that?
I am actively using V4.4 easyfile and some non Sandisk cards work but the worst that should happen is that they fail to mount, not wipe easyfile. There is no mechanism for that to happen so if it is repeatable then if you don't mind trying it out again and maybe copy your terminal screen from the initial compile to when it gets corrupted. I'd like to get to the bottom of this but is there any reason why you can't just the Ultras?
btw, that version number doesn't sound right, typo?
Using >FILE does cause a restart.
This is using a brand new 16GB SanDisk Ultra.
loaded up 4.4 2017-06-04 on PropBOE
My old 4GB SD-HC is not properly handled (worked well with Tachyon before)
There is a known problem with "other" cards, SanDisk cards work well. Hoping for a update to EasyFile.fth that restores other cards to usable and also fixes APPEND. I'm still using V3 for "production".
I start to learn Tacyon.
I loaded TachyonV4.4.spin(Xtal:5MHz) to eeprom.
And loaded EXTEND-V4r4.fth.
I try to understand CHARLCD.fth because I don't know Tachyon manner at all.
I copy/paste it to TeraTerm.
But error occured.
Code-loading is wrong?
What is this [30424][12844]?
And more '.' , '0' output.
Why error ocurr?
( 0001 $33B0 ok ) LAP LAP LAP LAP LAP LAP LAP LAP LAP LAP LAP LAP LAP LAP .LAP
0 cycles at 80MHz = 0.000us
( 0001 $33B0 ok )
Why 0.000us?
This is abnormal?
I just made a copy of CHARLCD.FTH in the V4r4 folder and modified an ADO to the newer DOFOR format which simplifies the normal DO LOOP arrangement. Since it has a few tables in there it can sometimes require a bit more compile time so I slowed minicom down to 10ms line delay (no character delay) @921600 baud. TeraTerm works fine at this baud rate too.
As regards stack operations you will not find any warnings on stack underflow as that only slows down any runtime system but there is protection built in so what you are seeing is simply the "top of stack" register since the top four items are maintained in fixed registers to suit the Prop's lack of indexed addressing. That's how a fetch from memory is something as simple as: which is only one of the reasons why Tachyon is so fast. You can check the stacks at any time with a simple ^? (control key + ?) or zero the stack with ^S. Most Forths will automatically clear the stack on encountering an error but I Tachyon does not act so presumptuously, it's my data, don't touch it and certainly means we don't have to keep typing in the same stuff every time we get an error.
To measure how fast that operation is we take laps which capture the timing difference between the last two laps. Here we try it on @:
It doesn't matter how many laps we do beforehand: and in fact LAP LAP is used by .LAP to calculate the lap overhead which is subtracted from the reading which is why LAP LAP .LAP will always report 0us.
LAP can be used in many situations but it is always important to LAP only that section that you are interested in, so say for instance you want to time a FOR NEXT loop you won't get an accurate overhead by reading one but if we do 1 million of them we can easily divide the reading from milliseconds to nanoseconds. I didn't want to add the 1,000,000 to the reading although we can't help including the overhead of FOR itself but each NEXT takes 500ns to count and loop. Notice too that in interactive mode lower case can also be used as can standard numeric separators too.
Thank you for your reply.
I placed 1 2 3 4 on stack.
After ctrlKey+S, I checked stack by [ctrlKey+?].
There is 4 on stack although Data Stack is 0.
Why?
Yes, you had 4 values on the stack and then you initialized the stack but this does not change the top 4 values that are held in registers. The !SP function is actually implemented as LMM code in hub since it doesn't have to be fast but it can't really be high level code since it would use the very stack it is trying to initialize.
When you print the top value it is read from the tos register which still holds 4 however the print operation itself uses the stack of course and the residual value is 0 which is dropped at the end but is still present in the tos register, hence the zero values thereafter.
Btw, DROP calls POPX where you can see it detects a depth of zero and skips popping the stack.
I'm reading CHARLCD.fth.
I don't understant below;
I try to input [#lcdpins 8 MASKS == #lcdbus].
After entered [#lcdpins 8 MASKS ], [???] is printed.
[???] indicate error?
[MASKS] don't exist?
How to use [WORDS]?
@rest org simply restores the data memory that was used by CHARLCD if it already exists as is the case when this code is reloaded over an older version. When CHARLCD is compiled it will create a restore marker to data memory using "@org W@ == @rest" which reads the contents of the data pointer @org and assigns that value to the constant @reset.
Tachyon separates the dictionary and data space from code space so that the hub RAM can be utilized more effectively. V3 would mix data in with code which was not always a good thing since code could be corrupted by overwriting.
You can define your own LCD pins and hopefully if you do this before you load CHARLCD then it will detect this and not use its own default. If you change the default in CHARLCD itself rather than predefine them then you should rename it so that you know since CHARLCD could be upgraded anytime. Predefining these constants will allow you to load the current version of CHARLCD without having to maintain the patch. However I will probably update CHARLCD so that it can be loaded without having to specify pins beforehand in much the same way EASYFILE and EASYNET and other drivers now accept a parameter at runtime to specify the pins and settings to use. CHARLCD is intended to be used as an output device as if it were a remote serial display rather than have an application call the various internal methods. If you type in LCD from the console then all output will be redirected and handled correctly on the LCD display for instance.
Some traditional Forth words are replaced with more familiar symbols so that rather than CONSTANT I end up using == instead. One reason for this is readability as I have found over the years that the word itself tends to overshadow the value and name we are creating. Then there is the opposite also in traditional Forth such as the print number symbol . which seems to disappear into the source code and can easily be skipped over. Although I retain these traditional symbols I favor using PRINT instead of . just as I also favor using pub and pri and even pre instead of a plain : but then again that is also to convey information for the compiler so that all pri defined words have a tag set in the header so that a RECLAIM operation can remove those headers from the dictionary and reclaim memory.
There's a lot of very good reasons for why Tachyon does things differently just as there are very good reasons why the Propeller chip does things differently from traditional CPUs.
Please teach me how to get string.
Incase of PropForth c" abcde" lcd_str
I can get length and address for string[abcde] by c" ".
How to do same in Tachyon?
All strings in Tachyon are passed as an pointer to a null terminated string. They are defined simply as a leading quote as such:
" Hello World"
Here's how we use it:
In those examples we are working interactively but strings are exactly the same whether compiled into a definition or typed in at the console. There are no special forms since Tachyon is always compiling, which is why you can run loops without putting them in a definition first. Strings may also be terminated by any byte with the msb bit as well.
This here may be the smallest hello world program, just one line that executes immediately.
Btw, as you type in the console Tachyon will compile each word immediately upon a space or enter, and automatically execute the temporary compilation on an enter. There are some immediate words that execute as soon as you type them too of course.
Also, try WWORDS which prints out a formatted color-coded dictionary list otherwise you can always do the simpler WORDS or even hit ^W
.VARS will list all the variable and constants it tries to find.
lsi2c will list all I2C devices it finds etc.
I try to write code.
But error occur at code's top.
Tachyon freeze.
What is wrong?
Cannot load at all.
What part is wrong?