OSDN Git Service

[General][Qt] Merge upstream 2015-03-15.
[csp-qt/common_source_project-fm7.git] / source / src / vm / memory.cpp
1 /*
2         Skelton for retropc emulator
3
4         Author : Takeda.Toshiya
5         Date   : 2010.09.16-
6
7         [ memory ]
8 */
9
10 #include "memory.h"
11
12 #define ADDR_MASK (MEMORY_ADDR_MAX - 1)
13 #define BANK_MASK (MEMORY_BANK_SIZE - 1)
14
15 void MEMORY::release()
16 {
17         free(read_table);
18         free(write_table);
19 }
20
21 uint32 MEMORY::read_data8(uint32 addr)
22 {
23         int bank = (addr & ADDR_MASK) >> addr_shift;
24         
25         if(read_table[bank].dev != NULL) {
26                 return read_table[bank].dev->read_memory_mapped_io8(addr);
27         } else {
28                 return read_table[bank].memory[addr & BANK_MASK];
29         }
30 }
31
32 void MEMORY::write_data8(uint32 addr, uint32 data)
33 {
34         int bank = (addr & ADDR_MASK) >> addr_shift;
35         
36         if(write_table[bank].dev != NULL) {
37                 write_table[bank].dev->write_memory_mapped_io8(addr, data);
38         } else {
39                 write_table[bank].memory[addr & BANK_MASK] = data;
40         }
41 }
42
43 uint32 MEMORY::read_data16(uint32 addr)
44 {
45         int bank = (addr & ADDR_MASK) >> addr_shift;
46         
47         if(read_table[bank].dev != NULL) {
48                 return read_table[bank].dev->read_memory_mapped_io16(addr);
49         } else {
50                 uint32 val = read_data8(addr);
51                 val |= read_data8(addr + 1) << 8;
52                 return val;
53         }
54 }
55
56 void MEMORY::write_data16(uint32 addr, uint32 data)
57 {
58         int bank = (addr & ADDR_MASK) >> addr_shift;
59         
60         if(write_table[bank].dev != NULL) {
61                 write_table[bank].dev->write_memory_mapped_io16(addr, data);
62         } else {
63                 write_data8(addr, data & 0xff);
64                 write_data8(addr + 1, (data >> 8) & 0xff);
65         }
66 }
67
68 uint32 MEMORY::read_data32(uint32 addr)
69 {
70         int bank = (addr & ADDR_MASK) >> addr_shift;
71         
72         if(read_table[bank].dev != NULL) {
73                 return read_table[bank].dev->read_memory_mapped_io32(addr);
74         } else {
75                 uint32 val = read_data16(addr);
76                 val |= read_data16(addr + 2) << 16;
77                 return val;
78         }
79 }
80
81 void MEMORY::write_data32(uint32 addr, uint32 data)
82 {
83         int bank = (addr & ADDR_MASK) >> addr_shift;
84         
85         if(write_table[bank].dev != NULL) {
86                 write_table[bank].dev->write_memory_mapped_io32(addr, data);
87         } else {
88                 write_data16(addr, data & 0xffff);
89                 write_data16(addr + 2, (data >> 16) & 0xffff);
90         }
91 }
92
93 uint32 MEMORY::read_data8w(uint32 addr, int* wait)
94 {
95         int bank = (addr & ADDR_MASK) >> addr_shift;
96         
97         *wait = read_table[bank].wait;
98         if(read_table[bank].dev != NULL) {
99                 return read_table[bank].dev->read_memory_mapped_io8(addr);
100         } else {
101                 return read_table[bank].memory[addr & BANK_MASK];
102         }
103 }
104
105 void MEMORY::write_data8w(uint32 addr, uint32 data, int* wait)
106 {
107         int bank = (addr & ADDR_MASK) >> addr_shift;
108         
109         *wait = write_table[bank].wait;
110         if(write_table[bank].dev != NULL) {
111                 write_table[bank].dev->write_memory_mapped_io8(addr, data);
112         } else {
113                 write_table[bank].memory[addr & BANK_MASK] = data;
114         }
115 }
116
117 uint32 MEMORY::read_data16w(uint32 addr, int* wait)
118 {
119         int wait_l, wait_h;
120         uint32 val = read_data8w(addr, &wait_l);
121         val |= read_data8w(addr + 1, &wait_h) << 8;
122         *wait = wait_l + wait_h;
123         return val;
124 }
125
126 void MEMORY::write_data16w(uint32 addr, uint32 data, int* wait)
127 {
128         int wait_l, wait_h;
129         write_data8w(addr, data & 0xff, &wait_l);
130         write_data8w(addr + 1, (data >> 8) & 0xff, &wait_h);
131         *wait = wait_l + wait_h;
132 }
133
134 uint32 MEMORY::read_data32w(uint32 addr, int* wait)
135 {
136         int wait_l, wait_h;
137         uint32 val = read_data16w(addr, &wait_l);
138         val |= read_data16w(addr + 2, &wait_h) << 16;
139         *wait = wait_l + wait_h;
140         return val;
141 }
142
143 void MEMORY::write_data32w(uint32 addr, uint32 data, int* wait)
144 {
145         int wait_l, wait_h;
146         write_data16w(addr, data & 0xffff, &wait_l);
147         write_data16w(addr + 2, (data >> 16) & 0xffff, &wait_h);
148         *wait = wait_l + wait_h;
149 }
150
151 // register
152
153 void MEMORY::set_memory_r(uint32 start, uint32 end, uint8 *memory)
154 {
155         uint32 start_bank = start >> addr_shift;
156         uint32 end_bank = end >> addr_shift;
157         
158         for(uint32 i = start_bank; i <= end_bank; i++) {
159                 read_table[i].dev = NULL;
160                 read_table[i].memory = memory + MEMORY_BANK_SIZE * (i - start_bank);
161         }
162 }
163
164 void MEMORY::set_memory_w(uint32 start, uint32 end, uint8 *memory)
165 {
166         uint32 start_bank = start >> addr_shift;
167         uint32 end_bank = end >> addr_shift;
168         
169         for(uint32 i = start_bank; i <= end_bank; i++) {
170                 write_table[i].dev = NULL;
171                 write_table[i].memory = memory + MEMORY_BANK_SIZE * (i - start_bank);
172         }
173 }
174
175 void MEMORY::set_memory_mapped_io_r(uint32 start, uint32 end, DEVICE *device)
176 {
177         uint32 start_bank = start >> addr_shift;
178         uint32 end_bank = end >> addr_shift;
179         
180         for(uint32 i = start_bank; i <= end_bank; i++) {
181                 read_table[i].dev = device;
182         }
183 }
184
185 void MEMORY::set_memory_mapped_io_w(uint32 start, uint32 end, DEVICE *device)
186 {
187         uint32 start_bank = start >> addr_shift;
188         uint32 end_bank = end >> addr_shift;
189         
190         for(uint32 i = start_bank; i <= end_bank; i++) {
191                 write_table[i].dev = device;
192         }
193 }
194
195 void MEMORY::set_wait_r(uint32 start, uint32 end, int wait)
196 {
197         uint32 start_bank = start >> addr_shift;
198         uint32 end_bank = end >> addr_shift;
199         
200         for(uint32 i = start_bank; i <= end_bank; i++) {
201                 read_table[i].wait = wait;
202         }
203 }
204
205 void MEMORY::set_wait_w(uint32 start, uint32 end, int wait)
206 {
207         uint32 start_bank = start >> addr_shift;
208         uint32 end_bank = end >> addr_shift;
209         
210         for(uint32 i = start_bank; i <= end_bank; i++) {
211                 write_table[i].wait = wait;
212         }
213 }
214
215 void MEMORY::unset_memory_r(uint32 start, uint32 end)
216 {
217         uint32 start_bank = start >> addr_shift;
218         uint32 end_bank = end >> addr_shift;
219         
220         for(uint32 i = start_bank; i <= end_bank; i++) {
221                 read_table[i].dev = NULL;
222                 read_table[i].memory = read_dummy;
223         }
224 }
225
226 void MEMORY::unset_memory_w(uint32 start, uint32 end)
227 {
228         uint32 start_bank = start >> addr_shift;
229         uint32 end_bank = end >> addr_shift;
230         
231         for(uint32 i = start_bank; i <= end_bank; i++) {
232                 write_table[i].dev = NULL;
233                 write_table[i].memory = write_dummy;
234         }
235 }
236
237 // load/save image
238
239 int MEMORY::read_bios(_TCHAR *file_name, uint8 *buffer, int size)
240 {
241         FILEIO* fio = new FILEIO();
242         int length = 0;
243         
244         if(fio->Fopen(emu->bios_path(file_name), FILEIO_READ_BINARY)) {
245                 fio->Fread(buffer, size, 1);
246                 length = fio->Ftell();
247                 fio->Fclose();
248         }
249         delete fio;
250         return length;
251 }
252
253 bool MEMORY::write_bios(_TCHAR *file_name, uint8 *buffer, int size)
254 {
255         FILEIO* fio = new FILEIO();
256         bool result = false;
257         
258         if(fio->Fopen(emu->bios_path(file_name), FILEIO_WRITE_BINARY)) {
259                 fio->Fwrite(buffer, size, 1);
260                 fio->Fclose();
261                 result = true;
262         }
263         delete fio;
264         return result;
265 }
266
267 bool MEMORY::read_image(_TCHAR *file_path, uint8 *buffer, int size)
268 {
269         FILEIO* fio = new FILEIO();
270         bool result = false;
271         
272         if(fio->Fopen(file_path, FILEIO_READ_BINARY)) {
273                 fio->Fread(buffer, size, 1);
274                 fio->Fclose();
275                 result = true;
276         }
277         delete fio;
278         return result;
279 }
280
281 bool MEMORY::write_image(_TCHAR* file_path, uint8* buffer, int size)
282 {
283         FILEIO* fio = new FILEIO();
284         bool result = false;
285         
286         if(fio->Fopen(file_path, FILEIO_WRITE_BINARY)) {
287                 fio->Fwrite(buffer, size, 1);
288                 fio->Fclose();
289                 result = true;
290         }
291         delete fio;
292         return result;
293 }