Bug in (at least) 20X2 simulator vs compiler

Aries

New Member
I won't try to explain how I ended up here, but code something like this gives unexpected results when actually run on a 20X2:
Code:
#picaxe 20x2
for w12 = 0 to 2
    w10 = 128 * w12
    w11 = 2
    gosub PrintPTR
next w12
end

PrintPTR:
    ptr = w10
    sertxd(13,10,"Print PTR")
    do
        sertxd(13,10,#ptr," ",#@ptrinc)
    loop until ptr = w11
    sertxd(13,10,"End PTR")
    return
The simulator does this:
Code:
Print PTR
0 0
1 0
End PTR
Print PTR
0 0
1 0
End PTR
Print PTR
0 0
1 0
End PTR
But the 20X2 itself does this:
Code:
Print PTR
0 0
1 0
End PTR
Print PTR
0 0
1 0
End PTR
Print PTR
256 0
257 0
258 0
259 0
260 0
... etc
I had expected (a) both simulator and chip to give the same results and (b) ptr to overflow automatically at 128 (or a multiple thereof), going back to zero. In fact, the 20X2 goes back to the number it first thought of (256 in this case). There are clearly some other subtleties (for example, starting at 389 actually starts at 261), but it certainly does not work consistently or - I suspect - as intended.
 

oracacle

Senior Member
OK i got a little curious. ptr put info into the scratchpad, the 20x2 only has 127 scratchpad addresses (had to check the "put" command for that info)
tried running this and check the scratach pad window in simulator
Code:
main:
    ptr = 255
    @ptr = 99
    
    ptr = 256
    @ptr = 100
99 shows up in address 127, while 100 shows up in address 0.
The simulator seems to be missing the address overflow, however the picaxe did not.
Interestingly, it also show that all 3 of the addresses you refrence would right to address 0. I wonder if the picaxe if automatically rapping the round
ie:
Code:
if address > 127 then
  address = address - 127
end if
If this is the case 256-127=129 which is higher than the value of w11. you first address of 0 would have no wrap around, and the second address of 128 maybe wrapping around to address 1 which is lower than the value of w11.
From this i am surmising that after running the above internally and still being out of the address range it defaults back to the address you gave it and doesn't really know what to do with it. I suspect that it will loop back round after it reaches the max value of a word.
 

inglewoodpete

Senior Member
It would be better to just include the line address = address AND %01111111 before doing a Get or Put, to limit the pointer to 7 bits (or maximum value of 127. This will cause the pointer to roll back to 0 when 127 is exceeded.
 

Aries

New Member
I agree - however, this happened because of a programming error on my part: w10 was overwritten before PrintPTR was called, and the routine then went into an endless loop, even though w11 was within the range 0-127. Had the Picaxe behaved like the simulator, I would have had incorrect data printed, but the program would have carried on.
 

hippy

Technical Support
Staff member
The chip will be truncating 'ptr' and 'bptr' values so they are valid addresses, so on a 20X2 that should be 0 to 127 for 'ptr', but I am not certain where that truncation is actually done, where the wrapround on '@ptrinc' and '@ptrdec'. would be observed.

It would seem there is some mismatch between how the chip does things and how it is handled in simulation which would need to be investigated.
 
Top