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