87 lines
2.6 KiB
C
87 lines
2.6 KiB
C
|
#include <stdint.h>
|
||
|
#include <stdio.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;
|
||
|
|
||
|
// 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(int romSize, int ramSize) {
|
||
|
uint8_t rom[romSize];
|
||
|
uint8_t ram[ramSize];
|
||
|
|
||
|
AddressSpace addressSpace = { rom, romSize, ram, ramSize };
|
||
|
|
||
|
return addressSpace;
|
||
|
}
|
||
|
|
||
|
int read_address_space(const AddressSpace *addressSpace, uint32_t address, const int n, uint8_t *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 {
|
||
|
for (int i=0; i<n; i++) {
|
||
|
dest[i] = addressSpace->rom[address + i];
|
||
|
}
|
||
|
}
|
||
|
} 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 {
|
||
|
address -= romSize;
|
||
|
for (int i=0; i<n; i++) {
|
||
|
dest[i] = addressSpace->ram[address + i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
// TODO IO
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int write_address_space(const AddressSpace *addressSpace, uint32_t address, const int n, uint8_t *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 {
|
||
|
for (int i=0; i<n; i++) {
|
||
|
addressSpace->rom[address + i] = src[i];
|
||
|
}
|
||
|
}
|
||
|
} 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 {
|
||
|
address -= romSize;
|
||
|
for (int i=0; i<n; i++) {
|
||
|
addressSpace->ram[address + i] = src[i];
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
// TODO IO
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|