├── cpack ├── icon.ico ├── uninstall.ico ├── nsis_banner.bmp ├── nsis_header.bmp ├── fakeroot_fix.cmake ├── convert_images.sh └── description.txt ├── template ├── system.cnf ├── CMakeLists.txt ├── CMakePresets.json └── main.c ├── examples ├── cdrom │ ├── cdxa │ │ ├── system.cnf │ │ ├── ball16c.tim │ │ ├── CMakeLists.txt │ │ └── iso.xml │ └── cdbrowse │ │ ├── system.cnf │ │ ├── ball16c.tim │ │ ├── CMakeLists.txt │ │ └── iso.xml ├── system │ ├── dynlink │ │ ├── system.cnf │ │ ├── library │ │ │ ├── ball16c.tim │ │ │ ├── dll_common.h │ │ │ └── balls.c │ │ ├── CMakeLists.txt │ │ └── iso.xml │ ├── console │ │ ├── ball16c.tim │ │ └── CMakeLists.txt │ ├── childexec │ │ ├── ball16c.tim │ │ └── CMakeLists.txt │ ├── tty │ │ ├── CMakeLists.txt │ │ └── main.c │ └── timer │ │ ├── CMakeLists.txt │ │ └── main.c ├── mdec │ ├── strvideo │ │ ├── system.cnf │ │ ├── CMakeLists.txt │ │ └── iso.xml │ └── mdecimage │ │ ├── image.bin │ │ ├── parkway.png │ │ ├── CMakeLists.txt │ │ └── main.c ├── sound │ ├── cdstream │ │ ├── system.cnf │ │ ├── stream.vag │ │ ├── CMakeLists.txt │ │ └── iso.xml │ ├── vagsample │ │ ├── 3dfx.vag │ │ ├── proyt.vag │ │ └── CMakeLists.txt │ └── spustream │ │ ├── stream.vag │ │ └── CMakeLists.txt ├── demos │ └── n00bdemo │ │ ├── logo.h │ │ ├── data │ │ ├── bulb.smd │ │ ├── font.bmp │ │ ├── font.tim │ │ ├── hatkid.png │ │ ├── hatkid.smd │ │ ├── hatkid.tim │ │ ├── logo.smd │ │ ├── star.smd │ │ ├── bungirl.smd │ │ ├── bungirl.tim │ │ ├── celmapi.bmp │ │ ├── celmapi.tim │ │ ├── clktower.tim │ │ ├── mtekdisk.smd │ │ ├── mtektext.smd │ │ ├── petscum.smd │ │ ├── riftbld1.tim │ │ ├── riftbld2.tim │ │ ├── timerift.smd │ │ ├── lamelotl16c.png │ │ ├── lamelotl16c.tim │ │ ├── lightworld.smd │ │ ├── petscum16c.png │ │ ├── petscum16c.tim │ │ ├── psn00blogo.smd │ │ ├── rbowshade.smd │ │ ├── star_mask.smd │ │ ├── n00blogo-pixel.png │ │ ├── n00blogo-pixel.tim │ │ ├── star_mask.smx │ │ └── star.smx │ │ ├── plasma_tbl.h │ │ ├── data.h │ │ ├── disp.h │ │ ├── CMakeLists.txt │ │ ├── disp.c │ │ ├── data.xml │ │ ├── smd.h │ │ └── smdparser.s ├── graphics │ ├── gte │ │ ├── texture.tim │ │ └── CMakeLists.txt │ ├── balls │ │ ├── ball16c.tim │ │ └── CMakeLists.txt │ ├── rgb24 │ │ ├── bunpattern.png │ │ ├── bunpattern.tim │ │ ├── CMakeLists.txt │ │ └── main.c │ ├── billboard │ │ ├── texture64.tim │ │ └── CMakeLists.txt │ ├── tilesasm │ │ ├── tiles_256.png │ │ ├── tiles_256.tim │ │ └── CMakeLists.txt │ ├── render2tex │ │ ├── blendpattern.png │ │ ├── blendpattern-16c.png │ │ ├── blendpattern-16c.tim │ │ └── CMakeLists.txt │ ├── fpscam │ │ ├── lookat.h │ │ ├── CMakeLists.txt │ │ ├── clip.h │ │ ├── lookat.c │ │ └── clip.c │ └── hdtv │ │ ├── lookat.h │ │ ├── CMakeLists.txt │ │ ├── clip.h │ │ ├── lookat.c │ │ └── clip.c ├── lowlevel │ └── cartrom │ │ ├── rom.ld │ │ ├── cop0.inc │ │ ├── bios.inc │ │ ├── CMakeLists.txt │ │ └── parse.inc ├── beginner │ ├── hello │ │ ├── CMakeLists.txt │ │ └── main.c │ └── cppdemo │ │ ├── CMakeLists.txt │ │ └── main.cpp ├── io │ ├── pads │ │ ├── CMakeLists.txt │ │ └── spi.h │ └── system573 │ │ ├── CMakeLists.txt │ │ ├── iso.xml │ │ └── k573io.c └── CMakeLists.txt ├── doc ├── LibPSn00b Reference.odt └── known_bugs.md ├── libpsn00b ├── psxgpu │ ├── dbugfont.png │ ├── dbugfont.tim │ └── readme.txt ├── libc │ ├── abs.c │ ├── _start.s │ ├── memcpy.s │ ├── rand.s │ ├── memcmp.s │ ├── abort.c │ ├── memmove.s │ ├── clz.s │ ├── cpp_support.cpp │ ├── readme.txt │ ├── start.c │ └── memset.s ├── include │ ├── malloc.h │ ├── ioctl.h │ ├── sys │ │ ├── types.h │ │ └── fcntl.h │ ├── ctype.h │ ├── strings.h │ ├── lzp │ │ └── lzqlp.h │ ├── assert.h │ ├── string.h │ ├── stdio.h │ ├── stdlib.h │ ├── gtereg.inc │ ├── psxkernel.h │ ├── lzconfig.h │ └── inline_s.inc ├── lzp │ ├── bit.h │ ├── lzqlp.h │ ├── bit.c │ ├── qlp.c │ ├── crc.c │ └── lzp.c ├── psxetc │ ├── readme.txt │ └── _dl_resolve_wrapper.s ├── psxapi │ ├── _initcd.s │ ├── fs.s │ ├── _syscalls.s │ ├── stdio.s │ ├── drivers.s │ └── generate_stubs.py ├── psxgte │ ├── initgeom.s │ ├── readme.txt │ ├── isin.c │ ├── matrix.c │ ├── vector.s │ └── squareroot.s ├── psxspu │ └── readme.txt ├── psxcd │ └── readme.txt ├── psxpress │ └── README.md ├── psxsio │ └── tty.c ├── cmake │ ├── flags.cmake │ └── sdk.cmake ├── ldscripts │ └── exe.ld └── CMakeLists.txt ├── .editorconfig ├── .gitmodules ├── .gitignore ├── tools ├── smxlink │ ├── timreader.h │ └── timreader.cpp ├── lzpack │ ├── filelist.h │ ├── filelist.cpp │ └── lzp │ │ └── lzconfig.h ├── tools.txt ├── util │ └── elf.h └── CMakeLists.txt ├── CMakePresets.json └── indev └── README.md /cpack/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/cpack/icon.ico -------------------------------------------------------------------------------- /cpack/uninstall.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/cpack/uninstall.ico -------------------------------------------------------------------------------- /template/system.cnf: -------------------------------------------------------------------------------- 1 | BOOT=cdrom:\template.exe;1 2 | TCB=4 3 | EVENT=10 4 | STACK=801FFFF0 5 | -------------------------------------------------------------------------------- /cpack/nsis_banner.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/cpack/nsis_banner.bmp -------------------------------------------------------------------------------- /cpack/nsis_header.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/cpack/nsis_header.bmp -------------------------------------------------------------------------------- /examples/cdrom/cdxa/system.cnf: -------------------------------------------------------------------------------- 1 | BOOT=cdrom:\cdxa.exe;1 2 | TCB=4 3 | EVENT=10 4 | STACK=801FFFF0 5 | -------------------------------------------------------------------------------- /examples/system/dynlink/system.cnf: -------------------------------------------------------------------------------- 1 | BOOT=cdrom:\main.exe;1 2 | TCB=4 3 | EVENT=10 4 | STACK=801FFFF0 5 | -------------------------------------------------------------------------------- /examples/cdrom/cdbrowse/system.cnf: -------------------------------------------------------------------------------- 1 | BOOT=cdrom:\cdbrowse.exe;1 2 | TCB=4 3 | EVENT=10 4 | STACK=801FFFF0 5 | -------------------------------------------------------------------------------- /examples/mdec/strvideo/system.cnf: -------------------------------------------------------------------------------- 1 | BOOT=cdrom:\strvideo.exe;1 2 | TCB=4 3 | EVENT=10 4 | STACK=801FFFF0 5 | -------------------------------------------------------------------------------- /examples/sound/cdstream/system.cnf: -------------------------------------------------------------------------------- 1 | BOOT=cdrom:\cdstream.exe;1 2 | TCB=4 3 | EVENT=10 4 | STACK=801FFFF0 5 | -------------------------------------------------------------------------------- /doc/LibPSn00b Reference.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/doc/LibPSn00b Reference.odt -------------------------------------------------------------------------------- /libpsn00b/psxgpu/dbugfont.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/libpsn00b/psxgpu/dbugfont.png -------------------------------------------------------------------------------- /libpsn00b/psxgpu/dbugfont.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/libpsn00b/psxgpu/dbugfont.tim -------------------------------------------------------------------------------- /examples/cdrom/cdxa/ball16c.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/cdrom/cdxa/ball16c.tim -------------------------------------------------------------------------------- /examples/demos/n00bdemo/logo.h: -------------------------------------------------------------------------------- 1 | #ifndef _LOGO_H 2 | #define _LOGO_H 3 | 4 | void intro(); 5 | 6 | #endif // _LOGO_H 7 | -------------------------------------------------------------------------------- /examples/graphics/gte/texture.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/graphics/gte/texture.tim -------------------------------------------------------------------------------- /examples/mdec/mdecimage/image.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/mdec/mdecimage/image.bin -------------------------------------------------------------------------------- /examples/sound/cdstream/stream.vag: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/sound/cdstream/stream.vag -------------------------------------------------------------------------------- /examples/sound/vagsample/3dfx.vag: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/sound/vagsample/3dfx.vag -------------------------------------------------------------------------------- /examples/sound/vagsample/proyt.vag: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/sound/vagsample/proyt.vag -------------------------------------------------------------------------------- /examples/cdrom/cdbrowse/ball16c.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/cdrom/cdbrowse/ball16c.tim -------------------------------------------------------------------------------- /examples/graphics/balls/ball16c.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/graphics/balls/ball16c.tim -------------------------------------------------------------------------------- /examples/mdec/mdecimage/parkway.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/mdec/mdecimage/parkway.png -------------------------------------------------------------------------------- /examples/sound/spustream/stream.vag: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/sound/spustream/stream.vag -------------------------------------------------------------------------------- /examples/system/console/ball16c.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/system/console/ball16c.tim -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/bulb.smd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/bulb.smd -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/font.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/font.bmp -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/font.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/font.tim -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/hatkid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/hatkid.png -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/hatkid.smd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/hatkid.smd -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/hatkid.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/hatkid.tim -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/logo.smd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/logo.smd -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/star.smd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/star.smd -------------------------------------------------------------------------------- /examples/graphics/rgb24/bunpattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/graphics/rgb24/bunpattern.png -------------------------------------------------------------------------------- /examples/graphics/rgb24/bunpattern.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/graphics/rgb24/bunpattern.tim -------------------------------------------------------------------------------- /examples/system/childexec/ball16c.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/system/childexec/ball16c.tim -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/bungirl.smd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/bungirl.smd -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/bungirl.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/bungirl.tim -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/celmapi.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/celmapi.bmp -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/celmapi.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/celmapi.tim -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/clktower.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/clktower.tim -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/mtekdisk.smd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/mtekdisk.smd -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/mtektext.smd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/mtektext.smd -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/petscum.smd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/petscum.smd -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/riftbld1.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/riftbld1.tim -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/riftbld2.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/riftbld2.tim -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/timerift.smd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/timerift.smd -------------------------------------------------------------------------------- /examples/graphics/billboard/texture64.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/graphics/billboard/texture64.tim -------------------------------------------------------------------------------- /examples/graphics/tilesasm/tiles_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/graphics/tilesasm/tiles_256.png -------------------------------------------------------------------------------- /examples/graphics/tilesasm/tiles_256.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/graphics/tilesasm/tiles_256.tim -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/lamelotl16c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/lamelotl16c.png -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/lamelotl16c.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/lamelotl16c.tim -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/lightworld.smd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/lightworld.smd -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/petscum16c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/petscum16c.png -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/petscum16c.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/petscum16c.tim -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/psn00blogo.smd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/psn00blogo.smd -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/rbowshade.smd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/rbowshade.smd -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/star_mask.smd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/star_mask.smd -------------------------------------------------------------------------------- /examples/system/dynlink/library/ball16c.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/system/dynlink/library/ball16c.tim -------------------------------------------------------------------------------- /examples/graphics/render2tex/blendpattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/graphics/render2tex/blendpattern.png -------------------------------------------------------------------------------- /libpsn00b/libc/abs.c: -------------------------------------------------------------------------------- 1 | int abs(int i) { 2 | return (i < 0) ? (-i) : i; 3 | } 4 | 5 | long labs(long i) { 6 | return (i < 0) ? (-i) : i; 7 | } 8 | -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/n00blogo-pixel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/n00blogo-pixel.png -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/n00blogo-pixel.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/demos/n00bdemo/data/n00blogo-pixel.tim -------------------------------------------------------------------------------- /examples/graphics/render2tex/blendpattern-16c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/graphics/render2tex/blendpattern-16c.png -------------------------------------------------------------------------------- /examples/graphics/render2tex/blendpattern-16c.tim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spicyjpeg/PSn00bSDK/HEAD/examples/graphics/render2tex/blendpattern-16c.tim -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_style = tab 7 | indent_size = 4 8 | trim_trailing_whitespace = true -------------------------------------------------------------------------------- /libpsn00b/include/malloc.h: -------------------------------------------------------------------------------- 1 | #ifndef _MALLOC_H 2 | #define _MALLOC_H 3 | 4 | #warning " is deprecated, include instead" 5 | 6 | #include 7 | 8 | #endif // _MALLOC_H -------------------------------------------------------------------------------- /examples/lowlevel/cartrom/rom.ld: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | ROM : ORIGIN = 0x1f000000, LENGTH = 256K 3 | } 4 | 5 | ENTRY (entry) 6 | 7 | SECTIONS { 8 | .text :{ 9 | *(.text) 10 | } >ROM 11 | } 12 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "tools/tinyxml2"] 2 | path = tools/tinyxml2 3 | url = https://github.com/leethomason/tinyxml2 4 | [submodule "tools/mkpsxiso"] 5 | path = tools/mkpsxiso 6 | url = https://github.com/Lameguy64/mkpsxiso 7 | -------------------------------------------------------------------------------- /examples/demos/n00bdemo/plasma_tbl.h: -------------------------------------------------------------------------------- 1 | #ifndef _PLASMA_TBL_H 2 | #define _PLASMA_TBL_H 3 | 4 | extern unsigned int plasma_colors[]; 5 | extern short plasma_sin1[]; 6 | extern short plasma_sin2[]; 7 | extern short plasma_sin3[]; 8 | 9 | #endif -------------------------------------------------------------------------------- /examples/lowlevel/cartrom/cop0.inc: -------------------------------------------------------------------------------- 1 | .set BPC, $3 2 | .set BDA, $5 3 | .set JUMPDEST, $6 4 | .set DCIC, $7 5 | .set BADVADDR, $8 6 | .set BDAM, $9 7 | .set BPCM, $11 8 | .set SR, $12 9 | .set CAUSE, $13 10 | .set EPC, $14 11 | .set PRID, $15 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .svn 2 | .vscode 3 | .DS_Store 4 | build 5 | bin 6 | old 7 | scrap 8 | *.a 9 | *.o 10 | *.obj 11 | *.elf 12 | *.so 13 | *.exe 14 | *.map 15 | *.dll 16 | *.lzp 17 | *.qlp 18 | *.iso 19 | *.rom 20 | *.code-workspace 21 | CMakeUserPresets.json 22 | -------------------------------------------------------------------------------- /libpsn00b/include/ioctl.h: -------------------------------------------------------------------------------- 1 | #ifndef _IOCTL_H 2 | #define _IOCTL_H 3 | 4 | #ifndef NULL 5 | #define NULL 0 6 | #endif 7 | 8 | #ifndef EOF 9 | #define EOF -1 10 | #endif 11 | 12 | // General 13 | #define FIONBLOCK (('f'<<8)|1) 14 | #define FIOCSCAN (('f'<<8)|2) 15 | 16 | // disk 17 | #define DIO_FORMAT (('d'<<8)|1) 18 | 19 | #endif -------------------------------------------------------------------------------- /libpsn00b/include/sys/types.h: -------------------------------------------------------------------------------- 1 | #ifndef _TYPES_H 2 | #define _TYPES_H 3 | 4 | //#warning " and u_* types are deprecated, include instead" 5 | 6 | //#include 7 | 8 | typedef unsigned char u_char; 9 | typedef unsigned short u_short; 10 | typedef unsigned int u_int; 11 | typedef unsigned long u_long; 12 | 13 | #endif // _TYPES_H -------------------------------------------------------------------------------- /libpsn00b/include/ctype.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PSn00bSDK standard library 3 | * (C) 2019-2022 PSXSDK authors, Lameguy64, spicyjpeg - MPL licensed 4 | */ 5 | 6 | #ifndef __CTYPE_H 7 | #define __CTYPE_H 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | int tolower(int chr); 14 | int toupper(int chr); 15 | 16 | #ifdef __cplusplus 17 | } 18 | #endif 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data.h: -------------------------------------------------------------------------------- 1 | #ifndef _DATA_H 2 | #define _DATA_H 3 | 4 | extern unsigned char _lz_resources[]; 5 | 6 | #define lz_resources ((const LZP_HEAD*) _lz_resources) 7 | 8 | /*extern unsigned char smd_mtekdisk[]; 9 | extern unsigned char smd_mtektext[]; 10 | extern unsigned char smd_star[]; 11 | extern unsigned char smd_psn00b[]; 12 | extern unsigned char smd_scarletlogo[];*/ 13 | 14 | #endif -------------------------------------------------------------------------------- /libpsn00b/libc/_start.s: -------------------------------------------------------------------------------- 1 | # PSn00bSDK _start() trampoline 2 | # (C) 2022 spicyjpeg - MPL licensed 3 | # 4 | # This file provides a weak function that can be easily overridden to e.g. set 5 | # $sp or perform additional initialization before the "real" _start() function 6 | # (_start_inner()) is called. 7 | 8 | .set noreorder 9 | 10 | .section .text._start 11 | .global _start 12 | .type _start, @function 13 | .weak _start 14 | _start: 15 | la $gp, _gp 16 | j _start_inner 17 | nop 18 | -------------------------------------------------------------------------------- /examples/demos/n00bdemo/disp.h: -------------------------------------------------------------------------------- 1 | #ifndef _DISP_H 2 | #define _DISP_H 3 | 4 | #include 5 | #include 6 | 7 | #define SCENE_TIME 60*15 8 | 9 | #define CENTERX 320 10 | #define CENTERY 240 11 | 12 | #define OT_LEN 260 13 | 14 | void initDisplay(); 15 | void display(); 16 | 17 | extern u_long ot[2][OT_LEN]; 18 | extern char *nextpri; 19 | extern int db; 20 | 21 | extern DISPENV disp; 22 | extern DRAWENV draw; 23 | 24 | extern MATRIX mtx; 25 | 26 | #endif // _DISP_H -------------------------------------------------------------------------------- /libpsn00b/lzp/bit.h: -------------------------------------------------------------------------------- 1 | #ifndef _LZP_BIT_H 2 | #define _LZP_BIT_H 3 | 4 | extern const unsigned char* inPtr; 5 | extern int inBytes; 6 | extern unsigned char* outPtr; 7 | extern int outBytes; 8 | 9 | extern int bit_buf; 10 | extern int bit_count; 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | void init_bits(); 17 | void put_bits(int n, int x); 18 | void flush_bits(); 19 | int get_bits(int n); 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | 25 | 26 | #endif // _LZP_BIT_H 27 | -------------------------------------------------------------------------------- /examples/graphics/fpscam/lookat.h: -------------------------------------------------------------------------------- 1 | #ifndef _LOOKAT_H 2 | #define _LOOKAT_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /* LookAt 9 | * 10 | * Generates a matrix that looks from 'eye' to 'at'. 11 | * 12 | * eye - Position of viewpoint 13 | * at - Position to 'look at' from viewpoint 14 | * up - Vector that defines the 'up' direction 15 | * mtx - Matrix output 16 | * 17 | */ 18 | void LookAt(VECTOR *eye, VECTOR *at, SVECTOR *up, MATRIX *mtx); 19 | 20 | #endif // _LOOKAT_H -------------------------------------------------------------------------------- /examples/graphics/hdtv/lookat.h: -------------------------------------------------------------------------------- 1 | #ifndef _LOOKAT_H 2 | #define _LOOKAT_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /* LookAt 9 | * 10 | * Generates a matrix that looks from 'eye' to 'at'. 11 | * 12 | * eye - Position of viewpoint 13 | * at - Position to 'look at' from viewpoint 14 | * up - Vector that defines the 'up' direction 15 | * mtx - Matrix output 16 | * 17 | */ 18 | void LookAt(VECTOR *eye, VECTOR *at, SVECTOR *up, MATRIX *mtx); 19 | 20 | #endif // _LOOKAT_H -------------------------------------------------------------------------------- /libpsn00b/libc/memcpy.s: -------------------------------------------------------------------------------- 1 | # High speed ASM memcpy implementation by Lameguy64 2 | # 3 | # Part of PSn00bSDK 4 | 5 | .set noreorder 6 | 7 | .section .text 8 | 9 | # Arguments: 10 | # a0 - destination address 11 | # a1 - source adress 12 | # a2 - bytes to copy 13 | .global memcpy 14 | .type memcpy, @function 15 | memcpy: 16 | move $v0, $a0 17 | .Lloop: 18 | blez $a2, .Lexit 19 | addi $a2, -1 20 | lbu $a3, 0($a1) 21 | addiu $a1, 1 22 | sb $a3, 0($a0) 23 | b .Lloop 24 | addiu $a0, 1 25 | .Lexit: 26 | jr $ra 27 | nop 28 | -------------------------------------------------------------------------------- /examples/system/tty/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | tty 8 | LANGUAGES C 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK stdio terminal example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c) 15 | psn00bsdk_add_executable(tty GPREL ${_sources}) 16 | #psn00bsdk_add_cd_image(tty_iso tty iso.xml DEPENDS tty) 17 | 18 | install(FILES ${PROJECT_BINARY_DIR}/tty.exe TYPE BIN) 19 | -------------------------------------------------------------------------------- /libpsn00b/include/strings.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PSn00bSDK standard library 3 | * (C) 2019-2022 PSXSDK authors, Lameguy64, spicyjpeg - MPL licensed 4 | */ 5 | 6 | #ifndef __STRINGS_H 7 | #define __STRINGS_H 8 | 9 | #include 10 | 11 | /* Compatibility macros (this header is useless) */ 12 | 13 | #define bcopy(src, dst, len) memmove(dst, src, len) 14 | #define bzero(ptr, len) memset(ptr, 0, len) 15 | #define bcmp(b1, b2, len) memcmp(b1, b2, len) 16 | #define index(s, c) strchr(s, c) 17 | #define rindex(s, c) strrchr(s, c) 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /examples/graphics/hdtv/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | hdtv 8 | LANGUAGES C 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK HDTV widescreen example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c) 15 | psn00bsdk_add_executable(hdtv GPREL ${_sources}) 16 | #psn00bsdk_add_cd_image(hdtv_iso hdtv iso.xml DEPENDS hdtv) 17 | 18 | install(FILES ${PROJECT_BINARY_DIR}/hdtv.exe TYPE BIN) 19 | -------------------------------------------------------------------------------- /examples/beginner/hello/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | hello 8 | LANGUAGES C 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK hello world example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c) 15 | psn00bsdk_add_executable(hello GPREL ${_sources}) 16 | #psn00bsdk_add_cd_image(hello_iso hello iso.xml DEPENDS hello) 17 | 18 | install(FILES ${PROJECT_BINARY_DIR}/hello.exe TYPE BIN) 19 | -------------------------------------------------------------------------------- /examples/io/pads/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | pads 8 | LANGUAGES C ASM 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK controller polling example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c *.s) 15 | psn00bsdk_add_executable(pads GPREL ${_sources}) 16 | #psn00bsdk_add_cd_image(pads_iso pads iso.xml DEPENDS pads) 17 | 18 | install(FILES ${PROJECT_BINARY_DIR}/pads.exe TYPE BIN) 19 | -------------------------------------------------------------------------------- /examples/system/timer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | timer 8 | LANGUAGES C 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK hardware timer example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c) 15 | psn00bsdk_add_executable(timer GPREL ${_sources}) 16 | #psn00bsdk_add_cd_image(timer_iso timer iso.xml DEPENDS timer) 17 | 18 | install(FILES ${PROJECT_BINARY_DIR}/timer.exe TYPE BIN) 19 | -------------------------------------------------------------------------------- /examples/beginner/cppdemo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | cppdemo 8 | LANGUAGES CXX 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK basic C++ example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.cpp) 15 | psn00bsdk_add_executable(cppdemo GPREL ${_sources}) 16 | #psn00bsdk_add_cd_image(cppdemo_iso cppdemo iso.xml DEPENDS cppdemo) 17 | 18 | install(FILES ${PROJECT_BINARY_DIR}/cppdemo.exe TYPE BIN) 19 | -------------------------------------------------------------------------------- /examples/graphics/fpscam/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | fpscam 8 | LANGUAGES C 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK 3D camera controls example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c) 15 | psn00bsdk_add_executable(fpscam GPREL ${_sources}) 16 | #psn00bsdk_add_cd_image(fpscam_iso fpscam iso.xml DEPENDS fpscam) 17 | 18 | install(FILES ${PROJECT_BINARY_DIR}/fpscam.exe TYPE BIN) 19 | -------------------------------------------------------------------------------- /libpsn00b/libc/rand.s: -------------------------------------------------------------------------------- 1 | .set noreorder 2 | .set noat 3 | 4 | .section .text 5 | 6 | 7 | .global rand 8 | .type rand, @function 9 | rand: 10 | 11 | la $at, _randseed 12 | lw $v0, 0($at) 13 | li $v1, 0x41c64e6d 14 | 15 | multu $v0, $v1 16 | mflo $v0 17 | nop 18 | addiu $v0, 12345 19 | sw $v0, 0($at) 20 | 21 | jr $ra 22 | andi $v0, 0x7fff 23 | 24 | 25 | .global srand 26 | .type srand, @function 27 | srand: 28 | la $at, _randseed 29 | jr $ra 30 | sw $a0, 0($at) 31 | 32 | 33 | .section .data 34 | 35 | .type _randseed, @object 36 | _randseed: 37 | .word 1 38 | -------------------------------------------------------------------------------- /template/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | PSn00bSDK-template 8 | LANGUAGES C CXX ASM 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK template" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | psn00bsdk_add_executable(template GPREL main.c) 15 | 16 | psn00bsdk_add_cd_image( 17 | iso # Target name 18 | template # Output file name (= template.bin + template.cue) 19 | iso.xml # Path to config file 20 | DEPENDS template 21 | ) 22 | -------------------------------------------------------------------------------- /libpsn00b/libc/memcmp.s: -------------------------------------------------------------------------------- 1 | # High speed ASM memcmp implementation by Lameguy64 2 | # 3 | # Part of PSn00bSDK 4 | 5 | .set noreorder 6 | 7 | .section .text 8 | 9 | # Arguments: 10 | # a0 - buffer 1 address 11 | # a1 - buffer 2 address 12 | # a2 - bytes to compare 13 | .global memcmp 14 | .type memcmp, @function 15 | memcmp: 16 | blez $a2, .Lexit 17 | addi $a2, -1 18 | lbu $v0, 0($a0) 19 | lbu $v1, 0($a1) 20 | addiu $a0, 1 21 | bne $v0, $v1, .Lmismatch 22 | addiu $a1, 1 23 | b memcmp 24 | nop 25 | .Lmismatch: 26 | jr $ra 27 | sub $v0, $v1 28 | .Lexit: 29 | jr $ra 30 | move $v0, $0 31 | -------------------------------------------------------------------------------- /libpsn00b/psxetc/readme.txt: -------------------------------------------------------------------------------- 1 | PSX Misc library, part of PSn00bSDK 2 | 2021 Lameguy64 / Meido-Tek Productions 3 | 4 | Licensed under Mozilla Public License 5 | 6 | Open source implementation of the ETC library. Currently provides the interrupt 7 | and DMA callback dispatchers (used by other libraries) as well as the DL_* and 8 | dl* functions for dynamic library loading (original, not present in the official 9 | SDK but similar to the standard dlopen() API). 10 | 11 | Library developer(s): 12 | 13 | Lameguy64 14 | spicyjpeg 15 | 16 | Library header(s): 17 | 18 | psxetc.h 19 | dlfcn.h 20 | elf.h (used internally) 21 | -------------------------------------------------------------------------------- /examples/graphics/gte/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | gte 8 | LANGUAGES C ASM 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK GTE 3D cube example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c) 15 | psn00bsdk_add_executable(gte GPREL ${_sources}) 16 | #psn00bsdk_add_cd_image(gte_iso gte iso.xml DEPENDS gte) 17 | 18 | psn00bsdk_target_incbin(gte PRIVATE tim_texture texture.tim) 19 | 20 | install(FILES ${PROJECT_BINARY_DIR}/gte.exe TYPE BIN) 21 | -------------------------------------------------------------------------------- /examples/graphics/balls/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | balls 8 | LANGUAGES C ASM 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK sprites example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c) 15 | psn00bsdk_add_executable(balls GPREL ${_sources}) 16 | #psn00bsdk_add_cd_image(balls_iso balls iso.xml DEPENDS balls) 17 | 18 | psn00bsdk_target_incbin(balls PRIVATE ball16c ball16c.tim) 19 | 20 | install(FILES ${PROJECT_BINARY_DIR}/balls.exe TYPE BIN) 21 | -------------------------------------------------------------------------------- /examples/graphics/rgb24/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | rgb24 8 | LANGUAGES C ASM 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK 24-bit RGB display example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c) 15 | psn00bsdk_add_executable(rgb24 GPREL ${_sources}) 16 | #psn00bsdk_add_cd_image(rgb24_iso rgb24 iso.xml DEPENDS rgb24) 17 | 18 | psn00bsdk_target_incbin(rgb24 PRIVATE tim_image bunpattern.tim) 19 | 20 | install(FILES ${PROJECT_BINARY_DIR}/rgb24.exe TYPE BIN) 21 | -------------------------------------------------------------------------------- /examples/system/console/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | console 8 | LANGUAGES C ASM 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK stdio console example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c) 15 | psn00bsdk_add_executable(console GPREL ${_sources}) 16 | #psn00bsdk_add_cd_image(console_iso console iso.xml DEPENDS console) 17 | 18 | psn00bsdk_target_incbin(console PRIVATE ball16c ball16c.tim) 19 | 20 | install(FILES ${PROJECT_BINARY_DIR}/console.exe TYPE BIN) 21 | -------------------------------------------------------------------------------- /examples/sound/cdstream/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | cdstream 8 | LANGUAGES C 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK SPU CD audio streaming example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c) 15 | psn00bsdk_add_executable(cdstream GPREL ${_sources}) 16 | psn00bsdk_add_cd_image(cdstream_iso cdstream iso.xml DEPENDS cdstream) 17 | 18 | install( 19 | FILES 20 | ${PROJECT_BINARY_DIR}/cdstream.bin 21 | ${PROJECT_BINARY_DIR}/cdstream.cue 22 | TYPE BIN 23 | ) 24 | -------------------------------------------------------------------------------- /examples/io/system573/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | system573 8 | LANGUAGES C ASM 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK Konami System 573 example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c *.s) 15 | psn00bsdk_add_executable(system573 GPREL ${_sources}) 16 | psn00bsdk_add_cd_image(system573_iso system573 iso.xml DEPENDS system573) 17 | 18 | install( 19 | FILES 20 | ${PROJECT_BINARY_DIR}/system573.bin 21 | ${PROJECT_BINARY_DIR}/system573.cue 22 | TYPE BIN 23 | ) 24 | -------------------------------------------------------------------------------- /examples/mdec/mdecimage/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | mdecimage 8 | LANGUAGES C ASM 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK MDEC static image example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c) 15 | psn00bsdk_add_executable(mdecimage GPREL ${_sources}) 16 | #psn00bsdk_add_cd_image(mdecimage_iso mdecimage iso.xml DEPENDS mdecimage) 17 | 18 | psn00bsdk_target_incbin(mdecimage PRIVATE mdec_image image.bin) 19 | 20 | install(FILES ${PROJECT_BINARY_DIR}/mdecimage.exe TYPE BIN) 21 | -------------------------------------------------------------------------------- /examples/graphics/billboard/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | billboard 8 | LANGUAGES C ASM 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK billboard sprite example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c) 15 | psn00bsdk_add_executable(billboard GPREL ${_sources}) 16 | #psn00bsdk_add_cd_image(billboard_iso billboard iso.xml DEPENDS billboard) 17 | 18 | psn00bsdk_target_incbin(billboard PRIVATE tim_image texture64.tim) 19 | 20 | install(FILES ${PROJECT_BINARY_DIR}/billboard.exe TYPE BIN) 21 | -------------------------------------------------------------------------------- /examples/sound/spustream/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | spustream 8 | LANGUAGES C ASM 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK SPU audio streaming example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c) 15 | psn00bsdk_add_executable(spustream GPREL ${_sources}) 16 | #psn00bsdk_add_cd_image(spustream_iso spustream iso.xml DEPENDS spustream) 17 | 18 | psn00bsdk_target_incbin(spustream PRIVATE stream_data stream.vag) 19 | 20 | install(FILES ${PROJECT_BINARY_DIR}/spustream.exe TYPE BIN) 21 | -------------------------------------------------------------------------------- /examples/graphics/tilesasm/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | tilesasm 8 | LANGUAGES C ASM 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK Tiles drawing with assembly example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.s *.c) 15 | psn00bsdk_add_executable(tilesasm GPREL ${_sources}) 16 | #psn00bsdk_add_cd_image(tilesasm_iso tilesasm iso.xml DEPENDS tilesasm) 17 | 18 | psn00bsdk_target_incbin(tilesasm PRIVATE tim_tileset tiles_256.tim) 19 | 20 | install(FILES ${PROJECT_BINARY_DIR}/tilesasm.exe TYPE BIN) 21 | -------------------------------------------------------------------------------- /examples/system/dynlink/library/dll_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PSn00bSDK dynamic linker example (shared header) 3 | * (C) 2021 spicyjpeg - MPL licensed 4 | */ 5 | 6 | #ifndef __DLL_COMMON_H 7 | #define __DLL_COMMON_H 8 | 9 | #include 10 | #include 11 | 12 | /* Common structures shared by the main executable and DLLs */ 13 | 14 | #define OT_LEN 256 15 | #define PACKET_LEN 16384 16 | 17 | typedef struct { 18 | DISPENV disp; 19 | DRAWENV draw; 20 | uint32_t ot[OT_LEN]; 21 | uint8_t p[PACKET_LEN]; 22 | } Framebuffer; 23 | 24 | typedef struct { 25 | Framebuffer db[2]; 26 | int db_active; 27 | uint8_t *db_nextpri; 28 | } RenderContext; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /examples/graphics/render2tex/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | render2tex 8 | LANGUAGES C ASM 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK render-to-texture example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c) 15 | psn00bsdk_add_executable(render2tex GPREL ${_sources}) 16 | #psn00bsdk_add_cd_image(render2tex_iso render2tex iso.xml DEPENDS render2tex) 17 | 18 | psn00bsdk_target_incbin(render2tex PRIVATE tim_blendpattern blendpattern-16c.tim) 19 | 20 | install(FILES ${PROJECT_BINARY_DIR}/render2tex.exe TYPE BIN) 21 | -------------------------------------------------------------------------------- /examples/mdec/strvideo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | strvideo 8 | LANGUAGES C 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK .STR video playback example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c) 15 | psn00bsdk_add_executable(strvideo GPREL ${_sources}) 16 | #psn00bsdk_add_cd_image(strvideo_iso strvideo iso.xml DEPENDS strvideo) 17 | 18 | install( 19 | FILES 20 | #${PROJECT_BINARY_DIR}/strvideo.bin 21 | #${PROJECT_BINARY_DIR}/strvideo.cue 22 | ${PROJECT_BINARY_DIR}/strvideo.exe 23 | TYPE BIN 24 | ) 25 | -------------------------------------------------------------------------------- /examples/graphics/fpscam/clip.h: -------------------------------------------------------------------------------- 1 | #ifndef _CLIP_H 2 | #define _CLIP_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /* tri_clip 9 | * 10 | * Returns non-zero if a triangle (v0, v1, v2) is outside 'clip'. 11 | * 12 | * clip - Clipping area 13 | * v0,v1,v2 - Triangle coordinates 14 | * 15 | */ 16 | int tri_clip(RECT *clip, DVECTOR *v0, DVECTOR *v1, DVECTOR *v2); 17 | 18 | /* quad_clip 19 | * 20 | * Returns non-zero if a quad (v0, v1, v2, v3) is outside 'clip'. 21 | * 22 | * clip - Clipping area 23 | * v0,v1,v2,v3 - Quad coordinates 24 | * 25 | */ 26 | int quad_clip(RECT *clip, DVECTOR *v0, DVECTOR *v1, DVECTOR *v2, DVECTOR *v3); 27 | 28 | #endif // _CLIP_H -------------------------------------------------------------------------------- /examples/graphics/hdtv/clip.h: -------------------------------------------------------------------------------- 1 | #ifndef _CLIP_H 2 | #define _CLIP_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /* tri_clip 9 | * 10 | * Returns non-zero if a triangle (v0, v1, v2) is outside 'clip'. 11 | * 12 | * clip - Clipping area 13 | * v0,v1,v2 - Triangle coordinates 14 | * 15 | */ 16 | int tri_clip(RECT *clip, DVECTOR *v0, DVECTOR *v1, DVECTOR *v2); 17 | 18 | /* quad_clip 19 | * 20 | * Returns non-zero if a quad (v0, v1, v2, v3) is outside 'clip'. 21 | * 22 | * clip - Clipping area 23 | * v0,v1,v2,v3 - Quad coordinates 24 | * 25 | */ 26 | int quad_clip(RECT *clip, DVECTOR *v0, DVECTOR *v1, DVECTOR *v2, DVECTOR *v3); 27 | 28 | #endif // _CLIP_H -------------------------------------------------------------------------------- /template/CMakePresets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "cmakeMinimumRequired": { 4 | "major": 3, 5 | "minor": 21, 6 | "patch": 0 7 | }, 8 | "configurePresets": [ 9 | { 10 | "name": "default", 11 | "displayName": "Default configuration", 12 | "description": "Use this preset to build the project using PSn00bSDK.", 13 | "generator": "Ninja", 14 | "toolchainFile": "$env{PSN00BSDK_LIBS}/cmake/sdk.cmake", 15 | "binaryDir": "${sourceDir}/build", 16 | "cacheVariables": { 17 | "CMAKE_BUILD_TYPE": "Debug", 18 | "PSN00BSDK_TC": "", 19 | "PSN00BSDK_TARGET": "mipsel-none-elf" 20 | }, 21 | "warnings": { 22 | "dev": false 23 | } 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /examples/cdrom/cdbrowse/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | cdbrowse 8 | LANGUAGES C ASM 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK CD file browser example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c) 15 | psn00bsdk_add_executable(cdbrowse GPREL ${_sources}) 16 | psn00bsdk_add_cd_image(cdbrowse_iso cdbrowse iso.xml DEPENDS cdbrowse) 17 | 18 | psn00bsdk_target_incbin(cdbrowse PRIVATE ball16c ball16c.tim) 19 | 20 | install( 21 | FILES 22 | ${PROJECT_BINARY_DIR}/cdbrowse.bin 23 | ${PROJECT_BINARY_DIR}/cdbrowse.cue 24 | TYPE BIN 25 | ) 26 | -------------------------------------------------------------------------------- /examples/sound/vagsample/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | vagsample 8 | LANGUAGES C ASM 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK SPU sound playback example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c) 15 | psn00bsdk_add_executable(vagsample GPREL ${_sources}) 16 | #psn00bsdk_add_cd_image(vagsample_iso vagsample iso.xml DEPENDS vagsample) 17 | 18 | psn00bsdk_target_incbin(vagsample PRIVATE proyt proyt.vag) 19 | psn00bsdk_target_incbin(vagsample PRIVATE tdfx 3dfx.vag) 20 | 21 | install(FILES ${PROJECT_BINARY_DIR}/vagsample.exe TYPE BIN) 22 | -------------------------------------------------------------------------------- /libpsn00b/psxgpu/readme.txt: -------------------------------------------------------------------------------- 1 | PSX GPU library, part of PSn00bSDK 2 | 2019 Lameguy64 / Meido-Tek Productions 3 | 4 | Licensed under Mozilla Public License 5 | 6 | Open source implementation of the GPU library written entirely in C. Supports 7 | DMA transfers for drawing OTs (with an internal queue so DrawOTag() can be 8 | called even when another OT is being drawn) and transferring image data to and 9 | from VRAM. The syntax is intentionally made to closely resemble Sony's syntax 10 | for familiarity and to make porting homebrew made using the official SDK to 11 | PSn00bSDK a little easier. 12 | 13 | Library developer(s): 14 | 15 | Lameguy64 (initial implementation in assembly, debug font API) 16 | spicyjpeg 17 | 18 | Library header(s): 19 | 20 | psxgpu.h 21 | -------------------------------------------------------------------------------- /tools/smxlink/timreader.h: -------------------------------------------------------------------------------- 1 | #ifndef _TIMREADER_H 2 | #define _TIMREADER_H 3 | 4 | typedef struct { 5 | struct { 6 | unsigned int pmode:3; // Pixel mode (0: 4-bit, 1: 8-bit, 2: 16-bit, 3: 24-bit) 7 | unsigned int cf:1; // CLUT flag (if 1, CLUT is present) 8 | unsigned int reserved:28; 9 | } flag; 10 | struct { 11 | unsigned int length; 12 | unsigned short px,py; 13 | unsigned short pw,ph; 14 | } clutdata; 15 | struct { 16 | unsigned int length; 17 | unsigned short px,py; 18 | unsigned short pw,ph; 19 | } pixdata; 20 | } TIM_COORDS; 21 | 22 | int GetTimCoords(const char *fileName, TIM_COORDS *coords); 23 | 24 | unsigned short GetClut(int cx, int cy); 25 | 26 | unsigned short GetTPage(int tp, int abr, int x, int y); 27 | 28 | #endif // _TIMREADER_H 29 | -------------------------------------------------------------------------------- /libpsn00b/lzp/lzqlp.h: -------------------------------------------------------------------------------- 1 | #ifndef _QLP_H 2 | #define _QLP_H 3 | 4 | #include 5 | #ifdef _WIN32 6 | #include 7 | #endif 8 | 9 | #define PACK_ERR_NONE 0 10 | #define PACK_ERR_INVALID -1 11 | #define PACK_ERR_NOTFOUND -2 12 | #define PACK_ERR_INCOMPLETE -3 13 | #define PACK_ERR_READ_FAULT -4 14 | 15 | typedef struct { 16 | char id[3]; 17 | uint8_t numfiles; 18 | } QLP_HEAD; 19 | 20 | typedef struct { 21 | char name[16]; 22 | uint32_t size; 23 | uint32_t offs; 24 | } QLP_FILE; 25 | 26 | int qlpFileCount(const QLP_HEAD* qlpfile); 27 | const QLP_FILE* qlpFileEntry(int index, const QLP_HEAD* qlpfile); 28 | const void* qlpFileAddr(int index, const QLP_HEAD* qlpfile); 29 | int qlpFindFile(char* fileName, const QLP_HEAD* qlpfile); 30 | 31 | #endif // _QLP_H -------------------------------------------------------------------------------- /libpsn00b/include/lzp/lzqlp.h: -------------------------------------------------------------------------------- 1 | #ifndef _QLP_H 2 | #define _QLP_H 3 | 4 | #include 5 | #ifdef _WIN32 6 | #include 7 | #endif 8 | 9 | #define PACK_ERR_NONE 0 10 | #define PACK_ERR_INVALID -1 11 | #define PACK_ERR_NOTFOUND -2 12 | #define PACK_ERR_INCOMPLETE -3 13 | #define PACK_ERR_READ_FAULT -4 14 | 15 | typedef struct { 16 | char id[3]; 17 | uint8_t numfiles; 18 | } QLP_HEAD; 19 | 20 | typedef struct { 21 | char name[16]; 22 | uint32_t size; 23 | uint32_t offs; 24 | } QLP_FILE; 25 | 26 | int qlpFileCount(const QLP_HEAD* qlpfile); 27 | const QLP_FILE* qlpFileEntry(int index, const QLP_HEAD* qlpfile); 28 | const void* qlpFileAddr(int index, const QLP_HEAD* qlpfile); 29 | int qlpFindFile(char* fileName, const QLP_HEAD* qlpfile); 30 | 31 | #endif // _QLP_H -------------------------------------------------------------------------------- /examples/cdrom/cdxa/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | cdxa 8 | LANGUAGES C ASM 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK CD-XA playback example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | # TODO: add rules to actually generate a valid .XA file 15 | file(GLOB _sources *.c) 16 | psn00bsdk_add_executable(cdxa GPREL ${_sources}) 17 | #psn00bsdk_add_cd_image(cdxa_iso cdxa iso.xml DEPENDS cdxa) 18 | 19 | psn00bsdk_target_incbin(cdxa PRIVATE ball16c ball16c.tim) 20 | 21 | install( 22 | FILES 23 | #${PROJECT_BINARY_DIR}/cdxa.bin 24 | #${PROJECT_BINARY_DIR}/cdxa.cue 25 | ${PROJECT_BINARY_DIR}/cdxa.exe 26 | TYPE BIN 27 | ) 28 | -------------------------------------------------------------------------------- /libpsn00b/libc/abort.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PSn00bSDK assert macro and internal logging 3 | * (C) 2022 spicyjpeg - MPL licensed 4 | */ 5 | 6 | #undef SDK_LIBRARY_NAME 7 | 8 | #include 9 | #include 10 | 11 | /* Internal function used by assert() macro */ 12 | 13 | void _assert_abort(const char *file, int line, const char *expr) { 14 | _sdk_log("%s:%d: assert(%s)\n", file, line, expr); 15 | 16 | for (;;) 17 | __asm__ volatile(""); 18 | } 19 | 20 | /* Standard abort */ 21 | 22 | void abort(void) { 23 | _sdk_log("abort()\n"); 24 | 25 | for (;;) 26 | __asm__ volatile(""); 27 | } 28 | 29 | /* Pure virtual function call (C++) */ 30 | 31 | void __cxa_pure_virtual(void) { 32 | _sdk_log("__cxa_pure_virtual()\n"); 33 | 34 | for (;;) 35 | __asm__ volatile(""); 36 | } 37 | -------------------------------------------------------------------------------- /libpsn00b/libc/memmove.s: -------------------------------------------------------------------------------- 1 | .set noreorder 2 | 3 | .section .text 4 | 5 | # Arguments 6 | # a0 - destination address 7 | # a1 - source address 8 | # a2 - bytes to move 9 | .global memmove 10 | .type memmove, @function 11 | memmove: 12 | move $v0, $a0 13 | sltu $v1, $a0, $a1 14 | blez $v1, .Linit_backward 15 | .Lloop_forward: 16 | blez $a2, .Lexit 17 | addi $a2, -1 18 | lbu $v1, 0($a1) 19 | addiu $a1, 1 20 | sb $v1, 0($a0) 21 | addiu $a0, 1 22 | b .Lloop_forward 23 | nop 24 | .Linit_backward: 25 | addu $a0, $a2 26 | addu $a1, $a2 27 | addiu $a0, -1 28 | addiu $a1, -1 29 | b .Lloop_backward 30 | nop 31 | .Lloop_backward: 32 | blez $a2, .Lexit 33 | addi $a2, -1 34 | lbu $v1, 0($a1) 35 | addiu $a1, -1 36 | sb $v1, 0($a0) 37 | addiu $a0, -1 38 | b .Lloop_backward 39 | nop 40 | .Lexit: 41 | jr $ra 42 | nop -------------------------------------------------------------------------------- /libpsn00b/include/sys/fcntl.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_FCNTL_H 2 | #define _SYS_FCNTL_H 3 | 4 | // File control mode flags for BIOS file functions 5 | // (many weren't documented in nocash docs) 6 | #define FREAD 0x1 // Read 7 | #define FWRITE 0x2 // Write 8 | #define FNBLOCK 0x4 // Non-blocking read access 9 | #define FRLOCK 0x10 // Read lock 10 | #define FWLOCK 0x20 // Write lock 11 | #define FAPPEND 0x100 // Append 12 | #define FCREATE 0x200 // Create if not exist 13 | #define FTRUNC 0x400 // Truncate to zero length 14 | #define FSCAN 0x2000 // Scanning type 15 | #define FRCOM 0x2000 // Remote command entry 16 | #define FNBUF 0x4000 // No ring buffer and terminal interrupt 17 | #define FASYNC 0x8000 // Asynchronous I/O 18 | #define FNBLOCKS(a) (a<<16) // Number of blocks? (from nocash docs) 19 | 20 | #endif -------------------------------------------------------------------------------- /libpsn00b/psxapi/_initcd.s: -------------------------------------------------------------------------------- 1 | .section .text 2 | .set noreorder 3 | 4 | .include "hwregs_a.inc" 5 | 6 | .global _InitCd 7 | .type _InitCd, @function 8 | _InitCd: 9 | addiu $sp, -8 10 | sw $ra, 0($sp) 11 | 12 | lui $a0, IOBASE # Load IOBASE value 13 | 14 | lw $v0, DMA_DPCR($a0) # Get current DMA settings 15 | nop 16 | sw $v0, 4($sp) # Save to stack 17 | 18 | jal _96_init # Init CD subsystem 19 | nop 20 | 21 | lui $a0, IOBASE # Load IOBASE again 22 | 23 | lw $v0, 4($sp) # Get old DMA control settings 24 | lw $v1, DMA_DPCR($a0) # Get DMA settings by _96_init() 25 | 26 | lui $a1, 0xffff # Mask out settings for CD DMA 27 | ori $a1, 0x0f00 28 | and $v0, $a1 29 | 30 | or $v0, $v1 # Merge and set new DMA settings 31 | sw $v0, DMA_DPCR($a0) 32 | 33 | lw $ra, 0($sp) 34 | addiu $sp, 8 35 | jr $ra 36 | nop 37 | -------------------------------------------------------------------------------- /examples/mdec/strvideo/iso.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /examples/sound/cdstream/iso.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /examples/system/dynlink/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | dynlink 8 | LANGUAGES C ASM 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK dynamic linker example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c) 15 | psn00bsdk_add_executable(dynlink_main NOGPREL ${_sources}) 16 | psn00bsdk_add_library (dynlink_cube SHARED library/cube.c) 17 | psn00bsdk_add_library (dynlink_balls SHARED library/balls.c) 18 | psn00bsdk_add_cd_image( 19 | dynlink_iso dynlink iso.xml 20 | DEPENDS dynlink_main dynlink_cube dynlink_balls 21 | ) 22 | 23 | psn00bsdk_target_incbin(dynlink_balls PRIVATE ball16c library/ball16c.tim) 24 | 25 | install( 26 | FILES 27 | ${PROJECT_BINARY_DIR}/dynlink.bin 28 | ${PROJECT_BINARY_DIR}/dynlink.cue 29 | TYPE BIN 30 | ) 31 | -------------------------------------------------------------------------------- /libpsn00b/psxgte/initgeom.s: -------------------------------------------------------------------------------- 1 | .set noreorder 2 | 3 | .include "hwregs_a.inc" 4 | .include "gtereg.inc" 5 | 6 | .section .text.InitGeom 7 | .global InitGeom 8 | .type InitGeom, @function 9 | InitGeom: 10 | # Disable interrupts and make sure the GTE is enabled in COP0. 11 | lui $v0, IOBASE 12 | lhu $v1, IRQ_MASK($v0) 13 | nop 14 | sh $0, IRQ_MASK($v0) 15 | 16 | mfc0 $a0, $12 17 | lui $a1, 0x4000 18 | or $a1, $a0 19 | mtc0 $a1, $12 20 | nop 21 | #nop 22 | 23 | # Re-enable interrupts, then load default values into some GTE registers. 24 | sh $v1, IRQ_MASK($v0) 25 | 26 | ctc2 $0, C2_OFX 27 | nop 28 | ctc2 $0, C2_OFY 29 | 30 | li $a0, 320 31 | ctc2 $a0, C2_H 32 | 33 | li $a0, 0x155 34 | ctc2 $a0, C2_ZSF3 35 | li $a0, 0x100 36 | ctc2 $a0, C2_ZSF4 37 | 38 | li $a0, 0xef9e 39 | ctc2 $a0, C2_DQA 40 | lui $a0, 0x0140 41 | ctc2 $a0, C2_DQB 42 | 43 | jr $ra 44 | nop 45 | -------------------------------------------------------------------------------- /examples/cdrom/cdbrowse/iso.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /libpsn00b/include/assert.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PSn00bSDK assert macro and internal logging 3 | * (C) 2022 spicyjpeg - MPL licensed 4 | * 5 | * Note that the _sdk_log() macro is used internally by PSn00bSDK to output 6 | * debug messages and warnings. 7 | */ 8 | 9 | #ifndef __ASSERT_H 10 | #define __ASSERT_H 11 | 12 | #include 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | void _assert_abort(const char *file, int line, const char *expr); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | #ifdef NDEBUG 25 | 26 | #define assert(expr) 27 | #define _sdk_log(fmt, ...) 28 | 29 | #else 30 | 31 | #define assert(expr) \ 32 | ((expr) ? ((void) 0) : _assert_abort(__FILE__, __LINE__, #expr)) 33 | 34 | #ifdef SDK_LIBRARY_NAME 35 | #define _sdk_log(fmt, ...) printf(SDK_LIBRARY_NAME ": " fmt, ##__VA_ARGS__) 36 | #else 37 | #define _sdk_log(fmt, ...) printf(fmt, ##__VA_ARGS__) 38 | #endif 39 | 40 | #endif 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /libpsn00b/psxspu/readme.txt: -------------------------------------------------------------------------------- 1 | PSX SPU Library, part of PSn00bSDK 2 | 2019 Lameguy64 / Meido-Tek Productions 3 | 4 | Licensed under Mozilla Public License 5 | 6 | Open source implementation of the SPU library written entirely in C. Currently 7 | only supports SPU initialization, reading/writing SPU RAM using DMA and basic 8 | sample playback. Most of the official API is not going to be implemented as the 9 | vast majority of it is just inefficient wrappers around accessing SPU registers 10 | directly, which can be done already using the macros defined in hwregs_c.h. 11 | 12 | Library developer(s): 13 | 14 | Lameguy64 (initial implementation in assembly) 15 | spicyjpeg 16 | 17 | Library header(s): 18 | 19 | psxspu.h 20 | 21 | Todo list: 22 | 23 | * SPU RAM allocation routines yet to be implemented (heap must only be 24 | stored in main RAM and not SPU RAM like in the official SDK). 25 | 26 | * SPU reverb configuration functions yet to be implemented. 27 | -------------------------------------------------------------------------------- /examples/cdrom/cdxa/iso.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /tools/lzpack/filelist.h: -------------------------------------------------------------------------------- 1 | #ifndef _FILELIST_H 2 | #define _FILELIST_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #ifdef WIN32 10 | #include 11 | #else 12 | #include 13 | #endif 14 | 15 | #ifndef MAX_PATH 16 | #define MAX_PATH PATH_MAX 17 | #endif 18 | 19 | typedef struct { 20 | char* fileName; 21 | char* aliasName; 22 | int windowSize; 23 | int hash1Size; 24 | int hash2Size; 25 | } FileListEntry; 26 | 27 | class FileListClass { 28 | 29 | int NumFiles; 30 | int AllocFiles; 31 | FileListEntry* FileList; 32 | 33 | public: 34 | 35 | FileListClass(); 36 | virtual ~FileListClass(); 37 | 38 | void AddFileEntry(const char* fileName, const char* aliasName, short windowSize, short hash1Size, short hash2Size); 39 | 40 | const FileListEntry* Entry(int index); 41 | int EntryCount(); 42 | 43 | void PrintEntries(); 44 | 45 | }; 46 | 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /libpsn00b/lzp/bit.c: -------------------------------------------------------------------------------- 1 | #include "bit.h" 2 | 3 | // Bit I/O 4 | // 5 | 6 | const unsigned char* inPtr = 0; 7 | int inBytes = 0; 8 | unsigned char* outPtr = 0; 9 | int outBytes = 0; 10 | 11 | int bit_buf; 12 | int bit_count; 13 | 14 | void init_bits() { 15 | 16 | bit_count = bit_buf=0; 17 | 18 | } 19 | 20 | void put_bits(int n, int x) { 21 | 22 | bit_buf |= x<= 8) { 26 | 27 | *outPtr = bit_buf; 28 | outPtr++; 29 | outBytes++; 30 | 31 | bit_buf >>= 8; 32 | bit_count -= 8; 33 | 34 | } 35 | 36 | } 37 | 38 | void flush_bits() { 39 | 40 | put_bits(7, 0); 41 | bit_count = bit_buf = 0; 42 | 43 | } 44 | 45 | int get_bits(int n) { 46 | 47 | int x; 48 | 49 | while(bit_count < n) { 50 | 51 | bit_buf |= *inPtr<>= n; 61 | bit_count -= n; 62 | 63 | return(x); 64 | 65 | } 66 | -------------------------------------------------------------------------------- /libpsn00b/libc/clz.s: -------------------------------------------------------------------------------- 1 | # PSn00bSDK leading zero count intrinsics 2 | # (C) 2022 spicyjpeg - MPL licensed 3 | # 4 | # libgcc provides two functions used internally by GCC to count the number of 5 | # leading zeroes or ones in a value, _clzsi2() (32-bit) and _clzdi2() (64-bit). 6 | # This file overrides them with faster implementations that make use of the 7 | # GTE's LZCS/LZCR registers. 8 | 9 | .set noreorder 10 | 11 | .section .text._clzsi2 12 | .global _clzsi2 13 | .type _clzsi2, @function 14 | _clzsi2: 15 | mtc2 $a0, $30 16 | nop 17 | nop 18 | mfc2 $v0, $31 19 | 20 | jr $ra 21 | nop 22 | 23 | .section .text._clzdi2 24 | .global _clzdi2 25 | .type _clzdi2, @function 26 | _clzdi2: 27 | bnez $a1, .Lhas_msb 28 | nop 29 | 30 | mtc2 $a0, $30 # if (!msb) return 32 + clz(lsb) 31 | b .Lreturn 32 | li $v1, 32 33 | 34 | .Lhas_msb: 35 | mtc2 $a1, $30 # if (msb) return 0 + clz(msb) 36 | nop 37 | li $v1, 0 38 | 39 | .Lreturn: 40 | mfc2 $v0, $31 41 | 42 | jr $ra 43 | addu $v0, $v1 44 | -------------------------------------------------------------------------------- /examples/system/dynlink/iso.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /libpsn00b/psxapi/fs.s: -------------------------------------------------------------------------------- 1 | # PSn00bSDK BIOS API stubs 2 | # (C) 2022 spicyjpeg - MPL licensed 3 | 4 | # This file has been generated automatically. Each function is placed in its 5 | # own section to allow the linker to strip unused functions. 6 | 7 | .set noreorder 8 | 9 | ## B0 table functions (5) 10 | 11 | .section .text.chdir 12 | .global chdir 13 | .type chdir, @function 14 | chdir: 15 | li $t2, 0xb0 16 | jr $t2 17 | li $t1, 0x40 18 | 19 | .section .text.firstfile 20 | .global firstfile 21 | .type firstfile, @function 22 | firstfile: 23 | li $t2, 0xb0 24 | jr $t2 25 | li $t1, 0x42 26 | 27 | .section .text.nextfile 28 | .global nextfile 29 | .type nextfile, @function 30 | nextfile: 31 | li $t2, 0xb0 32 | jr $t2 33 | li $t1, 0x43 34 | 35 | .section .text.rename 36 | .global rename 37 | .type rename, @function 38 | rename: 39 | li $t2, 0xb0 40 | jr $t2 41 | li $t1, 0x44 42 | 43 | .section .text.erase 44 | .global erase 45 | .type erase, @function 46 | erase: 47 | li $t2, 0xb0 48 | jr $t2 49 | li $t1, 0x45 50 | 51 | -------------------------------------------------------------------------------- /libpsn00b/psxgte/readme.txt: -------------------------------------------------------------------------------- 1 | PSX GTE library, part of PSn00bSDK 2 | 2019 Lameguy64 / Meido-Tek Productions 3 | 4 | Licensed under Mozilla Public License 5 | 6 | Open source implementation of the GTE library written mostly in MIPS 7 | assembly. It makes full use of the GTE in complex matrix multiplication 8 | operations. The syntax is intentionally made to closely resemble Sony's syntax 9 | for familiarity and to make porting homebrew made using the official SDK to 10 | PSn00bSDK a little easier. 11 | 12 | Unlike the official GTE libraries using the inline GTE macro functions does 13 | not require running your object file through some stupid tool such as DMPSX. 14 | The GTE macros use the corresponding cop2 opcodes already. 15 | 16 | 17 | Library developer(s): 18 | 19 | Lameguy64 20 | 21 | 22 | Library header(s): 23 | 24 | gtereg.inc 25 | inline_c.h 26 | inline_s.inc 27 | psxgte.h 28 | 29 | 30 | Todo list: 31 | 32 | * Alternate RotMatrix() functions with different rotation orders are yet to 33 | be implemented. 34 | * Various high level RotTransPersp style functions not yet implemented. 35 | 36 | -------------------------------------------------------------------------------- /tools/tools.txt: -------------------------------------------------------------------------------- 1 | To build the tools, simply run 'make all install' in this directory. The 2 | binaries of the tools should reside in a directory named bin for your 3 | convenience. 4 | 5 | 6 | Brief tools summary: 7 | 8 | lzpack - File compression and packing utility for creating LZP, PCK and 9 | QLP archive files. Depends on tinyxml2. 10 | 11 | smxlink - SMX to SMD linker tool (from Project Scarlet/Scarlet Engine). 12 | SMD drawing and parsing code can be found in the n00bdemo example. 13 | Depends on tinyxml2. 14 | 15 | plugins - Includes a plugin for exporting models into Project Scarlet/Scarlet 16 | Engine SMX model data format. 17 | 18 | util - A collection of small single C or C++ file tools such as elf2x. 19 | 20 | 21 | Other tools you may want: 22 | 23 | img2tim - Image to TIM texture file converter powered by FreeImage. 24 | https://github.com/Lameguy64/img2tim 25 | 26 | smxtool - SMX model data tweaking tool. 27 | https://github.com/Lameguy64/smxtool 28 | 29 | mkpsxiso - PlayStation ISO creation tool with CD-DA, CD-XA and STR file support. 30 | https://github.com/Lameguy64/mkpsxiso -------------------------------------------------------------------------------- /libpsn00b/psxgte/isin.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PSn00bSDK (incomplete) trigonometry library 3 | * (C) 2019-2022 Lameguy64, spicyjpeg - MPL licensed 4 | * 5 | * Based on isin_S4 implementation from coranac: 6 | * https://www.coranac.com/2009/07/sines 7 | */ 8 | 9 | #define qN_l 10 10 | #define qN_h 15 11 | #define qA 12 12 | #define B 19900 13 | #define C 3516 14 | 15 | static inline int _isin(int qN, int x) { 16 | int c, x2, y; 17 | 18 | c = x << (30 - qN); // Semi-circle info into carry. 19 | x -= 1 << qN; // sine -> cosine calc 20 | 21 | x <<= (31 - qN); // Mask with PI 22 | x >>= (31 - qN); // Note: SIGNED shift! (to qN) 23 | x *= x; 24 | x >>= (2 * qN - 14); // x=x^2 To Q14 25 | 26 | y = B - (x * C >> 14); // B - x^2*C 27 | y = (1 << qA) - (x * y >> 16); // A - x^2*(B-x^2*C) 28 | 29 | return (c >= 0) ? y : (-y); 30 | } 31 | 32 | int isin(int x) { 33 | return _isin(qN_l, x); 34 | } 35 | 36 | int icos(int x) { 37 | return _isin(qN_l, x + (1 << qN_l)); 38 | } 39 | 40 | int hisin(int x) { 41 | return _isin(qN_h, x); 42 | } 43 | 44 | int hicos(int x) { 45 | return _isin(qN_h, x + (1 << qN_h)); 46 | } 47 | -------------------------------------------------------------------------------- /libpsn00b/include/string.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PSn00bSDK standard library 3 | * (C) 2019-2022 PSXSDK authors, Lameguy64, spicyjpeg - MPL licensed 4 | */ 5 | 6 | #ifndef __STRING_H 7 | #define __STRING_H 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | int strcmp(const char *dst , const char *src); 14 | int strncmp(const char *dst , const char *src , int len); 15 | char *strpbrk(const char *dst , const char *src); 16 | char *strtok(char *s , char *set); 17 | char *strstr(const char *big , const char *little); 18 | 19 | char *strcat(char *s , const char *append); 20 | char *strncat(char *s , const char *append, int n); 21 | char *strcpy(char *dst , const char *src); 22 | char *strncpy(char *dst , const char *src , int n); 23 | int strlen(const char *s); 24 | char *strchr(const char *s , int c); 25 | char *strrchr(const char *s , int c); 26 | 27 | void *memmove(void *dst , const void *src , int n); 28 | void *memchr(void *s , int c , int n); 29 | void *memcpy(void *dst , const void *src , int n); 30 | void *memset(void *dst , char c , int n); 31 | int memcmp(const void *b1 , const void *b2 , int n); 32 | 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /examples/lowlevel/cartrom/bios.inc: -------------------------------------------------------------------------------- 1 | printf: 2 | addiu $t2, $0, 0xA0 3 | jr $t2 4 | addiu $t1, $0, 0x3F 5 | 6 | atoi: 7 | addiu $t2, $0, 0xA0 8 | jr $t2 9 | addiu $t1, $0, 0x10 10 | 11 | toupper: 12 | addiu $t2, $0, 0xA0 13 | jr $t2 14 | addiu $t1, $0, 0x25 15 | 16 | open: 17 | addiu $t2, $0, 0xB0 18 | jr $t2 19 | addiu $t1, $0, 0x32 20 | 21 | read: 22 | addiu $t2, $0, 0xB0 23 | jr $t2 24 | addiu $t1, $0, 0x34 25 | 26 | close: 27 | addiu $t2, $0, 0xB0 28 | jr $t2 29 | addiu $t1, $0, 0x36 30 | 31 | _96_init: 32 | addiu $t2, $0, 0xA0 33 | jr $t2 34 | addiu $t1, $0, 0x71 35 | 36 | LoadExe: 37 | addiu $t2, $0, 0xA0 38 | jr $t2 39 | addiu $t1, $0, 0x42 40 | 41 | DoExec: 42 | addiu $t2, $0, 0xA0 43 | jr $t2 44 | addiu $t1, $0, 0x43 45 | 46 | SetConf: 47 | addiu $t2, $0, 0xA0 48 | jr $t2 49 | addiu $t1, $0, 0x9C 50 | 51 | SetDefaultExitFromException: 52 | addiu $t2, $0, 0xB0 53 | jr $t2 54 | addiu $t1, $0, 0x18 55 | 56 | EnterCriticalSection: 57 | addiu $a0, $0, 1 58 | syscall 0 59 | jr $ra 60 | nop 61 | 62 | ExitCriticalSection: 63 | addiu $a0, $0, 2 64 | syscall 0 65 | jr $ra 66 | nop 67 | -------------------------------------------------------------------------------- /examples/lowlevel/cartrom/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | cartrom 8 | LANGUAGES C ASM 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK expansion port ROM example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c *.s) 15 | 16 | # This example only uses the toolchain (without the rest of the SDK), so the 17 | # executable has to be created manually and converted into raw binary format 18 | # (for testing on emulators or flashing to a cheat cartridge). 19 | add_executable (cartrom ${_sources}) 20 | target_link_options (cartrom PRIVATE -T${PROJECT_SOURCE_DIR}/rom.ld) 21 | set_target_properties( 22 | cartrom PROPERTIES 23 | PREFIX "" 24 | SUFFIX ".elf" 25 | PSN00BSDK_TARGET_TYPE EXECUTABLE_NOGPREL 26 | ) 27 | 28 | target_include_directories(cartrom PRIVATE ${PROJECT_SOURCE_DIR}) 29 | 30 | add_custom_command( 31 | TARGET cartrom POST_BUILD 32 | COMMAND ${CMAKE_OBJCOPY} -O binary cartrom.elf cartrom.bin 33 | BYPRODUCTS cartrom.bin 34 | ) 35 | 36 | install(FILES ${PROJECT_BINARY_DIR}/cartrom.bin TYPE BIN) 37 | -------------------------------------------------------------------------------- /libpsn00b/psxapi/_syscalls.s: -------------------------------------------------------------------------------- 1 | # PSn00bSDK syscall wrappers 2 | # (C) 2022 spicyjpeg - MPL licensed 3 | 4 | .set noreorder 5 | 6 | .section .text.EnterCriticalSection 7 | .global EnterCriticalSection 8 | .type EnterCriticalSection, @function 9 | EnterCriticalSection: 10 | li $a0, 0x01 11 | syscall 0 12 | 13 | jr $ra 14 | nop 15 | 16 | .section .text.ExitCriticalSection 17 | .global ExitCriticalSection 18 | .type ExitCriticalSection, @function 19 | ExitCriticalSection: 20 | li $a0, 0x02 21 | syscall 0 22 | 23 | jr $ra 24 | nop 25 | 26 | .section .text.SwEnterCriticalSection 27 | .global SwEnterCriticalSection 28 | .type SwEnterCriticalSection, @function 29 | SwEnterCriticalSection: 30 | mfc0 $a0, $12 # cop0r12 &= ~0x401 31 | li $a1, -1026 32 | and $a1, $a0 33 | mtc0 $a1, $12 34 | andi $a0, 0x0401 # return ((cop0r12_prev & 0x401) == 0x401) 35 | sltiu $v0, $a0, 0x0401 36 | 37 | jr $ra 38 | xori $v0, 1 39 | 40 | .section .text.SwExitCriticalSection 41 | .global SwExitCriticalSection 42 | .type SwExitCriticalSection, @function 43 | SwExitCriticalSection: 44 | mfc0 $a0, $12 # cop0r12 |= 0x401 45 | nop 46 | ori $a0, 0x0401 47 | mtc0 $a0, $12 48 | nop 49 | 50 | jr $ra 51 | nop 52 | -------------------------------------------------------------------------------- /examples/graphics/hdtv/lookat.c: -------------------------------------------------------------------------------- 1 | // LookAt matrix code (may be implemented into libpsxgte soon) 2 | 3 | #include "lookat.h" 4 | 5 | void crossProduct(SVECTOR *v0, SVECTOR *v1, VECTOR *out) { 6 | 7 | out->vx = ((v0->vy*v1->vz)-(v0->vz*v1->vy))>>12; 8 | out->vy = ((v0->vz*v1->vx)-(v0->vx*v1->vz))>>12; 9 | out->vz = ((v0->vx*v1->vy)-(v0->vy*v1->vx))>>12; 10 | 11 | } 12 | 13 | void LookAt(VECTOR *eye, VECTOR *at, SVECTOR *up, MATRIX *mtx) { 14 | 15 | VECTOR taxis; 16 | SVECTOR zaxis; 17 | SVECTOR xaxis; 18 | SVECTOR yaxis; 19 | VECTOR pos; 20 | VECTOR vec; 21 | 22 | setVector(&taxis, at->vx-eye->vx, at->vy-eye->vy, at->vz-eye->vz); 23 | VectorNormalS(&taxis, &zaxis); 24 | crossProduct(&zaxis, up, &taxis); 25 | VectorNormalS(&taxis, &xaxis); 26 | crossProduct(&zaxis, &xaxis, &taxis); 27 | VectorNormalS(&taxis, &yaxis); 28 | 29 | mtx->m[0][0] = xaxis.vx; mtx->m[1][0] = yaxis.vx; mtx->m[2][0] = zaxis.vx; 30 | mtx->m[0][1] = xaxis.vy; mtx->m[1][1] = yaxis.vy; mtx->m[2][1] = zaxis.vy; 31 | mtx->m[0][2] = xaxis.vz; mtx->m[1][2] = yaxis.vz; mtx->m[2][2] = zaxis.vz; 32 | 33 | pos.vx = -eye->vx;; 34 | pos.vy = -eye->vy;; 35 | pos.vz = -eye->vz;; 36 | 37 | ApplyMatrixLV(mtx, &pos, &vec); 38 | TransMatrix(mtx, &vec); 39 | 40 | } -------------------------------------------------------------------------------- /examples/graphics/fpscam/lookat.c: -------------------------------------------------------------------------------- 1 | // LookAt matrix code (may be implemented into libpsxgte soon) 2 | 3 | #include "lookat.h" 4 | 5 | void crossProduct(SVECTOR *v0, SVECTOR *v1, VECTOR *out) { 6 | 7 | out->vx = ((v0->vy*v1->vz)-(v0->vz*v1->vy))>>12; 8 | out->vy = ((v0->vz*v1->vx)-(v0->vx*v1->vz))>>12; 9 | out->vz = ((v0->vx*v1->vy)-(v0->vy*v1->vx))>>12; 10 | 11 | } 12 | 13 | void LookAt(VECTOR *eye, VECTOR *at, SVECTOR *up, MATRIX *mtx) { 14 | 15 | VECTOR taxis; 16 | SVECTOR zaxis; 17 | SVECTOR xaxis; 18 | SVECTOR yaxis; 19 | VECTOR pos; 20 | VECTOR vec; 21 | 22 | setVector(&taxis, at->vx-eye->vx, at->vy-eye->vy, at->vz-eye->vz); 23 | VectorNormalS(&taxis, &zaxis); 24 | crossProduct(&zaxis, up, &taxis); 25 | VectorNormalS(&taxis, &xaxis); 26 | crossProduct(&zaxis, &xaxis, &taxis); 27 | VectorNormalS(&taxis, &yaxis); 28 | 29 | mtx->m[0][0] = xaxis.vx; mtx->m[1][0] = yaxis.vx; mtx->m[2][0] = zaxis.vx; 30 | mtx->m[0][1] = xaxis.vy; mtx->m[1][1] = yaxis.vy; mtx->m[2][1] = zaxis.vy; 31 | mtx->m[0][2] = xaxis.vz; mtx->m[1][2] = yaxis.vz; mtx->m[2][2] = zaxis.vz; 32 | 33 | pos.vx = -eye->vx;; 34 | pos.vy = -eye->vy;; 35 | pos.vz = -eye->vz;; 36 | 37 | ApplyMatrixLV(mtx, &pos, &vec); 38 | TransMatrix(mtx, &vec); 39 | 40 | } -------------------------------------------------------------------------------- /tools/util/elf.h: -------------------------------------------------------------------------------- 1 | #ifndef _ELF_H 2 | #define _ELF_H 3 | 4 | #pragma pack(push, 1) 5 | 6 | typedef struct { 7 | 8 | unsigned int magic; // 0-3 9 | unsigned char word_size; // 4 10 | unsigned char endianness; // 5 11 | unsigned char elf_version; // 6 12 | unsigned char os_abi; // 7 13 | unsigned int unused[2]; // 8-15 14 | 15 | unsigned short type; // 16-17 16 | unsigned short instr_set; // 18-19 17 | unsigned int elf_version2; // 20-23 18 | 19 | unsigned int prg_entry_addr; // 24-27 20 | unsigned int prg_head_pos; // 28-31 21 | unsigned int sec_head_pos; // 32-35 22 | unsigned int flags; // 36-39 23 | unsigned short head_size; // 40-41 24 | unsigned short prg_entry_size; // 42-23 25 | unsigned short prg_entry_count; // 44-45 26 | unsigned short sec_entry_size; // 46-47 27 | unsigned short sec_entry_count; // 48-49 28 | unsigned short sec_names_index; // 50-51 29 | 30 | } ELF_HEADER; 31 | 32 | typedef struct { 33 | unsigned int seg_type; 34 | unsigned int p_offset; 35 | unsigned int p_vaddr; 36 | unsigned int undefined; 37 | unsigned int p_filesz; 38 | unsigned int p_memsz; 39 | unsigned int flags; 40 | unsigned int alignment; 41 | } PRG_HEADER; 42 | 43 | #pragma pack(pop) 44 | 45 | #endif /* _ELF_H */ -------------------------------------------------------------------------------- /libpsn00b/libc/cpp_support.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PSn00bSDK C++ support library 3 | * (C) 2019-2022 Lameguy64, spicyjpeg - MPL licensed 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | /* GCC builtins */ 11 | 12 | extern "C" void *__builtin_new(size_t size) { 13 | return malloc(size); 14 | } 15 | 16 | extern "C" void __builtin_delete(void *ptr) { 17 | free(ptr); 18 | } 19 | 20 | /* Default new/delete operators */ 21 | 22 | void *operator new(size_t size) noexcept { 23 | return malloc(size); 24 | } 25 | 26 | void *operator new[](size_t size) noexcept { 27 | return malloc(size); 28 | } 29 | 30 | void operator delete(void *ptr) noexcept { 31 | free(ptr); 32 | } 33 | 34 | void operator delete[](void *ptr) noexcept { 35 | free(ptr); 36 | } 37 | 38 | // https://en.cppreference.com/w/cpp/memory/new/operator_delete 39 | void operator delete(void *ptr, size_t size) noexcept { 40 | free(ptr); 41 | } 42 | 43 | void operator delete[](void *ptr, size_t size) noexcept { 44 | free(ptr); 45 | } 46 | 47 | /* Placement new operators */ 48 | 49 | void *operator new(size_t size, void *ptr) noexcept { 50 | return ptr; 51 | } 52 | 53 | void *operator new[](size_t size, void *ptr) noexcept { 54 | return ptr; 55 | } 56 | -------------------------------------------------------------------------------- /examples/graphics/rgb24/main.c: -------------------------------------------------------------------------------- 1 | /* LibPSn00b Example Programs 2 | * Part of the PSn00bSDK Project 3 | * 4 | * RGB24 Example by Lameguy64 5 | * 6 | * 7 | * This example demonstrates the 24-bit color mode of the PS1. This mode is 8 | * not practical for gameplay as the GPU can only draw graphics primitives 9 | * in 16-bit color depth so this feature would normally be used only for 10 | * fullscreen graphic illustrations or FMV sequences. 11 | * 12 | * 13 | * Changelog: 14 | * 15 | * May 10, 2021 - Variable types updated for psxgpu.h changes. 16 | * 17 | * May 3, 2019 - Initial version. 18 | * 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | // So data from tim.s can be accessed 27 | extern u_long tim_image[]; 28 | 29 | int main() { 30 | 31 | DISPENV disp; 32 | TIM_IMAGE tim; 33 | 34 | // Reset GPU 35 | ResetGraph(0); 36 | 37 | // Setup 640x480 24-bit video mode 38 | SetDefDispEnv(&disp, 0, 0, 640, 480); 39 | disp.isrgb24 = 1; 40 | disp.isinter = 1; 41 | 42 | // Apply and enable display 43 | PutDispEnv(&disp); 44 | SetDispMask(1); 45 | 46 | // Upload image to VRAM 47 | GetTimInfo(tim_image, &tim); 48 | LoadImage(tim.prect, tim.paddr); 49 | DrawSync(0); 50 | 51 | while(1) { 52 | } 53 | 54 | return 0; 55 | } -------------------------------------------------------------------------------- /examples/demos/n00bdemo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | n00bdemo 8 | LANGUAGES C ASM 9 | VERSION 1.0.0 10 | DESCRIPTION "n00bdemo (PSn00bSDK demo)" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | set(DATA_DIR ${PROJECT_SOURCE_DIR}/data) 15 | 16 | configure_file(data.xml _data.xml) 17 | 18 | # Add a build step to pack assets into a single .LZP file. Note that, since we 19 | # are specifying dependencies, CMake can detect when source assets are edited 20 | # and rebuild the archive automatically. 21 | file(GLOB _assets ${DATA_DIR}/*.tim ${DATA_DIR}/*.smd) 22 | add_custom_command( 23 | COMMAND ${LZPACK} -y _data.xml 24 | OUTPUT data.lzp 25 | BYPRODUCTS textures.qlp 26 | DEPENDS ${_assets} 27 | COMMENT "Building LZP archive" 28 | ) 29 | 30 | file(GLOB _sources *.s *.c) 31 | psn00bsdk_add_executable(n00bdemo GPREL ${_sources}) 32 | #psn00bsdk_add_cd_image(n00bdemo_iso n00bdemo iso.xml DEPENDS n00bdemo) 33 | 34 | target_include_directories(n00bdemo PRIVATE ${PROJECT_SOURCE_DIR}) 35 | psn00bsdk_target_incbin( 36 | n00bdemo PRIVATE _lz_resources 37 | ${PROJECT_BINARY_DIR}/data.lzp 38 | ) 39 | 40 | install(FILES ${PROJECT_BINARY_DIR}/n00bdemo.exe TYPE BIN) 41 | -------------------------------------------------------------------------------- /libpsn00b/include/stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDIO_H 2 | #define _STDIO_H 3 | 4 | #include 5 | 6 | // BIOS seek modes 7 | #ifndef SEEK_SET 8 | #define SEEK_SET 0 9 | #endif 10 | #ifndef SEEK_CUR 11 | #define SEEK_CUR 1 12 | #endif 13 | #ifndef SEEK_END 14 | #define SEEK_END 2 /* warning: reportedly buggy */ 15 | #endif 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | // The following functions use the BIOS 22 | extern void printf (const char *__format, ...); 23 | 24 | extern int getc(int __fd); 25 | extern int putc(int __char, int __fd); 26 | 27 | #define fputc(__char, __fd) putc(__char, __fd) 28 | #define fgetc(__char, __fd) getc(__char, __fd) 29 | 30 | // Console TTY 31 | extern void gets(char *__s); 32 | extern void puts(const char *__s); 33 | extern int getchar(void); 34 | extern void putchar(int __c); 35 | 36 | // The following functions do not use the BIOS 37 | int vsnprintf(char *string, unsigned int size, const char *fmt, va_list ap); 38 | int vsprintf(char *string, const char *fmt, va_list ap); 39 | int sprintf(char *string, const char *fmt, ...); 40 | int snprintf(char *string, unsigned int size, const char *fmt, ...); 41 | 42 | int vsscanf(const char *str, const char *format, va_list ap); 43 | int sscanf(const char *str, const char *fmt, ...); 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | 49 | #endif // _STDIO_H -------------------------------------------------------------------------------- /cpack/fakeroot_fix.cmake: -------------------------------------------------------------------------------- 1 | # This script works around a bug in CPack's DEB/RPM generator, which causes 2 | # files installed by subprojects (not by the main CMake script) to end up in 3 | # packages alongside the "real" installation directory. It probably happens due 4 | # to CMake running under fakeroot (when invoked by CPack to prepare the files 5 | # to be packaged) and referencing absolute paths, which would explain why the 6 | # entire build directory tree is replicated inside the packages. What this 7 | # script does is simply finding and deleting all directories that do not match 8 | # the installation prefix before CPack generates the package. 9 | 10 | cmake_minimum_required(VERSION 3.21) 11 | 12 | set(_prefix ${CPACK_TEMPORARY_INSTALL_DIRECTORY}${CPACK_PACKAGING_INSTALL_PREFIX}) 13 | 14 | file( 15 | GLOB_RECURSE _entries 16 | LIST_DIRECTORIES ON 17 | ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/* 18 | ) 19 | 20 | foreach(_entry IN LISTS _entries) 21 | # Skip the entry if it (or its parent directory) has already been deleted. 22 | if(NOT EXISTS ${_entry}) 23 | continue() 24 | endif() 25 | 26 | # Delete anything whose path doesn't start with the expected prefix. 27 | string(FIND ${_entry} ${_prefix} _index) 28 | if(NOT _index EQUAL 0) 29 | message(NOTICE "Deleting unneeded entry from package: ${_entry}") 30 | file(REMOVE_RECURSE ${_entry}) 31 | endif() 32 | endforeach() 33 | -------------------------------------------------------------------------------- /tools/smxlink/timreader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "timreader.h" 4 | 5 | #ifdef WIN32 6 | #define strcasecmp _stricmp 7 | #endif 8 | 9 | int GetTimCoords(const char* fileName, TIM_COORDS *coords) { 10 | 11 | FILE* fp = fopen(fileName, "rb"); 12 | 13 | if (fp == NULL) 14 | return false; 15 | 16 | 17 | unsigned int id; 18 | 19 | fread(&id, 4, 1, fp); 20 | 21 | if (id != 0x00000010) { 22 | 23 | fclose(fp); 24 | return false; 25 | 26 | } 27 | 28 | fread(&coords->flag, 4, 1, fp); 29 | 30 | if (coords->flag.cf) { 31 | 32 | fread(&coords->clutdata, 12, 1, fp); 33 | fseek(fp, coords->clutdata.length-12, SEEK_CUR); 34 | 35 | } else { 36 | 37 | memset(&coords->clutdata, 0x00, 12); 38 | 39 | } 40 | 41 | fread(&coords->pixdata, 12, 1, fp); 42 | 43 | fclose(fp); 44 | 45 | return true; 46 | 47 | } 48 | 49 | unsigned short GetClut(int cx, int cy) { 50 | 51 | unsigned short clut = (cx/16)&0x3f; 52 | clut |= (cy&0x1ff)<<6; 53 | 54 | return clut; 55 | 56 | } 57 | 58 | unsigned short GetTPage(int tp, int abr, int x, int y) { 59 | 60 | unsigned short tpage = (x/64)&0xf; // Set X 61 | tpage |= ((y/256)&0x1)<<4; // Set Y 62 | 63 | tpage |= (abr&0x3)<<5; // Set blend mode 64 | tpage |= (tp&0x3)<<7; // Set page mode 65 | tpage |= 1<<9; // Set dither processing bit 66 | 67 | return tpage; 68 | 69 | } 70 | -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/star_mask.smx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data/star.smx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /examples/system/childexec/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK example CMake script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | childexec 8 | LANGUAGES C ASM 9 | VERSION 1.0.0 10 | DESCRIPTION "PSn00bSDK child process example" 11 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 12 | ) 13 | 14 | file(GLOB _sources *.c) 15 | file(GLOB _child_sources child/*.c) 16 | psn00bsdk_add_executable(childexec GPREL ${_sources}) 17 | psn00bsdk_add_executable(childexec_child GPREL ${_child_sources}) 18 | #psn00bsdk_add_cd_image(childexec_iso childexec iso.xml DEPENDS childexec) 19 | 20 | psn00bsdk_target_incbin(childexec PRIVATE ball16c ball16c.tim) 21 | psn00bsdk_target_incbin( 22 | childexec PRIVATE child_exe 23 | ${PROJECT_BINARY_DIR}/childexec_child.exe 24 | ) 25 | 26 | # Relocate the child executable to a non-default address to prevent it from 27 | # overlapping with the main one at 0x80010000. 28 | # NOTE: child executables are not position-independent and can't be relocated 29 | # at runtime. If you need your code to be relocatable (e.g. to load it into a 30 | # dynamically-allocated buffer), consider using a DLL instead. 31 | target_link_options(childexec_child PRIVATE -Ttext=0x80030000) 32 | 33 | # Make sure the child executable is built before the parent. 34 | add_dependencies(childexec childexec_child) 35 | 36 | install(FILES ${PROJECT_BINARY_DIR}/childexec.exe TYPE BIN) 37 | -------------------------------------------------------------------------------- /CMakePresets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "cmakeMinimumRequired": { 4 | "major": 3, 5 | "minor": 21, 6 | "patch": 0 7 | }, 8 | "configurePresets": [ 9 | { 10 | "name": "default", 11 | "displayName": "Default configuration", 12 | "description": "Use this preset when building the SDK for local installation.", 13 | "generator": "Ninja", 14 | "binaryDir": "${sourceDir}/build", 15 | "warnings": { 16 | "dev": false 17 | } 18 | }, 19 | { 20 | "name": "package", 21 | "displayName": "Installer package", 22 | "description": "Use this preset to build installer packages via CPack.", 23 | "inherits": "default", 24 | "cacheVariables": { 25 | "CMAKE_BUILD_TYPE": "Release", 26 | "SKIP_EXAMPLES": "ON", 27 | "BUNDLE_TOOLCHAIN": "ON", 28 | "BUNDLE_NINJA": "ON" 29 | } 30 | }, 31 | { 32 | "name": "ci", 33 | "displayName": "CI build", 34 | "description": "This preset is used by GitHub Actions to build PSn00bSDK.", 35 | "inherits": "default", 36 | "binaryDir": "${sourceDir}/../build", 37 | "cacheVariables": { 38 | "CMAKE_BUILD_TYPE": "Release", 39 | "BUNDLE_TOOLCHAIN": "ON", 40 | "BUNDLE_NINJA": "ON", 41 | "LIBPSN00B_GENERATOR": "Ninja", 42 | "PSN00BSDK_TARGET": "$env{GCC_TARGET}", 43 | "PSN00BSDK_GIT_TAG": "$env{GITHUB_REF_NAME}", 44 | "PSN00BSDK_GIT_COMMIT": "$env{GITHUB_SHA}" 45 | } 46 | } 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /indev/README.md: -------------------------------------------------------------------------------- 1 | # The indev directory 2 | 3 | This directory is intended to contain work-in-progress SDK components 4 | (libraries, tools, etc) that are still in prototype stage. These files are 5 | not to be compiled in a typical SDK installation but is added into the 6 | main repo as the redundant SVN repo on the Lameguy64 website will soon be 7 | retired. Contributed components that are in work-in-progress status may 8 | also go into this directory. 9 | 10 | ## Lameguy's indev components 11 | 12 | * libpad: The early beginnings of a pad/card library using routines that 13 | accesses the pad/card interfaces directly. Ideally PSn00bSDK's pad library 14 | should include the functionality of pad/tap/gun peripherals into one 15 | library as well as include functions for reading and writing memory card 16 | sectors. Routines and callback hooks for directly controlling the pad/card 17 | interface should also be provided to support homebrewn peripherals. 18 | 19 | The Github release of this work-in-progress component includes delay 20 | corrections for PAL consoles. 21 | 22 | **NOTE**: the `io/pads` example also shows how to poll controllers manually 23 | in a slightly different way (using a timer), and includes a reusable 24 | low-level pad driver. 25 | 26 | Work-in-progress components such as psxcd, interlace-exp, xptest and partest 27 | are not included, as the former was completed while the remaining latter are 28 | merely scrap test programs. -------------------------------------------------------------------------------- /libpsn00b/libc/readme.txt: -------------------------------------------------------------------------------- 1 | Limited C standard library implementation, part of PSn00bSDK 2 | 2019 Lameguy64 / Meido-Tek Productions 3 | 4 | Some components were inherited from PSXSDK. This library covers only the 5 | most commonly used C functions, mainly most string and memory manipulation 6 | functions. Improvements to this library such as adding more standard C 7 | functions are welcome. 8 | 9 | This library also contains the start code written in assembler which 10 | performs basic initialization such as clearing the bss section, setting the 11 | correct gp register value and initializing the heap for malloc. 12 | 13 | The dynamic memory allocation functions featured in this library are of 14 | an original implementation and do not use the BIOS memory allocation functions 15 | as they are are reportedly prone to memory leakage and is even explained in 16 | the official library documents. The implementation employed uses a simple 17 | first-fit memory allocation logic. 18 | 19 | 20 | Library developer(s)/contributor(s): 21 | 22 | Lameguy64 23 | 24 | 25 | Library header(s): 26 | 27 | stdio.h 28 | stdlib.h 29 | string.h 30 | strings.h 31 | malloc.h 32 | 33 | 34 | Todo list: 35 | 36 | * Many of the string manipulation and memory fill functions in string.c 37 | are yet to be replaced with more efficient assembly implementations. 38 | 39 | 40 | Changelog: 41 | 42 | 05-23-2019 by Lameguy64: 43 | 44 | * Made stack usage a lot less wastefull in _start entrypoint. 45 | -------------------------------------------------------------------------------- /libpsn00b/lzp/qlp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "lzqlp.h" 6 | 7 | static char* lcase(char* str) { 8 | 9 | while(*str != 0x00) { 10 | *str = tolower(*str); 11 | str++; 12 | } 13 | 14 | return(str); 15 | 16 | } 17 | 18 | int qlpFileCount(const QLP_HEAD* qlpfile) { 19 | 20 | if (strncmp(qlpfile->id, "QLP", 3) != 0) 21 | return(PACK_ERR_INVALID); 22 | 23 | return(qlpfile->numfiles); 24 | 25 | } 26 | 27 | const QLP_FILE* qlpFileEntry(int index, const QLP_HEAD* qlpfile) { 28 | 29 | if (strncmp(qlpfile->id, "QLP", 3) != 0) 30 | return(NULL); 31 | 32 | if (index > qlpfile->numfiles) 33 | return(NULL); 34 | 35 | return(&((QLP_FILE*)(((const char*)qlpfile)+sizeof(QLP_HEAD)))[index]); 36 | 37 | } 38 | 39 | const void* qlpFileAddr(int index, const QLP_HEAD* qlpfile) { 40 | 41 | return( ((const char*)qlpfile)+((QLP_FILE*)(((const char*)qlpfile)+sizeof(QLP_HEAD)))[index].offs ); 42 | 43 | } 44 | 45 | int qlpFindFile(char* fileName, const QLP_HEAD* qlpfile) { 46 | 47 | int i; 48 | char nameBuff[2][16]; 49 | 50 | strcpy(nameBuff[0], fileName); 51 | lcase(nameBuff[0]); 52 | 53 | for(i=0; i<(qlpfile->numfiles); i++) { 54 | 55 | strcpy(nameBuff[1], ((QLP_FILE*)(((const char*)qlpfile)+sizeof(QLP_HEAD)))[i].name); 56 | lcase(nameBuff[1]); 57 | 58 | if (strcmp(nameBuff[0], nameBuff[1]) == 0) 59 | return(i); 60 | 61 | } 62 | 63 | return(PACK_ERR_NOTFOUND); 64 | 65 | } -------------------------------------------------------------------------------- /examples/demos/n00bdemo/disp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "smd.h" 7 | #include "disp.h" 8 | 9 | DISPENV disp; 10 | DRAWENV draw; 11 | 12 | char pribuff[2][131072]; 13 | u_long ot[2][OT_LEN]; 14 | char *nextpri; 15 | int db = 0; 16 | 17 | MATRIX mtx; 18 | 19 | 20 | void initDisplay() { 21 | 22 | ResetGraph( 0 ); 23 | 24 | if( GetVideoMode() == MODE_NTSC ) { 25 | SetDefDispEnv( &disp, 0, 0, 640, 480 ); 26 | SetDefDrawEnv( &draw, 0, 0, 640, 480 ); 27 | scSetClipRect( 0, 0, 640, 480 ); 28 | printf("NTSC System.\n"); 29 | } else { 30 | SetDefDispEnv( &disp, 0, 0, 640, 512 ); 31 | SetDefDrawEnv( &draw, 0, 0, 640, 512 ); 32 | scSetClipRect( 0, 0, 640, 512 ); 33 | disp.screen.y = 20; 34 | disp.screen.h = 256; 35 | printf("PAL System.\n"); 36 | } 37 | 38 | disp.isinter = 1; 39 | draw.isbg = 1; 40 | 41 | PutDispEnv( &disp ); 42 | PutDrawEnv( &draw ); 43 | 44 | ClearOTagR( ot[0], OT_LEN ); 45 | ClearOTagR( ot[1], OT_LEN ); 46 | nextpri = pribuff[0]; 47 | 48 | InitGeom(); 49 | gte_SetGeomScreen( 320 ); 50 | 51 | if( GetVideoMode() == MODE_NTSC ) { 52 | gte_SetGeomOffset( 320, 240 ); 53 | } else { 54 | gte_SetGeomOffset( 320, 256 ); 55 | } 56 | 57 | } 58 | 59 | void display() { 60 | 61 | DrawSync(0); 62 | VSync(0); 63 | 64 | PutDrawEnv( &draw ); 65 | DrawOTag( ot[db]+OT_LEN-1 ); 66 | 67 | db ^= 1; 68 | ClearOTagR( ot[db], OT_LEN ); 69 | nextpri = pribuff[db]; 70 | 71 | SetDispMask( 1 ); 72 | 73 | } -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK examples build script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | PSn00bSDK-examples 8 | LANGUAGES NONE 9 | DESCRIPTION "PSn00bSDK examples" 10 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 11 | ) 12 | 13 | include(GNUInstallDirs) 14 | 15 | # Find all subdirectories that contain a CMake build script. This includes the 16 | # top-level examples directory and this file as well, however we're going to 17 | # skip it. 18 | file( 19 | GLOB_RECURSE _examples 20 | RELATIVE ${PROJECT_SOURCE_DIR} 21 | ${PROJECT_SOURCE_DIR}/CMakeLists.txt 22 | ) 23 | 24 | foreach(_script IN LISTS _examples) 25 | if(_script STREQUAL "CMakeLists.txt") 26 | continue() 27 | endif() 28 | 29 | # CMake provides no way to override the install prefix of a subdirectory, 30 | # as it "imports" its targets into the main project rather than treating it 31 | # as a separate project. However, as the example subdirectories use 32 | # install(... TYPE BIN) to install executables, it is possible to override 33 | # CMAKE_INSTALL_BINDIR temporarily to place them in any directory within 34 | # the install prefix. This is a hack, but it allows us to preserve the 35 | # examples' folder hierarchy in the installation directory (it is already 36 | # preserved by CMake in the build tree!) with minimal effort. 37 | cmake_path(GET _script PARENT_PATH _dir) 38 | cmake_path(GET _dir PARENT_PATH CMAKE_INSTALL_BINDIR) 39 | 40 | add_subdirectory(${PROJECT_SOURCE_DIR}/${_dir}) 41 | endforeach() 42 | -------------------------------------------------------------------------------- /libpsn00b/psxcd/readme.txt: -------------------------------------------------------------------------------- 1 | PSX CD-ROM library, part of PSn00bSDK 2 | 2020-2022 Lameguy64 / Meido-Tek Productions 3 | 4 | Licensed under Mozilla Public License 5 | 6 | Open source implementation of the long awaited CD-ROM library that provides 7 | greater functionality than the BIOS CD-ROM subsystem. Supports pretty much all 8 | features of the CD-ROM hardware such as CD data read, CD Audio and XA audio 9 | playback, with the exception of the St*() APIs for .STR playback (but manual 10 | streaming using CdReadyCallback() is still supported). 11 | 12 | An ISO9660 file system driver for locating files within the CD-ROM is also 13 | included. Unlike the ISO9660 parser in the official libraries, libpsxcd can 14 | parse directories containing any number of files. Currently no ISO9660 15 | extensions are supported. 16 | 17 | Be aware that the CD-ROM library might have some loose ends as it is still a 18 | work in progress, but should work flawlessly in most use cases. 19 | 20 | Library developer(s): 21 | 22 | Lameguy64 (ISO9660 driver, initial implementation of low-level functions) 23 | spicyjpeg (C rewrite) 24 | 25 | Library header(s): 26 | 27 | psxcd.h 28 | 29 | Todo list: 30 | 31 | * Command query mechanism so that more than 2 CD-ROM commands can 32 | easily be issued in callbacks. Official library probably does this. 33 | 34 | * Helper functions for handling disc changes (CdDiskReady and 35 | CdGetDiskType) are not yet implemented. 36 | 37 | * Data streaming functions (prefixed with St*) not yet implemented. 38 | Would require devising a PSn00bSDK equivalent of the STR file 39 | format. 40 | -------------------------------------------------------------------------------- /examples/io/system573/iso.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 16 | 17 | 18 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /libpsn00b/include/stdlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PSn00bSDK standard library 3 | * (C) 2019-2022 PSXSDK authors, Lameguy64, spicyjpeg - MPL licensed 4 | */ 5 | 6 | #ifndef __STDLIB_H 7 | #define __STDLIB_H 8 | 9 | #include 10 | 11 | /* Definitions */ 12 | 13 | #define RAND_MAX 0x7fff 14 | 15 | /* Structure definitions */ 16 | 17 | typedef struct _HeapUsage { 18 | size_t total; // Total size of heap + stack 19 | size_t heap; // Amount of memory currently reserved for heap 20 | size_t stack; // Amount of memory currently reserved for stack 21 | size_t alloc; // Amount of memory currently allocated 22 | size_t alloc_max; // Maximum amount of memory ever allocated 23 | } HeapUsage; 24 | 25 | /* API */ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | extern int __argc; 32 | extern const char **__argv; 33 | 34 | void abort(void); 35 | 36 | int rand(void); 37 | void srand(int seed); 38 | 39 | int abs(int j); 40 | long labs(long i); 41 | 42 | long strtol(const char *nptr, char **endptr, int base); 43 | long long strtoll(const char *nptr, char **endptr, int base); 44 | float strtof(const char *nptr, char **endptr); 45 | double strtod(const char *nptr, char **endptr); 46 | long double strtold(const char *nptr, char **endptr); 47 | 48 | void InitHeap(void *addr, size_t size); 49 | void *sbrk(ptrdiff_t incr); 50 | 51 | void TrackHeapUsage(ptrdiff_t alloc_incr); 52 | void GetHeapUsage(HeapUsage *usage); 53 | 54 | void *malloc(size_t size); 55 | void *calloc(size_t num, size_t size); 56 | void *realloc(void *ptr, size_t size); 57 | void free(void *ptr); 58 | 59 | #ifdef __cplusplus 60 | } 61 | #endif 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /libpsn00b/include/gtereg.inc: -------------------------------------------------------------------------------- 1 | # GTE register definitions for GNU assembler (as). 2 | # 3 | # Part of the PSn00bSDK Project by Lameguy64. 4 | # 2019 Meido-Tek Productions 5 | 6 | # 7 | # GTE data registers (use mfc2, mtc2, lwc2, swc2) 8 | # 9 | .set C2_VXY0, $0 10 | .set C2_VZ0, $1 11 | .set C2_VXY1, $2 12 | .set C2_VZ1, $3 13 | .set C2_VXY2, $4 14 | .set C2_VZ2, $5 15 | .set C2_RGB, $6 16 | .set C2_OTZ, $7 17 | 18 | .set C2_IR0, $8 19 | .set C2_IR1, $9 20 | .set C2_IR2, $10 21 | .set C2_IR3, $11 22 | .set C2_SXY0, $12 23 | .set C2_SXY1, $13 24 | .set C2_SXY2, $14 25 | .set C2_SXYP, $15 26 | 27 | .set C2_SZ0, $16 28 | .set C2_SZ1, $17 29 | .set C2_SZ2, $18 30 | .set C2_SZ3, $19 31 | .set C2_RGB0, $20 32 | .set C2_RGB1, $21 33 | .set C2_RGB2, $22 34 | 35 | .set C2_MAC0, $24 36 | .set C2_MAC1, $25 37 | .set C2_MAC2, $26 38 | .set C2_MAC3, $27 39 | .set C2_IRGB, $28 40 | .set C2_ORGB, $29 41 | .set C2_LZCS, $30 42 | .set C2_LZCR, $31 43 | 44 | # 45 | # GTE control registers (use cfc2/ctc2) 46 | # 47 | .set C2_R11R12, $0 48 | .set C2_R13R21, $1 49 | .set C2_R22R23, $2 50 | .set C2_R31R32, $3 51 | .set C2_R33, $4 52 | .set C2_TRX, $5 53 | .set C2_TRY, $6 54 | .set C2_TRZ, $7 55 | 56 | .set C2_L11L12, $8 57 | .set C2_L13L21, $9 58 | .set C2_L22L23, $10 59 | .set C2_L31L32, $11 60 | .set C2_L33, $12 61 | .set C2_RBK, $13 62 | .set C2_GBK, $14 63 | .set C2_BBK, $15 64 | 65 | .set C2_LR1LR2, $16 66 | .set C2_LR3LG1, $17 67 | .set C2_LG2LG3, $18 68 | .set C2_LB1LB2, $19 69 | .set C2_LB3, $20 70 | .set C2_RFC, $21 71 | .set C2_GFC, $22 72 | .set C2_BFC, $23 73 | 74 | .set C2_OFX, $24 75 | .set C2_OFY, $25 76 | .set C2_H, $26 77 | .set C2_DQA, $27 78 | .set C2_DQB, $28 79 | .set C2_ZSF3, $29 80 | .set C2_ZSF4, $30 81 | .set C2_FLAG, $31 82 | -------------------------------------------------------------------------------- /libpsn00b/lzp/crc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "lzp.h" 3 | 4 | void initTable16(uint16_t *table) { 5 | 6 | int i, j; 7 | uint16_t crc, c; 8 | 9 | for (i=0; i<256; i++) { 10 | 11 | crc = 0; 12 | c = (uint16_t) i; 13 | 14 | for (j=0; j<8; j++) { 15 | 16 | if ( (crc ^ c) & 0x0001 ) 17 | crc = ( crc >> 1 ) ^ 0xA001; 18 | else 19 | crc = crc >> 1; 20 | 21 | c = c >> 1; 22 | } 23 | 24 | table[i] = crc; 25 | } 26 | 27 | } 28 | 29 | void initTable32(uint32_t *table) { 30 | 31 | int i,j; 32 | uint32_t crcVal; 33 | 34 | for(i=0; i<256; i++) { 35 | 36 | crcVal = i; 37 | 38 | for(j=0; j<8; j++) { 39 | 40 | if (crcVal&0x00000001L) 41 | crcVal = (crcVal>>1)^0xEDB88320L; 42 | else 43 | crcVal = crcVal>>1; 44 | 45 | } 46 | 47 | table[i] = crcVal; 48 | 49 | } 50 | 51 | } 52 | 53 | uint16_t lzCRC16(const void* buff, int bytes, uint16_t crc) { 54 | 55 | int i; 56 | uint16_t tmp, short_c; 57 | uint16_t crcTable[256]; 58 | 59 | initTable16(crcTable); 60 | 61 | for(i=0; i> 8) ^ crcTable[tmp&0xff]; 67 | 68 | } 69 | 70 | return(crc); 71 | 72 | } 73 | 74 | uint32_t lzCRC32(const void* buff, int bytes, uint32_t crc) { 75 | 76 | int i; 77 | const uint8_t *byteBuff = (const uint8_t *)buff; 78 | uint32_t byte; 79 | uint32_t crcTable[256]; 80 | 81 | initTable32(crcTable); 82 | 83 | for(i=0; i>8)^crcTable[(crc^byte)&0xff]; 87 | 88 | } 89 | 90 | return(crc^0xFFFFFFFF); 91 | 92 | } 93 | -------------------------------------------------------------------------------- /libpsn00b/psxetc/_dl_resolve_wrapper.s: -------------------------------------------------------------------------------- 1 | # PSn00bSDK dynamic linker 2 | # (C) 2021-2022 spicyjpeg - MPL licensed 3 | # 4 | # This function is called by the lazy loader stubs generated by GCC in the 5 | # .plt/.MIPS.stubs section when attempting to call a GOT entry whose address 6 | # hasn't yet been resolved. The generated stubs conform to the MIPS ABI and 7 | # uses the following registers: 8 | # - $t7 = address the resolved function should return to (i.e. $ra of the 9 | # caller that triggered the stub) 10 | # - $t8 = index of the function in the .dynsym symbol table 11 | # - $t9 = _dl_resolve_wrapper itself's address 12 | 13 | .set noreorder 14 | 15 | .section .text._dl_resolve_wrapper 16 | .global _dl_resolve_wrapper 17 | .type _dl_resolve_wrapper, @function 18 | _dl_resolve_wrapper: 19 | # Save the arguments being passed to the function to be resolved. 20 | addiu $sp, -20 21 | sw $a0, 0($sp) 22 | sw $a1, 4($sp) 23 | sw $a2, 8($sp) 24 | sw $a3, 12($sp) 25 | sw $t7, 16($sp) # (will be restored directly to $ra) 26 | 27 | # Figure out where the DLL's struct is. dlinit() places a pointer to the 28 | # struct in the second GOT entry, so it's just a matter of indexing the GOT 29 | # using $gp. Then call _dl_resolve_helper with the struct and $t8 as 30 | # arguments, and store the return value into $t0. 31 | lw $a0, -0x7fec($gp) # dll = &((uint32_t *) (gp - 0x7ff0))[1] 32 | move $a1, $t8 33 | 34 | jal _dl_resolve_helper 35 | addiu $sp, -8 36 | addiu $sp, 8 37 | 38 | # Restore the arguments from the stack and tail-call the function at the 39 | # address returned by the resolver. 40 | lw $a0, 0($sp) 41 | lw $a1, 4($sp) 42 | lw $a2, 8($sp) 43 | lw $a3, 12($sp) 44 | lw $ra, 16($sp) 45 | 46 | jr $v0 47 | addiu $sp, 20 48 | -------------------------------------------------------------------------------- /cpack/convert_images.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This script generates Windows bitmaps from the SVGs in this directory. The 3 | # bitmaps are displayed by the NSIS installers generated using CPack. Inkscape 4 | # and ImageMagick must be installed for this script to work. 5 | 6 | INDEXED_SIZES=(16 24 32 48) 7 | RGB_ONLY_SIZES=(64 96 128 256) 8 | DITHER_OPTIONS="-dither riemersma" 9 | OUTPUT_OPTIONS="+compress -strip" 10 | 11 | svg_to_bitmap() { 12 | inkscape -z -e rgb.png $1 13 | 14 | # There seems to be no way to tell ImageMagick to generate an 8-bit indexed 15 | # BMP directly, so the image has to be converted to indexed PNG first. NSIS 16 | # seems to reject all BMP versions other than "bmp3". 17 | convert $DITHER_OPTIONS -colors 256 +remap rgb.png png8:i8.png 18 | convert i8.png $OUTPUT_OPTIONS bmp3:$2 19 | rm -f rgb.png i8.png 20 | } 21 | 22 | # https://stackoverflow.com/a/52636645 23 | svg_to_icon() { 24 | for size in ${INDEXED_SIZES[@]} ${RGB_ONLY_SIZES[@]}; do 25 | inkscape -z -e $size.png -w $size -h $size $1 26 | done 27 | 28 | # Windows expects some of the smaller sizes to be available in 4- and 8-bit 29 | # indexed color formats, as well as RGB. 30 | for size in ${INDEXED_SIZES[@]}; do 31 | convert $DITHER_OPTIONS -colors 256 +remap $size.png png8:$size-i8.png 32 | convert $DITHER_OPTIONS -colors 16 +remap $size.png png8:$size-i4.png 33 | done 34 | 35 | icons="${INDEXED_SIZES[@]/%/.png} ${INDEXED_SIZES[@]/%/-i8.png} ${INDEXED_SIZES[@]/%/-i4.png} ${RGB_ONLY_SIZES[@]/%/.png}" 36 | convert $icons $OUTPUT_OPTIONS $2 37 | rm -f $icons 38 | } 39 | 40 | rm -f *.ico *.bmp 41 | 42 | svg_to_icon icon.svg icon.ico 43 | svg_to_icon uninstall.svg uninstall.ico 44 | svg_to_bitmap nsis_banner.svg nsis_banner.bmp 45 | svg_to_bitmap nsis_header.svg nsis_header.bmp 46 | -------------------------------------------------------------------------------- /cpack/description.txt: -------------------------------------------------------------------------------- 1 | PSn00bSDK is a 100% free and open source SDK project for the original Sony 2 | PlayStation for developing homebrew applications and games for the console 3 | 100% freely. This SDK can be used for freeware, commercial, and open source 4 | homebrew projects. 5 | 6 | The SDK is composed mainly of libraries (libpsn00b) and some utilities that 7 | provide a basic framework for developing software for the PlayStation 8 | hardware, the compiler is separate (GCC) and should be acquired from GNU. 9 | The library API is intentionally written to resemble the library API of the 10 | official libraries as closely as possible. This design decision is not only 11 | for familiarity reasons to experienced programmers, but also so that existing 12 | sample code and tutorials would still apply to this SDK, as well as making 13 | the process of porting over existing homebrew originally made with official 14 | SDKs easier with minimal modification, provided it doesn't use libgs. 15 | 16 | PSn00bSDK is currently a work in progress and cannot really be considered 17 | production ready, but what is currently implemented should be enough to 18 | produce some interesting homebrew with the SDK, especially with its extensive 19 | support for the GPU and GTE hardware. There's no reason not to fully support 20 | hardware features of a target platform when said hardware features have been 21 | fully documented for years (nocash's PSX specs document in this case). 22 | 23 | Most of libpsn00b is written mostly in MIPS assembly, moreso functions that 24 | interface with the hardware. Many of the standard C functions are implemented 25 | in custom MIPS assembly instead of equivalents found in the BIOS ROM, for both 26 | stability (the BIOS libc implementation of the PlayStation is actually buggy) 27 | and performance reasons. 28 | -------------------------------------------------------------------------------- /examples/demos/n00bdemo/data.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ${DATA_DIR}/petscum16c.tim 6 | ${DATA_DIR}/bungirl.tim 7 | 8 | 9 | ${DATA_DIR}/clktower.tim 10 | ${DATA_DIR}/riftbld1.tim 11 | ${DATA_DIR}/riftbld2.tim 12 | ${DATA_DIR}/hatkid.tim 13 | 14 | ${DATA_DIR}/celmapi.tim 15 | 16 | ${DATA_DIR}/lamelotl16c.tim 17 | ${DATA_DIR}/n00blogo-pixel.tim 18 | ${DATA_DIR}/font.tim 19 | 20 | 21 | 22 | 23 | 24 | 25 | ${DATA_DIR}/mtekdisk.smd 26 | ${DATA_DIR}/mtektext.smd 27 | ${DATA_DIR}/star.smd 28 | ${DATA_DIR}/psn00blogo.smd 29 | ${DATA_DIR}/logo.smd 30 | 31 | 32 | ${DATA_DIR}/petscum.smd 33 | ${DATA_DIR}/bulb.smd 34 | 35 | 36 | ${DATA_DIR}/bungirl.smd 37 | 38 | ${DATA_DIR}/star_mask.smd 39 | ${DATA_DIR}/timerift.smd 40 | ${DATA_DIR}/rbowshade.smd 41 | 42 | ${DATA_DIR}/hatkid.smd 43 | 44 | 45 | textures.qlp 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /tools/lzpack/filelist.cpp: -------------------------------------------------------------------------------- 1 | #include "filelist.h" 2 | 3 | FileListClass::FileListClass() { 4 | 5 | NumFiles = 0; 6 | AllocFiles = 1; 7 | 8 | FileList = (FileListEntry*)malloc(sizeof(FileListEntry)); 9 | memset(FileList, 0x00, sizeof(FileListEntry)); 10 | 11 | } 12 | 13 | FileListClass::~FileListClass() { 14 | 15 | for(int i=NumFiles-1; i>=0; i--) { 16 | 17 | if (FileList[i].fileName != NULL) 18 | free(FileList[i].fileName); 19 | 20 | if (FileList[i].aliasName != NULL) 21 | free(FileList[i].aliasName); 22 | 23 | } 24 | 25 | free(FileList); 26 | 27 | } 28 | 29 | void FileListClass::AddFileEntry(const char* fileName, const char* aliasName, short windowSize, short hash1Size, short hash2Size) { 30 | 31 | if (NumFiles >= AllocFiles) { 32 | 33 | FileList = (FileListEntry*)realloc(FileList, sizeof(FileListEntry)*(AllocFiles+1)); 34 | memset(&FileList[AllocFiles], 0x00, sizeof(FileListEntry)); 35 | 36 | AllocFiles++; 37 | 38 | } 39 | 40 | if (aliasName == NULL) 41 | FileList[NumFiles].aliasName = NULL; 42 | else 43 | FileList[NumFiles].aliasName = strdup(aliasName); 44 | 45 | FileList[NumFiles].fileName = strdup(fileName); 46 | FileList[NumFiles].windowSize = windowSize; 47 | FileList[NumFiles].hash1Size = hash1Size; 48 | FileList[NumFiles].hash2Size = hash2Size; 49 | NumFiles++; 50 | 51 | } 52 | 53 | const FileListEntry* FileListClass::Entry(int index) { 54 | 55 | return(&FileList[index]); 56 | 57 | } 58 | 59 | int FileListClass::EntryCount() { 60 | 61 | return(NumFiles); 62 | 63 | } 64 | 65 | void FileListClass::PrintEntries() { 66 | 67 | for(int i=0; i 7 | #include 8 | #include 9 | 10 | #include "k573io.h" 11 | 12 | uint32_t K573_GetJAMMAInputs(void) { 13 | uint32_t inputs; 14 | 15 | inputs = K573_JAMMA_IN; 16 | inputs |= ((K573_EXT_IN_P1 >> 8) & 0x0f) << 16; 17 | inputs |= ((K573_EXT_IN_P2 >> 8) & 0x0f) << 20; 18 | inputs |= ((K573_MISC_IN >> 8) & 0x1f) << 24; 19 | inputs |= (K573_DIP_CART_IN & 0x07) << 29; 20 | 21 | return ~inputs; 22 | } 23 | 24 | void K573_SetAnalogLights(uint32_t lights) { 25 | uint32_t bits = 0xffffffff; 26 | 27 | bits ^= (lights & 0x00010101) << 7; // Bit 0 -> bit 7 28 | bits ^= (lights & 0x00020202) >> 1; // Bit 1 -> bit 0 29 | bits ^= (lights & 0x00040404) << 4; // Bit 2 -> bit 6 30 | bits ^= (lights & 0x00080808) >> 2; // Bit 3 -> bit 1 31 | bits ^= (lights & 0x00101010) << 1; // Bit 4 -> bit 5 32 | bits ^= (lights & 0x00202020) >> 3; // Bit 5 -> bit 2 33 | bits ^= (lights & 0x00404040) >> 2; // Bit 6 -> bit 4 34 | bits ^= (lights & 0x00808080) >> 4; // Bit 7 -> bit 3 35 | bits ^= (lights & 0x0f000000) >> 24; 36 | 37 | K573_IO_BOARD[ANALOG_IO_REG_LIGHTS_A] = (bits) & 0xff; 38 | K573_IO_BOARD[ANALOG_IO_REG_LIGHTS_B] = (bits >> 8) & 0xff; 39 | K573_IO_BOARD[ANALOG_IO_REG_LIGHTS_C] = (bits >> 16) & 0xff; 40 | K573_IO_BOARD[ANALOG_IO_REG_LIGHTS_D] = (bits >> 24) & 0xff; 41 | } 42 | 43 | void K573_Init(void) { 44 | BUS_EXP1_ADDR = 0x1f000000; 45 | BUS_EXP1_CFG = 0x24173f47; // 573 BIOS uses this value 46 | 47 | // Bit 6 of this register controls the audio DAC and must be set, otherwise 48 | // no sound will be output. Most of the other bits are data clocks/strobes 49 | // and should be pulled high when not in use. 50 | K573_MISC_OUT = 51 | MISC_OUT_ADC_MOSI | MISC_OUT_ADC_CS | MISC_OUT_ADC_SCK | 52 | MISC_OUT_CDDA_ENABLE | MISC_OUT_SPU_ENABLE | MISC_OUT_MCU_CLOCK; 53 | 54 | K573_RESET_WATCHDOG(); 55 | } 56 | -------------------------------------------------------------------------------- /examples/io/pads/spi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PSn00bSDK controller polling example (SPI driver) 3 | * (C) 2021 spicyjpeg - MPL licensed 4 | */ 5 | 6 | #ifndef __SPI_H 7 | #define __SPI_H 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | // Maximum request/response length (34 bytes for pads, 140 for memory cards). 14 | // Must be a multiple of 4 to avoid memory alignment issues. 15 | //#define SPI_BUFF_LEN 36 16 | #define SPI_BUFF_LEN 140 17 | 18 | /* Request structures */ 19 | 20 | typedef void (*SPI_Callback)(uint32_t port, const volatile uint8_t *buff, size_t rx_len); 21 | 22 | typedef struct _SPI_Request { 23 | union { 24 | uint8_t data[SPI_BUFF_LEN]; 25 | PadRequest pad_req; 26 | MemCardRequest mcd_req; 27 | }; 28 | uint32_t len, port; 29 | SPI_Callback callback; 30 | struct _SPI_Request *next; 31 | } SPI_Request; 32 | 33 | /* Public API */ 34 | 35 | #ifdef __cplusplus 36 | extern "C" { 37 | #endif 38 | 39 | /** 40 | * @brief Allocates a new request object and adds it to the request queue. The 41 | * object must be populated afterwards by setting the length, callback and 42 | * filling in the TX data buffer. 43 | */ 44 | SPI_Request *SPI_CreateRequest(void); 45 | 46 | /** 47 | * @brief Changes the controller polling rate. The lowest supported rate is 65 48 | * Hz (requests sent every 1/65th of a second, each port polled at 32.5 Hz when 49 | * no request is pending). 50 | * 51 | * @param value 52 | */ 53 | void SPI_SetPollRate(uint32_t value); 54 | 55 | /** 56 | * @brief Installs the SPI and timer 2 interrupt handlers and starts the poll 57 | * timer. By default the polling rate is set to 250 Hz (125 Hz per port), 58 | * however it can be changed at any time by calling SPI_SetPollRate(). 59 | * 60 | * The provided callback (if any) is called to report the result of poll 61 | * requests, which are issued automatically when no other request is in the 62 | * queue. Passing NULL as callback does not disable auto-polling. 63 | * 64 | * @param callback 65 | */ 66 | void SPI_Init(SPI_Callback callback); 67 | 68 | #ifdef __cplusplus 69 | } 70 | #endif 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /libpsn00b/psxpress/README.md: -------------------------------------------------------------------------------- 1 | 2 | # PSn00bSDK MDEC library 3 | 4 | This is a fully open source reimplementation of the official SDK's "data 5 | compression" library. This library is made up of two parts, the MDEC API and 6 | functions to decompress Huffman-encoded bitstreams (.BS files, or frames in 7 | .STR files) into data to be fed to the MDEC. FMV playback is not part of this 8 | library (nor the official one) per se, but can implemented by using these APIs 9 | alongside some code to stream data from the CD drive. 10 | 11 | **Currently only version 1 and 2 bitstreams are supported**. 12 | 13 | ## MDEC API 14 | 15 | The MDEC data input/output API is almost identical to the official one, with 16 | only two minor differences: 17 | 18 | - `DecDCTPutEnv()` takes a second argument specifying whether the MDEC shall be 19 | put into monochrome or color mode (the original API only supported color). 20 | - A `DecDCTinRaw()` function was added for easier feeding of headerless data 21 | buffers to the MDEC. This function does not affect how `DecDCTin()` works. 22 | 23 | ## Decompression API 24 | 25 | The following functions are currently provided: 26 | 27 | - `DecDCTvlcStart()`, `DecDCTvlcContinue()`: a decompressor implementation that 28 | uses a small (<1 KB) lookup table and leverages the GTE, written in assembly. 29 | `DecDCTvlcCopyTable()` can optionally be called to temporarily move the table 30 | to the scratchpad region to improve decompression speed. 31 | - `DecDCTvlcStart2()`, `DecDCTvlcContinue2()`: a different implementation using 32 | a large (34 KB) lookup table in main RAM, written in C. The table must be 33 | decompressed ahead of time using `DecDCTvlcBuild()`, but can be deallocated 34 | when no longer needed. 35 | - `DecDCTvlc()`, `DecDCTvlc2()`: wrappers around the functions listed above, 36 | for compatibility with the Sony SDK. Using them is not recommended. 37 | 38 | ## SPU ADPCM encoding API 39 | 40 | The Sony library has functions that can be used to convert raw 16-bit PCM audio 41 | data to SPU ADPCM. These are currently unimplemented due to their limited 42 | usefulness, but might be added at some point. 43 | -------------------------------------------------------------------------------- /tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PSn00bSDK tools build script 2 | # (C) 2021 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | project( 7 | PSn00bSDK-tools 8 | LANGUAGES C CXX 9 | DESCRIPTION "PSn00bSDK command-line tools" 10 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 11 | ) 12 | 13 | include(GNUInstallDirs) 14 | 15 | set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") 16 | set(CMAKE_C_STANDARD 11) 17 | set(CMAKE_CXX_STANDARD 17) 18 | 19 | ## Dependencies 20 | 21 | if(NOT EXISTS ${PROJECT_SOURCE_DIR}/tinyxml2/tinyxml2.cpp) 22 | message(FATAL_ERROR "The tinyxml2 directory is empty. Run 'git submodule update --init --recursive' to populate it.") 23 | endif() 24 | 25 | # Build tinyxml2. I didn't bother with tinyxml2's actual CMake integration 26 | # because it's far easier do do this. It is a single-file library after all. 27 | add_library (tinyxml2 STATIC tinyxml2/tinyxml2.cpp) 28 | target_include_directories(tinyxml2 PUBLIC tinyxml2) 29 | 30 | #add_subdirectory(tinyxml2) 31 | 32 | # Build liblzp using sources from the libpsn00b tree. Hacky but it works. 33 | set(LIBPSN00B_PATH ${PROJECT_SOURCE_DIR}/../libpsn00b) 34 | file( 35 | GLOB _sources 36 | ${LIBPSN00B_PATH}/lzp/*.c 37 | #${LIBPSN00B_PATH}/lzp/*.cpp 38 | ) 39 | 40 | add_library(lzp STATIC ${_sources}) 41 | target_include_directories( 42 | lzp PUBLIC 43 | lzpack/lzp 44 | ${LIBPSN00B_PATH}/include/lzp 45 | ) 46 | 47 | ## Executables 48 | 49 | add_executable(elf2x util/elf2x.c) 50 | add_executable(elf2cpe util/elf2cpe.c) 51 | add_executable(smxlink smxlink/main.cpp smxlink/timreader.cpp) 52 | add_executable(lzpack lzpack/main.cpp lzpack/filelist.cpp) 53 | target_link_libraries(smxlink tinyxml2) 54 | target_link_libraries(lzpack tinyxml2 lzp) 55 | 56 | ## Installation 57 | 58 | # Install the executables and copy the Blender SMX export plugin to the data 59 | # directory (for manual installation). 60 | install(TARGETS elf2x elf2cpe smxlink lzpack) 61 | install( 62 | DIRECTORY plugin 63 | DESTINATION ${CMAKE_INSTALL_DATADIR}/psn00bsdk 64 | ) 65 | 66 | include(InstallRequiredSystemLibraries) 67 | -------------------------------------------------------------------------------- /doc/known_bugs.md: -------------------------------------------------------------------------------- 1 | 2 | # Known PSn00bSDK bugs 3 | 4 | This is an incomplete list of things that are known to be currently broken (or 5 | not behaving as they should, or untested on real hardware) and haven't yet been 6 | fixed. 7 | 8 | ## Toolchain 9 | 10 | - ~~It is currently not possible to link static libraries (including the SDK~~ 11 | ~~libraries themselves) with DLLs, since the build scripts currently assume~~ 12 | ~~that static library object files are always going to be linked into~~ 13 | ~~executables. This can be worked around by linking all static libraries as~~ 14 | ~~part of the main executable rather than the DLLs: the dynamic linker will~~ 15 | ~~automatically search the executable for undefined symbols used by a DLL~~ 16 | ~~and patch the code to use them.~~ Static libraries are now fully supported, 17 | and SDK libraries can be linked to both executables and DLLs. See the CMake 18 | reference for more details. 19 | 20 | - Link-time optimization is broken due to GCC not supporting it when linking 21 | weak functions written in assembly. 22 | 23 | ## Libraries 24 | 25 | `psxgpu`: 26 | 27 | - `LoadImage()` and `StoreImage()` use DMA to transfer data to/from the GPU. 28 | As the DMA channel is configured to transfer 8 words (32 bytes) at a time, 29 | the length of the data *must* be a multiple of 32 bytes. Attempting to 30 | transfer any data whose length isn't a multiple of 32 bytes will result in 31 | `DrawSync()` hanging and never returning, however a warning will be printed 32 | on the debug console if the executable is built in debug mode. 33 | 34 | `psxspu`: 35 | 36 | - `SpuInit()`, `SpuRead()` and `SpuWrite()` may take several seconds on MAME 37 | due to the SPU status register being emulated incorrectly. They work as 38 | expected on other emulators as well as on real hardware. 39 | 40 | `psxcd`: 41 | 42 | - The library seems to get into an unpredictable state when removing discs on 43 | pcsx-redux (and possibly real hardware?). 44 | 45 | ## Examples 46 | 47 | See [README.md in the examples directory](../examples/README.md#examples-summary). 48 | 49 | ----------------------------------------- 50 | _Last updated on 2022-12-18 by spicyjpeg_ 51 | -------------------------------------------------------------------------------- /libpsn00b/psxapi/stdio.s: -------------------------------------------------------------------------------- 1 | # PSn00bSDK BIOS API stubs 2 | # (C) 2022 spicyjpeg - MPL licensed 3 | 4 | # This file has been generated automatically. Each function is placed in its 5 | # own section to allow the linker to strip unused functions. 6 | 7 | .set noreorder 8 | 9 | ## A0 table functions (13) 10 | 11 | .section .text.open 12 | .global open 13 | .type open, @function 14 | open: 15 | li $t2, 0xa0 16 | jr $t2 17 | li $t1, 0x00 18 | 19 | .section .text.seek 20 | .global seek 21 | .type seek, @function 22 | seek: 23 | li $t2, 0xa0 24 | jr $t2 25 | li $t1, 0x01 26 | 27 | .section .text.read 28 | .global read 29 | .type read, @function 30 | read: 31 | li $t2, 0xa0 32 | jr $t2 33 | li $t1, 0x02 34 | 35 | .section .text.write 36 | .global write 37 | .type write, @function 38 | write: 39 | li $t2, 0xa0 40 | jr $t2 41 | li $t1, 0x03 42 | 43 | .section .text.close 44 | .global close 45 | .type close, @function 46 | close: 47 | li $t2, 0xa0 48 | jr $t2 49 | li $t1, 0x04 50 | 51 | .section .text.ioctl 52 | .global ioctl 53 | .type ioctl, @function 54 | ioctl: 55 | li $t2, 0xa0 56 | jr $t2 57 | li $t1, 0x05 58 | 59 | .section .text.getc 60 | .global getc 61 | .type getc, @function 62 | getc: 63 | li $t2, 0xa0 64 | jr $t2 65 | li $t1, 0x08 66 | 67 | .section .text.putc 68 | .global putc 69 | .type putc, @function 70 | putc: 71 | li $t2, 0xa0 72 | jr $t2 73 | li $t1, 0x09 74 | 75 | .section .text.getchar 76 | .global getchar 77 | .type getchar, @function 78 | getchar: 79 | li $t2, 0xa0 80 | jr $t2 81 | li $t1, 0x3b 82 | 83 | .section .text.putchar 84 | .global putchar 85 | .type putchar, @function 86 | putchar: 87 | li $t2, 0xa0 88 | jr $t2 89 | li $t1, 0x3c 90 | 91 | .section .text.gets 92 | .global gets 93 | .type gets, @function 94 | gets: 95 | li $t2, 0xa0 96 | jr $t2 97 | li $t1, 0x3d 98 | 99 | .section .text.puts 100 | .global puts 101 | .type puts, @function 102 | puts: 103 | li $t2, 0xa0 104 | jr $t2 105 | li $t1, 0x3e 106 | 107 | .section .text.printf 108 | .global printf 109 | .type printf, @function 110 | printf: 111 | li $t2, 0xa0 112 | jr $t2 113 | li $t1, 0x3f 114 | 115 | -------------------------------------------------------------------------------- /libpsn00b/psxgte/matrix.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | MATRIX *RotMatrix(SVECTOR *r, MATRIX *m) { 4 | short s[3],c[3]; 5 | MATRIX tm[3]; 6 | 7 | s[0] = isin(r->vx); s[1] = isin(r->vy); s[2] = isin(r->vz); 8 | c[0] = icos(r->vx); c[1] = icos(r->vy); c[2] = icos(r->vz); 9 | 10 | // mX 11 | m->m[0][0] = ONE; m->m[0][1] = 0; m->m[0][2] = 0; 12 | m->m[1][0] = 0; m->m[1][1] = c[0]; m->m[1][2] = -s[0]; 13 | m->m[2][0] = 0; m->m[2][1] = s[0]; m->m[2][2] = c[0]; 14 | 15 | // mY 16 | tm[0].m[0][0] = c[1]; tm[0].m[0][1] = 0; tm[0].m[0][2] = s[1]; 17 | tm[0].m[1][0] = 0; tm[0].m[1][1] = ONE; tm[0].m[1][2] = 0; 18 | tm[0].m[2][0] = -s[1]; tm[0].m[2][1] = 0; tm[0].m[2][2] = c[1]; 19 | 20 | // mZ 21 | tm[1].m[0][0] = c[2]; tm[1].m[0][1] = -s[2]; tm[1].m[0][2] = 0; 22 | tm[1].m[1][0] = s[2]; tm[1].m[1][1] = c[2]; tm[1].m[1][2] = 0; 23 | tm[1].m[2][0] = 0; tm[1].m[2][1] = 0; tm[1].m[2][2] = ONE; 24 | 25 | PushMatrix(); 26 | MulMatrix0( m, &tm[0], &tm[2] ); 27 | MulMatrix0( &tm[2], &tm[1], m ); 28 | PopMatrix(); 29 | 30 | return m; 31 | } 32 | 33 | MATRIX *HiRotMatrix(VECTOR *r, MATRIX *m) { 34 | short s[3],c[3]; 35 | MATRIX tm[3]; 36 | 37 | s[0] = hisin(r->vx); s[1] = hisin(r->vy); s[2] = hisin(r->vz); 38 | c[0] = hicos(r->vx); c[1] = hicos(r->vy); c[2] = hicos(r->vz); 39 | 40 | // mX 41 | m->m[0][0] = ONE; m->m[0][1] = 0; m->m[0][2] = 0; 42 | m->m[1][0] = 0; m->m[1][1] = c[0]; m->m[1][2] = -s[0]; 43 | m->m[2][0] = 0; m->m[2][1] = s[0]; m->m[2][2] = c[0]; 44 | 45 | // mY 46 | tm[0].m[0][0] = c[1]; tm[0].m[0][1] = 0; tm[0].m[0][2] = s[1]; 47 | tm[0].m[1][0] = 0; tm[0].m[1][1] = ONE; tm[0].m[1][2] = 0; 48 | tm[0].m[2][0] = -s[1]; tm[0].m[2][1] = 0; tm[0].m[2][2] = c[1]; 49 | 50 | // mZ 51 | tm[1].m[0][0] = c[2]; tm[1].m[0][1] = -s[2]; tm[1].m[0][2] = 0; 52 | tm[1].m[1][0] = s[2]; tm[1].m[1][1] = c[2]; tm[1].m[1][2] = 0; 53 | tm[1].m[2][0] = 0; tm[1].m[2][1] = 0; tm[1].m[2][2] = ONE; 54 | 55 | PushMatrix(); 56 | MulMatrix0( m, &tm[0], &tm[2] ); 57 | MulMatrix0( &tm[2], &tm[1], m ); 58 | PopMatrix(); 59 | 60 | return m; 61 | } 62 | 63 | MATRIX *TransMatrix(MATRIX *m, VECTOR *r) { 64 | m->t[0] = r->vx; 65 | m->t[1] = r->vy; 66 | m->t[2] = r->vz; 67 | 68 | return m; 69 | } 70 | -------------------------------------------------------------------------------- /examples/lowlevel/cartrom/parse.inc: -------------------------------------------------------------------------------- 1 | # Skips spaces and equal signs (used by CNF parser) 2 | skipspace: 3 | # a0 - Input string 4 | # Return: v0 - Address to first non-space character. 5 | lbu $v1, 0($a0) 6 | nop 7 | beq $v1, ' ', .skip 8 | nop 9 | beq $v1, '=', .skip 10 | nop 11 | jr $ra 12 | move $v0, $a0 13 | .skip: 14 | b skipspace 15 | addiu $a0, 1 16 | 17 | 18 | # Copies a string until a CR/LF or space is encountered 19 | getline: 20 | # a0 - Output address 21 | # a1 - String to copy from 22 | lbu $v0, 0($a1) 23 | addiu $a1, 1 24 | beqz $v0, .end 25 | nop 26 | beq $v0, 0x0D, .end 27 | nop 28 | beq $v0, 0x0A, .end 29 | nop 30 | beq $v0, ' ', .end 31 | nop 32 | sb $v0, 0($a0) 33 | b getline 34 | addiu $a0, 1 35 | .end: 36 | jr $ra 37 | sb $0, 0($a0) 38 | 39 | 40 | # strcasestr implementation 41 | strcasestr: 42 | # a0 - String to search 43 | # a1 - String to find 44 | addiu $sp, -24 45 | sw $ra, 0($sp) 46 | sw $s0, 4($sp) 47 | sw $s1, 8($sp) 48 | sw $a1, 16($sp) 49 | 50 | .scan_start: 51 | 52 | sw $a0, 12($sp) 53 | 54 | .comp_loop: 55 | 56 | lbu $s0, 0($a0) # Load character from A and B 57 | lbu $s1, 0($a1) 58 | 59 | beqz $s0, .end_strcasestr 60 | nop 61 | beqz $s1, .found 62 | nop 63 | 64 | sw $a0, 20($sp) # Save a0 parameter 65 | 66 | jal toupper # tolower character A 67 | move $a0, $s0 68 | move $s0, $v0 69 | 70 | jal toupper # tolower character B 71 | move $a0, $s1 72 | move $s1, $v0 73 | 74 | lw $a0, 20($sp) # Restore a0 parameter 75 | 76 | addiu $a1, 1 77 | addiu $a0, 1 78 | 79 | beq $s0, $s1, .comp_loop # If value matches continue compare 80 | nop 81 | 82 | .end_strcasestr: 83 | 84 | lw $a0, 12($sp) # Rescan from next character of string A 85 | lw $a1, 16($sp) 86 | addiu $a0, 1 87 | 88 | lbu $v0, 0($a0) 89 | nop 90 | beqz $v0, .not_found # If terminator is reached, string is not found 91 | nop 92 | 93 | b .scan_start 94 | nop 95 | 96 | .not_found: 97 | 98 | b .quit 99 | move $v0, $0 100 | 101 | .found: 102 | 103 | lw $v0, 12($sp) # Return address of string match 104 | 105 | .quit: 106 | 107 | lw $ra, 0($sp) 108 | lw $s0, 4($sp) 109 | lw $s1, 8($sp) 110 | jr $ra 111 | addiu $sp, 24 112 | 113 | 114 | -------------------------------------------------------------------------------- /libpsn00b/lzp/lzp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "lzp.h" 7 | 8 | 9 | static char* lcase(char* text) { 10 | 11 | int i; 12 | 13 | for(i=0; text[i]!=0x00; i++) 14 | text[i] = tolower(text[i]); 15 | 16 | return(text); 17 | 18 | } 19 | 20 | 21 | int lzpSearchFile(const char* fileName, const LZP_HEAD* lzpack) { 22 | 23 | int i; 24 | char searchName[16]; 25 | char compareName[16]; 26 | LZP_FILE* fileEntry; 27 | 28 | strcpy(searchName, fileName); 29 | lcase(searchName); 30 | 31 | fileEntry = (LZP_FILE*)(((const char*)lzpack)+sizeof(LZP_HEAD)); 32 | for(i=0; i<(lzpack->numFiles); i++) { 33 | 34 | strcpy(compareName, fileEntry[i].fileName); 35 | lcase(compareName); 36 | 37 | if (strcmp(searchName, compareName) == 0) 38 | return(i); 39 | 40 | } 41 | 42 | return(LZP_ERR_NOTFOUND); 43 | 44 | } 45 | 46 | const LZP_FILE* lzpFileEntry(const LZP_HEAD* lzpack, int fileNum) { 47 | 48 | if (strncmp("LZP", lzpack->id, 3) != 0) 49 | return(NULL); 50 | 51 | if ((fileNum < 0) || (fileNum > (lzpack->numFiles-1))) 52 | return(NULL); 53 | 54 | return &((LZP_FILE*)(((const char*)lzpack)+sizeof(LZP_HEAD)))[fileNum]; 55 | 56 | } 57 | 58 | int lzpFileSize(const LZP_HEAD* lzpack, int fileNum) { 59 | 60 | if (strncmp("LZP", lzpack->id, 3) != 0) 61 | return 0; 62 | 63 | if ((fileNum < 0) || (fileNum > (lzpack->numFiles-1))) 64 | return 0; 65 | 66 | return ((LZP_FILE*)(((const char*)lzpack)+sizeof(LZP_HEAD)))[fileNum].fileSize; 67 | } 68 | 69 | int lzpUnpackFile(void* buff, const LZP_HEAD* lzpack, int fileNum) { 70 | 71 | LZP_FILE* fileEntry = &((LZP_FILE*)(((const char*)lzpack)+sizeof(LZP_HEAD)))[fileNum]; 72 | int unpackedSize; 73 | 74 | // Check ID header 75 | if (strncmp("LZP", lzpack->id, 3) != 0) 76 | return(LZP_ERR_INVALID_PACK); 77 | 78 | // Do a CRC16 check of the compressed data's integrity 79 | if (lzCRC32(((const char*)lzpack)+fileEntry->offset, fileEntry->packedSize, LZP_CRC32_REMAINDER) != fileEntry->crc) 80 | return(LZP_ERR_CRC_MISMATCH); 81 | 82 | // Decompress data to the specified address 83 | unpackedSize = lzDecompress(buff, ((const char*)lzpack)+fileEntry->offset, fileEntry->packedSize); 84 | if (unpackedSize < 0) 85 | return(unpackedSize); 86 | 87 | return(unpackedSize); 88 | 89 | } 90 | -------------------------------------------------------------------------------- /examples/demos/n00bdemo/smdparser.s: -------------------------------------------------------------------------------- 1 | .set noreorder 2 | 3 | .include "smd_s.h" 4 | 5 | .set SMD_PRI_ID, 0 6 | .set SMD_PRI_v0, 4 7 | .set SMD_PRI_v1, 6 8 | .set SMD_PRI_v2, 8 9 | .set SMD_PRI_v3, 10 10 | .set SMD_PRI_n0, 12 11 | .set SMD_PRI_n1, 14 12 | .set SMD_PRI_n2, 16 13 | .set SMD_PRI_n3, 18 14 | .set SMD_PRI_rgbc0, 20 15 | .set SMD_PRI_rgbc1, 24 16 | .set SMD_PRI_rgbc2, 28 17 | .set SMD_PRI_rgbc3, 32 18 | .set SMD_PRI_tuv0, 36 19 | .set SMD_PRI_tuv1, 38 20 | .set SMD_PRI_tuv2, 40 21 | .set SMD_PRI_tuv3, 42 22 | .set SMD_PRI_tpage, 44 23 | .set SMD_PRI_clut, 46 24 | 25 | .section .text 26 | 27 | 28 | .comm _smd_parse_addr, 4, 4 29 | 30 | 31 | .global OpenSMD 32 | .type OpenSMD, @function 33 | OpenSMD: 34 | lw $v0, SMD_HEAD_ID($a0) 35 | li $v1, 0x01444d53 36 | 37 | bne $v0, $v1, .not_smd 38 | nop 39 | 40 | lw $v0, SMD_HEAD_PPRIMS($a0) 41 | la $v1, _smd_parse_addr 42 | sw $v0, 0($v1) 43 | 44 | jr $ra 45 | lhu $v0, SMD_HEAD_NPRIMS($a0) 46 | 47 | .not_smd: 48 | jr $ra 49 | move $v0, $0 50 | 51 | 52 | .global ReadSMD 53 | .type ReadSMD, @function 54 | ReadSMD: 55 | 56 | la $v0, _smd_parse_addr 57 | lw $v0, 0($v0) 58 | nop 59 | 60 | lw $a2, 0($v0) # Load primitive ID 61 | addiu $a1, $v0, 4 62 | 63 | sw $a2, SMD_PRI_ID($a0) 64 | 65 | beqz $a2, $end_prim 66 | nop 67 | 68 | srl $v1, $a2, 24 # Get primitive size 69 | addu $v0, $v1 70 | la $v1, _smd_parse_addr 71 | sw $v0, 0($v1) 72 | 73 | lw $v0, 0($a1) # Copy vertex coords 74 | lw $v1, 4($a1) 75 | sw $v0, SMD_PRI_v0($a0) 76 | sw $v1, SMD_PRI_v2($a0) 77 | addiu $a1, 8 78 | 79 | srl $v0, $a2, 2 # Lighting enabled? 80 | andi $v0, 0x3 81 | bnez $v0, $light 82 | nop 83 | 84 | b $no_light 85 | nop 86 | 87 | $light: 88 | srl $v1, $a2, 2 89 | lw $v0, 0($a1) # Copy vertex coords 90 | andi $v1, 0x3 91 | sw $v0, SMD_PRI_n0($a0) 92 | 93 | bne $v1, 0x2, $light_flat 94 | addiu $a1, 4 95 | 96 | lw $v1, 0($a1) 97 | addiu $a1, 4 98 | sw $v1, SMD_PRI_n2($a0) 99 | 100 | $light_flat: 101 | $no_light: 102 | 103 | lw $v0, 0($a1) 104 | nop 105 | sw $v0, SMD_PRI_rgbc0($a0) 106 | addiu $a1, 4 107 | 108 | srl $v0, $a2, 5 109 | andi $v0, 0x1 110 | beqz $v0, $not_textured 111 | nop 112 | 113 | lw $v0, 0($a1) 114 | lw $v1, 4($a1) 115 | sw $v0, SMD_PRI_tuv0($a0) 116 | lw $v0, 8($a1) 117 | sw $v1, SMD_PRI_tuv2($a0) 118 | sw $v0, SMD_PRI_tpage($a0) 119 | 120 | $not_textured: 121 | 122 | jr $ra 123 | move $v0, $a0 124 | 125 | $end_prim: 126 | 127 | jr $ra 128 | move $v0, $0 129 | -------------------------------------------------------------------------------- /libpsn00b/psxsio/tty.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PSn00bSDK serial port BIOS TTY driver 3 | * (C) 2019-2022 Lameguy64, spicyjpeg - MPL licensed 4 | * 5 | * This driver is designed to be as simple and reliable as possible: as such it 6 | * only relies on the SIO_*() API for receiving and sends data synchronously. 7 | * This allows printf() to work without issues, albeit slowly, if called from a 8 | * critical section or even from an interrupt handler. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | /* TTY device control block */ 17 | 18 | static int _sio_open(FCB *fcb, const char* file, int mode) { 19 | fcb->diskid = 1; 20 | return 0; 21 | } 22 | 23 | static int _sio_inout(FCB *fcb, int cmd) { 24 | char *ptr = (char*) fcb->trns_addr; 25 | 26 | switch (cmd) { 27 | case 1: // read 28 | for (int i = 0; i < fcb->trns_len; i++) 29 | *(ptr++) = (char) SIO_ReadByte(); 30 | 31 | return fcb->trns_len; 32 | 33 | case 2: // write 34 | for (int i = 0; i < fcb->trns_len; i++) { 35 | while (!(SIO_STAT(1) & (SR_TXRDY | SR_TXU))) 36 | __asm__ volatile(""); 37 | 38 | SIO_DATA(1) = *(ptr++); 39 | } 40 | 41 | return fcb->trns_len; 42 | 43 | default: 44 | return 0; 45 | } 46 | } 47 | 48 | static int _sio_close(FCB *fcb) { 49 | return 0; 50 | } 51 | 52 | static int _sio_ioctl(FCB *fcb, int cmd, int arg) { 53 | switch (cmd) { 54 | case FIOCSCAN: 55 | return SIO_ReadSync(1) ? 0 : -1; 56 | 57 | default: 58 | return -1; 59 | } 60 | } 61 | 62 | static int _sio_dummy(void) { 63 | return -1; 64 | } 65 | 66 | static DCB _sio_dcb = { 67 | .name = "tty", 68 | .flags = 3, 69 | .ssize = 1, 70 | .desc = "PSXSIO SERIAL CONSOLE", 71 | .f_init = &_sio_dummy, 72 | .f_open = &_sio_open, 73 | .f_inout = &_sio_inout, 74 | .f_close = &_sio_close, 75 | .f_ioctl = &_sio_ioctl, 76 | .f_read = &_sio_dummy, 77 | .f_write = &_sio_dummy, 78 | .f_erase = &_sio_dummy, 79 | .f_undelete = &_sio_dummy, 80 | .f_firstfile = &_sio_dummy, 81 | .f_nextfile = &_sio_dummy, 82 | .f_format = &_sio_dummy, 83 | .f_chdir = &_sio_dummy, 84 | .f_rename = &_sio_dummy, 85 | .f_remove = &_sio_dummy, 86 | .f_testdevice = &_sio_dummy 87 | }; 88 | 89 | /* Public API */ 90 | 91 | void AddSIO(int baud) { 92 | SIO_Init(baud, MR_SB_01 | MR_CHLEN_8); 93 | 94 | close(0); 95 | close(1); 96 | DelDev(_sio_dcb.name); 97 | AddDev(&_sio_dcb); 98 | open(_sio_dcb.name, 2); 99 | open(_sio_dcb.name, 1); 100 | } 101 | 102 | void DelSIO(void) { 103 | SIO_Quit(); 104 | 105 | DelDev(_sio_dcb.name); 106 | AddDummyTty(); 107 | } 108 | -------------------------------------------------------------------------------- /examples/graphics/hdtv/clip.c: -------------------------------------------------------------------------------- 1 | /* Polygon clip detection code 2 | * 3 | * The polygon clipping logic is based on the Cohen-Sutherland algorithm, but 4 | * only the off-screen detection logic is used to determine which polygon edges 5 | * are off-screen. 6 | * 7 | * In tri_clip, the following edges are checked as follows: 8 | * 9 | * |\ 10 | * | \ 11 | * | \ 12 | * | \ 13 | * |-------- 14 | * 15 | * In quad_clip, the following edges are checked as follows: 16 | * 17 | * |---------| 18 | * | \ / | 19 | * | \ / | 20 | * | / \ | 21 | * | / \ | 22 | * |---------| 23 | * 24 | * The inner portion of the quad is checked, otherwise the quad will be 25 | * culled out if the camera faces right into it, where all four edges 26 | * are off-screen at once. 27 | * 28 | */ 29 | 30 | #include "clip.h" 31 | 32 | #define CLIP_LEFT 1 33 | #define CLIP_RIGHT 2 34 | #define CLIP_TOP 4 35 | #define CLIP_BOTTOM 8 36 | 37 | int test_clip(RECT *clip, short x, short y) { 38 | 39 | // Tests which corners of the screen a point lies outside of 40 | 41 | int result = 0; 42 | 43 | if ( x < clip->x ) { 44 | result |= CLIP_LEFT; 45 | } 46 | 47 | if ( x >= (clip->x+(clip->w-1)) ) { 48 | result |= CLIP_RIGHT; 49 | } 50 | 51 | if ( y < clip->y ) { 52 | result |= CLIP_TOP; 53 | } 54 | 55 | if ( y >= (clip->y+(clip->h-1)) ) { 56 | result |= CLIP_BOTTOM; 57 | } 58 | 59 | return result; 60 | 61 | } 62 | 63 | int tri_clip(RECT *clip, DVECTOR *v0, DVECTOR *v1, DVECTOR *v2) { 64 | 65 | // Returns non-zero if a triangle is outside the screen boundaries 66 | 67 | short c[3]; 68 | 69 | c[0] = test_clip(clip, v0->vx, v0->vy); 70 | c[1] = test_clip(clip, v1->vx, v1->vy); 71 | c[2] = test_clip(clip, v2->vx, v2->vy); 72 | 73 | if ( ( c[0] & c[1] ) == 0 ) 74 | return 0; 75 | if ( ( c[1] & c[2] ) == 0 ) 76 | return 0; 77 | if ( ( c[2] & c[0] ) == 0 ) 78 | return 0; 79 | 80 | return 1; 81 | } 82 | 83 | int quad_clip(RECT *clip, DVECTOR *v0, DVECTOR *v1, DVECTOR *v2, DVECTOR *v3) { 84 | 85 | // Returns non-zero if a quad is outside the screen boundaries 86 | 87 | short c[4]; 88 | 89 | c[0] = test_clip(clip, v0->vx, v0->vy); 90 | c[1] = test_clip(clip, v1->vx, v1->vy); 91 | c[2] = test_clip(clip, v2->vx, v2->vy); 92 | c[3] = test_clip(clip, v3->vx, v3->vy); 93 | 94 | if ( ( c[0] & c[1] ) == 0 ) 95 | return 0; 96 | if ( ( c[1] & c[2] ) == 0 ) 97 | return 0; 98 | if ( ( c[2] & c[3] ) == 0 ) 99 | return 0; 100 | if ( ( c[3] & c[0] ) == 0 ) 101 | return 0; 102 | if ( ( c[0] & c[2] ) == 0 ) 103 | return 0; 104 | if ( ( c[1] & c[3] ) == 0 ) 105 | return 0; 106 | 107 | return 1; 108 | } -------------------------------------------------------------------------------- /examples/graphics/fpscam/clip.c: -------------------------------------------------------------------------------- 1 | /* Polygon clip detection code 2 | * 3 | * The polygon clipping logic is based on the Cohen-Sutherland algorithm, but 4 | * only the off-screen detection logic is used to determine which polygon edges 5 | * are off-screen. 6 | * 7 | * In tri_clip, the following edges are checked as follows: 8 | * 9 | * |\ 10 | * | \ 11 | * | \ 12 | * | \ 13 | * |-------- 14 | * 15 | * In quad_clip, the following edges are checked as follows: 16 | * 17 | * |---------| 18 | * | \ / | 19 | * | \ / | 20 | * | / \ | 21 | * | / \ | 22 | * |---------| 23 | * 24 | * The inner portion of the quad is checked, otherwise the quad will be 25 | * culled out if the camera faces right into it, where all four edges 26 | * are off-screen at once. 27 | * 28 | */ 29 | 30 | #include "clip.h" 31 | 32 | #define CLIP_LEFT 1 33 | #define CLIP_RIGHT 2 34 | #define CLIP_TOP 4 35 | #define CLIP_BOTTOM 8 36 | 37 | int test_clip(RECT *clip, short x, short y) { 38 | 39 | // Tests which corners of the screen a point lies outside of 40 | 41 | int result = 0; 42 | 43 | if ( x < clip->x ) { 44 | result |= CLIP_LEFT; 45 | } 46 | 47 | if ( x >= (clip->x+(clip->w-1)) ) { 48 | result |= CLIP_RIGHT; 49 | } 50 | 51 | if ( y < clip->y ) { 52 | result |= CLIP_TOP; 53 | } 54 | 55 | if ( y >= (clip->y+(clip->h-1)) ) { 56 | result |= CLIP_BOTTOM; 57 | } 58 | 59 | return result; 60 | 61 | } 62 | 63 | int tri_clip(RECT *clip, DVECTOR *v0, DVECTOR *v1, DVECTOR *v2) { 64 | 65 | // Returns non-zero if a triangle is outside the screen boundaries 66 | 67 | short c[3]; 68 | 69 | c[0] = test_clip(clip, v0->vx, v0->vy); 70 | c[1] = test_clip(clip, v1->vx, v1->vy); 71 | c[2] = test_clip(clip, v2->vx, v2->vy); 72 | 73 | if ( ( c[0] & c[1] ) == 0 ) 74 | return 0; 75 | if ( ( c[1] & c[2] ) == 0 ) 76 | return 0; 77 | if ( ( c[2] & c[0] ) == 0 ) 78 | return 0; 79 | 80 | return 1; 81 | } 82 | 83 | int quad_clip(RECT *clip, DVECTOR *v0, DVECTOR *v1, DVECTOR *v2, DVECTOR *v3) { 84 | 85 | // Returns non-zero if a quad is outside the screen boundaries 86 | 87 | short c[4]; 88 | 89 | c[0] = test_clip(clip, v0->vx, v0->vy); 90 | c[1] = test_clip(clip, v1->vx, v1->vy); 91 | c[2] = test_clip(clip, v2->vx, v2->vy); 92 | c[3] = test_clip(clip, v3->vx, v3->vy); 93 | 94 | if ( ( c[0] & c[1] ) == 0 ) 95 | return 0; 96 | if ( ( c[1] & c[2] ) == 0 ) 97 | return 0; 98 | if ( ( c[2] & c[3] ) == 0 ) 99 | return 0; 100 | if ( ( c[3] & c[0] ) == 0 ) 101 | return 0; 102 | if ( ( c[0] & c[2] ) == 0 ) 103 | return 0; 104 | if ( ( c[1] & c[3] ) == 0 ) 105 | return 0; 106 | 107 | return 1; 108 | } -------------------------------------------------------------------------------- /libpsn00b/cmake/flags.cmake: -------------------------------------------------------------------------------- 1 | # PSn00bSDK interface targets 2 | # (C) 2021-2022 spicyjpeg - MPL licensed 3 | 4 | # This script creates several "virtual" targets (psn00bsdk_*) that set include 5 | # directories and compiler flags when a target is linked against them. It is 6 | # only used when building libpsn00b, as CMake automatically saves these targets 7 | # into the export script once libpsn00b is installed. 8 | 9 | add_library (psn00bsdk INTERFACE) 10 | link_libraries(psn00bsdk) 11 | 12 | target_compile_options( 13 | psn00bsdk INTERFACE 14 | # Options common to all target types 15 | -g 16 | -Wa,--strip-local-absolute 17 | -ffreestanding 18 | -fno-builtin 19 | -nostdlib 20 | -fdata-sections 21 | -ffunction-sections 22 | -fsigned-char 23 | -fno-strict-overflow 24 | -fdiagnostics-color=always 25 | -msoft-float 26 | -march=r3000 27 | -mtune=r3000 28 | -mabi=32 29 | -mno-mt 30 | -mno-llsc 31 | $<$: 32 | # Options common to all target types (C++) 33 | -fno-exceptions 34 | -fno-rtti 35 | -fno-unwind-tables 36 | -fno-threadsafe-statics 37 | -fno-use-cxa-atexit 38 | > 39 | $, 40 | # Options for debug builds 41 | -Og 42 | -mdivide-breaks 43 | , 44 | # Options for release builds 45 | -O2 46 | > 47 | $<$>,EXECUTABLE_GPREL>: 48 | # Options for executables with $gp-relative addressing 49 | -G8 50 | -fno-pic 51 | -mno-abicalls 52 | -mgpopt 53 | -mno-extern-sdata 54 | > 55 | $<$>,EXECUTABLE_NOGPREL>: 56 | # Options for executables without $gp-relative addressing 57 | -G0 58 | -fno-pic 59 | -mno-abicalls 60 | -mno-gpopt 61 | > 62 | $<$>,SHARED_LIBRARY>: 63 | # Options for DLLs 64 | -G0 65 | -fPIC 66 | -mabicalls 67 | -mno-gpopt 68 | -mshared 69 | > 70 | ) 71 | target_link_options( 72 | psn00bsdk INTERFACE 73 | # Options common to all target types 74 | -nostdlib 75 | -Wl,-gc-sections 76 | $<$>,EXECUTABLE_GPREL>: 77 | # Options for executables with $gp-relative addressing 78 | -G8 79 | -static 80 | > 81 | $<$>,EXECUTABLE_NOGPREL>: 82 | # Options for executables without $gp-relative addressing 83 | -G0 84 | -static 85 | > 86 | $<$>,SHARED_LIBRARY>: 87 | # Options for DLLs 88 | -G0 89 | -shared 90 | > 91 | ) 92 | target_compile_definitions( 93 | psn00bsdk INTERFACE 94 | PSN00BSDK=1 95 | $, 96 | #NDEBUG=0 97 | , 98 | NDEBUG=1 99 | > 100 | ) 101 | -------------------------------------------------------------------------------- /template/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * LibPSn00b Example Programs 3 | * 4 | * Hello World Example 5 | * 2019-2020 Meido-Tek Productions / PSn00bSDK Project 6 | * 7 | * The obligatory hello world example normally included in nearly every 8 | * SDK package. This example should also get you started in how to manage 9 | * the display using psxgpu. 10 | * 11 | * Example by Lameguy64 12 | * 13 | * 14 | * Changelog: 15 | * 16 | * January 1, 2020 - Initial version 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | 26 | // Define display/draw environments for double buffering 27 | DISPENV disp[2]; 28 | DRAWENV draw[2]; 29 | int db; 30 | 31 | 32 | // Init function 33 | void init(void) 34 | { 35 | // This not only resets the GPU but it also installs the library's 36 | // ISR subsystem to the kernel 37 | ResetGraph(0); 38 | 39 | // Define display environments, first on top and second on bottom 40 | SetDefDispEnv(&disp[0], 0, 0, 320, 240); 41 | SetDefDispEnv(&disp[1], 0, 240, 320, 240); 42 | 43 | // Define drawing environments, first on bottom and second on top 44 | SetDefDrawEnv(&draw[0], 0, 240, 320, 240); 45 | SetDefDrawEnv(&draw[1], 0, 0, 320, 240); 46 | 47 | // Set and enable clear color 48 | setRGB0(&draw[0], 0, 96, 0); 49 | setRGB0(&draw[1], 0, 96, 0); 50 | draw[0].isbg = 1; 51 | draw[1].isbg = 1; 52 | 53 | // Clear double buffer counter 54 | db = 0; 55 | 56 | // Apply the GPU environments 57 | PutDispEnv(&disp[db]); 58 | PutDrawEnv(&draw[db]); 59 | 60 | // Load test font 61 | FntLoad(960, 0); 62 | 63 | // Open up a test font text stream of 100 characters 64 | FntOpen(0, 8, 320, 224, 0, 100); 65 | } 66 | 67 | // Display function 68 | void display(void) 69 | { 70 | // Flip buffer index 71 | db = !db; 72 | 73 | // Wait for all drawing to complete 74 | DrawSync(0); 75 | 76 | // Wait for vertical sync to cap the logic to 60fps (or 50 in PAL mode) 77 | // and prevent screen tearing 78 | VSync(0); 79 | 80 | // Switch pages 81 | PutDispEnv(&disp[db]); 82 | PutDrawEnv(&draw[db]); 83 | 84 | // Enable display output, ResetGraph() disables it by default 85 | SetDispMask(1); 86 | 87 | } 88 | 89 | // Main function, program entrypoint 90 | int main(int argc, const char *argv[]) 91 | { 92 | int counter; 93 | 94 | // Init stuff 95 | init(); 96 | 97 | // Main loop 98 | counter = 0; 99 | while(1) 100 | { 101 | 102 | // Print the obligatory hello world and counter to show that the 103 | // program isn't locking up to the last created text stream 104 | FntPrint(-1, "HELLO WORLD\n"); 105 | FntPrint(-1, "COUNTER=%d\n", counter); 106 | 107 | // Draw the last created text stream 108 | FntFlush(-1); 109 | 110 | // Update display 111 | display(); 112 | 113 | // Increment the counter 114 | counter++; 115 | } 116 | 117 | return 0; 118 | } 119 | -------------------------------------------------------------------------------- /examples/beginner/hello/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * LibPSn00b Example Programs 3 | * 4 | * Hello World Example 5 | * 2019-2020 Meido-Tek Productions / PSn00bSDK Project 6 | * 7 | * The obligatory hello world example normally included in nearly every 8 | * SDK package. This example should also get you started in how to manage 9 | * the display using psxgpu. 10 | * 11 | * Example by Lameguy64 12 | * 13 | * 14 | * Changelog: 15 | * 16 | * January 1, 2020 - Initial version 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | 26 | // Define display/draw environments for double buffering 27 | DISPENV disp[2]; 28 | DRAWENV draw[2]; 29 | int db; 30 | 31 | 32 | // Init function 33 | void init(void) 34 | { 35 | // This not only resets the GPU but it also installs the library's 36 | // ISR subsystem to the kernel 37 | ResetGraph(0); 38 | 39 | // Define display environments, first on top and second on bottom 40 | SetDefDispEnv(&disp[0], 0, 0, 320, 240); 41 | SetDefDispEnv(&disp[1], 0, 240, 320, 240); 42 | 43 | // Define drawing environments, first on bottom and second on top 44 | SetDefDrawEnv(&draw[0], 0, 240, 320, 240); 45 | SetDefDrawEnv(&draw[1], 0, 0, 320, 240); 46 | 47 | // Set and enable clear color 48 | setRGB0(&draw[0], 0, 96, 0); 49 | setRGB0(&draw[1], 0, 96, 0); 50 | draw[0].isbg = 1; 51 | draw[1].isbg = 1; 52 | 53 | // Clear double buffer counter 54 | db = 0; 55 | 56 | // Apply the GPU environments 57 | PutDispEnv(&disp[db]); 58 | PutDrawEnv(&draw[db]); 59 | 60 | // Load test font 61 | FntLoad(960, 0); 62 | 63 | // Open up a test font text stream of 100 characters 64 | FntOpen(0, 8, 320, 224, 0, 100); 65 | } 66 | 67 | // Display function 68 | void display(void) 69 | { 70 | // Flip buffer index 71 | db = !db; 72 | 73 | // Wait for all drawing to complete 74 | DrawSync(0); 75 | 76 | // Wait for vertical sync to cap the logic to 60fps (or 50 in PAL mode) 77 | // and prevent screen tearing 78 | VSync(0); 79 | 80 | // Switch pages 81 | PutDispEnv(&disp[db]); 82 | PutDrawEnv(&draw[db]); 83 | 84 | // Enable display output, ResetGraph() disables it by default 85 | SetDispMask(1); 86 | 87 | } 88 | 89 | // Main function, program entrypoint 90 | int main(int argc, const char *argv[]) 91 | { 92 | int counter; 93 | 94 | // Init stuff 95 | init(); 96 | 97 | // Main loop 98 | counter = 0; 99 | while(1) 100 | { 101 | 102 | // Print the obligatory hello world and counter to show that the 103 | // program isn't locking up to the last created text stream 104 | FntPrint(-1, "HELLO WORLD\n"); 105 | FntPrint(-1, "COUNTER=%d\n", counter); 106 | 107 | // Draw the last created text stream 108 | FntFlush(-1); 109 | 110 | // Update display 111 | display(); 112 | 113 | // Increment the counter 114 | counter++; 115 | } 116 | 117 | return 0; 118 | } 119 | -------------------------------------------------------------------------------- /examples/mdec/mdecimage/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PSn00bSDK MDEC static image example 3 | * (C) 2022 spicyjpeg - MPL licensed 4 | * 5 | * This is a modified version of the graphics/rgb24 example showing how to feed 6 | * run-length encoded data into the MDEC and retrieve a decoded 24bpp image. To 7 | * keep the example simple no additional compression is applied (usually MDEC 8 | * data would be Huffman encoded to save more space, with the initial 9 | * decompression being done in software). A Python script is included to encode 10 | * an image into the format expected by the MDEC; quality and file size can be 11 | * tweaked by changing the quantization scales with the -y and -c arguments. 12 | * 13 | * Using the MDEC to decode static images can be useful for e.g. menu 14 | * backgrounds or loading screens, where smaller file sizes are desirable even 15 | * if quality is sacrificed. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | extern const uint32_t mdec_image[]; 25 | extern const size_t mdec_image_size; 26 | 27 | #define SCREEN_XRES 640 28 | #define SCREEN_YRES 480 29 | 30 | //#define BLOCK_SIZE 8 // Monochrome (8x8), 15bpp display 31 | //#define BLOCK_SIZE 12 // Monochrome (8x8), 24bpp display 32 | //#define BLOCK_SIZE 16 // Color (16x16), 15bpp display 33 | #define BLOCK_SIZE 24 // Color (16x16), 24bpp display 34 | 35 | int main(int argc, const char* argv[]) { 36 | DISPENV disp; 37 | 38 | ResetGraph(0); 39 | DecDCTReset(0); 40 | 41 | // Set up the GPU for 640x480 interlaced 24bpp output. 42 | SetDefDispEnv(&disp, 0, 0, SCREEN_XRES, SCREEN_YRES); 43 | disp.isrgb24 = 1; 44 | disp.isinter = 1; 45 | 46 | PutDispEnv(&disp); 47 | SetDispMask(1); 48 | 49 | // Start feeding image data to the MDEC. This doesn't immediately start the 50 | // decoding, instead the MDEC will wait until a destination buffer is also 51 | // set up. 52 | MDEC0 = 0x30000000 | (mdec_image_size / 4); // 0x38000000 for 15bpp 53 | DecDCTinRaw(mdec_image, mdec_image_size / 4); 54 | 55 | // Fetch decoded data from the MDEC in vertical 8x480 or 16x480 "slices". 56 | // This is necessary as the MDEC doesn't buffer an entire frame but only 57 | // returns a series of square macroblocks, which can't be placed into VRAM 58 | // with a single LoadImage() call. 59 | //for (uint32_t x = 0; x < SCREEN_XRES; x += BLOCK_SIZE) { // 15bpp 60 | for (uint32_t x = 0; x < (SCREEN_XRES * 3 / 2); x += BLOCK_SIZE) { // 24bpp 61 | RECT rect; 62 | uint32_t slice[BLOCK_SIZE * SCREEN_YRES / 2]; 63 | 64 | rect.x = x; 65 | rect.y = 0; 66 | rect.w = BLOCK_SIZE; 67 | rect.h = SCREEN_YRES; 68 | 69 | // Configure the MDEC to output to the slice buffer and let it finish 70 | // decoding a slice, then upload it to the framebuffer. 71 | DecDCTout(slice, BLOCK_SIZE * SCREEN_YRES / 2); 72 | DecDCToutSync(0); 73 | 74 | LoadImage(&rect, slice); 75 | DrawSync(0); 76 | } 77 | 78 | for (;;) 79 | __asm__ volatile(""); 80 | 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /libpsn00b/psxapi/drivers.s: -------------------------------------------------------------------------------- 1 | # PSn00bSDK BIOS API stubs 2 | # (C) 2022 spicyjpeg - MPL licensed 3 | 4 | # This file has been generated automatically. Each function is placed in its 5 | # own section to allow the linker to strip unused functions. 6 | 7 | .set noreorder 8 | 9 | ## A0 table functions (7) 10 | 11 | .section .text._bu_init 12 | .global _bu_init 13 | .type _bu_init, @function 14 | _bu_init: 15 | li $t2, 0xa0 16 | jr $t2 17 | li $t1, 0x55 18 | 19 | .section .text._96_init 20 | .global _96_init 21 | .type _96_init, @function 22 | _96_init: 23 | li $t2, 0xa0 24 | jr $t2 25 | li $t1, 0x71 26 | 27 | .section .text._96_remove 28 | .global _96_remove 29 | .type _96_remove, @function 30 | _96_remove: 31 | li $t2, 0xa0 32 | jr $t2 33 | li $t1, 0x72 34 | 35 | .section .text.AddDummyTty 36 | .global AddDummyTty 37 | .type AddDummyTty, @function 38 | AddDummyTty: 39 | li $t2, 0xa0 40 | jr $t2 41 | li $t1, 0x99 42 | 43 | .section .text._card_info 44 | .global _card_info 45 | .type _card_info, @function 46 | _card_info: 47 | li $t2, 0xa0 48 | jr $t2 49 | li $t1, 0xab 50 | 51 | .section .text._card_load 52 | .global _card_load 53 | .type _card_load, @function 54 | _card_load: 55 | li $t2, 0xa0 56 | jr $t2 57 | li $t1, 0xac 58 | 59 | .section .text._card_clear 60 | .global _card_clear 61 | .type _card_clear, @function 62 | _card_clear: 63 | li $t2, 0xa0 64 | jr $t2 65 | li $t1, 0xaf 66 | 67 | ## B0 table functions (12) 68 | 69 | .section .text.AddDev 70 | .global AddDev 71 | .type AddDev, @function 72 | AddDev: 73 | li $t2, 0xb0 74 | jr $t2 75 | li $t1, 0x47 76 | 77 | .section .text.DelDev 78 | .global DelDev 79 | .type DelDev, @function 80 | DelDev: 81 | li $t2, 0xb0 82 | jr $t2 83 | li $t1, 0x48 84 | 85 | .section .text.ListDev 86 | .global ListDev 87 | .type ListDev, @function 88 | ListDev: 89 | li $t2, 0xb0 90 | jr $t2 91 | li $t1, 0x49 92 | 93 | .section .text.InitCARD 94 | .global InitCARD 95 | .type InitCARD, @function 96 | InitCARD: 97 | li $t2, 0xb0 98 | jr $t2 99 | li $t1, 0x4a 100 | 101 | .section .text.StartCARD 102 | .global StartCARD 103 | .type StartCARD, @function 104 | StartCARD: 105 | li $t2, 0xb0 106 | jr $t2 107 | li $t1, 0x4b 108 | 109 | .section .text.StopCARD 110 | .global StopCARD 111 | .type StopCARD, @function 112 | StopCARD: 113 | li $t2, 0xb0 114 | jr $t2 115 | li $t1, 0x4c 116 | 117 | .section .text._card_write 118 | .global _card_write 119 | .type _card_write, @function 120 | _card_write: 121 | li $t2, 0xb0 122 | jr $t2 123 | li $t1, 0x4e 124 | 125 | .section .text._card_read 126 | .global _card_read 127 | .type _card_read, @function 128 | _card_read: 129 | li $t2, 0xb0 130 | jr $t2 131 | li $t1, 0x4f 132 | 133 | .section .text._new_card 134 | .global _new_card 135 | .type _new_card, @function 136 | _new_card: 137 | li $t2, 0xb0 138 | jr $t2 139 | li $t1, 0x50 140 | 141 | .section .text._card_chan 142 | .global _card_chan 143 | .type _card_chan, @function 144 | _card_chan: 145 | li $t2, 0xb0 146 | jr $t2 147 | li $t1, 0x58 148 | 149 | .section .text._card_status 150 | .global _card_status 151 | .type _card_status, @function 152 | _card_status: 153 | li $t2, 0xb0 154 | jr $t2 155 | li $t1, 0x5c 156 | 157 | .section .text._card_wait 158 | .global _card_wait 159 | .type _card_wait, @function 160 | _card_wait: 161 | li $t2, 0xb0 162 | jr $t2 163 | li $t1, 0x5d 164 | 165 | -------------------------------------------------------------------------------- /libpsn00b/libc/start.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PSn00bSDK startup code 3 | * (C) 2021 Lameguy64, spicyjpeg - MPL licensed 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define KERNEL_ARG_STRING ((const char *) 0x80000180) 12 | #define KERNEL_RETURN_VALUE ((volatile int *) 0x8000dffc) 13 | 14 | /* Argument parsing */ 15 | 16 | int __argc; 17 | const char **__argv; 18 | 19 | #define ARGC_MAX 16 20 | 21 | static const char *_argv_buffer[ARGC_MAX]; 22 | static char _arg_string_buffer[132]; 23 | 24 | static void _parse_kernel_args(void) { 25 | // Copy the argument string from kernel memory into a private buffer (which 26 | // won't be cleared or deallocated) and trim it at the first newline. 27 | memset(_arg_string_buffer, 0, 132); 28 | strncpy(_arg_string_buffer, KERNEL_ARG_STRING, 128); 29 | 30 | for (char *ptr = _arg_string_buffer; *ptr; ptr++) { 31 | if ((*ptr == '\r') || (*ptr == '\n')) { 32 | *ptr = 0; 33 | break; 34 | } 35 | } 36 | 37 | __argv = _argv_buffer; 38 | for (__argc = 0; __argc < ARGC_MAX; __argc++) { 39 | const char *ptr; 40 | if (!__argc) 41 | ptr = strtok(_arg_string_buffer, " "); 42 | else 43 | ptr = strtok(0, " "); 44 | 45 | _argv_buffer[__argc] = ptr; 46 | if (!ptr) 47 | break; 48 | } 49 | } 50 | 51 | /* Main */ 52 | 53 | // These are defined by the linker script. Note that these are *NOT* pointers, 54 | // they are virtual symbols whose location matches their value. The simplest 55 | // way to turn them into pointers is to declare them as arrays, so here we go. 56 | extern uint8_t __text_start[]; 57 | extern uint8_t __bss_start[]; 58 | extern uint8_t _end[]; 59 | //extern uint8_t _gp[]; 60 | 61 | extern void (*__CTOR_LIST__[])(void); 62 | extern void (*__DTOR_LIST__[])(void); 63 | 64 | extern int main(int argc, const char* argv[]); 65 | 66 | // Even though _start() usually takes no arguments, this implementation allows 67 | // parent executables to pass args directly to child executables without having 68 | // to overwrite the arg strings in kernel RAM. 69 | void _start_inner(int32_t override_argc, const char **override_argv) { 70 | //__asm__ volatile("la $gp, _gp;"); 71 | 72 | // Clear BSS 4 bytes at a time. BSS is always aligned to 4 bytes by the 73 | // linker script. 74 | for (uint32_t *i = (uint32_t *) __bss_start; i < (uint32_t *) _end; i++) 75 | *i = 0; 76 | 77 | // Initialize the heap and place it after the executable, assuming 2 MB of 78 | // RAM. Note that InitHeap() can be called again in main(). 79 | InitHeap((void *) _end + 4, (void *) 0x801ffff8 - (void *) _end); 80 | 81 | if (override_argv) { 82 | __argc = override_argc; 83 | __argv = override_argv; 84 | } else { 85 | _parse_kernel_args(); 86 | } 87 | 88 | // Call the global constructors (if any) to initialize global objects 89 | // before calling main(). Constructors are put by the linker script in a 90 | // length-prefixed array in reverse order. 91 | for (uint32_t i = (uint32_t) __CTOR_LIST__[0]; i >= 1; i--) 92 | __CTOR_LIST__[i](); 93 | 94 | // Store main()'s return value into the kernel return value area (for child 95 | // executables). 96 | *KERNEL_RETURN_VALUE = main(__argc, __argv); 97 | 98 | // Call global destructors (in forward order). 99 | for (uint32_t i = 0; i < (uint32_t) __DTOR_LIST__[0]; i++) 100 | __DTOR_LIST__[i + 1](); 101 | } 102 | -------------------------------------------------------------------------------- /libpsn00b/ldscripts/exe.ld: -------------------------------------------------------------------------------- 1 | /* 2 | * PSn00bSDK linker script for executables 3 | * (C) 2021 spicyjpeg - MPL licensed 4 | * 5 | * GP-relative addressing (i.e. placing small variables in a 64 KB block and 6 | * using $gp to reference them) is fully supported; the block is made up of 7 | * sections .sdata and .sbss. Note that GP-relative addressing is not 8 | * compatible with dynamic linking, as DLLs require GP to be unused. 9 | * 10 | * This linker script assumes main RAM is 8 MB to allow executables meant for 11 | * devkits or arcade systems to be built, however the executable conversion 12 | * tool (elf2x) will throw a warning if the size exceeds 2 MB. 13 | */ 14 | 15 | /*OUTPUT_FORMAT(elf32-littlemips)*/ 16 | ENTRY(_start) 17 | /*STARTUP(start.o)*/ 18 | 19 | MEMORY { 20 | /* Mapped into KSEG0 */ 21 | KERNEL_RAM (rwx) : ORIGIN = 0x80000000, LENGTH = 0x010000 22 | APP_RAM (rwx) : ORIGIN = 0x80010000, LENGTH = 0x7f0000 23 | } 24 | 25 | SECTIONS { 26 | /* Text section, i.e. code and constants */ 27 | 28 | .text : { 29 | __text_start = .; 30 | 31 | *(.text .text.* .gnu.linkonce.t.*) 32 | *(.plt .MIPS.stubs) 33 | } > APP_RAM 34 | .rodata : { 35 | *(.rodata .rodata.* .gnu.linkonce.r.*) 36 | } > APP_RAM 37 | 38 | /* Global constructor and destructor arrays (length-prefixed) */ 39 | 40 | /* 41 | * TODO: replace this crap with .init_array and .fini_array, which are the 42 | * "modern" way of doing it without reversed arrays and weird length 43 | * prefixes. That would require even more patching though. 44 | * 45 | * https://sourceware.org/binutils/docs/ld/Output-Section-Keywords.html 46 | * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46770 47 | */ 48 | .ctors : ALIGN(16) { 49 | __CTOR_LIST__ = .; 50 | 51 | LONG(((__CTOR_END__ - __CTOR_LIST__) / 4) - 2) 52 | KEEP(*(SORT(.ctors.*))) 53 | KEEP(*(.ctors)) 54 | LONG(0) 55 | 56 | __CTOR_END__ = .; 57 | } > APP_RAM 58 | .dtors : ALIGN(16) { 59 | __DTOR_LIST__ = .; 60 | 61 | LONG(((__DTOR_END__ - __DTOR_LIST__) / 4) - 2) 62 | KEEP(*(SORT(.dtors.*))) 63 | KEEP(*(.dtors)) 64 | LONG(0) 65 | 66 | __DTOR_END__ = .; 67 | } > APP_RAM 68 | 69 | /* Data sections, i.e. variables with default values */ 70 | 71 | .data : { 72 | *(.data .data.* .gnu.linkonce.d.*) 73 | } > APP_RAM 74 | 75 | /* 76 | * Set _gp to point to the beginning of .sdata plus 0x7ff0, so anything 77 | * within .sdata (and .sbss) can be accessed using the $gp register as 78 | * base plus a signed 16-bit immediate. Note that $gp is set to _gp on 79 | * boot by _start() in the SDK. 80 | */ 81 | HIDDEN(_gp = ALIGN(16) + 0x7ff0); 82 | 83 | .sdata : { 84 | *(.sdata .sdata.* .gnu.linkonce.s.*) 85 | } > APP_RAM 86 | 87 | /* BSS sections, i.e. uninitialized variables */ 88 | 89 | /* 90 | * Align all BSS sections to 4 bytes to ensure _start() doesn't perform 91 | * unaligned memory accesses when clearing them. 92 | */ 93 | . = ALIGN((. != 0) ? 4 : 1); 94 | __bss_start = .; 95 | 96 | .sbss (NOLOAD) : { 97 | *(.sbss .sbss.* .gnu.linkonce.sb.*) 98 | *(.scommon) 99 | } > APP_RAM 100 | .bss (NOLOAD) : { 101 | *(.bss .bss.* .gnu.linkonce.b.*) 102 | *(COMMON) 103 | } > APP_RAM 104 | 105 | . = ALIGN((. != 0) ? 4 : 1); 106 | _end = .; 107 | 108 | /* Dummy section */ 109 | 110 | .dummy (NOLOAD) : { 111 | KEEP(*(.dummy)) 112 | } > APP_RAM 113 | 114 | /* Remove anything flagged as link-time optimized */ 115 | 116 | /DISCARD/ : { 117 | *(.gnu.lto_*) 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /examples/beginner/cppdemo/main.cpp: -------------------------------------------------------------------------------- 1 | /* Work in progress example, need to add comments. 2 | * 3 | * Basically a quick little example that showcases C++ classes are 4 | * functioning in PSn00bSDK. - Lameguy64 5 | * 6 | * First written in December ‎18, ‎2020. 7 | * 8 | * Changelog: 9 | * 10 | * May 10, 2021 - Variable types updated for psxgpu.h changes. 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | class GraphClass 21 | { 22 | u_long *_ot[2]; 23 | u_char *_pri[2]; 24 | u_char *_nextpri; 25 | 26 | int _ot_count; 27 | int _db; 28 | 29 | DISPENV _disp[2]; 30 | DRAWENV _draw[2]; 31 | 32 | public: 33 | 34 | GraphClass( int ot_len = 8, int pri_len = 8192 ) 35 | { 36 | _ot[0] = (u_long*)malloc( sizeof(u_long)*ot_len ); 37 | _ot[1] = (u_long*)malloc( sizeof(u_long)*ot_len ); 38 | 39 | _db = 0; 40 | _ot_count = ot_len; 41 | ClearOTagR( _ot[0], _ot_count ); 42 | ClearOTagR( _ot[1], _ot_count ); 43 | 44 | _pri[0] = (u_char*)malloc( pri_len ); 45 | _pri[1] = (u_char*)malloc( pri_len ); 46 | 47 | _nextpri = _pri[0]; 48 | 49 | printf( "GraphClass::GraphClass: Buffers allocated.\n" ); 50 | 51 | } /* GraphClass */ 52 | 53 | virtual ~GraphClass() 54 | { 55 | /* free the OTs and primitive buffers */ 56 | free( _ot[0] ); 57 | free( _ot[1] ); 58 | 59 | free( _pri[0] ); 60 | free( _pri[1] ); 61 | 62 | printf( "GraphClass::GraphClass: Buffers freed.\n" ); 63 | 64 | } /* ~GraphClass */ 65 | 66 | void SetRes( int w, int h ) 67 | { 68 | SetDefDispEnv( &_disp[0], 0, h, w, h ); 69 | SetDefDispEnv( &_disp[1], 0, 0, w, h ); 70 | 71 | SetDefDrawEnv( &_draw[0], 0, 0, w, h ); 72 | SetDefDrawEnv( &_draw[1], 0, h, w, h ); 73 | 74 | setRGB0( &_draw[0], 63, 0, 127 ); 75 | _draw[0].isbg = 1; 76 | _draw[0].dtd = 1; 77 | setRGB0( &_draw[1], 63, 0, 127 ); 78 | _draw[1].isbg = 1; 79 | _draw[1].dtd = 1; 80 | 81 | PutDispEnv( &_disp[0] ); 82 | PutDrawEnv( &_draw[0] ); 83 | 84 | } /* SetRes */ 85 | 86 | void IncPri( int bytes ) 87 | { 88 | _nextpri += bytes; 89 | 90 | } /* IncPri */ 91 | 92 | void SetPri( u_char *ptr ) 93 | { 94 | _nextpri = ptr; 95 | 96 | } /* SetPri */ 97 | 98 | u_char *GetNextPri( void ) 99 | { 100 | return( _nextpri ); 101 | 102 | } /* GetNextPri */ 103 | 104 | u_long *GetOt( void ) 105 | { 106 | return( _ot[_db] ); 107 | 108 | } /* GetOt */ 109 | 110 | void Display( void ) 111 | { 112 | VSync( 0 ); 113 | DrawSync( 0 ); 114 | SetDispMask( 1 ); 115 | 116 | _db = !_db; 117 | 118 | PutDispEnv( &_disp[_db] ); 119 | PutDrawEnv( &_draw[_db] ); 120 | 121 | DrawOTag( _ot[!_db]+(_ot_count-1) ); 122 | 123 | ClearOTagR( _ot[_db], _ot_count ); 124 | _nextpri = _pri[_db]; 125 | 126 | } /* Display */ 127 | 128 | }; /* GraphClass */ 129 | 130 | GraphClass *otable; 131 | 132 | int main( int argc, const char *argv[] ) 133 | { 134 | TILE *tile; 135 | 136 | ResetGraph( 0 ); 137 | 138 | otable = new GraphClass(); 139 | 140 | otable->SetRes( 320, 240 ); 141 | 142 | while( 1 ) 143 | { 144 | tile = (TILE*)otable->GetNextPri(); 145 | setTile( tile ); 146 | setXY0( tile, 32, 32 ); 147 | setWH( tile, 128, 128 ); 148 | setRGB0( tile, 255, 255, 0 ); 149 | addPrim( otable->GetOt(), tile ); 150 | otable->IncPri( sizeof(TILE) ); 151 | 152 | otable->Display(); 153 | } 154 | 155 | return( 0 ); 156 | 157 | } /* main */ -------------------------------------------------------------------------------- /libpsn00b/psxapi/generate_stubs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # PSn00bSDK BIOS stub generator 3 | # (C) 2022 spicyjpeg - MPL licensed 4 | 5 | import os, sys, json 6 | from argparse import ArgumentParser, FileType 7 | 8 | ## Listing section generation 9 | 10 | SECTION_TEMPLATE = """## {title} ({count}) 11 | 12 | {body}""" 13 | FUNCTION_TEMPLATE = """.section .text.{name} 14 | .global {name} 15 | .type {name}, @function 16 | {name}: 17 | li $t2, 0x{address:02x} 18 | jr $t2 19 | li $t1, 0x{id:02x} 20 | 21 | """ 22 | SYSCALL_TEMPLATE = """.section .text.{name} 23 | .global {name} 24 | .type {name}, @function 25 | {name}: 26 | li $a0, 0x{id:02x} 27 | syscall 0 28 | jr $ra 29 | nop 30 | 31 | """ 32 | 33 | STUB_TYPES = { 34 | "a": ( 0xa0, FUNCTION_TEMPLATE, "A0 table functions" ), 35 | "b": ( 0xb0, FUNCTION_TEMPLATE, "B0 table functions" ), 36 | "c": ( 0xc0, FUNCTION_TEMPLATE, "C0 table functions" ), 37 | "syscall": ( 0x00, SYSCALL_TEMPLATE, "Syscalls" ) 38 | } 39 | 40 | def generate_section(_type, entries): 41 | address, template, title = STUB_TYPES[_type] 42 | body = "" 43 | 44 | for entry in entries: 45 | if entry.get("comment", None): 46 | body += f"# {entry['comment'].strip()}\n" 47 | 48 | body += template.format( 49 | name = entry["name"].strip(), 50 | address = address, 51 | id = entry["id"] 52 | ) 53 | 54 | return SECTION_TEMPLATE.format( 55 | title = title, 56 | count = len(entries), 57 | body = body 58 | ) 59 | 60 | ## Main 61 | 62 | HEADER_TEMPLATE = """# PSn00bSDK BIOS API stubs 63 | # (C) 2022 spicyjpeg - MPL licensed 64 | 65 | # This file has been generated automatically. Each function is placed in its 66 | # own section to allow the linker to strip unused functions. 67 | 68 | .set noreorder 69 | 70 | """ 71 | 72 | def get_args(): 73 | parser = ArgumentParser( 74 | description = "Generates MIPS assembly listings of BIOS API stubs." 75 | ) 76 | parser.add_argument( 77 | "json_list", 78 | type = FileType("rt"), 79 | help = "path to JSON list of stubs to generate" 80 | ) 81 | parser.add_argument( 82 | "-o", "--output", 83 | type = str, 84 | default = os.curdir, 85 | help = "where to save generated files (current directory by default)", 86 | metavar = "directory" 87 | ) 88 | 89 | return parser.parse_args() 90 | 91 | def main(): 92 | args = get_args() 93 | 94 | with args.json_list as _file: 95 | all_entries = json.load(_file) 96 | 97 | # { file: { type: [ entry, ... ], ... }, ... } 98 | files = {} 99 | 100 | # Sort all functions by the file they are going to be put in, and by the 101 | # type within the file. 102 | for entry in all_entries: 103 | _type = entry["type"].strip().lower() 104 | _file = entry["file"].strip() 105 | 106 | if type(entry["id"]) is str: 107 | entry["id"] = int(entry["id"], 0) 108 | 109 | if _file not in files: 110 | files[_file] = { _type: [] for _type in STUB_TYPES.keys() } 111 | 112 | files[_file][_type].append(entry) 113 | 114 | for path, types in files.items(): 115 | full_path = os.path.normpath(os.path.join(args.output, path)) 116 | listing = HEADER_TEMPLATE 117 | 118 | for _type, entries in types.items(): 119 | if not entries: 120 | continue 121 | 122 | entries.sort(key = lambda entry: entry["id"]) 123 | listing += generate_section(_type, entries) 124 | 125 | with open(full_path, "wt", newline = "\n") as _file: 126 | _file.write(listing) 127 | 128 | if __name__ == "__main__": 129 | main() 130 | -------------------------------------------------------------------------------- /examples/system/dynlink/library/balls.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PSn00bSDK dynamic linker example (DLL 2) 3 | * (C) 2021 spicyjpeg - MPL licensed 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "dll_common.h" 15 | 16 | extern const uint32_t ball16c[]; 17 | 18 | /* Balls data */ 19 | 20 | typedef struct { 21 | int16_t x, y; 22 | int16_t xdir, ydir; 23 | uint8_t r, g, b, p; 24 | } Ball; 25 | 26 | #define MAX_BALLS 512 27 | 28 | /* Functions called by the main executable */ 29 | 30 | // NOTE: DLLs have no main(), _start() or other defined entry point. C++ global 31 | // objects are automatically constructed when loading the library, and their 32 | // destructors are called when unloading it via dlclose(). Other than that, the 33 | // main executable can freely call DLL functions in any order, however it's 34 | // still recommended (at least for C code) to have an init() function to e.g. 35 | // initialize variables or hardware. 36 | 37 | static uint32_t frame = 0; 38 | static Ball balls[MAX_BALLS]; 39 | static TIM_IMAGE ball_tim; 40 | 41 | void init(RenderContext *ctx) { 42 | Framebuffer *db = &(ctx->db[ctx->db_active]); 43 | 44 | GetTimInfo(ball16c, &ball_tim); 45 | LoadImage(ball_tim.prect, ball_tim.paddr); 46 | if (ball_tim.mode & 8) 47 | LoadImage(ball_tim.crect, ball_tim.caddr); 48 | 49 | // Initialize the balls by giving them a random initial position, velocity 50 | // and color. 51 | for (uint32_t i = 0; i < MAX_BALLS; i++) { 52 | Ball *b = &(balls[i]); 53 | 54 | b->x = rand() % (db->draw.clip.w - 16); 55 | b->y = rand() % (db->draw.clip.h - 16); 56 | b->xdir = ((rand() & 1) ? 1 : -1) * ((rand() % 3) + 1); 57 | b->ydir = ((rand() & 1) ? 1 : -1) * ((rand() % 3) + 1); 58 | b->r = rand() & 0xff; 59 | b->g = rand() & 0xff; 60 | b->b = rand() & 0xff; 61 | } 62 | } 63 | 64 | void render(RenderContext *ctx, uint16_t buttons) { 65 | Framebuffer *db = &(ctx->db[ctx->db_active]); 66 | SPRT_16 *sprt = (SPRT_16 *) ctx->db_nextpri; 67 | 68 | for (uint32_t i = 0; i < MAX_BALLS; i++) { 69 | Ball *b = &(balls[i]); 70 | 71 | setSprt16(sprt); 72 | 73 | setXY0(sprt, b->x, b->y); 74 | setRGB0(sprt, b->r, b->g, b->b); 75 | setUV0(sprt, 0, 0); 76 | setClut(sprt, ball_tim.crect->x, ball_tim.crect->y); 77 | 78 | addPrim(&(db->ot[OT_LEN - 1]), sprt); 79 | sprt++; 80 | 81 | // Update the ball's velocity and acceleration, moving them slower if 82 | // cross is pressed. 83 | int16_t step = !(buttons & PAD_CROSS) ? 1 : 0; 84 | b->x += b->xdir >> step; 85 | b->y += b->ydir >> step; 86 | 87 | if ( 88 | (b->x < 0) || 89 | ((b->x + 16) > db->draw.clip.w) 90 | ) 91 | b->xdir *= -1; 92 | if ( 93 | (b->y < 0) || 94 | ((b->y + 16) > db->draw.clip.h) 95 | ) 96 | b->ydir *= -1; 97 | } 98 | 99 | ctx->db_nextpri = (uint8_t *) sprt; 100 | 101 | // Add a TPAGE "primitive" to ensure the GPU finds the ball texture. 102 | DR_TPAGE *tpri = (DR_TPAGE * ) ctx->db_nextpri; 103 | 104 | setDrawTPage( 105 | tpri, 106 | 0, 107 | 0, 108 | getTPage(0, 0, ball_tim.prect->x, ball_tim.prect->y) 109 | ); 110 | addPrim(&(db->ot[OT_LEN - 1]), tpri); 111 | tpri++; 112 | 113 | ctx->db_nextpri = (uint8_t *) tpri; 114 | 115 | // Due to our custom resolver, this will actually call dll_printf() in the 116 | // main executable. 117 | printf("DRAWING BALLS, COUNTER=%d\n", frame++); 118 | } 119 | -------------------------------------------------------------------------------- /libpsn00b/libc/memset.s: -------------------------------------------------------------------------------- 1 | # PSn00bSDK optimized memset 2 | # (C) 2022 spicyjpeg - MPL licensed 3 | 4 | .set noreorder 5 | 6 | .section .text.memset 7 | .global memset 8 | .type memset, @function 9 | memset: 10 | # If more than 16 bytes have to be written then take the "large" path, 11 | # otherwise use the code below. 12 | addiu $t0, $a2, -16 13 | bgtz $t0, .Llarge_fill 14 | move $v0, $a0 # return_value = dest 15 | 16 | # Jump to one of the sb opcodes below. This is basically a cut-down Duff's 17 | # device implementation with no looping. 18 | la $t0, .Lsmall_duff + 0x40 # jump_addr = &small_duff[(16 - count) * 4] 19 | sll $t1, $a2, 2 20 | subu $t0, $t1 21 | addu $a0, $a2 # dest -= 16 - count 22 | jr $t0 23 | addiu $a0, -16 24 | 25 | .Lsmall_duff: 26 | sb $a1, 0x0($a0) 27 | sb $a1, 0x1($a0) 28 | sb $a1, 0x2($a0) 29 | sb $a1, 0x3($a0) 30 | sb $a1, 0x4($a0) 31 | sb $a1, 0x5($a0) 32 | sb $a1, 0x6($a0) 33 | sb $a1, 0x7($a0) 34 | sb $a1, 0x8($a0) 35 | sb $a1, 0x9($a0) 36 | sb $a1, 0xa($a0) 37 | sb $a1, 0xb($a0) 38 | sb $a1, 0xc($a0) 39 | sb $a1, 0xd($a0) 40 | sb $a1, 0xe($a0) 41 | sb $a1, 0xf($a0) 42 | jr $ra 43 | nop 44 | 45 | .Llarge_fill: 46 | # Initialize fast filling by repeating the fill byte 4 times, so it can be 47 | # written 32 bits at a time. 48 | andi $a1, 0xff # ch &= 0xff 49 | sll $t0, $a1, 8 # ch |= (ch << 8) | (ch << 16) | (ch << 24) 50 | or $a1, $t0 51 | sll $t0, $a1, 16 52 | or $a1, $t0 53 | 54 | # Fill the first 1-4 bytes (here the swr instruction does all the magic) 55 | # and update dest and count accordingly. 56 | swr $a1, 0($a0) 57 | andi $t0, $a0, 3 # align = 4 - (dest % 4) 58 | addiu $t0, -4 59 | addu $a2, $t0 # count -= align 60 | subu $a0, $t0 # dest += align 61 | 62 | la $t1, .Llarge_duff 63 | andi $t2, $a2, 3 # remainder = count % 4 64 | subu $a2, $t2 # count -= remainder 65 | 66 | .Llarge_fill_loop: 67 | # If 128 bytes or more still have to be written, skip calculating the jump 68 | # offset and execute the whole block of sw opcodes. 69 | addiu $a2, -0x80 # count -= 0x80 70 | bgez $a2, .Llarge_duff 71 | #nop 72 | 73 | # Jump to one of the sw opcodes below. This is the "full" Duff's device. 74 | subu $t0, $t1, $a2 # jump_addr = &large_duff[0x80 - (count + 0x80)] 75 | jr $t0 76 | addu $a0, $a2 # dest -= 0x80 - (count + 0x80) 77 | 78 | .Llarge_duff: 79 | sw $a1, 0x00($a0) 80 | sw $a1, 0x04($a0) 81 | sw $a1, 0x08($a0) 82 | sw $a1, 0x0c($a0) 83 | sw $a1, 0x10($a0) 84 | sw $a1, 0x14($a0) 85 | sw $a1, 0x18($a0) 86 | sw $a1, 0x1c($a0) 87 | sw $a1, 0x20($a0) 88 | sw $a1, 0x24($a0) 89 | sw $a1, 0x28($a0) 90 | sw $a1, 0x2c($a0) 91 | sw $a1, 0x30($a0) 92 | sw $a1, 0x34($a0) 93 | sw $a1, 0x38($a0) 94 | sw $a1, 0x3c($a0) 95 | sw $a1, 0x40($a0) 96 | sw $a1, 0x44($a0) 97 | sw $a1, 0x48($a0) 98 | sw $a1, 0x4c($a0) 99 | sw $a1, 0x50($a0) 100 | sw $a1, 0x54($a0) 101 | sw $a1, 0x58($a0) 102 | sw $a1, 0x5c($a0) 103 | sw $a1, 0x60($a0) 104 | sw $a1, 0x64($a0) 105 | sw $a1, 0x68($a0) 106 | sw $a1, 0x6c($a0) 107 | sw $a1, 0x70($a0) 108 | sw $a1, 0x74($a0) 109 | sw $a1, 0x78($a0) 110 | sw $a1, 0x7c($a0) 111 | 112 | bgtz $a2, .Llarge_fill_loop 113 | addiu $a0, 0x80 # dest += 0x80 114 | 115 | # Fill the remaining 1-4 bytes, using (again) an unaligned store. 116 | addu $a0, $t2 # last_byte = dest + remainder - 1 117 | jr $ra 118 | swl $a1, -1($a0) 119 | -------------------------------------------------------------------------------- /libpsn00b/include/inline_s.inc: -------------------------------------------------------------------------------- 1 | # Inline GTE macros for GNU assembler (as). 2 | # 3 | # Part of the PSn00bSDK Project by Lameguy64. 4 | # 2019 Meido-Tek Productions 5 | # 6 | # Similar to inline_c.h, it does not require running your object file 7 | # through some silly tool. 8 | 9 | .macro nRTPS 10 | nop 11 | nop 12 | cop2 0x0180001 13 | .endm 14 | 15 | .macro nRTPT 16 | nop 17 | nop 18 | cop2 0x0280030 19 | .endm 20 | 21 | .macro nNCLIP 22 | nop 23 | nop 24 | cop2 0x1400006 25 | .endm 26 | 27 | .macro nAVSZ3 28 | nop 29 | nop 30 | cop2 0x158002D 31 | .endm 32 | 33 | .macro nAVSZ4 34 | nop 35 | nop 36 | cop2 0x168002E 37 | .endm 38 | 39 | .macro nMVMVA sf mx v cv lm 40 | nop 41 | nop 42 | cop2 0x0400012|(\sf<<19)|(\mx<<17)|(\v<<15)|(\cv<<13)|(\lm<<10) 43 | .endm 44 | 45 | .macro nSQR sf 46 | nop 47 | nop 48 | cop2 0x0A00428|(\sf<<19) 49 | .endm 50 | 51 | .macro nnOP sf lm # extra n to prevent conflict with the nop opcode 52 | nop 53 | nop 54 | cop2 0x170000C|(\sf<<19)|(\lm<<10) 55 | .endm 56 | 57 | .macro nNCS 58 | nop 59 | nop 60 | cop2 0x0C8041E 61 | .endm 62 | 63 | .macro nNCT 64 | nop 65 | nop 66 | cop2 0x0D80420 67 | .endm 68 | 69 | .macro nNCCS 70 | nop 71 | nop 72 | cop2 0x108041B 73 | .endm 74 | 75 | .macro nNCCT 76 | nop 77 | nop 78 | cop2 0x118043F 79 | .endm 80 | 81 | .macro nNCDS 82 | nop 83 | nop 84 | cop2 0x0E80413 85 | .endm 86 | 87 | .macro nNCDT 88 | nop 89 | nop 90 | cop2 0x0F80416 91 | .endm 92 | 93 | .macro nCC 94 | nop 95 | nop 96 | cop2 0x138041C 97 | .endm 98 | 99 | .macro nCDP 100 | nop 101 | nop 102 | cop2 0x1280414 103 | .endm 104 | 105 | .macro nDCPL 106 | nop 107 | nop 108 | cop2 0x0680029 109 | .endm 110 | 111 | .macro nDPCS 112 | nop 113 | nop 114 | cop2 0x0780010 115 | .endm 116 | 117 | .macro nDPCT 118 | nop 119 | nop 120 | cop2 0x0180001 121 | .endm 122 | 123 | .macro nINTPL 124 | nop 125 | nop 126 | cop2 0x0980011 127 | .endm 128 | 129 | .macro nGPF sf 130 | nop 131 | nop 132 | cop2 0x190003D|(\sf<<19) 133 | .endm 134 | 135 | .macro nGPL sf 136 | nop 137 | nop 138 | cop2 0x1A0003E|(\sf<<19) 139 | .endm 140 | 141 | # 142 | # Macros without leading nops (for optimized usage) 143 | # 144 | .macro RTPS 145 | cop2 0x0180001 146 | .endm 147 | 148 | .macro RTPT 149 | cop2 0x0280030 150 | .endm 151 | 152 | .macro NCLIP 153 | cop2 0x1400006 154 | .endm 155 | 156 | .macro AVSZ3 157 | cop2 0x158002D 158 | .endm 159 | 160 | .macro AVSZ4 161 | cop2 0x168002E 162 | .endm 163 | 164 | .macro MVMVA sf mx v cv lm 165 | cop2 0x0400012|(\sf<<19)|(\mx<<17)|(\v<<15)|(\cv<<13)|(\lm<<10) 166 | .endm 167 | 168 | .macro SQR sf 169 | cop2 0x0A00428|(\sf<<19) 170 | .endm 171 | 172 | .macro OP sf lm 173 | cop2 0x170000C|(\sf<<19)|(\lm<<10) 174 | .endm 175 | 176 | .macro NCS 177 | cop2 0x0C8041E 178 | .endm 179 | 180 | .macro NCT 181 | cop2 0x0D80420 182 | .endm 183 | 184 | .macro NCCS 185 | cop2 0x108041B 186 | .endm 187 | 188 | .macro NCCT 189 | cop2 0x118043F 190 | .endm 191 | 192 | .macro NCDS 193 | cop2 0x0E80413 194 | .endm 195 | 196 | .macro NCDT 197 | cop2 0x0F80416 198 | .endm 199 | 200 | .macro CC 201 | cop2 0x138041C 202 | .endm 203 | 204 | .macro CDP 205 | cop2 0x1280414 206 | .endm 207 | 208 | .macro DCPL 209 | cop2 0x0680029 210 | .endm 211 | 212 | .macro DPCS 213 | cop2 0x0780010 214 | .endm 215 | 216 | .macro DPCT 217 | cop2 0x0180001 218 | .endm 219 | 220 | .macro INTPL 221 | cop2 0x0980011 222 | .endm 223 | 224 | .macro GPF sf 225 | cop2 0x190003D|(\sf<<19) 226 | .endm 227 | 228 | .macro GPL sf 229 | cop2 0x1A0003E|(\sf<<19) 230 | .endm 231 | -------------------------------------------------------------------------------- /libpsn00b/cmake/sdk.cmake: -------------------------------------------------------------------------------- 1 | # PSn00bSDK toolchain setup file for CMake 2 | # (C) 2021-2022 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | set( 7 | PSN00BSDK_TC "" 8 | CACHE PATH "Path to the GCC toolchain's installation directory (if not in PATH)" 9 | ) 10 | set( 11 | PSN00BSDK_TARGET mipsel-none-elf 12 | CACHE STRING "GCC toolchain target triplet" 13 | ) 14 | 15 | ## CMake configuration 16 | 17 | set(CMAKE_SYSTEM_NAME Generic) 18 | set(CMAKE_SYSTEM_PROCESSOR mipsel) 19 | 20 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 21 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 22 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 23 | #set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) 24 | 25 | # Tell CMake not to run the linker when compiling test programs, and to pass 26 | # toolchain settings to the generated test projects. This dodges missing C++ 27 | # standard library errors. 28 | set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) 29 | set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES PSN00BSDK_TC PSN00BSDK_TARGET PSN00BSDK_VERSION) 30 | 31 | # Always generate compile_commands.json alongside build scripts. This allows 32 | # some IDEs and tools (such as clangd) to automatically configure include 33 | # directories and other options. 34 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 35 | 36 | ## Toolchain path setup 37 | 38 | # Attempt to find GCC using a list of common installation locations. 39 | # PSN00BSDK_TC can be left unset if the toolchain can be found in any of these 40 | # or in the PATH environment variable. 41 | find_program( 42 | _gcc ${PSN00BSDK_TARGET}-gcc 43 | HINTS 44 | ${PSN00BSDK_TC}/bin 45 | ${PSN00BSDK_TC}/../bin 46 | # Same as ${CMAKE_INSTALL_PREFIX}/bin 47 | ${CMAKE_CURRENT_LIST_DIR}/../../../bin 48 | # Same as ${CMAKE_INSTALL_PREFIX}/${PSN00BSDK_TARGET}/bin 49 | ${CMAKE_CURRENT_LIST_DIR}/../../../${PSN00BSDK_TARGET}/bin 50 | PATHS 51 | "C:/Program Files/${PSN00BSDK_TARGET}/bin" 52 | "C:/Program Files (x86)/${PSN00BSDK_TARGET}/bin" 53 | "C:/${PSN00BSDK_TARGET}/bin" 54 | /opt/${PSN00BSDK_TARGET}/bin 55 | /usr/local/${PSN00BSDK_TARGET}/bin 56 | /usr/${PSN00BSDK_TARGET}/bin 57 | NO_CACHE REQUIRED 58 | ) 59 | cmake_path(GET _gcc PARENT_PATH _bin) 60 | cmake_path(GET _bin PARENT_PATH _toolchain) 61 | 62 | # Overwrite the empty cache entry, so it won't have to be found again. 63 | if(NOT IS_DIRECTORY PSN00BSDK_TC) 64 | set( 65 | PSN00BSDK_TC ${_toolchain} 66 | CACHE PATH "Path to the GCC toolchain's installation directory (if not in PATH)" 67 | FORCE 68 | ) 69 | endif() 70 | 71 | ## Toolchain executables 72 | 73 | # As we have overridden ${CMAKE_EXECUTABLE_SUFFIX} we can't rely on it to 74 | # determine the host OS extension for executables. A workaround is to extract 75 | # the extension from the path returned by find_program() using a regex. 76 | set(_prefix ${_bin}/${PSN00BSDK_TARGET}) 77 | string(REGEX MATCH ".+-gcc(.*)$" _dummy ${_gcc}) 78 | 79 | set(CMAKE_ASM_COMPILER ${_prefix}-gcc${CMAKE_MATCH_1}) 80 | set(CMAKE_C_COMPILER ${_prefix}-gcc${CMAKE_MATCH_1}) 81 | set(CMAKE_CXX_COMPILER ${_prefix}-g++${CMAKE_MATCH_1}) 82 | set(CMAKE_AR ${_prefix}-ar${CMAKE_MATCH_1}) 83 | set(CMAKE_LINKER ${_prefix}-ld${CMAKE_MATCH_1}) 84 | set(CMAKE_RANLIB ${_prefix}-ranlib${CMAKE_MATCH_1}) 85 | set(CMAKE_OBJCOPY ${_prefix}-objcopy${CMAKE_MATCH_1}) 86 | set(CMAKE_SIZE ${_prefix}-size${CMAKE_MATCH_1}) 87 | set(CMAKE_STRIP ${_prefix}-strip${CMAKE_MATCH_1}) 88 | set(TOOLCHAIN_NM ${_prefix}-nm${CMAKE_MATCH_1}) 89 | 90 | ## SDK setup 91 | 92 | # Continue initialization by running internal_setup.cmake after project() is 93 | # invoked. 94 | set(CMAKE_PROJECT_INCLUDE ${CMAKE_CURRENT_LIST_DIR}/internal_setup.cmake) 95 | -------------------------------------------------------------------------------- /libpsn00b/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # libpsn00b build script 2 | # (C) 2021-2022 spicyjpeg - MPL licensed 3 | 4 | cmake_minimum_required(VERSION 3.21) 5 | 6 | # ${PROJECT_SOURCE_DIR} is not available until project() is called. 7 | set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/cmake/sdk.cmake) 8 | 9 | project( 10 | libpsn00b 11 | LANGUAGES C CXX ASM 12 | DESCRIPTION "PSn00bSDK libraries" 13 | HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" 14 | ) 15 | 16 | include(${PROJECT_SOURCE_DIR}/cmake/flags.cmake) 17 | 18 | ## Libraries 19 | 20 | set(_types EXECUTABLE_GPREL EXECUTABLE_NOGPREL SHARED_LIBRARY) 21 | set(_suffixes _exe_gprel _exe_nogprel _dll) 22 | 23 | foreach(_library IN LISTS PSN00BSDK_LIBRARIES) 24 | # libc needs special handling due to the different directory name. 25 | if(${_library} STREQUAL "c") 26 | set(_path ${PROJECT_SOURCE_DIR}/libc) 27 | else() 28 | set(_path ${PROJECT_SOURCE_DIR}/${_library}) 29 | endif() 30 | 31 | file( 32 | GLOB_RECURSE _sources 33 | ${_path}/*.s ${_path}/*.c ${_path}/*.cpp 34 | ) 35 | 36 | # Build a separate version of the library for each supported target type 37 | # and create a virtual target that links the appropriate version of the 38 | # library. 39 | add_library(${_library} INTERFACE) 40 | 41 | foreach(_type _suffix IN ZIP_LISTS _types _suffixes) 42 | set(_name ${_library}${_suffix}) 43 | list(APPEND _libraries ${_name}) 44 | 45 | psn00bsdk_add_library(${_name} STATIC ${_sources}) 46 | set_target_properties(${_name} PROPERTIES PSN00BSDK_TARGET_TYPE ${_type}) 47 | target_link_libraries( 48 | ${_library} INTERFACE 49 | $<$>,${_type}>:${_name}> 50 | ) 51 | 52 | target_compile_definitions(${_name} PRIVATE SDK_LIBRARY_NAME="${_library}") 53 | endforeach() 54 | endforeach() 55 | 56 | # Add binary assets to each version of the libraries. 57 | foreach(_suffix IN LISTS _suffixes) 58 | psn00bsdk_target_incbin( 59 | psxgpu${_suffix} PRIVATE _gpu_debug_font 60 | psxgpu/dbugfont.tim 61 | ) 62 | endforeach() 63 | 64 | ## Installation 65 | 66 | install( 67 | TARGETS psn00bsdk ${PSN00BSDK_LIBRARIES} ${_libraries} 68 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpsn00b/$> 69 | EXPORT libpsn00b 70 | ) 71 | install( 72 | DIRECTORY cmake ldscripts 73 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpsn00b 74 | ) 75 | install( 76 | DIRECTORY include/ 77 | DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libpsn00b 78 | ) 79 | 80 | # Generate build.json. This file is used to determine the SDK version after 81 | # installation and may contain additional metadata about the build. 82 | file( 83 | CONFIGURE 84 | OUTPUT build.json 85 | CONTENT [[{ 86 | "version": "${PSN00BSDK_VERSION}", 87 | "build_date": "${PSN00BSDK_BUILD_DATE}", 88 | "git_tag": "${PSN00BSDK_GIT_TAG}", 89 | "git_commit": "${PSN00BSDK_GIT_COMMIT}", 90 | "cmake_version": "${CMAKE_VERSION}", 91 | "host_system": "${CMAKE_HOST_SYSTEM_NAME}" 92 | }]] 93 | ESCAPE_QUOTES 94 | NEWLINE_STYLE LF 95 | ) 96 | install( 97 | FILES ${PROJECT_BINARY_DIR}/build.json 98 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpsn00b 99 | ) 100 | 101 | # Generate an import script, which will be used by the setup script to find the 102 | # libraries. Note that CMake actually generates two separate import scripts 103 | # (one setting configuration-specific options), so this won't create conflicts 104 | # once the debug and release builds are merged into the same installation tree. 105 | install( 106 | EXPORT libpsn00b 107 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpsn00b/cmake 108 | #EXPORT_LINK_INTERFACE_LIBRARIES 109 | ) 110 | -------------------------------------------------------------------------------- /libpsn00b/psxgte/vector.s: -------------------------------------------------------------------------------- 1 | .set noreorder 2 | .set noat 3 | 4 | .include "gtereg.inc" 5 | .include "inline_s.inc" 6 | 7 | .section .text.Square0 8 | .global Square0 9 | .type Square0, @function 10 | Square0: 11 | # a0 - Pointer to input vector (v0) 12 | # a1 - Pointer to output vector (v1) 13 | 14 | lwc2 C2_IR1, 0($a0) 15 | lwc2 C2_IR2, 4($a0) 16 | lwc2 C2_IR3, 8($a0) 17 | 18 | nSQR(0) 19 | 20 | swc2 C2_IR1, 0($a1) 21 | swc2 C2_IR2, 4($a1) 22 | swc2 C2_IR3, 8($a1) 23 | 24 | jr $ra 25 | nop 26 | 27 | .section .text.VectorNormalS 28 | .global VectorNormalS 29 | .type VectorNormalS, @function 30 | VectorNormalS: 31 | 32 | lw $t0, 0($a0) 33 | lw $t1, 4($a0) 34 | lw $t2, 8($a0) 35 | 36 | mtc2 $t0, C2_IR1 37 | mtc2 $t1, C2_IR2 38 | mtc2 $t2, C2_IR3 39 | 40 | nSQR(0) 41 | 42 | mfc2 $t3, C2_MAC1 43 | mfc2 $t4, C2_MAC2 44 | mfc2 $t5, C2_MAC3 45 | 46 | add $t3, $t4 47 | add $v0, $t3, $t5 48 | mtc2 $v0, C2_LZCS 49 | nop 50 | nop 51 | mfc2 $v1, C2_LZCR 52 | 53 | addiu $at, $0 , -2 54 | and $v1, $at 55 | 56 | addiu $t6, $0 , 0x1f 57 | sub $t6, $v1 58 | sra $t6, 1 59 | addiu $t3, $v1, -24 60 | 61 | bltz $t3, .Lvalue_neg 62 | nop 63 | b .Lvalue_pos 64 | sllv $t4, $v0, $t3 65 | .Lvalue_neg: 66 | addiu $t3, $0 , 24 67 | sub $t3, $v1 68 | srav $t4, $v0, $t3 69 | .Lvalue_pos: 70 | addi $t4, -64 71 | sll $t4, 1 72 | 73 | la $t5, _norm_table 74 | addu $t5, $t4 75 | lh $t5, 0($t5) 76 | 77 | mtc2 $t0, C2_IR1 78 | mtc2 $t1, C2_IR2 79 | mtc2 $t2, C2_IR3 80 | mtc2 $t5, C2_IR0 81 | 82 | nGPF(0) 83 | 84 | mfc2 $t0, C2_MAC1 85 | mfc2 $t1, C2_MAC2 86 | mfc2 $t2, C2_MAC3 87 | 88 | sra $t0, $t6 89 | sra $t1, $t6 90 | sra $t2, $t6 91 | 92 | sh $t0, 0($a1) 93 | sh $t1, 2($a1) 94 | jr $ra 95 | sh $t2, 4($a1) 96 | 97 | .section .data._norm_table 98 | .type _norm_table, @object 99 | _norm_table: 100 | .hword 0x1000, 0x0fe0, 0x0fc1, 0x0fa3, 0x0f85, 0x0f68, 0x0f4c, 0x0f30 101 | .hword 0x0f15, 0x0efb, 0x0ee1, 0x0ec7, 0x0eae, 0x0e96, 0x0e7e, 0x0e66 102 | .hword 0x0e4f, 0x0e38, 0x0e22, 0x0e0c, 0x0df7, 0x0de2, 0x0dcd, 0x0db9 103 | .hword 0x0da5, 0x0d91, 0x0d7e, 0x0d6b, 0x0d58, 0x0d45, 0x0d33, 0x0d21 104 | .hword 0x0d10, 0x0cff, 0x0cee, 0x0cdd, 0x0ccc, 0x0cbc, 0x0cac, 0x0c9c 105 | .hword 0x0c8d, 0x0c7d, 0x0c6e, 0x0c5f, 0x0c51, 0x0c42, 0x0c34, 0x0c26 106 | .hword 0x0c18, 0x0c0a, 0x0bfd, 0x0bef, 0x0be2, 0x0bd5, 0x0bc8, 0x0bbb 107 | .hword 0x0baf, 0x0ba2, 0x0b96, 0x0b8a, 0x0b7e, 0x0b72, 0x0b67, 0x0b5b 108 | .hword 0x0b50, 0x0b45, 0x0b39, 0x0b2e, 0x0b24, 0x0b19, 0x0b0e, 0x0b04 109 | .hword 0x0af9, 0x0aef, 0x0ae5, 0x0adb, 0x0ad1, 0x0ac7, 0x0abd, 0x0ab4 110 | .hword 0x0aaa, 0x0aa1, 0x0a97, 0x0a8e, 0x0a85, 0x0a7c, 0x0a73, 0x0a6a 111 | .hword 0x0a61, 0x0a59, 0x0a50, 0x0a47, 0x0a3f, 0x0a37, 0x0a2e, 0x0a26 112 | .hword 0x0a1e, 0x0a16, 0x0a0e, 0x0a06, 0x09fe, 0x09f6, 0x09ef, 0x09e7 113 | .hword 0x09e0, 0x09d8, 0x09d1, 0x09c9, 0x09c2, 0x09bb, 0x09b4, 0x09ad 114 | .hword 0x09a5, 0x099e, 0x0998, 0x0991, 0x098a, 0x0983, 0x097c, 0x0976 115 | .hword 0x096f, 0x0969, 0x0962, 0x095c, 0x0955, 0x094f, 0x0949, 0x0943 116 | .hword 0x093c, 0x0936, 0x0930, 0x092a, 0x0924, 0x091e, 0x0918, 0x0912 117 | .hword 0x090d, 0x0907, 0x0901, 0x08fb, 0x08f6, 0x08f0, 0x08eb, 0x08e5 118 | .hword 0x08e0, 0x08da, 0x08d5, 0x08cf, 0x08ca, 0x08c5, 0x08bf, 0x08ba 119 | .hword 0x08b5, 0x08b0, 0x08ab, 0x08a6, 0x08a1, 0x089c, 0x0897, 0x0892 120 | .hword 0x088d, 0x0888, 0x0883, 0x087e, 0x087a, 0x0875, 0x0870, 0x086b 121 | .hword 0x0867, 0x0862, 0x085e, 0x0859, 0x0855, 0x0850, 0x084c, 0x0847 122 | .hword 0x0843, 0x083e, 0x083a, 0x0836, 0x0831, 0x082d, 0x0829, 0x0824 123 | .hword 0x0820, 0x081c, 0x0818, 0x0814, 0x0810, 0x080c, 0x0808, 0x0804 124 | -------------------------------------------------------------------------------- /examples/system/tty/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * LibPSn00b Example Programs 3 | * 4 | * Teletype Example 5 | * 2020 - 2021 Meido-Tek Productions / PSn00bSDK Project 6 | * 7 | * This example showcases the uses of tty through stdio facilities. If you've 8 | * written text console applications before, this one is not too dissimilar to 9 | * that. Escape codes for formatting and such should work as this is more 10 | * dependant on the terminal program used than the PS1 console itself. 11 | * 12 | * 13 | * Example by Lameguy64 14 | * 15 | * Changelog: 16 | * 17 | * May 10, 2021 - Variable types updated for psxgpu.h changes. 18 | * 19 | * April 23, 2020 - Initial version. 20 | * 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | /* Memory viewer thing, you may use this in your own applications 29 | * for testing or analysis */ 30 | void memory_browser(unsigned int addr) 31 | { 32 | int i,j,key; 33 | unsigned char *ptr,*pptr; 34 | 35 | while(1) 36 | { 37 | /* Set cursor position to top-left */ 38 | printf("\033[1;1H"); 39 | printf("MEMVIEW 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 0123456789ABCDEF"); 40 | 41 | ptr = (unsigned char*)addr; 42 | 43 | /* Print contents from current location of memory */ 44 | for(j=0; j<23; j++) 45 | { 46 | printf("\n%04X: ", (unsigned int)ptr); 47 | pptr = ptr; 48 | for(i=0; i<16; i++) 49 | { 50 | printf("%02X ", *ptr); 51 | ptr++; 52 | } 53 | printf(" "); 54 | for(i=0; i<16; i++) 55 | { 56 | if(( *pptr < 32 ) || ( *pptr > 127 ) ) 57 | { 58 | printf("."); 59 | } 60 | else 61 | { 62 | printf("%c", *pptr); 63 | } 64 | pptr++; 65 | } 66 | } 67 | 68 | /* Parse input */ 69 | while(1) 70 | { 71 | key = getchar(); 72 | if( key == 0x1B ) 73 | { 74 | key = getchar(); 75 | 76 | if( key == 0x5B ) 77 | { 78 | key = getchar(); 79 | if( key == 0x41 ) // Up 80 | { 81 | addr -= 16; 82 | break; 83 | } 84 | else if( key == 0x42 ) // Down 85 | { 86 | addr += 16; 87 | break; 88 | } 89 | if( key == 0x35 ) // Page up 90 | { 91 | addr -= 16*23; 92 | break; 93 | } 94 | else if( key == 0x36 ) // Page down 95 | { 96 | addr += 16*23; 97 | break; 98 | } 99 | } 100 | } 101 | 102 | } 103 | } 104 | 105 | } 106 | 107 | 108 | int main(int argc, const char *argv[]) 109 | { 110 | int i; 111 | char strbuff[32]; 112 | 113 | /* Mostly to get interrupts going for this example */ 114 | ResetGraph( 0 ); 115 | 116 | /* Uncomment if you don't have an environment that provides tty access 117 | * by default */ 118 | //AddSIO(115200); 119 | 120 | /* A standby loop until 'Y' is entered */ 121 | while(1) 122 | { 123 | /* Print banner */ 124 | printf("Hello world!\n"); 125 | printf("Press 'Y' to proceed with this demonstration.\n"); 126 | 127 | /* Get input for a Y character */ 128 | i = getchar(); 129 | if( tolower(i) == 'y' ) 130 | break; 131 | } 132 | 133 | /* Do a classic text input prompt and display the inputted text */ 134 | printf("Enter a string, any string (no more than 32 characters):\n"); 135 | gets(strbuff); 136 | 137 | printf("You've entered: %s\n\n", strbuff); 138 | 139 | /* Prompt entering into the memory browser */ 140 | printf("Press a key to enter a memory browser demo...\n"); 141 | printf("Make sure your terminal or text console supports vt100 escape codes!\n"); 142 | getchar(); 143 | 144 | /* Start the memory browser interface */ 145 | memory_browser(0x80010000); 146 | 147 | return 0; 148 | } 149 | -------------------------------------------------------------------------------- /libpsn00b/psxgte/squareroot.s: -------------------------------------------------------------------------------- 1 | .set noreorder 2 | 3 | .include "gtereg.inc" 4 | .include "inline_s.inc" 5 | 6 | .section .text.SquareRoot12 7 | .global SquareRoot12 8 | .type SquareRoot12, @function 9 | SquareRoot12: 10 | mtc2 $a0, C2_LZCS 11 | nop 12 | nop 13 | mfc2 $v0, C2_LZCR 14 | beq $v0, 32, .Lbad_sqr12 15 | nop 16 | andi $t0, $v0, 0x1 17 | addiu $v1, $0 , -2 18 | and $t2, $v0, $v1 19 | li $t1, 19 20 | sub $t1, $t2 21 | sra $t1, 1 22 | addi $t3, $t2, -24 23 | bltz $t3, .Lvalue_less12 24 | nop 25 | sllv $t4, $a0, $t3 26 | b .Lvalue_greater12 27 | .Lvalue_less12: 28 | addiu $t3, $0 , 24 29 | sub $t3, $t2 30 | srav $t4, $a0, $t3 31 | .Lvalue_greater12: 32 | addi $t4, -64 33 | sll $t4, 1 34 | la $t5, _sqrt_table 35 | addu $t5, $t4 36 | lh $t5, 0($t5) 37 | nop 38 | 39 | bltz $t1, .L1594c 40 | nop 41 | jr $ra 42 | sllv $v0, $t5, $t1 43 | 44 | .L1594c: 45 | sub $t1, $0 , $t1 46 | jr $ra 47 | srl $v0, $t5, $t1 48 | 49 | .Lbad_sqr12: 50 | jr $ra 51 | move $v0, $0 52 | 53 | .section .text.SquareRoot0 54 | .global SquareRoot0 55 | .type SquareRoot0, @function 56 | SquareRoot0: 57 | mtc2 $a0, C2_LZCS 58 | nop 59 | nop 60 | mfc2 $v0, C2_LZCR 61 | beq $v0, 32, .Lbad_sqr 62 | nop 63 | andi $t0, $v0, 0x1 64 | addiu $v1, $0 , -2 65 | and $t2, $v0, $v1 66 | li $t1, 31 67 | sub $t1, $t2 68 | sra $t1, 1 69 | addi $t3, $t2, -24 70 | bltz $t3, .Lvalue_less 71 | nop 72 | sllv $t4, $a0, $t3 73 | b .Lvalue_greater 74 | .Lvalue_less: 75 | addiu $t3, $0 , 24 76 | sub $t3, $t2 77 | srav $t4, $a0, $t3 78 | .Lvalue_greater: 79 | addi $t4, -64 80 | sll $t4, 1 81 | la $t5, _sqrt_table 82 | addu $t5, $t4 83 | lh $t5, 0($t5) 84 | nop 85 | sllv $t5, $t5, $t1 86 | jr $ra 87 | srl $v0, $t5, 12 88 | .Lbad_sqr: 89 | jr $ra 90 | move $v0, $0 91 | 92 | .section .data._sqrt_table 93 | .type _sqrt_table, @object 94 | _sqrt_table: 95 | .hword 0x1000, 0x101f, 0x103f, 0x105e, 0x107e, 0x109c, 0x10bb, 0x10da 96 | .hword 0x10f8, 0x1116, 0x1134, 0x1152, 0x116f, 0x118c, 0x11a9, 0x11c6 97 | .hword 0x11e3, 0x1200, 0x121c, 0x1238, 0x1254, 0x1270, 0x128c, 0x12a7 98 | .hword 0x12c2, 0x12de, 0x12f9, 0x1314, 0x132e, 0x1349, 0x1364, 0x137e 99 | .hword 0x1398, 0x13b2, 0x13cc, 0x13e6, 0x1400, 0x1419, 0x1432, 0x144c 100 | .hword 0x1465, 0x147e, 0x1497, 0x14b0, 0x14c8, 0x14e1, 0x14f9, 0x1512 101 | .hword 0x152a, 0x1542, 0x155a, 0x1572, 0x158a, 0x15a2, 0x15b9, 0x15d1 102 | .hword 0x15e8, 0x1600, 0x1617, 0x162e, 0x1645, 0x165c, 0x1673, 0x1689 103 | .hword 0x16a0, 0x16b7, 0x16cd, 0x16e4, 0x16fa, 0x1710, 0x1726, 0x173c 104 | .hword 0x1752, 0x1768, 0x177e, 0x1794, 0x17aa, 0x17bf, 0x17d5, 0x17ea 105 | .hword 0x1800, 0x1815, 0x182a, 0x183f, 0x1854, 0x1869, 0x187e, 0x1893 106 | .hword 0x18a8, 0x18bd, 0x18d1, 0x18e6, 0x18fa, 0x190f, 0x1923, 0x1938 107 | .hword 0x194c, 0x1960, 0x1974, 0x1988, 0x199c, 0x19b0, 0x19c4, 0x19d8 108 | .hword 0x19ec, 0x1a00, 0x1a13, 0x1a27, 0x1a3a, 0x1a4e, 0x1a61, 0x1a75 109 | .hword 0x1a88, 0x1a9b, 0x1aae, 0x1ac2, 0x1ad5, 0x1ae8, 0x1afb, 0x1b0e 110 | .hword 0x1b21, 0x1b33, 0x1b46, 0x1b59, 0x1b6c, 0x1b7e, 0x1b91, 0x1ba3 111 | .hword 0x1bb6, 0x1bc8, 0x1bdb, 0x1bed, 0x1c00, 0x1c12, 0x1c24, 0x1c36 112 | .hword 0x1c48, 0x1c5a, 0x1c6c, 0x1c7e, 0x1c90, 0x1ca2, 0x1cb4, 0x1cc6 113 | .hword 0x1cd8, 0x1ce9, 0x1cfb, 0x1d0d, 0x1d1e, 0x1d30, 0x1d41, 0x1d53 114 | .hword 0x1d64, 0x1d76, 0x1d87, 0x1d98, 0x1daa, 0x1dbb, 0x1dcc, 0x1ddd 115 | .hword 0x1dee, 0x1e00, 0x1e11, 0x1e22, 0x1e33, 0x1e43, 0x1e54, 0x1e65 116 | .hword 0x1e76, 0x1e87, 0x1e98, 0x1ea8, 0x1eb9, 0x1eca, 0x1eda, 0x1eeb 117 | .hword 0x1efb, 0x1f0c, 0x1f1c, 0x1f2d, 0x1f3d, 0x1f4e, 0x1f5e, 0x1f6e 118 | .hword 0x1f7e, 0x1f8f, 0x1f9f, 0x1faf, 0x1fbf, 0x1fcf, 0x1fdf, 0x1fef 119 | -------------------------------------------------------------------------------- /examples/system/timer/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | /* OT and Packet Buffer sizes */ 9 | #define OT_LEN 256 10 | #define PACKET_LEN 1024 11 | 12 | /* Screen resolution */ 13 | #define SCREEN_XRES 320 14 | #define SCREEN_YRES 240 15 | 16 | /* Screen center position */ 17 | #define CENTERX SCREEN_XRES>>1 18 | #define CENTERY SCREEN_YRES>>1 19 | 20 | 21 | /* Double buffer structure */ 22 | typedef struct { 23 | DISPENV disp; /* Display environment */ 24 | DRAWENV draw; /* Drawing environment */ 25 | } DB; 26 | 27 | /* Double buffer variables */ 28 | DB db[2]; 29 | int db_active = 0; 30 | 31 | 32 | /* Function declarations */ 33 | void init(); 34 | void display(); 35 | 36 | 37 | volatile int timer_calls = 0; 38 | 39 | void timer_func() 40 | { 41 | timer_calls++; 42 | } 43 | 44 | volatile int vsync_count = 0; 45 | volatile int tick_count = 0; 46 | volatile int tick_value = 0; 47 | 48 | void vsync_func() 49 | { 50 | vsync_count++; 51 | if( vsync_count > 60 ) 52 | { 53 | tick_value = timer_calls-tick_count; 54 | tick_count = timer_calls; 55 | vsync_count = 0; 56 | } 57 | } 58 | 59 | /* Main function */ 60 | int main() { 61 | 62 | int counter; 63 | 64 | /* Init graphics and GTE */ 65 | init(); 66 | 67 | 68 | EnterCriticalSection(); 69 | //SetRCnt(RCntCNT2, 0xF040, RCntMdINTR); 70 | 71 | // NTSC clock base 72 | counter = 4304000/560; 73 | 74 | // PAL clock base 75 | //counter = 5163000/560; 76 | 77 | SetRCnt(RCntCNT2, counter, RCntMdINTR); 78 | TIMER_CTRL(2) = 0x1E58; 79 | InterruptCallback(6, timer_func); 80 | StartRCnt(RCntCNT2); 81 | ChangeClearRCnt(2, 0); 82 | ExitCriticalSection(); 83 | 84 | VSyncCallback(vsync_func); 85 | 86 | /* Main loop */ 87 | while( 1 ) { 88 | 89 | FntPrint(-1, "TIMER COUNT=%d\n", timer_calls); 90 | FntPrint(-1, "TICKS/SEC=%d\n", tick_value); 91 | 92 | /* Swap buffers and draw text */ 93 | display(); 94 | 95 | } 96 | 97 | return 0; 98 | 99 | } 100 | 101 | void init() { 102 | 103 | /* Reset the GPU, also installs a VSync event handler */ 104 | ResetGraph( 0 ); 105 | //SetVideoMode(MODE_PAL); 106 | 107 | /* Set display and draw environment areas */ 108 | /* (display and draw areas must be separate, otherwise hello flicker) */ 109 | SetDefDispEnv( &db[0].disp, 0, 0, SCREEN_XRES, SCREEN_YRES ); 110 | SetDefDrawEnv( &db[0].draw, SCREEN_XRES, 0, SCREEN_XRES, SCREEN_YRES ); 111 | 112 | /* Enable draw area clear and dither processing */ 113 | setRGB0( &db[0].draw, 63, 0, 127 ); 114 | db[0].draw.isbg = 1; 115 | db[0].draw.dtd = 1; 116 | 117 | 118 | /* Define the second set of display/draw environments */ 119 | SetDefDispEnv( &db[1].disp, SCREEN_XRES, 0, SCREEN_XRES, SCREEN_YRES ); 120 | SetDefDrawEnv( &db[1].draw, 0, 0, SCREEN_XRES, SCREEN_YRES ); 121 | 122 | //db[0].disp.screen.y = 24; 123 | //db[1].disp.screen.y = 24; 124 | 125 | setRGB0( &db[1].draw, 63, 0, 127 ); 126 | db[1].draw.isbg = 1; 127 | db[1].draw.dtd = 1; 128 | 129 | 130 | /* Apply the drawing environment of the first double buffer */ 131 | PutDrawEnv( &db[0].draw ); 132 | 133 | FntLoad(960, 0); 134 | FntOpen(0, 8, 320, 216, 0, 100); 135 | 136 | } 137 | 138 | void display() { 139 | 140 | FntFlush(-1); 141 | 142 | /* Wait for GPU to finish drawing and vertical retrace */ 143 | DrawSync( 0 ); 144 | VSync( 0 ); 145 | 146 | /* Swap buffers */ 147 | db_active ^= 1; 148 | 149 | /* Apply display/drawing environments */ 150 | PutDrawEnv( &db[db_active].draw ); 151 | PutDispEnv( &db[db_active].disp ); 152 | 153 | /* Enable display */ 154 | SetDispMask( 1 ); 155 | 156 | } --------------------------------------------------------------------------------