OSDN Git Service

[VM][FMTOWNS][JOYSTICK][MOUSE] Readerble port value from connected device.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmtowns / joystick.cpp
1 /*
2         FUJITSU FM Towns Emulator 'eFMTowns'
3
4         Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
5         Date   : 2020.01.28 -
6     History : 2020.01.28 Initial from FM7.
7         [ Towns Joystick ports]
8
9 */
10
11 #include "./joystick.h"
12 #include "./mouse.h"
13
14 namespace FMTOWNS {
15         
16 void JOYSTICK::reset()
17 {
18         mouse_mask = 0x00;
19         update_config(); // Update MOUSE PORT.
20         
21         for(int i = 0; i < 2; i++) {
22                 if(connected_type[i] == SIG_JOYPORT_TYPE_2BUTTONS) {
23                         write_signals(&outputs_query, 1 << i);
24                 } else if(connected_type[i] == SIG_JOYPORT_TYPE_MOUSE) {
25                         write_signals(&outputs_query, (1 << i) | 0x04);
26                 }
27
28         }
29 }
30
31 void JOYSTICK::initialize()
32 {
33         joydata[0] = joydata[1] = 0x00;
34
35         // Force reset pads.
36         connected_type[0] = 0xffffffff;
37         connected_type[1] = 0xffffffff;
38         stat_com[0] = stat_com[1] = false;
39
40 }
41
42 void JOYSTICK::release()
43 {
44 }
45         
46 void JOYSTICK::write_io8(uint32_t address, uint32_t data)
47 {
48         // ToDo: Mouse
49         if(address == 0x04d6) {
50                 if(mouse_mask != data) {
51                         mouse_mask = data;
52                         write_signals(&outputs_mask, data);
53                 }
54         }
55 }
56
57 uint32_t JOYSTICK::read_io8(uint32_t address)
58 {
59         // ToDo: Implement 6 buttons pad. & mouse
60         uint8_t retval = 0;
61         uint8_t port_num = (address & 0x02) >> 1;
62         switch(address) {
63         case 0x04d0:
64         case 0x04d2:
65                 {
66                         uint8_t trig = (mouse_mask >> (port_num << 1)) & 0x03;
67                         uint8_t mask2 = (mouse_mask >> (port_num + 4)) & 0x01;
68                         retval = 0x0f;
69                         if(connected_type[port_num] == SIG_JOYPORT_TYPE_2BUTTONS) {
70                                 write_signals(&outputs_query, 1 << port_num);
71                         } else if(connected_type[port_num] == SIG_JOYPORT_TYPE_MOUSE) {
72                                 if(emulate_mouse[port_num]) {
73                                         write_signals(&outputs_query, (1 << port_num) | 0x04);
74                                 }
75                         } else { 
76                                 // None Connected
77                                 if((mask2 != 0) && (stat_com[port_num])) { // COM
78                                         retval |= 0x40;
79                                 }
80                                 return retval;
81                         }
82                         if((mask2 != 0) && (stat_com[port_num])) { // COM
83                                 retval |= 0x40;
84                         }
85                         // Trigger independents from direction keys.
86                         if(((trig & 0x02) != 0) && ((joydata[port_num] & LINE_JOYPORT_B) == 0)) {
87                                 retval = retval | 0x20;
88                         }
89                         if(((trig & 0x01) != 0) && ((joydata[port_num] & LINE_JOYPORT_A) == 0)) {
90                                 retval = retval | 0x10;
91                         }
92                         //if((mask & (0x10 << port_num)) == 0) {
93 //                              if((mask2 & 0x01) == 0) { // COM
94                         if((joydata[port_num] & LINE_JOYPORT_LEFT) != 0) { // LEFT
95                                 retval = retval & ~0x04; // LEFT
96                         }
97                         if((joydata[port_num] & LINE_JOYPORT_RIGHT) != 0) { // RIGHT
98                                 retval = retval & ~0x08; // RIGHT
99                         }                               
100                         if((joydata[port_num] & LINE_JOYPORT_UP) != 0) { // UP
101                                 retval = retval & ~0x01; // FWD
102                         }
103                         if((joydata[port_num] & LINE_JOYPORT_DOWN) != 0) { // DOWN
104                                 retval = retval & ~0x02; // BACK
105                         }
106 //                              }
107                         return retval;
108                 }
109                 break;
110         default:
111                 break;
112         }
113         return 0xff;
114 }
115
116
117 void JOYSTICK::write_signal(int id, uint32_t data, uint32_t mask)
118 {
119         int ch = (id >> 24) & 1;
120         int bustype = id  & 0x300;
121         int num = id & 0xff;
122         //out_debug_log(_T("SIGNAL SENT, CH=%d TYPE=%d  VALUE=%08X"), ch, num, data);
123         if(num == connected_type[ch]) {
124                 switch(bustype) {
125                 case SIG_JOYPORT_DATA:
126                         joydata[ch] = data;
127                         break;
128                 case SIG_JOYPORT_COM:
129                         stat_com[ch] = ((data & mask) != 0) ? true : false;
130                         break;
131                 }
132         }
133         //if(type != connected_type[num]) return;
134 }       
135 uint32_t JOYSTICK::read_signal(int id)
136 {
137         int ch = (id >> 24) & 1;
138         int bustype = id  & 0x300;
139         int num = id & 0xff;
140         uint32_t data = 0;
141         switch(bustype) {
142         case SIG_JOYPORT_DATA:
143                 data = joydata[ch];
144                 break;
145         case SIG_JOYPORT_COM:
146                 data = (stat_com[ch]) ? 0xffffffff : 0;
147                 break;
148         case SIG_JOYPORT_MASK:
149                 data = mouse_mask;
150                 break;
151         }
152         return data;
153 }
154
155 void JOYSTICK::update_config(void)
156 {
157         uint32_t ntype[2] = {0};
158         for(int i = 0; i < 2; i++) {
159                 switch(config.joystick_type) {
160                 case 0:
161                         ntype[i] = SIG_JOYPORT_TYPE_NULL;
162                         break;
163                 case 1:
164                         ntype[i] = SIG_JOYPORT_TYPE_2BUTTONS;
165                         break;
166                 case 2:
167                         ntype[i] = SIG_JOYPORT_TYPE_6BUTTONS;
168                         break;
169                 }
170         }
171         set_emulate_mouse();
172         if(emulate_mouse[0]) {
173                 ntype[0] = SIG_JOYPORT_TYPE_MOUSE;
174         }
175         if(emulate_mouse[1]) {
176                 ntype[1] = SIG_JOYPORT_TYPE_MOUSE;
177         }
178         
179         write_signals(&outputs_mask, mouse_mask);
180         for(int i = 0; i < 2; i++) {
181 //              if(connected_type[i] != ntype[i]) {
182                         write_signals(&outputs_enable[i], 1 << ntype[i]);
183 //              }
184                 switch(ntype[i]) {
185                 case SIG_JOYPORT_TYPE_2BUTTONS:
186                 case SIG_JOYPORT_TYPE_6BUTTONS:
187                         connected_type[i] = SIG_JOYPORT_TYPE_2BUTTONS;
188                         break;
189                 default:
190                         connected_type[i] = ntype[i];
191                         break;
192                 }
193         }
194         
195 }
196
197 void JOYSTICK::set_emulate_mouse()
198 {
199         switch(config.mouse_type & 0x03){
200         case 1:
201                 emulate_mouse[0] = true;
202                 emulate_mouse[1] = false;
203                 if(d_mouse != nullptr) {
204                         d_mouse->write_signal(SIG_MOUSE_ENABLE, 0xfffffffe, 0xffffffff);
205                 }
206                 break;
207         case 2:
208                 emulate_mouse[0] = false;
209                 emulate_mouse[1] = true;
210                 if(d_mouse != nullptr) {
211                         d_mouse->write_signal(SIG_MOUSE_ENABLE, 0xffffffff, 0xffffffff);
212                 }
213                 break;
214         default:
215                 emulate_mouse[0] = false;
216                 emulate_mouse[1] = false;
217                 if(d_mouse != nullptr) {
218                         d_mouse->write_signal(SIG_MOUSE_ENABLE, 0x00000000, 0xffffffff);
219                 }
220                 break;
221         }
222 }
223
224 #define STATE_VERSION 6
225
226 bool JOYSTICK::process_state(FILEIO *state_fio, bool loading)
227 {
228         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
229                 return false;
230         }
231         if(!state_fio->StateCheckInt32(this_device_id)) {
232                 return false;
233         }
234         state_fio->StateValue(mouse_mask);
235         state_fio->StateArray(joydata, sizeof(joydata), 1);
236         state_fio->StateArray(connected_type, sizeof(connected_type), 1);
237         
238         state_fio->StateArray(emulate_mouse, sizeof(emulate_mouse), 1);
239         state_fio->StateArray(stat_com, sizeof(stat_com), 1);
240
241         return true;
242 }
243
244 }