00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00063 #include "StdAfx.h"
00064 #include "System.h"
00065 #include "Keyboard.h"
00066 #include "AliM1543C.h"
00067 #include <math.h>
00068
00069 #include "gui/scancodes.h"
00070 #include "gui/keymap.h"
00071
00075 CKeyboard::CKeyboard(CConfigurator* cfg, CSystem* c) : CSystemComponent(cfg, c)
00076 {
00077 if(theKeyboard != 0)
00078 FAILURE(Configuration, "More than one Keyboard controller");
00079 theKeyboard = this;
00080 }
00081
00085 void CKeyboard::init()
00086 {
00087 int i;
00088
00089 cSystem->RegisterMemory(this, 0, U64(0x00000801fc000060), 1);
00090 cSystem->RegisterMemory(this, 1, U64(0x00000801fc000064), 1);
00091
00092 resetinternals(1);
00093
00094 state.kbd_internal_buffer.led_status = 0;
00095 state.kbd_internal_buffer.scanning_enabled = 1;
00096
00097 state.mouse_internal_buffer.num_elements = 0;
00098 for(i = 0; i < BX_MOUSE_BUFF_SIZE; i++)
00099 state.mouse_internal_buffer.buffer[i] = 0;
00100 state.mouse_internal_buffer.head = 0;
00101
00102 state.status.pare = 0;
00103 state.status.tim = 0;
00104 state.status.auxb = 0;
00105 state.status.keyl = 1;
00106 state.status.c_d = 1;
00107 state.status.sysf = 0;
00108 state.status.inpb = 0;
00109 state.status.outb = 0;
00110
00111 state.kbd_clock_enabled = 1;
00112 state.aux_clock_enabled = 0;
00113 state.allow_irq1 = 1;
00114 state.allow_irq12 = 1;
00115 state.kbd_output_buffer = 0;
00116 state.aux_output_buffer = 0;
00117 state.last_comm = 0;
00118 state.expecting_port60h = 0;
00119 state.irq1_requested = 0;
00120 state.irq12_requested = 0;
00121 state.expecting_mouse_parameter = 0;
00122 state.bat_in_progress = 0;
00123 state.scancodes_translate = 1;
00124
00125 state.timer_pending = 0;
00126
00127
00128 state.mouse.captured = myCfg->get_bool_value("mouse.enabled", true);
00129 state.mouse.sample_rate = 100;
00130 state.mouse.resolution_cpmm = 4;
00131 state.mouse.scaling = 1;
00132 state.mouse.mode = MOUSE_MODE_RESET;
00133 state.mouse.enable = 0;
00134 state.mouse.delayed_dx = 0;
00135 state.mouse.delayed_dy = 0;
00136 state.mouse.delayed_dz = 0;
00137 state.mouse.im_request = 0;
00138 state.mouse.im_mode = 0;
00139 for(i = 0; i < BX_KBD_CONTROLLER_QSIZE; i++)
00140 state.kbd_controller_Q[i] = 0;
00141 state.kbd_controller_Qsize = 0;
00142 state.kbd_controller_Qsource = 0;
00143
00144 myThread = 0;
00145
00146 printf("kbc: $Id: Keyboard.cpp,v 1.9 2008/03/16 11:22:08 iamcamiel Exp $\n");
00147 }
00148
00149 void CKeyboard::start_threads()
00150 {
00151 if(!myThread)
00152 {
00153 myThread = new Poco::Thread("kbd");
00154 printf(" %s", myThread->getName().c_str());
00155 StopThread = false;
00156 myThread->start(*this);
00157 }
00158 }
00159
00160 void CKeyboard::stop_threads()
00161 {
00162 StopThread = true;
00163 if(myThread)
00164 {
00165 printf(" %s", myThread->getName().c_str());
00166 myThread->join();
00167 delete myThread;
00168 myThread = 0;
00169 }
00170 }
00171
00175 CKeyboard::~CKeyboard()
00176 {
00177 stop_threads();
00178 }
00179
00180 u64 CKeyboard::ReadMem(int index, u64 address, int dsize)
00181 {
00182 switch(index)
00183 {
00184 case 0: return read_60(); break;
00185 case 1: return read_64(); break;
00186 default: FAILURE(InvalidArgument, "kbc: ReadMem index out of range");
00187 }
00188 }
00189
00190 void CKeyboard::WriteMem(int index, u64 address, int dsize, u64 data)
00191 {
00192 switch(index)
00193 {
00194 case 0: write_60((u8) data); break;
00195 case 1: write_64((u8) data); break;
00196 default: FAILURE(InvalidArgument, "kbc: ReadMem index out of range");
00197 }
00198 }
00199
00204 void CKeyboard::gen_scancode(u32 key)
00205 {
00206 unsigned char* scancode;
00207 u8 i;
00208
00209 #if defined(DEBUG_KBD)
00210 printf("gen_scancode(): %s %s \n", bx_keymap->getBXKeyName(key),
00211 (key >> 31) ? "released" : "pressed");
00212 if(!state.scancodes_translate)
00213 BX_DEBUG(("keyboard: gen_scancode with scancode_translate cleared"));
00214 #endif
00215
00216
00217 if(state.kbd_clock_enabled == 0)
00218 return;
00219
00220
00221 if(state.kbd_internal_buffer.scanning_enabled == 0)
00222 return;
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 if(key & BX_KEY_RELEASED)
00278 scancode = (unsigned char*) scancodes[(key & 0xFF)][state.current_scancodes_set].brek;
00279 else
00280 scancode = (unsigned char*) scancodes[(key & 0xFF)][state.current_scancodes_set].make;
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 if(state.scancodes_translate)
00313 {
00314
00315
00316 u8 escaped = 0x00;
00317
00318 for(i = 0; i < strlen((const char*) scancode); i++)
00319 {
00320 if(scancode[i] == 0xF0)
00321 {
00322 escaped = 0x80;
00323 }
00324 else
00325 {
00326 #if defined(DEBUG_KBD)
00327 printf("gen_scancode(): writing translated %02x \n",
00328 translation8042[scancode[i]] | escaped);
00329 #endif
00330 enQ(translation8042[scancode[i]] | escaped);
00331 escaped = 0x00;
00332 }
00333 }
00334 }
00335 else
00336 {
00337
00338
00339 for(i = 0; i < strlen((const char*) scancode); i++)
00340 {
00341 #if defined(DEBUG_KBD)
00342 printf("gen_scancode(): writing raw %02x \n", scancode[i]);
00343 #endif
00344 enQ(scancode[i]);
00345 }
00346 }
00347 }
00348
00352 void CKeyboard::resetinternals(bool powerup)
00353 {
00354 state.kbd_internal_buffer.num_elements = 0;
00355 for(int i = 0; i < BX_KBD_ELEMENTS; i++)
00356 state.kbd_internal_buffer.buffer[i] = 0;
00357 state.kbd_internal_buffer.head = 0;
00358
00359 state.kbd_internal_buffer.expecting_typematic = 0;
00360 state.kbd_internal_buffer.expecting_make_break = 0;
00361
00362
00363 state.expecting_scancodes_set = 0;
00364
00365
00366 state.current_scancodes_set = 2;
00367
00368
00369 if(powerup)
00370 {
00371 state.kbd_internal_buffer.expecting_led_write = 0;
00372 state.kbd_internal_buffer.delay = 1;
00373 state.kbd_internal_buffer.repeat_rate = 0x0b;
00374 }
00375 }
00376
00380 void CKeyboard::enQ(u8 scancode)
00381 {
00382 int tail;
00383
00384 #if defined(DEBUG_KBD)
00385 printf("enQ(0x%02x)", (unsigned) scancode);
00386 #endif
00387 if(state.kbd_internal_buffer.num_elements >= BX_KBD_ELEMENTS)
00388 {
00389 printf("internal keyboard buffer full, ignoring scancode.(%02x) \n",
00390 (unsigned) scancode);
00391 return;
00392 }
00393
00394
00395 #if defined(DEBUG_KBD)
00396 BX_DEBUG(("enQ: putting scancode 0x%02x in internal buffer", (unsigned) scancode));
00397 #endif
00398 tail =
00399 (
00400 state.kbd_internal_buffer.head +
00401 state.kbd_internal_buffer.num_elements
00402 ) %
00403 BX_KBD_ELEMENTS;
00404 state.kbd_internal_buffer.buffer[tail] = scancode;
00405 state.kbd_internal_buffer.num_elements++;
00406
00407 if(!state.status.outb && state.kbd_clock_enabled)
00408 {
00409 state.timer_pending = 1;
00410 return;
00411 }
00412 }
00413
00417 u8 CKeyboard::read_60()
00418 {
00419 u8 val;
00420
00421
00422 if(state.status.auxb)
00423 {
00424 val = state.aux_output_buffer;
00425 state.aux_output_buffer = 0;
00426 state.status.outb = 0;
00427 state.status.auxb = 0;
00428 state.irq12_requested = 0;
00429
00430 if(state.kbd_controller_Qsize)
00431 {
00432 unsigned i;
00433 state.aux_output_buffer = state.kbd_controller_Q[0];
00434 state.status.outb = 1;
00435 state.status.auxb = 1;
00436 if(state.allow_irq12)
00437 state.irq12_requested = 1;
00438 for(i = 0; i < state.kbd_controller_Qsize - 1; i++)
00439 {
00440
00441
00442 state.kbd_controller_Q[i] = state.kbd_controller_Q[i + 1];
00443 }
00444
00445 state.kbd_controller_Qsize--;
00446 }
00447
00448
00449 state.timer_pending = 1;
00450 execute();
00451 #if defined(DEBUG_KBD)
00452 BX_DEBUG(("[mouse] read from 0x60 returns 0x%02x", val));
00453 #endif
00454 return val;
00455 }
00456 else if(state.status.outb)
00457 {
00458 val = state.kbd_output_buffer;
00459 state.status.outb = 0;
00460 state.status.auxb = 0;
00461 state.irq1_requested = 0;
00462 state.bat_in_progress = 0;
00463
00464 if(state.kbd_controller_Qsize)
00465 {
00466 unsigned i;
00467 state.aux_output_buffer = state.kbd_controller_Q[0];
00468 state.status.outb = 1;
00469 state.status.auxb = 1;
00470 if(state.allow_irq1)
00471 state.irq1_requested = 1;
00472 for(i = 0; i < state.kbd_controller_Qsize - 1; i++)
00473 {
00474
00475
00476 state.kbd_controller_Q[i] = state.kbd_controller_Q[i + 1];
00477 }
00478
00479 #if defined(DEBUG_KBD)
00480 BX_DEBUG(("s.controller_Qsize: %02X", state.kbd_controller_Qsize));
00481 #endif
00482 state.kbd_controller_Qsize--;
00483 }
00484
00485
00486 state.timer_pending = 1;
00487 execute();
00488 #if defined(DEBUG_KBD)
00489 BX_DEBUG(("READ(60) = %02x", (unsigned) val));
00490 #endif
00491 return val;
00492 }
00493 else
00494 {
00495 #if defined(DEBUG_KBD)
00496 BX_DEBUG(("num_elements = %d", state.kbd_internal_buffer.num_elements));
00497 BX_DEBUG(("read from port 60h with outb empty"));
00498 BX_DEBUG(("READ(60) = %02x", state.kbd_output_buffer));
00499 #endif
00500 return state.kbd_output_buffer;
00501 }
00502 }
00503
00550 u8 CKeyboard::read_64()
00551 {
00552 u8 val;
00553
00554
00555 val = (state.status.pare << 7) | (state.status.tim << 6) |
00556 (state.status.auxb << 5) | (state.status.keyl << 4) |
00557 (state.status.c_d << 3) | (state.status.sysf << 2) |
00558 (state.status.inpb << 1) | (state.status.outb << 0);
00559 state.status.tim = 0;
00560 #if defined(DEBUG_KBD)
00561 BX_DEBUG(("read from 0x64 returns 0x%02x", val));
00562 #endif
00563 return val;
00564 }
00565
00569 void CKeyboard::write_60(u8 value)
00570 {
00571 #if defined(DEBUG_KBD)
00572 printf("kbd: port 60 write: %02x. \n", value);
00573 #endif
00574
00575
00576 state.status.c_d = 0;
00577
00578
00579 if(state.expecting_port60h)
00580 {
00581 state.expecting_port60h = 0;
00582 #if defined(DEBUG_KBD)
00583 if(state.status.inpb)
00584 printf("write to port 60h, not ready for write \n");
00585 #endif
00586 switch(state.last_comm)
00587 {
00588 case 0x60:
00589 {
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637 bool scan_convert;
00638
00639
00640 bool disable_keyboard;
00641
00642
00643 bool disable_aux;
00644
00645 scan_convert = (value >> 6) & 0x01;
00646 disable_aux = (value >> 5) & 0x01;
00647 disable_keyboard = (value >> 4) & 0x01;
00648 state.status.sysf = (value >> 2) & 0x01;
00649 state.allow_irq1 = (value >> 0) & 0x01;
00650 state.allow_irq12 = (value >> 1) & 0x01;
00651 set_kbd_clock_enable(!disable_keyboard);
00652 set_aux_clock_enable(!disable_aux);
00653 if(state.allow_irq12 && state.status.auxb)
00654 state.irq12_requested = 1;
00655 else if(state.allow_irq1 && state.status.outb)
00656 state.irq1_requested = 1;
00657
00658 #if defined(DEBUG_KBD)
00659 BX_DEBUG((" allow_irq12 set to %u", (unsigned) state.allow_irq12));
00660 if(!scan_convert)
00661 BX_INFO(("keyboard: scan convert turned off"));
00662 #endif
00663
00664
00665 state.scancodes_translate = scan_convert;
00666 }
00667 break;
00668
00669 case 0xd1:
00670 #if defined(DEBUG_KBD)
00671 BX_DEBUG(("write output port with value %02xh", (unsigned) value));
00672 #endif
00673 break;
00674
00675 case 0xd4:
00676
00677
00678 ctrl_to_mouse(value);
00679
00680
00681 break;
00682
00683 case 0xd3:
00684
00685 controller_enQ(value, 1);
00686 break;
00687
00688 case 0xd2:
00689
00690
00691 controller_enQ(value, 0);
00692 break;
00693
00694 default:
00695 printf("=== unsupported write to port 60h(lastcomm=%02x): %02x \n",
00696 (unsigned) state.last_comm, (unsigned) value);
00697 }
00698 }
00699 else
00700 {
00701
00702
00703 state.status.c_d = 0;
00704 state.expecting_port60h = 0;
00705
00706
00707
00708
00709 if(state.kbd_clock_enabled == 0)
00710 set_kbd_clock_enable(1);
00711 ctrl_to_kbd(value);
00712 }
00713
00714 execute();
00715 }
00716
00720 void CKeyboard::write_64(u8 value)
00721 {
00722 #if defined(DEBUG_KBD)
00723 printf("kbd: port 64 write: %02x. \n", value);
00724 #endif
00725
00726 static int kbd_initialized = 0;
00727 u8 command_byte;
00728
00729
00730 state.status.c_d = 1;
00731 state.last_comm = value;
00732
00733
00734 state.expecting_port60h = 0;
00735
00736 switch(value)
00737 {
00738 case 0x20:
00739 #if defined(DEBUG_KBD)
00740 BX_DEBUG(("get keyboard command byte"));
00741 #endif
00742
00743
00744 if(state.status.outb)
00745 {
00746 #if defined(DEBUG_KBD)
00747 BX_ERROR(("kbd: OUTB set and command 0x%02x encountered", value));
00748 #endif
00749 break;
00750 }
00751
00752 command_byte = (state.scancodes_translate << 6) |
00753 ((!state.aux_clock_enabled) << 5) | ((!state.kbd_clock_enabled) << 4) |
00754 (0 << 3) | (state.status.sysf << 2) | (state.allow_irq12 << 1) |
00755 (state.allow_irq1 << 0);
00756 controller_enQ(command_byte, 0);
00757 break;
00758
00759 case 0x60:
00760 #if defined(DEBUG_KBD)
00761 printf("kbd_ctrl: command 60: write command byte. \n");
00762 #endif
00763
00764
00765 state.expecting_port60h = 1;
00766 break;
00767
00768 case 0xa0:
00769 #if defined(DEBUG_KBD)
00770 printf("kbd_ctrl: command a0: BIOS name (not supported). \n");
00771 #endif
00772 break;
00773
00774 case 0xa1:
00775 #if defined(DEBUG_KBD)
00776 printf("kbd_ctrl: command a0: BIOS version (not supported). \n");
00777 #endif
00778 break;
00779
00780 case 0xa7:
00781 set_aux_clock_enable(0);
00782 #if defined(DEBUG_KBD)
00783 printf("kbd_ctrl: command a7: aux i/f disable. \n");
00784 #endif
00785 break;
00786
00787 case 0xa8:
00788 set_aux_clock_enable(1);
00789 #if defined(DEBUG_KBD)
00790 printf("kbd_ctrl: command a7: aux i/f enable. \n");
00791 #endif
00792 break;
00793
00794 case 0xa9:
00795
00796 #if defined(DEBUG_KBD)
00797 printf("kbd_ctrl: command a9: aux i/f test. \n");
00798 #endif
00799 if(state.status.outb)
00800 {
00801 printf("kbd: OUTB set and command 0x%02x encountered", value);
00802 break;
00803 }
00804
00805 controller_enQ(0x00, 0);
00806 break;
00807
00808 case 0xaa:
00809 #if defined(DEBUG_KBD)
00810 printf("kbd_ctrl: command aa: self test. \n");
00811 #endif
00812 if(kbd_initialized == 0)
00813 {
00814 state.kbd_controller_Qsize = 0;
00815 state.status.outb = 0;
00816 kbd_initialized = 1;
00817 }
00818
00819
00820 if(state.status.outb)
00821 {
00822 printf("kbd: OUTB set and command 0x%02x encountered", value);
00823
00824
00825
00826 state.kbd_internal_buffer.head = 0;
00827 state.kbd_internal_buffer.num_elements = 0;
00828 state.status.outb = 0;
00829 }
00830
00831 state.status.sysf = 1;
00832 controller_enQ(0x55, 0);
00833 break;
00834
00835 case 0xab:
00836 #if defined(DEBUG_KBD)
00837 printf("kbd_ctrl: command ab: kbd i/f test. \n");
00838 #endif
00839
00840
00841 if(state.status.outb)
00842 {
00843 printf("kbd: OUTB set and command 0x%02x encountered", value);
00844 break;
00845 }
00846
00847 controller_enQ(0x00, 0);
00848 break;
00849
00850 case 0xad:
00851 set_kbd_clock_enable(0);
00852 #if defined(DEBUG_KBD)
00853 printf("kbd_ctrl: command ad: kbd i/f disable. \n");
00854 #endif
00855 break;
00856
00857 case 0xae:
00858 set_kbd_clock_enable(1);
00859 #if defined(DEBUG_KBD)
00860 printf("kbd_ctrl: command ae: kbd i/f enable. \n");
00861 #endif
00862 break;
00863
00864 case 0xaf:
00865 #if defined(DEBUG_KBD)
00866 printf("kbd_ctrl: command af: controller version (not supported). \n");
00867 #endif
00868 break;
00869
00870 case 0xc0:
00871 #if defined(DEBUG_KBD)
00872 printf("kbd_ctrl: command c0: read input port. \n");
00873 #endif
00874
00875
00876 if(state.status.outb)
00877 {
00878 BX_PANIC(("kbd: OUTB set and command 0x%02x encountered", value));
00879 break;
00880 }
00881
00882
00883 controller_enQ(0x80, 0);
00884 break;
00885
00886 case 0xd0:
00887 #if defined(DEBUG_KBD)
00888 printf("kbd_ctrl: command d0: read output port. (partial) \n");
00889 #endif
00890
00891
00892 if(state.status.outb)
00893 {
00894 BX_PANIC(("kbd: OUTB set and command 0x%02x encountered", value));
00895 break;
00896 }
00897
00898 controller_enQ((state.irq12_requested << 5) | (state.irq1_requested << 4) |
00899
00900 0x01, 0);
00901 break;
00902
00903 case 0xd1:
00904 #if defined(DEBUG_KBD)
00905 printf("kbd_ctrl: command d1: write output port. \n");
00906 #endif
00907
00908
00909 state.expecting_port60h = 1;
00910 break;
00911
00912 case 0xd3:
00913 #if defined(DEBUG_KBD)
00914 printf("kbd_ctrl: command d3: write aux output buffer. \n");
00915 #endif
00916
00917
00918 state.expecting_port60h = 1;
00919 break;
00920
00921 case 0xd4:
00922 #if defined(DEBUG_KBD)
00923 printf("kbd_ctrl: command d4: write to aux. \n");
00924 #endif
00925
00926
00927 state.expecting_port60h = 1;
00928 break;
00929
00930 case 0xd2:
00931 #if defined(DEBUG_KBD)
00932 printf("kbd_ctrl: command d2: write kbd output buffer. \n");
00933 #endif
00934 state.expecting_port60h = 1;
00935 break;
00936
00937 case 0xc1:
00938 case 0xc2:
00939 case 0xe0:
00940 BX_PANIC(("io write 0x64: command = %02xh", (unsigned) value));
00941 break;
00942
00943 default:
00944 if(value == 0xff || (value >= 0xf0 && value <= 0xfd))
00945 {
00946
00947
00948 #if defined(DEBUG_KBD)
00949 BX_DEBUG(("io write to port 64h, useless command %02x", (unsigned) value));
00950 #endif
00951 return;
00952 }
00953
00954 BX_ERROR(("unsupported io write to keyboard port 64, value = %x",
00955 (unsigned) value));
00956 break;
00957 }
00958
00959 execute();
00960 }
00961
00965 void CKeyboard::controller_enQ(u8 data, unsigned source)
00966 {
00967
00968
00969 #if defined(DEBUG_KBD)
00970 BX_DEBUG(("controller_enQ(%02x) source=%02x", (unsigned) data, source));
00971 #endif
00972
00973
00974
00975 if(state.status.outb)
00976 {
00977 if(state.kbd_controller_Qsize >= BX_KBD_CONTROLLER_QSIZE)
00978 FAILURE(Runtime, "controller_enq(): controller_Q full!");
00979 state.kbd_controller_Q[state.kbd_controller_Qsize++] = data;
00980 state.kbd_controller_Qsource = source;
00981 return;
00982 }
00983
00984
00985 if(source == 0)
00986 {
00987 state.kbd_output_buffer = data;
00988 state.status.outb = 1;
00989 state.status.auxb = 0;
00990 state.status.inpb = 0;
00991 if(state.allow_irq1)
00992 state.irq1_requested = 1;
00993 }
00994 else
00995 {
00996 state.aux_output_buffer = data;
00997 state.status.outb = 1;
00998 state.status.auxb = 1;
00999 state.status.inpb = 0;
01000 if(state.allow_irq12)
01001 state.irq12_requested = 1;
01002 }
01003 }
01004
01008 void CKeyboard::set_kbd_clock_enable(u8 value)
01009 {
01010 bool prev_kbd_clock_enabled;
01011
01012 if(value == 0)
01013 {
01014 state.kbd_clock_enabled = 0;
01015 }
01016 else
01017 {
01018
01019
01020 prev_kbd_clock_enabled = state.kbd_clock_enabled;
01021 state.kbd_clock_enabled = 1;
01022
01023 if(prev_kbd_clock_enabled == 0 && state.status.outb == 0)
01024 state.timer_pending = 1;
01025 }
01026 }
01027
01031 void CKeyboard::set_aux_clock_enable(u8 value)
01032 {
01033 bool prev_aux_clock_enabled;
01034
01035 #if defined(DEBUG_KBD)
01036 BX_DEBUG(("set_aux_clock_enable(%u)", (unsigned) value));
01037 #endif
01038 if(value == 0)
01039 {
01040 state.aux_clock_enabled = 0;
01041 }
01042 else
01043 {
01044
01045
01046 prev_aux_clock_enabled = state.aux_clock_enabled;
01047 state.aux_clock_enabled = 1;
01048 if(prev_aux_clock_enabled == 0 && state.status.outb == 0)
01049 state.timer_pending = 1;
01050 }
01051 }
01052
01056 void CKeyboard::ctrl_to_kbd(u8 value)
01057 {
01058 #if defined(DEBUG_KBD)
01059 BX_DEBUG(("controller passed byte %02xh to keyboard", value));
01060 #endif
01061 if(state.kbd_internal_buffer.expecting_make_break)
01062 {
01063 state.kbd_internal_buffer.expecting_make_break = 0;
01064 #if defined(DEBUG_KBD)
01065 printf("setting key %x to make/break mode (unused) \n", value);
01066 #endif
01067 enQ(0xFA);
01068 return;
01069 }
01070
01071 if(state.kbd_internal_buffer.expecting_typematic)
01072 {
01073 state.kbd_internal_buffer.expecting_typematic = 0;
01074 state.kbd_internal_buffer.delay = (value >> 5) & 0x03;
01075 #if defined(DEBUG_KBD)
01076 switch(state.kbd_internal_buffer.delay)
01077 {
01078 case 0: BX_INFO(("setting delay to 250 mS (unused)")); break;
01079 case 1: BX_INFO(("setting delay to 500 mS (unused)")); break;
01080 case 2: BX_INFO(("setting delay to 750 mS (unused)")); break;
01081 case 3: BX_INFO(("setting delay to 1000 mS (unused)")); break;
01082 }
01083 #endif
01084 state.kbd_internal_buffer.repeat_rate = value & 0x1f;
01085 #if defined(DEBUG_KBD)
01086 double cps = 1 /
01087 ((double) (8 + (value & 0x07)) * (double) exp(log((double) 2) * (double) ((value >> 3) & 0x03)) * 0.00417);
01088 BX_INFO(("setting repeat rate to %.1f cps (unused)", cps));
01089 #endif
01090 enQ(0xFA);
01091 return;
01092 }
01093
01094 if(state.kbd_internal_buffer.expecting_led_write)
01095 {
01096 state.kbd_internal_buffer.expecting_led_write = 0;
01097 state.kbd_internal_buffer.led_status = value;
01098 #if defined(DEBUG_KBD)
01099 BX_DEBUG(("LED status set to %02x",
01100 (unsigned) state.kbd_internal_buffer.led_status));
01101 #endif
01102 enQ(0xFA);
01103 return;
01104 }
01105
01106 if(state.expecting_scancodes_set)
01107 {
01108 state.expecting_scancodes_set = 0;
01109 if(value != 0)
01110 {
01111 if(value < 4)
01112 {
01113 state.current_scancodes_set = (value - 1);
01114 #if defined(DEBUG_KBD)
01115 BX_INFO(("Switched to scancode set %d",
01116 (unsigned) state.current_scancodes_set + 1));
01117 #endif
01118 enQ(0xFA);
01119 }
01120 else
01121 {
01122 BX_ERROR(("Received scancodes set out of range: %d", value));
01123 enQ(0xFF);
01124 }
01125 }
01126 else
01127 {
01128
01129
01130 enQ(0xFA);
01131
01132
01133 if(state.scancodes_translate)
01134 enQ(translation8042[1 + state.current_scancodes_set]);
01135 else
01136 enQ(1 + state.current_scancodes_set);
01137 }
01138
01139 return;
01140 }
01141
01142 switch(value)
01143 {
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160 case 0xed:
01161 state.kbd_internal_buffer.expecting_led_write = 1;
01162 #if defined(DEBUG_KBD)
01163 printf("kbd: Expecting led write info. \n");
01164 #endif
01165 enQ_imm(0xFA);
01166 break;
01167
01168 case 0xee:
01169 #if defined(DEBUG_KBD)
01170 printf("kbd: command ee: echo. \n");
01171 #endif
01172 enQ(0xEE);
01173 break;
01174
01175 case 0xf0:
01176 state.expecting_scancodes_set = 1;
01177 #if defined(DEBUG_KBD)
01178 printf("kbd: Expecting scancode set info. \n");
01179 #endif
01180 enQ(0xFA);
01181 break;
01182
01183 case 0xf2:
01184 #if defined(DEBUG_KBD)
01185 printf("kbd: command f2: identify keyboard. \n");
01186 #endif
01187
01188
01189
01190
01191
01192 enQ(0xFA);
01193 enQ(0xAB);
01194
01195 if(state.scancodes_translate)
01196 enQ(0x41);
01197 else
01198 enQ(0x83);
01199 break;
01200
01201 case 0xf3:
01202 state.kbd_internal_buffer.expecting_typematic = 1;
01203 #if defined(DEBUG_KBD)
01204 printf("kbd: Expecting typematic info. \n");
01205 #endif
01206 enQ(0xFA);
01207 break;
01208
01209 case 0xf4:
01210 state.kbd_internal_buffer.scanning_enabled = 1;
01211 #if defined(DEBUG_KBD)
01212 printf("kbd: command f4: enable keyboard. \n");
01213 #endif
01214 enQ(0xFA);
01215 break;
01216
01217 case 0xf5:
01218 resetinternals(1);
01219 enQ(0xFA);
01220 state.kbd_internal_buffer.scanning_enabled = 0;
01221 #if defined(DEBUG_KBD)
01222 printf("kbd: command f5: reset and disable keyboard. \n");
01223 #endif
01224 break;
01225
01226 case 0xf6:
01227 resetinternals(1);
01228 enQ(0xFA);
01229 state.kbd_internal_buffer.scanning_enabled = 1;
01230 #if defined(DEBUG_KBD)
01231 printf("kbd: command f6: reset and enable keyboard. \n");
01232 #endif
01233 break;
01234
01235 case 0xfc:
01236 state.kbd_internal_buffer.expecting_make_break = 1;
01237 #if defined(DEBUG_KBD)
01238 printf("kbd: Expecting make/break info. \n");
01239 #endif
01240 enQ(0xFA);
01241 break;
01242
01243 case 0xfe:
01244 printf("kbd: resend command received. \n");
01245 break;
01246
01247 case 0xff:
01248 #if defined(DEBUG_KBD)
01249 printf("kbd: command ff: reset keyboard w/BAT. \n");
01250 #endif
01251 resetinternals(1);
01252 enQ(0xFA);
01253 state.bat_in_progress = 1;
01254 enQ(0xAA);
01255 break;
01256
01257
01258
01259
01260 case 0xf7:
01261 case 0xf8:
01262 case 0xf9:
01263 case 0xfa:
01264 case 0xfb:
01265 case 0xfd:
01266 printf("kbd: unhandled command: %02x, ACKing \n", value);
01267 enQ(0xFA);
01268 break;
01269
01270 default:
01271 printf("kbd: command %02x: not recognized! \n", value);
01272 enQ(0xFE);
01273 break;
01274 }
01275 }
01276
01280 void CKeyboard::enQ_imm(u8 val)
01281 {
01282 int tail;
01283
01284 if(state.kbd_internal_buffer.num_elements >= BX_KBD_ELEMENTS)
01285 {
01286 BX_PANIC(("internal keyboard buffer full (imm)"));
01287 return;
01288 }
01289
01290 tail =
01291 (
01292 state.kbd_internal_buffer.head +
01293 state.kbd_internal_buffer.num_elements
01294 ) %
01295 BX_KBD_ELEMENTS;
01296
01297 state.kbd_output_buffer = val;
01298 state.status.outb = 1;
01299
01300 if(state.allow_irq1)
01301 state.irq1_requested = 1;
01302 }
01303
01307 void CKeyboard::ctrl_to_mouse(u8 value)
01308 {
01309 #if defined(DEBUG_KBD)
01310 BX_DEBUG(("MOUSE: ctrl_to_mouse(%02xh)", (unsigned) value));
01311 BX_DEBUG((" enable = %u", (unsigned) state.mouse.enable));
01312 BX_DEBUG((" allow_irq12 = %u", (unsigned) state.allow_irq12));
01313 BX_DEBUG((" aux_clock_enabled = %u", (unsigned) state.aux_clock_enabled));
01314 #endif
01315
01316
01317
01318 if(state.expecting_mouse_parameter)
01319 {
01320 state.expecting_mouse_parameter = 0;
01321 switch(state.last_mouse_command)
01322 {
01323 case 0xf3:
01324 state.mouse.sample_rate = value;
01325 #if defined(DEBUG_KBD)
01326 BX_DEBUG(("[mouse] Sampling rate set: %d Hz", value));
01327 #endif
01328 if((value == 200) && (!state.mouse.im_request))
01329 {
01330 state.mouse.im_request = 1;
01331 }
01332 else if((value == 100) && (state.mouse.im_request == 1))
01333 {
01334 state.mouse.im_request = 2;
01335 }
01336 else if((value == 80) && (state.mouse.im_request == 2))
01337 {
01338 #if defined(DEBUG_KBD)
01339 BX_INFO(("wheel mouse mode enabled"));
01340 #endif
01341 state.mouse.im_mode = 1;
01342 state.mouse.im_request = 0;
01343 }
01344 else
01345 {
01346 state.mouse.im_request = 0;
01347 }
01348
01349 controller_enQ(0xFA, 1);
01350 break;
01351
01352 case 0xe8:
01353 switch(value)
01354 {
01355 case 0: state.mouse.resolution_cpmm = 1; break;
01356 case 1: state.mouse.resolution_cpmm = 2; break;
01357 case 2: state.mouse.resolution_cpmm = 4; break;
01358 case 3: state.mouse.resolution_cpmm = 8; break;
01359 default: BX_PANIC(("[mouse] Unknown resolution %d", value)); break;
01360 }
01361
01362 #if defined(DEBUG_KBD)
01363 BX_DEBUG(("[mouse] Resolution set to %d counts per mm", state.mouse.
01364 resolution_cpmm));
01365 #endif
01366 controller_enQ(0xFA, 1);
01367 break;
01368
01369 default:
01370 BX_PANIC(("MOUSE: unknown last command (%02xh)",
01371 (unsigned) state.last_mouse_command));
01372 }
01373 }
01374 else
01375 {
01376 state.expecting_mouse_parameter = 0;
01377 state.last_mouse_command = value;
01378
01379
01380 if(state.mouse.mode == MOUSE_MODE_WRAP)
01381 {
01382
01383
01384
01385 if((value != 0xff) && (value != 0xec))
01386 {
01387
01388
01389 #if defined(DEBUG_KBD)
01390 BX_INFO(("[mouse] wrap mode: Ignoring command %0X02.", value));
01391 #endif
01392 controller_enQ(value, 1);
01393
01394
01395 return;
01396 }
01397 }
01398
01399 switch(value)
01400 {
01401 case 0xe6:
01402 controller_enQ(0xFA, 1);
01403 state.mouse.scaling = 2;
01404 #if defined(DEBUG_KBD)
01405 BX_DEBUG(("[mouse] Scaling set to 1:1"));
01406 #endif
01407 break;
01408
01409 case 0xe7:
01410 controller_enQ(0xFA, 1);
01411 state.mouse.scaling = 2;
01412 #if defined(DEBUG_KBD)
01413 BX_DEBUG(("[mouse] Scaling set to 2:1"));
01414 #endif
01415 break;
01416
01417 case 0xe8:
01418 controller_enQ(0xFA, 1);
01419 state.expecting_mouse_parameter = 1;
01420 break;
01421
01422 case 0xea:
01423
01424 #if defined(DEBUG_KBD)
01425 BX_INFO(("[mouse] Mouse stream mode on."));
01426 #endif
01427 state.mouse.mode = MOUSE_MODE_STREAM;
01428 controller_enQ(0xFA, 1);
01429 break;
01430
01431 case 0xec:
01432
01433 if(state.mouse.mode == MOUSE_MODE_WRAP)
01434 {
01435
01436
01437 #if defined(DEBUG_KBD)
01438 BX_INFO(("[mouse] Mouse wrap mode off."));
01439 #endif
01440
01441
01442
01443 state.mouse.mode = state.mouse.saved_mode;
01444 controller_enQ(0xFA, 1);
01445 }
01446 break;
01447
01448 case 0xee:
01449
01450
01451
01452 #if defined(DEBUG_KBD)
01453 BX_INFO(("[mouse] Mouse wrap mode on."));
01454 #endif
01455 state.mouse.saved_mode = state.mouse.mode;
01456 state.mouse.mode = MOUSE_MODE_WRAP;
01457 controller_enQ(0xFA, 1);
01458 break;
01459
01460 case 0xf0:
01461
01462 #if defined(DEBUG_KBD)
01463 BX_INFO(("[mouse] Mouse remote mode on."));
01464 #endif
01465
01466
01467 state.mouse.mode = MOUSE_MODE_REMOTE;
01468 controller_enQ(0xFA, 1);
01469 break;
01470
01471 case 0xf2:
01472 controller_enQ(0xFA, 1);
01473 if(state.mouse.im_mode)
01474 controller_enQ(0x03, 1);
01475 else
01476 controller_enQ(0x00, 1);
01477 #if defined(DEBUG_KBD)
01478 BX_DEBUG(("[mouse] Read mouse ID"));
01479 #endif
01480 break;
01481
01482 case 0xf3:
01483 controller_enQ(0xFA, 1);
01484 state.expecting_mouse_parameter = 1;
01485 break;
01486
01487 case 0xf4:
01488 state.mouse.enable = 1;
01489 controller_enQ(0xFA, 1);
01490 #if defined(DEBUG_KBD)
01491 BX_DEBUG(("[mouse] Mouse enabled (stream mode)"));
01492 #endif
01493 break;
01494
01495 case 0xf5:
01496 state.mouse.enable = 0;
01497 controller_enQ(0xFA, 1);
01498 #if defined(DEBUG_KBD)
01499 BX_DEBUG(("[mouse] Mouse disabled (stream mode)"));
01500 #endif
01501 break;
01502
01503 case 0xf6:
01504 state.mouse.sample_rate = 100;
01505 state.mouse.resolution_cpmm = 4;
01506 state.mouse.scaling = 1;
01507 state.mouse.enable = 0;
01508 state.mouse.mode = MOUSE_MODE_STREAM;
01509 controller_enQ(0xFA, 1);
01510 #if defined(DEBUG_KBD)
01511 BX_DEBUG(("[mouse] Set Defaults"));
01512 #endif
01513 break;
01514
01515 case 0xff:
01516 state.mouse.sample_rate = 100;
01517 state.mouse.resolution_cpmm = 4;
01518 state.mouse.scaling = 1;
01519 state.mouse.mode = MOUSE_MODE_RESET;
01520 state.mouse.enable = 0;
01521 #if defined(DEBUG_KBD)
01522 if(state.mouse.im_mode)
01523 BX_INFO(("wheel mouse mode disabled"));
01524 #endif
01525 state.mouse.im_mode = 0;
01526 controller_enQ(0xFA, 1);
01527 controller_enQ(0xAA, 1);
01528 controller_enQ(0x00, 1);
01529 #if defined(DEBUG_KBD)
01530 BX_DEBUG(("[mouse] Mouse reset"));
01531 #endif
01532 break;
01533
01534 case 0xe9:
01535
01536 controller_enQ(0xFA, 1);
01537 controller_enQ(state.mouse.get_status_byte(), 1);
01538 controller_enQ(state.mouse.get_resolution_byte(), 1);
01539 controller_enQ(state.mouse.sample_rate, 1);
01540 #if defined(DEBUG_KBD)
01541 BX_DEBUG(("[mouse] Get mouse information"));
01542 #endif
01543 break;
01544
01545 case 0xeb:
01546 controller_enQ(0xFA, 1);
01547
01548
01549 mouse_enQ_packet(((state.mouse.button_status & 0x0f) | 0x08), 0x00, 0x00,
01550 0x00);
01551
01552
01553 #if defined(DEBUG_KBD)
01554 BX_ERROR(("[mouse] Warning: Read Data command partially supported."));
01555 #endif
01556 break;
01557
01558 case 0xbb:
01559 #if defined(DEBUG_KBD)
01560 BX_ERROR(("[mouse] ignoring 0xbb command"));
01561 #endif
01562 break;
01563
01564 default:
01565 BX_ERROR(("[mouse] ctrl_to_mouse(): got value of 0x%02x", value));
01566 controller_enQ(0xFE, 1);
01567 }
01568 }
01569 }
01570
01574 bool CKeyboard::mouse_enQ_packet(u8 b1, u8 b2, u8 b3, u8 b4)
01575 {
01576 int bytes = 3;
01577 if(state.mouse.im_mode)
01578 bytes = 4;
01579
01580 if((state.mouse_internal_buffer.num_elements + bytes) >= BX_MOUSE_BUFF_SIZE)
01581 {
01582 return(0);
01583 }
01584
01585 mouse_enQ(b1);
01586 mouse_enQ(b2);
01587 mouse_enQ(b3);
01588 if(state.mouse.im_mode)
01589 mouse_enQ(b4);
01590
01591 return(1);
01592 }
01593
01597 void CKeyboard::mouse_enQ(u8 mouse_data)
01598 {
01599 int tail;
01600
01601 #if defined(DEBUG_KBD)
01602 BX_DEBUG(("mouse_enQ(%02x)", (unsigned) mouse_data));
01603 #endif
01604 if(state.mouse_internal_buffer.num_elements >= BX_MOUSE_BUFF_SIZE)
01605 {
01606 BX_ERROR(("[mouse] internal mouse buffer full, ignoring mouse data.(%02x)",
01607 (unsigned) mouse_data));
01608 return;
01609 }
01610
01611
01612 tail =
01613 (
01614 state.mouse_internal_buffer.head +
01615 state.mouse_internal_buffer.num_elements
01616 ) %
01617 BX_MOUSE_BUFF_SIZE;
01618 state.mouse_internal_buffer.buffer[tail] = mouse_data;
01619 state.mouse_internal_buffer.num_elements++;
01620
01621 if(!state.status.outb && state.aux_clock_enabled)
01622 {
01623 state.timer_pending = 1;
01624 return;
01625 }
01626 }
01627
01631 unsigned CKeyboard::periodic()
01632 {
01633 u8 retval;
01634
01635 retval = (state.irq1_requested << 0) | (state.irq12_requested << 1);
01636 state.irq1_requested = 0;
01637 state.irq12_requested = 0;
01638
01639 if(state.timer_pending == 0)
01640 {
01641 return(retval);
01642 }
01643
01644 if(1 >= state.timer_pending)
01645 {
01646 state.timer_pending = 0;
01647 }
01648 else
01649 {
01650 state.timer_pending--;
01651 return(retval);
01652 }
01653
01654 if(state.status.outb)
01655 {
01656 return(retval);
01657 }
01658
01659
01660 if(state.kbd_internal_buffer.num_elements
01661 && (state.kbd_clock_enabled || state.bat_in_progress))
01662 {
01663 #if defined(DEBUG_KBD)
01664 BX_DEBUG(("service_keyboard: key in internal buffer waiting"));
01665 #endif
01666 state.kbd_output_buffer = state.kbd_internal_buffer.buffer[state.kbd_internal_buffer.head];
01667 state.status.outb = 1;
01668
01669
01670
01671
01672 state.kbd_internal_buffer.head = (state.kbd_internal_buffer.head + 1) % BX_KBD_ELEMENTS;
01673 state.kbd_internal_buffer.num_elements--;
01674 if(state.allow_irq1)
01675 state.irq1_requested = 1;
01676 }
01677 else
01678 {
01679 create_mouse_packet(0);
01680 if(state.aux_clock_enabled && state.mouse_internal_buffer.num_elements)
01681 {
01682 #if defined(DEBUG_KBD)
01683 BX_DEBUG(("service_keyboard: key(from mouse) in internal buffer waiting"));
01684 #endif
01685 state.aux_output_buffer = state.mouse_internal_buffer.buffer[state.mouse_internal_buffer.head];
01686
01687 state.status.outb = 1;
01688 state.status.auxb = 1;
01689 state.mouse_internal_buffer.head =
01690 (
01691 state.mouse_internal_buffer.head +
01692 1
01693 ) %
01694 BX_MOUSE_BUFF_SIZE;
01695 state.mouse_internal_buffer.num_elements--;
01696 if(state.allow_irq12)
01697 state.irq12_requested = 1;
01698 }
01699
01700 #if defined(DEBUG_KBD)
01701 else
01702 {
01703 BX_DEBUG(("service_keyboard(): no keys waiting"));
01704 }
01705 #endif
01706 }
01707
01708 return(retval);
01709 }
01710
01714 void CKeyboard::create_mouse_packet(bool force_enq)
01715 {
01716 u8 b1;
01717
01718 u8 b2;
01719
01720 u8 b3;
01721
01722 u8 b4;
01723
01724 if(state.mouse_internal_buffer.num_elements && !force_enq)
01725 return;
01726
01727 s16 delta_x = state.mouse.delayed_dx;
01728 s16 delta_y = state.mouse.delayed_dy;
01729 u8 button_state = state.mouse.button_status | 0x08;
01730
01731 if(!force_enq && !delta_x && !delta_y)
01732 {
01733 return;
01734 }
01735
01736 if(delta_x > 254)
01737 delta_x = 254;
01738 if(delta_x < -254)
01739 delta_x = -254;
01740 if(delta_y > 254)
01741 delta_y = 254;
01742 if(delta_y < -254)
01743 delta_y = -254;
01744
01745 b1 = (button_state & 0x0f) | 0x08;
01746 if((delta_x >= 0) && (delta_x <= 255))
01747 {
01748 b2 = (u8) delta_x;
01749 state.mouse.delayed_dx -= delta_x;
01750 }
01751 else if(delta_x > 255)
01752 {
01753 b2 = (u8) 0xff;
01754 state.mouse.delayed_dx -= 255;
01755 }
01756 else if(delta_x >= -256)
01757 {
01758 b2 = (u8) delta_x;
01759 b1 |= 0x10;
01760 state.mouse.delayed_dx -= delta_x;
01761 }
01762 else
01763 {
01764 b2 = (u8) 0x00;
01765 b1 |= 0x10;
01766 state.mouse.delayed_dx += 256;
01767 }
01768
01769 if((delta_y >= 0) && (delta_y <= 255))
01770 {
01771 b3 = (u8) delta_y;
01772 state.mouse.delayed_dy -= delta_y;
01773 }
01774 else if(delta_y > 255)
01775 {
01776 b3 = (u8) 0xff;
01777 state.mouse.delayed_dy -= 255;
01778 }
01779 else if(delta_y >= -256)
01780 {
01781 b3 = (u8) delta_y;
01782 b1 |= 0x20;
01783 state.mouse.delayed_dy -= delta_y;
01784 }
01785 else
01786 {
01787 b3 = (u8) 0x00;
01788 b1 |= 0x20;
01789 state.mouse.delayed_dy += 256;
01790 }
01791
01792 b4 = (u8) - state.mouse.delayed_dz;
01793
01794 mouse_enQ_packet(b1, b2, b3, b4);
01795 }
01796
01806 void CKeyboard::execute()
01807 {
01808 unsigned retval;
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818 retval = periodic();
01819
01820 if(retval & 0x01)
01821 theAli->pic_interrupt(0, 1);
01822 if(retval & 0x02)
01823 theAli->pic_interrupt(1, 4);
01824 }
01825
01829 void CKeyboard::check_state()
01830 {
01831 if(myThread && !myThread->isRunning())
01832 FAILURE(Thread, "KBD thread has died");
01833 }
01834
01838 void CKeyboard::run()
01839 {
01840 try
01841 {
01842 for(;;)
01843 {
01844 if(StopThread)
01845 return;
01846 execute();
01847 Poco::Thread::sleep(20);
01848 }
01849 }
01850
01851 catch(Poco::Exception & e)
01852 {
01853 printf("Exception in kbd thread: %s.\n", e.displayText().c_str());
01854
01855
01856 }
01857 }
01858
01859 static u32 kb_magic1 = 0x65481687;
01860 static u32 kb_magic2 = 0x24895375;
01861
01865 int CKeyboard::SaveState(FILE* f)
01866 {
01867 long ss = sizeof(state);
01868
01869 fwrite(&kb_magic1, sizeof(u32), 1, f);
01870 fwrite(&ss, sizeof(long), 1, f);
01871 fwrite(&state, sizeof(state), 1, f);
01872 fwrite(&kb_magic2, sizeof(u32), 1, f);
01873 printf("kbc: %d bytes saved.\n", (int) ss);
01874 return 0;
01875 }
01876
01880 int CKeyboard::RestoreState(FILE* f)
01881 {
01882 long ss;
01883 u32 m1;
01884 u32 m2;
01885 size_t r;
01886
01887 r = fread(&m1, sizeof(u32), 1, f);
01888 if(r != 1)
01889 {
01890 printf("kbc: unexpected end of file!\n");
01891 return -1;
01892 }
01893
01894 if(m1 != kb_magic1)
01895 {
01896 printf("kbc: MAGIC 1 does not match!\n");
01897 return -1;
01898 }
01899
01900 fread(&ss, sizeof(long), 1, f);
01901 if(r != 1)
01902 {
01903 printf("kbc: unexpected end of file!\n");
01904 return -1;
01905 }
01906
01907 if(ss != sizeof(state))
01908 {
01909 printf("kbc: STRUCT SIZE does not match!\n");
01910 return -1;
01911 }
01912
01913 fread(&state, sizeof(state), 1, f);
01914 if(r != 1)
01915 {
01916 printf("kbc: unexpected end of file!\n");
01917 return -1;
01918 }
01919
01920 r = fread(&m2, sizeof(u32), 1, f);
01921 if(r != 1)
01922 {
01923 printf("kbc: unexpected end of file!\n");
01924 return -1;
01925 }
01926
01927 if(m2 != kb_magic2)
01928 {
01929 printf("kbc: MAGIC 1 does not match!\n");
01930 return -1;
01931 }
01932
01933 printf("kbc: %d bytes restored.\n", (int) ss);
01934 return 0;
01935 }
01936
01937 CKeyboard* theKeyboard = 0;