Skip to content

Commit

Permalink
Translate some documentations of vram_mgr
Browse files Browse the repository at this point in the history
  • Loading branch information
dogo committed Sep 2, 2024
1 parent a2d9d3c commit 70f0575
Showing 1 changed file with 57 additions and 56 deletions.
113 changes: 57 additions & 56 deletions src/vram_mgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,146 +26,148 @@ typedef struct {

OSL_VRAMBLOCK *osl_vramBlocks;

void oslVramMgrInit() {
//If we don't use it OR it has already been initialized
void oslVramMgrInit() {
// If we don't use it OR it has already been initialized
if (!osl_useVramManager || osl_vramBlocksMax > 0)
return;

osl_vramBlocksMax = DEFAULT_TABLE_SIZE;
osl_vramBlocksNb = 1;
osl_vramBlocks = (OSL_VRAMBLOCK*)malloc(osl_vramBlocksMax * sizeof(OSL_VRAMBLOCK));
if (!osl_vramBlocks){
if (!osl_vramBlocks) {
osl_useVramManager = 0;
osl_vramBlocksMax = 0;
osl_vramBlocksNb = 0;
return;
}

//Premier bloc: libre, taille totale de la VRAM, adresse 0
// Initialize the first block's size to 0
osl_vramBlocks[0].size = 0;

// First block: free, total size of VRAM, address 0
setBlockOffset(0, 0);
//La taille en blocs doit être divisée par 16 puisqu'on n'utilise pas des octets sinon il serait impossible de coder toute la VRAM sur 16 bits
// The block size must be divided by 16 because we don't use bytes; otherwise, it would be impossible to encode all of VRAM in 16 bits
setBlockSize(0, osl_vramSize);
setBlockFree(0, 1);
}

void *oslVramMgrAllocBlock(int blockSize) {
void *oslVramMgrAllocBlock(int blockSize) {
int i;

osl_skip = osl_vramBlocks[0].size;
//Le bloc ne peut pas être de taille nulle ou négative
// The block cannot be of zero or negative size
if (blockSize <= 0)
return NULL;

//La taille est toujours multiple de 16 - arrondir au bloc supérieur
// The size is always a multiple of 16 - round up to the next block
if (blockSize & 15)
blockSize += 16;

//Sans le manager, c'est plus simple...
if (!osl_useVramManager) {
// Without the manager, it's simpler...
if (!osl_useVramManager) {
int ptr = osl_currentVramPtr;
//Dépassement de la mémoire?
// Memory overflow?
if (osl_currentVramPtr + blockSize >= osl_vramBase + osl_vramSize)
return NULL;
osl_currentVramPtr += blockSize;
return (void*)ptr;
}

for (i=0;i<osl_vramBlocksNb;i++) {
//Ce bloc est-il suffisant?
for (i = 0; i < osl_vramBlocksNb; i++) {
// Is this block sufficient?
if (isBlockFree(i) && getBlockSize(i) >= blockSize)
break;
}

//Aucun bloc libre
// No free block
if (i >= osl_vramBlocksNb)
return NULL;

//Pile la mémoire qu'il faut? - pas géré, il faut toujours que le dernier bloc soit marqué comme libre (même s'il reste 0 octet) pour ulSetTexVramParameters
if (getBlockSize(i) == blockSize && i != osl_vramBlocksNb - 1) {
//Il n'est plus libre
// Exactly the needed memory? - not handled, the last block must always be marked as free (even if 0 bytes are left) for ulSetTexVramParameters
if (getBlockSize(i) == blockSize && i != osl_vramBlocksNb - 1) {
// It is no longer free
setBlockFree(i, 0);
}
else {
//On va ajouter un nouveau bloc
} else {
// We will add a new block
osl_vramBlocksNb++;

//Plus de mémoire pour le tableau? On l'aggrandit
if (osl_vramBlocksNb >= osl_vramBlocksMax) {
// No more memory for the array? Let's expand it
if (osl_vramBlocksNb >= osl_vramBlocksMax) {
OSL_VRAMBLOCK *oldBlock = osl_vramBlocks;
osl_vramBlocksMax += DEFAULT_TABLE_SIZE;
osl_vramBlocks = (OSL_VRAMBLOCK*)realloc(osl_vramBlocks, osl_vramBlocksMax);

//Vérification que la mémoire a bien pu être allouée
if (!osl_vramBlocks) {
// Check that memory allocation was successful
if (!osl_vramBlocks) {
osl_vramBlocks = oldBlock;
osl_vramBlocksMax -= DEFAULT_TABLE_SIZE;
//Pas assez de mémoire
// Not enough memory
return NULL;
}
}

//Décalage pour insérer notre nouvel élément
// Shift to insert our new element
memmove(osl_vramBlocks + i + 1, osl_vramBlocks + i, sizeof(OSL_VRAMBLOCK) * (osl_vramBlocksNb - i - 1));

//Remplissons notre nouveau bloc
// Fill our new block
setBlockSize(i, blockSize);
//Il a l'adresse du bloc qui était là avant
// It has the address of the block that was there before
setBlockOffset(i, getBlockOffset(i + 1));
//Il n'est pas libre
// It is not free
setBlockFree(i, 0);

//Pour le prochain, sa taille diminue
// For the next one, its size decreases
setBlockSize(i + 1, getBlockSize(i + 1) - blockSize);
//ATTENTION: calcul d'offset
// WARNING: offset calculation
setBlockOffset(i + 1, getBlockOffset(i + 1) + blockSize);
}

//Note: il faut traduire l'offset en vraie adresse
// Note: the offset must be translated into a real address
return (void*)(getBlockOffset(i) + osl_vramBase);
}

//Note: il faut traduire une vraie adresse en offset
int oslVramMgrFreeBlock(void *blockAddress, int blockSize) {
// Note: we need to translate a real address into an offset
int oslVramMgrFreeBlock(void *blockAddress, int blockSize) {
int i, j, updateNeeded;
int blockOffset = (u32)blockAddress - (u32)osl_vramBase;

//Sans le manager, c'est plus simple...
if (!osl_useVramManager) {
// Without the manager, it's simpler...
if (!osl_useVramManager) {
osl_currentVramPtr -= blockSize;
//Pas vraiment utile, juste là pour s'assurer qu'on ne dépassera jamais de l'espace alloué
// Not really useful, just here to ensure we never exceed the allocated space
if (osl_currentVramPtr < osl_vramBase)
osl_currentVramPtr = osl_vramBase;
return 1;
}

//Trouvons le bloc qui va bien
for (i=0;i<osl_vramBlocksNb;i++) {
// Let's find the correct block
for (i = 0; i < osl_vramBlocksNb; i++) {
if (getBlockOffset(i) == blockOffset)
break;
}

//Impossible de trouver le bloc
// Unable to find the block
if (i >= osl_vramBlocksNb)
return 0;

//Le bloc est maintenant libre ^^
// The block is now free ^^
setBlockFree(i, 1);

//Bon maintenant reste à "assembler" les blocs libres adjacents
do {
// Now let's "merge" adjacent free blocks
do {
updateNeeded = 0;
for (j=0;j<osl_vramBlocksNb-1;j++) {
//Cherchons deux blocs adjacents
for (j = 0; j < osl_vramBlocksNb - 1; j++) {
// Let's look for two adjacent blocks
if ((isBlockFree(j) && isBlockFree(j + 1))
|| (isBlockFree(j) && getBlockSize(j) == 0)) {
//Assemblons ces blocs maintenant
|| (isBlockFree(j) && getBlockSize(j) == 0)) {
// Merge these blocks now
int newSize = getBlockSize(j) + getBlockSize(j + 1), newAdd = getBlockOffset(j);
memmove(osl_vramBlocks + j, osl_vramBlocks + j + 1, sizeof(OSL_VRAMBLOCK) * (osl_vramBlocksNb - j - 1));
setBlockOffset(j, newAdd);
setBlockSize(j, newSize);
//Le bloc entre deux est supprimé
// The block in between is removed
osl_vramBlocksNb--;
//ATT: On devra refaire un tour pour vérifier si de nouveaux blocs n'ont pas été créés
// Note: We will need another pass to check if new blocks were created
updateNeeded = 1;
}
}
Expand All @@ -175,30 +177,29 @@ int oslVramMgrFreeBlock(void *blockAddress, int blockSize) {
return 1;
}

int oslVramMgrSetParameters(void *baseAddr, int size) {
int oslVramMgrSetParameters(void *baseAddr, int size) {
int curVramSize = osl_vramSize;
int blockNum = osl_vramBlocksNb - 1;
int sizeDiff;

if (!osl_useVramManager)
return 0;
//La taille est toujours multiple de 16 - arrondir au bloc supérieur
// The size is always a multiple of 16 - round up to the next block
if (size & 15)
size += 16;

//Différence de taille (négatif pour réduction, positif pour aggrandissement)
// Size difference (negative for reduction, positive for increase)
sizeDiff = size - curVramSize;

//Le dernier bloc est TOUJOURS libre, même s'il reste 0 octet. Cf la bidouille dans ulTexVramAlloc
if (isBlockFree(blockNum) && getBlockSize(blockNum) + sizeDiff >= 0) {
// The last block is ALWAYS free, even if there are 0 bytes left. See the workaround in ulTexVramAlloc
if (isBlockFree(blockNum) && getBlockSize(blockNum) + sizeDiff >= 0) {
setBlockSize(blockNum, getBlockSize(blockNum) + sizeDiff);
osl_vramBase = (u32)baseAddr;
osl_vramSize = size;
//Pour ceux qui ne veulent pas utiliser le gestionnaire...
// For those who do not want to use the manager...
osl_currentVramPtr = osl_vramBase;
}
else
return 0;
return 1;
}

0 comments on commit 70f0575

Please sign in to comment.