2 FUJITSU FM16beta Emulator 'eFM16beta'
\r
4 Author : Takeda.Toshiya
\r
12 #include "keyboard.h"
\r
13 #include "../disk.h"
\r
14 #include "../i8237.h"
\r
15 #include "../i8259.h"
\r
17 #include "../i286.h"
\r
19 #include "../mb8877.h"
\r
20 #include "../msm58321.h"
\r
21 #include "../pcm1bit.h"
\r
23 void MAIN::initialize()
\r
25 MEMORY::initialize();
\r
27 memset(ram, 0x00, sizeof(ram));
\r
28 memset(rom, 0xff, sizeof(rom));
\r
31 read_bios(_T("IPL.ROM"), rom, sizeof(rom));
\r
33 set_memory_rw(0x00000, 0xfbfff, ram);
\r
34 set_memory_r(0xfc000, 0xfffff, rom);
\r
37 // sub_busy = false;
\r
40 sidereg_2hd = 0; // side 0
\r
41 drvreg_2hd = 0; // drive #0, motor on
\r
43 d_fdc_2hd->write_signal(SIG_MB8877_MOTOR, 1, 1);
\r
44 d_fdc_2hd->write_signal(SIG_MB8877_DRIVEREG, 0, 3);
\r
47 sidereg_2d = 0; // side 0
\r
48 drvreg_2d = 0x80; // drive #0, motor on
\r
50 d_fdc_2d->write_signal(SIG_MB8877_MOTOR, 1, 1);
\r
51 d_fdc_2d->write_signal(SIG_MB8877_DRIVEREG, 0, 3);
\r
57 irq_enb = ext_irq_enb = 0;
\r
58 irq0_tx = irq0_rx = irq0_syn = irq1 = irq2 = irq3 = irq4 = irq5 = irq6 = irq7 = irq8 = irq9 = false;
\r
59 firq0 = firq1 = firq2 = firq3 = false;
\r
60 int0 = int1 = int2 = int3 = int4 = int5 = int6 = int7 = false;
\r
63 void MAIN::release()
\r
73 d_dma->set_address_mask(0x000fffff);
\r
74 d_cpu->set_address_mask(0x000fffff);
\r
79 d_pcm->write_signal(SIG_PCM1BIT_ON, 0, 0);
\r
82 void MAIN::write_io8(uint32_t addr, uint32_t data)
\r
88 d_dma->write_signal(SIG_I8237_BANK0, data, 0xff);
\r
91 d_dma->write_signal(SIG_I8237_BANK1, data, 0xff);
\r
94 d_dma->write_signal(SIG_I8237_BANK2, data, 0xff);
\r
97 d_dma->write_signal(SIG_I8237_BANK3, data, 0xff);
\r
103 if((data & 0xc0) == 0x40) {
\r
108 d_dma->set_address_mask(0x00ffffff);
\r
109 d_cpu->set_address_mask(0x00ffffff);
\r
111 d_dma->set_address_mask(0x000fffff);
\r
112 d_cpu->set_address_mask(0x000fffff);
\r
117 change = irq_enb ^ data;
\r
119 if(change & 0x01) update_int7(); // Printer
\r
120 if(change & 0x0e) update_int4(); // RS-232C
\r
121 if(change & 0x10) update_int0(); // PTM
\r
122 if(change & 0x20) update_int6(); // 320KB FDD
\r
123 if(change & 0x80) update_int1(); // Keyboard
\r
126 d_pcm->write_signal(SIG_PCM1BIT_ON, data, 0x80);
\r
130 d_sub->write_signal(SIG_SUB_MAINACK, 1, 1);
\r
134 d_sub->write_signal(SIG_SUB_HALT, data, 0x80);
\r
135 d_sub->write_signal(SIG_SUB_CANCEL, data, 0x40);
\r
139 change = direct ^ data;
\r
141 if(change & 0x80) {
\r
142 if(direct & 0x80) {
\r
143 set_memory_mapped_io_rw(0xc0000, 0xcffff, d_sub);
\r
145 set_memory_rw(0xc0000, 0xcffff, ram + 0xc0000);
\r
148 d_keyboard->write_signal(SIG_KEYBOARD_INSLED, data, 0x02);
\r
151 d_rtc->write_signal(SIG_MSM58321_DATA, data, 0x0f);
\r
154 d_rtc->write_signal(SIG_MSM58321_CS, data, 0x80);
\r
155 d_rtc->write_signal(SIG_MSM58321_READ, data, 0x04);
\r
156 d_rtc->write_signal(SIG_MSM58321_WRITE, data, 0x02);
\r
157 d_rtc->write_signal(SIG_MSM58321_ADDR_WRITE, data, 0x01);
\r
161 d_fdc_2d->write_signal(SIG_MB8877_SIDEREG, data, 0x01);
\r
165 d_fdc_2d->write_signal(SIG_MB8877_MOTOR, data, 0x80);
\r
166 d_fdc_2d->write_signal(SIG_MB8877_DRIVEREG, data, 0x03);
\r
172 change = ext_irq_enb ^ data;
\r
173 ext_irq_enb = data;
\r
174 if(change & 0x08) update_int2(); // 1MB FDD
\r
178 d_fdc_2hd->write_signal(SIG_MB8877_SIDEREG, data, 0x01);
\r
179 sidereg_2hd = data;
\r
182 d_fdc_2hd->write_signal(SIG_MB8877_MOTOR, ~data, 0x80);
\r
183 d_fdc_2hd->write_signal(SIG_MB8877_DRIVEREG, data, 0x03);
\r
190 uint32_t MAIN::read_io8(uint32_t addr)
\r
196 uint8_t val = rst | (d_cpu->get_shutdown_flag() << 1);
\r
198 d_cpu->set_shutdown_flag(0);
\r
203 return (irq8 ? 0x01 : 0) | (irq7 ? 0x02 : 0) | (irq4 ? 0x08 : 0) | (irq3 ? 0x10 : 0) | (irq2 ? 0x20 : 0) | (irq1 ? 0x40 : 0) | (irq0_tx || irq0_rx || irq0_syn ? 0x80 : 0);
\r
207 return (firq0 ? 0x01 : 0) | (firq1 ? 0x02 : 0) | (firq2 ? 0x80 : 0);
\r
210 return (sub_busy ? 0x80 : 0);
\r
223 return (irq4 ? 0x40 : 0) | (drq_2d ? 0x80 : 0);
\r
226 return (irq6 ? 0x04 : 0) | (irq5 ? 0x40 : 0);
\r
229 return sidereg_2hd;
\r
234 uint8_t val = 0x40; // DSNS=1
\r
235 if(d_fdc_2hd->read_signal(SIG_MB8877_MOTOR)) {
\r
236 for(int i = 0; i < 4; i++) {
\r
237 if(d_fdc_2hd->is_disk_inserted(i)) {
\r
242 DISK *disk = d_fdc_2hd->get_disk_handler(drvreg_2hd & 3);
\r
243 if(disk->get_rpm() == 300) {
\r
246 if(disk->inserted && disk->two_side) {
\r
252 return (irq5 ? 0x40 : 0) | (drq_2hd ? 0x80 : 0);
\r
260 void MAIN::write_signal(int id, uint32_t data, uint32_t mask)
\r
262 if(id == SIG_MAIN_IRQ0_TX) {
\r
263 irq0_tx = ((data & mask) != 0);
\r
265 } else if(id == SIG_MAIN_IRQ0_RX) {
\r
266 irq0_rx = ((data & mask) != 0);
\r
268 } else if(id == SIG_MAIN_IRQ0_SYN) {
\r
269 irq0_syn = ((data & mask) != 0);
\r
271 } else if(id == SIG_MAIN_IRQ1) {
\r
272 if(!(irq_enb & 0x80)) {
\r
273 d_sub->write_signal(SIG_SUB_KEY, data, mask);
\r
275 irq1 = ((data & mask) != 0);
\r
277 } else if(id == SIG_MAIN_IRQ2) {
\r
278 irq2 = ((data & mask) != 0);
\r
280 } else if(id == SIG_MAIN_IRQ3) {
\r
281 irq3 = ((data & mask) != 0); // dma
\r
283 } else if(id == SIG_MAIN_IRQ4) {
\r
284 irq4 = ((data & mask) != 0);
\r
286 } else if(id == SIG_MAIN_IRQ5) {
\r
287 irq5 = ((data & mask) != 0);
\r
289 } else if(id == SIG_MAIN_IRQ6) {
\r
290 irq6 = ((data & mask) != 0);
\r
292 } else if(id == SIG_MAIN_IRQ7) {
\r
293 irq7 = ((data & mask) != 0);
\r
295 } else if(id == SIG_MAIN_IRQ8) {
\r
296 irq8 = ((data & mask) != 0);
\r
298 } else if(id == SIG_MAIN_IRQ9) {
\r
299 irq9 = ((data & mask) != 0);
\r
301 } else if(id == SIG_MAIN_FIRQ0) {
\r
302 firq0 = ((data & mask) != 0);
\r
304 } else if(id == SIG_MAIN_FIRQ1) {
\r
305 firq1 = ((data & mask) != 0);
\r
307 } else if(id == SIG_MAIN_FIRQ2) {
\r
308 firq2 = ((data & mask) != 0);
\r
310 } else if(id == SIG_MAIN_FIRQ3) {
\r
311 firq3 = ((data & mask) != 0);
\r
313 } else if(id == SIG_MAIN_SUB_BUSY) {
\r
314 sub_busy = ((data & mask) != 0);
\r
316 this->out_debug_log(_T("SUB -> MAIN: SUB BUSY = %d\n"), sub_busy);
\r
318 } else if(id == SIG_MAIN_DRQ_2HD) {
\r
319 drq_2hd = ((data & mask) != 0);
\r
320 } else if(id == SIG_MAIN_DRQ_2D) {
\r
321 drq_2d = ((data & mask) != 0);
\r
322 } else if(id == SIG_MAIN_RTC_DATA) {
\r
323 rtc_data = (data & mask) | (rtc_data & ~mask);
\r
324 } else if(id == SIG_MAIN_RTC_BUSY) {
\r
325 rtc_data = (data & mask) | (rtc_data & ~mask);
\r
331 IRQ8:
\83^
\83C
\83}
\81[
\r
332 IRQ1 + FIRQ1 -> INT1
\r
333 IRQ1:
\83L
\81[
\83{
\81[
\83h
\r
334 FIRQ1: BREAK
\83L
\81[
\r
335 IRQ5 + IRQ6 -> INT2
\r
336 IRQ5: IMB
\83t
\83\8d\83b
\83s
\83B
\83f
\83B
\83X
\83N
\r
337 IRQ6:
\83n
\81[
\83h
\83f
\83B
\83X
\83N
\r
338 FIRQ0 + FIRQ2 + FIRQ3 -> INT3
\r
339 FIRQ0: SUB
\83A
\83e
\83\93\83V
\83\87\83\93\r
341 FIRQ3:
\83\86\81[
\83U
\97p
\r
344 IRQ2 + IRQ9 + INTNDP -> INT5
\r
346 IRQ9:
\83\86\81[
\83U
\97p
\r
348 IRQ4: 320KB
\83t
\83\8d\83b
\83s
\83B
\83f
\83B
\83X
\83N
\r
350 IRQ7:
\83v
\83\8a\83\93\83^
\r
353 void MAIN::update_int0()
\r
355 // bool prev = int0;
\r
356 int0 = (irq8 && (irq_enb & 0x10));
\r
357 // if(prev != int0) {
\r
358 d_pic->write_signal(SIG_I8259_IR0, int0 ? 1 : 0, 1);
\r
362 void MAIN::update_int1()
\r
364 // bool prev = int1;
\r
365 int1 = (irq1 && (irq_enb & 0x80)) || firq1;
\r
366 // if(prev != int1) {
\r
367 d_pic->write_signal(SIG_I8259_IR1, int1 ? 1 : 0, 1);
\r
371 void MAIN::update_int2()
\r
373 // bool prev = int2;
\r
374 int2 = (irq5 && (ext_irq_enb & 0x08)) || irq6;
\r
375 // if(prev != int2) {
\r
376 d_pic->write_signal(SIG_I8259_IR2, int2 ? 1 : 0, 1);
\r
380 void MAIN::update_int3()
\r
382 // bool prev = int3;
\r
383 int3 = firq0 || firq2 || firq3;
\r
384 // if(prev != int3) {
\r
385 d_pic->write_signal(SIG_I8259_IR3, int3 ? 1 : 0, 1);
\r
389 void MAIN::update_int4()
\r
391 // bool prev = int4;
\r
392 int4 = (irq0_tx && (irq_enb & 0x02)) || (irq0_rx && (irq_enb & 0x04)) || (irq0_syn && (irq_enb & 0x08));
\r
393 // if(prev != int4) {
\r
394 d_pic->write_signal(SIG_I8259_IR4, int4 ? 1 : 0, 1);
\r
398 void MAIN::update_int5()
\r
400 // bool prev = int5;
\r
401 int5 = irq2 || irq9;
\r
402 // if(prev != int5) {
\r
403 d_pic->write_signal(SIG_I8259_IR5, int5 ? 1 : 0, 1);
\r
407 void MAIN::update_int6()
\r
409 // bool prev = int6;
\r
410 int6 = (irq6 && (irq_enb & 0x20));
\r
411 // if(prev != int6) {
\r
412 d_pic->write_signal(SIG_I8259_IR6, int6 ? 1 : 0, 1);
\r
416 void MAIN::update_int7()
\r
418 // bool prev = int7;
\r
419 int7 = irq7 && (irq_enb & 0x01);
\r
420 // if(prev != int7) {
\r
421 d_pic->write_signal(SIG_I8259_IR7, int7 ? 1 : 0, 1);
\r
425 #define STATE_VERSION 1
\r
427 bool MAIN::process_state(FILEIO* state_fio, bool loading)
\r
429 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
\r
432 if(!state_fio->StateCheckInt32(this_device_id)) {
\r