1.1 --- a/src/keyboard.c Wed Dec 29 09:06:17 2010 +0000 1.2 +++ b/src/keyboard.c Wed Feb 09 15:03:31 2011 +0000 1.3 @@ -1,4 +1,6 @@ 1.4 +#include <stdbool.h> 1.5 #include "SDL.h" 1.6 +#include "keyboard.h" 1.7 1.8 /** 1.9 * Key map -- a mapping from SDLK_xxx constants to scancodes and vice versa. 1.10 @@ -126,19 +128,96 @@ 1.11 // { SDLK_, 1, 0x7f }, // Dlete 1.12 }; 1.13 1.14 -/** 1.15 - * List of key states 1.16 - */ 1.17 -int keystate[0x80]; 1.18 - 1.19 -void keyboard_init(void) 1.20 +void keyboard_init(KEYBOARD_STATE *ks) 1.21 { 1.22 // Set all key states to "not pressed" 1.23 - for (int i=0; i<(sizeof(keystate)/sizeof(keystate[0])); i++) { 1.24 - keystate[i] = 0; 1.25 + for (int i=0; i<(sizeof(ks->keystate)/sizeof(ks->keystate[0])); i++) { 1.26 + ks->keystate[i] = 0; 1.27 + } 1.28 + 1.29 + // Reset the R/W pointers and length 1.30 + ks->readp = ks->writep = ks->buflen = 0; 1.31 +} 1.32 + 1.33 +void keyboard_event(KEYBOARD_STATE *ks, SDL_Event *ev) 1.34 +{ 1.35 + // event handler -- handles SDL events 1.36 +} 1.37 + 1.38 +void keyboard_scan(KEYBOARD_STATE *ks) 1.39 +{ 1.40 + // if buffer empty, do a keyboard scan 1.41 + if (ks->buflen == 0) { 1.42 + for (int i=0; i<(sizeof(ks->keystate)/sizeof(ks->keystate[0])); i++) { 1.43 + if (ks->keystate[i]) { 1.44 + ks->buffer[ks->writep] = i; 1.45 + ks->writep = (ks->writep + 1) % KEYBOARD_BUFFER_SIZE; 1.46 + } 1.47 + } 1.48 } 1.49 } 1.50 1.51 -void keyboard_event(SDL_Event *ev) 1.52 +bool keyboard_get_irq(KEYBOARD_STATE *ks) 1.53 +{ 1.54 + bool irq_status = false; 1.55 + 1.56 + // Conditions which may cause an IRQ :- 1.57 + // Read Data Reg has data and RxIRQ enabled 1.58 + if (ks->rxie) 1.59 + if (ks->buflen > 0) irq_status = true; 1.60 + 1.61 + // Transmit Data Reg empty and TxIRQ enabled 1.62 +// if (ks->txie) 1.63 + 1.64 + // DCD set and RxIRQ enabled 1.65 +// 1.66 + 1.67 + // returns interrupt status -- i.e. is there data in the buffer? 1.68 + return irq_status; 1.69 +} 1.70 + 1.71 +uint8_t keyboard_read(KEYBOARD_STATE *ks, uint8_t addr) 1.72 { 1.73 + if ((addr & 1) == 0) { 1.74 + // Status register -- RS=0, read 1.75 + return 1.76 + (ks->buflen > 0) ? 1 : 0 + // SR0: a new character has been received 1.77 + 0 + // SR1: Transmitter Data Register Empty 1.78 + 0 + // SR2: Data Carrier Detect 1.79 + 0 + // SR3: Clear To Send 1.80 + 0 + // SR4: Framing Error 1.81 + 0 + // SR5: Receiver Overrun 1.82 + 0 + // SR6: Parity Error 1.83 + (keyboard_get_irq(ks)) ? 0x80 : 0; // SR7: IRQ status 1.84 + } else { 1.85 + // return data, pop off the fifo 1.86 + uint8_t x = ks->buffer[ks->readp]; 1.87 + ks->readp = (ks->readp + 1) % KEYBOARD_BUFFER_SIZE; 1.88 + return x; 1.89 + } 1.90 } 1.91 + 1.92 +void keyboard_write(KEYBOARD_STATE *ks, uint8_t addr, uint8_t val) 1.93 +{ 1.94 + if ((addr & 1) == 0) { 1.95 + // write to control register 1.96 + // transmit intr enabled when CR6,5 = 01 1.97 + // receive intr enabled when CR7 = 1 1.98 + 1.99 + // CR0,1 = divider registers. When =11, do a software reset 1.100 + if ((val & 3) == 3) { 1.101 + ks->readp = ks->writep = ks->buflen = 0; 1.102 + } 1.103 + 1.104 + // Ignore CR2,3,4 (word length)... 1.105 + 1.106 + // CR5,6 = Transmit Mode 1.107 + ks->txie = (val & 0x60)==0x20; 1.108 + 1.109 + // CR7 = Receive Interrupt Enable 1.110 + ks->rxie = (val & 0x80)==0x80; 1.111 + } else { 1.112 + // Write command to KBC -- TODO! 1.113 + } 1.114 +} 1.115 +