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

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

13839414344109

Comments

  • artkennedyartkennedy Posts: 174
    edited 2014-02-17 14:28
    In attempting to understand some of the words in Tachyon I have opened Tachyon V2.3.spin and the extension files looking for clues. When I do I often get a warning "Not all unicode characters could be converted to ASCII". My favorite editor is The Semware Editor - known as QEdit with I first started using it. I have also noticed some characters that the editor displays as upper 128 code ASCII. I have also looked at the file in WordPad and seen those upper characters. Am I endangering the contents of those files if I have to save, for instance if I must customize a parameter? What would be a better editor to use? I luv my TSE.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-17 15:15
    artkennedy wrote: »
    In attempting to understand some of the words in Tachyon I have opened Tachyon V2.3.spin and the extension files looking for clues. When I do I often get a warning "Not all unicode characters could be converted to ASCII". My favorite editor is The Semware Editor - known as QEdit with I first started using it. I have also noticed some characters that the editor displays as upper 128 code ASCII. I have also looked at the file in WordPad and seen those upper characters. Am I endangering the contents of those files if I have to save, for instance if I must customize a parameter? What would be a better editor to use? I luv my TSE.

    That's a new one on me, I've never seen or had any problems with text editors, I have plenty to choose from in Linux where I mainly use medit but on Windows I have used Context with a Forth highlighter, both of which you will find in the Tachyon dropbox folder (see my sigs) under PC utilities. When you mentioned QEdit it brought back images of the clunky old DOS days!!! As long as a text editor can open a file I'm happy, if it has sensible shortcut keys, I'm happy. If it has highlighting, I'm happy. Sure there are other things to look for but that's a start, otherwise I don't really have a favorite.
  • D.PD.P Posts: 790
    edited 2014-02-17 16:55
    Output of strings over serial in tasks? Can you point out the bugz, wyht (when you have time)
    Not sure what I can and can't do here re strings, the other parts work as expected

    Thanks
    " THE 1st STRING" $10 STRING A$  
    : STROUT ( str -- ) DUP LEN$ ADO I C@ 9 SEROUT LOOP ;
    
    : MYTASK  
      9600d SERBAUD
      " THE 2nd STRING" $10 STRING B$ 
      #12 9 SEROUT     \ clr lcd
      #17 9 SEROUT    \ turn on bl
      #100 ms 
      $3A $30 DO I 9 SEROUT LOOP $47 $41 DO I 9 SEROUT LOOP    \ output 0-1A-F
      #2000 ms 
      A$ STROUT     \ no joy
      #2000 ms
      B$ STROUT    \ not this way either
      #1000 ms
      #12 9 SEROUT   
      #18 9 SEROUT 
    ;  
    
    
  • D.PD.P Posts: 790
    edited 2014-02-17 17:04
    @MAX72
    Tracy Allen made an integer only version of the sensirion (in spin). Maybe you can check it.

    The application is a far end (90 - 100%) RH sensor in a condensing, dirty environment and sensirion, honeywell .... just can't handle the abuse. These "membrane" sensors have extremely poor resolution at the high end, not to mention drift and downright failure. Thus I must use the Saturation VP to get the best resolution via wet/dry bulb temps and ambient pressure. Tracy knows about this application and its issues.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-17 17:19
    D.P wrote: »
    Output of strings over serial in tasks? Can you point out the bugz, wyht (when you have time)
    Not sure what I can and can't do here re strings, the other parts work as expected

    Thanks

    This is exactly why we have character I/O redirection for EMIT and KEY, so that we don't have to have special routines for all these displays etc.
    Here's the code using redirection and also the STRING word is a defining word, you don't use it inside another definition, that was your main problem. Otherwise you can just use a literal string inside the definition without defining it.
    [FONT=courier new]\ Define the emit word for this output
    : LCDEMIT        9 SEROUT ;
    : LCD        ' LCDEMIT uemit W! ;
      " THE 2nd STRING" 0 STRING B$ 
      " HOW IS LONG IS" 0 STRING A$
    : MYTASK  
      9600d SERBAUD
      LCD
      CLS     \ clr lcd
      #17 EMIT    \ turn on bl
      #100 ms 
      "0" #10 ADO I EMIT LOOP   "A" 6 ADO I EMIT LOOP    \ output 0-1A-F
      2 seconds 
      A$ PRINT$
      2 seconds
      B$ PRINT$
      1 second
      " any old string" PRINT$
      1 second
      CR PRINT" That's all folks!"
      1 second
      CLS
      #18 EMIT
      CON
    ;
    
    [/FONT]
    

    EDIT: I've added a couple of lines showing a literal string and what I normally do, just print what I want to say. Notice that there are PRINT aliases for many normal Forth words, so PRINT is the "dot" word, and PRINT$ is TYPE$ and PRINT" is ." as I find that the . itself barely stands out in forums and on documents so I chose PRINT as that is instantly recognizable to anyone.
  • D.PD.P Posts: 790
    edited 2014-02-17 19:37
    This is exactly why we have character I/O redirection for EMIT and KEY, so that we don't have to have special routines for all these displays etc.
    Here's the code using redirection and also the STRING word is a defining word, you don't use it inside another definition, that was your main problem. Otherwise you can just use a literal string inside the definition without defining it.
    [FONT=courier new]\ Define the emit word for this output
    : LCDEMIT        9 SEROUT ;
    : LCD        ' LCDEMIT uemit W! ;
      " THE 2nd STRING" 0 STRING B$ 
      " HOW IS LONG IS" 0 STRING A$
    : MYTASK  
      9600d SERBAUD
      LCD
      CLS     \ clr lcd
      #17 EMIT    \ turn on bl
      #100 ms 
      "0" #10 ADO I EMIT LOOP   "A" 6 ADO I EMIT LOOP    \ output 0-1A-F
      2 seconds 
      A$ PRINT$
      2 seconds
      B$ PRINT$
      1 second
      " any old string" PRINT$
      1 second
      CR PRINT" That's all folks!"
      1 second
      CLS
      #18 EMIT
      CON
    ;
    
    [/FONT]
    

    EDIT: I've added a couple of lines showing a literal string and what I normally do, just print what I want to say. Notice that there are PRINT aliases for many normal Forth words, so PRINT is the "dot" word, and PRINT$ is TYPE$ and PRINT" is ." as I find that the . itself barely stands out in forums and on documents so I chose PRINT as that is instantly recognizable to anyone.

    Maybe I didn't explain myself well.

    ' MYTASK 4 RUN \ trying to run this in a task, guess I shouldn't have left out that info. This is why I took the approach I did, I do realize all the aliases that have been created.

    Update: everything runs but the string values.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-17 22:05
    D.P wrote: »
    Maybe I didn't explain myself well.

    ' MYTASK 4 RUN \ trying to run this in a task, guess I shouldn't have left out that info. This is why I took the approach I did, I do realize all the aliases that have been created.

    Update: everything runs but the string values.

    If you disable the LCD word in MYTASK it emits to the console which I checked a couple of different ways, it all works, the strings print etc. It doesn't matter that it runs in another task either except you need to allocate a data stack for it these days as the cog only has a depth of 4 levels and the rest is external. Here's an example of starting up a task to do nothing more than buffer some RS232 data. You can follow the way it creates a datastack and assigns that memory to the cog task.
    [FONT=courier new]TABLE stack232     $40 ALLOT
    TABLE buf232    $80 ALLOT
    BYTE rxrd,rxwr
    LONG logrcd
    
    \ Buffer data from the RS232 port - nothing else
    pub RS232_TASK
        stack232 SP! !SP        \ Set the stack pointer for this cog and make sure it's initalized (optional)
        logbaud @ SERBAUD
        DTR232 PINSET
        RTS232 PINSET
        TXD232 PINSET
        rxrd C~ rxwr C~ buf232 $80 ERASE 
        BEGIN 
          logport C@ SERIN 
          rxwr C@ $7F AND buf232 + C! 
          rxwr C++ 
        AGAIN  
        ;[/FONT]
    

    So when you are debugging stuff like your code always try to run it in the main console cog first and even direct output back to the console too. Then try the redirect to the LCD, and then finally as a task when you know everything else is working fine.
  • artkennedyartkennedy Posts: 174
    edited 2014-02-17 22:15
    I am finding these references to aliases confusing. The only PRINT I am finding in the WORDS list is PRINT" and yet in the code you post you use PRINT" and refer to PRINT as an alias for the dot word. By this do you mean that using PRINT" instead of ." is just for clarity when communicating about code rather than writing code for execution?

    Geez. I getting all muddled up just trying to ask the question.
  • D.PD.P Posts: 790
    edited 2014-02-17 22:37
    If you disable the LCD word in MYTASK it emits to the console which I checked a couple of different ways, it all works, the strings print etc. It doesn't matter that it runs in another task either except you need to allocate a data stack for it these days as the cog only has a depth of 4 levels and the rest is external. Here's an example of starting up a task to do nothing more than buffer some RS232 data. You can follow the way it creates a datastack and assigns that memory to the cog task.
    [FONT=courier new]TABLE stack232     $40 ALLOT
    TABLE buf232    $80 ALLOT
    BYTE rxrd,rxwr
    LONG logrcd
    
    \ Buffer data from the RS232 port - nothing else
    pub RS232_TASK
        stack232 SP! !SP        \ Set the stack pointer for this cog and make sure it's initalized (optional)
        logbaud @ SERBAUD
        DTR232 PINSET
        RTS232 PINSET
        TXD232 PINSET
        rxrd C~ rxwr C~ buf232 $80 ERASE 
        BEGIN 
          logport C@ SERIN 
          rxwr C@ $7F AND buf232 + C! 
          rxwr C++ 
        AGAIN  
        ;[/FONT]
    

    So when you are debugging stuff like your code always try to run it in the main console cog first and even direct output back to the console too. Then try the redirect to the LCD, and then finally as a task when you know everything else is working fine.

    ACKnowledged, understood, thanks.
  • artkennedyartkennedy Posts: 174
    edited 2014-02-17 23:37
    What is the meaning of "pub", "pri", and "code" within the Tachyon context? Of course I know that it is "public", "private" and so on but what are the implications for the use of those words?
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-17 23:56
    artkennedy wrote: »
    I am finding these references to aliases confusing. The only PRINT I am finding in the WORDS list is PRINT" and yet in the code you post you use PRINT" and refer to PRINT as an alias for the dot word. By this do you mean that using PRINT" instead of ." is just for clarity when communicating about code rather than writing code for execution?

    Geez. I getting all muddled up just trying to ask the question.

    The aliases are actually meant to make it clearer, not get you muddled!!! Just make sure you have the latest kernels compiled, the aliases are something I've added recently. As I mentioned the reason I have done so is because the dot symbol is hard to see in a lot of documents but PRINT punches you in the face and is well recognized.
    [FONT=courier new]standard       -- alias
    .              -- PRINT
    ."             -- PRINT"
    TYPE$          -- PRINT$[/FONT]
    
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-18 00:23
    artkennedy wrote: »
    What is the meaning of "pub", "pri", and "code" within the Tachyon context? Of course I know that it is "public", "private" and so on but what are the implications for the use of those words?

    The colon word is the normal Forth defining word and pub and pri do the same thing except that pri sets a private bit in the attribute flags of the header. This does nothing normally but when I run RECLAIM it scans for any names that have the private attribute and strips them from the dictionary thus saving both precious memory and also preventing the misuse of these words normally. So pub is exactly the same as the colon but the other reason I use pub and pri is simply to make it easier to see in documents, much like the PRINT word does and also to make it recognizable to anyone who has programmed in Spin as that is the "native HLL language" of the Prop.

    The "code" tag only shows up when you do a WORDS listing to identify what type of word it is.
  • artkennedyartkennedy Posts: 174
    edited 2014-02-18 01:44
    What is the difference between BEGIN . . . UNTIL and BEGIN . . . REPEAT ?
  • artkennedyartkennedy Posts: 174
    edited 2014-02-18 01:50
    If the data stack can exceed 4 levels by overflowing into hub memory how can you determine the size of the stack? DROP does decrease the size of the stack doesn't it?
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-18 03:53
    artkennedy wrote: »
    If the data stack can exceed 4 levels by overflowing into hub memory how can you determine the size of the stack? DROP does decrease the size of the stack doesn't it?
    What is the difference between BEGIN . . . UNTIL and BEGIN . . . REPEAT ?

    I don't (cog-wise) waste time trying to determine if the stack is greater then 4 levels deep, it always overflows into hub RAM even if there is only one item, so the depth is determined from the stack write index. Before when I had a 12 level deep cog RAM stack all the pushing and popping was done by moving memory and there was no depth pointer. So interestingly the change to a hybrid stack hasn't actually slowed anything down as the time lost to hub access is made up for the time gained from not moving 8 cog locations. So DROP will continue to drop until the stack is empty but will stop there, the DEPTH word will tell you how deep the stack is.

    As for BEGIN UNTIL vs BEGIN REPEAT, that's really BEGIN WHILE REPEAT and although I would have preferred to say BEGIN WHILE AGAIN in keeping with the simpler BEGIN AGAIN construct, it is however been a standard to use REPEAT to match up with a WHILE. So BEGIN AGAIN is a forever loop typically used in a task, BEGIN UNTIL for a conditional exit from the loop, BEGIN WHILE REPEAT for an infinite loop (REPEAT == AGAIN) except the WHILE determines what it will do and for how long. i.e. BEGIN ANY_DATA? WHILE PROCESS_DATA REPEAT
  • richaj45richaj45 Posts: 179
    edited 2014-02-18 09:22
    @Peter

    Looking through the v2.3 code i see a "+s" in many places being added to a label.

    I did not notice were it was defined so what is that offset and why is it there?

    Thanks for the education.
    rich
  • D.PD.P Posts: 790
    edited 2014-02-18 09:48
    \ Here is an extremely basic Inter Task Communication example, not optimized, I didn't know if it should go into the intro doc or not.
    It uses BEGIN AGAIN to run the TASK continuously.
    WORD  BLINKRUN                 \ global variable to save the state of the blinky task
    
    #13 MASK CONSTANT RDYLED       \ define a constant mask for the led pin, define your pin
    
    : BLINKY 
        BEGIN
          ATN@ DUP 0= 
          IF DROP                 \ no command, drop the 0 returned by ATN@ and continue
            BLINKRUN W@           \ read the global variable to see what we need to do 
            IF              
              RDYLED OUTSET 100d ms RDYLED OUTCLR 100d ms \ it was ON we are running blink
            ELSE
              RDYLED OUTSET         \ else it was OFF just set the led on
            THEN
          ELSE              \ got a command let's check it
            DUP #33 =       \ dup it and check it against #33 our blink on command
            IF      
              #33 ENQ!            \ send the command back to the task that called us  
              ON BLINKRUN W!      \ set the global variable state
            THEN
            #66 =                 \ check it against #66, use last stack item, stack clean
            IF                    \ if so set blink off 
              #66 ENQ!            \ echo back the command again
              OFF BLINKRUN W!     \ set the global variabl state
            THEN
          THEN
        AGAIN                     \ do it forever
    
       ;
    
    : BLKYINIT ' BLINKY 4 RUN     \ start the BLINKY Task in COG 4  and start blinking
                  #33 4 ATN! 
    ;
    
    : BLKYSTOP #66 4 ATN! 100 ms 4 ENQ@ . ;  \ send stop command,read response
    : BLKYSTART #33 4 ATN! 100 ms 4 ENQ@ . ;  \ send start command, read response
    
    \   USAGE
    {
    DECIMAL  ok
    BLKYINIT  ok
    BLKYSTOP   66 ok
    BLKYSTART 33 ok
    BLKYSTOP    66 ok
    }
    
  • artkennedyartkennedy Posts: 174
    edited 2014-02-18 13:23
    I don't (cog-wise) waste time trying to determine if the stack is greater then 4 levels deep, it always overflows into hub RAM even if there is only one item, so the depth is determined from the stack write index. Before when I had a 12 level deep cog RAM stack all the pushing and popping was done by moving memory and there was no depth pointer. So interestingly the change to a hybrid stack hasn't actually slowed anything down as the time lost to hub access is made up for the time gained from not moving 8 cog locations. So DROP will continue to drop until the stack is empty but will stop there, the DEPTH word will tell you how deep the stack is.

    As for BEGIN UNTIL vs BEGIN REPEAT, that's really BEGIN WHILE REPEAT and although I would have preferred to say BEGIN WHILE AGAIN in keeping with the simpler BEGIN AGAIN construct, it is however been a standard to use REPEAT to match up with a WHILE. So BEGIN AGAIN is a forever loop typically used in a task, BEGIN UNTIL for a conditional exit from the loop, BEGIN WHILE REPEAT for an infinite loop (REPEAT == AGAIN) except the WHILE determines what it will do and for how long. i.e. BEGIN ANY_DATA? WHILE PROCESS_DATA REPEAT

    Thanks, Peter. I guess I should have searched for DEPTH in the word list. That's a no brainer - same as the hp calculators I love. I'm trying to research this stuff myself as much as possible because I know that is the best way to learn but there is an awful lot and sometimes nothing in the Intro to go on. I have "Starting Forth" standing by, the word list captured from Tachyon, and the source files and extensions. I try to check those before I post.
  • artkennedyartkennedy Posts: 174
    edited 2014-02-18 13:38
    Cool. Tried it out instead of colon - it works. Knowing this will make the kernel source more understandable.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-18 14:40
    richaj45 wrote: »
    @Peter

    Looking through the v2.3 code i see a "+s" in many places being added to a label.

    I did not notice were it was defined so what is that offset and why is it there?

    Thanks for the education.
    rich
    That's the old header offset that's needed as the Spin compiler (we really only compile PASM) generates absolute addresses offset by $10 as the first 16 bytes of memory hold the clock freqency, code and stack initialization parameters etc. So any PASM source needs to add this offset if it wants the real absolute memory address.

    The "s" is a lot less distracting than $10 or the like, it is defined just before the cog VM kernel about 75% through the source:
    [FONT=courier new]                       org        $10[/FONT][FONT=courier new]
    [/FONT]
    [FONT=courier new]s                        ' just an offset to be used in DAT sections rather than the distracting +$10[/FONT]
    
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-18 14:50
    D.P wrote: »
    \ Here is an extremely basic Inter Task Communication example, not optimized, I didn't know if it should go into the intro doc or not.
    It uses BEGIN AGAIN to run the TASK continuously.

    Didn't I give you edit rights to that document? You just have to start exercising that great responsibility now! :)
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-18 14:55
    artkennedy wrote: »
    Thanks, Peter. I guess I should have searched for DEPTH in the word list. That's a no brainer - same as the hp calculators I love. I'm trying to research this stuff myself as much as possible because I know that is the best way to learn but there is an awful lot and sometimes nothing in the Intro to go on. I have "Starting Forth" standing by, the word list captured from Tachyon, and the source files and extensions. I try to check those before I post.
    Bearing in mind that the Introduction to Tachyon Forth is not really an Introduction to Forth in general please feel free to make suggestions, even compiling the suggestions into a list and posting these. If some of the suggestions are more general to Forth in nature and too wordy to include then I may just link to that material instead.

    In addition to the Intro page Tachyon also needs a reference manual I guess but the reason that I haven't done one is that it is a lot of work and also the source code documents are readily available and formatted with some usage examples etc.
  • richaj45richaj45 Posts: 179
    edited 2014-02-18 15:03
    Thanks Peter on the "s" info. I would not have figured that out.

    BTW what do mean by old header. Is there a newer file i should be studying?

    cheers,
    rich
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-18 15:49
    richaj45 wrote: »
    Thanks Peter on the "s" info. I would not have figured that out.

    BTW what do mean by old header. Is there a newer file i should be studying?

    cheers,
    rich

    old as in "ole familiar" header :)

    The offset gets used in Tachyon when it needs to know the absolute address at compile time (it's a compiler work-around). Here the vector table needs to have the absolute address compiled so that at runtime it can just load the address from the table. The Spin operator @ returns with the address and the +s adds in the extra 16 bytes.
    [FONT=courier new]xFILL                long @FILL+s[/FONT]
    [FONT=courier new]xERASE               long @ERASE+s[/FONT]
    
  • D.PD.P Posts: 790
    edited 2014-02-18 17:33
    Okay so I am able to start tasks with there own stack as you demonstrated in the RS232 snipet.

    The serial task that outputs to a LCD works correctly now.

    Something I'm not understanding about uemit and ukey though.

    The LCD serial task starts and continously loops through the messages but the console keyboard input is vectored to the LCD
    ,which cause the LCD to freeze, and does not remain in the console. Issuing a CON gets the keyboard back but now the system is unstable and requires a reboot.

    I thought that "calling" LCD from within the task would not vector the console's keyboard input to the LCD
    : LCDEMIT        9 SEROUT ;             \ define emit word for this output
    : LCD        ' LCDEMIT uemit W! ;       \ vector it to uemit
    

    Obviously it's my lack of understanding of uemit and ukey in tasks.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-18 18:04
    D.P wrote: »
    Okay so I am able to start tasks with there own stack as you demonstrated in the RS232 snipet.

    The serial task that outputs to a LCD works correctly now.

    Something I'm not understanding about uemit and ukey though.

    The LCD serial task starts and continously loops through the messages but the console keyboard input is vectored to the LCD
    ,which cause the LCD to freeze, and does not remain in the console. Issuing a CON gets the keyboard back but now the system is unstable and requires a reboot.

    I thought that "calling" LCD from within the task would not vector the console's keyboard input to the LCD
    : LCDEMIT        9 SEROUT ;             \ define emit word for this output
    : LCD        ' LCDEMIT uemit W! ;       \ vector it to uemit
    

    Obviously it's my lack of understanding of uemit and ukey in tasks.

    Okay, as you can see from the code the only vector that was changed was the emit vector, not the key vector, so the LCD word only redirects output. What also happens though is that your task may use other common areas however what you can do is allocate memory for the Forth task variables or what I call registers. Each TF cog can point to it's own set of registers if it wants and the registers are so structured that you don't have to implement them all, the basic ones to do with redirection and number base etc are near the start of the register memory. Here is a snippet from the source:
    [B][B][COLOR=#999999][FONT=Arial][B]{[/B][/FONT][/COLOR][COLOR=#000000][FONT=Arial][B]TASK REGISTERS[/B][/FONT][/COLOR][COLOR=#999999][FONT=Arial][B]}[/B][/FONT][/COLOR][/B]
    
    [COLOR=#020FC0][FONT=Ubuntu Mono]' Task registers can be switched easily by setting "regptr" ( 7 COGREG! )[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]' New tasks may only need room for the first 32 or 72 bytes[/FONT][/COLOR]
    
    
    [COLOR=#020FC0][FONT=Ubuntu Mono]registers        long 0[64]        'Variables used by kernel + general-purpose[/FONT][/COLOR]
    
    [COLOR=#000000][FONT=Ubuntu Mono]    org  0[/FONT][/COLOR]
    [COLOR=#000000][FONT=Ubuntu Mono]' register offsets within "registers". Access as    REG,delim   ...  REG,base ... etc[/FONT][/COLOR]
    [COLOR=#000000][FONT=Ubuntu Mono]'[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]' Minimum registers required for a new task - other registers after the ' ---- are not needed other than by the console[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]temp        res 12    ' general purpose[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]cntr        res 4    ' hold CNT or temp[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]' @16[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]uemit        res 2[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]ukey        res 2[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]keypoll        res 2    ' poll user routines - low priority background task[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]unum        res 2    ' User number processing routine - executed if number failed and UNUM <> 0[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]baudcnt        res 4    ' baud cnt value where baud = clkfreq/baudcnt[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]uswitch        res 4    ' target parameter used in CASE structures[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]' @32[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]padwr        res 1        ' write index (builds characters down from lsb to msb in MODULO style)[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]numpad        res numpadsz    ' Number print format routines assemble digit characters here[/FONT][/COLOR]
    
    [/B]
    

    Notice there are 16 bytes reserved for temp and cntr and then you have uemit and ukey so you can allocate just the memory you need. I also notice that I could still rearrange some of the other registers to move closer to the start, including base etc. To set a new register base there is the TASKREGS word in EXTEND which just performs a 7 COGREG!.
  • Brian RileyBrian Riley Posts: 626
    edited 2014-02-18 18:21
    I tried some older code on the latest Dropbox (Tachyon 2.3.spin plus EXTEND and followed the "8 bit PWM" commentary and this is what happened ... every time

    [code]

    Propeller .:.:--TACHYON--:.:. Forth V23140216.1600

    NAMES: $5E70...74EF for 5759 (3245 bytes added)
    CODE: $0000...3101 for 6786 (6401 bytes added)
    CALLS: 0500 vectors free
    RAM: 11631 bytes free

    AUTORUN EXTEND.boot
    MODULES LOADED:
    1800: EXTEND.fth Primary extensions to TACHYON kernel - 140216-1400

    ok
    TABLE pwm #256 ALLOT ok
    #1000 PWMFREQ ok
    0 8 RUNPWM ok
    Ŀ --> <-- NOT FOUND
  • D.PD.P Posts: 790
    edited 2014-02-18 18:23
    Okay, as you can see from the code the only vector that was changed was the emit vector, not the key vector, so the LCD word only redirects output. What also happens though is that your task may use other common areas however what you can do is allocate memory for the Forth task variables or what I call registers. Each TF cog can point to it's own set of registers if it wants and the registers are so structured that you don't have to implement them all, the basic ones to do with redirection and number base etc are near the start of the register memory. Here is a snippet from the source:
    [B][B][COLOR=#999999][FONT=Arial][B]{[/B][/FONT][/COLOR][COLOR=#000000][FONT=Arial][B]TASK REGISTERS[/B][/FONT][/COLOR][COLOR=#999999][FONT=Arial][B]}[/B][/FONT][/COLOR][/B]
    
    [COLOR=#020FC0][FONT=Ubuntu Mono]' Task registers can be switched easily by setting "regptr" ( 7 COGREG! )[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]' New tasks may only need room for the first 32 or 72 bytes[/FONT][/COLOR]
    
    
    [COLOR=#020FC0][FONT=Ubuntu Mono]registers        long 0[64]        'Variables used by kernel + general-purpose[/FONT][/COLOR]
    
    [COLOR=#000000][FONT=Ubuntu Mono]    org  0[/FONT][/COLOR]
    [COLOR=#000000][FONT=Ubuntu Mono]' register offsets within "registers". Access as    REG,delim   ...  REG,base ... etc[/FONT][/COLOR]
    [COLOR=#000000][FONT=Ubuntu Mono]'[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]' Minimum registers required for a new task - other registers after the ' ---- are not needed other than by the console[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]temp        res 12    ' general purpose[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]cntr        res 4    ' hold CNT or temp[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]' @16[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]uemit        res 2[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]ukey        res 2[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]keypoll        res 2    ' poll user routines - low priority background task[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]unum        res 2    ' User number processing routine - executed if number failed and UNUM <> 0[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]baudcnt        res 4    ' baud cnt value where baud = clkfreq/baudcnt[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]uswitch        res 4    ' target parameter used in CASE structures[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]' @32[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]padwr        res 1        ' write index (builds characters down from lsb to msb in MODULO style)[/FONT][/COLOR]
    [COLOR=#020FC0][FONT=Ubuntu Mono]numpad        res numpadsz    ' Number print format routines assemble digit characters here[/FONT][/COLOR]
    
    [/B]
    

    Notice there are 16 bytes reserved for temp and cntr and then you have uemit and ukey so you can allocate just the memory you need. I also notice that I could still rearrange some of the other registers to move closer to the start, including base etc. To set a new register base there is the TASKREGS word in EXTEND which just performs a 7 COGREG!.

    So how to structure this code with TASKREGS then?
    TABLE stacktsk     $40 ALLOT
    
    : LCDEMIT        9 SEROUT ;             \ define emit word for this output
    : LCD        ' LCDEMIT uemit W! ;       \ vector it to uemit
      " THE 2nd STRING" 0 STRING B$         \ tachyon string variable
      " HOW IS LONG IS" 0 STRING A$
    
    : MYTASK             \ task to demonstrate  LCD output 
      \  TASKREGS       \ what is it about this I don't understand,   need to allocate space for these I guess
      stacktsk SP! !SP   \ assign this task a local stack and initialize to a depth of 0
      9600d SERBAUD      \ set this task's BAUD
      LCD                \ re-vector output          
      BEGIN
        CLS              \ clr lcd
        #17 EMIT         \ turn on bl
        #100 ms 
        "0" #10 ADO I EMIT LOOP   "A" 6 ADO I EMIT LOOP    \ output 0-1A-F
        2 seconds 
        A$ PRINT$
        2 seconds
        CLS
        B$ PRINT$
        2 second
        CLS
        " any old string" PRINT$
        1 second
        CLS
        CR PRINT" That's all folks!"
        1 second
        CLS
        #18 EMIT      \ turn off bl
       1 second
      AGAIN
    ;
    
    
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-18 18:43
    D.P wrote: »
    So how to structure this code with TASKREGS then?

    I was going to leave that exercise to you :) but I have included the extra line or two to show you what I would do in this circumstance.
    TABLE regs1         $20 ALLOT           \ some room for temp register + uemit and ukey
    TABLE stacktsk     $40 ALLOT
    
    : LCDEMIT        9 SEROUT ;             \ define emit word for this output
    : LCD        ' LCDEMIT uemit W! ;       \ vector it to uemit
      " THE 2nd STRING" 0 STRING B$         \ tachyon string variable
      " HOW IS LONG IS" 0 STRING A$
    
    : MYTASK             \ task to demonstrate  LCD output 
      regs1  TASKREGS       \  <----- setup separate task registers for this task
      stacktsk SP! !SP   \ assign this task a local stack and initialize to a depth of 0
      9600d SERBAUD      \ set this task's BAUD
      LCD                \ re-vector output          
      BEGIN
        CLS              \ clr lcd
        #17 EMIT         \ turn on bl
        #100 ms 
        "0" #10 ADO I EMIT LOOP   "A" 6 ADO I EMIT LOOP    \ output 0-1A-F
        2 seconds 
        A$ PRINT$
        2 seconds
        CLS
        B$ PRINT$
        2 second
        CLS
        " any old string" PRINT$
        1 second
        CLS
        CR PRINT" That's all folks!"
        1 second
        CLS
        #18 EMIT      \ turn off bl
       1 second
      AGAIN
    ;
    
    
  • D.PD.P Posts: 790
    edited 2014-02-18 19:09
    I was going to leave that exercise to you :) but I have included the extra line or two to show you what I would do in this circumstance.
    TABLE regs1         $20 ALLOT           \ some room for temp register + uemit and ukey
    TABLE stacktsk     $40 ALLOT
    
    : LCDEMIT        9 SEROUT ;             \ define emit word for this output
    : LCD        ' LCDEMIT uemit W! ;       \ vector it to uemit
      " THE 2nd STRING" 0 STRING B$         \ tachyon string variable
      " HOW IS LONG IS" 0 STRING A$
    
    : MYTASK             \ task to demonstrate  LCD output 
      regs1  TASKREGS       \  <----- setup separate task registers for this task
      stacktsk SP! !SP   \ assign this task a local stack and initialize to a depth of 0
      9600d SERBAUD      \ set this task's BAUD
      LCD                \ re-vector output          
      BEGIN
        CLS              \ clr lcd
        #17 EMIT         \ turn on bl
        #100 ms 
        "0" #10 ADO I EMIT LOOP   "A" 6 ADO I EMIT LOOP    \ output 0-1A-F
        2 seconds 
        A$ PRINT$
        2 seconds
        CLS
        B$ PRINT$
        2 second
        CLS
        " any old string" PRINT$
        1 second
        CLS
        CR PRINT" That's all folks!"
        1 second
        CLS
        #18 EMIT      \ turn off bl
       1 second
      AGAIN
    ;
    
    

    This has been elusive for me for some reason. I'm just now proceding from FORTH/Tachyon syntax to more "how it works" stuff.
    Getting past this hurdle has helped me greatly, I just couldn't glean what I needed from within the source.
    Now I have renewed motivation, thanks for the "thorn removal"

    UPDATE, while this has removed the keyboard issue the LCD is "no op", LCD checked with console testing? I've tried with $20,$30 ALLOT for regs1

    UPDATE2****** NEED TO HAVE A BLANK LINE BETWEEN EACH ALLOT STATEMENT, ARRG I BEEN BITTEN BY THIS BEFORE! BEWARE
    TABLE regs1         $20 ALLOT           \ some room for temp register + uemit and ukey
    TABLE stacktsk     $40 ALLOT
    
    \ shoud be 
    
    TABLE regs1         $20 ALLOT           \ some room for temp register + uemit and ukey
    
    TABLE stacktsk     $40 ALLOT
    
Sign In or Register to comment.