OSDN Git Service

[VM][General] Merge Upstream 20180530.
[csp-qt/common_source_project-fm7.git] / source / src / vm / mz2800 / sasi.cpp
1 /*
2         SHARP MZ-2800 Emulator 'EmuZ-2800'
3
4         Author : Takeda.Toshiya
5         Date   : 2018.05.25 -
6
7         [ SASI I/F ]
8 */
9
10 #include "sasi.h"
11 #include "../i8259.h"
12 #include "../upd71071.h"
13 #include "../scsi_host.h"
14
15 #define STATUS_INT      0x01
16 #define STATUS_IXO      0x04
17 #define STATUS_CXD      0x08
18 #define STATUS_MSG      0x10
19 #define STATUS_BSY      0x20
20 #define STATUS_ACK      0x40
21 #define STATUS_REQ      0x80
22
23 void SASI::reset()
24 {
25         control = 0x00;
26         irq_status = drq_status = false;
27 }
28
29 void SASI::write_io8(uint32_t addr, uint32_t data)
30 {
31         switch(addr & 0xff) {
32         case 0xa4:
33                 #ifdef _SCSI_DEBUG_LOG
34                         this->out_debug_log(_T("[SASI] out %04X %02X\n"), addr, data);
35                 #endif
36 //              if(!d_host->read_signal(SIG_SCSI_IO)) {
37                         d_host->write_dma_io8(addr, data);
38 //              }
39                 break;
40         case 0xa5:
41                 #ifdef _SCSI_DEBUG_LOG
42                         this->out_debug_log(_T("[SASI] out %04X %02X\n"), addr, data);
43                 #endif
44                 if((control & 0x20) != (data & 0x20)) {
45                         d_host->write_signal(SIG_SCSI_SEL, data, 0x20);
46                 }
47                 if((control & 0x08) != (data & 0x08)) {
48                         d_host->write_signal(SIG_SCSI_RST, data, 0x08);
49                 }
50                 control = data;
51                 break;
52         }
53 }
54
55 uint32_t SASI::read_io8(uint32_t addr)
56 {
57         uint32_t val = 0;
58         
59         switch(addr & 0xff) {
60         case 0xa4:
61 //              if(d_host->read_signal(SIG_SCSI_IO)) {
62                         val = d_host->read_dma_io8(addr);
63 //              }
64                 #ifdef _SCSI_DEBUG_LOG
65                         this->out_debug_log(_T("[SASI] in  %04X %02X\n"), addr, val);
66                 #endif
67                 return val;
68         case 0xa5:
69                 val = (d_host->read_signal(SIG_SCSI_REQ) ? STATUS_REQ : 0) |
70 //                    (d_host->read_signal(SIG_SCSI_ACK) ? STATUS_ACK : 0) |
71                       (d_host->read_signal(SIG_SCSI_BSY) ? STATUS_BSY : 0) |
72                       (d_host->read_signal(SIG_SCSI_MSG) ? STATUS_MSG : 0) |
73                       (d_host->read_signal(SIG_SCSI_CD ) ? STATUS_CXD : 0) |
74                       (d_host->read_signal(SIG_SCSI_IO ) ? STATUS_IXO : 0) |
75                       (irq_status                        ? STATUS_INT : 0);
76                 irq_status = false;
77                 #ifdef _SCSI_DEBUG_LOG
78                         this->out_debug_log(_T("[SASI] in  %04X %02X (REQ=%d,BSY=%d,MSG=%d,CxD=%d,IxO=%d)\n"), addr, val,
79                                 (val & STATUS_REQ) ? 1 : 0,
80                                 (val & STATUS_BSY) ? 1 : 0,
81                                 (val & STATUS_MSG) ? 1 : 0,
82                                 (val & STATUS_CXD) ? 1 : 0,
83                                 (val & STATUS_IXO) ? 1 : 0);
84                 #endif
85                 return val | 0x02;
86         }
87         return 0xff;
88 }
89
90 void SASI::write_dma_io8(uint32_t addr, uint32_t data)
91 {
92         write_io8(0xa4, data);
93 }
94
95 uint32_t SASI::read_dma_io8(uint32_t addr)
96 {
97         return read_io8(0xa4);
98 }
99
100 void SASI::write_signal(int id, uint32_t data, uint32_t mask)
101 {
102         switch(id) {
103         case SIG_SASI_IRQ:
104                 #ifdef _SCSI_DEBUG_LOG
105                         this->out_debug_log(_T("[SASI] IRQ=%d\n"), (data & mask) ? 1 : 0);
106                 #endif
107                 if(control & 0x01) {
108                         d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR4, data, mask);
109                 }
110                 irq_status = ((data & mask) != 0);
111                 break;
112         case SIG_SASI_DRQ:
113                 #ifdef _SCSI_DEBUG_LOG
114                         this->out_debug_log(_T("[SASI] DRQ=%d\n"), (data & mask) ? 1 : 0);
115                 #endif
116                 if(control & 0x02) {
117                         d_dma->write_signal(SIG_UPD71071_CH0, data, mask);
118                 }
119                 drq_status = ((data & mask) != 0);
120                 break;
121         }
122 }
123
124 #define STATE_VERSION   2
125
126 void SASI::save_state(FILEIO* state_fio)
127 {
128         state_fio->FputUint32(STATE_VERSION);
129         state_fio->FputInt32(this_device_id);
130         
131         state_fio->FputUint8(control);
132         state_fio->FputBool(irq_status);
133         state_fio->FputBool(drq_status);
134 }
135
136 bool SASI::load_state(FILEIO* state_fio)
137 {
138         if(state_fio->FgetUint32() != STATE_VERSION) {
139                 return false;
140         }
141         if(state_fio->FgetInt32() != this_device_id) {
142                 return false;
143         }
144         control = state_fio->FgetUint8();
145         irq_status = state_fio->FgetBool();
146         drq_status = state_fio->FgetBool();
147         return true;
148 }
149