OSDN Git Service

c0f2aa9a94cdae3d2f2b738a77e26670830c55ca
[csp-qt/common_source_project-fm7.git] / source / src / vm / pasopia7 / memory.cpp
1 /*
2         TOSHIBA PASOPIA 7 Emulator 'EmuPIA7'
3
4         Author : Takeda.Toshiya
5         Date   : 2006.09.20 -
6
7         [ memory ]
8 */
9
10 #include "memory.h"
11 #include "iobus.h"
12 #include "../i8255.h"
13
14 #define SET_BANK(s, e, w, r) { \
15         int sb = (s) >> 12, eb = (e) >> 12; \
16         for(int i = sb; i <= eb; i++) { \
17                 if((w) == wdmy) { \
18                         wbank[i] = wdmy; \
19                 } else { \
20                         wbank[i] = (w) + 0x1000 * (i - sb); \
21                 } \
22                 if((r) == rdmy) { \
23                         rbank[i] = rdmy; \
24                 } else { \
25                         rbank[i] = (r) + 0x1000 * (i - sb); \
26                 } \
27         } \
28 }
29
30 void MEMORY::initialize()
31 {
32         memset(bios, 0xff, sizeof(bios));
33         memset(basic, 0xff, sizeof(basic));
34         memset(rdmy, 0xff, sizeof(rdmy));
35         
36         // load rom images
37         FILEIO* fio = new FILEIO();
38         if(fio->Fopen(create_local_path(_T("BIOS.ROM")), FILEIO_READ_BINARY)) {
39                 fio->Fread(bios, sizeof(bios), 1);
40                 fio->Fclose();
41         }
42         if(fio->Fopen(create_local_path(_T("BASIC.ROM")), FILEIO_READ_BINARY)) {
43                 fio->Fread(basic, sizeof(basic), 1);
44                 fio->Fclose();
45         }
46         delete fio;
47         
48         mem_map = 0xff;
49         update_memory_map();
50         
51         plane = 0;
52         vram_sel = pal_sel = attr_wrap = false;
53 }
54
55 void MEMORY::reset()
56 {
57         memset(vram, 0, sizeof(vram));
58 }
59
60 void MEMORY::write_data8(uint32_t addr, uint32_t data)
61 {
62         addr &= 0xffff;
63         if(vram_sel && (addr & 0xc000) == 0x8000) {
64                 if(pal_sel && !(plane & 0x70)) {
65                         pal[addr & 0x0f] = data & 0x0f;
66                         return;
67                 }
68                 uint32_t laddr = addr & 0x3fff;
69                 if(plane & 0x10) {
70                         vram[0x0000 | laddr] = (plane & 0x1) ? data : 0xff;
71                 }
72                 if(plane & 0x20) {
73                         vram[0x4000 | laddr] = (plane & 0x2) ? data : 0xff;
74                 }
75                 if(plane & 0x40) {
76                         vram[0x8000 | laddr] = (plane & 0x4) ? data : 0xff;
77                         attr_latch = attr_wrap ? attr_latch : attr_data;
78                         vram[0xc000 | laddr] = attr_latch;
79                         // 8255-0, Port B
80                         d_pio0->write_signal(SIG_I8255_PORT_B, (attr_latch << 4) | (attr_latch & 7), 0x87);
81                 }
82                 return;
83         }
84         wbank[addr >> 12][addr & 0xfff] = data;
85 }
86
87 uint32_t MEMORY::read_data8(uint32_t addr)
88 {
89         addr &= 0xffff;
90         if(vram_sel && (addr & 0xc000) == 0x8000) {
91                 if(pal_sel && !(plane & 0x70)) {
92                         return pal[addr & 0x0f];
93                 }
94                 uint32_t laddr = addr & 0x3fff, val = 0xff;
95                 if((plane & 0x11) == 0x11) {
96                         val &= vram[0x0000 | laddr];
97                 }
98                 if((plane & 0x22) == 0x22) {
99                         val &= vram[0x4000 | laddr];
100                 }
101                 if((plane & 0x44) == 0x44) {
102                         attr_latch = vram[0xc000 | laddr];
103                         val &= vram[0x8000 | laddr];
104                         // 8255-0, Port B
105                         d_pio0->write_signal(SIG_I8255_PORT_B, (attr_latch << 4) | (attr_latch & 7), 0x87);
106                 }
107                 return val;
108         }
109         return rbank[addr >> 12][addr & 0xfff];
110 }
111
112 void MEMORY::write_io8(uint32_t addr, uint32_t data)
113 {
114         if(mem_map != (data & 7)) {
115                 mem_map = data & 7;
116                 update_memory_map();
117         }
118         vram_sel = ((data & 4) != 0);
119         
120         // I/O memory access
121         d_iobus->write_signal(SIG_IOBUS_MIO, data, 8);
122         
123         // 8255-2, Port C
124         d_pio2->write_signal(SIG_I8255_PORT_C, data, 3);
125 }
126
127 void MEMORY::write_signal(int id, uint32_t data, uint32_t mask)
128 {
129         if(id == SIG_MEMORY_I8255_1_A) {
130                 plane = data;
131         } else if(id == SIG_MEMORY_I8255_1_B) {
132                 attr_data = data & 0x0f;
133         } else if(id == SIG_MEMORY_I8255_1_C) {
134                 attr_wrap = ((data & 0x10) != 0);
135                 pal_sel = ((data & 0x0c) != 0);
136         }
137 }
138
139 void MEMORY::update_memory_map()
140 {
141         if(mem_map == 0xff) {
142                 SET_BANK(0x0000, 0x3fff, wdmy, bios);
143                 SET_BANK(0x4000, 0x7fff, wdmy, bios);
144                 SET_BANK(0x8000, 0xbfff, wdmy, bios);
145                 SET_BANK(0xc000, 0xffff, wdmy, bios);
146         } else {
147                 if(mem_map & 2) {
148                         SET_BANK(0x0000, 0x3fff, ram + 0x0000, ram + 0x0000);
149                 } else {
150                         SET_BANK(0x0000, 0x3fff, ram + 0x0000, basic + 0x0000);
151                 }
152                 if(mem_map & 1) {
153                         SET_BANK(0x4000, 0x7fff, ram + 0x4000, bios + 0x0000);
154                 } else if(mem_map & 2) {
155                         SET_BANK(0x4000, 0x7fff, ram + 0x4000, ram + 0x4000);
156                 } else {
157                         SET_BANK(0x4000, 0x7fff, ram + 0x4000, basic + 0x4000);
158                 }
159                 if(mem_map & 4) {
160                         SET_BANK(0x8000, 0xbfff, wdmy, rdmy);
161                 } else {
162                         SET_BANK(0x8000, 0xbfff, ram + 0x8000, ram + 0x8000);
163                 }
164                 SET_BANK(0xc000, 0xffff, ram + 0xc000, ram + 0xc000);
165         }
166 }
167
168 #define STATE_VERSION   1
169
170 #include "../../statesub.h"
171
172 void MEMORY::decl_state()
173 {
174         enter_decl_state(STATE_VERSION);
175         
176         DECL_STATE_ENTRY_1D_ARRAY(ram, sizeof(ram));
177         DECL_STATE_ENTRY_1D_ARRAY(vram, sizeof(vram));
178         DECL_STATE_ENTRY_1D_ARRAY(pal, sizeof(pal));
179         DECL_STATE_ENTRY_UINT8(mem_map);
180         DECL_STATE_ENTRY_UINT8(plane);
181         DECL_STATE_ENTRY_UINT8(attr_data);
182         DECL_STATE_ENTRY_UINT8(attr_latch);
183         DECL_STATE_ENTRY_BOOL(vram_sel);
184         DECL_STATE_ENTRY_BOOL(pal_sel);
185         DECL_STATE_ENTRY_BOOL(attr_wrap);
186
187         leave_decl_state();
188 }
189
190 void MEMORY::save_state(FILEIO* state_fio)
191 {
192         if(state_entry != NULL) {
193                 state_entry->save_state(state_fio);
194         }
195 //      state_fio->FputUint32(STATE_VERSION);
196 //      state_fio->FputInt32(this_device_id);
197         
198 //      state_fio->Fwrite(ram, sizeof(ram), 1);
199 //      state_fio->Fwrite(vram, sizeof(vram), 1);
200 //      state_fio->Fwrite(pal, sizeof(pal), 1);
201 //      state_fio->FputUint8(mem_map);
202 //      state_fio->FputUint8(plane);
203 //      state_fio->FputUint8(attr_data);
204 //      state_fio->FputUint8(attr_latch);
205 //      state_fio->FputBool(vram_sel);
206 //      state_fio->FputBool(pal_sel);
207 //      state_fio->FputBool(attr_wrap);
208 }
209
210 bool MEMORY::load_state(FILEIO* state_fio)
211 {
212         bool mb = false;
213         if(state_entry != NULL) {
214                 mb = state_entry->load_state(state_fio);
215         }
216         if(!mb) return false;
217 //      if(state_fio->FgetUint32() != STATE_VERSION) {
218 //              return false;
219 //      }
220 //      if(state_fio->FgetInt32() != this_device_id) {
221 //              return false;
222 //      }
223 //      state_fio->Fread(ram, sizeof(ram), 1);
224 //      state_fio->Fread(vram, sizeof(vram), 1);
225 //      state_fio->Fread(pal, sizeof(pal), 1);
226 //      mem_map = state_fio->FgetUint8();
227 //      plane = state_fio->FgetUint8();
228 //      attr_data = state_fio->FgetUint8();
229 //      attr_latch = state_fio->FgetUint8();
230 //      vram_sel = state_fio->FgetBool();
231 //      pal_sel = state_fio->FgetBool();
232 //      attr_wrap = state_fio->FgetBool();
233         
234         // post process
235         update_memory_map();
236         return true;
237 }
238
239 bool MEMORY::process_state(FILEIO* state_fio, bool loading)
240 {
241         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
242                 return false;
243         }
244         if(!state_fio->StateCheckInt32(this_device_id)) {
245                 return false;
246         }
247         state_fio->StateBuffer(ram, sizeof(ram), 1);
248         state_fio->StateBuffer(vram, sizeof(vram), 1);
249         state_fio->StateBuffer(pal, sizeof(pal), 1);
250         state_fio->StateUint8(mem_map);
251         state_fio->StateUint8(plane);
252         state_fio->StateUint8(attr_data);
253         state_fio->StateUint8(attr_latch);
254         state_fio->StateBool(vram_sel);
255         state_fio->StateBool(pal_sel);
256         state_fio->StateBool(attr_wrap);
257         
258         // post process
259         if(loading) {
260                 update_memory_map();
261         }
262         return true;
263 }