2 SHARP MZ-3500 Emulator 'EmuZ-3500'
4 Author : Takeda.Toshiya
11 #include "../upd765a.h"
15 #define SET_BANK(s, e, w, r) { \
16 int sb = (s) >> 11, eb = (e) >> 11; \
17 for(int i = sb; i <= eb; i++) { \
21 wbank[i] = (w) + 0x800 * (i - sb); \
26 rbank[i] = (r) + 0x800 * (i - sb); \
31 void MAIN::initialize()
34 memset(ipl, 0xff, sizeof(ipl));
35 memset(ram, 0, sizeof(ram));
36 memset(common, 0, sizeof(common));
37 memset(basic, 0xff, sizeof(basic));
38 memset(ext, 0xff, sizeof(ext));
39 memset(rdmy, 0xff, sizeof(rdmy));
42 FILEIO* fio = new FILEIO();
43 if(fio->Fopen(create_local_path(_T("IPL.ROM")), FILEIO_READ_BINARY)) {
44 fio->Fread(ipl, sizeof(ipl), 1);
47 if(fio->Fopen(create_local_path(_T("BASIC.ROM")), FILEIO_READ_BINARY)) {
48 fio->Fread(basic, sizeof(basic), 1);
51 if(fio->Fopen(create_local_path(_T("EXT.ROM")), FILEIO_READ_BINARY)) {
52 fio->Fread(ext, sizeof(ext), 1);
57 crt_400line = (config.monitor_type == 0 || config.monitor_type == 1);
74 intfd = int0 = int1 = int2 = int3 = int4 = false;
82 void MAIN::write_data8(uint32_t addr, uint32_t data)
85 wbank[addr >> 11][addr & 0x7ff] = data;
88 uint32_t MAIN::read_data8(uint32_t addr)
91 return rbank[addr >> 11][addr & 0x7ff];
94 uint32_t MAIN::fetch_op(uint32_t addr, int *wait)
98 return read_data8(addr);
101 void MAIN::write_io8(uint32_t addr, uint32_t data)
103 switch(addr & 0xff) {
104 case 0xec: // mz3500sm p.17
113 case 0xf8: // mz3500sm p.59
116 for(int i = 0; i < 3; i++) {
117 if(data & (1 << i)) {
118 // this->out_debug_log(_T("MAIN->FDC\tDRIVE=%d\n"), i);
119 d_fdc->write_signal(SIG_UPD765A_DRVSEL, i, 3);
124 d_fdc->write_signal(SIG_UPD765A_MOTOR, data, 0x10);
125 d_fdc->write_signal(SIG_UPD765A_TC, data, 0x20);
126 motor = ((data & 0x10) != 0);
128 bool new_me = ((data & 0x80) != 0);
135 case 0xf9: // mz3500sm p.59
137 d_fdc->write_dma_io8(1, data);
139 case 0xfc: // mz3500sm p.23
140 if((srqb & 2) != (data & 2)) {
141 // this->out_debug_log(_T("MAIN->SUB\tBUSREQ=%d\n"), (data&2)?1:0);
142 d_subcpu->write_signal(SIG_CPU_BUSREQ, data, 2);
146 bool new_e1 = ((data & 1) != 0);
153 case 0xfd: // mz3500sm p.23
154 if(!(sres & 0x80) && (data & 0x80)) {
155 // this->out_debug_log(_T("MAIN->SUB\tRESET\n"));
160 uint8_t new_ms = data & 3;
167 case 0xfe: // mz3500sm p.23
169 uint8_t new_mo = data & 7;
170 uint8_t new_ma = (data >> 4) & 0x0f;
171 if(mo != new_mo || ma != new_ma) {
178 case 0xff: // mz3500sm p.23
180 bool new_me1 = ((data & 1) != 0);
181 bool new_me2 = ((data & 2) != 0);
182 if(me1 != new_me1 || me2 != new_me2) {
192 uint32_t MAIN::read_io8(uint32_t addr)
196 switch(addr & 0xff) {
197 case 0xec: // mz3500sm p.17
206 case 0xf8: // mz3500sm p.59
208 return 0xf8 | (drq ? 1 : 0) | (index ? 2 : 0) | (motor ? 4 : 0);
209 case 0xf9: // mz3500sm p.59
211 return d_fdc->read_dma_io8(1);
212 case 0xfc: // mz3500sm p.23
214 case 0xfd: // mz3500sm p.23
216 case 0xfe: // mz3500sm p.23,85-86
217 // bit4: sw4=on, select period for decimal point
218 // bit3: sw3=on, select hiresolution crt
219 // bit2: sw2=off, select MZ-1P02
221 // bit0: sec=on, select double side mini floppy
222 return 0xe0 | (((~config.dipswitch) & 0x0b) << 1) | (crt_400line ? 0 : 8);
223 case 0xff: // mz3500sm p.23,85-86
224 // bit7: fd3=off, select double side mini floppy
225 // bit6: fd2=off, select double side mini floppy
226 // bit5: fd1=off, normally small letter and in capital letter when shifted
227 return 0xc0 | ((config.dipswitch & 0x80) ? 0 : 0x20) | (srdy ? 0x10 : 0) | (sack ? 0 : 8) | (inp & 7);
232 void MAIN::write_signal(int id, uint32_t data, uint32_t mask)
234 if(id == SIG_MAIN_SACK) {
235 sack = ((data & mask) != 0);
236 // this->out_debug_log(_T("SUB->MAIN\tSACK=%d\n"), sack?1:0);
237 } else if(id == SIG_MAIN_SRDY) {
238 srdy = ((data & mask) != 0);
239 // this->out_debug_log(_T("SUB->MAIN\tSRDY=%d\n"), srdy?1:0);
240 } else if(id == SIG_MAIN_INTFD) {
241 intfd = ((data & mask) != 0);
242 // this->out_debug_log(_T("FDC->MAIN\tINTFD=%d\n"), intfd?1:0);
244 } else if(id == SIG_MAIN_INT0) {
245 int0 = ((data & mask) != 0);
246 // this->out_debug_log(_T("SUB->MAIN\tINT0=%d\n"), int0?1:0);
248 } else if(id == SIG_MAIN_INT1) {
249 int1 = ((data & mask) != 0);
251 } else if(id == SIG_MAIN_INT2) {
252 int2 = ((data & mask) != 0);
254 } else if(id == SIG_MAIN_INT3) {
255 int3 = ((data & mask) != 0);
257 } else if(id == SIG_MAIN_INT4) {
258 int4 = ((data & mask) != 0);
260 } else if(id == SIG_MAIN_DRQ) {
261 drq = ((data & mask) != 0);
262 } else if(id == SIG_MAIN_INDEX) {
263 index = ((data & mask) != 0);
267 void MAIN::update_irq()
294 // this->out_debug_log(_T("MAIN IRQ=%d SRC=%d\n"), next?1:0,inp);
295 d_maincpu->set_intr_line(true, true, 0);
299 void MAIN::update_bank()
301 SET_BANK(0x0000, 0xffff, wdmy, rdmy);
304 // SD0: INITIALIZE STATE, mz3500sm p.7
305 SET_BANK(0x0000, 0x0fff, wdmy, ipl + 0x1000);
306 SET_BANK(0x1000, 0x1fff, wdmy, ipl + 0x1000);
307 SET_BANK(0x2000, 0x3fff, wdmy, basic + 0x2000);
309 SET_BANK(0x4000, 0x7fff, ram + 0x4000, ram + 0x4000);
312 SET_BANK(0x8000, 0xbfff, ram + 0x8000, ram + 0x8000);
315 case 0x00: SET_BANK(0xc000, 0xffff, ram + 0x0c000, ram + 0x0c000); break;
316 case 0x01: SET_BANK(0xc000, 0xffff, ram + 0x00000, ram + 0x00000); break;
317 case 0x0f: SET_BANK(0xf800, 0xffff, common, common); break;
319 } else if((ms & 3) == 1) {
320 // SD1: SYSTEM LOADING & CP/M, mz3500sm p.9
321 SET_BANK(0x0000, 0xf7ff, ram, ram);
322 SET_BANK(0xf800, 0xffff, common, common);
323 } else if((ms & 3) == 2) {
324 // SD2: ROM based BASIC, mz3500sm p.10
325 SET_BANK(0x0000, 0x1fff, wdmy, basic);
327 case 0x00: SET_BANK(0x2000, 0x3fff, wdmy, basic + 0x2000); break;
328 case 0x01: SET_BANK(0x2000, 0x3fff, wdmy, basic + 0x4000); break;
329 case 0x02: SET_BANK(0x2000, 0x3fff, wdmy, basic + 0x6000); break;
330 case 0x03: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x0000); break;
331 case 0x04: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x2000); break;
332 case 0x05: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x4000); break;
333 case 0x06: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x6000); break;
336 SET_BANK(0x4000, 0x7fff, ram + 0x4000, ram + 0x4000);
339 SET_BANK(0x8000, 0xbfff, ram + 0x8000, ram + 0x8000);
342 case 0x00: SET_BANK(0xc000, 0xffff, ram + 0x0c000, ram + 0x0c000); break;
343 case 0x01: SET_BANK(0xc000, 0xffff, ram + 0x00000, ram + 0x00000); break;
344 case 0x02: SET_BANK(0xc000, 0xffff, ram + 0x10000, ram + 0x10000); break;
345 case 0x03: SET_BANK(0xc000, 0xffff, ram + 0x14000, ram + 0x14000); break;
346 case 0x04: SET_BANK(0xc000, 0xffff, ram + 0x18000, ram + 0x18000); break;
347 case 0x05: SET_BANK(0xc000, 0xffff, ram + 0x1c000, ram + 0x1c000); break;
348 case 0x06: SET_BANK(0xc000, 0xffff, ram + 0x20000, ram + 0x20000); break;
349 case 0x07: SET_BANK(0xc000, 0xffff, ram + 0x24000, ram + 0x24000); break;
350 case 0x08: SET_BANK(0xc000, 0xffff, ram + 0x28000, ram + 0x28000); break;
351 case 0x09: SET_BANK(0xc000, 0xffff, ram + 0x2c000, ram + 0x2c000); break;
352 case 0x0a: SET_BANK(0xc000, 0xffff, ram + 0x30000, ram + 0x30000); break;
353 case 0x0b: SET_BANK(0xc000, 0xffff, ram + 0x34000, ram + 0x34000); break;
354 case 0x0c: SET_BANK(0xc000, 0xffff, ram + 0x38000, ram + 0x38000); break;
355 case 0x0d: SET_BANK(0xc000, 0xffff, ram + 0x3c000, ram + 0x3c000); break;
356 case 0x0f: SET_BANK(0xf800, 0xffff, common, common); break;
359 // SD3: RAM based BASIC, mz3500sm p.11
360 SET_BANK(0x0000, 0x1fff, ram, ram);
362 case 0x0: SET_BANK(0x2000, 0x3fff, ram + 0x2000, ram + 0x2000); break;
363 case 0x1: SET_BANK(0x2000, 0x3fff, ram + 0xc000, ram + 0xc000); break;
364 case 0x2: SET_BANK(0x2000, 0x3fff, ram + 0xe000, ram + 0xe000); break;
365 case 0x3: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x0000); break;
366 case 0x4: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x2000); break;
367 case 0x5: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x4000); break;
368 case 0x6: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x6000); break;
371 SET_BANK(0x4000, 0x7fff, ram + 0x4000, ram + 0x4000);
374 SET_BANK(0x8000, 0xbfff, ram + 0x8000, ram + 0x8000);
377 case 0x00: SET_BANK(0xc000, 0xffff, ram + 0x10000, ram + 0x10000); break;
378 case 0x01: SET_BANK(0xc000, 0xffff, ram + 0x14000, ram + 0x14000); break;
379 case 0x02: SET_BANK(0xc000, 0xffff, ram + 0x18000, ram + 0x18000); break;
380 case 0x03: SET_BANK(0xc000, 0xffff, ram + 0x1c000, ram + 0x1c000); break;
381 case 0x04: SET_BANK(0xc000, 0xffff, ram + 0x20000, ram + 0x20000); break;
382 case 0x05: SET_BANK(0xc000, 0xffff, ram + 0x24000, ram + 0x24000); break;
383 case 0x06: SET_BANK(0xc000, 0xffff, ram + 0x28000, ram + 0x28000); break;
384 case 0x07: SET_BANK(0xc000, 0xffff, ram + 0x2c000, ram + 0x2c000); break;
385 case 0x08: SET_BANK(0xc000, 0xffff, ram + 0x30000, ram + 0x30000); break;
386 case 0x09: SET_BANK(0xc000, 0xffff, ram + 0x34000, ram + 0x34000); break;
387 case 0x0a: SET_BANK(0xc000, 0xffff, ram + 0x38000, ram + 0x38000); break;
388 case 0x0b: SET_BANK(0xc000, 0xffff, ram + 0x3c000, ram + 0x3c000); break;
389 case 0x0f: SET_BANK(0xf800, 0xffff, common, common); break;
394 #define STATE_VERSION 2
396 bool MAIN::process_state(FILEIO* state_fio, bool loading)
398 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
401 if(!state_fio->StateCheckInt32(this_device_id)) {
404 state_fio->StateBuffer(ram, sizeof(ram), 1);
405 state_fio->StateBuffer(common, sizeof(common), 1);
406 state_fio->StateUint8(ma);
407 state_fio->StateUint8(ms);
408 state_fio->StateUint8(mo);
409 state_fio->StateBool(me1);
410 state_fio->StateBool(me2);
411 state_fio->StateUint8(srqb);
412 state_fio->StateUint8(sres);
413 state_fio->StateBool(sack);
414 state_fio->StateBool(srdy);
415 state_fio->StateBool(intfd);
416 state_fio->StateBool(int0);
417 state_fio->StateBool(int1);
418 state_fio->StateBool(int2);
419 state_fio->StateBool(int3);
420 state_fio->StateBool(int4);
421 state_fio->StateBool(me);
422 state_fio->StateBool(e1);
423 state_fio->StateUint8(inp);
424 state_fio->StateBool(motor);
425 state_fio->StateBool(drq);
426 state_fio->StateBool(index);
427 state_fio->StateBool(crt_400line);