"Fossies" - the Fresh Open Source Software Archive

Member "alec64-1.13/src/key_go32.c" (3 Aug 1996, 31233 Bytes) of package /linux/misc/old/alec64-1.13.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2  *  The C64 emulator
    3  *
    4  *  Copyright 1992-96 by ALE.
    5  *  written by Lutz Sammer.
    6  *
    7  *  Keyboard emulation for GO32 (MSDOS version of GNU-C)
    8  *-----------------------------------------------------------------------------
    9  * $Id: key_go32.c,v 1.15 1996/07/04 23:31:21 ari Exp root $
   10  * $Log: key_go32.c,v $
   11  * Revision 1.15  1996/07/04 23:31:21  ari
   12  * Rewritten DPMI keyboard interrupt handler, to remove conflict with
   13  * sound interrupts.
   14  *
   15  * Revision 1.14  1996/06/16 00:43:33  ari
   16  * Splitted into extra file.
   17  *
   18  * Revision 1.13  1995/06/01 12:08:24  ari
   19  * added full DPMI-compliance to GO32 version - now usable under OS/2 + Windows
   20  *
   21  * Revision 1.12  1995/02/13  11:27:22  ari
   22  * second linux port ( by ari ) integration
   23  *
   24  * Revision 1.11  1995/02/06  23:56:41  johns
   25  * go32 DPMI keyboard support
   26  *
   27  * Revision 1.10  1994/07/16  13:59:15  root
   28  * support go32 1.11.m5 changed keyboard interrupt handle
   29  *
   30  * Revision 1.9  1993/12/30  11:46:21  root
   31  * go32-changes integrated in unix version
   32  *
   33  * Revision 1.8  1993/09/07  21:40:26  johns
   34  * key mapping modification F12 <-> PageUp, add PageDown as Key102 alias
   35  *
   36  * Revision 1.7  1993/08/31  20:30:03  johns
   37  * go32 initial support
   38  *
   39  * Revision 1.6  1993/06/13  12:25:00  johns
   40  * final vt-switching mods
   41  *
   42  * Revision 1.5  1993/01/05  12:41:24  johns
   43  * Checkin before applying wuebbel patches
   44  *
   45  * Revision 1.4  1992/07/28  19:47:42  johns
   46  * F9/F10 changes VicFetch VicFetchAdd.
   47  *
   48  * Revision 1.3  1992/07/20  04:15:46  johns
   49  * Better macros for (re)set key in c64 matrix.
   50  * Keyboard joystick emulation improved for release.
   51  *
   52  * Revision 1.2  1992/07/13  04:36:26  johns
   53  * Missing led ioctl fixed.
   54  *
   55  * Revision 1.1  1992/07/11  18:34:08  johns
   56  * Initial revision
   57  *
   58  *-----------------------------------------------------------------------------
   59  */
   60 
   61 #ifdef __GO32__ /* { */
   62 
   63 #include <stdio.h>
   64 
   65 #include <sys/types.h>
   66 #include <go32.h>
   67 #include <dos.h>
   68 #include <dpmi.h>
   69 #include <stdlib.h>
   70 
   71 #include "c64.h"
   72 #include "vic.h"
   73 #include "sid.h"
   74 
   75 /*---------------------------------------------------------------------------*/
   76 
   77 extern void SaveSnapShot(CONST char*);
   78 
   79 /*---------------------------------------------------------------------------*/
   80 
   81 /*
   82  *  Reset key in C64 keyboard matrix
   83  */
   84 #define MatrixReset(bit,mask) \
   85     do {                                        \
   86     int i,j;                                \
   87                         \
   88     for( j=0; j<256; j+=(bit) ) {           \
   89         for( i=0; i<(bit); ++i ) {          \
   90         KeyMatrix[j++]|=(mask);            \
   91         }                                   \
   92     }                                       \
   93     } while( 0 )
   94 
   95 /*
   96  *      Set key in C64 keyboard matrix
   97  */
   98 #define MatrixSet(bit,mask) \
   99     do {                                        \
  100     int i,j;                                \
  101                         \
  102     for( j=0; j<256; j+=(bit) ) {           \
  103         for( i=0; i<(bit); ++i ) {          \
  104         KeyMatrix[j++]&=(mask)^0xFF;       \
  105         }                                   \
  106     }                                       \
  107     } while( 0 )
  108 
  109 /*---------------------------------------------------------------------------*/
  110 
  111 /*
  112  *      Modifier set:
  113  */
  114 #define KEY_S_NONE      0x00
  115 #define KEY_S_SHIFT     0x01
  116 #define KEY_S_CTRL      0x02
  117 #define KEY_S_LALT      0x04
  118 #define KEY_S_RALT      0x08
  119 #define KEY_S_ALT       0x0C
  120 #define KEY_S_CAPS      0x10
  121 #define KEY_S_NUM       0x20
  122 #define KEY_S_SCROLL    0x40
  123 #define KEY_S_REPEAT    0x80
  124 
  125 /*
  126  *      Scancodes enumerated.
  127  */
  128 /*
  129  * definition of the AT84/MF101/MF102 Keyboard:
  130  * ============================================================
  131  *       Defined             Key Cap Glyphs       Pressed value
  132  *      Key Name            Main       Also       (hex)    (dec)
  133  *      ----------------   ---------- -------    ------    ------
  134  */
  135 #define KEY_Escape      /* Escape                0x01  */    1  
  136 #define KEY_1           /* 1           !         0x02  */    2 
  137 #define KEY_2           /* 2           @         0x03  */    3 
  138 #define KEY_3           /* 3           #         0x04  */    4 
  139 #define KEY_4           /* 4           $         0x05  */    5 
  140 #define KEY_5           /* 5           %         0x06  */    6 
  141 #define KEY_6           /* 6           ^         0x07  */    7 
  142 #define KEY_7           /* 7           &         0x08  */    8 
  143 #define KEY_8           /* 8           *         0x09  */    9 
  144 #define KEY_9           /* 9           (         0x0a  */   10 
  145 #define KEY_0           /* 0           )         0x0b  */   11 
  146 #define KEY_Minus       /* - (Minus)   _ (Under) 0x0c  */   12
  147 #define KEY_Equal       /* = (Equal)   +         0x0d  */   13 
  148 #define KEY_BackSpace   /* Back Space            0x0e  */   14 
  149 #define KEY_Tab         /* Tab                   0x0f  */   15
  150 #define KEY_Q           /* Q                     0x10  */   16
  151 #define KEY_W           /* W                     0x11  */   17
  152 #define KEY_E           /* E                     0x12  */   18
  153 #define KEY_R           /* R                     0x13  */   19
  154 #define KEY_T           /* T                     0x14  */   20
  155 #define KEY_Y           /* Y                     0x15  */   21
  156 #define KEY_U           /* U                     0x16  */   22
  157 #define KEY_I           /* I                     0x17  */   23
  158 #define KEY_O           /* O                     0x18  */   24
  159 #define KEY_P           /* P                     0x19  */   25
  160 #define KEY_LeftBrace   /* [           {         0x1a  */   26
  161 #define KEY_RightBrace  /* ]           }         0x1b  */   27 
  162 #define KEY_Return      /* Return                0x1c  */   28
  163 #define KEY_LeftCtrl    /* Ctrl(left)            0x1d  */   29
  164 #define KEY_A           /* A                     0x1e  */   30
  165 #define KEY_S           /* S                     0x1f  */   31
  166 #define KEY_D           /* D                     0x20  */   32 
  167 #define KEY_F           /* F                     0x21  */   33
  168 #define KEY_G           /* G                     0x22  */   34
  169 #define KEY_H           /* H                     0x23  */   35
  170 #define KEY_J           /* J                     0x24  */   36
  171 #define KEY_K           /* K                     0x25  */   37
  172 #define KEY_L           /* L                     0x26  */   38
  173 #define KEY_SemiColon   /* ;(SemiColon) :(Colon) 0x27  */   39
  174 #define KEY_Quote       /* ' (Apostr)  " (Quote) 0x28  */   40
  175 #define KEY_Accent      /* ` (Accent)  ~ (Tilde) 0x29  */   41
  176 #define KEY_LeftShift   /* Shift(left)           0x2a  */   42
  177 #define KEY_BackSlash   /* \(BckSlash) |(VertBar)0x2b  */   43
  178 #define KEY_Z           /* Z                     0x2c  */   44
  179 #define KEY_X           /* X                     0x2d  */   45
  180 #define KEY_C           /* C                     0x2e  */   46
  181 #define KEY_V           /* V                     0x2f  */   47
  182 #define KEY_B           /* B                     0x30  */   48
  183 #define KEY_N           /* N                     0x31  */   49
  184 #define KEY_M           /* M                     0x32  */   50
  185 #define KEY_Comma       /* , (Comma)   < (Less)  0x33  */   51
  186 #define KEY_Dot         /* . (Period)  >(Greater)0x34  */   52
  187 #define KEY_Slash       /* / (Slash)   ?         0x35  */   53
  188 #define KEY_RightShift  /* Shift(right)          0x36  */   54
  189 #define KEY_KP_Multiply /* *                     0x37  */   55
  190 #define KEY_LeftAlt     /* Alt(left)             0x38  */   56
  191 #define KEY_Space       /*   (SpaceBar)          0x39  */   57
  192 #define KEY_CapsLock    /* CapsLock              0x3a  */   58
  193 #define KEY_F1          /* F1                    0x3b  */   59
  194 #define KEY_F2          /* F2                    0x3c  */   60
  195 #define KEY_F3          /* F3                    0x3d  */   61
  196 #define KEY_F4          /* F4                    0x3e  */   62
  197 #define KEY_F5          /* F5                    0x3f  */   63
  198 #define KEY_F6          /* F6                    0x40  */   64
  199 #define KEY_F7          /* F7                    0x41  */   65
  200 #define KEY_F8          /* F8                    0x42  */   66
  201 #define KEY_F9          /* F9                    0x43  */   67
  202 #define KEY_F10         /* F10                   0x44  */   68
  203 #define KEY_NumLock     /* NumLock               0x45  */   69
  204 #define KEY_ScrollLock  /* ScrollLock            0x46  */   70
  205 #define KEY_KP_7        /* 7           Home      0x47  */   71 
  206 #define KEY_KP_8        /* 8           Up        0x48  */   72 
  207 #define KEY_KP_9        /* 9           PgUp      0x49  */   73 
  208 #define KEY_KP_Minus    /* - (Minus)             0x4a  */   74
  209 #define KEY_KP_4        /* 4           Left      0x4b  */   75
  210 #define KEY_KP_5        /* 5                     0x4c  */   76
  211 #define KEY_KP_6        /* 6           Right     0x4d  */   77
  212 #define KEY_KP_Plus     /* + (Plus)              0x4e  */   78
  213 #define KEY_KP_1        /* 1           End       0x4f  */   79
  214 #define KEY_KP_2        /* 2           Down      0x50  */   80
  215 #define KEY_KP_3        /* 3           PgDown    0x51  */   81
  216 #define KEY_KP_0        /* 0           Insert    0x52  */   82
  217 #define KEY_KP_Dot      /* . (Decimal) Delete    0x53  */   83 
  218 #define KEY_SysReqest   /* SysReqest             0x54  */   84
  219             /* NOTUSED               0x55  */
  220 #define KEY_102         /* < (Less)   >(Greater) 0x56  */   86
  221 #define KEY_F11         /* F11                   0x57  */   87
  222 #define KEY_F12         /* F12                   0x58  */   88
  223 
  224 #define KEY_Prefix0     /* special ( & 0x7f )    0x60  */   96
  225 #define KEY_Prefix1     /* special ( & 0x7f )    0x61  */   97
  226 
  227 /*
  228  * The 'scancodes' below are generated by the server, because the MF101/102
  229  * keyboard sends them as sequence of other scancodes
  230  */
  231 #define KEY_Home        /* Home                  0x59  */   89
  232 #define KEY_Up          /* Up                    0x5a  */   90
  233 #define KEY_PageUp      /* PgUp                  0x5b  */   91
  234 #define KEY_Left        /* Left                  0x5c  */   92
  235 #define KEY_Begin       /* Begin                 0x5d  */   93
  236 #define KEY_Right       /* Right                 0x5e  */   94
  237 #define KEY_End         /* End                   0x5f  */   95
  238 #define KEY_Down        /* Down                  0x60  */   96
  239 #define KEY_PageDown    /* PgDown                0x61  */   97
  240 #define KEY_Insert      /* Insert                0x62  */   98
  241 #define KEY_Delete      /* Delete                0x63  */   99
  242 #define KEY_KP_Enter    /* Enter                 0x64  */  100
  243 #define KEY_RightCtrl   /* Ctrl(right)           0x65  */  101
  244 #define KEY_Pause       /* Pause                 0x66  */  102
  245 #define KEY_Print       /* Print                 0x67  */  103
  246 #define KEY_KP_Divide   /* Didive                0x68  */  104
  247 #define KEY_RightAlt    /* AltLang(right)        0x69  */  105
  248 #define KEY_Break       /* Break                 0x6a  */  106
  249 
  250 #define KEY_Released    128
  251 
  252 #define CAPS_LED        1
  253 #define NUM_LED         2
  254 #define SCROLL_LED      4
  255 
  256 #define IS_KEY_DOWN(k)  (KeyDown[(k)>>3]&(1<<((k)&7)))
  257 #define IS_VTSW_QUAL    (0)
  258 #define VT_ACTCON(xx) 
  259 
  260 static int KeyState;            /* Current state */
  261 static int KeyPrefix;           /* Current prefix */
  262 static int KeyLeds;         /* Current leds */
  263 static char KeyDown[128/8];     /* Keys currently pressed */ 
  264 
  265 static _go32_dpmi_seginfo RmKHMem;
  266 static unsigned long vecsave;
  267 static unsigned long kbcntp;
  268 static unsigned long kbreadp;
  269 static unsigned long kbbufp;
  270 static unsigned long go32kbvp;
  271 static unsigned char keyrupt[62] = {
  272     0x1E, 0x50, 0x53, 0x51, 0x52, 0x0E, 0x1F, 0xE4,
  273     0x60, 0xBB, 0x10, 0x00, 0x8B, 0x0F, 0x3B, 0xCB,
  274     0x7D, 0x18, 0x8B, 0x5F, 0x02, 0x88, 0x07, 0x43,
  275     0x83, 0xFB, 0x10, 0x75, 0x02, 0x2B, 0xDB, 0x8B,
  276     0xD3, 0xBB, 0x10, 0x00, 0x89, 0x57, 0x02, 0x41,
  277     0x89, 0x0F, 0xBA, 0x61, 0x00, 0xEC, 0x0C, 0x80,
  278     0xEE, 0x24, 0x7F, 0xEE, 0xB0, 0x20, 0xE6, 0x20,
  279     0x5A, 0x59, 0x5B, 0x58, 0x1F, 0xCF
  280 };
  281 
  282 void ShowLeds(int dummy)
  283 {
  284     KeyLeds=0;
  285     if( JoyStick==&JoyStick2 )
  286     KeyLeds|=NUM_LED;
  287     if( AutoFire )
  288     KeyLeds|=SCROLL_LED;   /* REALLY: CAPS_LED */
  289     if( VicEmulateRate==1 )
  290     KeyLeds|=CAPS_LED;     /* REALLY: SCROLL_LED */
  291 
  292     outb(0x60, 0xed);
  293     delay(10);
  294     outb(0x60, KeyLeds);
  295     delay(10);
  296 }
  297 
  298 void SuspendKeyboard(void)
  299 {
  300     LeaveKey();
  301 }
  302 
  303 void ResumeKeyboard(void)
  304 {
  305     EnterKey();
  306 }
  307 
  308 void EnterKey()
  309 {
  310     unsigned short p1[2];
  311     unsigned long p2;
  312     unsigned long rmaddr;
  313     unsigned long intaddr;
  314     unsigned char tmpmem[32];
  315     
  316     if (RmKHMem.size == 0) {
  317     RmKHMem.size = 128/16;
  318     if (_go32_dpmi_allocate_dos_memory(&RmKHMem)) {
  319         printf("Unable to allocate dos memory for KeyHandler!\n");
  320         Cleanup();
  321         exit(1);
  322     }
  323     }
  324     dosmemget(0x24, 4, &p1);
  325     p2 = p1[0] + p1[1] * 16ul;
  326     rmaddr = RmKHMem.rm_segment * 16;
  327     kbreadp = 0;
  328     kbbufp = rmaddr;
  329     kbcntp = rmaddr + 16;
  330     intaddr = (RmKHMem.rm_segment << 16) + 32;
  331     
  332     /* Heavy magic : pick go32 __ev_oldkbint savevector from go32. */
  333     dosmemget(p2 + 15, 2, &p1);
  334     go32kbvp = p1[0] + p1[1] * 16ul;
  335     dosmemget(go32kbvp, 4, &vecsave);
  336 
  337     memset(tmpmem, 0, 32);
  338     dosmemput(tmpmem, 32, rmaddr);
  339     dosmemput(keyrupt, sizeof(keyrupt), rmaddr + 32);
  340     disable();
  341     dosmemput(&intaddr, 4, go32kbvp);
  342     p1[0] = 1;
  343     dosmemput(p1, 2, go32kbvp + 4);
  344     enable();
  345 
  346     ShowLeds(0);
  347 }
  348 
  349 void LeaveKey()
  350 {                        
  351     unsigned char oldleds;
  352     unsigned char bits = 0;
  353     unsigned short t;
  354 
  355     dosmemget(0x417, 1, &oldleds);
  356     if (oldleds & 0x10)
  357     bits |= 1;
  358     if (oldleds & 0x20)
  359     bits |= 2;
  360     if (oldleds & 0x40)
  361     bits |= 4;
  362     outb(0x60,0xed);
  363     delay(10);
  364     outb(0x60,bits);
  365     delay(10);
  366 
  367     if (RmKHMem.size) {
  368     disable();
  369     t = 0;
  370     dosmemput(&t, 2, go32kbvp + 4);
  371     dosmemput(&vecsave, 4, go32kbvp);
  372     enable();
  373     _go32_dpmi_free_dos_memory(&RmKHMem);
  374     RmKHMem.size = 0;
  375     }
  376 }
  377 
  378 short 
  379 kbgetkey()
  380 {
  381     short c, x;
  382 
  383     dosmemget(kbcntp, 2, &c);
  384     if (c == 0)
  385     return -1;
  386     c = 0;
  387     dosmemget(kbbufp + kbreadp++, 1, &c);
  388     if (kbreadp == 16)
  389     kbreadp = 0;
  390     disable();
  391     dosmemget(kbcntp, 2, &x);
  392     x--;
  393     dosmemput(&x, 2, kbcntp);
  394     enable();
  395     return c;
  396 }
  397 
  398 short 
  399 kbsnoopkey()
  400 {
  401     short c;
  402 
  403     dosmemget(kbcntp, 2, &c);
  404     if (c == 0)
  405     return -1;
  406     c = 0;
  407     dosmemget(kbbufp + kbreadp, 1, &c);
  408     return c;
  409 }
  410 
  411 /****** KeyboarLevel0 (1.00) *****
  412  *
  413  *      Level 0 Keyboard scancode processing:
  414  *      Map scancodes to one scancode.
  415  */
  416 static int KeyboardLevel0(key)
  417 int key;
  418 {
  419     int scancode;
  420     int released;
  421 
  422     scancode=key&0x7F;
  423     released=key&0x80;
  424     switch( KeyPrefix ) {                                                       /* Handle according current prefix */
  425     case KEY_Prefix0:
  426         KeyPrefix=0;
  427         switch( scancode ) {                                                /* NUM-PAD */
  428         case KEY_KP_7:          scancode=KEY_Home;      break;
  429         case KEY_KP_8:          scancode=KEY_Up;        break;
  430         case KEY_KP_9:          scancode=KEY_PageUp;    break;
  431         case KEY_KP_4:          scancode=KEY_Left;      break;
  432         /* case KEY_KP_5:          scancode=KEY_Begin;     break; */
  433         case KEY_KP_6:          scancode=KEY_Right;     break;
  434         case KEY_KP_1:          scancode=KEY_End;       break;
  435         case KEY_KP_2:          scancode=KEY_Down;      break;
  436         case KEY_KP_3:          scancode=KEY_PageDown;  break;
  437         case KEY_KP_0:          scancode=KEY_Insert;    break;
  438         case KEY_KP_Dot:    scancode=KEY_Delete;    break;
  439         case KEY_Return:        scancode=KEY_KP_Enter;  break;
  440         case KEY_LeftCtrl:      scancode=KEY_RightCtrl; break;
  441         case KEY_KP_Multiply:   scancode=KEY_Print;     break;
  442         case KEY_Slash:         scancode=KEY_KP_Divide; break;
  443         case KEY_LeftAlt:       scancode=KEY_RightAlt;  break;
  444         case KEY_ScrollLock:    scancode=KEY_Break;     break;
  445         default:                                                        /* Ignore other shifts */
  446             return 0;
  447         }
  448         break;
  449 
  450     case KEY_Prefix1:                                                       /* Pause: Prefix1|LeftCtrl|NumLock */
  451         KeyPrefix= (scancode==KEY_LeftCtrl) ? scancode : 0;
  452         return 0;
  453     
  454     case KEY_LeftCtrl:                                                      /* Pause: Prefix1|LeftCtrl|NumLock */
  455         KeyPrefix=0;
  456         if( scancode!=KEY_NumLock )
  457         return 0;
  458         scancode=KEY_Pause;
  459         break;
  460     
  461     default:                                                                /* No prefix yet */
  462         switch( scancode ) {
  463         case KEY_Prefix0:
  464         case KEY_Prefix1:
  465             KeyPrefix=scancode;
  466             return 0;
  467         default:
  468             break;
  469         }
  470         break;
  471     }
  472     if( !released && (KeyDown[scancode>>3]&(1<<(scancode&7))) )                 /* Check for autorepeat */
  473     KeyState|=KEY_S_REPEAT;
  474     else
  475     KeyState&=~KEY_S_REPEAT;
  476 
  477     if( released )                                                              /* Set key in pressed/released set */
  478     KeyDown[scancode>>3]&=~(1<<(scancode&7));
  479     else
  480     KeyDown[scancode>>3]|=1<<(scancode&7);
  481 
  482     return released|scancode;
  483 }
  484 
  485 /*
  486  *      Set/Reset C64 Leftshift key.
  487  */
  488 static void LeftShift(key)
  489 int key;
  490 {
  491     if( key&KEY_Released ) {
  492     if( !IS_KEY_DOWN(KEY_LeftShift) ) {
  493         MatrixReset(0x02,0x80);
  494     }
  495     } else {
  496     MatrixSet(0x02,0x80);
  497     }
  498 }
  499 
  500 /*
  501  *      Convert scancode -> C64 key matrix
  502  */
  503 static void EncodeKey(key)
  504 int key;
  505 {
  506     int b,m;
  507     char buf[256];
  508 
  509     switch( key&0x7F ) {
  510     case KEY_Accent:        b=0x80; m=0x02; break;                          /* <- */
  511     case KEY_1:             b=0x80; m=0x01; break;
  512     case KEY_2:             b=0x80; m=0x08; break;
  513     case KEY_3:             b=0x02; m=0x01; break;
  514     case KEY_4:             b=0x02; m=0x08; break;
  515     case KEY_5:             b=0x04; m=0x01; break;
  516     case KEY_6:             b=0x04; m=0x08; break;
  517     case KEY_7:             b=0x08; m=0x01; break;
  518     case KEY_8:             b=0x08; m=0x08; break;
  519     case KEY_9:             b=0x10; m=0x01; break;
  520     case KEY_0:             b=0x10; m=0x08; break;
  521     case KEY_Minus:         b=0x20; m=0x01; break;                          /* + */
  522     case KEY_Equal:         b=0x20; m=0x08; break;                          /* - */
  523     case KEY_Home:          b=0x40; m=0x08; break;                          /* CLR/HOME */
  524     case KEY_BackSpace:     b=0x01; m=0x01; break;                          /* INS/DEL */
  525 
  526     case KEY_Tab:           b=0x80; m=0x04; break;                          /* Control */
  527     case KEY_Q:             b=0x80; m=0x40; break;
  528     case KEY_W:             b=0x02; m=0x02; break;
  529     case KEY_E:             b=0x02; m=0x40; break;
  530     case KEY_R:             b=0x04; m=0x02; break;
  531     case KEY_T:             b=0x04; m=0x40; break;
  532     case KEY_Y:             b=0x08; m=0x02; break;
  533     case KEY_U:             b=0x08; m=0x40; break;
  534     case KEY_I:             b=0x10; m=0x02; break;
  535     case KEY_O:             b=0x10; m=0x40; break;
  536     case KEY_P:             b=0x20; m=0x02; break;
  537     case KEY_LeftBrace:     b=0x20; m=0x40; break;                          /* @ */
  538     case KEY_RightBrace:    b=0x40; m=0x02; break;                          /* * */
  539 
  540     case KEY_PageDown:                          /* be nice to 101-keyboard-users */
  541     case KEY_102:           b=0x40; m=0x40; break;                          /* Arrow up */
  542     case KEY_PageUp:    b=0x40; m=0x01; break;              /* pound */
  543 
  544     case KEY_CapsLock:      b=0x80; m=0x80; break;                          /* RUN/STOP */
  545     case KEY_A:             b=0x02; m=0x04; break;
  546     case KEY_S:             b=0x02; m=0x20; break;
  547     case KEY_D:             b=0x04; m=0x04; break;
  548     case KEY_F:             b=0x04; m=0x20; break;
  549     case KEY_G:             b=0x08; m=0x04; break;
  550     case KEY_H:             b=0x08; m=0x20; break;
  551     case KEY_J:             b=0x10; m=0x04; break;
  552     case KEY_K:             b=0x10; m=0x20; break;
  553     case KEY_L:             b=0x20; m=0x04; break;
  554     case KEY_SemiColon:     b=0x20; m=0x20; break;                          /* : */
  555     case KEY_Quote:         b=0x40; m=0x04; break;                          /* ; */
  556     case KEY_BackSlash:     b=0x40; m=0x20; break;                          /* = */
  557     case KEY_KP_Enter:
  558     case KEY_Return:        b=0x01; m=0x02; break;                          /* RETURN */
  559 
  560     case KEY_LeftShift:     b=0x02; m=0x80; break;                          /* Leftshift */
  561     case KEY_Z:             b=0x02; m=0x10; break;
  562     case KEY_X:             b=0x04; m=0x80; break;
  563     case KEY_C:             b=0x04; m=0x10; break;
  564     case KEY_V:             b=0x08; m=0x80; break;
  565     case KEY_B:             b=0x08; m=0x10; break;
  566     case KEY_N:             b=0x10; m=0x80; break;
  567     case KEY_M:             b=0x10; m=0x10; break;
  568     case KEY_Comma:         b=0x20; m=0x80; break;                          /* , */
  569     case KEY_Dot:           b=0x20; m=0x10; break;                          /* . */
  570     case KEY_KP_Divide:
  571     case KEY_Slash:         b=0x40; m=0x80; break;                          /* / */
  572     case KEY_RightShift:    b=0x40; m=0x10; break;                          /* Rightshift */
  573 
  574     case KEY_Space:         b=0x80; m=0x10; break;                          /* Space */
  575 
  576     case KEY_F1:            if IS_VTSW_QUAL {
  577                     VT_ACTCON(0);
  578                     return;
  579                 } else {
  580                     b=0x01; m=0x10;
  581                 } break;                                        /* F1 */
  582     case KEY_F3:            if IS_VTSW_QUAL {
  583                     VT_ACTCON(2);
  584                     return;
  585                 } else {
  586                     b=0x01; m=0x20;
  587                 } break;                                        /* F3 */
  588     case KEY_F5:            if IS_VTSW_QUAL {
  589                     VT_ACTCON(4);
  590                     return;
  591                 } else {
  592                     b=0x01; m=0x40;
  593                 } break;                                        /* F5 */
  594     case KEY_F7:            if IS_VTSW_QUAL {
  595                     VT_ACTCON(6);
  596                     return;
  597                 } else {
  598                     b=0x01; m=0x08;
  599                 } break;                                        /* F7 */
  600     case KEY_Right:         b=0x01; m=0x04; break;                          /* Right/Left */
  601     case KEY_Down:          b=0x01; m=0x80; break;                          /* Down/Up */
  602 
  603     case KEY_LeftCtrl:      b=0x80; m=0x04; break;                          /* Control */
  604 
  605     case KEY_LeftAlt:       b=0x80; m=0x20; break;                          /* C= */
  606     case KEY_RightAlt:      b=0x80; m=0x20; break;                          /* C= */
  607 
  608     case KEY_End:
  609         if( key&KEY_Released ) Nmi();       return;                         /* Restore */
  610 
  611 /*---------------------------------------------------------------------------*/
  612 
  613     case KEY_Insert:
  614         LeftShift(key);     b=0x01; m=0x01; break;                          /* Shift + INS/DEL */
  615 
  616     case KEY_Up:
  617         LeftShift(key);     b=0x01; m=0x80; break;                          /* Shift + Down/Up */
  618 
  619     case KEY_Left:
  620         LeftShift(key);     b=0x01; m=0x04; break;                          /* Shift + Right/Left */
  621 
  622     case KEY_F2:            if IS_VTSW_QUAL {
  623                     VT_ACTCON(1);
  624                     return;
  625                 } else {
  626         LeftShift(key);     b=0x01; m=0x10; break;                          /* Shift + F1 */
  627                 }
  628     case KEY_F4:            if IS_VTSW_QUAL {
  629                     VT_ACTCON(3);
  630                     return;
  631                 } else {
  632         LeftShift(key);     b=0x01; m=0x20; break;                          /* Shift + F3 */
  633                 }
  634     case KEY_F6:            if IS_VTSW_QUAL {
  635                     VT_ACTCON(5);
  636                     return;
  637                 } else {
  638         LeftShift(key);     b=0x01; m=0x40; break;                          /* Shift + F5 */
  639                 }
  640     case KEY_F8:            if IS_VTSW_QUAL {
  641                     VT_ACTCON(7);
  642                     return;
  643                 } else {
  644         LeftShift(key);     b=0x01; m=0x08; break;                          /* Shift + F7 */
  645                 }
  646 
  647 /*---------------------------------------------------------------------------*/
  648 
  649     case KEY_KP_7:                                                          /* Joystick Left+Up */
  650         if( key&KEY_Released ) {
  651         if( !IS_KEY_DOWN(KEY_KP_8) )
  652             *JoyStick|=0x1;
  653         if( !IS_KEY_DOWN(KEY_KP_4) )
  654             *JoyStick|=0x4;
  655         } else {
  656         *JoyStick&=~0x5;
  657         }
  658         return;
  659     case KEY_KP_8:                                                          /* Joystick Up */
  660         if( key&KEY_Released ) {
  661         if( !IS_KEY_DOWN(KEY_KP_7) && !IS_KEY_DOWN(KEY_KP_9) )
  662             *JoyStick|=0x1;
  663         } else {
  664         *JoyStick&=~0x1;
  665         }
  666         return;
  667     case KEY_KP_9:                                                          /* Joystick Right+Up */
  668         if( key&KEY_Released ) {
  669         if( !IS_KEY_DOWN(KEY_KP_8) )
  670             *JoyStick|=0x1;
  671         if( !IS_KEY_DOWN(KEY_KP_6) )
  672             *JoyStick|=0x8;
  673         } else {
  674         *JoyStick&=~0x9;
  675         }
  676         return;
  677     case KEY_KP_4:                                                          /* Joystick Left */
  678         if( key&KEY_Released ) {
  679         if( !IS_KEY_DOWN(KEY_KP_7) && !IS_KEY_DOWN(KEY_KP_1) )
  680             *JoyStick|=0x4;
  681         } else {
  682         *JoyStick&=~0x4;
  683         }
  684         return;
  685     case KEY_KP_6:                                                          /* Joystick Right */
  686         if( key&KEY_Released ) {
  687         if( !IS_KEY_DOWN(KEY_KP_9) && !IS_KEY_DOWN(KEY_KP_3) )
  688             *JoyStick|=0x8;
  689         } else {
  690         *JoyStick&=~0x8;
  691         }
  692         return;
  693     case KEY_KP_1:                                                          /* Joystick Left+Down */
  694         if( key&KEY_Released ) {
  695         if( !IS_KEY_DOWN(KEY_KP_4) )
  696             *JoyStick|=0x4;
  697         if( !IS_KEY_DOWN(KEY_KP_2) )
  698             *JoyStick|=0x2;
  699         } else {
  700         *JoyStick&=~0x6;
  701         }
  702         return;
  703     case KEY_KP_2:                                                          /* Joystick Down */
  704         if( key&KEY_Released ) {
  705         if( !IS_KEY_DOWN(KEY_KP_1) && !IS_KEY_DOWN(KEY_KP_3) )
  706             *JoyStick|=0x2;
  707         } else {
  708         *JoyStick&=~0x2;
  709         }
  710         return;
  711     case KEY_KP_3:                                                          /* Joystick Right+Down */
  712         if( key&KEY_Released ) {
  713         if( !IS_KEY_DOWN(KEY_KP_6) )
  714             *JoyStick|=0x8;
  715         if( !IS_KEY_DOWN(KEY_KP_2) )
  716             *JoyStick|=0x2;
  717         } else {
  718         *JoyStick&=~0xA;
  719         }
  720         return;
  721     case KEY_KP_5:
  722     case KEY_RightCtrl:                         /* Control */
  723     case KEY_Escape:                            /* Joystick Fire */
  724         if( key&KEY_Released ) {
  725         *JoyStick|=0x10;
  726         } else {
  727         *JoyStick&=~0x10;
  728         }
  729         return;
  730     case KEY_NumLock:                                                       /* Joystick emulation toggle */
  731         if( key&KEY_Released ) {
  732         if( JoyStick==&JoyStick2 ) {
  733             JoyStick = &JoyStick1, OtherJoyStick = &JoyStick2;
  734             VicMessage("Joystick 1",FRAMES_PER_SECOND);
  735         } else {
  736             JoyStick = &JoyStick2, OtherJoyStick = &JoyStick1;
  737             VicMessage("Joystick 2",FRAMES_PER_SECOND);
  738         }
  739         }
  740         JoyStick2 = JoyStick1 = 0xFF;
  741         ShowLeds(0);
  742         return;
  743 
  744 /*---------------------------------------------------------------------------*/
  745 
  746     case KEY_F9:                                                            /* Video timing test +- */
  747         if IS_VTSW_QUAL 
  748             VT_ACTCON(8);
  749         else if( key&KEY_Released ) {
  750         if( IS_KEY_DOWN(KEY_LeftShift) )
  751             ++VicFetch;
  752         else
  753             --VicFetch;
  754         sprintf(buf,"%d fetch",VicFetch);
  755         VicMessage(buf,FRAMES_PER_SECOND);
  756         }
  757         return;
  758 
  759     case KEY_F10:                                                           /* Video timing test +- */
  760         if IS_VTSW_QUAL 
  761             VT_ACTCON(9);
  762         else if( key&KEY_Released ) {
  763         if( IS_KEY_DOWN(KEY_LeftShift) )
  764             ++VicFetchAdd;
  765         else
  766             --VicFetchAdd;
  767         sprintf(buf,"%d add",VicFetchAdd);
  768         VicMessage(buf,FRAMES_PER_SECOND);
  769         }
  770         return;
  771 
  772     case KEY_F11:                                                           /* Sound on/off toggle */
  773         if IS_VTSW_QUAL 
  774             VT_ACTCON(10);
  775         else if( key&KEY_Released ) {
  776         ToggleSound();
  777         if( SidSoundOff ) {
  778             VicMessage("sound off",FRAMES_PER_SECOND);
  779         } else {
  780             VicMessage("sound on",FRAMES_PER_SECOND);
  781         }
  782         }
  783         return;
  784 
  785     case KEY_F12:
  786         if IS_VTSW_QUAL {
  787             VT_ACTCON(11);
  788         return;
  789         }
  790         if( key&KEY_Released ) {
  791         if( IS_KEY_DOWN(KEY_RightCtrl) || IS_KEY_DOWN(KEY_LeftCtrl) ) { /* Freeze/make snapshot */
  792             SaveSnapShot(C64SNAPSHOT);
  793         } else {                                                        /* Enter monitor */
  794             MonitorOn();
  795         }
  796         }
  797         return;
  798 
  799     case KEY_Print:                                                         /* Autofire on/off toggle */
  800         if( key&KEY_Released ) {
  801         if( IS_KEY_DOWN(KEY_LeftAlt) || IS_KEY_DOWN(KEY_RightAlt) )
  802             Exit(0);
  803         AutoFire^=1;
  804         if( !AutoFire ) {
  805             if( IS_KEY_DOWN(KEY_Escape) ) {
  806             *JoyStick|=0x10;
  807             }
  808             VicMessage("Autofire off",FRAMES_PER_SECOND);
  809         } else {
  810             VicMessage("Autofire on",FRAMES_PER_SECOND);
  811         }
  812         ShowLeds(0);
  813         }
  814         return;
  815 
  816     case KEY_SysReqest:                         /* Leave emulator */
  817         if( key&KEY_Released ) {
  818         Exit(0);
  819         }
  820         return;
  821 
  822     case KEY_ScrollLock:                                                    /* Update speed round about */
  823         if( key&KEY_Released ) {
  824         if( IS_KEY_DOWN(KEY_LeftShift) ) {
  825             VicEmulateRate=(VicEmulateRate&3)+1;
  826             sprintf(buf,"1/%d emulate",VicEmulateRate);
  827             VicMessage(buf,FRAMES_PER_SECOND);
  828             ShowLeds(0);
  829         } else {
  830             VicRefreshRate=(VicRefreshRate&3)+1;
  831             sprintf(buf,"1/%d updates",VicRefreshRate);
  832             VicMessage(buf,FRAMES_PER_SECOND);
  833             ShowLeds(0);
  834         }
  835         }
  836         return;
  837 
  838     case KEY_KP_Dot:                                                        /* Exit/Interrupt key 2 */
  839         if( key&KEY_Released )
  840 #ifndef __OLD__
  841         if (IS_KEY_DOWN(KEY_LeftAlt) && IS_KEY_DOWN(KEY_LeftCtrl))
  842 #endif
  843             Exit(0);
  844         return;
  845 
  846     case KEY_Delete:                                                        /* DEL - Exit/Interrupt key */
  847         if( key&KEY_Released ) {
  848 #ifndef __OLD__
  849         if (IS_KEY_DOWN(KEY_LeftAlt) && IS_KEY_DOWN(KEY_LeftCtrl))
  850 #endif
  851             Exit(0);
  852         }
  853         b=0x01; m=0x01; break;                                      /* INS/DEL */
  854 
  855     case KEY_Pause:                                                         /* C64 emulator pause */
  856         if( key&KEY_Released ) {
  857         SuspendSound();
  858         SuspendKeyboard();
  859         SuspendVideo();
  860         printf("Come back...\n");
  861         while( getchar()!='\n' )
  862             ;
  863         ResumeVideo();
  864         ResumeKeyboard();
  865         ResumeSound();
  866         }
  867         return;
  868 
  869     case KEY_Break:                                                         /* C64 emulator reset */
  870         if( key&KEY_Released )
  871         Reset();
  872         return;
  873     
  874     case KEY_KP_Plus:
  875         HandleKey(!(key&KEY_Released),KEY_NEXT_DISC);
  876         return;
  877     case KEY_KP_Minus:
  878         HandleKey(!(key&KEY_Released),KEY_PREV_DISC);
  879         return;
  880     case KEY_KP_Multiply:
  881         HandleKey(!(key&KEY_Released),KEY_FASTLOADER_TOGGLE);
  882         return;
  883 
  884     default:
  885         /* For keyboard debugging:
  886         Cleanup();
  887         printf("unkown key-code %d\n",key);
  888         abort();
  889         */
  890         return;
  891     }
  892     if( key&KEY_Released ) {
  893     MatrixReset(b,m);
  894     } else {
  895     MatrixSet(b,m);
  896     }
  897 }
  898 
  899 /*
  900  *      Look for keyboard events.
  901  *
  902  *      Translate system keyboard events -> c64 keyboard matrix
  903  *
  904  *      Called with 50hz/60hz in video blank.
  905  */
  906 void EmulKeyboard(void)
  907 {
  908     int key;
  909 
  910     while ((key = kbgetkey()) != -1) 
  911     { 
  912     if((key=KeyboardLevel0(key)) && !(KeyState&KEY_S_REPEAT)) 
  913     {
  914         EncodeKey(key);
  915         if(!(key & KEY_Released)) 
  916         { 
  917         while ((key = kbsnoopkey()) != -1)
  918         {
  919             if (key & KEY_Released)
  920             break;
  921             (void)kbgetkey();
  922             if( (key=KeyboardLevel0(key)) && !(KeyState&KEY_S_REPEAT) )
  923             EncodeKey(key);
  924         }
  925         }
  926     }
  927     }
  928 
  929     /*
  930     **  Autofire on and ESCAPE pressed toggle fire button
  931     */
  932     if( AutoFire && (IS_KEY_DOWN(KEY_Escape) && IS_KEY_DOWN(KEY_RightCtrl)) ) {
  933     *JoyStick^=0x10;
  934     }
  935 }
  936 
  937 #endif  /* } __GO32__ */
  938 
  939 /*
  940  *      PORTING:          
  941  *
  942  *              EnterKey        Turn keyboard on
  943  *              LeaveKey        Turn keyboard off
  944  *              EmulKeyboard    Translate keys
  945  *              ShowLeds        Show some states
  946  */