|
|
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.