Tuesday, November 29, 2016

NESDev - Overdue Update

 The end of the semester is approximately 3 weeks away, and I realized that I am well overdue for a blog post.

I have opted out of the "Nerdy Nights" tutorial series for the time being, as they have taken on a rather steep learning curve near the last few lessons.  I noticed that the last lesson I covered observed how sprites are loaded into the PPU and onto the screen, so I will try to summarize everything from that point to where the project sits now.


Controller Input

Controller inputs are read through register $4016 for Player 1 and $4017 for Player 2.Each button value is read in a particular order:
    1. A
    2. B
    3. Select
    4. Start
    5. Up
    6. Down
    7. Left
    8. Right
The standard method of reading these values is through a basic loop that is constantly stored into a single byte, as seen from the Nerdy Nights Tutorial here:

ReadController:
  LDA #$01
  STA $4016
  LDA #$00
  STA $4016
  LDX #$08
ReadControllerLoop:
  LDA $4016
  LSR A           ; bit0 -> Carry
  ROL buttons     ; bit0 <- Carry
  DEX
  BNE ReadControllerLoop
  RTS

This code uses the LSR and ROL commands in an interesting manner.  LSR (Logical Shift Right) moves the rightmost bit into the 'carry' position of Accumulator A, then the ROL (Rotate Left) command moves the value in the carry position back into the first bit of the "buttons" directive. Every time a new value read into the "buttons" directive, it scoots the previous value over one bit, until each of the 8 button values fill a whole byte.  As the controller is read in that order with every refresh, those values will be consistently changing.  Then the program can compare each individual bit to jump to a subroutine designated for each button's functionality.

A somewhat uglier way of programming this functionality is by simply laying out each step of the controller reading cycle, like so:

ReadA: 
LDA $4016      
        * code here*
ReadB: 
LDA $4016        ;
        * code here*
ReadSelect: 
LDA $4016       
        * code here*
ReadStart: 
LDA $4016       
        * code here*
ReadUp: 
LDA $4016       
        * code here*
ReadDown: 
LDA $4016       
        * code here*
ReadLeft: 
LDA $4016       
        * code here*
ReadRight: 
LDA $4016       
        * code here*

Order matters.

For the sake of moving forward with the little time I have remaining, I chose to stick to the latter method of controller reading and moved on to adding movement to my own sprites.



While I had hoped to create my sprites in a more "raw" fashion, it seems the most common way to go about creating a chr file is through the use of third-party software.  In my case, I opted to use yy-chr.  This tool simplified the process, creating an environment similar to microsoft paint that featured a grid to match each 8x8 pixel tile.  My wife asked to do the pixel art for my project, below is some of the work she did:


As I am looking to create a very basic 2 player game, I will be using only 
two of the characters she drew up for me.


Sprite Movement

A concept that concerned me was how to make multiple sprites move together as one entity.  It turns out, it's not quite so difficult.  To demonstrate this example I'll use some code snippets from my WIP game.

You of course need to start off by loading the sprites into the PPU registers.  Using a directive for each sprite and a looping structure to load them is the simplest and most straightforward:

sprites:
     ;vert tile attr horiz
; Y - TILE - ATTR - X
.db $80, $00, $00, $80   ;headleft $0200 - $0203
.db $80, $01, $00, $88 ;headright $0204 - $0207
.db $88, $10, $00, $80   ;spine $0208 - $020B
.db $88, $11, $00, $88   ;front $020C - $020F
.db $90, $20, $00, $80 ;back leg $0210 - $0213
.db $90, $21, $00, $88   ;front leg $0214 - $0217

---------------------------------------

LoadSprites:
LDX #$00              ; start at 0
LoadSpritesLoop:
LDA sprites, x        ; load data from address (sprites +  x)
STA $0200, x          ; store into RAM address ($0200 + x)
INX                   ; X = X + 1
CPX #$28              ; Compare X to hex $20, decimal 32
BNE LoadSpritesLoop   ;
LDA #%10000000   ; enable NMI, sprites from Pattern Table 1
STA $2000

LDA #010000   ; enable sprites
STA $2001

The upper snippet of code is how my directives are constructed, while the bottom snippet is the looping structure to load the sprites into memory, which was broken down in a previous post.  The more sprites I add to the directive will naturally result in an expansion of this looping structure. The directive places everything in the appropriate order, and as you can see, the inital X and Y values are put into place.  From here, it is a simple matter of adding or subtracting the value of '1' to those values whenever the left or right button is pushed, making the sprite move left and right.
;;;;;;;;;; HEAD LEFT ;;;;;;;;;;
LDA #%01000000   ; Flip Horizon
STA $0202 ; Data Sprite 1
LDA $0203       ; load sprite X position
CLC ;
SBC #$01 ;
STA $0203         ; Save Sprite 1 X position
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

I have commented this code to reflect what part of the character it will move, in this case the left side of the head.  In this case I am trying to "flip" the sprite by loading the value 01000000 into the data register of that particular sprite.  From there, I have just loaded the current X value, used CLC to ensure the carry bit is clear, and subtracted 1, as moving left is considered a negative movement on the screen.



Up Next

The current issue I am trying to fix is using the PPU's mirroring capability to force the character to face the direction it is heading.  Unfortunately, this is a process I have to figure out on my own.  What I have been doing thus far is checking the position of the front-facing sprite in relation to the back sprites when the left or right buttons are pressed.  If the "back" sprite is in front of the "front" sprite, then the program should jump to a subroutine immediately adding a value of 8 to the front sprite's current X coordinate.  This is my current result:


It appears that the code is acting as it should, but only when the character scrolls off screen and appears on the opposite end (I have left scrolling on as I thought it might add some fun to the game).

Once I fix this issue, here is my potential "TO DO" list:
  • Higher Priority
    • "Jump" code
    • Adding 2nd player
  • If I Have Time
    • Attacking projectiles
    • Registering hits
    • Health
I will probably be ignoring the idea of start screens or even sounds, as I am running low on time for this project.

Wish me luck.




Friday, October 7, 2016

NESDev - Sprites

I'm really overdue for this post.

Week 4 of the Nerdy Nights tutorial covered the NES color palettes as well as a brief introduction to sprites.  Week 5 followed up with more elaboration on sprites and introducing controls.  It was a fair amount of information to take in and understand,and seeing as how I started the lesson 2 weeks ago, I may be scrambling together it all back together again.

For now, I'll just go off the notes I had taken at the time...


Sprites/PPU Review

  • Sprites - non-static graphics that are separate from the background.
    • made up of 8x8 tiles of pixels
    • PPU can hold up to 64 sprites
  • Sprite DMA - "Direct Memory Access"
    • This is apparently a method for transfer sprites into memory, and the way it works is described as "a block of RAM is copied from CPU memory to the PPU sprite memory". 
    • Typically uses addresses $0200-$02FF 
    • I'll be coming back to this one...

Let's break down the code... "sprites.asm"


We left off discussing how the color palette gets loaded into the NES PPU.  Following this in the code structure of sprites.asm is the loading and placement of a single sprite.  The way sprites are loaded in to the PPU is brokem down into 4 specific bytes of data:
  1. Y-Position
  2. Tile number - referencing the pattern table position
  3. Attributes - color and display info
  4. X-Position
The x and y position seems to work on a grid, similar to below:

-- INSERT GRID HERE --


The tile number is in reference to the placement of tiles within the .chr file.  Using FCEUX SP, we can see those values quite clearly:



Lastly, the attributes are adjusted in a similar fashion to the PPUCTRL register discussed previously.  The program sends a string of 8 buts to the last register reserved for this sprite.  Those bits are organized as such (from Nerdy Nights):

  76543210
  |||   ||
  |||   ++- Color Palette of sprite.  Choose which set of 4 from the 16 colors to use
  |||
  ||+------ Priority (0: in front of background; 1: behind background)
  |+------- Flip sprite horizontally
  +-------- Flip sprite vertically

There are essentially 4 steps to loading a sprite into the PPU.  The code snippet included in this weeks tutorial paints this quite simply using 1 byte to center the sprite (#$80), and 1 byte to determine which sprite to place and how it will look (#$00):

  LDA #$80
  STA $0200        ;put sprite 0 in center ($80) of screen vertically
  STA $0203        ;put sprite 0 in center ($80) of screen horizontally
  LDA #$00
  STA $0201        ;tile number = 0
  STA $0202        ;color palette = 0, no flipping

  LDA #%10000000   ; enable NMI, sprites from Pattern Table 0 (PPUCNTRL)
  STA $2000

  LDA #010000   ; no intensify (black background), enable sprites (PPUMASK)
  STA $2001

Notice where the data is being loaded.  As mentioned previously, the Sprite DMA typically uses addresses $0200 - $02FF.  Each sprite that is loaded will use 4 adresses to cover the 4 bytes of data we have mentioned here, hence why this particular sprite is loaded into registers $0200 - $0203.

It is worth noting that this code snippet also loads to PPUCTRL and PPUMASK (last 4 lines).  The comments should speak to themselves as to what the values are controlling.  However, I am finding it useful to keep a reference sheet on hand.

Multiple Sprites

In the following week's lesson, bunnyboy goes into the process of placing multiple sprites into the PPU.  There isn't too much to this, we can apply the same logic used when we loaded color palette data previously.  Storing those 4 values into a .db directive helps keep everything organized:

sprites:
     ;vert tile attr horiz
  .db $80, $32, $00, $80   ;sprite 0
  .db $80, $33, $00, $88   ;sprite 1
  .db $88, $34, $00, $80   ;sprite 2
  .db $88, $35, $00, $88   ;sprite 3

Using the X index, we can apply these bytes of data into the appropriate addresses within $0200-$02FF using a simple loop.


LoadSprites:
  LDX #$00              ; start at 0
LoadSpritesLoop:
  LDA sprites, x        ; load data from address (sprites + x)
  STA $0200, x          ; store into RAM address ($0200 + x)
  INX                   ; X = X + 1
  CPX #$10              ; Compare X to hex $10, decimal 16
  BNE LoadSpritesLoop   ; Branch to LoadSpritesLoop if compare was Not Equal to zero
                        ; if compare was equal to 16, continue down

I've given up on formatting.

This logic should be fairly easy to follow, but just in case, I'll break it down:
  1. Load #$00 into Index X.  As we will be using this register to keep count as we load each individual byte of sprite data, we may as well be starting at 0.
  2. Load the first byte from the sprites .db directive.  As we are starting at 0, value 0 is loaded into Accumulator A ($80, in this case).
  3. Store the loaded byte into $0200.  The reference to accumulator X will result in a step up to the next register once the loop completes and starts again.
  4. Increment X.  This adds #$01 to the number currently stored in index X.  This allows us to step up to the next byte of data in the sprite directory and the next PPU address to store the data in.
  5. Compare X to #$10 and branch back to loop start if they are not equal.  This compares the current index count to the decimal number 16, which is the number of bytes we have stored in the sprite directory.  If we have hit this number, then we have loaded all of our sprites and can move on in the code.

For the next post I will be going into the use on controllers and how they control the movement of these sprites.  I will probably be referring a lot to the information covered in this post.

Cheers,
-JWest

Yes, I have a lot of holes to fill in this post.

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.

Wednesday, May 18, 2016

NESDev - Architecture Overview

As I mentioned in my last post, the majority of this process will simply involve following the "Nerdy Nights" tutorial.  Hopefully, my blog posts won't simply just sound like I'm just repeating everything I read there, but more like I'm reading, understanding, and connecting dots, adding my own research in an attempt to learn more of what I can do with this...

Anyway -


THE NINTENDO ENTERTAINMENT SYSTEM

For the most part, the system is built just like your standard every-day computer.   It features a central processor (CPU), a graphics processor (PPU - P.icture P.rocessing U.int), an audio processor (APU), RAM and ROM.  Granted, not all of these components are actually featured inside of the NES console itself.  The console contains the CPU, PPU, and APU, while each individual game cartridge holds the ROM and RAM.  Week 2 of Nerdy Nights features a few images that illustrate this architecture well.

A bit more detail...

  • The CPU of the NES is a "custom 6052" processor.  This processor was featured in many other home entertainment units, like the Apple II, Atari, and the Commodore P.E.T..  It is an 8-bit processor featuring a 16-bit address bus.  I will go further into the features of the board when we get into the assembly programming.
  • The PPU fetches all graphical data from the game cartridge, known as CHR (character memory), primarily containing sprites.  This graphical data will come in the form of tiles, sprites, pallettes, tables, and a background.
    • Tiles are 8x8 squares of pixels.  These tiles are tied together to make the background or a Sprite.
      • Background tiles are snapped to a grid and cannot move freely, while sprites are the opposite. 
      • I recall from Rob Santos's post-mortem that getting tiles to work cohesively as a sprite was a bit of a challenge, I guess we'll see what he means when we actually get to coding!
        A single sprite from The Legend of Zelda.  Link is made up of multiple sprites.
    • The Background is 32x30 tiles in size, and has the ability to scroll.  The graphical RAM can hold up to two screens of background, one of which is updated off screen.

      -- SKETCH OF THE "2-SCREEN" CONCEPT HERE --
    • A Pattern Table is where the tile data is stored on a cartridge.  There are 2 tables, each of which can hold 256 tiles.  One holds tiles for the background, one for sprites.
    • An Attribute Table is a 64 byte array that stores color palette information for the background.  The attribute table controls this information in 2x2 tile sections.
    • The Color Palette for the NES is rather limited; only 16 colors available.  Two are stored, one for the background, and another for sprites.



  • The NES color palette.

  •  The system also features a "Lockout Chip", a 4-bit processor called the 10NES, both within the console and on the cartridge.  This chip was used to authenticate (i.e. approved by Nintendo) any game being inserted into the console.  If the console ever got stuck in a "reboot loop", these chips were the cause.  If I am to port a game onto actual hardware, i may have to find a way around this...Of course, all of these concepts will be covered in much greater detail as this learning process continues.  Next post will go over the introduction to the assembly programming language that the 6052 processor will use.
    I reserve the right to come back and edit this post in case I made mistakes.  :|
    -JWest  

Friday, May 6, 2016

It's been a year...

Hello,

I opened up my blog for the first time in God knows how long, and finally mustered up the courage to look at the date of my last post.  It's been a little more than a year - April 4th, 2015.

I think about games nearly all the time.  Video games are still a big part of my life, and they have been since I was a child.  However, making games has been a slightly different story.  The last couple of weeks I've been kicking around the idea of letting my wife pursue her career and act as the stay at home dad int the future.  Not only would it allow me to dedicate the majority of the day to our kids, but being at home without work or school to stress over would also allow me to actually build.  But these are thoughts for the future, not necessarily something to act upon quite yet.

Something else I've been reflecting on is a feeling I've been fighting with for the last few years is just the motivation to do something of my own volition.  At the end of each day, I just want to sit at my chair and play video games.  So this summer, I'm starting again.  I'm not jumping into game design, like I originally aimed.  Well, not directly, anyway.

This time I'm looking at NES development.  This will just be the study of how games were made back when the cartridge was required, and games were coded purely in (by my understanding) assembly.  Not only will this tie closely to what I've studied the last 3 years, this will also be something exciting, something that I might actually desire to sit and work on.  Now that I have my old computer set-up running again, I can keep a blog about my findings and developments a little more easily as well.

I'll be studying the tutorials found here, and I'll share any relevant information I come across with every blog post I right.  The next post will be observing the NES architecture, but I am just about to finish the semester, so it may not be written for a few days.

Here's to hoping I keep my word this time.

Cheers,
-JWest