From beb76e4dd362374b8f42cd971d394bba1074cd8d Mon Sep 17 00:00:00 2001 From: Xavier Del Campo Romero Date: Sat, 5 Jul 2025 02:34:11 +0200 Subject: Replace .include with #include For some reason, both mipsel-unknown-elf-gcc 8.2.0 and mipsel-non-elf 15.1.0 were unable to resolve .include assembler directives. As a workaround, it is still possible to use the preprocessor, and therefore the usual #include preprocessor directive. However, this requires the assembly files to use the uppercase .S file extension. --- examples/demos/n00bdemo/plasmagen.S | 181 ++++++++++++++ examples/demos/n00bdemo/plasmagen.s | 181 -------------- examples/graphics/tilesasm/drawtiles.S | 272 +++++++++++++++++++++ examples/graphics/tilesasm/drawtiles.s | 272 --------------------- examples/lowlevel/cartrom/CMakeLists.txt | 2 +- examples/lowlevel/cartrom/rom.S | 402 +++++++++++++++++++++++++++++++ examples/lowlevel/cartrom/rom.s | 402 ------------------------------- 7 files changed, 856 insertions(+), 856 deletions(-) create mode 100644 examples/demos/n00bdemo/plasmagen.S delete mode 100644 examples/demos/n00bdemo/plasmagen.s create mode 100644 examples/graphics/tilesasm/drawtiles.S delete mode 100644 examples/graphics/tilesasm/drawtiles.s create mode 100644 examples/lowlevel/cartrom/rom.S delete mode 100644 examples/lowlevel/cartrom/rom.s (limited to 'examples') diff --git a/examples/demos/n00bdemo/plasmagen.S b/examples/demos/n00bdemo/plasmagen.S new file mode 100644 index 0000000..07b3f48 --- /dev/null +++ b/examples/demos/n00bdemo/plasmagen.S @@ -0,0 +1,181 @@ +.set noreorder + +.set POLYG4_tag, 0 +.set POLYG4_rgb0, 4 +.set POLYG4_xy0, 8 +.set POLYG4_rgb1, 12 +.set POLYG4_xy1, 16 +.set POLYG4_rgb2, 20 +.set POLYG4_xy2, 24 +.set POLYG4_rgb3, 28 +.set POLYG4_xy3, 32 +.set POLYG4_len, 36 + +# a0 - Plasma output +# a1 - Counter +.global genPlasma +.type genPlasma, @function +genPlasma: + move $t1, $0 + +.gn_y_loop: move $t0, $0 + +.gn_x_loop: la $v0, plasma_sin1 + sll $v1, $t0, 1 + addu $v1, $v0 + lh $v0, 0($v1) + + la $a2, plasma_sin2 + sll $v1, $t1, 1 + addu $v1, $a2 + lh $v1, 0($v1) + nop + add $v0, $v1 + + add $v1, $t0, $t1 + add $v1, $a1 + divu $v1, 90 + la $a2, plasma_sin3 + mfhi $v1 + + sll $v1, 1 + addu $v1, $a2 + lh $v1, 0($v1) + nop + add $v0, $v1 + + andi $v0, 0xff + + sb $v0, 0($a0) + addu $a0, 1 + + addiu $t0, 1 + blt $t0, 41, .gn_x_loop + nop + + addiu $t1, 1 + blt $t1, 31, .gn_y_loop + nop + + jr $ra + nop + + +# a0 - OT entry +# a1 - Primitive address +# a2 - Plasma map source +.global sortPlasma +.type sortPlasma, @function +sortPlasma: + move $t1, $0 + +.y_loop: + move $t0, $0 + +.x_loop: + lbu $v0, 0($a2) + addiu $a2, 1 + la $a3, plasma_colors + sll $v0, 2 + addu $v0, $a3 + lw $v0, 0($v0) + + lui $v1, 0x3800 + or $v0, $v1 + sw $v0, POLYG4_rgb0($a1) + + + lbu $v0, 0($a2) + nop + sll $v0, 2 + addu $v0, $a3 + lw $v0, 0($v0) + nop + sw $v0, POLYG4_rgb1($a1) + + + lbu $v0, 40($a2) + nop + sll $v0, 2 + addu $v0, $a3 + lw $v0, 0($v0) + nop + sw $v0, POLYG4_rgb2($a1) + + + lbu $v0, 41($a2) + nop + sll $v0, 2 + addu $v0, $a3 + lw $v0, 0($v0) + nop + sw $v0, POLYG4_rgb3($a1) + + + sll $v0, $t0, 4 + andi $v0, 0xffff + sll $v1, $t1, 20 + or $v0, $v1 + sw $v0, POLYG4_xy0($a1) + + sll $v0, $t0, 4 + andi $v0, 0xffff + addi $v0, 16 + sll $v1, $t1, 20 + or $v0, $v1 + sw $v0, POLYG4_xy1($a1) + + sll $v0, $t0, 4 + andi $v0, 0xffff + sll $v1, $t1, 4 + addi $v1, 16 + sll $v1, 16 + or $v0, $v1 + sw $v0, POLYG4_xy2($a1) + + sll $v0, $t0, 4 + andi $v0, 0xffff + addi $v0, 16 + sll $v1, $t1, 4 + addi $v1, 16 + sll $v1, 16 + or $v0, $v1 + sw $v0, POLYG4_xy3($a1) + + .set noat + + lui $v1, 0x0800 + lw $v0, 0($a0) + lui $at, 0xff00 + and $v1, $at + lui $at, 0x00ff + or $at, 0xffff + and $v0, $at + or $v1, $v0 + sw $v1, 0($a1) + lw $v0, 0($a0) + and $a1, $at + lui $at, 0xff00 + and $v0, $at + or $v0, $a1 + sw $v0, 0($a0) + + .set at + + lui $v0, 0x8000 + or $a1, $v0 + addiu $a1, POLYG4_len + + + addiu $t0, 1 + blt $t0, 40, .x_loop + nop + + addiu $a2, 1 + addiu $t1, 1 + blt $t1, 30, .y_loop + nop + + + jr $ra + move $v0, $a1 \ No newline at end of file diff --git a/examples/demos/n00bdemo/plasmagen.s b/examples/demos/n00bdemo/plasmagen.s deleted file mode 100644 index 07b3f48..0000000 --- a/examples/demos/n00bdemo/plasmagen.s +++ /dev/null @@ -1,181 +0,0 @@ -.set noreorder - -.set POLYG4_tag, 0 -.set POLYG4_rgb0, 4 -.set POLYG4_xy0, 8 -.set POLYG4_rgb1, 12 -.set POLYG4_xy1, 16 -.set POLYG4_rgb2, 20 -.set POLYG4_xy2, 24 -.set POLYG4_rgb3, 28 -.set POLYG4_xy3, 32 -.set POLYG4_len, 36 - -# a0 - Plasma output -# a1 - Counter -.global genPlasma -.type genPlasma, @function -genPlasma: - move $t1, $0 - -.gn_y_loop: move $t0, $0 - -.gn_x_loop: la $v0, plasma_sin1 - sll $v1, $t0, 1 - addu $v1, $v0 - lh $v0, 0($v1) - - la $a2, plasma_sin2 - sll $v1, $t1, 1 - addu $v1, $a2 - lh $v1, 0($v1) - nop - add $v0, $v1 - - add $v1, $t0, $t1 - add $v1, $a1 - divu $v1, 90 - la $a2, plasma_sin3 - mfhi $v1 - - sll $v1, 1 - addu $v1, $a2 - lh $v1, 0($v1) - nop - add $v0, $v1 - - andi $v0, 0xff - - sb $v0, 0($a0) - addu $a0, 1 - - addiu $t0, 1 - blt $t0, 41, .gn_x_loop - nop - - addiu $t1, 1 - blt $t1, 31, .gn_y_loop - nop - - jr $ra - nop - - -# a0 - OT entry -# a1 - Primitive address -# a2 - Plasma map source -.global sortPlasma -.type sortPlasma, @function -sortPlasma: - move $t1, $0 - -.y_loop: - move $t0, $0 - -.x_loop: - lbu $v0, 0($a2) - addiu $a2, 1 - la $a3, plasma_colors - sll $v0, 2 - addu $v0, $a3 - lw $v0, 0($v0) - - lui $v1, 0x3800 - or $v0, $v1 - sw $v0, POLYG4_rgb0($a1) - - - lbu $v0, 0($a2) - nop - sll $v0, 2 - addu $v0, $a3 - lw $v0, 0($v0) - nop - sw $v0, POLYG4_rgb1($a1) - - - lbu $v0, 40($a2) - nop - sll $v0, 2 - addu $v0, $a3 - lw $v0, 0($v0) - nop - sw $v0, POLYG4_rgb2($a1) - - - lbu $v0, 41($a2) - nop - sll $v0, 2 - addu $v0, $a3 - lw $v0, 0($v0) - nop - sw $v0, POLYG4_rgb3($a1) - - - sll $v0, $t0, 4 - andi $v0, 0xffff - sll $v1, $t1, 20 - or $v0, $v1 - sw $v0, POLYG4_xy0($a1) - - sll $v0, $t0, 4 - andi $v0, 0xffff - addi $v0, 16 - sll $v1, $t1, 20 - or $v0, $v1 - sw $v0, POLYG4_xy1($a1) - - sll $v0, $t0, 4 - andi $v0, 0xffff - sll $v1, $t1, 4 - addi $v1, 16 - sll $v1, 16 - or $v0, $v1 - sw $v0, POLYG4_xy2($a1) - - sll $v0, $t0, 4 - andi $v0, 0xffff - addi $v0, 16 - sll $v1, $t1, 4 - addi $v1, 16 - sll $v1, 16 - or $v0, $v1 - sw $v0, POLYG4_xy3($a1) - - .set noat - - lui $v1, 0x0800 - lw $v0, 0($a0) - lui $at, 0xff00 - and $v1, $at - lui $at, 0x00ff - or $at, 0xffff - and $v0, $at - or $v1, $v0 - sw $v1, 0($a1) - lw $v0, 0($a0) - and $a1, $at - lui $at, 0xff00 - and $v0, $at - or $v0, $a1 - sw $v0, 0($a0) - - .set at - - lui $v0, 0x8000 - or $a1, $v0 - addiu $a1, POLYG4_len - - - addiu $t0, 1 - blt $t0, 40, .x_loop - nop - - addiu $a2, 1 - addiu $t1, 1 - blt $t1, 30, .y_loop - nop - - - jr $ra - move $v0, $a1 \ No newline at end of file diff --git a/examples/graphics/tilesasm/drawtiles.S b/examples/graphics/tilesasm/drawtiles.S new file mode 100644 index 0000000..15a0707 --- /dev/null +++ b/examples/graphics/tilesasm/drawtiles.S @@ -0,0 +1,272 @@ +# +# LibPSn00b Example Programs +# +# Drawing Tile-maps with Assembler Routines +# 2022 Meido-Tek Productions / PSn00bSDK Project +# +# Example by John "Lameguy" Wilbert Villamor (Lameguy64) +# +# This file contains the assembler routine DrawTiles which can be called from +# a C or C++ compiled module. The routine makes use of constants and assembler +# macros written in the GNU GAS syntax. +# +# Assembler routines called from C-language modules can freely use registers +# $v0-$v1, $at, $a0-$a3, $t0-$t9 without preserving through stack. Registers +# $s0-$s9, $gp and $fp must be preserved through stack before returning and +# registers $k0-$k1 should not be used for obvious reasons (kernel registers). +# $sp and $ra is used as stack pointer and return address respectively. +# $0 or $zero is constantly zero. +# +# A C caller always passes arguments as 32-bit values on registers $a0 to $a3 +# regardless of the data type specified in the function's C declaration. +# Additional arguments are stored in the stack 16 bytes relative to the stack +# pointer ($sp). To get around the stack being modified in different parts of +# a larger routine the stack pointer would be copied to the frame pointer ($fp) +# and the previous value of the frame pointer would be pushed into stack. This +# way additional arguments may be read anywhere starting from $fp+20 instead. +# +.set noreorder # Disable GAS' annoying nop insertion + +.equ db, 1 # Constants for "emulating" SNASM style structs +.equ dh, 2 +.equ dw, 4 + +# +# TILEDEF struct +# + rs=0 # rs is used to emulate SNASM style structs +.equ TILEDEF_uv , rs # Tile texture coordinate + rs=rs+dh +.equ TILEDEF_clut , rs # Tile CLUT + rs=rs+dh +.equ TILEDEF_pad , rs # Padding + rs=rs+dh +.equ TILEDEF_tpage , rs # Tile tpage + rs=rs+dh +.equ TILEDEF_len , rs # Entry length + +# +# TILEINFO struct (to use as offsets) +# + rs=0 +.equ TILEINFO_window_x , rs # \ + rs=rs+dh # - Window coordinates +.equ TILEINFO_window_y , rs # / + rs=rs+dh +.equ TILEINFO_window_w , rs # \ + rs=rs+dh # - Window size +.equ TILEINFO_window_h , rs # / + rs=rs+dh +.equ TILEINFO_tiles , rs # Pointer to TILEDEF entries + rs=rs+dw +.equ TILEINFO_mapdata , rs # Pointer to map data + rs=rs+dw +.equ TILEINFO_map_w , rs # Map width in tile units + rs=rs+dh +.equ TILEINFO_map_h , rs # Map height in tile units + rs=rs+dh + +# +# TILEPKT struct +# + rs=0 +.equ TILEPKT_tag , rs # Primitive tag + rs=rs+dw +.equ TILEPKT_tpage , rs # tpage packet + rs=rs+dw +.equ TILEPKT_rgbc , rs # Tile color + rs=rs+dw +.equ TILEPKT_x , rs # Tile screen coordinates + rs=rs+dh +.equ TILEPKT_y , rs + rs=rs+dh +.equ TILEPKT_uv , rs # Tile texture coordinates + rs=rs+dh +.equ TILEPKT_clut , rs # Tile CLUT + rs=rs+dh +.equ TILEPKT_len , rs # Packet length + +# addprim Macro +# +# Registers a primitive to a ordering table entry. +# +# Arguments: +# ot - Register name of pointer to ordering table entry +# pri - Pointer to a primitive packet +# len - Size of packet in long words (specify as 0xnn00, ie. 0x2000) +# +# Destroys: +# at, v0, v1 +# +.macro addprim ot,pri,len + .set noat + lw $v0, 0(\ot) # Get OT entry + lui $at, 0x00ff # Mask out the packet length field + or $at, 0xffff + and $v0, $at + lui $v1, \len # Merge packet length + or $v1, $v0 + sw $v1, 0(\pri) # Store updated OT entry to packet + lw $v0, 0(\ot) # Get OT entry + and \pri, $at # Mask out last 8-bits of packet address + lui $at, 0xff00 # Mask out OT entry's address + and $v0, $at + or $v0, \pri # Merge packet address to OT entry + sw $v0, 0(\ot) # Store updated OT entry + .set at +.endm + +# +# Start of text section +# +.section .text + +# DrawTiles Function +# +# Renders a tilemap by generating TILEPKT primitives (combined SPRT_16 and +# DR_TPAGE primitives) and registering it to the specified ordering table. +# The drawing region, tile definitions and the tilemap are specified through +# a TILEINFO struct. +# +# C Declaration: +# extern u_char *DrawTiles(int scroll_x, int scroll_y, +# TILEINFO *info, long *ot, u_char *pri); +# +# Arguments: +# scroll_x - X scrolling offset of tile-map +# scroll_y - Y scrolling offset of tile-map +# info - Pointer to a TILEINFO struct +# ot - Pointer to a ordering table entry +# pri - Pointer to next primitive (placed in stack) +# +# Returns: +# New next primitive pointer value. +# +.global DrawTiles # Declare symbol as global +.type DrawTiles, @function # Declare it as a function +DrawTiles: # Symbol label of function + + addiu $sp, -4 # Push frame pointer (fp) to stack + sw $fp, 0($sp) + move $fp, $sp # Copy stack pointer (sp) to fp + + # Register reference: + # + # t0 - Packet address + # t1 - Map data address + # t2 - Tile X offset + # t3 - Tile Y offset + # t4 - Tile X coordinate backup + # t5 - Tile X loop counter + # t6 - Number of tiles to sort per row + # t7 - Number of tile rows to sort + + lhu $t6, TILEINFO_window_w($a2) # Calculate size of window in tiles + lhu $t7, TILEINFO_window_h($a2) + addi $t6, 15 # So the result will be rounded-up + addi $t7, 15 + srl $t6, 4 # Effectively divide by 16 + srl $t7, 4 + + lw $t0, 20($sp) # Obtain next primitive pointer + + srl $t2, $a0, 4 # Compute map offset in tile units + srl $t3, $a1, 4 + + bgez $a0, .Lno_neg_clip_X # Negative X clip test + sub $v0, $0 , $a0 + move $t2, $0 # Force tile offset to zero + add $v0, 15 # Reduce number of tile columns + srl $v0, 4 + sub $t6, $v0 +.Lno_neg_clip_X: + lhu $v1, TILEINFO_map_w($a2) # Positive X clip test + add $v0, $t2, $t6 + addi $v0, 1 + blt $v0, $v1, .Lno_pos_clip_X + nop + sub $v0, $v1 # Compute how many tiles to clip + sub $t6, $v0 # Reduce number of tile columns +.Lno_pos_clip_X: + bgez $a1, .Lno_neg_clip_Y # Negative Y clip test + sub $v0, $0 , $a1 + move $t3, $0 + add $v0, 15 + srl $v0, 4 + sub $t7, $v0 +.Lno_neg_clip_Y: + lhu $v1, TILEINFO_map_h($a2) # Positive Y clip test + add $v0, $t3, $t7 + addi $v0, 1 + blt $v0, $v1, .Lno_pos_clip_Y + nop + sub $v0, $v1 + sub $t7, $v0 +.Lno_pos_clip_Y: + bltz $t6, .Lno_draw # Exit when no tiles to draw + nop + bltz $t7, .Lno_draw + nop + + lh $v0, TILEINFO_window_x($a2) # Compute pixel coordinates for + sub $a0, $v0, $a0 # tiles based on the scroll offset + sll $v0, $t2, 4 + add $a0, $v0 + lh $v0, TILEINFO_window_y($a2) + sub $a1, $v0, $a1 + sll $v0, $t3, 4 + add $a1, $v0 + move $t4, $a0 + sll $t2, 1 + +.Lloop_y: # Begin of tile row loop + lhu $v0, TILEINFO_map_w($a2) # Get width of tilemap + move $t5, $t6 # n tiles to draw row + mult $t3, $v0 # Multiply Y offset by map width + lw $t1, TILEINFO_mapdata($a2) # Get tilemap address + nop + addu $t1, $t2 # Add X offset to address + mflo $v0 # Get Y offset result + sll $v0, 1 # Multiply by two + addu $t1, $v0 # Add to tile address + +.Lloop_x: # Begin of tile column loop + lhu $v1, 0($t1) # Load tile index + addiu $t1, 2 # Advance to next tile + beq $v1, 0xFFFF, .Lskip_tile # Skip tile if index is 0xFFFF + nop + lw $v0, TILEINFO_tiles($a2) # Get pointer to TILEDEF entries + sll $v1, 3 # Multiply by 8 (size of TILEDEFs) + addu $v1, $v0 # Adjust to tiledefs pointer + lw $v0, TILEDEF_uv($v1) # Obtain UV+CLUT + lhu $v1, TILEDEF_tpage($v1) # Obtain tpage + sw $v0, TILEPKT_uv($t0) # Start constructing packet + lui $v0, 0xE100 # tpage packet code + or $v0, $v1 # Merge tpage bits + sw $v0, TILEPKT_tpage($t0) + sh $a0, TILEPKT_x($t0) # Set tile screen coords + sh $a1, TILEPKT_y($t0) + li $v0, 0x7C7F7F7F # Packet code and color + sw $v0, TILEPKT_rgbc($t0) + addprim $a3, $t0, 0x0400 # Register to OT + addiu $t0, TILEPKT_len # Advance packet pointer +.Lskip_tile: + addi $t5, -1 # Decrement and continue iterating + bgez $t5, .Lloop_x # if non-zero + addiu $a0, 16 # Advance X tile coordinate + + move $a0, $t4 # Restore tile X coordinate + addi $t3, 1 # Increment Y offset + addi $t7, -1 # Decrement and continue iterating + bgez $t7, .Lloop_y # if non-zero + addiu $a1, 16 # Advance Y tile coordinate + +.Lno_draw: + + move $v0, $t0 # Set packet pointer as return value + + lw $fp, 0($sp) # Restore frame pointer and return + jr $ra + addiu $sp, 4 + # DrawTiles + \ No newline at end of file diff --git a/examples/graphics/tilesasm/drawtiles.s b/examples/graphics/tilesasm/drawtiles.s deleted file mode 100644 index 15a0707..0000000 --- a/examples/graphics/tilesasm/drawtiles.s +++ /dev/null @@ -1,272 +0,0 @@ -# -# LibPSn00b Example Programs -# -# Drawing Tile-maps with Assembler Routines -# 2022 Meido-Tek Productions / PSn00bSDK Project -# -# Example by John "Lameguy" Wilbert Villamor (Lameguy64) -# -# This file contains the assembler routine DrawTiles which can be called from -# a C or C++ compiled module. The routine makes use of constants and assembler -# macros written in the GNU GAS syntax. -# -# Assembler routines called from C-language modules can freely use registers -# $v0-$v1, $at, $a0-$a3, $t0-$t9 without preserving through stack. Registers -# $s0-$s9, $gp and $fp must be preserved through stack before returning and -# registers $k0-$k1 should not be used for obvious reasons (kernel registers). -# $sp and $ra is used as stack pointer and return address respectively. -# $0 or $zero is constantly zero. -# -# A C caller always passes arguments as 32-bit values on registers $a0 to $a3 -# regardless of the data type specified in the function's C declaration. -# Additional arguments are stored in the stack 16 bytes relative to the stack -# pointer ($sp). To get around the stack being modified in different parts of -# a larger routine the stack pointer would be copied to the frame pointer ($fp) -# and the previous value of the frame pointer would be pushed into stack. This -# way additional arguments may be read anywhere starting from $fp+20 instead. -# -.set noreorder # Disable GAS' annoying nop insertion - -.equ db, 1 # Constants for "emulating" SNASM style structs -.equ dh, 2 -.equ dw, 4 - -# -# TILEDEF struct -# - rs=0 # rs is used to emulate SNASM style structs -.equ TILEDEF_uv , rs # Tile texture coordinate - rs=rs+dh -.equ TILEDEF_clut , rs # Tile CLUT - rs=rs+dh -.equ TILEDEF_pad , rs # Padding - rs=rs+dh -.equ TILEDEF_tpage , rs # Tile tpage - rs=rs+dh -.equ TILEDEF_len , rs # Entry length - -# -# TILEINFO struct (to use as offsets) -# - rs=0 -.equ TILEINFO_window_x , rs # \ - rs=rs+dh # - Window coordinates -.equ TILEINFO_window_y , rs # / - rs=rs+dh -.equ TILEINFO_window_w , rs # \ - rs=rs+dh # - Window size -.equ TILEINFO_window_h , rs # / - rs=rs+dh -.equ TILEINFO_tiles , rs # Pointer to TILEDEF entries - rs=rs+dw -.equ TILEINFO_mapdata , rs # Pointer to map data - rs=rs+dw -.equ TILEINFO_map_w , rs # Map width in tile units - rs=rs+dh -.equ TILEINFO_map_h , rs # Map height in tile units - rs=rs+dh - -# -# TILEPKT struct -# - rs=0 -.equ TILEPKT_tag , rs # Primitive tag - rs=rs+dw -.equ TILEPKT_tpage , rs # tpage packet - rs=rs+dw -.equ TILEPKT_rgbc , rs # Tile color - rs=rs+dw -.equ TILEPKT_x , rs # Tile screen coordinates - rs=rs+dh -.equ TILEPKT_y , rs - rs=rs+dh -.equ TILEPKT_uv , rs # Tile texture coordinates - rs=rs+dh -.equ TILEPKT_clut , rs # Tile CLUT - rs=rs+dh -.equ TILEPKT_len , rs # Packet length - -# addprim Macro -# -# Registers a primitive to a ordering table entry. -# -# Arguments: -# ot - Register name of pointer to ordering table entry -# pri - Pointer to a primitive packet -# len - Size of packet in long words (specify as 0xnn00, ie. 0x2000) -# -# Destroys: -# at, v0, v1 -# -.macro addprim ot,pri,len - .set noat - lw $v0, 0(\ot) # Get OT entry - lui $at, 0x00ff # Mask out the packet length field - or $at, 0xffff - and $v0, $at - lui $v1, \len # Merge packet length - or $v1, $v0 - sw $v1, 0(\pri) # Store updated OT entry to packet - lw $v0, 0(\ot) # Get OT entry - and \pri, $at # Mask out last 8-bits of packet address - lui $at, 0xff00 # Mask out OT entry's address - and $v0, $at - or $v0, \pri # Merge packet address to OT entry - sw $v0, 0(\ot) # Store updated OT entry - .set at -.endm - -# -# Start of text section -# -.section .text - -# DrawTiles Function -# -# Renders a tilemap by generating TILEPKT primitives (combined SPRT_16 and -# DR_TPAGE primitives) and registering it to the specified ordering table. -# The drawing region, tile definitions and the tilemap are specified through -# a TILEINFO struct. -# -# C Declaration: -# extern u_char *DrawTiles(int scroll_x, int scroll_y, -# TILEINFO *info, long *ot, u_char *pri); -# -# Arguments: -# scroll_x - X scrolling offset of tile-map -# scroll_y - Y scrolling offset of tile-map -# info - Pointer to a TILEINFO struct -# ot - Pointer to a ordering table entry -# pri - Pointer to next primitive (placed in stack) -# -# Returns: -# New next primitive pointer value. -# -.global DrawTiles # Declare symbol as global -.type DrawTiles, @function # Declare it as a function -DrawTiles: # Symbol label of function - - addiu $sp, -4 # Push frame pointer (fp) to stack - sw $fp, 0($sp) - move $fp, $sp # Copy stack pointer (sp) to fp - - # Register reference: - # - # t0 - Packet address - # t1 - Map data address - # t2 - Tile X offset - # t3 - Tile Y offset - # t4 - Tile X coordinate backup - # t5 - Tile X loop counter - # t6 - Number of tiles to sort per row - # t7 - Number of tile rows to sort - - lhu $t6, TILEINFO_window_w($a2) # Calculate size of window in tiles - lhu $t7, TILEINFO_window_h($a2) - addi $t6, 15 # So the result will be rounded-up - addi $t7, 15 - srl $t6, 4 # Effectively divide by 16 - srl $t7, 4 - - lw $t0, 20($sp) # Obtain next primitive pointer - - srl $t2, $a0, 4 # Compute map offset in tile units - srl $t3, $a1, 4 - - bgez $a0, .Lno_neg_clip_X # Negative X clip test - sub $v0, $0 , $a0 - move $t2, $0 # Force tile offset to zero - add $v0, 15 # Reduce number of tile columns - srl $v0, 4 - sub $t6, $v0 -.Lno_neg_clip_X: - lhu $v1, TILEINFO_map_w($a2) # Positive X clip test - add $v0, $t2, $t6 - addi $v0, 1 - blt $v0, $v1, .Lno_pos_clip_X - nop - sub $v0, $v1 # Compute how many tiles to clip - sub $t6, $v0 # Reduce number of tile columns -.Lno_pos_clip_X: - bgez $a1, .Lno_neg_clip_Y # Negative Y clip test - sub $v0, $0 , $a1 - move $t3, $0 - add $v0, 15 - srl $v0, 4 - sub $t7, $v0 -.Lno_neg_clip_Y: - lhu $v1, TILEINFO_map_h($a2) # Positive Y clip test - add $v0, $t3, $t7 - addi $v0, 1 - blt $v0, $v1, .Lno_pos_clip_Y - nop - sub $v0, $v1 - sub $t7, $v0 -.Lno_pos_clip_Y: - bltz $t6, .Lno_draw # Exit when no tiles to draw - nop - bltz $t7, .Lno_draw - nop - - lh $v0, TILEINFO_window_x($a2) # Compute pixel coordinates for - sub $a0, $v0, $a0 # tiles based on the scroll offset - sll $v0, $t2, 4 - add $a0, $v0 - lh $v0, TILEINFO_window_y($a2) - sub $a1, $v0, $a1 - sll $v0, $t3, 4 - add $a1, $v0 - move $t4, $a0 - sll $t2, 1 - -.Lloop_y: # Begin of tile row loop - lhu $v0, TILEINFO_map_w($a2) # Get width of tilemap - move $t5, $t6 # n tiles to draw row - mult $t3, $v0 # Multiply Y offset by map width - lw $t1, TILEINFO_mapdata($a2) # Get tilemap address - nop - addu $t1, $t2 # Add X offset to address - mflo $v0 # Get Y offset result - sll $v0, 1 # Multiply by two - addu $t1, $v0 # Add to tile address - -.Lloop_x: # Begin of tile column loop - lhu $v1, 0($t1) # Load tile index - addiu $t1, 2 # Advance to next tile - beq $v1, 0xFFFF, .Lskip_tile # Skip tile if index is 0xFFFF - nop - lw $v0, TILEINFO_tiles($a2) # Get pointer to TILEDEF entries - sll $v1, 3 # Multiply by 8 (size of TILEDEFs) - addu $v1, $v0 # Adjust to tiledefs pointer - lw $v0, TILEDEF_uv($v1) # Obtain UV+CLUT - lhu $v1, TILEDEF_tpage($v1) # Obtain tpage - sw $v0, TILEPKT_uv($t0) # Start constructing packet - lui $v0, 0xE100 # tpage packet code - or $v0, $v1 # Merge tpage bits - sw $v0, TILEPKT_tpage($t0) - sh $a0, TILEPKT_x($t0) # Set tile screen coords - sh $a1, TILEPKT_y($t0) - li $v0, 0x7C7F7F7F # Packet code and color - sw $v0, TILEPKT_rgbc($t0) - addprim $a3, $t0, 0x0400 # Register to OT - addiu $t0, TILEPKT_len # Advance packet pointer -.Lskip_tile: - addi $t5, -1 # Decrement and continue iterating - bgez $t5, .Lloop_x # if non-zero - addiu $a0, 16 # Advance X tile coordinate - - move $a0, $t4 # Restore tile X coordinate - addi $t3, 1 # Increment Y offset - addi $t7, -1 # Decrement and continue iterating - bgez $t7, .Lloop_y # if non-zero - addiu $a1, 16 # Advance Y tile coordinate - -.Lno_draw: - - move $v0, $t0 # Set packet pointer as return value - - lw $fp, 0($sp) # Restore frame pointer and return - jr $ra - addiu $sp, 4 - # DrawTiles - \ No newline at end of file diff --git a/examples/lowlevel/cartrom/CMakeLists.txt b/examples/lowlevel/cartrom/CMakeLists.txt index 6a94d9f..b674002 100644 --- a/examples/lowlevel/cartrom/CMakeLists.txt +++ b/examples/lowlevel/cartrom/CMakeLists.txt @@ -11,7 +11,7 @@ project( HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" ) -file(GLOB _sources *.c *.s) +file(GLOB _sources *.c *.S) # This example only uses the toolchain (without the rest of the SDK), so the # executable has to be created manually and converted into raw binary format diff --git a/examples/lowlevel/cartrom/rom.S b/examples/lowlevel/cartrom/rom.S new file mode 100644 index 0000000..587ba6f --- /dev/null +++ b/examples/lowlevel/cartrom/rom.S @@ -0,0 +1,402 @@ +# LibPSn00b Example Programs +# Part of the PSn00bSDk project +# +# TurboBoot Example by Lameguy64 +# +# Note: This example is being obsoleted as GAS is not ideal for making +# ROM firmwares. Use ARMIPS instead, but it cannot build this example +# as it is not GAS syntax compatible. + + +# Uncomment either PAR or XPLORER depending on the cartridge +# you're going to use (makes disabling turbo boot via switch to work) + +#.set PAR, 0 +#.set XPLORER, 1 + + +.set noreorder + +.include "cop0.inc" # Contains definitions for cop0 registers + +.set SP_base, 0x801ffff0 +.set BREAK_ADDR, 0xa0000040 # cop0 breakpoint vector address + + +.set RAM_buff, 2048 +.set RAM_handle, 2052 +.set RAM_tcb, 2056 +.set RAM_evcb, 2060 +.set RAM_stack, 2064 +.set RAM_psexe, 2068 + + +.set EXE_pc0, 0 # PS-EXE header offsets +.set EXE_gp0, 4 +.set EXE_taddr, 8 +.set EXE_tsize, 12 +.set EXE_daddr, 16 +.set EXE_dsize, 20 +.set EXE_baddr, 24 +.set EXE_bsize, 28 +.set EXE_spaddr, 32 +.set EXE_sp_size, 36 +.set EXE_sp, 40 +.set EXE_fp, 44 +.set EXE_gp, 48 +.set EXE_ret, 52 +.set EXE_base, 56 +.set EXE_datapos, 60 + + +.section .text + + +# ROM header +# +# The Licensed by... strings are essential otherwise the BIOS will not +# execute the boot vectors. Always make sure the tty message fields (string +# after Licensed by) must be no more than 80 bytes long and must have a null +# terminating byte. +# +# Postboot vector isn't particularly practical as its only executed in between +# the PS boot logo and the point where game execution occurs. +# +header: + # Postboot vector + .word 0 + .ascii "Licensed by Sony Computer Entertainment Inc." + .ascii "Not officially licensed or endorsed by Sony Computer Entertainment Inc." + + .balign 0x80 # This keeps things in the header aligned + + # Preboot vector + .word preboot + .ascii "Licensed by Sony Computer Entertainment Inc." + .ascii "Cart ROM example for PSn00bSDK https://github.com/lameguy64/psn00bsdk" + + .balign 0x80 # This keeps things in the header aligned + + +# Preboot vector +# +# All it does is it initializes a breakpoint vector at 0x40 +# and sets a cop0 breakpoint at 0x80030000 to perform a midboot +# exploit as preboot doesn't have the kernel area initialized. +# +preboot: + + li $v0, 1 + +.ifdef XPLORER + lui $a0, 0x1f06 # Read switch status for Xplorer + lbu $v0, 0($a0) +.endif + +.ifdef PAR + lui $a0, 0x1f02 # Read switch status for PAR/GS devices + lbu $v0, 0x18($a0) +.endif + + nop + andi $v0, 0x1 + beqz $v0, .no_rom # If switch is off don't install hook + nop # and effectively disables the cartridge + + li $v0, BREAK_ADDR # Patch a jump at cop0 breakpoint vector + + li $a0, 0x3c1a1f00 # lui $k0, $1f00 + sw $a0, 0($v0) + la $a1, entry # ori $k0, < address to code entrypoint > + andi $a1, 0xffff + lui $a0, 0x375a + or $a0, $a1 + sw $a0, 4($v0) + li $a0, 0x03400008 # jr $k0 + sw $a0, 8($v0) + sw $0 , 12($v0) # nop + + lui $v0, 0xffff # Set BPCM and BDAM masks + ori $v0, 0xffff + mtc0 $v0, BDAM + mtc0 $v0, BPCM + + + li $v0, 0x80030000 # Set break on PC and data-write address + + mtc0 $v0, BDA # BPC break is for compatibility with no$psx + mtc0 $v0, BPC # as it does not emulate break on BDA + + lui $v0, 0xeb80 # Enable break on data-write and and break + mtc0 $v0, DCIC # on PC to DCIC control register + +.no_rom: + + jr $ra # Return to BIOS + nop + + +# Actual ROM entrypoint +.global entry +entry: + + mtc0 $0 , DCIC # Clear DCIC register + + la $sp, SP_base # Set stack base + la $gp, 0x8000c000 # Set GP address as RAM base addr in this case + + jal SetDefaultExitFromException # Set default exit handler just in case + nop + jal ExitCriticalSection # Exit out of critical section (brings back interrupts) + nop + + # Beyond this point, the PS1 is in full control to the ROM + + la $a0, m_banner # Print out program banner + jal printf + addiu $sp, -4 + addiu $sp, 4 + + la $a0, m_cdinit + jal printf + addiu $sp, -4 + addiu $sp, 4 + + jal _96_init # Initialize the CD + nop + + la $a0, m_ok # Print OK message if init didn't crash + jal printf + addiu $sp, -4 + addiu $sp, 4 + + la $a0, m_readfile + la $a1, s_systemcnf + jal printf + addiu $sp, -8 + addiu $sp, 8 + + la $a0, s_systemcnf # Attempt to open the SYSTEM.CNF file on CD + li $a1, 1 + jal open + addiu $sp, -8 + addiu $sp, 8 + + bltz $v0, .no_systemcnf # Fallback to loading PSX.EXE if not found + nop + + sw $v0, RAM_handle($gp) # Save file handle + + move $a0, $v0 # Read file contents of SYSTEM.CNF + move $a1, $gp + li $a2, 0x0800 + jal read + addiu $sp, -12 + addiu $sp, 12 + + lw $a0, RAM_handle($gp) # Close file + jal close + addiu $sp, -4 + addiu $sp, 4 + + la $a0, m_ok # Output ok message + jal printf + addiu $sp, -4 + addiu $sp, 4 + + # Parse CNF file + + la $a0, m_parsecnf + jal printf + nop + + la $a1, s_tcb # Get TCB number + jal strcasestr + move $a0, $gp + jal skipspace # Skip spaces + addiu $a0, $v0, 3 + addiu $a0, $v0, -2 # Step two charactters back and inject '0x' + li $v0, '0' + sb $v0, 0($a0) + li $v0, 'x' + sb $v0, 1($a0) + jal atoi + addiu $sp, -4 + addiu $sp, 4 + move $s1, $v0 + + la $a1, s_evcb # Get EVCB number + jal strcasestr + move $a0, $gp + jal skipspace + addiu $a0, $v0, 5 + addiu $a0, $v0, -2 + li $v0, '0' + sb $v0, 0($a0) + li $v0, 'x' + sb $v0, 1($a0) + jal atoi + addiu $sp, -4 + addiu $sp, 4 + move $s0, $v0 + + la $a1, s_stack # Get STACK address + jal strcasestr + move $a0, $gp + jal skipspace + addiu $a0, $v0, 5 + addiu $a0, $v0, -2 + li $v0, '0' + sb $v0, 0($a0) + li $v0, 'x' + sb $v0, 1($a0) + jal atoi + addiu $sp, -4 + addiu $sp, 4 + move $s2, $v0 + + la $a1, s_boot # Get the PS-EXE file name + jal strcasestr + move $a0, $gp + + jal skipspace # Skip spaces + addiu $a0, $v0, 4 + + addiu $a0, $gp, RAM_psexe # Extract the line + jal getline + move $a1, $v0 + + la $a0, m_ok # Print successful parsing + jal printf + addiu $sp, -4 + addiu $sp, 4 + + la $a0, m_readfile + addiu $a1, $gp, RAM_psexe + jal printf + addiu $sp, -8 + addiu $sp, 8 + + b .do_load # Proceed loading PS-EXE + addiu $a0, $gp, RAM_psexe + +.no_systemcnf: # Load fallback + + la $a0, m_notfound + jal printf + addiu $sp, -4 + addiu $sp, 4 + + la $a0, m_fallback + jal printf + addiu $sp, -4 + addiu $sp, 4 + + li $s0, 0x10 # Default EvCBs and TCBs + li $s1, 0x04 + li $s2, SP_base # Default stack + la $a0, s_psxexe # Attempt loading PSX.EXE + +.do_load: + + jal LoadExe # Load PS-EXE + move $a1, $gp + + beqz $v0, load_fail + nop + + la $a0, m_ok + jal printf + addiu $sp, -4 + addiu $sp, 4 + + sw $s2, EXE_sp($gp) # Patch the header + sw $s2, EXE_spaddr($gp) + + la $a0, m_boot + jal printf + addiu $sp, -4 + addiu $sp, 4 + + jal EnterCriticalSection # Disable interrupt handling + nop + + move $a0, $s0 # Set configuration (EvCBs and TCBs) + move $a1, $s1 + move $a2, $s2 + jal SetConf + addiu $sp, -12 + addiu $sp, 12 + + move $a0, $gp # Transfer execution + move $a1, $0 + move $a2, $0 + jal DoExec + addiu $sp, -12 + addiu $sp, 12 + + +load_fail: # Fail state + la $a0, m_loadfail + jal printf + nop +.fail_loop: + b .fail_loop + nop + + +.include "parse.inc" +.include "bios.inc" + + +# Strings + +s_boot: + .asciz "BOOT" + .balign 4 +s_tcb: + .asciz "TCB" + .balign 4 +s_evcb: + .asciz "EVENT" + .balign 4 +s_stack: + .asciz "STACK" + .balign 4 +s_systemcnf: + .asciz "cdrom:SYSTEM.CNF;1" + .balign 4 +s_psxexe: + .asciz "cdrom:PSX.EXE;1" + .balign 4 + + +# Message strings + +m_banner: + .asciz "\nCARTROM Bootstrap Example by Lameguy64\nPart of the PSn00bSDK Project\n\n" + .balign 4 +m_cdinit: + .asciz "Initializing CD-ROM (BIOS)... " + .balign 4 +m_readfile: + .asciz "Attempting to read %s... " + .balign 4 +m_parsecnf: + .asciz "Parsing CNF file... " + .balign 4 +m_fallback: + .asciz "Falling back to loading PSX.EXE... " + .balign 4 +m_notfound: + .asciiz "Not found.\n" + .balign 4 +m_ok: + .asciz "Ok.\n" + .balign 4 +m_boot: + .asciz "Boot!\n" + .balign 4 +m_loadfail: + .asciz "Failed to load PS-EXE file.\n" + .balign 4 diff --git a/examples/lowlevel/cartrom/rom.s b/examples/lowlevel/cartrom/rom.s deleted file mode 100644 index 587ba6f..0000000 --- a/examples/lowlevel/cartrom/rom.s +++ /dev/null @@ -1,402 +0,0 @@ -# LibPSn00b Example Programs -# Part of the PSn00bSDk project -# -# TurboBoot Example by Lameguy64 -# -# Note: This example is being obsoleted as GAS is not ideal for making -# ROM firmwares. Use ARMIPS instead, but it cannot build this example -# as it is not GAS syntax compatible. - - -# Uncomment either PAR or XPLORER depending on the cartridge -# you're going to use (makes disabling turbo boot via switch to work) - -#.set PAR, 0 -#.set XPLORER, 1 - - -.set noreorder - -.include "cop0.inc" # Contains definitions for cop0 registers - -.set SP_base, 0x801ffff0 -.set BREAK_ADDR, 0xa0000040 # cop0 breakpoint vector address - - -.set RAM_buff, 2048 -.set RAM_handle, 2052 -.set RAM_tcb, 2056 -.set RAM_evcb, 2060 -.set RAM_stack, 2064 -.set RAM_psexe, 2068 - - -.set EXE_pc0, 0 # PS-EXE header offsets -.set EXE_gp0, 4 -.set EXE_taddr, 8 -.set EXE_tsize, 12 -.set EXE_daddr, 16 -.set EXE_dsize, 20 -.set EXE_baddr, 24 -.set EXE_bsize, 28 -.set EXE_spaddr, 32 -.set EXE_sp_size, 36 -.set EXE_sp, 40 -.set EXE_fp, 44 -.set EXE_gp, 48 -.set EXE_ret, 52 -.set EXE_base, 56 -.set EXE_datapos, 60 - - -.section .text - - -# ROM header -# -# The Licensed by... strings are essential otherwise the BIOS will not -# execute the boot vectors. Always make sure the tty message fields (string -# after Licensed by) must be no more than 80 bytes long and must have a null -# terminating byte. -# -# Postboot vector isn't particularly practical as its only executed in between -# the PS boot logo and the point where game execution occurs. -# -header: - # Postboot vector - .word 0 - .ascii "Licensed by Sony Computer Entertainment Inc." - .ascii "Not officially licensed or endorsed by Sony Computer Entertainment Inc." - - .balign 0x80 # This keeps things in the header aligned - - # Preboot vector - .word preboot - .ascii "Licensed by Sony Computer Entertainment Inc." - .ascii "Cart ROM example for PSn00bSDK https://github.com/lameguy64/psn00bsdk" - - .balign 0x80 # This keeps things in the header aligned - - -# Preboot vector -# -# All it does is it initializes a breakpoint vector at 0x40 -# and sets a cop0 breakpoint at 0x80030000 to perform a midboot -# exploit as preboot doesn't have the kernel area initialized. -# -preboot: - - li $v0, 1 - -.ifdef XPLORER - lui $a0, 0x1f06 # Read switch status for Xplorer - lbu $v0, 0($a0) -.endif - -.ifdef PAR - lui $a0, 0x1f02 # Read switch status for PAR/GS devices - lbu $v0, 0x18($a0) -.endif - - nop - andi $v0, 0x1 - beqz $v0, .no_rom # If switch is off don't install hook - nop # and effectively disables the cartridge - - li $v0, BREAK_ADDR # Patch a jump at cop0 breakpoint vector - - li $a0, 0x3c1a1f00 # lui $k0, $1f00 - sw $a0, 0($v0) - la $a1, entry # ori $k0, < address to code entrypoint > - andi $a1, 0xffff - lui $a0, 0x375a - or $a0, $a1 - sw $a0, 4($v0) - li $a0, 0x03400008 # jr $k0 - sw $a0, 8($v0) - sw $0 , 12($v0) # nop - - lui $v0, 0xffff # Set BPCM and BDAM masks - ori $v0, 0xffff - mtc0 $v0, BDAM - mtc0 $v0, BPCM - - - li $v0, 0x80030000 # Set break on PC and data-write address - - mtc0 $v0, BDA # BPC break is for compatibility with no$psx - mtc0 $v0, BPC # as it does not emulate break on BDA - - lui $v0, 0xeb80 # Enable break on data-write and and break - mtc0 $v0, DCIC # on PC to DCIC control register - -.no_rom: - - jr $ra # Return to BIOS - nop - - -# Actual ROM entrypoint -.global entry -entry: - - mtc0 $0 , DCIC # Clear DCIC register - - la $sp, SP_base # Set stack base - la $gp, 0x8000c000 # Set GP address as RAM base addr in this case - - jal SetDefaultExitFromException # Set default exit handler just in case - nop - jal ExitCriticalSection # Exit out of critical section (brings back interrupts) - nop - - # Beyond this point, the PS1 is in full control to the ROM - - la $a0, m_banner # Print out program banner - jal printf - addiu $sp, -4 - addiu $sp, 4 - - la $a0, m_cdinit - jal printf - addiu $sp, -4 - addiu $sp, 4 - - jal _96_init # Initialize the CD - nop - - la $a0, m_ok # Print OK message if init didn't crash - jal printf - addiu $sp, -4 - addiu $sp, 4 - - la $a0, m_readfile - la $a1, s_systemcnf - jal printf - addiu $sp, -8 - addiu $sp, 8 - - la $a0, s_systemcnf # Attempt to open the SYSTEM.CNF file on CD - li $a1, 1 - jal open - addiu $sp, -8 - addiu $sp, 8 - - bltz $v0, .no_systemcnf # Fallback to loading PSX.EXE if not found - nop - - sw $v0, RAM_handle($gp) # Save file handle - - move $a0, $v0 # Read file contents of SYSTEM.CNF - move $a1, $gp - li $a2, 0x0800 - jal read - addiu $sp, -12 - addiu $sp, 12 - - lw $a0, RAM_handle($gp) # Close file - jal close - addiu $sp, -4 - addiu $sp, 4 - - la $a0, m_ok # Output ok message - jal printf - addiu $sp, -4 - addiu $sp, 4 - - # Parse CNF file - - la $a0, m_parsecnf - jal printf - nop - - la $a1, s_tcb # Get TCB number - jal strcasestr - move $a0, $gp - jal skipspace # Skip spaces - addiu $a0, $v0, 3 - addiu $a0, $v0, -2 # Step two charactters back and inject '0x' - li $v0, '0' - sb $v0, 0($a0) - li $v0, 'x' - sb $v0, 1($a0) - jal atoi - addiu $sp, -4 - addiu $sp, 4 - move $s1, $v0 - - la $a1, s_evcb # Get EVCB number - jal strcasestr - move $a0, $gp - jal skipspace - addiu $a0, $v0, 5 - addiu $a0, $v0, -2 - li $v0, '0' - sb $v0, 0($a0) - li $v0, 'x' - sb $v0, 1($a0) - jal atoi - addiu $sp, -4 - addiu $sp, 4 - move $s0, $v0 - - la $a1, s_stack # Get STACK address - jal strcasestr - move $a0, $gp - jal skipspace - addiu $a0, $v0, 5 - addiu $a0, $v0, -2 - li $v0, '0' - sb $v0, 0($a0) - li $v0, 'x' - sb $v0, 1($a0) - jal atoi - addiu $sp, -4 - addiu $sp, 4 - move $s2, $v0 - - la $a1, s_boot # Get the PS-EXE file name - jal strcasestr - move $a0, $gp - - jal skipspace # Skip spaces - addiu $a0, $v0, 4 - - addiu $a0, $gp, RAM_psexe # Extract the line - jal getline - move $a1, $v0 - - la $a0, m_ok # Print successful parsing - jal printf - addiu $sp, -4 - addiu $sp, 4 - - la $a0, m_readfile - addiu $a1, $gp, RAM_psexe - jal printf - addiu $sp, -8 - addiu $sp, 8 - - b .do_load # Proceed loading PS-EXE - addiu $a0, $gp, RAM_psexe - -.no_systemcnf: # Load fallback - - la $a0, m_notfound - jal printf - addiu $sp, -4 - addiu $sp, 4 - - la $a0, m_fallback - jal printf - addiu $sp, -4 - addiu $sp, 4 - - li $s0, 0x10 # Default EvCBs and TCBs - li $s1, 0x04 - li $s2, SP_base # Default stack - la $a0, s_psxexe # Attempt loading PSX.EXE - -.do_load: - - jal LoadExe # Load PS-EXE - move $a1, $gp - - beqz $v0, load_fail - nop - - la $a0, m_ok - jal printf - addiu $sp, -4 - addiu $sp, 4 - - sw $s2, EXE_sp($gp) # Patch the header - sw $s2, EXE_spaddr($gp) - - la $a0, m_boot - jal printf - addiu $sp, -4 - addiu $sp, 4 - - jal EnterCriticalSection # Disable interrupt handling - nop - - move $a0, $s0 # Set configuration (EvCBs and TCBs) - move $a1, $s1 - move $a2, $s2 - jal SetConf - addiu $sp, -12 - addiu $sp, 12 - - move $a0, $gp # Transfer execution - move $a1, $0 - move $a2, $0 - jal DoExec - addiu $sp, -12 - addiu $sp, 12 - - -load_fail: # Fail state - la $a0, m_loadfail - jal printf - nop -.fail_loop: - b .fail_loop - nop - - -.include "parse.inc" -.include "bios.inc" - - -# Strings - -s_boot: - .asciz "BOOT" - .balign 4 -s_tcb: - .asciz "TCB" - .balign 4 -s_evcb: - .asciz "EVENT" - .balign 4 -s_stack: - .asciz "STACK" - .balign 4 -s_systemcnf: - .asciz "cdrom:SYSTEM.CNF;1" - .balign 4 -s_psxexe: - .asciz "cdrom:PSX.EXE;1" - .balign 4 - - -# Message strings - -m_banner: - .asciz "\nCARTROM Bootstrap Example by Lameguy64\nPart of the PSn00bSDK Project\n\n" - .balign 4 -m_cdinit: - .asciz "Initializing CD-ROM (BIOS)... " - .balign 4 -m_readfile: - .asciz "Attempting to read %s... " - .balign 4 -m_parsecnf: - .asciz "Parsing CNF file... " - .balign 4 -m_fallback: - .asciz "Falling back to loading PSX.EXE... " - .balign 4 -m_notfound: - .asciiz "Not found.\n" - .balign 4 -m_ok: - .asciz "Ok.\n" - .balign 4 -m_boot: - .asciz "Boot!\n" - .balign 4 -m_loadfail: - .asciz "Failed to load PS-EXE file.\n" - .balign 4 -- cgit v1.2.3