src/keyboard.c

changeset 80
9581358e92b0
parent 74
51cbc7a44cd9
child 82
4c72b03ffdc0
     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 +