|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * DOS handlers. ! 5: * ! 6: * (c) 1997 Gustavo Goedert ! 7: * ! 8: * Led routines by Michael Sontheimer ! 9: */ ! 10: ! 11: #include "sysconfig.h" ! 12: #include "sysdeps.h" ! 13: ! 14: #include <dos.h> ! 15: #include <go32.h> ! 16: #include <dpmi.h> ! 17: #include <sys/farptr.h> ! 18: ! 19: #include "config.h" ! 20: #include "options.h" ! 21: #include "threaddep/penguin.h" ! 22: #include "memory.h" ! 23: #include "custom.h" ! 24: #include "readcpu.h" ! 25: #include "newcpu.h" ! 26: #include "keyboard.h" ! 27: #include "xwin.h" ! 28: #include "keybuf.h" ! 29: #include "disk.h" ! 30: #include "gui.h" ! 31: #include "tui.h" ! 32: #include "uae.h" ! 33: #include "picasso96.h" ! 34: #include "misc/handlers.h" ! 35: #include "misc/misc.h" ! 36: ! 37: /* dummie Amiga Keys */ ! 38: #define AK_EjectDisk 0xfa ! 39: #define AK_ChangeDisk 0xfb ! 40: #define AK_SaveScreen1 0xfc ! 41: #define AK_SaveScreen2 0xfd ! 42: #define AK_TougleScreen 0xfe ! 43: #define AK_QuitProgram 0xff ! 44: ! 45: /* Event Flags */ ! 46: #define EF_ResetCPU 0x0001 ! 47: #define EF_EjectDisk0 0x0002 ! 48: #define EF_EjectDisk1 0x0004 ! 49: #define EF_EjectDisk2 0x0008 ! 50: #define EF_EjectDisk3 0x0010 ! 51: #define EF_ChangeDisk0 0x0020 ! 52: #define EF_ChangeDisk1 0x0040 ! 53: #define EF_ChangeDisk2 0x0080 ! 54: #define EF_ChangeDisk3 0x0100 ! 55: #define EF_ChangeOptions 0x0200 ! 56: #define EF_EnterDebug 0x0400 ! 57: #define EF_SaveScreen 0x0800 ! 58: #define EF_TougleScreen 0x1000 ! 59: #define EF_TougleSound 0x2000 ! 60: #define EF_TougleCapsLock 0x4000 ! 61: #define EF_QuitProgram 0x8000 ! 62: ! 63: extern int kpb_first, kpb_last; ! 64: extern int keybuf[256]; ! 65: ! 66: int Original_produce_sound; ! 67: int KeyBoardInstalled = 0, MouseInstalled = 0; ! 68: int EventFlags = 0; ! 69: int KeyState[256]; ! 70: int buttonstate[3] = {0, 0, 0}; ! 71: int lastmx, lastmy; ! 72: int newmousecounters = 0; ! 73: _go32_dpmi_seginfo OldKeyboardHandler, NewKeyboardHandler, NewMouseHandler; ! 74: _go32_dpmi_registers MouseCallbackRegs; ! 75: volatile int NumLockState = -1, CapsLockState = -1, ScrollLockState = -1; ! 76: UBYTE SavedLEDa; ! 77: ! 78: int AmigaKeys[128] = { ! 79: -1, AK_ESC, AK_1, AK_2, AK_3, AK_4, AK_5, AK_6, ! 80: AK_7, AK_8, AK_9, AK_0, AK_MINUS, AK_EQUAL, AK_BS, AK_TAB, ! 81: AK_Q, AK_W, AK_E, AK_R, AK_T, AK_Y, AK_U, AK_I, ! 82: AK_O, AK_P, AK_LBRACKET, AK_RBRACKET, AK_RET, AK_CTRL, AK_A, AK_S, ! 83: AK_D, AK_F, AK_G, AK_H, AK_J, AK_K, AK_L, AK_SEMICOLON, ! 84: AK_QUOTE, AK_NUMBERSIGN, AK_LSH, AK_LTGT, AK_Z, AK_X, AK_C, AK_V, ! 85: AK_B, AK_N, AK_M, AK_COMMA, AK_PERIOD, AK_SLASH, AK_RSH, -1, ! 86: AK_LALT, AK_SPC, AK_CAPSLOCK, AK_F1, AK_F2, AK_F3, AK_F4, AK_F5, ! 87: AK_F6, AK_F7, AK_F8, AK_F9, AK_F10, -1, AK_TougleScreen, AK_NP7, ! 88: AK_NP8, AK_NP9, -1, AK_NP4, AK_NP5, AK_NP6, -1, AK_NP1, ! 89: AK_NP2, AK_NP3, AK_NP0, -1, -1, -1, -1, AK_BACKSLASH, ! 90: AK_QuitProgram, -1, -1, -1, -1, -1, -1, -1, ! 91: -1, AK_RCTRL, AK_SaveScreen1, AK_SaveScreen2, AK_RALT, -1, AK_ChangeDisk, AK_UP, ! 92: AK_RAMI, AK_LF, AK_RT, AK_EjectDisk, AK_DN, AK_LAMI, AK_HELP, AK_DEL, ! 93: -1, -1, -1, -1, -1, -1, -1, -1, ! 94: -1, -1, -1, -1, -1, AK_LAMI, AK_RAMI, -1 ! 95: }; ! 96: ! 97: unsigned char EscapeKeys[128] = { ! 98: 0, 0, 0, 0, 0, 0, 0, 0, ! 99: 0, 0, 0, 0, 0, 0, 0, 0, ! 100: 0, 0, 0, 0, 0, 0, 0, 0, ! 101: 0, 0, 0, 0, 96, 97, 0, 0, ! 102: 0, 0, 0, 0, 0, 0, 0, 0, ! 103: 0, 0, 98, 0, 0, 0, 0, 0, ! 104: 0, 0, 0, 0, 0, 0, 0, 99, ! 105: 100, 0, 0, 0, 0, 0, 0, 0, ! 106: 0, 0, 0, 0, 0, 0, 0, 102, ! 107: 103, 104, 0, 105, 0, 106, 0, 107, ! 108: 108, 109, 110, 111, 0, 0, 0, 0, ! 109: 0, 0, 0, 125, 126, 127, 0, 0, ! 110: 0, 0, 0, 0, 0, 0, 0, 0, ! 111: 0, 0, 0, 0, 0, 0, 0, 0, ! 112: 0, 0, 0, 0, 0, 0, 0, 0, ! 113: 0, 0, 0, 0, 0, 0, 0, 0, ! 114: }; ! 115: ! 116: int InstallHandlers(void) { ! 117: if (!KeyBoardInstalled) ! 118: if (!InstallKeyboardHandler()) ! 119: return(0); ! 120: if (!MouseInstalled) ! 121: if (!InstallMouseHandler()) ! 122: return(0); ! 123: SavedLEDa = InitLED(); ! 124: return(1); ! 125: } ! 126: ! 127: void UninstallHandlers(void) { ! 128: if (KeyBoardInstalled) ! 129: UninstallKeyboardHandler(); ! 130: if (MouseInstalled) ! 131: UninstallMouseHandler(); ! 132: RestoreLEDStatus(SavedLEDa); ! 133: } ! 134: ! 135: void handle_events(void) { ! 136: if (EventFlags) { ! 137: if (EventFlags & EF_ResetCPU) { ! 138: m68k_reset(); ! 139: EventFlags &= ~EF_ResetCPU; ! 140: } ! 141: if (EventFlags & EF_EjectDisk0) { ! 142: disk_eject(0); ! 143: EventFlags &= ~EF_EjectDisk0; ! 144: } ! 145: if (EventFlags & EF_EjectDisk1) { ! 146: disk_eject(1); ! 147: EventFlags &= ~EF_EjectDisk1; ! 148: } ! 149: if (EventFlags & EF_EjectDisk2) { ! 150: disk_eject(2); ! 151: EventFlags &= ~EF_EjectDisk2; ! 152: } ! 153: if (EventFlags & EF_EjectDisk3) { ! 154: disk_eject(3); ! 155: EventFlags &= ~EF_EjectDisk3; ! 156: } ! 157: if (EventFlags & EF_ChangeDisk0) { ! 158: HandleDisk(0); ! 159: KeyState[AK_ChangeDisk] = 0; ! 160: KeyState[AK_F1] = 0; ! 161: record_key ((AK_F1 << 1) | 1); ! 162: EventFlags &= ~EF_ChangeDisk0; ! 163: } ! 164: if (EventFlags & EF_ChangeDisk1) { ! 165: HandleDisk(1); ! 166: KeyState[AK_ChangeDisk] = 0; ! 167: KeyState[AK_F2] = 0; ! 168: record_key ((AK_F2 << 1) | 1); ! 169: EventFlags &= ~EF_ChangeDisk1; ! 170: } ! 171: if (EventFlags & EF_ChangeDisk2) { ! 172: HandleDisk(2); ! 173: KeyState[AK_ChangeDisk] = 0; ! 174: KeyState[AK_F3] = 0; ! 175: record_key ((AK_F3 << 1) | 1); ! 176: EventFlags &= ~EF_ChangeDisk2; ! 177: } ! 178: if (EventFlags & EF_ChangeDisk3) { ! 179: HandleDisk(3); ! 180: KeyState[AK_ChangeDisk] = 0; ! 181: KeyState[AK_F4] = 0; ! 182: record_key ((AK_F4 << 1) | 1); ! 183: EventFlags &= ~EF_ChangeDisk3; ! 184: } ! 185: if (EventFlags & EF_EnterDebug) { ! 186: EnterDebug(); ! 187: EventFlags &= ~EF_EnterDebug; ! 188: } ! 189: if (EventFlags & EF_SaveScreen) { ! 190: SaveScreen(); ! 191: EventFlags &= ~EF_SaveScreen; ! 192: } ! 193: if (EventFlags & EF_TougleScreen) { ! 194: inhibit_frame ^= 1; ! 195: EventFlags &= ~EF_TougleScreen; ! 196: } ! 197: if (EventFlags & EF_TougleSound) { ! 198: if (currprefs.produce_sound == 0) ! 199: currprefs.produce_sound = Original_produce_sound; ! 200: else ! 201: currprefs.produce_sound = 0; ! 202: EventFlags &= ~EF_TougleSound; ! 203: } ! 204: if (EventFlags & EF_TougleCapsLock) { ! 205: CapsLockLED(!CapsLockState); ! 206: EventFlags &= ~EF_TougleCapsLock; ! 207: } ! 208: if (EventFlags & EF_QuitProgram) { ! 209: regs.spcflags |= SPCFLAG_BRK; ! 210: quit_program = 1; ! 211: EventFlags &= ~EF_QuitProgram; ! 212: } ! 213: } ! 214: #ifdef PICASSO96 ! 215: PicassoRefresh(); ! 216: #endif ! 217: } ! 218: ! 219: static void KeyboardHandler(void) { ! 220: static int IsEscape = 0, CapsLockCanChange = 1; ! 221: int ScanCode, NewState, AmigaKey; ! 222: ! 223: ScanCode = inportb(0x60); ! 224: ! 225: if (ScanCode == 0xe0) { ! 226: IsEscape = 1; ! 227: outportb(0x20, 0x20); ! 228: return; ! 229: } ! 230: ! 231: /* PAUSE Key */ ! 232: if (IsEscape > 1) { ! 233: IsEscape++; ! 234: if (IsEscape == 7) { ! 235: EventFlags |= EF_TougleSound; ! 236: IsEscape = 0; ! 237: } ! 238: outportb(0x20, 0x20); ! 239: return; ! 240: } ! 241: if (ScanCode == 0xe1) { ! 242: IsEscape = 2; ! 243: outportb(0x20, 0x20); ! 244: return; ! 245: } ! 246: ! 247: NewState = !(ScanCode & 0x80); ! 248: ScanCode = ScanCode & 0x7f; ! 249: if (IsEscape) { ! 250: ScanCode = EscapeKeys[ScanCode]; ! 251: IsEscape = 0; ! 252: } ! 253: outportb(0x20, 0x20); ! 254: ! 255: AmigaKey = AmigaKeys[ScanCode]; ! 256: ! 257: if (AmigaKey == -1) ! 258: return; ! 259: ! 260: if (AmigaKey == AK_CAPSLOCK) { ! 261: if (NewState) { ! 262: if (CapsLockCanChange) { ! 263: NewState = !KeyState[AmigaKey]; ! 264: CapsLockCanChange = 0; ! 265: } else ! 266: return; ! 267: } else { ! 268: CapsLockCanChange = 1; ! 269: return; ! 270: } ! 271: EventFlags |= EF_TougleCapsLock; ! 272: } ! 273: ! 274: if (KeyState[AmigaKey] == NewState) ! 275: return; ! 276: KeyState[AmigaKey] = NewState; ! 277: ! 278: if (AmigaKey < AK_EjectDisk) { ! 279: if (NewState) ! 280: record_key (AmigaKey << 1); ! 281: else ! 282: record_key ((AmigaKey << 1) | 1); ! 283: } ! 284: ! 285: if ((KeyState[AK_CTRL] && KeyState[AK_LAMI] && KeyState[AK_RAMI]) || ! 286: (KeyState[AK_RCTRL] && KeyState[AK_LAMI] && KeyState[AK_RAMI])) ! 287: EventFlags |= EF_ResetCPU; ! 288: if (KeyState[AK_EjectDisk]) { ! 289: if (KeyState[AK_F1]) ! 290: EventFlags |= EF_EjectDisk0; ! 291: if (KeyState[AK_F2]) ! 292: EventFlags |= EF_EjectDisk1; ! 293: if (KeyState[AK_F3]) ! 294: EventFlags |= EF_EjectDisk2; ! 295: if (KeyState[AK_F4]) ! 296: EventFlags |= EF_EjectDisk3; ! 297: } ! 298: if (KeyState[AK_ChangeDisk]) { ! 299: if (KeyState[AK_F1]) ! 300: EventFlags |= EF_ChangeDisk0; ! 301: if (KeyState[AK_F2]) ! 302: EventFlags |= EF_ChangeDisk1; ! 303: if (KeyState[AK_F3]) ! 304: EventFlags |= EF_ChangeDisk2; ! 305: if (KeyState[AK_F4]) ! 306: EventFlags |= EF_ChangeDisk3; ! 307: if (KeyState[AK_F6]) ! 308: EventFlags |= EF_EnterDebug; ! 309: } ! 310: if (KeyState[AK_TougleScreen]) ! 311: EventFlags |= EF_TougleScreen; ! 312: if (KeyState[AK_SaveScreen1] && KeyState[AK_SaveScreen2]) ! 313: EventFlags |= EF_SaveScreen; ! 314: if (KeyState[AK_QuitProgram]) ! 315: EventFlags |= EF_QuitProgram; ! 316: } ! 317: ! 318: int InstallKeyboardHandler(void) { ! 319: int i; ! 320: ! 321: if (KeyBoardInstalled) ! 322: return(1); ! 323: _go32_dpmi_get_protected_mode_interrupt_vector(9, &OldKeyboardHandler); ! 324: NewKeyboardHandler.pm_offset = (int)KeyboardHandler; ! 325: if (_go32_dpmi_allocate_iret_wrapper(&NewKeyboardHandler) != 0) { ! 326: printf ("Can't allocate keyboard iret_wrapper.\n"); ! 327: return(0); ! 328: } ! 329: if (_go32_dpmi_set_protected_mode_interrupt_vector(9, &NewKeyboardHandler) != 0) { ! 330: printf ("Can't set protected mode interrupt vector.\n"); ! 331: return(0); ! 332: } ! 333: for(i = 0; i < 256; i++) ! 334: KeyState[i] = 0; ! 335: _go32_dpmi_lock_code(KeyboardHandler, (unsigned int)InstallKeyboardHandler-(unsigned int)KeyboardHandler); ! 336: _go32_dpmi_lock_data(AmigaKeys, sizeof(AmigaKeys)); ! 337: _go32_dpmi_lock_data(EscapeKeys, sizeof(EscapeKeys)); ! 338: _go32_dpmi_lock_data(KeyState, sizeof(KeyState)); ! 339: _go32_dpmi_lock_data(&EventFlags, sizeof(EventFlags)); ! 340: _go32_dpmi_lock_data(&OldKeyboardHandler, sizeof(OldKeyboardHandler)); ! 341: _go32_dpmi_lock_data(&NewKeyboardHandler, sizeof(NewKeyboardHandler)); ! 342: _go32_dpmi_lock_code(record_key, (unsigned int)keybuf_init-(unsigned int)record_key); ! 343: _go32_dpmi_lock_data(&kpb_first, sizeof(kpb_first)); ! 344: _go32_dpmi_lock_data(&kpb_last, sizeof(kpb_last)); ! 345: _go32_dpmi_lock_data(keybuf, sizeof(keybuf)); ! 346: KeyBoardInstalled = 1; ! 347: return(1); ! 348: } ! 349: ! 350: void UninstallKeyboardHandler(void) { ! 351: if (!KeyBoardInstalled) ! 352: return; ! 353: _go32_dpmi_set_protected_mode_interrupt_vector(9, &OldKeyboardHandler); ! 354: _go32_dpmi_free_iret_wrapper(&NewKeyboardHandler); ! 355: KeyBoardInstalled = 0; ! 356: } ! 357: ! 358: static void MouseHandler(_go32_dpmi_registers *MouseRegs) { ! 359: lastmx = (short)MouseRegs->x.si; ! 360: lastmy = (short)MouseRegs->x.di; ! 361: buttonstate[0] = MouseRegs->x.bx & 1; ! 362: buttonstate[1] = MouseRegs->x.bx & 4; ! 363: buttonstate[2] = MouseRegs->x.bx & 2; ! 364: } ! 365: ! 366: int InstallMouseHandler(void) { ! 367: _go32_dpmi_registers IntRegs; ! 368: ! 369: if (MouseInstalled) ! 370: return(1); ! 371: IntRegs.x.ax = 0; ! 372: IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0; ! 373: _go32_dpmi_simulate_int(0x33, &IntRegs); ! 374: if (IntRegs.x.ax==0) { ! 375: printf ("Mouse driver not present.\n"); ! 376: return(0); ! 377: } ! 378: NewMouseHandler.pm_offset = (int)MouseHandler; ! 379: if (_go32_dpmi_allocate_real_mode_callback_retf(&NewMouseHandler, &MouseCallbackRegs) != 0) { ! 380: printf ("Can't allocate mouse callback_retf.\n"); ! 381: return(0); ! 382: } ! 383: IntRegs.x.ax = 0xc; ! 384: IntRegs.x.cx = 0x7f; ! 385: IntRegs.x.es = NewMouseHandler.rm_segment; ! 386: IntRegs.x.dx = NewMouseHandler.rm_offset; ! 387: IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0; ! 388: buttonstate[0] = buttonstate[1] = buttonstate[2] = 0; ! 389: lastmx = lastmy = 0; ! 390: newmousecounters = 0; ! 391: _go32_dpmi_simulate_int(0x33, &IntRegs); ! 392: _go32_dpmi_lock_code(MouseHandler, (unsigned int)InstallMouseHandler-(unsigned int)MouseHandler); ! 393: _go32_dpmi_lock_data(&lastmx, sizeof(lastmx)); ! 394: _go32_dpmi_lock_data(&lastmy, sizeof(lastmy)); ! 395: _go32_dpmi_lock_data(buttonstate, sizeof(buttonstate)); ! 396: _go32_dpmi_lock_data(&NewMouseHandler, sizeof(NewMouseHandler)); ! 397: _go32_dpmi_lock_data(&MouseCallbackRegs, sizeof(MouseCallbackRegs)); ! 398: MouseInstalled = 1; ! 399: return(1); ! 400: } ! 401: ! 402: void UninstallMouseHandler(void) { ! 403: _go32_dpmi_registers IntRegs; ! 404: ! 405: if (!MouseInstalled) ! 406: return; ! 407: IntRegs.x.ax = 0xc; ! 408: IntRegs.x.cx = 0x0; ! 409: IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0; ! 410: _go32_dpmi_simulate_int(0x33, &IntRegs); ! 411: _go32_dpmi_free_real_mode_callback(&NewMouseHandler); ! 412: MouseInstalled = 0; ! 413: } ! 414: ! 415: ! 416: void LED(int on) { ! 417: ! 418: ScrollLockLED(!on); ! 419: ! 420: } ! 421: ! 422: void NumLockLED(int on) { ! 423: ! 424: _go32_dpmi_registers regs; ! 425: ! 426: if( NumLockState != on ) // Avoid more int's than necessary ! 427: { ! 428: if( on ) ! 429: _farnspokeb( (0x40<<4)+0x17, _farnspeekb( (0x40<<4)+0x17 ) | 32 ); ! 430: else ! 431: _farnspokeb( (0x40<<4)+0x17, _farnspeekb( (0x40<<4)+0x17 ) & ~32 ); ! 432: ! 433: regs.x.ax = 0x0100; ! 434: regs.x.ss=regs.x.sp=regs.x.flags=0; ! 435: _go32_dpmi_simulate_int(0x16, ®s); ! 436: ! 437: NumLockState = on; ! 438: } ! 439: ! 440: } ! 441: ! 442: void CapsLockLED(int on) { ! 443: ! 444: _go32_dpmi_registers regs; ! 445: ! 446: if( CapsLockState != on ) // Avoid more int's than necessary ! 447: { ! 448: if( on ) ! 449: _farnspokeb( (0x40<<4)+0x17, _farnspeekb( (0x40<<4)+0x17 ) | 64 ); ! 450: else ! 451: _farnspokeb( (0x40<<4)+0x17, _farnspeekb( (0x40<<4)+0x17 ) & ~64 ); ! 452: ! 453: regs.x.ax = 0x0100; ! 454: regs.x.ss=regs.x.sp=regs.x.flags=0; ! 455: _go32_dpmi_simulate_int(0x16, ®s); ! 456: ! 457: CapsLockState = on; ! 458: } ! 459: ! 460: } ! 461: ! 462: void ScrollLockLED(int on) { ! 463: ! 464: _go32_dpmi_registers regs; ! 465: ! 466: if( ScrollLockState != on ) // Avoid more int's than necessary ! 467: { ! 468: if( on ) ! 469: _farnspokeb( (0x40<<4)+0x17, _farnspeekb( (0x40<<4)+0x17 ) | 16 ); ! 470: else ! 471: _farnspokeb( (0x40<<4)+0x17, _farnspeekb( (0x40<<4)+0x17 ) & ~16 ); ! 472: ! 473: regs.x.ax = 0x0100; ! 474: regs.x.ss=regs.x.sp=regs.x.flags=0; ! 475: _go32_dpmi_simulate_int(0x16, ®s); ! 476: ! 477: ScrollLockState = on; ! 478: } ! 479: ! 480: } ! 481: ! 482: UBYTE InitLED(void) { ! 483: ! 484: UBYTE ubSavedLED; ! 485: ! 486: ubSavedLED = _farnspeekb( (0x40<<4)+0x17 ); // Save LED-status ! 487: ! 488: NumLockLED(0); ! 489: CapsLockLED(0); ! 490: ScrollLockLED(0); ! 491: ! 492: return(ubSavedLED); ! 493: ! 494: } ! 495: ! 496: void RestoreLEDStatus(UBYTE ubSavedLED) { ! 497: ! 498: _go32_dpmi_registers regs; ! 499: ! 500: _farnspokeb( (0x40<<4)+0x17, ubSavedLED ); ! 501: ! 502: regs.x.ax = 0x0100; ! 503: regs.x.ss=regs.x.sp=regs.x.flags=0; ! 504: _go32_dpmi_simulate_int(0x16, ®s); ! 505: ! 506: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.