107 lines
2.4 KiB
C
107 lines
2.4 KiB
C
#include "segments.h"
|
|
#include "segmentsFile.h"
|
|
#include "../common/platform.h"
|
|
|
|
void Segments_unmapAll(mmu_t *mmu) {
|
|
memory_map_t *map;
|
|
|
|
//iterate all segments
|
|
while(mmu->length) {
|
|
map=&mmu->segments[0];
|
|
int type=map->info;
|
|
|
|
//unmap accordingly
|
|
switch(type) {
|
|
case MAPPING_INFO_ram:
|
|
//free the RAM
|
|
free(map->pointer);
|
|
Mmu_removeSegment(mmu, map->pos);
|
|
break;
|
|
|
|
case MAPPING_INFO_stack:
|
|
case MAPPING_INFO_vram:
|
|
//simply unmap stack and vram
|
|
Mmu_removeSegment(mmu, map->pos);
|
|
break;
|
|
|
|
case MAPPING_INFO_file:
|
|
//handle files correctly
|
|
Segments_unmapFile(mmu, map->pos);
|
|
break;
|
|
|
|
default:
|
|
//remove other segments
|
|
Mmu_removeSegment(mmu, map->pos);
|
|
}
|
|
}
|
|
}
|
|
|
|
int Segments_mapRam(mmu_t *mmu, int pos, int len, char access) {
|
|
if(mmu->length>=32) return 0;
|
|
|
|
//allocate the RAM
|
|
char* ptr=(char*) calloc(len, 1);
|
|
if(!ptr) return 0;
|
|
|
|
//map it
|
|
if(!Mmu_addSegment(mmu, pos, len, ptr, access, MAPPING_INFO_ram)) {
|
|
free(ptr);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
void Segments_unmapRam(mmu_t *mmu, int pos) {
|
|
memory_map_t *map;
|
|
|
|
//iterate all segments
|
|
for(int i=0; i<mmu->length; i++) {
|
|
map=&mmu->segments[i];
|
|
if(map->info==MAPPING_INFO_ram&&map->pos==pos) free(map->pointer);
|
|
}
|
|
|
|
Mmu_removeSegment(mmu, pos);
|
|
}
|
|
|
|
int Segments_mapVram(mmu_t *mmu, int pos) {
|
|
char* ptr=Graph_getVramAddress();
|
|
return Mmu_addSegment(mmu, pos, VRAM_LENGTH, ptr, MMU_ACCESS_r|MMU_ACCESS_w, MAPPING_INFO_vram);
|
|
}
|
|
|
|
int Segments_mapStack(mmu_t *mmu, stack_t *stack, int pos, char access) {
|
|
int len=sizeof(stack_t);
|
|
return Mmu_addSegment(mmu, pos, len, (char*) stack, access, MAPPING_INFO_stack);
|
|
}
|
|
|
|
int Segments_mapFile(mmu_t *mmu, int fd, int pos, int len, int off, char access) {
|
|
//create and configure the segment
|
|
file_segment_t *segment=malloc(sizeof(file_segment_t));
|
|
if(!segment) return 0;
|
|
fileSegmentInit(segment, fd, off, len, access);
|
|
|
|
//add it to the MMU
|
|
if(!Mmu_addAbsentSegment(mmu, pos, len, fileSegmentRead, fileSegmentWrite, segment, access, MAPPING_INFO_file)) {
|
|
File_close(fd);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
void Segments_unmapFile(mmu_t *mmu, int pos) {
|
|
memory_map_t *map;
|
|
|
|
//iterate all segments
|
|
for(int i=0; i<mmu->length; i++) {
|
|
map=&mmu->segments[i];
|
|
if(map->info==MAPPING_INFO_file&&map->pos==pos) {
|
|
file_segment_t *segment=(file_segment_t*) map->opaque;
|
|
#if defined(PC)
|
|
fileSegmentFlush(segment);
|
|
#endif
|
|
File_close(segment->fd);
|
|
}
|
|
}
|
|
|
|
Mmu_removeSegment(mmu, pos);
|
|
}
|