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
1 /*
2         NEC PC-9801VX Emulator 'ePC-9801VX'
3         NEC PC-9801RA Emulator 'ePC-9801RA'
4         NEC PC-98XA Emulator 'ePC-98XA'
5         NEC PC-98XL Emulator 'ePC-98XL'
6         NEC PC-98RL Emulator 'ePC-98RL'
7
8         Author : Takeda.Toshiya
9         Date   : 2018.04.01-
10
11         [ sasi i/f ]
12 */
13
14 #include "sasi.h"
15 #include "../harddisk.h"
16 #include "../i8237.h"
17 #include "../i8259.h"
18 #include "../scsi_host.h"
19 #include "../scsi_hdd.h"
20
21 #define OCR_CHEN        0x80
22 #define OCR_NRDSW       0x40
23 #define OCR_SEL         0x20
24 #define OCR_RST         0x08
25 #define OCR_DMAE        0x02
26 #define OCR_INTE        0x01
27
28 #define ISR_REQ         0x80
29 #define ISR_ACK         0x40
30 #define ISR_BSY         0x20
31 #define ISR_MSG         0x10
32 #define ISR_CXD         0x08
33 #define ISR_IXO         0x04
34 #define ISR_INT         0x01
35
36 namespace PC9801 {
37
38 void SASI::reset()
39 {
40         ocr = 0;
41         irq_status = drq_status = false;
42 }
43
44 void SASI::write_io8(uint32_t addr, uint32_t data)
45 {
46         switch(addr) {
47         case 0x0080:
48                 #ifdef _SCSI_DEBUG_LOG
49                         this->out_debug_log(_T("[SASI] out %04X %02X\n"), addr, data);
50                 #endif
51 //              if(ocr & OCR_CHEN) {
52                         d_host->write_dma_io8(addr, data);
53 //              }
54                 break;
55                 
56         case 0x0082:
57                 #ifdef _SCSI_DEBUG_LOG
58                         this->out_debug_log(_T("[SASI] out %04X %02X\n"), addr, data);
59                 #endif
60                 d_host->write_signal(SIG_SCSI_RST, data, OCR_RST);
61                 d_host->write_signal(SIG_SCSI_SEL, data, OCR_SEL);
62                 ocr = data;
63                 break;
64         }
65 }
66
67 uint32_t SASI::read_io8(uint32_t addr)
68 {
69         uint32_t value = 0;
70         
71         switch(addr) {
72         case 0x0080:
73 //              if(ocr & OCR_CHEN) {
74                         value = d_host->read_dma_io8(addr);
75 //              }
76                 #ifdef _SCSI_DEBUG_LOG
77                         this->out_debug_log(_T("[SASI] in  %04X %02X\n"), addr, value);
78                 #endif
79                 return value;
80                 
81         case 0x0082:
82                 if(ocr & OCR_NRDSW) {
83                         value = (d_host->read_signal(SIG_SCSI_REQ) ? ISR_REQ : 0) |
84 //                              (d_host->read_signal(SIG_SCSI_ACK) ? ISR_ACK : 0) |
85                                 (d_host->read_signal(SIG_SCSI_BSY) ? ISR_BSY : 0) |
86                                 (d_host->read_signal(SIG_SCSI_MSG) ? ISR_MSG : 0) |
87                                 (d_host->read_signal(SIG_SCSI_CD ) ? ISR_CXD : 0) |
88                                 (d_host->read_signal(SIG_SCSI_IO ) ? ISR_IXO : 0) |
89                                 (irq_status                        ? ISR_INT : 0);
90 //                      irq_status = false;
91                         #ifdef _SCSI_DEBUG_LOG
92                                 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,
93                                         (value & ISR_REQ) ? 1 : 0,
94                                         (value & ISR_BSY) ? 1 : 0,
95                                         (value & ISR_MSG) ? 1 : 0,
96                                         (value & ISR_CXD) ? 1 : 0,
97                                         (value & ISR_IXO) ? 1 : 0,
98                                         vm->get_cpu(0)->read_debug_reg(_T("DH")), vm->get_cpu(0)->read_debug_reg(_T("DL")));
99                         #endif
100                 } else {
101                         value = 0;
102                         for(int i = 0; i < 2; i++) {
103                                 HARDDISK *unit = d_hdd->get_disk_handler(i);
104                                 uint32_t dt = 7, ct = 0;
105                                 
106                                 if(unit != NULL && unit->mounted()) {
107                                         double size = unit->sector_num * unit->sector_size;
108                                         int size_mb = (int)(size / 1024.0 / 1024.0 + 0.5);
109                                         
110                                         if(size_mb <= 6) {
111                                                 dt = 0;
112                                         } else if(size_mb <= 11) {
113                                                 dt = 1;
114                                         } else if(size_mb <= 16) {
115                                                 dt = 2;
116                                         } else if(size_mb <= 21) {
117                                                 if(unit->surfaces != 4) {
118                                                         dt = 3;
119                                                 } else {
120                                                         dt = 4;
121                                                 }
122                                         } else if(size_mb <= 31) {
123                                                 dt = 5;
124                                         } else {
125                                                 dt = 6;
126                                         }
127                                         if(unit->sector_size == 512) {
128                                                 ct = 1;
129                                         }
130                                 }
131                                 value |= dt << (i == 0 ? 3 : 0);
132                                 value |= ct << (i == 0 ? 7 : 6);
133                         }
134                         #ifdef _SCSI_DEBUG_LOG
135                                 this->out_debug_log(_T("[SASI] in  %04X %02X (NRDSW=0)\n"), addr, value);
136                         #endif
137                 }
138                 return value;
139         }
140         return 0xff;
141 }
142
143 /*
144 void SASI::write_dma_io8(uint32_t addr, uint32_t data)
145 {
146         write_io8(0x0080, data);
147 }
148
149 uint32_t SASI::read_dma_io8(uint32_t addr)
150 {
151         return read_io8(0x0080);
152 }
153 */
154
155 void SASI::write_signal(int id, uint32_t data, uint32_t mask)
156 {
157         switch(id) {
158         case SIG_SASI_IRQ:
159                 #ifdef _SCSI_DEBUG_LOG
160                         this->out_debug_log(_T("[SASI] IRQ=%d\n"), (data & mask) ? 1 : 0);
161                 #endif
162                 if(ocr & OCR_INTE) {
163                         d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR1, data, mask);
164                 }
165                 irq_status = ((data & mask) != 0);
166                 break;
167                 
168         case SIG_SASI_DRQ:
169                 #ifdef _SCSI_DEBUG_LOG
170                         this->out_debug_log(_T("[SASI] DRQ=%d\n"), (data & mask) ? 1 : 0);
171                 #endif
172                 if(ocr & OCR_DMAE) {
173                         #ifdef _PC98XA
174                                 d_dma->write_signal(SIG_I8237_CH3, data, mask);
175                         #else
176                                 d_dma->write_signal(SIG_I8237_CH0, data, mask);
177                         #endif
178                 } else {
179                         if(data & mask) {
180                                 #ifdef _SCSI_DEBUG_LOG
181                                         this->out_debug_log(_T("[SASI] DMAE=0, change IRQ\n"));
182                                 #endif
183                                 write_signal(SIG_SASI_IRQ, data, mask);
184                         }
185                 }
186                 drq_status = ((data & mask) != 0);
187                 break;
188                 
189         case SIG_SASI_TC:
190                 #ifdef _SCSI_DEBUG_LOG
191                         this->out_debug_log(_T("[SASI] TC=%d\n"), (data & mask) ? 1 : 0);
192                 #endif
193                 if(data & mask) {
194                         ocr &= ~OCR_DMAE;
195                 }
196                 break;
197         }
198 }
199
200 #define STATE_VERSION   2
201
202 bool SASI::process_state(FILEIO* state_fio, bool loading)
203 {
204         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
205                 return false;
206         }
207         if(!state_fio->StateCheckInt32(this_device_id)) {
208                 return false;
209         }
210         state_fio->StateUint8(ocr);
211         state_fio->StateBool(irq_status);
212         state_fio->StateBool(drq_status);
213         return true;
214 }
215
216 }
217