OSDN Git Service

[VM][STATE] Use namespace {VMNAME} to separate per VMs.
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc9801 / sasi.cpp
index 341f6b6..f4a2856 100644 (file)
@@ -1,6 +1,7 @@
 /*
        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'
 
 */
 
 #include "sasi.h"
+#include "../harddisk.h"
+#include "../i8237.h"
+#include "../i8259.h"
+#include "../scsi_host.h"
+#include "../scsi_hdd.h"
 
 #define OCR_CHEN       0x80
 #define OCR_NRDSW      0x40
 #define ISR_IXO                0x04
 #define ISR_INT                0x01
 
-void SASI::initialize()
-{
-       
-}
+namespace PC9801 {
 
 void SASI::reset()
 {
-       
+       ocr = 0;
+       irq_status = drq_status = false;
 }
 
 void SASI::write_io8(uint32_t addr, uint32_t data)
 {
        switch(addr) {
        case 0x0080:
+               #ifdef _SCSI_DEBUG_LOG
+                       this->out_debug_log(_T("[SASI] out %04X %02X\n"), addr, data);
+               #endif
+//             if(ocr & OCR_CHEN) {
+                       d_host->write_dma_io8(addr, data);
+//             }
                break;
+               
        case 0x0082:
+               #ifdef _SCSI_DEBUG_LOG
+                       this->out_debug_log(_T("[SASI] out %04X %02X\n"), addr, data);
+               #endif
+               d_host->write_signal(SIG_SCSI_RST, data, OCR_RST);
+               d_host->write_signal(SIG_SCSI_SEL, data, OCR_SEL);
                ocr = data;
                break;
        }
@@ -50,20 +66,81 @@ void SASI::write_io8(uint32_t addr, uint32_t data)
 
 uint32_t SASI::read_io8(uint32_t addr)
 {
+       uint32_t value = 0;
+       
        switch(addr) {
        case 0x0080:
-               break;
+//             if(ocr & OCR_CHEN) {
+                       value = d_host->read_dma_io8(addr);
+//             }
+               #ifdef _SCSI_DEBUG_LOG
+                       this->out_debug_log(_T("[SASI] in  %04X %02X\n"), addr, value);
+               #endif
+               return value;
+               
        case 0x0082:
                if(ocr & OCR_NRDSW) {
-                       return isr;
+                       value = (d_host->read_signal(SIG_SCSI_REQ) ? ISR_REQ : 0) |
+//                             (d_host->read_signal(SIG_SCSI_ACK) ? ISR_ACK : 0) |
+                               (d_host->read_signal(SIG_SCSI_BSY) ? ISR_BSY : 0) |
+                               (d_host->read_signal(SIG_SCSI_MSG) ? ISR_MSG : 0) |
+                               (d_host->read_signal(SIG_SCSI_CD ) ? ISR_CXD : 0) |
+                               (d_host->read_signal(SIG_SCSI_IO ) ? ISR_IXO : 0) |
+                               (irq_status                        ? ISR_INT : 0);
+//                     irq_status = false;
+                       #ifdef _SCSI_DEBUG_LOG
+                               this->out_debug_log(_T("[SASI] in  %04X %02X (REQ=%d,BSY=%d,MSG=%d,CxD=%d,IxO=%d,DH=%02X,DL=%02X)\n"), addr, value,
+                                       (value & ISR_REQ) ? 1 : 0,
+                                       (value & ISR_BSY) ? 1 : 0,
+                                       (value & ISR_MSG) ? 1 : 0,
+                                       (value & ISR_CXD) ? 1 : 0,
+                                       (value & ISR_IXO) ? 1 : 0,
+                                       vm->get_cpu(0)->read_debug_reg(_T("DH")), vm->get_cpu(0)->read_debug_reg(_T("DL")));
+                       #endif
                } else {
-                       
+                       value = 0;
+                       for(int i = 0; i < 2; i++) {
+                               HARDDISK *unit = d_hdd->get_disk_handler(i);
+                               uint32_t dt = 7, ct = 0;
+                               
+                               if(unit != NULL && unit->mounted()) {
+                                       double size = unit->sector_num * unit->sector_size;
+                                       int size_mb = (int)(size / 1024.0 / 1024.0 + 0.5);
+                                       
+                                       if(size_mb <= 6) {
+                                               dt = 0;
+                                       } else if(size_mb <= 11) {
+                                               dt = 1;
+                                       } else if(size_mb <= 16) {
+                                               dt = 2;
+                                       } else if(size_mb <= 21) {
+                                               if(unit->surfaces != 4) {
+                                                       dt = 3;
+                                               } else {
+                                                       dt = 4;
+                                               }
+                                       } else if(size_mb <= 31) {
+                                               dt = 5;
+                                       } else {
+                                               dt = 6;
+                                       }
+                                       if(unit->sector_size == 512) {
+                                               ct = 1;
+                                       }
+                               }
+                               value |= dt << (i == 0 ? 3 : 0);
+                               value |= ct << (i == 0 ? 7 : 6);
+                       }
+                       #ifdef _SCSI_DEBUG_LOG
+                               this->out_debug_log(_T("[SASI] in  %04X %02X (NRDSW=0)\n"), addr, value);
+                       #endif
                }
-               break;
+               return value;
        }
        return 0xff;
 }
 
+/*
 void SASI::write_dma_io8(uint32_t addr, uint32_t data)
 {
        write_io8(0x0080, data);
@@ -73,23 +150,68 @@ uint32_t SASI::read_dma_io8(uint32_t addr)
 {
        return read_io8(0x0080);
 }
+*/
 
-#define STATE_VERSION  1
-
-void SASI::save_state(FILEIO* state_fio)
+void SASI::write_signal(int id, uint32_t data, uint32_t mask)
 {
-       state_fio->FputUint32(STATE_VERSION);
-       state_fio->FputInt32(this_device_id);
+       switch(id) {
+       case SIG_SASI_IRQ:
+               #ifdef _SCSI_DEBUG_LOG
+                       this->out_debug_log(_T("[SASI] IRQ=%d\n"), (data & mask) ? 1 : 0);
+               #endif
+               if(ocr & OCR_INTE) {
+                       d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR1, data, mask);
+               }
+               irq_status = ((data & mask) != 0);
+               break;
+               
+       case SIG_SASI_DRQ:
+               #ifdef _SCSI_DEBUG_LOG
+                       this->out_debug_log(_T("[SASI] DRQ=%d\n"), (data & mask) ? 1 : 0);
+               #endif
+               if(ocr & OCR_DMAE) {
+                       #ifdef _PC98XA
+                               d_dma->write_signal(SIG_I8237_CH3, data, mask);
+                       #else
+                               d_dma->write_signal(SIG_I8237_CH0, data, mask);
+                       #endif
+               } else {
+                       if(data & mask) {
+                               #ifdef _SCSI_DEBUG_LOG
+                                       this->out_debug_log(_T("[SASI] DMAE=0, change IRQ\n"));
+                               #endif
+                               write_signal(SIG_SASI_IRQ, data, mask);
+                       }
+               }
+               drq_status = ((data & mask) != 0);
+               break;
+               
+       case SIG_SASI_TC:
+               #ifdef _SCSI_DEBUG_LOG
+                       this->out_debug_log(_T("[SASI] TC=%d\n"), (data & mask) ? 1 : 0);
+               #endif
+               if(data & mask) {
+                       ocr &= ~OCR_DMAE;
+               }
+               break;
+       }
 }
 
-bool SASI::load_state(FILEIO* state_fio)
+#define STATE_VERSION  2
+
+bool SASI::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;
        }
+       state_fio->StateUint8(ocr);
+       state_fio->StateBool(irq_status);
+       state_fio->StateBool(drq_status);
        return true;
 }
 
+}
+