From 650a9559bc42e6fc0065330f1783d74683f41217 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Sun, 17 Mar 2024 07:39:50 +0200 Subject: [PATCH] start using GTE, rotate triangle with MVMVA cmd --- .gitignore | 3 +++ Makefile | 21 ++++++++++++--- src/gpu.h | 3 +-- src/gte.S | 16 ++++++++++++ src/gte.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/libc/stddef.h | 7 +++++ src/libc/stdint.h | 14 ++++++++++ src/libc/string.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++ src/libc/string.h | 8 ++++++ src/libc/syscall.S | 22 ++++++++++++++++ src/libc/syscall.h | 7 +++++ src/main.c | 43 ++++++++++++++++++++++++++---- src/sintab.h | 10 +++++++ tools/gensin.c | 29 ++++++++++++++++++++ 14 files changed, 314 insertions(+), 11 deletions(-) create mode 100644 src/gte.S create mode 100644 src/gte.h create mode 100644 src/libc/stddef.h create mode 100644 src/libc/stdint.h create mode 100644 src/libc/string.c create mode 100644 src/libc/string.h create mode 100644 src/libc/syscall.S create mode 100644 src/libc/syscall.h create mode 100644 src/sintab.h create mode 100644 tools/gensin.c diff --git a/.gitignore b/.gitignore index ccff81e..5f6d04d 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ license*.dat disasm *.json +comport.txt +sintab.S +tools/gensin diff --git a/Makefile b/Makefile index dc59471..d0585e2 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -csrc = $(wildcard src/*.c) -ssrc = $(wildcard src/*.S) +csrc = $(wildcard src/*.c) $(wildcard src/libc/*.c) +ssrc = $(wildcard src/*.S) $(wildcard src/libc/*.S) sintab.S obj = $(csrc:.c=.o) $(ssrc:.S=.o) dep = $(csrc:.c=.d) $(ssrc:.S=.d) @@ -16,15 +16,18 @@ AS = $(TCPREFIX)as LD = $(TCPREFIX)ld arch = -march=r3000 -msoft-float -mno-abicalls -mno-shared -fno-pic +inc = -nostdinc -Isrc/libc +opt = -O3 +dbg = -g -CFLAGS = $(arch) -pedantic -Wall -g -MMD +CFLAGS = $(arch) -pedantic -Wall $(dbg) $(opt) $(inc) -fno-strict-aliasing -MMD ASFLAGS = $(arch) LDFLAGS = -T psx.ld -print-gc-sections $(bin): $(elf) $(TCPREFIX)objcopy -O binary $< $@ -$(elf): $(obj) +$(elf): $(obj) sintab.o $(LD) -o $@ $(obj) -Map link.map $(LDFLAGS) $(iso): cd/cd.xml cd/system.cnf $(bin) @@ -32,6 +35,9 @@ $(iso): cd/cd.xml cd/system.cnf $(bin) -include $(dep) +sintab.S: tools/gensin + tools/gensin >$@ + %.s: %.c $(CC) $(CFLAGS) -S -o $@ $< @@ -56,3 +62,10 @@ run: $(bin) .PHONY: runiso runiso: $(iso) mednafen $(cue) + +.PHONY: runpsx +runpsx: $(bin) + nops /exe $(bin) /m /dev/ttyUSB0 + +tools/gensin: tools/gensin.c + cc -o $@ $< -lm diff --git a/src/gpu.h b/src/gpu.h index 81d341f..4bfe724 100644 --- a/src/gpu.h +++ b/src/gpu.h @@ -1,8 +1,7 @@ #ifndef GPU_H_ #define GPU_H_ -typedef short int16_t; -typedef unsigned long uint32_t; +#include /* flat vertex */ struct gpu_vert { diff --git a/src/gte.S b/src/gte.S new file mode 100644 index 0000000..d525992 --- /dev/null +++ b/src/gte.S @@ -0,0 +1,16 @@ +#include + .text + .set noreorder + + .equ C0_SR, $12 + + .globl gte_init +gte_init: + mfc0 t0, C0_SR + li t1, 0x40000000 + or t0, t0, t1 + jr ra + mtc0 t0, C0_SR # bd + + +# vi:ts=8 sts=8 sw=8 ft=mips: diff --git a/src/gte.h b/src/gte.h new file mode 100644 index 0000000..ff97eca --- /dev/null +++ b/src/gte.h @@ -0,0 +1,74 @@ +#ifndef GTE_H_ +#define GTE_H_ + +#include + +struct gte_svector { + int16_t x, y, z, pad; +}; + +void gte_init(void); + +#define gte_loadrot(mptr) \ + asm volatile ( \ + "lw $8, (%0)\n\t" \ + "lw $9, 4(%0)\n\t" \ + "ctc2 $8, $0\n\t" \ + "ctc2 $9, $1\n\t" \ + "lw $8, 8(%0)\n\t" \ + "lw $9, 12(%0)\n\t" \ + "ctc2 $8, $2\n\t" \ + "lw $8, 16(%0)\n\t" \ + "ctc2 $9, $3\n\t" \ + "ctc2 $8, $4\n\t" \ + : : "r"(mptr) \ + : "$8", "$9") + +#define gte_loadtrans(vptr) \ + asm volatile ( \ + "lw $8, (%0)\n\t" \ + "lw $9, 4(%0)\n\t" \ + "lw $10, 8(%0)\n\t" \ + "ctc2 $8, $5\n\t" \ + "ctc2 $9, $6\n\t" \ + "ctc2 $10, $7\n\t" \ + : : "r"(vptr) \ + : "$8", "$9", "$10") + +#define gte_loadsvec0(svptr) \ + asm volatile ( \ + "lwc2 $0, (%0)\n\t" \ + "lwc2 $1, 4(%0)\n\t" \ + : : "r"(svptr)) + +#define gte_loadsvec1(svptr) \ + asm volatile ( \ + "lwc2 $2, (%0)\n\t" \ + "lwc2 $3, 4(%0)\n\t" \ + : : "r"(svptr)) + +#define gte_loadsvec2(svptr) \ + asm volatile ( \ + "lwc2 $4, (%0)\n\t" \ + "lwc2 $5, 4(%0)\n\t" \ + : : "r"(svptr)) + +#define gte_getvec(vptr) \ + asm volatile ( \ + "swc2 $25, (%0)\n\t" \ + "swc2 $26, 4(%0)\n\t" \ + "swc2 $27, 8(%0)\n\t" \ + : : "r"(vptr) \ + : "memory") + +#define gte_cmd_rot() \ + asm volatile ( \ + "nop\n\t" \ + "cop2 0x86012\n\t") + +#define gte_cmd_rottrans() \ + asm volatile ( \ + "nop\n\t" \ + "cop2 0x80012\n\t") + +#endif /* GTE_H_ */ diff --git a/src/libc/stddef.h b/src/libc/stddef.h new file mode 100644 index 0000000..7fa572c --- /dev/null +++ b/src/libc/stddef.h @@ -0,0 +1,7 @@ +#ifndef LIBC_STDDEF_H_ +#define LIBC_STDDEF_H_ + +typedef int ssize_t; +typedef unsigned int size_t; + +#endif /* LIBC_STDDEF_H_ */ diff --git a/src/libc/stdint.h b/src/libc/stdint.h new file mode 100644 index 0000000..c5bf21d --- /dev/null +++ b/src/libc/stdint.h @@ -0,0 +1,14 @@ +#ifndef LIBC_STDINT_H_ +#define LIBC_STDINT_H_ + +typedef signed char int8_t; +typedef short int16_t; +typedef int int32_t; +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; + +typedef int32_t intptr_t; +typedef uint32_t uintptr_t; + +#endif /* LIBC_STDINT_H_ */ diff --git a/src/libc/string.c b/src/libc/string.c new file mode 100644 index 0000000..ac9f950 --- /dev/null +++ b/src/libc/string.c @@ -0,0 +1,68 @@ +#include +#include + +static inline void memcpy_words(uint32_t *dest, const uint32_t *src, size_t n) +{ + while(n-- > 0) { + *dest++ = *src++; + } +} + +static inline void memcpy_bytes(unsigned char *dest, const unsigned char *src, size_t n) +{ + while(n-- > 0) { + *dest++ = *src++; + } +} + +void *memcpy(void *dest, const void *src, size_t n) +{ + int pre; + size_t nwords; + int dalign = (uintptr_t)dest & 3; + int salign = (uintptr_t)src & 3; + unsigned char *bdest; + const unsigned char *bsrc; + uint32_t *wdest; + const uint32_t *wsrc; + + if(n < 4) { + memcpy_bytes(dest, src, n); + return dest; + } + + if(dalign != 0 || salign != 0) { + if(dalign != salign) { + /* alignment differs, copy bytes */ + memcpy_bytes(dest, src, n); + return dest; + } + + /* unaligned but on the same alignment, copy bytes first */ + pre = ~dalign & 3; + bdest = dest; + bsrc = src; + memcpy_bytes(dest, src, pre); + + wdest = (uint32_t*)((char*)dest + pre); + wsrc = (const uint32_t*)((char*)src + pre); + n -= pre; + } else { + /* both aligned */ + wdest = dest; + wsrc = src; + } + + nwords = n >> 2; + if(nwords) { + memcpy_words(wdest, wsrc, nwords); + } + + n &= 3; + if(n) { + bdest = (unsigned char*)(wdest + nwords); + bsrc = (const unsigned char*)(wsrc + nwords); + memcpy_bytes(bdest, bsrc, n); + } + return dest; +} diff --git a/src/libc/string.h b/src/libc/string.h new file mode 100644 index 0000000..642df2f --- /dev/null +++ b/src/libc/string.h @@ -0,0 +1,8 @@ +#ifndef LIBC_STRING_H_ +#define LIBC_STRING_H_ + +#include + +void *memcpy(void *dest, const void *src, size_t n); + +#endif /* LIBC_STRING_H_ */ diff --git a/src/libc/syscall.S b/src/libc/syscall.S new file mode 100644 index 0000000..df4ddeb --- /dev/null +++ b/src/libc/syscall.S @@ -0,0 +1,22 @@ +#include + .text + .set noreorder + + .equ SYS_ENTERCRIT, 1 + .equ SYS_EXITCRIT, 2 + + .globl sys_entercrit +sys_entercrit: + li a0, SYS_ENTERCRIT + syscall 0 + jr ra + nop + + .globl sys_exitcrit +sys_exitcrit: + li a0, SYS_EXITCRIT + syscall 0 + jr ra + nop + +# vi:ts=8 sts=8 sw=8 ft=mips: diff --git a/src/libc/syscall.h b/src/libc/syscall.h new file mode 100644 index 0000000..2ae2d36 --- /dev/null +++ b/src/libc/syscall.h @@ -0,0 +1,7 @@ +#ifndef LIBC_SYSCALL_H_ +#define LIBC_SYSCALL_H_ + +int sys_entercrit(void); +void sys_exitcrit(void); + +#endif /* LIBC_SYSCALL_H_ */ diff --git a/src/main.c b/src/main.c index c247f3c..073ea1c 100644 --- a/src/main.c +++ b/src/main.c @@ -1,14 +1,26 @@ #include "gpu.h" +#include "gte.h" #include "psxregs.h" +#include "sintab.h" -static struct gpu_gvert triangle[] = { - {0xff0000, 160, 16}, {0x00ff00, 32, 180}, {0x0000ff, 280, 220} +static struct gpu_gvert triangle[] = {{0xff0000}, {0x00ff00}, {0x0000ff}}; + +static struct gte_svector svtri[] = { + {-0x1000, -0x800}, {0, 0x1000}, {0x1000, -0x800} }; int dbg; int main(void) { + int i; + unsigned int frame = 0; + int16_t rotmat[9] = {0x1000, 0, 0, 0, 0x1000, 0, 0, 0, 0x1000}; + int trans[3] = {160, 120, 0}; + int resv[3]; + + gte_init(); + gpu_reset(); gpu_setmode(320, 264, 15, 50); gpu_display(1); @@ -18,10 +30,31 @@ int main(void) gpu_cliprect(0, 0, 320, 264); gpu_origin(0, 0); - gpu_fillrect(0, 0, 320, 264, 0x003f00); + for(;;) { + rotmat[0] = rotmat[4] = COS(frame); + rotmat[1] = SIN(frame); + rotmat[3] = -SIN(frame); + + gte_loadrot(rotmat); + //gte_loadtrans(trans); + for(i=0; i<3; i++) { + gte_loadsvec0(svtri + i); + gte_cmd_rot(); + gte_getvec(resv); + + triangle[i].x = (resv[0] >> 6) + 160; + triangle[i].y = (resv[1] >> 6) + 130; + } + + gpu_fillrect(0, 0, 320, 264, 0x202020); + + gpu_draw_gouraud(GP0_GTRI, triangle, 3); - gpu_draw_gouraud(GP0_GTRI, triangle, 3); + for(i=0; i<100000; i++) { + asm volatile("nop; nop; nop; nop"); + } - for(;;); + frame++; + } return 0; } diff --git a/src/sintab.h b/src/sintab.h new file mode 100644 index 0000000..6a24b03 --- /dev/null +++ b/src/sintab.h @@ -0,0 +1,10 @@ +#ifndef SINTAB_H_ +#define SINTAB_H_ + +extern int sintab[]; + +#define SINTAB_SIZE 1024 +#define SIN(x) sintab[(x) & 0x3ff] +#define COS(x) sintab[((x) + 256) & 0x3ff] + +#endif /* SINTAB_H_ */ diff --git a/tools/gensin.c b/tools/gensin.c new file mode 100644 index 0000000..2f8ddba --- /dev/null +++ b/tools/gensin.c @@ -0,0 +1,29 @@ +#include +#include + +int main(void) +{ + int i, len, val; + float theta; + + puts("\t.section .rodata"); + puts("\t.globl sintab"); + puts("sintab:"); + fputs("\t.word ", stdout); + len = 14; + for(i=0; i<1024; i++) { + theta = (float)i * (M_PI * 2.0f) / 1024.0f; + val = (int)(sin(theta) * 4096.0f); + len += printf("%d", val); + if(len >= 75) { + fputs("\n\t.word ", stdout); + len = 14; + } else if(i < 1023) { + fputs(", ", stdout); + len += 2; + } + } + putchar('\n'); + + return 0; +} -- 1.7.10.4