Rename vm.c to vminit.c, tlb.s to vm.s and annotate vm.s

This commit is contained in:
Ryan Dwyer 2023-05-21 15:54:54 +10:00
parent b4355ab55f
commit 4017d5cba5
21 changed files with 709 additions and 592 deletions

View File

@ -8,7 +8,7 @@ The decomp project wraps all decompiled piracy checks in `#if PIRACYCHECKS` stat
## List of Piracy Checks
### bootPhase1
### boot
**When Called:** On power-on before the legal screen appears.
@ -20,7 +20,7 @@ The decomp project wraps all decompiled piracy checks in `#if PIRACYCHECKS` stat
**When Called:** On every frame.
**What It Checks:** Checksums `bootPhase1` to make sure it hasn't been modified.
**What It Checks:** Checksums `boot` to make sure it hasn't been modified.
**Payload:** Writes 40 bytes of 0xff to 0x80095210. This appears to be related to sound effects but has no obvious effect.

View File

@ -1,5 +1,5 @@
#define LIBFILES(section) \
build/ROMID/lib/tlb.o (section); \
build/ROMID/lib/vm.o (section); \
build/ROMID/lib/segments.o (section); \
build/ROMID/lib/boot.o (section); \
build/ROMID/lib/sched.o (section); \
@ -26,7 +26,7 @@
build/ROMID/lib/ultra/io/conteeplongwrite.o (section); \
build/ROMID/lib/ultra/io/pfsresizefile.o (section); \
build/ROMID/lib/ultra/io/pfsinitpak.o (section); \
build/ROMID/lib/vm.o (section); \
build/ROMID/lib/vminit.o (section); \
build/ROMID/lib/rzip.o (section); \
build/ROMID/lib/audiomgr.o (section); \
build/ROMID/lib/audiodma.o (section); \

View File

@ -1,5 +1,5 @@
#define LIBFILES(section) \
build/ROMID/lib/tlb.o (section); \
build/ROMID/lib/vm.o (section); \
build/ROMID/lib/segments.o (section); \
build/ROMID/lib/boot.o (section); \
build/ROMID/lib/sched.o (section); \
@ -27,7 +27,7 @@
build/ROMID/lib/ultra/io/conteeplongwrite.o (section); \
build/ROMID/lib/ultra/io/pfsresizefile.o (section); \
build/ROMID/lib/ultra/io/pfsinitpak.o (section); \
build/ROMID/lib/vm.o (section); \
build/ROMID/lib/vminit.o (section); \
build/ROMID/lib/rzip.o (section); \
build/ROMID/lib/audiomgr.o (section); \
build/ROMID/lib/audiodma.o (section); \

View File

@ -1,5 +1,5 @@
#define LIBFILES(section) \
build/ROMID/lib/tlb.o (section); \
build/ROMID/lib/vm.o (section); \
build/ROMID/lib/segments.o (section); \
build/ROMID/lib/boot.o (section); \
build/ROMID/lib/sched.o (section); \
@ -26,7 +26,7 @@
build/ROMID/lib/ultra/io/conteeplongwrite.o (section); \
build/ROMID/lib/ultra/io/pfsresizefile.o (section); \
build/ROMID/lib/ultra/io/pfsinitpak.o (section); \
build/ROMID/lib/vm.o (section); \
build/ROMID/lib/vminit.o (section); \
build/ROMID/lib/rzip.o (section); \
build/ROMID/lib/audiomgr.o (section); \
build/ROMID/lib/audiodma.o (section); \

View File

@ -1,5 +1,5 @@
#define LIBFILES(section) \
build/ROMID/lib/tlb.o (section); \
build/ROMID/lib/vm.o (section); \
build/ROMID/lib/segments.o (section); \
build/ROMID/lib/boot.o (section); \
build/ROMID/lib/sched.o (section); \
@ -26,7 +26,7 @@
build/ROMID/lib/ultra/io/conteeplongwrite.o (section); \
build/ROMID/lib/ultra/io/pfsresizefile.o (section); \
build/ROMID/lib/ultra/io/pfsinitpak.o (section); \
build/ROMID/lib/vm.o (section); \
build/ROMID/lib/vminit.o (section); \
build/ROMID/lib/rzip.o (section); \
build/ROMID/lib/audiomgr.o (section); \
build/ROMID/lib/audiodma.o (section); \

View File

@ -1,5 +1,5 @@
#define LIBFILES(section) \
build/ROMID/lib/tlb.o (section); \
build/ROMID/lib/vm.o (section); \
build/ROMID/lib/segments.o (section); \
build/ROMID/lib/boot.o (section); \
build/ROMID/lib/sched.o (section); \
@ -26,7 +26,7 @@
build/ROMID/lib/ultra/io/conteeplongwrite.o (section); \
build/ROMID/lib/ultra/io/pfsresizefile.o (section); \
build/ROMID/lib/ultra/io/pfsinitpak.o (section); \
build/ROMID/lib/vm.o (section); \
build/ROMID/lib/vminit.o (section); \
build/ROMID/lib/rzip.o (section); \
build/ROMID/lib/audiomgr.o (section); \
build/ROMID/lib/audiodma.o (section); \

View File

@ -145,11 +145,11 @@ SECTIONS
END_SEG(preamble)
/**
/* tlbInit()'s address is 0x70001050, but preamble calls it by 0x80001050
/* vmBoot()'s address is 0x70001050, but preamble calls it by 0x80001050
* due to it not being TLB mapped yet. So we set up this variable to allow
* this to happen.
*/
tlbInitFromPreamble = tlbInit + 0x10000000;
vmBootFromPreamble = vmBoot + 0x10000000;
/***************************************************************************
* lib

View File

@ -25,7 +25,7 @@ extern u32 g_VmNumPageMisses;
extern u32 g_VmNumPageReplaces;
extern u8 *g_VmMarker;
extern u32 g_VmRamEnd;
extern u32 g_VmStateTableEnd;
extern u32 g_VmVirtualToPhysicalTableEnd;
extern AMAudioMgr g_AudioManager;
extern Mtx *var80092870;
extern s32 g_SndMaxFxBusses;

View File

@ -2,10 +2,10 @@
#define _IN_LIB_BOOT_H
#include <ultra64.h>
void bootPhase1(void);
void boot(void);
s32 bootGetMemSize(void);
void *bootAllocateStack(s32 threadid, s32 size);
void bootPhase2(void *arg);
void bootCreateThreads(void *arg);
void bootCheckStackOverflow(void);
#endif

View File

@ -2,10 +2,10 @@
#define _IN_LIB_TLB_H
#include <ultra64.h>
void tlbInit(void);
void tlb000010a4(void);
void tlb0000113c(void);
void tlbHandleMiss(void);
void tlbUnmapRange(u32 first, u32 last);
void vmBoot(void);
void vmInitVars(void);
void vmInitVacant(void);
void vmHandleMiss(void);
void vmUnmapRange(u32 first, u32 last);
#endif

View File

@ -1,11 +1,29 @@
#ifndef _IN_LIB_VM_H
#define _IN_LIB_VM_H
#ifdef _LANGUAGE_C
#include <ultra64.h>
#include "data.h"
#include "types.h"
extern u8 g_VmShowStats;
u32 vmInit(void);
void vmInit(void);
#endif
#if VERSION >= VERSION_NTSC_1_0
#define VM_NUM_SLOTS 268
#else
#define VM_NUM_SLOTS 266
#endif
#define VM_PAGE_SIZE_SHIFT 12
#define VM_PAGE_SIZE (1 << VM_PAGE_SIZE_SHIFT)
#define VM_BIGGEST_ZIP 0x1c80
#define VM_VACANTBITS_LEN ((VM_NUM_SLOTS + 7) / 8)
#define VM_VIRTUAL_ADDR 0x7f000000
#endif

View File

@ -72,7 +72,7 @@ u32 __osSetFpcCsr(u32 arg0);
* in RAM thanks to this but need to be relocated, and .data and lib need to be
* unzipped too.
*/
void bootPhase1(void)
void boot(void)
{
s32 datacomplen;
s32 inflatelen;
@ -135,7 +135,7 @@ void bootPhase1(void)
}
#endif
tlbUnmapRange(1, NTLBENTRIES);
vmUnmapRange(1, NTLBENTRIES);
// Clear the stack allocation pointers
for (i = 0; i < ARRAYCOUNT(g_StackLeftAddrs); i++) {
@ -168,7 +168,7 @@ void bootPhase1(void)
#endif
// Create and start the main thread
osCreateThread(&g_MainThread, THREAD_MAIN, bootPhase2, NULL, bootAllocateStack(THREAD_MAIN, STACKSIZE_MAIN), THREADPRI_MAIN);
osCreateThread(&g_MainThread, THREAD_MAIN, bootCreateThreads, NULL, bootAllocateStack(THREAD_MAIN, STACKSIZE_MAIN), THREADPRI_MAIN);
osStartThread(&g_MainThread);
}
@ -266,7 +266,7 @@ void bootCreateSchedThread(void)
g_SchedCmdQ = osScGetCmdQ(&g_Sched);
}
void bootPhase2(void *arg)
void bootCreateThreads(void *arg)
{
bootCreateIdleThread();
videbugCreate();

View File

@ -355,7 +355,7 @@ u32 crashGetParentStackFrame(u32 *origptr, u32 *minaddr, u32 origsp, u32 *regs)
bool crashIsReturnAddress(u32 *instruction)
{
if (((uintptr_t)instruction % 4) == 0
&& (uintptr_t)instruction >= (uintptr_t)tlbInit
&& (uintptr_t)instruction >= (uintptr_t)vmBoot
&& (uintptr_t)instruction <= (uintptr_t)&_libSegmentEnd) {
// This condition can never pass because 9 is masked out
if ((instruction[-2] & 0xfc00003c) == 9) {

View File

@ -412,9 +412,9 @@ void mainInit(void)
addr -= STACKSIZE_AUDIO;
addr -= 8; // markers for stack overflow detection
addr -= g_VmNumPages * 8; // vm state table
addr -= 268 * 4096; // vm loaded pages buffer
addr -= VM_NUM_SLOTS * VM_PAGE_SIZE; // vm loaded pages buffer
addr -= addr % 0x2000; // align down to a multiple of 0x2000
addr -= 0x1c80; // buffer for single biggest game zip
addr -= VM_BIGGEST_ZIP; // buffer for single biggest game zip
} else {
addr = K0BASE + 8 * 1024 * 1024;
}
@ -557,9 +557,9 @@ void mainInit(void)
addr -= STACKSIZE_SCHED;
addr -= STACKSIZE_AUDIO;
addr -= g_VmNumPages * 8; // vm state table
addr -= 266 * 4096; // vm loaded pages buffer
addr -= VM_NUM_SLOTS * VM_PAGE_SIZE; // vm loaded pages buffer
addr -= addr % 0x2000; // align down to a multiple of 0x2000
addr -= 0x1c80; // buffer for single biggest game zip
addr -= VM_BIGGEST_ZIP; // buffer for single biggest game zip
} else {
addr = K0BASE + 8 * 1024 * 1024;
}

View File

@ -402,7 +402,7 @@ void __scHandleTasks(OSSched *sc)
{
u32 checksum = 0;
s32 *end = (s32 *)&bootAllocateStack;
s32 *ptr = (s32 *)&bootPhase1;
s32 *ptr = (s32 *)&boot;
s32 i;
while (ptr < end) {

View File

@ -1,527 +0,0 @@
#include "os_tlb.h"
#include "asm_helper.h"
#include "macros.inc"
#include "versions.h"
.set noat
.set noreorder
.bss
.balign 4
glabel var8008ae20
.space 4
glabel g_VmStateTable
.space 4
glabel g_VmInitialised
.space 4
glabel g_VmZipBuffer
.space 4
glabel g_VmZipTable
.space 8
glabel var8008ae38
.space 0x1000
glabel var8008be38
.space 0x1400
glabel var8008d238
.space 0x20
glabel var8008d258
.space 4
glabel var8008d25c
.space 4
glabel var8008d260
.space 4
glabel var8008d264
.space 4
glabel var8008d268
.space 4
.text
/**
* Sets up TLB index 0 (0x70000000), then calls bootPhase1.
*/
glabel tlbInit
li $t0, OS_PM_4M
mtc0 $t0, C0_PAGEMASK
lui $t0, 0x7000
mtc0 $t0, C0_ENTRYHI
li $t0, 0x1f
mtc0 $t0, C0_ENTRYLO0
lui $t0, 0x1
ori $t0, $t0, 0x1f
mtc0 $t0, C0_ENTRYLO1
li $t0, 0
mtc0 $t0, C0_INX
nop
tlbwi
nop
nop
nop
lui $t0, %hi(bootPhase1)
addiu $t0, $t0, %lo(bootPhase1)
jr $t0
nop
glabel tlb000010a4
addiu $sp, $sp, -8
sw $ra, 0x0($sp)
mtc0 $zero, C0_CONTEXT
li $t0, 0x2
mtc0 $t0, C0_WIRED
li $t1, 0x1ff
lui $at, %hi(var8008d264+0x2)
sh $t1, %lo(var8008d264+0x2)($at)
#if VERSION >= VERSION_NTSC_1_0
li $a0, 268
#else
li $a0, 266
#endif
lui $at, %hi(g_VmInitialised+0x2)
sh $a0, %lo(g_VmInitialised+0x2)($at)
lui $at, %hi(var8008d258+0x2)
sh $a0, %lo(var8008d258+0x2)($at)
sll $a0, $a0, 0xc
lui $v0, %hi(var8008ae20)
lw $v0, %lo(var8008ae20)($v0)
lui $t1, %hi(_gameSegmentEnd)
addiu $t1, $t1, %lo(_gameSegmentEnd)
lui $t2, %hi(_gameSegmentStart)
addiu $t2, $t2, %lo(_gameSegmentStart)
subu $t1, $t1, $t2
lui $t0, 0xfff
ori $t0, $t0, 0xffff
and $v0, $v0, $t0
lui $at, %hi(var8008d268)
sw $v0, %lo(var8008d268)($at)
lui $v0, %hi(var8008d238)
addiu $v0, $v0, %lo(var8008d238)
li $a0, 0x21
lui $at, %hi(var8008d25c)
sw $v0, %lo(var8008d25c)($at)
addu $v1, $v0, $a0
lui $at, %hi(var8008d260)
sw $v1, %lo(var8008d260)($at)
lw $ra, 0x0($sp)
addiu $sp, $sp, 0x8
jr $ra
nop
glabel tlb0000113c
li $t0, 0xff
lui $v0, %hi(var8008d25c)
lw $v0, %lo(var8008d25c)($v0)
lui $v1, %hi(var8008d260)
lw $v1, %lo(var8008d260)($v1)
.L00001150:
sb $t0, 0x0($v0)
bne $v0, $v1, .L00001150
addiu $v0, $v0, 1
#if VERSION >= VERSION_NTSC_1_0
li $a0, 4
#else
li $a0, 2
#endif
beqz $a0, .L00001178
addiu $a0, $a0, -1
li $t0, 2
sllv $t0, $t0, $a0
addiu $t0, $t0, -1
sb $t0, 0x0($v1)
.L00001178:
jr $ra
nop
glabel tlbHandleMiss
mfc0 $t0, C0_CONTEXT
sll $s5, $t0, 0x9
lui $t1, 0x7f00
sub $t0, $s5, $t1
srl $t0, $t0, 0xc
sll $t0, $t0, 0x3
lui $t1, %hi(g_VmStateTable)
lw $t1, %lo(g_VmStateTable)($t1)
addu $s0, $t0, $t1
lui $s8, 0x7f00
slt $at, $s5, $s8
bnez $at, .L0000162c
nop
lui $t1, %hi(g_VmRamEnd)
lw $t1, %lo(g_VmRamEnd)($t1)
slt $at, $s5, $t1
beqz $at, .L0000162c
nop
#if VERSION < VERSION_NTSC_1_0
lui $t2, %hi(g_VmNumTlbMisses)
addiu $t2, $t2, %lo(g_VmNumTlbMisses)
lw $t6, 0($t2)
addiu $t6, $t6, 1
sw $t6, 0($t2)
#endif
mfc0 $t9, C0_BADVADDR
srl $t9, $t9, 0xc
andi $t9, $t9, 0x1
beqzl $t9, .L000011e0
lw $s1, 0x0($s0)
lw $s1, 0x8($s0)
.L000011e0:
bnezl $s1, .L000014c4
li $t5, 0x1
li $t5, 0x0
lui $t1, %hi(var8008d25c)
lw $t1, %lo(var8008d25c)($t1)
lui $t2, %hi(var8008d260)
lw $t2, %lo(var8008d260)($t2)
.L000011fc:
lbu $t0, 0x0($t1)
beqz $t0, .L0000122c
nop
li $t6, 0x0
li $t7, 0x1
.L00001210:
and $t8, $t0, $t7
bnez $t8, .L0000123c
nop
addiu $t6, $t6, 0x1
li $at, 0x8
bne $t6, $at, .L00001210
sll $t7, $t7, 0x1
.L0000122c:
bne $t1, $t2, .L000011fc
addiu $t1, $t1, 0x1
j .L00001570
nop
.L0000123c:
xor $t0, $t0, $t7
sb $t0, 0x0($t1)
lui $t2, %hi(var8008d25c)
lw $t2, %lo(var8008d25c)($t2)
lui $s1, %hi(var8008d268)
lw $s1, %lo(var8008d268)($s1)
subu $t1, $t1, $t2
sll $t1, $t1, 0x3
addu $t0, $t6, $t1
sll $t0, $t0, 0xc
addu $s1, $s1, $t0
.L00001268:
#if VERSION < VERSION_NTSC_1_0
lui $t2, %hi(g_VmNumPageMisses)
addiu $t2, $t2, %lo(g_VmNumPageMisses)
lw $t0, 0($t2)
addiu $t0, $t0, 1
sw $t0, 0($t2)
#endif
mfc0 $t2, C0_BADVADDR
lui $t0, 0xff
ori $t0, $t0, 0xf000
and $t2, $t2, $t0
srl $t2, $t2, 0xa
lui $t0, %hi(g_VmZipTable)
lw $t0, %lo(g_VmZipTable)($t0)
addu $t0, $t0, $t2
lw $t2, 0x0($t0)
lw $t0, 0x4($t0)
subu $t0, $t0, $t2
li $t1, -16
addiu $t0, $t0, 0xf
and $t6, $t0, $t1
lui $t0, 0xa460
ori $t0, $t0, 0x10
.L000012a8:
lw $t1, 0x0($t0)
andi $t1, $t1, 0x3
bnez $t1, .L000012a8
nop
lui $s6, 0xa430
lw $s6, 0x8($s6)
andi $s6, $s6, 0x10
lui $t0, 0xa460
lui $t1, %hi(g_VmZipBuffer)
lw $t1, %lo(g_VmZipBuffer)($t1)
lui $t7, 0xfff
ori $t7, $t7, 0xffff
and $t1, $t1, $t7
sw $t1, 0x0($t0)
lui $t0, 0xa460
ori $t0, $t0, 0x4
lui $t1, 0x8000
lw $t1, 0x308($t1)
or $t1, $t1, $t2
lui $t2, 0x1fff
ori $t2, $t2, 0xffff
and $t1, $t1, $t2
sw $t1, 0x0($t0)
lui $t0, 0xa460
ori $t0, $t0, 0xc
addiu $t6, $t6, -1
sw $t6, 0x0($t0)
beqzl $t9, .L00001324
nop
beqzl $zero, .L00001328
sw $s1, 0x8($s0)
.L00001324:
sw $s1, 0x0($s0)
.L00001328:
lui $t0, 0xa460
ori $t0, $t0, 0x10
.L00001330:
lw $t1, 0x0($t0)
andi $t1, $t1, 0x3
bnez $t1, .L00001330
nop
lui $t0, %hi(g_VmZipBuffer)
lw $t0, %lo(g_VmZipBuffer)($t0)
addiu $t1, $t0, 0x1000
.L0000134c:
cache 0x15, 0x0($t0)
sltu $at, $t0, $t1
bnez $at, .L0000134c
addiu $t0, $t0, 16
bnez $s6, .L00001370
nop
li $t0, 0x2
lui $at, 0xa460
sw $t0, 0x10($at)
.L00001370:
lui $a0, %hi(var8008ae38)
addiu $a0, $a0, %lo(var8008ae38)
addiu $a0, $a0, 0xff8
sw $sp, 0x0($a0)
addiu $sp, $a0, 0x0
lui $a0, %hi(g_VmZipBuffer)
lw $a0, %lo(g_VmZipBuffer)($a0)
addiu $a0, $a0, 0x2
lui $t0, 0x8000
or $a1, $s1, $t0
lui $a2, %hi(var8008be38)
addiu $a2, $a2, %lo(var8008be38)
addiu $sp, $sp, -128
sw $ra, 0x0($sp)
sw $at, 0x4($sp)
sw $v0, 0x8($sp)
sw $v1, 0xc($sp)
sw $a0, 0x10($sp)
sw $a1, 0x14($sp)
sw $a2, 0x18($sp)
sw $a3, 0x1c($sp)
sw $t0, 0x20($sp)
sw $t1, 0x24($sp)
sw $t2, 0x28($sp)
sw $t3, 0x2c($sp)
sw $t4, 0x30($sp)
sw $t5, 0x34($sp)
sw $t6, 0x38($sp)
sw $t7, 0x3c($sp)
sw $s0, 0x40($sp)
sw $s1, 0x44($sp)
sw $s2, 0x48($sp)
sw $s3, 0x4c($sp)
sw $s4, 0x50($sp)
sw $s5, 0x54($sp)
sw $s6, 0x58($sp)
sw $s7, 0x5c($sp)
sw $t8, 0x60($sp)
sw $t9, 0x64($sp)
sw $gp, 0x70($sp)
sw $sp, 0x74($sp)
sw $s8, 0x78($sp)
jal rzipInflate
nop
lw $ra, 0x0($sp)
lw $at, 0x4($sp)
lw $v0, 0x8($sp)
lw $v1, 0xc($sp)
lw $a0, 0x10($sp)
lw $a1, 0x14($sp)
lw $a2, 0x18($sp)
lw $a3, 0x1c($sp)
lw $t0, 0x20($sp)
lw $t1, 0x24($sp)
lw $t2, 0x28($sp)
lw $t3, 0x2c($sp)
lw $t4, 0x30($sp)
lw $t5, 0x34($sp)
lw $t6, 0x38($sp)
lw $t7, 0x3c($sp)
lw $s0, 0x40($sp)
lw $s1, 0x44($sp)
lw $s2, 0x48($sp)
lw $s3, 0x4c($sp)
lw $s4, 0x50($sp)
lw $s5, 0x54($sp)
lw $s6, 0x58($sp)
lw $s7, 0x5c($sp)
lw $t8, 0x60($sp)
lw $t9, 0x64($sp)
lw $gp, 0x70($sp)
lw $sp, 0x74($sp)
lw $s8, 0x78($sp)
addiu $sp, $sp, 0x80
lui $a0, %hi(var8008ae38)
addiu $a0, $a0, %lo(var8008ae38)
addiu $a0, $a0, 4088
lw $sp, 0x0($a0)
lui $t0, 0x8000
or $t0, $s1, $t0
addiu $t1, $t0, 0xff0
.L000014b4:
cache 0x19, 0x0($t0)
sltu $at, $t0, $t1
bnez $at, .L000014b4
addiu $t0, $t0, 0x10
.L000014c4:
li $t0, OS_PM_4K
mtc0 $t0, C0_PAGEMASK
mtc0 $s5, C0_ENTRYHI
nop
nop
nop
tlbp
nop
nop
mfc0 $t1, C0_INX
mtc0 $t0, C0_PAGEMASK
mtc0 $s5, C0_ENTRYHI
lw $t0, 0x0($s0)
srl $t0, $t0, 0xc
sll $t0, $t0, 0x6
bnezl $t0, .L00001508
ori $t0, $t0, 0x1e
.L00001508:
mtc0 $t0, C0_ENTRYLO0
lw $t0, 0x8($s0)
srl $t0, $t0, 0xc
sll $t0, $t0, 0x6
bnezl $t0, .L00001520
ori $t0, $t0, 0x1e
.L00001520:
mtc0 $t0, C0_ENTRYLO1
bltzl $t1, .L00001534
nop
b .L00001538
tlbwi
.L00001534:
tlbwr
.L00001538:
bnez $t5, .L00001568
nop
move $t0, $s5
bnezl $t9, .L0000154c
addiu $t0, $t0, 0x1000
.L0000154c:
addiu $t1, $t0, 0xfe0
andi $t2, $t0, 0x1f
subu $t0, $t0, $t2
.L00001558:
cache 0x10, 0x0($t0)
sltu $at, $t0, $t1
bnez $at, .L00001558
addiu $t0, $t0, 0x20
.L00001568:
jr $ra
nop
.L00001570:
#if VERSION < VERSION_NTSC_1_0
lui $t0, %hi(g_VmNumPageReplaces)
addiu $t0, $t0, %lo(g_VmNumPageReplaces)
lw $t1, 0($t0)
addiu $t1, $t1, 1
sw $t1, 0($t0)
#endif
.L00001570_2:
lui $s4, %hi(g_VmStateTable)
lw $s4, %lo(g_VmStateTable)($s4)
lui $gp, %hi(g_VmStateTableEnd)
lw $gp, %lo(g_VmStateTableEnd)($gp)
mfc0 $t0, C0_COUNT
lui $t1, %hi(var8008d264+0x2)
lhu $t1, %lo(var8008d264+0x2)($t1)
lui $t2, %hi(g_VmNumPages)
lw $t2, %lo(g_VmNumPages)($t2)
and $t0, $t0, $t1
slt $at, $t0, $t2
beqzl $at, .L000015a4
subu $t0, $t0, $t2
.L000015a4:
sll $t1, $t0, 0x3
addu $t1, $t1, $s4
.L000015ac:
lw $s1, 0x0($t1)
bnez $s1, .L000015cc
nop
addiu $t1, $t1, 8
bne $t1, $gp, .L000015ac
nop
j .L000015ac
move $t1, $s4
.L000015cc:
subu $t0, $t1, $s4
srl $t0, $t0, 0x3
sll $t0, $t0, 0xc
addu $t0, $t0, $s8
li $t2, -4096
and $t0, $t0, $t2
mtc0 $t0, C0_ENTRYHI
li $t0, 0x0
mtc0 $t0, C0_PAGEMASK
nop
nop
nop
tlbp
nop
nop
mfc0 $t2, C0_INX
mfc0 $t0, C0_ENTRYHI
bltz $t2, .L00001620
nop
j .L00001570_2
nop
.L00001620:
sw $zero, 0x0($t1)
j .L00001268
nop
.L0000162c:
j handle_fault
nop
glabel tlbUnmapRange
mfc0 $t0, C0_ENTRYHI
lui $t2, 0x8000
mtc0 $t2, C0_ENTRYHI
mtc0 $zero, C0_ENTRYLO0
mtc0 $zero, C0_ENTRYLO1
.L00001648:
mtc0 $a1, C0_INX
nop
tlbwi
nop
nop
bne $a1, $a0, .L00001648
addi $a1, $a1, -1
mtc0 $t0, C0_ENTRYHI
jr $ra
nop
#if VERSION < VERSION_NTSC_1_0
glabel tlb000016acnb
lui $t0, 0x8000
addiu $t1, $t0, 0x1ff0
.L000016b4:
cache 0x1, 0x0($t0)
sltu $at, $t0, $t1
bnez $at, .L000016b4
addiu $t0, $t0, 0x10
jr $ra
nop
#endif

View File

@ -436,7 +436,7 @@ glabel __osException
and $s0, $s0, $at
.handle_rmiss:
jal tlbHandleMiss
jal vmHandleMiss
nop
b .dispatch_thread
nop

631
src/lib/vm.s Normal file
View File

@ -0,0 +1,631 @@
#include "os_tlb.h"
#include "asm_helper.h"
#include "macros.inc"
#include "versions.h"
#include "lib/vm.h"
.set noat
.set noreorder
.bss
.balign 4
/**
* Quick figures (correct for ntsc-final):
* 443 pages
* Page size is 4096 (ie. 4KB each)
* Virtual range is 0x7f000000 to 0x7f1bb000 (0x7f000000 + 443 * 4096)
*
* There are 268 physical slots, meaning 268 pages can be loaded at a time.
* There are 30-ish entries in the TLB, so only 30-ish can be mapped at a time.
* Physical slots are in physical memory at 0x80220000 to 0x8032c000.
*/
# Pointer to the physical slots where pages can be loaded (ie. 0x80220000).
# Size = 268 * 4096
glabel g_VmPhysicalSlots
.space 4
# Pointer to the virtual-to-physical (V2P) table.
# Each entry is 8 bytes and there is one entry for each virtual page.
# The first word is the physical address where the page is loaded, or 0 if not loaded.
# The second word is unused.
# An example physical address is 0x00220000.
# Size = 443 * 8
glabel g_VmVirtualToPhysicalTable
.space 4
# Set but never read
glabel g_VmInitialised
.space 1
.align 1
# The number of pages that can be loaded at any one time (268).
# Written but never read.
glabel g_VmNumSlots
.space 2
# Pointer to a buffer that's big enough to hold the biggest zip file.
glabel g_VmZipBuffer
.space 4
# Pointer to an array of ROM offsets where each zip can be found.
# Size = 443 * sizeof(void *)
glabel g_VmZipTable
.space 4
# Temporary stack space. Used when unzipping a page.
.align 3
glabel g_VmTempStack
.space 0x1000
# A scratch area that can be used by rzipInflate.
glabel g_VmScratch
.space 0x1400
# Array where each bit represents a physical slot (268 bits).
# Bits are 1 if the slot is vacant.
glabel g_VmVacantBits
.space VM_VACANTBITS_LEN
# The number of pages that can be loaded at any one time (268).
# Written but never read.
# Duplicate of g_VmNumSlots.
glabel g_VmNumSlots2
.space 2
# Pointer to the first byte in the g_VmVacantBits array. Never changed once set.
glabel g_VmVacantFirstByte
.space 4
# Pointer to the last byte in the g_VmVacantBits array. Never changed once set.
glabel g_VmVacantLastByte
.space 4
# Unused.
glabel var8008d264
.space 2
# Masked with C0_COUNT to choose which page to replace.
# Initialised with the value 0x1ff then never changed.
glabel g_VmEvictMask
.space 2
# The physical address of the slots (0x00220000).
glabel g_VmSlotsPhysicalAddr
.space 4
.text
/**
* Sets up TLB index 0 (0x70000000), then calls boot.
*/
glabel vmBoot
li $t0, OS_PM_4M
mtc0 $t0, C0_PAGEMASK
li $t0, 0x70000000
mtc0 $t0, C0_ENTRYHI
li $t0, 0x1f
mtc0 $t0, C0_ENTRYLO0
li $t0, 0x1001f
mtc0 $t0, C0_ENTRYLO1
li $t0, 0
mtc0 $t0, C0_INX
nop
tlbwi
nop
nop
nop
la $t0, boot
jr $t0
nop
glabel vmInitVars
addiu $sp, $sp, -8
sw $ra, 0x0($sp)
mtc0 $zero, C0_CONTEXT
li $t0, 2
mtc0 $t0, C0_WIRED
li $t1, 0x1ff
lui $at, %hi(g_VmEvictMask)
sh $t1, %lo(g_VmEvictMask)($at)
li $a0, VM_NUM_SLOTS
lui $at, %hi(g_VmNumSlots)
sh $a0, %lo(g_VmNumSlots)($at)
lui $at, %hi(g_VmNumSlots2)
sh $a0, %lo(g_VmNumSlots2)($at)
sll $a0, $a0, VM_PAGE_SIZE_SHIFT
lw $v0, g_VmPhysicalSlots
la $t1, _gameSegmentEnd # unused
la $t2, _gameSegmentStart # unused
subu $t1, $t1, $t2 # unused
li $t0, 0x0fffffff
and $v0, $v0, $t0
lui $at, %hi(g_VmSlotsPhysicalAddr)
sw $v0, %lo(g_VmSlotsPhysicalAddr)($at)
la $v0, g_VmVacantBits
li $a0, VM_VACANTBITS_LEN - 1
lui $at, %hi(g_VmVacantFirstByte)
sw $v0, %lo(g_VmVacantFirstByte)($at)
addu $v1, $v0, $a0
lui $at, %hi(g_VmVacantLastByte)
sw $v1, %lo(g_VmVacantLastByte)($at)
lw $ra, 0x0($sp)
addiu $sp, $sp, 8
jr $ra
nop
glabel vmInitVacant
# Fill array with 0xff (ie. all vacant)
li $t0, 0xff
lw $v0, g_VmVacantFirstByte
lw $v1, g_VmVacantLastByte
.fill_loop:
sb $t0, 0x0($v0)
bne $v0, $v1, .fill_loop
addiu $v0, $v0, 1
# Set the last byte with a partial bitmask based on the number of page slots
li $a0, VM_NUM_SLOTS % 8
beqz $a0, .after_remainder
addiu $a0, $a0, -1
li $t0, 2
sllv $t0, $t0, $a0
addiu $t0, $t0, -1
sb $t0, 0x0($v1)
.after_remainder:
jr $ra
nop
/**
* vmHandleMiss is called from the exception handler when a request is made to
* access a virtual memory address that isn't currently mapped in the TLB.
* vmHandleMiss must load the page from ROM if not already loaded, then map it
* in the TLB.
*
* In NTSC Final, there are 443 virtual pages, 268 slots where these can be loaded,
* and 30 of these can be mapped in the TLB at the same time.
*/
glabel vmHandleMiss
# C0_CONTEXT must be the 512-byte chunk index that was requested?
# Convert it to a virtual address
mfc0 $t0, C0_CONTEXT
sll $s5, $t0, 9
li $t1, VM_VIRTUAL_ADDR
sub $t0, $s5, $t1
srl $t0, $t0, VM_PAGE_SIZE_SHIFT # t0 = virtual page index
# Multiply t0 by 8 to get the V2P table offset
sll $t0, $t0, 3
lw $t1, g_VmVirtualToPhysicalTable
addu $s0, $t0, $t1 # s0 = pointer to V2P entry
# Check that the requested address is within the virtual range
li $s8, VM_VIRTUAL_ADDR
slt $at, $s5, $s8
bnez $at, .out_of_range
nop
lw $t1, g_VmRamEnd
slt $at, $s5, $t1
beqz $at, .out_of_range
nop
#if VERSION < VERSION_NTSC_1_0
# Increment g_VmNumTlbMisses
la $t2, g_VmNumTlbMisses
lw $t6, 0($t2)
addiu $t6, $t6, 1
sw $t6, 0($t2)
#endif
# If the page index is even then read the current slot's unk00.
# If the page index is odd then read from the next slot's unk00.
mfc0 $t9, C0_BADVADDR
srl $t9, $t9, VM_PAGE_SIZE_SHIFT
andi $t9, $t9, 1
beqzl $t9, .after_odd_even_check1
lw $s1, 0x0($s0)
lw $s1, 0x8($s0)
.after_odd_even_check1:
bnezl $s1, .map_tlb # Page is already loaded, so just map it
li $t5, 1
li $t5, 0
lw $t1, g_VmVacantFirstByte
lw $t2, g_VmVacantLastByte
# Find any bit that is set in the byte array
.find_byte_loop:
lbu $t0, 0x0($t1)
beqz $t0, .after_bit_loop
nop
li $t6, 0
li $t7, 1
.find_bit_loop:
and $t8, $t0, $t7
bnez $t8, .use_empty_slot
nop
addiu $t6, $t6, 1
li $at, 8
bne $t6, $at, .find_bit_loop
sll $t7, $t7, 1
.after_bit_loop:
bne $t1, $t2, .find_byte_loop
addiu $t1, $t1, 1
# All slots are allocated
j .choose_page_to_replace
nop
.use_empty_slot:
# t0 is the available byte's value
# t1 is a pointer to the available byte
# t6 is the bit index (0-7) of the available bit
# t7 is the bit power (1, 2, 4.. 128) of the available bit
xor $t0, $t0, $t7
sb $t0, 0x0($t1)
lw $t2, g_VmVacantFirstByte
lw $s1, g_VmSlotsPhysicalAddr
subu $t1, $t1, $t2 # t1 = byte index
sll $t1, $t1, 3 # t1 now a V2P table byte offset
addu $t0, $t6, $t1 # t0 = offset to V2P table entry
sll $t0, $t0, VM_PAGE_SIZE_SHIFT # t0 now the virtual page index of the empty slot
addu $s1, $s1, $t0
.load_page:
#if VERSION < VERSION_NTSC_1_0
# Increment g_VmNumPageMisses
la $t2, g_VmNumPageMisses
lw $t0, 0($t2)
addiu $t0, $t0, 1
sw $t0, 0($t2)
#endif
# Calculate the offset of the entry in the zip table.
# The zip table is an array of ROM offsets where each zip can be found.
mfc0 $t2, C0_BADVADDR
li $t0, 0x01000000 - VM_PAGE_SIZE
and $t2, $t2, $t0
srl $t2, $t2, 10
lw $t0, g_VmZipTable
addu $t0, $t0, $t2
lw $t2, 0x0($t0) # t2 = zip ROM start address
lw $t0, 0x4($t0) # t0 = zip ROM end address
subu $t0, $t0, $t2 # t0 = zip length (compressed)
# Align the zip length to 0x10
li $t1, 0xfffffff0
addiu $t0, $t0, 15
and $t6, $t0, $t1
# Wait for the PI to be available
li $t0, PHYS_TO_K1(PI_STATUS_REG)
.wait_for_pi_ready_loop:
lw $t1, 0x0($t0)
andi $t1, $t1, PI_STATUS_DMA_BUSY | PI_STATUS_IO_BUSY
bnez $t1, .wait_for_pi_ready_loop
nop
# Check if the PI has a pending interrupt - this will be used after the DMA
lw $s6, PHYS_TO_K1(MI_INTR_REG)
andi $s6, $s6, MI_INTR_PI
# Set PI_DRAM_ADDR_REG to g_VmZipBuffer (where the zip will be loaded to)
li $t0, PHYS_TO_K1(PI_DRAM_ADDR_REG)
lw $t1, g_VmZipBuffer
li $t7, 0x0fffffff
and $t1, $t1, $t7
sw $t1, 0x0($t0)
# Set PI_CART_ADDR_REG to the ROM address of the zip
li $t0, PHYS_TO_K1(PI_CART_ADDR_REG)
lw $t1, osRomBase
or $t1, $t1, $t2
li $t2, 0x1fffffff
and $t1, $t1, $t2
sw $t1, 0x0($t0)
# Set PI_WR_LEN_REG to the aligned size of the zip
li $t0, PHYS_TO_K1(PI_WR_LEN_REG)
addiu $t6, $t6, -1
sw $t6, 0x0($t0)
beqzl $t9, .after_odd_even_check2
nop
beqzl $zero, .pointless_branch
sw $s1, 0x8($s0)
.after_odd_even_check2:
sw $s1, 0x0($s0)
.pointless_branch:
li $t0, PHYS_TO_K1(PI_STATUS_REG)
.wait_for_pi_dma_completed_loop:
lw $t1, 0x0($t0)
andi $t1, $t1, PI_STATUS_DMA_BUSY | PI_STATUS_IO_BUSY
bnez $t1, .wait_for_pi_dma_completed_loop
nop
# Invalidate cache in the zip buffer area
lw $t0, g_VmZipBuffer
addiu $t1, $t0, VM_PAGE_SIZE
.invalidate_dcache_loop:
cache 0x15, 0x0($t0)
sltu $at, $t0, $t1
bnez $at, .invalidate_dcache_loop
addiu $t0, $t0, 16
# If the PI didn't previously have a pending interrupt,
# make sure the above work hasn't triggered one
bnez $s6, .after_clear_pi_interrupt
nop
li $t0, PI_CLR_INTR
lui $at, %hi(PHYS_TO_K1(PI_STATUS_REG))
sw $t0, %lo(PHYS_TO_K1(PI_STATUS_REG))($at)
.after_clear_pi_interrupt:
# Set stack pointer to g_VmTempStack
la $a0, g_VmTempStack
addiu $a0, $a0, 0xff8
sw $sp, 0x0($a0)
addiu $sp, $a0, 0
# Prepare arguments for rzipInflate
lw $a0, g_VmZipBuffer
addiu $a0, $a0, 2 # Move past the 2-byte checksum
li $t0, K0BASE
or $a1, $s1, $t0
la $a2, g_VmScratch
# Save registers to the stack
addiu $sp, $sp, -0x80
sw $ra, 0x0($sp)
sw $at, 0x4($sp)
sw $v0, 0x8($sp)
sw $v1, 0xc($sp)
sw $a0, 0x10($sp)
sw $a1, 0x14($sp)
sw $a2, 0x18($sp)
sw $a3, 0x1c($sp)
sw $t0, 0x20($sp)
sw $t1, 0x24($sp)
sw $t2, 0x28($sp)
sw $t3, 0x2c($sp)
sw $t4, 0x30($sp)
sw $t5, 0x34($sp)
sw $t6, 0x38($sp)
sw $t7, 0x3c($sp)
sw $s0, 0x40($sp)
sw $s1, 0x44($sp)
sw $s2, 0x48($sp)
sw $s3, 0x4c($sp)
sw $s4, 0x50($sp)
sw $s5, 0x54($sp)
sw $s6, 0x58($sp)
sw $s7, 0x5c($sp)
sw $t8, 0x60($sp)
sw $t9, 0x64($sp)
sw $gp, 0x70($sp)
sw $sp, 0x74($sp)
sw $s8, 0x78($sp)
# Unzip the zip
jal rzipInflate
nop
# Reload registers from the stack
lw $ra, 0x0($sp)
lw $at, 0x4($sp)
lw $v0, 0x8($sp)
lw $v1, 0xc($sp)
lw $a0, 0x10($sp)
lw $a1, 0x14($sp)
lw $a2, 0x18($sp)
lw $a3, 0x1c($sp)
lw $t0, 0x20($sp)
lw $t1, 0x24($sp)
lw $t2, 0x28($sp)
lw $t3, 0x2c($sp)
lw $t4, 0x30($sp)
lw $t5, 0x34($sp)
lw $t6, 0x38($sp)
lw $t7, 0x3c($sp)
lw $s0, 0x40($sp)
lw $s1, 0x44($sp)
lw $s2, 0x48($sp)
lw $s3, 0x4c($sp)
lw $s4, 0x50($sp)
lw $s5, 0x54($sp)
lw $s6, 0x58($sp)
lw $s7, 0x5c($sp)
lw $t8, 0x60($sp)
lw $t9, 0x64($sp)
lw $gp, 0x70($sp)
lw $sp, 0x74($sp)
lw $s8, 0x78($sp)
addiu $sp, $sp, 0x80
# Restore the stack pointer
la $a0, g_VmTempStack
addiu $a0, $a0, 0xff8
lw $sp, 0x0($a0)
# Invalidate the cache
li $t0, K0BASE
or $t0, $s1, $t0
addiu $t1, $t0, VM_PAGE_SIZE - 0x10
.invalidate_dcache_loop2:
cache 0x19, 0x0($t0)
sltu $at, $t0, $t1
bnez $at, .invalidate_dcache_loop2
addiu $t0, $t0, 0x10
.map_tlb:
li $t0, OS_PM_4K
mtc0 $t0, C0_PAGEMASK
mtc0 $s5, C0_ENTRYHI
nop
nop
nop
tlbp
nop
nop
mfc0 $t1, C0_INX
mtc0 $t0, C0_PAGEMASK
mtc0 $s5, C0_ENTRYHI
lw $t0, 0x0($s0)
srl $t0, $t0, VM_PAGE_SIZE_SHIFT
sll $t0, $t0, 6
bnezl $t0, .set_entrylo0
ori $t0, $t0, 0x1e
.set_entrylo0:
mtc0 $t0, C0_ENTRYLO0
lw $t0, 0x8($s0)
srl $t0, $t0, VM_PAGE_SIZE_SHIFT
sll $t0, $t0, 6
bnezl $t0, .set_entrylo1
ori $t0, $t0, 0x1e
.set_entrylo1:
mtc0 $t0, C0_ENTRYLO1
bltzl $t1, .write_random_tlb_entry
nop
b .after_write_tlb
tlbwi # Replace TLB entry at index C0_INX
.write_random_tlb_entry:
tlbwr # Replace a random TLB entry
.after_write_tlb:
bnez $t5, .after_invalidate_cache
nop
move $t0, $s5
bnezl $t9, .after_odd_even_check3
addiu $t0, $t0, VM_PAGE_SIZE
.after_odd_even_check3:
addiu $t1, $t0, VM_PAGE_SIZE - 0x20
andi $t2, $t0, 0x1f
subu $t0, $t0, $t2
.invalidate_dcache_loop3:
cache 0x10, 0x0($t0)
sltu $at, $t0, $t1
bnez $at, .invalidate_dcache_loop3
addiu $t0, $t0, 0x20
.after_invalidate_cache:
jr $ra
nop
.choose_page_to_replace:
# This part of the function chooses a loaded-but-unmapped slot to be replaced.
# The physical address of the page is stored to s1, then it jumps to load_page.
#if VERSION < VERSION_NTSC_1_0
# Increment g_VmNumPageReplaces
la $t0, g_VmNumPageReplaces
lw $t1, 0($t0)
addiu $t1, $t1, 1
sw $t1, 0($t0)
#endif
.evict_loop:
# Choose a slot to evict. This is done by taking C0_COUNT & 0x1ff.
# If this is still bigger than the number of pages then the number of pages
# is subtracted from the value.
lw $s4, g_VmVirtualToPhysicalTable
lw $gp, g_VmVirtualToPhysicalTableEnd
mfc0 $t0, C0_COUNT
lhu $t1, g_VmEvictMask
lw $t2, g_VmNumPages
and $t0, $t0, $t1
slt $at, $t0, $t2
beqzl $at, .after_subtract
subu $t0, $t0, $t2
.after_subtract:
# Convert it to a V2P table offset
sll $t1, $t0, 3
addu $t1, $t1, $s4
# Move forward through the table until a loaded slot is found.
# If the end is reached, wrap back to the start.
.slot_loop:
lw $s1, 0x0($t1)
bnez $s1, .check_tlb_entry
nop
addiu $t1, $t1, 8
bne $t1, $gp, .slot_loop
nop
j .slot_loop
move $t1, $s4
.check_tlb_entry:
# Query the TLB to make sure this page isn't currently mapped.
# If it is then it must have been used recently, so find another page to replace.
subu $t0, $t1, $s4 # t0 is now an offset in the V2P table
srl $t0, $t0, 3 # t0 is now an index in the V2P table
sll $t0, $t0, VM_PAGE_SIZE_SHIFT # t0 is now the byte offset in the physical slots
addu $t0, $t0, $s8 # t0 += 0x7f000000
li $t2, 0x100000000 - VM_PAGE_SIZE
and $t0, $t0, $t2 # t0 is now aligned to a page
mtc0 $t0, C0_ENTRYHI
li $t0, OS_PM_4K
mtc0 $t0, C0_PAGEMASK
nop
nop
nop
# tlbp sets C0_INX to to the index of the TLB entry which has the given ENTRYHI
tlbp
nop
nop
mfc0 $t2, C0_INX
mfc0 $t0, C0_ENTRYHI
bltz $t2, .not_mapped
nop
j .evict_loop
nop
.not_mapped:
# The page is not mapped in the TLB, so it's okay to replace it.
sw $zero, 0x0($t1)
j .load_page
nop
.out_of_range:
j handle_fault
nop
glabel vmUnmapRange
mfc0 $t0, C0_ENTRYHI
li $t2, K0BASE
mtc0 $t2, C0_ENTRYHI
mtc0 $zero, C0_ENTRYLO0
mtc0 $zero, C0_ENTRYLO1
.unmap_loop:
mtc0 $a1, C0_INX
nop
tlbwi
nop
nop
bne $a1, $a0, .unmap_loop
addi $a1, $a1, -1
mtc0 $t0, C0_ENTRYHI
jr $ra
nop
#if VERSION < VERSION_NTSC_1_0
glabel vmInvalidateFirst8Kb
li $t0, K0BASE
addiu $t1, $t0, 0x1ff0
.invalidate_dcache_loop4:
cache 0x1, 0x0($t0)
sltu $at, $t0, $t1
bnez $at, .invalidate_dcache_loop4
addiu $t0, $t0, 0x10
jr $ra
nop
#endif

View File

@ -7,6 +7,7 @@
#include "lib/rzip.h"
#include "lib/dma.h"
#include "lib/lib_48150.h"
#include "lib/vm.h"
#include "data.h"
#include "types.h"
@ -74,7 +75,7 @@ u32 g_VmNumPageMisses;
u32 g_VmNumPageReplaces;
u8 *g_VmMarker;
u32 g_VmRamEnd;
u32 g_VmStateTableEnd;
u32 g_VmVirtualToPhysicalTableEnd;
#ifdef DEBUG
u8 g_VmShowStats = false;
@ -98,20 +99,12 @@ extern u8 _gameSegmentStart;
extern u8 _gameSegmentEnd;
extern u8 _gamezipSegmentRomStart;
extern u32 var8008ae20;
extern u32 *g_VmStateTable;
extern u32 g_VmPhysicalSlots;
extern u32 *g_VmVirtualToPhysicalTable;
extern u8 g_VmInitialised;
extern u32 g_VmZipBuffer;
extern u32 *g_VmZipTable;
#define PAGE_SIZE (1024 * 4)
#if VERSION >= VERSION_NTSC_1_0
#define MAX_LOADED_PAGES 268
#else
#define MAX_LOADED_PAGES 266
#endif
/**
* Initialise the virtual memory.
*
@ -152,7 +145,7 @@ extern u32 *g_VmZipTable;
* Addresses: 0x??? 0x80220000 0x803f50b8 0x80400000
* Lengths: 0x6ec 0x1b99e0 0xaf48 0
*
* zip buffer: is sized as PAGE_SIZE * 2, which guarantees it's big enough to
* zip buffer: is sized as VM_PAGE_SIZE * 2, which guarantees it's big enough to
* hold any zip.
* zip table: is the ROM offset table where each zip can be found.
* game seg: is where the entire game segment is unzipped to.
@ -214,14 +207,14 @@ void vmInit(void)
{
g_Is4Mb = true;
g_VmNumPages = (s32)((&_gameSegmentEnd - &_gameSegmentStart) + (PAGE_SIZE - 1)) / PAGE_SIZE;
g_VmNumPages = (s32)((&_gameSegmentEnd - &_gameSegmentStart) + (VM_PAGE_SIZE - 1)) / VM_PAGE_SIZE;
g_VmRamEnd = 0x7f000000 + PAGE_SIZE * g_VmNumPages;
g_VmStateTableEnd = STACK_START;
g_VmRamEnd = 0x7f000000 + VM_PAGE_SIZE * g_VmNumPages;
g_VmVirtualToPhysicalTableEnd = STACK_START;
gameseg = (u8 *) (STACK_START - g_VmNumPages * 8);
g_VmStateTable = (u32 *) gameseg;
g_VmVirtualToPhysicalTable = (u32 *) gameseg;
numpages = (u32) (((uintptr_t) &_gameSegmentEnd - (uintptr_t) &_gameSegmentStart) + (PAGE_SIZE - 1)) / PAGE_SIZE;
numpages = (u32) (((uintptr_t) &_gameSegmentEnd - (uintptr_t) &_gameSegmentStart) + (VM_PAGE_SIZE - 1)) / VM_PAGE_SIZE;
numentries = numpages + 1;
g_VmZipTable = (u32 *) ((uintptr_t) ((u32 *) gameseg - (numentries + 4)) & ~0xf);
@ -249,27 +242,27 @@ void vmInit(void)
s1 &= (u32) ~0xf;
g_VmZipBuffer = (uintptr_t) g_VmZipTable - s1;
g_VmZipBuffer &= ~0xf;
gameseg = (u8 *) (g_VmZipBuffer - MAX_LOADED_PAGES * PAGE_SIZE);
gameseg = (u8 *) (g_VmZipBuffer - VM_NUM_SLOTS * VM_PAGE_SIZE);
gameseg -= (uintptr_t) gameseg & 0x1fff;
var8008ae20 = (uintptr_t) gameseg;
g_VmPhysicalSlots = (uintptr_t) gameseg;
g_VmMarker = gameseg;
tlb000010a4();
vmInitVars();
// Clear the state table
ptr = g_VmStateTable;
ptr = g_VmVirtualToPhysicalTable;
statetablelen = (g_VmNumPages * 8) >> 2;
for (s1 = 0; s1 < statetablelen; s1++) {
ptr[s1] = 0;
}
tlb0000113c();
vmInitVacant();
} else {
// Expansion pak is being used
g_Is4Mb = numentries * false;
numpages = (u32)((&_gameSegmentEnd - &_gameSegmentStart) + (PAGE_SIZE - 1)) / PAGE_SIZE;
numpages = (u32)((&_gameSegmentEnd - &_gameSegmentStart) + (VM_PAGE_SIZE - 1)) / VM_PAGE_SIZE;
s7 = (u8 *) STACK_START;
#if VERSION >= VERSION_NTSC_1_0
@ -302,7 +295,7 @@ void vmInit(void)
// Load each zip from the ROM and inflate them to the game segment
s2 = gameseg;
chunkbuffer = (u8 *) ((uintptr_t) romaddrs - PAGE_SIZE * 2);
chunkbuffer = (u8 *) ((uintptr_t) romaddrs - VM_PAGE_SIZE * 2);
zip = chunkbuffer + 2;
for (ITER = 0; ITER < numentries2 - 1;) {

View File

@ -1,3 +1,4 @@
#include "asm_helper.h"
#include "macros.inc"
.set noat
.set noreorder
@ -6,21 +7,22 @@
/**
* This function is generated automatically by makerom. It clears the BSS
* segment, sets the stack pointer to 0x80000f10 and then calls boot.
* segment, sets the stack pointer to 0x80000f10 and then calls vmBoot.
*/
glabel preamble
lui $t0, %hi(_bssSegmentStart)
lui $t1, %hi(_bssSegmentLen)
addiu $t0, $t0, %lo(_bssSegmentStart)
ori $t1, $t1, %lo(_bssSegmentLen)
.L00001010:
.bss_loop:
addi $t1, $t1, -8
sw $zero, 0($t0)
sw $zero, 4($t0)
bnez $t1, .L00001010
bnez $t1, .bss_loop
addi $t0, $t0, 8
lui $t2, %hi(tlbInitFromPreamble)
lui $sp, 0x8000
addiu $t2, $t2, %lo(tlbInitFromPreamble)
lui $t2, %hi(vmBootFromPreamble)
li $sp, K0BASE
addiu $t2, $t2, %lo(vmBootFromPreamble)
jr $t2
addiu $sp, $sp, 0xf10

View File

@ -163,7 +163,7 @@ static void patch(Algo algo, char *patchfunc, char *sumfunc)
void piracy_patch_checksums(void)
{
// algorithm, patch function, sum function
patch(algo01, "__scHandleTasks", "bootPhase1");
patch(algo01, "__scHandleTasks", "boot");
patch(algo02, "cheatMenuHandleDialog", "__scHandleTasks");
patch(algo03, "botPickupProp", "doorFinishClose");
patch(algo04, "chrUncloak", "botPickupProp");