It is currently Sun Jun 25, 2017 5:02 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Sat Mar 11, 2017 11:25 am 
Offline
User avatar

Joined: Wed Apr 07, 2010 1:14 am
Posts: 463
Location: Iran
Code:
;NES Programming Tutorial
;Level 2 : iNES Header
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Constants
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Variables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;iNES header data (16bytes)
;32KB PRG + 8KB CHR + NROM-256 + Vertical Mirroring
  .db $4E,$45,$53,$1A,$02,$01,$01,$00
  .db $00,$00,$00,$00,$00,$00,$00,$00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;PRG codes $8000 ~ $FFFF (32KB)
  .base $8000
  ;user codes
  .pad $10000,$FF
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;CHR data $0000 ~ $1FFF (8KB)
  .base $0000
  ;graphic data
  .pad $2000,$FF


Explanation :

* The first 16KB of a nes game is header info which is used just by emulators to run the game. It gives information about PRG size, CHR size, Mapper number, Mirroring, etc.

* I setup the header to : 32KB PRG + 8KB CHR + NROM-256 + Vertical Mirroring.

* Need more info about iNES header? then read this : INES

* lines starting with . are directive commands of assembler

* .db puts a value in the file directly.

* .base $8000 is another directive command. It tells the assembler that the following commands will be loaded into $8000 of CPU. So labels addresses are adjusted according to $8000

* .pad $10000,$FF is another directive command. It fills the remaining empty space of memory up to $10000 with the value of #$FF

* We need an assembler (ASM6) to convert the source code of assembly language (Game.asm) to object code of machine language (Game.nes) so that you can run it on Emulator

/////////////////////////////////////////////////////////////////////////////////////////////////

How to use ASM6 :

* Download ASM6

* Make a new text file

* Write this inside of it :

Code:
ASM6 Game.asm Game.nes
pause


* Save it with this name : Assembler.bat

* Make sure these files are in the same folder :

Code:
asm6.exe
Assembler.bat
Game.asm


* Run Assembler.bat to make your FIRST NES GAME!

Image

/////////////////////////////////////////////////////////////////////////////////////////////////

How to use Hex Editor :

* Sometimes we need to see the exact values of 0 and 1 inside of a file (object code of machine language), so we use a Hex Editor program like HxD

* Download HxD

* Open Game.NES with HxD

* You can see the header data on the first line, they should match to the values which you used inside of the Game.asm

Image

* Note that values are in Hexadecimal system

* Each value is one byte

* Each byte has it's own address

* Their address starts from zero, so first byte is in the $0 address second byte is in the $01 address, and so on

/////////////////////////////////////////////////////////////////////////////////////////////////

Exercise :

Find out which byte of iNES data controls Mirroring and then set it to Horizontal (Vertical Arrangement).

/////////////////////////////////////////////////////////////////////////////////////////////////

Files :
asm6.exe
Assembler.bat
Game.asm

/////////////////////////////////////////////////////////////////////////////////////////////////

Former Level : NES Programming Tutorial : Source Code Structure
Next Level : NES Programming Tutorial : Interrupts


Last edited by FARID on Fri Mar 17, 2017 10:37 pm, edited 17 times in total.

Top
 Profile  
 
PostPosted: Sun Mar 12, 2017 10:39 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5311
Location: Canada
I might suggest writing it out in a way that makes it easier to change and see where the bits are going and what they mean, instead of just making it a block of mysterious hex numbers. In my example program I did it like this:
Code:
INES_MAPPER = 0 ; 0 = NROM
INES_MIRROR = 1 ; 0 = horizontal mirroring, 1 = vertical mirroring
INES_SRAM   = 0 ; 1 = battery backed SRAM at $6000-7FFF

.byte 'N', 'E', 'S', $1A ; ID
.byte $02 ; 16k PRG bank count
.byte $01 ; 8k CHR bank count
.byte INES_MIRROR | (INES_SRAM << 1) | ((INES_MAPPER & $f) << 4)
.byte (INES_MAPPER & %11110000)
.byte $0, $0, $0, $0, $0, $0, $0, $0 ; padding


Top
 Profile  
 
PostPosted: Sun Mar 12, 2017 11:02 am 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 589
Location: Sweden
You forgot byte 8 and 9: PRG-RAM size and PAL flag respectively.


Top
 Profile  
 
PostPosted: Sun Mar 12, 2017 11:23 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5311
Location: Canada
I didn't forget those. Those two bytes are late extensions by Marat, never really adopted by anyone else, and were also both reclaimed by iNES 2.

Most emulators ignore both of those bytes. Most ROMs that require PRG-RAM have 0 in byte 8, and most PAL ROMs have 0 in byte 9 as well, so emulators have to expect this anyway.

Implementing these in my example header would give the user an unrealistic expectation that either of these bytes is supposed to do something (which they won't, in most emulators), and set them up for a future incompatibility if they ever switch to iNES 2. The safest and most compatible thing is to leave them both as 0.


Top
 Profile  
 
PostPosted: Sun Mar 12, 2017 6:05 pm 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 589
Location: Sweden
I see, I thought they where in the official specifications. I guess it's better to use NES 2.0 for the NTSC/PAL setting.


Top
 Profile  
 
PostPosted: Sun Mar 12, 2017 6:44 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5311
Location: Canada
Pokun wrote:
I see, I thought they where in the official specifications.

They are, if Marat's spec is the "official" one. He invented the format, and he's the one that made those additions.

If you want the "de facto" standard, though, those bytes aren't really used, probably because it was easier to support the handful of games that needed them through other means (hash, filename, heuristics, etc.), and/or trying to cope with ROMs with garbage in the header's padding area?


Top
 Profile  
 
PostPosted: Mon Mar 13, 2017 4:30 pm 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 589
Location: Sweden
Yeah I guess it's what the ROMs use that is the real standard.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group