ikbd.cpp
1 /* 2 * Castaway 3 * (C) 1994 - 2002 Martin Doering, Joachim Hoenig 4 * 5 * ikbd.c - ST keyboard processor emulator (german keymap) 6 * 7 * This file is distributed under the GPL, version 2 or at your 8 * option any later version. See doc/license.txt for details. 9 * 10 * revision history 11 * 23.05.2002 0.02.00 JH FAST1.0.1 code import: KR -> ANSI, restructuring 12 * 09.06.2002 0.02.00 JH Renamed io.c to st.c again (io.h conflicts with system headers) 13 * 16.06.2002 0.02.00 JH New function: IkbdQueryBuffer(). X11 keysym conversion removed. 14 */ 15 static char sccsid[] = "$Id: ikbd.c,v 1.3 2002/06/16 23:16:09 jhoenig Exp $"; 16 //#include "winbase.h" 17 #include <stdio.h> 18 #include <string.h> 19 #include <Arduino.h> 20 #include "dcastaway.h" 21 #include "st.h" 22 #define IBS 10 /* Ikbd input buffer size */ 23 #define OBS 20 /* Ikbd output buffer size */ 24 25 26 //extern char Msg[400]; 27 extern FILE* logfile; 28 extern int exmousex,exmousey; 29 int pause = 0; 30 struct _mouse mouse; 31 struct _joystick joystick; 32 33 extern unsigned char joynum; 34 unsigned char inbuff[IBS]; 35 unsigned char outbuff[OBS]; 36 int inbuffi = 0; 37 int outbuffi = 0; 38 int oldjoystate =0; 39 int joytick=0; 40 unsigned char Buttons; 41 //SYSTEMTIME SystemTime; 42 unsigned char TempButtons=0x0a; 43 unsigned char PrevButtons; 44 45 unsigned char Misc_ConvertToBCD(unsigned short int Value) 46 { 47 return( ((Value&0xf0)>>4)*10 + (Value&0x0f) ); 48 } 49 50 PROGMEM void IkbdRecv(unsigned char inchar) 51 { 52 if (inbuffi == IBS) { 53 inbuffi = 0; 54 } 55 inbuff[inbuffi++] = inchar; 56 //Serial.print("d "); 57 //Serial.println(inbuff[0]); 58 switch (inbuff[0]) { 59 case 0x07: /* set mouse button action */ 60 if (inbuffi == 2) { 61 inbuffi = 0; 62 mouse.button_action = inbuff[1]; 63 } 64 break; 65 case 0x08: /* set relative mouse position reporting */ 66 inbuffi = 0; 67 mouse.mode = 1; 68 break; 69 case 0x09: /* set absolute mouse positioning */ 70 if (inbuffi == 5) { 71 mouse.mode = 2; 72 mouse.xmax = (inbuff[1] << 8) | inbuff[2]; 73 mouse.ymax = (inbuff[3] << 8) | inbuff[4]; 74 mouse.x=mouse.xmax/2; 75 mouse.y=mouse.ymax/2; 76 inbuffi = 0; 77 } 78 break; 79 case 0x0a: /* set mouse keycode mode */ 80 if (inbuffi == 3) { 81 mouse.mode = 3; 82 mouse.xkcm = inbuff[1]; 83 mouse.ykcm = inbuff[2]; 84 inbuffi = 0; 85 } 86 break; 87 case 0x0b: /* set mouse threshold */ 88 if (inbuffi == 3) { 89 mouse.xth = inbuff[1]; 90 mouse.yth = inbuff[2]; 91 inbuffi = 0; 92 } 93 break; 94 case 0x0c: /* set mouse scale */ 95 if (inbuffi == 3) { 96 mouse.xscale = inbuff[1]; 97 mouse.yscale = inbuff[2]; 98 inbuffi = 0; 99 } 100 break; 101 case 0x0d: /* interrogate mouse position */ 102 103 if (outbuffi < (OBS -6)){ 104 inbuffi = 0; 105 /* Test buttons */ 106 Buttons = 0; 107 /* Set buttons to show if up/down */ 108 if (mouse.stbuttons&1) Buttons |= 0x01; else Buttons |= 0x02; 109 if (mouse.stbuttons&2) Buttons |= 0x04; else Buttons |= 0x08; 110 111 /* Mask off it didn't send last time */ 112 PrevButtons = TempButtons; 113 TempButtons = Buttons; 114 Buttons &= ~PrevButtons; 115 116 IkbdSend (0xf7); 117 IkbdSend (Buttons); 118 IkbdSend (mouse.stx >> 8); 119 IkbdSend (mouse.stx); 120 IkbdSend (mouse.sty >> 8); 121 IkbdSend (mouse.sty); 122 } 123 break; 124 125 case 0x0e: /* load mouse position */ 126 if (inbuffi == 6) { 127 inbuffi = 0; 128 mouse.x = exmousex = mouse.stx = (inbuff[2] << 8) | inbuff[3]; 129 mouse.y = exmousey = mouse.sty = (inbuff[4] << 8) | inbuff[5]; 130 } 131 break; 132 case 0x0f: /* set Y=0 at bottom */ 133 inbuffi = 0; 134 mouse.yinv = 1; 135 break; 136 case 0x10: /* set Y=0 at top */ 137 inbuffi = 0; 138 mouse.yinv = 0; 139 break; 140 case 0x11: /* resume */ 141 inbuffi = 0; 142 pause = 0; 143 break; 144 case 0x12: /* disable mouse */ 145 inbuffi = 0; 146 //mouse.mode = 0; 147 break; 148 case 0x13: /* pause output */ 149 inbuffi = 0; 150 //pause = 1; 151 break; 152 case 0x14: /* set joystick event reporting */ 153 inbuffi = 0; 154 joystick.mode = 1; 155 break; 156 case 0x15: /* set joystick interrogation mode */ 157 inbuffi = 0; 158 joystick.mode = 2; 159 break; 160 case 0x16: /* joystick interrogation */ 161 inbuffi = 0; 162 IkbdSend (0xfd); 163 IkbdSend (0); 164 IkbdSend (oldjoystate); 165 break; 166 case 0x17: /* set joystick monitoring */ 167 if (inbuffi == 2) { 168 inbuffi = 0; 169 joystick.rate = inbuff[1]; 170 joystick.mode = 4; 171 } 172 break; 173 case 0x18: /* set fire button monitoring */ 174 inbuffi = 0; 175 joystick.mode = 5; 176 break; 177 case 0x19: /* set joystick keycode mode */ 178 if (inbuffi == 7) { 179 inbuffi = 0; 180 joystick.mode = 3; 181 } 182 break; 183 case 0x1a: /* disable joysticks */ 184 inbuffi = 0; 185 // joystick.mode = 0; 186 break; 187 case 0x1b: /* time-of-day clock set */ 188 if (inbuffi == 7) { 189 inbuffi = 0; 190 } 191 break; 192 case 0x1c: /* interrogate time-of-day clock */ 193 inbuffi = 0; 194 IkbdSend (0xfc); 195 IkbdSend (0x0); 196 IkbdSend (0x0); 197 IkbdSend (0x0); 198 IkbdSend (0x0); 199 IkbdSend (0x0); 200 IkbdSend (0x0); 201 break; 202 case 0x20: /* memory load */ 203 case 0x21: /* memory read */ 204 case 0x22: /* controller execute */ 205 inbuffi = 0; 206 break; 207 case 0x80: /* reset */ 208 if (inbuffi == 2) { 209 IkbdSend (0xf0); 210 inbuffi = 0; 211 mouse.buttons = mouse.stbuttons = 0; 212 switch (vid_shiftmode) { 213 case 0: 214 mouse.x = exmousex = mouse.stx = 160; 215 mouse.y = exmousey = mouse.sty = 100; 216 break; 217 case 1: 218 mouse.x = exmousex = mouse.stx = 320; 219 mouse.y = exmousey = mouse.sty = 100; 220 break; 221 case 2: 222 mouse.x = exmousex = mouse.stx = 320; 223 mouse.y = exmousey = mouse.sty = 200; 224 break; 225 } 226 } 227 break; 228 case 0x87: /* request button action */ 229 IkbdSend (0x07); 230 IkbdSend (mouse.button_action); 231 IkbdSend (0); 232 IkbdSend (0); 233 IkbdSend (0); 234 IkbdSend (0); 235 IkbdSend (0); 236 break; 237 case 0x88: /* request mouse mode */ 238 case 0x89: 239 case 0x8a: 240 switch (mouse.mode) { 241 case 1: 242 IkbdSend (0x08); 243 IkbdSend (0); 244 IkbdSend (0); 245 IkbdSend (0); 246 IkbdSend (0); 247 IkbdSend (0); 248 IkbdSend (0); 249 break; 250 case 2: 251 IkbdSend (0x09); 252 IkbdSend (mouse.xmax >> 8); 253 IkbdSend (mouse.xmax); 254 IkbdSend (mouse.ymax >> 8); 255 IkbdSend (mouse.ymax); 256 IkbdSend (0); 257 IkbdSend (0); 258 break; 259 case 3: 260 IkbdSend (0x09); 261 IkbdSend (mouse.xkcm); 262 IkbdSend (mouse.ykcm); 263 IkbdSend (0); 264 IkbdSend (0); 265 IkbdSend (0); 266 IkbdSend (0); 267 break; 268 } 269 inbuffi = 0; 270 mouse.mode = 1; 271 break; 272 case 0x8b: /* request mouse threshold */ 273 IkbdSend (0x0b); 274 IkbdSend (mouse.xth); 275 IkbdSend (mouse.yth); 276 IkbdSend (0); 277 IkbdSend (0); 278 IkbdSend (0); 279 IkbdSend (0); 280 inbuffi = 0; 281 break; 282 case 0x8c: /* request mouse scale */ 283 IkbdSend (0x0b); 284 IkbdSend (mouse.xscale); 285 IkbdSend (mouse.yscale); 286 IkbdSend (0); 287 IkbdSend (0); 288 IkbdSend (0); 289 IkbdSend (0); 290 inbuffi = 0; 291 break; 292 case 0x8f: /* request mouse vertical coordinates */ 293 case 0x90: 294 if (mouse.yinv) 295 IkbdSend (0x0f); 296 else 297 IkbdSend (0x10); 298 IkbdSend (0); 299 IkbdSend (0); 300 IkbdSend (0); 301 IkbdSend (0); 302 IkbdSend (0); 303 IkbdSend (0); 304 inbuffi = 0; 305 break; 306 case 0x92: /* disable mouse */ 307 if (mouse.mode) 308 IkbdSend (0); 309 else 310 IkbdSend (0x12); 311 IkbdSend (0); 312 IkbdSend (0); 313 IkbdSend (0); 314 IkbdSend (0); 315 IkbdSend (0); 316 IkbdSend (0); 317 inbuffi = 0; 318 break; 319 case 0x94: /* request joystick mode */ 320 case 0x95: 321 case 0x99: /* set joystick keycode mode */ 322 inbuffi = 0; 323 switch (joystick.mode) { 324 case 1: 325 IkbdSend (0x14); 326 IkbdSend (0); 327 IkbdSend (0); 328 IkbdSend (0); 329 IkbdSend (0); 330 IkbdSend (0); 331 IkbdSend (0); 332 break; 333 case 2: 334 IkbdSend (0x15); 335 IkbdSend (0); 336 IkbdSend (0); 337 IkbdSend (0); 338 IkbdSend (0); 339 IkbdSend (0); 340 IkbdSend (0); 341 break; 342 case 3: 343 IkbdSend (0x19); 344 IkbdSend (joystick.rx); 345 IkbdSend (joystick.ry); 346 IkbdSend (joystick.tx); 347 IkbdSend (joystick.ty); 348 IkbdSend (joystick.vx); 349 IkbdSend (joystick.vy); 350 break; 351 } 352 inbuffi = 0; 353 break; 354 case 0x9a: /* request joystick availability */ 355 if (joystick.mode) 356 IkbdSend (0); 357 else 358 IkbdSend (0x1a); 359 IkbdSend (joystick.rx); 360 IkbdSend (joystick.ry); 361 IkbdSend (joystick.tx); 362 IkbdSend (joystick.ty); 363 IkbdSend (joystick.vx); 364 IkbdSend (joystick.vy); 365 inbuffi = 0; 366 break; 367 } 368 } 369 370 void IkbdSend (unsigned char outchar) 371 { 372 if (outbuffi < (OBS - 1)) { 373 //Serial.print("q "); 374 //Serial.println(outchar); 375 outbuff[outbuffi++] = outchar; 376 } 377 } 378 379 PROGMEM void IkbdWriteBuffer(void) 380 { 381 /* 382 if (mouse.flag && (outbuffi < (OBS / 2))) { 383 IkbdMouse (); 384 } 385 if (joystick.mode==4) IkbdJoystick(); 386 */ 387 if (outbuffi>0) 388 { 389 if ((acia1_sr & 0x1) == 0) 390 { 391 //Serial.println("KW"); 392 acia1_sr |= 1; 393 if (acia1_cr & 0x80) { /* receiver interrupt enabled? */ 394 acia1_sr |= 0x80; 395 mfp_gpip &= (~0x10); 396 } 397 acia1_dr = outbuff[0]; 398 memcpy (&outbuff[0], &outbuff[1], (OBS - 1)); 399 outbuffi--; 400 } 401 } 402 } 403 404 PROGMEM void IkbdKeyPress (unsigned short keysym) { 405 IkbdSend (keysym); 406 } 407 408 PROGMEM void IkbdKeyRelease (unsigned short keysym) { 409 IkbdSend (0x80 | keysym); 410 } 411 412 PROGMEM void IkbdMouseMotion (int x, int y) 413 { 414 if (vid_shiftmode==1) {x+=x;} 415 if (vid_shiftmode==2) {x+=x; y+=y;} 416 mouse.x=x; mouse.y=y; 417 } 418 419 PROGMEM void IkbdMousePress (int code) { 420 mouse.buttons |= code; 421 } 422 423 PROGMEM void IkbdMouseRelease (int code) { 424 mouse.buttons &= ~code; 425 } 426 427 PROGMEM void joystickevent (int joystate) 428 { 429 //Has joystick moved? 430 if (joystate==oldjoystate) return; 431 oldjoystate=joystate; 432 //send fire button to mouse as well 433 if (mouse.mode==1 || mouse.mode==0) { 434 if (joystate&0x80) { 435 IkbdSend (0xf9); 436 IkbdSend (0); 437 IkbdSend (0); 438 } 439 else { 440 IkbdSend (0xf8); 441 IkbdSend (0); 442 IkbdSend (0); 443 } 444 } 445 //In event mode send the joystick event immediately 446 if (joystick.mode==1) { 447 IkbdSend (0xff); 448 IkbdSend (joystate); 449 } 450 } 451 452 PROGMEM void IkbdLoop() 453 { 454 int dx, dy; 455 if (mouse.mode==1) { 456 dx=mouse.x-mouse.stx; if (dx>127) dx=127; else if (dx<-127) dx=-127; 457 dy=mouse.y-mouse.sty; if (dy>127) dy=127; else if (dy<-127) dy=-127; 458 if (mouse.stbuttons!=mouse.buttons || dx>mouse.xth || dy>mouse.yth || -dx>mouse.xth || -dy>mouse.yth) { 459 if (outbuffi<OBS/2) { 460 mouse.stbuttons = mouse.buttons; 461 mouse.stx = mouse.stx + dx; 462 mouse.sty = mouse.sty + dy; 463 if (mouse.stx <= 0) {mouse.stx = 0; dx = -127;} 464 if (mouse.sty <= 0) {mouse.sty = 0; dy = -127;} 465 switch (vid_shiftmode) { 466 case 0: 467 if (mouse.stx >= 319) {mouse.stx = 319; dx = 127;} 468 if (mouse.sty >= 199) {mouse.sty = 199; dy = 127;} 469 break; 470 case 1: 471 if (mouse.stx >= 639) {mouse.stx = 639; dx = 127;} 472 if (mouse.sty >= 199) {mouse.sty = 199; dy = 127;} 473 break; 474 case 2: 475 if (mouse.stx >= 639) {mouse.stx = 639; dx = 127;} 476 if (mouse.sty >= 399) {mouse.sty = 399; dy = 127;} 477 break; 478 } 479 IkbdSend (0xf8 | (mouse.stbuttons&3)); 480 IkbdSend (dx); 481 IkbdSend (dy); 482 } 483 } 484 } 485 else { 486 if (mouse.x>mouse.xmax) mouse.x=mouse.xmax; 487 if (mouse.y>mouse.ymax) mouse.y=mouse.ymax; 488 mouse.stx=mouse.x; 489 mouse.sty=mouse.y; 490 mouse.stbuttons=mouse.buttons; 491 492 } 493 if (joystick.mode==4) { 494 //Called at 200hz when joystick is in mode 4 495 joytick+=2; 496 if (joytick<joystick.rate) return; 497 joytick=0; 498 IkbdSend (oldjoystate>>7); 499 IkbdSend (oldjoystate&15); 500 } 501 } 502 503 PROGMEM void IkbdReset (void) 504 { 505 joystick.mode=1; 506 mouse.mode=1; 507 IkbdSend(0x80); 508 IkbdSend(0xff); 509 IkbdSend(0x80); 510 acia1_cr=150; 511 acia1_sr=0; 512 acia1_dr=240; 513 acia2_cr=149; 514 acia2_sr=0; 515 acia2_dr=0; 516 inbuffi = 0; 517 outbuffi = 0; 518 } 519 520 521 PROGMEM void IkbdJoystickChange(int number, uint8 state) 522 { 523 joystickevent(state); 524 }