Shop OBEX P1 Docs P2 Docs Learn Events
TACHYON O/S V3.0 JUNO - Furiously Fast Forth, FAT32+LAN+VGA+RS485+OBEX ROMS+FP+LMM+++ - Page 16 — Parallax Forums

TACHYON O/S V3.0 JUNO - Furiously Fast Forth, FAT32+LAN+VGA+RS485+OBEX ROMS+FP+LMM+++

11314161819109

Comments

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2012-11-06 22:05
    I haven't been able to share my Tachyon applications because they are commercial but suffice to say that Tachyon is working extremely well in this regard. But I haven't any time to discuss what the language should or should not be as I am too busy busting bits n bytes with Tachyon to create new applications.

    What I can do for the brave hearted is give you this tiny bit of code that is a one word 16-bit signed wave player. It only uses the one cog for reading the SD card and playing at the same time. There are no special words or kernel enhancements, just Tachyon as it is. because it runs straight from SD card you don't even need buffers. I've tested this to 22.050kHz and given the rough bit of code that it is it runs extremely well.
    [FONT=courier new]TACHYON
    
    {
    WAVE PLAYER 
    11.025kHz 16-bit signed
    Reads and plays directly from the SD card using multiple block read mode
    Assumes file is non-fragmented (fairly normal for SD cards)
    External file system must locate the virtual address and size and pass this to PLAY
    RUNMOD is actually the instruction for SPIO (input and output) when the SPIO module is loaded
    
    Notes: Also seems to work fine at 22.050kHz sample rates
    }
    
    
    LONG rate
    
    : PLAY ( addr blocks rate pin -- )
        A DUTY APIN            \ audio dac
        CLKFREQ SWAP / rate !
        SWAP #18 CMD 0=            \ Issue a multiple block read command
          IF RES@ #datatkn =        \ when ready
            IF [SPIO] 8 SDCNT        \ ensure the bit count is 8 for byte transfers 
              FOR
              rate @ DELTA        \ reset play period ( slight delay because of reading end of block crc etc)
              $100 FOR -1 RUNMOD $FF AND -1 RUNMOD $80 + 8 SHL OR #16 SHL WAITCNT FRQA COG! NEXT
              -1 RUNMOD -1 RUNMOD 2DROP
              BEGIN -1 RUNMOD $FF AND $FF <> UNTIL    \ wait for SD card
              NEXT
            THEN
         THEN
        0 #12 CMD DROP
        ;
    
    END
    
    \ Demo - play a file located at $18.0000 for 3000 blocks @ 11.025kHz on P20
    !SD
    $18.0000 #3000 #11,025 #P20 PLAY
    
    [/FONT]
    

    EDIT: If you are only running at 11.025kHz you can move the line "rate @ DELTA" to just before the "FOR" instruction and it will be very smooth playing.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2012-11-07 06:59
    Here's some updated code of the wave player that I've placed onto a webpages version of the Google docs. This version doesn't seem to have any artefacts at 11.025kHz plus I've included a wave file (POPCORN) that you can just copy it onto your SD card (I used 2GB ones) and give it a go. My audio dac is a normal RC network of 220R from the pin to a 0.1uF cap to ground.

    So you can play wave files without dedicating 1K for buffers or other variables. It runs in a single non-dedicated cog and the only memory it basically takes up is 88 bytes for the code. You require the standard SDCARD.fth module loaded of course.
  • D.PD.P Posts: 790
    edited 2012-11-07 10:00
    Here's some updated code of the wave player that I've placed onto a webpages version of the Google docs. This version doesn't seem to have any artefacts at 11.025kHz plus I've included a wave file (POPCORN) that you can just copy it onto your SD card (I used 2GB ones) and give it a go. My audio dac is a normal RC network of 220R from the pin to a 0.1uF cap to ground.

    So you can play wave files without dedicating 1K for buffers or other variables. It runs in a single non-dedicated cog and the only memory it basically takes up is 88 bytes for the code. You require the standard SDCARD.fth module loaded of course.

    I look forward to hearing about your other success with Tachyon but realize the importance of project completion. I admire what seems to be your unstated philosophy of not letting the accidental complexity of the problem (tools, languages, methods...) get in the way of solving the inherent complexity of the issue at hand.

    Thanks for this snippet and everything else you have so generously shared.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2012-11-07 15:03
    D.P wrote: »
    I look forward to hearing about your other success with Tachyon but realize the importance of project completion. I admire what seems to be your unstated philosophy of not letting the accidental complexity of the problem (tools, languages, methods...) get in the way of solving the inherent complexity of the issue at hand.

    Thanks for this snippet and everything else you have so generously shared.

    Thanks for the feedback. Although there seems to be some real interest in Forth being generated and that's a good thing, I've also been hearing a lot of critique about what Forth should be or shouldn't be. This goes against what Forth is and it mightn't please some but for those who love standards the good news is that there are so many to choose from!

    Because Tachyon does the things the way it does it gets the job done rather than look pretty in a glossy. Because of it's "short" stack there are some standard words that don't make sense or can't be implemented. Because of it's multiple stacks it's also non-standard. Because Tachyon is written for the Propeller it is the way it is and it is not meant to be ported to another processor. BTW, the short stack has never been a problem in all my applications and it is very robust because it can underflow and overflow without crashing the chip. Error reporting is all very good and well on a PC but you wouldn't want one of your flight-control processors being so helpful and also automatically rebooting when it's a non-fatal soft error would you? That would be fatal.

    What the wave player snippet demonstrates is why speed is important (not just bit-bashing) but also the way you go about things too which is what Forth is about, allowing you to explore and test interactively. So this code is a quick hack but it works well whereas any other wave player on the Prop requires PASM, a dedicated cog, and buffer ram to playback the samples. Stripping away all the complexities also reveals that the complexities of a program are mostly from the programmer or more precisely, their way of working out a solution. When I was a very young child my brother and I took my sister's walking doll and hid under the bed while we pulled it apart to see what made it work. Well, we didn't figure that out then but us "boys" will want to pull things apart to see how they work. So it's much easier to do so when all the complexities are stripped away. However, my sister still remembers what we did to her prized doll to this day! :)
  • D.PD.P Posts: 790
    edited 2012-11-09 14:16
    In the lastest SDCARD.fth the commented pri NA@ word is causing .CARD to not compile obviously. More important is I can't get the wave player to run on my PBOE and can't get the SD card to work any longer using the lastest dropbox files after resolving the feature in the SDCARD.fth file? I've check my card and PBOE with a simple spin program just to make sure the HW is _still working correctly.
    \ pri NA@ ( addr -- long )  0 SWAP 4 0 DO C@++ I 2* 2* 2* SHL ROT + SWAP LOOP DROP ;
    
    CREATE tval	
    	#00 | #10 | #12 | #13 | 
      	#15 | #20 | #25 | #30 |
    	#35 | #40 | #45 | #50 | 
     	#55 | #60 | #70 | #80 |
    
    
    
    \ Card information
    pub .CARD
    \	  CR ." BYTES:  " SDSIZE? .
    	  \    0123456789ABCDEF012345
    	  CR ." MFG:    " cid C@ .BYTE
    	  CR ." OEM:    " cid 1+ 2 TYPE
    	  CR ." PROD:   " cid 3 + 5 TYPE
    	  CR ." REV:    " cid 8 + C@ .BYTE
    	  CR ." S/N:    " cid 9 + NA@ .LONG
    	  CR ." DATE:   " cid #13 + C@
    	  8 SHL cid #14 + C@ OR
    	  DUP 4 SHR #2000 + #10 .NUM
    	  ." /" $0F AND #10 .NUM
    	  CR ." CRC:    " cid #15 + C@ 2/ .BYTE
    	  CR
    	  CR ." TACC    " #119 #112 CSD@
    	  DUP 3 SHR tval + C@ #10 .NUM
    	  3 AND  1- 0 DO ." 0" LOOP ." ns"
    	  CR ." NSAC    " #111 #104 CSD@ .
    
    
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2012-11-09 21:34
    NA@ was replaced sometime ago with U@ which works a little differently internally in that it uses a CMOVE to a long aligned variable so it's actually faster. The dropbox files have now been updated plus just so we are on the same page I have been using V2.1 of the kernel as this extended the opcodes available with an XOP instruction. The ESPIO module that I use with the display is also part of this kernel and I am working on a suped-up version of this SPI that can run as fast as possible.
  • D.PD.P Posts: 790
    edited 2012-11-09 22:53
    Thanks for updating the dropbox and setting me straight version wise. Found one of the new displays your working with for $21.00 US, 10 shipping but still very reasonable for my prototyping.
  • SapiehaSapieha Posts: 2,964
    edited 2012-11-09 23:40
    Hi Peter.

    Why in v2.1 read.me file You have that version info ?
    Latest version: Propeller .:.:--TACHYON--:.:. Forth V1.0 rev120814.1230


    NA@ was replaced sometime ago with U@ which works a little differently internally in that it uses a CMOVE to a long aligned variable so it's actually faster. The dropbox files have now been updated plus just so we are on the same page I have been using V2.1 of the kernel as this extended the opcodes available with an XOP instruction. The ESPIO module that I use with the display is also part of this kernel and I am working on a suped-up version of this SPI that can run as fast as possible.
  • D.PD.P Posts: 790
    edited 2012-11-10 23:12
    {
    WAVE PLAYER
    11.025kHz 16-bit signed
    Reads and plays directly from the SD card using multiple block read mode
    Assumes file is non-fragmented (fairly normal for SD cards)
    External file system must locate the virtual address and size and pass this to PLAY
    RUNMOD is actually the instruction for SPIO (input and output) when the SPIO module is loaded

    Notes: Also seems to work fine at 22.050kHz sample rates
    }


    Peter I'm not sure how to locate the Popcorn.wav file's virtual address on the SD card with ?
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2012-11-11 05:09
    D.P wrote: »
    {
    WAVE PLAYER
    11.025kHz 16-bit signed
    Reads and plays directly from the SD card using multiple block read mode
    Assumes file is non-fragmented (fairly normal for SD cards)
    External file system must locate the virtual address and size and pass this to PLAY
    RUNMOD is actually the instruction for SPIO (input and output) when the SPIO module is loaded

    Notes: Also seems to work fine at 22.050kHz sample rates
    }


    Peter I'm not sure how to locate the Popcorn.wav file's virtual address on the SD card with ?
    Ahhh, that's a little trick as I either just write a little scan function or even XDUMP until I see the RIFF header. True. There is my FAT FS code I'm playing with but I need to polish it a bit more yet (when I get a "round tuit").

    Try this on a 2GB card as the only file (first off):

    4.0000 1.0000 XDUMP

    0004_C300: 41 50 00 4F 00 50 00 43 00 4F 00 0F 00 6E 52 00 AP.O.P.C.O...nR.
    0004_C310: 4E 00 2E 00 77 00 61 00 76 00 00 00 00 00 FF FF N...w.a.v.......
    0004_C320: 50 4F 50 43 4F 52 4E 20 57 41 56 20 00 00 8B 00 POPCORN WAV ....
    0004_C330: 68 41 68 41 00 00 41 BB 67 41 03 00 9A 79 31 00 hAhA..A.gA...y1.
    0004_C340: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

    5.8200 200 XDUMP
    0005_8300: 52 49 46 46 92 79 31 00 57 41 56 45 66 6D 74 20 RIFF.y1.WAVEfmt
    0005_8310: 10 00 00 00 01 00 01 00 11 2B 00 00 22 56 00 00 .........+.."V..
    0005_8320: 02 00 10 00 4C 49 53 54 28 00 00 00 49 4E 46 4F ....LIST(...INFO
    0005_8330: 49 4E 41 4D 08 00 00 00 50 6F 70 63 6F 72 6E 00 INAM....Popcorn.
    0005_8340: 49 41 52 54 0C 00 00 00 48 6F 74 20 42 75 74 74 IART....Hot Butt
    0005_8350: 65 72 00 00 64 61 74 61 3E 79 31 00 32 00 58 00 er..data>y1.2.X.
    0005_8360: 4D 00 53 00 4F 00 50 00 53 00 4E 00 53 00 4F 00 M.S.O.P.S.N.S.O.
    0005_8370: 50 00 53 00 4E 00 52 00 50 00 50 00 51 00 52 00 P.S.N.R.P.P.Q.R.

    Remember that XDUMP will skip blank sectors/blocks.
    Disregard the block address of 5_8300, it should be even at 5_8200 (I obviously have added a bug into XDUMP)
    $5.8200 #6332 #11,050 #P20 PLAY

    I have some rubbish problematic 2GB EBAY cards which do not always want to read the next block in time but all my other cards, even the old ones, are fine.


    EDIT: I've fixed the XDUMP bug by simply aligning the SD buffer. Try the code sample in the latter half of the source code document, it's only 76 bytes long. Here it is:
    [SIZE=1][FONT=courier new][/FONT][/SIZE][FONT=courier new]
    : GetSample ( -- sample )       
          -1 RUNMOD $FF AND -1 RUNMOD $80 + 8 SHL OR
          ;
    : WhenReady
          BEGIN -1 RUNMOD -1 <> UNTIL 
          ;
    : PLAY ( addr blocks rate pin -- )
          A DUTY APIN                              \ audio dac using counter A in duty mode to pin
          ROT #18 CMD DROP                         \ Issue a multiple block read command with addr
          [SPIO]                                   \ Switch to raw SPI mode
          WhenReady                                \ when SD card is ready
          CLKFREQ SWAP / DELTA                     \ set sample period from rate
          FOR                                      \ for multiple blocks - read samples and update dac counter
            #256 FOR                               \ 256 samples per 512 byte sector 
              GetSample                            \ Get a 16-bit biased sample from the SD card  
              #16 SHL WAITCNT FRQA COG!            \ left justify, synch, then update dac counter 
          NEXT                                   \ next sample
          GetSample DROP                         \ drop the CRC (treat as a sample)
            WhenReady                              \ wait for SD card ready
          NEXT                                     \ next block
          0 #12 CMD DROP                           \ STOP multiple block read
          ;[/FONT]
    [B][COLOR=#000000][FONT=Ubuntu Mono][/FONT][/COLOR][/B]
    
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2012-11-11 06:07
    Propeller.wikispaces.com is updating its listing and there is section for Forth on the Propeller. You might want to post an entry for Tachyon Forth.

    forums.parallax.com/showthread.php?143700-propeller.wikispaces.com-(fixed-and-open-for-business!)
  • D.PD.P Posts: 790
    edited 2012-11-11 12:10
    Ahhh, that's a little trick as I either just write a little scan function or even XDUMP until I see the RIFF header. True. There is my FAT FS code I'm playing with but I need to polish it a bit more yet (when I get a "round tuit").

    Try this on a 2GB card as the only file (first off):

    4.0000 1.0000 XDUMP

    0004_C300: 41 50 00 4F 00 50 00 43 00 4F 00 0F 00 6E 52 00 AP.O.P.C.O...nR.
    0004_C310: 4E 00 2E 00 77 00 61 00 76 00 00 00 00 00 FF FF N...w.a.v.......
    0004_C320: 50 4F 50 43 4F 52 4E 20 57 41 56 20 00 00 8B 00 POPCORN WAV ....
    0004_C330: 68 41 68 41 00 00 41 BB 67 41 03 00 9A 79 31 00 hAhA..A.gA...y1.
    0004_C340: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

    5.8200 200 XDUMP
    0005_8300: 52 49 46 46 92 79 31 00 57 41 56 45 66 6D 74 20 RIFF.y1.WAVEfmt
    0005_8310: 10 00 00 00 01 00 01 00 11 2B 00 00 22 56 00 00 .........+.."V..
    0005_8320: 02 00 10 00 4C 49 53 54 28 00 00 00 49 4E 46 4F ....LIST(...INFO
    0005_8330: 49 4E 41 4D 08 00 00 00 50 6F 70 63 6F 72 6E 00 INAM....Popcorn.
    0005_8340: 49 41 52 54 0C 00 00 00 48 6F 74 20 42 75 74 74 IART....Hot Butt
    0005_8350: 65 72 00 00 64 61 74 61 3E 79 31 00 32 00 58 00 er..data>y1.2.X.
    0005_8360: 4D 00 53 00 4F 00 50 00 53 00 4E 00 53 00 4F 00 M.S.O.P.S.N.S.O.
    0005_8370: 50 00 53 00 4E 00 52 00 50 00 50 00 51 00 52 00 P.S.N.R.P.P.Q.R.

    Remember that XDUMP will skip blank sectors/blocks.
    Disregard the block address of 5_8300, it should be even at 5_8200 (I obviously have added a bug into XDUMP)
    $5.8200 #6332 #11,050 #P20 PLAY

    I have some rubbish problematic 2GB EBAY cards which do not always want to read the next block in time but all my other cards, even the old ones, are fine.


    EDIT: I've fixed the XDUMP bug by simply aligning the SD buffer. Try the code sample in the latter half of the source code document, it's only 76 bytes long. Here it is:

    Well I did try XDUMP to locate the file before I submitted the last question. It seems all I get on my PNY 2gig disk is a repeating pattern being dumped by XDUMP. I have used SD-MMC_FATEngine.spin on this card/PBOE to make sure the file is readable and I can open and dump it this way as well, I'm just not familiar enough with this driver to find a raw virtual address for the file in question.

    EDIT
    I was able to dump the SD card using: (sudo dd if=/dev/disk1 of=~/Desktop/output.raw) and able to edit the file with OxED editor but unable to get the correct address I guess. I'm gonna wait for FAT FS to appear. No worries, I'll keep moving forward on other things.
    50 4F 50 43 4F 52 4E 2E 77 61 76 POPCORN.wav
    
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2012-11-11 14:23
    Did you initialize the SD card first? Use either !SD which returns a parameter or SD which lists the card.
    [FONT=courier new]SD 
    Card inserted 
    MFG:    02
    OEM:    TM
    PROD:   SD01G
    REV:    32
    S/N:    1BD7AA9B
    DATE:   2007/8
    CRC:    33
    
    TACC    500ns
    NSAC    0
    
    [/FONT]
    
  • D.PD.P Posts: 790
    edited 2012-11-11 18:31
    Did you initialize the SD card first? Use either !SD which returns a parameter or SD which lists the card.
    [FONT=courier new]SD 
    Card inserted 
    MFG:    02
    OEM:    TM
    PROD:   SD01G
    REV:    32
    S/N:    1BD7AA9B
    DATE:   2007/8
    CRC:    33
    
    TACC    500ns
    NSAC    0
    
    [/FONT]
    

    DOH, yes that would help quite a bit. My card says
    0004_C700: 50 4F 50 43 4F 52 4E 20 57 41 56 20 10 59 2A 81   POPCORN WAV .Y*.
    0004_C710: 6B 41 6B 41 00 00 A3 50 67 41 02 00 9A 79 31 00   kAkA...PgA...y1.
    
    5.0600 200 XDUMP
    0005_0700: 52 49 46 46 92 79 31 00 57 41 56 45 66 6D 74 20   RIFF.y1.WAVEfmt 
    0005_0710: 10 00 00 00 01 00 01 00 11 2B 00 00 22 56 00 00   .........+.."V..
    
    

    So the address is $5.0600, thanks for all the help. Tachyon is moving fast.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2012-11-12 18:38
    There is a neat little local variable function that I have added which is useful for reading stack parameters. At present they just have simple names such as X1 X2 X3 X4 corresponding to their position on the stack before they were pushed into a local variables area. Previous local variables are moved aside and restored automatically if the function uses the corresponding RELEASE word.

    Previously I had used an ITEMS word which simply grabbed the stack parameters and copied them into my general-purpose "register" area, but that was a bit limited. So this has been superseded with the LOCAL and RELEASE word.

    Here's how I use it when I draw a rectangle:
    [FONT=courier new]\ Draw a rectangle at x1 y1 
    pub RECT ( x1 y1 width height -- )
            ( X4 X3 X2    X1 )
        4 LOCAL
        X4 X3 X2 HLINE
        X4 X2 + X3 X1 VLINE
        X4 X3 X1 VLINE
        X4 X3 X1 + X2 HLINE
        4 RELEASE
        ;[/FONT]
    

    Here's how I will eventually use it when I draw a rectangle:
    [FONT=courier new]\ Draw a rectangle at x1 y1 
    pub RECT ( x1 y1 width height -- )
        4 LOCAL
        x1 y1 width HLINE
        x1 width + y1 height VLINE
        x1 y1 height VLINE
        x1 y1 height + width HLINE
        4 RELEASE
        ;[/FONT]
    
    I only want to use these locals as read only and do all the writing onto the stack so this is only for input parameters at present (where it's really needed).
  • MJBMJB Posts: 1,235
    edited 2012-11-13 04:36
    Peter: TACHYON 2.1
    xLOADMOD            jmp    #_LOADMOD
    
    ' 16 longs [B](or more)[/B] are reserved for a selectable module as a helper for specialized functions such as SPI etc.
    
    
    DAT
            org $[B]01D8 [/B]   ' fixed address - high-level code can always assume it is here
    xRUNMOD
    _RUNMOD        res [B]16[/B]
    
    
    you changed the starting address, but not the size ... I wondered what would be after ... but I assume it is just RUNMOD space. So it should be 24 now ??
    Of course makes no big problem here. Just for consistency.
    ... I do a compare, whenever you post a new version ;-.)
    so now my Sigma-Delta Module will fit more easily.
    MJB
  • Dave HeinDave Hein Posts: 6,347
    edited 2012-11-13 06:51
    Peter, the local variable feature looks good. One of the most frustrating things when programming with Forth is keeping track of the location of things on the stack. pick and roll are useful for accessing values if you know where they are, but local variables make it a lot easier.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2012-11-13 23:27
    Dave Hein wrote: »
    Peter, the local variable feature looks good. One of the most frustrating things when programming with Forth is keeping track of the location of things on the stack. pick and roll are useful for accessing values if you know where they are, but local variables make it a lot easier.

    So this may not be the final form, I've just fixed a couple of bugs in the code as well. I am looking at using the stack comment to automatically grab the parameters without having to explicitly say 4 LOCAL and 4 RELEASE for instance. So a modified stack comment could be LOCAL( x1 x2 xsize ysize -- ) which would grab the input parameters as local variables (essentially read-only). The exit would be flagged during compile to compile the release code before exit. Perhaps to cover an unstructured exit I could simply call the new word from a wrapper which worries about the LOCAL and RELEASE mechanisms.
  • MJBMJB Posts: 1,235
    edited 2012-11-14 05:45
    my understanding of the
    ITEMS word
    was, that you need to exactly know, what you do,
    since it uses the registers and those are not managed automatically. So using a function which used ITEMS inside another one which does the same could result in disaster.
    Previously I had used an ITEMS word which simply grabbed the stack parameters and copied them into my general-purpose "register" area, but that was a bit limited. So this has been superseded with the LOCAL and RELEASE word.
    with the LOCAL / RELEASE proposal you would need an additional LOCAL-Stack if those words using LOCAL / RELEASE should be nested - right?
    If there is a deep nesting this stack could quickly become quite deep.
    So the benefit of the COG register based ITEMS approach would suffer.
    As with data stack size this probably stongly depends on the usage 'habbits'.

    but: the idea using a modified stack comment word is great - and shows the benefits of FORTH, the extensibility of the language - WOW - Try to do this in C ;-) ...
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2012-11-14 06:21
    MJB wrote: »
    my understanding of the was, that you need to exactly know, what you do,
    since it uses the registers and those are not managed automatically. So using a function which used ITEMS inside another one which does the same could result in disaster.


    with the LOCAL / RELEASE proposal you would need an additional LOCAL-Stack if those words using LOCAL / RELEASE should be nested - right?
    If there is a deep nesting this stack could quickly become quite deep.
    So the benefit of the COG register based ITEMS approach would suffer.
    As with data stack size this probably stongly depends on the usage 'habbits'.

    but: the idea using a modified stack comment word is great - and shows the benefits of FORTH, the extensibility of the language - WOW - Try to do this in C ;-) ...

    The "registers" that ITEMS use are in hub RAM and accessed with the REG word as opposed to the COGREG word. The LOCAL variables have been implemented in hub RAM stack which is pushed and popped automatically using CMOVE and new <CMOVE instructions. So I've tested out the nesting to a few levels deep without any problems, I can make the locals stack as deep as I like if I need to.

    You may have noticed that I don't bother with PICK and ROLL instructions as I hate having to mangle the stack in this way, plus it's a headache. There are however the 3RD and 4TH words to directly copy those stack items but any further than 4 levels I try to avoid. The sooner I can implement the stack notation method for local variables, the better. Having them implicitly leave a value rather than having to use @ or anything is just sensible I think and leaving the output parameters as normal stack operations is just practical.

    I can't see a lot of these features being "standard" in any way but then neither is the Prop chip (what! no interrupts!, only 512 longs!!! useless chip I'd say). We nonetheless have fun and get stuff working at the same time.
  • MJBMJB Posts: 1,235
    edited 2012-11-14 07:03
    The "registers" that ITEMS use are in hub RAM and accessed with the REG word as opposed to the COGREG word. The LOCAL variables have been implemented in hub RAM stack which is pushed and popped automatically using CMOVE and new <CMOVE instructions. So I've tested out the nesting to a few levels deep without any problems, I can make the locals stack as deep as I like if I need to.
    arghh - of course you're right - my memory mixed TAKE4 with ITEMS - TAKE4 saves the 4 topmost stack items to COG registers, and ITEMS saves n stack items to HUB 'registers'.
    should verify before posting ...
    You may have noticed that I don't bother with PICK and ROLL instructions as I hate having to mangle the stack in this way, plus it's a headache.
    as a Forth newbie I couldn't agree more - even without those keeping track of stack is still the hardest part for me.
    There are however the 3RD and 4TH words to directly copy those stack items but any further than 4 levels I try to avoid. The sooner I can implement the stack notation method for local variables, the better. Having them implicitly leave a value rather than having to use @ or anything is just sensible I think and leaving the output parameters as normal stack operations is just practical.
    then it is not so much of whatever standard, but very intuitive and useful - especially for migrants from other languages
    For time critical code putting the LOCALS in HUB will cost some cycles - so the user can then decide NICE or FAST

    I am learning FORTH to program the PROP not for the language itself. So I don't need the ANS-Forth as discussed. My Prop-programs will never be ported to another controller - besides Prop2

    btw.
    Thinking about kernel optimization I was wondering how to get usage statistics for the byte codes to know which ones to put in first 256 longs, which in second 256 and which in HUB.
    Because lexical analysis would not really resemble the dynamic usage patterns.
    ' Fetch the next byte code instruction in hub RAM pointed to by the instruction pointer IP
    '
    doNEXT                  rdbyte  X,IP    'read byte code instruction
                            add     IP,#1   'advance IP to next byte token
                            jmp     X       'execute the code
    
    jmp     X
    
    could jump to high COG space
    for the COG-Kernel byte codes a separate HUB array of about 500 longs would hold the counters
    kind of
    kernelCtr X + C++
    
    in PASM

    and for the XCalls increment the high word in the XCALLS vectors (as long as those are not used yet) - and because of only 16bit this is only for short time measurements.
    Longer sample times would require longs to store the counters.
    xycall                  call    #SETUPIP        ' read offset in table
                            shl     X,#2    ' offset into longs in hub RAM
                            add     X,ACC
                            mov     ACC,#0  ' Always clear ACC to zero ready for reuse
                            rdword  IP,X
                            jmp     #doNEXT
    

    Then a simple DUMP would reveal the usage statistics.

    Of course this would slow down the code - so would only be implemented for performance optimization and not for production.

    This optimization might not be the most important right now - just wanted to share my thought.
  • Dave HeinDave Hein Posts: 6,347
    edited 2012-11-14 08:19
    I've found that one of the biggest time wasters with programming in Forth is trying to keep track of where things are in the stack. I have to scribble notes on paper to list the state of the stack as I progress through a word. Then I have to add a rot, over and sometimes a dup if I need to keep the original value. Occasionally I use pick or roll if the value I need is deeper than 3 entries in the stack. pick is also nice if you need to do an indexed selection from the stack. It's the only way I could figure out how to implement a "jump on zero" word without having an existing conditional jump word.

    Most other languages do all this book keeping for you, so you don't have to worry about the stack. I think using local variables in Forth, whether they are on the stack or in registers, is a great improvement.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2012-11-14 15:37
    MJB wrote: »
    then it is not so much of whatever standard, but very intuitive and useful - especially for migrants from other languages
    For time critical code putting the LOCALS in HUB will cost some cycles - so the user can then decide NICE or FAST
    Functions that require locals will not be impacted greatly by this speed reduction as there are other overheads anyway. In the case of the RECT word it spends a lot of time plotting and sending via SPI so using locals makes no discernible difference. So NICE *and* just as FAST.
    I am learning FORTH to program the PROP not for the language itself. So I don't need the ANS-Forth as discussed. My Prop-programs will never be ported to another controller - besides Prop2

    btw.
    Thinking about kernel optimization <snip>

    I notice what seems to be a contradiction here......? :)

    My optimizations are mostly intuitive and I especially target those words that are involved in loops and the loop words themselves. The other thing is that the Prop is very effective at being used for a lot of I/O bit-bashing rather than having specialized peripherals that might not do exactly what you want, hence it's flexibility. This however requires that Forth prove itself fast and efficient in this regard otherwise you end up programming in a mangled form of PASM to supplement Forth or not being able to do it at all. There is no practical gain in following a standard if it proves ineffective in operation and especially is this true in regards to embedded control in conjunction with the Propeller. The standard might be very effective when implemented in 90% of processors but a different standard might be required for the Propeller. If someone wants to be really standard, then don't use a very non-standard Propeller chip.
  • MJBMJB Posts: 1,235
    edited 2012-11-15 05:07
    Functions that require locals will not be impacted greatly by this speed reduction as there are other overheads anyway. In the case of the RECT word it spends a lot of time plotting and sending via SPI so using locals makes no discernible difference. So NICE *and* just as FAST.
    ok - in this case LOCALS will not be the bottleneck - and in many other cases it does not matter as well.
    I notice what seems to be a contradiction here......? :)
    - sorry maybe I was unclear - I was referring to the other threads about ANS compliant Forth's on the Prop.
    I think we are in agreement on this topic. better fast, focused on the job and easily adaptable - then necessarily compliant to some standard, that originated from different requirements.
    Kernel optimization
    when I find time, maybe I do the statistics as an exercise ...
  • Dave HeinDave Hein Posts: 6,347
    edited 2012-11-15 05:16
    ANS Forth compliance is not an either or thing. You can be standard's compliant and be fast. In the case of Tachyon, it could just continue to support the current word set plus any ANS core words that it's missing. I'm not saying that Tachyon needs to do this, but I am suggesting that it's possible.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2012-11-15 05:36
    Dave Hein wrote: »
    ANS Forth compliance is not an either or thing. You can be standard's compliant and be fast. In the case of Tachyon, it could just continue to support the current word set plus any ANS core words that it's missing. I'm not saying that Tachyon needs to do this, but I am suggesting that it's possible.

    I've looked at ANS many times before and even when it was do'able I still didn't choose to follow it. Now because of the way I have had to structure Tachyon in that it had to be custom carved for a good fit both for the Propeller and the Spin tool, I find there are a lot of redundancies in trying to implement ANS. For starters, I've got 4 stacks, not two, I've got a 12 word deep parameter stack, not 1200, plus I don't have a stack pointer. I could continue with a whole list of things but suffice to say I don't intend to cripple it just to make it standard because it would be useless for me. I wrote Tachyon because I had to and it has met the needs I have for my systems. On P2 I may do something different and maybe even more standard but I can't afford to do the same with the way P1 works.

    Now, I am quite happy for you to develop ANS Forth and you have all my source and documentation at your fingertips if you want to avail yourself of any features and we're all Prophead buddies anyway. What I'd like to see though is ANS Forth out on the track to see how it performs. Maybe then I will sit up and take notice.
  • Dave HeinDave Hein Posts: 6,347
    edited 2012-11-15 07:08
    I've been working on a smaller kernel for pfth that implements about 50 basic words so it will fit in a cog. It implements an additional 100 ANS Forth words by loading an external Forth program. In theory, the ANS word program can be loaded on any Forth kernel with some modifications. I'll post it in the pfth thread in the next few days.

    For me the only way to really learn Forth is to implement a Forth interpreter. I've learned quite a bit by just trying to implement basic ANS words in Forth, such as does>, literal and .
  • mindrobotsmindrobots Posts: 6,506
    edited 2012-11-27 11:19
    I'm feeling a bit silly about this question but after playing with Tachyon for a good part of the day and reading this thread and looking at the code, I'm thinking it's a bit like my wife! (It's an endearing quality, I assure you!)

    Does Tachyon ever FORGET? I can't find a way to FORGET my definitions (remove them from the dictionary in some way) without doing REBOOT. Am I missing something?
  • prof_brainoprof_braino Posts: 4,313
    edited 2012-11-27 12:49
    mindrobots wrote: »
    I'm feeling a bit silly about this question but after playing with Tachyon for a good part of the day and reading this thread and looking at the code, I'm thinking it's a bit like my wife! (It's an endearing quality, I assure you!)

    Does Tachyon ever FORGET? I can't find a way to FORGET my definitions (remove them from the dictionary in some way) without doing REBOOT. Am I missing something?

    Let me guess - Is your wife Karen, the same Karen that was Plankton's wife on Sponge Bob?

    http://spongebob.wikia.com/wiki/Karen
Sign In or Register to comment.