From 36b57d6221d89757421249febd2a07f0139130ea Mon Sep 17 00:00:00 2001 From: Ilya Shurumov Date: Thu, 29 Apr 2021 03:03:54 +0600 Subject: [PATCH] - adding PSX makefiles --- .gitignore | 6 +- PSXToolchain/.vscode/launch.json | 19 +++ PSXToolchain/Makefile | 109 ++++++++++++++++ PSXToolchain/README.md | 7 + PSXToolchain/common.mk | 104 +++++++++++++++ PSXToolchain/ps-exe.ld | 198 +++++++++++++++++++++++++++++ PSXToolchain/psx_build.bat | 19 +++ PSXToolchain/redriver2_overlays.ld | 77 +++++++++++ 8 files changed, 538 insertions(+), 1 deletion(-) create mode 100644 PSXToolchain/.vscode/launch.json create mode 100644 PSXToolchain/Makefile create mode 100644 PSXToolchain/README.md create mode 100644 PSXToolchain/common.mk create mode 100644 PSXToolchain/ps-exe.ld create mode 100644 PSXToolchain/psx_build.bat create mode 100644 PSXToolchain/redriver2_overlays.ld diff --git a/.gitignore b/.gitignore index 4ad6089a..0ba9e120 100644 --- a/.gitignore +++ b/.gitignore @@ -25,7 +25,11 @@ *.code-workspace .vscode/* .vs/* -PSXToolchain/* +PSXToolchain/GameSRC* +PSXToolchain/Overlay* +PSXToolchain/0_CD_DATA/* +PSXToolchain/PsyQ/* +PSXToolchain/mipsel-unknown-elf/* src_rebuild/dependencies/* src_rebuild/.vs/* src_rebuild/bin/* diff --git a/PSXToolchain/.vscode/launch.json b/PSXToolchain/.vscode/launch.json new file mode 100644 index 00000000..48987bd3 --- /dev/null +++ b/PSXToolchain/.vscode/launch.json @@ -0,0 +1,19 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + + { + "type": "gdb", + "request": "attach", + "name": "Attach to gdbserver", + "executable": "0_CD_DATA/DRIVER2.ps-exe", + "gdbpath": "D:/mingw/bin/gdb.exe", + "target": "localhost:3333", + "remote": true, + "cwd": "${workspaceRoot}" + } + ] +} \ No newline at end of file diff --git a/PSXToolchain/Makefile b/PSXToolchain/Makefile new file mode 100644 index 00000000..85994b79 --- /dev/null +++ b/PSXToolchain/Makefile @@ -0,0 +1,109 @@ +PSYQ_DIR ?= X:/PsyQ + +OBJDIR = obj +BINDIR ?= 0_CD_DATA/ +TARGET = DRIVER2 +TYPE = ps-exe +BUILD = Release + +SOURCES = GameSRC/Game + +OVERLAYSCRIPT ?= redriver2_overlays.ld +OVERLAYSECTION ?= .frnt .path .lead + +# Main sources +SRCS = \ + $(SOURCES)/ASM/asmtest.c\ + $(SOURCES)/ASM/compres.c\ + $(SOURCES)/ASM/d2mapasm.c\ + $(SOURCES)/ASM/rnc_2.c\ + $(SOURCES)/ASM/rndrasm.c\ + $(SOURCES)/C/E3stuff.c\ + $(SOURCES)/C/ai.c\ + $(SOURCES)/C/bcoll3d.c\ + $(SOURCES)/C/bcollide.c\ + $(SOURCES)/C/bomberman.c\ + $(SOURCES)/C/camera.c\ + $(SOURCES)/C/cars.c\ + $(SOURCES)/C/cell.c\ + $(SOURCES)/C/civ_ai.c\ + $(SOURCES)/C/convert.c\ + $(SOURCES)/C/cop_ai.c\ + $(SOURCES)/C/cosmetic.c\ + $(SOURCES)/C/cutscene.c\ + $(SOURCES)/C/debris.c\ + $(SOURCES)/C/denting.c\ + $(SOURCES)/C/director.c\ + $(SOURCES)/C/dr2roads.c\ + $(SOURCES)/C/draw.c\ + $(SOURCES)/C/drivinggames.c\ + $(SOURCES)/C/envsound.c\ + $(SOURCES)/C/event.c\ + $(SOURCES)/C/felony.c\ + $(SOURCES)/C/fmvplay.c\ + $(SOURCES)/C/gamesnd.c\ + $(SOURCES)/C/glaunch.c\ + $(SOURCES)/C/handling.c\ + $(SOURCES)/C/job_fx.c\ + $(SOURCES)/C/loadsave.c\ + $(SOURCES)/C/loadview.c\ + $(SOURCES)/C/main.c\ + $(SOURCES)/C/map.c\ + $(SOURCES)/C/mc_snd.c\ + $(SOURCES)/C/mdraw.c\ + $(SOURCES)/C/mgeneric.c\ + $(SOURCES)/C/mission.c\ + $(SOURCES)/C/models.c\ + $(SOURCES)/C/motion_c.c\ + $(SOURCES)/C/objanim.c\ + $(SOURCES)/C/objcoll.c\ + $(SOURCES)/C/overlay.c\ + $(SOURCES)/C/overmap.c\ + $(SOURCES)/C/pad.c\ + $(SOURCES)/C/pause.c\ + $(SOURCES)/C/pedest.c\ + $(SOURCES)/C/players.c\ + $(SOURCES)/C/pres.c\ + $(SOURCES)/C/replays.c\ + $(SOURCES)/C/roadbits.c\ + $(SOURCES)/C/scores.c\ + $(SOURCES)/C/search.c\ + $(SOURCES)/C/shadow.c\ + $(SOURCES)/C/sky.c\ + $(SOURCES)/C/sound.c\ + $(SOURCES)/C/spool.c\ + $(SOURCES)/C/state.c\ + $(SOURCES)/C/system.c\ + $(SOURCES)/C/targets.c\ + $(SOURCES)/C/texture.c\ + $(SOURCES)/C/tile.c\ + $(SOURCES)/C/time.c\ + $(SOURCES)/C/sysclock.c\ + $(SOURCES)/C/wheelforces.c\ + $(SOURCES)/C/xaplay.c\ + $(SOURCES)/C/xmplay.c + +# overlay sources +SRCS += \ + $(SOURCES)/Frontend/FEmain.c\ + $(SOURCES)/C/pathfind.c\ + $(SOURCES)/C/leadai.c + +SRCS += $(PSYQ_DIR)/common/crt0/crt0.s +INCL = $(SOURCES) $(PSYQ_DIR)/include + +DEFS = PSX NTSC_VERSION RELOC DEBUG_OPTIONS + +NOWARNS = write-strings narrowing + +CPPFLAGS += -x c++ -fno-threadsafe-statics $(addprefix -D,$(DEFS)) $(addprefix -I,$(INCL)) $(addprefix -Wno-,$(NOWARNS)) + +# Psy-Q libraries +LIBS = api c card etc gpu gte math mcrd pad snd spu cd + +LDFLAGS += -L$(PSYQ_DIR)/lib +LDFLAGS += -Wl,--start-group +LDFLAGS += $(addprefix -l,$(LIBS)) +LDFLAGS += -Wl,--end-group + +include common.mk \ No newline at end of file diff --git a/PSXToolchain/README.md b/PSXToolchain/README.md new file mode 100644 index 00000000..8a18fcd6 --- /dev/null +++ b/PSXToolchain/README.md @@ -0,0 +1,7 @@ +# Playstation build toolchain + +In order to start building a Playstation version of **REDRIVER2** you'll need to perform following steps: + + - Put **mipsel-unknown-elf** toolchain to this folder (https://github.com/majenkotech/mipsel-unknown-elf/releases) + - Obtain Psy-Q libraries converted for latest GCC + - Execute **psx_build.bat** \ No newline at end of file diff --git a/PSXToolchain/common.mk b/PSXToolchain/common.mk new file mode 100644 index 00000000..3ed4e4af --- /dev/null +++ b/PSXToolchain/common.mk @@ -0,0 +1,104 @@ +BUILD ?= Release + +HAS_LINUX_MIPS_GCC = $(shell which mipsel-linux-gnu-gcc > /dev/null 2> /dev/null && echo true || echo false) + +ifeq ($(HAS_LINUX_MIPS_GCC),true) +PREFIX ?= mipsel-linux-gnu +FORMAT ?= elf32-tradlittlemips +else +PREFIX ?= mipsel-unknown-elf +FORMAT ?= elf32-littlemips +endif + +# weird but it works +define \n + + +endef + +ROOTDIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) + +CC = $(PREFIX)-gcc +CXX = $(PREFIX)-g++ + +TYPE ?= cpe +LDSCRIPT ?= $(ROOTDIR)/$(TYPE).ld +ifneq ($(strip $(OVERLAYSCRIPT)),) +LDSCRIPT := $(addprefix $(OVERLAYSCRIPT) , -T$(LDSCRIPT)) +else +LDSCRIPT := $(addprefix $(ROOTDIR)/default.ld , -T$(LDSCRIPT)) +endif + +USE_FUNCTION_SECTIONS ?= true + +ARCHFLAGS = -march=mips1 -mabi=32 -EL -fno-pic -mno-shared -mno-abicalls -mfp32 -msoft-float +ARCHFLAGS += -fno-stack-protector -nostdlib -ffreestanding + +ifeq ($(USE_FUNCTION_SECTIONS),true) +CPPFLAGS += -ffunction-sections +endif + +CPPFLAGS += -mno-gpopt -fomit-frame-pointer +CPPFLAGS += -fno-builtin -fno-strict-aliasing -Wno-attributes +CPPFLAGS += $(ARCHFLAGS) +CPPFLAGS += -I$(ROOTDIR) + +LDFLAGS += -Wl,-Map=$(BINDIR)$(TARGET).map -nostdlib -T$(LDSCRIPT) -static -Wl,--gc-sections +LDFLAGS += $(ARCHFLAGS) -Wl,--oformat=$(FORMAT) + +# don't do O1/O2/O3 since it will grow code size +CPPFLAGS_Release += -Os +LDFLAGS_Release += -Os + +CPPFLAGS_Debug += -O0 + +LDFLAGS += -g +CPPFLAGS += -g + +CPPFLAGS += $(CPPFLAGS_$(BUILD)) +LDFLAGS += $(LDFLAGS_$(BUILD)) + +OBJS += $(addsuffix .o, $(basename $(SRCS))) + +all: dep $(BINDIR)$(TARGET).$(TYPE) + +$(BINDIR)$(TARGET).$(TYPE): $(BINDIR)$(TARGET).elf + $(PREFIX)-objcopy $(addprefix -R , $(OVERLAYSECTION)) -O binary $< $@ + $(foreach ovl, $(OVERLAYSECTION), $(PREFIX)-objcopy -j $(ovl) -O binary $< $(BINDIR)Overlay$(ovl) $(\n)) + +$(BINDIR)$(TARGET).elf: $(OBJS) + $(CC) -g -o $(BINDIR)$(TARGET).elf $(OBJS) $(LDFLAGS) + +%.o: %.s + $(CC) $(ARCHFLAGS) -I$(ROOTDIR) -g -c -o $@ $< + +%.dep: %.c + $(CC) $(CPPFLAGS) $(CFLAGS) -M -MT $(addsuffix .o, $(basename $@)) -MF $@ $< + +%.dep: %.cpp + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -M -MT $(addsuffix .o, $(basename $@)) -MF $@ $< + +%.dep: %.cc + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -M -MT $(addsuffix .o, $(basename $@)) -MF $@ $< + +# A bit broken, but that'll do in most cases. +%.dep: %.s + echo. 2> $@ + +DEPS := $(patsubst %.cpp, %.dep,$(filter %.cpp,$(SRCS))) +DEPS := $(patsubst %.cc, %.dep,$(filter %.cc,$(SRCS))) +DEPS += $(patsubst %.c, %.dep,$(filter %.c,$(SRCS))) +DEPS += $(patsubst %.s, %.dep,$(filter %.s,$(SRCS))) + +dep: $(DEPS) + +clean: + rm -f $(OBJS) $(BINDIR)Overlay.* $(BINDIR)*.elf $(BINDIR)*.ps-exe $(BINDIR)*.map $(DEPS) + +ifneq ($(MAKECMDGOALS), clean) +ifneq ($(MAKECMDGOALS), deepclean) +-include $(DEPS) +endif +endif + +.PHONY: clean dep all diff --git a/PSXToolchain/ps-exe.ld b/PSXToolchain/ps-exe.ld new file mode 100644 index 00000000..3714fb9f --- /dev/null +++ b/PSXToolchain/ps-exe.ld @@ -0,0 +1,198 @@ +/* + +MIT License + +Copyright (c) 2019 PCSX-Redux authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +OUTPUT_FORMAT("binary") + +EXTERN(_start) +ENTRY(_start) + +TLOAD_ADDR = DEFINED(TLOAD_ADDR) ? TLOAD_ADDR : 0x80010000; + +MEMORY { + loader : ORIGIN = (TLOAD_ADDR - 0x800), LENGTH = 2048 + ram (rwx) : ORIGIN = 0x80010000, LENGTH = 2M - 0x10000 + dcache : ORIGIN = 0x1f800000, LENGTH = 0x400 +} + +__ram_top = ORIGIN(ram) + LENGTH(ram); +__sp = __ram_top - 0x100; + +__dcache = ORIGIN(dcache); +__dcache_top = ORIGIN(dcache) + LENGTH(dcache); + +__bss_len = (__bss_end - __bss_start); +__ftext_len = (__ftext_end - __ftext_start); +__fdata_len = (__fdata_end - __fdata_start); + +__stack_start = ORIGIN(ram) + LENGTH(ram); + +SECTIONS { + .PSX_EXE_Header : { + /* + 0x0000 - 0x0007 : "PS-X EXE" + */ + BYTE(80); BYTE(83); BYTE(45); BYTE(88); BYTE(32); BYTE(69); BYTE(88); BYTE(69); + + /* 0x0008 - 0x000F : skip text_off and data_off since they're not supported by the PS1 BIOS */ + LONG(0); LONG(0); + + /* 0x0010 - 0x0013 : entry point */ + LONG(ABSOLUTE(_start)); + + /* 0x0014 - 0x0017 : initial value of $gp */ + LONG(0); + + /* 0x0018 - 0x001B : Memory address to load "text" section to. */ + /* + NOTE: The "text" section is actually all of the "load" + sections of the file including .text, .rodata, .data. + etc. + */ + LONG(TLOAD_ADDR); + + /* 0x001C - 0x001F : size, in bytes, of the "text" section. */ + LONG(__ftext_len + __fdata_len); + + /* 0x0020 - 0x002F : + Skip "data_addr", "data_size", "bss_addr" and "bss_size". + None of these are supported by retail PS1 BIOS. + */ + LONG(0); LONG(0); + LONG(0); LONG(0); + + /* 0x0030 - 0x0033 : Initial stack address. */ + LONG(DEFINED(_sp) ? ABSOLUTE(_sp) : 0x801FFF00); + + /* 0x0034 - 0x0037 : Initial stack size, set it to 0. */ + LONG(0); + + /* Skip the remaining fields as they're not supported by the BIOS */ + /* e.g. 2048 header bytes minus whatever we've actually used */ + . = . + 1992; + } > loader + + __ftext_start = ABSOLUTE(.); + .text TLOAD_ADDR : { + *(.start) + *(.init) + KEEP (*(SORT_NONE(.fini))) + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(.text .stub .text.* .gnu.linkonce.t.*) + + . = ALIGN(16); + KEEP(*(.init)) + . = ALIGN(16); + KEEP(*(.fini)) + } > ram + + . = ALIGN(16); + __text_end = .; + __ftext_end = ABSOLUTE(.); + + __fdata_start = ABSOLUTE(.); + + .rodata : { + *(.rodata .rodata.* .rdata .rdata.* .gnu.linkonce.r.*) + . = ALIGN(16); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(16); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + + . = ALIGN(16); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + __init_array_end = .; + + . = ALIGN(16); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + __fini_array_end = .; + __build_id = .; + *(.note.gnu.build-id) + __build_id_end = .; + } > ram + + .rodata1 : { + *(.rodata1) + } > ram + + __data_start = .; + .data : { + *(.a0table) + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + *(.sdata .sdata.* .gnu.linkonce.s.*) + *(.got.plt) + *(.got) + /* pad file to be a multiple of 2048 bytes. Needed for loading from CD-ROM. */ + . = ALIGN(2048); + } > ram + + __data_end = .; + __fdata_end = .; + + __bss_start = .; + .sbss (NOLOAD) : { + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + } > ram + + . = ALIGN(4); + __bss_end = .; + + __heap_start = __heap_base; + + . = ADDR(.text) - 0x800; + __end = .; + + /DISCARD/ : { *(.MIPS.abiflags) } + + /* Everything is statically linked, so discard PLTs. */ + /DISCARD/ : { *(.rel.iplt) *(.rela.iplt) *(.rel.plt) *(.rela.plt) *(.plt) *(.iplt) } + + /* Discard things that the standard link script drops, too. */ + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} diff --git a/PSXToolchain/psx_build.bat b/PSXToolchain/psx_build.bat new file mode 100644 index 00000000..a2675b85 --- /dev/null +++ b/PSXToolchain/psx_build.bat @@ -0,0 +1,19 @@ +set REDRIVER_FOLDER=%cd%/.. + +rem Make a symlink +mklink /J %REDRIVER_FOLDER%\PSXToolchain\GameSRC %REDRIVER_FOLDER%\src_rebuild + +rem Create output folder +mkdir 0_CD_DATA + +rem Create a virtual drive +SUBST X: %REDRIVER_FOLDER%\PSXToolchain + +set PATH=%PATH%;X:\mipsel-unknown-elf\bin; +make + +rem Cleanup +rem del GameSRC +SUBST X: /D + +pause \ No newline at end of file diff --git a/PSXToolchain/redriver2_overlays.ld b/PSXToolchain/redriver2_overlays.ld new file mode 100644 index 00000000..0b1c7ee1 --- /dev/null +++ b/PSXToolchain/redriver2_overlays.ld @@ -0,0 +1,77 @@ +__heap_base = memTab_end; + +SECTIONS { + + OVERLAY __bss_end : NOCROSSREFS SUBALIGN(4) + { + .memTab + { + memTab_org = .; + . = 0x50400; + memTab_end = .; + } + + .path + { + KEEP(GameSRC/Game/C/pathfind.o(.text)) + __path_ctor = .; + KEEP(GameSRC/Game/C/pathfind.o(.text.startup._GLOBAL__*)) + KEEP(GameSRC/Game/C/pathfind.o(.text.*)) + KEEP(GameSRC/Game/C/pathfind.o(.rodata*)) + KEEP(GameSRC/Game/C/pathfind.o(.sdata*)) + KEEP(GameSRC/Game/C/pathfind.o(.data*)) + KEEP(GameSRC/Game/C/pathfind.o(.sbss*)) + KEEP(GameSRC/Game/C/pathfind.o(.bss*)) + KEEP(GameSRC/Game/C/pathfind.o(.ctors)) + + . = ALIGN(4); + __path_end = .; + } + + .lead + { + KEEP(GameSRC/Game/C/leadai.o(.text)) + __lead_ctor = .; + KEEP(GameSRC/Game/C/leadai.o(.text.startup._GLOBAL__*)) + KEEP(GameSRC/Game/C/leadai.o(.text.*)) + KEEP(GameSRC/Game/C/leadai.o(.rodata*)) + KEEP(GameSRC/Game/C/leadai.o(.sdata*)) + KEEP(GameSRC/Game/C/leadai.o(.data*)) + KEEP(GameSRC/Game/C/leadai.o(.sbss*)) + KEEP(GameSRC/Game/C/leadai.o(.bss*)) + KEEP(GameSRC/Game/C/leadai.o(.ctors)) + + . = ALIGN(4); + __lead_end = .; + } + } + + OVERLAY LOADADDR(.memTab) + SIZEOF(.memTab) : NOCROSSREFS SUBALIGN(4) + { + .mallocTab + { + mallocTab_org = .; + . = 0xD7C00; + mallocTab_end = .; + } + + .frnt + { + KEEP(GameSRC/Game/*.o(.text)) + __frnt_ctor = .; + KEEP(GameSRC/Game/Frontend/*.o(.text.startup._GLOBAL__*)) + KEEP(GameSRC/Game/Frontend/*.o(.text.*)) + KEEP(GameSRC/Game/Frontend/*.o(.rodata*)) + KEEP(GameSRC/Game/Frontend/*.o(.sdata*)) + KEEP(GameSRC/Game/Frontend/*.o(.data*)) + KEEP(GameSRC/Game/Frontend/*.o(.sbss*)) + KEEP(GameSRC/Game/Frontend/*.o(.bss*)) + KEEP(GameSRC/Game/Frontend/*.o(.ctors)) + + . = ALIGN(4); + __frnt_end = .; + } + } +} + +