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