8x16 and whatever else unreg wants to know

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 and whatever else unreg wants to know

Post by unregistered »

tokumaru wrote: Mon Jan 03, 2022 6:08 am Well, there are legitimate reasons to directly change the PC value like that, such as beginning a new bank or assembling code that will run at an address different from where it's stored (i.e. code that will be copied to RAM), but in these cases you'd normally use a constant address, not one based on the current address... and since the assembler provides a dedicated directive for this purpose, it's probably better to use that than the PC assignment.
:D 👍
unregistered wrote: Mon Jan 03, 2022 1:56 amshould never store a value, that has to be calculated, to $. At least not 48 or so times in the same asm6 ROM. :wink:
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 and whatever else unreg wants to know

Post by unregistered »

Is it possible, on the NES and using asm6, to create a variable, like $00001 apple .dsb 3, and then later change apple’s location from $00001 to $00007?

I mean, even if apple started in a RAM location, its address is not RAM. And even “apple” doesn’t exist in the assembled ROM. It would be magical to be able to change every ROM address-byte $01 into $07.


It is possible, with asm6, at least, to rename a variable with pineapple = apple near the top of the code. But that just also joins pineapple to memory location $00001.


Guess I should move that apple to my massive MMC1-allotment of RAM and then assign it appropriate values after a certain choice is made in our game.
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 and whatever else unreg wants to know

Post by unregistered »

Hi.

Note: This question is a bit different from ^above.

[EDIT]Gah! Sigh, sorry, the answer I’m seeking is actually exactly the same.

After the game is assembled, the variable names don’t exist anymore. So, reassigning them is impossible. Looks like an ample opportunity to use more of this massive RAM space.[/EDIT]


Is it possible to reassign the 16bit address of a variable during runtime?

Like, say apple @$8010, pear @$C450, peach @$C9F3, and kiwi @$F21D. And we want to use load one of those variables with relation to X at runtime. Is there any cool way to have lda fruit,x and change fruit into apple, pear, peach, or kiwi during runtime?


Other than transferring “lda fruit,x” to RAM and writing twice to that RAM to overwrite fruit’s low and high byte?

It is freedom to use 16bit addresses before runtime (one variable name carries both low and high bytes), but once runtime starts is there a trick or way to circumvent the low AND the high byte use that seems, to me, to be required then?
User avatar
Jarhmander
Formerly ~J-@D!~
Posts: 569
Joined: Sun Mar 12, 2006 12:36 am
Location: Rive nord de Montréal

Re: 8x16 and whatever else unreg wants to know

Post by Jarhmander »

Not exactly sure of what you want, but it really looks like you want indirection. With indirect indexed addressing mode (like in lda (zp), y instruction), you can have a pointer in zero page and change it to point to a fruit. Your routines can then use the zero page pointer to do their work. Prior to calling your subroutines, you just have to set up your pointer in zero page.

What you're suggesting looks like self-modifing code, where you overwrite the address contained in the instruction to point to another fruit. That would work, but might be an hassle to implement correctly, because you'll have to overwrite each instruction containing the fruit address (doing the equivalent of runtime relocation).

If it can help, I can provide an example, using your fruit analogy.
((λ (x) (x x)) (λ (x) (x x)))
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: 8x16 and whatever else unreg wants to know

Post by tokumaru »

It looks like you're looking for a "trick" that doesn't really exist. If you have several fruits spread across the addressing space and you want to be able to access them all using the same piece of code, the only way to do it is with indirect indexed addressing via a pointer in ZP (lda (ZP), y. Or self-modidying code, which can be tricky on the NES since code doesn't normally run from RAM in that machine.

If the fruits are stored closer together, as in all data for all fruits fits in a contiguous block of 256 bytes of memory, you can use an index register as a sort of 8-bit pointer. You can do something like:

Code: Select all

  .enum 0
    BANANA_OFFSET .dsb 4
    APPLE_OFFSET .dsb 4
    KIWI_OFFSET .dsb 4
    PEAR_OFFSET .dsb 4
    ;(...)
  .ende

  .enum 0
    FRUIT_COLOR .dsb 1
    FRUIT_SIZE .dsb 1
    FRUIT_PRICE .dsb 2
  .ende

  ;loads apple's size
  ldx #APPLE_OFFSET
  lda FruitData+FRUIT_SIZE, x
If the fruits don't all have the same attributes, you can reserve different amounts of memory for each one and create constants for each one's properties (e.g. APPLE_COLOR).

If the fruits are in ROM, instead of enum it'd be better to calculate the offsets using labels:

Code: Select all

FruitData:
BananaData: .db FRUIT_COLOR_YELLOW, FRUIT_SIZE_LARGE, $01, $50
AppleData: .db FRUIT_COLOR_GREEN, FRIT_SIZE_MEDIUM, $02, $00
;(...)

BANANA_OFFSET = BananaData - FruitData
APPLE_OFFSET = AppleData - FruitData
;(...)
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 and whatever else unreg wants to know

Post by unregistered »

Thank you Jarhmander and tokumaru! :D

I appreciate y’all’s reminder about lda (zp), y! That’s kind of a bit of memory/instruction use/cycles spent to set up, but your idea tokumaru seems to be exciting! It even works with data stored In ROM! Wow! I’m going to try using that! Thank you so much!


I’m sry for my delayed response.
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 and whatever else unreg wants to know

Post by unregistered »

@tokumaru, it seems like your ROM labels idea won’t work for me for 3 2 reasons:

1.) My Fruitdata is NOT set up with specific items, so Fruit_Size would just be a number. And to specify that number each time, I’d have to use self-modifying code right?


2.) I can see how #Fruit_Size is 1, but, I guess, maybe I’d just make a separate section using enum 0 to set those labels up with being assigned to consecutive addresses (like 0, 1, 3, etc)… that enum isn’t for assigning variables, but it’s just to assign the addresses. Guess this is a problem bc of 1.). I’m never going to need to use Fruit_Size; just need to use something like AppleData, x.

So, I’d require an X for fruit type and an X for a certain data in that fruit type?


3.) The ROM offsets are assigned with the = and so that means, in order to use those offsets, they’d have to be declared before code which uses the offsets? That would be impossible since my FruitData sits toward the ROM’s end. Maybe the offsets could also take up ROM space to fix that problem?
Last edited by unregistered on Mon Jul 25, 2022 3:45 pm, edited 1 time in total.
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 and whatever else unreg wants to know

Post by unregistered »

unregistered wrote: Thu Jul 21, 2022 4:05 pm 3.) The ROM offsets are assigned with the = and so that means, in order to use those offsets, they’d have to be declared before code which uses the offsets? That would be impossible since my FruitData sits toward the ROM’s end. Maybe the offsets could also take up ROM space to fix that problem?
This reason is invalid; the offset creations can easily live at the top of the ROM.
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 and whatever else unreg wants to know

Post by unregistered »

tokumaru, sigh, I think I’m understanding your FruitData much better now.

To use this, I’ll have to change the routine:

So that it doesn’t run from the beginning of FruitData to its end. Rather, I can use enum 0 to set up each Fruit, and then I’ll have to specify each fruit being loaded… hmm… I bet this will work even better than that.

Going to try your suggestion/explanation tomorrow. :)
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 and whatever else unreg wants to know

Post by unregistered »

tokumaru wrote: Sat Jul 16, 2022 1:15 pm

Code: Select all

  .enum 0
    BANANA_OFFSET .dsb 4
    APPLE_OFFSET .dsb 4
    KIWI_OFFSET .dsb 4
    PEAR_OFFSET .dsb 4
    ;(...)
  .ende
Say I wanted to access the 4s… like 4, 4, 4, 4 would be

#BANANA_OFFSET, #APPLE_OFFSET, #KIWI_OFFSET, #PEAR_OFFSET?

Or, that would actually be 0, 4, 8, 12? That would be fine too. :)


So, if I wanted to use lbl, x could I add:

Code: Select all

   .enum 0
    Offsets
    BANANA_OFFSET .dsb 4
    APPLE_OFFSET .dsb 4
    KIWI_OFFSET .dsb 4
    PEAR_OFFSET .dsb 4
    ;(...)
  .ende
and then use: lda #Offsets,x?


Any ideas? Do I need to create a separate memory space of 4 bytes, bc that’s just not possible?


EDIT: Ah, but how would the assembler know which set of addresses I’m asking for, since there’s at least two .enum 0 and #Offsets is always == 0.

So, guess that creation of bytes in ROM is necessary for what I’m trying to do. If you have any ideas, I’d surely appreciate them! :)
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: 8x16 and whatever else unreg wants to know

Post by tokumaru »

Sorry about my lack of responses, but ever since my last reply I got pretty confused about what exactly you're trying to do here! :lol:
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 and whatever else unreg wants to know

Post by unregistered »

The confusion has been planned… I’m purposely talking about bananas, kiwis, pears, and fruit; our game contains NO fruit. :)

But, I believe I’m fully understanding the purpose behind your .enum 0s now and it’s coming together! :D

Slowly though, bc I was stung by 4 ground hornets recently; one stung my thumb and it’s still swollen. Happy you replied tokumaru! :D
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 and whatever else unreg wants to know

Post by unregistered »

This post is me trying to fully understand Indexed Indirect Addressing on the 2A03.

I’ve read this in MOS’ 6501-6505
preliminary manual from Aug 1975
:
INDEXED INDIRECT ADDRESSING - In indexed indirect addressing (referred to as (Indirect,X)), the second byte of the instruction is added to the contents of the X index register, discarding the carry. The result of this addition points to a memory location on page zero whose contents is the low order eight bits of the effective address. The next memory location in page zero contains the high order eight bits of the effective address. Both memory locations specifying the high and low order bytes of the effective address must be in page zero.
However, many at least a few forumers here have made it seem like once you use (ptr, x) you can only access another byte by manually changing the ptr.

Though, the MOS quote above makes it seem like, as long as all the bytes to access exist within the SAME page, (ptr, x) works exactly like (ptr),y. The only change, according to MOS Technology, between (ptr,x) and (ptr),y is that (ptr,x) DOESN’T use the carry to properly change ptr’s high byte?


What changed in the 2A03 to cause all of my nesdev-forum reading confusion? Or, did MOS change the 6502’s Indexed Indirect Addressing after making that preliminary manual data sheet?
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: 8x16 and whatever else unreg wants to know

Post by lidnariq »

(zp,x) means:

Fetch the 16 bit address stored at (zp+x). Use that as an address. Load/store that byte.

(zp),y means:

Fetch the 16 bit address stored at (zp). Add y to it. Use the sum as an address. Load/store that byte.
Garth
Posts: 246
Joined: Wed Nov 30, 2016 4:45 pm
Location: Southern California
Contact:

Re: 8x16 and whatever else unreg wants to know

Post by Garth »

unregistered wrote: Thu Sep 01, 2022 2:40 pm However, many at least a few forumers here have made it seem like once you use (ptr, x) you can only access another byte by manually changing the ptr
or the X value.
Though, the MOS quote above makes it seem like, as long as all the bytes to access exist within the SAME page, (ptr, x) works exactly like (ptr),y. The only change, according to MOS Technology, between (ptr,x) and (ptr),y is that (ptr,x) DOESN’T use the carry to properly change ptr’s high byte?
The difference between (ZP,X) and (ZP),Y regards whether the indexing is done before or after the indirection. The matter of the carry only has to do with the fact that the ZP address (in both cases) has to be in ZP. IOW, if you do ($F1,X) and X contains $15, it will not pick up the address from $0106 and $0107, but rather from 0006 and 0007. What they point to can be anywhere though, in both cases.
http://WilsonMinesCo.com/ lots of 6502 resources
Post Reply