OSDN Git Service

54bd0d877185ee04b1318141da5086ebd0806e9f
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmr50 / scsi.cpp
1 /*
2         FUJITSU FMR-50 Emulator 'eFMR-50'
3         FUJITSU FMR-60 Emulator 'eFMR-60'
4
5         Author : Takeda.Toshiya
6         Date   : 2016.03.03-
7
8         [ scsi ]
9 */
10
11 #include "scsi.h"
12 #include "../i8259.h"
13 #include "../scsi_host.h"
14 #include "../upd71071.h"
15
16 // control register
17 #define CTRL_WEN        0x80
18 #define CTRL_IMSK       0x40
19 #define CTRL_ATN        0x10
20 #define CTRL_SEL        0x04
21 #define CTRL_DMAE       0x02
22 #define CTRL_RST        0x01
23
24 #define STATUS_REQ      0x80
25 #define STATUS_IO       0x40
26 #define STATUS_MSG      0x20
27 #define STATUS_CD       0x10
28 #define STATUS_BSY      0x08
29 #define STATUS_INT      0x02
30 #define STATUS_PERR     0x01
31
32 void SCSI::reset()
33 {
34         ctrl_reg = CTRL_IMSK;
35         irq_status = false;
36 }
37
38 void SCSI::write_io8(uint32_t addr, uint32_t data)
39 {
40         switch(addr & 0xffff) {
41         case 0xc30:
42                 // data register
43                 #ifdef _SCSI_DEBUG_LOG
44                         this->out_debug_log(_T("[SCSI] out %04X %02X\n"), addr, data);
45                 #endif
46                 if(ctrl_reg & CTRL_WEN) {
47                         d_host->write_dma_io8(addr, data);
48                 }
49                 break;
50                 
51         case 0xc32:
52                 // control register
53                 #ifdef _SCSI_DEBUG_LOG
54                         this->out_debug_log(_T("[SCSI] out %04X %02X\n"), addr, data);
55                 #endif
56                 ctrl_reg = data;
57                 if(ctrl_reg  & CTRL_WEN) {
58                         d_host->write_signal(SIG_SCSI_RST, data, CTRL_RST);
59                         d_host->write_signal(SIG_SCSI_SEL, data, CTRL_SEL);
60                         d_host->write_signal(SIG_SCSI_ATN, data, CTRL_ATN);
61                 }
62                 break;
63         }
64 }
65
66 uint32_t SCSI::read_io8(uint32_t addr)
67 {
68         uint32_t value = 0;
69         
70         switch(addr & 0xffff) {
71         case 0xc30:
72                 // data register
73                 if(ctrl_reg & CTRL_WEN) {
74                         value = d_host->read_dma_io8(addr);
75                 }
76                 #ifdef _SCSI_DEBUG_LOG
77                         this->out_debug_log(_T("[SCSI] in  %04X %02X\n"), addr, value);
78                 #endif
79                 return value;
80                 
81         case 0xc32:
82                 // status register
83                 value = (d_host->read_signal(SIG_SCSI_REQ) ? STATUS_REQ : 0) |
84                         (d_host->read_signal(SIG_SCSI_IO ) ? STATUS_IO  : 0) |
85                         (d_host->read_signal(SIG_SCSI_MSG) ? STATUS_MSG : 0) |
86                         (d_host->read_signal(SIG_SCSI_CD ) ? STATUS_CD  : 0) |
87                         (d_host->read_signal(SIG_SCSI_BSY) ? STATUS_BSY : 0) |
88                         (irq_status                        ? STATUS_INT : 0);
89                 #ifdef _SCSI_DEBUG_LOG
90                         this->out_debug_log(_T("[SCSI] in  %04X %02X\n"), addr, value);
91                 #endif
92                 return value;
93         }
94         return 0xff;
95 }
96
97 void SCSI::write_signal(int id, uint32_t data, uint32_t mask)
98 {
99         switch(id) {
100         case SIG_SCSI_IRQ:
101                 if(ctrl_reg & CTRL_IMSK) {
102                         d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR0, data, mask);
103                 }
104                 irq_status = ((data & mask) != 0);
105                 break;
106                 
107         case SIG_SCSI_DRQ:
108                 if(ctrl_reg & CTRL_DMAE) {
109                         d_dma->write_signal(SIG_UPD71071_CH1, data, mask);
110                 }
111                 break;
112         }
113 }
114
115 #define STATE_VERSION   1
116
117 bool SCSI::process_state(FILEIO* state_fio, bool loading)
118 {
119         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
120                 return false;
121         }
122         if(!state_fio->StateCheckInt32(this_device_id)) {
123                 return false;
124         }
125         state_fio->StateUint8(ctrl_reg);
126         state_fio->StateBool(irq_status);
127         return true;
128 }