smallCharLine: addiu sp, sp, -0x50 sw s7, 0x44(sp) move s7, a0 ; s7 = text_ptr sw s0, 0x28(sp) move s0, a1 ; s0 = X sw s2, 0x30(sp) move s2, a2 ; s2 = Y sw s8, 0x48(sp) move s8, s0 ; s8 = X (copy) lui t0, 0xFF ori t0, t0, 0xFFFF sw s1, 0x2C(sp) andi s1, a3, 0xFF ; s1 = color move a0, s1 sw s5, 0x3C(sp) lui s5, 0x8008 lui a2, 0xFF00 lui v0, 0x8000 move t5, s5 lw v1, -0x6C20(s5) ; TextDMANexChainAddr lw a3, 0x60(sp) addiu t5, t5, -0x6C20 sw ra, 0x4C(sp) sw s6, 0x40(sp) sw s4, 0x38(sp) sw s3, 0x34(sp) ; === DMA INITIALIZATION === and a2, v1, a2 andi a1, a3, 0xFF and v1, v1, t0 or s4, v1, v0 ; s4 = DMA base andi a3, a3, 0x10 sltu a3, zero, a3 lw v0, 0x4(t5) ; TextDMACounter lw v1, 0x0(s4) addiu v0, v0, -1 and v1, v1, t0 or a2, a2, v1 sw v0, 0x4(t5) sw a2, -0x6C20(s5) jal FUN_8001adc8 sw a3, 0x18(sp) ; === CHARACTER SETUP === move a0, s4 sll s0, s0, 0x10 sra a1, s0, 0x10 sll s2, s2, 0x10 sra s0, s2, 0x10 move a2, s0 jal FUN_80019d70 move a3, s1 ; === GPU REGISTER SETUP === lui a1, 0x1F80 ori a1, a1, 0x0348 li v0, 0x2 li a3, 0xC sh v0, 0x14(sp) li v0, 0x10 sh a3, 0x16(sp) sb v0, 0x3(a1) lui v0, 0xA000 sw v0, 0x4(a1) lhu v1, 0x9C(gp) ; DAT_80078f40 lhu a0, 0x9E(gp) ; DAT_80078f42 lui v0, 0x100 lui at, 0x1F80 sw v0, 0x388(at) lw v0, 0x14(sp) lui s3, 0x1F80 sh v1, 0x10(sp) sh a0, 0x12(sp) lw v1, 0x10(sp) lh a0, 0x9C(gp) ori s3, s3, 0x3D0 sw v0, 0xC(a1) lui v0, 0x8001 move a2, a0 sw v1, 0x8(a1) ; === PATTERN SETUP === lui t5, 0x1F80 ori t5, t5, 0x2E0 addiu t8, v0, 0x3E8 lwl t6, 0x3(t8) lwr t6, 0x0(t8) lwl t7, 0x7(t8) lwr t7, 0x4(t8) swl t6, 0x3(t5) swr t6, 0x0(t5) swl t7, 0x7(t5) swr t7, 0x4(t5) lwl t6, 0xB(t8) lwr t6, 0x8(t8) lwl t7, 0xF(t8) lwr t7, 0xC(t8) swl t6, 0xB(t5) swr t6, 0x8(t5) swl t7, 0xF(t5) swr t7, 0xC(t5) lwl t6, 0x13(t8) lwr t6, 0x10(t8) lwl t7, 0x17(t8) lwr t7, 0x14(t8) swl t6, 0x13(t5) swr t6, 0x10(t5) swl t7, 0x17(t5) swr t7, 0x14(t5) lwl t6, 0x1B(t8) lwr t6, 0x18(t8) lwl t7, 0x1F(t8) lwr t7, 0x1C(t8) swl t6, 0x1B(t5) swr t6, 0x18(t5) swl t7, 0x1F(t5) swr t7, 0x1C(t5) ; === SPRITE COMMAND SETUP === li v0, 0x4 sb v0, 0x3(s3) li v0, 0x64 sb v0, 0x7(s3) li v0, 0x80 sb v0, 0x4(s3) sb v0, 0x5(s3) bgez a0, calc_x_offset sb v0, 0x6(s3) addiu a2, a0, 0x3F calc_x_offset: sra v0, a2, 0x6 sll v0, v0, 0x6 subu v0, a0, v0 lh v1, 0x9E(gp) sll v0, v0, 0x2 sb v0, 0xC(s3) bgez v1, calc_y_offset move v0, v1 addiu v0, v1, 0xFF calc_y_offset: sra v0, v0, 0x8 sll v0, v0, 0x8 subu v0, v1, v0 sb v0, 0xD(s3) lhu v1, 0xA4(gp) ; DAT_80078f48 li v0, 0x8 sh v0, 0x10(s3) sh a3, 0x12(s3) sh v1, 0xE(s3) ; === MAIN TEXT LOOP === lbu a1, 0x0(s7) beq a1, zero, finish addiu s7, s7, 0x1 move s6, s5 lui s5, 0x8008 addiu s5, s5, -0x6C20 sw s0, 0x1C(sp) lui s0, 0xFF ori s0, s0, 0xFFFF sw s2, 0x20(sp) text_loop: addiu v1, a1, -0x67 sltiu v0, v1, 0x13 beq v0, zero, switch_default sll v0, v1, 0x2 lui t6, 0x8001 addiu t6, t6, 0x4A0 addu v0, v0, t6 lw v0, 0x0(v0) jr v0 switch_cases: lw t7, 0x1C(sp) j after_switch addiu s2, t7, 0x2 switch_default: lw t8, 0x20(sp) sra s2, t8, 0x10 after_switch: lw t5, 0x18(sp) beq t5, zero, normal_pos addiu a1, a1, -0x20 lui v0, 0x8001 addiu v0, v0, 0x43C addu v0, a1, v0 lui v1, 0x8001 lbu v0, 0x0(v0) addiu v1, v1, 0x428 sll v0, v0, 0x1 addu v0, v0, v1 lbu v1, 0x0(v0) lbu v0, 0x1(v0) subu v1, s8, v1 sll a0, v1, 0x10 sra s1, a0, 0x10 j pos_calculated addu s8, v0, v1 normal_pos: sll v1, s8, 0x10 lhu v0, 0x4(s4) sra v1, v1, 0x10 sll v0, v0, 0x3 addu s1, v1, v0 pos_calculated: jal FUN_80019f84 move a0, a1 lui t4, 0x8000 lui t2, 0xFF00 move t1, s4 lui t3, 0x1F80 ori t3, t3, 0x388 move t0, s4 sh s1, 0x8(s3) sh s2, 0xA(s3) ; === DMA CHAIN PROCESSING === dma_loop: lw v0, -0x6C20(s6) and a0, v0, t2 and v0, v0, s0 or a1, v0, t4 lw v0, 0x4(s5) lw v1, 0x0(a1) addiu v0, v0, -1 and v1, v1, s0 or a0, a0, v1 sw v0, 0x4(s5) sw a0, -0x6C20(s6) lw t6, 0x0(s3) lw t7, 0x4(s3) lw t8, 0x8(s3) lw t5, 0xC(s3) sw t6, 0x0(a1) sw t7, 0x4(a1) sw t8, 0x8(a1) sw t5, 0xC(a1) lw t6, 0x10(s3) sw t6, 0x10(a1) lw v1, 0x18(t0) lw v0, 0x0(a1) lw v1, 0x0(v1) and v0, v0, t2 and v1, v1, s0 or v0, v0, v1 sw v0, 0x0(a1) lw a0, 0x18(t0) lw v0, 0x0(a0) and v1, a1, s0 and v0, v0, t2 or v0, v0, v1 sw v0, 0x0(a0) sw a1, 0x18(t0) lhu v0, 0x4(t1) beq v0, zero, is_first nop j not_first nop is_first: sw a1, 0x28(t0) sh s1, 0xC(t1) sh s2, 0xE(t1) not_first: lui a1, 0x1F80 ori a1, a1, 0x348 lw v0, -0x6C20(s6) and a0, v0, t2 and v0, v0, s0 or a3, v0, t4 move a2, a3 lw v0, 0x4(s5) lw v1, 0x0(a3) addiu v0, v0, -1 and v1, v1, s0 or a0, a0, v1 sw v0, 0x4(s5) andi v0, a3, 0x3 beq v0, zero, aligned_copy sw a0, -0x6C20(s6) unaligned_copy: lwl t6, 0x3(a1) lwr t6, 0x0(a1) lwl t7, 0x7(a1) lwr t7, 0x4(a1) lwl t8, 0xB(a1) lwr t8, 0x8(a1) lwl t5, 0xF(a1) lwr t5, 0xC(a1) swl t6, 0x3(a2) swr t6, 0x0(a2) swl t7, 0x7(a2) swr t7, 0x4(a2) swl t8, 0xB(a2) swr t8, 0x8(a2) swl t5, 0xF(a2) swr t5, 0xC(a2) addiu a1, a1, 0x10 bne a1, t3, unaligned_copy addiu a2, a2, 0x10 j copy_done nop aligned_copy: lw t6, 0x0(a1) lw t7, 0x4(a1) lw t8, 0x8(a1) lw t5, 0xC(a1) sw t6, 0x0(a2) sw t7, 0x4(a2) sw t8, 0x8(a2) sw t5, 0xC(a2) addiu a1, a1, 0x10 bne a1, t3, aligned_copy addiu a2, a2, 0x10 copy_done: lwl t6, 0x3(a1) lwr t6, 0x0(a1) swl t6, 0x3(a2) swr t6, 0x0(a2) lw v1, 0x18(t0) lw v0, 0x0(a3) lw v1, 0x0(v1) and v0, v0, t2 and v1, v1, s0 or v0, v0, v1 sw v0, 0x0(a3) lw a0, 0x18(t0) lw v0, 0x0(a0) and v1, a3, s0 and v0, v0, t2 or v0, v0, v1 sw v0, 0x0(a0) sw a3, 0x18(t0) addiu t0, t0, 0x4 addiu v0, t1, 0x8 sltu v0, t0, v0 bne v0, zero, dma_loop nop lhu v0, 0x4(s4) addiu v0, v0, 0x1 sh v0, 0x4(s4) lbu a1, 0x0(s7) bne a1, zero, text_loop addiu s7, s7, 0x1 ; === CLEANUP === finish: clear s2 lui s3, 0x8008 addiu s5, s3, -0x6C20 lui s1, 0xFF ori s1, s1, 0xFFFF move s0, s4 clear a1 cleanup_loop: li a2, 0x1 addu s2, s2, a2 lui v0, 0x8000 lui a0, 0xFF00 lw v1, -0x6C20(s3) lw a3, 0xA0(gp) and v1, v1, s1 or v1, v1, v0 sw v1, 0x30(s0) lw v0, -0x6C20(s3) lw v1, 0x0(v1) and v0, v0, a0 and v1, v1, s1 lw a0, 0x4(s5) or v0, v0, v1 sw v0, -0x6C20(s3) addiu a0, a0, -1 sw a0, 0x4(s5) lw a0, 0x30(s0) jal SetDrawTPage addiu s0, s0, 0x4 sltiu v0, s2, 0x2 bne v0, zero, cleanup_loop clear a1 move v0, s4 lw ra, 0x4C(sp) lw s8, 0x48(sp) lw s7, 0x44(sp) lw s6, 0x40(sp) lw s5, 0x3C(sp) lw s4, 0x38(sp) lw s3, 0x34(sp) lw s2, 0x30(sp) lw s1, 0x2C(sp) lw s0, 0x28(sp) jr ra addiu sp, sp, 0x50