Page 56 of 109

Re: 8x16 sprite is really a 16x32 pixel image?

Posted: Mon Dec 10, 2012 9:57 pm
by Kasumi
The 6502 deals with numbers low byte first. This means something like jmp $8D9A is assembled to $4C(opcode for the jmp instruction) $9A (low byte) $8D (high byte).

It may appear to be stored "backwards" to you, but it represents the exact same value. That's just how the CPU does things.

The PPU appears to like the high byte first. You write $8D to $2006, and then $9A to $2006. $2007 would be geared to write to $8D9A, not $9A8D. On one console, you get to deal with with both types of endianness!

If the 6502 is going to read a 16 bit value as an address or pointer, it has to be two contiguous bytes, low byte first.

But... any other time (like adding to an objects position), it doesn't matter.

consider this code:

Code: Select all

highbyte = $04
lowbyte = $EF

lda lowbyte
clc 
adc #$08
sta lowbyte

lda highbyte
adc #$00
sta highbyte
You'd get the expected high byte in the RAM location named highbyte, and the expected low byte in the RAM location named lowbyte. They don't even have to be contiguous.

I tend to store things high byte first because it's much easier to read when I'm peeking at the RAM in a debugger. It doesn't matter one way or the other except with pointers and addresses, which the 6502 will always read in its own way.

Just be consistent in your own code, and do what makes sense for you. I hope this post didn't serve to confuse you more.

edit: Wait. Is this the heart of the matter that you expect ox, ox+1, ox+2, and ox+3 to have the same values in the same order as position_hi etc?

Reversing those .ds statements for position_hi etc. wouldn't change the represented value at all. Even if they appeared in the "right" order after reversal, they represent the same thing either way. You could even do this:

Code: Select all

position_hi .DS 1
oX .ds 4
position_medium .DS 1
position_lo .ds 1
position_medihi .ds 1
The bytes that correspond with each other would still be equal, and together they would represent the same number, just in a different location in RAM. (which again, only matters for addresses and pointers.)

edit2: nevermind for what was once here. Not reading closely :(

Re: 8x16 sprite is really a 16x32 pixel image?

Posted: Tue Dec 11, 2012 12:18 pm
by unregistered
Kasumi wrote:The PPU appears to like the high byte first. You write $8D to $2006, and then $9A to $2006. $2007 would be geared to write to $8D9A, not $9A8D. On one console, you get to deal with with both types of endianness!

If the 6502 is going to read a 16 bit value as an address or pointer, it has to be two contiguous bytes, low byte first.

But... any other time (like adding to an objects position), it doesn't matter.

consider this code:

Code: Select all

highbyte = $04
lowbyte = $EF

lda lowbyte
clc 
adc #$08
sta lowbyte

lda highbyte
adc #$00
sta highbyte
You'd get the expected high byte in the RAM location named highbyte, and the expected low byte in the RAM location named lowbyte. They don't even have to be contiguous.
:? I'm dumb I dont understand what you are saying to me. :( Won't they be contiguous (near each other) since highbyte is right above lowbyte at the top of your code there? :) : )
Kasumi wrote:edit: Wait. Is this the heart of the matter that you expect ox, ox+1, ox+2, and ox+3 to have the same values in the same order as position_hi etc?

Reversing those .ds statements for position_hi etc. wouldn't change the represented value at all. Even if they appeared in the "right" order after reversal, they represent the same thing either way. You could even do this:

Code: Select all

position_hi .DS 1
oX .ds 4
position_medium .DS 1
position_lo .ds 1
position_medihi .ds 1
The bytes that correspond with each other would still be equal, and together they would represent the same number, just in a different location in RAM. (which again, only matters for addresses and pointers.)
Yes the different location in RAM was is important to me. I was trying to understand how the code would work using the oX+0 oX+1 oX+2 and oX+3. More on that in a bit.

unregistered wrote:I'm under some trouble with this code...

Code: Select all

;6502 Simulator
 .START $1000
 .ORG $0000
 
  .DB "ABC"

position_lo .DS 1
position_medium .ds 1
position_medihi .DS 1
position_hi .ds 1
oX .ds 4

 
 .ORG $1000
 
    

  ; set the position to $01FC
  lda #$01
  sta position_hi
  LDA #$01
  sta position_medihi
  LDA #$00
  sta position_medium
  LDA #$02
  STA position_lo
  
  LDa #$01
  STa oX+3
  LDa #$01
  STa oX+2
  lda #$00
  sta oX+1
  lda #$02
  STA oX+0
    

  ; now subtract eight (#$0008) from this position
  sec 
  lda position_lo  ; subtract from the low byte first
  sbc #$08
  sta position_lo
  LDA position_medium
  SBC #$00
  STA position_medium
  LDA position_medihi
  SBC #$00
  sta position_medihi
  LDA position_hi
  sbc #$00
  STA position_hi
  
  ; now subtract eight (#$0008) from this position
  sec 
  lda oX+0  ; subtract from the low byte first
  sbc #$08
  sta oX+0
  LDA oX+1
  SBC #$00
  STA oX+1
  LDA oX+2
  SBC #$00
  sta oX+2
  LDA oX+3
  sbc #$00
  STA oX+3
See what I was saying...? I reversed the order of the section of memory declarations and the RAM inverted... it was the same answer but the order of the values in RAM was upside down... and that had been confusing me... though now I understand. :)

unregistered wrote:Ok well that is my code I've explored in the 6502 Simulator from tokumaru. The only thing is that at the top of it I had to reverse this code.

position_hi .DS 1
position_medihi .ds 1
position_medium .DS 1
position_lo .ds 1


I started with that because tepples made his code up there very tricky... I think... :? because he started with

Code: Select all

position_hi = $0701
position_lo = $0700
and that has been confusing me. Should position_lo be above position_hi? :? :)
See reversing the order of the declarations reversed my view of the memory. It was the same answer though, you are right, thank you for pointing that out! I really appreciate that! :D I've learned a lot thinking about all of this. The coolest thing I've learned is that little-endianness makes sense when using one variable name for multiple bytes. You start with the lowest value... (i'm going to use oX for my variable name) oX+0. Ok, then as the number increases the importantance increases!!! oX+1 oX+2 oX+3.... that is AWESOME! :mrgreen: I'm happy Nintendo chose to use little-endianness! "Little-endian" won't confuse me as much anymore! :D

And thank you Kasumi for your endianness link! :D I'm not extreemly excited about wikipedia though. :roll:
Kasumi wrote:edit2: nevermind for what was once here. Not reading closely :(
Kasumi, it's ok :) I don't remember reading it; I found this second edit when I got up this morning.

edit.

Re: 8x16 sprite is really a 16x32 pixel image?

Posted: Tue Dec 11, 2012 1:07 pm
by 3gengames
With the order of the RAM things (Your first reply) it doesn't matter where the bytes of RAM are, you just have to add them and store them to the right places. I keep all mine next to each other, but they don't have to be. The processor just look at where to load and store, which you decide. It doesn't care if it's right next to each other or not. Now when you use an addressing mode like [ZeropageLocation],Y, then you DO have to have them next to each other (Low byte first since it's little endian) because then it does "care" about where they're at because the processor is hardwired to take the zero page location, then the zeropage location+1 the next time! When you're working with single bytes as 16-bit values, you don't have to keep them together because you probably aren't using the data with an addressing mode or anything like that.

Re: 8x16 sprite is really a 16x32 pixel image?

Posted: Tue Dec 11, 2012 1:44 pm
by unregistered
Thanks 3gengames for explaining my confusion away! :D I understand Kasumi more now.

I want to say that I edited my post up there twice because I came back to my computer and wrote that colored part in the middle. Then I submitted it without making it colored for adding/editing it. :(

edit.

Re: 8x16 sprite is really a 16x32 pixel image?

Posted: Tue Dec 11, 2012 4:43 pm
by Kasumi
I'm dumb I dont understand what you are saying to me. :( Won't they be contiguous (near each other) since highbyte is right above lowbyte at the top of your code there? :) : )
To expand on this point a little, there are things in your code that don't end up in your actual rom. For instance, labels. Labels actually take up zero space by themselves.

Code: Select all

.org $8D9A
label1:
label2:
label3:
label4:
label5:
;etc, etc
You could put a million random labels in your code, and your program would (or at least should) be assembled exactly the same. They only take up space when they're used in an instruction. What a label does is names an address for you automatically.

I explained how jmp $8D9A was assembled in the last post. In the above code, jmp label1, jmp label2, jmp label3 etc would all assemble the same as jmp $8D9A. Because even though label2 is after label1, label1 doesn't take up any space. There are no instructions that do take up space between them, so they refer to the same location.

When you add code, it makes every label after the change need a new address. But all the code you previously made (in most cases) will work the same, despite the address move. Similarly, you can switch where the RAM your program is using is, and (in most cases) it will also work the same. That's what I was trying to demonstrate. It doesn't matter what order your DS statements are in.

Code: Select all

highbyte = $04
lowbyte = $EF
Above, highbyte and lowbyte don't refer to contiguous RAM. (Like $04 and $05, or $EF and $F0). The fact they they're next to each other in your code doesn't matter.

You could add a million text = $whatever in your code and it shouldn't affect how your rom is assembled. My assembler (and I assume others as well), doesn't care where they are in the slightest. I could even do something like this:

Code: Select all

	lda #mario
mario = $04;Right in the middle of the code!
	clc
	adc #$08
And it would assemble the same as if mario = $04 was anywhere else in the code.

What does <> mean? Google search says nothing exists for <>

Posted: Wed Dec 12, 2012 4:50 pm
by unregistered
Please help me understand what <> means?

Re: What does <> mean? Google search says nothing exists fo

Posted: Wed Dec 12, 2012 5:28 pm
by tokumaru
unregistered wrote:what <> means
Different.

Re: What does <> mean? Google search says nothing exists fo

Posted: Wed Dec 12, 2012 5:31 pm
by unregistered
tokumaru wrote:
unregistered wrote:what <> means
Different.
THANK YOU TOKUMARU!!! :D

Re: 8x16 sprite is really a 16x32 pixel image?

Posted: Wed Dec 12, 2012 6:08 pm
by unregistered
Kasumi wrote:
I'm dumb I dont understand what you are saying to me. :( Won't they be contiguous (near each other) since highbyte is right above lowbyte at the top of your code there? :) : )
To expand on this point a little, there are things in your code that don't end up in your actual rom. For instance, labels. Labels actually take up zero space by themselves.

Code: Select all

.org $8D9A
label1:
label2:
label3:
label4:
label5:
;etc, etc
You could put a million random labels in your code, and your program would (or at least should) be assembled exactly the same. They only take up space when they're used in an instruction. What a label does is names an address for you automatically.

I explained how jmp $8D9A was assembled in the last post. In the above code, jmp label1, jmp label2, jmp label3 etc would all assemble the same as jmp $8D9A. Because even though label2 is after label1, label1 doesn't take up any space. There are no instructions that do take up space between them, so they refer to the same location.

When you add code, it makes every label after the change need a new address. But all the code you previously made (in most cases) will work the same, despite the address move. Similarly, you can switch where the RAM your program is using is, and (in most cases) it will also work the same. That's what I was trying to demonstrate. It doesn't matter what order your DS statements are in.

Code: Select all

highbyte = $04
lowbyte = $EF

Above, highbyte and lowbyte don't refer to contiguous RAM. (Like $04 and $05, or $EF and $F0). The fact they they're next to each other in your code doesn't matter.

You could add a million text = $whatever in your code and it shouldn't affect how your rom is assembled. My assembler (and I assume others as well), doesn't care where they are in the slightest. I could even do something like this:

Code: Select all

	lda #mario
mario = $04;Right in the middle of the code!
	clc
	adc #$08
And it would assemble the same as if mario = $04 was anywhere else in the code.
Thank you Kasumi. I kindof guessed that was true ("that" is a responce to your first sencence. After debugging with FCEUX for a whlile I noticed that my labels in the code were absent. It made me guess what you are talking about - I remember learning that labels dissappeared after assembly in one of my CS assembly @ut college courses.)... XFactor is coming on... I must go see and listen! ... but didn't know for sure ("didn't know for sure" is a response to your statement about how labels take up no space. All of your explaination made sense to me; it kind of solidified it all in my head-thanku! :)). Kasumi, Tthanks for your detailed explanations! :D

edit.

Re: 8x16 sprite is really a 16x32 pixel image?

Posted: Fri Dec 14, 2012 6:41 pm
by unregistered

Code: Select all

7  bit  0
---- ----
Rxxx xxxD
|       |
|       +- Data bit to be shifted into shift register, LSB first
+--------- 1: Reset shift register and write Control with (Control OR $0C),
              locking PRG ROM at $C000-$FFFF to the last bank.
When I come across something like this when looking through nes mappers on the nesdev wiki I always become confused. It looks like there is something there to write in a byte. But the bin is 8kb or something like that... and so I wonder if every byte in those 8kb should be setup in that form... but then I think that doesn't make sense... why would they require every byte to be like that? :?

Re: 8x16 sprite is really a 16x32 pixel image?

Posted: Fri Dec 14, 2012 7:20 pm
by 3gengames
That's MMC1. Mapper 1. It uses four 5-bit registers. You write the registers 1 bit at a time. Bit 7 is the reset bit and automatically assigns a few registers the default way. But you write the 5 bits of each register with data bit 0. You basically LDA with a number less then $80 (Because 80 will have bit 7 set, and will reset it, you don't want that when programming it) and you basically just STA (Memory region of the register you want to write: $8xxx,$Axxx,$Cxxx,$Exxx) and LSR.

Code: Select all

...
LDA #$[ValueToWriteMMC1]
STA $8000 ;1st write
LSR A
STA $8000 ;2nd write
LSR A
STA $8000 ;3rd write
LSR A
STA $8000 ;4th write
LSR A
STA $8000 ;Register NOW is programmed and updated.
...
For MMC1, the last write also finally selects which register to update, so you can write any places you want above $8000 as long as the last write goes where you want it.

Re: 8x16 sprite is really a 16x32 pixel image?

Posted: Fri Dec 14, 2012 7:46 pm
by tokumaru
unregistered wrote:the bin is 8kb or something like that
What bin are you talking about?

Anyway, those schematics show you how the mapper interprets writes to its registers, they have nothing to do with how data is set up. You know when you write to $2000 (one of the NES registers) and some bits select the active name table, another bit selects whether NMIs will happen, and so on? Mapper registers are just like that too. In the case of the MMC1, you have to write to the registers like 3gengames said.

Re: 8x16 sprite is really a 16x32 pixel image?

Posted: Fri Dec 14, 2012 8:37 pm
by unregistered
tokumaru wrote:
unregistered wrote:the bin is 8kb or something like that
What bin are you talking about?
Sorry... bank... an 8kb or a 16kb bank.

Lets say we are trying to use an 8kb register that is listed as $C000-$DFFF. How do you use it... write to it... it starts at $C000 so I could set that register with something like

Code: Select all

lda #00001011
sta $C000
and then how could I write 8kb of data to $C000-$DFFF?

Re: 8x16 sprite is really a 16x32 pixel image?

Posted: Fri Dec 14, 2012 9:18 pm
by tokumaru
unregistered wrote:Lets say we are trying to use an 8kb register
There's no such thing as an "8kb register".
that is listed as $C000-$DFFF.
This just means that the register can be accessed in any address between $C000 and $DFFF: writing to $CF8B is the same thing as writing to $DD0F, it doesn't matter. The register is mirrored across that range of memory, but it's still 1 register.
How do you use it... write to it... it starts at $C000 so I could set that register with something like

Code: Select all

lda #00001011
sta $C000
That's exactly it, but you could have used any address between $C000 and $DFFF.
and then how could I write 8kb of data to $C000-$DFFF?
There's no need to do this.

Re: 8x16 sprite is really a 16x32 pixel image?

Posted: Fri Dec 14, 2012 9:25 pm
by 3gengames
It's not right, you have to shift and store it 5 times, remember that! And only the last right matters, but don't worry about that, just write the register you need 5 times.

But yeah, what does copying 8KB of data to ROM? You can't over write ROM. It won't do anything. To switch more ROM data in, it basically looks at the address lines when read, and switches them! So if the ROM is in 8000-BFFF, it will "spit out" the new data that goes in that area. When it's C000-FFFF, it will spit out whatever it is assigned to put out there. that's how mappers work. All their locations they change is different, though. This example is for an MMC1, which seperates it into a 16KB "data" bank and then a 16KB "fixed" bank that can't be moved.

Also, worth noting: when mappers are present, they "consume" the WRITES to the ROM. When read, the mapper doesn't do anything except let the CPU look at the ROM.