sms: generate TMR SEGA signature in Collapse OS itself
Having the signature generation code in /tools prevents self-hosting on the SMS.
This commit is contained in:
parent
631e7f1008
commit
b4f3fde062
@ -1,9 +1,8 @@
|
|||||||
# See /doc/hw/z80/sms.txt
|
# See /doc/hw/z80/sms.txt
|
||||||
TARGET = os.bin
|
TARGET = os.sms
|
||||||
BASE = ../../..
|
BASE = ../../..
|
||||||
STAGE = $(BASE)/cvm/stage
|
STAGE = $(BASE)/cvm/stage
|
||||||
BLKPACK = $(BASE)/tools/blkpack
|
BLKPACK = $(BASE)/tools/blkpack
|
||||||
SMSROM = $(BASE)/tools/smsrom
|
|
||||||
EMUL = $(BASE)/emul/z80/sms
|
EMUL = $(BASE)/emul/z80/sms
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
@ -11,7 +10,6 @@ all: $(TARGET)
|
|||||||
$(TARGET): xcomp.fs $(STAGE) blkfs
|
$(TARGET): xcomp.fs $(STAGE) blkfs
|
||||||
cat xcomp.fs | $(STAGE) blkfs > $@
|
cat xcomp.fs | $(STAGE) blkfs > $@
|
||||||
|
|
||||||
$(SMSROM):
|
|
||||||
$(BLKPACK):
|
$(BLKPACK):
|
||||||
$(MAKE) -C ../tools
|
$(MAKE) -C ../tools
|
||||||
|
|
||||||
@ -21,9 +19,6 @@ blkfs: $(BLKPACK) $(BASE)/blk.fs blk.fs
|
|||||||
$(STAGE):
|
$(STAGE):
|
||||||
$(MAKE) -C $(BASE)/cvm stage
|
$(MAKE) -C $(BASE)/cvm stage
|
||||||
|
|
||||||
os.sms: $(TARGET) $(STAGE) $(SMSROM)
|
|
||||||
$(SMSROM) $(TARGET) > $@
|
|
||||||
|
|
||||||
$(EMUL):
|
$(EMUL):
|
||||||
$(MAKE) -C ${@:%/sms=%}
|
$(MAKE) -C ${@:%/sms=%}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ SYSVARS 0x74 + CONSTANT PAD_MEM
|
|||||||
: ZFILL, ( u ) 0 DO 0 A, LOOP ;
|
: ZFILL, ( u ) 0 DO 0 A, LOOP ;
|
||||||
262 LOAD ( xcomp )
|
262 LOAD ( xcomp )
|
||||||
524 LOAD ( font compiler )
|
524 LOAD ( font compiler )
|
||||||
|
165 LOAD ( Sega ROM signer )
|
||||||
282 LOAD ( boot.z80.decl )
|
282 LOAD ( boot.z80.decl )
|
||||||
270 LOAD ( xcomp overrides )
|
270 LOAD ( xcomp overrides )
|
||||||
|
|
||||||
@ -37,5 +38,6 @@ CREATE ~FNT CPFNT7x7
|
|||||||
( Update LATEST )
|
( Update LATEST )
|
||||||
PC ORG @ 8 + !
|
PC ORG @ 8 + !
|
||||||
," VDP$ GRID$ PAD$ (im1) " EOT,
|
," VDP$ GRID$ PAD$ (im1) " EOT,
|
||||||
ORG @ 0x100 - 256 /MOD 2 PC! 2 PC!
|
ORG @ 0x100 - DUP 256 /MOD 2 PC! 2 PC!
|
||||||
H@ 256 /MOD 2 PC! 2 PC!
|
DUP 1 ( 16K ) segasig
|
||||||
|
0x4000 + 256 /MOD 2 PC! 2 PC!
|
||||||
|
@ -17,6 +17,7 @@ SYSVARS 0x74 + CONSTANT PS2_MEM
|
|||||||
: ZFILL, ( u ) 0 DO 0 A, LOOP ;
|
: ZFILL, ( u ) 0 DO 0 A, LOOP ;
|
||||||
262 LOAD ( xcomp )
|
262 LOAD ( xcomp )
|
||||||
524 LOAD ( font compiler )
|
524 LOAD ( font compiler )
|
||||||
|
165 LOAD ( Sega ROM signer )
|
||||||
282 LOAD ( boot.z80.decl )
|
282 LOAD ( boot.z80.decl )
|
||||||
270 LOAD ( xcomp overrides )
|
270 LOAD ( xcomp overrides )
|
||||||
|
|
||||||
@ -38,5 +39,6 @@ CREATE ~FNT CPFNT7x7
|
|||||||
( Update LATEST )
|
( Update LATEST )
|
||||||
PC ORG @ 8 + !
|
PC ORG @ 8 + !
|
||||||
," VDP$ GRID$ PS2$ (im1) " EOT,
|
," VDP$ GRID$ PS2$ (im1) " EOT,
|
||||||
ORG @ 0x100 - 256 /MOD 2 PC! 2 PC!
|
ORG @ 0x100 - DUP 256 /MOD 2 PC! 2 PC!
|
||||||
H@ 256 /MOD 2 PC! 2 PC!
|
DUP 1 ( 16K ) segasig
|
||||||
|
0x4000 + 256 /MOD 2 PC! 2 PC!
|
||||||
|
@ -18,6 +18,7 @@ SYSVARS 0x74 + CONSTANT PS2_MEM
|
|||||||
: ZFILL, ( u ) 0 DO 0 A, LOOP ;
|
: ZFILL, ( u ) 0 DO 0 A, LOOP ;
|
||||||
262 LOAD ( xcomp )
|
262 LOAD ( xcomp )
|
||||||
524 LOAD ( font compiler )
|
524 LOAD ( font compiler )
|
||||||
|
165 LOAD ( Sega ROM signer )
|
||||||
282 LOAD ( boot.z80.decl )
|
282 LOAD ( boot.z80.decl )
|
||||||
270 LOAD ( xcomp overrides )
|
270 LOAD ( xcomp overrides )
|
||||||
|
|
||||||
@ -41,5 +42,6 @@ CREATE ~FNT CPFNT7x7
|
|||||||
( Update LATEST )
|
( Update LATEST )
|
||||||
PC ORG @ 8 + !
|
PC ORG @ 8 + !
|
||||||
," VDP$ GRID$ PS2$ BLK$ (im1) " EOT,
|
," VDP$ GRID$ PS2$ BLK$ (im1) " EOT,
|
||||||
ORG @ 0x100 - 256 /MOD 2 PC! 2 PC!
|
ORG @ 0x100 - DUP 256 /MOD 2 PC! 2 PC!
|
||||||
H@ 256 /MOD 2 PC! 2 PC!
|
DUP 1 ( 16K ) segasig
|
||||||
|
0x4000 + 256 /MOD 2 PC! 2 PC!
|
||||||
|
@ -18,6 +18,7 @@ SYSVARS 0x74 + CONSTANT PS2_MEM
|
|||||||
: ZFILL, ( u ) 0 DO 0 A, LOOP ;
|
: ZFILL, ( u ) 0 DO 0 A, LOOP ;
|
||||||
262 LOAD ( xcomp )
|
262 LOAD ( xcomp )
|
||||||
523 LOAD ( font compiler )
|
523 LOAD ( font compiler )
|
||||||
|
165 LOAD ( Sega ROM signer )
|
||||||
282 LOAD ( boot.z80.decl )
|
282 LOAD ( boot.z80.decl )
|
||||||
270 LOAD ( xcomp overrides )
|
270 LOAD ( xcomp overrides )
|
||||||
|
|
||||||
@ -40,5 +41,6 @@ CREATE ~FNT CPFNT5x7
|
|||||||
( Update LATEST )
|
( Update LATEST )
|
||||||
PC ORG @ 8 + !
|
PC ORG @ 8 + !
|
||||||
," TMS$ GRID$ PS2$ BLK$ ' SDC@ BLK@* ! (im1) " EOT,
|
," TMS$ GRID$ PS2$ BLK$ ' SDC@ BLK@* ! (im1) " EOT,
|
||||||
ORG @ 0x100 - 256 /MOD 2 PC! 2 PC!
|
ORG @ 0x100 - DUP 256 /MOD 2 PC! 2 PC!
|
||||||
H@ 256 /MOD 2 PC! 2 PC!
|
DUP 1 ( 16K ) segasig
|
||||||
|
0x4000 + 256 /MOD 2 PC! 2 PC!
|
||||||
|
14
blk.fs
14
blk.fs
@ -21,7 +21,7 @@ MASTER INDEX
|
|||||||
005 Z80 assembler 030 8086 assembler
|
005 Z80 assembler 030 8086 assembler
|
||||||
050 AVR assembler 70-99 unused
|
050 AVR assembler 70-99 unused
|
||||||
100 Block editor 120 Visual Editor
|
100 Block editor 120 Visual Editor
|
||||||
160 AVR SPI programmer
|
160 AVR SPI programmer 165 Sega ROM signer
|
||||||
170-259 unused 260 Cross compilation
|
170-259 unused 260 Cross compilation
|
||||||
280 Z80 boot code 350 Core words
|
280 Z80 boot code 350 Core words
|
||||||
400 AT28 EEPROM driver 401 Grid subsystem
|
400 AT28 EEPROM driver 401 Grid subsystem
|
||||||
@ -957,6 +957,18 @@ VARIABLE aspprevx
|
|||||||
: aspe! ( byte addr --, write to EEPROM )
|
: aspe! ( byte addr --, write to EEPROM )
|
||||||
256 /MOD ( b lsb msb ) SWAP
|
256 /MOD ( b lsb msb ) SWAP
|
||||||
0xc0 ( b msb lsb 0xc0 ) _cmd DROP asprdy ;
|
0xc0 ( b msb lsb 0xc0 ) _cmd DROP asprdy ;
|
||||||
|
( ----- 165 )
|
||||||
|
( Sega ROM signer. See doc/sega.txt )
|
||||||
|
: A!+^ ( a c -- a+1 ) OVER A! 1+ ;
|
||||||
|
: segasig ( addr size -- )
|
||||||
|
0x2000 OVER LSHIFT ( a sz bytesz )
|
||||||
|
ROT TUCK + 0x10 - ( sz a end )
|
||||||
|
TUCK SWAP 0 ROT> ( sz end sum end a ) DO ( sz end sum )
|
||||||
|
I A@ + LOOP ( sz end sum ) SWAP ( sz sum end )
|
||||||
|
'T' A!+^ 'M' A!+^ 'R' A!+^ 0x20 A!+^ 'S' A!+^ 'E' A!+^
|
||||||
|
'G' A!+^ 'A' A!+^ 0 A!+^ 0 A!+^
|
||||||
|
( sum's LSB ) OVER A!+^ ( MSB ) SWAP 8 RSHIFT OVER A! 1+
|
||||||
|
( sz end ) 0 A!+^ 0 A!+^ 0 A!+^ SWAP 0x4a + SWAP A! ;
|
||||||
( ----- 260 )
|
( ----- 260 )
|
||||||
Cross compilation program
|
Cross compilation program
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ so far. I haven't explored whether this can run on a megadrive).
|
|||||||
|
|
||||||
# Build the ROM
|
# Build the ROM
|
||||||
|
|
||||||
Running "make os.sms" in /arch/z80/sms will produce a "os.sms"
|
Running "make" in /arch/z80/sms will produce a "os.sms"
|
||||||
ROM that can be put as is on a SD card to the everdrive or
|
ROM that can be put as is on a SD card to the everdrive or
|
||||||
flashed as is on a writable ROM cart. Then, just run the thing!
|
flashed as is on a writable ROM cart. Then, just run the thing!
|
||||||
|
|
||||||
|
40
doc/sega.txt
Normal file
40
doc/sega.txt
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# Sega Master System ROM signatures
|
||||||
|
|
||||||
|
When loading ROM, the SMS' BIOS checks for a special signature
|
||||||
|
at the end of that ROM. If that signature is incorrect, the ROM
|
||||||
|
doesn't load.
|
||||||
|
|
||||||
|
Collapse OS has a program to generate that signature at B165.
|
||||||
|
This document describes what it does.
|
||||||
|
|
||||||
|
At boot, the BIOS checks 0x10 bytes before the 0x8000, then
|
||||||
|
0x4000, then 0x2000 mark for a signature. This signature has
|
||||||
|
the following structure.
|
||||||
|
|
||||||
|
0x00-0x07: String constant: "TMR SEGA"
|
||||||
|
0x08-0x09: null bytes
|
||||||
|
0x0a-0x0b: checksum
|
||||||
|
0x0c-0x0e: null bytes
|
||||||
|
0x0f : "size" flag
|
||||||
|
|
||||||
|
The checksum is a simple 16-bit sum of all bytes up to the
|
||||||
|
beginning of the signature.
|
||||||
|
|
||||||
|
The size flag can have 3 values: 0x4a for an 8K ROM, 0x4b for
|
||||||
|
16K and 0x4c for 32K. It can have other values for other kinds
|
||||||
|
of sizes, but we don't care about them in the context of
|
||||||
|
Collapse OS.
|
||||||
|
|
||||||
|
## Generating the signature
|
||||||
|
|
||||||
|
Before generating the signature, you need to have the contents
|
||||||
|
of your ROM somewhere in memory. Then, you load B165 and you
|
||||||
|
call "segasig" which has the signature "addr size". "addr" is
|
||||||
|
the adress of the beginning of the ROM and "size" is 0, 1 or 2
|
||||||
|
depending on whether your ROM is 8K, 16K or 32K.
|
||||||
|
|
||||||
|
Calling the word will write the 0x10 bytes signature at the
|
||||||
|
end of the ROM.
|
||||||
|
|
||||||
|
Note that all I/O use the "Addressed device" words (see
|
||||||
|
usage.txt), so I/O indirections will work.
|
@ -1,53 +0,0 @@
|
|||||||
/* ./smsrom fname
|
|
||||||
|
|
||||||
Transforms binary at fname into an 8K, 16K or 32K Sega Master System ROM with
|
|
||||||
a header fit for an Export SMS. The resulting ROM is spit to stdout.
|
|
||||||
|
|
||||||
Whether the ROM is 8, 16 or 32K depends on the size of binary at fname.
|
|
||||||
*/
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
if (argc != 2) {
|
|
||||||
fprintf(stderr, "Usage: ./smsrom fname\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
FILE *fp = fopen(argv[1], "r");
|
|
||||||
if (!fp) {
|
|
||||||
fprintf(stderr, "Can't open %s.\n", argv[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
fseek(fp, 0, SEEK_END);
|
|
||||||
long fsize = ftell(fp);
|
|
||||||
fseek(fp, 0, SEEK_SET);
|
|
||||||
uint8_t hdsz = 0x4a; // size flag in header. either 4a, 4b or 4c.
|
|
||||||
int romsize = 0x2000;
|
|
||||||
while (romsize-16 < fsize) {
|
|
||||||
romsize *= 2;
|
|
||||||
hdsz++;
|
|
||||||
if (romsize > 0x8000) {
|
|
||||||
fprintf(stderr, "binary too big\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uint16_t chksum = 0;
|
|
||||||
for (int i=0; i<romsize-16; i++) {
|
|
||||||
int c = getc(fp);
|
|
||||||
if (c == EOF) c = 0;
|
|
||||||
putchar(c);
|
|
||||||
chksum += c;
|
|
||||||
}
|
|
||||||
// and now, the header
|
|
||||||
printf("TMR SEGA");
|
|
||||||
putchar(0);
|
|
||||||
putchar(0);
|
|
||||||
putchar(chksum & 0xff);
|
|
||||||
putchar(chksum >> 8);
|
|
||||||
putchar(0);
|
|
||||||
putchar(0);
|
|
||||||
putchar(0);
|
|
||||||
putchar(hdsz);
|
|
||||||
return 0;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user