OSDN Git Service

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