mirror of
https://github.com/hsoft/collapseos.git
synced 2024-12-24 14:28:06 +11:00
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
|
||||
TARGET = os.bin
|
||||
TARGET = os.sms
|
||||
BASE = ../../..
|
||||
STAGE = $(BASE)/cvm/stage
|
||||
BLKPACK = $(BASE)/tools/blkpack
|
||||
SMSROM = $(BASE)/tools/smsrom
|
||||
EMUL = $(BASE)/emul/z80/sms
|
||||
|
||||
.PHONY: all
|
||||
@ -11,7 +10,6 @@ all: $(TARGET)
|
||||
$(TARGET): xcomp.fs $(STAGE) blkfs
|
||||
cat xcomp.fs | $(STAGE) blkfs > $@
|
||||
|
||||
$(SMSROM):
|
||||
$(BLKPACK):
|
||||
$(MAKE) -C ../tools
|
||||
|
||||
@ -21,9 +19,6 @@ blkfs: $(BLKPACK) $(BASE)/blk.fs blk.fs
|
||||
$(STAGE):
|
||||
$(MAKE) -C $(BASE)/cvm stage
|
||||
|
||||
os.sms: $(TARGET) $(STAGE) $(SMSROM)
|
||||
$(SMSROM) $(TARGET) > $@
|
||||
|
||||
$(EMUL):
|
||||
$(MAKE) -C ${@:%/sms=%}
|
||||
|
||||
|
@ -16,6 +16,7 @@ SYSVARS 0x74 + CONSTANT PAD_MEM
|
||||
: ZFILL, ( u ) 0 DO 0 A, LOOP ;
|
||||
262 LOAD ( xcomp )
|
||||
524 LOAD ( font compiler )
|
||||
165 LOAD ( Sega ROM signer )
|
||||
282 LOAD ( boot.z80.decl )
|
||||
270 LOAD ( xcomp overrides )
|
||||
|
||||
@ -37,5 +38,6 @@ CREATE ~FNT CPFNT7x7
|
||||
( Update LATEST )
|
||||
PC ORG @ 8 + !
|
||||
," VDP$ GRID$ PAD$ (im1) " EOT,
|
||||
ORG @ 0x100 - 256 /MOD 2 PC! 2 PC!
|
||||
H@ 256 /MOD 2 PC! 2 PC!
|
||||
ORG @ 0x100 - DUP 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 ;
|
||||
262 LOAD ( xcomp )
|
||||
524 LOAD ( font compiler )
|
||||
165 LOAD ( Sega ROM signer )
|
||||
282 LOAD ( boot.z80.decl )
|
||||
270 LOAD ( xcomp overrides )
|
||||
|
||||
@ -38,5 +39,6 @@ CREATE ~FNT CPFNT7x7
|
||||
( Update LATEST )
|
||||
PC ORG @ 8 + !
|
||||
," VDP$ GRID$ PS2$ (im1) " EOT,
|
||||
ORG @ 0x100 - 256 /MOD 2 PC! 2 PC!
|
||||
H@ 256 /MOD 2 PC! 2 PC!
|
||||
ORG @ 0x100 - DUP 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 ;
|
||||
262 LOAD ( xcomp )
|
||||
524 LOAD ( font compiler )
|
||||
165 LOAD ( Sega ROM signer )
|
||||
282 LOAD ( boot.z80.decl )
|
||||
270 LOAD ( xcomp overrides )
|
||||
|
||||
@ -41,5 +42,6 @@ CREATE ~FNT CPFNT7x7
|
||||
( Update LATEST )
|
||||
PC ORG @ 8 + !
|
||||
," VDP$ GRID$ PS2$ BLK$ (im1) " EOT,
|
||||
ORG @ 0x100 - 256 /MOD 2 PC! 2 PC!
|
||||
H@ 256 /MOD 2 PC! 2 PC!
|
||||
ORG @ 0x100 - DUP 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 ;
|
||||
262 LOAD ( xcomp )
|
||||
523 LOAD ( font compiler )
|
||||
165 LOAD ( Sega ROM signer )
|
||||
282 LOAD ( boot.z80.decl )
|
||||
270 LOAD ( xcomp overrides )
|
||||
|
||||
@ -40,5 +41,6 @@ CREATE ~FNT CPFNT5x7
|
||||
( Update LATEST )
|
||||
PC ORG @ 8 + !
|
||||
," TMS$ GRID$ PS2$ BLK$ ' SDC@ BLK@* ! (im1) " EOT,
|
||||
ORG @ 0x100 - 256 /MOD 2 PC! 2 PC!
|
||||
H@ 256 /MOD 2 PC! 2 PC!
|
||||
ORG @ 0x100 - DUP 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
|
||||
050 AVR assembler 70-99 unused
|
||||
100 Block editor 120 Visual Editor
|
||||
160 AVR SPI programmer
|
||||
160 AVR SPI programmer 165 Sega ROM signer
|
||||
170-259 unused 260 Cross compilation
|
||||
280 Z80 boot code 350 Core words
|
||||
400 AT28 EEPROM driver 401 Grid subsystem
|
||||
@ -957,6 +957,18 @@ VARIABLE aspprevx
|
||||
: aspe! ( byte addr --, write to EEPROM )
|
||||
256 /MOD ( b lsb msb ) SWAP
|
||||
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 )
|
||||
Cross compilation program
|
||||
|
||||
|
@ -57,7 +57,7 @@ so far. I haven't explored whether this can run on a megadrive).
|
||||
|
||||
# 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
|
||||
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