It is currently Thu Nov 23, 2017 1:31 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 1386 posts ]  Go to page Previous  1 ... 14, 15, 16, 17, 18, 19, 20 ... 93  Next
Author Message
 Post subject:
PostPosted: Mon Aug 22, 2011 6:47 pm 
Offline
Formerly 65024U

Joined: Sat Mar 27, 2010 12:57 pm
Posts: 2257
If you make the first byte a BRANCH to the part of the program you want, you can just so JMP Label and it'll run the code from RAM. :)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 22, 2011 7:13 pm 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1036
Okay. Here's a quick crash course.

So this is what an assembler does: It creates a sequence of bytes based on the instructions you give it.

Code:
reset:
     sei
     ldx #$00


becomes $78, $A2, $00. This is rom. If you opened your assembled rom in a hex editor and searched for this byte sequence you would find it. A guide like this: http://www.obelisk.demon.co.uk/6502/reference.html

Tells you what byte each instruction is assembled as, but that is not that important.

The next thing to know, is a label doesn't actually take any rom. What takes up space are references to it. In the code above, reset takes no rom. References to it are actually stored with the instruction.

So this:
Code:
reset:
     sei
     ldx #$00
     lda reset

would be assembled as
$78, $A2, $00, $AD, (low byte of reset), (high byte of reset).

All these bytes are actually part of your games binary (the .nes rom), so they are rom. To further bring this home, you can actually load an instruction's opcode. Remember how I said sei becomes $78?

So what do you think is stored in the accumulator when I lda reset in the code above? $78. lda reset+1? $A2.

When you directly load a number (lda #$00), the actual number (here it's 0) is stored in rom. $A9, $00 would be what is assembled. When you're referring to an address, you don't include the # part.

RAM is $0000-$07FF. Whenever you load a number from any of those locations, you're loading from RAM. These numbers can be changed. To put actual code in RAM is easy. You just look up the opcodes. Remember the byte stream of the code above?

$78, $A2, $00 was sei, ldx #$00

Code:
     lda #$78
     sta $00
     lda #$A2
     sta $01
     lda #$00
     sta $02
     jmp $0000

This stores code into RAM, then jmps there and runs it. The NES CPU makes no distinction between RAM and ROM when it's running through instructions.

RAM can't be changed before the program is run. If you want a location in RAM to be a certain number, you need to set it to that number at startup. It's as easy as loading the number you want, and storing it there. If you want to load the number from rom, you can incbin a byte stream, and load each value then store it in RAM, but I just use immediate addressing. What I think is being suggested to you is something like this:

You want ram locations $00, $01, $02, $03 to contain $F3, $FD, $08, $23 respectively. So you create a binary file that contains the bytes $F3, $FD, $08, and $23.

Then you incbin that file after an address.

Code:
zeropageinitialvalues:  incbin "zeropagebinary.bin"


Then you run code like what 3gengames wrote.

For reference, I'd just do this:
Code:
     lda #$F3
     sta $00
     lda #$FD
     sta $01
     lda #$08
     sta $02
     lda #$23
     sta $03

since it's easier to change a number, and you won't necessarily be storing numbers so sequentially.

If I were you, I would try to read and understand thing like the difference between lda #$00 and lda $00 before doing anything else. I might also try to completely rewrite whatever you've got, since if you didn't know this stuff, it has gotta be messy.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 22, 2011 7:18 pm 
Offline
Formerly 65024U

Joined: Sat Mar 27, 2010 12:57 pm
Posts: 2257
And also, I said use a branch because while you can only go about 127 bytes in either direction, the position doesn't matter wherever it is, while jumps will ALWAYS goto where it was compiled to go to weather it was moved or not.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 22, 2011 8:01 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10118
Location: Rio de Janeiro - Brazil
unregistered, you appear to be very lost, and not clear enough about what you want.

RAM is where your variables (i.e. dynamic data) sit. Variables are values that will change as the program runs, such as the positions of objects, number of lives, things like that. RAM is always "empty" (it's not really empty, but since its contents are somewhat random we should think of it as empty, although the correct term is "uninitialized") when the NES first starts. Before using our variables, we must initialize them.

When you do this:

Code:
enum $0000

currControllerButtons .dsb 1
lastControllerButtons .dsb 1

You are just telling the assembler where your variables should be stored. currControllerButtons will be at memory location $0000 and lastControllerButtons will be at memory location $0001. This simply declares the variables but they will be uninitiated when the program starts, so you have to initialize them yourself in the code. Nobody is gonna do it for you. So in order to do what you want you have to first declare the variables:

Code:
enum $0000

;(...)
oX .dsb 1
oY .dsb 1

And then, before using those variables in the program you have to initialize them:

Code:
   lda #$8b
   sta oX
   sta oY


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 22, 2011 9:15 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 803
Location: cypress, texas
Thank you everyone for helping.

tokumaru wrote:
unregistered, you appear to be very lost, and not clear enough about what you want.

RAM is where your variables (i.e. dynamic data) sit. Variables are values that will change as the program runs, such as the positions of objects, number of lives, things like that. RAM is always "empty" (it's not really empty, but since its contents are somewhat random we should think of it as empty, although the correct term is "uninitialized") when the NES first starts. Before using our variables, we must initialize them.

When you do this:

Code:
enum $0000

currControllerButtons .dsb 1
lastControllerButtons .dsb 1

You are just telling the assembler where your variables should be stored. currControllerButtons will be at memory location $0000 and lastControllerButtons will be at memory location $0001. This simply declares the variables but they will be uninitiated when the program starts, so you have to initialize them yourself in the code. Nobody is gonna do it for you. So in order to do what you want you have to first declare the variables:

Code:
enum $0000

;(...)
oX .dsb 1
oY .dsb 1

And then, before using those variables in the program you have to initialize them:

Code:
   lda #$8b
   sta oX
   sta oY


I understand at least most of that, but for this code:
Quote:
oX .dsb 1,#$8b
How could one get that code to work successfully? Why doesn't oX equal #$8b? Those are the two questions that went through my head... I'm sorry for my muddiness tonight. My time sheet says I've worked over 10 hours on the "game" today... too long... time to sleep.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 22, 2011 9:17 pm 
Offline
Formerly 65024U

Joined: Sat Mar 27, 2010 12:57 pm
Posts: 2257
LDA #$NUMBER
STA Label

Wil make it equal what you need it to, you HAVE TO do that.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 22, 2011 10:01 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10118
Location: Rio de Janeiro - Brazil
unregistered wrote:
Quote:
oX .dsb 1,#$8b
How could one get that code to work successfully?

Forget about this code, this is not how you do it! You simply can't declare the variable and give it a value at the same time, in assembly this is impossible (if someone mentions machines that load code into RAM only to confuse unregistered even more, I'll kill you). This has to be done in two steps: first declare the variable and later in the code you give it a value.

Quote:
Why doesn't oX equal #$8b?

Because RAM is uninitialized on start up, period. There's no way to change that. No matter what value you try to assign it, the variable will always contain an unpredictable value on start up, this is just how RAM works. You absolutely must use LDA / STA to assign values to your variables.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 22, 2011 11:39 pm 
Offline
User avatar

Joined: Sun Jul 31, 2011 11:53 am
Posts: 10
Location: Canada
I'll do my take on this.

Imagine a big deal of equally-sized boxes, like at a post office.

Image
That's RAM.

When the "world starts", they're all empty. Completely empty, with nothing in them*. All the boxes are numbered, of course, but these numbers... are not terribly helpful. What we need are some labels. So, we take out the dymo-tape...
Image

...and start labeling! In ASM6, when you do .dsb and .dsw in the .enum range of $0000-$07FF, this is exactly what you're doing: labeling. That way, when you get your instructions, they can be written in the form "put this letter in the box for Mr. Howe" as opposed to "put this letter in the 53rd box." Note that you can reserve multiple boxes this way.

Of course, the act of putting a letter in to the box doesn't just happen. You have to do it yourself! The world starts and all the boxes are empty (or "uninitialiazed" as tokumaru pointed out).

As before, in your initiation code before any of the actual action happens, just load whatever value into the accumulator (LDA #letter) you want and then store it in the RAM (sta MR_HOWE).

Finally note that .dsb and .dsw are general purpose and can be used to flood the ROM (the part of the game that is "written in stone") with values. That's what you're trying to do in RAM but this operation only works for ROM. In other words, that use of those directives only works on addresses $8000-$FFFF (or if you use more than one PRG bank and/or a mapper, whatever is applicable then).

* - not necessarily true; may have garbage values that are not zero. Check standard init code. The samples you'll find have a place to reset all RAM to zero.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 23, 2011 5:30 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19252
Location: NE Indiana, USA (NTSC)
tokumaru wrote:
You simply can't declare the variable and give it a value at the same time, in assembly this is impossible (if someone mentions machines that load code into RAM only to confuse unregistered even more, I'll kill you).

Load and run addresses for segment ".DATA". Kill Ullrich von Bassewitz.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 23, 2011 6:07 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10118
Location: Rio de Janeiro - Brazil
That's a very good analogy, booker. Hopefully this ought to get message across.

BTW, tepples, I knew you'd be the one to do it.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 23, 2011 6:42 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 803
Location: cypress, texas
Ah! Yes, booker, great analogy! Thank you so much! :D It really helped me recieve the entire message that yall were trying to give me! RAM is not ROM, it always starts uninitalized. :)

tokumaru, my friend, please don't kill tepples. : ) I didn't follow his link. : )


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 23, 2011 8:13 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 803
Location: cypress, texas
ahhh, the girl starts at (#$8b, #$8b) now!!!!!!!!!!!!!!!!!!! Tomorrow is going to be great! S cr oll in g!!! :)


Top
 Profile  
 
 Post subject:
PostPosted: Sat Aug 27, 2011 11:59 am 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 803
Location: cypress, texas
Ok, so I'm at the point now where I'm tryiing to write the code. My first goal is to get the screen to scroll to the next nametable as our character makes her way across the floor she starts on. This is susposed to be an easy goal to achieve. So far:
1.) I've set the PPU to mirror the nametables vertically.
2.) Both nametables have been set up correctly.
3.) Our lady character moves forward and backward very easily because the sound really works now.

The next step to reach my goal is to check if the lady character is far enough over to the right of the screen (then scrollling starts). I'm going to use an iterative construct to acomplish that. Is scroll always at the bottom left corner of the screen? If scroll is incremented every frame the screen scrolls over to the left. If the screen can make it over to 255 most of all of the second nametable would be shown. But you have to switch which nametable is on the left to get the rest of the second nametable to appear. :?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Aug 27, 2011 12:24 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19252
Location: NE Indiana, USA (NTSC)
The X,Y coordinate in the scroll register is that of the pixel at the top left corner of the screen, which does happen to be more or less equivalent to the bottom left corner but only in single-screen or vertical mirroring. To switch which nametable is at the top left corner, use bits 1 and 0 of PPUCTRL ($2000). One might think of these as the high bits of the scroll register.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Aug 27, 2011 4:08 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 803
Location: cypress, texas
I still don't understand why does the nametable on the left have to be switched for the right side of the second nametable to appear? I stopped my scroll at 255 and it is already showing most all of the second nametable. I'm so confused. :?

Thank you for reminding me it's the top left pixel! :D That helps! And it's nice to know that I can think of it being the bottom left corner because I'm not horizontally mirroring.

Here, bunnyboy wrote:
To set the starting nametable, change bit 0 of the PPU control register at $2000. Clearing it to 0 will put nametables 0 and 2 on the left side of the screen with 1 and 3 to the right. Setting it to 1 will put 1 and 3 on the left, and 0 and 2 on the right.

tepples wrote:
To switch which nametable is at the top left corner, use bits 1 and 0 of PPUCTRL ($2000).

So setting bits 1 and 0 of PPUCTRL to 10 will put nametables 2 and 0 on the left and 3 and 1 to the right? And setting PPUCTRL to xxxxxx11 will put nametables 3 and 1 on the left and 2 and 0 on the right? :)


Last edited by unregistered on Sat Aug 27, 2011 4:37 pm, edited 1 time in total.

Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1386 posts ]  Go to page Previous  1 ... 14, 15, 16, 17, 18, 19, 20 ... 93  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 4 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