read & peek into word var

BeanieBots

Moderator
PE 5.2.0

Peek and read do not give the expected result when used with a word variable.

"peek address,word wordvar" works fine.
However, "peek address,wordvar" only sets the lower byte. If wordvar previously held a value higher than 255, then the result is not what I'd expect.
The same is true for read.
I was expecting a similar result to:-
wordvar=bytevar.

Is this a bug or a way of saving program space?
 

hippy

Ex-Staff (retired)
Is this a bug or a way of saving program space?
It's a feature which caught me out when I first ran into it ...

READ adr, w0 - will only set b0, b1 is left as was

READ adr, WORD w0 - Should work as desired ( READ adr, b0 : READ adr+1, b1 )
 

BeanieBots

Moderator
I was hoping to get away with:-

read adr,w0

instead of:-

w0=0
read adr,w0

or

read adr,w0
w0=w0 and $00FF

or
read adr,b2
w0=b2

or a few other methods. I've got quite a few instances and it's a question of program space. "Read adr,word w0" uses a lot more program space, not to mention EEPROM.
 

Jeremy Leach

Senior Member
Maybe BB you shouldn't be trying to read into a word variable if you are just wanting to use the least sig byte anyway? What comes next after the reads that needs a word variable??
 

westaust55

Moderator
BB's experience does not seem to match the manual which states:
When word variables are used (with the keyword WORD) the two bytes of the
word are saved/retrieved
in a little endian manner (ie low byte at address, high byte at address + 1)

The same statement applies in Manual (reb 6.5b) for PEEK, POKE, READ and WRITE commands.

Maybe Technical (we will let Hippy off on his Birthday ;) ) needs to advise whether it is a documentation or firmware bug
 
Last edited:

BeanieBots

Moderator
Jez, I'm trying to save program space.
I'm storing voltage values in the range 900 to 1600.
Initially, I simply stored the raw number and hence used words.
When trying to get more space, I decided that I could cope with a resolution of "10" and so it would be possible to only store numbers in the range 90 to 160. However, the global program variable still requires 900 to 1600. So the very next statement would need to be "W0=W0*10".
If that was all I needed to do, it would save enough space for another two subroutine calls. However, needing to clear the MSByte of W0 first, actually makes using read_byte longer than using read_word.

@westaust55
I have no issue with "read adr,word w0". It works fine for me.
Be it big or little endian is of no consequence as long as read & write match up, which they do. I'm ex Z80, so my memory mapping is always the opposite of most conventions anyway.
 

westaust55

Moderator
BB,

while I quoted the entire sentence I was primarily trying to emphasise that two bytes were supposed to be SAVED and READ.

Not home this evening to try on my PICAXE , but in the simulator tried:
Code:
w0 =1024
poke $C0, WORD w0
w0 = 1
peek $C0, WORD w0
debug

w0 =128
poke $C0, WORD w0
w0 = 1
peek $C0, WORD w0
debug
watching the variables (b0 and b1) and the SFR memory area (locations 192 and 193) the commands are working correctly in simulation mode.

So suggests it is a firmware/interpreter bug.
 

BeanieBots

Moderator
You've missed the point.
"Peek adr,word wordvar" and "read adr, word wordvar" both work as expected in simulation and on the PICAXE.
It's when the keyword "WORD" is removed but a wordvar is still used that the confusion comes in.
"peek adr,wordvar" does not clear the MS byte of wordvar in the same way that w0=b2 for example would do.

Check my original post again. Also Hippy's reply.
Try your examples without the keyword "WORD" and see what happens.
Is that what you would expect to happen? It's not what I would have expected but I'm guessing it's done that way to keep code size down.
 
Last edited:

westaust55

Moderator
Ah yes you are right, sorry, I mis-read. :( :( :(

But then the manual say: "When word variables are used (with the keyword WORD) . . . .
so I would not have been trying to use a word variable without the WORD keyword.My reading of the manual tells me it will NOT save the two bytes of the word - ie unpredictable results unless the WORK keyword is present.

If it were to work as you say, that makes the need for the keyword obsolete (like the command LET which is not essential in every version of BASIC I have every used in the past 35 years).

Edit: Noted that the insertion of the WORD keyword is adding 3 bytes to program size for each instance.
Without the keyword WORD, same program space used whether word or byte variable is allocated.
 
Last edited:

BeanieBots

Moderator
If it were to work as you say, that makes the need for the keyword obsolete (like the command LET which is not essential in every version of BASIC I have every used in the past 35 years).
I was never expecting to WRITE without using "WORD".
Just thought READ/PEEK would put the byte value into a word variable. Much like any other data assigning command does.
Anyway, it works the way it does, I'll cope;)
 

lbenson

Senior Member
>If it were to work as you say, that makes the need for the keyword obsolete [(the keyword WORD)]

Not so as I understand what BB is saying:

peek 0x50, w1 ' would move the byte value at 0x50 into the low byte of w1 and zero the high byte (doesn't do this now)

peek 0x50, word w1 ' moves the two bytes at 0x50 into w1

This seems to me a plausible extension of the peek command. Correspondingly "poke 0x50, WORD 0" would put 0 in the first two bytes of 0x50.
 

Technical

Technical Support
Staff member
Peek and poke have always been 'byte only' commands, because you can only work a byte at a time. The WORD keyword actually outputs two separate peek/poke commands at consequative addresses.

BB is saying to use
peek $50,w0

as a shortcut for the two lines
peek $50,b0
b1 = 0

We can understand the logic in this, but it is not the way the commands currently work.
 
Top