Difference between revisions of "A78 Header Specification"

From 8BitDev.org - Atari 7800 Development Wiki
Jump to: navigation, search
 
(23 intermediate revisions by 2 users not shown)
Line 9: Line 9:
 
  {|  style="float:left;"
 
  {|  style="float:left;"
 
   |+A78 Header Fields
 
   |+A78 Header Fields
  ! 0000 || style="background-color: #fc8;" | 01 || style="background-color: #fcf;" | 41 || style="background-color: #fcf;" | 54 || style="background-color: #fcf;" | 41 || style="background-color: #fcf;" | 52 || style="background-color: #fcf;" | 49 || style="background-color: #fcf;" | 37 || style="background-color: #fcf;" | 38 || style="background-color: #fcf;" | 30 || style="background-color: #fcf;" | 30 || style="background-color: #fcf;" | 00 || style="background-color: #fcf;" | 00 || style="background-color: #fcf;" | 00 || style="background-color: #fcf;" | 00 || style="background-color: #fcf;" | 00 || style="background-color: #fcf;" | 00 || <tt>.ATARI7800......</tt>
+
  ! 0000 || style="background-color: #fc8;" | 04 || style="background-color: #fcf;" | 41 || style="background-color: #fcf;" | 54 || style="background-color: #fcf;" | 41 || style="background-color: #fcf;" | 52 || style="background-color: #fcf;" | 49 || style="background-color: #fcf;" | 37 || style="background-color: #fcf;" | 38 || style="background-color: #fcf;" | 30 || style="background-color: #fcf;" | 30 || style="background-color: #fcf;" | 00 || style="background-color: #fcf;" | 00 || style="background-color: #fcf;" | 00 || style="background-color: #fcf;" | 00 || style="background-color: #fcf;" | 00 || style="background-color: #fcf;" | 00 || <tt>.ATARI7800......</tt>
 
  |-
 
  |-
 
  ! 0010 || style="background-color: #fcf;" | 00 || style="background-color: #acf;" | 43 || style="background-color: #acf;" | 6f || style="background-color: #acf;" | 6d || style="background-color: #acf;" | 6d || style="background-color: #acf;" | 61 || style="background-color: #acf;" | 6e || style="background-color: #acf;" | 64 || style="background-color: #acf;" | 6f || style="background-color: #acf;" | 00 || style="background-color: #acf;" | 00 || style="background-color: #acf;" | 00 || style="background-color: #acf;" | 00 || style="background-color: #acf;" | 00 || style="background-color: #acf;" | 00 || style="background-color: #acf;" | 00 || <tt>.Commando.......</tt>
 
  ! 0010 || style="background-color: #fcf;" | 00 || style="background-color: #acf;" | 43 || style="background-color: #acf;" | 6f || style="background-color: #acf;" | 6d || style="background-color: #acf;" | 6d || style="background-color: #acf;" | 61 || style="background-color: #acf;" | 6e || style="background-color: #acf;" | 64 || style="background-color: #acf;" | 6f || style="background-color: #acf;" | 00 || style="background-color: #acf;" | 00 || style="background-color: #acf;" | 00 || style="background-color: #acf;" | 00 || style="background-color: #acf;" | 00 || style="background-color: #acf;" | 00 || style="background-color: #acf;" | 00 || <tt>.Commando.......</tt>
Line 17: Line 17:
 
  ! 0030 || style="background-color: #acf;" | 00 || style="background-color: #faa;" | 00 || style="background-color: #faa;" | 02 || style="background-color: #faa;" | 00 || style="background-color: #faa;" | 00 || style="background-color: #ffb;" | 00 || style="background-color: #ffb;" | 03 || style="background-color: #8fc;" | 01 || style="background-color: #caa;" | 01 || style="background-color: #8c8;" | 00 || style="background-color: #c8c;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #aac;" | 00 || <tt>................</tt>
 
  ! 0030 || style="background-color: #acf;" | 00 || style="background-color: #faa;" | 00 || style="background-color: #faa;" | 02 || style="background-color: #faa;" | 00 || style="background-color: #faa;" | 00 || style="background-color: #ffb;" | 00 || style="background-color: #ffb;" | 03 || style="background-color: #8fc;" | 01 || style="background-color: #caa;" | 01 || style="background-color: #8c8;" | 00 || style="background-color: #c8c;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #aac;" | 00 || <tt>................</tt>
 
  |-
 
  |-
  ! 0040 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || <tt>................</tt>
+
  ! 0040 || style="background-color: #966;" | 01 || style="background-color: #696;" | 00 || style="background-color: #669;" | 00 || style="background-color: #669;" | 05 || style="background-color: #996;" | 00 || style="background-color: #996;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || <tt>................</tt>
 
  |-
 
  |-
 
  ! 0050 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || <tt>................</tt>
 
  ! 0050 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || style="background-color: #eee;" | 00 || <tt>................</tt>
Line 50: Line 50:
 
  | style="background-color: #eee;" | &nbsp; || reserved || &nbsp; || &nbsp;
 
  | style="background-color: #eee;" | &nbsp; || reserved || &nbsp; || &nbsp;
 
  |-
 
  |-
  | style="background-color: #aac;" | &nbsp; || expansion module || 1 byte || 63 / 0x3F
+
  | style="background-color: #aac;" | &nbsp; || slot passthrough device || 1 byte || 63 / 0x3F
 +
|-
 +
| style="background-color: #966;" | &nbsp; || v4+ mapper || 1 byte || 64 / 0x40
 +
|-
 +
| style="background-color: #696;" | &nbsp; || v4+ mapper options || 1 byte || 65 / 0x41
 +
|-
 +
| style="background-color: #669;" | &nbsp; || v4+ audio || 2 bytes || 66 / 0x42
 +
|-
 +
| style="background-color: #996;" | &nbsp; || v4+ interrupt || 2 bytes || 68 / 0x44
 
  |-
 
  |-
 
  | style="background-color: #cf8;" | &nbsp; || header end magic-text || 28 bytes || 100 / 0x64
 
  | style="background-color: #cf8;" | &nbsp; || header end magic-text || 28 bytes || 100 / 0x64
Line 56: Line 64:
  
 
<div style="clear:both;"></div>
 
<div style="clear:both;"></div>
cart type word details::
+
cart type details::
   bit 0   = pokey at $4000
+
   bit 0 : pokey at $4000
   bit 1   = supergame bank switched
+
   bit 1 : supergame bank switched
   bit 2   = supergame ram at $4000
+
   bit 2 : supergame ram at $4000
   bit 3   = rom at $4000
+
   bit 3 : rom at $4000
   bit 4   = bank 6 at $4000
+
   bit 4 : bank 6 at $4000
   bit 5   = supergame banked ram
+
   bit 5 : banked ram
   bit 6   = pokey at $450
+
   bit 6 : pokey at $450
   bit 7   = mirror ram at $4000
+
   bit 7 : mirror ram at $4000
   bit 8-15 = special
+
   bit 8 : activision banking
 +
  bit 9  : absolute banking
 +
  bit 10 : pokey at $440
 +
  bit 11 : ym2151 at $460/$461
 +
  bit 12 : souper
 +
  bit 13 : banksets
 +
  bit 14 : halt banked ram
 +
  bit 15 : pokey@800
  
controller type byte details:
+
controller type details:
 
   0 = none
 
   0 = none
 
   1 = 7800 joystick
 
   1 = 7800 joystick
Line 78: Line 93:
 
   8 = ST mouse
 
   8 = ST mouse
 
   9 = Amiga mouse
 
   9 = Amiga mouse
 +
  10 = AtariVox/SaveKey
 +
  11 = SNES2Atari
 +
  12 = Mega7800
  
 
TV type details:
 
TV type details:
   0 = NTSC
+
   bit 0 : 0=NTSC, 1=PAL
   1 = PAL
+
  bit 1 : 0=component, 1=composite
 +
   bit 2 : 0=single region, 1=multi-region
  
 
save device details:
 
save device details:
   bit 1    = HSC
+
  bit 0 : HSC
   bit 2    = SaveKey/AtariVox
+
   bit 1 : SaveKey/AtariVox
 +
 
 +
slot passthrough device details:
 +
  bit 0 : XM
 +
 
 +
v4+ mapper details:
 +
  0 = Linear
 +
  1 = SuperGame
 +
  2 = Activision
 +
  3 = Absolute
 +
   4 = Souper
 +
 
 +
v4+ mapper options details: (The meaning of this field varies depending on the mapper chosen.)
 +
 
 +
  Linear
 +
   bit 7    : Bankset ROM
 +
  bits 0-1 : Option at @4000 (0=none, 1=16K RAM, 2=8K EXRAM/A8, 3=32K EXRAM/M2)
 +
 
 +
  SuperGame
 +
  bit 7    : Bankset ROM
 +
   bits 0-2 : Option at @4000 (0=none, 1=16K RAM, 2=8K EXRAM/A8, 3=32K EXRAM/M2, 4=EXROM, 5=EXFIX, 6=32k EXRAM/X2)
 +
 
 +
v4+ audio:
 +
  bit 5    : ADPCM Audio Stream @420
 +
  bit 4    : COVOX @430
 +
  bit 3    : YM2151 @460
 +
  bits 0-2 : POKEY (0=none, 1=@440, 2=@450, 3=@450+@440, 4=@800, 5=@4000)
  
 +
v4+ interrupt:
 +
  bit 2 : YM2151
 +
  bit 1 : POKEY 2 (@440)
 +
  bit 0 : POKEY 1 (@450 | @800 | @4000)
 +
 +
 +
== A78 Header Version Notes==
 +
 +
The current header version stands at 4, but not all flash carts and emulators are capable of reading v4 specific fields, nor do all games have v4 headers.
 +
 +
If game authors choose not to use/support any v4 features, then the header version should be kept at "3". If a v4 header is used, it's encouraged that v3 headers are also used where possible, to allow for maximal compatibility with emulators and flash carts.
 +
 +
If an emulator or flash cart are v4 compatible, and they receive a rom with a v4 header, the v4 fields should take precedence over anything encoded in the equivalent v3 fields.
  
expansion module:
 
  bit 1    = XM
 
  
 
==Adding Or Modifying an A78 Header on an Existing ROM==
 
==Adding Or Modifying an A78 Header on an Existing ROM==
Line 100: Line 156:
 
7800 A78 Header Info
 
7800 A78 Header Info
  
     embedded game name : commando
+
     embedded game name : Commando
 
     rom size          : 131072
 
     rom size          : 131072
     cart format        : Pokey@4000 SuperGame  
+
     cart format        : Pokey@4000 SuperGame
     controller 1      : Joystick
+
     controllers        : 7800joy1 7800joy2
    controller 2      : None
+
     save peripheral    : none
     save peripheral    : None
+
     xm/xboard          : not enabled
     xm/xboard          : not enabled  
 
 
     tv format          : NTSC
 
     tv format          : NTSC
  
Commands: "save"           Save the A78 file and exit.
+
Commands: "save" [name]  Save the A78 file and exit.
 +
          "strip" [name]  Save a headerless .BIN and exit.
 
           "set [option]"  Set one of the options.
 
           "set [option]"  Set one of the options.
 
           "unset [option]" Unset one of the options.
 
           "unset [option]" Unset one of the options.
Line 115: Line 171:
 
           "exit"          Exit the utility. Unsaved changes will be lost.
 
           "exit"          Exit the utility. Unsaved changes will be lost.
  
Options:  rom@4000 bank6@4000 pokey@450 pokey@4000 supergame supergameram
+
Options:  rom@4000 bank6@4000 pokey@440 pokey@450 pokey@800 pokey@4000
          supergamebankram absolute activision tvpal tvntsc savekey hsc xm
+
  ram@4000 mram@4000 hram@4000 ym2151@460 supergame bankram
          joystick1 joystick2 lightgun1 lightgun2  
+
  absolute activision souper bankset tvpal tvntsc composite
 
+
  7800joy1 7800joy2 lightgun1 lightgun2 paddle1 paddle2
 +
  tball1 tball2 2600joy1 2600joy2 driving1 driving2 keypad1
 +
  keypad2 stmouse1 stmouse2 amouse1 amouse2 hsc savekey xm
 
> exit
 
> exit
 
</pre>
 
</pre>
Line 126: Line 184:
 
To add an A78 header to your DASM source code, you can add or include the header at the start of your source, and adjust the fields to encode the hardware your game requires.
 
To add an A78 header to your DASM source code, you can add or include the header at the start of your source, and adjust the fields to encode the hardware your game requires.
  
<pre>
+
For the current a78 assembly-language header, see [https://github.com/7800-devtools/a78_asm_header/blob/main/a78header.asm the a78 header github]
        SEG    ROM
 
HEADER  ORG    ROMTOP-128
 
        DC.B    1  ; 0  Header version    - 1 byte
 
        DC.B    "ATARI7800"    ; 1..16  "ATARI7800  "  - 16 bytes
 
        DS      7,32
 
        DC.B    "Your Name Here"; 17..48 Cart title      - 32 bytes
 
        DS      HEADER+49-.,0
 
        DC.B    $00,$00,256->ROMTOP,$00; 49..52 data length      - 4 bytes
 
        DC.B    $00,$00  ; 53..54 cart type      - 2 bytes
 
    ;    bit 0 - pokey at $4000
 
    ;    bit 1 - supergame bank switched
 
    ;    bit 2 - supergame ram at $4000
 
    ;    bit 3 - rom at $4000
 
    ;    bit 4 - bank 6 at $4000
 
    ;    bit 5 - supergame banked ram
 
    ;    bit 6 - pokey at $450
 
    ;    bit 7 - mirror ram at $4000
 
    ;    bit 8-15 - Special
 
    ;  0 = Normal cart
 
        DC.B    1  ; 55  controller 1 type  - 1 byte
 
        DC.B    1  ; 56  controller 2 type  - 1 byte
 
    ;    0 = None
 
    ;    1 = Joystick
 
    ;    2 = Light Gun
 
        DC.B    0  ; 57 0 = NTSC 1 = PAL
 
        DC.B    0  ; 58  Save data peripheral - 1 byte (version 2)
 
    ;    0 = None / unknown (default)
 
    ;    1 = High Score Cart (HSC)
 
    ;    2 = SaveKey
 
        ORG    HEADER+63
 
        DC.B    0  ; 63  Expansion module
 
    ;    0 = No expansion module (default on all currently released games)
 
    ;    1 = Expansion module required
 
        ORG    HEADER+100      ; 100..127 "ACTUAL CART DATA STARTS HERE" - 28 bytes
 
        DC.B    "ACTUAL CART DATA STARTS HERE"
 
ROMTOP  ORG    $8000
 
</pre>
 

Latest revision as of 04:11, 21 January 2024

History and Purpose

The A78 header was originally created by Dan Boris, in tandem with his A7800 emulator. The header, which is added to the beginning of ROM images, serves to tell the emulator which hardware should be present for the game to run correctly.

The format has since been expanded to incorporate new hardware, and is now being used by multiple emulators and the Concerto 7800 flash cart.

A78 Header Fields

A78 Header Fields
0000 04 41 54 41 52 49 37 38 30 30 00 00 00 00 00 00 .ATARI7800......
0010 00 43 6f 6d 6d 61 6e 64 6f 00 00 00 00 00 00 00 .Commando.......
0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0030 00 00 02 00 00 00 03 01 01 00 00 00 00 00 00 00 ................
0040 01 00 00 05 00 00 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0060 00 00 00 00 41 43 54 55 41 4c 20 43 41 52 54 20 ....ACTUAL CART
0070 44 41 54 41 20 53 54 41 52 54 53 20 48 45 52 45 DATA STARTS HERE
color purpose size offset
  header version 1 byte 0 / 0x00
  ATARI7800 magic-text 16 bytes 1 / 0x01
  cart title 32 bytes 17 / 0x11
  rom size without header 4 bytes 49 / 0x31
  cart type 2 bytes 53 / 0x35
  controller 1 type 1 byte 55 / 0x37
  controller 2 type 1 byte 56 / 0x38
  TV type 1 byte 57 / 0x39
  save device 1 byte 58 / 0x3A
  reserved    
  slot passthrough device 1 byte 63 / 0x3F
  v4+ mapper 1 byte 64 / 0x40
  v4+ mapper options 1 byte 65 / 0x41
  v4+ audio 2 bytes 66 / 0x42
  v4+ interrupt 2 bytes 68 / 0x44
  header end magic-text 28 bytes 100 / 0x64

cart type details::

  bit 0  : pokey at $4000
  bit 1  : supergame bank switched
  bit 2  : supergame ram at $4000
  bit 3  : rom at $4000
  bit 4  : bank 6 at $4000
  bit 5  : banked ram
  bit 6  : pokey at $450
  bit 7  : mirror ram at $4000
  bit 8  : activision banking
  bit 9  : absolute banking
  bit 10 : pokey at $440
  bit 11 : ym2151 at $460/$461
  bit 12 : souper
  bit 13 : banksets
  bit 14 : halt banked ram
  bit 15 : pokey@800

controller type details:

  0 = none
  1 = 7800 joystick
  2 = lightgun
  3 = paddle
  4 = trakball
  5 = 2600 joystick
  6 = 2600 driving
  7 = 2600 keypad
  8 = ST mouse
  9 = Amiga mouse
  10 = AtariVox/SaveKey
  11 = SNES2Atari
  12 = Mega7800

TV type details:

  bit 0 : 0=NTSC, 1=PAL
  bit 1 : 0=component, 1=composite
  bit 2 : 0=single region, 1=multi-region

save device details:

  bit 0 : HSC
  bit 1 : SaveKey/AtariVox

slot passthrough device details:

  bit 0 : XM

v4+ mapper details:

  0 = Linear
  1 = SuperGame
  2 = Activision
  3 = Absolute
  4 = Souper

v4+ mapper options details: (The meaning of this field varies depending on the mapper chosen.)

  Linear
  bit 7    : Bankset ROM
  bits 0-1 : Option at @4000 (0=none, 1=16K RAM, 2=8K EXRAM/A8, 3=32K EXRAM/M2)
  SuperGame
  bit 7    : Bankset ROM
  bits 0-2 : Option at @4000 (0=none, 1=16K RAM, 2=8K EXRAM/A8, 3=32K EXRAM/M2, 4=EXROM, 5=EXFIX, 6=32k EXRAM/X2)

v4+ audio:

  bit 5    : ADPCM Audio Stream @420
  bit 4    : COVOX @430
  bit 3    : YM2151 @460
  bits 0-2 : POKEY (0=none, 1=@440, 2=@450, 3=@450+@440, 4=@800, 5=@4000)

v4+ interrupt:

  bit 2 : YM2151
  bit 1 : POKEY 2 (@440)
  bit 0 : POKEY 1 (@450 | @800 | @4000)


A78 Header Version Notes

The current header version stands at 4, but not all flash carts and emulators are capable of reading v4 specific fields, nor do all games have v4 headers.

If game authors choose not to use/support any v4 features, then the header version should be kept at "3". If a v4 header is used, it's encouraged that v3 headers are also used where possible, to allow for maximal compatibility with emulators and flash carts.

If an emulator or flash cart are v4 compatible, and they receive a rom with a v4 header, the v4 fields should take precedence over anything encoded in the equivalent v3 fields.


Adding Or Modifying an A78 Header on an Existing ROM

You can add or update an A78 header with the interactive command-line utility 7800header, which is distributed with 7800basic and the 7800AsmDevKit.

The utility displays the current header (or default header if the file is headerless) and you can set/unset hardware features with the displayed commands.

7800 A78 Header Info

    embedded game name : Commando
    rom size           : 131072
    cart format        : Pokey@4000 SuperGame
    controllers        : 7800joy1 7800joy2
    save peripheral    : none
    xm/xboard          : not enabled
    tv format          : NTSC

Commands: "save"  [name]   Save the A78 file and exit.
          "strip" [name]   Save a headerless .BIN and exit.
          "set [option]"   Set one of the options.
          "unset [option]" Unset one of the options.
          "name game name" Set the game name in the header.
          "exit"           Exit the utility. Unsaved changes will be lost.

Options:  rom@4000 bank6@4000 pokey@440 pokey@450 pokey@800 pokey@4000
   ram@4000 mram@4000 hram@4000 ym2151@460 supergame bankram
   absolute activision souper bankset tvpal tvntsc composite
   7800joy1 7800joy2 lightgun1 lightgun2 paddle1 paddle2
   tball1 tball2 2600joy1 2600joy2 driving1 driving2 keypad1
   keypad2 stmouse1 stmouse2 amouse1 amouse2 hsc savekey xm
> exit

Adding an A78 Header to Source Code

To add an A78 header to your DASM source code, you can add or include the header at the start of your source, and adjust the fields to encode the hardware your game requires.

For the current a78 assembly-language header, see the a78 header github