Any ideas on the Forth code snippet.
Ron Sutcliffe
Posts: 420
This piece of code is driving me nuts. It packs bytes into longs so that they can be saved to
a 512K byte block on Sdcard.
The WORD test simple stores a hex 61 at a location 823 above vram_base.
I have set a up a simple break point (db) at the end of each line in vb!
A snap shot of the stack at each break point is listed at the bottom of the code, so you don't have to run it, to follow it
I am sure that this code can be simplified but I can't see ATM. It's a bottleneck in a project so it needs the be the best it can be.
Any ideas, otherwise I will come back to it later and try again
Ron
a 512K byte block on Sdcard.
The WORD test simple stores a hex 61 at a location 823 above vram_base.
I have set a up a simple break point (db) at the end of each line in vb!
A snap shot of the stack at each break point is listed at the bottom of the code, so you don't have to run it, to follow it
I am sure that this code can be simplified but I can't see ATM. It's a bottleneck in a project so it needs the be the best it can be.
Any ideas, otherwise I will come back to it later and try again
Ron
fl hex 70100 constant v_ram_base variable p_blk variable temp wvariable col wvariable row hex : db st? key drop ; : vram_init v_ram_base p_blk L! ; : mask_byte dup 0 = if ffffff00 swap else dup 1 = if ffff00ff swap else dup 2 = if ff00ffff swap else dup 3 = if ffffff swap thens ; \ Gets a char from vmem pushes TOS (pb--char) pb is a pointer to a byte adr offset from v_ram_base (any byte in any block on SDcard) : vb@ 80 /mod 2 /mod v_ram_base + swap drop dup p_blk <> if dup p_blk L! sd_blockread else drop then 4 /mod sd_cogbuf + COG@ swap 8 * rshift ff and ; \ Puts a char to vmem (pb char--) pb the byte adr offset from v_ram_base (any byte in any block on SDcard) : vb! swap 80 /mod 2 /mod \ 1. calculate blocks from adr (256 words per block) v_ram_base + \ 2. add to v_ram_base swap drop \ 3. remove redundant 0 dup p_blk L! sd_blockread \ save one copy and do blockread 4 /mod dup \ 4. now convert remaing bytes to longs >r >r \ 5. copy ofset from sd_cogbuf to return stack dup >r \ 6. make copy of remaing byte (not enough to make up a long to save on return stack 8 * lshift \ 7. shift it one byte left r> \ 8. r> \ 9. sd_cogbuf + COG@ \ 10. swap mask_byte \ 11. pop return stack get mask it to make a hole drop \ 12 .finished with this now and \ 13. or \ 14. r> \ 15. sd_cogbuf + \ 16. COG! \ 17. p_blk L@ sd_blockwrite ; \ this blockwrite should only happen if the block has changed -----to fix : test sd_init 30 0 do hex 462 i + 61 i + vb! loop p_blk L@ sd_blockread sd_cogbuf 80 cogdump ; { Snapshot of stack at break points 1..17 ST: 00000061 00000042 00000000 00000008 ST: 00000061 00000042 00000000 00070108 ST: 00000061 00000042 00070108 ST: 00000061 00000002 00000010 00000010 ST: 00000061 00000002 ST: 00000061 00000002 ST: 00610000 ST: 00610000 00000002 ST: 00610000 00000002 00000010 ST: 00610000 00000002 61000000 ST: 00610000 61000000 FF00FFFF 00000002 ST: 00610000 61000000 FF00FFFF ST: 00610000 61000000 ST: 61610000 ST: 61610000 00000010 ST: 61610000 0000017C ST: }
Comments
There needs to be a comparison made between the current block and the old block and if they differ the oldblk must be written first before the new block is read, otherwise the last update will get missed.
Anyway I can fix that, but it adds to the bottleneck.