diff --git a/arch/z80/sms/Makefile b/arch/z80/sms/Makefile index a9c3a23..4ece6bb 100644 --- a/arch/z80/sms/Makefile +++ b/arch/z80/sms/Makefile @@ -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=%} diff --git a/arch/z80/sms/xcomp.fs b/arch/z80/sms/xcomp.fs index 82118cb..8844b82 100644 --- a/arch/z80/sms/xcomp.fs +++ b/arch/z80/sms/xcomp.fs @@ -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! diff --git a/arch/z80/sms/xcompkbd.fs b/arch/z80/sms/xcompkbd.fs index c04f488..fea5a08 100644 --- a/arch/z80/sms/xcompkbd.fs +++ b/arch/z80/sms/xcompkbd.fs @@ -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! diff --git a/arch/z80/sms/xcompsdc.fs b/arch/z80/sms/xcompsdc.fs index ae61224..727932f 100644 --- a/arch/z80/sms/xcompsdc.fs +++ b/arch/z80/sms/xcompsdc.fs @@ -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! diff --git a/arch/z80/sms/xcomptextmode.fs b/arch/z80/sms/xcomptextmode.fs index ecbacd3..d152809 100644 --- a/arch/z80/sms/xcomptextmode.fs +++ b/arch/z80/sms/xcomptextmode.fs @@ -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! diff --git a/blk.fs b/blk.fs index ab9633a..3a90684 100644 --- a/blk.fs +++ b/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 diff --git a/doc/hw/z80/sms/intro.txt b/doc/hw/z80/sms/intro.txt index ab60aaf..d321c3e 100644 --- a/doc/hw/z80/sms/intro.txt +++ b/doc/hw/z80/sms/intro.txt @@ -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! diff --git a/doc/sega.txt b/doc/sega.txt new file mode 100644 index 0000000..be703d0 --- /dev/null +++ b/doc/sega.txt @@ -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. diff --git a/tools/smsrom.c b/tools/smsrom.c deleted file mode 100644 index 77136d0..0000000 --- a/tools/smsrom.c +++ /dev/null @@ -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 -#include - -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> 8); - putchar(0); - putchar(0); - putchar(0); - putchar(hdsz); - return 0; -}