Mercurial > repos > blastem
comparison io.c @ 912:599e2861f484
Rough emulation of mouse response delays when TR is toggled. Latch current mouse value rather than delta. Some other IO cleanup/fixes
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 06 Dec 2015 19:29:34 -0800 |
parents | 73732ae76fa8 |
children | a5a51465f8b0 |
comparison
equal
deleted
inserted
replaced
911:73732ae76fa8 | 912:599e2861f484 |
---|---|
17 | 17 |
18 #include "io.h" | 18 #include "io.h" |
19 #include "blastem.h" | 19 #include "blastem.h" |
20 #include "render.h" | 20 #include "render.h" |
21 #include "util.h" | 21 #include "util.h" |
22 | |
23 #define CYCLE_NEVER 0xFFFFFFFF | |
22 | 24 |
23 const char * device_type_names[] = { | 25 const char * device_type_names[] = { |
24 "3-button gamepad", | 26 "3-button gamepad", |
25 "6-button gamepad", | 27 "6-button gamepad", |
26 "Mega Mouse", | 28 "Mega Mouse", |
605 port->device.mouse.mouse_num = device_type[mouse_len+1] - '1'; | 607 port->device.mouse.mouse_num = device_type[mouse_len+1] - '1'; |
606 port->device.mouse.last_read_x = 0; | 608 port->device.mouse.last_read_x = 0; |
607 port->device.mouse.last_read_y = 0; | 609 port->device.mouse.last_read_y = 0; |
608 port->device.mouse.cur_x = 0; | 610 port->device.mouse.cur_x = 0; |
609 port->device.mouse.cur_y = 0; | 611 port->device.mouse.cur_y = 0; |
612 port->device.mouse.latched_x = 0; | |
613 port->device.mouse.latched_y = 0; | |
614 port->device.mouse.ready_cycle = CYCLE_NEVER; | |
610 port->device.mouse.tr_counter = 0; | 615 port->device.mouse.tr_counter = 0; |
611 } else if(!strcmp(device_type, "sega_parallel")) { | 616 } else if(!strcmp(device_type, "sega_parallel")) { |
612 port->device_type = IO_SEGA_PARALLEL; | 617 port->device_type = IO_SEGA_PARALLEL; |
613 port->device.stream.data_fd = -1; | 618 port->device.stream.data_fd = -1; |
614 port->device.stream.listen_fd = -1; | 619 port->device.stream.listen_fd = -1; |
996 | 1001 |
997 #define TH 0x40 | 1002 #define TH 0x40 |
998 #define TR 0x20 | 1003 #define TR 0x20 |
999 #define TH_TIMEOUT 56000 | 1004 #define TH_TIMEOUT 56000 |
1000 | 1005 |
1006 void mouse_check_ready(io_port *port, uint32_t current_cycle) | |
1007 { | |
1008 if (current_cycle >= port->device.mouse.ready_cycle) { | |
1009 port->device.mouse.tr_counter++; | |
1010 port->device.mouse.ready_cycle = CYCLE_NEVER; | |
1011 if (port->device.mouse.tr_counter == 3) { | |
1012 port->device.mouse.latched_x = port->device.mouse.cur_x; | |
1013 port->device.mouse.latched_y = port->device.mouse.cur_y; | |
1014 } | |
1015 } | |
1016 } | |
1017 | |
1001 void io_adjust_cycles(io_port * port, uint32_t current_cycle, uint32_t deduction) | 1018 void io_adjust_cycles(io_port * port, uint32_t current_cycle, uint32_t deduction) |
1002 { | 1019 { |
1003 /*uint8_t control = pad->control | 0x80; | 1020 /*uint8_t control = pad->control | 0x80; |
1004 uint8_t th = control & pad->output; | 1021 uint8_t th = control & pad->output; |
1005 if (pad->input[GAMEPAD_TH0] || pad->input[GAMEPAD_TH1]) { | 1022 if (pad->input[GAMEPAD_TH0] || pad->input[GAMEPAD_TH1]) { |
1010 if (current_cycle >= port->device.pad.timeout_cycle) | 1027 if (current_cycle >= port->device.pad.timeout_cycle) |
1011 { | 1028 { |
1012 port->device.pad.th_counter = 0; | 1029 port->device.pad.th_counter = 0; |
1013 } else { | 1030 } else { |
1014 port->device.pad.timeout_cycle -= deduction; | 1031 port->device.pad.timeout_cycle -= deduction; |
1032 } | |
1033 } else if (port->device_type == IO_MOUSE) { | |
1034 mouse_check_ready(port, current_cycle); | |
1035 if (port->device.mouse.ready_cycle != CYCLE_NEVER) { | |
1036 port->device.mouse.ready_cycle -= deduction; | |
1015 } | 1037 } |
1016 } | 1038 } |
1017 } | 1039 } |
1018 | 1040 |
1019 #ifndef _WIN32 | 1041 #ifndef _WIN32 |
1116 } | 1138 } |
1117 } | 1139 } |
1118 } | 1140 } |
1119 #endif | 1141 #endif |
1120 | 1142 |
1143 const int mouse_delays[] = {112*7, 120*7, 96*7, 132*7, 104*7, 96*7, 112*7, 96*7}; | |
1144 | |
1121 void io_data_write(io_port * port, uint8_t value, uint32_t current_cycle) | 1145 void io_data_write(io_port * port, uint8_t value, uint32_t current_cycle) |
1122 { | 1146 { |
1147 uint8_t old_output = (port->control & port->output) | (~port->control & 0xFF); | |
1148 uint8_t output = (port->control & value) | (~port->control & 0xFF); | |
1123 switch (port->device_type) | 1149 switch (port->device_type) |
1124 { | 1150 { |
1125 case IO_GAMEPAD6: | 1151 case IO_GAMEPAD6: |
1126 if (port->control & TH) { | 1152 //check if TH has changed |
1127 //check if TH has changed | 1153 if ((old_output & TH) ^ (output & TH)) { |
1128 if ((port->output & TH) ^ (value & TH)) { | 1154 if (current_cycle >= port->device.pad.timeout_cycle) { |
1129 if (current_cycle >= port->device.pad.timeout_cycle) { | 1155 port->device.pad.th_counter = 0; |
1130 port->device.pad.th_counter = 0; | 1156 } |
1131 } | 1157 if (!(output & TH)) { |
1132 if (!(value & TH)) { | 1158 port->device.pad.th_counter++; |
1133 port->device.pad.th_counter++; | 1159 } |
1134 } | 1160 port->device.pad.timeout_cycle = current_cycle + TH_TIMEOUT; |
1135 port->device.pad.timeout_cycle = current_cycle + TH_TIMEOUT; | 1161 } |
1136 } | |
1137 } | |
1138 port->output = value; | |
1139 break; | 1162 break; |
1140 case IO_MOUSE: | 1163 case IO_MOUSE: |
1141 if ((port->control & (TH|TR)) == (TH|TR)) { | 1164 mouse_check_ready(port, current_cycle); |
1142 if (!(value & TH) && (value & TR) != (port->output & TR)) { | 1165 if (output & TH) { |
1143 port->device.mouse.tr_counter++; | 1166 //request is over or mouse is being reset |
1144 } | 1167 if (port->device.mouse.tr_counter) { |
1168 //request is over | |
1169 port->device.mouse.last_read_x = port->device.mouse.latched_x; | |
1170 port->device.mouse.last_read_y = port->device.mouse.latched_y; | |
1171 } | |
1172 port->device.mouse.tr_counter = 0; | |
1173 port->device.mouse.ready_cycle = CYCLE_NEVER; | |
1145 } else { | 1174 } else { |
1146 port->device.mouse.tr_counter = 0; | 1175 if ((output & TR) != (old_output & TR)) { |
1147 } | 1176 int delay_index = port->device.mouse.tr_counter >= sizeof(mouse_delays) ? sizeof(mouse_delays)-1 : port->device.mouse.tr_counter; |
1148 port->output = value; | 1177 port->device.mouse.ready_cycle = current_cycle + mouse_delays[delay_index]; |
1178 } | |
1179 } | |
1149 break; | 1180 break; |
1150 #ifndef _WIN32 | 1181 #ifndef _WIN32 |
1151 case IO_GENERIC: | 1182 case IO_GENERIC: |
1152 wait_for_connection(port); | 1183 wait_for_connection(port); |
1153 port->input[IO_STATE] = IO_WRITE_PENDING; | 1184 port->input[IO_STATE] = IO_WRITE_PENDING; |
1154 port->output = value; | |
1155 service_socket(port); | 1185 service_socket(port); |
1156 break; | 1186 break; |
1157 #endif | 1187 #endif |
1158 default: | 1188 } |
1159 port->output = value; | 1189 port->output = value; |
1160 } | |
1161 | 1190 |
1162 } | 1191 } |
1163 | 1192 |
1164 uint8_t io_data_read(io_port * port, uint32_t current_cycle) | 1193 uint8_t io_data_read(io_port * port, uint32_t current_cycle) |
1165 { | 1194 { |
1206 input = ~input; | 1235 input = ~input; |
1207 break; | 1236 break; |
1208 } | 1237 } |
1209 case IO_MOUSE: | 1238 case IO_MOUSE: |
1210 { | 1239 { |
1240 mouse_check_ready(port, current_cycle); | |
1211 uint8_t tr = output & TR; | 1241 uint8_t tr = output & TR; |
1212 if (th) { | 1242 if (th) { |
1213 if (tr) { | 1243 if (tr) { |
1214 input = 0x10; | 1244 input = 0x10; |
1215 } else { | 1245 } else { |
1216 input = 0; | 1246 input = 0; |
1217 } | 1247 } |
1218 } else { | 1248 } else { |
1249 | |
1250 int16_t delta_x = port->device.mouse.latched_x - port->device.mouse.last_read_x; | |
1251 int16_t delta_y = port->device.mouse.last_read_y - port->device.mouse.latched_y; | |
1219 switch (port->device.mouse.tr_counter) | 1252 switch (port->device.mouse.tr_counter) |
1220 { | 1253 { |
1221 case 0: | 1254 case 0: |
1222 input = 0xB; | 1255 input = 0xB; |
1223 break; | 1256 break; |
1225 case 2: | 1258 case 2: |
1226 input = 0xF; | 1259 input = 0xF; |
1227 break; | 1260 break; |
1228 case 3: | 1261 case 3: |
1229 input = 0; | 1262 input = 0; |
1230 //it would be unfortunate if our event handler updated cur_x or cur_y in the middle | 1263 if (delta_y > 255 || delta_y < -255) { |
1231 //of the mouse poll sequence, so we save the delta here | |
1232 port->device.mouse.delta_x = port->device.mouse.cur_x - port->device.mouse.last_read_x; | |
1233 port->device.mouse.delta_y = port->device.mouse.last_read_y - port->device.mouse.cur_y; | |
1234 if (port->device.mouse.delta_y > 255 || port->device.mouse.delta_y < -255) { | |
1235 input |= 8; | 1264 input |= 8; |
1236 } | 1265 } |
1237 if (port->device.mouse.delta_x > 255 || port->device.mouse.delta_x < -255) { | 1266 if (delta_x > 255 || delta_x < -255) { |
1238 input |= 4; | 1267 input |= 4; |
1239 } | 1268 } |
1240 if (port->device.mouse.delta_y < 0) { | 1269 if (delta_y < 0) { |
1241 input |= 2; | 1270 input |= 2; |
1242 } | 1271 } |
1243 if (port->device.mouse.delta_x < 0) { | 1272 if (delta_x < 0) { |
1244 input |= 1; | 1273 input |= 1; |
1245 } | 1274 } |
1246 break; | 1275 break; |
1247 case 4: | 1276 case 4: |
1248 input = port->input[0]; | 1277 input = port->input[0]; |
1249 break; | 1278 break; |
1250 case 5: | 1279 case 5: |
1251 input = port->device.mouse.delta_x >> 4 & 0xF; | 1280 input = delta_x >> 4 & 0xF; |
1252 break; | 1281 break; |
1253 case 6: | 1282 case 6: |
1254 input = port->device.mouse.delta_x & 0xF; | 1283 input = delta_x & 0xF; |
1255 break; | 1284 break; |
1256 case 7: | 1285 case 7: |
1257 input = port->device.mouse.delta_y >> 4 & 0xF; | 1286 input = delta_y >> 4 & 0xF; |
1258 break; | 1287 break; |
1259 case 8: | 1288 case 8: |
1260 input = port->device.mouse.delta_y & 0xF; | 1289 default: |
1261 //need to figure out when this actually happens | 1290 input = delta_y & 0xF; |
1262 port->device.mouse.last_read_x = port->device.mouse.cur_x; | |
1263 port->device.mouse.last_read_y = port->device.mouse.cur_y; | |
1264 break; | 1291 break; |
1265 default: | 1292 } |
1266 //need to test what happens here | 1293 input |= ((port->device.mouse.tr_counter & 1) == 0) << 4; |
1267 input = 0; | |
1268 break; | |
1269 } | |
1270 input |= tr >> 1; | |
1271 } | 1294 } |
1272 break; | 1295 break; |
1273 } | 1296 } |
1274 #ifndef _WIN32 | 1297 #ifndef _WIN32 |
1275 case IO_SEGA_PARALLEL: | 1298 case IO_SEGA_PARALLEL: |