OSDN Git Service

[VM] .
[csp-qt/common_source_project-fm7.git] / source / src / vm / upd71071.cpp
index dd94e7a..387d8cb 100644 (file)
@@ -9,25 +9,36 @@
 
 #include "upd71071.h"
 
+void UPD71071::initialize()
+{
+       DEVICE::initialize();
+       _SINGLE_MODE_DMA = osd->check_feature(_T("SINGLE_MODE_DMA"));
+       
+       for(int i = 0; i < 4; i++) {
+               dma[i].areg = dma[i].bareg = 0;
+               dma[i].creg = dma[i].bcreg = 0;
+       }
+}
+
 void UPD71071::reset()
 {
        for(int i = 0; i < 4; i++) {
-               dma[i].mode = 0;
+               dma[i].mode = 0x04;
        }
        b16 = selch = base = 0;
        cmd = tmp = 0;
        req = sreq = tc = 0;
-       mask = 0xff;
+       mask = 0x0f;
 }
 
-void UPD71071::write_io8(uint32 addr, uint32 data)
+void UPD71071::write_io8(uint32_t addr, uint32_t data)
 {
        switch(addr & 0x0f) {
        case 0x00:
                if(data & 1) {
                        // dma reset
                        for(int i = 0; i < 4; i++) {
-                               dma[i].mode = 0;
+                               dma[i].mode = 0x04;
                        }
                        selch = base = 0;
                        cmd = tmp = 0;
@@ -47,9 +58,9 @@ void UPD71071::write_io8(uint32 addr, uint32 data)
 //             }
                break;
        case 0x03:
-               dma[selch].bcreg = (dma[selch].bcreg & 0xff) | (data << 8);
+               dma[selch].bcreg = (dma[selch].bcreg & 0x00ff) | (data << 8);
 //             if(!base) {
-                       dma[selch].creg = (dma[selch].creg & 0xff) | (data << 8);
+                       dma[selch].creg = (dma[selch].creg & 0x00ff) | (data << 8);
 //             }
                break;
        case 0x04:
@@ -65,9 +76,9 @@ void UPD71071::write_io8(uint32 addr, uint32 data)
 //             }
                break;
        case 0x06:
-               dma[selch].bareg = (dma[selch].bareg & 0xffff) | (data << 16);
+               dma[selch].bareg = (dma[selch].bareg & 0x00ffff) | (data << 16);
 //             if(!base) {
-                       dma[selch].areg = (dma[selch].areg & 0xffff) | (data << 16);
+                       dma[selch].areg = (dma[selch].areg & 0x00ffff) | (data << 16);
 //             }
                break;
        case 0x08:
@@ -80,10 +91,10 @@ void UPD71071::write_io8(uint32 addr, uint32 data)
                dma[selch].mode = data;
                break;
        case 0x0e:
-               if((sreq = data) != 0) {
-#ifndef SINGLE_MODE_DMA
+               if(((sreq = data) != 0) && !(_SINGLE_MODE_DMA)) {
+//#ifndef SINGLE_MODE_DMA
                        do_dma();
-#endif
+//#endif
                }
                break;
        case 0x0f:
@@ -92,9 +103,9 @@ void UPD71071::write_io8(uint32 addr, uint32 data)
        }
 }
 
-uint32 UPD71071::read_io8(uint32 addr)
+uint32_t UPD71071::read_io8(uint32_t addr)
 {
-       uint32 val;
+       uint32_t val;
        
        switch(addr & 0x0f) {
        case 0x00:
@@ -153,16 +164,16 @@ uint32 UPD71071::read_io8(uint32 addr)
        return 0xff;
 }
 
-void UPD71071::write_signal(int id, uint32 data, uint32 mask)
+void UPD71071::write_signal(int id, uint32_t data, uint32_t mask)
 {
-       uint8 bit = 1 << (id & 3);
+       uint8_t bit = 1 << (id & 3);
        
        if(data & mask) {
                if(!(req & bit)) {
                        req |= bit;
-#ifndef SINGLE_MODE_DMA
-                       do_dma();
-#endif
+//#ifndef SINGLE_MODE_DMA
+                       if(!_SINGLE_MODE_DMA) do_dma();
+//#endif
                }
        } else {
                req &= ~bit;
@@ -180,27 +191,70 @@ void UPD71071::do_dma()
        
        // run dma
        for(int c = 0; c < 4; c++) {
-               uint8 bit = 1 << c;
+               uint8_t bit = 1 << c;
                if(((req | sreq) & bit) && !(mask & bit)) {
                        // execute dma
                        while((req | sreq) & bit) {
-                               if((dma[c].mode & 0x0c) == 4) {
-                                       // io -> memory
-                                       uint32 val = dma[c].dev->read_dma_io8(0);
-                                       d_mem->write_dma_data8(dma[c].areg, val);
-                                       // update temporary register
-                                       tmp = (tmp >> 8) | (val << 8);
-                               } else if((dma[c].mode & 0x0c) == 8) {
-                                       // memory -> io
-                                       uint32 val = d_mem->read_dma_data8(dma[c].areg);
-                                       dma[c].dev->write_dma_io8(0, val);
-                                       // update temporary register
-                                       tmp = (tmp >> 8) | (val << 8);
-                               }
-                               if(dma[c].mode & 0x20) {
-                                       dma[c].areg = (dma[c].areg - 1) & 0xffffff;
-                               } else {
-                                       dma[c].areg = (dma[c].areg + 1) & 0xffffff;
+                               // ToDo: Will check WORD transfer mode for FM-Towns.(mode.bit0 = '1).
+/*
+                               if((dma[c].mode & 0x01) == 1) {
+                                       // 16bit transfer mode
+                                       if((dma[c].mode & 0x0c) == 0x00) {
+                                               // verify
+                                               uint32_t val = dma[c].dev->read_dma_io16(0);
+                                               // update temporary register
+                                               tmp = val;
+                                       } else if((dma[c].mode & 0x0c) == 0x04) {
+                                               // io -> memory
+                                               uint32_t val;
+                                               if(dma[c].dev != NULL) {
+                                                       val = dma[c].dev->read_dma_io16(0);
+                                               } else {
+                                                       val = 0xffff;
+                                               }
+                                               d_mem->write_dma_data16(dma[c].areg, val);
+                                               // update temporary register
+                                               tmp = val;
+                                       } else if((dma[c].mode & 0x0c) == 0x08) {
+                                               // memory -> io
+                                               uint32_t val = d_mem->read_dma_data16(dma[c].areg);
+                                               if(dma[c].dev != NULL) dma[c].dev->write_dma_io16(0, val);
+                                               // update temporary register
+                                               tmp = val;
+                                       }
+                                       if(dma[c].mode & 0x20) {
+                                               dma[c].areg = (dma[c].areg - 2) & 0xffffff;
+                                       } else {
+                                               dma[c].areg = (dma[c].areg + 2) & 0xffffff;
+                                       }
+                               } else
+*/
+                               {
+                                       // 8bit transfer mode
+                                       if((dma[c].mode & 0x0c) == 0x00) {
+                                               // verify
+                                               uint32_t val = dma[c].dev->read_dma_io8(0);
+                                               // update temporary register
+                                               tmp = (tmp >> 8) | (val << 8);
+                                       } else if((dma[c].mode & 0x0c) == 0x04) {
+                                               // io -> memory
+                                               uint32_t val;
+                                               val = dma[c].dev->read_dma_io8(0);
+                                               d_mem->write_dma_data8(dma[c].areg, val);
+                                               // update temporary register
+                                               tmp = (tmp >> 8) | (val << 8);
+                                       } else if((dma[c].mode & 0x0c) == 0x08) {
+                                               // memory -> io
+                                               uint32_t val = d_mem->read_dma_data8(dma[c].areg);
+                                               dma[c].dev->write_dma_io8(0, val);
+                                               // update temporary register
+                                               tmp = (tmp >> 8) | (val << 8);
+                                       }
+                                       if(dma[c].mode & 0x20) {
+                                               dma[c].areg = (dma[c].areg - 1) & 0xffffff;
+                                       } else {
+                                               dma[c].areg = (dma[c].areg + 1) & 0xffffff;
+                                       }
                                }
                                if(dma[c].creg-- == 0) {
                                        // TC
@@ -216,71 +270,52 @@ void UPD71071::do_dma()
                                        tc |= bit;
                                        
                                        write_signals(&outputs_tc, 0xffffffff);
-#ifdef SINGLE_MODE_DMA
-                               } else if((dma[c].mode & 0xc0) == 0x40) {
-                                       // single mode
-                                       break;
-#endif
+//#ifdef SINGLE_MODE_DMA
+                               } else if(_SINGLE_MODE_DMA) {
+                                       if((dma[c].mode & 0xc0) == 0x40) {
+                                               // single mode
+                                               break;
+                                       }
+//#endif
                                }
                        }
                }
        }
-#ifdef SINGLE_MODE_DMA
-       if(d_dma) {
-               d_dma->do_dma();
+//#ifdef SINGLE_MODE_DMA
+       if(_SINGLE_MODE_DMA) {
+               if(d_dma) {
+                       d_dma->do_dma();
+               }
        }
-#endif
+//#endif
 }
 
 #define STATE_VERSION  1
 
-void UPD71071::save_state(FILEIO* state_fio)
+bool UPD71071::process_state(FILEIO* state_fio, bool loading)
 {
-       state_fio->FputUint32(STATE_VERSION);
-       state_fio->FputInt32(this_device_id);
-       
-       for(int i = 0; i < 4; i++) {
-               state_fio->FputUint32(dma[i].areg);
-               state_fio->FputUint32(dma[i].bareg);
-               state_fio->FputUint16(dma[i].creg);
-               state_fio->FputUint16(dma[i].bcreg);
-               state_fio->FputUint8(dma[i].mode);
-       }
-       state_fio->FputUint8(b16);
-       state_fio->FputUint8(selch);
-       state_fio->FputUint8(base);
-       state_fio->FputUint16(cmd);
-       state_fio->FputUint16(tmp);
-       state_fio->FputUint8(req);
-       state_fio->FputUint8(sreq);
-       state_fio->FputUint8(mask);
-       state_fio->FputUint8(tc);
-}
-
-bool UPD71071::load_state(FILEIO* state_fio)
-{
-       if(state_fio->FgetUint32() != STATE_VERSION) {
-               return false;
-       }
-       if(state_fio->FgetInt32() != this_device_id) {
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       if(!state_fio->StateCheckInt32(this_device_id)) {
                return false;
        }
        for(int i = 0; i < 4; i++) {
-               dma[i].areg = state_fio->FgetUint32();
-               dma[i].bareg = state_fio->FgetUint32();
-               dma[i].creg = state_fio->FgetUint16();
-               dma[i].bcreg = state_fio->FgetUint16();
-               dma[i].mode = state_fio->FgetUint8();
+               state_fio->StateUint32(dma[i].areg);
+               state_fio->StateUint32(dma[i].bareg);
+               state_fio->StateUint16(dma[i].creg);
+               state_fio->StateUint16(dma[i].bcreg);
+               state_fio->StateUint8(dma[i].mode);
        }
-       b16 = state_fio->FgetUint8();
-       selch = state_fio->FgetUint8();
-       base = state_fio->FgetUint8();
-       cmd = state_fio->FgetUint16();
-       tmp = state_fio->FgetUint16();
-       req = state_fio->FgetUint8();
-       sreq = state_fio->FgetUint8();
-       mask = state_fio->FgetUint8();
-       tc = state_fio->FgetUint8();
+       state_fio->StateUint8(b16);
+       state_fio->StateUint8(selch);
+       state_fio->StateUint8(base);
+       state_fio->StateUint16(cmd);
+       state_fio->StateUint16(tmp);
+       state_fio->StateUint8(req);
+       state_fio->StateUint8(sreq);
+       state_fio->StateUint8(mask);
+       state_fio->StateUint8(tc);
        return true;
 }