"Fossies" - the Fresh Open Source Software Archive

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