initial cd image build system

This commit is contained in:
Zack Buhman 2023-10-11 18:49:58 +00:00
parent 5c4c107eaf
commit 327e57a520
27 changed files with 603 additions and 1 deletions

11
.gitignore vendored
View File

@ -1,3 +1,12 @@
*.pyc
__pycache__
.~*
.~*
*.BIN
*.bin
*.elf
*.d
*.iso
*.cdi
*.o
scramble
cdi4dc

1
ABSTRACT.TXT Normal file
View File

@ -0,0 +1 @@
abstract

1
BIBLIOGR.TXT Normal file
View File

@ -0,0 +1 @@
bibliography

1
COPYRIGH.TXT Normal file
View File

@ -0,0 +1 @@
Copyright(c) SEGA ENTERPRISES, LTD. 1998

1
Makefile Normal file
View File

@ -0,0 +1 @@
include common.mk

112
common.mk Normal file
View File

@ -0,0 +1,112 @@
LIB ?= .
OPT ?= -Og
DEBUG ?= -g -gdwarf-4
GENERATED ?=
AARCH = --isa=sh4 --little
AFLAGS = --fatal-warnings
CARCH = -m4-single-only -ml
CFLAGS += -falign-functions=4 -ffunction-sections -fdata-sections -fshort-enums -ffreestanding -nostdlib
CFLAGS += -Wall -Werror -Wfatal-errors -Wno-error=unused-variable
DEPFLAGS = -MMD -E
# --print-gc-sections
LDFLAGS = --gc-sections --no-warn-rwx-segment --print-memory-usage --entry=_start --orphan-handling=error
CXXFLAGS = -std=c++20 -fno-exceptions -fno-non-call-exceptions -fno-rtti -fno-threadsafe-statics
TARGET = sh4-none-elf-
CC = $(TARGET)gcc
CXX = $(TARGET)g++
AS = $(TARGET)as
LD = $(TARGET)ld
OBJCOPY = $(TARGET)objcopy
OBJDUMP = $(TARGET)objdump
IP_OBJ = \
systemid.o \
toc.o \
sg/sg_sec.o \
sg/sg_arejp.o \
sg/sg_areus.o \
sg/sg_areec.o \
sg/sg_are00.o \
sg/sg_are01.o \
sg/sg_are02.o \
sg/sg_are03.o \
sg/sg_are04.o \
sg/sg_ini.o \
sg/aip.o
all: main.elf
%.o: %.obj
$(OBJCOPY) -g \
--rename-section IP=.text.$* \
$< $@
%.o: %.s
$(AS) $(AARCH) $(AFLAGS) $(DEBUG) $< -o $@
%.c.d: | $(GENERATED)
$(CC) $(CARCH) $(CFLAGS) $(OPT) $(DEBUG) $(DEPFLAGS) -c $(basename $@) -MF $@ -o /dev/null
%.o: %.c %.c.d
$(CC) $(CARCH) $(CFLAGS) $(OPT) $(DEBUG) -c $< -o $@
main.elf: main.o
$(LD) $(LDFLAGS) -T $(LIB)/main.lds $^ -o $@
%.bin: %.elf
$(OBJCOPY) -O binary $< $@
ip.elf: $(IP_OBJ)
$(LD) --print-memory-usage -T $(LIB)/ip.lds $^ -o $@
audio.pcm:
sox \
--rate 44100 \
--encoding signed-integer \
--bits 16 \
--channels 2 \
--endian little \
--null \
$@.raw \
synth 1 sin 440 vol -10dB
mv $@.raw $@
1ST_READ.BIN: main.bin
./scramble main.bin 1ST_READ.BIN
%.iso: 1ST_READ.BIN ip.bin
mkisofs \
-C 0,11702 \
-sysid "SEGA SEGAKATANA" \
-volid "SAMPLE_GAME_TITLE" \
-volset "SAMPLE_GAME_TITLE" \
-publisher "SEGA ENTERPRISES, LTD." \
-preparer "CRI CD CRAFT VER.2.27" \
-copyright "COPYRIGH.TXT" \
-abstract "ABSTRACT.TXT" \
-biblio "BIBLIOGR.TXT" \
-sectype data \
-G ip.bin \
-o $@ \
-graft-points \
/=./1ST_READ.BIN \
/=./COPYRIGH.TXT \
/=./ABSTRACT.TXT \
/=./BIBLIOGR.TXT
%.cdi: %.iso
./cdi4dc $< $@ >/dev/null
.SUFFIXES:
.INTERMEDIATE:
.SECONDARY:
.PHONY: all clean
%: RCS/%,v
%: RCS/%
%: %,v
%: s.%
%: SCCS/s.%

56
ip.lds Normal file
View File

@ -0,0 +1,56 @@
OUTPUT_FORMAT("elf32-shl", "elf32-shl", "elf32-shl")
MEMORY
{
systemid (arx) : ORIGIN = 0x8c008000, LENGTH = 0x100
toc (arx) : ORIGIN = 0x8c008100, LENGTH = 0x200
sg_sec (arx) : ORIGIN = 0x8c008300, LENGTH = 0x3400
sg_are (arx) : ORIGIN = 0x8c00b700, LENGTH = 0x100
sg_ini (arx) : ORIGIN = 0x8c00b800, LENGTH = 0x2800
aip (arx) : ORIGIN = 0x8c00e000, LENGTH = 0x2000
}
SECTIONS
{
.text.systemid :
{
KEEP(*(.text.systemid))
} > systemid
.text.toc :
{
KEEP(*(.text.toc))
} > toc
.text.sg_sec :
{
KEEP(*(.text.sg_sec))
} > sg_sec
.text.sg_are :
{
KEEP(*(.text.sg_arejp))
KEEP(*(.text.sg_areus))
KEEP(*(.text.sg_areec))
KEEP(*(.text.sg_are00))
KEEP(*(.text.sg_are01))
KEEP(*(.text.sg_are02))
KEEP(*(.text.sg_are03))
KEEP(*(.text.sg_are04))
} > sg_are
.text.sg_ini :
{
KEEP(*(.text.sg_ini))
} > sg_ini
.text.aip :
{
KEEP(*(.text.aip))
} > aip
/DISCARD/ :
{
*(*)
}
}

53
main.c Normal file
View File

@ -0,0 +1,53 @@
#include <stdint.h>
volatile uint8_t * SCFTDR2 = (volatile uint8_t *)0xFFE8000C;
volatile uint32_t * SOFT_RESET = (volatile uint32_t *)0xa05f8008;
volatile uint32_t * STARTRENDER = (volatile uint32_t *)0xa05f8014;
volatile uint32_t * VO_CONTROL = (volatile uint32_t *)0xa05f80e8;
volatile uint32_t * VO_BORDER_COL = (volatile uint32_t *)0xa05f8040;
volatile uint32_t * FB_R_SOF1 = (volatile uint32_t *)0xa05f8050;
volatile uint32_t * RAM = (volatile uint32_t *)0xa5000000;
volatile uint32_t * SPG_STATUS = (volatile uint32_t *)0xa05f810;
void start()
{
*SCFTDR2 = 'H';
*SCFTDR2 = 'e';
*SCFTDR2 = 'l';
*SCFTDR2 = 'l';
*SCFTDR2 = '3';
*SOFT_RESET = 0b111;
*SOFT_RESET = 0b000;
*VO_CONTROL |= 1 << 3;
*VO_BORDER_COL = 31;
for (int i = 0; i < (2*1024*1024 + 1024 * 2 + 512 + 4) / 4; i++) {
RAM[i] = 0x1;
}
while (1) {
}
}
/*
{
DM_640x480,
640, 480,
VID_INTERLACE, // flags
CT_VGA, // cable type
0, // pixel mode
0x20C, 0x359, // scanlines, clocks per scanline
0xAC, 0x28, // bitmap x, bitmap y
0x15, 0x104, // first scanline interrupt, second scanline interrupt
0x7E, 0x345, // border x start, border x stop
0x24, 0x204, // border y start, border y stop
0, 1, // current framebuffer, number of framebuffers
{ 0, 0, 0, 0 } // offset to framebuffers
},
*/

53
main.lds Normal file
View File

@ -0,0 +1,53 @@
OUTPUT_FORMAT("elf32-shl", "elf32-shl", "elf32-shl")
MEMORY
{
ram : ORIGIN = 0x8c010000, LENGTH = 1M
}
SECTIONS
{
. = 0x8c010000;
.text ALIGN(4) : SUBALIGN(4)
{
KEEP(*(.text.start))
*(.text)
*(.text.*)
} > ram
.data ALIGN(4) : SUBALIGN(4)
{
*(.data)
*(.data.*)
} > ram
.rodata ALIGN(4) : SUBALIGN(4)
{
*(.rodata)
*(.rodata.*)
} > ram
.ctors ALIGN(4) : SUBALIGN(4)
{
KEEP(*(.ctors))
KEEP(*(.ctors.*))
} > ram
.bss ALIGN(4) (NOLOAD) : SUBALIGN(4)
{
*(.bss)
*(.bss.*)
} > ram
/DISCARD/ :
{
*(.debug*)
*(.comment*)
*(.rela*)
}
__bss_link_start = ADDR(.bss);
__bss_link_end = ADDR(.bss) + SIZEOF(.bss);
__ctors_link_start = ADDR(.ctors);
__ctors_link_end = ADDR(.ctors) + SIZEOF(.ctors);
}

259
scramble.c Normal file
View File

@ -0,0 +1,259 @@
#include <stdio.h>
#include <stdlib.h>
#define MAXCHUNK (2048*1024)
static unsigned int seed;
void my_srand(unsigned int n)
{
seed = n & 0xffff;
}
unsigned int my_rand()
{
seed = (seed * 2109 + 9273) & 0x7fff;
return (seed + 0xc000) & 0xffff;
}
void load(FILE *fh, unsigned char *ptr, unsigned long sz)
{
if(fread(ptr, 1, sz, fh) != sz)
{
fprintf(stderr, "Read error!\n");
exit(1);
}
}
void load_chunk(FILE *fh, unsigned char *ptr, unsigned long sz)
{
static int idx[MAXCHUNK/32];
int i;
/* Convert chunk size to number of slices */
sz /= 32;
/* Initialize index table with unity,
so that each slice gets loaded exactly once */
for(i = 0; i < sz; i++)
idx[i] = i;
for(i = sz-1; i >= 0; --i)
{
/* Select a replacement index */
int x = (my_rand() * i) >> 16;
/* Swap */
int tmp = idx[i];
idx[i] = idx[x];
idx[x] = tmp;
/* Load resulting slice */
load(fh, ptr+32*idx[i], 32);
}
}
void load_file(FILE *fh, unsigned char *ptr, unsigned long filesz)
{
unsigned long chunksz;
my_srand(filesz);
/* Descramble 2 meg blocks for as long as possible, then
gradually reduce the window down to 32 bytes (1 slice) */
for(chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1)
while(filesz >= chunksz)
{
load_chunk(fh, ptr, chunksz);
filesz -= chunksz;
ptr += chunksz;
}
/* Load final incomplete slice */
if(filesz)
load(fh, ptr, filesz);
}
void read_file(char *filename, unsigned char **ptr, unsigned long *sz)
{
FILE *fh = fopen(filename, "rb");
if(fh == NULL)
{
fprintf(stderr, "Can't open \"%s\".\n", filename);
exit(1);
}
if(fseek(fh, 0, SEEK_END)<0)
{
fprintf(stderr, "Seek error.\n");
exit(1);
}
*sz = ftell(fh);
*ptr = malloc(*sz);
if( *ptr == NULL )
{
fprintf(stderr, "Out of memory.\n");
exit(1);
}
if(fseek(fh, 0, SEEK_SET)<0)
{
fprintf(stderr, "Seek error.\n");
exit(1);
}
load_file(fh, *ptr, *sz);
fclose(fh);
}
void save(FILE *fh, unsigned char *ptr, unsigned long sz)
{
if(fwrite(ptr, 1, sz, fh) != sz)
{
fprintf(stderr, "Write error!\n");
exit(1);
}
}
void save_chunk(FILE *fh, unsigned char *ptr, unsigned long sz)
{
static int idx[MAXCHUNK/32];
int i;
/* Convert chunk size to number of slices */
sz /= 32;
/* Initialize index table with unity,
so that each slice gets saved exactly once */
for(i = 0; i < sz; i++)
idx[i] = i;
for(i = sz-1; i >= 0; --i)
{
/* Select a replacement index */
int x = (my_rand() * i) >> 16;
/* Swap */
int tmp = idx[i];
idx[i] = idx[x];
idx[x] = tmp;
/* Save resulting slice */
save(fh, ptr+32*idx[i], 32);
}
}
void save_file(FILE *fh, unsigned char *ptr, unsigned long filesz)
{
unsigned long chunksz;
my_srand(filesz);
/* Descramble 2 meg blocks for as long as possible, then
gradually reduce the window down to 32 bytes (1 slice) */
for(chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1)
while(filesz >= chunksz)
{
save_chunk(fh, ptr, chunksz);
filesz -= chunksz;
ptr += chunksz;
}
/* Save final incomplete slice */
if(filesz)
save(fh, ptr, filesz);
}
void write_file(char *filename, unsigned char *ptr, unsigned long sz)
{
FILE *fh = fopen(filename, "wb");
if(fh == NULL)
{
fprintf(stderr, "Can't open \"%s\".\n", filename);
exit(1);
}
save_file(fh, ptr, sz);
fclose(fh);
}
void descramble(char *src, char *dst)
{
unsigned char *ptr = NULL;
unsigned long sz = 0;
FILE *fh;
read_file(src, &ptr, &sz);
fh = fopen(dst, "wb");
if(fh == NULL)
{
fprintf(stderr, "Can't open \"%s\".\n", dst);
exit(1);
}
if( fwrite(ptr, 1, sz, fh) != sz )
{
fprintf(stderr, "Write error.\n");
exit(1);
}
fclose(fh);
free(ptr);
}
void scramble(char *src, char *dst)
{
unsigned char *ptr = NULL;
unsigned long sz = 0;
FILE *fh;
fh = fopen(src, "rb");
if(fh == NULL)
{
fprintf(stderr, "Can't open \"%s\".\n", src);
exit(1);
}
if(fseek(fh, 0, SEEK_END)<0)
{
fprintf(stderr, "Seek error.\n");
exit(1);
}
sz = ftell(fh);
ptr = malloc(sz);
if( ptr == NULL )
{
fprintf(stderr, "Out of memory.\n");
exit(1);
}
if(fseek(fh, 0, SEEK_SET)<0)
{
fprintf(stderr, "Seek error.\n");
exit(1);
}
if( fread(ptr, 1, sz, fh) != sz )
{
fprintf(stderr, "Read error.\n");
exit(1);
}
fclose(fh);
write_file(dst, ptr, sz);
free(ptr);
}
int main(int argc, char *argv[])
{
int opt = 0;
if(argc > 1 && !strcmp(argv[1], "-d"))
opt ++;
if(argc != 3+opt)
{
fprintf(stderr, "Usage: %s [-d] from to\n", argv[0]);
exit(1);
}
if(opt)
descramble(argv[2], argv[3]);
else
scramble(argv[1], argv[2]);
return 0;
}

BIN
sg/aip.obj Normal file

Binary file not shown.

BIN
sg/sg_are00.obj Normal file

Binary file not shown.

BIN
sg/sg_are01.obj Normal file

Binary file not shown.

BIN
sg/sg_are02.obj Normal file

Binary file not shown.

BIN
sg/sg_are03.obj Normal file

Binary file not shown.

BIN
sg/sg_are04.obj Normal file

Binary file not shown.

BIN
sg/sg_are05.obj Normal file

Binary file not shown.

BIN
sg/sg_are06.obj Normal file

Binary file not shown.

BIN
sg/sg_areec.obj Normal file

Binary file not shown.

BIN
sg/sg_arejp.obj Normal file

Binary file not shown.

BIN
sg/sg_areus.obj Normal file

Binary file not shown.

BIN
sg/sg_ini.obj Normal file

Binary file not shown.

BIN
sg/sg_sec.obj Normal file

Binary file not shown.

BIN
sg/strt2.obj Normal file

Binary file not shown.

BIN
sg/zero.obj Normal file

Binary file not shown.

52
systemid.s Normal file
View File

@ -0,0 +1,52 @@
/*
<A><-------B------> <C->
1100 0000 0000 0000 1000 0001 0000
0000 0000 0000 0000 0000 0000 0000
^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^ ^
|||| |||| |||| |||| |||| | |
|||| |||| |||| |||| |||| | +----- Uses Windows CE
|||| |||| |||| |||| |||| |
|||| |||| |||| |||| |||| +----- VGA box support
|||| |||| |||| |||| ||||
|||| |||| |||| |||| |||+----- Other expansions
|||| |||| |||| |||| ||+----- Puru Puru pack
|||| |||| |||| |||| |+----- Mike device
|||| |||| |||| |||| +----- Memory card
|||| |||| |||| |||+------ Start + A + B + Directions
|||| |||| |||| ||+------ C button
|||| |||| |||| |+------ D button
|||| |||| |||| +------ X button
|||| |||| |||+------- Y button
|||| |||| ||+------- Z button
|||| |||| |+------- Expanded direction buttons
|||| |||| +------- Analog R trigger
|||| |||+-------- Analog L trigger
|||| ||+-------- Analog horizontal controller
|||| |+-------- Analog vertical controller
|||| +-------- Expanded analog horizontal
|||+--------- Expanded analog vertical
||+--------- Gun
|+--------- Keyboard
+--------- Mouse
*/
.section .text.systemid
.ascii "SEGA SEGAKATANA " /* H/W identifier */
.ascii "SEGA ENTERPRISES" /* H/W Vendor ID */
.ascii "39F1 " /* Media ID */
.ascii "GD-ROM1/1 " /* Media information */
.ascii "JUE " /* Compatible Area Symbol */
.ascii "C000810 " /* Compatible peripherals */
.ascii "HDR-0900 " /* Product number */
.ascii "V0.000" /* Version number */
.ascii "19980901" /* Release date */
.ascii " " /* Reserved */
.ascii "1ST_READ.BIN"
.ascii " " /* Reserved */
.ascii "SEGA LC-KAISYAID" /* Maker identifier */
.ascii "SAMPLE GAME " /* Game title */
.fill (96-16),1,0x20 /* Game title */
.fill 32,1,0x20 /* Reserved */

4
toc.s Normal file
View File

@ -0,0 +1,4 @@
.section .text.toc
.fill (101*4),1,0xff
.fill (27 *4),1,0x00