It is currently Fri Nov 17, 2017 2:32 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 1385 posts ]  Go to page Previous  1 ... 53, 54, 55, 56, 57, 58, 59 ... 93  Next
Author Message
PostPosted: Mon Dec 10, 2012 9:57 pm 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1035
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:
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:
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 :(

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
PostPosted: Tue Dec 11, 2012 12:18 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 802
Location: cypress, texas
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:
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:
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:
;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:
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.


Last edited by unregistered on Tue Dec 11, 2012 1:26 pm, edited 2 times in total.

Top
 Profile  
 
PostPosted: Tue Dec 11, 2012 1:07 pm 
Offline
Formerly 65024U

Joined: Sat Mar 27, 2010 12:57 pm
Posts: 2257
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.


Top
 Profile  
 
PostPosted: Tue Dec 11, 2012 1:44 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 802
Location: cypress, texas
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.


Top
 Profile  
 
PostPosted: Tue Dec 11, 2012 4:43 pm 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1035
Quote:
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:
.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:
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:
   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.

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
PostPosted: Wed Dec 12, 2012 4:50 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 802
Location: cypress, texas
(this page) wrote:
If the Z flag is 0, then A <> NUM and BNE will branch
Please help me understand what <> means?


Top
 Profile  
 
PostPosted: Wed Dec 12, 2012 5:28 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10112
Location: Rio de Janeiro - Brazil
unregistered wrote:
what <> means

Different.


Top
 Profile  
 
PostPosted: Wed Dec 12, 2012 5:31 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 802
Location: cypress, texas
tokumaru wrote:
unregistered wrote:
what <> means

Different.

THANK YOU TOKUMARU!!! :D


Top
 Profile  
 
PostPosted: Wed Dec 12, 2012 6:08 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 802
Location: cypress, texas
Kasumi wrote:
Quote:
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:
.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:
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:
   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.


Top
 Profile  
 
PostPosted: Fri Dec 14, 2012 6:41 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 802
Location: cypress, texas
Code:
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? :?


Top
 Profile  
 
PostPosted: Fri Dec 14, 2012 7:20 pm 
Offline
Formerly 65024U

Joined: Sat Mar 27, 2010 12:57 pm
Posts: 2257
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:
...
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.


Last edited by 3gengames on Fri Dec 14, 2012 7:50 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Fri Dec 14, 2012 7:46 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10112
Location: Rio de Janeiro - Brazil
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.


Top
 Profile  
 
PostPosted: Fri Dec 14, 2012 8:37 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 802
Location: cypress, texas
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:
lda #00001011
sta $C000

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


Top
 Profile  
 
PostPosted: Fri Dec 14, 2012 9:18 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10112
Location: Rio de Janeiro - Brazil
unregistered wrote:
Lets say we are trying to use an 8kb register

There's no such thing as an "8kb register".

Quote:
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.

Quote:
How do you use it... write to it... it starts at $C000 so I could set that register with something like
Code:
lda #00001011
sta $C000

That's exactly it, but you could have used any address between $C000 and $DFFF.

Quote:
and then how could I write 8kb of data to $C000-$DFFF?

There's no need to do this.


Top
 Profile  
 
PostPosted: Fri Dec 14, 2012 9:25 pm 
Offline
Formerly 65024U

Joined: Sat Mar 27, 2010 12:57 pm
Posts: 2257
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.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1385 posts ]  Go to page Previous  1 ... 53, 54, 55, 56, 57, 58, 59 ... 93  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 guests


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

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group