major work on keyboard driver

Wed, 09 Feb 2011 16:35:49 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Wed, 09 Feb 2011 16:35:49 +0000
changeset 84
0d903718da81
parent 83
7d2f720daed8
child 85
9883eb142f70

major work on keyboard driver

doc/3B1 Memory Map.ods file | annotate | diff | revisions
src/keyboard.c file | annotate | diff | revisions
src/memory.c file | annotate | diff | revisions
     1.1 diff -r 7d2f720daed8 -r 0d903718da81 doc/3B1 Memory Map.ods
     1.2 Binary file doc/3B1 Memory Map.ods has changed
     2.1 diff -r 7d2f720daed8 -r 0d903718da81 src/keyboard.c
     2.2 --- a/src/keyboard.c	Wed Feb 09 15:43:48 2011 +0000
     2.3 +++ b/src/keyboard.c	Wed Feb 09 16:35:49 2011 +0000
     2.4 @@ -146,8 +146,12 @@
     2.5  
     2.6  	// scan the keymap
     2.7  	int keyidx = 0;
     2.8 +	bool found = false;
     2.9  	for (keyidx=0; keyidx < sizeof(keymap)/sizeof(keymap[0]); keyidx++) {
    2.10 -		if (keymap[keyidx].key == ev->key.keysym.sym) break;
    2.11 +		if (keymap[keyidx].key == ev->key.keysym.sym) {
    2.12 +			found = true;
    2.13 +			break;
    2.14 +		}
    2.15  	}
    2.16  
    2.17  	switch (ev->type) {
    2.18 @@ -157,23 +161,45 @@
    2.19  			break;
    2.20  		// key released
    2.21  		case SDL_KEYUP:
    2.22 -			ks->keystate[keymap[keyidx].scancode] = 1;
    2.23 +			ks->keystate[keymap[keyidx].scancode] = 0;
    2.24  			break;
    2.25  	}
    2.26  }
    2.27  
    2.28  void keyboard_scan(KEYBOARD_STATE *ks)
    2.29  {
    2.30 +	int nkeys = 0;
    2.31 +
    2.32  	// if buffer empty, do a keyboard scan
    2.33  	if (ks->buflen == 0) {
    2.34 -		// TODO: inject "keyboard data follows" chunk header
    2.35 +		// Keyboard Data Begins Here (BEGKBD)
    2.36 +		ks->buffer[ks->writep] = 0xDF;
    2.37 +		ks->writep = (ks->writep + 1) % KEYBOARD_BUFFER_SIZE;
    2.38 +		if (ks->buflen < KEYBOARD_BUFFER_SIZE) ks->buflen++;
    2.39 +
    2.40  		for (int i=0; i<(sizeof(ks->keystate)/sizeof(ks->keystate[0])); i++) {
    2.41  			if (ks->keystate[i]) {
    2.42 +				printf("\tKBC KEY DOWN: %d\n", i);
    2.43  				ks->buffer[ks->writep] = i;
    2.44  				ks->writep = (ks->writep + 1) % KEYBOARD_BUFFER_SIZE;
    2.45 +				if (ks->buflen < KEYBOARD_BUFFER_SIZE) ks->buflen++;
    2.46 +				nkeys++;
    2.47  			}
    2.48  		}
    2.49 +
    2.50 +		// If no keys down, then send All Keys Up byte
    2.51 +		if (nkeys == 0) {
    2.52 +			ks->buffer[ks->writep] = 0x40;
    2.53 +			ks->writep = (ks->writep + 1) % KEYBOARD_BUFFER_SIZE;
    2.54 +			if (ks->buflen < KEYBOARD_BUFFER_SIZE) ks->buflen++;
    2.55 +		}
    2.56 +
    2.57  		// TODO: inject "mouse data follows" chunk header and mouse movement info
    2.58 +
    2.59 +		// Last Entry In List
    2.60 +		ks->buffer[ks->writep] = 0x80;
    2.61 +		ks->writep = (ks->writep + 1) % KEYBOARD_BUFFER_SIZE;
    2.62 +		if (ks->buflen < KEYBOARD_BUFFER_SIZE) ks->buflen++;
    2.63  	}
    2.64  }
    2.65  
    2.66 @@ -200,19 +226,22 @@
    2.67  {
    2.68  	if ((addr & 1) == 0) {
    2.69  		// Status register -- RS=0, read
    2.70 -		return
    2.71 -			(ks->buflen > 0) ? 1 : 0 +		// SR0: a new character has been received
    2.72 -			0 +								// SR1: Transmitter Data Register Empty
    2.73 -			0 +								// SR2: Data Carrier Detect
    2.74 -			0 +								// SR3: Clear To Send
    2.75 -			0 +								// SR4: Framing Error
    2.76 -			0 +								// SR5: Receiver Overrun
    2.77 -			0 +								// SR6: Parity Error
    2.78 -			(keyboard_get_irq(ks)) ? 0x80 : 0;	// SR7: IRQ status
    2.79 +		uint8_t sr = 0;
    2.80 +		if (ks->buflen > 0) sr |= 1;			// SR0: a new character has been received
    2.81 +		sr |= 2;								// SR1: Transmitter Data Register Empty
    2.82 +//			0 +								// SR2: Data Carrier Detect
    2.83 +//			0 +								// SR3: Clear To Send
    2.84 +//			0 +								// SR4: Framing Error
    2.85 +//			0 +								// SR5: Receiver Overrun
    2.86 +//			0 +								// SR6: Parity Error
    2.87 +		if (keyboard_get_irq(ks)) sr |= 0x80;	// SR7: IRQ status
    2.88 +		printf("\tKBD DBG: sr=%02X\n", sr);
    2.89 +		return sr;
    2.90  	} else {
    2.91  		// return data, pop off the fifo
    2.92  		uint8_t x = ks->buffer[ks->readp];
    2.93  		ks->readp = (ks->readp + 1) % KEYBOARD_BUFFER_SIZE;
    2.94 +		if (ks->buflen > 0) ks->buflen--;
    2.95  		return x;
    2.96  	}
    2.97  }
    2.98 @@ -238,6 +267,7 @@
    2.99  		ks->rxie = (val & 0x80)==0x80;
   2.100  	} else {
   2.101  		// Write command to KBC -- TODO!
   2.102 +		printf("KBC TODO: write keyboard data 0x%02X\n", val);
   2.103  	}
   2.104  }
   2.105  
     3.1 diff -r 7d2f720daed8 -r 0d903718da81 src/memory.c
     3.2 --- a/src/memory.c	Wed Feb 09 15:43:48 2011 +0000
     3.3 +++ b/src/memory.c	Wed Feb 09 16:35:49 2011 +0000
     3.4 @@ -399,6 +399,11 @@
     3.5  						}
     3.6  						break;
     3.7  					case 0x070000:		// [ef][7f]xxxx ==> 6850 Keyboard Controller
     3.8 +						// TODO: figure out which sizes are valid (probably just 8 and 16)
     3.9 +						// ENFORCE_SIZE_W(bits, address, 16, "KEYBOARD CONTROLLER");
    3.10 +						printf("KBD WR %02X => %04X\n", (address >> 1) & 3, data >> 8);
    3.11 +						keyboard_write(&state.kbd, (address >> 1) & 3, data >> 8);
    3.12 +						handled = true;
    3.13  						break;
    3.14  				}
    3.15  		}
    3.16 @@ -544,6 +549,14 @@
    3.17  						}
    3.18  						break;
    3.19  					case 0x070000:		// [ef][7f]xxxx ==> 6850 Keyboard Controller
    3.20 +						// TODO: figure out which sizes are valid (probably just 8 and 16)
    3.21 +						//ENFORCE_SIZE_R(bits, address, 16, "KEYBOARD CONTROLLER");
    3.22 +						{
    3.23 +							uint16_t data = keyboard_read(&state.kbd, (address >> 1) & 3);
    3.24 +							data = (data << 8) + data;
    3.25 +							//printf("KBD RD %02X => %04X\n", (address >> 1) & 3, data);
    3.26 +							return data;
    3.27 +						}
    3.28  						break;
    3.29  				}
    3.30  		}