]> 4ch.mooo.com Git - 16.git/blob - 16/modex16/dos_kb.c
16_ca needs huge amounts of work and I should remember what needs to be done soon...
[16.git] / 16 / modex16 / dos_kb.c
1 /* Thanks to Alex Russell for example code */
2 /* Thanks to Gary Neal for example code */
3 #include "dos_kb.h"
4
5 // keyboard buffer
6 static byte key[NUM_SCANCODES]; // pressed
7 static byte kea[NUM_SCANCODES]; // released
8
9 #ifdef __cplusplus              /* Function must be declared C style */
10 extern "C" {
11 #endif
12 static void interrupt (far *oldkb)(void) = NULL; /* BIOS keyboard handler */
13 #ifdef __cplusplus
14 }
15 #endif
16
17 /*
18  * Comment out the following #define if you don't want the testing main()
19  * to be included.
20  */
21 //#define TESTING
22 #define TESTING2
23
24 /*****************NEW KEYBOARD 09h ISR***********************/
25 void interrupt newkb(void){
26         byte kee;
27         register char qx;
28
29         kee = inp(0x60);        /* Read the keyboard scan code */
30
31         /* Clear keyboard controller on XT machines */
32         qx = inp(0x61);    /* Get keyboard control register */
33         qx |= 0x82;
34         outp(0x61, qx);    /* Toggle acknowledge bit high */
35         qx &= 0x7F;
36         outp(0x61, qx);    /* Toggle acknowledge bit low */
37
38         /* Interpret the scan code and set our flags */
39         #ifdef TESTING2
40         //printf("%d[%d]\n",kee,key[kee]);
41         printf("\0"); // bug
42         #endif
43         if(kee & 0x80)
44                 key[kee & 0x7F] = 0; // a key is released
45         else
46                 key[kee] = kea[kee] = 1; // a key is pressed
47
48         /* Acknowledge the interrupt to the programmable interrupt controller */
49         outp(0x20, 0x20);      /* Signal non specific end of interrupt */
50 }
51
52 /* ---------------------- init_keyboard() ---------------- April 17,1993 */
53 /* restore the bios keyboard handler */
54 /* ---------------------- deinit_keyboard() -------------- April 17,1993 */
55 void setkb(int vq){
56         int i;  /* Index variable */
57         if(!vq){ // deinitiation
58                 /* Abort if our function pointer has no valid address */
59                 if(oldkb == NULL) return;
60                 /* Set address in our function pointer in interrupt vector table */
61                 _dos_setvect(9, oldkb);
62                 /* Reset our function pointer to contain no valid address */
63                 oldkb = NULL;
64                 #ifdef TESTING
65                 /* Print the key heap */
66                 printf("\n");
67                 for(i=0; i<NUM_SCANCODES; i++){
68                         if(i==NUM_SCANCODES/2) printf("================================\n");
69                         printf("%03d[%d][%d]",i+1,key[i],kea[i]);
70                         if(key[i]==1)printf("====");
71                         printf(",\n");
72                 }
73                 #endif
74         }else if(vq == 1){ // initiation
75                 byte far *lock_key;
76
77                 /* Abort if our function pointer has a valid address. */
78                 if(oldkb != NULL) return;
79
80                 /* Clear the keyboard buttons state arrays */
81                 for(i = 0; i < NUM_SCANCODES; i++)
82                         key[i] = kea[i] = 0;
83
84                 /* save old BIOS key board handler */
85                 oldkb = _dos_getvect(9);
86
87                 // turn off num-lock via BIOS
88                 lock_key = MK_FP(0x040, 0x017); // Pointing to the address of the bios shift state keys
89                 *lock_key&=(~(16 | 32 | 64)); // toggle off the locks by changing the values of the 4th, 5th, and 6th bits of the address byte of 0040:0017
90                 oldkb();        // call BIOS keyhandler to change keyboard lights
91
92                 /* setup our own handler */
93                 _dos_setvect(9, newkb);
94         }
95 }
96
97 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
98  * keyp                                                       *
99  *                                                                       *
100  * Returns the status of the key requested.                             *
101  * The status is 1 if the key is pressed or has been pressed since the     *
102  * last call to this function for that particular key.               *
103 \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
104 int keyp(byte c){
105         register char retVal;
106
107         /* Key value in range of keyboard keys available */
108         c &= 0x7F;
109
110         /* Get the status of the key requested */
111         retVal = key[c] | kea[c];
112
113         /* Reset the was pressed status for the requested key */
114         kea[c] = 0;
115
116         /* Return the requested key's state */
117         return retVal;
118 }
119
120
121 /*
122  * The library testing routines follows below.
123  */
124
125 #ifdef TESTING
126
127 /*
128  * Library test (program) entry point.
129  */
130
131 void main(void)
132 {
133         byte q;
134         setkb(1);
135         while(!keyp(1))
136         {
137                 keyp(q);
138         }
139         setkb(0);
140 }
141
142 #endif