OSDN Git Service

[VM][General] Track to upstream, 2015-01-21.
[csp-qt/common_source_project-fm7.git] / source / src / vm / qc10 / memory.cpp
1 /*\r
2         EPSON QC-10 Emulator 'eQC-10'\r
3 \r
4         Author : Takeda.Toshiya\r
5         Date   : 2008.02.15 -\r
6 \r
7         [ memory ]\r
8 */\r
9 \r
10 #include "memory.h"\r
11 #include "../i8253.h"\r
12 #include "../pcm1bit.h"\r
13 #include "../upd765a.h"\r
14 #include "../../fileio.h"\r
15 \r
16 #define SET_BANK(s, e, w, r) { \\r
17         int sb = (s) >> 11, eb = (e) >> 11; \\r
18         for(int i = sb; i <= eb; i++) { \\r
19                 wbank[i] = (w) + 0x800 * (i - sb); \\r
20                 rbank[i] = (r) + 0x800 * (i - sb); \\r
21         } \\r
22 }\r
23 \r
24 void MEMORY::initialize()\r
25 {\r
26         // init memory\r
27         memset(ram, 0, sizeof(ram));\r
28         memset(cmos, 0, sizeof(cmos));\r
29         memset(ipl, 0xff, sizeof(ipl));\r
30         memset(rdmy, 0xff, sizeof(rdmy));\r
31         \r
32         // load rom images\r
33         FILEIO* fio = new FILEIO();\r
34         if(fio->Fopen(emu->bios_path(_T("IPL.ROM")), FILEIO_READ_BINARY)) {\r
35                 fio->Fread(ipl, sizeof(ipl), 1);\r
36                 fio->Fclose();\r
37         }\r
38         if(fio->Fopen(emu->bios_path(_T("CMOS.BIN")), FILEIO_READ_BINARY)) {\r
39                 fio->Fread(cmos, sizeof(cmos), 1);\r
40                 fio->Fclose();\r
41         }\r
42         delete fio;\r
43         \r
44         cmos_crc32 = getcrc32(cmos, sizeof(cmos));\r
45 }\r
46 \r
47 void MEMORY::release()\r
48 {\r
49         if(cmos_crc32 != getcrc32(cmos, sizeof(cmos))) {\r
50                 FILEIO* fio = new FILEIO();\r
51                 if(fio->Fopen(emu->bios_path(_T("CMOS.BIN")), FILEIO_WRITE_BINARY)) {\r
52                         fio->Fwrite(cmos, sizeof(cmos), 1);\r
53                         fio->Fclose();\r
54                 }\r
55                 delete fio;\r
56         }\r
57 }\r
58 \r
59 void MEMORY::reset()\r
60 {\r
61         // init memory map\r
62         bank = 0x10;\r
63         psel = csel = 0;\r
64         update_map();\r
65         \r
66         // init pcm\r
67         pcm_on = pcm_cont = pcm_pit = false;\r
68         \r
69         // init fdc/fdd status\r
70         fdc_irq = motor = false;\r
71 }\r
72 \r
73 void MEMORY::write_data8(uint32 addr, uint32 data)\r
74 {\r
75         addr &= 0xffff;\r
76         wbank[addr >> 11][addr & 0x7ff] = data;\r
77 }\r
78 \r
79 uint32 MEMORY::read_data8(uint32 addr)\r
80 {\r
81         addr &= 0xffff;\r
82         return rbank[addr >> 11][addr & 0x7ff];\r
83 }\r
84 \r
85 void MEMORY::write_io8(uint32 addr, uint32 data)\r
86 {\r
87         switch(addr & 0xff) {\r
88         case 0x18: case 0x19: case 0x1a: case 0x1b:\r
89                 bank = data;\r
90                 // timer gate signal\r
91                 d_pit->write_signal(SIG_I8253_GATE_0, data, 1);\r
92                 d_pit->write_signal(SIG_I8253_GATE_2, data, 2);\r
93                 // pcm on\r
94                 pcm_cont = ((data & 4) != 0);\r
95                 update_pcm();\r
96                 break;\r
97         case 0x1c: case 0x1d: case 0x1e: case 0x1f:\r
98                 psel = data;\r
99                 break;\r
100         case 0x20: case 0x21: case 0x22: case 0x23:\r
101                 csel = data;\r
102                 break;\r
103         }\r
104         update_map();\r
105 }\r
106 \r
107 uint32 MEMORY::read_io8(uint32 addr)\r
108 {\r
109         switch(addr & 0xff) {\r
110         case 0x18: case 0x19: case 0x1a: case 0x1b:\r
111                 return ~config.dipswitch & 0xff;\r
112         case 0x30: case 0x31: case 0x32: case 0x33:\r
113                 return (bank & 0xf0) | (d_fdc->disk_inserted() ? 8 : 0) | (motor ? 0 : 2) | (fdc_irq ? 1 : 0);\r
114         }\r
115         return 0xff;\r
116 }\r
117 \r
118 /*\r
119         0000-DFFF       : RAM * 4banks\r
120         E000-FFFF       : RAM\r
121         ----\r
122         0000-1FFF       : IPL\r
123         8000-87FF       : CMOS\r
124 */\r
125 \r
126 void MEMORY::write_signal(int id, uint32 data, uint32 mask)\r
127 {\r
128         if(id == SIG_MEMORY_PCM) {\r
129                 // pcm on from pit\r
130                 pcm_pit = ((data & mask) != 0);\r
131                 update_pcm();\r
132         } else if(id == SIG_MEMORY_FDC_IRQ) {\r
133                 fdc_irq = ((data & mask) != 0);\r
134         } else if(id == SIG_MEMORY_MOTOR) {\r
135                 motor = ((data & mask) != 0);\r
136         }\r
137 }\r
138 \r
139 void MEMORY::update_map()\r
140 {\r
141         if(!(psel & 1)) {\r
142                 SET_BANK(0x0000, 0x1fff, wdmy, ipl);\r
143                 SET_BANK(0x2000, 0xdfff, wdmy, rdmy);\r
144         } else if(csel & 1) {\r
145                 if(bank & 0x10) {\r
146                         SET_BANK(0x0000, 0x7fff, ram + 0x00000, ram + 0x00000);\r
147                 } else if(bank & 0x20) {\r
148                         SET_BANK(0x0000, 0x7fff, ram + 0x10000, ram + 0x10000);\r
149                 } else if(bank & 0x40) {\r
150                         SET_BANK(0x0000, 0x7fff, ram + 0x20000, ram + 0x20000);\r
151                 } else if(bank & 0x80) {\r
152                         SET_BANK(0x0000, 0x7fff, ram + 0x30000, ram + 0x30000);\r
153                 } else {\r
154                         SET_BANK(0x0000, 0x7fff, wdmy, rdmy);\r
155                 }\r
156                 SET_BANK(0x8000, 0x87ff, cmos, cmos);\r
157         } else {\r
158                 if(bank & 0x10) {\r
159                         SET_BANK(0x0000, 0xdfff, ram + 0x00000, ram + 0x00000);\r
160                 } else if(bank & 0x20) {\r
161                         SET_BANK(0x0000, 0xdfff, ram + 0x10000, ram + 0x10000);\r
162                 } else if(bank & 0x40) {\r
163                         SET_BANK(0x0000, 0xdfff, ram + 0x20000, ram + 0x20000);\r
164                 } else if(bank & 0x80) {\r
165                         SET_BANK(0x0000, 0xdfff, ram + 0x30000, ram + 0x30000);\r
166                 } else {\r
167                         SET_BANK(0x0000, 0xdfff, wdmy, rdmy);\r
168                 }\r
169         }\r
170         SET_BANK(0xe000, 0xffff, ram + 0xe000, ram + 0xe000);\r
171 }\r
172 \r
173 void MEMORY::update_pcm()\r
174 {\r
175         if(!pcm_on && (pcm_cont || pcm_pit)) {\r
176                 d_pcm->write_signal(SIG_PCM1BIT_ON, 1, 1);\r
177                 pcm_on = true;\r
178         } else if(pcm_on && !(pcm_cont || pcm_pit)) {\r
179                 d_pcm->write_signal(SIG_PCM1BIT_ON, 0, 1);\r
180                 pcm_on = false;\r
181         }\r
182 }\r
183 \r
184 #define STATE_VERSION   1\r
185 \r
186 void MEMORY::save_state(FILEIO* state_fio)\r
187 {\r
188         state_fio->FputUint32(STATE_VERSION);\r
189         state_fio->FputInt32(this_device_id);\r
190         \r
191         state_fio->Fwrite(ram, sizeof(ram), 1);\r
192         state_fio->Fwrite(cmos, sizeof(cmos), 1);\r
193         state_fio->FputUint32(cmos_crc32);\r
194         state_fio->FputUint8(bank);\r
195         state_fio->FputUint8(psel);\r
196         state_fio->FputUint8(csel);\r
197         state_fio->FputBool(pcm_on);\r
198         state_fio->FputBool(pcm_cont);\r
199         state_fio->FputBool(pcm_pit);\r
200         state_fio->FputBool(fdc_irq);\r
201         state_fio->FputBool(motor);\r
202 }\r
203 \r
204 bool MEMORY::load_state(FILEIO* state_fio)\r
205 {\r
206         if(state_fio->FgetUint32() != STATE_VERSION) {\r
207                 return false;\r
208         }\r
209         if(state_fio->FgetInt32() != this_device_id) {\r
210                 return false;\r
211         }\r
212         state_fio->Fread(ram, sizeof(ram), 1);\r
213         state_fio->Fread(cmos, sizeof(cmos), 1);\r
214         cmos_crc32 = state_fio->FgetUint32();\r
215         bank = state_fio->FgetUint8();\r
216         psel = state_fio->FgetUint8();\r
217         csel = state_fio->FgetUint8();\r
218         pcm_on = state_fio->FgetBool();\r
219         pcm_cont = state_fio->FgetBool();\r
220         pcm_pit = state_fio->FgetBool();\r
221         fdc_irq = state_fio->FgetBool();\r
222         motor = state_fio->FgetBool();\r
223         \r
224         // post process\r
225         update_map();\r
226         return true;\r
227 }\r
228 \r