NES adventures

I recently picked up a homebrew NES game Malasombra which is awesome and unforgiving in true NES fashion. But having played this I wondered how difficult it would be to make my own homebrew game. Don’t get me wrong I’m using AI to help me with the Assembly. I started this little project back during the Xmas break. Really just to track my own progress and see if it’s something I can accomplish.

Day 1-5: Concept

I have NESMaker but didn’t want to go with a typical side-scroller or shoot em up. So i decided to do all this manually. I came up with what I think is a simple concept, although that remains to be seen. I wanted the movement and play style to be similar to Crystalis. Somewhat of a Zelda-esque type game that I loved very much as a kid.

concept

After a bit of reading. I figured I would need some tools. NEXXT studio is what I found to create my backgrounds/sprites or what the program calls them .chr files. I already have Mesen which is a great emulator to run ROMs. After some more research I found other people writing games in C and Assembly. Which makes sense, but not knowing much C at all. I figured I would stick with just plain Assembly and go from there. I’ve also been reading a lot of useful information from the NesDev forums. So far I think I have the basic foundation set up. The .segment "HEADER" is essentially the magic identifier which tells the emulators how to load the ROM. The hardware registers or PPU section are the memory addresses thatn control the Picture Processing Unit. This has it’s own address space separate from the CPU. Obviously the controller section defines how to read player input from the controller. Finally the .segment "ZEROPAGE" controls things like tracking the screen refresh..etc.

; NES Isometric Game - Main Entry Point
; Implements basic ROM structure with iNES header

.segment "HEADER"
    ; iNES header (16 bytes)
    .byte "NES", $1A        ; iNES magic number
    .byte $02               ; 2 x 16KB PRG-ROM banks (32KB total)
    .byte $01               ; 1 x 8KB CHR-ROM bank
    .byte $01               ; Mapper 0, vertical mirroring
    .byte $00               ; Mapper 0, no special features
    .byte $00, $00, $00, $00, $00, $00, $00, $00  ; Padding

; PPU Register addresses
PPUCTRL   = $2000
PPUMASK   = $2001
PPUSTATUS = $2002
OAMADDR   = $2003
PPUSCROLL = $2005
PPUADDR   = $2006
PPUDATA   = $2007
OAMDMA    = $4014

; Controller register addresses
CONTROLLER1 = $4016
CONTROLLER2 = $4017

; Controller button bit masks
BUTTON_A      = %10000000
BUTTON_B      = %01000000
BUTTON_SELECT = %00100000
BUTTON_START  = %00010000
BUTTON_UP     = %00001000
BUTTON_DOWN   = %00000100
BUTTON_LEFT   = %00000010
BUTTON_RIGHT  = %00000001

.segment "ZEROPAGE"
    ; Zero page variables
    nmi_ready: .res 1       ; Flag: 1 when NMI has occurred
    frame_count: .res 1     ; Frame counter
    game_state: .res 1      ; Current game state
    buttons: .res 1         ; Current button state
    buttons_prev: .res 1    ; Previous frame button state
    input_dx: .res 1        ; Input movement delta X (signed)
    input_dy: .res 1        ; Input movement delta Y (signed)

Right now it’s just been alot of reading. Which there will be alot of that it seems. But I’m interested to see how easy it will be to get something on screen. For now this is all I have. I plan to use this to track my progress and make updates when necessary.