93 lines
No EOL
2.9 KiB
C
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;
|
|
} |