OSDN Git Service

92aecc25ace0fdb069afd89a545171c71ea4d7d2
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc8201 / memory.cpp
1 /*
2         NEC PC-8201 Emulator 'ePC-8201'
3
4         Author : Takeda.Toshiya
5         Date   : 2009.03.31-
6
7         [ memory ]
8 */
9
10 #include "memory.h"
11 #include "cmt.h"
12 #include "../datarec.h"
13 #include "../upd1990a.h"
14
15 #define SET_BANK(s, e, w, r) { \
16         int sb = (s) >> 12, eb = (e) >> 12; \
17         for(int i = sb; i <= eb; i++) { \
18                 if((w) == wdmy) { \
19                         wbank[i] = wdmy; \
20                 } else { \
21                         wbank[i] = (w) + 0x1000 * (i - sb); \
22                 } \
23                 if((r) == rdmy) { \
24                         rbank[i] = rdmy; \
25                 } else { \
26                         rbank[i] = (r) + 0x1000 * (i - sb); \
27                 } \
28         } \
29 }
30
31 void MEMORY::initialize()
32 {
33         // init memory
34         memset(ram, 0, sizeof(ram));
35         memset(ipl, 0xff, sizeof(ipl));
36         memset(ext, 0xff, sizeof(ext));
37         memset(rdmy, 0xff, sizeof(rdmy));
38         
39         // load rom / ram images
40         FILEIO* fio = new FILEIO();
41         if(fio->Fopen(create_local_path(_T("IPL.ROM")), FILEIO_READ_BINARY)) {
42                 fio->Fread(ipl, sizeof(ipl), 1);
43                 fio->Fclose();
44         }
45         if(fio->Fopen(create_local_path(_T("EXT.ROM")), FILEIO_READ_BINARY)) {
46                 fio->Fread(ext, sizeof(ext), 1);
47                 fio->Fclose();
48         }
49         if(fio->Fopen(create_local_path(_T("RAM.BIN")), FILEIO_READ_BINARY)) {
50                 fio->Fread(ram, sizeof(ram), 1);
51                 fio->Fclose();
52         }
53         delete fio;
54 }
55
56 void MEMORY::release()
57 {
58         // save ram image
59         FILEIO* fio = new FILEIO();
60         if(fio->Fopen(create_local_path(_T("RAM.BIN")), FILEIO_WRITE_BINARY)) {
61                 fio->Fwrite(ram, sizeof(ram), 1);
62                 fio->Fclose();
63         }
64         delete fio;
65 }
66
67 void MEMORY::reset()
68 {
69         sio = bank = 0;
70         update_bank();
71 }
72
73 void MEMORY::write_data8(uint32_t addr, uint32_t data)
74 {
75         addr &= 0xffff;
76         wbank[addr >> 12][addr & 0xfff] = data;
77 }
78
79 uint32_t MEMORY::read_data8(uint32_t addr)
80 {
81         addr &= 0xffff;
82         return rbank[addr >> 12][addr & 0xfff];
83 }
84
85 void MEMORY::write_io8(uint32_t addr, uint32_t data)
86 {
87         switch(addr & 0xf0) {
88         case 0x90:
89                 // system control
90                 if((sio & 8) != (data & 8)) {
91                         d_cmt->write_signal(SIG_CMT_REMOTE, data, 8);
92                         d_drec->write_signal(SIG_DATAREC_REMOTE, data, 8);
93                 }
94                 if((sio & 0x10) != (data & 0x10)) {
95                         d_rtc->write_signal(SIG_UPD1990A_STB, data, 0x10);
96                 }
97                 sio = data;
98                 break;
99         case 0xa0:
100                 // bank control
101                 bank = data;
102                 update_bank();
103                 break;
104         }
105 }
106
107 uint32_t MEMORY::read_io8(uint32_t addr)
108 {
109         // $A0: bank status
110         return (sio & 0xc0) | (bank & 0xf);
111 }
112
113 void MEMORY::update_bank()
114 {
115         switch(bank & 3) {
116         case 0:
117                 SET_BANK(0x0000, 0x7fff, wdmy, ipl);
118                 break;
119         case 1:
120                 SET_BANK(0x0000, 0x7fff, wdmy, ext);
121                 break;
122         case 2:
123                 SET_BANK(0x0000, 0x7fff, ram + 0x08000, ram + 0x08000);
124                 break;
125         case 3:
126                 SET_BANK(0x0000, 0x7fff, ram + 0x10000, ram + 0x10000);
127                 break;
128         }
129         switch((bank >> 2) & 3) {
130         case 0:
131                 SET_BANK(0x8000, 0xffff, ram + 0x00000, ram + 0x00000);
132                 break;
133         case 1:
134                 SET_BANK(0x8000, 0xffff, wdmy, rdmy);
135                 break;
136         case 2:
137                 SET_BANK(0x8000, 0xffff, ram + 0x08000, ram + 0x08000);
138                 break;
139         case 3:
140                 SET_BANK(0x8000, 0xffff, ram + 0x10000, ram + 0x10000);
141                 break;
142         }
143 }
144
145 #define STATE_VERSION   1
146
147 #include "../../statesub.h"
148
149 void MEMORY::decl_state()
150 {
151         enter_decl_state(STATE_VERSION);
152
153         DECL_STATE_ENTRY_1D_ARRAY(ram, sizeof(ram));
154         DECL_STATE_ENTRY_UINT8(sio);
155         DECL_STATE_ENTRY_UINT8(bank);
156
157         leave_decl_state();
158 }
159
160 void MEMORY::save_state(FILEIO* state_fio)
161 {
162         if(state_entry != NULL) {
163                 state_entry->save_state(state_fio);
164         }
165 //      state_fio->FputUint32(STATE_VERSION);
166 //      state_fio->FputInt32(this_device_id);
167         
168 //      state_fio->Fwrite(ram, sizeof(ram), 1);
169 //      state_fio->FputUint8(sio);
170 //      state_fio->FputUint8(bank);
171 }
172
173 bool MEMORY::load_state(FILEIO* state_fio)
174 {
175         bool mb = false;
176         if(state_entry != NULL) {
177                 mb = state_entry->load_state(state_fio);
178         }
179         if(!mb) {
180                 return false;
181         }
182 //      if(state_fio->FgetUint32() != STATE_VERSION) {
183 //              return false;
184 //      }
185 //      if(state_fio->FgetInt32() != this_device_id) {
186 //              return false;
187 //      }
188 //      state_fio->Fread(ram, sizeof(ram), 1);
189 //      sio = state_fio->FgetUint8();
190 //      bank = state_fio->FgetUint8();
191         
192         // post process
193         update_bank();
194         return true;
195 }
196
197 bool MEMORY::process_state(FILEIO* state_fio, bool loading)
198 {
199         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
200                 return false;
201         }
202         if(!state_fio->StateCheckInt32(this_device_id)) {
203                 return false;
204         }
205         state_fio->StateBuffer(ram, sizeof(ram), 1);
206         state_fio->StateUint8(sio);
207         state_fio->StateUint8(bank);
208         
209         // post process
210         if(loading) {
211                 update_bank();
212         }
213         return true;
214 }