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/thread.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_Options 0x1fc
39 #define AK_SaveScreen1 0x1fd
40 #define AK_SaveScreen2 0x1fe
41 #define AK_TougleScreen 0x1ff
42
43 /* Event Flags */
44 #define EF_ResetCPU 0x01
45 #define EF_ChangeOptions 0x02
46 #define EF_EnterDebug 0x04
47 #define EF_SaveScreen 0x08
48 #define EF_TougleScreen 0x10
49 #define EF_TougleSound 0x20
50 #define EF_TougleCapsLock 0x40
51 #define EF_QuitProgram 0x80
52
53 extern int kpb_first, kpb_last;
54 extern int keybuf[256];
55
56 int Original_produce_sound;
57 int KeyBoardInstalled = 0, MouseInstalled = 0;
58 int EventFlags = 0;
59 int KeyState[512];
60 int buttonstate[3] = {0, 0, 0};
61 int lastmx, lastmy;
62 int newmousecounters = 0;
63 _go32_dpmi_seginfo OldKeyboardHandler, NewKeyboardHandler, NewMouseHandler;
64 _go32_dpmi_registers MouseCallbackRegs;
65 volatile int NumLockState = -1, CapsLockState = -1, ScrollLockState = -1;
66 UBYTE SavedLEDa;
67
68 int AmigaKeys[128] = {
69 -1, AK_ESC, AK_1, AK_2, AK_3, AK_4, AK_5, AK_6,
70 AK_7, AK_8, AK_9, AK_0, AK_MINUS, AK_EQUAL, AK_BS, AK_TAB,
71 AK_Q, AK_W, AK_E, AK_R, AK_T, AK_Y, AK_U, AK_I,
72 AK_O, AK_P, AK_LBRACKET, AK_RBRACKET, AK_RET, AK_CTRL, AK_A, AK_S,
73 AK_D, AK_F, AK_G, AK_H, AK_J, AK_K, AK_L, AK_SEMICOLON,
74 AK_QUOTE, AK_NUMBERSIGN, AK_LSH, AK_LTGT, AK_Z, AK_X, AK_C, AK_V,
75 AK_B, AK_N, AK_M, AK_COMMA, AK_PERIOD, AK_SLASH, AK_RSH, -1,
76 AK_LALT, AK_SPC, AK_CAPSLOCK, AK_F1, AK_F2, AK_F3, AK_F4, AK_F5,
77 AK_F6, AK_F7, AK_F8, AK_F9, AK_F10, -1, AK_TougleScreen, AK_NP7,
78 AK_NP8, AK_NP9, -1, AK_NP4, AK_NP5, AK_NP6, -1, AK_NP1,
79 AK_NP2, AK_NP3, AK_NP0, -1, -1, -1, -1, AK_BACKSLASH,
80 -1, -1, -1, -1, -1, -1, -1, -1,
81 -1, AK_RCTRL, AK_SaveScreen1, AK_SaveScreen2, AK_RALT, -1, AK_Options, AK_UP,
82 AK_RAMI, AK_LF, AK_RT, -1, AK_DN, AK_LAMI, AK_HELP, AK_DEL,
83 -1, -1, -1, -1, -1, -1, -1, -1,
84 -1, -1, -1, -1, -1, AK_LAMI, AK_RAMI, -1
85 };
86
87 unsigned char EscapeKeys[128] = {
88 0, 0, 0, 0, 0, 0, 0, 0,
89 0, 0, 0, 0, 0, 0, 0, 0,
90 0, 0, 0, 0, 0, 0, 0, 0,
91 0, 0, 0, 0, 96, 97, 0, 0,
92 0, 0, 0, 0, 0, 0, 0, 0,
93 0, 0, 98, 0, 0, 0, 0, 0,
94 0, 0, 0, 0, 0, 0, 0, 99,
95 100, 0, 0, 0, 0, 0, 0, 0,
96 0, 0, 0, 0, 0, 0, 0, 102,
97 103, 104, 0, 105, 0, 106, 0, 107,
98 108, 109, 110, 111, 0, 0, 0, 0,
99 0, 0, 0, 125, 126, 127, 0, 0,
100 0, 0, 0, 0, 0, 0, 0, 0,
101 0, 0, 0, 0, 0, 0, 0, 0,
102 0, 0, 0, 0, 0, 0, 0, 0,
103 0, 0, 0, 0, 0, 0, 0, 0,
104 };
105
InstallHandlers(void)106 int InstallHandlers(void) {
107 if (!KeyBoardInstalled)
108 if (!InstallKeyboardHandler())
109 return(0);
110 if (!MouseInstalled)
111 if (!InstallMouseHandler())
112 return(0);
113 SavedLEDa = InitLED();
114 return(1);
115 }
116
UninstallHandlers(void)117 void UninstallHandlers(void) {
118 if (KeyBoardInstalled)
119 UninstallKeyboardHandler();
120 if (MouseInstalled)
121 UninstallMouseHandler();
122 RestoreLEDStatus(SavedLEDa);
123 }
124
handle_events(void)125 void handle_events(void) {
126 if (EventFlags) {
127 if (EventFlags & EF_ResetCPU) {
128 m68k_reset();
129 EventFlags &= ~EF_ResetCPU;
130 }
131 if (EventFlags & EF_ChangeOptions) {
132 HandleOptions();
133 KeyState[AK_Options] = 0;
134 KeyState[AK_F1] = 0;
135 record_key ((AK_F1 << 1) | 1);
136 EventFlags &= ~EF_ChangeOptions;
137 }
138 if (EventFlags & EF_EnterDebug) {
139 EnterDebug();
140 EventFlags &= ~EF_EnterDebug;
141 }
142 if (EventFlags & EF_SaveScreen) {
143 SaveScreen();
144 EventFlags &= ~EF_SaveScreen;
145 }
146 if (EventFlags & EF_TougleScreen) {
147 inhibit_frame ^= 1;
148 EventFlags &= ~EF_TougleScreen;
149 }
150 if (EventFlags & EF_TougleSound) {
151 if (currprefs.produce_sound == 0)
152 currprefs.produce_sound = Original_produce_sound;
153 else
154 currprefs.produce_sound = 0;
155 EventFlags &= ~EF_TougleSound;
156 }
157 if (EventFlags & EF_TougleCapsLock) {
158 CapsLockLED(!CapsLockState);
159 EventFlags &= ~EF_TougleCapsLock;
160 }
161 if (EventFlags & EF_QuitProgram) {
162 regs.spcflags |= SPCFLAG_BRK;
163 quit_program = 1;
164 EventFlags &= ~EF_QuitProgram;
165 }
166 }
167 #ifdef PICASSO96
168 PicassoRefresh();
169 #endif
170 }
171
KeyboardHandler(void)172 static void KeyboardHandler(void) {
173 static int IsEscape = 0, CapsLockCanChange = 1;
174 int ScanCode, NewState, AmigaKey;
175
176 ScanCode = inportb(0x60);
177
178 if (ScanCode == 0xe0) {
179 IsEscape = 1;
180 outportb(0x20, 0x20);
181 return;
182 }
183
184 /* PAUSE Key */
185 if (IsEscape > 1) {
186 IsEscape++;
187 if (IsEscape == 7) {
188 EventFlags |= EF_TougleSound;
189 IsEscape = 0;
190 }
191 outportb(0x20, 0x20);
192 return;
193 }
194 if (ScanCode == 0xe1) {
195 IsEscape = 2;
196 outportb(0x20, 0x20);
197 return;
198 }
199
200 NewState = !(ScanCode & 0x80);
201 ScanCode = ScanCode & 0x7f;
202 if (IsEscape) {
203 ScanCode = EscapeKeys[ScanCode];
204 IsEscape = 0;
205 }
206 outportb(0x20, 0x20);
207
208 AmigaKey = AmigaKeys[ScanCode];
209
210 if (AmigaKey == -1)
211 return;
212
213 if (AmigaKey == AK_CAPSLOCK) {
214 if (NewState) {
215 if (CapsLockCanChange) {
216 NewState = !KeyState[AmigaKey];
217 CapsLockCanChange = 0;
218 } else
219 return;
220 } else {
221 CapsLockCanChange = 1;
222 return;
223 }
224 EventFlags |= EF_TougleCapsLock;
225 }
226
227 if (KeyState[AmigaKey] == NewState)
228 return;
229 KeyState[AmigaKey] = NewState;
230
231 if (AmigaKey < AK_Options) {
232 if (NewState)
233 record_key (AmigaKey << 1);
234 else
235 record_key ((AmigaKey << 1) | 1);
236 }
237
238 if ((KeyState[AK_CTRL] && KeyState[AK_LAMI] && KeyState[AK_RAMI]) ||
239 (KeyState[AK_RCTRL] && KeyState[AK_LAMI] && KeyState[AK_RAMI]))
240 EventFlags |= EF_ResetCPU;
241 if (KeyState[AK_Options]) {
242 if (KeyState[AK_ESC])
243 EventFlags |= EF_QuitProgram;
244 if (KeyState[AK_F1])
245 EventFlags |= EF_ChangeOptions;
246 if (KeyState[AK_F2])
247 EventFlags |= EF_EnterDebug;
248 }
249 if (KeyState[AK_TougleScreen])
250 EventFlags |= EF_TougleScreen;
251 if (KeyState[AK_SaveScreen1] && KeyState[AK_SaveScreen2])
252 EventFlags |= EF_SaveScreen;
253 }
254
InstallKeyboardHandler(void)255 int InstallKeyboardHandler(void) {
256 int i;
257
258 if (KeyBoardInstalled)
259 return(1);
260 _go32_dpmi_get_protected_mode_interrupt_vector(9, &OldKeyboardHandler);
261 NewKeyboardHandler.pm_offset = (int)KeyboardHandler;
262 if (_go32_dpmi_allocate_iret_wrapper(&NewKeyboardHandler) != 0) {
263 printf ("Can't allocate keyboard iret_wrapper.\n");
264 return(0);
265 }
266 if (_go32_dpmi_set_protected_mode_interrupt_vector(9, &NewKeyboardHandler) != 0) {
267 printf ("Can't set protected mode interrupt vector.\n");
268 return(0);
269 }
270 for(i = 0; i < 256; i++)
271 KeyState[i] = 0;
272 _go32_dpmi_lock_code(KeyboardHandler, (unsigned int)InstallKeyboardHandler-(unsigned int)KeyboardHandler);
273 _go32_dpmi_lock_data(AmigaKeys, sizeof(AmigaKeys));
274 _go32_dpmi_lock_data(EscapeKeys, sizeof(EscapeKeys));
275 _go32_dpmi_lock_data(KeyState, sizeof(KeyState));
276 _go32_dpmi_lock_data(&EventFlags, sizeof(EventFlags));
277 _go32_dpmi_lock_data(&OldKeyboardHandler, sizeof(OldKeyboardHandler));
278 _go32_dpmi_lock_data(&NewKeyboardHandler, sizeof(NewKeyboardHandler));
279 _go32_dpmi_lock_code(record_key, (unsigned int)keybuf_init-(unsigned int)record_key);
280 _go32_dpmi_lock_data(&kpb_first, sizeof(kpb_first));
281 _go32_dpmi_lock_data(&kpb_last, sizeof(kpb_last));
282 _go32_dpmi_lock_data(keybuf, sizeof(keybuf));
283 KeyBoardInstalled = 1;
284 return(1);
285 }
286
UninstallKeyboardHandler(void)287 void UninstallKeyboardHandler(void) {
288 if (!KeyBoardInstalled)
289 return;
290 _go32_dpmi_set_protected_mode_interrupt_vector(9, &OldKeyboardHandler);
291 _go32_dpmi_free_iret_wrapper(&NewKeyboardHandler);
292 KeyBoardInstalled = 0;
293 }
294
MouseHandler(_go32_dpmi_registers * MouseRegs)295 static void MouseHandler(_go32_dpmi_registers *MouseRegs) {
296 lastmx = (short)MouseRegs->x.si;
297 lastmy = (short)MouseRegs->x.di;
298 buttonstate[0] = MouseRegs->x.bx & 1;
299 buttonstate[1] = MouseRegs->x.bx & 4;
300 buttonstate[2] = MouseRegs->x.bx & 2;
301 }
302
InstallMouseHandler(void)303 int InstallMouseHandler(void) {
304 _go32_dpmi_registers IntRegs;
305
306 if (MouseInstalled)
307 return(1);
308 IntRegs.x.ax = 0;
309 IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0;
310 _go32_dpmi_simulate_int(0x33, &IntRegs);
311 if (IntRegs.x.ax==0) {
312 printf ("Mouse driver not present.\n");
313 return(0);
314 }
315 NewMouseHandler.pm_offset = (int)MouseHandler;
316 if (_go32_dpmi_allocate_real_mode_callback_retf(&NewMouseHandler, &MouseCallbackRegs) != 0) {
317 printf ("Can't allocate mouse callback_retf.\n");
318 return(0);
319 }
320 IntRegs.x.ax = 0xc;
321 IntRegs.x.cx = 0x7f;
322 IntRegs.x.es = NewMouseHandler.rm_segment;
323 IntRegs.x.dx = NewMouseHandler.rm_offset;
324 IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0;
325 buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
326 lastmx = lastmy = 0;
327 newmousecounters = 0;
328 _go32_dpmi_simulate_int(0x33, &IntRegs);
329 _go32_dpmi_lock_code(MouseHandler, (unsigned int)InstallMouseHandler-(unsigned int)MouseHandler);
330 _go32_dpmi_lock_data(&lastmx, sizeof(lastmx));
331 _go32_dpmi_lock_data(&lastmy, sizeof(lastmy));
332 _go32_dpmi_lock_data(buttonstate, sizeof(buttonstate));
333 _go32_dpmi_lock_data(&NewMouseHandler, sizeof(NewMouseHandler));
334 _go32_dpmi_lock_data(&MouseCallbackRegs, sizeof(MouseCallbackRegs));
335 MouseInstalled = 1;
336 return(1);
337 }
338
UninstallMouseHandler(void)339 void UninstallMouseHandler(void) {
340 _go32_dpmi_registers IntRegs;
341
342 if (!MouseInstalled)
343 return;
344 IntRegs.x.ax = 0xc;
345 IntRegs.x.cx = 0x0;
346 IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0;
347 _go32_dpmi_simulate_int(0x33, &IntRegs);
348 _go32_dpmi_free_real_mode_callback(&NewMouseHandler);
349 MouseInstalled = 0;
350 }
351
352
LED(int on)353 void LED(int on) {
354
355 ScrollLockLED(!on);
356
357 }
358
NumLockLED(int on)359 void NumLockLED(int on) {
360
361 _go32_dpmi_registers regs;
362
363 if( NumLockState != on ) // Avoid more int's than necessary
364 {
365 if( on )
366 _farnspokeb( (0x40<<4)+0x17, _farnspeekb( (0x40<<4)+0x17 ) | 32 );
367 else
368 _farnspokeb( (0x40<<4)+0x17, _farnspeekb( (0x40<<4)+0x17 ) & ~32 );
369
370 regs.x.ax = 0x0100;
371 regs.x.ss=regs.x.sp=regs.x.flags=0;
372 _go32_dpmi_simulate_int(0x16, ®s);
373
374 NumLockState = on;
375 }
376
377 }
378
CapsLockLED(int on)379 void CapsLockLED(int on) {
380
381 _go32_dpmi_registers regs;
382
383 if( CapsLockState != on ) // Avoid more int's than necessary
384 {
385 if( on )
386 _farnspokeb( (0x40<<4)+0x17, _farnspeekb( (0x40<<4)+0x17 ) | 64 );
387 else
388 _farnspokeb( (0x40<<4)+0x17, _farnspeekb( (0x40<<4)+0x17 ) & ~64 );
389
390 regs.x.ax = 0x0100;
391 regs.x.ss=regs.x.sp=regs.x.flags=0;
392 _go32_dpmi_simulate_int(0x16, ®s);
393
394 CapsLockState = on;
395 }
396
397 }
398
ScrollLockLED(int on)399 void ScrollLockLED(int on) {
400
401 _go32_dpmi_registers regs;
402
403 if( ScrollLockState != on ) // Avoid more int's than necessary
404 {
405 if( on )
406 _farnspokeb( (0x40<<4)+0x17, _farnspeekb( (0x40<<4)+0x17 ) | 16 );
407 else
408 _farnspokeb( (0x40<<4)+0x17, _farnspeekb( (0x40<<4)+0x17 ) & ~16 );
409
410 regs.x.ax = 0x0100;
411 regs.x.ss=regs.x.sp=regs.x.flags=0;
412 _go32_dpmi_simulate_int(0x16, ®s);
413
414 ScrollLockState = on;
415 }
416
417 }
418
InitLED(void)419 UBYTE InitLED(void) {
420
421 UBYTE ubSavedLED;
422
423 ubSavedLED = _farnspeekb( (0x40<<4)+0x17 ); // Save LED-status
424
425 NumLockLED(0);
426 CapsLockLED(0);
427 ScrollLockLED(0);
428
429 return(ubSavedLED);
430
431 }
432
RestoreLEDStatus(UBYTE ubSavedLED)433 void RestoreLEDStatus(UBYTE ubSavedLED) {
434
435 _go32_dpmi_registers regs;
436
437 _farnspokeb( (0x40<<4)+0x17, ubSavedLED );
438
439 regs.x.ax = 0x0100;
440 regs.x.ss=regs.x.sp=regs.x.flags=0;
441 _go32_dpmi_simulate_int(0x16, ®s);
442
443 }
444