This current version of Tachyon called TAQOZ (pronounced just like tacos) is aimed at being even more compact so it can be squeezed into the boot ROM. Anyway, if you want to try it out there is tacoz.spin2 in the P2/V27 dropbox folder and the Forth files such as EXTEND etc are in the P2/Forth folder. It works well on the A7 and A9 boards.
I wanted to id my pins on the scope so here is a quick one-liner to show you how easy it is to get it to exercise the hardware:
61 0 DO I PIN I 1+ KHZ LOOP
As you can imagine all the smartpins on my A9 board are going off at different frequencies in steps of 1kHz.
Now, how do you turn all those smartpin thingies off?
61 0 DO I PIN MUTE LOOP
I will probably add my flexible FOR NEXT looping arrangement from P1 V4 so muting looks like this:
61 FOR I PIN MUTE NEXT
Since FOR NEXT in that arrangement uses an index that starts from 0 unless we say different. Normal FOR NEXT loops don't have an index, just a down count.
BTW, I develop for the P2 under WINXP in VirtualBox on Linux Mint since PNut doesn't seem to work too well under Wine. So I use TeraTerm but there is no need for any delays when sending files as I dedicate about 60k just for a receive buffer! However it seems to compile just as fast as it can get it at 921600 baud.
I'm definitely struggling to make sense of any of that code, Peter. How to distinguish between a command and a parameter? I gather there is no specific delimitation between commands. And is it only values that get stacked?
I think it's the difference between code that gets lexed and compiled vs code that just is and everything separated by whitespace will do something. For instance, numbers are numbers and get stacked so 61 0 are simply stacked yet DO grabs those two parameters just as we might say FOR I = 0 TO 60 in BASIC for instance where the default step is +1
The I is always the current index of a DO LOOP structure which of course leaves a number on the stack which is passed to PIN whose only responsibility is to set an internal register to that number. That way when we say I 1+ it will be the value of the index starting at 0 plus 1 passed to the KHZ word which configures the smartpin as an NCO with the correct timing for that value of kHz. LOOP will simply increment the index and compare that against the limit of 61 and exit the loop if equal.
Tachyon is a little bit different in that it also compiles by default so it is possible to execute one-liners with loops and branches without having to first enter it into a definition. The other thing that I take for granted though is that unlike conventional languages where you only have one function per line is that you can enter a really really long line of code in Tachyon, no need for lines and braces. It reads from left to right in a single pass. Best understood by interacting with it, hence the one-liners.
I am struggling there too, but the stack in FORTH is different from what one 'usually' thinks of a stack.
'usually' one thinks that calling some function will push parameter on a stack, call some code, code gets parameter from stack does something and returns some value on the stack.
after successful calling that function the stack is at the same place as before calling the function.
Not so in forth.
some words behave like above, but some words consume stack items or leave stack items behind. Or even both of it, changing the stack completely.
I try to think of it as parameter-stack independent of any return-address stack.
61 0 DO I PIN I 1+ KHZ LOOP
is for me
(61, 0)DO ( (I)PIN ( (I, 1)+ )KHZ )LOOP
or
DO(61,0) ( PIN(I) KHZ(+(I,1)) ) LOOP
still looking weird, but forth just removes all the parentheses out of the source and you 'just' have to keep track of your data-stack.
I am quite fascinated by the idea behind FORTH, but am barely able to read some of it.
It's just completely backwards for me.
But I really like the idea of TAQOZ in ROM. As small and lean as possible, I trust Peter there to get that done.
The big point is the build in extensibility of FORTH in general. As soon as you define a word you can use it like any other ones.
And one would not really need to program in forth, I am sure one can define a word in TAQOZ calling some PASM code of own creation directly.
Ok, I fixed the various little problems I was having and some of it may have to do with some coginit code too. My CVA9 board is plugged into a motherboard with two other SD card sockets on it into which I have a 4GB, a 32GB, and a 64GB card loaded. If I pickup some 128GB cards I could access 384GB. No idea what I'd do with that, but it sounds cool.
Here is where I mount the three drives, open a Webster's dictionary file and dump some text from 20MB into it.
TAQOZ# C:
Mounted 7803.AA00-F84E.1690 NO NAME FAT32 4,119MB (32,768/cluster)
ok
TAQOZ# ls
NO NAME
WARPEACE.TXT EXTEND .FTH EEWORDS .FTH VGA .FTH CLOCK .FTH
EASYFILE.FTH BREAKOUT.FTH SDCARD .FTH W5500 .FTH LIFE .FTH
EASYNET .FTH IOT5500 .HTM WELCOME .TEL POPCORN .MP3 HOME .HTM
P8CPU .JPG IOTPINS .JPG LOVE .WAV HELP .TXT P8 .H
IOT5500H.JPG DRAGON .JPG IOT5500 .JPG 128K .BIN 256K .BIN
W5200 .FTH PREVIOUS.ROM DEBUG .ROM POPCORN .WAV P8X32A .PDF
IMAGE3 FRED .PNG FSRSCH .PNG FSRPCB .PNG IMAGE
HTTP404 .HTM IMAGE2 IMAGE1 LOGON .HTM TACHYON .HTM
WELCOME .FTP P2BOOT .IMG POWERMAX.LOG SITE0002.LOG SITE0001.LOG
FAVICON .ICO PARALLAX.PNG HOME1 .HTM SYSLOG .TXT HCB4208 .JPG
CE1372 .JPG CE1372 .PDF CHARLCD .JPG ECOLCD .PDF LOVE .MP3
FIRMWARE.ROM ok
TAQOZ# D:
Mounted F959.C01F-83AD.B80C mkfs.fat PBJ32C FAT32 31,910MB (16,384/cluster)
ok
TAQOZ# ls
PBJ32C
[CODE ] [HELP ] [VIDEOS ] HOME .HTM HTTP001 .HTM
HTTP404 .HTM LOGON .HTM P8X32A .PDF PARALLAX.PNG POPCORN .WAV
WARPEACE.TXT TEMP .TXT A ok
TAQOZ# E:
Mounted 0048.DEDA-451D.4524 mkfs.fat SD64G FAT32 62,545MB (32,768/cluster)
ok
TAQOZ# ls
SD64G
[HELP ] EASYFILE.FTH EXTEND .FTH EASYNET .FTH LIFE .FTH
CALCDEMO.FTH KJV .TXT SEE .FTH SPLAT-V4.FTH WARPEACE.TXT
LOVE .WAV POPCORN .WAV CVA9V26 .JIC TF2 .OGV WEBSTERS.TXT
ILIAD .TXT PRIDE .TXT ok
TAQOZ# FOPEN WEBSTERS.TXT...opened at 0004.249A ok
TAQOZ# 20 MB $80 FS DUMP
40.0000: 74 2E 20 5B 69 6D 70 2E 20 26 20 70 2E 20 70 2E t. [imp. & p. p.
40.0010: 20 52 65 6E 64 65 72 65 64 20 28 2D 64 72 64 29 Rendered (-drd)
40.0020: 3B 70 2E 20 70 72 2E 20 26 20 76 62 2E 20 6E 2E ;p. pr. & vb. n.
40.0030: 0D 0A 52 65 6E 64 65 72 69 6E 67 2E 5D 20 45 74 ..Rendering.] Et
40.0040: 79 6D 3A 20 5B 46 2E 20 72 65 6E 64 72 65 2C 20 ym: [F. rendre,
40.0050: 4C 4C 2E 20 72 65 6E 64 72 65 2C 20 66 72 2E 20 LL. rendre, fr.
40.0060: 4C 2E 20 72 65 64 64 65 72 65 3B 20 70 72 65 66 L. reddere; pref
40.0070: 2E 20 72 65 64 2D 2C 0D 0A 72 65 2D 2C 20 72 65 . red-,..re-, re ok
TAQOZ#
One, it being arguments first. That's just hard for me personally. I just don't think that way intrinsically. It's like doing something with your lesser hand. Possible, but thought isn't action. It's thought, more thought, then action. There is a layer there hard to crack for some of us. Me.
The other is needing to know what words want what.
Actually, three things: Keeping a stack in my head gets confusing too, but I see a lot of that can be avoided too. It's all about what words people define and use.
Got a question about that next comment Peter.
I find most Tachyon things pretty darn readable actually. When I really think about it, I can make it do things. Simple things. In concept, Forth is brilliant. There is only a little syntax, and the arguments preceding the words that operate on them make it very small, in concept. Not much is needed, which is why bootstrapping a Forth onto a new CPU happens as it does. A couple of K can get one going. Through a dictionary at that and BOOM! Might not be optimized, but it's capable.
Wash, rinse, repeat on another CPU.
That's cool.
Re: Define a word in PASM, then launch it.
YES!
Frankly, if the ROM version contains a reasonable assembler, I think people will use that option a lot. If you want, that PASM can do most anything, and the Forth becomes a sort of "shell", with a lot of the harder / confusing things being optional.
It's my hope we see this in ROM, and given the assembler option, and a few obvious "one liner" type things documented, people will get good use out of the software for test, learning the P2 hardware, and some other basics.
And I'll bet we see a few who really get it. Forth is that way. Some of us grok it right away, and the result is kind of amazing.
In this ROM Tachyon, is it possible to just break the rules, ignore the stack, and use HUB memory explicitly, like by address?
I know it's bad form, or at least I think so, given my limited understanding of Forth, but...
Doing that might actually help some people get more use out of the system, at the cost of "not forthy" code.
Just wondering here.
And I'm wondering, because words take stuff off the stack, and that's simplest, but can't they also be made to work by address, sort of like a variable works in most other ways, and in PASM?
Something people don't realize about Forth is that every application you create in Forth is a Domain Specific Language.
You want to define your "words" to be specific to and appropriately describe aspects of your application. The more words you use, the more modular your solution will be. You don't really want to only use the supplied words. That would be like coding in "Forth assembly" (that would probably feel normal for many on this forum ;-).
As for wrapping your head around the reverse polish notation;
I think of it like assembly, you have to have your registers/accumulator(s) filled with data FIRST, THEN you can do something with it.
@potatohead - Ooops! sorry, I meant to say I had cards(3), a GB(4). a GB(32), and GB(64), just in case you were confused
If you operated on hub memory directly for parameters then you would need to expand each instruction to include source and destination fields etc. Hang on, that's PASM.
A simple fruit shop POS example program could work like this:
6 apples 8 bananas 1 bag grapes 20.00 tendered total
I'm pretty sure anyone would grok that. As thej said, you create a "Domain Specific Language", in this case fruit etc.
In fact my very first major Forth project was designing POS terminals although a lot more complex than this simple example it still worked in that "unnatural way", you know, with the number first, like 6 beers 2 rums etc
What would go a long way in overcoming the reluctance of adoption might be to have a graphical animation of what is actually happening with the stack. That could make things very easy. Also, maybe a variably-detailed library listing of words.
What would go a long way in overcoming the reluctance of adoption might be to have a graphical animation of what is actually happening with the stack. That could make things very easy. Also, maybe a variably-detailed library listing of words.
Not being able to see the stack as code executes is like only being able to see half of your program !
The stack holds ALL your program state. Being able to see it is really useful !!! (to say the least :-)
From my experience, the need (or even the desire) for a stack animation fades rapidly as familiarity with FORTH and the words you use grows. (To a great degree, the code documents itself in that regard.) I can imagine Peter wouldn't be thrilled about creating such an animation. Some authors have done a great job illustrating stack action. Leo Brodie comes to mind.
From my experience, the need (or even the desire) for a stack animation fades rapidly as familiarity with FORTH and the words you use grows. (To a great degree, the code documents itself in that regard.) I can imagine Peter wouldn't be thrilled about creating such an animation. Some authors have done a great job illustrating stack action. Leo Brodie comes to mind.
I agree completely with you. Where it has it's value is when your debugging some code or learning words you didn't create.
You would definitely want it set up so it can be turned On or Off as needed.
Even Apple 2 Forths like SkyForth had this capability.
Of course, keeping the code behind your Words short and using names that actually describe what the word does goes a long way to having "self documenting" code.
For those who think they know Forth here is the console output from a quick little routine the puts the LOOP not only before the DO but also in another definition. But how does it work?
TAQOZ# : T1 I EMIT LOOP ; ok
TAQOZ# : T2 $7F $20 DO T1 ; ok
TAQOZ# T2 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ok
Here's a hint by how traditional Forth works and why it would be impossible.
DO is normally an immediate word that doesn't get compiled but stacks the compilation address and compiles a different runtime version of DO, usually named (DO). Now (DO) pushes the starting index and the limit onto the return stack so "I" which reads the current loop index has to access the return stack. So you can never use "I" in called function as it gets buried in the return stack. Then there is LOOP which is also normally an immediate word that compiles a runtime version called (LOOP) and a branch address based on the address left by DO.
But Tachyon seems to break all the rules of Forth. Understanding the differences helps to understand the strengths, speed, and benefits of Tachyon.
Here's a hint by how traditional Forth works and why it would be impossible.
DO is normally an immediate word that doesn't get compiled but stacks the compilation address and compiles a different runtime version of DO, usually named (DO). Now (DO) pushes the starting index and the limit onto the return stack so "I" which reads the current loop index has to access the return stack. So you can never use "I" in called function as it gets buried in the return stack. Then there is LOOP which is also normally an immediate word that compiles a runtime version called (LOOP) and a branch address based on the address left by DO.
But Tachyon seems to break all the rules of Forth. Understanding the differences helps to understand the strengths, speed, and benefits of Tachyon.
I follow the source but has it always been this way? Or is this new in TAQOZ?
I've always had it this way for Tachyon but it certainly is never like this in other Forths which for some reason like to be traditional and nostalgic (and ANSI)
I always hated those two step words that had to compile a runtime equivalent and I try to do away with them as much as possible.
Here's a hint by how traditional Forth works and why it would be impossible.
DO is normally an immediate word that doesn't get compiled but stacks the compilation address and compiles a different runtime version of DO, usually named (DO). Now (DO) pushes the starting index and the limit onto the return stack so "I" which reads the current loop index has to access the return stack. So you can never use "I" in called function as it gets buried in the return stack. Then there is LOOP which is also normally an immediate word that compiles a runtime version called (LOOP) and a branch address based on the address left by DO.
But Tachyon seems to break all the rules of Forth. Understanding the differences helps to understand the strengths, speed, and benefits of Tachyon.
looks perfectly NORMAL to me - since I do not know the 'right' (old) FORTH way anyhow ;-)
all (most) I know about FORTH is TACHYON ... and I like it very much
In preparing Tachyon for a boot ROM version I have been whittling down the initialization sequence for SD cards by interacting with them and introducing all kinds of scenarios. I've found that I don't need to preclock the card and that most of the initialization time (not clocks) is spent waiting for the card after a 41 ACMD. The first initialization after card power-up takes the longest and that could be anywhere from 90ms to 200ms or so. However any further initializations only take around 1.5ms and mounting the FAT32 filesystem only adds another 4ms. This has been tested on a wide assortment of cards of various brands and capacities from 4GB to 64GB.
It is an description, how to be pride just for reaching a position, you just can't believe. 'I'm a Propeller! Can you believe it? Comes close to the content.
TAQOZ# FOPEN PRIDE.TXT...opened at 0005.0ADA ok
TAQOZ# FSIZE@ . 726223 ok
TAQOZ# 200000 1000 FS DUMPA
03.0D40: upon it, Mr. Collins,... she added, ...that Lizzy shall be..brou
03.0D80: ght to reason. I will speak to her about it directly. She is a v
03.0DC0: ery..headstrong, foolish girl, and does not know her own interes
03.0E00: t but I will.._make_ her know it...........Pardon me for interru
03.0E40: pting you, madam,... cried Mr. Collins; ...but if..she is really
03.0E80: headstrong and foolish, I know not whether she would..altogethe
03.0EC0: r be a very desirable wife to a man in my situation, who..natura
03.0F00: lly looks for happiness in the marriage state. If therefore she.
03.0F40: .actually persists in rejecting my suit, perhaps it were better
03.0F80: not..to force her into accepting me, because if liable to such d
03.0FC0: efects of..temper, she could not contribute much to my felicity.
03.1000: ..........Sir, you quite misunderstand me,... said Mrs. Bennet,
03.1040: alarmed. ...Lizzy is..only headstrong in such matters as these.
03.1080: In everything else she is as..good-natured a girl as ever lived.
03.10C0: I will go directly to Mr. Bennet, and..we shall very soon settl
03.1100: e it with her, I am sure........She would not give him time to r ok
A lot of these text files such as the Bible and dictionaries (VULGAR btw means "common" language, but modern semantics has a more negative connotation) are useful for testing file searching and access. Some files such as FISH2.VT are meant for ANSI terminal animation and there are WAV files that I can play as well etc.
Saw a post where someone was trying to drive LEDs via shift registers. Well, here is a little taste how it can be done with TAQOZ in the blink of an eye, 11us blink @80MHz that is. For this example I am only using clock and data with 74HC164 shift registers and tied the reset high. I didn't need to define a buffer, I just used some memory at $4000 and filled it for the test.
Since it writes so fast there is no ghosting and with another one liner I could do brightness without any extra components.
This code crumb just sets up SPI pins as 21 for the clock and 22 for the data (CS is set to 22 as a dummy and serial in is not used). The LEDS routine could be a DO LOOP and runs in <30us but the BUF>SPI function is simpler and faster.
TAQOZ# &22.00.22.21 SPIPINS ok
TAQOZ# : LEDS ( buf -- ) 8 BUF>SPI ; ok
TAQOZ# $4000 5 $FF FILL ok
TAQOZ# $4000 LEDS ok
TAQOZ# $4000 LAP LEDS LAP .LAP 905 cycles = 11.312us ok
TAQOZ#
Here's a shot of the P2 motherboard with the CVA9 plugged in underneath. The W5500 Ethernet module is unplugged so I could borrow the pins for the bar graph LEDs. Why one of Cluso99's Blade2 boards in the center? Because I almost gave up on the P2 at one time and soldered this in instead but never connected it up.
Comments
I wanted to id my pins on the scope so here is a quick one-liner to show you how easy it is to get it to exercise the hardware: As you can imagine all the smartpins on my A9 board are going off at different frequencies in steps of 1kHz.
Now, how do you turn all those smartpin thingies off?
I will probably add my flexible FOR NEXT looping arrangement from P1 V4 so muting looks like this: Since FOR NEXT in that arrangement uses an index that starts from 0 unless we say different. Normal FOR NEXT loops don't have an index, just a down count.
BTW, I develop for the P2 under WINXP in VirtualBox on Linux Mint since PNut doesn't seem to work too well under Wine. So I use TeraTerm but there is no need for any delays when sending files as I dedicate about 60k just for a receive buffer! However it seems to compile just as fast as it can get it at 921600 baud.
The I is always the current index of a DO LOOP structure which of course leaves a number on the stack which is passed to PIN whose only responsibility is to set an internal register to that number. That way when we say I 1+ it will be the value of the index starting at 0 plus 1 passed to the KHZ word which configures the smartpin as an NCO with the correct timing for that value of kHz. LOOP will simply increment the index and compare that against the limit of 61 and exit the loop if equal.
Tachyon is a little bit different in that it also compiles by default so it is possible to execute one-liners with loops and branches without having to first enter it into a definition. The other thing that I take for granted though is that unlike conventional languages where you only have one function per line is that you can enter a really really long line of code in Tachyon, no need for lines and braces. It reads from left to right in a single pass. Best understood by interacting with it, hence the one-liners.
I am struggling there too, but the stack in FORTH is different from what one 'usually' thinks of a stack.
'usually' one thinks that calling some function will push parameter on a stack, call some code, code gets parameter from stack does something and returns some value on the stack.
after successful calling that function the stack is at the same place as before calling the function.
Not so in forth.
some words behave like above, but some words consume stack items or leave stack items behind. Or even both of it, changing the stack completely.
I try to think of it as parameter-stack independent of any return-address stack.
61 0 DO I PIN I 1+ KHZ LOOP
is for me
(61, 0)DO ( (I)PIN ( (I, 1)+ )KHZ )LOOP
or
DO(61,0) ( PIN(I) KHZ(+(I,1)) ) LOOP
still looking weird, but forth just removes all the parentheses out of the source and you 'just' have to keep track of your data-stack.
I am quite fascinated by the idea behind FORTH, but am barely able to read some of it.
It's just completely backwards for me.
But I really like the idea of TAQOZ in ROM. As small and lean as possible, I trust Peter there to get that done.
The big point is the build in extensibility of FORTH in general. As soon as you define a word you can use it like any other ones.
And one would not really need to program in forth, I am sure one can define a word in TAQOZ calling some PASM code of own creation directly.
Mike
Here is where I mount the three drives, open a Webster's dictionary file and dump some text from 20MB into it.
My struggle with Forth has two components:
One, it being arguments first. That's just hard for me personally. I just don't think that way intrinsically. It's like doing something with your lesser hand. Possible, but thought isn't action. It's thought, more thought, then action. There is a layer there hard to crack for some of us. Me.
The other is needing to know what words want what.
Actually, three things: Keeping a stack in my head gets confusing too, but I see a lot of that can be avoided too. It's all about what words people define and use.
Got a question about that next comment Peter.
I find most Tachyon things pretty darn readable actually. When I really think about it, I can make it do things. Simple things. In concept, Forth is brilliant. There is only a little syntax, and the arguments preceding the words that operate on them make it very small, in concept. Not much is needed, which is why bootstrapping a Forth onto a new CPU happens as it does. A couple of K can get one going. Through a dictionary at that and BOOM! Might not be optimized, but it's capable.
Wash, rinse, repeat on another CPU.
That's cool.
Re: Define a word in PASM, then launch it.
YES!
Frankly, if the ROM version contains a reasonable assembler, I think people will use that option a lot. If you want, that PASM can do most anything, and the Forth becomes a sort of "shell", with a lot of the harder / confusing things being optional.
It's my hope we see this in ROM, and given the assembler option, and a few obvious "one liner" type things documented, people will get good use out of the software for test, learning the P2 hardware, and some other basics.
And I'll bet we see a few who really get it. Forth is that way. Some of us grok it right away, and the result is kind of amazing.
I know it's bad form, or at least I think so, given my limited understanding of Forth, but...
Doing that might actually help some people get more use out of the system, at the cost of "not forthy" code.
Just wondering here.
And I'm wondering, because words take stuff off the stack, and that's simplest, but can't they also be made to work by address, sort of like a variable works in most other ways, and in PASM?
You want to define your "words" to be specific to and appropriately describe aspects of your application. The more words you use, the more modular your solution will be. You don't really want to only use the supplied words. That would be like coding in "Forth assembly" (that would probably feel normal for many on this forum ;-).
As for wrapping your head around the reverse polish notation;
I think of it like assembly, you have to have your registers/accumulator(s) filled with data FIRST, THEN you can do something with it.
If you operated on hub memory directly for parameters then you would need to expand each instruction to include source and destination fields etc. Hang on, that's PASM.
A simple fruit shop POS example program could work like this:
6 apples 8 bananas 1 bag grapes 20.00 tendered total
I'm pretty sure anyone would grok that. As thej said, you create a "Domain Specific Language", in this case fruit etc.
In fact my very first major Forth project was designing POS terminals although a lot more complex than this simple example it still worked in that "unnatural way", you know, with the number first, like 6 beers 2 rums etc
What would go a long way in overcoming the reluctance of adoption might be to have a graphical animation of what is actually happening with the stack. That could make things very easy. Also, maybe a variably-detailed library listing of words.
Also, consistency in words, like PASM.
Domain specific... I have always internalized that as a forth simply becomes the target apllication.
Not being able to see the stack as code executes is like only being able to see half of your program !
The stack holds ALL your program state. Being able to see it is really useful !!! (to say the least :-)
I agree completely with you. Where it has it's value is when your debugging some code or learning words you didn't create.
You would definitely want it set up so it can be turned On or Off as needed.
Even Apple 2 Forths like SkyForth had this capability.
Of course, keeping the code behind your Words short and using names that actually describe what the word does goes a long way to having "self documenting" code.
For those who think they know Forth here is the console output from a quick little routine the puts the LOOP not only before the DO but also in another definition. But how does it work?
Mike
DO is normally an immediate word that doesn't get compiled but stacks the compilation address and compiles a different runtime version of DO, usually named (DO). Now (DO) pushes the starting index and the limit onto the return stack so "I" which reads the current loop index has to access the return stack. So you can never use "I" in called function as it gets buried in the return stack. Then there is LOOP which is also normally an immediate word that compiles a runtime version called (LOOP) and a branch address based on the address left by DO.
But Tachyon seems to break all the rules of Forth. Understanding the differences helps to understand the strengths, speed, and benefits of Tachyon.
I follow the source but has it always been this way? Or is this new in TAQOZ?
I always hated those two step words that had to compile a runtime equivalent and I try to do away with them as much as possible.
all (most) I know about FORTH is TACHYON ... and I like it very much
In preparing Tachyon for a boot ROM version I have been whittling down the initialization sequence for SD cards by interacting with them and introducing all kinds of scenarios. I've found that I don't need to preclock the card and that most of the initialization time (not clocks) is spent waiting for the card after a 41 ACMD. The first initialization after card power-up takes the longest and that could be anywhere from 90ms to 200ms or so. However any further initializations only take around 1.5ms and mounting the FAT32 filesystem only adds another 4ms. This has been tested on a wide assortment of cards of various brands and capacities from 4GB to 64GB.
Mount drive FAT32 Eject and time the basic SD card initialization Warm init
Mounting three SD cards and listing directory two different ways.
A lot of these text files such as the Bible and dictionaries (VULGAR btw means "common" language, but modern semantics has a more negative connotation) are useful for testing file searching and access. Some files such as FISH2.VT are meant for ANSI terminal animation and there are WAV files that I can play as well etc.
Since it writes so fast there is no ghosting and with another one liner I could do brightness without any extra components.
This code crumb just sets up SPI pins as 21 for the clock and 22 for the data (CS is set to 22 as a dummy and serial in is not used). The LEDS routine could be a DO LOOP and runs in <30us but the BUF>SPI function is simpler and faster.
Here's a shot of the P2 motherboard with the CVA9 plugged in underneath. The W5500 Ethernet module is unplugged so I could borrow the pins for the bar graph LEDs. Why one of Cluso99's Blade2 boards in the center? Because I almost gave up on the P2 at one time and soldered this in instead but never connected it up.