Changing rom header w/o recompiling SGDK

SGDK only sub forum

Moderator: Stef

Post Reply
Moon-Watcher
Very interested
Posts: 117
Joined: Sun Jan 02, 2011 9:14 pm
Contact:

Changing rom header w/o recompiling SGDK

Post by Moon-Watcher » Fri Aug 23, 2013 10:32 am

How?

Xynxyn
Very interested
Posts: 54
Joined: Fri Jun 15, 2012 10:32 am
Location: Poland

Post by Xynxyn » Fri Aug 23, 2013 10:46 am

You may use hexadecimal editor or edit "src\boot\rom_head.h".
Rozumiem / Ma saan aru :D

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Post by Stef » Fri Aug 23, 2013 12:34 pm

Just modify the file SGDK/src/boot/rom_head.c
You don't need to recompile the library, the header is always recompiled for each project, but still you have to modify rom_head.c in the SGDK directory for each project. I couldn't find a way to have the rom_head.c file directly located in the project folder.

Moon-Watcher
Very interested
Posts: 117
Joined: Sun Jan 02, 2011 9:14 pm
Contact:

Post by Moon-Watcher » Fri Aug 23, 2013 2:08 pm

Hmmm, /me thinking about a configuration file + command line tool executed in the makefile to modify the rom.bin could do the work...

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Post by Stef » Fri Aug 23, 2013 3:24 pm

Yeah of course we could directly modify the rom_head.bin file but i think the rom_head.c is easy to modify, you directly see what field you are modifying :)

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Fri Aug 23, 2013 6:03 pm

All my code uses a different header for every project since they all use different header info. What trouble did you have trying to put the header in the project directory? It seems a simple enough change to the makefile in the project directory - just use the current directory for the path to the header instead of the path to the common header you use now.

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Post by Stef » Fri Aug 23, 2013 8:55 pm

Chilly Willy wrote:All my code uses a different header for every project since they all use different header info. What trouble did you have trying to put the header in the project directory? It seems a simple enough change to the makefile in the project directory - just use the current directory for the path to the header instead of the path to the common header you use now.
It does not work because of the .incbin asm directive which is not able to use the include directory option parameters (.incbin is used in sega.s file to include the compiled header file).
But i guess i can find a work around, i did not investigated that much to be honest ;)

Moon-Watcher
Very interested
Posts: 117
Joined: Sun Jan 02, 2011 9:14 pm
Contact:

Post by Moon-Watcher » Sat Aug 24, 2013 2:01 pm

Stef wrote:
Chilly Willy wrote:All my code uses a different header for every project since they all use different header info. What trouble did you have trying to put the header in the project directory? It seems a simple enough change to the makefile in the project directory - just use the current directory for the path to the header instead of the path to the common header you use now.
It does not work because of the .incbin asm directive which is not able to use the include directory option parameters (.incbin is used in sega.s file to include the compiled header file).
But i guess i can find a work around, i did not investigated that much to be honest ;)
I would prefer other way. Meanwhile I've developed a preliminary code that modifies rom.bin header. My idea is:

- makefile calls SGDK\bin\rom_head.exe
- rom_head.exe reads <project_dir>\rom_head.conf
- rom_head.exe overwrites <project_dir>\out\rom.bin with rom_head.conf data

rom_head.php

Code: Select all

<?php

//
// rom_head.php --> rom_head.exe
//
// To compile with Bambalam PHP EXE Compiler/Embedder 1.21 
// (bamcompile.exe)
//
// 20130824
//

$head_data = array
( 
	"console"       => array ( 16, "string"  ), 
	"copyright"     => array ( 16, "string"  ),
	"title_local"   => array ( 48, "string"  ), 
	"title_int"     => array ( 48, "string"  ),	
	"serial"        => array ( 14, "string"  ),	
	"checksum"      => array (  2, "integer" ),	
	"IOSupport"     => array ( 16, "string"  ),	
	"rom_start"     => array (  4, "integer" ),	
	"rom_end"       => array (  4, "integer" ),	
	"ram_start"     => array (  4, "integer" ),	
	"ram_end"       => array (  4, "integer" ),	
	"sram_sig"      => array (  2, "string"  ),	
	"sram_type"     => array (  2, "integer" ),	
	"sram_start"    => array (  4, "integer" ),	
	"sram_end"      => array (  4, "integer" ),	
	"modem_support" => array ( 12, "string"  ),	  
	"notes"         => array ( 40, "string"  ),	  
	"region"        => array ( 16, "string"  ),	  
);

copy ( "rom.0.bin", "rom.bin" );

$f = fopen("rom.bin","rb+");
$lines = file('rom_head.conf');

$i = 0;
$seek = 256;

foreach ( $head_data as $data )
{
	$size = $data[0];
	$type = $data[1];
	$line = $lines[$i++];
		
	if ( $type == "string" ) 
	{
		$write = substr ( $line, 0, $size );
	}
	
	if ( $type == "integer" )
	{
		$counter   = 1;
		$hex_bytes = array();

		while ( $counter <= $size )
		{
			$hex_bytes[] = substr ( $line, $counter*2, 2 );
			$counter++;
		}
		
		$code_array = array_map ( "hexdec", $hex_bytes);
		$char_array = array_map ( "chr", $code_array );
		$write      = implode ( $char_array );
	}
	
	fseek ( $f, $seek );
	fwrite ( $f, $write );
	
	$seek += $size;
}

fclose ( $f );

echo "Done.";

?>
rom_head.conf

Code: Select all

SEGA MEGA DRIVE
(C)Oook!Lab 2013
Griel's Ques Sega Genesis/Megadrive Edition
Griel's Ques Sega Genesis/Megadrive Edition
OL 00000000-01
0x1234
JD
0x00000000
0x00100000
0x00FF0000
0x00FFFFFF
AAX
0x0000
0x00200000
0x3020111f
AAAAAAAAAAAA
FIND THE PASSWORDS AND ENJOY
JUE
It may be used as a start point to a better tool used to store major version, number of compilations or whatever on rom head...

Waiting for your thoughts.

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Post by Stef » Sat Aug 24, 2013 5:01 pm

I think we need something like that but writing a specific tool for that seems a bit "over sized". Also i would like to keep the rom_head in C format so we could freely use the header structure in others parts of source :)

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Sat Aug 24, 2013 5:54 pm

Very nice! I was thinking of something like that, but could also handle 32X rom headers (which also use a jump table for exceptions as well as a security binary blob). At the moment, the rom header and anything else goes in the project directory as it's all linked to the project.

I use an assembly file so it's easy to link. I put the header in the crt0.s file, which is normally like this:

Code: Select all

| SEGA MegaDrive support code
| by Chilly Willy

        .text

| Initial exception vectors

        .long   0x01000000,initialize,exception,exception,exception,exception,exception,exception
        .long   exception,exception,exception,exception,exception,exception,exception,exception
        .long   exception,exception,exception,exception,exception,exception,exception,exception
        .long   exception,exception,exception,exception,hblank,exception,vblank,exception
        .long   exception,exception,exception,exception,exception,exception,exception,exception
        .long   exception,exception,exception,exception,exception,exception,exception,exception
        .long   exception,exception,exception,exception,exception,exception,exception,exception
        .long   exception,exception,exception,exception,exception,exception,exception,exception

| Standard MegaDrive ROM header at 0x100

        .ascii  "SEGA Mode1 Demo "      /* SEGA must be the first four chars for TMSS */
        .ascii  "(C)2011         "
        .ascii  "Mode 1 CD Player"      /* export name */
        .ascii  "                "
        .ascii  "                "
        .ascii  "Mode 1 CD Player"      /* domestic (Japanese) name */
        .ascii  "                "
        .ascii  "                "
        .ascii  "GM MK-0000 -00"
        .word   0x0000                  /* checksum - not needed */
        .ascii  "J6              "
        .long   0x00000000,0x0007FFFF   /* ROM start, end */
        .long   0x00FF0000,0x00FFFFFF   /* RAM start, end */

        .ifdef  HAS_SAVE_RAM
        .ascii  "RA"                    /* External RAM */
        .byte   0xF8                    /* don't clear + odd bytes */
        .byte   0x20                    /* SRAM */
        .long   0x00200001,0x0020FFFF   /* SRAM start, end */
        .else
        .ascii  "            "          /* no SRAM */
        .endif

        .ascii  "    "
        .ascii  "        "
        .ascii  "        "              /* memo */
        .ascii  "                "
        .ascii  "                "
        .ascii  "F               "      /* enable any hardware configuration */


| Standard MegaDrive startup at 0x200

initialize:
        move    #0x2700,sr              /* disable interrupts */

        tst.l   0xA10008                /* check CTRL1 and CTRL2 setup */
        bne.b   1f
        tst.w   0xA1000C                /* check CTRL3 setup */
1:
        bne.b   skip_tmss               /* if any controller control port is setup, skip TMSS handling */

| Check Hardware Version Number
        move.b  0xA10001,d0
        andi.b  #0x0F,d0                /* VERS */
        beq     2f                      /* 0 = original hardware, TMSS not present */
        move.l  #0x53454741,0xA14000    /* Store Sega Security Code "SEGA" to TMSS */
2:
        move.w  0xC00004,d0             /* read VDP Status reg */

skip_tmss:
        move.w  #0x8104,0xC00004        /* display off, vblank disabled */
        move.w  0xC00004,d0             /* read VDP Status reg */

| Clear Work RAM
        lea     0xFF0000,a0
        moveq   #0,d0
        move.w  #0x3FFF,d1
1:
        move.l  d0,(a0)+
        dbra    d1,1b

| Copy initialized variables from ROM to Work RAM
        lea     _stext,a0
        lea     0xFF0000,a1
        move.l  #_sdata,d0
        lsr.l   #1,d0
        subq.w  #1,d0
2:
        move.w  (a0)+,(a1)+
        dbra    d0,2b

        lea     0x01000000,a0
        movea.l a0,sp                   /* set stack pointer to top of Work RAM */
        link.w  a6,#-8                  /* set up initial stack frame */

        jsr     init_hardware           /* initialize the console hardware */

        jsr     __INIT_SECTION__        /* do all program initializers */
        jsr     main                    /* call program main() */
        jsr     __FINI_SECTION__        /* do all program finishers */
3:
        bra.b   3b


| put redirection vectors and gTicks at start of Work RAM

        .data

        .global exception_vector
exception_vector:
        .long   0
        .global hblank_vector
hblank_vector:
        .long   0
        .global vblank_vector
vblank_vector:
        .long   0
        .global gTicks
gTicks:
        .long   0

| Exception handlers

exception:
        move.l  exception_vector,-(sp)
        beq.b   1f
        rts
1:
        addq.l  #4,sp
        rte

hblank:
        move.l  hblank_vector,-(sp)
        beq.b   1f
        rts
1:
        addq.l  #4,sp
        rte

vblank:
        addq.l  #1,gTicks

        move.l  vblank_vector,-(sp)
        beq.b   1f
        rts
1:
        addq.l  #4,sp
        rte

        .text

        .global gen_lvl2
gen_lvl2:
        movem.l d0/a0,-(sp)
        lea     0xA12000,a0
        move.w  (a0),d0
        ori.w   #0x0100,d0
        move.w  d0,(a0)
        movem.l (sp)+,d0/a0
        rte
Then in the make file, just have crt0.o before any other object files. Done.

Post Reply