OSDN Git Service

[VM][PC9801] Enable to build PC-9801 with upstream 2018-10-05.
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc9801 / floppy.cpp
index 8a5cb0e..fa2bae8 100644 (file)
@@ -1,6 +1,14 @@
 /*
        NEC PC-9801 Emulator 'ePC-9801'
        NEC PC-9801E/F/M Emulator 'ePC-9801E'
+       NEC PC-9801U Emulator 'ePC-9801U'
+       NEC PC-9801VF Emulator 'ePC-9801VF'
+       NEC PC-9801VM Emulator 'ePC-9801VM'
+       NEC PC-9801VX Emulator 'ePC-9801VX'
+       NEC PC-9801RA Emulator 'ePC-9801RA'
+       NEC PC-98XA Emulator 'ePC-98XA'
+       NEC PC-98XL Emulator 'ePC-98XL'
+       NEC PC-98RL Emulator 'ePC-98RL'
        NEC PC-98DO Emulator 'ePC-98DO'
 
        Author : Takeda.Toshiya
@@ -43,15 +51,16 @@ void FLOPPY::reset()
 
 void FLOPPY::write_io8(uint32_t addr, uint32_t data)
 {
-       switch(addr & 0xffff) {
+       switch(addr) {
 #if defined(SUPPORT_2HD_FDD_IF)
-       case 0x90:
+       case 0x0090:
                d_fdc_2hd->write_io8(0, data);
                break;
-       case 0x92:
+       case 0x0092:
                d_fdc_2hd->write_io8(1, data);
                break;
-       case 0x94:
+       case 0x0094:
+       case 0x0096:
                if(!(ctrlreg_2hd & 0x80) && (data & 0x80)) {
                        d_fdc_2hd->reset();
                }
@@ -60,13 +69,14 @@ void FLOPPY::write_io8(uint32_t addr, uint32_t data)
                break;
 #endif
 #if defined(SUPPORT_2DD_FDD_IF)
-       case 0xc8:
+       case 0x00c8:
                d_fdc_2dd->write_io8(0, data);
                break;
-       case 0xca:
+       case 0x00ca:
                d_fdc_2dd->write_io8(1, data);
                break;
-       case 0xcc:
+       case 0x00cc:
+       case 0x00ce:
                if(!(ctrlreg_2dd & 0x80) && (data & 0x80)) {
                        d_fdc_2dd->reset();
                }
@@ -81,40 +91,66 @@ void FLOPPY::write_io8(uint32_t addr, uint32_t data)
                break;
 #endif
 #if defined(SUPPORT_2HD_2DD_FDD_IF)
-       case 0x90:
-       case 0xc8:
-               if(((addr >> 4) & 1) == (modereg & 1)) {
+       case 0x0090:
+#if !defined(SUPPORT_HIRESO)
+       case 0x00c8:
+               if(((addr >> 4) & 1) == (modereg & 1))
+#endif
+               {
                        d_fdc->write_io8(0, data);
                }
                break;
-       case 0x92:
-       case 0xca:
-               if(((addr >> 4) & 1) == (modereg & 1)) {
+       case 0x0092:
+#if !defined(SUPPORT_HIRESO)
+       case 0x00ca:
+               if(((addr >> 4) & 1) == (modereg & 1))
+#endif
+               {
                        d_fdc->write_io8(1, data);
                }
                break;
-       case 0x94:
-       case 0xcc:
-               if(((addr >> 4) & 1) == (modereg & 1)) {
+       case 0x0094:
+       case 0x0096:
+#if !defined(SUPPORT_HIRESO)
+       case 0x00cc:
+       case 0x00ce:
+               if(((addr >> 4) & 1) == (modereg & 1))
+#endif
+               {
                        if(!(ctrlreg & 0x80) && (data & 0x80)) {
                                d_fdc->reset();
                        }
-                       if(!(addr == 0xcc && !(data & 0x20))) {
+#if !defined(SUPPORT_HIRESO)
+                       if(!(addr == 0xcc && !(data & 0x20)))
+#endif
+                       {
                                d_fdc->write_signal(SIG_UPD765A_FREADY, data, 0x40);
                        }
-                       if(data & 1) {
+#if defined(SUPPORT_HIRESO)
+                       if((ctrlreg & 0x20) && !(data & 0x20)) {
+                               d_fdc->set_drive_type(0, DRIVE_TYPE_2HD);
+                               d_fdc->set_drive_type(1, DRIVE_TYPE_2HD);
+                       } else if(!(ctrlreg & 0x20) && (data & 0x20)) {
+                               d_fdc->set_drive_type(0, DRIVE_TYPE_2DD);
+                               d_fdc->set_drive_type(1, DRIVE_TYPE_2DD);
+                       }
+#endif
+//#if !defined(_PC98XA) && !defined(_PC98XL)
+//                     if(modereg & 0x04) {
+//                             d_fdc->write_signal(SIG_UPD765A_MOTOR, data, 0x08);
+//                     }
+                       if(data & 0x01) {
                                if(timer_id != -1) {
                                        cancel_event(this, timer_id);
                                }
                                register_event(this, EVENT_TIMER, 100000, false, &timer_id);
                        }
-//                     if(modereg & 4) {
-//                             d_fdc->write_signal(SIG_UPD765A_MOTOR, data, 0x08);
-//                     }
                        ctrlreg = data;
+//#endif
                }
                break;
-       case 0xbe:
+       case 0x00be:
+#if !defined(SUPPORT_HIRESO)
                if(!(modereg & 2) && (data & 2)) {
                        d_fdc->set_drive_type(0, DRIVE_TYPE_2HD);
                        d_fdc->set_drive_type(1, DRIVE_TYPE_2HD);
@@ -122,6 +158,7 @@ void FLOPPY::write_io8(uint32_t addr, uint32_t data)
                        d_fdc->set_drive_type(0, DRIVE_TYPE_2DD);
                        d_fdc->set_drive_type(1, DRIVE_TYPE_2DD);
                }
+#endif
                modereg = data;
                break;
 #endif
@@ -130,51 +167,91 @@ void FLOPPY::write_io8(uint32_t addr, uint32_t data)
 
 uint32_t FLOPPY::read_io8(uint32_t addr)
 {
-       switch(addr & 0xffff) {
+       uint32_t value = 0;
+       
+       switch(addr) {
 #if defined(SUPPORT_2HD_FDD_IF)
-       case 0x90:
+       case 0x0090:
                return d_fdc_2hd->read_io8(0);
-       case 0x92:
+       case 0x0092:
                return d_fdc_2hd->read_io8(1);
-#if !defined(_PC9801)
-       case 0x94:
-               return 0x5f;    // 0x40 ???
-#endif
+       case 0x0094:
+       case 0x0096:
+//             value |= 0x80; // FINT1 (DIP SW 1-7), 1 = OFF, 0 = ON
+               value |= 0x40; // FINT0 (DIP SW 1-6), 1 = OFF, 0 = ON
+//             value |= 0x20; // DMACH (DIP SW 1-3), 1 = OFF, 0 = ON
+               return value;
 #endif
 #if defined(SUPPORT_2DD_FDD_IF)
-       case 0xc8:
+       case 0x00c8:
                return d_fdc_2dd->read_io8(0);
-       case 0xca:
+       case 0x00ca:
                return d_fdc_2dd->read_io8(1);
-       case 0xcc:
-               return (d_fdc_2dd->is_disk_inserted() ? 0x10 : 0) | 0x6f;       // 0x60 ???
+       case 0x00cc:
+       case 0x00ce:
+//             value |= 0x80; // FINT1 (DIP SW 1-7), 1 = OFF, 0 = ON
+               value |= 0x40; // FINT0 (DIP SW 1-6), 1 = OFF, 0 = ON
+               value |= 0x20; // DMACH (DIP SW 1-3), 1 = OFF, 0 = ON
+               if(d_fdc_2dd->is_disk_inserted()) {
+                       value |= 0x10; // RDY
+               }
+               return value;
 #endif
 #if defined(SUPPORT_2HD_2DD_FDD_IF)
-       case 0x90:
-       case 0xc8:
-               if(((addr >> 4) & 1) == (modereg & 1)) {
+       case 0x0090:
+#if !defined(SUPPORT_HIRESO)
+       case 0x00c8:
+               if(((addr >> 4) & 1) == (modereg & 1))
+#endif
+               {
                        return d_fdc->read_io8(0);
                }
                break;
-       case 0x92:
-       case 0xca:
-               if(((addr >> 4) & 1) == (modereg & 1)) {
+       case 0x0092:
+#if !defined(SUPPORT_HIRESO)
+       case 0x00ca:
+               if(((addr >> 4) & 1) == (modereg & 1))
+#endif
+               {
                        return d_fdc->read_io8(1);
                }
                break;
-       case 0x94:
+       case 0x0094:
+       case 0x0096:
+#if !defined(SUPPORT_HIRESO)
                if(modereg & 1) {
-                       return 0x44;
+//                     value |= 0x80; // FINT1 (DIP SW 1-7), 1 = OFF, 0 = ON
+                       value |= 0x40; // FINT0 (DIP SW 1-6), 1 = OFF, 0 = ON
+//                     value |= 0x20; // DMACH (DIP SW 1-3), 1 = OFF, 0 = ON
+//                     value |= 0x08; // TYP1,0 (DIP SW 1-4), 1,0 = ON  Internal FDD: #3,#4, External FDD: #1,#2
+                       value |= 0x04; // TYP1,0 (DIP SW 1-4), 0,1 = OFF Internal FDD: #1,#2, External FDD: #3,#4
+                       return value;
                }
+#else
+//             value |= 0x80; // MODE, 0 = Internal FDD existing
+               value |= ctrlreg & 0x20; // High Density, 1 = 640KB, 0 = 1MB
+               return value;
+#endif
                break;
-       case 0xbe:
+#if !defined(SUPPORT_HIRESO)
+       case 0x00be:
                return 0xf8 | (modereg & 3);
-       case 0xcc:
+       case 0x00cc:
+       case 0x00ce:
                if(!(modereg & 1)) {
-                       return (d_fdc->is_disk_inserted() ? 0x10 : 0) | 0x64;   // 0x60 ???
+//                     value |= 0x80; // FINT1 (DIP SW 1-7), 1 = OFF, 0 = ON
+                       value |= 0x40; // FINT0 (DIP SW 1-6), 1 = OFF, 0 = ON
+                       value |= 0x20; // DMACH (DIP SW 1-3), 1 = OFF, 0 = ON
+//                     value |= 0x08; // TYP1,0 (DIP SW 1-4), 1,0 = ON  Internal FDD: #3,#4, External FDD: #1,#2
+                       value |= 0x04; // TYP1,0 (DIP SW 1-4), 0,1 = OFF Internal FDD: #1,#2, External FDD: #3,#4
+                       if(d_fdc->is_disk_inserted()) {
+                               value |= 0x10; // RDY
+                       }
+                       return value;
                }
                break;
 #endif
+#endif
        }
        return 0xff;//addr & 0xff;
 }
@@ -200,18 +277,26 @@ void FLOPPY::write_signal(int id, uint32_t data, uint32_t mask)
 #endif
 #if defined(SUPPORT_2HD_2DD_FDD_IF)
        case SIG_FLOPPY_IRQ:
+#if !defined(SUPPORT_HIRESO)
                if(modereg & 1) {
                        d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR3, data, mask);
                } else {
                        d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR2, data, mask);
                }
+#else
+               d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR3, data, mask);
+#endif
                break;
        case SIG_FLOPPY_DRQ:
+#if !defined(SUPPORT_HIRESO)
                if(modereg & 1) {
                        d_dma->write_signal(SIG_I8237_CH2, data, mask);
                } else {
                        d_dma->write_signal(SIG_I8237_CH3, data, mask);
                }
+#else
+               d_dma->write_signal(SIG_I8237_CH1, data, mask);
+#endif
                break;
 #endif
        }
@@ -221,12 +306,12 @@ void FLOPPY::event_callback(int event_id, int err)
 {
 #if defined(SUPPORT_2DD_FDD_IF)
        if(ctrlreg_2dd & 4) {
-               d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR2, 1, 1);
+               write_signal(SIG_FLOPPY_2DD_IRQ, 1, 1);
        }
 #endif
 #if defined(SUPPORT_2HD_2DD_FDD_IF)
        if(ctrlreg & 4) {
-               d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR2, 1, 1);
+               write_signal(SIG_FLOPPY_IRQ, 1, 1);
        }
 #endif
        timer_id = -1;
@@ -234,43 +319,25 @@ void FLOPPY::event_callback(int event_id, int err)
 
 #define STATE_VERSION  1
 
-void FLOPPY::save_state(FILEIO* state_fio)
-{
-       state_fio->FputUint32(STATE_VERSION);
-       state_fio->FputInt32(this_device_id);
-       
-#if defined(SUPPORT_2HD_FDD_IF)
-       state_fio->FputUint8(ctrlreg_2hd);
-#endif
-#if defined(SUPPORT_2DD_FDD_IF)
-       state_fio->FputUint8(ctrlreg_2dd);
-#endif
-#if defined(SUPPORT_2HD_2DD_FDD_IF)
-       state_fio->FputUint8(ctrlreg);
-       state_fio->FputUint8(modereg);
-#endif
-       state_fio->FputInt32(timer_id);
-}
-
-bool FLOPPY::load_state(FILEIO* state_fio)
+bool FLOPPY::process_state(FILEIO* state_fio, bool loading)
 {
-       if(state_fio->FgetUint32() != STATE_VERSION) {
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
                return false;
        }
-       if(state_fio->FgetInt32() != this_device_id) {
+       if(!state_fio->StateCheckInt32(this_device_id)) {
                return false;
        }
 #if defined(SUPPORT_2HD_FDD_IF)
-       ctrlreg_2hd = state_fio->FgetUint8();
+       state_fio->StateUint8(ctrlreg_2hd);
 #endif
 #if defined(SUPPORT_2DD_FDD_IF)
-       ctrlreg_2dd = state_fio->FgetUint8();
+       state_fio->StateUint8(ctrlreg_2dd);
 #endif
 #if defined(SUPPORT_2HD_2DD_FDD_IF)
-       ctrlreg = state_fio->FgetUint8();
-       modereg = state_fio->FgetUint8();
+       state_fio->StateUint8(ctrlreg);
+       state_fio->StateUint8(modereg);
 #endif
-       timer_id = state_fio->FgetInt32();
+       state_fio->StateInt32(timer_id);
        return true;
 }