I scoured this (and many other) pages for the past two hours so I apologize if this is already answered somewhere, but I'm at my wit's end. I'm trying to load more than 256 bytes to a memory blob (for collision detection). I load the high and low bytes of the collision data blob (728 bytes) and want to store accumulator values in that data using indirect addressing. The problem, however, is that I can't stick my data into it. I've tried several things (some below), but feel like I'm missing a fundamental syntax here...

2. collision_low is not on the zero page. There are only 256 bytes of ZP and you've already reserved 768 bytes on it before trying to add collision_low. (The two bytes of an indirect address pointer must be on the ZP.)

As a quick fix, try swapping the position of the pointer and the array in memory:

Code:

collision_low .rs 1 collision_high .rs 1collision_map .rs 768

The problem seems to be that the 768-byte array is bumping the pointer to a memory position that's not in page 0, and indirect indexed addressing only works if the pointer is in ZP.

You will have to do something about that 768-byte array though, because starting it in ZP will make it occupy the rest of ZP, the entirity of pages 1 (the stack!) and 2 (normally the OAM buffer), and a bit of page 3. You should probably start this array on page 3 at least, and have it occupy 3 consecutive pages (3, 4 and 5).

The above code will stick the low byte of the address of the collision_map variable, i.e. value $05, into variable collision_low. It'll then put the high byte of the address of the collision_map variable, i.e. $00, into variable collision_high.

Using indirect addressing, you can then begin accessing data stored in collision_map like so:

Code:

ldy #0lda [collision_low], y

This would access the first byte of what's contained at collision_map.

Now, let's talk about this, because it'll shed light on the situation:

Code:

STA [collision_low], Y ; Doesn't build: Incorrect zero page address!

And here we have our answer: this assembler error is valid. It means that collision_low is not within zero page. For indirect addressing to work, the variables (for the low and high byte) need to be stored in zero page ($00 to $FF).

What this means is that collision_low and collision_high are outside of zero page. And that's certainly the case, because, again:

Don't keep it that way though. Big arrays don't belong in zero page, which should be reserved for pointers and commonly used variables as much as possible, but way more importantly than that, the array is so big that it completely overlaps page 1, where the stack lies. This means that when the stack is used, the array will get corrupted, and when the array is written to, the stack might get corrupted, possibly crashing the program.

Definitely heard you all on the problems with putting the blob in the zero page and of course once I loaded my blob, I saw the program crash. Still getting a handle on this so I appreciate your patience. Anyway, finally have it all loading as desired without crashing so I figured I'd post what finally worked for me. I'm sure it's still far from perfect, but figured it might be helpful for the next guy. Thanks again everyone for the quick/informative responses!

Definitely heard you all on the problems with putting the blob in the zero page and of course once I loaded my blob, I saw the program crash. Still getting a handle on this so I appreciate your patience. Anyway, finally have it all loading as desired without crashing so I figured I'd post what finally worked for me. I'm sure it's still far from perfect, but figured it might be helpful for the next guy. Thanks again everyone for the quick/informative responses!

Code:

LDX $00 LDY $00

These are loading contents into X and Y, respectively, from zero page location $00, which is going to be the first byte of collision_map. You meant to use immediate addressing, ex.:

Code:

ldx #0ldy #0

...or alternately, if you prefer:

ldx #$00ldy #$00

Edit: P.S. -- You don't need to cpy #$00 after iny. iny modifies the both the CPU flags N and Z, so you don't need the comparison for comparing against zero here. You can just do iny, bne ....

werps. Good catch with the $00 vs #$00. fixed it in place. As for the compare. will fix that in my code, but I'll leave it above. Guessing for anyone at my level that this'll help for, the extra logic is worth making it easier to understand.

werps. Good catch with the $00 vs #$00. fixed it in place. As for the compare. will fix that in my code, but I'll leave it above. Guessing for anyone at my level that this'll help for, the extra logic is worth making it easier to understand.

Purely an optimisation thing; has nothing to do with fixing a bug. If the explicit compare is helpful for you, keep it. :-)

As for the rest of the code: it should "function", but it probably won't work right once Y wraps from $FF to $00. Hint: think about collision_low. You're increasing the high byte of the address, but collision_low will still contain whatever address it did prior to the wrap. Think about the implications if, say, collision_map is at $03B4 (or any non-zero low byte of the address).

You're increasing the high byte of the address, but collision_low will still contain whatever address it did prior to the wrap. Think about the implications if, say, collision_map is at $03B4 (or any non-zero low byte of the address).

Actually, this kind of data transfer loop works just fine and is very common in 6502 ASM (you'd normally just use INC on the high byte of the pointer though, not LDA + CLC + ADC + STA). Look:

Also, while there is no convenient way to increment A, there is a convenient instruction for incrementing a byte of RAM directly (INC).

Code:

LDA collision_high CLC ADC #$01 STA collision_high

; the following does the same job:

INC collision_high

Aside from being faster and shorter, the INC instruction does not modify A, and does not modify the carry bit (like ADC does), though it does still modify the zero bit. (However, an increment that should "carry" would have a result of zero anyway, so that flag is sufficient if you need it.)

Edit: sorry, was redundant to tokumaru's post, though maybe a little more explicit.

Who is online

Users browsing this forum: No registered users and 4 guests

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum