Wed, 09 Feb 2011 23:45:55 +0000
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