OSDN Git Service

[General][VM] Merge upstream, 2015-04-10.
[csp-qt/common_source_project-fm7.git] / source / src / vm / mz2800 / memory.cpp
1 /*
2         SHARP MZ-2800 Emulator 'EmuZ-2800'
3
4         Author : Takeda.Toshiya
5         Date   : 2007.08.13 -
6
7         [ memory ]
8 */
9
10 #include "memory.h"
11 #include "../../fileio.h"
12
13 #define SET_BANK(s, e, w, r) { \
14         int sb = (s) >> 11, eb = (e) >> 11; \
15         for(int i = sb; i <= eb; i++) { \
16                 if((w) == wdmy) { \
17                         wbank[i] = wdmy; \
18                 } else { \
19                         wbank[i] = (w) + 0x800 * (i - sb); \
20                 } \
21                 if((r) == rdmy) { \
22                         rbank[i] = rdmy; \
23                 } else { \
24                         rbank[i] = (r) + 0x800 * (i - sb); \
25                 } \
26         } \
27 }
28
29 void MEMORY::initialize()
30 {
31         // init memory
32         memset(ram, 0, sizeof(ram));
33         memset(ext, 0, sizeof(ext));
34         memset(vram, 0, sizeof(vram));
35         memset(tvram, 0, sizeof(tvram));
36         memset(pcg, 0, sizeof(pcg));
37         memset(ipl, 0xff, sizeof(ipl));
38         memset(kanji, 0xff, sizeof(kanji));
39         memset(dic, 0xff, sizeof(dic));
40         memset(rdmy, 0xff, sizeof(rdmy));
41         
42         // load rom images
43         FILEIO* fio = new FILEIO();
44         if(fio->Fopen(emu->bios_path(_T("IPL.ROM")), FILEIO_READ_BINARY)) {
45                 fio->Fread(ipl, sizeof(ipl), 1);
46                 fio->Fclose();
47         }
48         if(fio->Fopen(emu->bios_path(_T("KANJI.ROM")), FILEIO_READ_BINARY)) {
49                 fio->Fread(dic, sizeof(dic), 1);
50                 fio->Fclose();
51                 
52                 // kanji rom is on even addr
53                 for(int i = 0; i < 0x40000; i++) {
54                         kanji[i << 1] = dic[i];
55                 }
56                 memset(dic, 0xff, sizeof(dic));
57         }
58         if(fio->Fopen(emu->bios_path(_T("DICT.ROM")), FILEIO_READ_BINARY)) {
59                 fio->Fread(dic, sizeof(dic), 1);
60                 fio->Fclose();
61         }
62         delete fio;
63 }
64
65 void MEMORY::reset()
66 {
67         SET_BANK(0x000000, 0x0bffff, ram, ram);
68         SET_BANK(0x0c0000, 0x0dffff, vram, vram);
69         SET_BANK(0x0e0000, 0x0effff, wdmy, dic);
70         SET_BANK(0x0f0000, 0x0f3fff, pcg, ipl);
71         SET_BANK(0x0f4000, 0x0f5fff, tvram, ipl + 0x4000);
72         SET_BANK(0x0f6000, 0x0f7fff, tvram, ipl + 0x6000);
73         SET_BANK(0x0f8000, 0x0fffff, wdmy, ipl + 0x8000);
74         SET_BANK(0x100000, 0x1fffff, wdmy, rdmy);
75         SET_BANK(0x200000, 0x7fffff, ext, ext);
76         SET_BANK(0x800000, 0xfeffff, wdmy, rdmy);
77         SET_BANK(0xff0000, 0xffffff, wdmy, ipl);
78         
79         mem_window = 2 << 18;
80         vram_bank = dic_bank = kanji_bank = 0;
81 }
82
83 void MEMORY::write_data8(uint32 addr, uint32 data)
84 {
85         if((addr & 0xfc0000) == 0x80000) {
86                 write_dma_data8((addr & 0x3ffff) | mem_window, data);
87         } else if((addr & 0xfe0000) == 0xc0000 && !vram_bank) {
88                 d_crtc->write_data8(addr, data);
89         } else {
90                 write_dma_data8(addr, data);
91         }
92 }
93
94 uint32 MEMORY::read_data8(uint32 addr)
95 {
96         if((addr & 0xfc0000) == 0x80000) {
97                 return read_dma_data8((addr & 0x3ffff) | mem_window);
98         } else if((addr & 0xfe0000) == 0xc0000 && !vram_bank) {
99                 return d_crtc->read_data8(addr);
100         } else {
101                 return read_dma_data8(addr);
102         }
103 }
104
105 void MEMORY::write_dma_data8(uint32 addr, uint32 data)
106 {
107         wbank[addr >> 11][addr & 0x7ff] = data;
108 }
109
110 uint32 MEMORY::read_dma_data8(uint32 addr)
111 {
112         return rbank[addr >> 11][addr & 0x7ff];
113 }
114
115 void MEMORY::write_io8(uint32 addr, uint32 data)
116 {
117         switch(addr & 0x7fff) {
118         case 0x8c:
119                 // memory window register
120                 mem_window = (data & 0x3f) << 18;
121                 break;
122         case 0x8d:
123                 // vram bank
124                 if(data == 0) {
125                         // read modify write ???
126                         
127                         // temporary implement
128                         if(kanji_bank & 0x80) {
129                                 SET_BANK(0x0f0000, 0x0f0fff, wdmy, kanji + 0x1000 * (kanji_bank & 0x7f));
130                         } else {
131                                 SET_BANK(0x0f0000, 0x0f0fff, pcg, pcg);
132                         }
133                         SET_BANK(0x0f1000, 0x0f3fff, pcg + 0x1000, pcg + 0x1000);
134                         SET_BANK(0x0f4000, 0x0f5fff, tvram, tvram);
135                         SET_BANK(0x0f6000, 0x0f7fff, tvram, tvram);
136                 } else if(data == 4) {
137                         SET_BANK(0x0c0000, 0x0dffff, vram + 0x00000, vram + 0x00000);
138                 } else if(data == 5) {
139                         SET_BANK(0x0c0000, 0x0dffff, vram + 0x20000, vram + 0x20000);
140                 } else if(data == 6) {
141                         SET_BANK(0x0c0000, 0x0dffff, vram + 0x40000, vram + 0x40000);
142                 } else if(data == 7) {
143                         SET_BANK(0x0c0000, 0x0dffff, vram + 0x60000, vram + 0x60000);
144                 }
145                 vram_bank = data;
146                 break;
147         case 0xce:
148                 // dictionary rom bank
149                 SET_BANK(0x0e0000, 0x0effff, wdmy, dic + ((data & 0x18) >> 3) * 0x10000);
150                 dic_bank = data;
151                 break;
152         case 0x274:
153                 // kanji rom / pcg bank
154                 if(data & 0x80) {
155                         SET_BANK(0x0f0000, 0x0f0fff, wdmy, kanji + 0x1000 * (data & 0x7f));
156                 } else {
157                         SET_BANK(0x0f0000, 0x0f0fff, pcg, pcg);
158                 }
159                 kanji_bank = data;
160                 break;
161         }
162 }
163
164 uint32 MEMORY::read_io8(uint32 addr)
165 {
166         switch(addr & 0x7fff) {
167         case 0x8c:
168                 return mem_window >> 18;
169         case 0x8d:
170                 return vram_bank;
171         case 0xce:
172                 return dic_bank;
173         case 0x274:
174                 return kanji_bank;
175         }
176         return 0xff;
177 }
178
179 #define STATE_VERSION   2
180
181 void MEMORY::save_state(FILEIO* state_fio)
182 {
183         state_fio->FputUint32(STATE_VERSION);
184         state_fio->FputInt32(this_device_id);
185         
186         state_fio->Fwrite(ram, sizeof(ram), 1);
187         state_fio->Fwrite(ext, sizeof(ext), 1);
188         state_fio->Fwrite(vram, sizeof(vram), 1);
189         state_fio->Fwrite(tvram, sizeof(tvram), 1);
190         state_fio->Fwrite(pcg, sizeof(pcg), 1);
191         state_fio->FputUint32(mem_window);
192         state_fio->FputUint8(vram_bank);
193         state_fio->FputUint8(dic_bank);
194         state_fio->FputUint8(kanji_bank);
195 }
196
197 bool MEMORY::load_state(FILEIO* state_fio)
198 {
199         if(state_fio->FgetUint32() != STATE_VERSION) {
200                 return false;
201         }
202         if(state_fio->FgetInt32() != this_device_id) {
203                 return false;
204         }
205         state_fio->Fread(ram, sizeof(ram), 1);
206         state_fio->Fread(ext, sizeof(ext), 1);
207         state_fio->Fread(vram, sizeof(vram), 1);
208         state_fio->Fread(tvram, sizeof(tvram), 1);
209         state_fio->Fread(pcg, sizeof(pcg), 1);
210         mem_window = state_fio->FgetUint32();
211         vram_bank = state_fio->FgetUint8();
212         dic_bank = state_fio->FgetUint8();
213         kanji_bank = state_fio->FgetUint8();
214         
215         // post process
216         if(vram_bank == 4) {
217                 SET_BANK(0x0c0000, 0x0dffff, vram + 0x00000, vram + 0x00000);
218         } else if(vram_bank == 5) {
219                 SET_BANK(0x0c0000, 0x0dffff, vram + 0x20000, vram + 0x20000);
220         } else if(vram_bank == 6) {
221                 SET_BANK(0x0c0000, 0x0dffff, vram + 0x40000, vram + 0x40000);
222         } else if(vram_bank == 7) {
223                 SET_BANK(0x0c0000, 0x0dffff, vram + 0x60000, vram + 0x60000);
224         } else {
225                 SET_BANK(0x0c0000, 0x0dffff, vram + 0x00000, vram + 0x00000);
226         }
227         SET_BANK(0x0e0000, 0x0effff, wdmy, dic + ((dic_bank & 0x18) >> 3) * 0x10000);
228         if(kanji_bank & 0x80) {
229                 SET_BANK(0x0f0000, 0x0f0fff, wdmy, kanji + 0x1000 * (kanji_bank & 0x7f));
230         } else {
231                 SET_BANK(0x0f0000, 0x0f0fff, pcg, pcg);
232         }
233         SET_BANK(0x0f1000, 0x0f3fff, pcg + 0x1000, pcg + 0x1000);
234         SET_BANK(0x0f4000, 0x0f5fff, tvram, tvram);
235         SET_BANK(0x0f6000, 0x0f7fff, tvram, tvram);
236         return true;
237 }
238