OSDN Git Service

[VM][FMTOWNS][FLOPPY] Implement some bits and disk changed feature (0208h:bit0:R...
authorK.Ohta <whatisthis.sowhat@gmail.com>
Fri, 25 Sep 2020 10:29:55 +0000 (19:29 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Fri, 25 Sep 2020 10:29:55 +0000 (19:29 +0900)
source/src/vm/fmtowns/floppy.cpp
source/src/vm/fmtowns/floppy.h
source/src/vm/fmtowns/fmtowns.cpp

index 67263d3..b730804 100644 (file)
@@ -16,6 +16,9 @@ namespace FMTOWNS {
 void FLOPPY::initialize()
 {
        drive_swapped = false; // ToDo: implement via config;
+       for(int i = 0; i < 4; i++) {
+               is_inserted[i] = false;
+       }
 }
 
 void FLOPPY::reset()
@@ -23,6 +26,7 @@ void FLOPPY::reset()
        drvreg = 0;
        irq = irqmsk = false;
        drvsel = (drive_swapped) ? 2 : 0;
+
        for(int i = 0; i < MAX_DRIVE; i++) {
                d_fdc->set_drive_type(i, DRIVE_TYPE_2HD);
        }
@@ -37,9 +41,69 @@ void FLOPPY::write_io8(uint32_t addr, uint32_t data)
                // drive control register
                irqmsk = ((data & 1) != 0);
                update_intr();
-               d_fdc->write_signal(SIG_MB8877_MOTOR, data, 0x10);
+               if((drvsel < 2) || (machine_id < 0x0200)) {
+                       d_fdc->write_signal(SIG_MB8877_MOTOR, data, 0x10);
+               } else {
+                       // 5 Inch
+                       d_fdc->write_signal(SIG_MB8877_MOTOR, data, 0x40);
+               }
                d_fdc->write_signal(SIG_MB8877_SIDEREG, data, 4);
                 // ToDo: Single dencity.
+               {
+                       DISK *_disk = d_fdc->get_disk_handler(drvsel);
+                       uint8_t _media = d_fdc->get_media_type(drvsel);
+                       if((data & 0x02) != 0) { // DDEN=2D/2DD/2HD
+                               if(_disk != NULL) {
+                                       _disk->track_mfm = true;
+                               }
+                               if((data & 0x20) == 0) { // 2HD or 144
+                                       switch(_media) {
+                                       case MEDIA_TYPE_2HD:
+                                               d_fdc->set_drive_type(drvsel, DRIVE_TYPE_2HD);
+                                               break;
+                                       case MEDIA_TYPE_144: // ToDo: Write failure, Read success. 20200925 K.O
+                                               d_fdc->set_drive_type(drvsel, DRIVE_TYPE_144);
+                                               break;
+                                       default:
+                                               d_fdc->set_drive_type(drvsel, DRIVE_TYPE_UNK); // CLOCK IS WRONG.
+                                               break;
+                                       }
+                               } else {
+                                       switch(_media) {
+                                       case MEDIA_TYPE_2DD:
+                                               d_fdc->set_drive_type(drvsel, DRIVE_TYPE_2D);
+                                               break;
+                                       case MEDIA_TYPE_2D:
+                                               d_fdc->set_drive_type(drvsel, DRIVE_TYPE_2D);
+                                               break;
+                                       default:
+                                               d_fdc->set_drive_type(drvsel, DRIVE_TYPE_UNK); // CLOCK IS WRONG.
+                                               break;
+                                       }
+                               }
+                       } else { // 2DD or 2D or 1D
+                               if(_disk != NULL) {
+                                       _disk->track_mfm = false;
+                               }
+                               if((data & 0x20) == 0) { // 2HD or 144
+                                       d_fdc->set_drive_type(drvsel, DRIVE_TYPE_UNK); // CLOCK IS WRONG.
+                                       // And maybe single density of 2HD/144HD don't exist.
+                               } else {
+                                       // OK. Now use single density disk.
+                                       switch(_media) {
+                                       case MEDIA_TYPE_2DD:
+                                               d_fdc->set_drive_type(drvsel, DRIVE_TYPE_2D);
+                                               break;
+                                       case MEDIA_TYPE_2D:
+                                               d_fdc->set_drive_type(drvsel, DRIVE_TYPE_2D);
+                                               break;
+                                       default:
+                                               d_fdc->set_drive_type(drvsel, DRIVE_TYPE_UNK); // CLOCK IS WRONG.
+                                               break;
+                                       }
+                               }                                       
+                       }
+               }
                break;
        case 0x20c:
                // drive select register
@@ -72,9 +136,19 @@ uint32_t FLOPPY::read_io8(uint32_t addr)
        uint8_t val;
        switch(addr & 0xffff) {
        case 0x208:
-               val = 0x01;
+               if(machine_id >= 0x0200) {
+                       if(is_inserted[drvsel]) { // OK?
+                               val = 0x00;
+                       } else {
+                               val = 0x01;
+                       }
+               } else {
+                       val = 0x01;
+               }
+               is_inserted[drvsel] = false;
                if(d_fdc->is_disk_inserted(drvsel)) val |= 0x02;
                val |= 0x04; // ToDo 5.25 inch
+               val |= 0x80; // 2 Drives (maybe default, will change) 20200925 K.O
                return val;
        case 0x20c:
                return drvreg;
@@ -98,7 +172,7 @@ void FLOPPY::update_intr()
        write_signals(&output_intr_line, irq && irqmsk ? 1 : 0);
 }
 
-#define STATE_VERSION  1
+#define STATE_VERSION  2
 
 bool FLOPPY::process_state(FILEIO* state_fio, bool loading)
 {
@@ -114,6 +188,11 @@ bool FLOPPY::process_state(FILEIO* state_fio, bool loading)
        state_fio->StateValue(irq);
        state_fio->StateValue(irqmsk);
        state_fio->StateValue(drive_swapped);
+       
+       state_fio->StateValue(cpu_id);
+       state_fio->StateValue(machine_id);
+       state_fio->StateBuffer(is_inserted, sizeof(is_inserted), 1);
+       
        return true;
 }
 
index 75ac897..c56a5fa 100644 (file)
@@ -28,12 +28,19 @@ private:
        int drvreg, drvsel;
        bool irq, irqmsk;
        bool drive_swapped;
-       void update_intr();
+       uint16_t machine_id;
+       uint8_t cpu_id;
+       bool is_removed;
+       bool is_inserted[4];
        
+       void update_intr();
+
 public:
        FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu)
        {
                initialize_output_signals(&output_intr_line);
+               machine_id = 0x0100;
+               cpu_id = 0x01;
        }
        ~FLOPPY() {}
        
@@ -55,6 +62,18 @@ public:
        {
                register_output_signal(&output_intr_line, dev, id, mask);
        }
+       void set_machine_id(uint16_t val)
+       {
+               machine_id = val & 0xfff8;
+       }
+       void set_cpu_id(uint16_t val)
+       {
+               cpu_id = val & 0x07;
+       }
+       void change_disk(int drv)
+       {
+               is_inserted[drv] = true;
+       }
 };
 }
 
index 04fef32..b91adb4 100644 (file)
@@ -682,6 +682,10 @@ void VM::set_machine_type(uint16_t machine_id, uint16_t cpu_id)
                serialrom->set_cpu_id(cpu_id);
                serialrom->set_machine_id(machine_id);
        }
+       if(floppy != NULL) {
+               floppy->set_cpu_id(cpu_id);
+               floppy->set_machine_id(machine_id);
+       }
 #if defined(HAS_20PIX_FONTS)
        if(fontrom_20pix != NULL) {
                fontrom_20pix->set_cpu_id(cpu_id);
@@ -1084,8 +1088,11 @@ bool VM::is_cart_inserted(int drv)
 
 void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank)
 {
+       
        fdc->open_disk(drv, file_path, bank);
-//     floppy->change_disk(drv);
+       if(fdc->is_disk_inserted(drv)) {
+               floppy->change_disk(drv);
+       }
 }
 
 void VM::close_floppy_disk(int drv)