Thursday, September 29, 2016

NESDev - Hardware Implementation

I'm taking a small break from the Nerdy Nights tutorials and looking ahead to the hardware implementation of this project.  It has been my understanding that in order for me to write my own code onto a cartridge's ROM chip, I would need to get my hands on an EPROM programmer.  Thankfully, the University I study at happened to have one:


I spent a few hours with my professor teaching ourselves how it worked using a GAL chip to create some basic logic gates.  Fortunately, even as outdated as this programmer is, there was still software available for it online for Windows XP (at the verrrry bottom of the download list).  It took some effort before we were able to get the programmer into a working state.


 Thankfully, my research brought me to a a great "how-to" article on the ROM programming process by The Poor Student Hobbyist.  It looks as though the process of actually programming ROM chips and adding them to the cartridge PCB will be quite simple; the trick will be determining what size EPROM chips I will need for my CHR and PRG files.  It looks as though 128k and 32k size chips were popular for most NES cartridges at the time (source).  Which one I will need will naturally depend on the size of my game.  Either way, most of the EPROM chips used in these cartridges are compatible with this programmer, so I should not face any issues with equipment.

However, the concept of mappers are coming up again.  It might be time to write about them, either in an edit to this post or the next one.

Back to programming.

-JWest


Wednesday, September 21, 2016

NESDev - Dev Environment

This will be a little side post to talk about my current set up for working on this project.

Currently, I have 3 machines I plan on using:
  • Home Desktop
    • Running Windows 10, I use this machine for mostly gaming, browsing, and homework assignments.  
    • As the software required to complete the Nerdy Nights tutorial is intended for windows usage, I have had no issues running them on this machine (dated as it may be).
  • Macook Pro
    • The laptop I carry everywhere.  It is currently running on El Capitan (10.11.3) and is primarily used for browsing, blogging, photography, and programming.
    • Making the NESASM assembler work proved to take a little more effort to get running on the Macbook, but it is do-able.  I am having trouble with FCEUX, however.  If I get it working I will add an update, but I may wind up getting stuck with NEStopia...  I will add a footnote to the bottom of this post to share how I installed the software.
  • Acer Netbook
    • This little machine can not run anything above Windows XP.  I figured I would keep it as a backup to use the software in case I had issues with working on the macbook or the desktop.
As I am obviously looking to make my work as portable as possible, I am exploring the best method for storing files.  Currently I am just sticking to dropbox for any of the Nerdy Nights sample code, ans it will allow me to make sure that the software is working in a similar fashion across all platforms.  When I actually start building my own game, I am fairly certain it will be kept on github.

I pulled NESASM from the from cesarparent's repo.


Saturday, September 17, 2016

NESDev - Color Palettes

Since my last post, I have added a few more resources to my bibliography (which will be a separate post at the end of the project).  I recently received the book "I am Error" by Nathan Altice in the mail, and it so far has been a fantastic read.  It dives into the hardware or the NES and Famicom systems pretty early on, so I will probably reference the book a bit more in future posts.

I will also be cross-referencing a lot of terms and concepts from the "Nerdy Nights" tutorials with info from the NesDev Wiki.  As these tutorials are meant to sort of get you programming fairly quickly, they gloss over a lot of the details as to the inner workings of the hardware.  Hopefully my posts will be able to help make a bridge between the code samples and the interactions with the processors and memory.

Now then...

Color Palettes

  • There are essentially 2 groupings of color palettes, one for the background and one for sprites.
    • These 2 groupings each contain 8 separate color palettes (4 bytes in size).  Although each palette is 4 bytes in size, only 3 different colors could be stored in each palette, as you will see in the table below.
    • The PPU addresses start at $3F00 (background) and $3F10 (sprites).  The table of these values are listed below.  Note that some addresses (like $3F04, $3F09, etc.) are skipped.  These addresses contain either a) the common background color, shared in each background palette or b) transparency, used for sprites in each sprite palette
Courtesy of wiki.nesdev.com

  • The NES PPU had a total of 64 colors you could choose from, but was limited to only displaying 25 different colors on the screen at any one time.
    • This 25 color limit is broken up "4 palettes x 3 colors = 12 for sprites, 4 palettes x 3 colors = 12 for background tiles, 1 for background" (thanks Noel Berry).
Moving over to the programming...


Courtesy of Nerdy Nights - Week 4.  Each hex value represents one of the usable 64 colors in the PPU.

  • When writing colors into the background/sprite palettes, the appropriate address must be set into the PPU address $2006.  For example, passing $3F00 to $2006 would allow you to add colors to the background palette.  Each port must be written into $2006 twice, writing the high byte first, then for the low byte.  This can best be demonstrated by the Nerdy Nights code snippet below.

LDA $2002 ; read PPU status to reset the high/low latch to high
LDA #$3F
STA $2006 ; write the high byte of $3F10 address
LDA #$10
STA $2006 ; write the low byte of $3F10 address

In this case, the tutorial will be setting the color palette for sprites ($3F10).

  • AT this point, the PPU is set to start taking color values for its sprite palette.  As pointed out in the tutorial, you can load them one by one into $2007, where the PPU will automatically increment the palette address after each write to $2007.

  LDA #$32   ;code for light blueish
  STA $2007  ;write to PPU $3F10
  LDA #$14   ;code for pinkish
  STA $2007  ;write to PPU $3F11
  LDA #$2A   ;code for greenish
  STA $2007  ;write to PPU $3F12
  LDA #$16   ;code for redish
  STA $2007  ;write to PPU $3F13

Thankfully, "bunnyboy" points out that a much easier way to go about this is to create a ".db directive"...


PaletteData:
  .db $0F,$31,$32,$33,$0F,$35,$36,$37,$0F,$39,$3A,$3B,$0F,$3D,$3E,$0F  ;background palette data
  .db $0F,$1C,$15,$14,$0F,$02,$38,$3C,$0F,$1C,$15,$14,$0F,$02,$38,$3C  ;sprite palette data

A .db directive essentially works like the arrays of modern day programming, storing a large group of values into one place.  This can be combined with the use of the X Index register, which allows the program to step through each byte of data individually.

  LDX #$00                ; start out at 0
LoadPalettesLoop:
  LDA PaletteData, x      ; load data from address (PaletteData + the value in x)
                          ; 1st time through loop it will load PaletteData+0
                          ; 2nd time through loop it will load PaletteData+1
                          ; 3rd time through loop it will load PaletteData+2
                          ; etc
  STA $2007               ; write to PPU
  INX                     ; X = X + 1
  CPX #$20                ; Compare X to hex $20, decimal 32
  BNE LoadPalettesLoop    ; Branch to LoadPalettesLoop if compare was Not Equal to zero
                          ; if compare was equal to 32, keep going down

Once the above code finishes its application, the color palette is set up and ready to go.

The next post will go into more detail about the second part of "Nerdy Nights - Week 4": Sprites.  Seeing as how much information was put into a single post for color palettes, I may save the Sprites post for a later day this week.

-JWest

Sunday, September 4, 2016

NESDEV - Assembly

I originally started this post a little more than 3 months ago.  Two things have happened since...
  • Not long after starting, I realized how sick I was of coding in Assembly (a result of my Computer Engineering Technology degree).  I had abandoned this project to simply focus on games, making small projects in Unity and Unreal.
  • A few days ago, I received approval to create a fully functioning NES cartridge as my Senior Project.  Hence, I am putting Unreal and Unity back on the shelf to put more focus back onto this project.
Hopefully, the result of the above events will result in a blog post AT LEAST once a week (as I will have to attend class to work on it anyway.  The ultimate goal now is to (hopefully) design an original game, and look into the equipment required to write it onto a cartridge, and write a paper reviewing my research and methodology.

--- Original Post Below ---

This post will be based upon Week 3 of the Nerdy Nights Tutorial, as well as diving further into the 6052 processor.  As I already have some familiarity with assembly programming, I may skip over some of the basics.  If I somehow manage to get people who want to know more, I'll update.

The 6052 Processor

The memory addresses of the 6052 processor are divided up as such:
  • $0000 - $0800 = Internal RAM
  • $2000 - $2007 = PPU Access Ports
  • $4000 - $4017 = Ausio and Controller Access Ports
  • $6000 - $7FFF = Optional WRAM (read from cart)
  • $8000 - $FFFF = ROM (read from cart)
The last set of addresses ($8000-$FFFF) will store the bulk of our code.

Like other microprocessors during this time, the 6052 has 3 key 8-bit registers that will no doubt be used frequently: Accumulator (A), and Index Registers X & Y. The accumulator is typically used to store data and perform basic math operations, while the two indexes are ofthen used to keep track of loops, counting, or accessing memory.  There is also a status register that hold information about the most previous instruction the CPU performed.

Assembly Code Structure

 This part of the post may require some research before I post any notes.  It appears for the purpose of emulation, we will be using an assembler known as NESASM3.  Below will be a few new concepts  that will be required in each programfor emulation.

 I have highlighted a few topics topics so that I may come back to them and add more info.
  • iNES Header
    • iNES is a NES emulator
    • This 16-byte header provides all the necessary information to the emulator concerning the specs of the game, including mapping, graphics mirroring, and PGR/CHR sizes.
    • This is not necessary for real hardware usage.
  • Banking
    • The 6502 processor breaks the 32kB limit of code into 8kB "banks".  I will need to revisit this in the future to understand the importance of using these banks.
  •  Vectors
    • a.k.s "Interrupts" - There are 3 occurrences when the NES will interrupt your program to jump to a specific point.  Those points are assigned the following tags:
      • NMI Vector: Occurs every frame, PPU is letting the processor know that it is open for graphic updates (enterng the "V Blank"[1] state).
      • RESET Vector:  Called everytime the reset button is hit or when the NES is powered on.
      • IRQ Vector:  Typically controlled by the mapper.  Need more info on this (not being included in Nerdy Nights tutorial). 
    • Each of these interrupts must appear in the PRG code, even if it is not being used.
I am considering scanning my notebook page where I printed off the Nerdy Nights "background.asm" example code and made annotations, as I feel it would be better seeing each of the above code snippets in context.  Maybe I will just make that a separate blog post.

The next Nerdy Nights lesson goes more in-depth on the PPU.  I will save the code overview notebook post until after I share those notes.

Cheers,
-JWest

[1] The "V Blank" state is the period when the PPU refreshed the screen.  I don't recall if I had already clarified that term before this post or not.