criscv/src/address_space.c
2024-10-16 15:34:06 +02:00

93 lines
No EOL
2.9 KiB
C

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct AddressSpace_s {
// A pointer to a ROM array. The array can vary in length.
uint8_t *rom;
// The size of ROM.
uint32_t romSize; // TODO look into making it const
// A pointer to a RAM array. The array can vary in length.
uint8_t *ram;
// The size of RAM.
uint32_t ramSize;
};
typedef struct AddressSpace_s AddressSpace;
AddressSpace *create_address_space(const uint32_t romSize, const uint32_t ramSize) {
uint8_t *rom = calloc(romSize, 1);
uint8_t *ram = calloc(ramSize, 1);
AddressSpace *addressSpace = malloc(sizeof(AddressSpace));
if (rom == NULL || ram == NULL || addressSpace == NULL) {
free(rom);
free(ram);
free(addressSpace);
return NULL; // Memory allocation failed
}
addressSpace->rom = rom;
addressSpace->romSize = romSize;
addressSpace->ram = ram;
addressSpace->ramSize = ramSize;
return addressSpace;
}
int read_address_space(const AddressSpace *addressSpace, const uint32_t address, const int n, void *dest) {
uint32_t romSize = addressSpace->romSize;
uint32_t ramSize = addressSpace->ramSize;
if (address < romSize) {
if (address + n >= romSize) {
fprintf(stderr, "Reading %d bytes from %d will exceed ROM address space of %d\n", n, address, romSize); // TODO maybe move to perror
return 1;
} else {
memcpy(dest, addressSpace->rom + address, n);
}
} else if (address < romSize + ramSize) {
if (address + n >= romSize + ramSize) {
fprintf(stderr, "Reading %d bytes from %d (total %d) will exceed RAM address space of %d (total %d)\n", n, address, address + romSize, ramSize, romSize + ramSize);
return 1;
} else {
memcpy(dest, addressSpace->ram + address - romSize, n);
}
} else {
// TODO IO
return 1;
}
return 0;
}
int write_address_space(const AddressSpace *addressSpace, const uint32_t address, const int n, void *src) {
uint32_t romSize = addressSpace->romSize;
uint32_t ramSize = addressSpace->ramSize;
if (address < romSize) {
if (address + n >= romSize) {
fprintf(stderr, "Writing %d bytes to %d will exceed ROM address space of %d\n", n, address, romSize);
return 1;
} else {
memcpy(addressSpace->rom + address, src, n);
}
} else if (address < romSize + ramSize) {
if (address + n >= romSize + ramSize) {
fprintf(stderr, "Writing %d bytes to %d (total %d) will exceed RAM address space of %d (total %d)\n", n, address, address + romSize, ramSize, romSize + ramSize);
return 1;
} else {
memcpy(addressSpace->ram + address - romSize, src, n);
}
} else {
// TODO IO
return 1;
}
return 0;
}