diff options
author | mrb0nk500 <b0nk@b0nk.xyz> | 2020-10-04 18:22:00 -0400 |
---|---|---|
committer | mrb0nk500 <b0nk@b0nk.xyz> | 2020-10-04 18:22:00 -0400 |
commit | ca8e2f93acc794b00464c5513956bd84de258913 (patch) | |
tree | 83153822fdea777bd11a8254c0e4bd87fe1d8350 /sux.h | |
parent | 784ff59108b887e246b0f33ff696dfd981659ab2 (diff) |
- Added support for reading, and writing outside the
emulator's memory.
All reads outside of the emulator's memory give back
$/0xFF bytes, while all writes outside of the
emulator's memory are ignored.
- Implemented malloc(), and free() in the SuB Suite.
In order to do this, I had to add support for a heap,
which I did by reserving the first 3 banks of the
address space (the first 192K), and by adding a
routine that finds the end of the RAM.
In this case, I set the starting address for the
routine at bank 3 (bank 4 with one indexing), but,
the routine's starting address isn't hardcoded, and
thus, any starting address can be passed as an
argument.
The routine uses the fact that we can now read/write
outside the emulator's memory, and also uses the
fact that writing outside the emulator's memory will
be ignored, and that reading outside the emulator's
memory will always read $/0xFF bytes, and uses that
to signal that it's reached the end of the RAM.
- Added a test program for getting the size of RAM
starting at address $/0x20000.
Diffstat (limited to 'sux.h')
-rw-r--r-- | sux.h | 88 |
1 files changed, 47 insertions, 41 deletions
@@ -77,56 +77,62 @@ static void *memcopy(void *restrict dst, const void *restrict src, unsigned int static inline uint64_t read_value(struct sux *cpu, uint64_t reg, uint64_t address, uint8_t size, uint8_t inc_clk, uint8_t check_io) { - #if (IO || debug) && !branch - #if keypoll - pthread_mutex_lock(&mutex); - #endif - if (check_io) { - io(address, 1); - } - #if keypoll - pthread_mutex_unlock(&mutex); - #endif - #endif #if getclk cpu->clk += inc_clk; #endif size = (size > 7) ? 7 : size; - #if 1 - if (size < 7) { - uint64_t mask = (-(uint64_t)1 >> ((7 - size) * 8)); - return (reg & ~mask) | (*(uint64_t *)(addr+address) & mask); + uint64_t mask = (-(uint64_t)1 >> ((7 - size) * 8)); + if (address < mem_size) { + #if (IO || debug) && !branch + #if keypoll + pthread_mutex_lock(&mutex); + #endif + if (check_io) { + io(address, 1); + } + #if keypoll + pthread_mutex_unlock(&mutex); + #endif + #endif + #if 1 + if (size < 7) { + return (reg & ~mask) | (*(uint64_t *)(addr+address) & mask); + } else { + return *(uint64_t *)(addr+address); + } + #else + return *(uint64_t *)memcopy(®, addr+address, size+1); + #endif } else { - return *(uint64_t *)(addr+address); + return (size < 7) ? (reg & ~mask) | (mask) : mask; } - #else - return *(uint64_t *)memcopy(®, addr+address, size+1); - #endif } static inline void write_value(struct sux *cpu, uint64_t value, uint64_t address, uint8_t size, uint8_t inc_clk, uint8_t check_io) { - size = (size > 7) ? 7 : size; - #if 1 - if (size < 7) { - uint64_t mask = (-(uint64_t)1 >> ((7 - size) * 8)); - *(uint64_t *)(addr+address) = (*(uint64_t *)(addr+address) & ~mask) | (value & mask); - } else { - *(uint64_t *)(addr+address) = value; + if (address < mem_size) { + size = (size > 7) ? 7 : size; + #if 1 + if (size < 7) { + uint64_t mask = (-(uint64_t)1 >> ((7 - size) * 8)); + *(uint64_t *)(addr+address) = (*(uint64_t *)(addr+address) & ~mask) | (value & mask); + } else { + *(uint64_t *)(addr+address) = value; + } + #else + memcopy(addr+address, &value, size+1); + #endif + #if (IO || debug) && !branch + #if keypoll + pthread_mutex_lock(&mutex); + #endif + if (check_io) { + io(address, 0); + } + #if keypoll + pthread_mutex_unlock(&mutex); + #endif + #endif } - #else - memcopy(addr+address, &value, size+1); - #endif - #if (IO || debug) && !branch - #if keypoll - pthread_mutex_lock(&mutex); - #endif - if (check_io) { - io(address, 0); - } - #if keypoll - pthread_mutex_unlock(&mutex); - #endif - #endif #if getclk cpu->clk += inc_clk; #endif @@ -276,7 +282,7 @@ static inline uint64_t sbc(struct sux *cpu, uint64_t reg, uint64_t value, uint8_ setflag(sum == 0, Z); setflag(sum >> 63, N); setflag(((reg^value) >> 63) && ((reg^sum) >> 63), V); - setflag((sum > value), C); + setflag((sum < value), C); return sum; } |