Casio_asm/interpreter/segments.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);
}