Attempt to decompile vmInit

This commit is contained in:
Ryan Dwyer committed 2021-11-05 22:14:12 +10:00
1 parent 8a8b762c10
commit c4f6aaab83
9 files changed
+352 -91

No files matched your search

+3 -8
View File
@@ -4,11 +4,6 @@
#include "constants.h"
#include "types.h"
extern u32 var8008ae20;
extern u32 var8008ae24;
extern u32 var8008ae28;
extern u32 var8008ae2c;
extern u32 var8008ae30;
extern OSThread g_MainThread;
extern OSMesgQueue g_SchedMesgQueue;
extern OSSched g_Sched;
@@ -28,9 +23,9 @@ extern u8 g_Is4Mb;
extern u32 g_VmNumTlbMisses;
extern u32 g_VmNumPageMisses;
extern u32 g_VmNumPageReplaces;
extern u32 var80090b00;
extern u32 var80090b04;
extern u32 var80090b08;
extern u32 g_VmMarker;
extern u32 g_VmRamEnd;
extern u32 g_VmStateTableEnd;
extern AMAudioMgr g_AudioManager;
extern Mtx *var80092870;
extern s32 g_SndMaxFxBusses;
+1 -1
View File
@@ -23,7 +23,7 @@
#define ALIGN2(val) (((val) | 1) ^ 0x1)
#define ALIGN8(val) (((val) + 0x7 | 0x7) ^ 0x7)
#define ALIGN16(val) (((val) + 0xf | 0xf) ^ 0xf)
#define ALIGN64(val) ((((u32)val) + 0x3f | 0x3f) ^ 0x3f)
#define ALIGN64(val) ((((u32)(val)) + 0x3f | 0x3f) ^ 0x3f)
#define ARRAYCOUNT(a) (s32)(sizeof(a) / sizeof(a[0]))
#define CHRRACE(chr) (chr ? chr->race : RACE_HUMAN)
#define CRASH() *(u8 *)0 = 69
+1 -1
View File
@@ -27,7 +27,7 @@ extern u32 var8005cf30;
extern OSTime osClockRate;
extern s32 osViClock;
extern u32 __osGlobalIntMask;
extern u32 var8005cf84;
extern s32 g_VmNumPages;
extern u8 g_LoadType;
extern s32 g_MainIsEndscreen;
extern s32 var8005dd18;
+2 -2
View File
@@ -4,8 +4,8 @@
#include "data.h"
#include "types.h"
u32 rzipInflate(void *src, void *dst, void *scratch);
u32 rzipInflateFixed(void);
s32 rzipInflate(void *src, void *dst, void *scratch);
u32 rzipInit(void);
bool rzipIs1173(void *buffer);
u32 rzipGetSomething(void);
+3 -3
View File
@@ -3,9 +3,9 @@
#include <ultra64.h>
void tlbInit(void);
s32 tlb000010a4(void);
s32 tlb0000113c(void);
s32 tlbHandleMiss(void);
void tlb000010a4(void);
void tlb0000113c(void);
void tlbHandleMiss(void);
void tlbUnmapRange(u32 first, u32 last);
#endif
+6 -6
View File
@@ -823,8 +823,8 @@ glabel mainInit
/* d6f0: 0041082a */ slt $at,$v0,$at
/* d6f4: 1020000e */ beqz $at,.L0000d730
/* d6f8: 3c028080 */ lui $v0,0x8080
/* d6fc: 3c0b8006 */ lui $t3,%hi(var8005cf84)
/* d700: 8d6bcf84 */ lw $t3,%lo(var8005cf84)($t3)
/* d6fc: 3c0b8006 */ lui $t3,%hi(g_VmNumPages)
/* d700: 8d6bcf84 */ lw $t3,%lo(g_VmNumPages)($t3)
/* d704: 3c18803f */ lui $t8,0x803f
/* d708: 371850b8 */ ori $t8,$t8,0x50b8
/* d70c: 3c01ffef */ lui $at,0xffef
@@ -1003,8 +1003,8 @@ glabel mainInit
/* d984: 3c04800b */ lui $a0,%hi(_bssSegmentEnd)
/* d988: 0c012d20 */ jal osVirtualToPhysical
/* d98c: 2484d1c0 */ addiu $a0,$a0,%lo(_bssSegmentEnd)
/* d990: 3c038009 */ lui $v1,%hi(var80090b00)
/* d994: 8c630b00 */ lw $v1,%lo(var80090b00)($v1)
/* d990: 3c038009 */ lui $v1,%hi(g_VmMarker)
/* d994: 8c630b00 */ lw $v1,%lo(g_VmMarker)($v1)
/* d998: 3c018000 */ lui $at,0x8000
/* d99c: 00412025 */ or $a0,$v0,$at
/* d9a0: 0c00487a */ jal mempInit
@@ -1538,7 +1538,7 @@ const char var70053aa0[] = " -ml0 -me0 -mgfx100 -mvtx50 -mt700 -ma400";
// u32 stack;
//
// if (bootGetMemSize() <= 4 * 1024 * 1024) {
// iVar5 = 0x803f50b8 - var8005cf84 * 8;
// iVar5 = 0x803f50b8 - g_VmNumPages * 8;
// iVar5 -= 548864 * 2;
// iVar5 = iVar5 - (iVar5 & 0x1fff) - 0x1c80;
// } else {
@@ -1635,7 +1635,7 @@ const char var70053aa0[] = " -ml0 -me0 -mgfx100 -mvtx50 -mt700 -ma400";
// }
//
// uVar2 = osVirtualToPhysical(&_bssSegmentEnd) | 0x80000000;
// tmp = var80090b00;
// tmp = g_VmMarker;
// mempInit(uVar2, tmp - uVar2);
//
// mempResetPool(MEMPOOL_8);
+3 -3
View File
@@ -573,7 +573,7 @@ glabel rzipInflateBlock
.L000079e8:
bne $t3, $at, .L00007a00
nop
jal rzipInflateFixed2
jal rzipInflateFixed
nop
j .L00007a04
nop
@@ -1013,7 +1013,7 @@ glabel rzipInflateStored
jr $ra
li $v0, 1
glabel rzipInflateFixed2
glabel rzipInflateFixed
sw $ra, 0xa44($sp)
sw $s6, 0xa74($sp)
lui $s6, %hi(var80090b10)
@@ -1629,7 +1629,7 @@ glabel rzipInflateCodes
jr $ra
li $v0, 4
glabel rzipInflateFixed
glabel rzipInit
addiu $sp, $sp, -2696
sw $s0, 0xa48($sp)
sw $s1, 0xa4c($sp)
+36 -36
View File
@@ -1,3 +1,4 @@
#include "os_tlb.h"
#include "asm_helper.h"
#include "macros.inc"
#include "versions.h"
@@ -9,16 +10,16 @@
glabel var8008ae20
.space 4
glabel var8008ae24;
glabel g_VmStateTable;
.space 4
glabel var8008ae28;
glabel g_VmInitialised;
.space 4
glabel var8008ae2c;
glabel g_VmZipBuffer;
.space 4
glabel var8008ae30;
glabel g_VmZipTable;
.space 8
glabel var8008ae38
@@ -51,8 +52,7 @@ glabel var8008d268
* Sets up TLB index 0 (0x70000000), then calls bootPhase1.
*/
glabel tlbInit
lui $t0, 0x7f
ori $t0, $t0, 0xe000
li $t0, OS_PM_4M
mtc0 $t0, C0_PAGEMASK
lui $t0, 0x7000
mtc0 $t0, C0_ENTRYHI
@@ -61,7 +61,7 @@ glabel tlbInit
lui $t0, 0x1
ori $t0, $t0, 0x1f
mtc0 $t0, C0_ENTRYLO1
addiu $t0, $zero, 0x0
addiu $t0, $zero, 0
mtc0 $t0, C0_INX
nop
tlbwi
@@ -87,8 +87,8 @@ glabel tlb000010a4
#else
addiu $a0, $zero, 266
#endif
lui $at, %hi(var8008ae28+0x2)
sh $a0, %lo(var8008ae28+0x2)($at)
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
@@ -96,8 +96,8 @@ glabel tlb000010a4
lw $v0, %lo(var8008ae20)($v0)
lui $t1, %hi(_gameSegmentEnd)
addiu $t1, $t1, %lo(_gameSegmentEnd)
lui $t2, %hi(func0f000000)
addiu $t2, $t2, %lo(func0f000000)
lui $t2, %hi(_gameSegmentStart)
addiu $t2, $t2, %lo(_gameSegmentStart)
subu $t1, $t1, $t2
lui $t0, 0xfff
ori $t0, $t0, 0xffff
@@ -149,21 +149,21 @@ glabel tlbHandleMiss
sub $t0, $s5, $t1
srl $t0, $t0, 0xc
sll $t0, $t0, 0x3
lui $t1, %hi(var8008ae24)
lw $t1, %lo(var8008ae24)($t1)
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(var80090b04)
lw $t1, %lo(var80090b04)($t1)
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, 0x8009
addiu $t2, $t2, 0x30e4
lui $t2, %hi(g_VmNumTlbMisses)
addiu $t2, $t2, %lo(g_VmNumTlbMisses)
lw $t6, 0($t2)
addiu $t6, $t6, 1
sw $t6, 0($t2)
@@ -215,8 +215,8 @@ glabel tlbHandleMiss
addu $s1, $s1, $t0
.L00001268:
#if VERSION < VERSION_NTSC_1_0
lui $t2, 0x8009
addiu $t2, $t2, 0x30e8
lui $t2, %hi(g_VmNumPageMisses)
addiu $t2, $t2, %lo(g_VmNumPageMisses)
lw $t0, 0($t2)
addiu $t0, $t0, 1
sw $t0, 0($t2)
@@ -226,8 +226,8 @@ glabel tlbHandleMiss
ori $t0, $t0, 0xf000
and $t2, $t2, $t0
srl $t2, $t2, 0xa
lui $t0, %hi(var8008ae30)
lw $t0, %lo(var8008ae30)($t0)
lui $t0, %hi(g_VmZipTable)
lw $t0, %lo(g_VmZipTable)($t0)
addu $t0, $t0, $t2
lw $t2, 0x0($t0)
lw $t0, 0x4($t0)
@@ -246,8 +246,8 @@ glabel tlbHandleMiss
lw $s6, 0x8($s6)
andi $s6, $s6, 0x10
lui $t0, 0xa460
lui $t1, %hi(var8008ae2c)
lw $t1, %lo(var8008ae2c)($t1)
lui $t1, %hi(g_VmZipBuffer)
lw $t1, %lo(g_VmZipBuffer)($t1)
lui $t7, 0xfff
ori $t7, $t7, 0xffff
and $t1, $t1, $t7
@@ -279,8 +279,8 @@ glabel tlbHandleMiss
andi $t1, $t1, 0x3
bnez $t1, .L00001330
nop
lui $t0, %hi(var8008ae2c)
lw $t0, %lo(var8008ae2c)($t0)
lui $t0, %hi(g_VmZipBuffer)
lw $t0, %lo(g_VmZipBuffer)($t0)
addiu $t1, $t0, 0x1000
.L0000134c:
cache 0x15, 0x0($t0)
@@ -298,8 +298,8 @@ glabel tlbHandleMiss
addiu $a0, $a0, 0xff8
sw $sp, 0x0($a0)
addiu $sp, $a0, 0x0
lui $a0, %hi(var8008ae2c)
lw $a0, %lo(var8008ae2c)($a0)
lui $a0, %hi(g_VmZipBuffer)
lw $a0, %lo(g_VmZipBuffer)($a0)
addiu $a0, $a0, 0x2
lui $t0, 0x8000
or $a1, $s1, $t0
@@ -380,7 +380,7 @@ glabel tlbHandleMiss
bnez $at, .L000014b4
addiu $t0, $t0, 0x10
.L000014c4:
addiu $t0, $zero, 0x0
addiu $t0, $zero, OS_PM_4K
mtc0 $t0, C0_PAGEMASK
mtc0 $s5, C0_ENTRYHI
nop
@@ -432,22 +432,22 @@ glabel tlbHandleMiss
nop
.L00001570:
#if VERSION < VERSION_NTSC_1_0
lui $t0, 0x8009
addiu $t0, $t0, 0x30ec
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(var8008ae24)
lw $s4, %lo(var8008ae24)($s4)
lui $gp, %hi(var80090b08)
lw $gp, %lo(var80090b08)($gp)
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(var8005cf84)
lw $t2, %lo(var8005cf84)($t2)
lui $t2, %hi(g_VmNumPages)
lw $t2, %lo(g_VmNumPages)($t2)
and $t0, $t0, $t1
slt $at, $t0, $t2
beqzl $at, .L000015a4
+297 -31
View File
@@ -8,14 +8,71 @@
#include "data.h"
#include "types.h"
/**
* vm - virtual memory
*
* To get around memory limitations, Perfect Dark implements a memory paging
* system similar to ones found in modern operating systems. Memory is divided
* into pages and can be accessed by virtual addresses. If the page does not
* exist in physical memory then the operating system can replace a page in
* physical memory with the required one and try again. This allows the system
* to address more memory than is actually loaded and have a smaller memory
* footprint.
*
* All code in the game is divided into two segments: Unpagable and pagable.
*
* Unpagable:
* - Is what decomp calls lib.
* - Is virtual at 0x70000000 and statically mapped to 0x80000000.
* - Contains frequently used code which would be a bad idea to swap in and out,
* as well as all of libultra.
*
* Pagable:
* - Is what decomp calls game.
* - Is virtual at 0x7f000000.
* - Contains the majority of the game code.
*
* Paging cannot occur for any sections which are writeable in memory because
* the N64 ROM is read only. Sections of this type are .data and .bss.
* These sections reside in physical memory at 0x80000000 and are not pagable.
*
* Paging is implemented for the .text (ie. code) and .rodata segments. When
* building the ROM image, these are grouped into one binary then sliced into
* chunks of size 4KB (the page size). Each chunk is zipped and then each zip is
* placed on the ROM along with a zip offset table.
*
* The N64 contains a translation lookaside buffer (TLB), a feature of the CPU
* which can map virtual memory to physical memory. The TLB contains a table of
* 32 entries. Each entry can map two pages, and PD's page size is 4KB. The
* unpagable segment described above is mapped using one TLB entry, leaving 31
* entries for dynamic paging.
*
* A page an be in one of three states:
* - Mapped in the TLB and loaded in physical memory.
* - Not mapped in the TLB but still loaded in physical memory.
* - Not mapped in the TLB and not in physical memory
* (must be unzipped from the ROM to access).
*
* A TLB miss occurs when a request is made for a page that isn't mapped in the
* TLB. When this happens, the system's exception handler checks if the page
* exists in physical memory or not. If it does, a TLB entry is created for it.
*
* A page miss occurs when the page didn't exist in physical memory. In this
* case the exception handler must load it from the ROM, unzip the page and
* replace an existing one.
*
* Paging is only implemented for 4MB systems (ie. when the expansion pak is not
* being used). When using the expansion pak all game code is loaded and the
* mappings in the TLB are static.
*/
u8 g_Is4Mb;
u32 g_VmNumTlbMisses;
u32 g_VmNumPageMisses;
u32 g_VmNumPageReplaces;
u32 var80090b00;
u32 var80090b04;
u32 var80090b08;
u32 var80090b0c;
u32 g_VmMarker;
u32 g_VmRamEnd;
u32 g_VmStateTableEnd;
#if VERSION < VERSION_NTSC_1_0
u8 g_VmShowStats = false;
@@ -23,9 +80,30 @@ u32 fillnb[2] = {0};
#endif
u32 var8005cf80 = 0;
u32 var8005cf84 = 0;
s32 g_VmNumPages = 0;
u32 var8005cf88 = 0;
extern u8 _gameSegmentStart;
extern u8 _gameSegmentEnd;
extern u8 _gamezipSegmentRomStart;
extern u32 var8008ae20;
extern u32 *g_VmStateTable;
extern u8 g_VmInitialised;
extern u32 g_VmZipBuffer;
extern u32 *g_VmZipTable;
#define PAGE_SIZE (1024 * 4)
#define MAX_LOADED_PAGES 268
#define VM_MEMORY_END (0x80400000 \
- STACKSIZE_MAIN \
- STACKSIZE_IDLE \
- STACKSIZE_RMON \
- STACKSIZE_SCHED \
- STACKSIZE_AUDIO - 8)
#if VERSION >= VERSION_NTSC_1_0
GLOBAL_ASM(
glabel vmInit
@@ -33,7 +111,7 @@ glabel vmInit
/* 70d4: afb0001c */ sw $s0,0x1c($sp)
/* 70d8: 24100001 */ addiu $s0,$zero,0x1
/* 70dc: afbf003c */ sw $ra,0x3c($sp)
/* 70e0: 3c018009 */ lui $at,%hi(var8008ae28)
/* 70e0: 3c018009 */ lui $at,%hi(g_VmInitialised)
/* 70e4: afb70038 */ sw $s7,0x38($sp)
/* 70e8: afb60034 */ sw $s6,0x34($sp)
/* 70ec: afb50030 */ sw $s5,0x30($sp)
@@ -41,8 +119,8 @@ glabel vmInit
/* 70f4: afb30028 */ sw $s3,0x28($sp)
/* 70f8: afb20024 */ sw $s2,0x24($sp)
/* 70fc: afb10020 */ sw $s1,0x20($sp)
/* 7100: 0c00222c */ jal rzipInflateFixed
/* 7104: a030ae28 */ sb $s0,%lo(var8008ae28)($at)
/* 7100: 0c00222c */ jal rzipInit
/* 7104: a030ae28 */ sb $s0,%lo(g_VmInitialised)($at)
/* 7108: 0c0005b0 */ jal bootGetMemSize
/* 710c: 00000000 */ nop
/* 7110: 3c010040 */ lui $at,0x40
@@ -51,25 +129,25 @@ glabel vmInit
/* 711c: 10200074 */ beqz $at,.L000072f0
/* 7120: 3c087f1c */ lui $t0,%hi(_gameSegmentEnd)
/* 7124: 3c087f1c */ lui $t0,%hi(_gameSegmentEnd)
/* 7128: 3c097f00 */ lui $t1,%hi(func0f000000)
/* 712c: 25290000 */ addiu $t1,$t1,%lo(func0f000000)
/* 7128: 3c097f00 */ lui $t1,%hi(_gameSegmentStart)
/* 712c: 25290000 */ addiu $t1,$t1,%lo(_gameSegmentStart)
/* 7130: 250899e0 */ addiu $t0,$t0,%lo(_gameSegmentEnd)
/* 7134: 3c018009 */ lui $at,%hi(g_Is4Mb)
/* 7138: 01097023 */ subu $t6,$t0,$t1
/* 713c: a0300af0 */ sb $s0,%lo(g_Is4Mb)($at)
/* 7140: 25cf0fff */ addiu $t7,$t6,0xfff
/* 7144: 3c178006 */ lui $s7,%hi(var8005cf84)
/* 7148: 26f7cf84 */ addiu $s7,$s7,%lo(var8005cf84)
/* 7144: 3c178006 */ lui $s7,%hi(g_VmNumPages)
/* 7148: 26f7cf84 */ addiu $s7,$s7,%lo(g_VmNumPages)
/* 714c: 3c07803f */ lui $a3,0x803f
/* 7150: 01091023 */ subu $v0,$t0,$t1
/* 7154: 34e750b8 */ ori $a3,$a3,0x50b8
/* 7158: 24420fff */ addiu $v0,$v0,0xfff
/* 715c: 00027302 */ srl $t6,$v0,0xc
/* 7160: 25c60002 */ addiu $a2,$t6,0x2
/* 7164: 3c158009 */ lui $s5,%hi(var8008ae30)
/* 7164: 3c158009 */ lui $s5,%hi(g_VmZipTable)
/* 7168: 25d60001 */ addiu $s6,$t6,0x1
/* 716c: 3c120005 */ lui $s2,%hi(_gamezipSegmentRomStart)
/* 7170: 26b5ae30 */ addiu $s5,$s5,%lo(var8008ae30)
/* 7170: 26b5ae30 */ addiu $s5,$s5,%lo(g_VmZipTable)
/* 7174: 05e10003 */ bgez $t7,.L00007184
/* 7178: 000fc303 */ sra $t8,$t7,0xc
/* 717c: 25e10fff */ addiu $at,$t7,0xfff
@@ -79,15 +157,15 @@ glabel vmInit
/* 7188: 0018cb00 */ sll $t9,$t8,0xc
/* 718c: 03216021 */ addu $t4,$t9,$at
/* 7190: aef80000 */ sw $t8,0x0($s7)
/* 7194: 3c018009 */ lui $at,%hi(var80090b04)
/* 7198: ac2c0b04 */ sw $t4,%lo(var80090b04)($at)
/* 719c: 3c018009 */ lui $at,%hi(var80090b08)
/* 7194: 3c018009 */ lui $at,%hi(g_VmRamEnd)
/* 7198: ac2c0b04 */ sw $t4,%lo(g_VmRamEnd)($at)
/* 719c: 3c018009 */ lui $at,%hi(g_VmStateTableEnd)
/* 71a0: 001868c0 */ sll $t5,$t8,0x3
/* 71a4: ac270b08 */ sw $a3,%lo(var80090b08)($at)
/* 71a4: ac270b08 */ sw $a3,%lo(g_VmStateTableEnd)($at)
/* 71a8: 00ed9823 */ subu $s3,$a3,$t5
/* 71ac: 3c018009 */ lui $at,%hi(var8008ae24)
/* 71ac: 3c018009 */ lui $at,%hi(g_VmStateTable)
/* 71b0: 25cf0005 */ addiu $t7,$t6,0x5
/* 71b4: ac33ae24 */ sw $s3,%lo(var8008ae24)($at)
/* 71b4: ac33ae24 */ sw $s3,%lo(g_VmStateTable)($at)
/* 71b8: 000fc080 */ sll $t8,$t7,0x2
/* 71bc: 00066880 */ sll $t5,$a2,0x2
/* 71c0: 0278c823 */ subu $t9,$s3,$t8
@@ -143,21 +221,21 @@ glabel vmInit
/* 7274: 0311c823 */ subu $t9,$t8,$s1
/* 7278: 032b6824 */ and $t5,$t9,$t3
/* 727c: 34214000 */ ori $at,$at,0x4000
/* 7280: 3c028009 */ lui $v0,%hi(var8008ae2c)
/* 7280: 3c028009 */ lui $v0,%hi(g_VmZipBuffer)
/* 7284: 01a19821 */ addu $s3,$t5,$at
/* 7288: 2442ae2c */ addiu $v0,$v0,%lo(var8008ae2c)
/* 7288: 2442ae2c */ addiu $v0,$v0,%lo(g_VmZipBuffer)
/* 728c: ac590000 */ sw $t9,0x0($v0)
/* 7290: 326e1fff */ andi $t6,$s3,0x1fff
/* 7294: ac4d0000 */ sw $t5,0x0($v0)
/* 7298: 026e9823 */ subu $s3,$s3,$t6
/* 729c: 3c018009 */ lui $at,%hi(var8008ae20)
/* 72a0: ac33ae20 */ sw $s3,%lo(var8008ae20)($at)
/* 72a4: 3c018009 */ lui $at,%hi(var80090b00)
/* 72a4: 3c018009 */ lui $at,%hi(g_VmMarker)
/* 72a8: 0c000429 */ jal tlb000010a4
/* 72ac: ac330b00 */ sw $s3,%lo(var80090b00)($at)
/* 72ac: ac330b00 */ sw $s3,%lo(g_VmMarker)($at)
/* 72b0: 8ee30000 */ lw $v1,0x0($s7)
/* 72b4: 3c048009 */ lui $a0,%hi(var8008ae24)
/* 72b8: 8c84ae24 */ lw $a0,%lo(var8008ae24)($a0)
/* 72b4: 3c048009 */ lui $a0,%hi(g_VmStateTable)
/* 72b8: 8c84ae24 */ lw $a0,%lo(g_VmStateTable)($a0)
/* 72bc: 000378c0 */ sll $t7,$v1,0x3
/* 72c0: 000f1883 */ sra $v1,$t7,0x2
/* 72c4: 18600006 */ blez $v1,.L000072e0
@@ -174,8 +252,8 @@ glabel vmInit
/* 72e8: 1000006a */ b .L00007494
/* 72ec: 00000000 */ nop
.L000072f0:
/* 72f0: 3c097f00 */ lui $t1,%hi(func0f000000)
/* 72f4: 25290000 */ addiu $t1,$t1,%lo(func0f000000)
/* 72f0: 3c097f00 */ lui $t1,%hi(_gameSegmentStart)
/* 72f4: 25290000 */ addiu $t1,$t1,%lo(_gameSegmentStart)
/* 72f8: 250899e0 */ addiu $t0,$t0,%lo(_gameSegmentEnd)
/* 72fc: 0109c823 */ subu $t9,$t0,$t1
/* 7300: 272c003f */ addiu $t4,$t9,0x3f
@@ -199,12 +277,12 @@ glabel vmInit
/* 7348: 026c6823 */ subu $t5,$s3,$t4
/* 734c: 25c6000f */ addiu $a2,$t6,0xf
/* 7350: 3c120005 */ lui $s2,%hi(_gamezipSegmentRomStart)
/* 7354: 3c018009 */ lui $at,%hi(var80090b00)
/* 7354: 3c018009 */ lui $at,%hi(g_VmMarker)
/* 7358: 27160001 */ addiu $s6,$t8,0x1
/* 735c: 2652fc40 */ addiu $s2,$s2,%lo(_gamezipSegmentRomStart)
/* 7360: 34cf000f */ ori $t7,$a2,0xf
/* 7364: 01aba824 */ and $s5,$t5,$t3
/* 7368: ac330b00 */ sw $s3,%lo(var80090b00)($at)
/* 7368: ac330b00 */ sw $s3,%lo(g_VmMarker)($at)
/* 736c: 02a02025 */ or $a0,$s5,$zero
/* 7370: 39e6000f */ xori $a2,$t7,0xf
/* 7374: 02402825 */ or $a1,$s2,$zero
@@ -323,7 +401,7 @@ glabel vmInit
/* 71d4: afb30060 */ sw $s3,0x60($sp)
/* 71d8: afb2005c */ sw $s2,0x5c($sp)
/* 71dc: afb10058 */ sw $s1,0x58($sp)
/* 71e0: 0c002294 */ jal rzipInflateFixed
/* 71e0: 0c002294 */ jal rzipInit
/* 71e4: a030d458 */ sb $s0,-0x2ba8($at)
/* 71e8: 0c013d4c */ jal osGetMemSize
/* 71ec: 00000000 */ sll $zero,$zero,0x0
@@ -639,3 +717,191 @@ glabel vmInit
/* 7684: 27bd1568 */ addiu $sp,$sp,0x1568
);
#endif
/**
* Initialise the virtual memory.
*
* The logic here is different depending on whether the system has the 4MB
* of onboard memory or is using the expansion pak for a total of 8MB.
*
* -- For 4MB systems --
*
* vmInit allocates space in memory for the TLB to be able to load zips in its
* exception handler. It initialises the zip table then leaves it to the TLB to
* load the game zips as needed.
*
* The memory is laid out like this:
*
* (zip buffer) (zip table) (state table) (stack) (end of onboard memory)
* Addresses: 0x??? 0x??? 0x803f50b8 0x80400000
* Lengths: 0x6ec 0xdd8 0xaf48 0
*
* zip buffer - is sized according to the biggest single game zip, and is
* reserved space where the TLB's exception handler can DMA the zip to RAM
* before unzipping it.
* zip table - is the ROM offset table where each zip can be found, which is
* used by the TLB's exception handler.
* state table - is cleared by vmInit then left to the TLB's exception handler
* for it to populate as zips are loaded and paged out.
* stack - is reserved stack space for different threads, which vmInit must not
* write into.
*
* -- For 8MB systems --
*
* vmInit loads all game zips into memory and sets TLB entries to map it to
* virtual address space. The page swapping feature is not used as the TLB
* never encounters a page miss.
*
* The memory is laid out like this:
*
* (zip buffer) (zip table) (game seg) (stack) (end of onboard memory)
* 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
* 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.
* stack: is reserved stack space for different threads, which vmInit must not
* write into.
*
* -- Both systems --
*
* Regardless of the amount of memory being used, it is critical that vmInit
* sets the g_VmMarker global variable correctly. This marks the point in memory
* where memory must be preserved. The main thread uses this variable as the end
* address of memp's heap.
*
* In 4MB, g_VmMarker is set to the start of the zip buffer because the zip
* buffer is used by the exception handler.
*
* In 8MB, the zip buffer and zip table are no longer needed, so g_VmMarker is
* set to the start of the unzipped game segment.
*/
// Mismatch: Calclulations near the start are hard to match
//void vmInit(void)
//{
// s32 i;
// s32 j;
// u8 *s3;
// u32 *s5;
// u32 t8;
// u8 *s2;
// u8 *s1;
// u8 *chunkbuffer;
// s32 maxsize;
// u32 sp1474; // aka s6
// u8 sp68[1024 * 5]; // 68 to 1467
// u8 *gameseg; // 54
// u8 *zip; // 48
// u8 *s7;
// s32 statetablelen;
//
// g_VmInitialised = true;
//
// rzipInit();
//
// if (bootGetMemSize() <= 0x400000) {
// g_Is4Mb = true;
//
// g_VmNumPages = (s32)((&_gameSegmentEnd - &_gameSegmentStart) + 0xfff) / PAGE_SIZE;
// t8 = (u32)((&_gameSegmentEnd - &_gameSegmentStart) + 0xfff) / PAGE_SIZE;
// sp1474 = t8 + 1;
//
// g_VmRamEnd = 0x7f000000 + PAGE_SIZE * g_VmNumPages;
// g_VmStateTableEnd = VM_MEMORY_END;
// g_VmStateTable = (u32 *)(VM_MEMORY_END - g_VmNumPages * 8);
// g_VmZipTable = (u32 *)(((u32)g_VmStateTable - (sp1474 + 5) * 4) & ~0xf);
//
// // Load gamezips pointer list
// dmaExec(g_VmZipTable, (u32)&_gamezipSegmentRomStart, ALIGN16((sp1474 + 1) * 4));
//
// // Make pointers absolute instead of relative to their segment
// for (i = 0; i < sp1474; i++) {
// g_VmZipTable[i] += (u32)&_gamezipSegmentRomStart;
// }
//
// // Find the size of the biggest compressed zip
// maxsize = 0;
//
// for (i = 0; i < sp1474 - 1; i++) {
// u32 size = g_VmZipTable[i + 1] - g_VmZipTable[i];
//
// if (size > maxsize) {
// maxsize = size;
// }
// }
//
// maxsize += 0x40;
// maxsize &= ~0xf;
// g_VmZipBuffer = (u32)g_VmZipTable - maxsize;
// g_VmZipBuffer &= ~0xf;
// gameseg = (u8 *)(g_VmZipBuffer - MAX_LOADED_PAGES * PAGE_SIZE);
// gameseg -= (u32)gameseg & 0x1fff;
// var8008ae20 = (u32)gameseg;
// g_VmMarker = (u32)gameseg;
//
// tlb000010a4();
//
// statetablelen = (g_VmNumPages * 8) >> 2;
//
// for (i = 0; i < statetablelen; i++) {
// g_VmStateTable[i] = 0;
// }
//
// tlb0000113c();
// } else {
// // Expansion pak is being used
// g_Is4Mb = false;
//
// t8 = (u32)((&_gameSegmentEnd - &_gameSegmentStart) + 0xfff) / PAGE_SIZE;
// s7 = (u8 *)VM_MEMORY_END;
// gameseg = (u8 *)(((u32)s7 - ALIGN64(&_gameSegmentEnd - &_gameSegmentStart)) & 0xfffe0000);
// sp1474 = t8 + 1;
//
// s5 = (u32 *)(((u32)gameseg - ((t8 + 5) * 4)) & ~0xf);
// g_VmMarker = (u32)gameseg;
//
// // Load gamezips pointer list
// dmaExec(s5, (u32)&_gamezipSegmentRomStart, ALIGN16((sp1474 + 1) * 4));
//
// // Make pointers absolute instead of relative to their segment
// for (i = 0; i < sp1474; i++) {
// s5[i] += (u32)&_gamezipSegmentRomStart;
// }
//
// // Load each zip from the ROM and inflate them to the game segment
// s2 = gameseg;
// chunkbuffer = (u8 *)((u32)s5 - PAGE_SIZE * 2);
// zip = chunkbuffer + 2;
//
// for (i = 0; i < sp1474 - 1; i++) {
// dmaExec(chunkbuffer, s5[i], ALIGN16(s5[i + 1] - s5[i]));
// s2 += rzipInflate(zip, s2, sp68);
// }
//
// // This loop sets the following TLB entries:
// // entry 2: 0x7f000000 to 0x7f010000 and 0x7f010000 to 0x7f020000
// // entry 3: 0x7f020000 to 0x7f030000 and 0x7f030000 to 0x7f040000
// // ...
// // entry 14: 0x7f1a0000 to 0x7f1b0000 and 0x7f1b0000 to 0x7f1c0000
// s1 = (u8 *)0x7f000000;
// i = 2;
//
// while (gameseg <= s7) {
// osMapTLB(i, OS_PM_64K, s1,
// osVirtualToPhysical((void *)gameseg),
// osVirtualToPhysical((void *)(gameseg + 0x10000)), -1);
//
// gameseg += 0x20000;
// s1 += 0x20000;
// i++;
// }
// }
//
// g_VmNumTlbMisses = 0;
// g_VmNumPageMisses = 0;
// g_VmNumPageReplaces = 0;
//
// osInvalICache(0, ICACHE_SIZE);
//}