OSDN Git Service

63c6c179e9d154365205eadb7e92f2641b65280e
[csp-qt/common_source_project-fm7.git] / source / src / vm / tk80bs / memory.cpp
1 /*
2         NEC TK-80BS (COMPO BS/80) Emulator 'eTK-80BS'
3
4         Author : Takeda.Toshiya
5         Date   : 2015.12.14-
6
7         [ memory ]
8 */
9
10 // AUTO/STEP\83X\83C\83b\83`\82Ì\82½\82ß\82É\8eÀ\91\95\92\86\82Ì\83\\81[\83X
11 // \8eÀ\8dÛ\82É\8eg\97p\82·\82é\82©\82Í\96¢\92è
12
13 #include "memory.h"
14 #include "../i8080.h"
15
16 #define SET_BANK(s, e, w, r) { \
17         int sb = (s) >> 9, eb = (e) >> 9; \
18         for(int i = sb; i <= eb; i++) { \
19                 if((w) == wdmy) { \
20                         wbank[i] = wdmy; \
21                 } else { \
22                         wbank[i] = (w) + 0x200 * (i - sb); \
23                 } \
24                 if((r) == rdmy) { \
25                         rbank[i] = rdmy; \
26                 } else { \
27                         rbank[i] = (r) + 0x200 * (i - sb); \
28                 } \
29         } \
30 }
31
32 void MEMORY::initialize()
33 {
34         boot_mode = -1;
35         
36         memset(mon, 0xff, sizeof(mon));
37         memset(bsmon, 0xff, sizeof(bsmon));
38         memset(ext, 0xff, sizeof(ext));
39         
40         static const uint8_t top[3] = {0xc3, 0x00, 0xf0};
41         static const uint8_t rst[3] = {0xc3, 0xdd, 0x83};
42         
43         FILEIO* fio = new FILEIO();
44         if(fio->Fopen(create_local_path(_T("TK80.ROM")), FILEIO_READ_BINARY)) {
45                 fio->Fread(mon, sizeof(mon), 1);
46                 fio->Fclose();
47         } else {
48                 // default
49                 memcpy(mon, top, sizeof(top));
50                 memcpy(mon + 0x38, rst, sizeof(rst));
51         }
52         if(fio->Fopen(create_local_path(_T("BSMON.ROM")), FILEIO_READ_BINARY)) {
53                 fio->Fread(bsmon, sizeof(bsmon), 1);
54                 fio->Fclose();
55                 // patch
56                 memcpy(mon + 0x38, rst, sizeof(rst));
57         }
58         if(fio->Fopen(create_local_path(_T("EXT.ROM")), FILEIO_READ_BINARY)) {
59                 fio->Fread(ext, sizeof(ext), 1);
60                 fio->Fclose();
61         }
62         delete fio;
63         
64         // set memory map
65         SET_BANK(0x0000, 0x07ff, wdmy, mon  );
66         SET_BANK(0x0800, 0x0bff, wdmy, rdmy );
67         SET_BANK(0x0c00, 0x7bff, wdmy, ext  );
68         SET_BANK(0x7c00, 0x7dff, wdmy, rdmy ); // mmio
69         SET_BANK(0x7e00, 0x7fff, vram, vram );
70         SET_BANK(0x8000, 0xcfff, ram,  ram  );
71         SET_BANK(0xd000, 0xefff, wdmy, basic);
72         SET_BANK(0xf000, 0xffff, wdmy, bsmon);
73 }
74
75 void MEMORY::reset()
76 {
77         // load basic rom
78         if(boot_mode != config.boot_mode) {
79                 memset(basic, 0xff, sizeof(basic));
80                 FILEIO* fio = new FILEIO();
81                 if(config.boot_mode == 0) {
82                         if(fio->Fopen(create_local_path(_T("LV1BASIC.ROM")), FILEIO_READ_BINARY)) {
83                                 fio->Fread(basic + 0x1000, 0x1000, 1);
84                                 fio->Fclose();
85                         }
86                 } else {
87                         if(fio->Fopen(create_local_path(_T("LV2BASIC.ROM")), FILEIO_READ_BINARY)) {
88                                 fio->Fread(basic, sizeof(basic), 1);
89                                 fio->Fclose();
90                         }
91                 }
92                 delete fio;
93                 boot_mode = config.boot_mode;
94                 
95                 memset(ram, 0, sizeof(ram));
96                 memset(vram, 0x20, sizeof(vram));
97         }
98 }
99
100 void MEMORY::write_data8(uint32_t addr, uint32_t data)
101 {
102         addr &= 0xffff;
103         switch(addr) {
104         case 0x7df8:
105         case 0x7df9:
106                 d_sio->write_io8(addr, data);
107                 break;
108         case 0x7dfc:
109         case 0x7dfd:
110         case 0x7dfe:
111         case 0x7dff:
112                 d_pio->write_io8(addr, data);
113                 break;
114         }
115         wbank[addr >> 9][addr & 0x1ff] = data;
116 }
117
118 uint32_t MEMORY::read_data8(uint32_t addr)
119 {
120         addr &= 0xffff;
121         switch(addr) {
122         case 0x7df8:
123         case 0x7df9:
124                 return d_sio->read_io8(addr, data);
125         case 0x7dfc:
126         case 0x7dfd:
127         case 0x7dfe:
128                 return d_pio->read_io8(addr, data);
129         }
130         return rbank[addr >> 9][addr & 0x1ff];
131 }
132
133 uint32_t MEMORY::fetch_op(uint32_t addr, int *wait)
134 {
135         if((config.dipswitch & 1) && d_cpu->read_signal(SIG_I8080_INTE)) {
136                 d_cpu->write_signal(SIG_I8080_INTR, 1, 1);
137         }
138         *wait = 0;
139         return read_data8(addr);
140 }
141
142 void MEMORY::load_binary(const _TCHAR* file_path)
143 {
144         FILEIO* fio = new FILEIO();
145         if(fio->Fopen(file_path, FILEIO_READ_BINARY)) {
146                 fio->Fread(ram, sizeof(ram), 1);
147                 fio->Fclose();
148         }
149         delete fio;
150 }
151
152 void MEMORY::save_binary(const _TCHAR* file_path)
153 {
154         FILEIO* fio = new FILEIO();
155         if(fio->Fopen(file_path, FILEIO_WRITE_BINARY)) {
156                 fio->Fwrite(ram, sizeof(ram), 1);
157                 fio->Fclose();
158         }
159         delete fio;
160 }
161
162 #define STATE_VERSION   1
163
164 void MEMORY::decl_state(FILEIO* state_fio)
165 {
166         // enter_decl_state(STATE_VERSION);
167
168         DECL_STATE_ENTRY_1D_ARRAY(ram, sizeof(ram));
169         DECL_STATE_ENTRY_1D_ARRAY(vram, sizeof(vram));
170         // leave_decl_state();
171 }
172
173 void MEMORY::save_state(FILEIO* state_fio)
174 {
175         if(state_entry != NULL) {
176                 state_entry->save_state(state_fio);
177         }
178 //      state_fio->FputUint32(STATE_VERSION);
179 //      state_fio->FputInt32(this_device_id);
180         
181 //      state_fio->Fwrite(ram, sizeof(ram), 1);
182 //      state_fio->Fwrite(vram, sizeof(vram), 1);
183 }
184
185 bool MEMORY::load_state(FILEIO* state_fio)
186 {
187         bool mb = false;
188         if(state_entry != NULL) {
189                 mb = state_entry->load_state(state_fio);
190         }
191         if(!mb) {
192                 return false;
193         }
194 //      if(state_fio->FgetUint32() != STATE_VERSION) {
195 //              return false;
196 //      }
197 //      if(state_fio->FgetInt32() != this_device_id) {
198 //              return false;
199 //      }
200 //      state_fio->Fread(ram, sizeof(ram), 1);
201 //      state_fio->Fread(vram, sizeof(vram), 1);
202         return true;
203 }
204
205 bool MEMORY::process_state(FILEIO* state_fio, bool loading)
206 {
207         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
208                 return false;
209         }
210         if(!state_fio->StateCheckInt32(this_device_id)) {
211                 return false;
212         }
213         state_fio->StateBuffer(ram, sizeof(ram), 1);
214         state_fio->StateBuffer(vram, sizeof(vram), 1);
215         return true;
216 }