OSDN Git Service

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