|
1 | 1 | #include "armmem.h" |
2 | 2 |
|
| 3 | +#include "armstate.h" |
| 4 | + |
3 | 5 | #include <assert.h> |
4 | 6 | #include <stdlib.h> |
| 7 | +#include <string.h> |
5 | 8 |
|
6 | | -arm_mem_state_t arm_mem; |
| 9 | +#define ARM_FLASH_WORDS 0x10000 |
| 10 | +#define ARM_RAM_WORDS 0x2000 |
7 | 11 |
|
8 | | -void arm_mem_reset(void) { |
9 | | - free(arm_mem.flash); |
10 | | - free(arm_mem.ram); |
11 | | - arm_mem.flash = calloc(0x10000, sizeof(uint32_t)); |
12 | | - arm_mem.ram = calloc(0x2000, sizeof(uint32_t)); |
| 12 | +bool arm_mem_init(arm_state_t *state) { |
| 13 | + state->flash = calloc(ARM_FLASH_WORDS, sizeof(uint32_t)); |
| 14 | + if (state->flash) { |
| 15 | + state->ram = calloc(ARM_RAM_WORDS, sizeof(uint32_t)); |
| 16 | + if (state->ram) { |
| 17 | + return true; |
| 18 | + free(state->ram); |
| 19 | + } |
| 20 | + free(state->flash); |
| 21 | + } |
| 22 | + return false; |
| 23 | +} |
| 24 | + |
| 25 | +void arm_mem_destroy(arm_state_t *state) { |
| 26 | + free(state->flash); |
| 27 | + free(state->ram); |
| 28 | +} |
| 29 | + |
| 30 | +void arm_mem_reset(arm_state_t *state) { |
| 31 | + memset(state->ram, 0, ARM_RAM_WORDS * sizeof(uint32_t)); |
| 32 | +} |
| 33 | + |
| 34 | +bool arm_mem_load_rom(arm_state_t *state, FILE *file) { |
| 35 | + size_t read = fread(state->flash, 1, ARM_FLASH_WORDS * sizeof(uint32_t), file); |
| 36 | + if (!read) { |
| 37 | + return false; |
| 38 | + } |
| 39 | + memset(state->flash + read, ~0, ARM_FLASH_WORDS * sizeof(uint32_t) - read); |
| 40 | + return true; |
13 | 41 | } |
14 | 42 |
|
15 | | -uint8_t arm_mem_load_byte(uint32_t addr) { |
16 | | - return arm_mem_load_word(addr & ~UINT32_C(3)) >> ((addr & UINT32_C(3)) << UINT32_C(3)); |
| 43 | +uint8_t arm_mem_load_byte(arm_state_t *state, uint32_t addr) { |
| 44 | + return arm_mem_load_word(state, addr & ~UINT32_C(3)) >> ((addr & UINT32_C(3)) << UINT32_C(3)); |
17 | 45 | } |
18 | 46 |
|
19 | | -uint16_t arm_mem_load_half(uint32_t addr) { |
20 | | - return arm_mem_load_word(addr & ~UINT32_C(2)) >> ((addr & UINT32_C(2)) << UINT32_C(3)); |
| 47 | +uint16_t arm_mem_load_half(arm_state_t *state, uint32_t addr) { |
| 48 | + return arm_mem_load_word(state, addr & ~UINT32_C(2)) >> ((addr & UINT32_C(2)) << UINT32_C(3)); |
21 | 49 | } |
22 | 50 |
|
23 | | -uint32_t arm_mem_load_word(uint32_t addr) { |
| 51 | +uint32_t arm_mem_load_word(arm_state_t *state, uint32_t addr) { |
24 | 52 | assert(!(addr & UINT32_C(3))); |
25 | 53 | if (addr - UINT32_C(0) < UINT32_C(0x40000)) { |
26 | | - return arm_mem.flash[(addr - UINT32_C(0)) >> 2]; |
| 54 | + return state->flash[(addr - UINT32_C(0)) >> 2]; |
27 | 55 | } |
28 | 56 | if (addr - UINT32_C(0x20000000) < UINT32_C(0x8000)) { |
29 | | - return arm_mem.ram[(addr - UINT32_C(0x20000000)) >> 2]; |
| 57 | + return state->ram[(addr - UINT32_C(0x20000000)) >> 2]; |
30 | 58 | } |
31 | 59 | return 0; |
32 | 60 | } |
33 | 61 |
|
34 | | -static void arm_mem_store(uint32_t val, uint32_t mask, uint32_t addr) { |
| 62 | +static void arm_mem_store(arm_state_t *state, uint32_t val, uint32_t mask, uint32_t addr) { |
35 | 63 | assert(!(addr & UINT32_C(3)) && !(val & ~mask)); |
36 | 64 | if (addr - UINT32_C(0x20000000) < UINT32_C(0x8000)) { |
37 | | - uint32_t *ptr = &arm_mem.ram[(addr - UINT32_C(0x20000000)) >> UINT32_C(2)]; |
| 65 | + uint32_t *ptr = &state->ram[(addr - UINT32_C(0x20000000)) >> UINT32_C(2)]; |
38 | 66 | *ptr = (*ptr & ~mask) | val; |
39 | 67 | } |
40 | 68 | } |
41 | 69 |
|
42 | | -void arm_mem_store_byte(uint8_t val, uint32_t addr) { |
| 70 | +void arm_mem_store_byte(arm_state_t *state, uint8_t val, uint32_t addr) { |
43 | 71 | uint32_t shift = (addr & UINT32_C(3)) << UINT32_C(3); |
44 | | - arm_mem_store(val << shift, UINT32_C(0xFF) << shift, addr & ~UINT32_C(3)); |
| 72 | + arm_mem_store(state, val << shift, UINT32_C(0xFF) << shift, addr & ~UINT32_C(3)); |
45 | 73 | } |
46 | 74 |
|
47 | | -void arm_mem_store_half(uint16_t val, uint32_t addr) { |
| 75 | +void arm_mem_store_half(arm_state_t *state, uint16_t val, uint32_t addr) { |
48 | 76 | uint32_t shift = (addr & UINT32_C(2)) << UINT32_C(3); |
49 | | - arm_mem_store(val << shift, UINT32_C(0xFFFF) << shift, addr & ~UINT32_C(2)); |
| 77 | + arm_mem_store(state, val << shift, UINT32_C(0xFFFF) << shift, addr & ~UINT32_C(2)); |
50 | 78 | } |
51 | 79 |
|
52 | | -void arm_mem_store_word(uint32_t val, uint32_t addr) { |
53 | | - arm_mem_store(val, UINT32_C(0xFFFFFFFF), addr); |
| 80 | +void arm_mem_store_word(arm_state_t *state, uint32_t val, uint32_t addr) { |
| 81 | + arm_mem_store(state, val, UINT32_C(0xFFFFFFFF), addr); |
54 | 82 | } |
0 commit comments