OSDN Git Service

bee0fd7fefe19f06230ef0aa4677ea3f47ece5d3
[csp-qt/common_source_project-fm7.git] / source / src / vm / gamegear / memory.cpp
1 /*
2         SEGA GAME GEAR Emulator 'yaGAME GEAR'
3
4         Author : tanam
5         Date   : 2013.08.24-
6
7         [ memory ]
8 */
9
10 #include "memory.h"
11
12 void MEMORY::sms_mapper_w(uint32_t addr, uint32_t data)
13 {
14         /* Calculate ROM page index */
15         uint8_t page = (data % pages);
16
17         /* Save frame control register data */
18         fcr[addr] = data;
19
20         switch(addr)
21         {
22         case 0:
23                 if (data & 8) {
24                         save = 1;
25                         /* Page in ROM */
26                         cpu_readmap[4]  = &sram[(data & 4) ? 0x4000 : 0x0000];
27                         cpu_readmap[5]  = &sram[(data & 4) ? 0x6000 : 0x2000];
28                         cpu_writemap[4] = &sram[(data & 4) ? 0x4000 : 0x0000];
29                         cpu_writemap[5] = &sram[(data & 4) ? 0x6000 : 0x2000];
30                 } else {
31                         /* Page in RAM */
32                         cpu_readmap[4]  = &cart[((fcr[3] % pages) << 14) + 0x0000];
33                         cpu_readmap[5]  = &cart[((fcr[3] % pages) << 14) + 0x2000];
34                         cpu_writemap[4] = ram + 0x8000;
35                         cpu_writemap[5] = ram + 0xA000;
36                 }
37                 break;
38         case 1:
39                 cpu_readmap[0] = &cart[(page << 14) + 0x0000];
40                 cpu_readmap[1] = &cart[(page << 14) + 0x2000];
41                 break;
42         case 2:
43                 cpu_readmap[2] = &cart[(page << 14) + 0x0000];
44                 cpu_readmap[3] = &cart[(page << 14) + 0x2000];
45                 break;
46         case 3:
47                 if (!(fcr[0] & 0x08)) {
48                         cpu_readmap[4] = &cart[(page << 14) + 0x0000];
49                         cpu_readmap[5] = &cart[(page << 14) + 0x2000];
50                 }
51                 break;
52         }
53 }
54
55 void MEMORY::initialize()
56 {
57         cart=NULL;
58         
59         memset(ram, 0, sizeof(ram));
60         memset(rdmy, 0xff, sizeof(rdmy));
61     memset(sram, 0, sizeof(sram));
62         
63         // set memory map
64         cpu_readmap[0] = ram;
65         cpu_readmap[1] = ram + 0x2000;
66         cpu_readmap[2] = ram + 0x4000;
67         cpu_readmap[3] = ram + 0x6000;
68         cpu_readmap[4] = ram + 0x8000;
69         cpu_readmap[5] = ram + 0xA000;
70         cpu_readmap[6] = ram + 0xC000;
71         cpu_readmap[7] = ram + 0xE000;
72         
73         cpu_writemap[0] = ram;
74         cpu_writemap[1] = ram + 0x2000;
75         cpu_writemap[2] = ram + 0x4000;
76         cpu_writemap[3] = ram + 0x6000;
77         cpu_writemap[4] = ram + 0x8000;
78         cpu_writemap[5] = ram + 0xA000;
79         cpu_writemap[6] = ram + 0xC000;
80         cpu_writemap[7] = ram + 0xE000;
81         
82         fcr[0] = 0x00;
83         fcr[1] = 0x00;
84         fcr[2] = 0x01;
85         fcr[3] = 0x00;
86         
87         inserted = false;
88 }
89
90 void MEMORY::release()
91 {
92         if (cart) free(cart);
93 }
94
95 void MEMORY::bios()
96 {
97         FILEIO* fio = new FILEIO();
98         
99         if(fio->Fopen(create_local_path(_T("COLECO.ROM")), FILEIO_READ_BINARY)) {
100                 fio->Fseek(0, FILEIO_SEEK_END);
101                 size=fio->Ftell();
102                 pages = (size / 0x4000);
103                 fio->Fseek(0, FILEIO_SEEK_SET);
104                 if (size == 0x2000 && cpu_readmap[0] != cart) {
105                         fio->Fread(ram, size, 1);
106                         /* $0000-$1FFF mapped to internal ROM (8K) */
107                         cpu_readmap[0]  = ram;
108                         cpu_writemap[0] = ram;
109                         /* $2000-$5FFF mapped to expansion */
110                         cpu_readmap[1]  = rdmy;
111                         cpu_readmap[2]  = rdmy;
112                         /* $6000-$7FFF mapped to RAM (1K mirrored) */
113                         cpu_readmap[3]  = ram + 0x6000;
114                         /* $8000-$FFFF mapped to Cartridge ROM (max. 32K) */
115                         if (!cart) {
116                                 cpu_readmap[4] = ram + 0x8000;
117                                 cpu_readmap[5] = ram + 0xA000;
118                                 cpu_readmap[6] = ram + 0xC000;
119                                 cpu_readmap[7] = ram + 0xE000;
120                         }
121                         cpu_writemap[0] = ram;
122                         cpu_writemap[1] = ram + 0x2000;
123                         cpu_writemap[2] = ram + 0x4000;
124                         cpu_writemap[3] = ram + 0x6000;
125                         cpu_writemap[4] = ram + 0x8000;
126                         cpu_writemap[5] = ram + 0xA000;
127                         cpu_writemap[6] = ram + 0xC000;
128                         cpu_writemap[7] = ram + 0xE000;
129                         fcr[0] = 0x00;
130                         fcr[1] = 0x00;
131                         fcr[2] = 0x01;
132                         fcr[3] = 0x00;
133                 }
134                 fio->Fclose();
135         }
136         delete fio;
137 }
138
139 void MEMORY::write_data8(uint32_t addr, uint32_t data)
140 {
141         cpu_writemap[(addr >> 13)][(addr & 0x1FFF)] = data;
142         if (pages < 4) return;
143         if (addr >= 0xFFFC) sms_mapper_w(addr & 3, data);
144 }
145
146 uint32_t MEMORY::read_data8(uint32_t addr)
147 {
148         return cpu_readmap[(addr >> 13)][(addr & 0x1FFF)];
149 }
150
151 void MEMORY::write_signal(int id, uint32_t data, uint32_t mask)
152 {
153         // from PIO-P6
154         if(data & mask) {
155                 cpu_readmap[0] = ram;
156                 cpu_readmap[1] = ram + 0x2000;
157                 cpu_readmap[2] = ram + 0x4000;
158                 cpu_readmap[3] = ram + 0x6000;
159                 cpu_readmap[4] = ram + 0x8000;
160                 cpu_writemap[0] = ram;
161                 cpu_writemap[1] = ram + 0x2000;
162                 cpu_writemap[2] = ram + 0x4000;
163                 cpu_writemap[3] = ram + 0x6000;
164                 cpu_writemap[4] = ram + 0x8000;
165         }
166         else {
167                 // ROM
168                 cpu_readmap[0] = cart;
169                 cpu_readmap[1] = rdmy;
170                 cpu_readmap[2] = ram + 0x4000;
171                 cpu_readmap[3] = ram + 0x6000;
172                 cpu_readmap[4] = ram + 0x8000;
173                 cpu_writemap[0] = ram;
174                 cpu_writemap[1] = ram + 0x2000;
175                 cpu_writemap[2] = ram + 0x4000;
176                 cpu_writemap[3] = ram + 0x6000;
177                 cpu_writemap[4] = ram + 0x8000;
178         }
179 }
180
181 void MEMORY::open_cart(const _TCHAR* file_path)
182 {
183         FILEIO* fio = new FILEIO();
184         
185         if(fio->Fopen(file_path, FILEIO_READ_BINARY)) {
186                 fio->Fseek(0, FILEIO_SEEK_END);
187                 size=fio->Ftell();
188                 pages = (size / 0x4000);
189                 fio->Fseek(0, FILEIO_SEEK_SET);
190                 if (cart) free(cart);
191                 cart=(uint8_t *)malloc(size);
192                 fio->Fread(cart, size, 1);
193                 fio->Fclose();
194                 delete fio;
195                 inserted = true;
196         } else {
197                 delete fio;
198                 return;
199         }
200         if (check_file_extension(file_path, _T(".col"))) {
201                 /* $0000-$1FFF mapped to internal ROM (8K) */
202                 cpu_readmap[0]  = ram;
203                 cpu_writemap[0] = ram;
204                 /* $2000-$5FFF mapped to expansion */
205                 cpu_readmap[1]  = rdmy;
206                 cpu_readmap[2]  = rdmy;
207                 /* $6000-$7FFF mapped to RAM (1K mirrored) */
208                 cpu_readmap[3]  = ram + 0x6000;
209                 /* $8000-$FFFF mapped to Cartridge ROM (max. 32K) */
210                 cpu_readmap[4] = cart;
211                 if (size>0x2000) cpu_readmap[5] = cart + 0x2000;
212                 else cpu_readmap[5] = rdmy;
213                 if (size>0x4000) cpu_readmap[6] = cart + 0x4000;
214                 else cpu_readmap[6] = rdmy;
215                 if (size>0x6000) cpu_readmap[7] = cart + 0x6000;
216                 else cpu_readmap[7] = rdmy;
217         } else {
218                 // set memory map
219                 cpu_readmap[0] = cart;
220                 if (size>0x2000) cpu_readmap[1] = cart + 0x2000;
221                 else cpu_readmap[1] = rdmy;
222                 if (size>0x4000) cpu_readmap[2] = cart + 0x4000;
223                 else cpu_readmap[2] = rdmy;
224                 if (size>0x6000) cpu_readmap[3] = cart + 0x6000;
225                 else cpu_readmap[3] = rdmy;
226                 if (size>0x8000) cpu_readmap[4] = cart + 0x8000;
227                 else cpu_readmap[4] = ram + 0x8000;
228                 if (size>0xA000) cpu_readmap[5] = cart + 0xA000;
229                 else cpu_readmap[5] = ram + 0xA000;
230                 cpu_readmap[6] = ram + 0xC000;
231                 cpu_readmap[7] = ram + 0xE000;
232         }
233         if (_tcsicmp(file_path, _T("SMS.ROM"))) {
234                 cart[0x77]=0;
235                 cart[0x79]=0;
236         }
237         cpu_writemap[0] = ram;
238         cpu_writemap[1] = ram + 0x2000;
239         cpu_writemap[2] = ram + 0x4000;
240         cpu_writemap[3] = ram + 0x6000;
241         cpu_writemap[4] = ram + 0x8000;
242         cpu_writemap[5] = ram + 0xA000;
243         cpu_writemap[6] = ram + 0xC000;
244         cpu_writemap[7] = ram + 0xE000;
245         fcr[0] = 0x00;
246         fcr[1] = 0x00;
247         fcr[2] = 0x01;
248         fcr[3] = 0x00;
249 }
250
251 void MEMORY::close_cart()
252 {
253         if (cart) free(cart);
254         initialize();
255 }