Hello, new here, and need best recommandations.

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

DocWaluigean
Posts: 205
Joined: Sun Jun 17, 2018 6:41 pm

Re: Hello, new here, and need best recommandations.

Post by DocWaluigean »

Verrryyy much post and I'm confused easily, when I just want to know if I did the examples of A X Y register right.

But, what is the complete abilities or restrictions differs of A X Y [and other 2 registers?]
User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Re: Hello, new here, and need best recommandations.

Post by Kasumi »

A, X, and Y can all hold a single value in the range of 0 to 255. (Edit: 128 to 255 can optionally be interpreted as -128 to -1.) They can all load their value from and store their value to a specific location in memory.

A value in A can be manipulated in many ways X and Y can't be. (Addition and subtraction of any value, division and multiplication by 2 and other "bitwise operations".) If you wanted to do those things to a value in X or Y, you'd have to transfer them to A first, manipulate them, then transfer them back.

You can add and subtract exactly 1 from the value in X or Y. (A allows for adding and subtracting of any value.)

A also has more power to load and store its value to neighbors of a specific location in memory. If you're familiar with arrays, the value in X and Y can be used as an offset to access a specific array element. Y specifically allows a convenient way to access an array through a pointer. If that doesn't mean anything to you right now, that's totally fine.

The other registers are
1. Program Counter, which a programmer doesn't really work with directly. (JMP directly changes it, I guess...)
2. Stack Pointer, which until one learns a bit more is touched once at the start of the program and then not worked with directly.
3. Processor Status Flags. These are individual bits that are updated after each instruction is run. You can "branch" conditionally based on whether individual bits are true are false, which is basically how "if statements" can be constructed.
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: Hello, new here, and need best recommandations.

Post by unregistered »

DocWaluigean wrote:Verrryyy much post and I'm confused easily, when I just want to know if I did the examples of A X Y register right.
unregistered wrote:

Code: Select all

.enum $0000 ;declare names for variables starting at beginning of the zeropage (location $0000)
  BED .dsb 1 ;BED is now at location $0000
  LAMP .dsb 1 ;LAMP is now at location $0001
.ende ;ends this variable declaration section

...

ROOM:
lda #100 ;yes, this loads the A register with #100 (A = #100)
sta BED ;$0000 = #100

lda #10
sta LAMP ; $0001 = #10

rts ;ends function ROOM
...

I don't have time to use your second part but for the most part it looked ok to me. :)
Sorry DocWaluigean, too much post from me. :(


edited once to add some relevant code in my quote.
DocWaluigean
Posts: 205
Joined: Sun Jun 17, 2018 6:41 pm

Re: Hello, new here, and need best recommandations.

Post by DocWaluigean »

unregistered wrote:
DocWaluigean wrote:Verrryyy much post and I'm confused easily, when I just want to know if I did the examples of A X Y register right.
unregistered wrote:

Code: Select all

.enum $0000 ;declare names for variables starting at beginning of the zeropage (location $0000)
  BED .dsb 1 ;BED is now at location $0000
  LAMP .dsb 1 ;LAMP is now at location $0001
.ende ;ends this variable declaration section

...

ROOM:
lda #100 ;yes, this loads the A register with #100 (A = #100)
sta BED ;$0000 = #100

lda #10
sta LAMP ; $0001 = #10

rts ;ends function ROOM
...

I don't have time to use your second part but for the most part it looked ok to me. :)
Sorry DocWaluigean, too much post from me. :(


edited once to add some relevant code in my quote.
It's alright! I appreciate it though.

I'm going to see something else about it, I'm going toward Week 4 now.
DocWaluigean
Posts: 205
Joined: Sun Jun 17, 2018 6:41 pm

Re: Hello, new here, and need best recommandations.

Post by DocWaluigean »

Ok, I'm still on Week 4 because I just got NES Classic Editions, and I'm loving it so much. The fact I got Mario Adventure from DahrkDaiz made me so happy, I didn't read any at all, just play play play.

Right now, I'm burned out from playing it, and I'm worried if that will affect my concentrations in trying to learn to make NES games. Anyone have tips?
DocWaluigean
Posts: 205
Joined: Sun Jun 17, 2018 6:41 pm

Re: Hello, new here, and need best recommandations.

Post by DocWaluigean »

DocWaluigean wrote:Ok, I'm still on Week 4 because I just got NES Classic Editions, and I'm loving it so much. The fact I got Mario Adventure from DahrkDaiz made me so happy, I didn't read any at all, just play play play.

Right now, I'm burned out from playing it, and I'm worried if that will affect my concentrations in trying to learn to make NES games. Anyone have tips?


After months of no responses of motivations here, I got it back as I saw the NESMaker and the RIKI Japanese home-brew game; it helps me get back in now...

Going to have to re-read the Nerdy Nights again, and this thread again...
DocWaluigean
Posts: 205
Joined: Sun Jun 17, 2018 6:41 pm

Re: Hello, new here, and need best recommandations.

Post by DocWaluigean »

Onto Night 3; This is going to be ridiculous because I may ask so many questions. I will try this one from background.asm in the Nerdy Nights Week 3.

Remember - the only dumb question is the question that remains unasked.

---

Code: Select all

 
  .inesprg 1   ; 1x 16KB PRG code
  .ineschr 1   ; 1x  8KB CHR data
  .inesmap 0   ; mapper 0 = NROM, no bank swapping
  .inesmir 1   ; background mirroring
-So the iNES header is an information. But I'm assuming this ines only works in the ASM6.

-Is there a limit to numbers for each codes beside inesmap? I'm sure you can go up to inesmap 255 something with Namco mapper, Konami mapper, Sunsoft mapper, etc.

-So PRG code is "assign scripts to sprites, by limit"? and CHR data "the amount of sprite and tile banks"? ineschr 1 = 1 bank of tiles/sprites? can it go up to over 128?

-Obviously a good idea to ignore for now, but is there importances for inesmir 1?

---

Universal question: At which part is needed to show the entire gray screen? Up to ines? need bank 0, 1, and 2 to make a correct blank NES?
DocWaluigean
Posts: 205
Joined: Sun Jun 17, 2018 6:41 pm

Re: Hello, new here, and need best recommandations.

Post by DocWaluigean »

Code: Select all

.bank 0
  .org $C000 
RESET:
  SEI          ; disable IRQs
  CLD          ; disable decimal mode
  LDX #$40
  STX $4017    ; disable APU frame IRQ
  LDX #$FF
  TXS          ; Set up stack
  INX          ; now X = 0
  STX $2000    ; disable NMI
  STX $2001    ; disable rendering
  STX $4010    ; disable DMC IRQs

vblankwait1:       ; First wait for vblank to make sure PPU is ready
  BIT $2002
  BPL vblankwait1

clrmem:
  LDA #$00
  STA $0000, x
  STA $0100, x
  STA $0200, x
  STA $0400, x
  STA $0500, x
  STA $0600, x
  STA $0700, x
  LDA #$FE
  STA $0300, x
  INX
  BNE clrmem
   
vblankwait2:      ; Second wait for vblank, PPU is ready after this
  BIT $2002
  BPL vblankwait2


  LDA #%10000000   ;intensify blues
  STA $2001

Forever:
  JMP Forever     ;jump back to Forever, infinite loop
  
 

NMI:
  RTI


-----

-Obviously the $C000 is in the cartridge ROM section, which is fine. But why is it in $C000 instead of $8000, which is more organize than in the middle of those code? I know in some sections, the address represent something for the NES "lever and buttons", like $3F10 - $3F1F is the address section for color palettes. But for the Cartridge ROM, why isn't there an overview for the entire Address beside PPU?

-I been looking further before reading back on Nerdy Nights,
LDX #$40
STX $4017 ; disable APU frame IRQ
LDX #$FF
Why is it arranged like this instead "LDX, LDX, STX"? Obviously high and low power style, but why? For new people, it could mess up a code like this... I don't want to be judgeful, but coding is one of the hardest things I ever got to learn in my life.
DocWaluigean
Posts: 205
Joined: Sun Jun 17, 2018 6:41 pm

Re: Hello, new here, and need best recommandations.

Post by DocWaluigean »

Code: Select all

;;;;;;;;;;;;;;  
  
  
  
  .bank 1
  .org $FFFA     ;first of the three vectors starts here
  .dw NMI        ;when an NMI happens (once per frame if enabled) the 
                   ;processor will jump to the label NMI:
  .dw RESET      ;when the processor first turns on or is reset, it will jump
                   ;to the label RESET:
  .dw 0          ;external interrupt IRQ is not used in this tutorial
  
  
;;;;;;;;;;;;;;  
  
  
  .bank 2
  .org $0000
  .incbin "mario.chr"   ;includes 8KB graphics file from SMB1 
---

Because of "peer pressure" situations, I can't even ask any questions about .dw, .nmi, and other situations.

-------

I know you guys literally sick and tired of hearing this about anyone like me requesting for a private tutor, but there's people like me who has capacities to do something very complex, like 3D modelling, ideas, free-writing storytellings, etc. But can't understand forms of writings and tutorials that keeps backing away from learning NES assembly languages.

As for people who said, "please do some research on your own now.", there's people like me who literally tried to comprehend writings from Bunnyboy, Easy6502, etc. that literally needs help, whose real serious in learning about this stuff. I got lucky on understanding what binary, HEX, and decimals do, and nearly all forms of Codes Layout, but further readings just threw me off with words that I can't put two and two together. I'm even willing to make a tutorial that's more comprehend-able than BunnyBoy if I understand everything.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Hello, new here, and need best recommandations.

Post by tokumaru »

DocWaluigean wrote:-So the iNES header is an information. But I'm assuming this ines only works in the ASM6.
The .ines*** directives only exist in NESASM. In most other assemblers people just create the header using .db/.byte statements. It's also possible to create macros that simulate NESASM's directives.
-Is there a limit to numbers for each codes beside inesmap? I'm sure you can go up to inesmap 255 something with Namco mapper, Konami mapper, Sunsoft mapper, etc.
Mapper numbers are normally assigned by whoever discovers/creates them. The wiki has a list of the most popular mappers: https://wiki.nesdev.com/w/index.php/List_of_mappers

The limits for the other fields will depend on the mapper. Each mapper supports different amounts of PRG and CHR stand use different techniques for bankswitching them.
-So PRG code is "assign scripts to sprites, by limit"?
The PRG field is the amount of PRoGram-ROM, measured in units of 16KB. This is the memory used to hold the game program, the code that the CPU runs to make stuff happen. All the game logic is here, along with all the data used by the game (e.g. levels, music, etc.).
and CHR data "the amount of sprite and tile banks"?
Yes, that's the amount of CHaRacter-ROM, measured in units of 8KB (512 tiles).
ineschr 1 = 1 bank of tiles/sprites? can it go up to over 128?
Don't get too hung up on the term "bank" here, since the size of a bank varies from mapper to mapper. CHR-ROM banks can be any of 8KB, 4KB, 2KB or 1KB, but the INES header always measures the total amount in multiples of 8KB, regardless of the mapper.

How high you can go will depend on the mapper. 128 x 8KB would be 1MB, and not many mappers support that. Another thing to keep in mind is that even though the total amount of tiles can be significantly high, you can't use any tile you want whenever you want, because the NES still only sees a small number of them at a time. The way in which you select which tiles will be usable at any given time will depend on the mapper.
-Obviously a good idea to ignore for now, but is there importances for inesmir 1?
The NES has a virtual background space of 4 screens arranged in a 2x2 grid, but it only has enough memory to hold 2 screens, which means that 2 of those 4 will have to be repeats. The mirroring setting selects whether the screens will repeat horizontally or vertically.
Universal question: At which part is needed to show the entire gray screen? Up to ines?

I don't understand the question. What do you mean by "entire gray screen"?

need bank 0, 1, and 2 to make a correct blank NES?
Memory chips are only manufacred in sizes that are powers of 2 (e.g. 8KB, 16KB, 32KB, 64KB, 128KB, etc.), so you need to have a number of banks that adds up to a power of 2 in order to represent a valid memory chip, even if they are empty.

Do note that NESASM's .bank directive creates banks that are 8KB in size, while the INES header counts banks that are 16KB. So in this case, NESASM banks 0 and 1 would be the one 16KB bank defined via .inesprg, and bank 2 is the one 8KB bank defined via .ineschr.

Like I said, don't focus too much on the work "bank" as used by NESASM and the INES header, because the actual size of the banks is defined by the bankswitching scheme of the mapper you use. Just think of INES banks as units for counting, and NESASM's banks as blocks of 8KB, which won't necessarily be manipulated individually.
Last edited by tokumaru on Sat Aug 11, 2018 11:10 pm, edited 1 time in total.
User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Re: Hello, new here, and need best recommandations.

Post by Kasumi »

Ninja'd by tokumaru, but the information presented is slightly different, so sure, I'll still post.
DocWaluigean wrote:

Code: Select all

 
  .inesprg 1   ; 1x 16KB PRG code
  .ineschr 1   ; 1x  8KB CHR data
  .inesmap 0   ; mapper 0 = NROM, no bank swapping
  .inesmir 1   ; background mirroring
-So the iNES header is an information. But I'm assuming this ines only works in the ASM6.
On an actual NES catridge, hardware dictates behavior. An NES ROM mostly contains the software. Because there are so many different cartridge types with different hardware, an NES ROM also has a 16 byte "header" that describes the hardware so emulators can properly run it.

The .ines commands are for creating this header. They only work with NESASM, not ASM6. In ASM6 you have to build the header manually.
-Is there a limit to numbers for each codes beside inesmap? I'm sure you can go up to inesmap 255 something with Namco mapper, Konami mapper, Sunsoft mapper, etc.
The limit is different for every cartridge type. I don't know of one offhand that allows 255. That's just shy of 4 Megabytes! (16 kilobytes * 255)
-So PRG code is "assign scripts to sprites, by limit"? and CHR data "the amount of sprite and tile banks"? ineschr 1 = 1 bank of tiles/sprites? can it go up to over 128?
PRG is just bytes of data the CPU can easily access. You can store code there, levels/text/music/other data there, or even graphics there. (Assuming you are using CHR RAM.)

CHR is bytes of data the PPU can easily access. The amount of sprite and tile banks is a good way to think about it.
-Obviously a good idea to ignore for now, but is there importances for inesmir 1?
NES has 4 screens worth of "tilemap" laid out in a 2 by 2 square. (That essentially repeats forever.) However, there can only be 2 unique screens usually. The other two are copies or "mirrors".

Super Mario Bros. has the top and bottom rows of the 2by2 square "mirrored" because it scrolls horizontally. This allows it to easily update the level offscreen to the right of the scroll edge.

Ice Climber has the left and right columns of the 2 by 2 square "mirrored" because it scrolls vertically. This allows it to easily update the level offscreen above the top of the scroll edge.

.inesmir 0 denotes Ice Climber Style.
.inesmir 1 denotes Super Mario Bros. style.

Some cartridge types effectively ignore this.

---
Universal question: At which part is needed to show the entire gray screen? Up to ines? need bank 0, 1, and 2 to make a correct blank NES?
You need at least two NESASM banks to create a totally blank ROM, but you will probably want three, yes.

Code: Select all

.inesprg 1
	.ineschr 1
	.inesmir 0
	.inesmap 0

	.code
	.bank 0
	.org $C000

	
	.bank 1
	.org $E000 

	

	.org $FFFA
	.dw 0;This is where you'd put the label where the CPU should jump to when an NMI happens
	.dw 0;This is where you'd put the label where the CPU should jump to when the console is reset
	.dw 0;This is where you'd put the label where the CPU should jump to when an IRW happens

	.bank 2
	.org $0000
Should give you an entirely blank ROM. .org tells the assembler where in memory the bytes that follow are meant to go. $FFFA is where it expects certain addresses. This is how the CPU knows where the game starts on reset, for example. You don't technically need that for a blank ROM, but you may as well have it.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Hello, new here, and need best recommandations.

Post by tokumaru »

DocWaluigean wrote:But why is it in $C000 instead of $8000
Because this is probably a 16KB program, and the NES CPU can see 32KB of code, so the same code appears twice in that space. This means that either $8000 or $C000 will work fine, you can use whichever you like best, because in the end, THE CODE WILL APPEAR AT BOTH ADDRESSES. Most people like to think of the program as being aligned to the upper end of the address space though, because the CPU vectors are traditionally accessed at $FFFA-$FFFF, the very end of the ROM area. But like I said, you can use $8000 as the origin for your 16KB program if you prefer, because the vectors will appear at both $BFFA-$BFFF and $FFFA-$FFFF, where the CPU will actually look for them.
But for the Cartridge ROM, why isn't there an overview for the entire Address beside PPU?
Here's the memory map for the CPU: https://wiki.nesdev.com/w/index.php/CPU_memory_map
LDX #$40
STX $4017 ; disable APU frame IRQ
LDX #$FF
Why is it arranged like this instead "LDX, LDX, STX"?
Because programming is basically moving numbers around and doing math operations on them. For moving data around, we need to use the CPU registers (A, X, Y). We need to send a number/code to the APU, telling it to disable frame IRQs, so we put this number in a register (LDX), and then store that register (STX) in the appropriate APU port. That part is done, we can now use X for other stuff, so we put the next value we'll use in it, $FF, that we'll use to initialize the stack pointer. This is just moving data around. If you mess up the order, you'll end up putting the wrong values in the wrong places.
high and low power style
What is "high and low power style"?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Hello, new here, and need best recommandations.

Post by tokumaru »

DocWaluigean wrote:I'm even willing to make a tutorial that's more comprehend-able than BunnyBoy if I understand everything.
You'd be surprised by how many people have said that, but either "forgot" or just gave up on NES development.

It's not easy to word this stuff in simpler terms, because this really isn't a simple subject. You can't replace terms like registers, mirroring, addressing, etc. by simpler ones because they describe unique things and behaviors that don't necessarily have counterparts that are easier to comprehend. We can EXPLAIN all the terms and behaviors individually so that when you see them at a later time they won't sound like alien concepts, but programming knowledge is something you build progressively, you have to understand one layer before moving on to the next, you can't skip to the topmost layer and expect things to be worded in a way that circumvents everything established in the layers below.
User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Re: Hello, new here, and need best recommandations.

Post by Kasumi »

Tokumaru covered the other post WAY more succinctly than what I was working on. :beer:
Because of "peer pressure" situations, I can't even ask any questions about .dw, .nmi, and other situations.
I think both Tokumaru and I covered this a bit.

.dw will add a 16byte number you give it to the ROM.
.db will add an 8 bit number you give it to the ROM.

I had mentioned that the CPU looks for addresses starting at $FFFA to know where to start executing code in certain situations. There's no further explanation beyond, "That's how the CPU was designed." It has to start some known place or software couldn't be run reliably on it. You can use .dw with a label. So if your code looks like:

Code: Select all

  .org $E000
reset:
  jmp reset

NMI:
  rti
IRQ:
  rti

  .org $FFFA
  .dw NMI
  .dw reset
  .dw IRQ
When you turn the NES on, it will start executing code at $E000. (The reset label.) The NMI (on NES) can happen once every 60th of a second if you have it enabled. This is one thing that allows games on NES to run at a consistent speed.

When a frame is about to start (every 60th of a second) the CPU will stop what it was doing, and go to the address (label) at $FFFA. The RTI will send it back to what it was doing before this happened. The NMI is an "interrupt" (Non Maskable Interrupt). Precisely because it interrupts whatever the CPU was doing and jumps somewhere else. And again, the RTI allows it to return to what it was doing before the interrupt happened.

If some of that doesn't make sense, that's okay for now. You mentioned easy6502. Is there some part you're stuck on in that tutorial? If so, feel free to ask about it. 6502 itself is way easier than the NES hardware, so if you can get working there you might have more progress. There's less to do to get visual output that shows the code is working on the easy6502 website.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Hello, new here, and need best recommandations.

Post by tokumaru »

Kasumi wrote:6502 itself is way easier than the NES hardware, so if you can get working there you might have more progress.
I fully agree.

Back when I started, I only knew how to program in QBASIC, and assembly didn't make any sense to me. Learning about hardware architecture and the NES registers at the same time I was learning assembly ended up being way too confusing, and I actually did give up for a few years.

On my second try, I put the NES aside and studied only 6502 assembly, using a simulator, and I didn't move forward until I understood what every instruction did and I was able to code actual algorithms (multiplication, division, sorting, etc.) in that language. Only then did I try to make an NES ROM again.

You see, talking to the NES is like other kinds of communication. Say you are the manager in a company that makes boxes. You must know how boxes are made, so you can tell the workers what they have to do, and you must speak the same language as the workers, so you can effectively communicate the instructions to them. If you don't speak the same language, and you don't know how to make boxes, it will be extra hard to end up with something that resembles a box in the end.

So yeah, learn assembly first of you can, without the specificities of the NES getting in the way. Then, when you know HOW to communicate, focus on learning WHAT to say to the NES so it does what you want.

And don't forget that in order to make games, you not only need to know the language and the architecture of the environment you're coding for, but also the general concepts of game programming, which are universal to any programming language, such as animation, object management, physics, collision, and so on.
Post Reply