2 FUJITSU FMR-50 Emulator 'eFMR-50'
3 FUJITSU FMR-60 Emulator 'eFMR-60'
5 Author : Takeda.Toshiya
13 #include "../scsi_host.h"
16 #undef _SCSI_DEBUG_LOG
19 #define CTRL_IMSK 0x40
22 #define CTRL_DMAE 0x02
25 #define STATUS_REQ 0x80
26 #define STATUS_IO 0x40
27 #define STATUS_MSG 0x20
28 #define STATUS_CD 0x10
29 #define STATUS_BSY 0x08
30 #define STATUS_INT 0x02
31 #define STATUS_PERR 0x01
39 irq_status_bak = false;
41 ex_int_enable = false;
45 void SCSI::write_io8w(uint32_t addr, uint32_t data, int *wait)
47 // out_debug_log(_T("Write I/O %04X %02X"), addr, data);
48 *wait = 6; // temporally.
49 switch(addr & 0xffff) {
52 #ifdef _SCSI_DEBUG_LOG
53 this->out_debug_log(_T("[SCSI] out %04X %02X\n"), addr, data);
55 // d_host->write_signal(SIG_SCSI_REQ, 0, 0);
56 if(ctrl_reg & CTRL_WEN) {
57 // if((ctrl_reg & CTRL_WEN) && !(ctrl_reg & CTRL_DMAE)) {
58 d_host->write_dma_io8(addr, data);
64 #ifdef _SCSI_DEBUG_LOG
65 this->out_debug_log(_T("[SCSI] out %04X %02X\n"), addr, data);
67 if((machine_id >= 0x0300) & ((machine_id & 0xff00) != 0x0400)) { // After UX
68 ex_int_enable = ((data & 0x20) != 0) ? true : false;
69 // Set host to 16bit bus width. BIT3 ,= '1'.
71 if(ctrl_reg & CTRL_WEN) {
72 d_host->write_signal(SIG_SCSI_RST, data, CTRL_RST);
73 d_host->write_signal(SIG_SCSI_ATN, data, CTRL_ATN);
74 d_host->write_signal(SIG_SCSI_SEL, data, CTRL_SEL);
75 d_host->write_signal(SIG_SCSI_HOST_DMAE, data, CTRL_DMAE);
78 if((data & CTRL_DMAE) != 0) dma_enabled = true;
84 uint32_t SCSI::read_io8w(uint32_t addr, int* wait)
87 *wait = 6; // Temporally
88 switch(addr & 0xffff) {
90 // if(machine_id >= 0x0600) { // After UG
91 // value = 0x7f; // Ready to transfer 16bit width DMA, excepts CX/UX.
98 // d_host->write_signal(SIG_SCSI_REQ, 0, 0);
99 // if((ctrl_reg & CTRL_WEN) && !(ctrl_reg & CTRL_DMAE)) {
100 if(ctrl_reg & CTRL_WEN) {
101 value = d_host->read_dma_io8(addr);
103 #ifdef _SCSI_DEBUG_LOG
104 this->out_debug_log(_T("[SCSI] in %04X %02X\n"), addr, value);
110 value = (d_host->read_signal(SIG_SCSI_REQ) ? STATUS_REQ : 0) |
111 (d_host->read_signal(SIG_SCSI_IO ) ? STATUS_IO : 0) |
112 (d_host->read_signal(SIG_SCSI_MSG) ? STATUS_MSG : 0) |
113 (d_host->read_signal(SIG_SCSI_CD ) ? STATUS_CD : 0) |
114 (d_host->read_signal(SIG_SCSI_BSY) ? STATUS_BSY : 0) |
115 (irq_status ? STATUS_INT : 0);
116 if((machine_id >= 0x0300) & ((machine_id & 0xff00) != 0x0400)) { // After UX
117 value = value | 0x00;
119 value = value | 0x04; // Disable EX-Int.
121 #ifdef _SCSI_DEBUG_LOG
122 this->out_debug_log(_T("[SCSI] in %04X %02X\n"), addr, value);
124 // irq_status = false;
129 // Linux uses this port to detect the ability to do word transfers. We'll tell it that it doesn't for now.
133 // out_debug_log(_T("[SCSI] READ I/O %04X %02X\n"), addr, value);
137 void SCSI::write_io16w(uint32_t addr, uint32_t data, int *wait)
139 write_io8w(addr & 0xfffe, data, wait);
141 uint32_t SCSI::read_io16w(uint32_t addr, int *wait)
143 return read_io8w(addr & 0xfffe, wait);
146 void SCSI::write_signal(int id, uint32_t data, uint32_t mask)
149 case SIG_SCSI_16BIT_BUS:
150 //transfer_16bit = ((data & mask) != 0) ? true : false;
153 if((ctrl_reg & CTRL_IMSK)) {
154 // if(irq_status_bak != ((data & mask) != 0)) {
155 d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR0, data, mask);
156 //out_debug_log(_T("[SCSI] IRQ %04X %02X\n"), data, mask);
158 irq_status_bak = ((data & mask) != 0);
160 if((machine_id >= 0x0300) & ((machine_id & 0xff00) != 0x0400)) { // After UX
161 if(!(exirq_status)) {
162 irq_status = ((data & mask) != 0);
167 irq_status = ((data & mask) != 0);
172 if(((ctrl_reg & CTRL_DMAE) != 0) /*&& (dma_enabled)*/) {
173 d_dma->write_signal(SIG_UPD71071_CH1, data, mask);
175 /* if((machine_id >= 0x0300) & ((machine_id & 0xff00) != 0x0400)) { // After UX
177 d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR0, data, mask);
178 exirq_status = ((data & mask) != 0);
181 } else if(!(irq_status_bak)) {
188 dma_enabled = ((data & mask) == 0) ? true : false;
193 #define STATE_VERSION 4
195 bool SCSI::process_state(FILEIO* state_fio, bool loading)
197 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
200 if(!state_fio->StateCheckInt32(this_device_id)) {
203 state_fio->StateValue(machine_id);
204 state_fio->StateValue(cpu_id);
206 state_fio->StateValue(ctrl_reg);
207 state_fio->StateValue(irq_status);
208 state_fio->StateValue(irq_status_bak);
209 state_fio->StateValue(dma_enabled);
211 if((machine_id >= 0x0300) & ((machine_id & 0xff00) != 0x0400)) { // After UX
212 state_fio->StateValue(ex_int_enable);
213 state_fio->StateValue(exirq_status);