mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-22 05:59:15 +01:00
[SC64][SW][DOCS] Reduced bootloader binary size / updated readme
This commit is contained in:
parent
5b85b0f661
commit
aa82984472
@ -15,11 +15,12 @@
|
|||||||
- Status LED and button for general use
|
- Status LED and button for general use
|
||||||
- 64DD add-on emulation
|
- 64DD add-on emulation
|
||||||
- IS-Viewer 64 debug interface
|
- IS-Viewer 64 debug interface
|
||||||
- Software and firmware update via USB interface
|
|
||||||
- N64 bootloader with support for IPL3 registers spoofing and loading menu from SD card
|
- N64 bootloader with support for IPL3 registers spoofing and loading menu from SD card
|
||||||
- Enhanced [UltraCIC_C](https://github.com/jago85/UltraCIC_C) emulation with automatic region switching and programmable seed/checksum values
|
- Enhanced [UltraCIC_C](https://github.com/jago85/UltraCIC_C) emulation with automatic region switching and programmable seed/checksum values
|
||||||
- PC app for communicating with flashcart (game/save data upload/download, feature enable control and debug terminal)
|
- PC app for communicating with flashcart (game/save data upload/download, feature enable control and debug terminal)
|
||||||
- [UNFLoader](https://github.com/buu342/N64-UNFLoader) support
|
- [UNFLoader](https://github.com/buu342/N64-UNFLoader) support
|
||||||
|
- Initial board programming via UART header on board or dedicated JTAG/SWD interfaces
|
||||||
|
- Software and firmware update via USB interface
|
||||||
- 3D printable plastic shell
|
- 3D printable plastic shell
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -1,95 +1,95 @@
|
|||||||
TOOLCHAIN = mips64-elf-
|
TOOLCHAIN = mips64-elf-
|
||||||
CC = $(TOOLCHAIN)gcc
|
CC = $(TOOLCHAIN)gcc
|
||||||
CXX = $(TOOLCHAIN)g++
|
CXX = $(TOOLCHAIN)g++
|
||||||
OBJCOPY = $(TOOLCHAIN)objcopy
|
OBJCOPY = $(TOOLCHAIN)objcopy
|
||||||
OBJDUMP = $(TOOLCHAIN)objdump
|
OBJDUMP = $(TOOLCHAIN)objdump
|
||||||
SIZE = $(TOOLCHAIN)size
|
SIZE = $(TOOLCHAIN)size
|
||||||
PYTHON = python3
|
PYTHON = python3
|
||||||
|
|
||||||
FLAGS = -march=vr4300 -mtune=vr4300 $(USER_FLAGS)
|
FLAGS = -march=vr4300 -mtune=vr4300 $(USER_FLAGS)
|
||||||
CFLAGS = -Os -Wall -ffunction-sections -fdata-sections -ffreestanding -MMD -MP
|
CFLAGS = -Os -Wall -ffunction-sections -fdata-sections -ffreestanding -MMD -MP
|
||||||
ASFLAGS = -Wa,-I$(N64_INST)/mips64-elf/lib
|
ASFLAGS = -Wa,-I$(N64_INST)/mips64-elf/lib
|
||||||
LDFLAGS = -lc -nostartfiles -Wl,--gc-sections
|
LDFLAGS = -lc -nostartfiles -Wl,--gc-sections
|
||||||
|
|
||||||
SRC_DIR = src
|
SRC_DIR = src
|
||||||
ASSET_DIR = assets
|
ASSET_DIR = assets
|
||||||
BUILD_DIR = build
|
BUILD_DIR = build
|
||||||
|
|
||||||
SRC_FILES = \
|
SRC_FILES = \
|
||||||
startup.S \
|
startup.S \
|
||||||
boot.c \
|
boot.c \
|
||||||
crc32.c \
|
crc32.c \
|
||||||
display.c \
|
display.c \
|
||||||
error.c \
|
error.c \
|
||||||
exception.c \
|
exception.c \
|
||||||
exception.S \
|
exception.S \
|
||||||
font.c \
|
font.c \
|
||||||
init.c \
|
init.c \
|
||||||
interrupt.c \
|
interrupt.c \
|
||||||
io.c \
|
io.c \
|
||||||
ipl2.S \
|
ipl2.S \
|
||||||
main.c \
|
main.c \
|
||||||
menu.c \
|
menu.c \
|
||||||
sc64.c \
|
sc64.c \
|
||||||
syscalls.c \
|
syscalls.c \
|
||||||
test.c \
|
test.c \
|
||||||
version.c \
|
version.c \
|
||||||
fatfs/diskio.c \
|
fatfs/diskio.c \
|
||||||
fatfs/ff.c \
|
fatfs/ff.c \
|
||||||
fatfs/ffsystem.c \
|
fatfs/ffsystem.c \
|
||||||
fatfs/ffunicode.c
|
fatfs/ffunicode.c
|
||||||
|
|
||||||
ASSET_FILES = \
|
ASSET_FILES = \
|
||||||
sc64_logo_640_240_dimmed.png
|
sc64_logo_640_240_dimmed.png
|
||||||
|
|
||||||
SRCS = $(SRC_FILES) $(ASSET_FILES)
|
SRCS = $(SRC_FILES) $(ASSET_FILES)
|
||||||
SRC_OBJS = $(patsubst %,%.o,$(SRC_FILES))
|
SRC_OBJS = $(patsubst %,%.o,$(SRC_FILES))
|
||||||
ASSET_OBJS = $(patsubst %,%.asset.o,$(basename $(ASSET_FILES)))
|
ASSET_OBJS = $(patsubst %,%.asset.o,$(basename $(ASSET_FILES)))
|
||||||
OBJS = $(addprefix $(BUILD_DIR)/,$(notdir $(SRC_OBJS) $(ASSET_OBJS)))
|
OBJS = $(addprefix $(BUILD_DIR)/,$(notdir $(SRC_OBJS) $(ASSET_OBJS)))
|
||||||
DEPS = $(OBJS:.o=.d)
|
DEPS = $(OBJS:.o=.d)
|
||||||
VPATH = $(SRC_DIR) $(SRC_DIR)/fatfs $(ASSET_DIR)
|
VPATH = $(SRC_DIR) $(SRC_DIR)/fatfs $(ASSET_DIR)
|
||||||
|
|
||||||
$(@info $(shell mkdir -p ./$(BUILD_DIR) &> /dev/null))
|
$(@info $(shell mkdir -p ./$(BUILD_DIR) &> /dev/null))
|
||||||
|
|
||||||
$(BUILD_DIR)/%.S.o: %.S
|
$(BUILD_DIR)/%.S.o: %.S
|
||||||
$(CC) -x assembler-with-cpp $(FLAGS) $(ASFLAGS) $(CFLAGS) -c $< -o $@
|
$(CC) -x assembler-with-cpp $(FLAGS) $(ASFLAGS) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/%.c.o: %.c
|
$(BUILD_DIR)/%.c.o: %.c
|
||||||
$(CC) $(FLAGS) $(CFLAGS) -c $< -o $@
|
$(CC) $(FLAGS) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/%.asset: $(ASSET_DIR)/%.png
|
$(BUILD_DIR)/%.asset: $(ASSET_DIR)/%.png tools/asset_converter.py
|
||||||
$(PYTHON) tools/asset_converter.py $< $@
|
$(PYTHON) tools/asset_converter.py $< $@ --compress
|
||||||
|
|
||||||
$(BUILD_DIR)/%.asset.o: $(BUILD_DIR)/%.asset $(ASSET_DIR)/assets.S
|
$(BUILD_DIR)/%.asset.o: $(BUILD_DIR)/%.asset $(ASSET_DIR)/assets.S
|
||||||
@sed -e "s,@sym@,$*,g" -e "s,@file@,$<," < $(ASSET_DIR)/assets.S | $(CC) -x assembler-with-cpp $(FLAGS) $(ASFLAGS) $(CFLAGS) -c - -o $@
|
@sed -e "s,@sym@,$*,g" -e "s,@file@,$<," < $(ASSET_DIR)/assets.S | $(CC) -x assembler-with-cpp $(FLAGS) $(ASFLAGS) $(CFLAGS) -c - -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/bootloader.elf: $(OBJS) N64.ld
|
$(BUILD_DIR)/bootloader.elf: $(OBJS) N64.ld
|
||||||
$(CXX) $(FLAGS) $(LDFLAGS) -TN64.ld $(OBJS) -o $@
|
$(CXX) $(FLAGS) $(LDFLAGS) -TN64.ld $(OBJS) -o $@
|
||||||
@$(OBJDUMP) -S $@ > $(BUILD_DIR)/bootloader.lst
|
@$(OBJDUMP) -S $@ > $(BUILD_DIR)/bootloader.lst
|
||||||
|
|
||||||
$(BUILD_DIR)/bootloader.bin: $(BUILD_DIR)/bootloader.elf
|
$(BUILD_DIR)/bootloader.bin: $(BUILD_DIR)/bootloader.elf tools/strip.py
|
||||||
@$(OBJCOPY) -O binary $< $@
|
@$(OBJCOPY) -O binary $< $@
|
||||||
@chksum64 $@ > /dev/null
|
@chksum64 $@ > /dev/null
|
||||||
@$(PYTHON) tools/strip.py $@
|
@$(PYTHON) tools/strip.py $@
|
||||||
|
|
||||||
$(BUILD_DIR)/bootloader.hex: $(BUILD_DIR)/bootloader.bin
|
$(BUILD_DIR)/bootloader.hex: $(BUILD_DIR)/bootloader.bin
|
||||||
@$(OBJCOPY) -I binary -O ihex $< $@
|
@$(OBJCOPY) -I binary -O ihex $< $@
|
||||||
|
|
||||||
print_size: $(BUILD_DIR)/bootloader.elf
|
print_size: $(BUILD_DIR)/bootloader.elf
|
||||||
@echo 'Size of modules:'
|
@echo 'Size of modules:'
|
||||||
@$(SIZE) -B -d -t --common $(OBJS)
|
@$(SIZE) -B -d -t --common $(OBJS)
|
||||||
@echo 'Size of bootloader:'
|
@echo 'Size of bootloader:'
|
||||||
@$(SIZE) -B -d $<
|
@$(SIZE) -B -d $<
|
||||||
|
|
||||||
all: $(BUILD_DIR)/bootloader.hex print_size
|
all: $(BUILD_DIR)/bootloader.hex print_size
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@rm -rf ./$(BUILD_DIR)/*
|
@rm -rf ./$(BUILD_DIR)/*
|
||||||
|
|
||||||
$(BUILD_DIR)/version.c.o: .FORCE
|
$(BUILD_DIR)/version.c.o: .FORCE
|
||||||
|
|
||||||
.FORCE:
|
.FORCE:
|
||||||
|
|
||||||
.PHONY: .FORCE all clean print_size
|
.PHONY: .FORCE all clean print_size
|
||||||
|
|
||||||
-include $(DEPS)
|
-include $(DEPS)
|
||||||
|
@ -60,6 +60,34 @@ static const vi_regs_t vi_config[] = {{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
|
static void display_decompress_background (uint32_t *background) {
|
||||||
|
uint32_t pixel_count = ((*background++) / sizeof(uint32_t));
|
||||||
|
uint32_t pixels_painted = 0;
|
||||||
|
uint8_t *background_data = (uint8_t *) (background);
|
||||||
|
uint32_t *framebuffer = (uint32_t *) (display_framebuffer);
|
||||||
|
|
||||||
|
while (pixels_painted < pixel_count) {
|
||||||
|
int pixel_repeat = ((background_data[0]) + 1);
|
||||||
|
uint32_t pixel_value = (
|
||||||
|
((background_data[1]) << 24) |
|
||||||
|
((background_data[2]) << 16) |
|
||||||
|
((background_data[3]) << 8) |
|
||||||
|
(background_data[4])
|
||||||
|
);
|
||||||
|
for (int i = 0; i < pixel_repeat; i++) {
|
||||||
|
io_write(framebuffer++, pixel_value);
|
||||||
|
}
|
||||||
|
pixels_painted += pixel_repeat;
|
||||||
|
background_data += 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void display_clear_background (void) {
|
||||||
|
for (int i = 0; i < (SCREEN_WIDTH * SCREEN_HEIGHT); i++) {
|
||||||
|
io_write(&display_framebuffer[i], BACKGROUND_COLOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void display_draw_character (char c) {
|
static void display_draw_character (char c) {
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
char_x = BORDER_WIDTH;
|
char_x = BORDER_WIDTH;
|
||||||
@ -106,14 +134,10 @@ void display_init (uint32_t *background) {
|
|||||||
char_x = BORDER_WIDTH;
|
char_x = BORDER_WIDTH;
|
||||||
char_y = BORDER_HEIGHT;
|
char_y = BORDER_HEIGHT;
|
||||||
|
|
||||||
if (background == NULL) {
|
if (background != NULL) {
|
||||||
for (int i = 0; i < (SCREEN_WIDTH * SCREEN_HEIGHT); i++) {
|
display_decompress_background(background);
|
||||||
io_write(&display_framebuffer[i], BACKGROUND_COLOR);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < (SCREEN_WIDTH * SCREEN_HEIGHT); i++) {
|
display_clear_background();
|
||||||
io_write(&display_framebuffer[i], *background++);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
io_write(&VI->MADDR, (uint32_t) (display_framebuffer));
|
io_write(&VI->MADDR, (uint32_t) (display_framebuffer));
|
||||||
|
@ -5,22 +5,53 @@ from PIL import Image
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def compress(data: bytes, step_size: int=4) -> bytes:
|
||||||
|
uncompressed_length = len(data)
|
||||||
|
|
||||||
|
if ((uncompressed_length % step_size) != 0):
|
||||||
|
raise ValueError(f'Data length not aligned to {step_size}')
|
||||||
|
|
||||||
|
compressed_data = bytes()
|
||||||
|
compressed_data += uncompressed_length.to_bytes(4, byteorder='big')
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
last_value = b''
|
||||||
|
|
||||||
|
for offset in range(0, uncompressed_length + step_size, step_size):
|
||||||
|
next_value = data[offset:(offset + step_size)]
|
||||||
|
|
||||||
|
if (offset != 0):
|
||||||
|
if ((next_value == last_value) and (count < 255)):
|
||||||
|
count += 1
|
||||||
|
else:
|
||||||
|
compressed_data += count.to_bytes(1, byteorder='big')
|
||||||
|
compressed_data += last_value
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
last_value = next_value
|
||||||
|
|
||||||
|
return compressed_data
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
if (len(sys.argv) != 3):
|
if (len(sys.argv) < 3):
|
||||||
print(f"Usage: python {sys.argv[0]} input_path output_path")
|
print(f"Usage: python {sys.argv[0]} input_path output_path [--compress]")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
asset_input = sys.argv[1]
|
asset_input = sys.argv[1]
|
||||||
asset_output = sys.argv[2]
|
asset_output = sys.argv[2]
|
||||||
|
asset_compress = len(sys.argv) > 3 and (sys.argv[3] == '--compress')
|
||||||
|
|
||||||
source_asset = None
|
source_asset = None
|
||||||
final_asset = None
|
final_asset = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
source_asset = Image.open(asset_input)
|
source_asset = Image.open(asset_input)
|
||||||
converted_asset = source_asset.convert("RGBA")
|
converted_asset = source_asset.convert("RGBA").tobytes()
|
||||||
|
if (asset_compress):
|
||||||
|
converted_asset = compress(converted_asset)
|
||||||
final_asset = open(asset_output, "wb")
|
final_asset = open(asset_output, "wb")
|
||||||
final_asset.write(converted_asset.tobytes())
|
final_asset.write(converted_asset)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
print(f"Couldn't open file \"{asset_input}\"")
|
print(f"Couldn't open file \"{asset_input}\"")
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
Loading…
Reference in New Issue
Block a user