From 72cf6380cd4882da1ecc1266c1ebb29cd04401a1 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Tue, 5 Mar 2024 03:25:12 +0200 Subject: [PATCH] initial commit --- .gitignore | 6 +++++ Makefile | 43 ++++++++++++++++++++++++++++++++++++ psx.ld | 53 ++++++++++++++++++++++++++++++++++++++++++++ src/exehdr.S | 18 +++++++++++++++ src/main.c | 4 ++++ src/psxregs.h | 40 +++++++++++++++++++++++++++++++++ src/startup.S | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 232 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 psx.ld create mode 100644 src/exehdr.S create mode 100644 src/main.c create mode 100644 src/psxregs.h create mode 100644 src/startup.S diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e3b2a3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.o +*.d +*.swp +*.elf +*.psx +*.map diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5da7d41 --- /dev/null +++ b/Makefile @@ -0,0 +1,43 @@ +csrc = $(wildcard src/*.c) +ssrc = $(wildcard src/*.S) +obj = $(csrc:.c=.o) $(ssrc:.S=.o) +dep = $(csrc:.c=.d) $(ssrc:.S=.d) + +elf = test1.elf +bin = test1.psx + +TCPREFIX = mipsel-linux-gnu- + +CC = $(TCPREFIX)gcc +AS = $(TCPREFIX)as +LD = $(TCPREFIX)ld +OBJCOPY = $(TCPREFIX)objcopy + +arch = -march=r3000 -msoft-float -mno-abicalls -mno-shared -fno-pic + +CFLAGS = $(arch) -pedantic -Wall -g -MMD +ASFLAGS = $(arch) +LDFLAGS = -T psx.ld -print-gc-sections + +$(bin): $(elf) + $(OBJCOPY) -O binary $< $@ + +$(elf): $(obj) + $(LD) -o $@ $(obj) -Map link.map $(LDFLAGS) + +-include $(dep) + +%.s: %.c + $(CC) $(CFLAGS) -S -o $@ $< + +.PHONY: clean +clean: + rm -f $(obj) $(bin) $(elf) link.map + +.PHONY: cleandep +cleandep: + rm -f $(dep) + +.PHONY: run +run: $(bin) + mednafen $< diff --git a/psx.ld b/psx.ld new file mode 100644 index 0000000..4f6d4cd --- /dev/null +++ b/psx.ld @@ -0,0 +1,53 @@ +ENTRY(_start) + +MEMORY { + ram : ORIGIN = 0x80010000 - 0x800, LENGTH = 2M - 0x10000 + 0x800 + dcache : ORIGIN = 0x1f800000, LENGTH = 0x400 +} + +_stacktop = ORIGIN(ram) + LENGTH(ram); +_dcache = ORIGIN(dcache); +_dcache_end = ORIGIN(dcache) + LENGTH(dcache); +_progsize = _imgend - _start; + +SECTIONS { + /* put the exe header at the start, and pad it to 2k */ + .exehdr : { + * (.exehdr); + . = ALIGN(0x800); + } >ram + + .text : { + /* the entry point should go first */ + * (.startup); + * (.text*); + } >ram + + .rodata : { * (.rodata*); } >ram + .data : { * (.data*); } >ram + + _gp = ALIGN(16) + 0x7ff0; + .sdata : { + * (.sdata*); + KEEP(*(.keep)); + } >ram + + _imgend = .; + + .bss ALIGN(4) : { + _bss_start = .; + /* .sbss first to be reachable by _gp */ + * (.sbss*); + * (.bss*); + * (COMMON) + . = ALIGN(4); + _bss_end = .; + } + + _end = .; + + /DISCARD/ : { + *(.note.GNU-stack); + *(.comment); + } +} diff --git a/src/exehdr.S b/src/exehdr.S new file mode 100644 index 0000000..40ad204 --- /dev/null +++ b/src/exehdr.S @@ -0,0 +1,18 @@ + .section .exehdr + + .extern _start + .extern _progsize + .extern _stacktop + + .ascii "PS-X EXE" # 0: sig + .word 0, 0 # 8-16: ? + .word _start # 16: initial pc + .word _gp # 20: initial gp + .word _start # 24: .text start + .word _progsize # 28: prog length without header + .word 0, 0, 0, 0 # 32-48: ? + .word _stacktop # 48: initial sp & fp + .skip 24 + .ascii "Sony Computer Entertainment Inc. for Europe area" # 76 + +# vi:ts=8 sts=8 sw=8 ft=mips: diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..31dbf45 --- /dev/null +++ b/src/main.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff --git a/src/psxregs.h b/src/psxregs.h new file mode 100644 index 0000000..dc3a7f1 --- /dev/null +++ b/src/psxregs.h @@ -0,0 +1,40 @@ +#ifndef PSXREGS_H_ +#define PSXREGS_H_ + +#define REG_BASE 0x1f800000 +#define REGPTR32(x) (*(volatile unsigned long*)(REG_BASE | (x))) +#define REGPTR16(x) (*(volatile unsigned short*)(REG_BASE | (x))) + +/* --- GPU --- */ +#define REGN_GP0 0x1810 +#define REGN_GP1 0x1814 +#define REGN_GPUREAD REGN_GP0 +#define REGN_GPUSTAT REGN_GP1 + +#define REG_GP0 REGPTR32(REGN_GP0) +#define REG_GP1 REGPTR32(REGN_GP1) +#define REG_GPUREAD REGPTR32(REGN_GPUREAD) +#define REG_GPUSTAT REGPTR32(REGN_GPUSTAT) + +/* --- interrupts --- */ +#define REGN_ISTAT 1070h +#define REGN_IMASK 1074h + +#define REG_ISTAT REGPTR32(REGN_ISTAT) +#define REG_IMASK REGPTR32(REGN_IMASK) + +enum { + IRQ_VBLANK = 0x0001, + IRQ_GPU = 0x0002, + IRQ_CDROM = 0x0004, + IRQ_DMA = 0x0008, + IRQ_TIMER0 = 0x0010, + IRQ_TIMER1 = 0x0020, + IRQ_TIMER2 = 0x0040, + IRQ_JOYMC = 0x0080, + IRQ_SIO = 0x0100, + IRQ_SPU = 0x0200, + IRQ_LPEN = 0x0400 +}; + +#endif /* PSXREGS_H_ */ diff --git a/src/startup.S b/src/startup.S new file mode 100644 index 0000000..3df6b83 --- /dev/null +++ b/src/startup.S @@ -0,0 +1,68 @@ +#include + + .equ REG_BASE, 0x1f80 + .equ REG_GP0, 0x1810 + .equ REG_GP1, 0x1814 + + .set noreorder + .section .startup + + .extern main + + .globl _start +_start: + lui a0, REG_BASE + + # setup screen mode + li t0, 0 + sw t0, REG_GP1(a0) # GP1 0: reset + + li t0, 0x03000000 # GP1 3: display enable + sw t0, REG_GP1(a0) + li t0, 0x08000009 # GP1 8: display mode (320x240 15bpp PAL) + sw t0, REG_GP1(a0) + li t0, 0x06c60260 # GP1 6: horiz. display range (608-3168) + sw t0, REG_GP1(a0) + li t0, 0x07049c1f # GP1 7: vert. display range (31-295) + sw t0, REG_GP1(a0) + + li t0, 0xe1000600 # GP0 e1: draw mode (draw allowed & dither enable) + sw t0, REG_GP0(a0) + li t0, 0xe3000000 # draw area top left (0, 0) + sw t0, REG_GP0(a0) + li t0, 0xe4041d3f # draw area bottom right (319,263) + sw t0, REG_GP0(a0) + li t0, 0xe5000000 # draw offset (0, 0) + sw t0, REG_GP0(a0) + + # clear screen + li t0, 0x02302010 # cmd 2: fill area (BBGGRR) + sw t0, REG_GP0(a0) + li t0, 0 + sw t0, REG_GP0(a0) # ... top left 0,0 (YYYYXXXX) + li t0, 0x00ef013f # ... size 319x239 (HHHHWWWW) + sw t0, REG_GP0(a0) + + # draw gouraud triangle + li t0, 0x30ff0000 + sw t0, REG_GP0(a0) + li t0, 160 | (16 << 16) + sw t0, REG_GP0(a0) + + li t0, 0x0000ff00 + sw t0, REG_GP0(a0) + li t0, 32 | (180 << 16) + sw t0, REG_GP0(a0) + + li t0, 0x000000ff + sw t0, REG_GP0(a0) + li t0, 280 | (220 << 16) + sw t0, REG_GP0(a0) + + #jal main + nop + +0: b 0b + nop + +# vi:ts=8 sts=8 sw=8 ft=mips: -- 1.7.10.4