criscv/src/address_space.c

80 lines
2.5 KiB
C
Raw Normal View History

2024-10-14 19:48:56 +02:00
#include <stdint.h>
#include <stdio.h>
2024-10-15 13:30:45 +02:00
#include <string.h>
2024-10-14 19:48:56 +02:00
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;
}
2024-10-15 13:30:45 +02:00
int read_address_space(const AddressSpace *addressSpace, uint32_t address, const int n, void *dest) {
2024-10-14 19:48:56 +02:00
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 {
2024-10-15 13:30:45 +02:00
memcpy(dest, addressSpace->rom + address, n);
2024-10-14 19:48:56 +02:00
}
} 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;
2024-10-15 13:30:45 +02:00
memcpy(dest, addressSpace->ram + address, n);
2024-10-14 19:48:56 +02:00
}
} else {
// TODO IO
}
return 0;
}
2024-10-15 13:30:45 +02:00
int write_address_space(const AddressSpace *addressSpace, uint32_t address, const int n, void *src) {
2024-10-14 19:48:56 +02:00
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 {
2024-10-15 13:30:45 +02:00
memcpy(addressSpace->rom + address, src, n);
2024-10-14 19:48:56 +02:00
}
} 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;
2024-10-15 13:30:45 +02:00
memcpy(addressSpace->ram + address, src, n);
2024-10-14 19:48:56 +02:00
}
} else {
// TODO IO
}
return 0;
}