1 /** ADAMEm: Coleco ADAM emulator ********************************************/
2 /** **/
3 /** MSDOS.c **/
4 /** **/
5 /** This file contains generic MS-DOS specific routines. It does not **/
6 /** include the sound emulation code **/
7 /** **/
8 /** Copyright (C) Marcel de Kogel 1996,1997,1998,1999 **/
9 /** You are not allowed to distribute this software commercially **/
10 /** Please, notify me, if you make any changes to this file **/
11 /****************************************************************************/
12
13 #include "Coleco.h"
14 #include "MSDOS.h"
15 #include "Bitmap.h"
16 #include "INT.h"
17 #include "Asm.h"
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <signal.h>
23 #include <sys/time.h>
24 #include <sys/farptr.h>
25 #include <go32.h>
26 #include <dpmi.h>
27 #include <pc.h>
28 #include <dos.h>
29 #include <crt0.h>
30 #include <math.h>
31 #include <conio.h>
32
33 /* Title for -help output */
34 char Title[]="ADAMEm MS-DOS 1.0";
35
36 #define NUM_STACKS 8 /* Number of IRQ stacks */
37 #define STACK_SIZE 16384 /* Stack size */
38
39 /* DJGPP startup flags */
40 int _crt0_startup_flags = _CRT0_FLAG_NONMOVE_SBRK | _CRT0_FLAG_LOCK_MEMORY;
41
42 /* Key mapping */
43 static int KEY_LEFT,KEY_RIGHT,KEY_UP,KEY_DOWN,
44 KEY_BUTTONA,KEY_BUTTONB,KEY_BUTTONC,KEY_BUTTOND;
45
46 /* Current VGA palette */
47 static byte VGA_Palette[17*3];
48
49 static byte PalBuf[16]; /* Palette buffer */
50 static int default_mouse_sens=200;/* Default mouse sensitivity */
51 static int keyboardmode; /* 0=joystick, 1=keyboard */
52 static word MouseJoyState[2]; /* Current mouse status */
53 static word JoystickJoyState[2]; /* Current joystick status */
54 static int nOldVideoMode; /* Videomode when ADAMem was started */
55 static unsigned font2screen[16*16*16];
56 /* Used by screen refresh driver */
57 #ifdef DEBUG
58 static int dumpram=0;
59 #endif
60 static int makeshot=0; /* 1 if screen shot should be taken */
61 static int makesnap=0; /* 1 if snapshot should be written */
62 static int OldTimer=0; /* Last value of timer */
63 static int NewTimer=0; /* New value of timer */
64 static int calloptions=0; /* If 1, OptionsDialogue() is called */
65 static int in_options_dialogue=0; /* If 1, chain to old keyboard IRQ handler*/
66 static int SwitchVideoMode=0; /* If 1, switch video mode in Keyboard() */
67
68 word cs_alias; /* Our data selector */
69 word DosSelector; /* Selector of DOS memory */
70 byte DisplayBuf[WIDTH*HEIGHT]; /* Screen buffer */
71 char szBitmapFile[256]; /* Next screen shot file */
72 char szSnapshotFile[256]; /* Next snapshot file */
73 char szJoystickFileName[256]; /* File holding joystick information */
74 char *szKeys="CBCDC8D0381D2A2C"; /* Key scancodes */
75 int mouse_sens=200; /* Mouse sensitivity */
76 int keypadmode=0; /* 1 if keypad should be reversed */
77 int joystick=1; /* Joystick support */
78 int calibrate=0; /* Set to 1 to force joystick calibration */
79 int swapbuttons=0; /* 1=joystick, 2=keyboard, 4=mouse */
80 int expansionmode=0; /* Expansion module emulated */
81 int useoverscan=1; /* Overscan colour support */
82 int videomode=0; /* 0=320x200 1=256x192 */
83 int syncemu=1; /* 0 - Don't sync emulation */
84 /* 1 - Sync emulation to PC timer */
85 int Text80; /* 1 if in Text80 mode */
86 int Text80Colour; /* Text80 foreground colour */
87 int AutoText80; /* 1 if auto-switch to Text80 mode on */
88
89 /****************************************************************************/
90 /** VGA routines **/
91 /****************************************************************************/
VGA_SetPalette(int n,unsigned char * pal)92 static void VGA_SetPalette (int n,unsigned char *pal)
93 {
94 int i;
95 __disable ();
96 while ((inportb(0x3DA)&0x08)!=0);/* Wait until vertical retrace is off */
97 while ((inportb(0x3DA)&0x08)==0);/* Now wait until it is on */
98 outportb (0x3C8,0); /* Start updating palette */
99 for (i=0;i<n*3;++i)
100 outportb(0x3C9,pal[i]/4);
101 __enable ();
102 }
103
VGA_Reset(void)104 static void VGA_Reset (void) /* Reset old video mode */
105 {
106 __dpmi_regs r;
107 r.x.ax=(short)nOldVideoMode;
108 __dpmi_int (0x10, &r);
109 }
110
VGA_SetTweakMode(int mode)111 static void VGA_SetTweakMode (int mode)
112 {
113 static const byte crtc_regs_1[25]=
114 {
115 0x63,
116 0x4F,0x3F,0x40,0x92,
117 0x44,0x10,0xAF,0x1F,
118 0x00,0x41,0x00,0x00,
119 0x00,0x00,0x00,0x00,
120 0x8C,0x8E,0x7F,0x20,
121 0x40,0x86,0xA9,0xA3
122 };
123 static const byte crtc_regs_2[25]=
124 {
125 0xE3,
126 0x4F,0x3F,0x40,0x92,
127 0x44,0x10,0x0D,0x3E,
128 0x00,0x41,0x00,0x00,
129 0x00,0x00,0x00,0x00,
130 0xEA,0xAC,0xDF,0x20,
131 0x40,0xE7,0x06,0xA3
132 };
133 static const char *crtc_regs;
134 int i;
135 crtc_regs=(mode)? crtc_regs_2 : crtc_regs_1;
136 __disable ();
137 while (inportb(0x3DA)&8);
138 while ((inportb(0x3DA)&8)==0);
139 outportw (0x3C4,0x100); /* sequencer reset */
140 outportb (0x3C2,*crtc_regs++); /* misc. output reg */
141 outportw (0x3C4,0x300); /* clear sequencer reset */
142 outportw (0x3D4,((crtc_regs[0x11]&0x7F)<<8)+0x11); /* deprotect regs 0-7 */
143 for (i=0;i<24;++i)
144 outportw (0x3D4,(crtc_regs[i]<<8)+i);
145 __enable ();
146 }
147
VGA_SetBkColour(unsigned char colour)148 static void VGA_SetBkColour (unsigned char colour)
149 {
150 static int currbkcol=-1;
151 if (currbkcol==colour)
152 return;
153 currbkcol=colour;
154 VGA_Palette[0]=VGA_Palette[3]=Coleco_Palette[colour*3+0];
155 VGA_Palette[1]=VGA_Palette[4]=Coleco_Palette[colour*3+1];
156 VGA_Palette[2]=VGA_Palette[5]=Coleco_Palette[colour*3+2];
157 __disable ();
158 while (inportb(0x3DA)&8);
159 while ((inportb(0x3DA)&8)==0);
160 if (useoverscan || Text80)
161 {
162 outportb (0x3C8,0);
163 outportb (0x3C9,VGA_Palette[0]/4);
164 outportb (0x3C9,VGA_Palette[1]/4);
165 outportb (0x3C9,VGA_Palette[2]/4);
166 }
167 if (!Text80)
168 {
169 outportb (0x3C8,1);
170 outportb (0x3C9,VGA_Palette[3]/4);
171 outportb (0x3C9,VGA_Palette[4]/4);
172 outportb (0x3C9,VGA_Palette[5]/4);
173 }
174 __enable ();
175 }
176
VGA_Init(void)177 static int VGA_Init (void) /* Get old mode and set mode 13h */
178 {
179 __dpmi_regs r;
180 r.x.ax=0x0F00;
181 __dpmi_int (0x10,&r);
182 nOldVideoMode=(int)(r.h.al & 0x7F);
183 r.x.ax=0x0013;
184 __dpmi_int (0x10,&r);
185 if (videomode)
186 VGA_SetTweakMode (videomode-1);
187 VGA_SetPalette (17,VGA_Palette);
188 return 1;
189 }
190
PutImage(void)191 static void PutImage (void)
192 {
193 if (Text80)
194 {
195 int i,b1,b2;
196 _farsetsel (DosSelector);
197 b1=Text80Colour;
198 b2=Text80Colour<<4;
199 for (i=0;i<80*24;++i)
200 {
201 byte c;
202 c=DisplayBuf[i];
203 _farnspokeb (0xB8000+i*2,c&127);
204 _farnspokeb (0xB8001+i*2,(c&128)? b2:b1);
205 }
206 }
207 else
208 PutImage_Asm ();
209 }
210
InitText80(void)211 void InitText80 (void)
212 {
213 __dpmi_regs r;
214 r.x.ax=3; /* Set 80x25 text mode */
215 __dpmi_int (0x10, &r);
216 r.h.ah=1; /* Turn off cursor */
217 r.x.cx=0x0F00;
218 __dpmi_int (0x10, &r);
219 VGA_SetPalette (16,VGA_Palette+3); /* Set palette */
220 Text80=1;
221 RefreshScreen(1); /* Force a screen refresh */
222 }
223
ResetText80(void)224 void ResetText80 (void)
225 {
226 VGA_Init ();
227 Text80=0;
228 RefreshScreen(1);
229 }
230
231 /****************************************************************************/
232 /** Keyboard routines **/
233 /****************************************************************************/
234 static __volatile__ int PausePressed=0;
235 static __volatile__ byte keybstatus[256];
236 static _go32_dpmi_seginfo keybirq;
237
238 static byte keyboard_buffer[16];
239 static int keyboard_buffer_count=0;
LocalAddToKeyboardBuffer(byte ch)240 static void LocalAddToKeyboardBuffer (byte ch)
241 {
242 keyboard_buffer[keyboard_buffer_count]=ch;
243 keyboard_buffer_count=(keyboard_buffer_count+1)&15;
244 keyboard_buffer[keyboard_buffer_count]=0;
245 }
LocalGetKeyboardChar(void)246 static int LocalGetKeyboardChar (void)
247 {
248 int retval;
249 keyboard_buffer_count=(keyboard_buffer_count-1)&15;
250 retval=keyboard_buffer[keyboard_buffer_count];
251 keyboard_buffer[keyboard_buffer_count]=0;
252 return retval;
253 }
254
255 static const byte scan2ascii[256] =
256 {
257 0,27,'1','2','3','4','5','6','7','8','9','0','-','=',8,
258 9,'q','w','e','r','t','y','u','i','o','p','[',']',13,
259 0,'a','s','d','f','g','h','j','k','l',';',39,'`',
260 0,92,'z','x','c','v','b','n','m',',','.','/',0,
261 '*',0,' ',0,129,130,131,132,133,134,144,145,0,0,
262 0,0,171,160,168,'-',163,128,161,'+',170,162,169,148,151,
263 0,0,0,0,0,0,0,0,0,0,0,0,
264 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
265 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
266 /* extended keys */
267 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
268 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
269 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
270 0,0,0,0,0,'/',0,0,0,0,0,0,0,0,0,0,
271 0,0,0,0,0,0,0,146,160,150,0,163,0,161,0,147,
272 162,149,148,151,0,0,0,0,0,0,0,0,0,0,0,0,
273 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
274 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
275 };
276 static const byte scan2ascii_shift[256] =
277 {
278 0,27,'!','@','#','$','%','^','&','*','(',')','_','+',184,
279 185,'Q','W','E','R','T','Y','U','I','O','P','{','}',13,
280 0,'A','S','D','F','G','H','J','K','L',':',34,'~',
281 0,'|','Z','X','C','V','B','N','M','<','>','?',0,
282 '*',0,' ',0,137,138,139,140,141,142,152,153,0,0,
283 0,0,0,0,0,'-',0,0,0,'+',0,0,0,156,159,
284 0,0,0,0,0,0,0,0,0,0,0,0,
285 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
286 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
287 /* extended keys */
288 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
289 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
290 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
291 0,0,0,0,0,'/',0,0,0,0,0,0,0,0,0,0,
292 0,0,0,0,0,0,0,154,0,158,0,0,0,0,0,155,
293 0,157,156,159,0,0,0,0,0,0,0,0,0,0,0,0,
294 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
295 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
296 };
297 static const byte scan2ascii_ctrl[256] =
298 {
299 0,27,0,255,0,0,0,30,0,0,0,0,31,0,127,
300 0,17,23,5,18,20,25,21,9,15,16,27,29,13,
301 0,1,19,4,6,7,8,10,11,12,0,0,0,
302 0,28,26,24,3,22,2,14,13,0,0,0,0,
303 0,0,32,0,0,0,0,0,0,0,0,0,0,0,
304 0,0,0,164,0,0,167,0,165,0,0,166,0,0,0,
305 0,0,0,0,0,0,0,0,0,0,0,0,
306 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
307 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
308 /* extended keys */
309 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
310 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
311 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
312 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
313 0,0,0,0,0,0,0,0,164,0,0,167,0,165,0,0,
314 166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
315 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
316 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
317 };
AltPressed(void)318 static inline int AltPressed (void)
319 {
320 return keybstatus[VK_Alt]||keybstatus[VK_Alt+128];
321 }
CtrlPressed(void)322 static inline int CtrlPressed (void)
323 {
324 return keybstatus[VK_Ctrl]||keybstatus[VK_Ctrl+128];
325 }
keyb_interrupt(void)326 static int keyb_interrupt (void)
327 {
328 unsigned code;
329 static int extkey;
330 static int CapsLock=0;
331 code=inportb (0x60); /* get scancode */
332 if (code<0xE0) /* ignore codes >0xE0 */
333 {
334 if (code & 0x80) /* key is released */
335 {
336 code&=0x7F;
337 if (extkey)
338 keybstatus[code+128]=0;
339 else
340 keybstatus[code]=0;
341 }
342 else /* key is pressed */
343 {
344 if (extkey)
345 {
346 if (!keybstatus[code+128])
347 {
348 keybstatus[code+128]=1;
349 if (in_options_dialogue) /* jump to old interrupt handler */
350 return 1;
351 PausePressed=0;
352 switch (code)
353 {
354 case VK_Insert:
355 if (!keyboardmode || AltPressed())
356 joystick=1;
357 break;
358 case VK_Home:
359 if (!keyboardmode || AltPressed())
360 joystick=2;
361 break;
362 case VK_PageUp:
363 if (!keyboardmode || AltPressed())
364 joystick=3;
365 break;
366 case VK_Del:
367 if (!keyboardmode || AltPressed())
368 swapbuttons^=1;
369 break;
370 case VK_End:
371 if (!keyboardmode || AltPressed())
372 swapbuttons^=2;
373 break;
374 case VK_PageDown:
375 if (!keyboardmode || AltPressed())
376 swapbuttons^=4;
377 break;
378 }
379 }
380 }
381 else
382 {
383 if (!keybstatus[code])
384 {
385 keybstatus[code]=1;
386 if (in_options_dialogue)
387 return 1;
388 if (CtrlPressed() &&
389 (code==VK_F11 || code==VK_F12))
390 {
391 if (code==VK_F11)
392 PausePressed=2;
393 else
394 PausePressed=1;
395 }
396 else
397 PausePressed=0;
398 switch (code)
399 {
400 case VK_CapsLock:
401 CapsLock^=1;
402 break;
403 case VK_F1:
404 if (!keyboardmode || AltPressed())
405 ToggleSoundChannel (0);
406 break;
407 case VK_F2:
408 if (!keyboardmode || AltPressed())
409 ToggleSoundChannel (1);
410 break;
411 case VK_F3:
412 if (!keyboardmode || AltPressed())
413 ToggleSoundChannel (2);
414 break;
415 case VK_F4:
416 if (!keyboardmode || AltPressed())
417 ToggleSoundChannel (3);
418 break;
419 case VK_F5:
420 if (!keyboardmode || AltPressed())
421 ToggleSound ();
422 break;
423 case VK_F11:
424 if (!PausePressed && !AltPressed())
425 DecreaseSoundVolume ();
426 break;
427 case VK_F12:
428 if (!PausePressed && !AltPressed())
429 IncreaseSoundVolume ();
430 break;
431 case VK_F10:
432 Z80_Running=0;
433 break;
434 case VK_F7:
435 #ifdef DEBUG
436 if (CtrlPressed())
437 {
438 Z80_Trace=!Z80_Trace;
439 break;
440 }
441 #endif
442 if (!keyboardmode || AltPressed())
443 makesnap=1;
444 break;
445 case VK_F8:
446 #ifdef DEBUG
447 if (CtrlPressed())
448 dumpram=1;
449 else
450 #endif
451 if (!keyboardmode || AltPressed())
452 makeshot=1;
453 break;
454 case VK_F9:
455 if (EmuMode)
456 {
457 if (AltPressed())
458 SwitchVideoMode=1;
459 else
460 if (CtrlPressed())
461 calloptions=1;
462 else
463 keyboardmode=(keyboardmode)? 0:1;
464 }
465 break;
466 }
467 }
468 }
469 if (keyboardmode && !AltPressed()) /* Modify keyboard buffer */
470 {
471 /* Check for HOME+Cursor key and Cursor key combinations */
472 if (code==VK_NumPad5 && !extkey)
473 {
474 if (keybstatus[VK_Left] ||
475 keybstatus[VK_Left+128]) { code=175; goto put_char_in_buf; }
476 if (keybstatus[VK_Right] ||
477 keybstatus[VK_Right+128]) { code=173; goto put_char_in_buf; }
478 if (keybstatus[VK_Up] ||
479 keybstatus[VK_Up+128]) { code=172; goto put_char_in_buf; }
480 if (keybstatus[VK_Down] ||
481 keybstatus[VK_Down+128]) { code=170; goto put_char_in_buf; }
482 }
483 if (keybstatus[VK_NumPad5])
484 {
485 if (code==VK_Left) { code=175; goto put_char_in_buf; }
486 if (code==VK_Right) { code=173; goto put_char_in_buf; }
487 if (code==VK_Up) { code=172; goto put_char_in_buf; }
488 if (code==VK_Down) { code=170; goto put_char_in_buf; }
489 }
490 if (code==VK_Up)
491 {
492 if (keybstatus[VK_Right] ||
493 keybstatus[VK_Right+128]) { code=168; goto put_char_in_buf; }
494 if (keybstatus[VK_Left] ||
495 keybstatus[VK_Left+128]) { code=171; goto put_char_in_buf; }
496 }
497 if (code==VK_Right)
498 {
499 if (keybstatus[VK_Up] ||
500 keybstatus[VK_Up+128]) { code=168; goto put_char_in_buf; }
501 if (keybstatus[VK_Down] ||
502 keybstatus[VK_Down+128]) { code=169; goto put_char_in_buf; }
503 }
504 if (code==VK_Down)
505 {
506 if (keybstatus[VK_Right] ||
507 keybstatus[VK_Right+128]) { code=169; goto put_char_in_buf; }
508 if (keybstatus[VK_Left] ||
509 keybstatus[VK_Left+128]) { code=170; goto put_char_in_buf; }
510 }
511 if (code==VK_Left)
512 {
513 if (keybstatus[VK_Up] ||
514 keybstatus[VK_Up+128]) { code=171; goto put_char_in_buf; }
515 if (keybstatus[VK_Down] ||
516 keybstatus[VK_Down+128]) { code=170; goto put_char_in_buf; }
517 }
518 if (extkey) code+=128;
519 if (keybstatus[VK_Ctrl] || keybstatus[VK_Ctrl+128])
520 code=scan2ascii_ctrl[code];
521 else if (keybstatus[VK_RightShift] || keybstatus[VK_LeftShift])
522 code=scan2ascii_shift[code];
523 else
524 code=scan2ascii[code];
525 put_char_in_buf:
526 if (CapsLock)
527 {
528 if (code>='a' && code<='z') code+='A'-'a';
529 else if (code>='A' && code<='Z') code+='a'-'A';
530 }
531 if (code) LocalAddToKeyboardBuffer (code);
532 }
533 }
534 extkey=0;
535 }
536 else
537 if (code==0xE0)
538 extkey=1;
539 if (in_options_dialogue)
540 return 1;
541 code=inportb (0x61); /* acknowledge interrupt */
542 outportb (0x61,code | 0x80);
543 outportb (0x61,code);
544 outportb (0x20,0x20);
545 return 0; /* Do not chain to old handler */
546 }
547
Keyb_Init(void)548 static int Keyb_Init (void) /* get old handler and install our own */
549 {
550 keybirq.pm_offset=(int)keyb_interrupt;
551 keybirq.pm_selector=_go32_my_cs();
552 SetInt (9,&keybirq);
553 return 1;
554 }
555
Keyb_Reset(void)556 static void Keyb_Reset (void) /* install the old handler */
557 {
558 ResetInt (9,&keybirq);
559 }
560
561 /****************************************************************************/
562 /** Mouse routines **/
563 /****************************************************************************/
564 static _go32_dpmi_seginfo mouse_seginfo;
565 static _go32_dpmi_registers mouse_regs;
566 static int mouse_buttons=0; /* mouse buttons pressed */
567 static int mouse_xpos=500; /* horizontal position (0 - 1000) */
568 static int mouse_ypos=500; /* vertical position (0 - 1000) */
569 static int mouse_x=0; /* horizontal position (-500 - 500) */
570 static int mouse_y=0; /* vertical position (-500 - 500) */
571 static int got_mouse=0; /* 1 if mouse was properly initialised */
572
Mouse_SetJoyState()573 static void Mouse_SetJoyState ()
574 {
575 if (mouse_buttons&1)
576 MouseJoyState[0]&=0xBFFF;
577 if (mouse_buttons&2)
578 MouseJoyState[0]&=0xFFBF;
579 if (mouse_buttons&4)
580 MouseJoyState[1]&=0xBFFF;
581 if (mouse_buttons&8)
582 MouseJoyState[1]&=0xFFBF;
583 SpinnerPosition[0]=(default_mouse_sens*mouse_x*(abs(mouse_x)+mouse_sens))/
584 (mouse_sens*mouse_sens);
585 SpinnerPosition[1]=(default_mouse_sens*mouse_y*(abs(mouse_y)+mouse_sens))/
586 (mouse_sens*mouse_sens);
587 }
588
Mouse_Callback(_go32_dpmi_registers * r)589 static void Mouse_Callback (_go32_dpmi_registers *r)
590 {
591 mouse_buttons=r->x.bx&7;
592 mouse_xpos=r->x.cx;
593 mouse_ypos=r->x.dx;
594 }
595
Mouse_Check(void)596 static void Mouse_Check (void)
597 {
598 __dpmi_regs r;
599 int tmp;
600 if (!got_mouse)
601 return;
602 mouse_x=mouse_xpos-500;
603 mouse_y=mouse_ypos-500;
604 tmp=mouse_buttons;
605 if (mouse_x || mouse_y)
606 {
607 r.x.ax=0x04;
608 r.x.cx=500;
609 r.x.dx=500;
610 __dpmi_int (0x33,&r);
611 mouse_xpos=mouse_ypos=500;
612 }
613 switch (expansionmode)
614 {
615 case 4: /* emulate driving module */
616 if (mouse_buttons&7)
617 MouseJoyState[0]&=0xFEFF;
618 mouse_x/=4;
619 mouse_y=0;
620 mouse_buttons=0;
621 break;
622 case 5: /* emulate SA speed roller on both ports */
623 mouse_x=(-mouse_x)/4;
624 mouse_y=-mouse_x;
625 mouse_buttons=0;
626 break;
627 case 6: /* emulate SA speed roller on port 1 */
628 mouse_x=(-mouse_x)/4;
629 mouse_y=0;
630 mouse_buttons=0;
631 break;
632 case 7: /* emulate SA speed roller on port 2 */
633 mouse_y=mouse_x/4;
634 mouse_x=0;
635 mouse_buttons=0;
636 break;
637 }
638 if (swapbuttons&4)
639 mouse_buttons=(mouse_buttons&(~3))|
640 ((mouse_buttons&1)<<1)|
641 ((mouse_buttons&2)>>1);
642 Mouse_SetJoyState ();
643 mouse_buttons=tmp;
644 }
645
Mouse_Detect(void)646 static int Mouse_Detect (void)
647 {
648 __dpmi_regs r;
649 r.x.ax=0;
650 __dpmi_int (0x33,&r);
651 if (r.x.ax==0)
652 return 0;
653 got_mouse=1;
654 return 1;
655 }
656
Mouse_Init(void)657 static void Mouse_Init (void)
658 {
659 __dpmi_regs r;
660 if (!got_mouse)
661 return;
662 r.x.ax=0x07; /* set horizontal range */
663 r.x.cx=0;
664 r.x.dx=1000;
665 __dpmi_int (0x33,&r);
666 r.x.ax=0x08; /* set vertical range */
667 r.x.cx=0;
668 r.x.dx=1000;
669 __dpmi_int (0x33,&r);
670 r.x.ax=0x04; /* set position */
671 r.x.cx=500;
672 r.x.dx=500;
673 __dpmi_int (0x33,&r);
674 r.x.ax=0x0F; /* set sensitivity */
675 r.x.cx=3;
676 r.x.dx=3;
677 __dpmi_int (0x33,&r);
678 mouse_seginfo.pm_selector=_my_cs();
679 mouse_seginfo.pm_offset=(unsigned)Mouse_Callback;
680 _go32_dpmi_allocate_real_mode_callback_retf (&mouse_seginfo,&mouse_regs);
681 r.x.ax=0x0C;
682 r.x.cx=0x1F;
683 r.x.dx=mouse_seginfo.rm_offset;
684 r.x.es=mouse_seginfo.rm_segment;
685 __dpmi_int (0x33,&r);
686 return;
687 }
688
Mouse_Exit(void)689 static void Mouse_Exit (void)
690 {
691 __dpmi_regs r;
692 if (!got_mouse)
693 return;
694 r.x.ax=0x0C;
695 r.x.cx=0;
696 r.x.dx=0;
697 r.x.es=0;
698 __dpmi_int (0x33,&r);
699 r.x.ax=0;
700 __dpmi_int (0x33,&r);
701 _go32_dpmi_free_real_mode_callback (&mouse_seginfo);
702 }
703
704 /****************************************************************************/
705 /** Joystick routines **/
706 /****************************************************************************/
707 typedef struct joyposstruct
708 {
709 int x,y;
710 } joypos;
711
712 static int gotjoy=0; /* 1 if joystick was properly initialised */
713
714 static joypos joycentre; /* joystick centre position */
715 static joypos joymin; /* left-upper corner position */
716 static joypos joymax; /* right-lower corner position */
717 static joypos joy_lowmargin; /* start of 'dead' region */
718 static joypos joy_highmargin; /* end of 'dead' region */
719
_JoyGetPos(joypos * jp)720 static int _JoyGetPos (joypos *jp)
721 {
722 unsigned tmp;
723 tmp=JoyGetPos ();
724 jp->x=(unsigned) (tmp&0xFFFF);
725 if (jp->x>=10000)
726 return 0;
727 jp->y=(unsigned) (tmp>>16);
728 if (jp->y>=10000)
729 return 0;
730 return 1;
731 }
732
Joy_Init(void)733 static int Joy_Init (void)
734 {
735 joypos jp;
736 if (!_JoyGetPos (&jp))
737 return 0;
738 joycentre.x=jp.x;
739 joycentre.y=jp.y;
740 gotjoy=1;
741 return 1;
742 }
743
CalibrateJoystick(void)744 static void CalibrateJoystick (void)
745 {
746 FILE *joyfile=NULL;
747 if (!calibrate)
748 joyfile=fopen(szJoystickFileName,"rb");
749 if (!joyfile)
750 {
751 fprintf (stderr,"Move joystick to top left and press any key\n");
752 getch ();
753 _JoyGetPos (&joymin);
754 fprintf (stderr,"Move joystick to bottom right and press any key\n");
755 getch ();
756 _JoyGetPos (&joymax);
757 joyfile=fopen(szJoystickFileName,"wb");
758 if (joyfile)
759 {
760 fwrite (&joymin,sizeof(joymin),1,joyfile);
761 fwrite (&joymax,sizeof(joymax),1,joyfile);
762 fclose (joyfile);
763 }
764 }
765 else
766 {
767 fread (&joymin,sizeof(joymin),1,joyfile);
768 fread (&joymax,sizeof(joymax),1,joyfile);
769 fclose (joyfile);
770 }
771 joy_lowmargin.x=joycentre.x-(joycentre.x-joymin.x)/8;
772 joy_lowmargin.y=joycentre.y-(joycentre.y-joymin.y)/8;
773 joy_highmargin.x=joycentre.x+(joymax.x-joycentre.x)/8;
774 joy_highmargin.y=joycentre.y+(joymax.y-joycentre.y)/8;
775 /* prevent a divide by zero in JoySortOutAnalogue() */
776 if (joy_lowmargin.x-joymin.x==0)
777 joy_lowmargin.x++;
778 if (joymax.x-joy_highmargin.x==0)
779 joy_highmargin.x--;
780 if (joy_lowmargin.y-joymin.y==0)
781 joy_lowmargin.y++;
782 if (joymax.y-joy_highmargin.y==0)
783 joy_highmargin.y--;
784 }
785
786 #define JOY_RANGE 128
JoySortOutAnalogue(joypos * jp)787 static void JoySortOutAnalogue (joypos *jp)
788 {
789 if (jp->x < joymin.x)
790 jp->x=-JOY_RANGE;
791 else
792 if (jp->x > joymax.x)
793 jp->x=JOY_RANGE;
794 else
795 if ((jp->x > joy_lowmargin.x) && (jp->x < joy_highmargin.x))
796 jp->x=0;
797 else
798 if (jp->x < joy_lowmargin.x)
799 jp->x=-JOY_RANGE+(jp->x-joymin.x)*JOY_RANGE/(joy_lowmargin.x-joymin.x);
800 else
801 jp->x=JOY_RANGE-(joymax.x-jp->x)*JOY_RANGE/(joymax.x-joy_highmargin.x);
802
803 if (jp->y < joymin.y)
804 jp->y=-JOY_RANGE;
805 else
806 if (jp->y > joymax.y)
807 jp->y=JOY_RANGE;
808 else
809 if ((jp->y > joy_lowmargin.y) && (jp->y < joy_highmargin.y))
810 jp->y=0;
811 else
812 if (jp->y < joy_lowmargin.y)
813 jp->y=-JOY_RANGE+(jp->y-joymin.y)*JOY_RANGE/(joy_lowmargin.y-joymin.y);
814 else
815 jp->y=JOY_RANGE-(joymax.y-jp->y)*JOY_RANGE/(joymax.y-joy_highmargin.y);
816 }
817
Joy_Check(void)818 static void Joy_Check (void)
819 {
820 joypos jp;
821 unsigned char joystatus;
822 if (!gotjoy)
823 return;
824 _JoyGetPos (&jp);
825 joystatus=inportb (0x201);
826 switch (expansionmode)
827 {
828 case 0:
829 case 5:
830 case 6:
831 case 7:
832 if (jp.x<(joycentre.x*3/4))
833 JoystickJoyState[0]&=0xF7FF;
834 else
835 if (jp.x>(joycentre.x*5/4))
836 JoystickJoyState[0]&=0xFDFF;
837 if (jp.y<(joycentre.y*3/4))
838 JoystickJoyState[0]&=0xFEFF;
839 else
840 if (jp.y>(joycentre.y*5/4))
841 JoystickJoyState[0]&=0xFBFF;
842 if ((joystatus&0x10)==0)
843 JoystickJoyState[0]&=(swapbuttons&1)? 0xFFBF:0xBFFF;
844 if ((joystatus&0x20)==0)
845 JoystickJoyState[0]&=(swapbuttons&1)? 0xBFFF:0xFFBF;
846 if ((joystatus&0x40)==0)
847 JoystickJoyState[0]=(JoyState[0]&0xFFF0)|12;
848 if ((joystatus&0x80)==0)
849 JoystickJoyState[0]=(JoyState[0]&0xFFF0)|13;
850 break;
851 case 2:
852 JoySortOutAnalogue (&jp);
853 mouse_x=jp.x;
854 mouse_y=jp.y;
855 mouse_buttons=0;
856 if ((joystatus&0x10)==0)
857 mouse_buttons|=(swapbuttons&1)? 2:1;
858 if ((joystatus&0x20)==0)
859 mouse_buttons|=(swapbuttons&1)? 1:2;
860 if ((joystatus&0x40)==0)
861 mouse_buttons|=4;
862 if ((joystatus&0x80)==0)
863 mouse_buttons|=8;
864 Mouse_SetJoyState ();
865 break;
866 case 3:
867 if (jp.y<(joycentre.y*3/4))
868 JoystickJoyState[0]&=0xFEFF;
869 JoySortOutAnalogue (&jp);
870 mouse_x=(jp.x/2);
871 mouse_y=0;
872 Mouse_SetJoyState ();
873 if ((joystatus&0x10)==0)
874 JoystickJoyState[1]&=(swapbuttons&1)? 0xFBFF:0xFEFF;
875 if ((joystatus&0x20)==0)
876 JoystickJoyState[1]&=(swapbuttons&1)? 0xFEFF:0xFBFF;
877 if ((joystatus&0x40)==0)
878 JoystickJoyState[1]&=0xF7FF;
879 if ((joystatus&0x80)==0)
880 JoystickJoyState[1]&=0xFDFF;
881 break;
882 }
883 }
884
885 /****************************************************************************/
886 /** Deallocate all resources taken by InitMachine() **/
887 /****************************************************************************/
TrashMachine(void)888 void TrashMachine(void)
889 {
890 Mouse_Exit ();
891 VGA_Reset ();
892 if(Verbose) printf("\n\nShutting down...\n");
893 TrashSound ();
894 RestoreTimer ();
895 Keyb_Reset ();
896 ExitStacks ();
897 }
898
NextFile(char * s)899 static int NextFile (char *s)
900 {
901 char *p;
902 p=s+strlen(s)-1;
903 if (*p=='9')
904 {
905 *p='0';
906 --p;
907 if (*p=='9')
908 {
909 (*p)++;
910 if (*p=='0')
911 return 0;
912 }
913 else
914 (*p)++;
915 }
916 else
917 (*p)++;
918 return 1;
919 }
920
NextBitmapFile(void)921 static int NextBitmapFile (void)
922 {
923 return NextFile (szBitmapFile);
924 }
925
NextSnapshotFile(void)926 static int NextSnapshotFile (void)
927 {
928 return NextFile (szSnapshotFile);
929 }
930
931 /****************************************************************************/
932 /** Allocate resources needed by MS-DOS-dependent code **/
933 /****************************************************************************/
InitMachine(void)934 int InitMachine(void)
935 {
936 int i,j,c;
937 FILE *bitmapfile,*snapshotfile;
938 if (Verbose) printf ("Initialising MSDOS drivers...\n");
939 if (videomode>2 || videomode<0)
940 videomode=0;
941 JoyState[0]=JoyState[1]=MouseJoyState[0]=MouseJoyState[1]=
942 JoystickJoyState[0]=JoystickJoyState[1]=0x7F7F;
943 cs_alias=_my_ds();
944 DosSelector=_dos_ds;
945 if (Verbose)
946 printf (" Allocating stack space... ");
947 i=InitStacks (NUM_STACKS,STACK_SIZE);
948 if (!i)
949 {
950 if (Verbose) puts ("FAILED\n");
951 return 0;
952 }
953 memset (DisplayBuf,0,sizeof(DisplayBuf));
954 for (i=0;i<16;++i)
955 PalBuf[i]=i+1;
956 if (Verbose)
957 printf ("OK\n Initialising conversion buffer... ");
958 for (i=0;i<16;++i)
959 for (j=0;j<16;++j)
960 for (c=0;c<16;++c)
961 {
962 unsigned a;
963 a=0;
964 #ifdef LSB_FIRST
965 if (c&0x08) a|=PalBuf[i]; else a|=PalBuf[j];
966 if (c&0x04) a|=(PalBuf[i]<<8); else a|=(PalBuf[j]<<8);
967 if (c&0x02) a|=(PalBuf[i]<<16); else a|=(PalBuf[j]<<16);
968 if (c&0x01) a|=(PalBuf[i]<<24); else a|=(PalBuf[j]<<24);
969 #else
970 if (c&0x01) a|=PalBuf[i]; else a|=PalBuf[j];
971 if (c&0x02) a|=(PalBuf[i]<<8); else a|=(PalBuf[j]<<8);
972 if (c&0x04) a|=(PalBuf[i]<<16); else a|=(PalBuf[j]<<16);
973 if (c&0x08) a|=(PalBuf[i]<<24); else a|=(PalBuf[j]<<24);
974 #endif
975 font2screen[i*16*16+j*16+c]=a;
976 }
977 if (Verbose) puts ("OK");
978 InitSound ();
979 if (expansionmode==2 || expansionmode==3 ||
980 (expansionmode!=1 && expansionmode!=4 && joystick))
981 {
982 if (Verbose)
983 printf (" Detecting joystick... ");
984 i=Joy_Init ();
985 if (Verbose)
986 printf ((i)? "Found\n" : "Not found\n");
987 }
988 if (expansionmode==1 || expansionmode==4 ||
989 expansionmode==5 || expansionmode==6 ||
990 expansionmode==7)
991 {
992 if (Verbose)
993 printf (" Detecting mouse... ");
994 i=Mouse_Detect ();
995 if (Verbose)
996 printf ((i)? "Found\n" : "Not found\n");
997 }
998 if (mouse_sens<=0 || mouse_sens>1000)
999 mouse_sens=default_mouse_sens;
1000 switch (expansionmode)
1001 {
1002 case 2:
1003 case 3:
1004 if (!gotjoy)
1005 {
1006 expansionmode=0;
1007 break;
1008 }
1009 CalibrateJoystick ();
1010 break;
1011 case 1:
1012 case 4:
1013 case 5:
1014 case 6:
1015 case 7:
1016 if (!got_mouse)
1017 expansionmode=0;
1018 break;
1019 default:
1020 expansionmode=0;
1021 default_mouse_sens*=5;
1022 break;
1023 }
1024 StartTimer ();
1025 if (syncemu)
1026 OldTimer=ReadTimer ();
1027 /* Parse keyboard mapping string */
1028 sscanf (szKeys,"%02X%02X%02X%02X%02X%02X%02X%02X",
1029 &KEY_LEFT,&KEY_RIGHT,&KEY_UP,&KEY_DOWN,
1030 &KEY_BUTTONA,&KEY_BUTTONB,&KEY_BUTTONC,&KEY_BUTTOND);
1031 Keyb_Init ();
1032 while ((bitmapfile=fopen(szBitmapFile,"rb"))!=NULL)
1033 {
1034 fclose (bitmapfile);
1035 if (!NextBitmapFile())
1036 break;
1037 }
1038 while ((snapshotfile=fopen(szSnapshotFile,"rb"))!=NULL)
1039 {
1040 fclose (snapshotfile);
1041 if (!NextSnapshotFile())
1042 break;
1043 }
1044 if (Verbose)
1045 {
1046 printf (" Next screenshot will be %s\n"
1047 " Next snapshot will be %s\n",
1048 szBitmapFile,szSnapshotFile);
1049 }
1050 if (Verbose)
1051 {
1052 fprintf (stderr,"Press space to run rom code...\n");
1053 while (!keybstatus[VK_Space]);
1054 }
1055 makeshot=0; makesnap=0;
1056 for (i=0;i<16*3;++i) VGA_Palette[i+3]=Coleco_Palette[i];
1057 VGA_Init ();
1058 VGA_SetBkColour (0);
1059 Mouse_Init ();
1060 keyboardmode=(EmuMode)? 1:0;
1061 return 1;
1062 }
1063
1064 /****************************************************************************/
1065 /** Routines to modify the Coleco gamport status **/
1066 /****************************************************************************/
numkeypressed(int nScanCode)1067 static int numkeypressed (int nScanCode)
1068 {
1069 int nOr;
1070 switch (nScanCode)
1071 {
1072 case VK_1:
1073 case VK_End:
1074 nOr=1;
1075 break;
1076 case VK_2:
1077 case VK_Down:
1078 nOr=2;
1079 break;
1080 case VK_3:
1081 case VK_PageDown:
1082 nOr=3;
1083 break;
1084 case VK_4:
1085 case VK_Left:
1086 nOr=4;
1087 break;
1088 case VK_5:
1089 case VK_NumPad5:
1090 nOr=5;
1091 break;
1092 case VK_6:
1093 case VK_Right:
1094 nOr=6;
1095 break;
1096 case VK_7:
1097 case VK_Home:
1098 nOr=7;
1099 break;
1100 case VK_8:
1101 case VK_Up:
1102 nOr=8;
1103 break;
1104 case VK_9:
1105 case VK_PageUp:
1106 nOr=9;
1107 break;
1108 case VK_Equal:
1109 case VK_Enter:
1110 nOr=10;
1111 break;
1112 case VK_Minus:
1113 case VK_Del:
1114 nOr=11;
1115 break;
1116 default:
1117 nOr=0;
1118 }
1119 return nOr;
1120 }
1121
Joysticks(void)1122 static void Joysticks (void)
1123 {
1124 int i,tmp,tmp2;
1125 MouseJoyState[0]|=0x7F7F;
1126 MouseJoyState[1]|=0x7F7F;
1127 Mouse_Check ();
1128 JoystickJoyState[0]|=0x7F7F;
1129 JoystickJoyState[1]|=0x7F7F;
1130 Joy_Check ();
1131 JoyState[1]=(MouseJoyState[0] & JoystickJoyState[0]);
1132 JoyState[0]=(MouseJoyState[1] & JoystickJoyState[1]);
1133 if (!keyboardmode)
1134 {
1135 if (keybstatus[KEY_BUTTONA])
1136 JoyState[0]&=(swapbuttons&2)? 0xFFBF:0xBFFF;
1137 if (keybstatus[KEY_BUTTONB])
1138 JoyState[0]&=(swapbuttons&2)? 0xBFFF:0xFFBF;
1139 if (keybstatus[KEY_DOWN])
1140 JoyState[0]&=0xFBFF;
1141 if (keybstatus[KEY_UP])
1142 JoyState[0]&=0xFEFF;
1143 if (keybstatus[KEY_LEFT])
1144 JoyState[0]&=0xF7FF;
1145 if (keybstatus[KEY_RIGHT])
1146 JoyState[0]&=0xFDFF;
1147 for (i=VK_1;i<=VK_Equal;++i)
1148 if (keybstatus[i])
1149 {
1150 tmp=numkeypressed(i);
1151 JoyState[0]=(JoyState[0]&0xFFF0)|tmp;
1152 }
1153 if (keybstatus[KEY_BUTTONC])
1154 JoyState[0]=(JoyState[0]&0xFFF0)|12;
1155 if (keybstatus[KEY_BUTTOND])
1156 JoyState[0]=(JoyState[0]&0xFFF0)|13;
1157 for (i=VK_Home;i<=VK_PageUp;++i)
1158 if (keybstatus[i])
1159 {
1160 tmp=numkeypressed((keypadmode)? (i-VK_Home+VK_End) : i);
1161 JoyState[1]=(JoyState[1]&0xFFF0)|tmp;
1162 }
1163 for (i=VK_Left;i<=VK_Right;++i)
1164 if (keybstatus[i])
1165 {
1166 tmp=numkeypressed(i);
1167 JoyState[1]=(JoyState[1]&0xFFF0)|tmp;
1168 }
1169 for (i=VK_End;i<=VK_PageDown;++i)
1170 if (keybstatus[i])
1171 {
1172 tmp=numkeypressed((keypadmode)? (i-VK_End+VK_Home) : i);
1173 JoyState[1]=(JoyState[1]&0xFFF0)|tmp;
1174 }
1175 if (keybstatus[VK_Insert])
1176 {
1177 tmp=numkeypressed((keypadmode)? VK_Del : VK_Insert);
1178 JoyState[1]=(JoyState[1]&0xFFF0)|tmp;
1179 }
1180 if (keybstatus[VK_Del])
1181 {
1182 tmp=numkeypressed((keypadmode)? VK_Insert : VK_Del);
1183 JoyState[1]=(JoyState[1]&0xFFF0)|tmp;
1184 }
1185 if (keybstatus[VK_Enter+128])
1186 {
1187 tmp=numkeypressed(VK_Enter);
1188 JoyState[1]=(JoyState[1]&0xFFF0)|tmp;
1189 }
1190 if (keybstatus[VK_PlusNumPad])
1191 JoyState[1]=(JoyState[1]&0xFFF0)|13;
1192 if (keybstatus[VK_MinusNumPad])
1193 JoyState[1]=(JoyState[1]&0xFFF0)|12;
1194 }
1195 switch (expansionmode)
1196 {
1197 case 1: /* emulate roller controller with mouse */
1198 case 2: /* emulate RC with joystick */
1199 if ((JoyState[1]&0x0F)==12 || (JoyState[1]&0x0F)==13)
1200 JoyState[1]|=0x0F;
1201 if ((JoyState[0]&0x0F)==12 || (JoyState[0]&0x0F)==13)
1202 JoyState[0]|=0x0F;
1203 tmp=JoyState[1];
1204 JoyState[1]=(JoyState[0]&0x707F)|0x0F00;
1205 JoyState[0]=(tmp&0x7F7F);
1206 if ((JoyState[1]&0xF)!=0xF)
1207 JoyState[0]=(JoyState[0]&0xFFF0)|(JoyState[1]&0x0F);
1208 JoyState[1]=(JoyState[1]&0xFFF0)|(JoyState[0]&0x0F);
1209 break;
1210 case 3: /* emulate driving module with joystick */
1211 case 4: /* emulate driving module with mouse */
1212 if ((JoyState[1]&0x0F)==12 || (JoyState[1]&0x0F)==13)
1213 JoyState[1]|=0x0F;
1214 if ((JoyState[0]&0x0F)==12 || (JoyState[0]&0x0F)==13)
1215 JoyState[0]|=0x0F;
1216 if ((JoyState[1]&0xF)!=0xF)
1217 JoyState[0]=(JoyState[0]&0xFFF0)|(JoyState[1]&0x0F);
1218 if ((JoyState[1]&0x0100)==0)
1219 JoyState[1]&=0xBFFF;
1220 else
1221 JoyState[1]|=0x4000;
1222 JoyState[1]|=0x0F7F;
1223 tmp=JoyState[1];
1224 JoyState[1]=JoyState[0];
1225 JoyState[0]=tmp|0x0040;
1226 break;
1227 default:
1228 switch (joystick)
1229 {
1230 case 1: /* Joystick 1=Joystick 2 */
1231 tmp=JoyState[0]&0x0F;
1232 tmp2=JoyState[1]&0x0F;
1233 if (tmp==12 || tmp==13)
1234 JoyState[1]=(JoyState[1]&0xFFF0)|(JoyState[0]&0xF);
1235 else
1236 if (tmp2==12 || tmp2==13)
1237 JoyState[0]=(JoyState[0]&0xFFF0)|(JoyState[1]&0xF);
1238 else
1239 if (tmp2!=15)
1240 {
1241 JoyState[0]=(JoyState[0]&0xFFF0)|(JoyState[1]&0x0F);
1242 JoyState[1]|=15;
1243 }
1244 JoyState[0]&=(JoyState[1]|0xF);
1245 JoyState[1]&=(JoyState[0]|0xF);
1246 break;
1247 case 2: /* Joystick 1=keyb, Joystick 2=joystick */
1248 break;
1249 case 3: /* Joystick 1=joystick, Joystick 2=keyb */
1250 tmp=JoyState[0];
1251 JoyState[0]=JoyState[1];
1252 JoyState[1]=tmp;
1253 break;
1254 }
1255 break;
1256 }
1257 }
1258
1259 /****************************************************************************/
1260 /*** Parse keyboard events ***/
1261 /****************************************************************************/
1262 extern byte *RAM;
Keyboard(void)1263 void Keyboard (void)
1264 {
1265 int tmp;
1266 /* Check if reset combination is pressed */
1267 if (AltPressed())
1268 {
1269 if (keybstatus[VK_F12]) ResetColeco (0);
1270 if (keybstatus[VK_F11]) ResetColeco (1);
1271 }
1272 /* Update keyboard buffer */
1273 do
1274 {
1275 tmp=LocalGetKeyboardChar ();
1276 if (tmp) AddToKeyboardBuffer (tmp);
1277 }
1278 while (tmp);
1279 /* Check mouse and joystick events */
1280 Joysticks ();
1281 /* Check if video mode should be switched */
1282 if (SwitchVideoMode)
1283 {
1284 SwitchVideoMode=0;
1285 AutoText80=0;
1286 if (Text80)
1287 ResetText80();
1288 else
1289 InitText80();
1290 }
1291 /* Check is PAUSE is pressed */
1292 if (PausePressed)
1293 {
1294 StopSound ();
1295 tmp=0;
1296 if (PausePressed==2)
1297 {
1298 tmp=1;
1299 VGA_SetBkColour (1);
1300 inportb (0x3BA);
1301 inportb (0x3DA);
1302 outportb (0x3C0,0);
1303 }
1304 while (PausePressed);
1305 if (tmp)
1306 {
1307 VGA_SetBkColour (VDP.BGColour);
1308 inportb (0x3BA);
1309 inportb (0x3DA);
1310 outportb (0x3C0,0x20);
1311 }
1312 ResumeSound ();
1313 if (syncemu)
1314 OldTimer=ReadTimer ();
1315 }
1316 /* Check if a screen shot should be taken */
1317 if (makeshot)
1318 {
1319 sound (440);
1320 WriteBitmap (szBitmapFile,8,17,WIDTH,256,192,
1321 DisplayBuf+(WIDTH-256)/2+(HEIGHT-192)*WIDTH,VGA_Palette);
1322 NextBitmapFile ();
1323 makeshot--;
1324 nosound ();
1325 }
1326 if (makesnap)
1327 {
1328 sound (220);
1329 SaveSnapshotFile (szSnapshotFile);
1330 NextSnapshotFile ();
1331 nosound ();
1332 makesnap--;
1333 }
1334 #ifdef DEBUG
1335 if (dumpram)
1336 {
1337 FILE *f;
1338 char buf[20];
1339 static int dumpram_count=0;
1340 sprintf (buf,"RAM.%03d",dumpram_count);
1341 dumpram_count++; if (dumpram_count>999) dumpram_count=0;
1342 f=fopen (buf,"wb");
1343 for (tmp=0;tmp<256;++tmp) fwrite (AddrTabl[tmp],1,256,f);
1344 fclose (f);
1345 dumpram--;
1346 }
1347 #endif
1348 /* Check if OptionsDialogue() should be called */
1349 if (calloptions)
1350 {
1351 in_options_dialogue=1;
1352 calloptions=0;
1353 StopSound ();
1354 VGA_Reset ();
1355 fflush (stdin);
1356 OptionsDialogue ();
1357 VGA_Init ();
1358 if (Text80) InitText80();
1359 in_options_dialogue=0;
1360 ResumeSound ();
1361 RefreshScreen (1);
1362 if (syncemu) OldTimer=ReadTimer();
1363 }
1364 }
1365
1366 /****************************************************************************/
1367 /** Interrupt routines **/
1368 /****************************************************************************/
1369 /* Gets called 50 times per second */
CheckScreenRefresh(void)1370 int CheckScreenRefresh (void)
1371 {
1372 static int skipped=0;
1373 if (syncemu)
1374 {
1375 NewTimer=ReadTimer ();
1376 OldTimer+=1192380/IFreq;
1377 if ((OldTimer-NewTimer)>0)
1378 {
1379 do
1380 NewTimer=ReadTimer ();
1381 while ((NewTimer-OldTimer)<0);
1382 skipped=0;
1383 return 1;
1384 }
1385 else
1386 if (++skipped>=UPeriod)
1387 {
1388 OldTimer=ReadTimer ();
1389 skipped=0;
1390 return 1;
1391 }
1392 else
1393 return 0;
1394 }
1395 return 2;
1396 }
1397
1398 /****************************************************************************/
1399 /** Screen refresh drivers **/
1400 /****************************************************************************/
1401 #define USE_LOOKUP_TABLE /* Use font2screen for faster refresh */
1402 #define _8BPP /* We have an 8 bpp video device */
1403
1404 #include "Common.h"
1405