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 bool MAIN::process_state(FILEIO* state_fio, bool loading)
396 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
399 if(!state_fio->StateCheckInt32(this_device_id)) {
402 state_fio->StateBuffer(ram, sizeof(ram), 1);
403 state_fio->StateBuffer(common, sizeof(common), 1);
404 state_fio->StateUint8(ma);
405 state_fio->StateUint8(ms);
406 state_fio->StateUint8(mo);
407 state_fio->StateBool(me1);
408 state_fio->StateBool(me2);
409 state_fio->StateUint8(srqb);
410 state_fio->StateUint8(sres);
411 state_fio->StateBool(sack);
412 state_fio->StateBool(srdy);
413 state_fio->StateBool(intfd);
414 state_fio->StateBool(int0);
415 state_fio->StateBool(int1);
416 state_fio->StateBool(int2);
417 state_fio->StateBool(int3);
418 state_fio->StateBool(int4);
419 state_fio->StateBool(me);
420 state_fio->StateBool(e1);
421 state_fio->StateUint8(inp);
422 state_fio->StateBool(motor);
423 state_fio->StateBool(drq);
424 state_fio->StateBool(index);
425 state_fio->StateBool(crt_400line);