Shop OBEX P1 Docs P2 Docs Learn Events
Tachyon V4 "DAWN" - exploring new worlds - Page 25 — Parallax Forums

Tachyon V4 "DAWN" - exploring new worlds

1222325272830

Comments

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-09-28 11:11
    V4.7 testing - extra PASM ops for free

    In the quest to squeeze more into the PASM kernel I have used the otherwise unused wordcodes from $7C00..$7DFF to encode a 9-bit PASM instruction.
    So instead of having a lot of repetitive 2 line PASM routines like:
    ' + ( n1 n2 -- n3 )
    _ADD		add    tos+1,tos
    		jmp   #DROP
    
    I have instead replaced these with decoded wordcodes, so any useful PASM instruction that fits this criteria of 2 parameters in with one result is free!
    CON { wordcoded PASM operations  }
    _AND    = $7CC1
    _ANDN   = $7CC9
    _OR     = $7CD1
    _XOR    = $7CD9
    _SHR    = $7C51
    _SHL    = $7C59
    _SAR    = $7C71
    _ROL    = $7C49
    _ROR    = $7C41
    _REV    = $7C79
    _SUB    = $7D09
    _ADD    = $7D01
    _CMPSUB = $7DC1
    _MIN    = $7C99   ' Forth MIN takes the minimum value vs PASM
    _MAX    = $7C91
    _MINS   = $7C89
    _MAXS   = $7C91
    _ADDABS = $7D11
    

    WORDCODES
    $0000..$01FF	directly executes cog PASM
    $0200..$73FF	calls hub wordcode
    $7600..$7BFF	<not used> - cog images are reused for buffers so no interpreted code would run here
    $7C00..$7DFF	PASM op - writes 9-bit instruction field and executes
    $7Exx		Task register offset
    $7Fxx		Conditional branch using signed 8-bit word displacement
    
  • max72max72 Posts: 1,155
    We need a bigger boat er.. a like button!
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-09-30 11:44
    fibonacci sequence revisited


    While optimizing the wordcode decode sequence for 4.7 I decided to run the old fibonacci tests again however I couldn't seem to locate my test results from earlier versions. I guess I could load an old version and check it again, however the results look good I think.

    EDIT: No, I've done better it looks
    V3.0 fibo(46)        = 1836311903    45.000us 
    V4.5 fibo(46)     = 1836311903      5072 cycles at 96MHz = 52.833us
    V4.7 fibo(46)     = 1836311903      5072 cycles at 96MHz = 52.833us
    

    V4.7
    ..  fibos 
    fibo(6)      = 8               1232 cycles at 96MHz = 12.833us 
    fibo(7)      = 13              1328 cycles at 96MHz = 13.833us 
    fibo(8)      = 21              1424 cycles at 96MHz = 14.833us 
    fibo(9)      = 34              1520 cycles at 96MHz = 15.833us 
    fibo(10)     = 55              1616 cycles at 96MHz = 16.833us 
    fibo(11)     = 89              1712 cycles at 96MHz = 17.833us 
    fibo(12)     = 144             1808 cycles at 96MHz = 18.833us 
    fibo(13)     = 233             1904 cycles at 96MHz = 19.833us 
    fibo(14)     = 377             2000 cycles at 96MHz = 20.833us 
    fibo(15)     = 610             2096 cycles at 96MHz = 21.833us 
    fibo(16)     = 987             2192 cycles at 96MHz = 22.833us 
    fibo(17)     = 1597            2288 cycles at 96MHz = 23.833us 
    fibo(18)     = 2584            2384 cycles at 96MHz = 24.833us 
    fibo(19)     = 4181            2480 cycles at 96MHz = 25.833us 
    fibo(20)     = 6765            2576 cycles at 96MHz = 26.833us 
    fibo(21)     = 10946           2672 cycles at 96MHz = 27.833us 
    fibo(22)     = 17711           2768 cycles at 96MHz = 28.833us 
    fibo(23)     = 28657           2864 cycles at 96MHz = 29.833us 
    fibo(24)     = 46368           2960 cycles at 96MHz = 30.833us 
    fibo(25)     = 75025           3056 cycles at 96MHz = 31.833us 
    fibo(26)     = 121393          3152 cycles at 96MHz = 32.833us 
    fibo(27)     = 196418          3248 cycles at 96MHz = 33.833us 
    fibo(28)     = 317811          3344 cycles at 96MHz = 34.833us 
    fibo(29)     = 514229          3440 cycles at 96MHz = 35.833us 
    fibo(30)     = 832040          3536 cycles at 96MHz = 36.833us 
    fibo(31)     = 1346269         3632 cycles at 96MHz = 37.833us 
    fibo(32)     = 2178309         3728 cycles at 96MHz = 38.833us 
    fibo(33)     = 3524578         3824 cycles at 96MHz = 39.833us 
    fibo(34)     = 5702887         3920 cycles at 96MHz = 40.833us 
    fibo(35)     = 9227465         4016 cycles at 96MHz = 41.833us 
    fibo(36)     = 14930352        4112 cycles at 96MHz = 42.833us 
    fibo(37)     = 24157817        4208 cycles at 96MHz = 43.833us 
    fibo(38)     = 39088169        4304 cycles at 96MHz = 44.833us 
    fibo(39)     = 63245986        4400 cycles at 96MHz = 45.833us 
    fibo(40)     = 102334155       4496 cycles at 96MHz = 46.833us 
    fibo(41)     = 165580141       4592 cycles at 96MHz = 47.833us 
    fibo(42)     = 267914296       4688 cycles at 96MHz = 48.833us 
    fibo(43)     = 433494437       4784 cycles at 96MHz = 49.833us 
    fibo(44)     = 701408733       4880 cycles at 96MHz = 50.833us 
    fibo(45)     = 1134903170      4976 cycles at 96MHz = 51.833us 
    fibo(46)     = 1836311903      5072 cycles at 96MHz = 52.833us  ok
    
  • fibonacci sequence revisited


    While optimizing the wordcode decode sequence for 4.7 I decided to run the old fibonacci tests again however I couldn't seem to locate my test results from earlier versions. I guess I could load an old version and check it again, however the results look good I think.

    EDIT: No, I've done better it looks
    V3.0 fibo(46)        = 1836311903    45.000us 
    V4.5 fibo(46)     = 1836311903      5072 cycles at 96MHz = 52.833us
    V4.7 fibo(46)     = 1836311903      5072 cycles at 96MHz = 52.833us
    

    V4.7
    ..  fibos 
    fibo(6)      = 8               1232 cycles at 96MHz = 12.833us 
    fibo(7)      = 13              1328 cycles at 96MHz = 13.833us 
    fibo(8)      = 21              1424 cycles at 96MHz = 14.833us 
    fibo(9)      = 34              1520 cycles at 96MHz = 15.833us 
    fibo(10)     = 55              1616 cycles at 96MHz = 16.833us 
    fibo(11)     = 89              1712 cycles at 96MHz = 17.833us 
    fibo(12)     = 144             1808 cycles at 96MHz = 18.833us 
    fibo(13)     = 233             1904 cycles at 96MHz = 19.833us 
    fibo(14)     = 377             2000 cycles at 96MHz = 20.833us 
    fibo(15)     = 610             2096 cycles at 96MHz = 21.833us 
    fibo(16)     = 987             2192 cycles at 96MHz = 22.833us 
    fibo(17)     = 1597            2288 cycles at 96MHz = 23.833us 
    fibo(18)     = 2584            2384 cycles at 96MHz = 24.833us 
    fibo(19)     = 4181            2480 cycles at 96MHz = 25.833us 
    fibo(20)     = 6765            2576 cycles at 96MHz = 26.833us 
    fibo(21)     = 10946           2672 cycles at 96MHz = 27.833us 
    fibo(22)     = 17711           2768 cycles at 96MHz = 28.833us 
    fibo(23)     = 28657           2864 cycles at 96MHz = 29.833us 
    fibo(24)     = 46368           2960 cycles at 96MHz = 30.833us 
    fibo(25)     = 75025           3056 cycles at 96MHz = 31.833us 
    fibo(26)     = 121393          3152 cycles at 96MHz = 32.833us 
    fibo(27)     = 196418          3248 cycles at 96MHz = 33.833us 
    fibo(28)     = 317811          3344 cycles at 96MHz = 34.833us 
    fibo(29)     = 514229          3440 cycles at 96MHz = 35.833us 
    fibo(30)     = 832040          3536 cycles at 96MHz = 36.833us 
    fibo(31)     = 1346269         3632 cycles at 96MHz = 37.833us 
    fibo(32)     = 2178309         3728 cycles at 96MHz = 38.833us 
    fibo(33)     = 3524578         3824 cycles at 96MHz = 39.833us 
    fibo(34)     = 5702887         3920 cycles at 96MHz = 40.833us 
    fibo(35)     = 9227465         4016 cycles at 96MHz = 41.833us 
    fibo(36)     = 14930352        4112 cycles at 96MHz = 42.833us 
    fibo(37)     = 24157817        4208 cycles at 96MHz = 43.833us 
    fibo(38)     = 39088169        4304 cycles at 96MHz = 44.833us 
    fibo(39)     = 63245986        4400 cycles at 96MHz = 45.833us 
    fibo(40)     = 102334155       4496 cycles at 96MHz = 46.833us 
    fibo(41)     = 165580141       4592 cycles at 96MHz = 47.833us 
    fibo(42)     = 267914296       4688 cycles at 96MHz = 48.833us 
    fibo(43)     = 433494437       4784 cycles at 96MHz = 49.833us 
    fibo(44)     = 701408733       4880 cycles at 96MHz = 50.833us 
    fibo(45)     = 1134903170      4976 cycles at 96MHz = 51.833us 
    fibo(46)     = 1836311903      5072 cycles at 96MHz = 52.833us  ok
    
    I guess that's the iterative FIBO not the recursive one?

  • Yeah, that's right David, some have had that discussion here before about recursive vs iterative but since the Tachyon return stack is held in the cog along with the kernel then there is a limit to the depth, 28 max in fact. So the iterative one gives me some idea but I'm testing out primes as well which is a better test really. Of course the only benchmark that ever really matters is the benchmark that a final application sets in the real world!

    V4 runs a little slower in this simple Fibonacci routine since it has an extra PASM instruction for every Forth wordcode it fetches plus NEXT in FOR NEXT executes an extra instruction to allow for variable stepping. Overall though V4 is faster than V3 but I will check out the benchmarks and publish a table of execution speed for common operations and benchmarks.
  • Yeah, that's right David, some have had that discussion here before about recursive vs iterative but since the Tachyon return stack is held in the cog along with the kernel then there is a limit to the depth, 28 max in fact. So the iterative one gives me some idea but I'm testing out primes as well which is a better test really. Of course the only benchmark that ever really matters is the benchmark that a final application sets in the real world!

    V4 runs a little slower in this simple Fibonacci routine since it has an extra PASM instruction for every Forth wordcode it fetches plus NEXT in FOR NEXT executes an extra instruction to allow for variable stepping. Overall though V4 is faster than V3 but I will check out the benchmarks and publish a table of execution speed for common operations and benchmarks.
    I think the idea of the FIBO benchmark was not so much to see how long it takes to compute a Fibonacci number but more to test the efficiency of non-primitive function invocation. In Forth terms I suppose that would be non-primitive words. Does your prime number benchmark do that? In any case, my guess is the Tachyon likely outperforms most if not all of the other options on the P1. In this case I guess you're really just testing one version of Tachyon against another. I really need to go back to look at what you've done with "word codes" vs. "byte codes". On the surface it seems like word codes would produce less dense code but that doesn't seem to have happened with Tachyon.
  • Yeah, that's right David, some have had that discussion here before about recursive vs iterative but since the Tachyon return stack is held in the cog along with the kernel then there is a limit to the depth, 28 max in fact. So the iterative one gives me some idea but I'm testing out primes as well which is a better test really. Of course the only benchmark that ever really matters is the benchmark that a final application sets in the real world!

    V4 runs a little slower in this simple Fibonacci routine since it has an extra PASM instruction for every Forth wordcode it fetches plus NEXT in FOR NEXT executes an extra instruction to allow for variable stepping. Overall though V4 is faster than V3 but I will check out the benchmarks and publish a table of execution speed for common operations and benchmarks.

    Neat stuff. I made the jump from 8.8 to 9.2 SAP. I think this is the last upgrade I can do in one life time. All is well. Now to dust off my project boxes and get back into Tachyon for some real productivity. Got my three junior SAs watching the SAP bridge.
  • In simple programs bytecode is more efficient than wordcode, its execution loop is only 3 instructions which directly calls code in the first 256 longs of a Tachyon cog. But to access the other 256 longs it needs an extra bytecode and the delay associated with that too. Also for bytecode to call code in hub memory it needs an extra bytecode to index a vector table which points to the code or else it needs 2 extra bytecodes to point directly to the table. V3 uses a mix of these calls but of course needs to maintain a vector table of 256x4 entries using 4 different bytecode calls. Some fast constants are encoded as a bytecode which calls cog code for that value, so there are only a handful of fast constants as all other literals have to be made up by adding 1 to 4 bytes to a bytecode.

    Contrast this with wordcode which can directly index all of cog memory and by using only one extra instruction in the execution loop can distinguish between cog or hub code. But since P1 hub memory is only usable in the first 32k then the msb is set to indicate that the other 15-bits are a literal, no need for fast constants. Now we have additional tests that continue to fall through while not impacting the speed of cog code that test for short conditional jumps, task register offset, or now a 9-bit pasm instruction encoded into wordcode. There is no need for a vector table and since all hub code is word aligned the lsb of the address is used to indicate a jump rather than a call. Overall, this is very efficient indeed.
  • In simple programs bytecode is more efficient than wordcode, its execution loop is only 3 instructions which directly calls code in the first 256 longs of a Tachyon cog. But to access the other 256 longs it needs an extra bytecode and the delay associated with that too. Also for bytecode to call code in hub memory it needs an extra bytecode to index a vector table which points to the code or else it needs 2 extra bytecodes to point directly to the table. V3 uses a mix of these calls but of course needs to maintain a vector table of 256x4 entries using 4 different bytecode calls. Some fast constants are encoded as a bytecode which calls cog code for that value, so there are only a handful of fast constants as all other literals have to be made up by adding 1 to 4 bytes to a bytecode.

    Contrast this with wordcode which can directly index all of cog memory and by using only one extra instruction in the execution loop can distinguish between cog or hub code. But since P1 hub memory is only usable in the first 32k then the msb is set to indicate that the other 15-bits are a literal, no need for fast constants. Now we have additional tests that continue to fall through while not impacting the speed of cog code that test for short conditional jumps, task register offset, or now a 9-bit pasm instruction encoded into wordcode. There is no need for a vector table and since all hub code is word aligned the lsb of the address is used to indicate a jump rather than a call. Overall, this is very efficient indeed.
    Nice design.

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-10-02 08:48
    The recent threads on the forum reminded me that there are a lot of goodies packed into a standard Tachyon kernel ready to run. Besides the normal WS2812 RGB LEDS, Ping sensors, DHT sensors, RTC, Serial etc I am also enhancing and adding many other drivers such as keypads and LCDs as standard that can be configured at runtime, so there is no need to compile the module and specify the pins at compile time, it is already loaded. To write to an array of 64 WS2812 RGB LEDs:
    <myarray> 64 LEDS

    Also, for instance, if you wanted a 4x4 keypad you would simply connect it up to 8 port pins, add 4 pullups, specify the starting pin:
    8 !KEYPAD
    and maybe an optional key beeper on P0
    0 BEEPER
    and all the key presses will be scanned, debounced, decoded, and buffered automatically without any extra cogs being used. In fact practically all the drivers run from the main Tachyon cog or the background timer cog.
    To read the keypad you can read the next character with KEYPAD@ or simply make it the console keyboard device with KEYPAD. You can add your own decode table by sending it a string that corresponds to the keys like this:
    " DCBA#9630852*741" KEYCODE!

    Here is a document describing some of these devices and how easy it is to use.

    This will all be part of the DEMONSTRATOR that I will get back into building.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-10-05 16:10
    256 KEY ARBITRARY MATRIX KEYPAD SCANNER

    Sounds great, but what does it mean? The other day I added a runtime configurable 4x4 keypad driver to EXTEND as a built-in device but as I was testing it on other hardware I had one device that had the row and columns scattered and not necessarily in order either. So I decided to redo the keypad driver so that I could specify a 32-bit mask for the rows and the same for the columns. These two longs are supplied to the keypad initialization routine !KEYPAD and the driver runs in the background only scanning and reading those bits that are specified in the masks.

    Since we can have any combination of port pins for row and column this also means that it would be possible to scan a 16x16 matrix for 256 keys or even a 28x4 matrix etc. The driver generates a 10-bit code that corresponds to the row and column port pins and if a decode table is specified then the table is searched for a match but failing that it simply returns with the scancode.

    How do you use it? Say if I had 4 columns on P0, P2, P4, P6, and 4 rows on P8,P9,P10,P11 I would start up the scanner with:
    %1111_00000000 %01010101 !KEYPAD
    
    As with the earlier driver you can also specify a beeper and also redirect console input to come from the keypad too etc.

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-10-11 01:53
    FOUR FUNCTION CALCULATOR APP

    To test out the use of the new keypad encoder and LCD driver that is now built into Tachyon I wrote a very small calculator app (316 bytes).
    In the process I found that the lines that I shared between the LCD and the keypad were causing problems as the keypad was
    being scanned by the timer cog and the LCD could be written to anytime. So I decided to buffer the LCD so the timer cog is now responsible
    for refreshing the LCD. This also means that the LCD can be called from another task without I/O conflicts or delays.

    Anyhow, the calculator is setup on a 20x4 LCD along with a 4x4 keypad and the LCD displays the last three entries over 3 lines.
    EDIT: perhaps I could interface F32, the floating point ROM built-into Tachyon and add a larger keypad for a programmable scientific calculator!
    TACHYON
    {
    Demonstrate use of built-in KEYPAD and LCD objects
    by running a simple 4 function RPN integer calculator
    using a 20x4 LCD and a 4x4 keypad
    along with a piezo transducer for sounds.
    }
    --- table for P1144 PCB and 4x4 keypad ---
    TABLE K1144
    	$0CB || '1' || $08B || '2' ||
    	$04B || '3' || $00B || 'A' ||
    	$0CA || '4' || $08A || '5' ||
    	$04A || '6' || $00A || 'B' ||
    	$0C9 || '7' || $089 || '8' ||
    	$049 || '9' || $009 || 'C' ||
    	$0C8 || '*' || $088 || '0' ||
    	$048 || '#' || $008 || 'D' ||
    	0 ||
    
    byte ent 	--- new entry flag
    byte digits
    
    pub .ITEM	CR 5 SPACES DUP ABS $6A0A PRINTNUM 0< IF '-' ELSE $20 THEN EMIT ;
    --- 		home - display top 3 on stack
    pub DISPLAY	1 EMIT 3RD .ITEM OVER .ITEM DUP .ITEM ;
    
    pub CLOCK	1 EMIT .DATE SPACE .TIME ;
    --- 		reenter?           flag as entered
    pub ENTER	ent C@ IF DUP THEN ent C~~ digits C~ ;
    --- 		Clear stack and push 3 dummy values
    pub CLEAR	LCD CLS  !SP 0 0 0 ent C~ digits C~ ;
    
    pri ADD		ENTER + ;
    pri SUBTRACT	ENTER - ;
    pri MULTIPLY	ENTER * ;
    pri DIVIDE	ENTER / ;
    
    pub KEYFNC
    	SWITCHES
    	'*' CLEAR
    	'#' ENTER
    	'A' ADD
    	'B' SUBTRACT
    	'C' MULTIPLY
    	'D' DIVIDE
    	NOP ( end switches with any non literal )
    --- 	start new entry?
    	ent C@ IF 0 ent C~ THEN
    	digits C@ 9 < 0EXIT
    --- 	add in new digit
    	10 * SWITCH@ '0' - +
    	digits C++
    	;
    
    pub !IO
    --- 	These I/O on the P1144 need to be taken low
    	16 LOW 14 LOW
    --- 	Setup keypad masks and key beep
    	K1144 %1010101 %1111_0000_0000 !KEYPAD
    	19 BEEPER
    --- 	&ch.ln 	&bl.ce.rs.dat - setup LCD
    	&20.4 	&18.17.15.0 !LCD
    	19 SPKR
    	;
    
    16 longs calclp	--- V4.7 loop stack (external in V4.5+)
    
    pub CALC.TASK
    	calclp LP!
    	!IO RING
    	CLEAR DISPLAY
    	BEGIN KEYPAD@ ?DUP IF KEYFNC DISPLAY ELSE CLOCK 100 ms THEN AGAIN
    	;
    --- LAUNCH CALCULATOR as a background task ---
    pub CALC	' CALC.TASK 3 RUN ;
    
    END
    
    1119 x 1536 - 162K
  • msrobotsmsrobots Posts: 3,709
    edited 2017-10-11 03:32
    316 bytes.

    beat that, Spin, C, PropBasic....

    don't stop teasing, Peter,

    Enjoy!

    Mike
  • Hi there,
    I'm working on a telnet application using an IoT5500.
    ..  .VER   Propeller .:.:--TACHYON--:.:. Forth V4.5 DAWN 450170727.1400 ok      
    ..  .MODULES *** MODULES ***                                                    
                           Propeller .:.:--TACHYON--:.:. Forth V4.5 DAWN 450170727.0
    52FA: EASYNET.fth         WIZNET NETWORK SERVERS 170821.0000                    
    4A74: W5500.fth           WIZNET W5500 driver 170708.0000                       
                                                                                    
    3800: EASYFILE.fth        SDHC card + FAT32 Virtual Memory Access File System L 
    1B40: EXTEND.fth          Primary extensions to TACHYON V4.5 kernel  - 170814-1k
    
    So far everything is working, but if the cable is plugged out there should be done some clean up code before leaving the connection.
    REVECTORING BYE seemed the right place to do the cleaning up as you see here:
    TACHYON V4
    FORGET TEST1234
    \ translate uSoll into dir and enable
    \
    pub TEST1234 ;
    
    #P14 == _enable                                              \ switch motor voltage on
    #P15 == _dir																								 \ 0: clockwise 1: counterclockwise
    #P21 == _red                                                 \ red LED
    #P22 == _green																						   \ green LED
    
    
    \ --- declare list of tx signals
    5 LONGS myruntime
    myruntime 4 + ORG
    4 DS txcnt
    4 DS RegArt
    4 DS uSoll
    4 DS var3
    
    \ --- initialize signals
    -1 txcnt !                                                   \ increment before every send
    0 RegArt !
    0 uSoll !
    0 var3 !
    
    pub BYE
    		." orig BYE is called"
    		_green  HIGH
    		_red    HIGH
    		;
    
    \ --- revector BYE for structured disconnection
    WORD old_BYE
    ' BYE old_BYE W!                                             \ remember old EASYNET BYE
    
    pub new_BYE
    		." new BYE is called"
    	_enable FLOAT
    	_dir    FLOAT
    	_green  FLOAT
    	_red    FLOAT
    \ 	old_BYE W@ CALL
    	;                              \ --- sDISCON CON SKT@ .SOCKET LAN ;
    
    \ REVECTOR BYE new_BYE
    
    END
    
    This is working fine
    ..  BYE orig BYE is called ok                                                   
    ..  new_BYE new BYE is called ok                                                
     .  REVECTOR BYE new_BYE                                                        
    ..  BYE new BYE is called ok                                                    
    .
    
    The problem lies in the word new_BYE where I wanted to CALL the original (' old_)BYE word but that isn't working as expected: What I'd like to do is
    old_BYE W@ CALL new BYE is called ok
    
    but as shown new_BYE is called nevertheless .
    Does anybody have an idea how I can call the old BYE word (maybe adding some offset bytes?

    If I remember right this was working before V4r5 ?!

    Thanks in advance,
    proplem
  • MJBMJB Posts: 1,235
    proplem wrote: »
    Hi there,
    I'm working on a telnet application using an IoT5500.
    ..  .VER   Propeller .:.:--TACHYON--:.:. Forth V4.5 DAWN 450170727.1400 ok      
    ..  .MODULES *** MODULES ***                                                    
                           Propeller .:.:--TACHYON--:.:. Forth V4.5 DAWN 450170727.0
    52FA: EASYNET.fth         WIZNET NETWORK SERVERS 170821.0000                    
    4A74: W5500.fth           WIZNET W5500 driver 170708.0000                       
                                                                                    
    3800: EASYFILE.fth        SDHC card + FAT32 Virtual Memory Access File System L 
    1B40: EXTEND.fth          Primary extensions to TACHYON V4.5 kernel  - 170814-1k
    
    So far everything is working, but if the cable is plugged out there should be done some clean up code before leaving the connection.
    REVECTORING BYE seemed the right place to do the cleaning up as you see here:
    TACHYON V4
    FORGET TEST1234
    \ translate uSoll into dir and enable
    \
    pub TEST1234 ;
    
    #P14 == _enable                                              \ switch motor voltage on
    #P15 == _dir																								 \ 0: clockwise 1: counterclockwise
    #P21 == _red                                                 \ red LED
    #P22 == _green																						   \ green LED
    
    
    \ --- declare list of tx signals
    5 LONGS myruntime
    myruntime 4 + ORG
    4 DS txcnt
    4 DS RegArt
    4 DS uSoll
    4 DS var3
    
    \ --- initialize signals
    -1 txcnt !                                                   \ increment before every send
    0 RegArt !
    0 uSoll !
    0 var3 !
    
    pub BYE
    		." orig BYE is called"
    		_green  HIGH
    		_red    HIGH
    		;
    
    \ --- revector BYE for structured disconnection
    WORD old_BYE
    ' BYE old_BYE W!                                             \ remember old EASYNET BYE
    
    pub new_BYE
    		." new BYE is called"
    	_enable FLOAT
    	_dir    FLOAT
    	_green  FLOAT
    	_red    FLOAT
    \ 	old_BYE W@ CALL
    	;                              \ --- sDISCON CON SKT@ .SOCKET LAN ;
    
    \ REVECTOR BYE new_BYE
    
    END
    
    This is working fine
    ..  BYE orig BYE is called ok                                                   
    ..  new_BYE new BYE is called ok                                                
     .  REVECTOR BYE new_BYE                                                        
    ..  BYE new BYE is called ok                                                    
    .
    
    The problem lies in the word new_BYE where I wanted to CALL the original (' old_)BYE word but that isn't working as expected: What I'd like to do is
    old_BYE W@ CALL new BYE is called ok
    
    but as shown new_BYE is called nevertheless .
    Does anybody have an idea how I can call the old BYE word (maybe adding some offset bytes?

    If I remember right this was working before V4r5 ?!

    Thanks in advance,
    proplem

    Hi Proplem,

    in V4.5 REVECTORING has changed.
    The first WORDcode of the old wordcode is replaced by a jump to the new wordcode.
    So the saved pointer to the old location will no longer work, actually just point to the new definition.
    But the old one is still there - just the first wordcode was lost.
    So you could copy the first wordcode of the to be redefined word to a save location and add a jump to the rest of the old code. ... will not work in many cases ... not a good solution.
    Or you could copy the complete original definition somewhere and point to it
    It is to late to do the full experiments -
    here just the first part:
    ..    pub BYE1 ." Bye1 called"   ;
    ..    pub BYE2 ." Bye2 called"   ;
    ..    BYE1  Bye1 called ok
    ..    BYE2  Bye2 called ok
     .    WORD oldBye1
    ..    ' BYE1 oldBye1 W!    ok
    ..    oldBye1 W@ CALL  Bye1 called ok
    ..    ' BYE1 50 DUMP
    0000.4AB0:   E4 06 42 79  65 31 20 63  61 6C 6C 65  64 00 3F 00    ..Bye1 called.?.
    0000.4AC0:   E4 06 42 79  65 32 20 63  61 6C 6C 65  64 00 3F 00    ..Bye2 called.?.
    0000.4AD0:   B0 CA 32 80  8E 05 3F 00  3F 00 00 00  00 00 00 00    ..2...?.?....... ok
     .  REVECTOR BYE1 BYE2
    ..   ' BYE1 50 DUMP
    0000.4AB0:   C1 4A 42 79  65 31 20 63  61 6C 6C 65  64 00 3F 00    .JBye1 called.?.
    0000.4AC0:   E4 06 42 79  65 32 20 63  61 6C 6C 65  64 00 3F 00    ..Bye2 called.?.
    0000.4AD0:   B0 CA 32 80  8E 05 3F 00  3F 00 00 00  00 00 00 00    ..2...?.?....... ok
     .  LONG oldBye1A
    ..  oldBye1A $06E4 SWAP W!  ok
    ..  oldBye1A 5 DUMP
    0000.7AF8:   E4 06 00 00  00 00 00 00  00 00 00 00  00 00 00 00    ................ ok
    ..  oldBye1A 2+ ' BYE1 2+ SWAP W!  ok
    ..  oldBye1A 5 DUMP
    0000.7AF8:   E4 06 B2 4A  00 00 00 00  00 00 00 00  00 00 00 00    ...J............ ok
    ..
    
    
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-10-18 04:43
    REVECTOR writes the address of the new routine into the first word of the old routine but it also sets bit0 of that it does a jump rather than a call. Be aware too that the simple test case of printing a string as the "first" word in a routine cannot be replaced with a call as the code would return to execute the string and crash. So it needs to be a jump which revector does.

    Anyway, why don't you just create the new BYE which includes source code from the original, and then revector the original to the new.
    pub new_BYE
    	_enable FLOAT
    	_dir    FLOAT
    	_green  FLOAT
    	_red    FLOAT
    	ISCON CON SKT@ .SOCKET LAN
    	;
    
    REVECTOR BYE new_BYE
    

    All code that calls the original BYE will jump to new_BYE.

    BTW, I'm thinking of writing a standalone app to make the IoT5500 a serial gateway with some extras, such as direct access to a target's Propeller to allow reprogramming by sending a file via FTP or even reading the target.
  • Tachyon is nice to use interactively but for longer larger FORTH source I prefer to use a text editor.
    Too often I forgot to save before uploading in minicom. So I created a simple IDE consisting of a text editor, a simple terminal and a function to upload the text without the need to first save it.
    I have created a github project for this: https://github.com/rbehm-ibb/Tachyon-IDE.
    This is currently quite unfinished work, it needs an ANSI interpreter in the terminal.

    Peter, I hope you don't mind that I stole your "Use the Forth" logo for this.
  • MJBMJB Posts: 1,235
    rbehm wrote: »
    Tachyon is nice to use interactively but for longer larger FORTH source I prefer to use a text editor.
    Too often I forgot to save before uploading in minicom. So I created a simple IDE consisting of a text editor, a simple terminal and a function to upload the text without the need to first save it.
    I have created a github project for this: https://github.com/rbehm-ibb/Tachyon-IDE.
    This is currently quite unfinished work, it needs an ANSI interpreter in the terminal.

    Peter, I hope you don't mind that I stole your "Use the Forth" logo for this.
    I also tried the ESPLORER made for ESP8266 with Tachyon.
    But I don't like the missing direct entry to the terminal.

    But usually I use Notepad++ with a Tachyon mode.
  • @MJB, @Peter,
    of course you're right one could do it like this
    ...
    Anyway, why don't you just create the new BYE which includes source code from the original, and then revector the original to the new.
    pub new_BYE
    	_enable FLOAT
    	_dir    FLOAT
    	_green  FLOAT
    	_red    FLOAT
    	ISCON CON SKT@ .SOCKET LAN
    	;
    
    REVECTOR BYE new_BYE
    
    but I prefer the method MJB gave some hints for.
    Why? I want to use EASYNET I don't want to copy or change it. If I'd copy the code, what would happen if Yoda decided to change the BYE word without asking his padawans? All padawans code would be wrong or incomplete.
    The current implementation of the REVECTOR mechanism lacks the functionality of un-REVECTORing . This could BTW be one snippet of the clean up code I want to implement.

    This is just one example of a general topic. In my opinion the previous implementation of REVECTOR was better in this way and I'd like to get this functionality back.

    @ MJB - thanks for your suggestion. I couldn't reproduce and analyze it further (time is short). Further I think this should be solved in tachyon itself.

    Thanks to you both, best regards,
    proplem
  • Proplem - the only way that REVECTOR could work in V3 was via the vector table which only existed for the first 512 calls.
    Originally there was room in the vector tables for 1,024 entries but at some point it runs out and so 3 bytes were used in a call with one bytecode plus 2 bytes for a 16-bit address. By the time EASYNET is loaded this table has long been exhausted and high level calls were using 3 bytes and therefore they were not revectorable.

    V4 by contrast does not need vector tables and a call is always one wordcode, so it is easy to replace the first wordcode with a jump. I do this all the time but if I want a little flexibility I simply add a NOP as the first word so it can be replaced with a call rather than a jump and after the return everything executes normally. For instance, this is the way that I patch in LED indicators for EASYFILE and EASYNET, as some systems have them and some don't, and the methods to access them vary. So the V4 REVECTOR works well in this regard. If it makes it easier for you I will simply add a NOP as the first wordcode in BYE.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-10-18 12:53
    rbehm wrote: »
    Tachyon is nice to use interactively but for longer larger FORTH source I prefer to use a text editor.
    Too often I forgot to save before uploading in minicom. So I created a simple IDE consisting of a text editor, a simple terminal and a function to upload the text without the need to first save it.
    I have created a github project for this: https://github.com/rbehm-ibb/Tachyon-IDE.
    This is currently quite unfinished work, it needs an ANSI interpreter in the terminal.

    Peter, I hope you don't mind that I stole your "Use the Forth" logo for this.

    Hi Reinhardt, how are the Taiwanese helicopters going? :)

    Thanks, I downloaded your code immediately after you posted but I didn't want to bury your post too soon by replying immediately. I did try to import it as a project into QT Creator running on Linux but it was missing config.h when I went to build it. I think I have to check my other settings when I get back to it.

    btw, I normally use sublime or medit and then run minicom as a terminal and just alt-tab between windows copying and pasting. I never really type more than one line in interactively as I find it very easy to copy and paste from the editor.





  • Hi Reinhardt, how are the Taiwanese helicopters going? :)
    Don't know, my customers are mainly on the other side of the planet (br, us).
    Thanks, I downloaded your code immediately after you posted but I didn't want to bury your post too soon by replying immediately. I did try to import it as a project into QT Creator running on Linux but it was missing config.h when I went to build it. I think I have to check my other settings when I get back to it.
    Maybe you were too fast. I had not yet put my standard lib files into the repo. This is fixed now.
    btw, I normally use sublime or medit and then run minicom as a terminal and just alt-tab between windows copying and pasting. I never really type more than one line in interactively as I find it very easy to copy and paste from the editor.

    An interesting feature I have included is a very simple parser for the FORTH source. It extracts all definitions (CONSTANT, == : PUB PRI, PRE, ..) and collects them into a list displayed in a sidebar. You can click into that and it jumps the editor window to this definition. I would also add a quick access to some help files in the future.




  • Hi Peter,
    Proplem - the only way that REVECTOR could work in V3 was via the vector table which only existed for the first 512 calls.
    Originally there was room in the vector tables for 1,024 entries but at some point it runs out and so 3 bytes were used in a call with one bytecode plus 2 bytes for a 16-bit address. By the time EASYNET is loaded this table has long been exhausted and high level calls were using 3 bytes and therefore they were not revectorable.

    V4 by contrast does not need vector tables and a call is always one wordcode, so it is easy to replace the first wordcode with a jump. I do this all the time but if I want a little flexibility I simply add a NOP as the first word so it can be replaced with a call rather than a jump and after the return everything executes normally. For instance, this is the way that I patch in LED indicators for EASYFILE and EASYNET, as some systems have them and some don't, and the methods to access them vary. So the V4 REVECTOR works well in this regard. If it makes it easier for you I will simply add a NOP as the first wordcode in BYE.
    It is really difficult to get managed with this because it dives quite deep into the internals for which I'm too short in time. I know from a didactic view it would be better to learn but practical requirements avoid that.
    So I have to choose the copy version too be quicker.
    As a feature request for Tachyon-P2 I would like REVECTORing implemented in the classical manner because it is more generic.

    Thanks for understanding,
    proplem
  • MJBMJB Posts: 1,235
    proplem wrote: »
    Hi Peter,
    Proplem - the only way that REVECTOR could work in V3 was via the vector table which only existed for the first 512 calls.
    Originally there was room in the vector tables for 1,024 entries but at some point it runs out and so 3 bytes were used in a call with one bytecode plus 2 bytes for a 16-bit address. By the time EASYNET is loaded this table has long been exhausted and high level calls were using 3 bytes and therefore they were not revectorable.

    V4 by contrast does not need vector tables and a call is always one wordcode, so it is easy to replace the first wordcode with a jump. I do this all the time but if I want a little flexibility I simply add a NOP as the first word so it can be replaced with a call rather than a jump and after the return everything executes normally. For instance, this is the way that I patch in LED indicators for EASYFILE and EASYNET, as some systems have them and some don't, and the methods to access them vary. So the V4 REVECTOR works well in this regard. If it makes it easier for you I will simply add a NOP as the first wordcode in BYE.
    It is really difficult to get managed with this because it dives quite deep into the internals for which I'm too short in time. I know from a didactic view it would be better to learn but practical requirements avoid that.
    So I have to choose the copy version too be quicker.
    As a feature request for Tachyon-P2 I would like REVECTORing implemented in the classical manner because it is more generic.

    Thanks for understanding,
    proplem

    In Symbolics Lisp-MAchine Lisp we had nice things like before and after demons and wrappers
    which allowed dynamic modification, extension and redefinition of functions.
    While those could be implemented in Tachyon as well and would be great,
    REVECTOR is one of those,
    I would NOT want to waste space or sacrifice performance for a rarely used feature
    if there are ways around for exceptional use cases.
    The COPY approach workes well.
    Extending every definition with a NOP just in case s.o. wants to revector it
    costs space and slows down.
    And if s.o. needs s.th. special you could create a Tachyon word / mechanism that does this without sacrificing general efficiency.
    Like dynamically copying the to be REDEFINED word to a safe location and do the patching.
    All the required introspection capabilities, access to the dictionary etc. are there.
    But you are right - it takes some time and learning curve to do it.
    The words doing a lookahead like ." make things a little tricky.

  • MJBMJB Posts: 1,235
    Hi PEter,
    long time ago we talked about nRF24L01+
    did you ever write code for it?
    I am just getting back to a possible application and still have some unused parts here ...
  • MJB wrote: »
    Hi PEter,
    long time ago we talked about nRF24L01+
    did you ever write code for it?
    I am just getting back to a possible application and still have some unused parts here ...

    I never did get these setup but only just the other day I was looking at what I could use for a link over 30m and of course these chips certainly are a possibility. I may end up getting sidetracked......

  • MJB wrote: »
    Hi PEter,
    long time ago we talked about nRF24L01+
    did you ever write code for it?
    I am just getting back to a possible application and still have some unused parts here ...

    I never did get these setup but only just the other day I was looking at what I could use for a link over 30m and of course these chips certainly are a possibility. I may end up getting sidetracked......
    Sweeet! I just bought 10 of these and havent used them yet
  • proplemproplem Posts: 233
    edited 2017-10-24 06:47
    Hi there,
    currently reactivating some pre v4r5 code I found this word:
    : !LCD lcdmem 4 COGREG! 4 3 COGREG! [PLOT] ;
    
    With my own words this code writes the address lcdmem into cog memory 4 and then writes a 4 into cog memory address 3. After that the plot code is loaded into cog memory.

    I would translate this into v4r5 like this:
    : !LCD lcdmem 4 COG! 4 3 COG! [PLOT] ;
    
    Correct? Or do I have to pay attention for something else?

    Thanks, proplem
  • @proplem - yes, only adjust any hard-coded constants by +1. These registers start in address $001 so they were simply offset and can of course write anywhere in cog memory.
    : !LCD lcdmem 5 COG! 4 4 COG! [PLOT] ;
    

    From the source code around line 6822 (in V4.7)
    org REG1
                    res 3
    pixshift        res 1
    pixeladr        res 1
    

    The pixshift of 4 is x16 bytes or 128 pixels.
  • Hi there,
    I've got a nesting loop issue:
    CLS
    .VER
    .MODULES
    2 FOR 3 FOR 4 FOR I . SPACE J . SPACE K . CR NEXT NEXT NEXT
    
    results in
    ..  CLS  ok
    .:.:--TACHYON--:.:. Forth V4.5 DAWN 450170727.1400 ok
    *** MODULES ***
    Propeller .:.:--TACHYON--:.:. Forth V4.5 DAWN 450170727.1400
    3800: lamestation.fth     lamestation - (C) LameStation LLC 170125.0000 
    1B40: EXTEND.fth          Primary extensions to TACHYON V4.5 kernel  - 170814-1100
     ok
    ..  2 FOR 3 FOR 4 FOR I . SPACE J . SPACE K  ??? . CR NEXT NEXT NEXT 0 0 0
    1 0 0
    2 0 0
    3 0 0
    0 1 0
    1 1 0
    2 1 0
    3 1 0
    0 2 0
    1 2 0
    2 2 0
    3 2 0
    0 0 0
    1 0 0
    2 0 0
    3 0 0
    0 1 0
    1 1 0
    2 1 0
    3 1 0
    0 2 0
    1 2 0
    2 2 0
    3 2 0
     ok
    
    Obviously K isn't usable.
    Is there a way to nest loops more than twice?

    Thanks,
    proplem
Sign In or Register to comment.