top of page
Search

[48] 2nd Attempt at the NES

  • Writer: Conlan Walker
    Conlan Walker
  • Sep 9, 2022
  • 5 min read

I told myself I wouldn't show much of this until I can put something on the screen, and this week I was able to to that, so here it is.


For a little over three weeks, I've been trying to learn cc65, and its assembler ca65.

cc65 is a C compiler that targets 6502-based systems, like the NES, and ca65 is a 6502 assembler.

I wanted to make at least some part of whatever NES project I make in C, because coding in assembly is usually painful. The last time I tried making something for the NES in pure 6502, this is about as far as I got:

It's basically a reset routine with a very short vblank interrupt routine that makes the screen change color every second or so.



I was alright with making more expensive routines in assembly, as long as I could call them as a function in C. The only problem is that the documentation for cc65, ca65, and the rest of the tools included in the cc65 package, is probably the worst that I've ever seen.

ree

I probably could've gotten something working in like a week if they just explained things properly.

I really shouldn't have to explain that I shouldn't have to look at old bulletin boards, other people's projects, and the source code for cc65 itself to figure out how all of this works.



Well, I've put most most of the annoying stuff behind me, so here's the progression of whatever it is I'm making. The latter half of the following uses C, but the former is just 6502 (also a bit of Python but that doesn't count.)

Speaking of Python, I made this script which I use as a sort of crude build tool.

ree


ree

This is the first sprite I was able to put on the screen.


It's not a video yet because it doesn't have to be.

It's an 8x8 grayscale amogus that stays in one place.










ree

I haven't yet made, or made use of tools to aid in making sprites easier, so I've been making them like this.

Each sprite is actually a 16 byte thing of 2 8-bit by 8-bit planes, which make up a 2 bit

image.


The NES is considered an 8-bit console, because the 6502's data width is 8-bit,

but the pixels of the graphics are actually made up of 2 bit indexes of a limited selection of palette colors.


This one moves, but I messed up the scaling and resolution, so it's a blurry 256x240 video:



Earlier I said that I wanted to bind 6502 routines to C, so I can conveniently call it as a function. I wanted to make a sine and cosine function, which my most accounts is a pretty process-heavy thing. A lot of that can be alleviated by using a lookup table, which is kinda the only realistic way to implement one.

ree

Nobody looks at code, but I'll be asked about it if I don't show it.

ree

All of that can be called as a C function, like this.

Kinda neat.

Here's the first test I did using it (now 768x720 instead of poorly-scaled 256x240):



At first, cos wasn't working properly, so this is the first successful use of it:

I also gave the amogus some palette colors.



This is about where I started using C as well, and to try out the new library routines I made, I made the amogus move around with subpixel precision:

To reliably change palettes as shown above, you'll likely need to do it in assembly,

as C is a tad too abstracted to upload data to video memory by itself.

On the NES, you can't access video memory directly. As such, editing the background involves a number of steps. Since I didn't have a 6502 routine that could upload a palette to video memory, I needed to embed 6502 into c with inline assembly statements.

ree

It's really ugly.

In the image shown left, you see, commented out, the original __asm__ statements used.


Shown below that, are the C functions they later turned into.











After this, I wanted to put some text on-screen, but that's a lot easier said than done.

First though, I needed a bitmap font.

I found one that was in an acceptable format, but when I put it in assembler syntax, the text characters showed up horizontally flipped.

ree
ree

To flip them back the right way, I needed to reverse their bit order. The problem is that manually flipping bit order of a hexadecimal number before putting it back as a hexadecimal number would take a biblical amount of time. So I made a script that does the heavy lifting:

ree

Now it works correctly.

ree
ree

Shown left is what the script outputs, and the graphics as seen within the NES ROM is shown above.



The memory mapper, or type of NES game I'm targeting is called NROM. It's the simplest NES game you can possibly make, allowing up to only a 40kB ROM. It's the largest amount of ROM the NES can see without doing some complicted memory bank switching stuff.


Here's an example of two NROM games, and how they store and handle text.

Super Mario Bros. is the more popular of the two examples. It only allows enough graphics space for decimal numbers, an all-uppercase alphabet, and a couple of other things:

ree

Micro Mages on the other hand, has its graphics usage very strictly planned out, including only the text characters that the game actually uses:

ree

It's a shame that the physical release of Micro Mages was very limited, likely due to the proprietary DRM chip used to block unlicensed games.



Here is where I started running out of time, so I made something quickly that looked cool so I could start writing this post.

Basically, I made the amogus turn to grayscale and move around faster when the B button was pressed. I also change the background tile for visual reference, and added 4 stars that cycle palette colors every frame and move around.

Here's the C code responsible for that. It's not very optimized.

ree

Next time I'd like to finish being able to write text to the background, maybe implement some kind of scrolling capability, and maybe some audio.


I was going to make some lengthy explanation about how the NES handles backgrounds but it is now 3 AM and I'd like to be a functioning member of society when I wake up.

So, here's a couple of examples of what scrolling looks like under the hood.

Here's a visual demo I found on the Nesdev wiki:

ree

Finally, this is a video I took of Super Mario Bros. while messing with background settings.

It shows what the offscreen scroll seam looks like (which I turned into a gif for some reason):

ree

The assembly portion of my work is too big to composite a screenshot of in a reasonable amount of time, so here's a Pastebin link to it: https://pastebin.com/W9BiyhHi

That's it for this week.

 
 
 

Comments


bottom of page