A Table Trick

lbenson

Senior Member
This is new to me, but obviously RevEd planned for it.

The command, TABLECOPY allows you to move table data to ram. Hundreds of bytes can be moved depending on the picaxe. I used a 14M2, with 512 bytes of ram.

I put 370-some bytes of zero-terminated strings in the table (favorite Shakespeare quotes), moved it to ram, ran through it byte by byte with bptr, saving the starts of the strings (also in ram with POKE Wn, Word Wn starting at byte 28, above the named registers), and then every 5 seconds randomly chose a string to display with sertxd.

If you run this in the simulator, be patient. It takes about 30 seconds (with the delay time set to 0) to scan the bytes in ram.

Then the strings display.

You can similarly run through the table itself a byte at a time with READTABLE (but a "@tptr" would help). This provides an alternate way.
Code:
' 14tabletrick.bas prints random lines from a table
#picaxe 14M2
#terminal 4800

table 80,("'Tis time to fear when tyrants s")
table 112,("eem to kiss",0)
table 124,("Some innocents 'scape not the th")
table 156,("underbolt",0)
table 166,("A friendly eye could never see s")
table 198,("uch faults",0)
table 209,("Ripeness is all",0)
table 225,("How poor are they that have not ")
table 257,("patience",0)
table 266,("Everything that grows holds in p")
table 298,("erfection but a little moment",0)
table 328,("One sorrow never comes but bring")
table 360,("s an heir",0)
table 370,("Have more than thou showest; spe")
table 402,("ak less than thou knowest; lend ")
table 434,("less than thou owest",0)
table 455,(0)

symbol cRamStart = 28
symbol cTableStart = 80
symbol cTableLen = 456-cTableStart
symbol cMaxRamAddr = 511
symbol cwRandomValue = 48611 ' seed with large prime number

symbol stringCount = b4 ' number of 0-delimited strings 
symbol stringNo    = b5 ' number of string to be displayed
symbol priorString = b6
symbol wScratch    = w12
symbol wRamAddr    = w13
symbol wRand       = s_w1

tablecopy 80,cTableLen

wRamAddr = cRamStart
bptr = cTableStart
poke wRamAddr, WORD bptr
wRamAddr = wRamAddr + 2
stringCount = 0
inc bptr
do while @bptrinc <> 0 and bptr < cMaxRamAddr
  if @bptr = 0 then
    inc bptr
    wScratch = bptr
'    poke wRamAddr, WORD bptr ' save address in ram (and table) of string; failed with bptr wrap
    poke wRamAddr, WORD wScratch ' save address in ram (and table) of string
    wRamAddr = wRamAddr + 2
    inc stringCount
  endif
loop

sertxd(#stringCount," strings found",cr,lf)
wRand = cwRandomValue

main:
  do
    random wRand
    stringNo = wRand // stringCount
    wRand = wRand * time
    if stringNo <> priorString then ' don't repeat
      priorString = stringNo
      wRamAddr = stringNo * 2 + cRamStart ' address in ram of address of string in ram or table
      peek wRamAddr, WORD wScratch
      bptr = wScratch
      do
        sertxd(@bptrinc)
        if @bptr = 0 then
          sertxd(cr,lf)
          exit
        endif
      loop
      pause 5000
    endif
  loop
I found a PE6 bug. If you use "poke wRamAddr, WORD bptr" when bptr > 255, only the least significant byte is saved.

Using this instead works:

wScratch = bptr
poke wRamAddr, WORD wScratch ' save address in ram (and table) of string

Same truncation occurs with "peek wRamAddr, WORD bptr".

bptr otherwise can contain values up to 511.

[If a large table, for instance for messages, is prepared by an external program, it might be better for that program also to make code for the starts of the strings.]
 
Last edited:

hippy

Technical Support
Staff member
I found a PE6 bug. If you use "poke wRamAddr, WORD bptr" when bptr > 255, only the least significant byte is saved.
Is that with Simulation and/or on a physical chip ? We will have to investigate the issue but it's either not being handled by the compiler correctly or it's because it's a system variable rather than a user variable.

It might be that the solution is to error it as "invalid" when "Word bPtr" is used and require the workround you used. It will depend upon what investigations reveal.
 

techElder

Well-known member
So, to understand you mentioning it as a bug, is this a problem because "bPtr" is always described as a "byte" variable and PE6 doesn't flag your use of it with the term "WORD" prefixed?
 

lbenson

Senior Member
So this is just a simulator error--it works on a real chip.

Code:
' 14bptrpoke ' test poke, peek of bptr
#picaxe 14M2
#terminal 4800

pause 2000
bptr = 256
poke 2,word bptr
peek 2,word w13
sertxd("bptr = ",#bptr,"; after poke, peek, = ",#w13,cr,lf)

w12 = bptr
poke 2,word w12
peek 2,word w13
sertxd("w12 = ",#w12,"; after poke, peek, = ",#w13,cr,lf)
In simulation, the output is:

bptr = 256; after poke, peek, = 0
w12 = 256; after poke, peek, = 256

Programmed onto a real chip:

bptr = 256; after poke, peek, = 256
w12 = 256; after poke, peek, = 256
 

lbenson

Senior Member
With the 14M2, bptr has worked for me for values of 0-511 on both the chip and in the simulator except that in the simulator, for peek and poke (e.g., poke 2,word bptr) it acts like a byte variable.

Since it works on the real chip, it would seem to be a simulator bug.
 
Top