2 SHARP MZ-3500 Emulator 'EmuZ-3500'
4 Author : Takeda.Toshiya
11 #include "../upd765a.h"
13 #define SET_BANK(s, e, w, r) { \
14 int sb = (s) >> 11, eb = (e) >> 11; \
15 for(int i = sb; i <= eb; i++) { \
19 wbank[i] = (w) + 0x800 * (i - sb); \
24 rbank[i] = (r) + 0x800 * (i - sb); \
29 void MAIN::initialize()
32 memset(ipl, 0xff, sizeof(ipl));
33 memset(ram, 0, sizeof(ram));
34 memset(common, 0, sizeof(common));
35 memset(basic, 0xff, sizeof(basic));
36 memset(ext, 0xff, sizeof(ext));
37 memset(rdmy, 0xff, sizeof(rdmy));
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);
45 if(fio->Fopen(create_local_path(_T("BASIC.ROM")), FILEIO_READ_BINARY)) {
46 fio->Fread(basic, sizeof(basic), 1);
49 if(fio->Fopen(create_local_path(_T("EXT.ROM")), FILEIO_READ_BINARY)) {
50 fio->Fread(ext, sizeof(ext), 1);
55 crt_400line = (config.monitor_type == 0 || config.monitor_type == 1);
72 intfd = int0 = int1 = int2 = int3 = int4 = false;
80 void MAIN::write_data8(uint32_t addr, uint32_t data)
83 wbank[addr >> 11][addr & 0x7ff] = data;
86 uint32_t MAIN::read_data8(uint32_t addr)
89 return rbank[addr >> 11][addr & 0x7ff];
92 uint32_t MAIN::fetch_op(uint32_t addr, int *wait)
96 return read_data8(addr);
99 void MAIN::write_io8(uint32_t addr, uint32_t data)
101 switch(addr & 0xff) {
102 case 0xec: // mz3500sm p.17
111 case 0xf8: // mz3500sm p.59
114 for(int i = 0; i < 3; i++) {
115 if(data & (1 << i)) {
116 // this->out_debug_log(_T("MAIN->FDC\tDRIVE=%d\n"), i);
117 d_fdc->write_signal(SIG_UPD765A_DRVSEL, i, 3);
122 d_fdc->write_signal(SIG_UPD765A_MOTOR, data, 0x10);
123 d_fdc->write_signal(SIG_UPD765A_TC, data, 0x20);
124 motor = ((data & 0x10) != 0);
126 bool new_me = ((data & 0x80) != 0);
133 case 0xf9: // mz3500sm p.59
135 d_fdc->write_dma_io8(1, data);
137 case 0xfc: // mz3500sm p.23
138 if((srqb & 2) != (data & 2)) {
139 // this->out_debug_log(_T("MAIN->SUB\tBUSREQ=%d\n"), (data&2)?1:0);
140 d_subcpu->write_signal(SIG_CPU_BUSREQ, data, 2);
144 bool new_e1 = ((data & 1) != 0);
151 case 0xfd: // mz3500sm p.23
152 if(!(sres & 0x80) && (data & 0x80)) {
153 // this->out_debug_log(_T("MAIN->SUB\tRESET\n"));
158 uint8_t new_ms = data & 3;
165 case 0xfe: // mz3500sm p.23
167 uint8_t new_mo = data & 7;
168 uint8_t new_ma = (data >> 4) & 0x0f;
169 if(mo != new_mo || ma != new_ma) {
176 case 0xff: // mz3500sm p.23
178 bool new_me1 = ((data & 1) != 0);
179 bool new_me2 = ((data & 2) != 0);
180 if(me1 != new_me1 || me2 != new_me2) {
190 uint32_t MAIN::read_io8(uint32_t addr)
194 switch(addr & 0xff) {
195 case 0xec: // mz3500sm p.17
204 case 0xf8: // mz3500sm p.59
206 return 0xf8 | (drq ? 1 : 0) | (index ? 2 : 0) | (motor ? 4 : 0);
207 case 0xf9: // mz3500sm p.59
209 return d_fdc->read_dma_io8(1);
210 case 0xfc: // mz3500sm p.23
212 case 0xfd: // mz3500sm p.23
214 case 0xfe: // mz3500sm p.23,85-86
215 // bit4: sw4=on, select period for decimal point
216 // bit3: sw3=on, select hiresolution crt
217 // bit2: sw2=off, select MZ-1P02
219 // bit0: sec=on, select double side mini floppy
220 return 0xe0 | (((~config.dipswitch) & 0x0b) << 1) | (crt_400line ? 0 : 8);
221 case 0xff: // mz3500sm p.23,85-86
222 // bit7: fd3=off, select double side mini floppy
223 // bit6: fd2=off, select double side mini floppy
224 // bit5: fd1=off, normally small letter and in capital letter when shifted
225 return 0xc0 | ((config.dipswitch & 0x80) ? 0 : 0x20) | (srdy ? 0x10 : 0) | (sack ? 0 : 8) | (inp & 7);
230 void MAIN::write_signal(int id, uint32_t data, uint32_t mask)
232 if(id == SIG_MAIN_SACK) {
233 sack = ((data & mask) != 0);
234 // this->out_debug_log(_T("SUB->MAIN\tSACK=%d\n"), sack?1:0);
235 } else if(id == SIG_MAIN_SRDY) {
236 srdy = ((data & mask) != 0);
237 // this->out_debug_log(_T("SUB->MAIN\tSRDY=%d\n"), srdy?1:0);
238 } else if(id == SIG_MAIN_INTFD) {
239 intfd = ((data & mask) != 0);
240 // this->out_debug_log(_T("FDC->MAIN\tINTFD=%d\n"), intfd?1:0);
242 } else if(id == SIG_MAIN_INT0) {
243 int0 = ((data & mask) != 0);
244 // this->out_debug_log(_T("SUB->MAIN\tINT0=%d\n"), int0?1:0);
246 } else if(id == SIG_MAIN_INT1) {
247 int1 = ((data & mask) != 0);
249 } else if(id == SIG_MAIN_INT2) {
250 int2 = ((data & mask) != 0);
252 } else if(id == SIG_MAIN_INT3) {
253 int3 = ((data & mask) != 0);
255 } else if(id == SIG_MAIN_INT4) {
256 int4 = ((data & mask) != 0);
258 } else if(id == SIG_MAIN_DRQ) {
259 drq = ((data & mask) != 0);
260 } else if(id == SIG_MAIN_INDEX) {
261 index = ((data & mask) != 0);
265 void MAIN::update_irq()
292 // this->out_debug_log(_T("MAIN IRQ=%d SRC=%d\n"), next?1:0,inp);
293 d_maincpu->set_intr_line(true, true, 0);
297 void MAIN::update_bank()
299 SET_BANK(0x0000, 0xffff, wdmy, rdmy);
302 // SD0: INITIALIZE STATE, mz3500sm p.7
303 SET_BANK(0x0000, 0x0fff, wdmy, ipl + 0x1000);
304 SET_BANK(0x1000, 0x1fff, wdmy, ipl + 0x1000);
305 SET_BANK(0x2000, 0x3fff, wdmy, basic + 0x2000);
307 SET_BANK(0x4000, 0x7fff, ram + 0x4000, ram + 0x4000);
310 SET_BANK(0x8000, 0xbfff, ram + 0x8000, ram + 0x8000);
313 case 0x00: SET_BANK(0xc000, 0xffff, ram + 0x0c000, ram + 0x0c000); break;
314 case 0x01: SET_BANK(0xc000, 0xffff, ram + 0x00000, ram + 0x00000); break;
315 case 0x0f: SET_BANK(0xf800, 0xffff, common, common); break;
317 } else if((ms & 3) == 1) {
318 // SD1: SYSTEM LOADING & CP/M, mz3500sm p.9
319 SET_BANK(0x0000, 0xf7ff, ram, ram);
320 SET_BANK(0xf800, 0xffff, common, common);
321 } else if((ms & 3) == 2) {
322 // SD2: ROM based BASIC, mz3500sm p.10
323 SET_BANK(0x0000, 0x1fff, wdmy, basic);
325 case 0x00: SET_BANK(0x2000, 0x3fff, wdmy, basic + 0x2000); break;
326 case 0x01: SET_BANK(0x2000, 0x3fff, wdmy, basic + 0x4000); break;
327 case 0x02: SET_BANK(0x2000, 0x3fff, wdmy, basic + 0x6000); break;
328 case 0x03: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x0000); break;
329 case 0x04: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x2000); break;
330 case 0x05: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x4000); break;
331 case 0x06: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x6000); break;
334 SET_BANK(0x4000, 0x7fff, ram + 0x4000, ram + 0x4000);
337 SET_BANK(0x8000, 0xbfff, ram + 0x8000, ram + 0x8000);
340 case 0x00: SET_BANK(0xc000, 0xffff, ram + 0x0c000, ram + 0x0c000); break;
341 case 0x01: SET_BANK(0xc000, 0xffff, ram + 0x00000, ram + 0x00000); break;
342 case 0x02: SET_BANK(0xc000, 0xffff, ram + 0x10000, ram + 0x10000); break;
343 case 0x03: SET_BANK(0xc000, 0xffff, ram + 0x14000, ram + 0x14000); break;
344 case 0x04: SET_BANK(0xc000, 0xffff, ram + 0x18000, ram + 0x18000); break;
345 case 0x05: SET_BANK(0xc000, 0xffff, ram + 0x1c000, ram + 0x1c000); break;
346 case 0x06: SET_BANK(0xc000, 0xffff, ram + 0x20000, ram + 0x20000); break;
347 case 0x07: SET_BANK(0xc000, 0xffff, ram + 0x24000, ram + 0x24000); break;
348 case 0x08: SET_BANK(0xc000, 0xffff, ram + 0x28000, ram + 0x28000); break;
349 case 0x09: SET_BANK(0xc000, 0xffff, ram + 0x2c000, ram + 0x2c000); break;
350 case 0x0a: SET_BANK(0xc000, 0xffff, ram + 0x30000, ram + 0x30000); break;
351 case 0x0b: SET_BANK(0xc000, 0xffff, ram + 0x34000, ram + 0x34000); break;
352 case 0x0c: SET_BANK(0xc000, 0xffff, ram + 0x38000, ram + 0x38000); break;
353 case 0x0d: SET_BANK(0xc000, 0xffff, ram + 0x3c000, ram + 0x3c000); break;
354 case 0x0f: SET_BANK(0xf800, 0xffff, common, common); break;
357 // SD3: RAM based BASIC, mz3500sm p.11
358 SET_BANK(0x0000, 0x1fff, ram, ram);
360 case 0x0: SET_BANK(0x2000, 0x3fff, ram + 0x2000, ram + 0x2000); break;
361 case 0x1: SET_BANK(0x2000, 0x3fff, ram + 0xc000, ram + 0xc000); break;
362 case 0x2: SET_BANK(0x2000, 0x3fff, ram + 0xe000, ram + 0xe000); break;
363 case 0x3: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x0000); break;
364 case 0x4: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x2000); break;
365 case 0x5: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x4000); break;
366 case 0x6: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x6000); break;
369 SET_BANK(0x4000, 0x7fff, ram + 0x4000, ram + 0x4000);
372 SET_BANK(0x8000, 0xbfff, ram + 0x8000, ram + 0x8000);
375 case 0x00: SET_BANK(0xc000, 0xffff, ram + 0x10000, ram + 0x10000); break;
376 case 0x01: SET_BANK(0xc000, 0xffff, ram + 0x14000, ram + 0x14000); break;
377 case 0x02: SET_BANK(0xc000, 0xffff, ram + 0x18000, ram + 0x18000); break;
378 case 0x03: SET_BANK(0xc000, 0xffff, ram + 0x1c000, ram + 0x1c000); break;
379 case 0x04: SET_BANK(0xc000, 0xffff, ram + 0x20000, ram + 0x20000); break;
380 case 0x05: SET_BANK(0xc000, 0xffff, ram + 0x24000, ram + 0x24000); break;
381 case 0x06: SET_BANK(0xc000, 0xffff, ram + 0x28000, ram + 0x28000); break;
382 case 0x07: SET_BANK(0xc000, 0xffff, ram + 0x2c000, ram + 0x2c000); break;
383 case 0x08: SET_BANK(0xc000, 0xffff, ram + 0x30000, ram + 0x30000); break;
384 case 0x09: SET_BANK(0xc000, 0xffff, ram + 0x34000, ram + 0x34000); break;
385 case 0x0a: SET_BANK(0xc000, 0xffff, ram + 0x38000, ram + 0x38000); break;
386 case 0x0b: SET_BANK(0xc000, 0xffff, ram + 0x3c000, ram + 0x3c000); break;
387 case 0x0f: SET_BANK(0xf800, 0xffff, common, common); break;
392 #define STATE_VERSION 2
394 #include "../../statesub.h"
396 void MAIN::decl_state()
398 enter_decl_state(STATE_VERSION);
400 DECL_STATE_ENTRY_1D_ARRAY(ram, sizeof(ram));
401 DECL_STATE_ENTRY_1D_ARRAY(common, sizeof(common));
402 DECL_STATE_ENTRY_UINT8(ma);
403 DECL_STATE_ENTRY_UINT8(ms);
404 DECL_STATE_ENTRY_UINT8(mo);
405 DECL_STATE_ENTRY_BOOL(me1);
406 DECL_STATE_ENTRY_BOOL(me2);
407 DECL_STATE_ENTRY_UINT8(srqb);
408 DECL_STATE_ENTRY_UINT8(sres);
409 DECL_STATE_ENTRY_BOOL(sack);
410 DECL_STATE_ENTRY_BOOL(srdy);
411 DECL_STATE_ENTRY_BOOL(intfd);
412 DECL_STATE_ENTRY_BOOL(int0);
413 DECL_STATE_ENTRY_BOOL(int1);
414 DECL_STATE_ENTRY_BOOL(int2);
415 DECL_STATE_ENTRY_BOOL(int3);
416 DECL_STATE_ENTRY_BOOL(int4);
417 DECL_STATE_ENTRY_BOOL(me);
418 DECL_STATE_ENTRY_BOOL(e1);
419 DECL_STATE_ENTRY_UINT8(inp);
420 DECL_STATE_ENTRY_BOOL(motor);
421 DECL_STATE_ENTRY_BOOL(drq);
422 DECL_STATE_ENTRY_BOOL(index);
423 DECL_STATE_ENTRY_BOOL(crt_400line);
428 void MAIN::save_state(FILEIO* state_fio)
430 if(state_entry != NULL) {
431 state_entry->save_state(state_fio);
433 // state_fio->FputUint32(STATE_VERSION);
434 // state_fio->FputInt32(this_device_id);
436 // state_fio->Fwrite(ram, sizeof(ram), 1);
437 // state_fio->Fwrite(common, sizeof(common), 1);
438 // state_fio->FputUint8(ma);
439 // state_fio->FputUint8(ms);
440 // state_fio->FputUint8(mo);
441 // state_fio->FputBool(me1);
442 // state_fio->FputBool(me2);
443 // state_fio->FputUint8(srqb);
444 // state_fio->FputUint8(sres);
445 // state_fio->FputBool(sack);
446 // state_fio->FputBool(srdy);
447 // state_fio->FputBool(intfd);
448 // state_fio->FputBool(int0);
449 // state_fio->FputBool(int1);
450 // state_fio->FputBool(int2);
451 // state_fio->FputBool(int3);
452 // state_fio->FputBool(int4);
453 // state_fio->FputBool(me);
454 // state_fio->FputBool(e1);
455 // state_fio->FputUint8(inp);
456 // state_fio->FputBool(motor);
457 // state_fio->FputBool(drq);
458 // state_fio->FputBool(index);
459 // state_fio->FputBool(crt_400line);
462 bool MAIN::load_state(FILEIO* state_fio)
465 if(state_entry != NULL) {
466 mb = state_entry->load_state(state_fio);
471 // if(state_fio->FgetUint32() != STATE_VERSION) {
474 // if(state_fio->FgetInt32() != this_device_id) {
477 // state_fio->Fread(ram, sizeof(ram), 1);
478 // state_fio->Fread(common, sizeof(common), 1);
479 // ma = state_fio->FgetUint8();
480 // ms = state_fio->FgetUint8();
481 // mo = state_fio->FgetUint8();
482 // me1 = state_fio->FgetBool();
483 // me2 = state_fio->FgetBool();
484 // srqb = state_fio->FgetUint8();
485 // sres = state_fio->FgetUint8();
486 // sack = state_fio->FgetBool();
487 // srdy = state_fio->FgetBool();
488 // intfd = state_fio->FgetBool();
489 // int0 = state_fio->FgetBool();
490 // int1 = state_fio->FgetBool();
491 // int2 = state_fio->FgetBool();
492 // int3 = state_fio->FgetBool();
493 // int4 = state_fio->FgetBool();
494 // me = state_fio->FgetBool();
495 // e1 = state_fio->FgetBool();
496 // inp = state_fio->FgetUint8();
497 // motor = state_fio->FgetBool();
498 // drq = state_fio->FgetBool();
499 // index = state_fio->FgetBool();
500 // crt_400line = state_fio->FgetBool();
507 bool MAIN::process_state(FILEIO* state_fio, bool loading)
509 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
512 if(!state_fio->StateCheckInt32(this_device_id)) {
515 state_fio->StateBuffer(ram, sizeof(ram), 1);
516 state_fio->StateBuffer(common, sizeof(common), 1);
517 state_fio->StateUint8(ma);
518 state_fio->StateUint8(ms);
519 state_fio->StateUint8(mo);
520 state_fio->StateBool(me1);
521 state_fio->StateBool(me2);
522 state_fio->StateUint8(srqb);
523 state_fio->StateUint8(sres);
524 state_fio->StateBool(sack);
525 state_fio->StateBool(srdy);
526 state_fio->StateBool(intfd);
527 state_fio->StateBool(int0);
528 state_fio->StateBool(int1);
529 state_fio->StateBool(int2);
530 state_fio->StateBool(int3);
531 state_fio->StateBool(int4);
532 state_fio->StateBool(me);
533 state_fio->StateBool(e1);
534 state_fio->StateUint8(inp);
535 state_fio->StateBool(motor);
536 state_fio->StateBool(drq);
537 state_fio->StateBool(index);
538 state_fio->StateBool(crt_400line);