only send kb state when the state changes, use kb command constants

Wed, 09 Feb 2011 23:45:55 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Wed, 09 Feb 2011 23:45:55 +0000
changeset 91
781c15e60012
parent 90
934ae2efdd01
child 92
3d5680edc1f0

only send kb state when the state changes, use kb command constants

src/keyboard.c file | annotate | diff | revisions
src/keyboard.h file | annotate | diff | revisions
src/main.c file | annotate | diff | revisions
     1.1 diff -r 934ae2efdd01 -r 781c15e60012 src/keyboard.c
     1.2 --- a/src/keyboard.c	Wed Feb 09 22:05:42 2011 +0000
     1.3 +++ b/src/keyboard.c	Wed Feb 09 23:45:55 2011 +0000
     1.4 @@ -160,6 +160,9 @@
     1.5  
     1.6  	// Reset the R/W pointers and length
     1.7  	ks->readp = ks->writep = ks->buflen = 0;
     1.8 +
     1.9 +	// Clear the update flag
    1.10 +	ks->update_flag = false;
    1.11  }
    1.12  
    1.13  void keyboard_event(KEYBOARD_STATE *ks, SDL_Event *ev)
    1.14 @@ -179,6 +182,9 @@
    1.15  			return;
    1.16  	}
    1.17  
    1.18 +	// If we got here, then the keystate must have changed...!
    1.19 +	ks->update_flag = true;
    1.20 +
    1.21  	// scan the keymap
    1.22  	for (int i=0; i < sizeof(keymap)/sizeof(keymap[0]); i++) {
    1.23  		if (keymap[i].key == ev->key.keysym.sym) {
    1.24 @@ -204,10 +210,13 @@
    1.25  {
    1.26  	int nkeys = 0;
    1.27  
    1.28 +	// Skip doing the scan if the keyboard hasn't changed state
    1.29 +	if (!ks->update_flag) return;
    1.30 +
    1.31  	// if buffer empty, do a keyboard scan
    1.32  	if (ks->buflen == 0) {
    1.33  		// Keyboard Data Begins Here (BEGKBD)
    1.34 -		ks->buffer[ks->writep] = 0xDF;
    1.35 +		ks->buffer[ks->writep] = KEY_BEGIN_KEYBOARD;
    1.36  		ks->writep = (ks->writep + 1) % KEYBOARD_BUFFER_SIZE;
    1.37  		if (ks->buflen < KEYBOARD_BUFFER_SIZE) ks->buflen++;
    1.38  
    1.39 @@ -223,7 +232,7 @@
    1.40  
    1.41  		// If no keys down, then send All Keys Up byte
    1.42  		if (nkeys == 0) {
    1.43 -			ks->buffer[ks->writep] = 0x40;
    1.44 +			ks->buffer[ks->writep] = KEY_ALL_UP;
    1.45  			ks->writep = (ks->writep + 1) % KEYBOARD_BUFFER_SIZE;
    1.46  			if (ks->buflen < KEYBOARD_BUFFER_SIZE) ks->buflen++;
    1.47  		}
    1.48 @@ -231,10 +240,13 @@
    1.49  		// TODO: inject "mouse data follows" chunk header and mouse movement info
    1.50  
    1.51  		// Last Entry In List
    1.52 -		ks->buffer[ks->writep] = 0x80;
    1.53 -		ks->writep = (ks->writep + 1) % KEYBOARD_BUFFER_SIZE;
    1.54 -		if (ks->buflen < KEYBOARD_BUFFER_SIZE) ks->buflen++;
    1.55 +//		ks->buffer[ks->writep] = 0x80;
    1.56 +//		ks->writep = (ks->writep + 1) % KEYBOARD_BUFFER_SIZE;
    1.57 +//		if (ks->buflen < KEYBOARD_BUFFER_SIZE) ks->buflen++;
    1.58  	}
    1.59 +
    1.60 +	// Clear the update flag
    1.61 +	ks->update_flag = false;
    1.62  }
    1.63  
    1.64  bool keyboard_get_irq(KEYBOARD_STATE *ks)
    1.65 @@ -302,6 +314,10 @@
    1.66  	} else {
    1.67  		// Write command to KBC -- TODO!
    1.68  		printf("KBC TODO: write keyboard data 0x%02X\n", val);
    1.69 +		if (val == KEY_CMD_RESET) {
    1.70 +			printf("\tKBC: KEYBOARD RESET!\n");
    1.71 +			ks->readp = ks->writep = ks->buflen = 0;
    1.72 +		}
    1.73  	}
    1.74  }
    1.75  
     2.1 diff -r 934ae2efdd01 -r 781c15e60012 src/keyboard.h
     2.2 --- a/src/keyboard.h	Wed Feb 09 22:05:42 2011 +0000
     2.3 +++ b/src/keyboard.h	Wed Feb 09 23:45:55 2011 +0000
     2.4 @@ -27,6 +27,9 @@
     2.5  
     2.6  	/// Receive Interrupt Enable
     2.7  	bool rxie;
     2.8 +
     2.9 +	/// "Keyboard State Changed" flag
    2.10 +	bool update_flag;
    2.11  } KEYBOARD_STATE;
    2.12  
    2.13  /**
     3.1 diff -r 934ae2efdd01 -r 781c15e60012 src/main.c
     3.2 --- a/src/main.c	Wed Feb 09 22:05:42 2011 +0000
     3.3 +++ b/src/main.c	Wed Feb 09 23:45:55 2011 +0000
     3.4 @@ -211,15 +211,18 @@
     3.5  	const uint32_t TIMESLOT_FREQUENCY = 1000;//240;	// Hz
     3.6  	const uint32_t MILLISECS_PER_TIMESLOT = 1e3 / TIMESLOT_FREQUENCY;
     3.7  	const uint32_t CLOCKS_PER_60HZ = (10e6 / 60);
     3.8 +	const uint32_t CLOCKS_PER_KBC_REFRESH = (10e6 / 10);
     3.9  	uint32_t next_timeslot = SDL_GetTicks() + MILLISECS_PER_TIMESLOT;
    3.10 -	uint32_t clock_cycles = 0;
    3.11 +	uint32_t clock_cycles = 0, keyb_clocks = 0, tmp;
    3.12  	bool exitEmu = false;
    3.13 -	bool lastirq_fdc = false;
    3.14 +	bool lastirq_fdc = false, lastirq_kbc = false;
    3.15  	for (;;) {
    3.16  		// Run the CPU for however many cycles we need to. CPU core clock is
    3.17  		// 10MHz, and we're running at 240Hz/timeslot. Thus: 10e6/240 or
    3.18  		// 41667 cycles per timeslot.
    3.19 -		clock_cycles += m68k_execute(10e6/TIMESLOT_FREQUENCY);
    3.20 +		tmp = m68k_execute(10e6/TIMESLOT_FREQUENCY);
    3.21 +		clock_cycles += tmp;
    3.22 +		keyb_clocks += tmp;
    3.23  
    3.24  		// Run the DMA engine
    3.25  		if (state.dmaen) {
    3.26 @@ -333,14 +336,15 @@
    3.27  			if (wd2797_get_irq(&state.fdc_ctx)) {
    3.28  				lastirq_fdc = true;
    3.29  				m68k_set_irq(2);
    3.30 -			} else {
    3.31 -				lastirq_fdc = false;
    3.32  			}
    3.33 -*/		if (keyboard_get_irq(&state.kbd)) {
    3.34 -			// TODO: this is a LEVEL, not an EDGE!
    3.35 -			m68k_set_irq(3);
    3.36 +*/		if (!lastirq_kbc) {
    3.37 +			if (keyboard_get_irq(&state.kbd)) {
    3.38 +				lastirq_fdc = true;
    3.39 +				m68k_set_irq(3);
    3.40 +			}
    3.41  		} else {
    3.42  			lastirq_fdc = wd2797_get_irq(&state.fdc_ctx);
    3.43 +			lastirq_kbc = keyboard_get_irq(&state.kbd);
    3.44  			m68k_set_irq(0);
    3.45  		}
    3.46  
    3.47 @@ -349,10 +353,16 @@
    3.48  			// Refresh the screen
    3.49  			refreshScreen(screen);
    3.50  			// TODO: trigger periodic interrupt (if enabled)
    3.51 +			// decrement clock cycle counter, we've handled the intr.
    3.52 +			clock_cycles -= CLOCKS_PER_60HZ;
    3.53 +		}
    3.54 +
    3.55 +		// Is it time to run the keyboard refresh yet?
    3.56 +		if (keyb_clocks > CLOCKS_PER_KBC_REFRESH) {
    3.57  			// scan the keyboard
    3.58  			keyboard_scan(&state.kbd);
    3.59 -			// decrement clock cycle counter, we've handled the intr.
    3.60 -			clock_cycles -= CLOCKS_PER_60HZ;
    3.61 +			// decrement clock cycle counter
    3.62 +			keyb_clocks -= CLOCKS_PER_KBC_REFRESH;
    3.63  		}
    3.64  
    3.65  		// handle SDL events -- returns true if we need to exit