Range error with indirect addressing in CC65

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
User avatar
DRW
Posts: 2070
Joined: Sat Sep 07, 2013 2:59 pm

Range error with indirect addressing in CC65

Post by DRW »

Since I didn't find an NES game with a female character that matches my taste, I decided to program one myself. So, I picked up NES programming again.
Last time, I didn't have an idea for a game, so I made slow progress, but this time I have a concept and I'm much more motivated.
I went through the Nerdy Nights tutorials again and now I also have a much better understanding of all that stuff than last time.

Since I'm planning to write some of the code in C, my first step is to convert my NESASM3 sample program into CC65 syntax. And there's where I've encountered the first problem:

In NESASM3, I had the following code to fill all the background tiles with values:

Code: Select all

	LDA #LOW(background)
	STA pointerLo
	LDA #HIGH(background)
	STA pointerHi
	LDX #$00
	LDY #$00
OutsideLoop:
InsideLoop:
	LDA [pointerLo], y
	; and so on.
In CC65, this produced errors and I changed the following:


I changed #HIGH to .HIWORD and #LOW to .LOWORD.
Is this the correct function?


Then I changed LDA [pointerLo], y to LDA (pointerLo), y.

But now, regarding this line, the compiler tells me:
"Error: Range error"

The pointer variable is declared in the zero page:

Code: Select all

.segment "ZP"

pointerLo: .res 1
pointerHi: .res 1
And my call is simply:
ca65 Test.s
(I don't link yet, I just try to create the object file for now.)

What am I doing wrong here?
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg
User avatar
thefox
Posts: 3139
Joined: Mon Jan 03, 2005 10:36 am
Location: Tampere, Finland
Contact:

Re: Range error with indirect addressing in CC65

Post by thefox »

DRW wrote:I changed #HIGH to .HIWORD and #LOW to .LOWORD.
Is this the correct function?
Nope. HIGH should become .HIBYTE and LOW should become .LOBYTE.
Then I changed LDA [pointerLo], y to LDA (pointerLo), y.
That's correct.
But now, regarding this line, the compiler tells me:
"Error: Range error"

The pointer variable is declared in the zero page:

Code: Select all

.segment "ZP"

pointerLo: .res 1
pointerHi: .res 1
What am I doing wrong here?
You need to specify that the segment is a zeropage segment like this:

Code: Select all

.segment "ZP" : zeropage
If the segment's name is "ZEROPAGE" or you use .zeropage, this is done automatically.
Last edited by thefox on Fri Jul 31, 2015 1:43 pm, edited 1 time in total.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Range error with indirect addressing in CC65

Post by tepples »

thefox wrote:If the segment's name is "ZEROPAGE", this is done automatically. If you use .zeropage, this is done automatically.
Both the stricken statement and the added statement are correct, to the best of my knowledge. I use .segment "ZEROPAGE" and it's automatically marked as zero page.

Is there a difference between the syntax .segment "ZEROPAGE", zeropage and .segment "ZEROPAGE": zeropage?
User avatar
thefox
Posts: 3139
Joined: Mon Jan 03, 2005 10:36 am
Location: Tampere, Finland
Contact:

Re: Range error with indirect addressing in CC65

Post by thefox »

tepples wrote:
thefox wrote:If the segment's name is "ZEROPAGE", this is done automatically. If you use .zeropage, this is done automatically.
Both the stricken statement and the added statement are correct, to the best of my knowledge. I use .segment "ZEROPAGE" and it's automatically marked as zero page.
Ah, that might be. I also had a faint memory it might be true, but didn't see a mention about it in the docs and couldn't bother to test it. :)
Is there a difference between the syntax .segment "ZEROPAGE", zeropage and .segment "ZEROPAGE": zeropage?
Yes, the syntax used in the docs doesn't work. I also noticed that earlier and opened an issue about it in cc65 issue tracker.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
User avatar
DRW
Posts: 2070
Joined: Sat Sep 07, 2013 2:59 pm

Re: Range error with indirect addressing in CC65

Post by DRW »

Thanks for the answers. I see it now: The name "ZP" in the config file is part of the "MEMORY" section, but I of course have to take the values from the "SEGMENTS" section where it's indeed called "ZEROPAGE".

thefox wrote:
DRW wrote:I changed #HIGH to .HIWORD and #LOW to .LOWORD.
Is this the correct function?
Nope. HIGH should become .HIBYTE and LOW should become .LOBYTE.
While it doesn't produce an error anymore, the code

Code: Select all

	LDA .LOBYTE(background)
	; ...
	LDA .HIBYTE(background)
produces a warning for each line:
"Warning: Suspicious address expression"

The background label is in the RODATA segment:

Code: Select all

.segment "RODATA"
background:
	.byte $24, $24, $24, $24, $24, $24, $24, $24, $24, $24, $24, $24, $24, $24, $24, $24
	; etc.
Can this warning be circumvented?
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Range error with indirect addressing in CC65

Post by tepples »

The "Suspicious address expression" is defined in instr.c. Based on my reading of the if statement that triggers this warning, it appears to happen when you take the low byte or high byte of an address defined in a zeropage segment. Beyond that, I don't know; I'm just giving others a starting point for research.
User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Re: Range error with indirect addressing in CC65

Post by Movax12 »

The warning "Suspicious address expression" is a warning for when you load a high or low byte of a label and don't use the immediate operator:

Example:

Code: Select all

mydata: .byte 12h,23h,34h,45h,57h

lda >mydata     ; the same as lda .hibyte(mydata)
ldx <mydata     ; the same as ldx .lobyte(mydata)
jsr processData
vs

Code: Select all

mydata: .byte 12h,23h,34h,45h,57h

lda #>mydata     ; the same as lda #.hibyte(mydata)
ldx #<mydata     ; the same as ldx #.lobyte(mydata)
jsr processData
You probably want the second thing. If you want to just load data from the table, just do:

Code: Select all

lda mydata
Or use x indexing or constant offset or both.
User avatar
DRW
Posts: 2070
Joined: Sat Sep 07, 2013 2:59 pm

Re: Range error with indirect addressing in CC65

Post by DRW »

Thanks a lot for the solution. Not only did it remove the warning, but it also corrected the faulty behavior that I got that I would have asked about next. (The background data was all nonsense. But now that I changed the lines by using the direct value with #, it works exactly as my NESASM program.)

Edit:
And now I also see why I did the error in the first place: I thought #LOW is the function name. But actually, the function name is LOW and the # is of course the "value of address" operator.
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg
Post Reply