-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsys_global.c
179 lines (147 loc) · 5.72 KB
/
sys_global.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#include <stdlib.h>
#include <stdio.h>
#include <emu_rom.h>
#include <emu_global.h>
#define OUTSIDE_MEM_RANGE(x) x >= physical_memory->address_space_size
#define POSSIBLE_DEVICE_MEM(x) (!is_rom_addr(x) && OUTSIDE_MEM_RANGE(x))
emu_memory_t* physical_memory = NULL;
emu_size_t staged_mem_size = 0;
extern emu_rom_mask_t* system_rom_mask;
extern long rom_size;
memory_redirect_callback read_byte_redirect_callback = NULL;
device_read_callback read_device_callback = NULL;
device_write_callback write_device_callback = NULL;
bool validate_memory() {
emu_size_t size = staged_mem_size * 1024;
if (size > (MAX_MEM_KB*1024)) {
EMU_ERRS("staged memory too high (bytes):");
EMU_ERRI(size);
EMU_ERRS("total address space cannot exceed the following maximum (bytes):");
EMU_ERRI(MAX_MEM_KB*1024);
return false;
}
// Memory is input from the shell in KiB so we multiply
// it by 1024 to get the size in bytes when we boot
staged_mem_size = size;
EMU_DBG("memory size set to byte size:");
EMU_DBGI(size);
return true;
}
emu_memory_t* emu_memory_init() {
emu_byte_t* mem = calloc(sizeof(emu_byte_t) * staged_mem_size,
sizeof(emu_byte_t));
emu_memory_t* ret = malloc(sizeof(emu_memory_t));
ret->memory = mem;
ret->address_space_size = staged_mem_size;
return ret;
}
void sys_preboot_init() {
EMU_DBG("entering sys_init()");
map_rom();
}
void sys_cleanup() {
free(system_rom_mask);
}
void set_memory_context(emu_memory_t* mem) {
physical_memory = mem;
}
emu_memory_t* get_memory_context() {
return physical_memory;
}
/* Skeleton functions for the 68k */
/* Required to link with Musashi */
// TODO: mask all of these against current system ADDRMASK
emu_size_t read_single_byte(emu_size_t address) {
emu_size_t modified_addr = address;
if (read_byte_redirect_callback != NULL)
modified_addr = read_byte_redirect_callback(address);
if (is_rom_addr(modified_addr))
return (emu_size_t)read_rom_byte(modified_addr);
/* if we read past whatever physical memory limitations we have
and it wasn't a ROM address, we should throw a bus error. */
// TODO: bus error handling. for now it just returns a 0
if (OUTSIDE_MEM_RANGE(modified_addr))
return 0;
return (emu_size_t)(physical_memory->memory[modified_addr]);
}
// TODO: POSSIBLE_DEVICE_MEM should be replaced with a function that checks
// if the current emulated machine has a device at the specified address
emu_size_t m68k_read_memory_8(emu_size_t address) {
if (POSSIBLE_DEVICE_MEM(address) && read_device_callback != NULL) {
emu_size_t* ret;
if (read_device_callback(address, 0xFF, ret) != DEVICE_MEM_SUCCESS) {
return *ret;
} else {
// TODO: Bus error?
EMU_DBG("Failure to read device");
EMU_DBGH(address);
return 0;
}
}
return read_single_byte(address);
}
emu_size_t m68k_read_memory_16(emu_size_t address) {
if (POSSIBLE_DEVICE_MEM(address) && read_device_callback != NULL) {
emu_size_t* ret;
if (read_device_callback(address, 0xFFFF, ret) != DEVICE_MEM_SUCCESS) {
return *ret;
} else {
// TODO: Bus error?
EMU_DBG("Failure to read device");
EMU_DBGH(address);
return 0;
}
}
return read_single_byte(address) & (read_single_byte(address+1) << 8);
}
emu_size_t m68k_read_memory_32(emu_size_t address) {
if (POSSIBLE_DEVICE_MEM(address) && read_device_callback != NULL) {
emu_size_t* ret;
if (read_device_callback(address, 0xFFFFFFFF, ret) != DEVICE_MEM_SUCCESS) {
return *ret;
} else {
// TODO: Bus error?
EMU_DBG("Failure to read device");
EMU_DBGH(address);
return 0;
}
}
return read_single_byte(address)
& (read_single_byte(address+1) << 8)
& (read_single_byte(address+2) << 16)
& (read_single_byte(address+3) << 24);
}
void m68k_write_memory_8(emu_size_t address, emu_size_t value) {
if (POSSIBLE_DEVICE_MEM(address) && write_device_callback != NULL)
return write_device_callback(address, value, 8);
if (is_rom_addr(address) || OUTSIDE_MEM_RANGE(address))
return;
physical_memory->memory[address] = (emu_byte_t)(0x000000FF & value);
}
void m68k_write_memory_16(emu_size_t address, emu_size_t value) {
if (POSSIBLE_DEVICE_MEM(address) && write_device_callback != NULL)
return write_device_callback(address, value, 16);
if (is_rom_addr(address) || OUTSIDE_MEM_RANGE(address))
return;
physical_memory->memory[address] = (emu_byte_t)(0x000000FF & value);
physical_memory->memory[address+1] = (emu_byte_t)((0x0000FF00 & value) >> 8);
}
void m68k_write_memory_32(emu_size_t address, emu_size_t value) {
if (POSSIBLE_DEVICE_MEM(address) && write_device_callback != NULL)
return write_device_callback(address, value, 32);
if (is_rom_addr(address) || OUTSIDE_MEM_RANGE(address))
return;
physical_memory->memory[address] = (emu_byte_t)(0x000000FF & value);
physical_memory->memory[address+1] = (emu_byte_t)((0x0000FF00 & value) >> 8);
physical_memory->memory[address+2] = (emu_byte_t)((0x00FF0000 & value) >> 16);
physical_memory->memory[address+3] = (emu_byte_t)((0xFF000000 & value) >> 24);
}
/* Below this line are placeholders until disassembly code is ported over */
/* You're still expected to implement these w/ Musashi, even though the readme
doesn't really touch on this (had to dig into their example to confirm) */
emu_size_t m68k_read_disassembler_16(emu_size_t addr) {
return 0;
}
emu_size_t m68k_read_disassembler_32(emu_size_t addr) {
return 0;
}