2 SHARP MZ-2500 Emulator 'EmuZ-2500'
4 Author : Takeda.Toshiya
12 #define PAGE_TYPE_NORMAL 0
13 #define PAGE_TYPE_VRAM 1
14 #define PAGE_TYPE_KANJI 2
15 #define PAGE_TYPE_DIC 3
16 #define PAGE_TYPE_MODIFY 4
18 #define SET_BANK(s, e, w, r) { \
19 int sb = (s) >> 11, eb = (e) >> 11; \
20 for(int i = sb; i <= eb; i++) { \
24 wbank[i] = (w) + 0x800 * (i - sb); \
29 rbank[i] = (r) + 0x800 * (i - sb); \
34 void MEMORY::initialize()
37 memset(ram, 0, sizeof(ram));
38 memset(vram, 0, sizeof(vram));
39 memset(tvram, 0, sizeof(tvram));
40 memset(pcg, 0, sizeof(pcg));
41 memset(ipl, 0xff, sizeof(ipl));
42 memset(kanji, 0xff, sizeof(kanji));
43 memset(dic, 0xff, sizeof(dic));
44 memset(phone, 0xff, sizeof(phone));
45 memset(rdmy, 0xff, sizeof(rdmy));
48 FILEIO* fio = new FILEIO();
49 if(fio->Fopen(create_local_path(_T("IPL.ROM")), FILEIO_READ_BINARY)) {
50 fio->Fread(ipl, sizeof(ipl), 1);
53 if(fio->Fopen(create_local_path(_T("KANJI.ROM")), FILEIO_READ_BINARY)) {
54 fio->Fread(kanji, sizeof(kanji), 1);
57 if(fio->Fopen(create_local_path(_T("DICT.ROM")), FILEIO_READ_BINARY)) {
58 fio->Fread(dic, sizeof(dic), 1);
61 if(fio->Fopen(create_local_path(_T("PHONE.ROM")), FILEIO_READ_BINARY)) {
62 fio->Fread(phone, sizeof(phone), 1);
68 // NOTE: IPL reset is done at system boot
84 blank = hblank = vblank = busreq = false;
88 void MEMORY::special_reset()
101 // reset crtc signals
102 blank = hblank = vblank = busreq = false;
106 void MEMORY::write_data8_tmp(int b, uint32_t addr, uint32_t data)
108 if(is_vram[b] && !blank) {
110 d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
113 if(page_type[b] == PAGE_TYPE_MODIFY) {
115 if(page[b] == 0x30) {
116 d_crtc->write_data8((addr & 0x1fff) + 0x0000, data);
117 } else if(page[b] == 0x31) {
118 d_crtc->write_data8((addr & 0x1fff) + 0x2000, data);
119 } else if(page[b] == 0x32) {
120 d_crtc->write_data8((addr & 0x1fff) + 0x4000, data);
122 d_crtc->write_data8((addr & 0x1fff) + 0x6000, data);
126 wbank[addr >> 11][addr & 0x7ff] = data;
129 uint32_t MEMORY::read_data8_tmp(int b, uint32_t addr)
131 if(is_vram[b] && !blank) {
133 d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
136 if(page_type[b] == PAGE_TYPE_MODIFY) {
138 if(page[b] == 0x30) {
139 return d_crtc->read_data8((addr & 0x1fff) + 0x0000);
140 } else if(page[b] == 0x31) {
141 return d_crtc->read_data8((addr & 0x1fff) + 0x2000);
142 } else if(page[b] == 0x32) {
143 return d_crtc->read_data8((addr & 0x1fff) + 0x4000);
145 return d_crtc->read_data8((addr & 0x1fff) + 0x6000);
148 return rbank[addr >> 11][addr & 0x7ff];
152 void MEMORY::write_data8(uint32_t addr, uint32_t data)
156 write_data8_tmp(b, addr, data);
159 uint32_t MEMORY::read_data8(uint32_t addr)
163 return read_data8_tmp(b, addr);
166 void MEMORY::write_data8w(uint32_t addr, uint32_t data, int* wait)
170 write_data8_tmp(b, addr, data);
174 extra_wait += page_wait[b];
176 *wait = page_wait[b] + extra_wait;
181 uint32_t MEMORY::read_data8w(uint32_t addr, int* wait)
185 uint32_t data = read_data8_tmp(b, addr);
189 extra_wait += page_wait[b];
191 *wait = page_wait[b] + extra_wait;
197 uint32_t MEMORY::fetch_op(uint32_t addr, int* wait)
200 return read_data8(addr);
203 void MEMORY::write_io8(uint32_t addr, uint32_t data)
205 switch(addr & 0xff) {
212 set_map(data & 0x3f);
216 dic_bank = data & 0x1f;
217 for(int i = 0; i < 8; i++) {
218 if(page_type[i] == PAGE_TYPE_DIC) {
219 SET_BANK(i * 0x2000, i * 0x2000 + 0x1fff, wdmy, dic + dic_bank * 0x2000);
226 for(int i = 0; i < 8; i++) {
227 if(page_type[i] == PAGE_TYPE_KANJI) {
228 if(kanji_bank & 0x80) {
229 SET_BANK(i * 0x2000, i * 0x2000 + 0x7ff, wdmy, kanji + (kanji_bank & 0x7f) * 0x800);
231 SET_BANK(i * 0x2000, i * 0x2000 + 0x7ff, pcg, pcg);
239 uint32_t MEMORY::read_io8(uint32_t addr)
241 switch(addr & 0xff) {
247 uint32_t val = page[bank];
248 bank = (bank + 1) & 7;
254 void MEMORY::write_signal(int id, uint32_t data, uint32_t mask)
256 if(id == SIG_MEMORY_HBLANK) {
257 hblank = ((data & mask) != 0);
258 } else if(id == SIG_MEMORY_VBLANK) {
259 vblank = ((data & mask) != 0);
262 // if blank, disable busreq
263 bool next = hblank || vblank;
264 if(!blank && next && busreq) {
265 d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
271 void MEMORY::set_map(uint8_t data)
273 int base = bank * 0x2000;
276 is_vram[bank] = false;
279 SET_BANK(base, base + 0x1fff, ram + data * 0x2000, ram + data * 0x2000);
280 page_type[bank] = PAGE_TYPE_NORMAL;
281 } else if(0x20 <= data && data <= 0x2f) {
283 static const int ofs_table[] = {0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0c, 0x0d, 0x02, 0x03, 0x06, 0x07, 0x0a, 0x0b, 0x0e, 0x0f};
284 int ofs = ofs_table[data - 0x20] * 0x2000;
285 SET_BANK(base, base + 0x1fff, vram + ofs, vram + ofs);
286 page_type[bank] = PAGE_TYPE_VRAM;
288 is_vram[bank] = true;
289 } else if(0x30 <= data && data <= 0x33) {
291 SET_BANK(base, base + 0x1fff, wdmy, rdmy);
292 page_type[bank] = PAGE_TYPE_MODIFY;
294 is_vram[bank] = true;
295 } else if(0x34 <= data && data <= 0x37) {
297 SET_BANK(base, base + 0x1fff, wdmy, ipl + (data - 0x34) * 0x2000);
298 page_type[bank] = PAGE_TYPE_NORMAL;
299 } else if(data == 0x38) {
301 SET_BANK(base , base + 0x17ff, tvram, tvram);
302 SET_BANK(base + 0x1800, base + 0x1fff, wdmy, rdmy);
303 page_type[bank] = PAGE_TYPE_VRAM;
305 is_vram[bank] = true;
306 } else if(data == 0x39) {
308 SET_BANK(base, base + 0x1fff, pcg, pcg);
309 if(kanji_bank & 0x80) {
310 SET_BANK(base, base + 0x7ff, wdmy, kanji + (kanji_bank & 0x7f) * 0x800);
312 page_type[bank] = PAGE_TYPE_KANJI;
314 } else if(data == 0x3a) {
316 SET_BANK(base, base + 0x1fff, wdmy, dic + dic_bank * 0x2000);
317 page_type[bank] = PAGE_TYPE_DIC;
318 } else if(0x3c <= data && data <= 0x3f) {
320 SET_BANK(base, base + 0x1fff, wdmy, phone + (data - 0x3c) * 0x2000);
321 page_type[bank] = PAGE_TYPE_NORMAL;
324 SET_BANK(base, base + 0x1fff, wdmy, rdmy);
325 page_type[bank] = PAGE_TYPE_NORMAL;
328 bank = (bank + 1) & 7;
331 #define STATE_VERSION 1
333 #include "../../statesub.h"
335 void MEMORY::decl_state()
337 enter_decl_state(STATE_VERSION);
339 DECL_STATE_ENTRY_1D_ARRAY(ram, sizeof(ram));
340 DECL_STATE_ENTRY_1D_ARRAY(vram, sizeof(vram));
341 DECL_STATE_ENTRY_1D_ARRAY(tvram, sizeof(tvram));
342 DECL_STATE_ENTRY_1D_ARRAY(pcg, sizeof(pcg));
343 DECL_STATE_ENTRY_UINT8(bank);
344 DECL_STATE_ENTRY_1D_ARRAY(page, sizeof(page));
345 DECL_STATE_ENTRY_UINT8(dic_bank);
346 DECL_STATE_ENTRY_UINT8(kanji_bank);
347 DECL_STATE_ENTRY_BOOL(blank);
348 DECL_STATE_ENTRY_BOOL(hblank);
349 DECL_STATE_ENTRY_BOOL(vblank);
350 DECL_STATE_ENTRY_BOOL(busreq);
355 void MEMORY::save_state(FILEIO* state_fio)
357 if(state_entry != NULL) {
358 state_entry->save_state(state_fio);
360 // state_fio->FputUint32(STATE_VERSION);
361 // state_fio->FputInt32(this_device_id);
363 // state_fio->Fwrite(ram, sizeof(ram), 1);
364 // state_fio->Fwrite(vram, sizeof(vram), 1);
365 // state_fio->Fwrite(tvram, sizeof(tvram), 1);
366 // state_fio->Fwrite(pcg, sizeof(pcg), 1);
367 // state_fio->FputUint8(bank);
368 // state_fio->Fwrite(page, sizeof(page), 1);
369 // state_fio->FputUint8(dic_bank);
370 // state_fio->FputUint8(kanji_bank);
371 // state_fio->FputBool(blank);
372 // state_fio->FputBool(hblank);
373 // state_fio->FputBool(vblank);
374 // state_fio->FputBool(busreq);
377 bool MEMORY::load_state(FILEIO* state_fio)
380 if(state_entry != NULL) {
381 mb = state_entry->load_state(state_fio);
386 // if(state_fio->FgetUint32() != STATE_VERSION) {
389 // if(state_fio->FgetInt32() != this_device_id) {
392 // state_fio->Fread(ram, sizeof(ram), 1);
393 // state_fio->Fread(vram, sizeof(vram), 1);
394 // state_fio->Fread(tvram, sizeof(tvram), 1);
395 // state_fio->Fread(pcg, sizeof(pcg), 1);
396 // bank = state_fio->FgetUint8();
397 // state_fio->Fread(page, sizeof(page), 1);
398 // dic_bank = state_fio->FgetUint8();
399 // kanji_bank = state_fio->FgetUint8();
400 // blank = state_fio->FgetBool();
401 // hblank = state_fio->FgetBool();
402 // vblank = state_fio->FgetBool();
403 // busreq = state_fio->FgetBool();
406 uint8_t bank_tmp = bank;
408 for(int i = 0; i < 8; i++) {
415 bool MEMORY::process_state(FILEIO* state_fio, bool loading)
417 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
420 if(!state_fio->StateCheckInt32(this_device_id)) {
423 state_fio->StateBuffer(ram, sizeof(ram), 1);
424 state_fio->StateBuffer(vram, sizeof(vram), 1);
425 state_fio->StateBuffer(tvram, sizeof(tvram), 1);
426 state_fio->StateBuffer(pcg, sizeof(pcg), 1);
427 state_fio->StateUint8(bank);
428 state_fio->StateBuffer(page, sizeof(page), 1);
429 state_fio->StateUint8(dic_bank);
430 state_fio->StateUint8(kanji_bank);
431 state_fio->StateBool(blank);
432 state_fio->StateBool(hblank);
433 state_fio->StateBool(vblank);
434 state_fio->StateBool(busreq);
438 uint8_t bank_tmp = bank;
440 for(int i = 0; i < 8; i++) {